aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java11
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/DownloadFile.java3
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/Scrobbler.java44
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/SongDBHandler.java109
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/Util.java3
-rw-r--r--app/src/main/res/values/strings.xml1
6 files changed, 153 insertions, 18 deletions
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java
index 6d25bc0b..d824a236 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java
@@ -77,6 +77,7 @@ import github.daneren2005.dsub.util.MenuUtil;
import github.daneren2005.dsub.util.ProgressListener;
import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.LoadingTask;
+import github.daneren2005.dsub.util.SongDBHandler;
import github.daneren2005.dsub.util.UpdateHelper;
import github.daneren2005.dsub.util.UserUtil;
import github.daneren2005.dsub.util.Util;
@@ -1293,6 +1294,16 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
headers.add(R.string.details_starred);
details.add(Util.formatBoolean(context, song.isStarred()));
+ try {
+ Long[] dates = SongDBHandler.getHandler(context).getLastPlayed(song.getId());
+ if(dates != null) {
+ headers.add(R.string.details_last_played);
+ details.add(Util.formatDate(dates[0]));
+ }
+ } catch(Exception e) {
+ Log.e(TAG, "Failed to get last played", e);
+ }
+
if(song instanceof PodcastEpisode) {
headers.add(R.string.details_description);
details.add(song.getAlbum());
diff --git a/app/src/main/java/github/daneren2005/dsub/service/DownloadFile.java b/app/src/main/java/github/daneren2005/dsub/service/DownloadFile.java
index 505e4a6d..cd36c56c 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/DownloadFile.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadFile.java
@@ -206,6 +206,9 @@ public class DownloadFile implements BufferFile {
return saveFile;
}
+ public File getSaveFile() {
+ return saveFile;
+ }
public File getPartialFile() {
return partialFile;
diff --git a/app/src/main/java/github/daneren2005/dsub/service/Scrobbler.java b/app/src/main/java/github/daneren2005/dsub/service/Scrobbler.java
index 1f8538c9..17a3a90d 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/Scrobbler.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/Scrobbler.java
@@ -5,6 +5,7 @@ import android.util.Log;
import github.daneren2005.dsub.domain.PodcastEpisode;
import github.daneren2005.dsub.util.SilentBackgroundTask;
+import github.daneren2005.dsub.util.SongDBHandler;
import github.daneren2005.dsub.util.Util;
/**
@@ -32,28 +33,11 @@ public class Scrobbler {
}
public void scrobble(final Context context, final DownloadFile song, final boolean submission) {
- if (song == null || !Util.isScrobblingEnabled(context)) {
- return;
- }
-
- // Ignore if online with no network access
- if(!Util.isOffline(context) && !Util.isNetworkConnected(context)) {
- return;
- }
-
- // Ignore podcasts
- if(song.getSong() instanceof PodcastEpisode) {
- return;
- }
-
- // Ignore songs which are under 30 seconds per Last.FM guidelines
- Integer duration = song.getSong().getDuration();
- if(duration != null && duration > 0 && duration < 30) {
+ if(song == null) {
return;
}
final String id = song.getSong().getId();
-
// Avoid duplicate registrations.
if (submission && id.equals(lastSubmission)) {
return;
@@ -71,6 +55,30 @@ public class Scrobbler {
new SilentBackgroundTask<Void>(context) {
@Override
protected Void doInBackground() {
+ // TODO: Need to move to register plays of offline songs as well
+ if(!Util.isOffline(context)) {
+ SongDBHandler.getHandler(context).setSongPlayed(song, submission);
+ }
+
+ // Scrobbling disabled
+ if (!Util.isScrobblingEnabled(context)) {
+ return null;
+ }
+ // Ignore if online with no network access
+ else if(!Util.isOffline(context) && !Util.isNetworkConnected(context)) {
+ return null;
+ }
+ // Ignore podcasts
+ else if(song.getSong() instanceof PodcastEpisode) {
+ return null;
+ }
+
+ // Ignore songs which are under 30 seconds per Last.FM guidelines
+ Integer duration = song.getSong().getDuration();
+ if(duration != null && duration > 0 && duration < 30) {
+ return null;
+ }
+
MusicService service = MusicServiceFactory.getMusicService(context);
try {
service.scrobble(id, submission, context, null);
diff --git a/app/src/main/java/github/daneren2005/dsub/util/SongDBHandler.java b/app/src/main/java/github/daneren2005/dsub/util/SongDBHandler.java
new file mode 100644
index 00000000..f123521f
--- /dev/null
+++ b/app/src/main/java/github/daneren2005/dsub/util/SongDBHandler.java
@@ -0,0 +1,109 @@
+/*
+ This file is part of Subsonic.
+ Subsonic 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.
+ Subsonic 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 Subsonic. If not, see <http://www.gnu.org/licenses/>.
+ Copyright 2015 (C) Scott Jackson
+*/
+
+package github.daneren2005.dsub.util;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+import java.util.Date;
+
+import github.daneren2005.dsub.domain.MusicDirectory;
+import github.daneren2005.dsub.service.DownloadFile;
+
+public class SongDBHandler extends SQLiteOpenHelper {
+ private static final String TAG = SongDBHandler.class.getSimpleName();
+ private static SongDBHandler dbHandler;
+
+ private static final int DATABASE_VERSION = 1;
+ public static final String DATABASE_NAME = "SongsDB";
+
+ public static final String TABLE_SONGS = "RegisteredSongs";
+ public static final String SONGS_ID = "id";
+ public static final String SONGS_SERVER_ID = "serverId";
+ public static final String SONGS_COMPLETE_PATH = "completePath";
+ public static final String SONGS_LAST_PLAYED = "lastPlayed";
+ public static final String SONGS_LAST_COMPLETED = "lastCompleted";
+
+ private SongDBHandler(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL("CREATE TABLE " + TABLE_SONGS + " ( " + SONGS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + SONGS_SERVER_ID + " TEXT NOT NULL UNIQUE, " + SONGS_COMPLETE_PATH + " TEXT NOT NULL, " + SONGS_LAST_PLAYED + " INTEGER, " + SONGS_LAST_COMPLETED + " INTEGER )");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_SONGS);
+ this.onCreate(db);
+ }
+
+ public synchronized void addSong(DownloadFile downloadFile) {
+ SQLiteDatabase db = this.getWritableDatabase();
+ addSong(db, downloadFile);
+ db.close();
+ }
+ protected synchronized void addSong(SQLiteDatabase db, DownloadFile downloadFile) {
+ ContentValues values = new ContentValues();
+ values.put(SONGS_SERVER_ID, downloadFile.getSong().getId());
+ values.put(SONGS_COMPLETE_PATH, downloadFile.getSaveFile().getAbsolutePath());
+
+ db.insertWithOnConflict(TABLE_SONGS, null, values, SQLiteDatabase.CONFLICT_REPLACE);
+ }
+
+ public synchronized void setSongPlayed(DownloadFile downloadFile, boolean submission) {
+ // Open and make sure song is in db
+ SQLiteDatabase db = this.getWritableDatabase();
+ addSong(db, downloadFile);
+
+ // Update song's last played
+ ContentValues values = new ContentValues();
+ values.put(submission ? SONGS_LAST_COMPLETED : SONGS_LAST_PLAYED, System.currentTimeMillis());
+ db.update(TABLE_SONGS, values, SONGS_SERVER_ID + " = ?", new String[]{downloadFile.getSong().getId()});
+ db.close();
+ }
+
+ public Long[] getLastPlayed(String id) {
+ SQLiteDatabase db = this.getReadableDatabase();
+
+ String[] columns = {SONGS_LAST_PLAYED, SONGS_LAST_COMPLETED};
+ Cursor cursor = db.query(TABLE_SONGS, columns, SONGS_SERVER_ID + " = ?", new String[] { id }, null, null, null, null);
+
+ try {
+ cursor.moveToFirst();
+
+ Long[] dates = new Long[2];
+ dates[0] = cursor.getLong(0);
+ dates[1] = cursor.getLong(1);
+ return dates;
+ } catch(Exception e) {}
+
+ return null;
+ }
+
+ public static SongDBHandler getHandler(Context context) {
+ if(dbHandler == null) {
+ dbHandler = new SongDBHandler(context);
+ }
+
+ return dbHandler;
+ }
+}
diff --git a/app/src/main/java/github/daneren2005/dsub/util/Util.java b/app/src/main/java/github/daneren2005/dsub/util/Util.java
index 490e922b..df5e512e 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/Util.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/Util.java
@@ -908,6 +908,9 @@ public final class Util {
}
}
}
+ public static String formatDate(long millis) {
+ return formatDate(new Date(millis));
+ }
public static String formatBoolean(Context context, boolean value) {
return context.getResources().getString(value ? R.string.common_true : R.string.common_false);
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 303a8e0e..3acbff3e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -642,6 +642,7 @@
<string name="details.position">Position</string>
<string name="details.updated">Updated</string>
<string name="details.starred">Starred</string>
+ <string name="details.last_played">Last Played</string>
<plurals name="select_album_n_songs">
<item quantity="zero">No songs</item>