AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

SceneRenamer - Renames "Scene" releases of TV Show
Goto page 1, 2, 3, 4, 5  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
strictlyfocused02



Joined: 21 Jan 2009
Posts: 63

PostPosted: Tue Oct 06, 2009 2:02 am    Post subject: SceneRenamer - Renames "Scene" releases of TV Show Reply with quote



Description
    The naming convention for "Scene" releases of TV Shows dictates that each file will have somewhat cryptic and long file name and usually doesn't contain the episode title. This bothered me ... so here is my solution.


Features
    - Parses show name from filename
    - Parses season and episode numbers from filename
    - Uses show name along with season number and episode number to connect to TheTVDB.com's extensive database
    - Renames the file based on info obtained from TheTVDB.com
    - Add an entire folder (great for seasons!)
    - Add an individual file(s) (now with multi-select!)
    - Right-Click context menu with useful entries (Open Item, Open Folder, Remove Item, Item Properties)
    - 4 different output naming formats (Shown in screenshot)
    - Ability to pad single digit episode and season numbers with a zero
    - Open Folder dialog box has an edit field so you can just paste a directory instead of using the clunky tree navigation pane
    - settings.ini file to set the approved filetypes and also set the directory Add Folder/File starts in (NEW!)
    - Drag and Drop file support (NEW!)
    - A full changelog can be found at the bottom of the script source code


Instructions
    1 - Add a file or folder using the appropriate button at the top of the window
    2 - If needed, remove any items you do not wish to scan against TheTVDB.com's database via the right-click menu
    3 - Press "Get TVDB Info" and wait for each row to have its "Preview" column filled
    4 - Remove any items that you do not wish to be renamed
    5 - Press "Rename Files"


Notes
    - Supports many "Scene" naming conventions (along with minor variations)
      - Show.Name.s01e01.avi
      - Show.Name.01x06.avi
      - Show.Name.104.avi

    - Show title is determined by looking behind the season and episode information
    - If the Naming scheme is changed you have to re-fetch the TVDB info again to apply the change
    - Titans "XPath" function was used so major thanks to Titan for that!
    - This is a complete re-write, but same concept, of my previous script located here
    - If the script is unable to get the episode info from TheTVDB it will rename the file as close as possible to the selected naming format (i.e. "Greek - 03x01.avi" if no episode title is present)
    - Due to some of recent changes made to the script Ive chosen to upload a nice little zip file to autohotkey.net which includes a compiled version (source included ofc!) of the script. More specifically, having moved xpath to its own subdir and the addition of an ini settings file the script has become more difficult to just "copypasta" and have everything work.

As always, any tips, suggestions, or any constructive criticism is not only welcomed, but encouraged!

Download


Last edited by strictlyfocused02 on Wed Oct 12, 2011 4:32 pm; edited 9 times in total
Back to top
View user's profile Send private message
madrano



Joined: 23 Aug 2008
Posts: 2

PostPosted: Thu Oct 08, 2009 8:06 am    Post subject: Reply with quote

fantastic script thx
Back to top
View user's profile Send private message
Thrawn



Joined: 12 May 2008
Posts: 30
Location: Germany

PostPosted: Thu Oct 08, 2009 4:26 pm    Post subject: Reply with quote

i'm coding something similar using thetvdb.com's api. currently in development, the configuration / update part are not fully implemented - mainly gui stuff. but what you can see in the screenshots works - in a perfectly usable speed. you won't see any filenames anymore, so it doesnt really matter how unreadable they are. currently its using xpath, gdip and some hacks for multiple scrollable areas (i am planning to implement majkinetors [module] Scroller 1.0 as soon as its able to handle scrollable panels).
Quote:



Back to top
View user's profile Send private message
ashius



Joined: 20 Oct 2009
Posts: 3

PostPosted: Tue Oct 20, 2009 10:24 pm    Post subject: Reply with quote

This is an awesome script! Thanks for sharing it.

I have modified it so on launch it automatically scans my 'new shows folder'. I also took off the preceding 0 on the season number too.

The only thing I find a bit clunky is when a show has more than one search result. I have been trying to think of a way to make it easier, I have a couple of ideas but no idea how to implement them.

1. After a match has been confirmed, in the context menu would be an item to store that ShowName with its corresponding SeriesName and SeriesIDNum for future matches. I guess this would be stored in a separate ini file, that the script checks first before hitting TheTVDB.

2. Instead of a series of yes/no dialog's the result could be presented in a list box format.

Do you think either of them would be possible?
Back to top
View user's profile Send private message
ashius



Joined: 20 Oct 2009
Posts: 3

PostPosted: Wed Oct 21, 2009 5:24 am    Post subject: Reply with quote

Well I gave the my number 1 option a shot myself and came up with the below. It seems to work well enough, tho I'm sure it hasn't been done the best way possible.

I'm pretty sure i commented on any changes I made to the code

Code:
; SceneRenamer by strictlyfocused02
;
; AutoHotkey Version: 1.0.48+
;
; Script Function:
;   Extracts season and episode info from the filename
;   and uses that to retreive info from TheTVDB.com to rename
;   the file to a user-specified format

;   Special thanks to TheTVDB.com
;   This project would not have been possible without their top-notch API

#Include xpath.ahk

#NoEnv
SendMode, Input
SetWorkingDir, %A_ScriptDir%

Gui, Add, Button, Default gButtonAddFolder, &Add folder
Gui, Add, Button, x+20 gButtonAddFile, &Add file
Gui, Add, Button, x+20 gButtonClear, &Clear list
Gui, Add, Button, x+20 TVRenameFolder, &TV Rename Folder ;Addtional button for scaning my default folder
Gui, Add, Button, x+20 ButtonAddRule, &Add Rule ; Add rule button


Gui, Add, ListView, xm r25 w800 vMyListView, Name|Preview|Directory|Extension|TVDB Series ID No|Show Name ;Added collum for getting the selected Show Name

Gui, Add, DropDownList, y+7 w250 AltSubmit vNameScheme, (Show Title) - (SS)x(EE) - (Episode Title)||(Show Title) - S(SS)E(EE) - (Episode Title)|(SS)x(EE) - Episode Title|S(SS)E(EE) - (Episode Title)
Gui, Add, Checkbox, x+30 Checked vZero, Pad with zero?
Gui, Add, Button, x+200 gButtonGetTVDBInfo, &Get TVDB Info
Gui, Add, Button, x+60 gButtonRename, &Rename files

Menu, MyContextMenu, Add, Open, ContextOpenFile
Menu, MyContextMenu, Add, Properties, ContextProperties
Menu, MyContextMenu, Add, Remove item, ContextRemoveItem

Gui, Show
Gosub, ButtonTVRenameFolder ;This is so it starts scaning once opened
Return



GuiClose:
   ExitApp

GuiContextMenu:
   If A_GuiControl <> MyListView
       Return
   Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY%
   Return

;Add new rule to the rules.ini
ButtonAddRule:
   FocusedRowNumber := LV_GetNext(0, "F")
   LV_GetText(SeriesIDNum, FocusedRowNumber, 5)
   LV_GetText(ShowName, FocusedRowNumber, 6)
   
   ;check for rules.ini and create if it doesnt exist
   IfNotExist, rules.ini
      IniWrite, AllRuleNames, rules.ini, Rules, AllRuleNames
   Else
   IniRead, AllRuleNames, rules.ini, Rules, AllRuleNames
   ;Check the rule doesnt already exist
   Loop, Parse, AllRuleNames, |
      {
         thisRule = %A_LoopField%
         if thisRule = %ShowName%
         {
            Msgbox %ShowName% already has a rule
            Return
         }
      }
   IniWrite, %AllRuleNames%%ShowName%|, rules.ini, Rules, AllRuleNames
   IniWrite, %ShowName%, rules.ini, %ShowName%, SeriesName
   IniWrite, %SeriesIDNum%, rules.ini, %ShowName%, SeriesIDNum
   Return
   
   
ContextOpenFile:
ContextProperties:
   FocusedRowNumber := LV_GetNext(0, "F")
   If not FocusedRowNumber
      return
   LV_GetText(FileName, FocusedRowNumber, 1)
   LV_GetText(FileDir, FocusedRowNumber, 3)
   IfInString A_ThisMenuItem, Open
      Run %FileDir%\%FileName%,, UseErrorLevel
   Else
      Run Properties "%FileDir%\%FileName%",, UseErrorLevel
   If ErrorLevel
      MsgBox Could not perform requested action on "%FileDir%\%FileName%".
   return
   
ContextRemoveItem:
   RowNumber = 0
   Loop
   {
      RowNumber := LV_GetNext(RowNumber - 1)
      If not RowNumber
           Break
      LV_Delete(RowNumber)
   }
   Return

ButtonAddFolder:
   Gui +OwnDialogs
   FileSelectFolder, TargetFolder,, 3, Select a folder:
   If not TargetFolder  ; The user pressed cancel
       Return
   StringRight, LastChar, TargetFolder, 1
   If LastChar = \
      StringTrimRight, TargetFolder, TargetFolder, 1
   GuiControl, -Redraw, MyListView ; Improves performance by disabling redrawing
   Loop %TargetFolder%\*.*
   {
      FileName := A_LoopFileFullPath
      SplitPath, FileName,,, FileExt  ; Get the file extension
      If FileExt in avi,mkv,mp4
         LV_Add(Row, A_LoopFileName, "", A_LoopFileDir, FileExt)
   }
   GuiControl, +Redraw, MyListView  ; Turn redrawing back on
   LV_ModifyCol()  ; Resize each column to fit
   LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
   LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
   LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   Return

   ;Auto load a default folder and scan it
 ButtonTVRenameFolder: 
   TargetFolder := "\\SPOON\Downloads\TV Rename\"
   Loop %TargetFolder%\*.*
   {
      FileName := A_LoopFileFullPath
      SplitPath, FileName,,, FileExt  ; Get the file extension
      If FileExt in avi,mkv,mp4
         LV_Add(Row, A_LoopFileName, "", A_LoopFileDir, FileExt)
   }
   GuiControl, +Redraw, MyListView  ; Turn redrawing back on
   LV_ModifyCol()  ; Resize each column to fit
   LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
   LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
   LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   Gosub, ButtonGetTVDBInfo
   Return
   
   
   
