diff --git a/databasewindow.cpp b/databasewindow.cpp index 7923030..cd1b142 100644 --- a/databasewindow.cpp +++ b/databasewindow.cpp @@ -11,7 +11,7 @@ DatabaseWindow::~DatabaseWindow() { std::cout << "Deleting" << std::endl; } -DatabaseWindow::DatabaseWindow( bool _linux, Curl &_c ) : c(_c), linux(_linux) { +DatabaseWindow::DatabaseWindow( bool _linux ) : linux(_linux) { set_title( "Database" ); set_default_size( 550, 350 ); @@ -48,13 +48,15 @@ DatabaseWindow::DatabaseWindow( bool _linux, Curl &_c ) : c(_c), linux(_linux) { row[m_columns_database.m_col_show] = x["SHOW"]; row[m_columns_database.m_col_path] = x["PATH"]; row[m_columns_database.m_col_lang] = x["LANGUAGE"]; - row[m_columns_database.m_col_url] = x["URL"]; + row[m_columns_database.m_col_show_id] = x["TVID"]; + row[m_columns_database.m_col_dvd] = x["DVD"]; } m_tree_database->append_column_editable( "Show", m_columns_database.m_col_show ); m_tree_database->append_column_editable( "Path", m_columns_database.m_col_path ); m_tree_database->append_column_editable( "Language", m_columns_database.m_col_lang ); - m_tree_database->append_column_editable( "URL", m_columns_database.m_col_url ); + m_tree_database->append_column_editable( "ID", m_columns_database.m_col_show_id ); + m_tree_database->append_column_editable( "DVD", m_columns_database.m_col_dvd ); m_button_save->signal_clicked().connect( sigc::mem_fun( *this, &DatabaseWindow::save ) ); @@ -73,13 +75,13 @@ void DatabaseWindow::save() { auto index = static_cast ( x[m_columns_database.m_col_id] ); if( changed_rows.find(index) != changed_rows.end() ) { auto index = static_cast< size_t > ( x[m_columns_database.m_col_id] ); - auto show = static_cast< std::string > ( x[m_columns_database.m_col_show] ); auto path = static_cast< std::string > ( x[m_columns_database.m_col_path] ); auto lang = static_cast< std::string > ( x[m_columns_database.m_col_lang] ); - auto url = static_cast< std::string > ( x[m_columns_database.m_col_url] ); - std::cout << index << " " << show << " " << path << " " << lang << " " << url << std::endl; - changeDB( index, path, lang, url, c ); - refreshSingleDB( index, linux, c ); + auto show_id = static_cast< std::string > ( x[m_columns_database.m_col_show_id] ); + bool dvd = static_cast< std::string > ( x[m_columns_database.m_col_dvd] ) == "1"; + std::cout << index << " " << path << " " << lang << " " << show_id << " " << dvd << std::endl; + changeDB( index, path, lang, show_id, dvd ); + refreshSingleDB( index, linux ); } } cleanDB(); diff --git a/databasewindow.hpp b/databasewindow.hpp index 4f5b4e2..5030346 100644 --- a/databasewindow.hpp +++ b/databasewindow.hpp @@ -19,7 +19,7 @@ class DatabaseWindow : public Gtk::Window { public: DatabaseWindow() = delete; - DatabaseWindow( bool _linux, Curl &_c); + DatabaseWindow( bool _linux ); virtual ~DatabaseWindow(); private: @@ -43,19 +43,20 @@ protected: add(m_col_show); add(m_col_path); add(m_col_lang); - add(m_col_url); + add(m_col_show_id); + add(m_col_dvd); } Gtk::TreeModelColumn< size_t > m_col_id; Gtk::TreeModelColumn< std::string > m_col_show; Gtk::TreeModelColumn< std::string > m_col_path; Gtk::TreeModelColumn< std::string > m_col_lang; - Gtk::TreeModelColumn< std::string > m_col_url; + Gtk::TreeModelColumn< std::string > m_col_show_id; + Gtk::TreeModelColumn< std::string > m_col_dvd; }; DatabaseColumns m_columns_database; Glib::RefPtr< Gtk::ListStore > m_model; - Curl &c; bool linux; }; diff --git a/functions.hpp b/functions.hpp index db2293a..dfcf5d0 100644 --- a/functions.hpp +++ b/functions.hpp @@ -29,22 +29,14 @@ using char_t = char; // CLI functions void printHelp(); -string encodeUrl( const string &url ); bool searchSeason( const char_t *const path, size_t &season_pos ); bool searchSeason( const char_t *const path, size_t &season_pos, size_t &ep_pos ); void parseSeasonNumbers( std::set< int > &seasons_num, const char_t *argument ); -string encodeUrl( const string &url ); - -#else -// GUI functions - -std::vector< std::pair< string, string > > -getPossibleShows( string show, const string &language ); - #endif // GUI +string encodeUrl( const string &url ); string userHome(); void prepareDB( const string &_pattern = TEXT( "" ) ); @@ -53,7 +45,7 @@ void addToDB( string &show, const string &path, const string &language, bool linux, bool dvd ); #else void addToDB( string &show, const string &path, const string &language, - const string &url, const string &pattern, bool linux, bool dvd ); + const string &id, const string &pattern, bool linux, bool dvd ); std::vector< std::unordered_map< std::string, std::string > > dbGetShows(); #endif void removeFromDB( const string &path ); diff --git a/gui.cpp b/gui.cpp index 2a78acc..ab6af9b 100644 --- a/gui.cpp +++ b/gui.cpp @@ -1,11 +1,16 @@ #include #include "mainwindow.hpp" +#include "tv_rename.hpp" + +#define API_KEY "42B66F5E-C6BF-423F-ADF9-CC97163472F6" int main( int argc, char **argv ) { auto app = Gtk::Application::create( argc, argv, "org.idonthaveanorganization.tvrename" ); + authenticate( API_KEY ); + MainWindow mw( app ); return app->run( mw ); diff --git a/mainwindow.cpp b/mainwindow.cpp index bf388d2..f126175 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -12,15 +12,6 @@ #include "databasewindow.hpp" #include "tv_rename.hpp" -constexpr std::array< const char *, 46 > languages{ - "en", "English", "sv", "Svenska", "no", "Norsk", "da", "Dansk", - "fi", "Suomeksi", "nl", "Nederlands", "de", "Deutsch", "it", "Italiano", - "es", "Español", "fr", "Français", "pl", "Polski", "hu", "Magyar", - "el", "Greek", "tr", "Turkish", "ru", "Russian", "he", "Hebrew", - "ja", "Japanese", "pt", "Portuguese", "zh", "Chinese", "cs", "Czech", - "sl", "Slovenian", "hr", "Croatian", "ko", "Korea" -}; - void MainWindow::chooseFile() { // create a dialog for choosing directory Gtk::FileChooserDialog dialog( "Select a directory", @@ -82,8 +73,8 @@ void MainWindow::process() { ( *m_combo_language->get_active() )[m_columns_language.m_col_code]; // fill up m_combo_possible with possible tv shows - auto possible_shows = getPossibleShows( - std::string( m_entry_show->get_text() ), language_code, c ); + auto possible_shows = searchShow( + std::string( m_entry_show->get_text() ), language_code ); // if no possible shows were found, tell the user if ( possible_shows.size() == 0 ) { @@ -100,20 +91,20 @@ void MainWindow::process() { m_combo_possible->show(); // fill up combo box with results from thetvdb - auto model = Gtk::ListStore::create( m_columns_url ); + auto model = Gtk::ListStore::create( m_columns_show ); m_combo_possible->set_model( model ); auto row = *( model->append() ); - row[m_columns_url.m_col_show] = possible_shows[0].first; - row[m_columns_url.m_col_url] = possible_shows[0].second; + row[m_columns_show.m_col_show] = possible_shows[0].first; + row[m_columns_show.m_col_id] = possible_shows[0].second; m_combo_possible->set_active( row ); for ( size_t i = 1; i < possible_shows.size(); i++ ) { auto row = *( model->append() ); - row[m_columns_url.m_col_show] = possible_shows[i].first; - row[m_columns_url.m_col_url] = possible_shows[i].second; + row[m_columns_show.m_col_show] = possible_shows[i].first; + row[m_columns_show.m_col_id] = possible_shows[i].second; } } @@ -161,15 +152,15 @@ void MainWindow::getNames() { */ void renameFiles( const std::vector< - std::pair< std::string, std::pair< std::string, std::string > > > + std::pair< std::pair< int, std::string >, std::pair< std::string, std::string > > > &renamed ) { for ( auto renamed_it = renamed.begin(); renamed_it != renamed.end(); ++renamed_it ) { - std::cout << renamed_it->first << "/" << renamed_it->second.first - << " --> " << renamed_it->first << "/" + std::cout << renamed_it->first.second << "/" << renamed_it->second.first + << " --> " << renamed_it->first.second << "/" << renamed_it->second.second << std::endl; - FSLib::rename( renamed_it->first + "/" + renamed_it->second.first, - renamed_it->first + "/" + renamed_it->second.second ); + FSLib::rename( renamed_it->first.second + "/" + renamed_it->second.first, + renamed_it->first.second + "/" + renamed_it->second.second ); } } @@ -180,17 +171,17 @@ void MainWindow::finishedSelection() { auto iter = m_combo_possible->get_active(); // debug output - std::cout << ( *iter )[m_columns_url.m_col_show] << " " << language_code + std::cout << ( *iter )[m_columns_show.m_col_show] << " " << language_code << std::endl; - std::string url = - static_cast< Glib::ustring >( ( *iter )[m_columns_url.m_col_url] ); + std::string show_id = + static_cast< Glib::ustring >( ( *iter )[m_columns_show.m_col_id] ); // shouldn't ever happen, but just to be sure - if ( url.empty() ) + if ( show_id.empty() ) return; - std::cout << "https://www.thetvdb.com" << url << std::endl; + std::cout << "https://www.thetvdb.com/series/" << show_id << std::endl; std::string input_pattern = m_entry_pattern->get_text(); @@ -204,11 +195,12 @@ void MainWindow::finishedSelection() { for ( auto &x : selected ) { // get renamed files for given season + // TODO dvd auto renamed_files = getRenamedFiles( - static_cast< Glib::ustring >( ( *iter )[m_columns_url.m_col_show] ), - x, "https://www.thetvdb.com" + url, language_code, + static_cast< Glib::ustring >( ( *iter )[m_columns_show.m_col_show] ), + x, show_id, language_code, ( input_pattern.empty() ? default_pattern : input_pattern ), - !m_check_linux->get_active(), c, files[x] ); + !m_check_linux->get_active(), files[x], false ); if ( renamed_files.empty() ) continue; @@ -401,10 +393,6 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr ) m_label_dir->set_label( "Directory:" ); m_label_pattern->set_label( "Pattern:" ); - // set dimensions - m_combo_language->set_size_request( 120 ); - m_combo_possible->set_size_request( 200 ); - m_entry_show->set_size_request( 170, 30 ); m_entry_dir->set_size_request( 170, 30 ); @@ -422,22 +410,22 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr ) auto model = Gtk::ListStore::create( m_columns_language ); m_combo_language->set_model( model ); - auto row = *( model->append() ); - row[m_columns_language.m_col_code] = "en"; - row[m_columns_language.m_col_language] = "English"; - - m_combo_language->set_active( row ); - - for ( size_t i = 2; i < languages.size(); i += 2 ) { - row = *( model->append() ); - row[m_columns_language.m_col_code] = languages[i]; - row[m_columns_language.m_col_language] = languages[i + 1]; + for ( const auto &x : getLangs() ) { + auto row = *( model->append() ); + row[m_columns_language.m_col_code] = x.first; + row[m_columns_language.m_col_language] = x.second; + if( x.first == "en" ) + m_combo_language->set_active( row ); } } // set column to be shown in comboboxes m_combo_language->pack_start( m_columns_language.m_col_language ); - m_combo_possible->pack_start( m_columns_url.m_col_show ); + m_combo_possible->pack_start( m_columns_show.m_col_show ); + + // set dimensions + m_combo_language->set_size_request( 120, 30 ); + m_combo_possible->set_size_request( 200, 30 ); // set signals m_button_dir->signal_clicked().connect( @@ -480,7 +468,7 @@ MainWindow::MainWindow( const Glib::RefPtr< Gtk::Application > &ptr ) } void MainWindow::dbUpdate() { - updateDB( !m_check_linux->get_active(), c ); + updateDB( !m_check_linux->get_active() ); } void MainWindow::dbClean() { @@ -488,7 +476,7 @@ void MainWindow::dbClean() { } void MainWindow::dbRefresh() { - refreshDB( !m_check_linux->get_active(), c ); + refreshDB( !m_check_linux->get_active() ); } void MainWindow::dbAdd() { @@ -508,18 +496,19 @@ void MainWindow::dbAdd() { auto iter = m_combo_possible->get_active(); std::string input_pattern = m_entry_pattern->get_text(); - std::string show = static_cast< Glib::ustring >( ( *iter )[m_columns_url.m_col_show] ); + std::string show = static_cast< Glib::ustring >( ( *iter )[m_columns_show.m_col_show] ); std::string language_code = static_cast< Glib::ustring >( ( *m_combo_language->get_active() )[m_columns_language.m_col_code] ); - std::string url = "https://www.thetvdb.com" + static_cast< Glib::ustring >( ( *iter )[m_columns_url.m_col_url] ); + std::string show_id = static_cast< Glib::ustring >( ( *iter )[m_columns_show.m_col_id] ); - std::cout << show << " " << language_code << " " << url << std::endl; + std::cout << show << " " << language_code << " " << show_id << std::endl; - addToDB( show, m_entry_dir->get_text(), language_code, url, - m_entry_pattern->get_text(), !m_check_linux->get_active(), c ); + // TODO dvd + addToDB( show, m_entry_dir->get_text(), language_code, show_id, + m_entry_pattern->get_text(), !m_check_linux->get_active(), false ); } void MainWindow::dbManage() { - auto *dbWindow = new DatabaseWindow( !m_check_linux->get_active(), c ); + auto *dbWindow = new DatabaseWindow( !m_check_linux->get_active() ); app->add_window( *dbWindow ); auto app_ptr = app; diff --git a/mainwindow.hpp b/mainwindow.hpp index 712f10d..d65db04 100644 --- a/mainwindow.hpp +++ b/mainwindow.hpp @@ -46,6 +46,8 @@ protected: Gtk::CheckButton *m_check_linux = new Gtk::CheckButton(); Gtk::CheckButton *m_check_trust = new Gtk::CheckButton(); + // TODO add dvd checkbox + Gtk::CheckButton *m_check_dvd = new Gtk::CheckButton(); Gtk::ComboBox *m_combo_language = new Gtk::ComboBox(); Gtk::ComboBox *m_combo_possible = new Gtk::ComboBox(); @@ -60,8 +62,6 @@ protected: Gtk::Label *m_label_dir = new Gtk::Label(); Gtk::Label *m_label_pattern = new Gtk::Label(); - Curl c; - class LanguageColumns : public Gtk::TreeModel::ColumnRecord { public: LanguageColumns() { @@ -72,24 +72,24 @@ protected: Gtk::TreeModelColumn< std::string > m_col_language; }; - class UrlColumns : public Gtk::TreeModel::ColumnRecord { + class ShowColumns : public Gtk::TreeModel::ColumnRecord { public: - UrlColumns() { - add( m_col_url ); + ShowColumns() { + add( m_col_id ); add( m_col_show ); } - Gtk::TreeModelColumn< Glib::ustring > m_col_url; + Gtk::TreeModelColumn< Glib::ustring > m_col_id; Gtk::TreeModelColumn< Glib::ustring > m_col_show; }; LanguageColumns m_columns_language; - UrlColumns m_columns_url; + ShowColumns m_columns_show; Glib::RefPtr< Gtk::Application > app; std::unique_ptr sw{nullptr}; std::vector< int > selected; - std::map< int, std::set< std::string > > files; + std::map< int, std::map< int, string > > files; std::string path; std::string language_code; std::string default_pattern; diff --git a/tv_rename.cpp b/tv_rename.cpp index 94e6f99..01a6a52 100644 --- a/tv_rename.cpp +++ b/tv_rename.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "filesystem.hpp" @@ -10,7 +11,6 @@ using json = nlohmann::json; #ifndef GUI -#include #include #include @@ -80,6 +80,7 @@ searchShow( const string &show, const string &language ) { return ret; } +#ifndef GUI // get show's ID string getShowId( string &show, const string &language ) { size_t order{}, pos{}; @@ -93,6 +94,7 @@ string getShowId( string &show, const string &language ) { cin.ignore( 1, '\n' ); return search_results[pos-1].second; } +#endif string showNameFromId( const string &id, const string &language ) { r.addHeader( TEXT( "Accept: application/json" ) ); @@ -240,12 +242,44 @@ getRenamedFiles( const string &show, int season, const string id, return renamed_files; } +std::vector< std::pair< string, string > > getLangs() { + std::vector< std::pair< string, string > > langs; + r.addHeader( TEXT( "Accept: application/json" ) ); + r.addHeader( TEXT( "Authorization: Bearer " ) + api_token ); + auto j = json::parse( r.get( TEXT( "/languages" ) ) ); + r.clearHeader(); + auto langs_json = j["data"].get< std::vector< json > >(); + for ( auto &x : langs_json ) { + langs.emplace_back( toString( x["abbreviation"].get< std::string >() ), + toString( x["name"].get< std::string >() ) ); + } + return langs; +} + +bool authenticate( const std::string &api_key ) { +#ifdef _WIN32 + r.setServer( TEXT( "api.thetvdb.com" ) ); +#else + r.setServer( "https://api.thetvdb.com" ); +#endif + r.addHeader( TEXT( "Accept: application/json" ) ); + r.addHeader( TEXT( "Content-Type: application/json" ) ); + auto j = json::parse( r.post( TEXT( "/login" ), + "{ \"apikey\": \"" + api_key + "\" }" ) ); + api_token = toString( j["token"].get< std::string >() ); + r.clearHeader(); + // TODO check return code + return true; +} + void singleSeason( const string &path, string &show, int season, string id, const string &language, const string &pattern, const bool &linux, const bool &trust, std::map< int, string > *files_ptr, bool print, bool dvd ) { +#ifndef GUI if ( id.empty() ) id = getShowId( show, language ); +#endif std::map< int, std::map< int, string > > *found_files = nullptr; @@ -332,20 +366,6 @@ void allSeasons( const string &path, string &show, const string &language, } } -std::vector< std::pair< string, string > > getLangs() { - std::vector< std::pair< string, string > > langs; - r.addHeader( TEXT( "Accept: application/json" ) ); - r.addHeader( TEXT( "Authorization: Bearer " ) + api_token ); - auto j = json::parse( r.get( TEXT( "/languages" ) ) ); - r.clearHeader(); - auto langs_json = j["data"].get< std::vector< json > >(); - for ( auto &x : langs_json ) { - langs.emplace_back( toString( x["abbreviation"].get< std::string >() ), - toString( x["name"].get< std::string >() ) ); - } - return langs; -} - void printLangs() { for ( auto &x : getLangs() ) cout << x.first << " - " << x.second << std::endl; @@ -359,20 +379,4 @@ bool findLanguage( const char_t *language ) { return false; } -bool authenticate( const std::string &api_key ) { -#ifdef _WIN32 - r.setServer( TEXT( "api.thetvdb.com" ) ); -#else - r.setServer( "https://api.thetvdb.com" ); -#endif - r.addHeader( TEXT( "Accept: application/json" ) ); - r.addHeader( TEXT( "Content-Type: application/json" ) ); - auto j = json::parse( r.post( TEXT( "/login" ), - "{ \"apikey\": \"" + api_key + "\" }" ) ); - api_token = toString( j["token"].get< std::string >() ); - r.clearHeader(); - // TODO check return code - return true; -} - #endif diff --git a/tv_rename.hpp b/tv_rename.hpp index 05baa7c..9846024 100644 --- a/tv_rename.hpp +++ b/tv_rename.hpp @@ -25,7 +25,6 @@ using char_t = char; #endif -// TODO change files_ptr contents to new file names void singleSeason( const string &path, string &show, int season, string id, const string &language, const string &pattern, const bool &linux, const bool &trust, @@ -39,26 +38,34 @@ void singleSeason( const string &path, string &show, int season, string id, #ifdef GUI -std::vector< std::pair< string, std::pair< string, string > > > -getRenamedFiles( const string &show, int season, string url, +std::vector< std::pair< std::pair< int, string >, std::pair< string, string > > > +getRenamedFiles( const string &show, int season, const string id, const string &language, const string &pattern, - const bool &linux, Curl &c, const std::map< int, string > &files, bool dvd = false ); + const bool &linux, const std::map< int, string > &files, bool dvd = false ); + +std::vector< std::pair< string, string > > getLangs(); #else void multipleSeasons( const string &path, string &show, const std::set< int > seasons, const string &language, const string &pattern, const size_t &flags ); + void allSeasons( const string &path, string &show, const string &language, const string &pattern, const size_t &flags ); +string getShowId( string &show, const string &language ); + #endif void printLangs(); + bool findLanguage( const char_t *language ); + bool authenticate( const std::string &api_key ); -string getShowId( string &show, const string &language ); + string showNameFromId( const string &id, const string &language ); + std::vector< std::pair< string, string > > searchShow( const string &show, const string &language );