diff options
author | Scott Jackson <daneren2005@gmail.com> | 2013-06-14 20:33:58 -0700 |
---|---|---|
committer | Scott Jackson <daneren2005@gmail.com> | 2013-06-14 20:33:58 -0700 |
commit | 8dd5b6136e8ae5dd41a9004617238f87a8d27281 (patch) | |
tree | 8197c8344e13fbe0f80aeb909f7150563b4d01e1 | |
parent | 5f45683e6937f13107775aa3434f7fcd01ebd9d6 (diff) | |
download | dsub-8dd5b6136e8ae5dd41a9004617238f87a8d27281.tar.gz dsub-8dd5b6136e8ae5dd41a9004617238f87a8d27281.tar.bz2 dsub-8dd5b6136e8ae5dd41a9004617238f87a8d27281.zip |
Convert offline scrobbling to SharedPreference, add support for offline mode with online added songs
9 files changed, 89 insertions, 96 deletions
diff --git a/subsonic-android/res/values/strings.xml b/subsonic-android/res/values/strings.xml index f3126ae0..224247fb 100644 --- a/subsonic-android/res/values/strings.xml +++ b/subsonic-android/res/values/strings.xml @@ -117,7 +117,8 @@ <string name="offline.scrobbles_dialog_title">Offline scrobbles file found.</string>
<string name="offline.scrobbles_dialog_message">Process offline scrobbles file?</string>
- <string name="offline.scrobbles_success">Successfully scrobbled songs</string>
+ <string name="offline.scrobbles_success">Successfully scrobbled %1$d songs</string>
+ <string name="offline.scrobbles_partial">Successfully scrobbled %1$d of %2$d songs. Try the rest on a different server.</string>
<string name="offline.scrobbles_error">Failed to scrobble songs</string>
<string name="select_genre.empty">No genres found</string>
diff --git a/subsonic-android/src/github/daneren2005/dsub/fragments/MainFragment.java b/subsonic-android/src/github/daneren2005/dsub/fragments/MainFragment.java index 645f2ae2..45d6eb49 100644 --- a/subsonic-android/src/github/daneren2005/dsub/fragments/MainFragment.java +++ b/subsonic-android/src/github/daneren2005/dsub/fragments/MainFragment.java @@ -4,6 +4,7 @@ import android.app.AlertDialog; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.StatFs;
@@ -204,9 +205,9 @@ public class MainFragment extends SubsonicFragment { context.getPagerAdapter().invalidate();
if(isOffline) {
- MusicService musicService = MusicServiceFactory.getMusicService(context);
- if(musicService.hasOfflineScrobbles()){
- showOfflineScrobblesDialog();
+ int count = Util.offlineScrobblesCount(context);
+ if(count > 0){
+ showOfflineScrobblesDialog(count);
}
}
}
@@ -227,7 +228,7 @@ public class MainFragment extends SubsonicFragment { }
}
- private void showOfflineScrobblesDialog() {
+ private void showOfflineScrobblesDialog(final int count) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(android.R.drawable.ic_dialog_info)
.setTitle(R.string.offline_scrobbles_dialog_title)
@@ -235,17 +236,20 @@ public class MainFragment extends SubsonicFragment { .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
- new SilentBackgroundTask<Void>(context) {
+ new SilentBackgroundTask<Integer>(context) {
@Override
- protected Void doInBackground() throws Throwable {
+ protected Integer doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
- musicService.processOfflineScrobbles(context, null);
- return null;
+ return musicService.processOfflineScrobbles(context, null);
}
@Override
- protected void done(Void result) {
- Util.toast(context, R.string.offline_scrobbles_success);
+ protected void done(Integer result) {
+ if(result == count) {
+ Util.toast(context, context.getResources().getString(R.string.offline_scrobbles_success, result));
+ } else {
+ Util.toast(context, context.getResources().getString(R.string.offline_scrobbles_partial, result, count));
+ }
}
@Override
@@ -264,7 +268,9 @@ public class MainFragment extends SubsonicFragment { @Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
- FileUtil.getOfflineScrobblesFile().delete();
+ SharedPreferences.Editor offline = Util.getOfflineSync(context).edit();
+ offline.putInt(Constants.OFFLINE_SCROBBLE_COUNT, 0);
+ offline.commit();
}
});
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java index 218949c4..59e81c3b 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java @@ -303,14 +303,9 @@ public class CachedMusicService implements MusicService { } @Override - public boolean hasOfflineScrobbles(){ - return musicService.hasOfflineScrobbles(); - } - - @Override - public void processOfflineScrobbles(final Context context, final ProgressListener progressListener) throws Exception{ - musicService.processOfflineScrobbles(context, progressListener); - } + public int processOfflineScrobbles(final Context context, final ProgressListener progressListener) throws Exception{ + return musicService.processOfflineScrobbles(context, progressListener); + } diff --git a/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java index 2787b75b..1689835f 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java @@ -118,7 +118,5 @@ public interface MusicService { public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception; - boolean hasOfflineScrobbles(); - - void processOfflineScrobbles(final Context context, final ProgressListener progressListener) throws Exception; + int processOfflineScrobbles(final Context context, final ProgressListener progressListener) throws Exception; }
\ No newline at end of file diff --git a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java index a9d18c5c..bda112ff 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java @@ -431,36 +431,42 @@ public class OfflineMusicService extends RESTMusicService { @Override public void scrobble(String id, boolean submission, Context context, ProgressListener progressListener) throws Exception { if(!submission) { - return; + return; } SharedPreferences prefs = Util.getPreferences(context); String cacheLocn = prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); - File offlineScrobblesFile = FileUtil.getOfflineScrobblesFile(); - - String scrobbleSearchCriteria = id.replace(cacheLocn, ""); - if(scrobbleSearchCriteria.startsWith("/")) { - scrobbleSearchCriteria = scrobbleSearchCriteria.substring(1); - } - - scrobbleSearchCriteria = scrobbleSearchCriteria.replace(".complete", "").replace(".partial", ""); - int index = scrobbleSearchCriteria.lastIndexOf("."); - scrobbleSearchCriteria = index == -1 ? scrobbleSearchCriteria : scrobbleSearchCriteria.substring(0, index); - String[] details = scrobbleSearchCriteria.split("/"); + SharedPreferences offline = Util.getOfflineSync(context); + int scrobbles = offline.getInt(Constants.OFFLINE_SCROBBLE_COUNT, 0); + scrobbles++; + SharedPreferences.Editor offlineEditor = offline.edit(); + + if(id.indexOf(cacheLocn) != -1) { + String scrobbleSearchCriteria = id.replace(cacheLocn, ""); + if(scrobbleSearchCriteria.startsWith("/")) { + scrobbleSearchCriteria = scrobbleSearchCriteria.substring(1); + } - //last.fm only uses artist and track title so broaden the search by just using those. doesn't matter if it find the track on a different album - String artist = "artist:\"" + details[0] + "\""; - String title = details[details.length - 1]; - title = "title:\"" + title.substring(title.indexOf('-') + 1) + "\""; + scrobbleSearchCriteria = scrobbleSearchCriteria.replace(".complete", "").replace(".partial", ""); + int index = scrobbleSearchCriteria.lastIndexOf("."); + scrobbleSearchCriteria = index == -1 ? scrobbleSearchCriteria : scrobbleSearchCriteria.substring(0, index); + String[] details = scrobbleSearchCriteria.split("/"); - scrobbleSearchCriteria = artist + " AND " + title; + //last.fm only uses artist and track title so broaden the search by just using those. doesn't matter if it find the track on a different album + String artist = "artist:\"" + details[0] + "\""; + String title = details[details.length - 1]; + title = "title:\"" + title.substring(title.indexOf('-') + 1) + "\""; - BufferedWriter bw = new BufferedWriter(new FileWriter(offlineScrobblesFile, true)); - bw.write(scrobbleSearchCriteria + "," + System.currentTimeMillis()); - bw.newLine(); - bw.flush(); - bw.close(); + scrobbleSearchCriteria = artist + " AND " + title; + offlineEditor.putString(Constants.OFFLINE_SCROBBLE_SEARCH + scrobbles, scrobbleSearchCriteria); + } else { + offlineEditor.putString(Constants.OFFLINE_SCROBBLE_ID + scrobbles, id); + } + + offlineEditor.putLong(Constants.OFFLINE_SCROBBLE_TIME + scrobbles, System.currentTimeMillis()); + offlineEditor.putInt(Constants.OFFLINE_SCROBBLE_COUNT, scrobbles); + offlineEditor.commit(); } @Override @@ -543,13 +549,8 @@ public class OfflineMusicService extends RESTMusicService { } @Override - public boolean hasOfflineScrobbles(){ - return false; - } - - @Override - public void processOfflineScrobbles(final Context context, final ProgressListener progressListener) throws Exception{ - throw new OfflineException("Offline scrobble cached can not be processes while in offline mode"); + public int processOfflineScrobbles(final Context context, final ProgressListener progressListener) throws Exception{ + throw new OfflineException("Offline scrobble cached can not be processes while in offline mode"); } private void listFilesRecursively(File parent, List<File> children) { diff --git a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java index 8a84cd21..53eccf71 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java @@ -869,35 +869,23 @@ public class RESTMusicService implements MusicService { } @Override - public boolean hasOfflineScrobbles(){ - return FileUtil.getOfflineScrobblesFile().exists(); - } - - @Override - public void processOfflineScrobbles(final Context context, final ProgressListener progressListener) throws Exception{ - File offlineScrobblesFile = FileUtil.getOfflineScrobblesFile(); - try{ - - BufferedReader br = new BufferedReader(new FileReader(offlineScrobblesFile)); - String line; - - ArrayList<String> lines = new ArrayList<String>(); - while ((line = br.readLine()) != null) { - lines.add(line); - } - br.close(); - offlineScrobblesFile.delete(); - - for(int i = 0; i < lines.size(); i++){ - line = lines.get(i); - String filename = line.substring(0, line.lastIndexOf(',')); - + public int processOfflineScrobbles(final Context context, final ProgressListener progressListener) throws Exception{ + SharedPreferences offline = Util.getOfflineSync(context); + SharedPreferences.Editor offlineEditor = offline.edit(); + int count = offline.getInt(Constants.OFFLINE_SCROBBLE_COUNT, 0); + int retry = 0; + for(int i = 1; i <= count; i++) { + String id = offline.getString(Constants.OFFLINE_SCROBBLE_ID + i, null); + long time = offline.getLong(Constants.OFFLINE_SCROBBLE_TIME + i, 0); + if(id != null) { + scrobble(id, true, time, context, progressListener); + } else { + String search = offline.getString(Constants.OFFLINE_SCROBBLE_SEARCH + i, ""); try{ - long time = Long.parseLong(line.substring(line.lastIndexOf(',')+1)); - SearchCritera critera = new SearchCritera(filename, 0, 0, 1); + SearchCritera critera = new SearchCritera(search, 0, 0, 1); SearchResult result = searchNew(critera, context, progressListener); if(result.getSongs().size() == 1){ - Log.i(TAG, "Query '" + filename + "' returned song " + result.getSongs().get(0).getTitle() + " by " + result.getSongs().get(0).getArtist() + " with id " + result.getSongs().get(0).getId()); + Log.i(TAG, "Query '" + search + "' returned song " + result.getSongs().get(0).getTitle() + " by " + result.getSongs().get(0).getArtist() + " with id " + result.getSongs().get(0).getId()); Log.i(TAG, "Scrobbling " + result.getSongs().get(0).getId() + " with time " + time); scrobble(result.getSongs().get(0).getId(), true, time, context, progressListener); } @@ -907,20 +895,17 @@ public class RESTMusicService implements MusicService { } catch(Exception e){ Log.e(TAG, e.toString()); - BufferedWriter bw = new BufferedWriter(new FileWriter(offlineScrobblesFile, true)); - bw.write(line); - bw.newLine(); - bw.flush(); - bw.close(); + retry++; + offlineEditor.putString(Constants.OFFLINE_SCROBBLE_SEARCH + retry, search); + offlineEditor.putLong(Constants.OFFLINE_SCROBBLE_TIME + retry, time); } } } - catch(FileNotFoundException fnfe){ - //ignore, we dont care - } - catch(Exception e){ - Log.e(TAG, e.toString()); - } + + offlineEditor.putInt(Constants.OFFLINE_SCROBBLE_COUNT, retry); + offlineEditor.commit(); + + return count - retry; } private Reader getReader(Context context, ProgressListener progressListener, String method, HttpParams requestParams) throws Exception { diff --git a/subsonic-android/src/github/daneren2005/dsub/util/Constants.java b/subsonic-android/src/github/daneren2005/dsub/util/Constants.java index d6aa4541..5714b1f1 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/Constants.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/Constants.java @@ -109,6 +109,11 @@ public final class Constants { public static final String PREFERENCES_KEY_CHAT_ENABLED = "chatEnabled"; public static final String PREFERENCES_KEY_VIDEO_PLAYER = "videoPlayer"; + public static final String OFFLINE_SCROBBLE_COUNT = "scrobbleCount"; + public static final String OFFLINE_SCROBBLE_ID = "scrobbleID"; + public static final String OFFLINE_SCROBBLE_SEARCH = "scrobbleTitle"; + public static final String OFFLINE_SCROBBLE_TIME = "scrobbleTime"; + public static final String CACHE_KEY_IGNORE = "ignoreArticles"; public static final String MAIN_BACK_STACK = "backStackIds"; @@ -118,6 +123,7 @@ public final class Constants { // Name of the preferences file. public static final String PREFERENCES_FILE_NAME = "github.daneren2005.dsub_preferences"; + public static final String OFFLINE_SYNC_NAME = "github.daneren2005.dsub.offline"; // Number of free trial days for non-licensed servers. public static final int FREE_TRIAL_DAYS = 30; @@ -126,8 +132,6 @@ public final class Constants { public static final String DONATION_URL = "http://subsonic.org/pages/android-donation.jsp"; public static final String ALBUM_ART_FILE = "albumart.jpg"; - - public static final String OFFLINE_SCROBBLES_FILE = "offline_scrobbles.log"; private Constants() { } diff --git a/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java b/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java index ca06b55f..7ead874c 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java @@ -149,11 +149,6 @@ public class FileUtil { } return dir; } - - public static File getOfflineScrobblesFile(){ - File offlineScrobblesFile = new File(getSubsonicDirectory(), fileSystemSafe(Constants.OFFLINE_SCROBBLES_FILE)); - return offlineScrobblesFile; - } public static void createDirectoryForParent(File file) { File dir = file.getParentFile(); diff --git a/subsonic-android/src/github/daneren2005/dsub/util/Util.java b/subsonic-android/src/github/daneren2005/dsub/util/Util.java index 269b05d3..76bf6a04 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/Util.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/Util.java @@ -332,6 +332,14 @@ public final class Util { public static SharedPreferences getPreferences(Context context) { return context.getSharedPreferences(Constants.PREFERENCES_FILE_NAME, 0); } + public static SharedPreferences getOfflineSync(Context context) { + return context.getSharedPreferences(Constants.OFFLINE_SYNC_NAME, 0); + } + + public static int offlineScrobblesCount(Context context) { + SharedPreferences offline = getOfflineSync(context); + return offline.getInt(Constants.OFFLINE_SCROBBLE_COUNT, 0); + } public static String getContentType(HttpEntity entity) { if (entity == null || entity.getContentType() == null) { |