ButtonAddFile:
   Gui +OwnDialogs
   FileSelectFile, TargetFile
   If not TargetFile
      Return
   SplitPath, TargetFile,,, FileExt  ; Get the file extension
   If FileExt in avi,mkv,mp4
   {
      SplitPath, TargetFile, FileName, TargetFolder
      LV_Add(Row, FileName, "", TargetFolder, FileExt)
      LV_ModifyCol()  ; Resize each column to fit
      LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
      LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
      LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   }
   Return

ButtonClear:
   TargetFolder =
   LV_Delete()
   Return

ButtonGetTVDBInfo:
   LV_GetText(LVFileName, 1, 1)  ; Get the filename
   If not LVFileName
   {
      MsgBox, 0,Fatal Error!, You must select a file or folder before connecting to TheTVDB.com!
      Return
   }
   Loop
   {
      RowNumber = %A_Index%
      LV_GetText(LVFileName, RowNumber, 1)  ; Get the filename
      If not LVFileName  ; Break the loop at the end of the list
         Break
      LV_GetText(LVFileDir, RowNumber, 3)  ; Get the file directory
      LV_GetText(LVFileExt, RowNumber, 4)  ; Get the file extension
      ShowInfo := GetTVDBShows(GetShowName(LVFileName))
      StringSplit, OutputArray, ShowInfo, `,
      ShowName = %OutputArray1%
      SeriesIDNo = %OutputArray2%
      SeasonNumber := GetSeasonNumber(LVFileName)
      EpisodeNumber := GetEpisodeNumber(LVFileName)
      If SeriesIDNo
      {
         EpisodeInfo := GetTVDBEpisodes(SeriesIDNo, SeasonNumber, EpisodeNumber)
         StringSplit, OutputArray, EpisodeInfo, `,
         SeasonNumber = %OutputArray1%
         EpisodeNumber = %OutputArray2%
         EpisodeTitle = %OutputArray3%
      }
      GuiControlGet, NamingScheme,, NameScheme
      If NamingScheme = 1
      {
         If EpisodeTitle
            NewFileName = %ShowName% - %SeasonNumber%x%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = %ShowName% - %SeasonNumber%x%EpisodeNumber%.%LVFileExt%
      }
      Else if NamingScheme = 2
      {
         If EpisodeTitle
            NewFileName = %ShowName% - S%SeasonNumber%E%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = %ShowName% - S%SeasonNumber%E%EpisodeNumber%.%LVFileExt%
      }
      Else If NamingScheme = 3
      {
         If EpisodeTitle
            NewFileName = %SeasonNumber%x%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = %SeasonNumber%x%EpisodeNumber%.%LVFileExt%
      }
      Else If NamingScheme = 4
      {
         If EpisodeTitle
            NewFileName = S%SeasonNumber%E%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = S%SeasonNumber%E%EpisodeNumber%.%LVFileExt%
      }

      LV_Modify(RowNumber, Col1, LVFileName, NewFileName, LVFileDir, LVFileExt, SeriesIDNo, ShowName)
      LV_ModifyCol()
      LV_ModifyCol(4, 60)
      LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   }
   Return

ButtonRename:
   Loop
   {
      RowNumber = %A_Index%
      LV_GetText(LVFileName, RowNumber, 1)  ; Get the original filename
      If not LVFileName  ; Break the loop at the end of the list
         Break
      LV_GetText(LVNewFileName, RowNumber, 2)  ; Get the new filename
      FileMove, %TargetFolder%\%LVFileName%, %TargetFolder%\%LVNewFileName%
   }
   RenameCount := RowNumber - 1
   MsgBox, 0, Success!, %RenameCount% files have been renamed!`n`nRefreshing file list...
   LV_Delete()
   Loop %TargetFolder%\*.*
   {
      FileName := A_LoopFileFullPath
      If not FileName
         Break
      SplitPath, FileName,,, FileExt  ; Get the file extension
      If FileExt in avi,mkv,mp4
         LV_Add(Row, A_LoopFileName, "", A_LoopFileDir, FileExt)
   }
   GuiControl, +Redraw, MyListView  ; Turn redrawing back on
   LV_ModifyCol()  ; Resize each column to fit
   LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
   LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
   LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   Return

;Provide a filename (greek.s01e01.avi) and this will hopefully detect and return the show name
GetShowName(FileName)
{
   IfInString, FileName, .
      StringReplace, NormalName, FileName, ., %A_Space%, All
   IfInString, NormalName, _
      StringReplace, NormalName, NormalName, _, %A_Space%, All
   If RegExMatch(NormalName, "i)s[0-9][0-9]? ?e[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, SeasonAndEpisodePos, NormalName, %SeasonAndEpisode%
      StringLeft, ShowName, NormalName, (SeasonAndEpisodePos - 1)
   }
   Else If RegExMatch(NormalName, "i)[0-9][0-9]?x[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, SeasonAndEpisodePos, NormalName, %SeasonAndEpisode%
      StringLeft, ShowName, NormalName, (SeasonAndEpisodePos - 1)
   }
   Else If RegExMatch(NormalName, "[0-9][0-9][0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, SeasonAndEpisodePos, NormalName, %SeasonAndEpisode%
      StringLeft, ShowName, NormalName, (SeasonAndEpisodePos - 1)
   }
   Loop
   {
      StringRight, LastChar, ShowName, 1
      If (LastChar = "-" or LastChar = " ")
         StringTrimRight, ShowName, ShowName, 1
      Else
         Break
   }
   Return ShowName
}

;Provide a filename (greek.s01e01.avi) and this will hopefully detect and return the season number
GetSeasonNumber(FileName)
{
   If RegExMatch(FileName, "i)s\K[0-9][0-9]?.?e[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, EPos, SeasonAndEpisode, e
      StringLeft, SeasonNumber, SeasonAndEpisode, %EPos%
      IfInString, SeasonNumber, .
         StringTrimRight, SeasonNumber, SeasonNumber, 1
      IfInString, SeasonNumber, 0
      {
         StringGetPos, ZeroLoc, SeasonNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, SeasonNumber, SeasonNumber, 1
      }
         
   }
   Else If RegExMatch(FileName, "i)[0-9][0-9]?x[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, XPos, SeasonAndEpisode, x
      StringLeft, SeasonNumber, SeasonAndEpisode, %XPos%
      IfInString, SeasonNumber, 0
      {
        StringGetPos, ZeroLoc, SeasonNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, SeasonNumber, SeasonNumber, 1
      }
   }
   Else If RegExMatch(FileName, "[0-9][0-9][0-9][0-9]?", SeasonAndEpisode)
   {
      StringTrimRight, SeasonNumber, SeasonAndEpisode, 2
      IfInString, SeasonNumber, 0
      {
         StringGetPos, ZeroLoc, SeasonNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, SeasonNumber, SeasonNumber, 1
      }
   }
   Return SeasonNumber
}

;Provide a filename (greek.s01e01.avi) and this will hopefully detect and return the episode number
GetEpisodeNumber(FileName)
{
   If RegExMatch(FileName, "i)s\K[0-9][0-9]?.?e[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, EPos, SeasonAndEpisode, e
      StringRight, EpisodeNumber, SeasonAndEpisode, %EPos%
      IfInString, EpisodeNumber, e
         StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      IfInString, EpisodeNumber, 0
      {
         StringGetPos, ZeroLoc, EpisodeNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      }
   }
   Else If RegExMatch(FileName, "i)[0-9][0-9]?x[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, XPos, SeasonAndEpisode, x
      StringRight, EpisodeNumber, SeasonAndEpisode, %XPos%
      IfInString, EpisodeNumber, 0
      {
         StringGetPos, ZeroLoc, EpisodeNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      }
   }
   Else If RegExMatch(FileName, "[0-9][0-9][0-9][0-9]?", SeasonAndEpisode)
   {
      StringRight, EpisodeNumber, SeasonAndEpisode, 2
      IfInString, EpisodeNumber, 0
      {
         StringGetPos, ZeroLoc, EpisodeNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      }
   }
   Return EpisodeNumber
}


