Album Collections v0.1: A Call for Input

This forum is for questions / discussions regarding development of addons / tweaks for MediaMonkey.

Moderator: Gurus

AngrySpade
Posts: 21
Joined: Fri Jun 10, 2011 8:31 pm

Album Collections v0.1: A Call for Input

Post by AngrySpade » Mon Jun 13, 2011 10:16 pm

Hello,

I've had a few questions over the past few days.
Bex has been kind enough to help me out with them.
Thanks.

I've want a way of maintaining collections of Albums in MediaMonkey.
I've always used Playlists to do this; they work fine for the most part, but its really hard to maintain an ordered set of Albums with Playlists.

For instance, Rolling Stones 500 Greatest Albums of All Time.
http://www.rollingstone.com/music/lists ... e-19691231

Ideally, I would also love to be able to import a text file that contains a list of Artists & Albums or if possible import it from a website like, ListsOfBests.
http://www.listsofbests.com/list/5413-5 ... f-all-time

My idea would have all the albums listed in a Tree Node.
Lets say this script would make its best attempt to find the album in my library by AlbumArtist & AlbumName.
If they aren't found they would be still be displayed (yet disabled somehow) in the Tree of that particular Album Collection.
As I collect them, I'd like to be able to mark them off by "linking" the Album to an Album in my library.

This is just an initial scratch at the idea.
I wanted to know what people thought, I'm sure someone has a few ideas for me.

The script adds an Album Collection Node to the tree.

Image

You can right click the Album Collection Node to add an Album Collection.
At what point, any song(s) that are dragged onto the Album Collection, crates an entry for the entire Album under the collection.
As of now Collections can be Added/Removed/Renamed, Albums can be Added/Removed.

Besides the magical "list import" & "linking" functionality I would love to add.
I would like Album Collections to be able to be organized in the Tree, in Folders (for lack of a better term).
I'd like Albums in the Album Collection to be easily sortable. Possibly dragging an Album in a collection on top of another Album, would put the prior ahead of the former.
I'd like like to optionally put Numbers ahead of each album in the tree. I'd like an Album collection to optionally group its children into sub-folders (1-50, 51-100, etc.)

These are all things that I try to do with my playlists, but I find it very frustrating at times.

So alas, I wanted to get the thoughts of the community here...
  • Is there an addon/script that already does this?
    Is this something that others would be interested in?
    Does anyone have any other ideas/wishes that I could add to this?
    I have to add two tables to the database to do this, what are peoples thoughts on that?
Save the following to a file in your \Scripts\Auto Folder

Thanks for checking it out if you do.

-AngrySpade

Code: Select all

' Album Collections
'
' Version: 0.1
' Date: 2011-06-13
' Author: Stanley Goldman

Const KEY_ALBUM_COLLECTION_ROOT_NODE = "SPADE_AlbumCollectionRootNode"
Const KEY_ALBUM_COLLECTION_MENU = "SPADE_AlbumCollectionRootMenu"

Const NODEID_ALBUM_COLLECTION_ROOT = 113113
Const NODEID_ALBUM_COLLECTION = 113114
Const NODEID_ALBUM_COLLECTION_ALBUM = 113115

Sub DebugBox (Message)
	SDB.MessageBox Message, mtInformation, Array(mbOk)
End Sub

Sub CreateSystemTables
		SDB.Database.ExecSql("CREATE TABLE IF NOT EXISTS SpadeAlbumCollections (ID integer PRIMARY KEY AUTOINCREMENT, Name text NOT NULL COLLATE IUNICODE)")
		SDB.Database.ExecSql("CREATE TABLE IF NOT EXISTS SpadeAlbumCollectionList (" & _ 
							 "ID integer PRIMARY KEY AUTOINCREMENT," & _
							 "AlbumCollectionID integer," & _
							 "AlbumArtist text COLLATE IUNICODE," & _
							 "Album text COLLATE IUNICODE," & _ 
							 "AlbumOrder integer NOT NULL, " & _
							 "AlbumID integer, " & _ 
							 "FOREIGN KEY (AlbumCollectionID) REFERENCES SpadeAlbumCollections(ID) ON DELETE CASCADE," & _
							 "FOREIGN KEY (AlbumID) REFERENCES Albums(ID) ON DELETE SET NULL)")
