/** * Marabou - Audio Tagger * Copyright (C) 2012 - 2016 Jan-Hendrik Peters * https://github.com/hennr/marabou * Marabou is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. */ package com.github.marabou.audio.store; import com.github.marabou.audio.AudioFile; import com.github.marabou.audio.AudioFileFactory; import com.github.marabou.audio.AudioFileProperty; import com.github.marabou.audio.save.SaveService; import com.github.marabou.ui.events.ErrorEvent; import com.github.marabou.ui.events.FilesSelectedEvent; import com.github.marabou.ui.events.OpenFileEvent; import com.github.marabou.ui.events.SaveSelectedFilesEvent; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.mpatric.mp3agic.ID3v24Tag; import com.mpatric.mp3agic.Mp3File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.util.*; import static com.github.marabou.helper.Constants.IGNORE_THIS_WHEN_SAVING; public class AudioFileStore { Logger log = LoggerFactory.getLogger(AudioFileStore.class); private final EventBus bus; private final SaveService saveService; AudioFileFactory audioFileFactory; protected Map<String, AudioFile> audioFiles = new HashMap<>(); protected Set<AudioFile> currentlySelectedFiles = new HashSet<>(); protected AudioFile sidePanelEntries = new AudioFile(""); public AudioFileStore(EventBus bus, AudioFileFactory audioFileFactory, SaveService saveService) { this.bus = bus; bus.register(this); this.audioFileFactory = audioFileFactory; this.saveService = saveService; } protected void addFile(final File inputFile) { if (isFileAlreadyInStore(inputFile)) { return; } try { AudioFile audioFile = audioFileFactory.createAudioFile(inputFile); storeAudioFile(audioFile); bus.post(new AudioFileAddedEvent(audioFile)); } catch (Exception e) { log.error("error during file add", e); bus.post(new ErrorEvent(e.getMessage())); } } private boolean isFileAlreadyInStore(File inputFile) { try { if (audioFiles.containsKey(inputFile.getCanonicalPath())) { return true; } } catch (IOException e) { e.printStackTrace(); } return false; } private void storeAudioFile(AudioFile newFile) { audioFiles.put(newFile.getFilePath(), newFile); } public void removeAudioFile(String filePath) { audioFiles.remove(filePath); } public AudioFile getAudioFileByFilePath(String filePath) { return audioFiles.get(filePath); } @Subscribe public void onOpenFile(OpenFileEvent openFileEvent) { try { addFile(openFileEvent.getFile()); } catch (RuntimeException e) { bus.post(new ErrorEvent("Couldn't open file: " + openFileEvent.getFile())); } } @Subscribe public void updateSidePanelModel(FilesSelectedEvent event) { currentlySelectedFiles = event.selectedAudioFiles; } @Subscribe public void onAudioFilePropertyUpdate(SidePanelModifiedEvent update) { AudioFileProperty property = update.getAudioFileProperty(); String newValue = update.getNewValue(); switch (property) { case Album: sidePanelEntries = sidePanelEntries.withAlbum(newValue); break; case Artist: sidePanelEntries = sidePanelEntries.withArtist(newValue); break; case Comments: sidePanelEntries = sidePanelEntries.withComment(newValue); break; case Composer: sidePanelEntries = sidePanelEntries.withComposer(newValue); break; case Disc_number: sidePanelEntries = sidePanelEntries.withDiscNumber(newValue); break; case Genre: sidePanelEntries = sidePanelEntries.withGenre(newValue); break; case Title: sidePanelEntries = sidePanelEntries.withTitle(newValue); break; case Track: sidePanelEntries = sidePanelEntries.withTrack(newValue); break; case Year: sidePanelEntries = sidePanelEntries.withYear(newValue); break; default: throw new RuntimeException("Found an untreated audio file property: " + property + " Please file a bug report at the project website."); } } @Subscribe public void onSaveSelectedFiles(SaveSelectedFilesEvent saveSelectedFilesEvent) { for (AudioFile audioFile : currentlySelectedFiles) { Mp3File mp3File = audioFileFactory.createMp3File(new File(audioFile.getFilePath())); mp3File.setId3v2Tag(createTagForAudioFile(audioFile)); try { String newFilePath = saveService.saveMp3File(mp3File); removeAudioFile(mp3File.getFilename()); storeAudioFile(audioFileFactory.createAudioFile(mp3File)); AudioFileSavedEvent savedEvent = new AudioFileSavedEvent(audioFile.getFilePath(), newFilePath); bus.post(savedEvent); } catch (RuntimeException e) { bus.post(new ErrorEvent("Error saving file: " + mp3File.getFilename())); } } } private ID3v24Tag createTagForAudioFile(AudioFile currentAudioFile) { ID3v24Tag id3Tag = new ID3v24Tag(); id3Tag.setAlbum(determineSaveValue(sidePanelEntries.getAlbum(), currentAudioFile.getAlbum())); id3Tag.setArtist(determineSaveValue(sidePanelEntries.getArtist(), currentAudioFile.getArtist())); id3Tag.setComment(determineSaveValue(sidePanelEntries.getComment(), currentAudioFile.getComment())); id3Tag.setComposer(determineSaveValue(sidePanelEntries.getComposer(), currentAudioFile.getComposer())); id3Tag.setPartOfSet(determineSaveValue(sidePanelEntries.getDiscNumber(), currentAudioFile.getDiscNumber())); id3Tag.setGenreDescription(determineSaveValue(sidePanelEntries.getGenre(), currentAudioFile.getGenre())); id3Tag.setTitle(determineSaveValue(sidePanelEntries.getTitle(), currentAudioFile.getTitle())); id3Tag.setTrack(determineSaveValue(sidePanelEntries.getTrack(), currentAudioFile.getTrack())); id3Tag.setYear(determineSaveValue(sidePanelEntries.getYear(), currentAudioFile.getYear())); return id3Tag; } private String determineSaveValue(String sidePanelValue, String oldValue) { return sidePanelValue.equals(IGNORE_THIS_WHEN_SAVING) ? oldValue : sidePanelValue; } public Set<AudioFile> getSelectedAudioFiles() { return currentlySelectedFiles; } public List<AudioFile> getStoredAudioFiles() { return new LinkedList<>(audioFiles.values()); } }