;Provide a show name (greek) and it will return the TVDB data for the show name (Greek) and series ID (80301) as a CSV (Greek,80301)
GetTVDBShows(ShowName)
{
;Check the rules.ini for a match
      IniRead, AllRuleNames, rules.ini, Rules, AllRuleNames
      Loop, Parse, AllRuleNames, |
      {
         thisRule = %A_LoopField%
         ;Continue on if there is no rule
         if (thisRule = "ERROR") or (thisRule = "")
         {
            Continue
         }
         if (thisRule = ShowName)
         {
         IniRead, SeriesName, rules.ini, %thisRule%, SeriesName
         IniRead, SeriesIDNum, rules.ini, %thisRule%, SeriesIDNum
         ;Jump to the end of GetTVDBShows if match ins found in rules.
         goto finish
         }
      }
   IfExist, Series_ID.xml
      FileDelete, Series_ID.xml
   UrlDownloadToFile, http://www.thetvdb.com/api/GetSeries.php?seriesname="%ShowName%", Series_ID.xml
   XPath_Load(xml, "Series_ID.xml")
   SeriesNameNodeCount := XPath(xml, "/Data/Series/SeriesName/Count()")
   If SeriesNameNodeCount = 1
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
   }
   Else If SeriesNameNodeCount >= 2
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
      SeriesOverview := XPath(xml, "/Data/Series/Overview/text()")
      StringSplit, OutputArraySID, SeriesIDNum, `,
      StringSplit, OutputArraySN, SeriesName, `,
      StringSplit, OutputArraySO, SeriesOverview, `,
     Loop, %SeriesNameNodeCount%
      {
         SeriesIDNum := OutputArraySID%A_Index%
         SeriesName := OutputArraySN%A_Index%
         SeriesOverview := OutputArraySO%A_Index%
         IfInString, SeriesOverview, &#44`;
            StringReplace, SeriesOverview, SeriesOverview, &#44`;, `,, All
         If not SeriesOverview
            SeriesOverview = (No show description provided)
         MsgBox, 3, Which show do you want?, %SeriesName%`n`n%SeriesOverview%
         IfMsgBox, Yes
            Break
         IfMsgBox, No
         {
            NoCount = %A_Index%
            If NoCount = %SeriesNameNodeCount%
            {
               SeriesName =
               SeriesIDNum =
               MsgBox, 0, Fatal Error!, No more show name suggestions provided!`n`nI will use the show name parsed from the filename and move on to the next row...
            }
         }
         IfMsgBox, Cancel
            Return
      }
   }
   finish:
   If not SeriesName
      SeriesName = %ShowName%
   FileDelete, Series_ID.xml
   Data = %SeriesName%,%SeriesIDNum%
   Return Data
}

;Provide the "TVDB series ID", "season number" and "episode number" and this will return the matching TVDB season number,episode number, and episode title as a CSV (3,1,The Day After)
GetTVDBEpisodes(SeriesIDNum, SeasonNum, EpisodeNum)
{
   IfExist, Episode_Info.xml
      FileDelete, Episode_Info.xml
   UrlDownloadToFile, http://www.thetvdb.com/api/563E39CDC7F666DF/series/%SeriesIDNum%/default/%SeasonNum%/%EpisodeNum%/en.xml, Episode_Info.xml
   XPath_Load(xml, "Episode_Info.xml")
   SeasonNumber := XPath(xml, "/Data/Episode/SeasonNumber/text()")
   EpisodeNumber := XPath(xml, "/Data/Episode/EpisodeNumber/text()")
   EpisodeTitle := XPath(xml, "/Data/Episode/EpisodeName/text()")
   FileDelete, Episode_Info.xml
   If not SeasonNumber
      SeasonNumber = %SeasonNum%
   If not EpisodeNumber
      EpisodeNumber = %EpisodeNum%
   IfInString, EpisodeTitle, ?
      StringReplace, EpisodeTitle, EpisodeTitle, ?,, All
   GuiControlGet, PadZero, , Zero
   If PadZero = 1
   {
      SeasonLen := StrLen(SeasonNumber)
      EpisodeLen := StrLen(EpisodeNumber)
      ;If SeasonLen = 1
       ;  SeasonNumber = 0%SeasonNumber%
      If EpisodeLen = 1
         EpisodeNumber = 0%EpisodeNumber%
   }
   K = %SeasonNumber%,%EpisodeNumber%,%EpisodeTitle%
   Return K
}


Any feedback would be great, I haven't really done anything like this before, and I'm sure I have made some mistakes
Back to top
View user's profile Send private message
strictlyfocused02



Joined: 21 Jan 2009
Posts: 63

PostPosted: Sun Oct 25, 2009 11:17 am    Post subject: Reply with quote

ashius wrote:
Well I gave the my number 1 option a shot myself and came up with the below. It seems to work well enough, tho I'm sure it hasn't been done the best way possible.

I'm pretty sure i commented on any changes I made to the code

Code:
; SceneRenamer by strictlyfocused02
;
; AutoHotkey Version: 1.0.48+
;
; Script Function:
;   Extracts season and episode info from the filename
;   and uses that to retreive info from TheTVDB.com to rename
;   the file to a user-specified format

;   Special thanks to TheTVDB.com
;   This project would not have been possible without their top-notch API

#Include xpath.ahk

#NoEnv
SendMode, Input
SetWorkingDir, %A_ScriptDir%

Gui, Add, Button, Default gButtonAddFolder, &Add folder
Gui, Add, Button, x+20 gButtonAddFile, &Add file
Gui, Add, Button, x+20 gButtonClear, &Clear list
Gui, Add, Button, x+20 TVRenameFolder, &TV Rename Folder ;Addtional button for scaning my default folder
Gui, Add, Button, x+20 ButtonAddRule, &Add Rule ; Add rule button


Gui, Add, ListView, xm r25 w800 vMyListView, Name|Preview|Directory|Extension|TVDB Series ID No|Show Name ;Added collum for getting the selected Show Name

Gui, Add, DropDownList, y+7 w250 AltSubmit vNameScheme, (Show Title) - (SS)x(EE) - (Episode Title)||(Show Title) - S(SS)E(EE) - (Episode Title)|(SS)x(EE) - Episode Title|S(SS)E(EE) - (Episode Title)
Gui, Add, Checkbox, x+30 Checked vZero, Pad with zero?
Gui, Add, Button, x+200 gButtonGetTVDBInfo, &Get TVDB Info
Gui, Add, Button, x+60 gButtonRename, &Rename files

Menu, MyContextMenu, Add, Open, ContextOpenFile
Menu, MyContextMenu, Add, Properties, ContextProperties
Menu, MyContextMenu, Add, Remove item, ContextRemoveItem

Gui, Show
Gosub, ButtonTVRenameFolder ;This is so it starts scaning once opened
Return



GuiClose:
   ExitApp

GuiContextMenu:
   If A_GuiControl <> MyListView
       Return
   Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY%
   Return

;Add new rule to the rules.ini
ButtonAddRule:
   FocusedRowNumber := LV_GetNext(0, "F")
   LV_GetText(SeriesIDNum, FocusedRowNumber, 5)
   LV_GetText(ShowName, FocusedRowNumber, 6)
   
   ;check for rules.ini and create if it doesnt exist
   IfNotExist, rules.ini
      IniWrite, AllRuleNames, rules.ini, Rules, AllRuleNames
   Else
   IniRead, AllRuleNames, rules.ini, Rules, AllRuleNames
   ;Check the rule doesnt already exist
   Loop, Parse, AllRuleNames, |
      {
         thisRule = %A_LoopField%
         if thisRule = %ShowName%
         {
            Msgbox %ShowName% already has a rule
            Return
         }
      }
   IniWrite, %AllRuleNames%%ShowName%|, rules.ini, Rules, AllRuleNames
   IniWrite, %ShowName%, rules.ini, %ShowName%, SeriesName
   IniWrite, %SeriesIDNum%, rules.ini, %ShowName%, SeriesIDNum
   Return
   
   
ContextOpenFile:
ContextProperties:
   FocusedRowNumber := LV_GetNext(0, "F")
   If not FocusedRowNumber
      return
   LV_GetText(FileName, FocusedRowNumber, 1)
   LV_GetText(FileDir, FocusedRowNumber, 3)
   IfInString A_ThisMenuItem, Open
      Run %FileDir%\%FileName%,, UseErrorLevel
   Else
      Run Properties "%FileDir%\%FileName%",, UseErrorLevel
   If ErrorLevel
      MsgBox Could not perform requested action on "%FileDir%\%FileName%".
   return
   
ContextRemoveItem:
   RowNumber = 0
   Loop
   {
      RowNumber := LV_GetNext(RowNumber - 1)
      If not RowNumber
           Break
      LV_Delete(RowNumber)
   }
   Return

ButtonAddFolder:
   Gui +OwnDialogs
   FileSelectFolder, TargetFolder,, 3, Select a folder:
   If not TargetFolder  ; The user pressed cancel
       Return
   StringRight, LastChar, TargetFolder, 1
   If LastChar = \
      StringTrimRight, TargetFolder, TargetFolder, 1
   GuiControl, -Redraw, MyListView ; Improves performance by disabling redrawing
   Loop %TargetFolder%\*.*
   {
      FileName := A_LoopFileFullPath
      SplitPath, FileName,,, FileExt  ; Get the file extension
      If FileExt in avi,mkv,mp4
         LV_Add(Row, A_LoopFileName, "", A_LoopFileDir, FileExt)
   }
   GuiControl, +Redraw, MyListView  ; Turn redrawing back on
   LV_ModifyCol()  ; Resize each column to fit
   LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
   LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
   LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   Return

   ;Auto load a default folder and scan it
 ButtonTVRenameFolder: 
   TargetFolder := "\\SPOON\Downloads\TV Rename\"
   Loop %TargetFolder%\*.*
   {
      FileName := A_LoopFileFullPath
      SplitPath, FileName,,, FileExt  ; Get the file extension
      If FileExt in avi,mkv,mp4
         LV_Add(Row, A_LoopFileName, "", A_LoopFileDir, FileExt)
   }
   GuiControl, +Redraw, MyListView  ; Turn redrawing back on
   LV_ModifyCol()  ; Resize each column to fit
   LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
   LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
   LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   Gosub, ButtonGetTVDBInfo
   Return
   
   
   
