package com.simplecity.amp_library.tagger;
import android.os.AsyncTask;
import android.os.ParcelFileDescriptor;
import android.support.v4.provider.DocumentFile;
import com.simplecity.amp_library.ShuttleApplication;
import com.simplecity.amp_library.model.TagUpdate;
import com.simplecity.amp_library.utils.ShuttleUtils;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.CannotWriteException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.TagException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class TaggerTask extends AsyncTask<Object, Integer, Boolean> {
public interface TagCompletionListener {
void onSuccess();
void onFailure();
void onProgress(int progress);
}
private TagCompletionListener tagCompletionListener;
private boolean showAlbum;
private boolean showTrack;
private List<String> paths;
private List<DocumentFile> documentFiles;
private List<File> tempFiles = new ArrayList<>();
private String titleText;
private String albumText;
private String artistText;
private String albumArtistText;
private String yearText;
private String trackText;
private String trackTotalText;
private String discText;
private String discTotalText;
private String lyricsText;
private String commentText;
private String genreText;
public TaggerTask() {
}
public TaggerTask(boolean showAlbum, boolean showTrack, List<String> paths,
List<DocumentFile> documentFiles, String titleText, String albumText,
String artistText, String albumArtistText, String yearText, String trackText,
String trackTotalText, String discText, String discTotalText, String lyricsText,
String commentText, String genreText,
TagCompletionListener listener) {
this.showAlbum = showAlbum;
this.showTrack = showTrack;
this.paths = paths;
this.documentFiles = documentFiles;
this.titleText = titleText;
this.albumText = albumText;
this.artistText = artistText;
this.albumArtistText = albumArtistText;
this.yearText = yearText;
this.trackText = trackText;
this.trackTotalText = trackTotalText;
this.discText = discText;
this.discTotalText = discTotalText;
this.lyricsText = lyricsText;
this.commentText = commentText;
this.genreText = genreText;
this.tagCompletionListener = listener;
}
@Override
protected Boolean doInBackground(Object... params) {
boolean success = false;
boolean requiresPermission = TaggerUtils.requiresPermission(paths);
for (int i = 0; i < paths.size(); i++) {
final String path = paths.get(i);
try {
File orig = new File(path);
AudioFile audioFile = AudioFileIO.read(orig);
Tag tag = audioFile.getTag();
if (tag == null) {
break;
}
TagUpdate tagUpdate = new TagUpdate(tag);
tagUpdate.softSetArtist(artistText);
tagUpdate.softSetAlbumArtist(albumArtistText);
tagUpdate.softSetGenre(genreText);
tagUpdate.softSetYear(yearText);
if (showAlbum) {
tagUpdate.softSetAlbum(albumText);
tagUpdate.softSetDiscTotal(discTotalText);
}
if (showTrack) {
tagUpdate.softSetTitle(titleText);
tagUpdate.softSetTrack(trackText);
tagUpdate.softSetTrackTotal(trackTotalText);
tagUpdate.softSetDisc(discText);
tagUpdate.softSetLyrics(lyricsText);
tagUpdate.softSetComment(commentText);
}
File temp = null;
if (tagUpdate.hasChanged()) {
if (ShuttleUtils.hasLollipop() && TaggerUtils.requiresPermission(paths)) {
temp = new File(ShuttleApplication.getInstance().getFilesDir(), orig.getName());
tempFiles.add(temp);
TaggerUtils.copyFile(orig, temp);
audioFile = AudioFileIO.read(temp);
tag = audioFile.getTag();
if (tag == null) {
break;
}
}
tagUpdate.updateTag(tag);
AudioFileIO.write(audioFile);
if (ShuttleUtils.hasLollipop() && requiresPermission && temp != null) {
DocumentFile documentFile = documentFiles.get(i);
if (documentFile != null) {
ParcelFileDescriptor pfd = ShuttleApplication.getInstance().getContentResolver().openFileDescriptor(documentFile.getUri(), "w");
if (pfd != null) {
FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
TaggerUtils.copyFile(temp, fileOutputStream);
pfd.close();
}
if (temp.delete()) {
if (tempFiles.contains(temp)) {
tempFiles.remove(temp);
}
}
}
}
}
publishProgress(i);
success = true;
} catch (CannotWriteException | IOException | CannotReadException | InvalidAudioFrameException | TagException | ReadOnlyFileException e) {
e.printStackTrace();
} finally {
//Try to clean up our temp files
if (tempFiles != null && tempFiles.size() != 0) {
for (int j = tempFiles.size() - 1; j >= 0; j--) {
File file = tempFiles.get(j);
file.delete();
tempFiles.remove(j);
}
}
}
}
return success;
}
@Override
protected void onPostExecute(Boolean success) {
if (tagCompletionListener != null) {
if (success) {
tagCompletionListener.onSuccess();
} else {
tagCompletionListener.onFailure();
}
}
}
@Override
protected void onProgressUpdate(Integer... object) {
if (tagCompletionListener != null) {
tagCompletionListener.onProgress(object[0] + 1);
}
}
//Builders
public TaggerTask setPaths(List<String> paths) {
this.paths = paths;
return this;
}
public TaggerTask setDocumentfiles(List<DocumentFile> documentFiles) {
this.documentFiles = documentFiles;
return this;
}
public TaggerTask showAlbum(boolean showAlbum) {
this.showAlbum = showAlbum;
return this;
}
public TaggerTask showTrack(boolean showTrack) {
this.showTrack = showTrack;
return this;
}
public TaggerTask title(String titleText) {
this.titleText = titleText;
return this;
}
public TaggerTask album(String albumText) {
this.albumText = albumText;
return this;
}
public TaggerTask artist(String artistText) {
this.artistText = artistText;
return this;
}
public TaggerTask albumArtist(String albumArtistText) {
this.albumArtistText = albumArtistText;
return this;
}
public TaggerTask year(String yearText) {
this.yearText = yearText;
return this;
}
public TaggerTask track(String trackText) {
this.trackText = trackText;
return this;
}
public TaggerTask trackTotal(String trackTotalText) {
this.trackTotalText = trackTotalText;
return this;
}
public TaggerTask disc(String discText) {
this.discText = discText;
return this;
}
public TaggerTask discTotal(String discTotalText) {
this.discTotalText = discTotalText;
return this;
}
public TaggerTask lyrics(String lyricsText) {
this.lyricsText = lyricsText;
return this;
}
public TaggerTask comment(String commentText) {
this.commentText = commentText;
return this;
}
public TaggerTask genre(String genreText) {
this.genreText = genreText;
return this;
}
public TaggerTask listener(TagCompletionListener listener) {
this.tagCompletionListener = listener;
return this;
}
public TaggerTask build() {
return new TaggerTask(showAlbum, showTrack, paths, documentFiles, titleText,
albumText, artistText, albumArtistText, yearText, trackText, trackTotalText,
discText, discTotalText, lyricsText, commentText, genreText,
tagCompletionListener);
}
}