End Sub

'*******************************************
'Album Functions
'*******************************************

Function AddAlbum(AlbumCollectionNode, ID, Name)
	Dim Tree : Set Tree = SDB.MainTree
	
	Dim AlbumNode : Set AlbumNode = Tree.CreateNode
	AlbumNode.CustomData = ID
	AlbumNode.Caption = Name
	AlbumNode.IconIndex = 17
	AlbumNode.UseScript = Script.ScriptPath
	
	Tree.AddNode AlbumCollectionNode, AlbumNode, 3
	
	Script.RegisterEvent AlbumNode, "OnFillTracks", "Album_OnFillTracks"
	Script.RegisterEvent AlbumNode, "OnExecMenuItem", "Album_OnExecMenuItem"
	Script.RegisterEvent AlbumNode, "OnShowMenuItem", "Album_OnShowMenuItem"
	
	
	Set AddAlbum = AlbumNode
End Function

'*******************************************
'End Album Functions
'*******************************************

'*******************************************
'Album Events
'*******************************************

Sub Album_OnFillTracks(AlbumNode)
	Dim AlbumID : AlbumID = AlbumNode.CustomData
	
	Set Trcks = SDB.MainTracksWindow
 
	Trcks.AddTracksFromCustomQuery("SELECT Songs.* FROM Songs WHERE Songs.IDALBUM = " & AlbumID)
	Trcks.FinishAdding
End Sub

Function Album_OnShowMenuItem(iItemIndex)
    Select Case iItemIndex
    Case 5
        Album_OnShowMenuItem = True
    Case Else
        Album_OnShowMenuItem = False
    End Select
End Function

Function Album_OnExecMenuItem(iItemIndex)
    If iItemIndex = 5 Then
        If Not SDB.MainTree.CurrentNode Is Nothing Then
			Dim AblumNode : Set AblumNode = SDB.MainTree.CurrentNode
			Dim AlbumID : AlbumID = AblumNode.CustomData
			
			SDB.Database.ExecSql("DELETE FROM SpadeAlbumCollectionList WHERE ID = " & AlbumID)
            SDB.MainTree.RemoveNode AblumNode
        End If
        Album_OnExecMenuItem = True
    Else
        Album_OnExecMenuItem = False
    End If
End Function

'*******************************************
'End Album Events
'*******************************************

'*******************************************
'Album Collection Functions
'*******************************************

Function AddAlbumCollection(ID, Name, HasChildren)
	Dim Tree : Set Tree = SDB.MainTree
	
	Dim AlbumCollectionNode : Set AlbumCollectionNode = Tree.CreateNode
	AlbumCollectionNode.CustomData = ID
	AlbumCollectionNode.Caption = Name
	AlbumCollectionNode.IconIndex = 23
	AlbumCollectionNode.UseScript = Script.ScriptPath
	
	Tree.AddNode SDB.Objects(KEY_ALBUM_COLLECTION_ROOT_NODE), AlbumCollectionNode, 3
	
	Script.RegisterEvent AlbumCollectionNode, "OnExecMenuItem", "AlbumCollection_OnExecMenuItem"
	Script.RegisterEvent AlbumCollectionNode, "OnShowMenuItem", "AlbumCollection_OnShowMenuItem"
	Script.RegisterEvent AlbumCollectionNode, "OnCanEditNode", "AlbumCollection_OnCanEditNode"
	Script.RegisterEvent AlbumCollectionNode, "OnNodeEditText", "AlbumCollection_OnNodeEditText"
	Script.RegisterEvent AlbumCollectionNode, "OnNodeEdited", "AlbumCollection_OnNodeEdited"
	Script.RegisterEvent AlbumCollectionNode, "OnNodeDragDrop", "AlbumCollection_OnNodeDragDrop"
	Script.RegisterEvent AlbumCollectionNode, "OnFillChildren", "AlbumCollection_OnFillChildren"
	Script.RegisterEvent AlbumCollectionNode, "OnFillTracks", "AlbumCollection_OnFillTracks"
	
	AlbumCollectionNode.HasChildren = HasChildren
	
	Set AddAlbumCollection = AlbumCollectionNode
