diff options
Diffstat (limited to 'subsonic-android')
13 files changed, 188 insertions, 33 deletions
diff --git a/subsonic-android/src/github/daneren2005/dsub/domain/MusicDirectory.java b/subsonic-android/src/github/daneren2005/dsub/domain/MusicDirectory.java index 185fc17f..14cb6694 100644 --- a/subsonic-android/src/github/daneren2005/dsub/domain/MusicDirectory.java +++ b/subsonic-android/src/github/daneren2005/dsub/domain/MusicDirectory.java @@ -21,6 +21,8 @@ package github.daneren2005.dsub.domain; import java.util.ArrayList; import java.util.List; import java.io.Serializable; +import java.util.Collections; +import java.util.Comparator; /** * @author Sindre Mehus @@ -28,7 +30,7 @@ import java.io.Serializable; public class MusicDirectory { private String name; - private final List<Entry> children = new ArrayList<Entry>(); + private List<Entry> children = new ArrayList<Entry>(); public String getName() { return name; @@ -59,6 +61,10 @@ public class MusicDirectory { } return result; } + + public void sortChildren() { + EntryComparator.sort(children); + } public static class Entry implements Serializable { private String id; @@ -283,4 +289,43 @@ public class MusicDirectory { return title; } } + + public static class EntryComparator implements Comparator<Entry> { + public int compare(Entry lhs, Entry rhs) { + Integer lhsDisc = lhs.getDiscNumber(); + Integer rhsDisc = rhs.getDiscNumber(); + + if(lhsDisc != null && rhsDisc != null) { + if(lhsDisc < rhsDisc) { + return -1; + } else if(lhsDisc > rhsDisc) { + return 1; + } + } else if(lhsDisc != null) { + return 1; + } else if(rhsDisc != null) { + return -1; + } + + Integer lhsTrack = lhs.getTrack(); + Integer rhsTrack = rhs.getTrack(); + if(lhsTrack != null && rhsTrack != null) { + if(lhsTrack < rhsTrack) { + return -1; + } else if(lhsTrack > rhsTrack) { + return 1; + } + } else if(lhsDisc != null) { + return 1; + } else if(rhsDisc != null) { + return -1; + } + + return lhs.getTitle().compareToIgnoreCase(rhs.getTitle()); + } + + public static void sort(List<Entry> entries) { + Collections.sort(entries, new EntryComparator()); + } + } }
\ 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 5f9aaf96..ee6e3885 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java @@ -123,6 +123,7 @@ public class OfflineMusicService extends RESTMusicService { result.addChild(createEntry(context, file, name)); } } + result.sortChildren(); return result; } @@ -162,6 +163,27 @@ public class OfflineMusicService extends RESTMusicService { // Failed parseInt, just means track filled out } } + + try { + MediaMetadataRetriever metadata = new MediaMetadataRetriever(); + metadata.setDataSource(file.getAbsolutePath()); + String discNumber = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER); + if(discNumber == null) { + discNumber = "1/1"; + } + int slashIndex = discNumber.indexOf("/"); + if(slashIndex > 0) { + discNumber = discNumber.substring(0, slashIndex); + } + entry.setDiscNumber(Integer.parseInt(discNumber)); + String bitrate = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE); + entry.setBitRate(Integer.parseInt((bitrate != null) ? bitrate : "0") / 1000); + String length = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); + entry.setDuration(Integer.parseInt(length) / 1000); + metadata.release(); + } catch(Exception e) { + Log.i(TAG, "Device doesn't properly support MediaMetadataRetreiver"); + } } entry.setTitle(title); diff --git a/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java b/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java index b80e71ca..b0434aca 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java @@ -59,4 +59,16 @@ public class MusicDirectoryEntryParser extends AbstractParser { } return entry; } + + protected MusicDirectory.Entry parseArtist() { + MusicDirectory.Entry entry = new MusicDirectory.Entry(); + + entry.setId(get("id")); + entry.setTitle(get("name")); + entry.setPath(entry.getTitle()); + entry.setStarred(true); + entry.setDirectory(true); + + return entry; + } }
\ No newline at end of file diff --git a/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java b/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java index 370df305..0bf6ded1 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java @@ -62,6 +62,7 @@ public class MusicDirectoryParser extends MusicDirectoryEntryParser { validate(); updateProgress(progressListener, R.string.parser_reading_done); + dir.sortChildren(); long t1 = System.currentTimeMillis(); Log.d(TAG, "Got music directory in " + (t1 - t0) + "ms."); diff --git a/subsonic-android/src/github/daneren2005/dsub/service/parser/StarredListParser.java b/subsonic-android/src/github/daneren2005/dsub/service/parser/StarredListParser.java index 2cb42f30..fc4cd175 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/parser/StarredListParser.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/parser/StarredListParser.java @@ -49,7 +49,7 @@ public class StarredListParser extends MusicDirectoryEntryParser { if ("album".equals(name) || "song".equals(name)) { dir.addChild(parseEntry("")); } else if("artist".equals(name)) { - + dir.addChild(parseArtist()); } else if ("error".equals(name)) { handleError(); } diff --git a/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java b/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java index c239fa43..60a17b67 100644 --- a/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java +++ b/subsonic-android/src/github/daneren2005/dsub/updates/Updater.java @@ -43,7 +43,7 @@ public class Updater { public void checkUpdates(Context context) {
this.context = context;
List<Updater> updaters = new ArrayList<Updater>();
- updaters.add(new Updater373());
+ updaters.add(new Updater403());
SharedPreferences prefs = Util.getPreferences(context);
int lastVersion = prefs.getInt(Constants.LAST_VERSION, 0);
diff --git a/subsonic-android/src/github/daneren2005/dsub/updates/Updater373.java b/subsonic-android/src/github/daneren2005/dsub/updates/Updater403.java index b56c2731..17947ce5 100644 --- a/subsonic-android/src/github/daneren2005/dsub/updates/Updater373.java +++ b/subsonic-android/src/github/daneren2005/dsub/updates/Updater403.java @@ -29,16 +29,16 @@ import java.io.File; *
* @author Scott
*/
-public class Updater373 extends Updater {
- public Updater373() {
- super(373);
- TAG = Updater373.class.getSimpleName();
+public class Updater403 extends Updater {
+ public Updater403() {
+ super(403);
+ TAG = Updater403.class.getSimpleName();
}
@Override
public void update(Context context) {
// Rename cover.jpeg to cover.jpg
- Log.i(TAG, "Running Updater373: updating cover.jpeg to cover.jpg");
+ Log.i(TAG, "Running Updater403: updating cover.jpg to albumart.jpg");
File dir = FileUtil.getMusicDirectory(context);
if(dir != null) {
moveArt(dir);
@@ -49,7 +49,7 @@ public class Updater373 extends Updater { for(File file: dir.listFiles()) {
if(file.isDirectory()) {
moveArt(file);
- } else if("cover.jpeg".equals(file.getName())) {
+ } else if("cover.jpg".equals(file.getName()) || "cover.jpeg".equals(file.getName())) {
File renamed = new File(dir, Constants.ALBUM_ART_FILE);
file.renameTo(renamed);
}
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java b/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java index c69a595c..44de369f 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java @@ -54,7 +54,7 @@ public class CacheCleaner { // No songs left in the folder if(children.length == 1 && children[0].getPath().equals(FileUtil.getAlbumArtFile(dir).getPath())) { - Util.delete(FileUtil.getAlbumArtFile(dir)); + Util.delete(children[0]); children = dir.listFiles(); } diff --git a/subsonic-android/src/github/daneren2005/dsub/util/Constants.java b/subsonic-android/src/github/daneren2005/dsub/util/Constants.java index 29c9a1aa..b1fcf5e6 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/Constants.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/Constants.java @@ -118,7 +118,7 @@ public final class Constants { // URL for project donations. public static final String DONATION_URL = "http://subsonic.org/pages/android-donation.jsp"; - public static final String ALBUM_ART_FILE = "cover.jpg"; + public static final String ALBUM_ART_FILE = "albumart.jpg"; 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 65f5a37f..7ead874c 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java @@ -129,6 +129,10 @@ public class FileUtil { File dir = new File(getMusicDirectory(context).getPath() + "/" + fileSystemSafe(artist.getName())); return dir; } + public static File getArtistDirectory(Context context, MusicDirectory.Entry artist) { + File dir = new File(getMusicDirectory(context).getPath() + "/" + fileSystemSafe(artist.getTitle())); + return dir; + } public static File getAlbumDirectory(Context context, MusicDirectory.Entry entry) { File dir; diff --git a/subsonic-android/src/github/daneren2005/dsub/view/ArtistEntryView.java b/subsonic-android/src/github/daneren2005/dsub/view/ArtistEntryView.java new file mode 100644 index 00000000..3b6a50e4 --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/view/ArtistEntryView.java @@ -0,0 +1,83 @@ +/*
+ 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 2009 (C) Sindre Mehus
+ */
+package github.daneren2005.dsub.view;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.domain.MusicDirectory;
+import github.daneren2005.dsub.util.FileUtil;
+import github.daneren2005.dsub.util.ImageLoader;
+import github.daneren2005.dsub.util.Util;
+import java.io.File;
+/**
+ * Used to display albums in a {@code ListView}.
+ *
+ * @author Sindre Mehus
+ */
+public class ArtistEntryView extends UpdateView {
+ private static final String TAG = AlbumView.class.getSimpleName();
+
+ private Context context;
+ private MusicDirectory.Entry artist;
+
+ private TextView titleView;
+ private ImageButton starButton;
+ private ImageView moreButton;
+
+ public ArtistEntryView(Context context) {
+ super(context);
+ this.context = context;
+ LayoutInflater.from(context).inflate(R.layout.artist_list_item, this, true);
+
+ titleView = (TextView) findViewById(R.id.artist_name);
+ starButton = (ImageButton) findViewById(R.id.artist_star);
+ moreButton = (ImageView) findViewById(R.id.artist_more);
+ moreButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ v.showContextMenu();
+ }
+ });
+ }
+
+ public void setArtist(MusicDirectory.Entry artist) {
+ this.artist = artist;
+
+ titleView.setText(artist.getTitle());
+ starButton.setVisibility((Util.isOffline(getContext()) || !artist.isStarred()) ? View.GONE : View.VISIBLE);
+ starButton.setFocusable(false);
+ update();
+ }
+
+ @Override
+ protected void update() {
+ starButton.setVisibility((Util.isOffline(getContext()) || !artist.isStarred()) ? View.GONE : View.VISIBLE);
+ File file = FileUtil.getArtistDirectory(context, artist);
+ if(file.exists()) {
+ moreButton.setImageResource(R.drawable.list_item_more_shaded);
+ } else {
+ moreButton.setImageResource(R.drawable.list_item_more);
+ }
+ }
+}
diff --git a/subsonic-android/src/github/daneren2005/dsub/view/EntryAdapter.java b/subsonic-android/src/github/daneren2005/dsub/view/EntryAdapter.java index 0d67c4c4..1a4544e0 100644 --- a/subsonic-android/src/github/daneren2005/dsub/view/EntryAdapter.java +++ b/subsonic-android/src/github/daneren2005/dsub/view/EntryAdapter.java @@ -54,11 +54,16 @@ public class EntryAdapter extends ArrayAdapter<MusicDirectory.Entry> { MusicDirectory.Entry entry = getItem(position); if (entry.isDirectory()) { - AlbumView view; - view = new AlbumView(activity); - view.setAlbum(entry, imageLoader); - return view; - + if(entry.getParent() != null) { + AlbumView view; + view = new AlbumView(activity); + view.setAlbum(entry, imageLoader); + return view; + } else { + ArtistEntryView view = new ArtistEntryView(activity); + view.setArtist(entry); + return view; + } } else { SongView view; if (convertView != null && convertView instanceof SongView) { diff --git a/subsonic-android/src/github/daneren2005/dsub/view/SongView.java b/subsonic-android/src/github/daneren2005/dsub/view/SongView.java index 51927304..40bedad6 100644 --- a/subsonic-android/src/github/daneren2005/dsub/view/SongView.java +++ b/subsonic-android/src/github/daneren2005/dsub/view/SongView.java @@ -72,23 +72,6 @@ public class SongView extends UpdateView implements Checkable { public void setSong(MusicDirectory.Entry song, boolean checkable) { this.song = song; - if(Util.isOffline(context)) { - DownloadFile downloadFile = new DownloadFile(context, song, false); - File file = downloadFile.getCompleteFile(); - if(file.exists()) { - try { - MediaMetadataRetriever metadata = new MediaMetadataRetriever(); - metadata.setDataSource(file.getAbsolutePath()); - String bitrate = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE); - song.setBitRate(Integer.parseInt((bitrate != null) ? bitrate : "0") / 1000); - String length = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); - song.setDuration(Integer.parseInt(length) / 1000); - } catch(Exception e) { - Log.i(TAG, "Device doesn't properly support MediaMetadataRetreiver"); - } - } - } - StringBuilder artist = new StringBuilder(40); String bitRate = null; |