File::TVShow::Organize - Perl module to move TVShow Files into their matching Show Folder on a media server.
VERSION 0.35
use File::TVShow::Organize; our $exceptionList = "S.W.A.T.2017:S.W.A.T 2017|Other:other"; my $obj = File::TVShow::Organize->new(); $obj->new_show_folder("/tmp/"); $obj->show_folder("/absolute/path/to/TV Shows"); if((!defined $obj->new_show_folder()) || (!defined $obj->show_folder())) { print "Verify your paths. Something in wrong\n"; exit; } # Create a hash for matching file name to Folders $obj->create_show_hash(); # Delete files are processing. $obj->delete(1); # Don't create sub Season folders under the root show name folder. # Instead just dump them all into the root folder $obj->season_folder(0); # Batch process a folder containing TVShow files $obj->process_new_shows(); # Report any file names which could not be handled automatically. $obj->were_there_errors(); #end of program
This module moves TV show files from the folder where they currently exist into the correct folder based on show name and season.
Folder structure: /base/folder/Castle -> Season1 -> Castle.S01E01.avi Season2 -> Castle.S02E01.avi Specials -> Castle.S00E01.avi
This season folder behaviour can be disabled by calling season_folder(0). In this case all files are simply placed under Castle without sorting into season folders.
Source files are renamed or deleted upon successful relocation. This depends on the state of delete(). The default is to rename the files and not to delete. See delete() for more details.
Possible uses might include moving the files from an original rip directory and moving them into the correct folder structure for media servers such as Plex or Kodi. Another use might be to sort shows that are already in a single folder and to move them to a season by season or Special folder struture for better folder management.
This module does not examine file encodings and only parses the initial file naming. "name.SXXEXX.*" anything after SXXEXX is ignored with the exception that files ending in ".done" are also ignored by the module. These files will have already been successfully processed in previous executions of code using this module.
Works on Mac OS and *nix systems.
Arguments: None or { Exeptions => 'MatchCase:DesiredValue'} $obj = File::TVShow::Organize->new(); $obj = File::TVShow::Organize->new({ Exceptions => 'MatchCase:DesiredValue' }) This subroutine creates a new object of type File::TVShow::Organize If Exceptions is passed to the method we load this data into a hash for later use to handle naming complications. E.G file: S.W.A.T.2017.S01E01.avi is not handled correctly by File::TVShow::Info so we need to know to handle this differently. Exceptions is an optional parameter and can be left out when calling new(). Currently Exceptions is a scalar string. Its format is "MatchCase:DesiredValue|MatchCase:DesiredValue"
Arguments: String: Note the format below is used as part of a regex check in the module. As such () should always be included at the start and end of the string. $obj->countries("(US|UK|AU)"); $obj->countries(); This subroutine sets the countries internal value and returns it. Default value: (UK|US) This allows the system to match against programs names such as Agent X US / Agent X (US) / Agent X and reference the same single folder
Arguments: None or String Set the path return undef is the path is invalid $obj->show_folder("/path/to/folder"); Return the path to the folder $obj->show_folder(); Always confirm this does not return undef before using. undef will be returned if the path is invalid. Also a valid "path/to/folder" will always return with the "/" having been appended. "path/to/folder/" This is where the TV Show Folder resides on the file system. If the path is invalid this would leave the internal value as being undef.
Arguments: None or String Set the path return undef is the path is invalid $obj->new_show_folder("/path/to/folder"); Return the path to the folder $obj->new_show_folder(); Always confirm this does not return undef before using. undef will be returned if the path is invalid. Also a valid "path/to/folder" will always return with the "/" having been appened. "path/to/folder/" This is where new files to be add to the TV Show store reside on the file system.
Arguments: None $obj->create_show_hash; This function creates a hash of show names with the correct path to store data based on the directories that are found in showFolder. Examples: Life on Mars (US) creates 3 keys which point to the same folder key: life on mars (us) => folder: Life on Mars (US) key: life on mars us => folder: Life on Mars (US) key: life on mars => folder: Life on Mars (US) However if there already exists a folder: "Life on Mars" and a folder "Life on Mars (US)" the following hash key:folder pairs will be created. Note that the folderis differ key: life on mars => folder: Life on Mars key: life on mars (us) => folder: Life on Mars (US) key: life on mars us => folder: Life on Mars (US) As such file naming relating to country of origin is important if you are moving versions of the same show based on country.
Arguments: None This function clears the ShowHash data so that create_show_hash can be run again before or after a folder change which might occur if show_folder() were to be set to a new folder.
Arguments: String $obj->show_path("Life on Mars US") returns the name of the folder "Life on Mars (US)" or undef if "Life on Mars US" does not exist as a key. No key will be found if there was no folder found when $obj->create_show_hash was called. Example: my $file = File::TVShow::Info->new("Life.on.Mars.(US).S01E01.avi"); # $file->{name} now contains "Life on Mars (US)" # $file->{season} now contains "01" my $dest = "/path/to/basefolder/" . $obj->show_path($file->{name}); result => $dest now cotains "/path/to/basefolder/Life on Mars (US)/" $dest = $obj->create_season_folder($dest,$file->{season}); result => $dest now contains "/path/to/basefolder/Life on Mars (US)/Season1/"
Arguments: None $obj->process_new_shows(); This function requires that $obj->show_folder("/absolute/path") and $obj->new_show_folder("/absoute/path") have already been called as their paths will be used in this function call. This is the main process for batch processing of a folder of show files. Hidden files, files ending in ".done" as well as directories are excluded from being processed. This function will process a single folder and no deeper if recursion is not enabled. If recursion is enabled it will process any sub folders that it finds from the initial folder.
Arguments: String, String, String The first arguement is the folder where the file is to be moved into The Second argument is the source folder where the new show file currently exists. The third argument is the file which is to be moved. $obj->move_show("/absolute/path/to/destintaion/folder/", "absolute/path/to/source/folder/", "file"); This function does the heavy lifting of actually moving the show file into the determined folder. This function is called by process_new_shows which does the work to determine the paths to folder and file. This function could be called on its own after you have verified "folder" and "file" It uses a system() call to rsync which always checks that the copy was successful. This function then checks the state of $obj->delete to determine if the processed file should be renamed "file.done" or should be removed using unlink(). Note delete(1) should be called before process_new_shows() if you wish to delete the processed file. By default the file is only renamed.
Arguments: None,0,1 $obj->delete return the current true or false state (1 or 0) $obj->delete(0) set delete to false $obj->delete(1) set delete to true Input should be 0 or 1. 0 being do not delete. 1 being delete. Set if we should delete source file after successfully moving it to the tv store or if we should rename it to $file.done The default is false and the file is simply renamed. Return undef if the varible passed to the function is not valid. Do not change the current state of delete.
Arguments None,0,1 $obj->recursion returns the current true or false state (1 or 0) $obj->recursion(0) set recursion to false $obj->recursion(1) set recursion to true This controls the behaviour of process_new_shows();
Arguments: None,0,1 $obj->season_folder return the current true or false state (1 or 0) $obj->season_folder(0) or season_folder(1) sets and returns the new value. $obj->season_folder() returns undef if the input is invalid and the internal state is unchanged. if(!defined $obj->season_folder("x")) { print "You passed and invalid value\n"; } The default is true.
Arguments: None $obj->were_there_errors; This should be called at the end of the program to report if any file names could not be handled correctly resulting in files not being processed. These missed files can then be manually moved or their show name can be added to the exceptionList variable. Remember to match the NAME preceeding SXX and to give the corrected name EG S.W.A.T.2017.SXX should get an entry such as: exceptionList = "S.W.A.T.2017:S.W.A.T 2017";
Arguments: String, Number The first argument is the current folder that the file should be moved to The second argument is the season number. $obj->create_season_folder("/absolute/path/to/show/folder/",$seasonNumber) This creates a folder within "/absolute/path/to/show/folder/" by calling make_path() returns the newly created path "absolute/path/to/show/folder/SeasonX/" or "/absolute/path/to/show/folder/Specials/" note: "/absolute/path/to/show/folder/" is not verified to be valid and is assumed to have been checked before being passed Based on SXX S01 creates Season1 S00 creates Specials
Arguments: None,0,1 $obj->verbose(); $obj->verbose(0); $obj->verbose(1); Return undef if passed an invalid imput and write to STDERR. Current value of verbose is not changed. Return 0 if verbose mode is off. Return 1 if verbose mode is on. This state is checked by create_season_folder(), move_show() This allows to system to give some user feedback on what is being done if you want to watch the module working.
#!/bin/perl use strict; use warnings; use File::TVShow::Organize; my $obj = File::TVShow::Organize->new(); $obj->new_show_folder("/tmp/"); $obj->show_folder("/absolute/path/to/TV Shows"); if((!defined $obj->new_show_folder()) || (!defined $obj->show_folder())) { print "Verify your paths. Something in wrong\n"; exit; } # Create a hash for matching file name to Folders $obj->create_show_hash(); # Don't create sub Season folders under the root show name folder. # Instead just dump them all into the root folder $obj->season_folder(0); # Batch process a folder containing TVShow files $obj->process_new_shows(); # Report any file names which could not be handled automatically. $obj->were_there_errors();
#!/bin/perl use strict; use warnings; use File::TVShow::Organize; my $obj = File::TVShow::Organize->new(); $obj->new_show_folder("/tmp/"); $obj->show_folder("/absolute/path/to/TV Shows"); if((!defined $obj->new_show_folder()) || (!defined $obj->show_folder())) { print "Verify your paths. Something in wrong\n"; exit; } # Create a hash for matching file name to Folders $obj->create_show_hash(); # Batch process first folder containing TVShow files $obj->new_show_folder("/tmp/"); $obj->process_new_shows(); # Batch process second folder containing TVShow files. $obj->new_show_folder("/tmp2/"); $obj->process_new_shows(); # Report any file names which could not be handled automatically. $obj->were_there_errors();
This has not been tested on a windows system and I expect it will not actually work.
I have not tested anycases where file names might be "showname.(US).(2003).S0XE0X.avi" as I have no such cases myself.
Adam Spann, <bans@cpan.org>
Copyright (C) 2018 by Adam Spann
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.12.4 or, at your option, any later version of Perl 5 you may have available.
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
To install File::TVShow::Organize, copy and paste the appropriate command in to your terminal.
cpanm
cpanm File::TVShow::Organize
CPAN shell
perl -MCPAN -e shell install File::TVShow::Organize
For more information on module installation, please visit the detailed CPAN module installation guide.