End Function

'*******************************************
'End Album Collection Functions
'*******************************************

'*******************************************
'Album Collection Events
'*******************************************

Sub AlbumCollection_OnFillChildren(AlbumCollectionNode)
	AlbumCollectionNode.HasChildren = False
	
	Dim AlbumCollectionID : AlbumCollectionID = AlbumCollectionNode.CustomData
	
	Dim Iter : Set Iter = SDB.Database.OpenSql("SELECT * FROM SpadeAlbumCollectionList WHERE AlbumCollectionID = " & AlbumCollectionID & " ORDER BY AlbumOrder")
	While Not Iter.EOF
		Dim AlbumNode : Set AlbumNode = AddAlbum(AlbumCollectionNode, Iter.StringByName("ALBUMID"), Iter.StringByName("ALBUM"))
		Iter.Next
	WEnd	
	Set Iter = Nothing
	
End Sub

Sub AlbumCollection_OnFillTracks(AlbumCollectionNode)
	Dim AlbumCollectionID : AlbumCollectionID = AlbumCollectionNode.CustomData
	
	Set Trcks = SDB.MainTracksWindow
 
	Trcks.AddTracksFromCustomQuery("SELECT Songs.* FROM Songs INNER JOIN SpadeAlbumCollectionList ON Songs.IDALBUM = AlbumID WHERE SpadeAlbumCollectionList.AlbumCollectionID = " & AlbumCollectionID & " ORDER BY SpadeAlbumCollectionList.AlbumOrder")
	Trcks.FinishAdding
End Sub

