[banshee] Implement random by album and artist (BGO #348582)
- From: Gabriel Burt <gburt src gnome org>
- To: svn-commits-list gnome org
- Subject: [banshee] Implement random by album and artist (BGO #348582)
- Date: Tue, 2 Jun 2009 21:58:03 -0400 (EDT)
commit 1013f9f9ad81c4468a89ef0b74e60a6e84780d7d
Author: Gabriel Burt <gabriel burt gmail com>
Date: Tue Jun 2 20:30:07 2009 -0500
Implement random by album and artist (BGO #348582)
The long-insensitive options for Shuffle by Artist and Album in the
random dropdown are finally enabled!
---
.../DatabaseTrackListModel.cs | 121 ++++++++++++++++++-
.../Banshee.Collection/MemoryTrackListModel.cs | 2 +-
.../Banshee.Collection/TrackListModel.cs | 2 +-
.../PlaybackControllerService.cs | 7 +-
.../Banshee.Gui/PlaybackShuffleActions.cs | 2 -
5 files changed, 119 insertions(+), 15 deletions(-)
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackListModel.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackListModel.cs
index 20a2c8d..fdd1f77 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackListModel.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackListModel.cs
@@ -42,6 +42,7 @@ using Hyena.Query;
using Banshee.Base;
using Banshee.Query;
using Banshee.Database;
+using Banshee.PlaybackController;
namespace Banshee.Collection.Database
{
@@ -336,23 +337,34 @@ namespace Banshee.Collection.Database
}
}
+#region Get random methods
+
+ private const string random_condition = "AND LastStreamError = 0 AND (LastPlayedStamp < ? OR LastPlayedStamp IS NULL) AND (LastSkippedStamp < ? OR LastSkippedStamp IS NULL)";
+ private static string random_fragment = String.Format ("{0} ORDER BY RANDOM()", random_condition);
+ private static string random_by_album_fragment = String.Format ("AND CoreTracks.AlbumID = ? {0} ORDER BY DiscNumber ASC, TrackNumber ASC", random_condition);
+ private static string random_by_artist_fragment = String.Format ("AND CoreAlbums.ArtistID = ? {0} ORDER BY CoreAlbums.TitleSortKey ASC, DiscNumber ASC, TrackNumber ASC", random_condition);
+
private DateTime random_began_at = DateTime.MinValue;
private DateTime last_random = DateTime.MinValue;
- private static string random_fragment = "AND (LastPlayedStamp < ? OR LastPlayedStamp IS NULL) AND (LastSkippedStamp < ? OR LastSkippedStamp IS NULL) ORDER BY RANDOM()";
- public override TrackInfo GetRandom (DateTime notPlayedSince, bool repeat)
+ private int? random_album_id;
+ private int? random_artist_id;
+
+ public override TrackInfo GetRandom (DateTime notPlayedSince, PlaybackShuffleMode mode, bool repeat)
{
lock (this) {
- if (Count == 0)
+ if (Count == 0) {
return null;
+ }
- if (random_began_at < notPlayedSince)
+ if (random_began_at < notPlayedSince) {
random_began_at = last_random = notPlayedSince;
+ }
- TrackInfo track = cache.GetSingle (random_fragment, random_began_at, random_began_at);
-
+ TrackInfo track = GetRandomTrack (mode, repeat);
if (track == null && repeat) {
random_began_at = last_random;
- track = cache.GetSingle (random_fragment, random_began_at, random_began_at);
+ random_album_id = random_artist_id = null;
+ track = GetRandomTrack (mode, repeat);
}
last_random = DateTime.Now;
@@ -360,6 +372,101 @@ namespace Banshee.Collection.Database
}
}
+ private TrackInfo GetRandomTrack (PlaybackShuffleMode mode, bool repeat)
+ {
+ if (mode == PlaybackShuffleMode.Album) {
+ random_artist_id = null;
+ if (random_album_id == null) {
+ random_album_id = GetRandomAlbumId (random_began_at);
+ if (random_album_id == null && repeat) {
+ random_began_at = last_random;
+ random_album_id = GetRandomAlbumId (random_began_at);
+ }
+ }
+
+ if (random_album_id != null) {
+ return cache.GetSingle (random_by_album_fragment, (int)random_album_id, random_began_at, random_began_at);
+ }
+ } else if (mode == PlaybackShuffleMode.Artist) {
+ random_album_id = null;
+ if (random_artist_id == null) {
+ random_artist_id = GetRandomArtistId (random_began_at);
+ if (random_artist_id == null && repeat) {
+ random_began_at = last_random;
+ random_artist_id = GetRandomArtistId (random_began_at);
+ }
+ }
+
+ if (random_artist_id != null) {
+ return cache.GetSingle (random_by_artist_fragment, (int)random_artist_id, random_began_at, random_began_at);
+ }
+ } else {
+ random_album_id = random_artist_id = null;
+ }
+
+ return cache.GetSingle (random_fragment, random_began_at, random_began_at);
+ }
+
+ private int? GetRandomAlbumId (DateTime stamp)
+ {
+ // Get a new Album that hasn't been played since y
+ int? album_id = null;
+ var reader = connection.Query (@"
+ SELECT a.AlbumID, a.Title, MAX(t.LastPlayedStamp) as LastPlayed, MAX(t.LastSkippedStamp) as LastSkipped
+ FROM CoreTracks t, CoreAlbums a, CoreCache c
+ WHERE
+ c.ModelID = ? AND
+ t.TrackID = c.ItemID AND
+ t.AlbumID = a.AlbumID AND
+ t.LastStreamError = 0
+ GROUP BY t.AlbumID
+ HAVING
+ (LastPlayed < ? OR LastPlayed IS NULL) AND
+ (LastSkipped < ? OR LastSkipped IS NULL)
+ ORDER BY RANDOM()
+ LIMIT 1",
+ CacheId, stamp, stamp
+ );
+
+ if (reader.Read ()) {
+ album_id = Convert.ToInt32 (reader[0]);
+ }
+
+ reader.Dispose ();
+ return album_id;
+ }
+
+ private int? GetRandomArtistId (DateTime stamp)
+ {
+ // Get a new Artist that hasn't been played since y
+ int? artist_id = null;
+ var reader = connection.Query (@"
+ SELECT a.ArtistID, a.ArtistName, MAX(t.LastPlayedStamp) as LastPlayed, MAX(t.LastSkippedStamp) as LastSkipped
+ FROM CoreTracks t, CoreAlbums a, CoreCache c
+ WHERE
+ c.ModelID = ? AND
+ t.TrackID = c.ItemID AND
+ t.AlbumID = a.AlbumID AND
+ t.LastStreamError = 0
+ GROUP BY a.ArtistID
+ HAVING
+ (LastPlayed < ? OR LastPlayed IS NULL) AND
+ (LastSkipped < ? OR LastSkipped IS NULL)
+ ORDER BY RANDOM()
+ LIMIT 1",
+ CacheId, stamp, stamp
+ );
+
+ if (reader.Read ()) {
+ artist_id = Convert.ToInt32 (reader[0]);
+ }
+
+ reader.Dispose ();
+ return artist_id;
+ }
+
+#endregion
+
public override TrackInfo this[int index] {
get {
lock (this) {
diff --git a/src/Core/Banshee.Services/Banshee.Collection/MemoryTrackListModel.cs b/src/Core/Banshee.Services/Banshee.Collection/MemoryTrackListModel.cs
index 75748c0..8f12c32 100644
--- a/src/Core/Banshee.Services/Banshee.Collection/MemoryTrackListModel.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection/MemoryTrackListModel.cs
@@ -81,7 +81,7 @@ namespace Banshee.Collection
get { lock (this) { return (index >= 0 && index < tracks.Count) ? tracks[index] : null; } }
}
- public override TrackInfo GetRandom (DateTime since, bool repeat)
+ public override TrackInfo GetRandom (DateTime since, Banshee.PlaybackController.PlaybackShuffleMode mode, bool repeat)
{
if (Count == 0)
return null;
diff --git a/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs b/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs
index 2201482..3b0e700 100644
--- a/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs
@@ -51,6 +51,6 @@ namespace Banshee.Collection
public abstract int IndexOf (TrackInfo track);
- public abstract TrackInfo GetRandom (DateTime notPlayedSince, bool repeat);
+ public abstract TrackInfo GetRandom (DateTime notPlayedSince, Banshee.PlaybackController.PlaybackShuffleMode mode, bool repeat);
}
}
diff --git a/src/Core/Banshee.Services/Banshee.PlaybackController/PlaybackControllerService.cs b/src/Core/Banshee.Services/Banshee.PlaybackController/PlaybackControllerService.cs
index f903542..da5fa71 100644
--- a/src/Core/Banshee.Services/Banshee.PlaybackController/PlaybackControllerService.cs
+++ b/src/Core/Banshee.Services/Banshee.PlaybackController/PlaybackControllerService.cs
@@ -311,7 +311,7 @@ namespace Banshee.PlaybackController
Log.DebugFormat ("Querying model for track to play in {0}:{1} mode", ShuffleMode, direction);
return ShuffleMode == PlaybackShuffleMode.Linear
? QueryTrackLinear (direction, restart)
- : QueryTrackRandom (restart);
+ : QueryTrackRandom (ShuffleMode, restart);
}
private TrackInfo QueryTrackLinear (Direction direction, bool restart)
@@ -340,10 +340,9 @@ namespace Banshee.PlaybackController
}
}
- private TrackInfo QueryTrackRandom (bool restart)
+ private TrackInfo QueryTrackRandom (PlaybackShuffleMode mode, bool restart)
{
- return Source.TrackModel.GetRandom (source_set_at, restart);
- //return Source.TrackModel[random.Next (0, Source.TrackModel.Count - 1)];
+ return Source.TrackModel.GetRandom (source_set_at, mode, restart);
}
private void QueuePlayTrack ()
diff --git a/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackShuffleActions.cs b/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackShuffleActions.cs
index faeec9c..983335d 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackShuffleActions.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Gui/PlaybackShuffleActions.cs
@@ -102,8 +102,6 @@ namespace Banshee.Gui
this["ShuffleSongAction"].IconName = "media-playlist-shuffle";
this["ShuffleArtistAction"].IconName = "media-playlist-shuffle";
this["ShuffleAlbumAction"].IconName = "media-playlist-shuffle";
- this["ShuffleArtistAction"].Sensitive = false;
- this["ShuffleAlbumAction"].Sensitive = false;
ServiceManager.PlaybackController.ShuffleModeChanged += OnShuffleModeChanged;
ServiceManager.PlaybackController.SourceChanged += OnPlaybackSourceChanged;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]