ButtonAddFile:
   Gui +OwnDialogs
   FileSelectFile, TargetFile
   If not TargetFile
      Return
   SplitPath, TargetFile,,, FileExt  ; Get the file extension
   If FileExt in avi,mkv,mp4
   {
      SplitPath, TargetFile, FileName, TargetFolder
      LV_Add(Row, FileName, "", TargetFolder, FileExt)
      LV_ModifyCol()  ; Resize each column to fit
      LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
      LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
      LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   }
   Return

ButtonClear:
   TargetFolder =
   LV_Delete()
   Return

ButtonGetTVDBInfo:
   LV_GetText(LVFileName, 1, 1)  ; Get the filename
   If not LVFileName
   {
      MsgBox, 0,Fatal Error!, You must select a file or folder before connecting to TheTVDB.com!
      Return
   }
   Loop
   {
      RowNumber = %A_Index%
      LV_GetText(LVFileName, RowNumber, 1)  ; Get the filename
      If not LVFileName  ; Break the loop at the end of the list
         Break
      LV_GetText(LVFileDir, RowNumber, 3)  ; Get the file directory
      LV_GetText(LVFileExt, RowNumber, 4)  ; Get the file extension
      ShowInfo := GetTVDBShows(GetShowName(LVFileName))
      StringSplit, OutputArray, ShowInfo, `,
      ShowName = %OutputArray1%
      SeriesIDNo = %OutputArray2%
      SeasonNumber := GetSeasonNumber(LVFileName)
      EpisodeNumber := GetEpisodeNumber(LVFileName)
      If SeriesIDNo
      {
         EpisodeInfo := GetTVDBEpisodes(SeriesIDNo, SeasonNumber, EpisodeNumber)
         StringSplit, OutputArray, EpisodeInfo, `,
         SeasonNumber = %OutputArray1%
         EpisodeNumber = %OutputArray2%
         EpisodeTitle = %OutputArray3%
      }
      GuiControlGet, NamingScheme,, NameScheme
      If NamingScheme = 1
      {
         If EpisodeTitle
            NewFileName = %ShowName% - %SeasonNumber%x%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = %ShowName% - %SeasonNumber%x%EpisodeNumber%.%LVFileExt%
      }
      Else if NamingScheme = 2
      {
         If EpisodeTitle
            NewFileName = %ShowName% - S%SeasonNumber%E%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = %ShowName% - S%SeasonNumber%E%EpisodeNumber%.%LVFileExt%
      }
      Else If NamingScheme = 3
      {
         If EpisodeTitle
            NewFileName = %SeasonNumber%x%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = %SeasonNumber%x%EpisodeNumber%.%LVFileExt%
      }
      Else If NamingScheme = 4
      {
         If EpisodeTitle
            NewFileName = S%SeasonNumber%E%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = S%SeasonNumber%E%EpisodeNumber%.%LVFileExt%
      }

      LV_Modify(RowNumber, Col1, LVFileName, NewFileName, LVFileDir, LVFileExt, SeriesIDNo, ShowName)
      LV_ModifyCol()
      LV_ModifyCol(4, 60)
      LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   }
   Return

ButtonRename:
   Loop
   {
      RowNumber = %A_Index%
      LV_GetText(LVFileName, RowNumber, 1)  ; Get the original filename
      If not LVFileName  ; Break the loop at the end of the list
         Break
      LV_GetText(LVNewFileName, RowNumber, 2)  ; Get the new filename
      FileMove, %TargetFolder%\%LVFileName%, %TargetFolder%\%LVNewFileName%
   }
   RenameCount := RowNumber - 1
   MsgBox, 0, Success!, %RenameCount% files have been renamed!`n`nRefreshing file list...
   LV_Delete()
   Loop %TargetFolder%\*.*
   {
      FileName := A_LoopFileFullPath
      If not FileName
         Break
      SplitPath, FileName,,, FileExt  ; Get the file extension
      If FileExt in avi,mkv,mp4
         LV_Add(Row, A_LoopFileName, "", A_LoopFileDir, FileExt)
   }
   GuiControl, +Redraw, MyListView  ; Turn redrawing back on
   LV_ModifyCol()  ; Resize each column to fit
   LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
   LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
   LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   Return

;Provide a filename (greek.s01e01.avi) and this will hopefully detect and return the show name
GetShowName(FileName)
{
   IfInString, FileName, .
      StringReplace, NormalName, FileName, ., %A_Space%, All
   IfInString, NormalName, _
      StringReplace, NormalName, NormalName, _, %A_Space%, All
   If RegExMatch(NormalName, "i)s[0-9][0-9]? ?e[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, SeasonAndEpisodePos, NormalName, %SeasonAndEpisode%
      StringLeft, ShowName, NormalName, (SeasonAndEpisodePos - 1)
   }
   Else If RegExMatch(NormalName, "i)[0-9][0-9]?x[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, SeasonAndEpisodePos, NormalName, %SeasonAndEpisode%
      StringLeft, ShowName, NormalName, (SeasonAndEpisodePos - 1)
   }
   Else If RegExMatch(NormalName, "[0-9][0-9][0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, SeasonAndEpisodePos, NormalName, %SeasonAndEpisode%
      StringLeft, ShowName, NormalName, (SeasonAndEpisodePos - 1)
   }
   Loop
   {
      StringRight, LastChar, ShowName, 1
      If (LastChar = "-" or LastChar = " ")
         StringTrimRight, ShowName, ShowName, 1
      Else
         Break
   }
   Return ShowName
}

;Provide a filename (greek.s01e01.avi) and this will hopefully detect and return the season number
GetSeasonNumber(FileName)
{
   If RegExMatch(FileName, "i)s\K[0-9][0-9]?.?e[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, EPos, SeasonAndEpisode, e
      StringLeft, SeasonNumber, SeasonAndEpisode, %EPos%
      IfInString, SeasonNumber, .
         StringTrimRight, SeasonNumber, SeasonNumber, 1
      IfInString, SeasonNumber, 0
      {
         StringGetPos, ZeroLoc, SeasonNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, SeasonNumber, SeasonNumber, 1
      }
         
   }
   Else If RegExMatch(FileName, "i)[0-9][0-9]?x[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, XPos, SeasonAndEpisode, x
      StringLeft, SeasonNumber, SeasonAndEpisode, %XPos%
      IfInString, SeasonNumber, 0
      {
        StringGetPos, ZeroLoc, SeasonNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, SeasonNumber, SeasonNumber, 1
      }
   }
   Else If RegExMatch(FileName, "[0-9][0-9][0-9][0-9]?", SeasonAndEpisode)
   {
      StringTrimRight, SeasonNumber, SeasonAndEpisode, 2
      IfInString, SeasonNumber, 0
      {
         StringGetPos, ZeroLoc, SeasonNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, SeasonNumber, SeasonNumber, 1
      }
   }
   Return SeasonNumber
}

;Provide a filename (greek.s01e01.avi) and this will hopefully detect and return the episode number
GetEpisodeNumber(FileName)
{
   If RegExMatch(FileName, "i)s\K[0-9][0-9]?.?e[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, EPos, SeasonAndEpisode, e
      StringRight, EpisodeNumber, SeasonAndEpisode, %EPos%
      IfInString, EpisodeNumber, e
         StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      IfInString, EpisodeNumber, 0
      {
         StringGetPos, ZeroLoc, EpisodeNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      }
   }
   Else If RegExMatch(FileName, "i)[0-9][0-9]?x[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, XPos, SeasonAndEpisode, x
      StringRight, EpisodeNumber, SeasonAndEpisode, %XPos%
      IfInString, EpisodeNumber, 0
      {
         StringGetPos, ZeroLoc, EpisodeNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      }
   }
   Else If RegExMatch(FileName, "[0-9][0-9][0-9][0-9]?", SeasonAndEpisode)
   {
      StringRight, EpisodeNumber, SeasonAndEpisode, 2
      IfInString, EpisodeNumber, 0
      {
         StringGetPos, ZeroLoc, EpisodeNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      }
   }
   Return EpisodeNumber
}


