Page 1 of 10

PUID Generator 2.5 - Updated 28/07/2012

Posted: Mon Jan 04, 2010 7:03 pm
by trixmoto
This new script was requested here... http://www.mediamonkey.com/forum/viewto ... =2&t=45560

It is designed to process all the selected tracks in the background, looping through them and generating the PUID. You will be asked to enter a field name which is one of the SongData properties. You will then get a confirmation screen before processing begins. Just a warning, this takes around 10 seconds per track, so don't select too many unless you've got plenty of time to spare! :)

As always, the installation package can be downloaded from my website. Here is this code...

Code: Select all

'
' MediaMonkey Script
'
' NAME: PUIDGenerator 2.5
'
' AUTHOR: trixmoto (http://trixmoto.net)
' DATE : 28/07/2012
'
' Thanks to Steegy for the SkinnedInputBox
'
' INSTALL: Copy to Scripts directory and add the following to Scripts.ini 
'          Don't forget to remove comments (') and set the order appropriately
'
' [PUIDGenerator]
' FileName=MIPT\PUIDGenerator.vbs
' ProcName=PUIDGenerator
' Order=50
' DisplayName=&PUID Generator 
' Description=Generate PUID for selected tracks
' Language=VBScript
' ScriptType=0 
' 
' FIXES: Fixed getting short path with new API method
'        Added option to tag with status if no PUID
'

Option Explicit
Dim Archive : Archive = True
Dim IncStatus : IncStatus = False

Sub PUIDGenerator
  'get selected tracks
  Dim list : Set list = SDB.SelectedSongList 
  If list.count = 0 Then 
    Set list = SDB.AllVisibleSongList 
  End If 
  If list.count = 0 Then
    Call SDB.MessageBox("PUIDGenerator: There are no selected tracks.",mtError,Array(mbOk))
    Exit Sub
  End If 
  
  'get field name
  Dim temp : temp = SDB.IniFile.StringValue("PUIDGenerator","Field")
  Dim name : name = SkinnedInputBox("Please enter field name:","PUIDGenerator",temp,"PUIDGenerator")
  SDB.IniFile.StringValue("PUIDGenerator","Field") = name
  
  'check field name
  If name = "" Then
    Call SDB.MessageBox("PUIDGenerator: No field name was specified.",mtError,Array(mbOk))
    Exit Sub
  Else
    On Error Resume Next
    Execute("temp = list.Item(0)."&name)    
    If Err.Number <> 0 Then
      Err.Clear
      Call SDB.MessageBox("PUIDGenerator: Invalid field name was specified.",mtError,Array(mbOk))
      Exit Sub
    End If
    Execute("list.Item(0)."&name&" = """"")
    If Err.Number <> 0 Then
      Err.Clear
      Call SDB.MessageBox("PUIDGenerator: Numeric field was specified.",mtError,Array(mbOk))
      Exit Sub
    Else
      Execute("list.Item(0)."&name&" = temp")
    End If
    On Error Goto 0
  End If
  
  'check application
  Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
  If Not (fso.FileExists(SDB.ScriptsPath&"MIPT\genpuid.exe")) Then
    Call SDB.MessageBox("PUIDGenerator: File 'genpuid.exe' is missing - search failed.",mtError,Array(mbOk))
    Exit Sub
  End If
  If Not (fso.FileExists(SDB.ScriptsPath&"MIPT\mipcore.exe")) Then
    Call SDB.MessageBox("PUIDGenerator: File 'micpcore.exe' is missing - search failed.",mtError,Array(mbOk))
    Exit Sub
  End If
  If Not (fso.FileExists(SDB.ScriptsPath&"MIPT\libexpat.dll")) Then
    Call SDB.MessageBox("PUIDGenerator: File 'libexpat.dll' is missing - search will be limited.",mtInformation,Array(mbOk))
  End If      
  
  'user confirmation
  Dim str : str = "This will populate field '"&name&"' with PUID for "&list.Count&" tracks."&VbCrLf&VbCrLf
  str = str&"If no PUID is available, do you want the field to be populated with the status instead?"
  Dim k : k = SDB.MessageBox("PUIDGenerator: "&str,mtConfirmation,Array(mbYes,mbNo,mbCancel))
  Select Case k
    Case mrYes
      IncStatus = True
    Case mrNo
      IncStatus = False
    Case Else
      Exit Sub
  End Select

  'create progress bar
  Set SDB.Objects("PUID-Data") = SDB.NewSongData
  Dim prog : Set prog = SDB.Progress
  prog.Value = 0
  prog.MaxValue = list.Count
  prog.Text = "PUIDGenerator: Initialising..."
  
  'initialise  
  Dim wsh : Set wsh = CreateObject("WScript.Shell")
  Dim loc : loc = SDB.TemporaryFolder
  If Right(loc,1) = "\" Then
    loc = loc&"PUID.xml"
  Else
    loc = loc&"\PUID.xml"
  End If
  Dim tmp : Set tmp = fso.CreateTextFile(loc,True)
  Call tmp.Close()
  Dim fs2 : Set fs2 = SDB.Tools.FileSystem
  Dim exe : exe = fs2.GetShortPath(SDB.ScriptsPath&"MIPT\genpuid.exe")
  Dim dat : dat = fs2.GetShortPath(loc)
  Dim beg : beg = Timer    
  Dim num : num = 0
  
  'process tracks
  For k = 0 To list.Count-1
    str = ""
    If k > 0 And list.Count > 3 Then
      Dim dif : dif = Timer-beg
      If dif < 0 Then
        dif = dif+86400
      End If      
      Dim sec : sec = (dif*list.Count/(k+1))-dif
      If num > 0 Then
        num = ((sec*.55)+(num*.45))
      Else
        num = sec
      End If
      Dim m : m = num\60 
      Dim h : h = m\60  
      Dim s : s = num Mod 60
      m = (m Mod 60)
      If h > 0 Then
        If h > 1 Then
          str = h&" hours and "
        Else
          str = "1 hour and "
        End If
        If m = 1 Then
          str = str&"1 minute"
        Else
          str = str&m&" minutes"
        End If
      Else
        If m > 0 Then
          If m > 1 Then
            str = m&" minutes and "
          Else
            str = "1 minute and "
          End If    
        End If
        If s > 0 Then
          If s = 1 Then    
            str = str&"1 second"
          Else
            str = str&s&" seconds"
          End If
        End If
      End If 
      str = " (time remaining: "&str&")"
    End If 
    prog.Text = "PUIDGenerator: Processing track "&(k+1)&" of "&(list.Count)&str&"..."
    SDB.ProcessMessages
    
    'call application    
    If fso.FileExists(dat) Then
      fso.DeleteFile(dat)
    End If
    Dim itm : Set itm = list.Item(k)
    If fso.FileExists(itm.Path) Then
      Dim mp3 : mp3 = fs2.GetShortPath(itm.Path)
      Dim cmd : cmd = "%comspec% /c "&exe&" f25c7a6acad172541066f475175465a7"
      If Archive Then
        Dim ext : ext = UCase(Right(mp3,4))
        If (ext = ".M4A") Or (ext = ".M4B") Then
          'don't archive
        Else
          cmd = cmd&" -archive"
        End If
      End If
      cmd = cmd&" -rmd=2 """&mp3&""" >"&dat
      Call wsh.Run(cmd,0,True)
      SDB.ProcessMessages
      If fso.FileExists(dat) Then      
        Dim fil : Set fil = fso.OpenTextFile(dat,1,True)
        If Not (fil.AtEndOfStream) Then
          str = Replace(fil.ReadAll,"mip:","")
          Dim i : i = InStr(str,"file=")-1
          If i > 0 Then
            Dim j : j = InStr(Mid(str,i+7),"""")+i+8
            str = Left(str,i)&Mid(str,j)
          End If
          fil.Close()
          If Left(str,1) = "<" Then
            Set fil = fso.OpenTextFile(dat,2,True)
            fil.Write(str)
            fil.Close()
            SDB.ProcessMessages
            Dim xml : Set xml = CreateObject("Microsoft.XMLDOM")    
            xml.async = True      
            Call xml.Load(dat) 
            Dim cnt : cnt = 0
            While (xml.readyState < 4 And cnt < 300)
              Call SDB.Tools.Sleep(100)
              SDB.ProcessMessages
              cnt = cnt+1
            WEnd      
            If xml.readyState > 3 Then
              If xml.parseError.errorCode = 0 Then
                For Each tmp In xml.getElementsByTagName("track")
                  str = tmp.getAttribute("puid")               
                  If ((str = "") Or (IsNull(str))) And (IncStatus = True) Then
                    str = tmp.getAttribute("status")
                    If (str = "") Or (IsNull(str)) Then
                      str = ""
                    Else
                      str = UCase(Left(str,1))&LCase(Mid(str,2))
                    End If
                  End If
                  If (str = "") Or (IsNull(str)) Then
                    str = ""
                  Else
                    Dim val : val = ""
                    Execute("val = itm."&name)
                    If Not (val = str) Then
                      Execute("itm."&name&" = str")
                      Dim l : Set l = SDB.NewSongList
                      Call l.Add(itm)
                      Call l.UpdateAll()
                    End If
                    Exit For              
                  End If
                Next
              End If
            End If
          End If
        End If
      End If        
    End If
    prog.Increase
    SDB.ProcessMessages
    If prog.Terminate Then
      Set SDB.Objects("PUID-Data") = Nothing 
      Exit Sub
    End If
  Next
  Set SDB.Objects("PUID-Data") = Nothing     
End Sub

Function SkinnedInputBox(Text, Caption, Input, PositionName)
   Dim Form, Label, Edt, btnOk, btnCancel, modalResult 

   ' Create the window to be shown 
   Set Form = SDB.UI.NewForm 
   Form.Common.SetRect 100, 100, 360, 130 
   Form.BorderStyle  = 2   ' Resizable 
   Form.FormPosition = 4   ' Screen Center 
   Form.SavePositionName = PositionName 
   Form.Caption = Caption 
      
   ' Create a button that closes the window 
   Set Label = SDB.UI.NewLabel(Form) 
   Label.Caption = Text 
   Label.Common.Left = 5 
   Label.Common.Top = 10 
     
   Set Edt = SDB.UI.NewEdit(Form) 
   Edt.Common.Left = Label.Common.Left 
   Edt.Common.Top = Label.Common.Top + Label.Common.Height + 5 
   Edt.Common.Width = Form.Common.Width - 20 
   Edt.Common.ControlName = "Edit1" 
   Edt.Common.Anchors = 1+2+4 'Left+Top+Right 
   Edt.Text = Input 
       
   ' Create a button that closes the window 
   Set BtnOk = SDB.UI.NewButton(Form) 
   BtnOk.Caption = "&OK" 
   BtnOk.Common.Top = Edt.Common.Top + Edt.Common.Height + 10 
   BtnOk.Common.Hint = "OK" 
   BtnOk.Common.Anchors = 4   ' Right 
   BtnOk.UseScript = Script.ScriptPath 
   BtnOk.Default = True
   BtnOk.ModalResult = 1 
    
   Set BtnCancel = SDB.UI.NewButton(Form) 
   BtnCancel.Caption = "&Cancel" 
   BtnCancel.Common.Left = Form.Common.Width - BtnCancel.Common.Width - 15 
   BtnOK.Common.Left = BtnCancel.Common.Left - BtnOK.Common.Width - 10 
   BtnCancel.Common.Top = BtnOK.Common.Top 
   BtnCancel.Common.Hint = "Cancel" 
   BtnCancel.Common.Anchors = 4   ' Right 
   BtnCancel.UseScript = Script.ScriptPath 
   BtnCancel.Cancel = True
   BtnCancel.ModalResult = 2 
       
   If Form.showModal = 1 Then
     SkinnedInputBox = Edt.Text
   Else
     SkinnedInputBox = ""
   End If  
End Function

Sub Install()
  Dim inip : inip = SDB.ApplicationPath&"Scripts\Scripts.ini"
  Dim inif : Set inif = SDB.Tools.IniFileByPath(inip)
  If Not (inif Is Nothing) Then
    inif.StringValue("PUIDGenerator","Filename") = "MIPT\PUIDGenerator.vbs"
    inif.StringValue("PUIDGenerator","Procname") = "PUIDGenerator"
    inif.StringValue("PUIDGenerator","Order") = "50"
    inif.StringValue("PUIDGenerator","DisplayName") = "&PUID Generator"
    inif.StringValue("PUIDGenerator","Description") = "Generate PUID for selected tracks"
    inif.StringValue("PUIDGenerator","Language") = "VBScript"
    inif.StringValue("PUIDGenerator","ScriptType") = "0"
    SDB.RefreshScriptItems
  End If
End Sub

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Mon Jan 04, 2010 7:58 pm
by Bex
Nice one, I like it! :D

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Mon Jan 04, 2010 8:27 pm
by gpzbc
Thanks for developing this Trixmoto! It seems like it could really be handy. MusicIP is pretty cool.

Although, I'm having a hard time convincing myself that my library needs this. Can someone explain a scenario where they use PUID's and where they would be valuable?

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Mon Jan 04, 2010 8:32 pm
by nynaevelan
Thanks I am going to give this a whirl. :D

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Tue Jan 05, 2010 4:40 am
by trixmoto
In the next version of my "MusicIP Tagger" script you will be able to use existing PUID values instead of recalculating them, so separating this processing would make the tagging part much quicker. I guess any script that calls MusicBrainz or MusicIP could use this value, in fact I might add it as an external panel to "Monkey Rok" in the next version as well.

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Tue Jan 05, 2010 10:12 am
by nynaevelan
Cool, and it worked like a charm. :D

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Tue Jan 05, 2010 11:05 am
by gpzbc
sounds good! Thanks Trixmoto!

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Thu Jan 07, 2010 12:49 am
by jimmy1one
Thanks, A great script as always it's like a gift from heaven to a Blues lover
jimmy1one :wink:

OK there seems to be a problem on my end. I entered Lyricist the script returned
eae32853-09d9-5fbe-f1b1-a3b8b43c7311. This is just an example it returns a different value for each song
For example it returned 94b19084-38ba-8e15-4f82-c8155b6f198a as the lyricist for 702 Finally. I have the lyrics for the song on file but not the lyricist or composer. Am I missing the idea, lyricist is in the Songdata file as a viable field? Again thanks in advance for any help you maybe able to provide
jimmy1one

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Thu Jan 07, 2010 9:23 am
by nynaevelan
JImmy:

You are using the wrong script, this one only downloads the PUID for the track. You want to use Trixmoto's MusicIP Tagger or maybe one of the other web taggers in order to download the lyricist's info.

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Fri Jan 08, 2010 6:52 am
by jimmy1one
Thanks nynaevelan what I'm getting is the identifier. I already use the MusicIP script to get the tag info. It's just that I need more info than is available from the services it's not the flaw of the scripts. I'm just trying to find a way to finish this project in my life time :lol: Thanks again
jimmy

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Fri Jan 08, 2010 1:41 pm
by trixmoto
What other information are you after?

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Sat Jan 09, 2010 5:28 pm
by Vyper
I've been trying to understand all this PUID business and I think I do now but I do have one question. You say it asks for a field to use, does it matter? What field should I use?

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Sat Jan 09, 2010 5:31 pm
by nynaevelan
I used custom4, it was previously used, but I switched things around because I wanted a field that is selectable as a viewable column. With the help of this script and Trixmoto's MusicIP script, I was able to use Bex's Adv Dupe Find & Fix scritp to find additional dupes.

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Sat Jan 09, 2010 5:54 pm
by Vyper
Cool. Thanks Nyn. :)

Re: PUID Generator 1.0 [MM3] - Created 04/01/2010

Posted: Sun Jan 10, 2010 6:55 am
by trixmoto
The field is just the one which is used to store the value, so you can select any field which you are not already using for something else.