Rebased on branch from develop. Overwrite files preference and renamed "groups" to "Playlists" (The term Groups really confused me!!!).

This commit is contained in:
Mark Gillespie 2017-01-19 23:03:44 +00:00
parent 782ada5c12
commit 81035f1082
7 changed files with 179 additions and 142 deletions

View file

@ -68,15 +68,12 @@ public class ExportAllService extends IntentService {
if (lTrack.isOfflineAvailable()) {
String lPath = MusicPathBuilder.Build(lTrack, lExportStructure);
try {
if (!isAlreadyThere(lUri, lPath)) {
if (lPlayMusicManager.exportMusicTrack(lTrack, lUri, lPath)) {
Log.i(TAG, "Exported Music Track: " + getStringForTrack(lTrack));
} else {
Log.i(TAG, "Failed to export Music Track: " + getStringForTrack(lTrack));
}
if (lPlayMusicManager.exportMusicTrack(lTrack, lUri, lPath, PlayMusicExporterPreferences.getFileOverwritePreference())) {
Log.i(TAG, "Exported Music Track: " + getStringForTrack(lTrack));
} else {
Log.i(TAG, lPath + " already exists.");
Log.i(TAG, "Failed to export Music Track: " + getStringForTrack(lTrack));
}
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Invalid URI:")) {
/*
@ -92,19 +89,6 @@ public class ExportAllService extends IntentService {
}
}
private boolean isAlreadyThere(Uri pUri, String pPath) {
DocumentFile lDocumentFile = DocumentFile.fromTreeUri(this, pUri);
for (String lDisplayName: pPath.split("/")) {
if (lDocumentFile.findFile(lDisplayName) != null) {
lDocumentFile = lDocumentFile.findFile(lDisplayName);
} else {
Log.i(TAG, pPath + " does not exist yet.");
return false;
}
}
return true;
}
private String getStringForTrack(MusicTrack pTrack) {
return pTrack.getAlbumArtist() + " - " + pTrack.getAlbum() + " - " + pTrack.getTitle();
}

View file

@ -35,6 +35,7 @@ import re.jcg.playmusicexporter.R;
import de.arcus.playmusiclib.PlayMusicManager;
import de.arcus.playmusiclib.datasources.MusicTrackDataSource;
import de.arcus.playmusiclib.items.MusicTrack;
import re.jcg.playmusicexporter.settings.PlayMusicExporterPreferences;
/**
* The export service
@ -199,7 +200,7 @@ public class ExportService extends IntentService {
updateNotification();
// Exports the song
if(!playMusicManager.exportMusicTrack(mTrackCurrent, uri, path)) {
if(!playMusicManager.exportMusicTrack(mTrackCurrent, uri, path, PlayMusicExporterPreferences.getFileOverwritePreference())) {
// Export failed
mTracksFailed ++;
}

View file

@ -16,6 +16,8 @@ public class PlayMusicExporterPreferences {
public static final boolean AUTO_EXPORT_ENABLED_DEFAULT = false;
public static final String AUTO_EXPORT_USES_DIFFERENT_PATH = "preference_auto_export_use_different_path";
public static final boolean AUTO_EXPORT_USES_DIFFERENT_PATH_DEFAULT = false;
private static final String FORCE_EXPORT_OVERWRITE = "preference_overwrite_existing_files";
private static final boolean FORCE_EXPORT_OVERWRITE_DEFAULT = false;
public static final String AUTO_EXPORT_USES_DIFFERENT_STRUCTURE = "preference_auto_export_use_different_structure";
public static final boolean AUTO_EXPORT_USES_DIFFERENT_STRUCTURE_DEFAULT = false;
public static final String AUTO_EXPORT_FREQUENCY = "preference_auto_export_frequency";
@ -63,6 +65,10 @@ public class PlayMusicExporterPreferences {
}
}
public static boolean getFileOverwritePreference() {
return preferences.getBoolean(FORCE_EXPORT_OVERWRITE, FORCE_EXPORT_OVERWRITE_DEFAULT);
}
public static boolean getAutoExportUsesDifferentPath() {
return preferences.getBoolean(AUTO_EXPORT_USES_DIFFERENT_PATH, AUTO_EXPORT_USES_DIFFERENT_PATH_DEFAULT);
}

View file

@ -101,4 +101,8 @@
<string name="dialog_superuser_access_denied_title">Administrator-Zugriff verweigert</string>
<string name="dialog_superuser_access_denied">Der Play Music Exporter benötigt Administrator Rechte, ohne diese Rechte kann die App nicht genutzt werden.</string>
<string name="settings_auto_export_different_structure_dialog_title">Verzeichnisbaum</string>
<string name="settings_export_overwrite_existing">Bestehende Dateien überschreiben</string>
<string name="file_handling_category">Dateiverarbeitung</string>
<string name="overwrite_summary">Überschreiben Sie die exportierte Datei immer, auch wenn sie bereits existiert.</string>
<string name="overwrite_title">Bestehende Dateien überschreiben.</string>
</resources>

View file

@ -73,7 +73,7 @@
<string name="settings_category_auto_export_path_subdir">Export path and subdirectory structure</string>
<string name="settings_category_debug">Debug</string>
<string name="settings_category_alba_export">Export location albums</string>
<string name="settings_category_groups_export">Export location groups</string>
<string name="settings_category_groups_export">Export location playlists</string>
<string name="settings_version_number">Version Number</string>
@ -101,7 +101,7 @@
<string name="settings_export_structure_alba_dialog_title">Set your subdirectory structure</string>
<string name="settings_export_subdirectory_structure_album_example">Example: Beatles/Help!/13. Yesterday.mp3</string>
<string name="settings_export_path_groups">Export path for groups</string>
<string name="settings_export_path_groups">Export path for playlists</string>
<string name="settings_export_structure_groups">Subdirectory structure for playlists</string>
<string name="settings_export_structure_groups_dialog_title">Set your subdirectory structure</string>
<string name="settings_export_subdirectory_structure_group_example">Example: Great Songs/4. Beatles - Yesterday.mp3</string>
@ -116,6 +116,7 @@
<string name="settings_export_id3_artwork_size_summary">If the artwork original size is larger than this setting the app will size down the artwork to this size.</string>
<string name="settings_export_path_custom">Custom path</string>
<string name="settings_export_overwrite_existing">Overwrite existing files</string>
<string name="settings_open_old_homepage_title" translatable="false">David-Schulte.de</string>
<string name="settings_open_old_homepage_url" translatable="false"><![CDATA[http://www.david-schulte.de/]]></string>
@ -142,4 +143,7 @@
<string name="settings_export_structure_groups_default_value" translatable="false">{group}/{group-no=$$.} {artist} - {title}.mp3</string>
<string name="debug_trigger_export_all_title">Trigger ExportAllService now</string>
<string name="file_handling_category">File Handling</string>
<string name="overwrite_summary">Always overwrite the exported file, even if it already exists.</string>
<string name="overwrite_title">Overwrite Existing Files</string>
</resources>

View file

@ -49,4 +49,10 @@
android:summary="@string/settings_export_id3_artwork_size_summary"
android:title="@string/settings_export_id3_artwork_size" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/file_handling_category">
<SwitchPreference
android:key="preference_overwrite_existing_files"
android:summary="@string/overwrite_summary"
android:title="@string/overwrite_title" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -34,6 +34,7 @@ import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.support.v4.provider.DocumentFile;
import android.text.TextUtils;
import android.util.Log;
import com.mpatric.mp3agic.ID3v1Genres;
import com.mpatric.mp3agic.ID3v1Tag;
@ -467,9 +468,10 @@ public class PlayMusicManager {
* Exports a track to the sd card
* @param musicTrack The music track you want to export
* @param dest The destination path
* @param forceOverwrite Forces overwrite of the destination file
* @return Returns whether the export was successful
*/
public boolean exportMusicTrack(MusicTrack musicTrack, String dest) {
public boolean exportMusicTrack(MusicTrack musicTrack, String dest, boolean forceOverwrite ) {
// Creates the destination directory
File directory = new File(dest).getParentFile();
@ -477,16 +479,17 @@ public class PlayMusicManager {
// Filename
String filename = new File(dest).getName();
return exportMusicTrack(musicTrack, Uri.fromFile(directory), filename);
return exportMusicTrack(musicTrack, Uri.fromFile(directory), filename, forceOverwrite);
}
/**
* Exports a track to the sd card
* @param musicTrack The music track you want to export
* @param uri The document tree
* @param forceOverwrite Forces overwrite of the destination file
* @return Returns whether the export was successful
*/
public boolean exportMusicTrack(MusicTrack musicTrack, Uri uri, String path) {
public boolean exportMusicTrack(MusicTrack musicTrack, Uri uri, String path, boolean forceOverwrite) {
// Check for null
if (musicTrack == null) return false;
@ -496,94 +499,109 @@ public class PlayMusicManager {
// Could not find the source file
if (srcFile == null) return false;
String fileTmp = getTempPath() + "tmp.mp3";
if ( forceOverwrite || !isAlreadyThere(uri, path) )
{
// Copy to temp path failed
if (!SuperUserTools.fileCopy(srcFile, fileTmp))
return false;
String fileTmp = getTempPath() + "tmp.mp3";
// Encrypt the file
if (musicTrack.isEncoded()) {
String fileTmpCrypt = getTempPath() + "crypt.mp3";
// Copy to temp path failed
if (!SuperUserTools.fileCopy(srcFile, fileTmp))
return false;
// Encrypts the file
if (trackEncrypt(musicTrack, fileTmp, fileTmpCrypt)) {
// Remove the old tmp file
FileTools.fileDelete(fileTmp);
// Encrypt the file
if (musicTrack.isEncoded()) {
String fileTmpCrypt = getTempPath() + "crypt.mp3";
// New tmp file
fileTmp = fileTmpCrypt;
} else {
Logger.getInstance().logWarning("ExportMusicTrack", "Encrypting failed! Continue with decrypted file.");
// Encrypts the file
if (trackEncrypt(musicTrack, fileTmp, fileTmpCrypt)) {
// Remove the old tmp file
FileTools.fileDelete(fileTmp);
// New tmp file
fileTmp = fileTmpCrypt;
} else {
Logger.getInstance().logWarning("ExportMusicTrack", "Encrypting failed! Continue with decrypted file.");
}
}
}
String dest;
Uri copyUri = null;
if (uri.toString().startsWith("file://")) {
// Build the full path
dest = uri.buildUpon().appendPath(path).build().getPath();
String dest;
Uri copyUri = null;
if (uri.toString().startsWith("file://")) {
// Build the full path
dest = uri.buildUpon().appendPath(path).build().getPath();
String parentDirectory = new File(dest).getParent();
FileTools.directoryCreate(parentDirectory);
} else {
// Complex uri (Lollipop)
dest = getTempPath() + "final.mp3";
String parentDirectory = new File(dest).getParent();
FileTools.directoryCreate(parentDirectory);
} else {
// Complex uri (Lollipop)
dest = getTempPath() + "final.mp3";
// The root
DocumentFile document = DocumentFile.fromTreeUri(mContext, uri);
// The root
DocumentFile document = DocumentFile.fromTreeUri(mContext, uri);
// Creates the subdirectories
String[] directories = path.split("\\/");
for(int i=0; i<directories.length - 1; i++) {
String directoryName = directories[i];
boolean found = false;
// Creates the subdirectories
String[] directories = path.split("\\/");
for(int i=0; i<directories.length - 1; i++) {
String directoryName = directories[i];
boolean found = false;
// Search all sub elements
for (DocumentFile subDocument: document.listFiles()) {
// Search all sub elements
for (DocumentFile subDocument: document.listFiles()) {
// Directory exists
if (subDocument.isDirectory() && subDocument.getName().equalsIgnoreCase(directoryName)) {
document = subDocument;
found = true;
break;
}
}
if (!found) {
// Create the directory
document = document.createDirectory(directoryName);
}
}
// Gets the filename
String filename = directories[directories.length - 1];
for (DocumentFile subDocument: document.listFiles()) {
// Directory exists
if (subDocument.isDirectory() && subDocument.getName().equals(directoryName)) {
document = subDocument;
found = true;
if (subDocument.isFile() && subDocument.getName().equalsIgnoreCase(filename)) {
// Delete the file
if ( forceOverwrite ) {
Logger.getInstance().logWarning("ExportMusicTrack", "(forceOverwrite) Deleting original file: " + filename);
}
subDocument.delete();
break;
}
}
if (!found) {
// Create the directory
document = document.createDirectory(directoryName);
}
// Create the mp3 file
document = document.createFile("music/mp3", filename);
// Create the directories
copyUri = document.getUri();
}
// Gets the filename
String filename = directories[directories.length - 1];
for (DocumentFile subDocument: document.listFiles()) {
// Directory exists
if (subDocument.isFile() && subDocument.getName().equals(filename)) {
// Delete the file
subDocument.delete();
break;
// We want to export the ID3 tags
if (mID3Enable) {
// Adds the meta data
if (!trackWriteID3(musicTrack, fileTmp, dest)) {
Logger.getInstance().logWarning("ExportMusicTrack", "ID3 writer failed! Continue without ID3 tags.");
// Failed, moving without meta data
if (!FileTools.fileMove(fileTmp, dest)) {
Logger.getInstance().logError("ExportMusicTrack", "Moving the raw file failed!");
// Could not copy the file
return false;
}
}
}
// Create the mp3 file
document = document.createFile("music/mp3", filename);
// Create the directories
copyUri = document.getUri();
}
// We want to export the ID3 tags
if (mID3Enable) {
// Adds the meta data
if (!trackWriteID3(musicTrack, fileTmp, dest)) {
Logger.getInstance().logWarning("ExportMusicTrack", "ID3 writer failed! Continue without ID3 tags.");
// Failed, moving without meta data
} else {
// Moving the file
if (!FileTools.fileMove(fileTmp, dest)) {
Logger.getInstance().logError("ExportMusicTrack", "Moving the raw file failed!");
@ -591,59 +609,73 @@ public class PlayMusicManager {
return false;
}
}
} else {
// Moving the file
if (!FileTools.fileMove(fileTmp, dest)) {
Logger.getInstance().logError("ExportMusicTrack", "Moving the raw file failed!");
// Could not copy the file
// We need to copy the file to a uri
if (copyUri != null) {
// Lollipop only
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
// Gets the file descriptor
ParcelFileDescriptor parcelFileDescriptor = mContext.getContentResolver().openFileDescriptor(copyUri, "w");
// Gets the output stream
FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
// Gets the input stream
FileInputStream fileInputStream = new FileInputStream(dest);
// Copy the stream
FileTools.fileCopy(fileInputStream, fileOutputStream);
// Close all streams
fileOutputStream.close();
fileInputStream.close();
parcelFileDescriptor.close();
} catch (FileNotFoundException e) {
Logger.getInstance().logError("ExportMusicTrack", "File not found!");
// Could not copy the file
return false;
} catch (IOException e) {
Logger.getInstance().logError("ExportMusicTrack", "Failed to write the document: " + e.toString());
// Could not copy the file
return false;
}
}
}
// Delete temp files
cleanUp();
// Adds the file to the media system
//new MediaScanner(mContext, dest);
} else {
Logger.getInstance().logInfo("exportMusicTrack", path + " already exists, skipping." );
}
// Done
return true;
}
/**
* Checks if the destination file already exists
* @param pUri the source file
* @param pPath The destination
* return true if the file already exists
*/
private boolean isAlreadyThere(Uri pUri, String pPath) {
DocumentFile lDocumentFile = DocumentFile.fromTreeUri(mContext, pUri);
for (String lDisplayName: pPath.split("/")) {
if (lDocumentFile.findFile(lDisplayName) != null) {
lDocumentFile = lDocumentFile.findFile(lDisplayName);
} else {
Logger.getInstance().logInfo("isAlreadyThere", pPath + " does not exist yet." );
return false;
}
}
// We need to copy the file to a uri
if (copyUri != null) {
// Lollipop only
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
// Gets the file descriptor
ParcelFileDescriptor parcelFileDescriptor = mContext.getContentResolver().openFileDescriptor(copyUri, "w");
// Gets the output stream
FileOutputStream fileOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
// Gets the input stream
FileInputStream fileInputStream = new FileInputStream(dest);
// Copy the stream
FileTools.fileCopy(fileInputStream, fileOutputStream);
// Close all streams
fileOutputStream.close();
fileInputStream.close();
parcelFileDescriptor.close();
} catch (FileNotFoundException e) {
Logger.getInstance().logError("ExportMusicTrack", "File not found!");
// Could not copy the file
return false;
} catch (IOException e) {
Logger.getInstance().logError("ExportMusicTrack", "Failed to write the document: " + e.toString());
// Could not copy the file
return false;
}
}
}
// Delete temp files
cleanUp();
// Adds the file to the media system
//new MediaScanner(mContext, dest);
// Done
return true;
}