;Provide a show name (greek) and it will return the TVDB data for the show name (Greek) and series ID (80301) as a CSV (Greek,80301)
GetTVDBShows(ShowName)
{
;Check the rules.ini for a match
      IniRead, AllRuleNames, rules.ini, Rules, AllRuleNames
      Loop, Parse, AllRuleNames, |
      {
         thisRule = %A_LoopField%
         ;Continue on if there is no rule
         if (thisRule = "ERROR") or (thisRule = "")
         {
            Continue
         }
         if (thisRule = ShowName)
         {
         IniRead, SeriesName, rules.ini, %thisRule%, SeriesName
         IniRead, SeriesIDNum, rules.ini, %thisRule%, SeriesIDNum
         ;Jump to the end of GetTVDBShows if match ins found in rules.
         goto finish
         }
      }
   IfExist, Series_ID.xml
      FileDelete, Series_ID.xml
   UrlDownloadToFile, http://www.thetvdb.com/api/GetSeries.php?seriesname="%ShowName%", Series_ID.xml
   XPath_Load(xml, "Series_ID.xml")
   SeriesNameNodeCount := XPath(xml, "/Data/Series/SeriesName/Count()")
   If SeriesNameNodeCount = 1
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
   }
   Else If SeriesNameNodeCount >= 2
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
      SeriesOverview := XPath(xml, "/Data/Series/Overview/text()")
      StringSplit, OutputArraySID, SeriesIDNum, `,
      StringSplit, OutputArraySN, SeriesName, `,
      StringSplit, OutputArraySO, SeriesOverview, `,
     Loop, %SeriesNameNodeCount%
      {
         SeriesIDNum := OutputArraySID%A_Index%
         SeriesName := OutputArraySN%A_Index%
         SeriesOverview := OutputArraySO%A_Index%
         IfInString, SeriesOverview, &#44`;
            StringReplace, SeriesOverview, SeriesOverview, &#44`;, `,, All
         If not SeriesOverview
            SeriesOverview = (No show description provided)
         MsgBox, 3, Which show do you want?, %SeriesName%`n`n%SeriesOverview%
         IfMsgBox, Yes
            Break
         IfMsgBox, No
         {
            NoCount = %A_Index%
            If NoCount = %SeriesNameNodeCount%
            {
               SeriesName =
               SeriesIDNum =
               MsgBox, 0, Fatal Error!, No more show name suggestions provided!`n`nI will use the show name parsed from the filename and move on to the next row...
            }
         }
         IfMsgBox, Cancel
            Return
      }
   }
   finish:
   If not SeriesName
      SeriesName = %ShowName%
   FileDelete, Series_ID.xml
   Data = %SeriesName%,%SeriesIDNum%
   Return Data
}

;Provide the "TVDB series ID", "season number" and "episode number" and this will return the matching TVDB season number,episode number, and episode title as a CSV (3,1,The Day After)
GetTVDBEpisodes(SeriesIDNum, SeasonNum, EpisodeNum)
{
   IfExist, Episode_Info.xml
      FileDelete, Episode_Info.xml
   UrlDownloadToFile, http://www.thetvdb.com/api/563E39CDC7F666DF/series/%SeriesIDNum%/default/%SeasonNum%/%EpisodeNum%/en.xml, Episode_Info.xml
   XPath_Load(xml, "Episode_Info.xml")
   SeasonNumber := XPath(xml, "/Data/Episode/SeasonNumber/text()")
   EpisodeNumber := XPath(xml, "/Data/Episode/EpisodeNumber/text()")
   EpisodeTitle := XPath(xml, "/Data/Episode/EpisodeName/text()")
   FileDelete, Episode_Info.xml
   If not SeasonNumber
      SeasonNumber = %SeasonNum%
   If not EpisodeNumber
      EpisodeNumber = %EpisodeNum%
   IfInString, EpisodeTitle, ?
      StringReplace, EpisodeTitle, EpisodeTitle, ?,, All
   GuiControlGet, PadZero, , Zero
   If PadZero = 1
   {
      SeasonLen := StrLen(SeasonNumber)
      EpisodeLen := StrLen(EpisodeNumber)
      ;If SeasonLen = 1
       ;  SeasonNumber = 0%SeasonNumber%
      If EpisodeLen = 1
         EpisodeNumber = 0%EpisodeNumber%
   }
   K = %SeasonNumber%,%EpisodeNumber%,%EpisodeTitle%
   Return K
}


Any feedback would be great, I haven't really done anything like this before, and I'm sure I have made some mistakes


I think it looks fine Smile ... as long as it works who cares how pretty it is. Like my father always told me, theres more than one way to skin a cat.

On topic, Im working on optimizing how show names are retreived in an effort to speed things up and to (potentially) reduce the number of queries against TheTVDB. This is going to involve a nicer show selection method when multiple shows are returned. Thanks for the ideas and kind words, ashius!
Back to top
View user's profile Send private message
ashius



Joined: 20 Oct 2009
Posts: 3

PostPosted: Mon Oct 26, 2009 8:14 am    Post subject: Reply with quote

Nice, I am looking forward to checking out the new changes. I don't how how you plan on speeding the process the up, it will be interesting to see.

I have been plugging away at the Rules idea. I have fleshed it out further:
-GUI for editing rules
-Rule removal
-Added a Button for setting a Default scanning folder.

Wow doesn't really seem a lot when it is put in bullet points Razz

Anyway here is the code:

Code:

; SceneRenamer by strictlyfocused02
;
; AutoHotkey Version: 1.0.48+
;
; Script Function:
;   Extracts season and episode info from the filename
;   and uses that to retreive info from TheTVDB.com to rename
;   the file to a user-specified format

;   Special thanks to TheTVDB.com
;   This project would not have been possible without their top-notch API

#Include xpath.ahk

#NoEnv
SendMode, Input
SetWorkingDir, %A_ScriptDir%
;check for rules.ini and create if it doesnt exist
IfNotExist, rules.ini
   Blank =
   IniWrite,%Blank%, rules.ini, Rules, AllRuleNames
;Get the default folder
IniRead,DefaultTargetFolder, rules.ini, DefaultFolder, Folder

MainGUI:
Gui, Destroy
Gui, Add, Button, Default gButtonAddFolder, &Add folder
Gui, Add, Button, x+20 gButtonAddFile, Add &file
Gui, Add, Button, x+20 gButtonClear, &Clear list
Gui, Add, Button, x+20 gButtonDefaultRenameFolder, &Default Rename Folder ;Addtional button for scaning the default folder
Gui, Add, Button, x+20 ButtonAddRule, Add &Rule ; Add rule button
Gui, Add, Button, x+20 ButtonEditRules, &Edit Rules ; Edit rule button
Gui, Add, Button, x+60 gButtonSetDefaultFolder, &Set Default Folder ; Edit rule button



Gui, Add, ListView, xm r25 w800 vMyListView, Name|Preview|Directory|Extension|TVDB Series ID No|Show Name|FileName ;Added collum for getting the selected Show Name

Gui, Add, DropDownList, y+7 w250 AltSubmit vNameScheme, (Show Title) - (SS)x(EE) - (Episode Title)||(Show Title) - S(SS)E(EE) - (Episode Title)|(SS)x(EE) - Episode Title|S(SS)E(EE) - (Episode Title)
Gui, Add, Checkbox, x+30 Checked vZero, Pad with zero?
Gui, Add, Button, x+200 gButtonGetTVDBInfo, &Get TVDB Info
Gui, Add, Button, x+60 gButtonRename, &Rename files

Menu, MyContextMenu, Add, Open, ContextOpenFile
Menu, MyContextMenu, Add, Properties, ContextProperties
Menu, MyContextMenu, Add, Remove item, ContextRemoveItem

Gui, Show
Gosub, ButtonDefaultRenameFolder ;This is so it starts scaning once opened
Return



GuiClose:
   ExitApp

GuiContextMenu:
   If A_GuiControl <> MyListView
       Return
   Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY%
   Return

