Sample AMG Search script: Difference between revisions
Jump to navigation
Jump to search
(Updated source code to reflect some changes on AMG servers) |
No edit summary |
||
(6 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
==Attention== | |||
'''Maybe this script should be changed to one using a website that allows this kind of action. ''AMG does not.''''' | |||
---- | |||
This script demonstrates how to plug-in into MediaMonkey Web Search dialog. It searches AMG web a lets user tag some basic fields. Don't forget that it's rather a sample of what [[Search scripts]] can do than fully working script. | This script demonstrates how to plug-in into MediaMonkey Web Search dialog. It searches AMG web a lets user tag some basic fields. Don't forget that it's rather a sample of what [[Search scripts]] can do than fully working script. | ||
It currently searches | It currently searches AllMusic's website for the given album, presents user results found and lets tag these fields: | ||
* Album | * Album | ||
* Artist | * Artist | ||
* Track titles | * Track titles | ||
* Album art | * Album art | ||
* Release year | |||
* Genres | |||
* Styles | |||
* Moods | |||
* Themes | |||
Line 26: | Line 36: | ||
' [SearchAMG] | ' [SearchAMG] | ||
' FileName=SearchAMG.vbs | ' FileName=SearchAMG.vbs | ||
' Order=10 | ' Order=10 | ||
' DisplayName=Search All Music Guide | ' DisplayName=Search All Music Guide | ||
Line 37: | Line 46: | ||
' MediaMonkey calls this method whenever a search is started using this script | ' MediaMonkey calls this method whenever a search is started using this script | ||
Sub StartSearch( Panel, SearchTerm, SearchArtist, SearchAlbum) | Sub StartSearch(Panel, SearchTerm, SearchArtist, SearchAlbum) | ||
Set UI = SDB.UI | Set UI = SDB.UI | ||
' This is a web browser that we use to present results to the user | ' This is a web browser that we use to present results to the user | ||
Set WB = UI.NewActiveX( Panel, "Shell.Explorer") | Set WB = UI.NewActiveX(Panel, "Shell.Explorer") | ||
WB.Common.Align = 5 ' Fill whole client rectangle | WB.Common.Align = 5 ' Fill whole client rectangle | ||
WB.Common.ControlName = "WB" | WB.Common.ControlName = "WB" | ||
' This is a hidden browser that we use to find results (a better solution can be used, but this seems to be the easiest...) | ' This is a hidden browser that we use to find results (a better solution can be used, but this seems to be the easiest...) | ||
Set WB2 = UI.NewActiveX( Panel, "Shell.Explorer") | Set WB2 = UI.NewActiveX(Panel, "Shell.Explorer") | ||
WB2.Common.ControlName = "WB2" | WB2.Common.ControlName = "WB2" | ||
Line 72: | Line 81: | ||
Set Doc2 = WB2Intf.Document | Set Doc2 = WB2Intf.Document | ||
Set SrchTxt = Doc2.getElementById("search_txt") | Set SrchTxt = Doc2.getElementById("search_txt") | ||
If SearchAlbum<>"" Then | If SearchAlbum <> "" Then | ||
SrchTxt.Value = SearchAlbum | SrchTxt.Value = SearchAlbum | ||
Else | Else | ||
Line 84: | Line 93: | ||
SrchButton.Click | SrchButton.Click | ||
Set Tmr = SDB.CreateTimer( 40) | Set Tmr = SDB.CreateTimer(40) | ||
Script.RegisterEvent Tmr, "OnTimer", "ContinueSearch" | Script.RegisterEvent Tmr, "OnTimer", "ContinueSearch" | ||
End Sub | End Sub | ||
' We use this procedure as a callback using Timer, so that we can present results as soon as they are downloaded | ' We use this procedure as a callback using Timer, so that we can present results as soon as they are downloaded | ||
Sub ContinueSearch( Timer) | Sub ContinueSearch(Timer) | ||
Script.UnregisterEvents Tmr | Script.UnregisterEvents Tmr | ||
Set Tmr = Nothing | Set Tmr = Nothing | ||
Line 95: | Line 104: | ||
Set WB2Intf = WB2.Interf | Set WB2Intf = WB2.Interf | ||
If Len(WB2Intf.LocationURL)<10 Then ' A trick - wait until navigation to the search results page starts | If Len(WB2Intf.LocationURL) < 10 Then ' A trick - wait until navigation to the search results page starts | ||
Set Tmr = SDB.CreateTimer( 40) | Set Tmr = SDB.CreateTimer(40) | ||
Script.RegisterEvent Tmr, "OnTimer", "ContinueSearch" | Script.RegisterEvent Tmr, "OnTimer", "ContinueSearch" | ||
Exit Sub | Exit Sub | ||
End If | End If | ||
If | If WB2Intf.ReadyState = 1 Or WB2Intf.Busy Then | ||
Set Tmr = SDB.CreateTimer( 40) | Set Tmr = SDB.CreateTimer(40) | ||
Script.RegisterEvent Tmr, "OnTimer", "ContinueSearch" | Script.RegisterEvent Tmr, "OnTimer", "ContinueSearch" | ||
Exit Sub | Exit Sub | ||
Line 117: | Line 126: | ||
For Each itm In AColl | For Each itm In AColl | ||
Set Imgs = itm.getElementsByTagName("img") | Set Imgs = itm.getElementsByTagName("img") | ||
pos = InStr( CStr(itm.href), ".com/") | pos = InStr(CStr(itm.href), ".com/") | ||
If pos>0 Then | If pos > 0 Then | ||
href = Mid( itm.href, pos) | href = Mid(itm.href, pos) | ||
If | If Left(href,Len(".com/cg/amg.dll?p=amg&sql=10:")) = ".com/cg/amg.dll?p=amg&sql=10:" And Imgs.length = 0 Then | ||
Results.Add itm.innerText | Results.Add itm.innerText | ||
FoundLinks.Add itm.href | FoundLinks.Add itm.href | ||
Line 128: | Line 137: | ||
SDB.Tools.WebSearch.SetSearchResults Results | SDB.Tools.WebSearch.SetSearchResults Results | ||
If Results.Count>0 Then | If Results.Count > 0 Then | ||
SDB.Tools.WebSearch.ResultIndex = 0 | SDB.Tools.WebSearch.ResultIndex = 0 | ||
End If | End If | ||
Line 137: | Line 146: | ||
' This procedure is called by MediaMonkey when user selects some of search results | ' This procedure is called by MediaMonkey when user selects some of search results | ||
Sub ShowResult( ResultID) | Sub ShowResult(ResultID) | ||
If ResultID>=0 And ResultID<FoundLinks.Count Then | If ResultID >= 0 And ResultID < FoundLinks.Count Then | ||
SDB.Tools.WebSearch.ClearTracksData ' Tell MM to disregard any previously set tracks' data | SDB.Tools.WebSearch.ClearTracksData ' Tell MM to disregard any previously set tracks' data | ||
WB.SetHTMLDocument "" ' To prevent usage of this data | WB.SetHTMLDocument "" ' To prevent usage of this data | ||
WB.Interf.Navigate FoundLinks.Item(ResultID) | WB.Interf.Navigate FoundLinks.Item(ResultID) | ||
Set Tmr = SDB.CreateTimer( 500) | Set Tmr = SDB.CreateTimer(500) | ||
Script.RegisterEvent Tmr, "OnTimer", "ResultFullyLoaded" | Script.RegisterEvent Tmr, "OnTimer", "ResultFullyLoaded" | ||
End If | End If | ||
Line 149: | Line 158: | ||
' This is a callback handled by a timer, so that we can respond as soon as album results are loaded | ' This is a callback handled by a timer, so that we can respond as soon as album results are loaded | ||
Sub ResultFullyLoaded( Timer) | Sub ResultFullyLoaded(Timer) | ||
Script.UnregisterEvents Tmr | Script.UnregisterEvents Tmr | ||
Set Tmr = Nothing | Set Tmr = Nothing | ||
Line 162: | Line 171: | ||
For Each itm In AColl | For Each itm In AColl | ||
Set Imgs = itm.getElementsByTagName("img") | Set Imgs = itm.getElementsByTagName("img") | ||
pos = InStr( CStr(itm.href), ".com/") | pos = InStr(CStr(itm.href), ".com/") | ||
If pos>0 Then | If pos > 0 Then | ||
href = Mid( itm.href, pos) | href = Mid(itm.href, pos) | ||
If | If Left(href,Len(".com/cg/amg.dll?p=amg&sql=33:")) = ".com/cg/amg.dll?p=amg&sql=33:" And Imgs.length = 0 Then | ||
Tracks.Add itm.innerText | Tracks.Add itm.innerText | ||
End If | End If | ||
End If | End If | ||
If itm.className="subtitle" Then | If itm.className = "subtitle" Then | ||
ArtistTitle = itm.innerText | ArtistTitle = itm.innerText | ||
End If | End If | ||
Line 177: | Line 186: | ||
Set SpanColl = Doc.getElementsByTagName("Span") | Set SpanColl = Doc.getElementsByTagName("Span") | ||
For Each itm in SpanColl | For Each itm in SpanColl | ||
If itm.className="title" Then | If itm.className = "title" Then | ||
AlbumTitle = itm.innerText | AlbumTitle = itm.innerText | ||
End If | End If | ||
Line 185: | Line 194: | ||
Set ImgColl = Doc.getElementsByTagName("Img") | Set ImgColl = Doc.getElementsByTagName("Img") | ||
For Each itm in ImgColl | For Each itm in ImgColl | ||
If | If Left(itm.src,Len("http://image.allmusic.com/")) = "http://image.allmusic.com/" Then | ||
SDB.Tools.WebSearch.AlbumArtURL = itm.src | SDB.Tools.WebSearch.AlbumArtURL = itm.src | ||
End If | |||
Next | |||
' Get release year | |||
Set SpanColl = Doc.getElementsByTagName("span") | |||
For Each itm In SpanColl | |||
pos = InStr(itm.innerText, "Release Date") | |||
If pos > 0 Then | |||
Set Parnt = itm.parentNode.parentNode.parentNode.parentNode | |||
Set TDColl = Parnt.getElementsByTagName("td") | |||
For Each itm2 In TDColl | |||
If itm2.className = "sub-text" Then | |||
ReleaseYear = Right(itm2.innerText, 4) | |||
Exit For | |||
End If | |||
Next | |||
Exit For | |||
End If | |||
Next | |||
' Get genres/styles/moods/themes | |||
ListCnt = 0 | |||
Set DivColl = Doc.getElementsByTagName("div") | |||
For Each itm In DivColl | |||
pos = InStr(itm.id, "left-sidebar-list") | |||
If pos > 0 Then | |||
Set AColl = itm.getElementsByTagName("a") | |||
MyList = "" | |||
For Each itm2 In AColl | |||
If MyList <> "" Then MyList = MyList & ";" | |||
MyList = MyList & itm2.innerText | |||
Next | |||
ListCnt = ListCnt + 1 | |||
Select Case ListCnt | |||
Case 1 | |||
Genres = MyList | |||
Case 2 | |||
Styles = MyList | |||
Case 3 | |||
Moods = MyList | |||
Case 4 | |||
Themes = MyList | |||
End Select | |||
End If | End If | ||
Next | Next | ||
End If | End If | ||
If Tracks.Count=0 Then | If Tracks.Count = 0 Then | ||
' Nothing found yet, wait some more time | ' Nothing found yet, wait some more time | ||
Set Tmr = SDB.CreateTimer( 500) | Set Tmr = SDB.CreateTimer(500) | ||
Script.RegisterEvent Tmr, "OnTimer", "ResultFullyLoaded" | Script.RegisterEvent Tmr, "OnTimer", "ResultFullyLoaded" | ||
Else | Else | ||
' Some results were found, notify MediaMonkey | ' Some results were found, notify MediaMonkey | ||
SDB.Tools.WebSearch.SmartUpdateTracks Tracks | SDB.Tools.WebSearch.SmartUpdateTracks Tracks | ||
For i=0 To SDB.Tools.WebSearch.NewTracks.Count-1 | For i = 0 To SDB.Tools.WebSearch.NewTracks.Count - 1 | ||
SDB.Tools.WebSearch.NewTracks.Item(i).ArtistName = ArtistTitle | SDB.Tools.WebSearch.NewTracks.Item(i).ArtistName = ArtistTitle | ||
SDB.Tools.WebSearch.NewTracks.Item(i).AlbumName = AlbumTitle | SDB.Tools.WebSearch.NewTracks.Item(i).AlbumName = AlbumTitle | ||
SDB.Tools.WebSearch.NewTracks.Item(i).Year = ReleaseYear | |||
SDB.Tools.WebSearch.NewTracks.Item(i).Genre = Genres | |||
SDB.Tools.WebSearch.NewTracks.Item(i).Custom1 = Styles | |||
SDB.Tools.WebSearch.NewTracks.Item(i).Custom2 = Moods | |||
SDB.Tools.WebSearch.NewTracks.Item(i).Custom3 = Themes | |||
Next | Next | ||
SDB.Tools.WebSearch.RefreshViews ' Tell MM that we have made some changes | SDB.Tools.WebSearch.RefreshViews ' Tell MM that we have made some changes | ||
Line 207: | Line 264: | ||
' This does the final clean up, so that our script doesn't leave any unwanted traces | ' This does the final clean up, so that our script doesn't leave any unwanted traces | ||
Sub FinishSearch( Panel) | Sub FinishSearch(Panel) | ||
' Correctly terminate all the actions we have started | ' Correctly terminate all the actions we have started | ||
WB.Common.DestroyControl | WB.Common.DestroyControl ' Destroy the external control | ||
WB2.Common.DestroyControl | WB2.Common.DestroyControl ' " " " " | ||
Set WB = Nothing | Set WB = Nothing ' Release global variable | ||
Set WB2 = Nothing | Set WB2 = Nothing ' " " " | ||
Set FoundLinks = Nothing ' " " " | |||
If IsObject(Tmr) Then | If IsObject(Tmr) Then | ||
Script.UnregisterEvents Tmr | Script.UnregisterEvents Tmr ' Unregister timer events | ||
Set Tmr = Nothing | Set Tmr = Nothing ' Release global variable | ||
End If | End If | ||
End Sub | End Sub | ||
</source> | </source> |
Latest revision as of 09:29, 19 January 2018
Attention
Maybe this script should be changed to one using a website that allows this kind of action. AMG does not.
This script demonstrates how to plug-in into MediaMonkey Web Search dialog. It searches AMG web a lets user tag some basic fields. Don't forget that it's rather a sample of what Search scripts can do than fully working script.
It currently searches AllMusic's website for the given album, presents user results found and lets tag these fields:
- Album
- Artist
- Track titles
- Album art
- Release year
- Genres
- Styles
- Moods
- Themes
There's a lot that could be improved, namely:
- Error handling - currently many possible problems aren't solved
- More fields could be tagged
- Results could be formatted using custom HTML page (not the downloaded one)
- Many others...
It's quite well documented, and so it can help in creation of your own Search scripts.
' Sample AMG Search script
'
' This script demonstrates how to plug-in into MediaMonkey Web Search dialog. You should save it to Scripts folder as
' SearchAMG.vbs. It has to be in Scripts.ini file, where entries can be as follows:
'
' [SearchAMG]
' FileName=SearchAMG.vbs
' Order=10
' DisplayName=Search All Music Guide
' Language=VBScript
' ScriptType=3
Dim WB, WB2
Dim FoundLinks
Dim Tmr
' MediaMonkey calls this method whenever a search is started using this script
Sub StartSearch(Panel, SearchTerm, SearchArtist, SearchAlbum)
Set UI = SDB.UI
' This is a web browser that we use to present results to the user
Set WB = UI.NewActiveX(Panel, "Shell.Explorer")
WB.Common.Align = 5 ' Fill whole client rectangle
WB.Common.ControlName = "WB"
' This is a hidden browser that we use to find results (a better solution can be used, but this seems to be the easiest...)
Set WB2 = UI.NewActiveX(Panel, "Shell.Explorer")
WB2.Common.ControlName = "WB2"
WB.Common.BringToFront
' The following HTML is taken from AMG web pages - so that we don't have to load the search page and can post the query directly
' The following line will probably need some better way of retrieving server name from AMG. Using www.allmusicguide.com doesn't work at this moment.
html = "<form name=""search"" action=""http://wm08.allmusic.com/cg/amg.dll"" method=""post"">"
html = html & "<input type=""hidden"" name=""P"" value=""amg"" />"
html = html & "<p><input type=""text"" name=""sql"" id=""search_txt"" />"
html = html & "<input type=""image"" src=""/i/pages/wide/go.gif"" id=""search_button"" /></p>"
html = html & "<p><select name=""opt1"" id=""search_opt"">"
html = html & " <option value=""1"" selected=""selected"">Artist/Group</option>"
html = html & " <option value=""2"">Album</option>"
html = html & " <option value=""3"">Song</option>"
html = html & " <option value=""55"">Classical Work</option>"
html = html & "</select></p>"
html = html & "</form>"
Set WB2Intf = WB2.Interf
WB2Intf.Visible = false
WB2.SetHTMLDocument html
Set Doc2 = WB2Intf.Document
Set SrchTxt = Doc2.getElementById("search_txt")
If SearchAlbum <> "" Then
SrchTxt.Value = SearchAlbum
Else
SrchTxt.Value = SearchTerm
End If
Set SrchType = Doc2.getElementById("search_opt")
SrchType.selectedIndex = 1 ' Search for an album
Set SrchButton = Doc2.getElementById("search_button")
SrchButton.Click
Set Tmr = SDB.CreateTimer(40)
Script.RegisterEvent Tmr, "OnTimer", "ContinueSearch"
End Sub
' We use this procedure as a callback using Timer, so that we can present results as soon as they are downloaded
Sub ContinueSearch(Timer)
Script.UnregisterEvents Tmr
Set Tmr = Nothing
Set WB2Intf = WB2.Interf
If Len(WB2Intf.LocationURL) < 10 Then ' A trick - wait until navigation to the search results page starts
Set Tmr = SDB.CreateTimer(40)
Script.RegisterEvent Tmr, "OnTimer", "ContinueSearch"
Exit Sub
End If
If WB2Intf.ReadyState = 1 Or WB2Intf.Busy Then
Set Tmr = SDB.CreateTimer(40)
Script.RegisterEvent Tmr, "OnTimer", "ContinueSearch"
Exit Sub
End If
Set Doc2 = WB2Intf.Document
Set DivResults = Doc2.body
Set Results = SDB.NewStringList
Set FoundLinks = SDB.NewStringList
If IsObject(DivResults) And Not IsNull(DivResults) Then
Set AColl = DivResults.getElementsByTagName("A")
For Each itm In AColl
Set Imgs = itm.getElementsByTagName("img")
pos = InStr(CStr(itm.href), ".com/")
If pos > 0 Then
href = Mid(itm.href, pos)
If Left(href,Len(".com/cg/amg.dll?p=amg&sql=10:")) = ".com/cg/amg.dll?p=amg&sql=10:" And Imgs.length = 0 Then
Results.Add itm.innerText
FoundLinks.Add itm.href
End If
End If
Next
SDB.Tools.WebSearch.SetSearchResults Results
If Results.Count > 0 Then
SDB.Tools.WebSearch.ResultIndex = 0
End If
Else
WB.SetHTMLDocument = Doc2.documentElement.innerHTML
End If
End Sub
' This procedure is called by MediaMonkey when user selects some of search results
Sub ShowResult(ResultID)
If ResultID >= 0 And ResultID < FoundLinks.Count Then
SDB.Tools.WebSearch.ClearTracksData ' Tell MM to disregard any previously set tracks' data
WB.SetHTMLDocument "" ' To prevent usage of this data
WB.Interf.Navigate FoundLinks.Item(ResultID)
Set Tmr = SDB.CreateTimer(500)
Script.RegisterEvent Tmr, "OnTimer", "ResultFullyLoaded"
End If
End Sub
' This is a callback handled by a timer, so that we can respond as soon as album results are loaded
Sub ResultFullyLoaded(Timer)
Script.UnregisterEvents Tmr
Set Tmr = Nothing
Set Tracks = SDB.NewStringList
Set Doc = WB.Interf.Document
If IsObject(Doc) Then
' Get track titles
Set AColl = Doc.getElementsByTagName("A")
For Each itm In AColl
Set Imgs = itm.getElementsByTagName("img")
pos = InStr(CStr(itm.href), ".com/")
If pos > 0 Then
href = Mid(itm.href, pos)
If Left(href,Len(".com/cg/amg.dll?p=amg&sql=33:")) = ".com/cg/amg.dll?p=amg&sql=33:" And Imgs.length = 0 Then
Tracks.Add itm.innerText
End If
End If
If itm.className = "subtitle" Then
ArtistTitle = itm.innerText
End If
Next
' Get album title
Set SpanColl = Doc.getElementsByTagName("Span")
For Each itm in SpanColl
If itm.className = "title" Then
AlbumTitle = itm.innerText
End If
Next
' Get Album art URL
Set ImgColl = Doc.getElementsByTagName("Img")
For Each itm in ImgColl
If Left(itm.src,Len("http://image.allmusic.com/")) = "http://image.allmusic.com/" Then
SDB.Tools.WebSearch.AlbumArtURL = itm.src
End If
Next
' Get release year
Set SpanColl = Doc.getElementsByTagName("span")
For Each itm In SpanColl
pos = InStr(itm.innerText, "Release Date")
If pos > 0 Then
Set Parnt = itm.parentNode.parentNode.parentNode.parentNode
Set TDColl = Parnt.getElementsByTagName("td")
For Each itm2 In TDColl
If itm2.className = "sub-text" Then
ReleaseYear = Right(itm2.innerText, 4)
Exit For
End If
Next
Exit For
End If
Next
' Get genres/styles/moods/themes
ListCnt = 0
Set DivColl = Doc.getElementsByTagName("div")
For Each itm In DivColl
pos = InStr(itm.id, "left-sidebar-list")
If pos > 0 Then
Set AColl = itm.getElementsByTagName("a")
MyList = ""
For Each itm2 In AColl
If MyList <> "" Then MyList = MyList & ";"
MyList = MyList & itm2.innerText
Next
ListCnt = ListCnt + 1
Select Case ListCnt
Case 1
Genres = MyList
Case 2
Styles = MyList
Case 3
Moods = MyList
Case 4
Themes = MyList
End Select
End If
Next
End If
If Tracks.Count = 0 Then
' Nothing found yet, wait some more time
Set Tmr = SDB.CreateTimer(500)
Script.RegisterEvent Tmr, "OnTimer", "ResultFullyLoaded"
Else
' Some results were found, notify MediaMonkey
SDB.Tools.WebSearch.SmartUpdateTracks Tracks
For i = 0 To SDB.Tools.WebSearch.NewTracks.Count - 1
SDB.Tools.WebSearch.NewTracks.Item(i).ArtistName = ArtistTitle
SDB.Tools.WebSearch.NewTracks.Item(i).AlbumName = AlbumTitle
SDB.Tools.WebSearch.NewTracks.Item(i).Year = ReleaseYear
SDB.Tools.WebSearch.NewTracks.Item(i).Genre = Genres
SDB.Tools.WebSearch.NewTracks.Item(i).Custom1 = Styles
SDB.Tools.WebSearch.NewTracks.Item(i).Custom2 = Moods
SDB.Tools.WebSearch.NewTracks.Item(i).Custom3 = Themes
Next
SDB.Tools.WebSearch.RefreshViews ' Tell MM that we have made some changes
End If
End Sub
' This does the final clean up, so that our script doesn't leave any unwanted traces
Sub FinishSearch(Panel)
' Correctly terminate all the actions we have started
WB.Common.DestroyControl ' Destroy the external control
WB2.Common.DestroyControl ' " " " "
Set WB = Nothing ' Release global variable
Set WB2 = Nothing ' " " "
Set FoundLinks = Nothing ' " " "
If IsObject(Tmr) Then
Script.UnregisterEvents Tmr ' Unregister timer events
Set Tmr = Nothing ' Release global variable
End If
End Sub