aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml4
-rw-r--r--res/menu/unstar.xml7
-rw-r--r--res/raw/changelog.xml13
-rw-r--r--res/values/strings.xml2
-rw-r--r--src/github/daneren2005/dsub/activity/SettingsActivity.java7
-rw-r--r--src/github/daneren2005/dsub/fragments/SearchFragment.java1
-rw-r--r--src/github/daneren2005/dsub/fragments/SelectArtistFragment.java6
-rw-r--r--src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java83
-rw-r--r--src/github/daneren2005/dsub/fragments/SubsonicFragment.java51
-rw-r--r--src/github/daneren2005/dsub/service/CachedMusicService.java63
-rw-r--r--src/github/daneren2005/dsub/service/MusicService.java6
-rw-r--r--src/github/daneren2005/dsub/service/OfflineMusicService.java17
-rw-r--r--src/github/daneren2005/dsub/service/RESTMusicService.java84
-rw-r--r--src/github/daneren2005/dsub/service/parser/AlbumListParser.java4
-rw-r--r--src/github/daneren2005/dsub/service/parser/IndexesParser.java2
-rw-r--r--src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java14
-rw-r--r--src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java12
-rw-r--r--src/github/daneren2005/dsub/service/parser/SearchResult2Parser.java4
-rw-r--r--src/github/daneren2005/dsub/service/parser/StarredListParser.java10
-rw-r--r--src/github/daneren2005/dsub/util/Constants.java1
-rw-r--r--src/github/daneren2005/dsub/util/FileUtil.java2
-rw-r--r--src/github/daneren2005/dsub/util/Util.java10
-rw-r--r--src/github/daneren2005/dsub/util/compat/RemoteControlClientKK.java3
23 files changed, 348 insertions, 58 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 531f208c..00ccdd2c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="github.daneren2005.dsub"
android:installLocation="internalOnly"
- android:versionCode="84"
- android:versionName="4.3.7">
+ android:versionCode="85"
+ android:versionName="4.4 Beta3">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
diff --git a/res/menu/unstar.xml b/res/menu/unstar.xml
new file mode 100644
index 00000000..4b629cda
--- /dev/null
+++ b/res/menu/unstar.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:compat="http://schemas.android.com/apk/res-auto">
+ <item
+ android:id="@+id/menu_unstar"
+ android:title="@string/common.unstar"/>
+</menu> \ No newline at end of file
diff --git a/res/raw/changelog.xml b/res/raw/changelog.xml
index 14f79de9..54ea6afb 100644
--- a/res/raw/changelog.xml
+++ b/res/raw/changelog.xml
@@ -1,5 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<changelog>
+ <release version="4.4 Beta3" versioncode="85" releasedate="1/22/2014">
+ <change>Updated to include 4.3.7 changes</change>
+ </release>
+ <release version="4.4 Beta2" versioncode="83" releasedate="1/21/2014">
+ <change>Fix Show All Media</change>
+ <change>Fix play/cache</change>
+ <change>Fix Show Artist/Album</change>
+ <change>Fix albums not showing as cached</change>
+ </release>
+ <release version="4.4.0" versioncode="82" releasedate="1/19/2014">
+ <change>Browse by ID3 Tags instead of folder structure (off by default)</change>
+ <change>Probably a good idea to clear existing cache since there will be many songs that don't match up</change>
+ </release>
<release version="4.3.7" versioncode="84" releasedate="1/22/2014">
<change>Add stats to genres for 4.9Beta3+ Servers</change>
<change>Fix stuck Last.FM notification if you use it to scrobble</change>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index af2b3693..f1f4a1ca 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -389,6 +389,8 @@
<string name="settings.menu_options.play_last_summary">Show Play last in menus</string>
<string name="settings.menu_options.star_summary">Show Star in menus</string>
<string name="settings.menu_options.shared_summary">Show Share in menus</string>
+ <string name="settings.browse_by_tags">Browse By Tags</string>
+ <string name="settings.browse_by_tags_summary">Browse by tags instead of by folder structure. Requires Subsonic 4.7+</string>
<string name="shuffle.title">Shuffle By</string>
<string name="shuffle.startYear">Start Year:</string>
diff --git a/src/github/daneren2005/dsub/activity/SettingsActivity.java b/src/github/daneren2005/dsub/activity/SettingsActivity.java
index 903f0f3e..7cebdbdd 100644
--- a/src/github/daneren2005/dsub/activity/SettingsActivity.java
+++ b/src/github/daneren2005/dsub/activity/SettingsActivity.java
@@ -384,6 +384,12 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer
serverPasswordPreference.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
serverPasswordPreference.setSummary("***");
serverPasswordPreference.setTitle(R.string.settings_server_password);
+
+ final CheckBoxPreference serverTagPreference = new CheckBoxPreference(this);
+ serverTagPreference.setKey(Constants.PREFERENCES_KEY_BROWSE_TAGS + instance);
+ serverTagPreference.setChecked(Util.isTagBrowsing(this, instance));
+ serverTagPreference.setSummary(R.string.settings_browse_by_tags_summary);
+ serverTagPreference.setTitle(R.string.settings_browse_by_tags);
serverPasswordPreference.setDialogTitle(R.string.settings_server_password);
final Preference serverOpenBrowser = new Preference(this);
@@ -452,6 +458,7 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer
screen.addPreference(serverLocalNetworkSSIDPreference);
screen.addPreference(serverUsernamePreference);
screen.addPreference(serverPasswordPreference);
+ screen.addPreference(serverTagPreference);
screen.addPreference(serverTestConnectionPreference);
screen.addPreference(serverOpenBrowser);
screen.addPreference(serverRemoveServerPreference);
diff --git a/src/github/daneren2005/dsub/fragments/SearchFragment.java b/src/github/daneren2005/dsub/fragments/SearchFragment.java
index b77df12b..86f31041 100644
--- a/src/github/daneren2005/dsub/fragments/SearchFragment.java
+++ b/src/github/daneren2005/dsub/fragments/SearchFragment.java
@@ -298,6 +298,7 @@ public class SearchFragment extends SubsonicFragment {
if(autoplay) {
args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true);
}
+ args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true);
fragment.setArguments(args);
replaceFragment(fragment, R.id.fragment_list_layout);
diff --git a/src/github/daneren2005/dsub/fragments/SelectArtistFragment.java b/src/github/daneren2005/dsub/fragments/SelectArtistFragment.java
index 5b46b40c..909165b7 100644
--- a/src/github/daneren2005/dsub/fragments/SelectArtistFragment.java
+++ b/src/github/daneren2005/dsub/fragments/SelectArtistFragment.java
@@ -51,6 +51,7 @@ public class SelectArtistFragment extends SubsonicFragment implements AdapterVie
artists = (List<Artist>) bundle.getSerializable(Constants.FRAGMENT_LIST);
musicFolders = (List<MusicFolder>) bundle.getSerializable(Constants.FRAGMENT_LIST2);
}
+ artist = true;
}
@Override
@@ -171,6 +172,7 @@ public class SelectArtistFragment extends SubsonicFragment implements AdapterVie
if("root".equals(artist.getId())) {
args.putSerializable(Constants.FRAGMENT_LIST, (Serializable) entries);
}
+ args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true);
fragment.setArguments(args);
replaceFragment(fragment, R.id.fragment_list_layout);
@@ -185,7 +187,7 @@ public class SelectArtistFragment extends SubsonicFragment implements AdapterVie
private void load(final boolean refresh) {
setTitle(R.string.button_bar_browse);
- if (Util.isOffline(context)) {
+ if (Util.isOffline(context) || Util.isTagBrowsing(context)) {
folderButton.setVisibility(View.GONE);
} else {
folderButton.setVisibility(View.VISIBLE);
@@ -196,7 +198,7 @@ public class SelectArtistFragment extends SubsonicFragment implements AdapterVie
@Override
protected Indexes doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
- if (!Util.isOffline(context)) {
+ if (!Util.isOffline(context) && !Util.isTagBrowsing(context)) {
musicFolders = musicService.getMusicFolders(refresh, context, this);
}
String musicFolderId = Util.getSelectedMusicFolderId(context);
diff --git a/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java b/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
index 65aeeb59..9e7d93fa 100644
--- a/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
+++ b/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
@@ -136,6 +136,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
albumListExtra = args.getString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA);
albumListSize = args.getInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0);
refreshListing = args.getBoolean(Constants.INTENT_EXTRA_REFRESH_LISTINGS);
+ artist = args.getBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, false);
if(entries == null) {
entries = (List<MusicDirectory.Entry>) args.getSerializable(Constants.FRAGMENT_LIST);
}
@@ -199,6 +200,10 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
}
}
+
+ if("starred".equals(albumListType)) {
+ menuInflater.inflate(R.menu.unstar, menu);
+ }
}
@Override
@@ -246,6 +251,10 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
case R.id.menu_show_all:
showAll = true;
refresh(true);
+ return true;
+ case R.id.menu_unstar:
+ unstarSelected();
+ return true;
}
if(super.onOptionsItemSelected(item)) {
@@ -320,6 +329,9 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
if ("newest".equals(albumListType)) {
args.putBoolean(Constants.INTENT_EXTRA_REFRESH_LISTINGS, true);
}
+ if(entry.getArtist() == null && entry.getParent() == null) {
+ args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true);
+ }
fragment.setArguments(args);
replaceFragment(fragment, rootId, true);
@@ -390,7 +402,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
new LoadTask() {
@Override
protected MusicDirectory load(MusicService service) throws Exception {
- return service.getMusicDirectory(id, name, refresh, context, this);
+ return getMusicDirectory(id, name, refresh, service, this);
}
@Override
@@ -409,7 +421,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
protected MusicDirectory load(MusicService service) throws Exception {
MusicDirectory root;
if(share == null) {
- root = service.getMusicDirectory(id, name, refresh, context, this);
+ root = getMusicDirectory(id, name, refresh, service, this);
} else {
root = share.getMusicDirectory();
}
@@ -423,7 +435,14 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
songs.addAll(parent.getChildren(false, true));
for (MusicDirectory.Entry dir : parent.getChildren(true, false)) {
MusicService musicService = MusicServiceFactory.getMusicService(context);
- getSongsRecursively(musicService.getMusicDirectory(dir.getId(), dir.getTitle(), refresh, context, this), songs);
+
+ MusicDirectory musicDirectory;
+ if(Util.isTagBrowsing(context) && !Util.isOffline(context)) {
+ musicDirectory = musicService.getAlbum(dir.getId(), dir.getTitle(), false, context, this);
+ } else {
+ musicDirectory = musicService.getMusicDirectory(dir.getId(), dir.getTitle(), false, context, this);
+ }
+ getSongsRecursively(musicDirectory, songs);
}
}
@@ -853,6 +872,64 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
});
}
+ public void unstarSelected() {
+ List<MusicDirectory.Entry> selected = getSelectedSongs();
+ if(selected.size() == 0) {
+ selected = entries;
+ }
+ if(selected.size() == 0) {
+ return;
+ }
+ final List<MusicDirectory.Entry> unstar = new ArrayList<MusicDirectory.Entry>();
+ unstar.addAll(selected);
+
+ new LoadingTask<Void>(context, true) {
+ @Override
+ protected Void doInBackground() throws Throwable {
+ MusicService musicService = MusicServiceFactory.getMusicService(context);
+ List<String> ids = new ArrayList<String>();
+ List<String> artists = new ArrayList<String>();
+ List<String> albums = new ArrayList<String>();
+ for(MusicDirectory.Entry entry: unstar) {
+ if(entry.isDirectory()) {
+ if(entry.getArtist() == null || entry.getParent() == null) {
+ artists.add(entry.getId());
+ } else {
+ albums.add(entry.getId());
+ }
+ } else {
+ ids.add(entry.getId());
+ }
+ }
+ musicService.setStarred(ids, artists, albums, false, context, this);
+ return null;
+ }
+
+ @Override
+ protected void done(Void result) {
+ Util.toast(context, context.getResources().getString(R.string.starring_content_unstarred, Integer.toString(unstar.size())));
+
+ for(MusicDirectory.Entry entry: unstar) {
+ entries.remove(entry);
+ }
+ entryAdapter.notifyDataSetChanged();
+ selectAll(false, false);
+ }
+
+ @Override
+ protected void error(Throwable error) {
+ String msg;
+ if (error instanceof OfflineException || error instanceof ServerTooOldException) {
+ msg = getErrorMessage(error);
+ } else {
+ msg = context.getResources().getString(R.string.starring_content_error, Integer.toString(unstar.size())) + " " + getErrorMessage(error);
+ }
+
+ Util.toast(context, msg, false);
+ }
+ }.execute();
+ }
+
private void checkLicenseAndTrialPeriod(LoadingTask onValid) {
if (licenseValid) {
onValid.execute();
diff --git a/src/github/daneren2005/dsub/fragments/SubsonicFragment.java b/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
index 4bba4e89..3ec1471f 100644
--- a/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
+++ b/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
@@ -62,6 +62,7 @@ import github.daneren2005.dsub.service.ServerTooOldException;
import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.FileUtil;
import github.daneren2005.dsub.util.ImageLoader;
+import github.daneren2005.dsub.util.ProgressListener;
import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.LoadingTask;
import github.daneren2005.dsub.util.Util;
@@ -70,6 +71,7 @@ import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
@@ -92,6 +94,8 @@ public class SubsonicFragment extends Fragment {
protected static Random random = new Random();
protected GestureDetector gestureScanner;
protected Share share;
+ protected boolean artist = false;
+ protected boolean artistOverride = false;
public SubsonicFragment() {
super();
@@ -266,21 +270,27 @@ public class SubsonicFragment extends Fragment {
toggleStarred(artist);
break;
case R.id.album_menu_play_now:
+ artistOverride = true;
downloadRecursively(entry.getId(), false, false, true, false, false);
break;
case R.id.album_menu_play_shuffled:
+ artistOverride = true;
downloadRecursively(entry.getId(), false, false, true, true, false);
break;
case R.id.album_menu_play_next:
+ artistOverride = true;
downloadRecursively(entry.getId(), false, true, false, false, false, true);
break;
case R.id.album_menu_play_last:
+ artistOverride = true;
downloadRecursively(entry.getId(), false, true, false, false, false);
break;
case R.id.album_menu_download:
+ artistOverride = true;
downloadRecursively(entry.getId(), false, true, false, false, true);
break;
case R.id.album_menu_pin:
+ artistOverride = true;
downloadRecursively(entry.getId(), true, true, false, false, true);
break;
case R.id.album_menu_star:
@@ -588,7 +598,15 @@ public class SubsonicFragment extends Fragment {
@Override
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
- musicService.setStarred(entry.getId(), starred, context, null);
+ if(entry.isDirectory() && Util.isTagBrowsing(context) && !Util.isOffline(context)) {
+ if(entry.getParent() == null || entry.getArtist() == null) {
+ musicService.setStarred(null, Arrays.asList(entry.getId()), null, starred, context, null);
+ } else {
+ musicService.setStarred(null, null, Arrays.asList(entry.getId()), starred, context, null);
+ }
+ } else {
+ musicService.setStarred(Arrays.asList(entry.getId()), null, null, starred, context, null);
+ }
// Make sure to clear parent cache
String s = Util.getRestUrl(context, null) + entry.getParent();
@@ -627,7 +645,11 @@ public class SubsonicFragment extends Fragment {
@Override
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
- musicService.setStarred(entry.getId(), starred, context, null);
+ if(Util.isTagBrowsing(context) && !Util.isOffline(context)) {
+ musicService.setStarred(null, Arrays.asList(entry.getId()), null, starred, context, null);
+ } else {
+ musicService.setStarred(Arrays.asList(entry.getId()), null, null, starred, context, null);
+ }
return null;
}
@@ -677,7 +699,7 @@ public class SubsonicFragment extends Fragment {
root = share.getMusicDirectory();
}
else if(isDirectory) {
- root = musicService.getMusicDirectory(id, name, false, context, this);
+ root = getMusicDirectory(id, name, false, musicService, this);
}
else {
root = musicService.getPlaylist(true, id, name, context, this);
@@ -699,7 +721,14 @@ public class SubsonicFragment extends Fragment {
}
for (MusicDirectory.Entry dir : parent.getChildren(true, false)) {
MusicService musicService = MusicServiceFactory.getMusicService(context);
- getSongsRecursively(musicService.getMusicDirectory(dir.getId(), dir.getTitle(), false, context, this), songs);
+
+ MusicDirectory musicDirectory;
+ if(Util.isTagBrowsing(context) && !Util.isOffline(context)) {
+ musicDirectory = musicService.getAlbum(dir.getId(), dir.getTitle(), false, context, this);
+ } else {
+ musicDirectory = musicService.getMusicDirectory(dir.getId(), dir.getTitle(), false, context, this);
+ }
+ getSongsRecursively(musicDirectory, songs);
}
}
@@ -721,12 +750,25 @@ public class SubsonicFragment extends Fragment {
downloadService.downloadBackground(songs, save);
}
}
+ artistOverride = false;
}
};
task.execute();
}
+ protected MusicDirectory getMusicDirectory(String id, String name, boolean refresh, MusicService service, ProgressListener listener) throws Exception {
+ if(Util.isTagBrowsing(context) && !Util.isOffline(context)) {
+ if(artist && !artistOverride) {
+ return service.getArtist(id, name, refresh, context, listener);
+ } else {
+ return service.getAlbum(id, name, refresh, context, listener);
+ }
+ } else {
+ return service.getMusicDirectory(id, name, refresh, context, listener);
+ }
+ }
+
protected void addToPlaylist(final List<MusicDirectory.Entry> songs) {
if(songs.isEmpty()) {
Util.toast(context, "No songs selected");
@@ -1081,6 +1123,7 @@ public class SubsonicFragment extends Fragment {
Bundle args = new Bundle();
args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getParent());
args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getArtist());
+ args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true);
fragment.setArguments(args);
replaceFragment(fragment, getRootId(), true);
diff --git a/src/github/daneren2005/dsub/service/CachedMusicService.java b/src/github/daneren2005/dsub/service/CachedMusicService.java
index 4da3aec2..b8b440d7 100644
--- a/src/github/daneren2005/dsub/service/CachedMusicService.java
+++ b/src/github/daneren2005/dsub/service/CachedMusicService.java
@@ -27,8 +27,6 @@ import org.apache.http.HttpResponse;
import android.content.Context;
import android.graphics.Bitmap;
-import android.support.v4.util.LruCache;
-import android.util.Log;
import github.daneren2005.dsub.domain.Bookmark;
import github.daneren2005.dsub.domain.ChatMessage;
@@ -66,6 +64,7 @@ public class CachedMusicService implements MusicService {
private final TimeLimitedCache<List<MusicFolder>> cachedMusicFolders = new TimeLimitedCache<List<MusicFolder>>(10 * 3600, TimeUnit.SECONDS);
private final TimeLimitedCache<List<PodcastChannel>> cachedPodcastChannels = new TimeLimitedCache<List<PodcastChannel>>(10 * 3600, TimeUnit.SECONDS);
private String restUrl;
+ private boolean isTagBrowsing = false;
public CachedMusicService(RESTMusicService musicService) {
this.musicService = musicService;
@@ -135,21 +134,53 @@ public class CachedMusicService implements MusicService {
@Override
public MusicDirectory getMusicDirectory(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
- MusicDirectory dir = null;
+ MusicDirectory dir = null;
- if(!refresh) {
- dir = FileUtil.deserialize(context, getCacheName(context, "directory", id), MusicDirectory.class);
- }
+ if(!refresh) {
+ dir = FileUtil.deserialize(context, getCacheName(context, "directory", id), MusicDirectory.class);
+ }
- if(dir == null) {
- dir = musicService.getMusicDirectory(id, name, refresh, context, progressListener);
- FileUtil.serialize(context, dir, getCacheName(context, "directory", id));
- }
+ if(dir == null) {
+ dir = musicService.getMusicDirectory(id, name, refresh, context, progressListener);
+ FileUtil.serialize(context, dir, getCacheName(context, "directory", id));
+ }
- return dir;
+ return dir;
}
- @Override
+ @Override
+ public MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
+ MusicDirectory dir = null;
+
+ if(!refresh) {
+ dir = FileUtil.deserialize(context, getCacheName(context, "artist", id), MusicDirectory.class);
+ }
+
+ if(dir == null) {
+ dir = musicService.getArtist(id, name, refresh, context, progressListener);
+ FileUtil.serialize(context, dir, getCacheName(context, "artist", id));
+ }
+
+ return dir;
+ }
+
+ @Override
+ public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
+ MusicDirectory dir = null;
+
+ if(!refresh) {
+ dir = FileUtil.deserialize(context, getCacheName(context, "album", id), MusicDirectory.class);
+ }
+
+ if(dir == null) {
+ dir = musicService.getAlbum(id, name, refresh, context, progressListener);
+ FileUtil.serialize(context, dir, getCacheName(context, "album", id));
+ }
+
+ return dir;
+ }
+
+ @Override
public SearchResult search(SearchCritera criteria, Context context, ProgressListener progressListener) throws Exception {
return musicService.search(criteria, context, progressListener);
}
@@ -318,8 +349,8 @@ public class CachedMusicService implements MusicService {
}
@Override
- public void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception {
- musicService.setStarred(id, starred, context, progressListener);
+ public void setStarred(List<String> id, List<String> artistId, List<String> albumId, boolean starred, Context context, ProgressListener progressListener) throws Exception {
+ musicService.setStarred(id, artistId, albumId, starred, context, progressListener);
}
@Override
@@ -480,13 +511,15 @@ public class CachedMusicService implements MusicService {
private void checkSettingsChanged(Context context) {
String newUrl = musicService.getRestUrl(context, null, false);
- if (!Util.equals(newUrl, restUrl)) {
+ boolean newIsTagBrowsing = Util.isTagBrowsing(context);
+ if (!Util.equals(newUrl, restUrl) || isTagBrowsing != newIsTagBrowsing) {
cachedMusicFolders.clear();
cachedLicenseValid.clear();
cachedIndexes.clear();
cachedPlaylists.clear();
cachedPodcastChannels.clear();
restUrl = newUrl;
+ isTagBrowsing = newIsTagBrowsing;
}
}
}
diff --git a/src/github/daneren2005/dsub/service/MusicService.java b/src/github/daneren2005/dsub/service/MusicService.java
index 0946c4f7..3674fd01 100644
--- a/src/github/daneren2005/dsub/service/MusicService.java
+++ b/src/github/daneren2005/dsub/service/MusicService.java
@@ -57,6 +57,10 @@ public interface MusicService {
MusicDirectory getMusicDirectory(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception;
+ MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception;
+
+ MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception;
+
SearchResult search(SearchCritera criteria, Context context, ProgressListener progressListener) throws Exception;
MusicDirectory getStarredList(Context context, ProgressListener progressListener) throws Exception;
@@ -113,7 +117,7 @@ public interface MusicService {
RemoteStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception;
- void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception;
+ void setStarred(List<String> id, List<String> artistId, List<String> albumId, boolean starred, Context context, ProgressListener progressListener) throws Exception;
List<Share> getShares(Context context, ProgressListener progressListener) throws Exception;
diff --git a/src/github/daneren2005/dsub/service/OfflineMusicService.java b/src/github/daneren2005/dsub/service/OfflineMusicService.java
index fdeb373c..a3cdd437 100644
--- a/src/github/daneren2005/dsub/service/OfflineMusicService.java
+++ b/src/github/daneren2005/dsub/service/OfflineMusicService.java
@@ -137,7 +137,17 @@ public class OfflineMusicService extends RESTMusicService {
return result;
}
- private String getName(File file) {
+ @Override
+ public MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
+ throw new OfflineException("Artist by tags not available in offline mode");
+ }
+
+ @Override
+ public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
+ throw new OfflineException("Album by tags not available in offline mode");
+ }
+
+ private String getName(File file) {
String name = file.getName();
if (file.isDirectory()) {
return name;
@@ -549,7 +559,7 @@ public class OfflineMusicService extends RESTMusicService {
}
@Override
- public void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception {
+ public void setStarred(List<String> ids, List<String> artistId, List<String> albumId, boolean starred, Context context, ProgressListener progressListener) throws Exception {
SharedPreferences prefs = Util.getPreferences(context);
String cacheLocn = prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null);
@@ -557,7 +567,8 @@ public class OfflineMusicService extends RESTMusicService {
int stars = offline.getInt(Constants.OFFLINE_STAR_COUNT, 0);
stars++;
SharedPreferences.Editor offlineEditor = offline.edit();
-
+
+ String id = ids.get(0);
if(id.indexOf(cacheLocn) != -1) {
String searchCriteria = Util.parseOfflineIDSearch(context, id, cacheLocn);
offlineEditor.putString(Constants.OFFLINE_STAR_SEARCH + stars, searchCriteria);
diff --git a/src/github/daneren2005/dsub/service/RESTMusicService.java b/src/github/daneren2005/dsub/service/RESTMusicService.java
index e220bf59..43b5f887 100644
--- a/src/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/src/github/daneren2005/dsub/service/RESTMusicService.java
@@ -63,7 +63,6 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
@@ -219,7 +218,7 @@ public class RESTMusicService implements MusicService {
parameterValues.add(musicFolderId);
}
- Reader reader = getReader(context, progressListener, "getIndexes", null, parameterNames, parameterValues);
+ Reader reader = getReader(context, progressListener, Util.isTagBrowsing(context, getInstance(context)) ? "getArtists" : "getIndexes", null, parameterNames, parameterValues);
try {
Indexes indexes = new IndexesParser(context).parse(reader, progressListener);
if (indexes != null) {
@@ -248,7 +247,7 @@ public class RESTMusicService implements MusicService {
private String getCachedIndexesFilename(Context context, String musicFolderId) {
String s = getRestUrl(context, null) + musicFolderId;
- return "indexes-" + Math.abs(s.hashCode()) + ".ser";
+ return (Util.isTagBrowsing(context, getInstance(context)) ? "artists-" : "indexes-") + Math.abs(s.hashCode()) + ".ser";
}
@Override
@@ -274,7 +273,27 @@ public class RESTMusicService implements MusicService {
}
}
- @Override
+ @Override
+ public MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
+ Reader reader = getReader(context, progressListener, "getArtist", null, "id", id);
+ try {
+ return new MusicDirectoryParser(context).parse(name, reader, progressListener);
+ } finally {
+ Util.close(reader);
+ }
+ }
+
+ @Override
+ public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
+ Reader reader = getReader(context, progressListener, "getAlbum", null, "id", id);
+ try {
+ return new MusicDirectoryParser(context).parse(name, reader, progressListener);
+ } finally {
+ Util.close(reader);
+ }
+ }
+
+ @Override
public SearchResult search(SearchCritera critera, Context context, ProgressListener progressListener) throws Exception {
try {
return searchNew(critera, context, progressListener);
@@ -307,7 +326,7 @@ public class RESTMusicService implements MusicService {
List<String> parameterNames = Arrays.asList("query", "artistCount", "albumCount", "songCount");
List<Object> parameterValues = Arrays.<Object>asList(critera.getQuery(), critera.getArtistCount(),
critera.getAlbumCount(), critera.getSongCount());
- Reader reader = getReader(context, progressListener, "search2", null, parameterNames, parameterValues);
+ Reader reader = getReader(context, progressListener, Util.isTagBrowsing(context, getInstance(context)) ? "search3" : "search2", null, parameterNames, parameterValues);
try {
return new SearchResult2Parser(context).parse(reader, progressListener);
} finally {
@@ -505,7 +524,7 @@ public class RESTMusicService implements MusicService {
@Override
public MusicDirectory getAlbumList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception {
- Reader reader = getReader(context, progressListener, "getAlbumList",
+ Reader reader = getReader(context, progressListener, Util.isTagBrowsing(context, getInstance(context)) ? "getAlbumList2" : "getAlbumList",
null, Arrays.asList("type", "size", "offset"), Arrays.<Object>asList(type, size, offset));
try {
return new AlbumListParser(context).parse(reader, progressListener);
@@ -545,7 +564,7 @@ public class RESTMusicService implements MusicService {
values.add(decade + 10);
}
- Reader reader = getReader(context, progressListener, "getAlbumList", null, names, values);
+ Reader reader = getReader(context, progressListener, Util.isTagBrowsing(context, getInstance(context)) ? "getAlbumList2" : "getAlbumList", null, names, values);
try {
return new AlbumListParser(context).parse(reader, progressListener);
} finally {
@@ -555,7 +574,7 @@ public class RESTMusicService implements MusicService {
@Override
public MusicDirectory getStarredList(Context context, ProgressListener progressListener) throws Exception {
- Reader reader = getReader(context, progressListener, "getStarred", null);
+ Reader reader = getReader(context, progressListener, Util.isTagBrowsing(context, getInstance(context)) ? "getStarred2" : "getStarred", null);
try {
return new StarredListParser(context).parse(reader, progressListener);
} finally {
@@ -574,7 +593,7 @@ public class RESTMusicService implements MusicService {
names.add("size");
values.add(size);
- if (musicFolderId != null && !"".equals(musicFolderId)) {
+ if (musicFolderId != null && !"".equals(musicFolderId) && !Util.isTagBrowsing(context, getInstance(context))) {
names.add("musicFolderId");
values.add(musicFolderId);
}
@@ -802,11 +821,37 @@ public class RESTMusicService implements MusicService {
}
@Override
- public void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception {
+ public void setStarred(List<String> ids, List<String> artistId, List<String> albumId, boolean starred, Context context, ProgressListener progressListener) throws Exception {
checkServerVersion(context, "1.8", "Starring is not supported.");
- id = getOfflineSongId(id, context, progressListener);
+
+ List<String> names = new ArrayList<String>();
+ List<Object> values = new ArrayList<Object>();
+
+ if(ids != null && ids.size() > 0) {
+ if(ids.size() > 1) {
+ for (String id : ids) {
+ names.add("id");
+ values.add(id);
+ }
+ } else {
+ names.add("id");
+ values.add(getOfflineSongId(ids.get(0), context, progressListener));
+ }
+ }
+ if(artistId != null && artistId.size() > 0) {
+ for (String id : artistId) {
+ names.add("artistId");
+ values.add(id);
+ }
+ }
+ if(albumId != null && albumId.size() > 0) {
+ for (String id : albumId) {
+ names.add("albumId");
+ values.add(id);
+ }
+ }
- Reader reader = getReader(context, progressListener, starred ? "star" : "unstar", null, "id", id);
+ Reader reader = getReader(context, progressListener, starred ? "star" : "unstar", null, names, values);
try {
new ErrorParser(context).parse(reader);
} finally {
@@ -1183,7 +1228,7 @@ public class RESTMusicService implements MusicService {
String id = offline.getString(Constants.OFFLINE_STAR_ID + i, null);
boolean starred = offline.getBoolean(Constants.OFFLINE_STAR_SETTING + i, false);
if(id != null) {
- setStarred(id, starred, context, progressListener);
+ setStarred(Arrays.asList(id), null, null, starred, context, progressListener);
} else {
String search = offline.getString(Constants.OFFLINE_STAR_SEARCH + i, "");
try{
@@ -1191,10 +1236,10 @@ public class RESTMusicService implements MusicService {
SearchResult result = searchNew(critera, context, progressListener);
if(result.getSongs().size() == 1){
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());
- setStarred(result.getSongs().get(0).getId(), starred, context, progressListener);
+ setStarred(Arrays.asList(result.getSongs().get(0).getId()), null, null, starred, context, progressListener);
} else if(result.getAlbums().size() == 1){
Log.i(TAG, "Query '" + search + "' returned song " + result.getAlbums().get(0).getTitle() + " by " + result.getAlbums().get(0).getArtist() + " with id " + result.getAlbums().get(0).getId());
- setStarred(result.getAlbums().get(0).getId(), starred, context, progressListener);
+ setStarred(Arrays.asList(result.getAlbums().get(0).getId()), null, null, starred, context, progressListener);
}
else{
throw new Exception("Song not found on server");
@@ -1440,7 +1485,14 @@ public class RESTMusicService implements MusicService {
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
return networkInfo == null ? -1 : networkInfo.getType();
}
-
+
+ private int getInstance(Context context) {
+ if(instance == null) {
+ return Util.getActiveServer(context);
+ } else {
+ return instance;
+ }
+ }
public String getRestUrl(Context context, String method) {
return getRestUrl(context, method, true);
}
diff --git a/src/github/daneren2005/dsub/service/parser/AlbumListParser.java b/src/github/daneren2005/dsub/service/parser/AlbumListParser.java
index 64145d67..9cf064e6 100644
--- a/src/github/daneren2005/dsub/service/parser/AlbumListParser.java
+++ b/src/github/daneren2005/dsub/service/parser/AlbumListParser.java
@@ -47,7 +47,9 @@ public class AlbumListParser extends MusicDirectoryEntryParser {
if (eventType == XmlPullParser.START_TAG) {
String name = getElementName();
if ("album".equals(name)) {
- dir.addChild(parseEntry(""));
+ MusicDirectory.Entry entry = parseEntry("");
+ entry.setDirectory(true);
+ dir.addChild(entry);
} else if ("error".equals(name)) {
handleError();
}
diff --git a/src/github/daneren2005/dsub/service/parser/IndexesParser.java b/src/github/daneren2005/dsub/service/parser/IndexesParser.java
index bf5bd8b1..30ea190b 100644
--- a/src/github/daneren2005/dsub/service/parser/IndexesParser.java
+++ b/src/github/daneren2005/dsub/service/parser/IndexesParser.java
@@ -67,7 +67,7 @@ public class IndexesParser extends MusicDirectoryEntryParser {
eventType = nextParseEvent();
if (eventType == XmlPullParser.START_TAG) {
String name = getElementName();
- if ("indexes".equals(name)) {
+ if ("indexes".equals(name) || "artists".equals(name)) {
changed = true;
lastModified = getLong("lastModified");
ignoredArticles = get("ignoredArticles");
diff --git a/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java b/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java
index 3c12dfd4..b9a77aa8 100644
--- a/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java
+++ b/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java
@@ -32,8 +32,20 @@ public class MusicDirectoryEntryParser extends AbstractParser {
protected MusicDirectory.Entry parseEntry(String artist) {
MusicDirectory.Entry entry = new MusicDirectory.Entry();
entry.setId(get("id"));
- entry.setParent(get("parent"));
+ String albumId = get("albumId");
+ if(albumId != null) {
+ entry.setParent(albumId);
+ entry.setGrandParent(get("artistId"));
+ } else {
+ entry.setParent(get("parent"));
+ }
+ if(entry.getParent() == null) {
+ entry.setParent(get("artistId"));
+ }
entry.setTitle(get("title"));
+ if(entry.getTitle() == null) {
+ entry.setTitle(get("name"));
+ }
entry.setDirectory(getBoolean("isDir"));
entry.setCoverArt(get("coverArt"));
entry.setArtist(get("artist"));
diff --git a/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java b/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java
index 7a49cfa5..75f878be 100644
--- a/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java
+++ b/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java
@@ -49,19 +49,25 @@ public class MusicDirectoryParser extends MusicDirectoryEntryParser {
MusicDirectory dir = new MusicDirectory();
int eventType;
+ boolean isArtist = false;
do {
eventType = nextParseEvent();
if (eventType == XmlPullParser.START_TAG) {
String name = getElementName();
- if ("child".equals(name)) {
+ if ("child".equals(name) || "song".equals(name) || "video".equals(name)) {
MusicDirectory.Entry entry = parseEntry(artist);
entry.setGrandParent(dir.getParent());
dir.addChild(entry);
- } else if ("directory".equals(name)) {
+ } else if ("directory".equals(name) || "artist".equals(name) || ("album".equals(name) && !isArtist)) {
dir.setName(get("name"));
dir.setId(get("id"));
dir.setParent(get("parent"));
- } else if ("error".equals(name)) {
+ isArtist = true;
+ } else if("album".equals(name)) {
+ MusicDirectory.Entry entry = parseEntry(artist);
+ entry.setDirectory(true);
+ dir.addChild(entry);
+ } else if ("error".equals(name)) {
handleError();
}
}
diff --git a/src/github/daneren2005/dsub/service/parser/SearchResult2Parser.java b/src/github/daneren2005/dsub/service/parser/SearchResult2Parser.java
index a0be07ac..abf96d7f 100644
--- a/src/github/daneren2005/dsub/service/parser/SearchResult2Parser.java
+++ b/src/github/daneren2005/dsub/service/parser/SearchResult2Parser.java
@@ -57,7 +57,9 @@ public class SearchResult2Parser extends MusicDirectoryEntryParser {
artist.setName(get("name"));
artists.add(artist);
} else if ("album".equals(name)) {
- albums.add(parseEntry(""));
+ MusicDirectory.Entry entry = parseEntry("");
+ entry.setDirectory(true);
+ albums.add(entry);
} else if ("song".equals(name)) {
songs.add(parseEntry(""));
} else if ("error".equals(name)) {
diff --git a/src/github/daneren2005/dsub/service/parser/StarredListParser.java b/src/github/daneren2005/dsub/service/parser/StarredListParser.java
index fc4cd175..bd2a7888 100644
--- a/src/github/daneren2005/dsub/service/parser/StarredListParser.java
+++ b/src/github/daneren2005/dsub/service/parser/StarredListParser.java
@@ -47,9 +47,15 @@ public class StarredListParser extends MusicDirectoryEntryParser {
if (eventType == XmlPullParser.START_TAG) {
String name = getElementName();
if ("album".equals(name) || "song".equals(name)) {
- dir.addChild(parseEntry(""));
+ MusicDirectory.Entry entry = parseEntry("");
+ if("album".equals(name)) {
+ entry.setDirectory(true);
+ }
+ dir.addChild(entry);
} else if("artist".equals(name)) {
- dir.addChild(parseArtist());
+ MusicDirectory.Entry entry = parseArtist();
+ entry.setDirectory(true);
+ dir.addChild(entry);
} else if ("error".equals(name)) {
handleError();
}
diff --git a/src/github/daneren2005/dsub/util/Constants.java b/src/github/daneren2005/dsub/util/Constants.java
index 1e56fbd4..651f043e 100644
--- a/src/github/daneren2005/dsub/util/Constants.java
+++ b/src/github/daneren2005/dsub/util/Constants.java
@@ -138,6 +138,7 @@ public final class Constants {
public static final String PREFERENCES_KEY_MENU_STAR = "showStar";
public static final String PREFERENCES_KEY_MENU_SHARED = "showShared";
public static final String PREFERENCES_KEY_SHARED_ENABLED = "sharedEnabled";
+ public static final String PREFERENCES_KEY_BROWSE_TAGS = "browseTags";
public static final String OFFLINE_SCROBBLE_COUNT = "scrobbleCount";
public static final String OFFLINE_SCROBBLE_ID = "scrobbleID";
diff --git a/src/github/daneren2005/dsub/util/FileUtil.java b/src/github/daneren2005/dsub/util/FileUtil.java
index 8ee8d0ba..8fa9796e 100644
--- a/src/github/daneren2005/dsub/util/FileUtil.java
+++ b/src/github/daneren2005/dsub/util/FileUtil.java
@@ -213,7 +213,7 @@ public class FileUtil {
} else {
// Do a special lookup since 4.7+ doesn't match artist/album to entry.getPath
String s = Util.getRestUrl(context, null, false) + entry.getId();
- String cacheName = "directory-" + s.hashCode() + ".ser";
+ String cacheName = (Util.isTagBrowsing(context) ? "album-" : "directory-") + s.hashCode() + ".ser";
MusicDirectory entryDir = FileUtil.deserialize(context, cacheName, MusicDirectory.class);
if(entryDir != null) {
diff --git a/src/github/daneren2005/dsub/util/Util.java b/src/github/daneren2005/dsub/util/Util.java
index eecdcdeb..28a8c138 100644
--- a/src/github/daneren2005/dsub/util/Util.java
+++ b/src/github/daneren2005/dsub/util/Util.java
@@ -388,9 +388,17 @@ public final class Util {
return builder.toString();
}
+
+ public static boolean isTagBrowsing(Context context) {
+ return isTagBrowsing(context, Util.getActiveServer(context));
+ }
+ public static boolean isTagBrowsing(Context context, int instance) {
+ SharedPreferences prefs = getPreferences(context);
+ return prefs.getBoolean(Constants.PREFERENCES_KEY_BROWSE_TAGS + instance, false);
+ }
public static String getVideoPlayerType(Context context) {
- SharedPreferences prefs = getPreferences(context);
+ SharedPreferences prefs = getPreferences(context);
return prefs.getString(Constants.PREFERENCES_KEY_VIDEO_PLAYER, "raw");
}
diff --git a/src/github/daneren2005/dsub/util/compat/RemoteControlClientKK.java b/src/github/daneren2005/dsub/util/compat/RemoteControlClientKK.java
index e88b4122..532aec5b 100644
--- a/src/github/daneren2005/dsub/util/compat/RemoteControlClientKK.java
+++ b/src/github/daneren2005/dsub/util/compat/RemoteControlClientKK.java
@@ -22,6 +22,7 @@ import github.daneren2005.dsub.service.MusicServiceFactory;
import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.Util;
import java.io.File;
+import java.util.Arrays;
@TargetApi(19)
public class RemoteControlClientKK extends RemoteControlClientJB {
@@ -64,7 +65,7 @@ public class RemoteControlClientKK extends RemoteControlClientJB {
protected Void doInBackground(Void... params) {
try {
MusicService musicService = MusicServiceFactory.getMusicService(downloadService);
- musicService.setStarred(entry.getId(), starred, downloadService, null);
+ musicService.setStarred(Arrays.asList(entry.getId()), null, null, starred, downloadService, null);
// Make sure to clear parent cache
String s = Util.getRestUrl(downloadService, null) + entry.getParent();