ButtonSetDefaultFolder:
   FocusedRowNumber := LV_GetNext(0, "F")
   LV_GetText(LVFileDir, FocusedRowNumber, 3)
   msgbox, 4, Set Default Directory, Set %LVFileDir% as the default directory for scanning? `nThis will make SceneRenamer scan this folder on start.
   Ifmsgbox yes
      IniWrite,%LVFileDir%, rules.ini, DefaultFolder, Folder
Return
   
;Add new rule to the rules.ini
ButtonAddRule:
   ;Get information on the Selected show
   FocusedRowNumber := LV_GetNext(0, "F")
   LV_GetText(PatternShowName, FocusedRowNumber, 7)
   LV_GetText(ShowName, FocusedRowNumber, 6)
   LV_GetText(SeriesIDNum, FocusedRowNumber, 5)

   IniRead, AllRuleNames, rules.ini, Rules, AllRuleNames
   ;Check the rule doesnt already exist
   Loop, Parse, AllRuleNames, |
      {
         thisRule = %A_LoopField%
         if thisRule = %PatternShowName%
         {
            Msgbox %PatternShowName% already has a rule
            Return
         }
      }
   IniWrite, %AllRuleNames%%PatternShowName%|, rules.ini, Rules, AllRuleNames
   IniWrite, %ShowName%, rules.ini, %PatternShowName%, SeriesName
   IniWrite, %SeriesIDNum%, rules.ini, %PatternShowName%, SeriesIDNum
   Return
   
   
ContextOpenFile:
ContextProperties:
   FocusedRowNumber := LV_GetNext(0, "F")
   If not FocusedRowNumber
      return
   LV_GetText(FileName, FocusedRowNumber, 1)
   LV_GetText(FileDir, FocusedRowNumber, 3)
   IfInString A_ThisMenuItem, Open
      Run %FileDir%\%FileName%,, UseErrorLevel
   Else
      Run Properties "%FileDir%\%FileName%",, UseErrorLevel
   If ErrorLevel
      MsgBox Could not perform requested action on "%FileDir%\%FileName%".
   return
   
ContextRemoveItem:
   RowNumber = 0
   Loop
   {
      RowNumber := LV_GetNext(RowNumber - 1)
      If not RowNumber
           Break
      LV_Delete(RowNumber)
   }
   Return

ButtonAddFolder:
   Gui +OwnDialogs
   FileSelectFolder, TargetFolder,, 3, Select a folder:
   If not TargetFolder  ; The user pressed cancel
       Return
   StringRight, LastChar, TargetFolder, 1
   If LastChar = \
      StringTrimRight, TargetFolder, TargetFolder, 1
   GuiControl, -Redraw, MyListView ; Improves performance by disabling redrawing
   Loop %TargetFolder%\*.*
   {
      FileName := A_LoopFileFullPath
      SplitPath, FileName,,, FileExt  ; Get the file extension
      If FileExt in avi,mkv,mp4
         LV_Add(Row, A_LoopFileName, "", A_LoopFileDir, FileExt)
   }
   GuiControl, +Redraw, MyListView  ; Turn redrawing back on
   LV_ModifyCol()  ; Resize each column to fit
   LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
   LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
   LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   Return

   ;Auto load a default folder and scan it
ButtonDefaultRenameFolder:
   If DefaultTargetFolder = ERROR
      Return
   Else
   ;Check a file exists before running Default scan
   IfExist, %DefaultTargetFolder%*.avi
      avi = 1
   IfExist, %DefaultTargetFolder%*.mkv
      mkv = 1
   IfExist, %DefaultTargetFolder%*.mp4
      mp4 = 1
   If (mkv = "" AND avi = "" AND mp4 = "")
      Return
   TargetFolder :=  DefaultTargetFolder
   ;TargetFolder = "\\SPOON\Downloads\TV Rename"
   Loop %TargetFolder%\*.*
   {
      FileName := A_LoopFileFullPath
      SplitPath, FileName,,, FileExt  ; Get the file extension
      If FileExt in avi,mkv,mp4
         LV_Add(Row, A_LoopFileName, "", A_LoopFileDir, FileExt)
   }
   GuiControl, +Redraw, MyListView  ; Turn redrawing back on
   LV_ModifyCol()  ; Resize each column to fit
   LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
   LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
   LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   Gosub, ButtonGetTVDBInfo
   Return
   
   
   
ButtonAddFile:
   Gui +OwnDialogs
   FileSelectFile, TargetFile
   If not TargetFile
      Return
   SplitPath, TargetFile,,, FileExt  ; Get the file extension
   If FileExt in avi,mkv,mp4
   {
      SplitPath, TargetFile, FileName, TargetFolder
      LV_Add(Row, FileName, "", TargetFolder, FileExt)
      LV_ModifyCol()  ; Resize each column to fit
      LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
      LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
      LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   }
   Return

ButtonClear:
   TargetFolder =
   LV_Delete()
   Return

ButtonGetTVDBInfo:
   LV_GetText(LVFileName, 1, 1)  ; Get the filename
   If not LVFileName
   {
      MsgBox, 0,Fatal Error!, You must select a file or folder before connecting to TheTVDB.com!
      Return
   }
   Loop
   {
      RowNumber = %A_Index%
      LV_GetText(LVFileName, RowNumber, 1)  ; Get the filename
      If not LVFileName  ; Break the loop at the end of the list
         Break
      LV_GetText(LVFileDir, RowNumber, 3)  ; Get the file directory
      LV_GetText(LVFileExt, RowNumber, 4)  ; Get the file extension
      ShowInfo := GetTVDBShows(GetShowName(LVFileName))
      StringSplit, OutputArray, ShowInfo, `,
      ShowName = %OutputArray1%
      SeriesIDNo = %OutputArray2%
      SeasonNumber := GetSeasonNumber(LVFileName)
      EpisodeNumber := GetEpisodeNumber(LVFileName)
      If SeriesIDNo
      {
         EpisodeInfo := GetTVDBEpisodes(SeriesIDNo, SeasonNumber, EpisodeNumber)
         StringSplit, OutputArray, EpisodeInfo, `,
         SeasonNumber = %OutputArray1%
         EpisodeNumber = %OutputArray2%
         EpisodeTitle = %OutputArray3%
      }
      GuiControlGet, NamingScheme,, NameScheme
      If NamingScheme = 1
      {
         If EpisodeTitle
            NewFileName = %ShowName% - %SeasonNumber%x%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = %ShowName% - %SeasonNumber%x%EpisodeNumber%.%LVFileExt%
      }
      Else if NamingScheme = 2
      {
         If EpisodeTitle
            NewFileName = %ShowName% - S%SeasonNumber%E%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = %ShowName% - S%SeasonNumber%E%EpisodeNumber%.%LVFileExt%
      }
      Else If NamingScheme = 3
      {
         If EpisodeTitle
            NewFileName = %SeasonNumber%x%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = %SeasonNumber%x%EpisodeNumber%.%LVFileExt%
      }
      Else If NamingScheme = 4
      {
         If EpisodeTitle
            NewFileName = S%SeasonNumber%E%EpisodeNumber% - %EpisodeTitle%.%LVFileExt%
         Else
            NewFileName = S%SeasonNumber%E%EpisodeNumber%.%LVFileExt%
      }
      LV_Modify(RowNumber, Col1, LVFileName, NewFileName, LVFileDir, LVFileExt, SeriesIDNo, ShowName, PatternShowName)
      LV_ModifyCol()
      LV_ModifyCol(4, 60)
      LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   }
   Return

ButtonRename:
   Loop
   {
      RowNumber = %A_Index%
      LV_GetText(LVFileName, RowNumber, 1)  ; Get the original filename
      If not LVFileName  ; Break the loop at the end of the list
         Break
      LV_GetText(LVNewFileName, RowNumber, 2)  ; Get the new filename
      FileMove, %TargetFolder%\%LVFileName%, %TargetFolder%\%LVNewFileName%
   }
   RenameCount := RowNumber - 1
   MsgBox, 0, Success!, %RenameCount% files have been renamed!`n`nRefreshing file list...
   LV_Delete()
   Loop %TargetFolder%\*.*
   {
      FileName := A_LoopFileFullPath
      If not FileName
         Break
      SplitPath, FileName,,, FileExt  ; Get the file extension
      If FileExt in avi,mkv,mp4
         LV_Add(Row, A_LoopFileName, "", A_LoopFileDir, FileExt)
   }
   GuiControl, +Redraw, MyListView  ; Turn redrawing back on
   LV_ModifyCol()  ; Resize each column to fit
   LV_ModifyCol(2, 60)  ; Expand "Preview" to keep the header visible
   LV_ModifyCol(4, 60)  ; Expand "Extension" to keep the header visible
   LV_ModifyCol(5, 110)  ; Expand "TVDB Series ID No" to keep the header visible
   Return

;Provide a filename (greek.s01e01.avi) and this will hopefully detect and return the show name
GetShowName(FileName)
{
   IfInString, FileName, .
      StringReplace, NormalName, FileName, ., %A_Space%, All
   IfInString, NormalName, _
      StringReplace, NormalName, NormalName, _, %A_Space%, All
   If RegExMatch(NormalName, "i)s[0-9][0-9]? ?e[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, SeasonAndEpisodePos, NormalName, %SeasonAndEpisode%
      StringLeft, ShowName, NormalName, (SeasonAndEpisodePos - 1)
   }
   Else If RegExMatch(NormalName, "i)[0-9][0-9]?x[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, SeasonAndEpisodePos, NormalName, %SeasonAndEpisode%
      StringLeft, ShowName, NormalName, (SeasonAndEpisodePos - 1)
   }
   Else If RegExMatch(NormalName, "[0-9][0-9][0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, SeasonAndEpisodePos, NormalName, %SeasonAndEpisode%
      StringLeft, ShowName, NormalName, (SeasonAndEpisodePos - 1)
   }
   Loop
   {
      StringRight, LastChar, ShowName, 1
      If (LastChar = "-" or LastChar = " ")
         StringTrimRight, ShowName, ShowName, 1
      Else
         Break
   }
   AutoTrim, off
   global PatternShowName = ShowName
   Return ShowName
   
}

;Provide a filename (greek.s01e01.avi) and this will hopefully detect and return the season number
GetSeasonNumber(FileName)
{
   If RegExMatch(FileName, "i)s\K[0-9][0-9]?.?e[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, EPos, SeasonAndEpisode, e
      StringLeft, SeasonNumber, SeasonAndEpisode, %EPos%
      IfInString, SeasonNumber, .
         StringTrimRight, SeasonNumber, SeasonNumber, 1
      IfInString, SeasonNumber, 0
      {
         StringGetPos, ZeroLoc, SeasonNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, SeasonNumber, SeasonNumber, 1
      }
         
   }
   Else If RegExMatch(FileName, "i)[0-9][0-9]?x[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, XPos, SeasonAndEpisode, x
      StringLeft, SeasonNumber, SeasonAndEpisode, %XPos%
      IfInString, SeasonNumber, 0
      {
        StringGetPos, ZeroLoc, SeasonNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, SeasonNumber, SeasonNumber, 1
      }
   }
   Else If RegExMatch(FileName, "[0-9][0-9][0-9][0-9]?", SeasonAndEpisode)
   {
      StringTrimRight, SeasonNumber, SeasonAndEpisode, 2
      IfInString, SeasonNumber, 0
      {
         StringGetPos, ZeroLoc, SeasonNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, SeasonNumber, SeasonNumber, 1
      }
   }
   Return SeasonNumber
}

;Provide a filename (greek.s01e01.avi) and this will hopefully detect and return the episode number
GetEpisodeNumber(FileName)
{
   If RegExMatch(FileName, "i)s\K[0-9][0-9]?.?e[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, EPos, SeasonAndEpisode, e
      StringRight, EpisodeNumber, SeasonAndEpisode, %EPos%
      IfInString, EpisodeNumber, e
         StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      IfInString, EpisodeNumber, 0
      {
         StringGetPos, ZeroLoc, EpisodeNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      }
   }
   Else If RegExMatch(FileName, "i)[0-9][0-9]?x[0-9][0-9]?", SeasonAndEpisode)
   {
      StringGetPos, XPos, SeasonAndEpisode, x
      StringRight, EpisodeNumber, SeasonAndEpisode, %XPos%
      IfInString, EpisodeNumber, 0
      {
         StringGetPos, ZeroLoc, EpisodeNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      }
   }
   Else If RegExMatch(FileName, "[0-9][0-9][0-9][0-9]?", SeasonAndEpisode)
   {
      StringRight, EpisodeNumber, SeasonAndEpisode, 2
      IfInString, EpisodeNumber, 0
      {
         StringGetPos, ZeroLoc, EpisodeNumber, 0
         If ZeroLoc = 0
            StringTrimLeft, EpisodeNumber, EpisodeNumber, 1
      }
   }
   Return EpisodeNumber
}


;Provide a show name (greek) and it will return the TVDB data for the show name (Greek) and series ID (80301) as a CSV (Greek,80301)
GetTVDBShows(ShowName)
{
;Check the rules.ini for a match
   IniRead, AllRuleNames, rules.ini, Rules, AllRuleNames
   Loop, Parse, AllRuleNames, |
   {
      thisRule = %A_LoopField%
      
      ;Continue on if there is no rule
      if (thisRule = "ERROR") or (thisRule = "")
      {
         Continue
      }
      if (thisRule = ShowName)
      {
      IniRead, SeriesName, rules.ini, %thisRule%, SeriesName
      IniRead, SeriesIDNum, rules.ini, %thisRule%, SeriesIDNum
      ;Jump to the end of GetTVDBShows if match is found in rules.
      goto finish
      }
   }
;Check for match online
   IfExist, Series_ID.xml
      FileDelete, Series_ID.xml
   UrlDownloadToFile, http://www.thetvdb.com/api/GetSeries.php?seriesname="%ShowName%", Series_ID.xml
   XPath_Load(xml, "Series_ID.xml")
   SeriesNameNodeCount := XPath(xml, "/Data/Series/SeriesName/Count()")
   If SeriesNameNodeCount = 1
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
   }
   Else If SeriesNameNodeCount >= 2
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
      SeriesOverview := XPath(xml, "/Data/Series/Overview/text()")
      StringSplit, OutputArraySID, SeriesIDNum, `,
      StringSplit, OutputArraySN, SeriesName, `,
      StringSplit, OutputArraySO, SeriesOverview, `,
     Loop, %SeriesNameNodeCount%
      {
         SeriesIDNum := OutputArraySID%A_Index%
         SeriesName := OutputArraySN%A_Index%
         SeriesOverview := OutputArraySO%A_Index%
         IfInString, SeriesOverview, &#44`;
            StringReplace, SeriesOverview, SeriesOverview, &#44`;, `,, All
         If not SeriesOverview
            SeriesOverview = (No show description provided)
         MsgBox, 3, Which show do you want?, %SeriesName%`n`n%SeriesOverview%
         IfMsgBox, Yes
         Break
         IfMsgBox, No
         {
            NoCount = %A_Index%
            If NoCount = %SeriesNameNodeCount%
            {
               SeriesName =
               SeriesIDNum =
               MsgBox, 0, Fatal Error!, No more show name suggestions provided!`n`nI will use the show name parsed from the filename and move on to the next row...
            }
         }
         IfMsgBox, Cancel
            Return
      }
   }
   finish:
   If not SeriesName
      SeriesName = %ShowName%
   FileDelete, Series_ID.xml
   Data = %SeriesName%,%SeriesIDNum%
   Return Data
}

