This is a script that I have been working on to help synchronize movie libraries, and assist with ripping new titles. I should mention right up front that I use XBMC, I have each movie in it's own folder, the folder name is the movie name, and each movie file contains the .nfo file for that movie. If your setup is different, mileage may vary.
Thanks to Lexikos, Sean, and Skan for the functions that each wrote that are contained in my script.
Sync Tab:
To synchronize files, you will need to have the Sync Media Files folder on both computers. From the first computer, enter your name and paths, and select 'Create List' and 'Have List' from the GUI. Click 'Create List'. Copy the file that you just created from Lists\Have\yourname.txt and put it in the Lists\Have folder on the second computer. Run the program, and set up a new user name, with the path to the movie files on that computer.
If you want to copy all files from computer2 that are not on computer1, Select 'Copy Files' and 'Have List'. Select the user name from the 'Copy Files For' drop down list that matches the have list that you created earlier. Any files that are not on the list will be copied your selected output folder.
If you already have a 'Have List' from computer2, you can create a 'Wish List' of files that you want to copy. When you copy from a wish list, only the files that are on the list are copied.
Creating a wish list:
When you create a wish list, a tree view is used to show files that are available from a 'Have List' that are not in your current library.
Click on the button 'Add From Series', and movies that you are missing from the Series Tab (See below) will be selected for you.
If I select 'Danny Glover' from the actors that are shown in the tree view:
all Danny Glover movies will be selected:
Series Tab:
The series tab will show you which movies that you are missing from a series. The check marks indicate which movies that I do have. If you have all movies in a series, they will not be shown in the tree view.
Rip Tab:
This is just to assist you in naming the movie that you are ripping correctly according to IMDB.
I typed 'american pie' in the box, and suggestions are made in the list view. The items with a '*' indicate movies that I already have in my library. Left click on a title to view an image, and right click to copy the title to the clipboard.
The 'Copy Options' behavior:
The path to your friends files is D:\Mike\Movies\
The path to which you want to save the files F:\Backup
If you select 'Use full path' the files will be saved in F:\Backup\D\Mike\Movies\
If you select 'Use partial path' the files will be saved in F:\Backup\Movies\
If you select 'Use one folder' the files will be saved in F:\Backup\[/img]
'DownLoad Sync Media Files.7z'
Code:
#NoEnv
#SingleInstance Force ;Off
SetWorkingDir, %A_ScriptDir%
OnExit, GuiClose
ScriptName := "Sync Media Files"
ScriptIni := "Sync Media Files.ini"
Null := ""
FileRead, TempVar, %ScriptIni%
Loop, Parse, TempVar, `r, `n
{
IfInString, A_LoopField, =
{
StringSplit, TempVar, A_LoopField, =
ComboText1 .= ComboText1 = "" ? TempVar1 "|" : "|" TempVar1
}
}
Gui, Add, Tab2,w570 h350 VCurrentTab gChangeTab, Sync|Series|Rip|
Gui, Tab, 1
Gui, Add, Text, Section x20 y45 vText1, Select or Type Your User Name
Gui, Add, ComboBox, x+6 yp-3 w150 Sort vUserName1 gSwitchUser, %ComboText1%|
Gui, Add, GroupBox, Section x15 y+10 w558 h160, Set Your Path(s)
Gui, Add, ListView, xs+20 ys+30 w434 r6 -Hdr vPathLV, Unused
Gui, Add, Button, x484 yp+3 w70 gAddPath, Add New
Gui, Add, Button, xp y+15 w70 gDeletePath, Delete
Gui, Add, Button, xp y+15 w70 gDeleteAll, Delete All
Gui, Add, GroupBox, Section x15 ys+170 w105 h75, Program Options
Gui, Add, Radio, xs+20 ys+30 vProgOption1 checked gGuiOptions, Copy Files
Gui, Add, Radio, xp yp+20 vProgOption2 gGuiOptions , Create List
Gui, Add, Text, xs y+20 vText2, Copy Files For
Gui, Add, Text, xp yp vText3, Create List From
Gui, Add, ComboBox, x+6 yp-3 w138 Sort vUserName2, %ComboText2%
Gui, Add, GroupBox, Section xs+120 ys w100 h75 vListGroup, List Options
Gui, Add, Radio, xs+20 ys+30 vListOption1 gGuiOptions, Wish List
Gui, Add, Radio, xp yp+20 vListOption2 checked gGuiOptions, Have List
Gui, Add, GroupBox, Section xs+115 ys w130 h100 vCopyGroup, Path Options
Gui, Add, Radio, xs+20 ys+30 vPathOption1, Use Full Path
Gui, Add, Radio, xp yp+20 vPathOption2 checked, Use Partial Path
Gui, Add, Radio, xp yp+20 vPathOption3, Use One Folder
Gui, Add, Button, xs+150 ys+40 w70 h30 vListButton gCreateList, Create List
Gui, Add, Button, xp yp w70 h30 vCopyButton gCopyFiles, Copy Files
Gui, Add, Button, x+15 yp w70 h30, Exit
Gui, Add, Button, w0 h0 Default vNull, Enter
Gui, Add, StatusBar
GuiControl, Hide, ListButton
GuiControl, Hide, Text3
Gui, Tab, 2
Gui, Add, TreeView, x20 y45 w350 r18 AltSubmit vSeriesTV Checked
Gui, Add, Text, x380 y80, (A) – Film series is 100`% animated
Gui, Add, Text, x380 y+10,(a) – Film series is not 100`% animated and`n has live action in a sequel or prequel
Gui, Add, Text, x380 y+10,(TV) – made-for-TV
Gui, Add, Text, x380 y+10,(V) – direct-to-video
Gui, Add, Text, x380 y+10, (*) – TV series attached
Gui, Tab, 3
Gui, Add, Text, x20 y45, Source
Gui, Add, DropDownList, Section xp y+5 W300 vDriveDDL gDriveDDL
Gui, Add, Text, xp y+10, Movie Title
Gui, Add, Edit, xp y+5 w300 vCurrentTitle gTitleTimer
Gui, Add, ListView, xp y+10 r8 w300 +altsubmit vTitleListLV gTitleListLV, Title Suggestions
Gui, Add, Picture, xp+355 ys+2 w160 h240 vImage, Images\wizard.ico
SB_SetText(" Ready.")
Gui, Show, Hide
Gosub, SwitchUser
Gui, 2:Default
Gui, +Owner1
Gui, Add, TreeView, x20 y20 w350 r20 AltSubmit vWishListTV gWishListTV Checked
Gui, Add, Button, y+10 x20 w70 h30, Save
Gui, Add, Button, Yp x+10 w70 h30, Cancel
Gui, Add, Button, Yp x+100 w100 h30 g2AddFromSeries, Add From Series
Gui, 1:Default
Gui, Show, w590 h390, %ScriptName%
Return
;************************************ End AutoExecute Section **************************************
^R::Reload
^Q::ExitApp
ButtonExit:
GuiClose:
WriteIni()
ExitApp
;***************************************************************************************************
;********************************************** Tab1 ***********************************************
;***************************************************************************************************
GuiOptions:
Gui, Submit, NoHide
If ProgOption1 = 1
{
GuiControl, Hide, ListButton
GuiControl, Enable, CopyGroup
GuiControl, Enable, PathOption1
GuiControl, Enable, PathOption2
GuiControl, Enable, PathOption3
GuiControl, Show, CopyButton
GuiControl, Show, UserName2
GuiControl, Show, Text2
GuiControl, Hide, Text3
}
Else
{
GuiControl, Disable, CopyGroup
GuiControl, Disable, PathOption1
GuiControl, Disable, PathOption2
GuiControl, Disable, PathOption3
GuiControl, Hide, CopyButton
GuiControl, Show, ListButton
If ListOption1 = 1
{
GuiControl, Show, UserName2
GuiControl, Hide, Text2
GuiControl, Show, Text3
}
Else
{
GuiControl, Hide, UserName2
GuiControl, Hide, Text2
GuiControl, Hide, Text3
}
}
Gosub, SetUser2
Return
SwitchUser:
Gui, Submit, NoHide
Gui, 1:ListView, PathLV
IniRead, TempVar, %ScriptIni%, Paths, %UserName1%
LV_Delete()
If TempVar <> Error
{
Loop, Parse, TempVar, |
If A_LoopField <>
LV_Add("", A_LoopField)
}
Gosub, SetUser2
ResetFileList = 1
ResetTreeView = 1
Return
SetUser2:
If (ProgOption2 = 1) AND (ListOption2 = 1)
Return
ComboText2 =
ListType := "Wish"
If ((ProgOption1 = 1) AND (ListOption2 = 1)) OR ((ProgOption2 = 1) AND (ListOption1 = 1))
ListType := "Have"
Loop, Lists\%ListType%\*.txt
{
StringTrimRight, UserName2, A_LoopFileName, 4
If (UserName1 <> UserName2)
ComboText2 .= ComboText2 = "" ? UserName2 "|" : "|" UserName2
}
If ComboText2 <>
{
IfNotInString, ComboText2, ||
ComboText2 .= "|"
}
GuiControl,, UserName2, |%ComboText2%
Return
ButtonEnter:
SB_SetText("")
GuiControlGet, TempVar, Focus
If TempVar = Edit1
{
GuiControlGet, UserName1
If UserName1 <>
{
StringReplace, ComboText1, ComboText1, ||, |, All
ComboText1 = |%ComboText1%|%UserName1%
Sort, ComboText1, U D|
StringReplace, ComboText1, ComboText1, |%UserName1%, |%UserName1%||
StringReplace, ComboText1, ComboText1, |||, ||
GuiControl,,UserName1, %ComboText1%
StringTrimLeft, ComboText1, ComboText1, 1
GuiControl, Focus, Null
Gosub, AddPath
WriteIni()
GoSub, SwitchUser
}
}
Return
#IfWinActive Sync Media Files
Del::
GuiControlGet, TempVar, Focus
If TempVar = Edit1
{
GuiControlGet, UserName1
MsgBox, 0x31, %ScriptName%, Delete all settings for %UserName1%?
IfMsgBox, Cancel
Return
StringReplace, ComboText1, ComboText1, ||, |, A
ComboText1 = |%ComboText1%|
StringReplace, ComboText1, ComboText1, |%UserName1%|, |
StringTrimLeft, ComboText1, ComboText1, 1
If (SubStr( ComboText1, 0) = "|")
StringTrimRight, ComboText1, ComboText1, 1
StringReplace, ComboText1, ComboText1, |, ||
GuiControl,, UserName1, |%ComboText1%
IniDelete, %ScriptIni%, Paths, %UserName1%
GoSub, SwitchUser
}
Return
#IfWinActive
ChangeTab:
GuiControlGet, CurrentTab
If CurrentTab = Series
{
GetExistingFileList()
Gosub, ViewSeries
}
If CurrentTab = Rip
{
;FileSelectFile, HaveListPath, 1, Lists\Have\%UserName1%.txt, Open a have list from which to work., *.txt
FileRead, HaveList, Lists\Have\%UserName1%.txt
CleanHaveList := CleanNames(HaveList)
Gosub, CheckDrive
SetTimer, CheckDrive, 5000
SetTimer, TooltipOff, 10000
}
Else
{
SetTimer, GetTitles, Off
SetTimer, CheckDrive, Off
SetTimer, TooltipOff, Off
}
Return
;***************************************** Paths ListView ******************************************
AddPath:
Gui, 1:ListView, PathLV
Gui +OwnDialogs
FileSelectFolder, NewFolder, *%NewFolder%,, Select the root folder that contains your movies.
If (ErrorLevel = 0) And (NewFolder <> "")
{
Loop, % LV_GetCount()
{
LV_GetText(Path, A_Index, 1)
If (NewFolder = Path)
{
SoundPlay *64
MsgBox, Path already exists.
Return
}
}
}
LV_ADD("", NewFolder)
WriteIni()
ResetFileList = 1
Return
DeletePath:
Gui, 1:ListView, PathLV
Loop
{
ToDelete := LV_GetNext(0)
If Not ToDelete
Break
LV_Delete(ToDelete)
}
WriteIni()
ResetFileList = 1
Return
DeleteAll:
Gui, 1:ListView, PathLV
LV_Delete()
WriteIni()
ResetFileList = 1
Return
;****************************************** Create Lists *******************************************
CreateList:
SB_SetText("")
WriteIni()
Gui,Submit, NoHide
If ListOption2 = 1
{
IfExist, Lists\Have\%UserName1%.txt
MsgBox, 0x2031, %A_ScriptName%, Existing list for %UserName1% will be over written.
IfMsgBox, Cancel
Return
FileDelete, Lists\Have\%UserName1%.txt
GetExistingFileList()
FileAppend, %ExistingFiles%, Lists\Have\%UserName1%.txt
SB_SetText(" Have list for " UserName1 " has been saved.")
TempVar=
ExistingFiles=
DuplicateList=
}
Else ;Wish List
{
TempVar =
IfNotExist, Lists\Have\%UserName2%.txt
{
MsgBox, 0x2031, %A_ScriptName%, There is no Have list for %UserName2% from which to work.
Return
}
GetExistingFileList()
FileRead, AvailableList, Lists\Have\%UserName2%.txt
Gui, 2:Default
TV_Delete()
Loop, Parse, AvailableList, `r, `n
{
If (A_LoopField <> "")
{
IfNotInString, CleanExistingFiles, % CleanNames(A_LoopField)
{
Parent := TV_Add(A_LoopField, "", "Sort")
IfExist, NFO\%A_LoopField%.nfo
{
FileRead, Data, NFO\%A_LoopField%.nfo
ActorList := GetMatch("<actor>", "<name>", "(.+?)", "</name>", "</movie>")
Loop, Parse, ActorList, `r, `n
TV_Add(A_LoopField, Parent)
}
}
}
}
FileList =
Gui, 2:Show, x100 y223, Create Wish List
}
SB_SetText(" Ready.")
Return
WishListTV:
If A_GuiEvent = Normal
{
Parent := TV_GetParent(A_EventInfo)
Action := "-Checked"
If TV_Get(A_EventInfo, "Checked") = 0 ;Not Checked
Action := "Checked" ;Check it
If (Parent = 0)
{
If (Action = "-Checked")
UserSelectedParents .= If UserSelectedParents = "" ? A_EventInfo : "," A_EventInfo
Else
{
StringReplace, UserSelectedParents, UserSelectedParents, %A_EventInfo%
If SubStr( UserSelectedParents, 0) = ","
StringTrimRight, UserSelectedParents, UserSelectedParents, 1
}
}
Else ; User (Un)checked a child
{
TV_GetText(CurrentActor, A_EventInfo)
ItemID = 0
Loop
{
ItemID := TV_GetNext(ItemID, "Full")
If ItemID = 0
Break
ParentID := TV_GetParent(ItemID)
IF ParentID <> 0 ;Child
{
TV_GetText(Actor, ItemID)
If (Actor = CurrentActor)
{
TV_Modify(ItemID, Action)
If (Action = "Checked")
{
If ParentID Not In %UserSelectedParents% ;Need to see if ANY children are checked, not just this one
{
ChildID := ParentID
Loop
{
Index := A_Index
ChildID := TV_GetNext(ChildID, "Checked")
If TV_GetParent(ChildID) = 0
Break
}
If Index = 1
TV_Modify(ParentID, "-Check")
}
}
Else TV_Modify(ParentID, "Check")
}
}
}
}
}
Return
;****************************************** Gui 2 Labels *******************************************
2ButtonCancel:
2GuiClose:
UserSelectedParents =
Gui, 2:Hide
Gui, 1:Default
Return
2AddFromSeries:
Gosub, ViewSeries
Gui, 2:Default
ItemID = 0
Loop
{
ItemID := TV_GetNext(ItemID, "Full")
If ItemID = 0
Break
TV_GetText(Title, ItemID)
If Title In %MissingSeries%
{
TV_Modify(ItemID, "Check")
UserSelectedParents .= If UserSelectedParents = "" ? Title : "," Title
}
}
Return
2ButtonSave:
Gui, 2:Default
FileNames =
IfExist, Lists\Wish\%UserName1%.txt
{
MsgBox, 0x2024, %A_ScriptName%, Select 'Yes' to append to existing file. 'No' to overwrite
IfMsgBox, Yes
FileRead, FileNames, Lists\Wish\%UserName1%.txt
FileDelete, Lists\Wish\%UserName1%.txt
}
ItemID = 0
Loop
{
ItemID := TV_GetNext(ItemID, "Checked")
If ItemID = 0
Break
ParentID := TV_GetParent(ItemID)
IF ParentID = 0
{
TV_GetText(Text, ItemID)
FileNames .= Text . "`r`n"
}
}
Sort, FileNames, U
FileAppend, %FileNames%, Lists\Wish\%UserName1%.txt
FileNames=
Gui, 2:Hide
Gui, 1:Default
SB_SetText(" Wish list for " UserName1 " has been saved.")
SoundPlay *64
Return
;****************************************** Copy Files *********************************************
CopyFiles:
Gui, 1:ListView, PathLV
If LV_GetCount() = 0
{
MsgBox, 0x2031, %A_ScriptName%, You must enter the paths to your files.
Return
}
Gui, Submit, NoHide
WriteIni()
ListType := ListOption1 = 1 ? "Wish" : "Have"
IfNotExist, Lists\%ListType%\%UserName2%.txt
{
MsgBox, 0x2031, %A_ScriptName%, There is no %ListType% list for %UserName2%.
Return
}
FileSelectFolder, SaveFolder, *Copy Test,,Select folder to which files will be copied
If (ErrorLevel = 1) OR (SaveFolder = "")
Return
FileRead, FileList, Lists\%ListType%\%UserName2%.txt
Source =
Target =
NumFiles =
Loop, % LV_GetCount()
{
LV_GetText(Path, A_Index, 1)
Loop, %Path%\*, 2
{
CopyIt =
IfInString, FileList, %A_LoopFileName%
{
If ListOption1 = 1
{
CopyIt = 1
}
}
Else
{
If ListOption2 = 1
{
CopyIt = 1
}
}
If CopyIt = 1
{
NumFiles++
If PathOption1 = 1
{
StringReplace, CopyPath, A_LoopFileFullPath, :
CopyPath := SaveFolder "\" CopyPath
}
Else If PathOption2 = 1
{
StringSplit, TempVar, A_LoopFileFullPath, \, :
If TempVar0 > 1
TempVar0--
CopyPath := SaveFolder "\" TempVar%TempVar0% "\" A_LoopFileName
}
Else CopyPath := SaveFolder "\" A_LoopFileName
Target .= CopyPath "|"
Source .= A_LoopFileFullPath "|"
}
}
}
Text := Numfiles > 1 ? " Folders" : " Folder"
SB_SetText(" Copying " NumFiles Text)
flags := ( FOF_RENAMEONCOLLISION := 0x8 ) | ( FOF_NOCONFIRMMKDIR := 0x200 ) | ( FOF_MULTIDESTFILES := 0x1 )
ShellFileOperation( 0x2, Source, Target, flags )
FileDelete, Lists\%ListType%\%UserName2%.txt
Loop, Parse, Target, |
{
IfExist, %A_LoopField%
SplitPath, A_LoopField, OutFile
{
If ListOption1 = 1
StringReplace, FileList, FileList, %OutFile%`r`n
Else FileList .= OutFile "`r`n"
}
}
If FileList <>
FileAppend, %FileList%, Lists\%ListType%\%UserName2%.txt
SoundPlay *64
SB_SetText(" Ready")
FileList=
Return
;***************************************************************************************************
;********************************************** Tab2 ***********************************************
;***************************************************************************************************
ViewSeries:
If (ResetTreeView <> 1)
Return
ResetTreeview =
FileRead, HaveList, Lists\Have\%UserName1%.txt
If (HaveList = "") AND (ErrorLevel = 1)
{
MsgBox, There is no Have List for %UserName1%
Return
}
SplashTextOn, , , Checking Series Information...
Gui, Submit, NoHide
Gui, 1:Default
TV_Delete()
MissingSeries =
CleanHaveList := CleanNames(HaveList)
GuiControl, -Redraw, SeriesTV
Loop, Movie Series HTML\*.txt
{
SB_SetText(" Getting data from " . A_LoopFileName)
FileRead, Data, %A_LoopFileLongPath%
Data := RegExReplace(Data, "<dd>.+?</dd>")
Pos := RegexMatch(Data, "<table style","",1)
EndPos := RegExMatch(Data, "</table>","",Pos)
;<li><i>The Wizard of Oz</i> (1914 series)
;<li><i><a href="/wiki/Crime_Doctor_(character)" title="Crime Doctor (character)">Crime Doctor</a></i>
;<li><i>Bill & Ted</i> <a href="/wiki/Bill_%26_Ted%27s_Excellent_Adventures_(disambiguation)"
; title="Bill & Ted's Excellent Adventures (disambiguation)" class="mw-redirect">*</a>*
;<li><i><a href="/wiki/Lewis_Carroll" title="Lewis Carroll">Lewis Carroll</a>'s Alice</i>
;<li><i>101 Dalmatians</i> (1961 series) (A) <a href="/wiki/101_Dalmatians:_The_Series" title="101 Dalmatians: The Series">*</a>
;<li><i>Casper</i> (<a href="/wiki/Hanna-Barbera" title="Hanna-Barbera">Hanna-Barbera</a> series) (A) <a href="/wiki/Casper_and_the_Angels"
; title="Casper and the Angels">*</a>
;<li><i>Casper</i> <a href="/wiki/The_Spooktacular_New_Adventures_of_Casper" title="The Spooktacular New Adventures of Casper">*</a> (live action-series)
;<li><i>Hulk</i> (<a href="/w/index.php?title=Marvel_Animated_Universe&action=edit&redlink=1" class="new"
; title="Marvel Animated Universe (page does not exist)">Marvel Animated Universe</a>) (A)
;<li><a href="/wiki/Alien_(franchise)" title="Alien (franchise)"><i>Alien</i></a>
Loop
{
Pos := RegExMatch( Data, "<li>(<i>)?(.+?)<ol>", Parent, Pos)
If (Pos = 0) OR (Pos > EndPos)
Break
Parent1 := Parent2
Pos += StrLen(Parent1)
IfInString, Parent1, <a href
{
If (SubStr(Parent1, 1, 7) = "<a href")
{
TempPos := RegExMatch( Parent1, "title=""(.*)", Parent)
Parent1 := UnHTM(Parent1)
StringSplit, Parent, Parent1, >
If (Parent2 <> "*")
Parent1 := Parent2
}
Else
{
Parent1 := RegExReplace(Parent1, "<a href.+?"">")
Parent1 := UnHTM(Parent1)
}
}
Else
Parent1 := UnHTM(Parent1)
StringReplace, Parent, Parent1, **, *, A
Parent := UTF82Ansi(Parent)
Parent2 := Parent
Parent := RegExReplace( Parent, "\[.+?]")
If Parent =
Parent := Parent2
Children =
TitleEndPos := RegexMatch(Data, "</ol>","", Pos)
Loop
{
Pos++
Pos := RegExMatch( Data, "<li><i>(.+?)</li>", Child, Pos)
If Pos = 0
Break
If (Pos > TitleEndPos)
{
Pos := TitleEndPos
Break
}
IfInString, Child1, <a href
TempPos := RegExMatch( Child1, "title=.+?"">(.*)", Child,1)
Child := UnHTM(Child1)
Child := UTF82Ansi(Child)
Children .= Children = "" ? Child : "`r`n" Child
}
Loop, Parse, Children, `r, `n ; If all children exist do not add to list.
{
IfInString, CleanHaveList, % CleanNames(A_LoopField)
{
Parent := TV_Add(Parent,"", "Sort")
Index = 0
Loop, Parse, Children, `r, `n
{
Index++
IfInString, CleanHaveList, % CleanNames(A_LoopField)
{
TV_Add(A_LoopField, Parent, "Check")
Index--
}
Else
{
TV_Add(A_LoopField, Parent)
MissingSeries .= MissingSeries = "" ? A_LoopField : "," A_LoopField
}
}
If Index = 0
TV_Delete(Parent)
Break
}
}
}
}
GuiControl, +Redraw, SeriesTV
SplashTextOff
SB_SetText(" Ready.")
Return
;***************************************************************************************************
;********************************************** Tab3 ***********************************************
;***************************************************************************************************
TooltipOff:
Tooltip
Return
CheckDrive:
DriveList =
DriveGet, DriveLetter, List, CDROM
Loop, Parse, DriveLetter
{
Title =
DriveGet, stat, status, %A_LoopField%:\
DriveGet, cap, capacity, %A_LoopField%:\
If (stat = "Ready" && cap > 1000)
{
DriveGet, Title, Label, %A_LoopField%:\
StringReplace, Title, Title , _, %A_Space%, All
}
DriveList .= A_LoopField ":\" Title "|"
}
StringReplace, DriveList, DriveList, |, ||
If (DriveList <> PrevDriveList)
{
PrevDriveList := DriveList
GuiControl,, DriveDDL, |%DriveList%
GoSub, DriveDDL
}
Return
DriveDDL:
GuiControlGet, Title,, DriveDDL
StringTrimLeft, Title, Title, 3
StringUpper, Title, Title, T
GuiControl,, CurrentTitle, %Title%
If Title =
{
Gui, 1:ListView, TitleListLV
LV_Delete()
GuiControl,, Image, Images\wizard.ico
}
Return
TitleTimer:
SetTimer, GetTitles, 1000
Return
GetTitles:
Gui, 1:ListView, TitleListLV
SetTimer, GetTitles, Off
GuiControlGet, Title,, CurrentTitle
If Title <>
{
SB_SetText(" Searchin IMDb for matching titles.")
StringReplace, SearchName, Title , %A_Space%, +, All
URLDownloadToFile, https://www.google.com/search?q=site:http://www.imdb.com/ %SearchName%, MovieRipper.tmp
FileRead, Data, MovieRipper.tmp
MovieList := GetMatch("""></span>", "title/tt\d{7}/'\)"">", "(.+?)", "</a>", "</html>")
LV_Delete()
If MovieList =
GuiControl,, Image, Images\No Image.png
Else
{
Loop, Parse, MovieList, `r, `n
{
StringReplace, LoopField, A_LoopField, Imdb -
StringReplace, LoopField, LoopField, - Imdb
LoopField = %LoopField%
IfInString, CleanHaveList, % CleanNames(LoopField)
LoopField = * %LoopField%
LV_Add("", LoopField)
}
}
}
Else
{
LV_Delete()
GuiControl,, Image, Images\wizard.ico
}
SB_SetText(" Ready.")
Return
TitleListLV:
Gui, 1:ListView, TitleListLV
If A_GuiEvent = Normal
{
SB_SetText(" Attempting to download image.")
LV_GetText(Movie, A_EventInfo, 1)
URLDownloadToFile,http://www.imdbapi.com/?t=%movie%&r=JSON&plot=full, %A_Temp%\MovieRipper.tmp
PosterPath = Images\No Image.png
If ErrorLevel = 1
PosterPath = Images\404.png
Else
{
FileRead, Data, %A_Temp%\MovieRipper.tmp
Pos := RegExMatch( Data, "Poster"":""(.+?)""", Poster)
If Poster1 <>
{
Poster := SubStr( Poster1,1,InStr( Poster1, "._V1" )-1 ) . "._V1._SX100_CR0,0,100,150_.jpg"
URLDownloadToFile, %Poster%, %A_Temp%\Poster.jpg
If ErrorLevel = 0
PosterPath = %A_Temp%\Poster.jpg
}
}
GuiControl,, Image, %PosterPath%
}
Else If (A_GuiEvent = "RightClick") AND (A_EventInfo <> 0)
{
LV_GetText(MovieTitle, A_EventInfo)
IfInString, CleanHaveList, % CleanNames(MovieTitle)
{
StringReplace, MovieTitle, MovieTitle, *
MovieTitle = %MovieTitle%
MsgBox, 4,, %MovieTitle% already exists. Continue?
IfMsgBox No
Return
}
StringSplit, TempVar1, MovieTitle, (, %A_Space%
Loop, Parse, CleanHaveList, `r, `n
{
StringSplit, TempVar2, A_LoopField, (, %A_Space%
If (TempVar11 = TempVar21)
{
MsgBox, Movie Exists as %A_LoopField%
Break
}
}
GuiControl,, CurrentTitle, %MovieTitle%
StringReplace, MovieTitle, MovieTitle, :, %A_Space%-, A
ClipBoard := MovieTitle
SetTimer, GetTitles, Off
}
SB_SetText(" Right click to copy title.")
Return
;****************************************** My Functions *******************************************
;******************************** Get list of users existing files *********************************
GetExistingFileList()
{
Global
If ResetFileList <> 1
Return
Gui, 1:ListView, PathLV
If LV_GetCount() = 0
{
MsgBox, 0x2031, %A_ScriptName%, You must enter the paths to your files.
Return
}
FileDelete, Lists\Duplicates\%UserName1%.txt
ExistingFiles=
DuplicateList=
ActorList =
Loop, % LV_GetCount()
{
LV_GetText(Path, A_Index, 1)
Loop, %Path%\*, 2
{
IfNotExist, NFO\%A_LoopFileName%\*.nfo
{
LoopFileName := A_LoopFileName
Loop, %A_LoopFileFullPath%\*.nfo
FileCopy, %A_LoopFileFullPath%, NFO\%LoopFileName%.nfo
}
IfInString, ExistingFiles, A_LoopFileName
DuplicateList .= A_LoopFileName "`r`n"
Else ExistingFiles .= A_LoopFileName . "`r`n"
}
}
Sort, ExistingFiles, U
If DuplicateList <>
{
MsgBox, Duplicate files detected.
FileAppend, %DuplicateList%, Lists\Duplicates\%UserName1%.txt
Sleep, 500
Run, Lists\Duplicates\%UserName1%.txt
}
CleanExistingFiles := CleanNames(ExistingFiles)
DuplicateList =
ResetFileList =
}
CleanNames(Name)
{
Name := RegExReplace( Name, "mi)^The ")
Name := RegExReplace( Name, "i) The( +\(\d{4}\))", "$1")
Name := RegExReplace( Name, "[^a-zA-Z0-9 ()\r\n]+")
Loop
{
StringReplace, Name, Name, %A_Space%%A_Space%, %A_Space%, UseErrorLevel
If ErrorLevel = 0
Break
}
Name = %Name%
Return Name
}
;************************************** Function / GetMatch ****************************************
GetMatch(StartText, Before, Pattern, After, StopText="", HTM="")
{
Global Data
Pos := StartText = "" ? 1 : RegexMatch(Data, StartText, FoundText) + StrLen(FoundText)
Match =
MaxPos := StopText = "" ? StrLen(Data) : Instr(Data, StopText, True, Pos)
Loop
{
Pos:= RegexMatch(Data, Before . Pattern . After, TempVar, Pos)
If (Pos = 0) Or (Pos > MaxPos)
Break
Match .= Match = "" ? TempVar1 : "`r`n" TempVar1
If (StopText = "")
Break
Pos += StrLen(TempVar1)
}
If HTM <> False
{
Match := UnHTM(Match,HTM)
Match := UTF82Ansi(Match)
}
Return Match
}
;***************************************** Write Ini File ******************************************
WriteIni()
{
Global
Gui, 1:ListView, PathLV
GuiControlGet, UserName1
TempVar =
Loop, % LV_GetCount()
{
LV_GetText(Path, A_Index, 1)
TempVar .= TempVar = "" ? Path : "|" Path
}
If TempVar =
IniDelete, %ScriptIni%, Paths, %UserName1%
Else IniWrite, %TempVar%, %ScriptIni%, Paths, %UserName1%
}
ExitApp
;**************************************** Other Functions ******************************************
;***************************************************************************************************
;************ By Skan - http://www.autohotkey.com/forum/viewtopic.php?p=133249#133249 **************
;***************************************************************************************************
ShellFileOperation( fileO=0x0, fSource="", fTarget="", flags=0x0, ghwnd=0x0 ) {
If ( SubStr(fSource,0) != "|" )
fSource := fSource . "|"
If ( SubStr(fTarget,0) != "|" )
fTarget := fTarget . "|"
fsPtr := &fSource
Loop, % StrLen(fSource)
If ( *(fsPtr+(A_Index-1)) = 124 )
DllCall( "RtlFillMemory", UInt, fsPtr+(A_Index-1), Int,1, UChar,0 )
ftPtr := &fTarget
Loop, % StrLen(fTarget)
If ( *(ftPtr+(A_Index-1)) = 124 )
DllCall( "RtlFillMemory", UInt, ftPtr+(A_Index-1), Int,1, UChar,0 )
VarSetCapacity( SHFILEOPSTRUCT, 30, 0 ) ; Encoding SHFILEOPSTRUCT
NextOffset := NumPut( ghwnd, &SHFILEOPSTRUCT ) ; hWnd of calling GUI
NextOffset := NumPut( fileO, NextOffset+0 ) ; File operation
NextOffset := NumPut( fsPtr, NextOffset+0 ) ; Source file / pattern
NextOffset := NumPut( ftPtr, NextOffset+0 ) ; Target file / folder
NextOffset := NumPut( flags, NextOffset+0, 0, "Short" ) ; options
DllCall( "Shell32\SHFileOperationA", UInt,&SHFILEOPSTRUCT )
Return NumGet( NextOffset+0 )
}
;***************************************************************************************************
;*********** By Lexikos - http://www.autohotkey.com/forum/viewtopic.php?p=183401#183401 ************
;***************************************************************************************************
Glob(ByRef list, Pattern, IncludeDirs=0)
{
if (i:=RegExMatch(Pattern,"[*?]")) && (i:=InStr(Pattern,"\",1,i+1))
Loop, % SubStr(Pattern, 1, i-1), 2
Glob(list, A_LoopFileLongPath . SubStr(Pattern,i), IncludeDirs)
else
Loop, %Pattern%, %IncludeDirs%
list .= (list="" ? "" : "`n") . A_LoopFileLongPath
}
;***************************************************************************************************
;******************* By Sean - http://www.autohotkey.com/forum/topic17343.html *********************
;***************************************************************************************************
UTF82Ansi(zString)
{
Ansi2Unicode(zString, wString, 65001)
Unicode2Ansi(wString, sString, 0)
Return sString
}
Ansi2Unicode(ByRef sString, ByRef wString, CP = 0)
{
nSize := DllCall("MultiByteToWideChar"
, "Uint", CP
, "Uint", 0
, "Uint", &sString
, "int", -1
, "Uint", 0
, "int", 0)
VarSetCapacity(wString, nSize * 2)
DllCall("MultiByteToWideChar"
, "Uint", CP
, "Uint", 0
, "Uint", &sString
, "int", -1
, "Uint", &wString
, "int", nSize)
}
Unicode2Ansi(ByRef wString, ByRef sString, CP = 0)
{
nSize := DllCall("WideCharToMultiByte"
, "Uint", CP
, "Uint", 0
, "Uint", &wString
, "int", -1
, "Uint", 0
, "int", 0
, "Uint", 0
, "Uint", 0)
VarSetCapacity(sString, nSize)
DllCall("WideCharToMultiByte"
, "Uint", CP
, "Uint", 0
, "Uint", &wString
, "int", -1
, "str", sString
, "int", nSize
, "Uint", 0
, "Uint", 0)
}
;***************************************************************************************************
;*********************** By SKAN - www.autohotkey.com/forum/topic51342.html ************************
;***************************************************************************************************
UnHTM( HTM, DEL="" ) {
Static HT,C=";"
IfEqual,HT,, SetEnv,HT, % "ááââ´´ææàà&ååãã&au"
. "mlä&bdquo„¦¦&bull•ç縸¢¢&circˆ©©¤¤&dagger†&dagger‡°"
. "°÷÷ééêêèèððëë&euro€&fnofƒ½½¼¼¾¾>>&h"
. "ellip…ííîî¡¡ìì¿¿ïï««&ldquo“&lsaquo‹&lsquo‘<<&m"
. "acr¯&mdash—µµ··  &ndash–¬¬ññóóôô&oeligœòò&or"
. "dfªººøøõõöö¶¶&permil‰±±££"""»»&rdquo”®"
. "®&rsaquo›&rsquo’&sbquo‚&scaronš§§­ ¹¹²²³³ßßþþ&tilde˜&tim"
. "es×&trade™úúûûùù¨¨üüýý¥¥ÿÿ"
$ := RegExReplace( HTM,"<[^>]+>", DEL ) ; Remove all tags between "<" and ">"
Loop, Parse, $, &`; ; Create a list of special characters
L := "&" A_LoopField C, R .= (!(A_Index&1)) ? ( (!InStr(R,L,1)) ? L:"" ) : ""
StringTrimRight, R, R, 1
Loop, Parse, R , %C% ; Parse Special Characters
If F := InStr( HT, L := A_LoopField ) ; Lookup HT Data
StringReplace, $,$, %L%%C%, % SubStr( HT,F+StrLen(L), 1 ), All
Else If ( SubStr( L,2,1)="#" )
StringReplace, $, $, %L%%C%, % Chr(((SubStr(L,3,1)="x") ? "0" : "" ) SubStr(L,3)), All
If DEL <>
{
Loop
{
StringReplace, $, $, %DEL%%DEL%, %DEL%, UseErrorlevel
If ErrorLevel = 0
Break
}
}
Return RegExReplace( $, "(^\s*|\s*$)") ; Remove leading/trailing white spaces
}