You own a huge collection of tracks?
And sometimes you do not want to choose what to listen to?
I propose as a script a new MM functionality i called "Selection of the Day".
Each time you start MM, an album, an artist and a bunch of independent tracks are randomly selected and stored under a specific tree node (namely "Today...").
A "forced mode" can be enabled to re-randomize the selection of the day. See the comments within the script code.
I hope you will enjoy it as i enjoyed writting it.
Octopod
Code: Select all
' ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
'
' "Auto/SelectionOfTheDay.vbs", Sept-01-2004
' VBScript for MediaMonkey 2.2.2 (or above), written by Octopod
'
'
' Purpose:
' - This script adds a new tree node named "Today..." after the Playlists one
' - Each time you start MediaMonkey: an artist, an album and 14 songs (default)
' are randomly selected from the entire DB
' - If you don't like the selection of the day, a toolbar icon can be enabled to
' re-randomize it ("Standard" toolbar)
' - If you do not change the used strings, this script is localization-compatible
' - Hope you will enjoy it!
'
' Known issue:
' - If a "today sub-node" is already selected when randomize is manually forced:
' 1. Bad node selection refresh
' 2. Tracks list is not updated (need to hit 'F5' or change node)
'
' Notes:
' - This script uses registry keys because i did not succeeded in retrieving a
' global value from the nodes callbacks
' - This script may be not or badly optimized as i do not know VBS
' - So, and although this script should be safe, USE AT YOUR OWN RISK
'
' ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
' --> Number of songs you want to be proposed?
NbSongs = 14
' --> Expand the node at startup?
ExpandNewNode = False
' --> Explicit nodes caption?
ExplicitCaption = True
' --> Enable re-randomize?
EnableReRandomize = False
' Globals (cardinals)
Dim ArtistsCardinal
Dim AlbumsCardinal
Dim SongsCardinal
' Globals (random positions)
Dim SelectedArtistPos
Dim SelectedAlbumPos
Dim SelectedSongsPos()
' ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
Sub OnStartup
Dim Tree
Set Tree = SDB.MainTree
' Main node
Set Node_Today = Tree.CreateNode
Node_Today.Caption = SDB.Localize("Today") + "..."
Node_Today.IconIndex = 49
Node_Today.UseScript = Script.ScriptPath
Tree.AddNode Tree.Node_Playlists, Node_Today, 1
SDB.Objects("Node_Today") = Node_Today
' Subnode 1 (Artist)
Set Node_TodayArtist = Tree.CreateNode
Node_TodayArtist.Caption = SDB.Localize("Artist")
Node_TodayArtist.IconIndex = 0
Node_TodayArtist.UseScript = Script.ScriptPath
Node_TodayArtist.OnFillTracksFunct = "FillTodayArtist"
Tree.AddNode Node_Today, Node_TodayArtist, 3
SDB.Objects("Node_TodayArtist") = Node_TodayArtist
' Subnode 2 (Album)
Set Node_TodayAlbum = Tree.CreateNode
Node_TodayAlbum.Caption = SDB.Localize("Album")
Node_TodayAlbum.IconIndex = 16
Node_TodayAlbum.UseScript = Script.ScriptPath
Node_TodayAlbum.OnFillTracksFunct = "FillTodayAlbum"
Tree.AddNode Node_Today, Node_TodayAlbum, 3
SDB.Objects("Node_TodayAlbum") = Node_TodayAlbum
' Subnode 3 (Songs)
Set Node_TodaySong = Tree.CreateNode
If (ExplicitCaption) Then
Node_TodaySong.Caption = "(" + CStr(NbSongs) + " " + SDB.Localize("tracks") + ")"
Else
Node_TodaySong.Caption = SDB.Localize("Title")
End If
Node_TodaySong.IconIndex = 3
Node_TodaySong.UseScript = Script.ScriptPath
Node_TodaySong.OnFillTracksFunct = "FillTodaySong"
Tree.AddNode Node_Today, Node_TodaySong, 3
If (EnableReRandomize) Then
' Add a button to the Standard toolbar...
Set UI = SDB.UI
UI.AddMenuItemSep UI.Menu_TbStandard, -1, 0
Set Mnu = UI.AddMenuItem( UI.Menu_TbStandard, 0, 0)
Mnu.UseScript = Script.ScriptPath
Mnu.OnClickFunc = "ForceNewSelection"
Mnu.IconIndex = 45
Mnu.Hint = SDB.Localize("Today") + "..."
End If
' Prepare selection at startup
Node_Today.Expanded = ExpandNewNode
NewSelection(dummy)
End Sub
' ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
Sub NewSelection(arg)
InitCardinals
InitSelections
' Explicit caption
If (ExplicitCaption) Then
Dim ID
' Artist
Set Node_TodayArtist = SDB.Objects("Node_TodayArtist")
ID = GetArtistID(SelectedArtistPos)
Set ArtistName = SDB.Database.OpenSQL("SELECT Artists.Artist FROM Artists WHERE Artists.ID = " + CStr(ID))
Node_TodayArtist.Caption = ArtistName.StringByIndex(0)
' Album
Set Node_TodayAlbum = SDB.Objects("Node_TodayAlbum")
ID = GetAlbumID(SelectedAlbumPos)
Set AlbumName = SDB.Database.OpenSQL("SELECT Albums.Album FROM Albums WHERE Albums.ID = " + CStr(ID))
Node_TodayAlbum.Caption = AlbumName.StringByIndex(0)
End If
End Sub
Sub ForceNewSelection(arg)
NewSelection(arg)
' Force explicit captions refresh
If (EnableReRandomize) Then
' Main node
Set Node_Today = SDB.Objects("Node_Today")
If (Node_Today.Expanded) Then
Node_Today.Expanded = False
Node_Today.Expanded = True
End If
End If
End Sub
Sub InitCardinals
' Artists (remove ID = 0 = "Unknown" artist)
Set AllArtists = SDB.Database.OpenSQL("SELECT COUNT(*) FROM Artists WHERE Artists.ID <> 0")
ArtistsCardinal = AllArtists.StringByIndex(0)
' Albums (remove ID = 0 = "Unknown" album)
Set AllAlbums = SDB.Database.OpenSQL("SELECT COUNT(*) FROM Albums WHERE Albums.ID <> 0")
AlbumsCardinal = AllAlbums.StringByIndex(0)
' Songs
Set AllSongs = SDB.Database.OpenSQL("SELECT COUNT(*) FROM Songs")
SongsCardinal = AllSongs.StringByIndex(0)
End Sub
Sub InitSelections
Randomize
' Randomly select a **position** within artists IDs records
SelectedArtistPos = Int(Rnd * ArtistsCardinal)
' Randomly select **position** within albums IDs records
SelectedAlbumPos = Int(Rnd * AlbumsCardinal)
' Randomly select "NbSongs" **positions** within songs IDs records
ReDim SelectedSongsPos(NbSongs)
For i = 1 to NbSongs
SelectedSongsPos(i) = Int(Rnd * SongsCardinal)
Next
' Bubble sort
' (sort positions to speed up songs display; only one loop)
Dim count, i, j, temp
count = UBound(SelectedSongsPos, 1)
For j = 0 To NbSongs - 1
For i = 0 To NbSongs - 1
If SelectedSongsPos(i) > SelectedSongsPos(i + 1) Then
temp = SelectedSongsPos(i + 1)
SelectedSongsPos(i + 1) = SelectedSongsPos(i)
SelectedSongsPos(i) = temp
End If
Next
Next
' Save selections
Set Regs = SDB.Registry
If Regs.OpenKey("SelectionOfTheDay", True) Then
Regs.IntValue("SelectedArtistPos") = SelectedArtistPos
Regs.IntValue("SelectedAlbumPos") = SelectedAlbumPos
For i = 1 to NbSongs
Regs.IntValue("SelectedSongsPos" + CStr(i)) = SelectedSongsPos(i)
Next
Regs.IntValue("SongsCardinal") = SongsCardinal
Regs.CloseKey
End If
End Sub
' ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
Function GetArtistID(ArtistPos)
' Get all available artists IDs
' (This query is done in the callback to avoid slowing startup)
Set ArtistsIDs = SDB.Database.OpenSQL("SELECT Artists.ID FROM Artists WHERE Artists.ID <> 0")
' Get its related **artist ID** (as position <> ID):
' 1. Forward to ArtistPos'th record
For j = 1 to ArtistPos - 1
ArtistsIDs.Next
Next
' 2. Then get its related artist ID
GetArtistID = ArtistsIDs.StringByIndex(0)
End Function
Sub FillTodayArtist(Node)
' Get back selected artist position
Set Regs = SDB.Registry
If Regs.OpenKey("SelectionOfTheDay", True) Then
SelectedArtistPos = Regs.IntValue("SelectedArtistPos")
Regs.CloseKey
End If
' Get back related artist ID
Dim ID
ID = GetArtistID(SelectedArtistPos)
' Prepare query
Dim ArtistQuery
ArtistQuery = "AND Songs.IDArtist = "
ArtistQuery = ArtistQuery + CStr(ID)
ArtistQuery = ArtistQuery + " ORDER BY Songs.Year DESC, Songs.IDAlbum, Songs.SongOrder"
' Now, invoke query and update tracks list
Set Tracks = SDB.MainTracksWindow
Tracks.AddTracksFromQuery ArtistQuery
Tracks.FinishAdding
End Sub
' ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
Function GetAlbumID(AlbumPos)
' Get all available albums IDs
' (This query is done in the callback to avoid slowing startup)
Set AlbumsIDs = SDB.Database.OpenSQL("SELECT Albums.ID FROM Albums WHERE Albums.ID <> 0")
' Get its related **album ID** (as position <> ID):
' 1. Forward to SelectedAlbumPos'th record
For j = 1 to SelectedAlbumPos - 1
AlbumsIDs.Next
Next
' 2. Then get its related album ID
GetAlbumID = AlbumsIDs.StringByIndex(0)
End Function
Sub FillTodayAlbum(Node)
' Get back selected album position
Set Regs = SDB.Registry
If Regs.OpenKey("SelectionOfTheDay", True) Then
SelectedAlbumPos = Regs.IntValue("SelectedAlbumPos")
Regs.CloseKey
End If
' Get back related album ID
Dim ID
ID = GetAlbumID(SelectedAlbumPos)
' Prepare query
Dim AlbumQuery
AlbumQuery = "AND Songs.IDAlbum = "
AlbumQuery = AlbumQuery + CStr(ID)
AlbumQuery = AlbumQuery + " ORDER BY Songs.SongOrder"
' Now, invoke query and update tracks list
Set Tracks = SDB.MainTracksWindow
Tracks.AddTracksFromQuery AlbumQuery
Tracks.FinishAdding
End Sub
' ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
Sub FillTodaySong(Node)
ReDim SelectedSongsPos(NbSongs)
Dim tempo
tempo = ""
' Get back selected songs positions
Set Regs = SDB.Registry
If Regs.OpenKey("SelectionOfTheDay", True) Then
For i = 1 to NbSongs
SelectedSongsPos(i) = Regs.IntValue("SelectedSongsPos" + CStr(i))
tempo = tempo + CStr(SelectedSongsPos(i)) + " / "
Next
SongsCardinal = Regs.IntValue("SongsCardinal")
Regs.CloseKey
End If
' Get all available songs IDs
' (This query is done in the callback to avoid slowing startup)
Set SongsIDs = SDB.Database.OpenSQL("SELECT Songs.ID FROM Songs ORDER BY Songs.ID")
' Store IDs
ReDim IDList(NbSongs)
Dim IDCardinal
IDCardinal = 0
' Current position counter
Dim NextID
NextID = 1
' Forward along the iterator
' (This block is a bit complex but its aim is to avoid browsing the iterator
' several times, so display of the selected tracks will be faster)
For j = 0 to (SongsCardinal - 1)
' Check if the current item is selected ("SelectedSongsPos" is sorted)
If (j = SelectedSongsPos(NextID)) Then
IDList(IDCardinal) = SongsIDs.StringByIndex(0)
IDCardinal = IDCardinal + 1
' Break loop if all IDs already found
If (NextID = NbSongs) Then
Exit For
End If
' Otherwise, update next position to reach
NextID = NextID + 1
' Check if douboons in the subsequent cells
If (NextID < NbSongs) Then
While (SelectedSongsPos(NextID) = SelectedSongsPos(NextID + 1))
NextID = NextID + 1
WEnd
End If
End If
' Continue...
SongsIDs.Next
Next
' Prepare query
Dim SongQuery
SongQuery = "AND Songs.ID IN ("
For i = 0 to (IDCardinal - 2)
SongQuery = SongQuery + CStr(IDList(i)) + ", "
Next
SongQuery = SongQuery + CStr(IDList(IDCardinal - 1)) + ") ORDER BY Songs.SongTitle"
' Now, invoke query and update tracks list
Set Tracks = SDB.MainTracksWindow
Tracks.AddTracksFromQuery SongQuery
Tracks.FinishAdding
' Because of possible doubloons and/or ghost songs IDs,
' less than "NbSongs" songs might be proposed
End Sub