I completed this a while back. There are still hardcoded paths (see the last few lines of the script) so it needs work before general release but it does work.
Code: Select all
option explicit
const sMMName = "Export to Unix"
const ExportToUnixObject = "ExportToUnixObject"
const ExportToUnixForSubNodes = "ExportToUnix"
const ExportToUnixIni = "ExportToUnix"
' ===================================
Class cConvert
' pipe delimited list
private Function Surround(ByVal a)
Surround = "|" & a & "|"
End Function
' covert a tree node caption (cccc) in a tree into aaaa/bbbb/cccc
Public Function getFullMmName(ByVal tree, ByVal node, ByVal ini)
Dim n : n = node.caption
Dim p : set p = node
If ini.UseParentNames = True Then
Dim i : For i = 1 To 10
set p = tree.ParentNode(p)
If p Is Nothing Then Exit For
If p.caption = "" Then Exit For
If InStr(1, Surround(ini.ignoreParents), Surround(p.caption), 1) = 0 Then
n = p.Caption & ini.MMFolderSep & n
End If
Next
End If
getFullMmName = n
End Function
' convert aaaa/bbbb/cccc into cccc
Public Function getLastMmName(ByVal fullName, ByVal ini)
Dim parts : parts = Split(fullName, ini.MMFolderSep)
getLastMmName = parts(UBound(parts))
End Function
End Class
' ===================================
' the cglobals used by the application
Class cG
' create globals
Public ini ' As cIni
Public log ' as cLog
Public convert ' as cConvert
' create globals
Public Sub class_initialize()
set ini = New cIni
set log = New cLog
set convert = New cConvert
End Sub
End Class
Sub createGlobal()
' if g is nothing then
set g = New cG
' end if
End Sub
' ==============
class cIni
private function getValue( tagName , defaultValue )
if SDB.IniFile.valueExists(exportToUnixIni, tagName) then
getValue = SDB.IniFile.stringValue (exportToUnixIni, tagName )
else
getValue = defaultValue
end if
end function
property get MMFolderName()
MMFolderName = cstr(getValue ( "MMFolderName" , "<MM>" ))
end property
property let MMFolderName(value)
SDB.IniFile.StringValue( exportToUnixIni , "MMFolderName" ) = value
end property
property get UseParentNames()
UseParentNames = cbool(getValue ( "UseParentNames", true ))
end property
property let UseParentNames(value)
SDB.IniFile.boolValue( exportToUnixIni , "UseParentNames" ) = value
end property
property get MMFolderSep()
MMFolderSep = cstr(getValue ( "MMFolderSep" , "/" ))
end property
property let MMFolderSep(value)
SDB.IniFile.StringValue( exportToUnixIni , "MMFolderSep" ) = value
end property
property get ignoreParents()
ignoreParents = cstr(getValue ( "ignoreParents" , "Playlists|Imported m3u playlists" ))
end property
property let ignoreParents(value)
SDB.IniFile.StringValue( exportToUnixIni , "ignoreParents" ) = value
end property
property get debug()
debug = cbool(getValue ("debug",false))
end property
property let debug(value)
SDB.IniFile.boolValue( exportToUnixIni , "debug" ) = value
end property
end class
Sub OptionsDialog()
Dim oForm
Dim btnOK
Dim btnCancel
Dim iBorderWidth
Dim iBorderHeight
Set oForm = SDB.UI.NewForm
iBorderWidth = oForm.Common.Width - oForm.Common.ClientWidth
iBorderHeight = oForm.Common.Height - oForm.Common.ClientHeight
oForm.Common.SetRect 100, 100, 467 + iBorderWidth, 270 + iBorderHeight
oForm.FormPosition = 4 ' Screen Centre
oForm.BorderStyle = 3 ' bsDialog
oForm.Caption = "Export To iTunes Options"
InitSheet1 oForm
dim h : h = 210
Set btnOK = SDB.UI.NewButton(oForm)
btnOK.Caption = "&OK"
btnOK.Common.SetRect 312, h, 73, 25
btnOK.Default = True
btnOK.ModalResult = 1
Set btnCancel = SDB.UI.NewButton(oForm)
btnCancel.Caption = "&Cancel"
btnCancel.Common.SetRect 392, h, 73, 25
btnCancel.Cancel = True
btnCancel.ModalResult = 2
oForm.SavePositionName = oForm.Caption
If oForm.ShowModal = 1 Then
SaveSheet1(oForm)
End If
End Sub
Sub InitSheet1(Sheet1)
dim ini : set ini = new cIni
dim l : l = 50 ' left column
dim l2 : l2 = 160' left column
dim s : s = 25 ' line spacing
dim h : h = 20 ' height
dim w : w = 100 ' width
with SDB.UI.NewCheckBox(Sheet1)
.Caption = "Sync iPod after exporting to iTunes (default)"
.Common.SetRect l2-h,s*1,w*2,h
.Common.ControlName = "syncIpod"
.Checked = ini.syncIpod
end with
with SDB.UI.NewCheckBox(Sheet1)
.Caption = "Use MM parent playlist names in iTunes"
.Common.SetRect l2-h,s*2,w*2,h
.Common.ControlName = "useParentNames"
.Checked = ini.useParentNames
end with
with SDB.UI.NewEdit(Sheet1)
.Text = ini.mmFolderSep
.Common.SetRect l,s*3,w,h
.Common.ControlName = "MMFolderSep"
with SDB.UI.NewLabel(Sheet1)
.Common.SetRect l2, s*3 ,w,h
.Caption = "iTunes folder separator"
end with
end with
with SDB.UI.NewEdit(Sheet1)
.Text = ini.mmFolderName
.Common.SetRect l, s*4 ,w,h
.Common.ControlName = "MMFolderName"
with SDB.UI.NewLabel(Sheet1)
.Common.SetRect l2, s*4 ,w,h
.Caption = "iTunes iPod folder name"
end with
end with
with SDB.UI.NewButton(Sheet1)
.Caption = "Delete"
.Common.SetRect l+300,s*4,75,25
.Common.ControlName = "deleteMMFolder"
.onClickFunc = "deleteMMFolderOnClick"
.UseScript = Script.ScriptPath
end with
with SDB.UI.NewButton(Sheet1)
.Caption = "Create"
.Common.SetRect l+300,s*4+30,75,25
.Common.ControlName = "createMMFolder"
.onClickFunc = "createMMFolderOnClick"
.UseScript = Script.ScriptPath
end with
with SDB.UI.NewButton(Sheet1)
.Caption = "Clear sync"
.Common.SetRect l+300,s*6+30,75,25
.Common.ControlName = "clearSync"
.onClickFunc = "clearSyncDataOnClick"
.UseScript = Script.ScriptPath
end with
with SDB.UI.NewEdit(Sheet1)
.Text = ini.MMEmptyName
.Common.SetRect l,s*5,w,h
.Common.ControlName = "MMEmptyName"
with SDB.UI.NewLabel(Sheet1)
.Common.SetRect l2, s*5 ,w,h
.Caption = "iTunes empty folder name"
end with
end with
with SDB.UI.NewEdit(Sheet1)
.Text = ini.MMEmptyCount
.Common.SetRect l,s*6,w,h
.Common.ControlName = "MMEmptyCount"
with SDB.UI.NewLabel(Sheet1)
.Common.SetRect l2, s*6 ,w,h
.Caption = "iTunes empty folder count"
end with
end with
with SDB.UI.NewCheckBox(Sheet1)
.Caption = "Debug mode"
.Common.SetRect l2-h,s*7,w*2,h
.Common.ControlName = "debug"
.Checked = ini.debug
end with
with SDB.UI.NewEdit(Sheet1)
.Text = ini.ExportToItunesPlaylist
.Common.SetRect l,s*8,w,h
.Common.ControlName = "ExportToItunesPlaylist"
with SDB.UI.NewLabel(Sheet1)
.Common.SetRect l2, s*8 ,w,h
.Caption = "Sync playlist name"
end with
end with
with SDB.UI.NewCheckBox(Sheet1)
.Caption = "Sync includes playcounts"
.Common.SetRect l2-h,s*9,w*2,h
.Common.ControlName = "recoverPlaycounts"
.Checked = ini.recoverPlaycounts
end with
with SDB.UI.NewCheckBox(Sheet1)
.Caption = "Sync includes ratings"
.Common.SetRect l2-h,s*10,w*2,h
.Common.ControlName = "recoverRatings"
.Checked = ini.recoverRatings
end with
'with SDB.UI.NewCheckBox(Sheet1)
' .Caption = "Track ratings are mastered in MM"
' .Common.SetRect l2-h,s*10,w*2,h
' .Common.ControlName = "masterRatingsInMM"
' .Checked = ini.masterRatingsInMM
'end with
End Sub
Sub SaveSheet1(Sheet1)
dim ini : set ini = new cIni
ini.mmFolderName = Sheet1.Common.ChildControl("MMFolderName").Text
ini.mmFolderSep = Sheet1.Common.ChildControl("MMFolderSep").Text
ini.mmEmptyName = Sheet1.Common.ChildControl("MMEmptyName").Text
ini.MMEmptyCount = cint(Sheet1.Common.ChildControl("MMEmptyCount").Text)
ini.useParentNames = sheet1.common.ChildControl("useParentNames").Checked
ini.syncIpod = sheet1.common.ChildControl("syncIpod").Checked
ini.debug = sheet1.common.ChildControl("debug").Checked
ini.ExportToItunesPlaylist = Sheet1.Common.ChildControl("ExportToItunesPlaylist").Text
ini.recoverPlaycounts = sheet1.common.ChildControl("recoverPlaycounts").Checked
'ini.masterRatingsInMM = sheet1.common.ChildControl("masterRatingsInMM").Checked
ini.recoverRatings = sheet1.common.ChildControl("recoverRatings").Checked
if ini.recoverPlaycounts then
ini.recoverPlaycountsWarning = false
end if
if ini.recoverRatings then
ini.masterRatingsWarning = false
end if
End Sub
sub createMMFolderOnClick(o)
createGlobal
dim p : set p = new cProgress
g.iTunes.connect p
g.itunes.createMMFolder p
p.terminate
end sub
sub deleteMMFolderOnClick(o)
createGlobal
dim p : set p = new cProgress
g.iTunes.connect p
dim f : Set f = g.iTunes.playlistsByName(g.ini.MMFolderName)
if not( f is nothing ) then
f.delete
' set g.list.firstItem = nothing
end if
p.terminate
end sub
sub clearSyncDataOnClick(o)
if false then
dim a : a="1"
select case a
case "1"
SDB.Messagebox "1" , mtWarning , array(mbOK)
case "2"
SDB.Messagebox "2" , mtWarning , array(mbOK)
end select
else
createGlobal
dim p : set p = new cProgress
g.itunes.clearSyncData g.ini.ExportToItunesPlaylist, p
p.terminate
end if
end sub
class cProgress
private mProgress ' as sdbprogress
private text ' as string
Private Sub Class_Initialize()
set mprogress = SDB.Progress
text=""
end sub
public sub init( Title , MaxValue )
' take a copy
text = Title
g.log.message text & cstr(MaxValue)
if MaxValue = 0 then
mProgress.Text = SDB.Localize(text)
else
mProgress.Text = SDB.Localize(text & " (" & cstr(MaxValue) & ")" )
end if
mProgress.MaxValue = MaxValue
mProgress.value = 0
SDB.ProcessMessages
end sub
public function terminated( )
terminated = mprogress.Terminate
end function
public function count( )
mprogress.increase
SDB.ProcessMessages
if mprogress.MaxValue = 0 then
mProgress.Text = SDB.Localize(text)
else
mProgress.Text = SDB.Localize(text & " (" & cstr(mProgress.value) & "/" & cstr(mProgress.MaxValue) & ")" )
end if
count = terminated()
end function
public function process( )
SDB.ProcessMessages
end function
public sub terminate
set mProgress = nothing
end sub
end class
function newLabel( form , left , top , caption )
Dim Label1 : Set Label1 = SDB.UI.NewLabel(Form)
Label1.Caption = caption
Label1.Common.Left = left
Label1.Common.Top = top
set newLabel = Label1
end function
function newSpinEdit( form , left , top , width , height , name )
Dim e : Set e = SDB.UI.NewSpinEdit(form)
e.Common.Left = left
e.Common.Top = top
e.Common.Width = width
e.Common.Height = height
e.Common.ControlName = name
set newSpinEdit = e
end function
function newEdit( form , left , top , width , name , text )
Dim e : Set e = SDB.UI.NewEdit(form)
e.Common.Left = left
e.Common.Top = top
e.Common.Width = width
e.Common.ControlName = name
e.Text = text
set newEdit = e
end function
function newButton( form , left , top , width , height , caption , OnClickFunc )
Dim Browse : Set Browse = SDB.UI.NewButton(Form)
Browse.Caption = caption
Browse.Common.Height = height
Browse.Common.Width = width
Browse.Common.Top = top
Browse.Common.Left = left
Browse.UseScript = Script.ScriptPath
Browse.OnClickFunc = OnClickFunc
set newButton = Browse
end function
function newCheckbox( form , left , top , width , caption , checked )
Dim Edt26 : Set Edt26 = SDB.UI.NewCheckbox(form)
Edt26.Caption = caption
Edt26.Common.Left = left
Edt26.Common.Top = top
Edt26.Common.Width = width
Edt26.Checked = checked
set newCheckBox = Edt26
end function
function newCombobox( form , left , top , width , name , list )
Set Edt27 = SDB.UI.NewDropDown(form)
Edt27.Common.Left = left
Edt27.Common.Top = top
Edt27.Common.Width = width
Edt27.Common.ControlName = name
Edt27.Style = 2
dim listArr : listArr = split( list , "|")
dim i : For each i in listArr
Edt27.AddItem i
Next
set newCombobox = Edt27
end function
function newPanel( form , left , top , width , height )
Dim panel : Set panel = SDB.UI.newTranspPanel(form)
panel.Common.SetRect left , top , width , height
set newPanel = panel
end function
function newForm( left , top , width , height , caption )
Dim Form : Set Form = SDB.UI.NewForm
Form.Common.SetRect left , top , width , height
Form.BorderStyle = 2
Form.FormPosition = 4
Form.Caption = caption
set newForm = Form
end function
' generic logging
Class cLog
public sub message(m) 'as string
if g.ini.debug = true then
SDB.Messagebox m , mtWarning , array(mbOK)
SDB.Tools.OutputDebugString m
end if
end sub
End Class
' ==============
'globals
Dim g ' As cG
Sub OnStartUp()
If SDB.Objects(ExportToUnixObject) Is Nothing Then
SDB.Objects(ExportToUnixObject) = CreateObject("Scripting.Dictionary")
With SDB.Objects(ExportToUnixObject)
Call .Add("OptionSheet", SDB.UI.AddOptionSheet("Export To Unix", Script.ScriptPath, "InitSheet1", "SaveSheet1", 0))
'SDB.Messagebox "Init Sheet added" , mtWarning , array(mbOK)
End With
End If
' empty the global memory
set g = nothing
End Sub
sub PerformTasksOnShutdown()
set g = nothing
End sub
' read the SDB treelist building a list of children playlists
sub getSDBPlaylists( tree , node , prependParents , progress , shellpath , createroot )
dim fout
fout = fout & "#start " & now & chr(10)
fout = fout & "echo Remove old folder contents at" & createroot & chr(10)
fout = fout & "rm -rf """ & createroot & """" & chr(10)
fout = fout & "echo Create new folder contents at" & createroot & chr(10)
fout = fout & "mkdir -p """ & createroot & """" & chr(10)
fout = fout & "cd """ & createroot & """" & chr(10)
getSDBPlaylistsR tree , node , prependParents, fout ,progress
fout = fout & "#end " & now & chr(10)
fout = fout & "#"
fout = fout & "#"
fout = fout & "#"
' write to file
dim fso : Set fso = SDB.Tools.FileSystem
dim f : Set f = fso.CreateTextFile( shellpath , True)
f.WriteLine fout
f.Close
end sub
sub getSDBPlaylistsR( tree , node , prependParents , fout , p)
' make sure that we see the children
node.expanded = true
if not p.terminated then
' do we contain child playlists
if node.HasChildren then
dim c : c = node.caption
dim cq : cq = """" & c & """"
fout = fout & "echo Start " & cq & chr(10)
fout = fout & "mkdir """ & c & """" & chr(10)
fout = fout & "cd """ & c & """" & chr(10)
' recurse through the children
dim n : set n = tree.FirstChildNode(node)
do while not ( n is nothing )
getSDBPlaylistsR tree , n , prependParents , fout , p
set n = tree.nextsiblingnode(n)
loop
fout = fout & "echo End " & cq & chr(10)
fout = fout & "cd .." & chr(10)
else
dim fullName : fullName = g.convert.getFullMmName( tree , node , g.ini )
export node , fullname , fout , p
end if
end if
end sub
sub export( node , fullname , fout , p )
dim pl : set pl = SDB.PlaylistByTitle( node.caption )
dim tracks
Set tracks = pl.Tracks
p.Init node.caption , tracks.count
if tracks.count>0 then
dim c : c = node.caption
dim cq : cq = """" & c & """"
fout = fout & "echo Export " & cq & chr(10)
fout = fout & "mkdir " & cq & chr(10)
fout = fout & "cd " & cq & chr(10)
dim max : max = pl.tracks.count
if max > 100 then max = 100
dim i : for i = 0 to max - 1
dim path : path = tracks.Item(i).Path
' replace some dangerous characters
path = replace( path , "/" , "-" )
path = replace( path , "?" , "" )
path = replace( path , "'" , "" )
path = replace( path , "`" , "" )
path = replace( path , """" , "" )
path = replace( path , "(" , "" )
path = replace( path , ")" , "" )
' make into a Unix path
path = replace( path , "\" , "/" )
path = replace( path , "K:" , "/k" )
dim file : file = right( "000"&(i+1) , 3 ) & " " & filename(path)
' and create the link
fout = fout & "ln -s """ & path & """ """ & File & """" & chr(10)
if p.Count() then exit For
Next
fout = fout & "cd .." & chr(10)
End If
end sub
function filename( fullname )
Dim parts : parts = Split(fullName, "/")
filename = parts(UBound(parts))
end function
sub main ( )
If SDB.MainTree.CurrentNode Is Nothing Then Exit Sub
' create globals
createGlobal
dim p : set p = New cProgress
' add/merge the SDB ones
getSDBPlaylists SDB.MainTree , SDB.MainTree.CurrentNode , g.ini.useParentNames , p , "K:\Dad\Music\Playlists-Subsonic-Create.sh" , "/k/Dad/Music/Playlists-Subsonic"
end sub
' routine for launching the script via the scripts menu
sub ExportToUnix
main
end sub