;Provide the "TVDB series ID", "season number" and "episode number" and this will return the matching TVDB season number,episode number, and episode title as a CSV (3,1,The Day After)
GetTVDBEpisodes(SeriesIDNum, SeasonNum, EpisodeNum)
{
   IfExist, Episode_Info.xml
      FileDelete, Episode_Info.xml
   UrlDownloadToFile, http://www.thetvdb.com/api/563E39CDC7F666DF/series/%SeriesIDNum%/default/%SeasonNum%/%EpisodeNum%/en.xml, Episode_Info.xml
   XPath_Load(xml, "Episode_Info.xml")
   SeasonNumber := XPath(xml, "/Data/Episode/SeasonNumber/text()")
   EpisodeNumber := XPath(xml, "/Data/Episode/EpisodeNumber/text()")
   EpisodeTitle := XPath(xml, "/Data/Episode/EpisodeName/text()")
   FileDelete, Episode_Info.xml
   If not SeasonNumber
      SeasonNumber = %SeasonNum%
   If not EpisodeNumber
      EpisodeNumber = %EpisodeNum%
   IfInString, EpisodeTitle, ?
      StringReplace, EpisodeTitle, EpisodeTitle, ?,, All
   GuiControlGet, PadZero, , Zero
   If PadZero = 1
   {
      SeasonLen := StrLen(SeasonNumber)
      EpisodeLen := StrLen(EpisodeNumber)
      ;If SeasonLen = 1
       ;  SeasonNumber = 0%SeasonNumber%
      If EpisodeLen = 1
         EpisodeNumber = 0%EpisodeNumber%
   }
   K = %SeasonNumber%,%EpisodeNumber%,%EpisodeTitle%
   Return K
}


ButtonEditRules:
Gui, 1: Destroy
Gui, 1: Add, ListView, x22 y30 w140 h340 AltSubmit vAllRules gSelectRule, Rules
Gui, 1: Add, Edit, x252 y70 w220 h20 vSeriesName,
Gui, 1: Add, Edit, x272 y110 w200 h20 vSeriesIDNum,
Gui, 1: Add, Text, x182 y70 w70 h20 , Series Name
Gui, 1: Add, Text, x182 y110 w90 h20 , TVDB ID Number
Gui, 1: Add, Button, x182 y320 w100 h30 gButtonSave, Save
Gui, 1: Add, Button, x352 y250 w100 h30 gButtonRemoveRule, Remove Rule
Gui, 1: Add, Button, x352 y320 w100 h30 gButtonCancel, Back
Gui, Add, Text, x182 y140 w290 h100 , `nSeries Name: Is the title that will be used in the file name.`n`nTVDB ID Number: Is used to get the episode names.
; Generated using SmartGUI Creator 4.0
Gui, Show, Edit Rules
gosub AllRules
Return

AllRules:
LV_Delete()
GuiControl, -Redraw, AllRules
IniRead, AllRuleNames, rules.ini, Rules, AllRuleNames
Loop, Parse, Allrulenames, |
   {
      If (A_LoopField = "")
         Break
      Else   
      LV_Add(Row,A_LoopField)
   }
LV_Modify(1, "Select")
LV_Modify(1, "Focus")
GuiControl, +Redraw, AllRules
gosub SelectRule
Return

SelectRule:
FocusedRowNumber := LV_GetNext(0, "F")
LV_GetText(RuleName, FocusedRowNumber)
IniRead, SeriesName, rules.ini, %RuleName%, SeriesName
IniRead, SeriesIDNum, rules.ini, %RuleName%, SeriesIDNum
GuiControl,, SeriesName, %SeriesName%
GuiControl,, SeriesIDNum, %SeriesIDNum%
Return

ButtonSave:
GuiControlGet, SeriesName
GuiControlGet, SeriesIDNum
IniWrite, %SeriesName%, rules.ini, %RuleName%, SeriesName
IniWrite, %SeriesIDNum%, rules.ini, %RuleName%, SeriesIDNum
Return

ButtonCancel:
Goto MainGUI
Return


ButtonRemoveRule:
   FocusedRowNumber := LV_GetNext(0, "F")
   LV_GetText(RemoveRule, FocusedRowNumber)
      Msgbox, 4, Confirm Rule Removal, Are you sure you want to remove the rule for %RemoveRule%
      IfMsgBox No
         Return
   IniRead, AllRuleNames, rules.ini, Rules, AllRuleNames
   Loop, Parse, AllRuleNames,|
   {
      if (A_LoopField = RemoveRule)
      {
         StringReplace, AllRuleNames, AllRuleNames, |%A_LoopField%|,|, UseErrorLevel
         If ErrorLevel = 0
         {
            StringReplace, AllRuleNames, AllRuleNames, %A_LoopField%|
         }
      IniDelete, rules.ini, %A_LoopField%
         
      }
   }
   IniWrite, %AllRuleNames%, rules.ini, Rules, AllRuleNames
gosub AllRules
Return


Edit - Forgot to add the code that checks if any video files are in the default folder before scanning.
Edit 2 - Fixed a mistake with the variables for adding rules. General clean-up.
Back to top
View user's profile Send private message
rednoah
Guest





PostPosted: Mon Oct 26, 2009 5:49 pm    Post subject: FileBot - The ultimate tv renamer Reply with quote

I've posted this before, but try FileBot, it's the ultimate tv renamer:

http://filebot.sourceforge.net

Works for pretty much anything, scene releases, anime, whatever. It's got a clean and efficient user interface and it will run on any platform. It's deployed via a single executable jar, or if you are really lazy you can launch it via Java Web Start directly from the homepage.
Back to top
strictlyfocused02



Joined: 21 Jan 2009
Posts: 63

PostPosted: Wed Oct 28, 2009 10:46 am    Post subject: Re: FileBot - The ultimate tv renamer Reply with quote

rednoah wrote:
I've posted this before, but try FileBot, it's the ultimate tv renamer:

http://filebot.sourceforge.net

Works for pretty much anything, scene releases, anime, whatever. It's got a clean and efficient user interface and it will run on any platform. It's deployed via a single executable jar, or if you are really lazy you can launch it via Java Web Start directly from the homepage.


But its so much more fun to code things yourself Laughing

Regardless, thanks for the heads-up about that app ... I may use some bits of it as "inspiration" haha
Back to top
View user's profile Send private message
Guest






PostPosted: Wed Oct 28, 2009 2:39 pm    Post subject: Re: FileBot - The ultimate tv renamer Reply with quote

strictlyfocused02 wrote:
But its so much more fun to code things yourself Laughing

Did you have a look at the episode naming system? You'll definitely like it. Wink
Back to top
strictlyfocused02



Joined: 21 Jan 2009
Posts: 63

PostPosted: Sun Nov 01, 2009 10:26 am    Post subject: Reply with quote

Okay, Im turning to you guys for help. Im re-writing a portion of the GetTVDBShows() function but I cannot for the life of me get the function to return the showname selected from the listview in Gui, 2. Heres what Im working with:

Code:
#Include xpath.ahk

#NoEnv
SendMode, Input
SetWorkingDir, %A_ScriptDir%

ShowInfo := GetTVDBShows("Greek")
MsgBox, ShowInfo = %ShowInfo%
ExitApp


;Provide a show name (greek) and it will return the TVDB data for the show name (Greek) and series ID (80301) as a CSV (Greek,80301)
GetTVDBShows(ShowName)
{
   IfExist, Series_ID.xml
      FileDelete, Series_ID.xml
   If not ShowName
   {
      MsgBox, 0, Fatal Error!, The ShowName variable is empty`n`nAborting query against TheTVDB.com
      Return
   }
   UrlDownloadToFile, http://www.thetvdb.com/api/GetSeries.php?seriesname="%ShowName%", Series_ID.xml
   XPath_Load(xml, "Series_ID.xml")
   FileDelete, Series_ID.xml
   SeriesNameNodeCount := XPath(xml, "/Data/Series/SeriesName/Count()")
   If SeriesNameNodeCount = 1
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
   }
   Else If SeriesNameNodeCount >= 2
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
      SeriesOverview := XPath(xml, "/Data/Series/Overview/text()")
      StringSplit, OutputArraySID, SeriesIDNum, `,
      StringSplit, OutputArraySN, SeriesName, `,
      StringSplit, OutputArraySO, SeriesOverview, `,
      Gui, 2: Default
      Gui, 2: +ToolWindow
      Gui, 2: Add, ListView, xm r10 w550, Show name|Show description|TVDB series ID no.
      Gui, 2: Add, Text, y+7
      Gui, 2: Add, Button, x+400, Select
      Gui, 2: Add, Button, x+15, Cancel
      Loop, %SeriesNameNodeCount%
      {
         SeriesIDNum := OutputArraySID%A_Index%
         SeriesName := OutputArraySN%A_Index%
         SeriesOverview := OutputArraySO%A_Index%
         IfInString, SeriesOverview, &#44`;
            StringReplace, SeriesOverview, SeriesOverview, &#44`;, `,, All
         If not SeriesOverview
            SeriesOverview = (No show description provided)
         LV_Add(Row, SeriesName, SeriesOverview, SeriesIDNum)
         LV_ModifyCol()
         LV_ModifyCol(3, 110)
         SeriesIDNum =
         SeriesName =
         SeriesOverview =
      }
      Gui, 2:Show,,Which Show?
      Gui, 2:+LastFound
      WinWaitClose
   }
   If not SeriesName
      SeriesName = %ShowName%
   J = %SeriesName%,%SeriesIDNum%
   Return J
}

