Option to specify filename pattern
This commit is contained in:
parent
b00e8a4305
commit
c5328f4057
@ -156,6 +156,14 @@ void printHelp() {
|
|||||||
std::cout << " --show-path show path, -p show path" << std::endl;
|
std::cout << " --show-path show path, -p show path" << std::endl;
|
||||||
std::cout << "\t\t\tPath of the directory with episodes" << std::endl;
|
std::cout << "\t\t\tPath of the directory with episodes" << std::endl;
|
||||||
std::cout << " --correct-path, -c\tThis is the correct path, stop asking me!" << std::endl;
|
std::cout << " --correct-path, -c\tThis is the correct path, stop asking me!" << std::endl;
|
||||||
|
std::cout << " --name-pattern pattern" << std::endl;
|
||||||
|
std::cout << "\t\t\tPattern to which change the file name. Possible sequences are:" << std::endl;
|
||||||
|
std::cout << "\t\t\t\t\%filename - original filename (without filetype extension)" << std::endl;
|
||||||
|
std::cout << "\t\t\t\t\%show - show name from thetvdb" << std::endl;
|
||||||
|
std::cout << "\t\t\t\t\%epname - episode name from thetvdb" << std::endl;
|
||||||
|
std::cout << "\t\t\t\t\%season - season number, possible to specify leading 0 like this: \%2season" << std::endl;
|
||||||
|
std::cout << "\t\t\t\t\%episode - episode number, possible to specify leading 0 like this: \%2season" << std::endl;
|
||||||
|
std::cout << "\t\t\tDefault pattern is \"$filename - $epname\"" << std::endl;
|
||||||
std::cout << " --trust, -t\t\tDon't ask whether the names are correct" << std::endl;
|
std::cout << " --trust, -t\t\tDon't ask whether the names are correct" << std::endl;
|
||||||
std::cout << " --linux, -x\t\tDon't replace characters characters that are illegal in Windows" << std::endl;
|
std::cout << " --linux, -x\t\tDon't replace characters characters that are illegal in Windows" << std::endl;
|
||||||
std::cout << " --lang language, -l language" << std::endl;
|
std::cout << " --lang language, -l language" << std::endl;
|
||||||
@ -211,3 +219,85 @@ std::string encodeUrl( const std::string &url ) {
|
|||||||
return encoded.str();
|
return encoded.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string compilePattern(const std::string &pattern, int season, int episode, const std::string &filename, const std::string &episodeName, const std::string &showName) {
|
||||||
|
std::string output;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < pattern.size(); i++ ) {
|
||||||
|
if( pattern[i] == '%' ) {
|
||||||
|
// if current character is % check if a pattern follows, otherwise put %
|
||||||
|
// check for numbers right after % indicating size of zero padding for numbers
|
||||||
|
auto pos = pattern.find_first_not_of("0123456789", i+1);
|
||||||
|
|
||||||
|
if( pattern.find( "season", pos - 1 ) == pos ) {
|
||||||
|
// if season is AFTER numbers, put season number padded
|
||||||
|
// with zeros
|
||||||
|
|
||||||
|
// get number of leading zeros
|
||||||
|
auto leading = std::atoi( pattern.c_str() + i + 1 );
|
||||||
|
// move i to the last char of 'season'
|
||||||
|
i = pos + 5;
|
||||||
|
auto season_num = std::to_string(season);
|
||||||
|
|
||||||
|
// get number of zeros to be put before the season number
|
||||||
|
leading -= season_num.size();
|
||||||
|
if( leading < 0 )
|
||||||
|
leading = 0;
|
||||||
|
|
||||||
|
// add padded season to output
|
||||||
|
output += std::string(leading, '0') + season_num;
|
||||||
|
} else if ( pattern.find( "season", i ) == i + 1 ) {
|
||||||
|
// if season isn't after numbers, just put season number to output
|
||||||
|
i += 6;
|
||||||
|
output += std::to_string(season);
|
||||||
|
} else if ( pattern.find( "episode", pos - 1 ) == pos ) {
|
||||||
|
// same principle as with season after number
|
||||||
|
auto leading = std::atoi( pattern.c_str() + i + 1 );
|
||||||
|
|
||||||
|
i = pos + 6;
|
||||||
|
auto ep_num = std::to_string(episode);
|
||||||
|
|
||||||
|
leading -= ep_num.size();
|
||||||
|
if( leading < 0 )
|
||||||
|
leading = 0;
|
||||||
|
|
||||||
|
output += std::string(leading, '0') + ep_num;
|
||||||
|
} else if ( pattern.find( "episode", i ) == i + 1 ) {
|
||||||
|
// if episode isn't after number, just put the episode number to output
|
||||||
|
i += 7;
|
||||||
|
output += std::to_string(episode);
|
||||||
|
} else if ( pattern.find( "epname", i ) == i + 1 ) {
|
||||||
|
// episode name from thetvdb
|
||||||
|
i += 6;
|
||||||
|
output += episodeName;
|
||||||
|
} else if ( pattern.find( "show", i ) == i + 1 ) {
|
||||||
|
// show name from thetvdb
|
||||||
|
i += 4;
|
||||||
|
output += showName;
|
||||||
|
} else if ( pattern.find( "filename", i ) == i + 1 ) {
|
||||||
|
// original file name
|
||||||
|
i += 8;
|
||||||
|
output += filename;
|
||||||
|
} else {
|
||||||
|
// output % if no escape sequence was found
|
||||||
|
output += '%';
|
||||||
|
}
|
||||||
|
} else if ( pattern[i] == '\\' ) {
|
||||||
|
// possibility to escape %
|
||||||
|
if( pattern[i+1] == '%' ) {
|
||||||
|
output += '%';
|
||||||
|
i++;
|
||||||
|
} else if ( pattern[i+1] == '\\' ) {
|
||||||
|
output += '\\';
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
output += '\\';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if char isn't % or / just add it to the output string
|
||||||
|
output += pattern[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -22,5 +22,6 @@ void printLangs();
|
|||||||
bool findLanguage( const char *language );
|
bool findLanguage( const char *language );
|
||||||
|
|
||||||
std::string encodeUrl( const std::string &url );
|
std::string encodeUrl( const std::string &url );
|
||||||
|
std::string compilePattern(const std::string &pattern, int season, int episode, const std::string &filename, const std::string &episodeName, const std::string &showName);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
17
main.cpp
17
main.cpp
@ -4,7 +4,7 @@
|
|||||||
#include "functions.hpp"
|
#include "functions.hpp"
|
||||||
#include "tv_rename.hpp"
|
#include "tv_rename.hpp"
|
||||||
|
|
||||||
int parseCommandLine(std::string &show, std::set<int> &seasons_num, std::string &path, bool &change_dir, std::string &language, bool &linux, bool &trust, int argc, char **argv) {
|
int parseCommandLine(std::string &show, std::set<int> &seasons_num, std::string &path, bool &change_dir, std::string &language, std::string &pattern, bool &linux, bool &trust, int argc, char **argv) {
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"show", required_argument, 0, 's' },
|
{"show", required_argument, 0, 's' },
|
||||||
{"season", required_argument, 0, 'n' },
|
{"season", required_argument, 0, 'n' },
|
||||||
@ -14,12 +14,13 @@ int parseCommandLine(std::string &show, std::set<int> &seasons_num, std::string
|
|||||||
{"linux", no_argument, 0, 'x' },
|
{"linux", no_argument, 0, 'x' },
|
||||||
{"lang", required_argument, 0, 'l' },
|
{"lang", required_argument, 0, 'l' },
|
||||||
{"print-langs", no_argument, 0, '0' },
|
{"print-langs", no_argument, 0, '0' },
|
||||||
|
{"name-pattern", required_argument, 0, '1' },
|
||||||
{"help", no_argument, 0, 'h' }
|
{"help", no_argument, 0, 'h' }
|
||||||
};
|
};
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
int option_index{0};
|
int option_index{0};
|
||||||
auto c = getopt_long(argc, argv, "s:n:cp:txl:0h", long_options, &option_index);
|
auto c = getopt_long(argc, argv, "s:n:cp:txl:01:h", long_options, &option_index);
|
||||||
if( c == -1 )
|
if( c == -1 )
|
||||||
break;
|
break;
|
||||||
switch(c) {
|
switch(c) {
|
||||||
@ -58,6 +59,9 @@ int parseCommandLine(std::string &show, std::set<int> &seasons_num, std::string
|
|||||||
case 'h':
|
case 'h':
|
||||||
printHelp();
|
printHelp();
|
||||||
return 1;
|
return 1;
|
||||||
|
case '1':
|
||||||
|
pattern = optarg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -74,10 +78,11 @@ int main(int argc, char** argv) {
|
|||||||
std::string language{"en"};
|
std::string language{"en"};
|
||||||
bool linux{false};
|
bool linux{false};
|
||||||
bool trust{false};
|
bool trust{false};
|
||||||
|
std::string pattern{"%file - %epname"};
|
||||||
Curl c;
|
Curl c;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto tmp = parseCommandLine(show, seasons_num, path, change_dir, language, linux, trust, argc, argv);
|
auto tmp = parseCommandLine(show, seasons_num, path, change_dir, language, pattern, linux, trust, argc, argv);
|
||||||
if( tmp == -1 )
|
if( tmp == -1 )
|
||||||
return 1;
|
return 1;
|
||||||
else if ( tmp == 1 )
|
else if ( tmp == 1 )
|
||||||
@ -122,11 +127,11 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( seasons_num.size() == 1 ) {
|
if( seasons_num.size() == 1 ) {
|
||||||
singleSeason(path, show, *seasons_num.begin(), "", language, linux, trust, c);
|
singleSeason(path, show, *seasons_num.begin(), "", language, pattern, linux, trust, c);
|
||||||
} else if ( seasons_num.size() != 0 ) {
|
} else if ( seasons_num.size() != 0 ) {
|
||||||
multipleSeasons(path, show, seasons_num, language, linux, trust, c);
|
multipleSeasons(path, show, seasons_num, language, pattern, linux, trust, c);
|
||||||
} else {
|
} else {
|
||||||
allSeasons(path, show, language, linux, trust, c);
|
allSeasons(path, show, language, pattern, linux, trust, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ std::vector<std::string> parseEpisodeNames( const std::string &season_code, cons
|
|||||||
return episodes;
|
return episodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void singleSeason( const std::string &path, const std::string &show, int season, std::string url, const std::string &language, const bool &linux, const bool &trust, Curl &c, std::set<std::string> const *files) {
|
void singleSeason( const std::string &path, const std::string &show, int season, std::string url, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c, std::set<std::string> const *files) {
|
||||||
if( url.empty() )
|
if( url.empty() )
|
||||||
url = getDefUrl(show, language, c);
|
url = getDefUrl(show, language, c);
|
||||||
url += "/seasons/" + std::to_string(season);
|
url += "/seasons/" + std::to_string(season);
|
||||||
@ -93,7 +93,9 @@ void singleSeason( const std::string &path, const std::string &show, int season,
|
|||||||
num -= 1;
|
num -= 1;
|
||||||
if( num < episodes.size() ) {
|
if( num < episodes.size() ) {
|
||||||
auto pos = name.find_last_of('.');
|
auto pos = name.find_last_of('.');
|
||||||
name.insert(pos, " - " + episodes[num]);
|
// get desired filename
|
||||||
|
name = compilePattern(pattern, season, num+1, name.substr(0, pos), episodes[num], show) + name.substr(pos);
|
||||||
|
// replace characters illegal in windows if desired
|
||||||
if( !linux ) {
|
if( !linux ) {
|
||||||
season_code.erase(std::remove_if(name.begin(), name.end(), [](char x) {return x == '?' || x == '"' || x == '\\' || x == '|' || x == '*';}), season_code.end());
|
season_code.erase(std::remove_if(name.begin(), name.end(), [](char x) {return x == '?' || x == '"' || x == '\\' || x == '|' || x == '*';}), season_code.end());
|
||||||
size_t max{name.size()};
|
size_t max{name.size()};
|
||||||
@ -140,23 +142,23 @@ void singleSeason( const std::string &path, const std::string &show, int season,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void multipleSeasons( const std::string &path, const std::string &show, const std::map<int, std::set<std::string>> &seasons, const std::string &language, const bool &linux, const bool &trust, Curl &c) {
|
void multipleSeasons( const std::string &path, const std::string &show, const std::map<int, std::set<std::string>> &seasons, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c) {
|
||||||
auto url = getDefUrl(show, language, c);
|
auto url = getDefUrl(show, language, c);
|
||||||
for( const auto &x : seasons ) {
|
for( const auto &x : seasons ) {
|
||||||
singleSeason( path, show, x.first, url, language, linux, trust, c, &x.second);
|
singleSeason( path, show, x.first, url, language, pattern, linux, trust, c, &x.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void multipleSeasons( const std::string &path, const std::string &show, const std::set<int> seasons, const std::string &language, const bool &linux, const bool &trust, Curl &c) {
|
void multipleSeasons( const std::string &path, const std::string &show, const std::set<int> seasons, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c) {
|
||||||
std::map<int, std::set<std::string>> season_map;
|
std::map<int, std::set<std::string>> season_map;
|
||||||
findSeasons(season_map, path, seasons);
|
findSeasons(season_map, path, seasons);
|
||||||
multipleSeasons(path, show, season_map, language, linux, trust, c);
|
multipleSeasons(path, show, season_map, language, pattern, linux, trust, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void allSeasons( const std::string &path, const std::string &show, const std::string &language, const bool &linux, const bool &trust, Curl &c) {
|
void allSeasons( const std::string &path, const std::string &show, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c) {
|
||||||
std::map<int, std::set<std::string>> seasons;
|
std::map<int, std::set<std::string>> seasons;
|
||||||
//get all season number from this directory and subdirectories
|
//get all season number from this directory and subdirectories
|
||||||
iterateFS(seasons, path);
|
iterateFS(seasons, path);
|
||||||
multipleSeasons( path, show, seasons, language, linux, trust, c);
|
multipleSeasons( path, show, seasons, language, pattern, linux, trust, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include "network.hpp"
|
#include "network.hpp"
|
||||||
|
|
||||||
void singleSeason( const std::string &path, const std::string &show, int season, std::string url, const std::string &language, const bool &linux, const bool &trust, Curl &c, std::set<std::string> const *files=nullptr);
|
void singleSeason( const std::string &path, const std::string &show, int season, std::string url, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c, std::set<std::string> const *files=nullptr);
|
||||||
void multipleSeasons( const std::string &path, const std::string &show, const std::set<int> seasons, const std::string &language, const bool &linux, const bool &trust, Curl &c);
|
void multipleSeasons( const std::string &path, const std::string &show, const std::set<int> seasons, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c);
|
||||||
void allSeasons( const std::string &path, const std::string &show, const std::string &language, const bool &linux, const bool &trust, Curl &c);
|
void allSeasons( const std::string &path, const std::string &show, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user