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