2GuiEscape:
2GuiClose:
2ButtonCancel:
{
   Gui, 2: Destroy
   Return
}


Any help would be greatly appreciated!!
Back to top
View user's profile Send private message
strictlyfocused02



Joined: 21 Jan 2009
Posts: 63

PostPosted: Sat Nov 07, 2009 11:12 am    Post subject: Reply with quote

Im still working on figuring out a nice way to to return the selected choice in this example. I added a small bit that show the vars I need (TVDB Name and Series ID No) are retrievable I just cant figure out a way to get them back into the function Embarassed

Code:
#Include xpath.ahk

#NoEnv
SendMode, Input
SetWorkingDir, %A_ScriptDir%

ShowInfo := GetTVDBShows("Greek")
;MsgBox, ShowInfo = %ShowInfo%
ExitApp


;Provide a show name (greek) and it will return the TVDB data for the show name (Greek) and series ID (80301) as a CSV (Greek,80301)
GetTVDBShows(ShowName)
{
   IfExist, Series_ID.xml
      FileDelete, Series_ID.xml
   If not ShowName
   {
      MsgBox, 0, Fatal Error!, The ShowName variable is empty`n`nAborting query against TheTVDB.com
      Return
   }
   UrlDownloadToFile, http://www.thetvdb.com/api/GetSeries.php?seriesname="%ShowName%", Series_ID.xml
   XPath_Load(xml, "Series_ID.xml")
   FileDelete, Series_ID.xml
   SeriesNameNodeCount := XPath(xml, "/Data/Series/SeriesName/Count()")
   If SeriesNameNodeCount = 1
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
   }
   Else If SeriesNameNodeCount > 1
   {
      SeriesIDNum := XPath(xml, "/Data/Series/seriesid/text()")
      SeriesName := XPath(xml, "/Data/Series/SeriesName/text()")
      SeriesOverview := XPath(xml, "/Data/Series/Overview/text()")
      StringSplit, OutputArraySID, SeriesIDNum, `,
      StringSplit, OutputArraySN, SeriesName, `,
      StringSplit, OutputArraySO, SeriesOverview, `,
      Gui, 2: Default
      Gui, 2: +ToolWindow
      Gui, 2: Add, ListView, xm r10 w550, Show name|Show description|TVDB series ID no.
      Gui, 2: Add, Text, y+7
      Gui, 2: Add, Button, x+400, Select
      Gui, 2: Add, Button, x+15, Cancel
      Loop, %SeriesNameNodeCount%
      {
         SeriesIDNum := OutputArraySID%A_Index%
         SeriesName := OutputArraySN%A_Index%
         SeriesOverview := OutputArraySO%A_Index%
         IfInString, SeriesOverview, &#44`;
            StringReplace, SeriesOverview, SeriesOverview, &#44`;, `,, All
         If not SeriesOverview
            SeriesOverview = (No show description provided)
         LV_Add(Row, SeriesName, SeriesOverview, SeriesIDNum)
         LV_ModifyCol()
         LV_ModifyCol(3, 110)
         SeriesIDNum =
         SeriesName =
         SeriesOverview =
      }
      Gui, 2:Show,,Which Show?
      Gui, 2:+LastFound
      WinWaitClose
   }
   If not SeriesName
      SeriesName = %ShowName%
   J = %SeriesName%,%SeriesIDNum%
   Return J
}

2GuiEscape:
2GuiClose:
2ButtonCancel:
{
   Gui, 2: Destroy
   Return
}

2ButtonSelect:
{
   FocusedRowNumber := LV_GetNext(0, "F")
   If not FocusedRowNumber
   {
      MsgBox, 0, Warning!, You must select a show or press cancel!
      Return
   }
   LV_GetText(SeriesName, FocusedRowNumber, 1)
   LV_GetText(SeriesIDNum, FocusedRowNumber, 3)
   MsgBox, SeriesName = %SeriesName%`nSeriesIDNum = %SeriesIDNum%
   ;Gui, 2:Destroy
   Return
}
Back to top
View user's profile Send private message
skwire



Joined: 18 Jan 2006
Posts: 273
Location: Conway, Arkansas

PostPosted: Sat Nov 07, 2009 6:44 pm    Post subject: Reply with quote

The easiest way would be to just make those two variables global:

Code:
;Provide a show name (greek) and it will return the TVDB data for the show name (Greek) and series ID (80301) as a CSV (Greek,80301)
GetTVDBShows(ShowName)
{
    Global SeriesName, SeriesIDNum
    [...]
}


Also, if I may make a suggestion, make use of the unHTML() function when adding the preview filenames to the list.

Code:
LV_Modify(RowNumber, Col1, LVFileName, unHTML( NewFileName ), LVFileDir, LVFileExt, SeriesIDNo)


Great script...well written and easy to follow. =]
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
strictlyfocused02



Joined: 21 Jan 2009
Posts: 63

PostPosted: Sun Nov 08, 2009 9:39 am    Post subject: Reply with quote

skwire wrote:
The easiest way would be to just make those two variables global:

Code:
;Provide a show name (greek) and it will return the TVDB data for the show name (Greek) and series ID (80301) as a CSV (Greek,80301)
GetTVDBShows(ShowName)
{
    Global SeriesName, SeriesIDNum
    [...]
}


Also, if I may make a suggestion, make use of the unHTML() function when adding the preview filenames to the list.

Code:
LV_Modify(RowNumber, Col1, LVFileName, unHTML( NewFileName ), LVFileDir, LVFileExt, SeriesIDNo)


Great script...well written and easy to follow. =]


Thank you, skwire! That did the trick. Very Happy

Ive updated the main post with my now *much* improved version. Let me know what you guys think!
Back to top
View user's profile Send private message
marcusmpe



Joined: 27 Feb 2009
Posts: 2

PostPosted: Thu Nov 12, 2009 11:06 pm    Post subject: Great script thanks! Reply with quote

Great work! I ran into this quirky part today:
Code:
StringGetPos, XPos, SeasonAndEpisode, x
StringLeft, SeasonNumber, SeasonAndEpisode, %XPos%

I had a case where this did not correctly extract the episode number from the regular expression result. But here I look today and you've already fixed it! Nicely done.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2, 3, 4, 5  Next
Page 1 of 5

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group