Function AlbumCollection_OnNodeDragDrop(AlbumCollectionNode, srcNode, SongList, DropType, Test)
	If Test Then
		AlbumCollection_OnNodeDragDrop = 4
	Else
		Dim AlbumCollectionExpanded : AlbumCollectionExpanded = AlbumCollectionNode.Expanded
		Dim AlbumCollectionID : AlbumCollectionID = AlbumCollectionNode.CustomData
			
		Dim AlbumIndex
		For AlbumIndex = 0 To (SongList.Albums.Count - 1)
			Dim Album : Set Album = SongList.Albums.Item(AlbumIndex)
					
			Dim Iter : Set Iter = SDB.Database.OpenSql("SELECT COALESCE(MAX(AlbumOrder), 0) as AlbumOrder FROM SpadeAlbumCollectionList WHERE AlbumCollectionID = " & AlbumCollectionID)
			Dim AlbumOrder : AlbumOrder = Iter.StringByName("AlbumOrder")
			AlbumOrder = AlbumOrder + 1
			Set Iter = Nothing
			
			SDB.Database.ExecSql "INSERT INTO SpadeAlbumCollectionList (AlbumCollectionID , AlbumArtist , Album , AlbumOrder , AlbumID ) VALUES (" & AlbumCollectionID & ", """ & Album.Artist.Name & """, """ & Album.Name & """ , " & AlbumOrder & ", " & Album.ID & ")"
		Next
		
		AlbumCollection_OnFillChildren AlbumCollectionNode
			AlbumCollectionNode.Expanded = AlbumCollectionExpanded
	End If
End Function

Function AlbumCollection_OnCanEditNode(AlbumCollectionNode)
	AlbumCollection_OnCanEditNode = True
End Function

Function AlbumCollection_OnNodeEditText(AlbumCollectionNode)
	AlbumCollection_OnNodeEditText = AlbumCollectionNode.Caption
End Function

Function AlbumCollection_OnNodeEdited(AlbumCollectionNode, NewText)
	Dim AlbumCollectionID : AlbumCollectionID = AlbumCollectionNode.CustomData

	SDB.Database.ExecSql "UPDATE SpadeAlbumCollections SET Name = """ & NewText & """ WHERE ID = " & AlbumCollectionID
	AlbumCollectionNode.Caption = NewText
End Function

Function AlbumCollection_OnShowMenuItem(iItemIndex)
    Select Case iItemIndex
    Case 5
        AlbumCollection_OnShowMenuItem = True
    Case Else
        AlbumCollection_OnShowMenuItem = False
    End Select
End Function

Function AlbumCollection_OnExecMenuItem(iItemIndex)
    If iItemIndex = 5 Then
        If Not SDB.MainTree.CurrentNode Is Nothing Then
			Dim AblumCollectionNode : Set AblumCollectionNode = SDB.MainTree.CurrentNode
			Dim AlbumCollectionID : AlbumCollectionID = AblumCollectionNode.CustomData
			
			SDB.Database.ExecSql("DELETE FROM SpadeAlbumCollections WHERE ID = " & AlbumCollectionID)
            SDB.MainTree.RemoveNode AblumCollectionNode
        End If
        AlbumCollection_OnExecMenuItem = True
    Else
        AlbumCollection_OnExecMenuItem = False
    End If
End Function

'*******************************************
'End Album Collection Events
'*******************************************

'*******************************************
'Album Collection Root Functions
'*******************************************

Sub CreateAlbumCollectionRoot
	Dim Tree : Set Tree = SDB.MainTree
	
	Dim AlbumCollectionRootNode : Set AlbumCollectionRootNode = Tree.CreateNode
	AlbumCollectionRootNode.CustomNodeId = NODEID_ALBUM_COLLECTION_ROOT
	AlbumCollectionRootNode.Caption = "Album Collections"
	AlbumCollectionRootNode.IconIndex = 10
	AlbumCollectionRootNode.UseScript = Script.ScriptPath
	AlbumCollectionRootNode.OnFillChildren = "AlbumCollectionRoot_OnFillChildren"
	
	SDB.Objects(KEY_ALBUM_COLLECTION_ROOT_NODE) = AlbumCollectionRootNode
    Tree.AddNode Tree.Node_Library, AlbumCollectionRootNode, 1
	AlbumCollectionRootNode.HasChildren = True
End Sub

'*******************************************
'End Album Collection Root Functions
'*******************************************

'*******************************************
'Album Collection Root Events
'*******************************************

Sub AlbumCollectionRoot_OnFillChildren(CollectionRootNode)
	CollectionRootNode.HasChildren = False
	
	Dim Iter : Set Iter = SDB.Database.OpenSql("SELECT SpadeAlbumCollections.*, COUNT(SpadeAlbumCollectionList.ID) as ChildCount FROM SpadeAlbumCollections LEFT JOIN SpadeAlbumCollectionList ON SpadeAlbumCollections.ID = SpadeAlbumCollectionList.AlbumCollectionID GROUP BY SpadeAlbumCollections.ID")
	
	While Not Iter.EOF
		Dim AlbumCollectionNode : Set AlbumCollectionNode = AddAlbumCollection(Iter.StringByName("ID"), Iter.StringByName("NAME"), Iter.StringByName("ChildCount") > 0)
		Iter.Next
	WEnd
	
	Set Iter = Nothing
End Sub

'*******************************************
'End Album Collection Root Events
'*******************************************

'*******************************************
'Album Collection Menu Function & Events
'*******************************************

Sub CreateAlbumCollectionMenus
	Dim AlbumCollectionMenu : Set AlbumCollectionMenu = SDB.UI.AddMenuItem( SDB.UI.Menu_Pop_Tree , -1, 1)
	AlbumCollectionMenu.Caption = "Add Album Collection"
	AlbumCollectionMenu.IconIndex = 9
	AlbumCollectionMenu.UseScript=Script.ScriptPath
	AlbumCollectionMenu.OnClickFunc="OnMenuClick_AddAlbumCollection"
	AlbumCollectionMenu.Visible = False
	
	SDB.Objects(KEY_ALBUM_COLLECTION_MENU) = AlbumCollectionMenu
End Sub

Sub OnMenuClick_AddAlbumCollection(Item)
	Dim NewAlbumName : NewAlbumName = "New Album Collection"
	SDB.Database.ExecSql("INSERT INTO SpadeAlbumCollections (Name) VALUES (""" & NewAlbumName & """)")
	
	Dim Iter : Set Iter = SDB.Database.OpenSql("SELECT last_insert_rowid()")
	Dim LastID : LastID = Iter.StringByIndex(0)
	
	Dim AlbumCollectionNode : Set AlbumCollectionNode = AddAlbumCollection(LastID, NewAlbumName, False)
	Set SDB.MainTree.CurrentNode = AlbumCollectionNode
End Sub

Sub SetVisibleMenus
	If Not SDB.MainTree.CurrentNode Is Nothing Then
		Dim CurrentNode : Set CurrentNode = SDB.MainTree.CurrentNode
		If CurrentNode.CustomNodeId = NODEID_ALBUM_COLLECTION_ROOT Then
			SDB.Objects(KEY_ALBUM_COLLECTION_MENU).Visible = True
		Else
			SDB.Objects(KEY_ALBUM_COLLECTION_MENU).Visible = False
		End If
	End If
End Sub

'*******************************************
'End Album Collection Menu Function & Events
'*******************************************

Sub OnStartUp()
	CreateSystemTables
	CreateAlbumCollectionRoot
	CreateAlbumCollectionMenus
		
	Script.RegisterEvent SDB, "OnChangedSelection", "SetVisibleMenus"
End Sub

ZvezdanD
Posts: 3084
Joined: Thu Jun 08, 2006 7:40 pm

Re: Album Collections v0.1: A Call for Input

Post by ZvezdanD » Tue Jun 14, 2011 1:47 am

AngrySpade wrote:I wanted to get the thoughts of the community here...
  • Is there an addon/script that already does this?
I am not sure, but I think that you could use the Magic Nodes add-on for that. Instead of creating a new table which contains list of albums in collections, you could just use some Custom field to specify if some album belongs to some collection. However, you need to specify the same value in the Custom field to all tracks from the same album, which wouldn't be a big problem if you use e.g. RegExp Find & Replace. Then you could use some Magic Nodes mask like this:

Code: Select all

Album Collections|Child of:Library\<Custom 1>\<Album|Show rank:Yes>
Using some Custom field instead of a table has a benefit if you need to restore audio library, for example if you get corrupted your database file or you want to use audio library on several computers, since Custom field is stored in audio files.
Magic Nodes 4.3.3 / 5.2 RegExp Find & Replace 4.4.9 / 5.2  Invert Selection/Select None 1.5.1  Export/Create Playlists for Child Nodes 4.1 / 5.4  Expand Child Nodes/Expand All 1.1.2  Event Logger 2.7  Filtered Statistics Report 1.6  Track Redirection & Synchronization 3.4.2  Restore/Synchronize Database 3.1.7 / 4.0  Find Currently Playing Track 1.3.2  Queue List 1.2.1  Add to Library on Play 1.0.1  Tree Report for Child Nodes 1.1.1  Update Location of Files in Database 1.4.3 / 2.2.2  Inherit Child Playlists 1.0.2  Add Currently Playing/Selected Track(s) to Playlist 1.1.2

AngrySpade
Posts: 21
Joined: Fri Jun 10, 2011 8:31 pm

Re: Album Collections v0.1: A Call for Input

Post by AngrySpade » Sat May 19, 2012 5:53 pm

http://www.mediamonkey.com/forum/viewto ... =2&t=60003

Check out the script.
Now that its pretty much exactly what I wanted.

Post Reply