Sample AMG Search script: Difference between revisions

From MediaMonkey Wiki
Jump to navigation Jump to search
(Updated source code to reflect some changes on AMG servers)
m (Added remark about wiki problem, and added/removed spaces)
Line 17: Line 17:


It's quite well documented, and so it can help in creation of your own Search scripts.
It's quite well documented, and so it can help in creation of your own Search scripts.
'''Important remark: due to a problem in the Wiki software, ''Shell_Explorer'' is displayed with an underscore instead of a dot. This isn't correct and the script won't work. Before running the script, be sure to change the underscore ( _ ) to a dot ( . )'''


<source lang="vb">
<source lang="vb">
Line 37: Line 40:


' 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 75:
   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 87:
   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 98:
   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 (WB2Intf.ReadyState=1) Or WB2Intf.Busy Then
   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 120:
     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 left(href,Len(".com/cg/amg.dll?p=amg&sql=10:")) = ".com/cg/amg.dll?p=amg&sql=10:" And Imgs.length=0 Then
         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 131:


     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 140:


' 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 152:


' 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 165:
     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 left(href,Len(".com/cg/amg.dll?p=amg&sql=33:")) = ".com/cg/amg.dll?p=amg&sql=33:" And Imgs.length=0 Then
         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 180:
     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 188:
     Set ImgColl = Doc.getElementsByTagName("Img")
     Set ImgColl = Doc.getElementsByTagName("Img")
     For Each itm in ImgColl
     For Each itm in ImgColl
       If left(itm.src,Len("http://image.allmusic.com/")) = "http://image.allmusic.com/" Then
       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
       End If
Line 191: Line 194:
   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
Line 207: Line 210:


' 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>

Revision as of 10:46, 2 November 2007

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 AllMusicGuide's web for the given album, presents user results found and lets tag some basic fields:

  • Album
  • Artist
  • Track titles
  • Album art


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.


Important remark: due to a problem in the Wiki software, Shell_Explorer is displayed with an underscore instead of a dot. This isn't correct and the script won't work. Before running the script, be sure to change the underscore ( _ ) to a dot ( . )

' 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
' ProcName=SearchAMG
' 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
  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
    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