From 64d87e6c3c907fb7d52bd823d63bcb8afbadf10b Mon Sep 17 00:00:00 2001 From: Karel Matas Date: Wed, 3 Jul 2013 20:19:23 +0200 Subject: [PATCH] initial version of loading dbscript (without web download) --- CHANGELOG | 2 ++ LICENCE | 34 ++++++++++++++++-- notes | 13 ------- src/aoi.cxx | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- src/aoi.hxx | 15 ++++++-- src/gui.cxx | 5 --- src/gui.hxx | 13 +++++++ src/main.cxx | 29 +++++++++++++++ 8 files changed, 191 insertions(+), 36 deletions(-) rewrite LICENCE (98%) delete mode 100755 notes diff --git a/CHANGELOG b/CHANGELOG index 1d7d323..19e2bce 100755 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,8 +1,10 @@ alpha.03 +- first public alpha - created user.db for all user changes and config - show all known informations about the selected word (temporary replacement of EditWord) - example sentences from Tatoeba project (initial version) +- downloading the database from internet alpha.02 - JLPT and Grade are now separate fields, not flags. diff --git a/LICENCE b/LICENCE dissimilarity index 98% index f224e01..40efdfc 100755 --- a/LICENCE +++ b/LICENCE @@ -1,3 +1,31 @@ -This program is released under GPL 3 Licence. - -For details see file help/index.html +Copyright 2013 Karel Matas (karel.matas@souko.cz) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. (file help/gpl3.html +or https://www.gnu.org/licenses/gpl.html) + + +This program uses the JMDICT and KANJIDIC dictionary files. These files +are the property of the Electronic Dictionary Research and Development +Group, and are used in conformance with the Group's licence. +http://www.csse.monash.edu.au/~jwb/jmdict.html +http://www.csse.monash.edu.au/~jwb/kanjidic2 +http://www.edrdg.org/edrdg/licence.html + + +Decompositions of the kanji to radicals are taken from the KRADFILE-U +- Copyright is held by Jim Rose. +http://www.kanjicafe.com/kradfile_license.htm + + +The SKIP (System of Kanji Indexing by Patterns) system for ordering kanji +used in this program was developed by Jack Halpern (Kanji Dictionary +Publishing Society at http://www.kanji.org/, and is used with his +permission. +http://www.kanji.org/kanji/dictionaries/skip_permission.htm diff --git a/notes b/notes deleted file mode 100755 index 29e3244..0000000 --- a/notes +++ /dev/null @@ -1,13 +0,0 @@ -testovat: - ana - kakeru - torikaeru - -zobrazovat xref: uzitecne daje (viz kakeru) - -dicview: tag 'xref' - FONT_KANJI () - -popup_kanji a podobne dialogy budou vychazet z GUI -GUI->Aoi::dotaz_na_kanji/slovo -GUI->Popup_kanji/slovo --> bude pruhlednejsi beh programu diff --git a/src/aoi.cxx b/src/aoi.cxx index 367936c..abf388a 100755 --- a/src/aoi.cxx +++ b/src/aoi.cxx @@ -26,6 +26,8 @@ using std::set; using aoi_ui::TextStyle; using utils::to_string; +//! See App::load_dbscript() and App::App() +const char *DB_BACKUP_FILE = "db.backup"; const char *LOG_FILE = "aoi.log"; const char SENSE_SEARCH_CHAR = ':'; @@ -37,22 +39,25 @@ App::App () logger_.filename(LOG_FILE); logger_.loglevel(Logger::MSG_DEBUG); + db_ = nullptr; // NECESSARY ( if db_ undefined then SEGFAULT in open_database() ) cfg_ = new aoi_config::Config(); ui_ = new aoi_ui::GUI(this); rmn_ = new Romanization(); - ui_->progress(0,"Opening database..."); - - try { - db_ = new SQLite3::SQLite3( get_config("db/file_main").c_str() ); - } - catch (SQLite3::CantOpenDatabase &e){ - log_e( "Aoi: Can't open database '" + string(e.what()) + "'."); + if ( utils::file_exists( DB_BACKUP_FILE ) ){ + log_w("Backup copy of the database found."); + std::stringstream ss; + ss << "Backup copy of the database found. Delete it?\n" + << "WARNING: You should check whether the current database\n" + << "works before deleting the backup."; + if ( ui_->choice(ss.str(), "Delete", "No") == 0 ){ + log("Deleting the backup copy of the database."); + remove(DB_BACKUP_FILE); + } } - std::stringstream ss; - ss << "ATTACH DATABASE '" << get_config("db/file_user") << "'as user;"; - query(ss.str().c_str()); + ui_->progress(0,"Opening database..."); + open_database(); ui_->progress( 30, "Checking tables..." ); check_tables(); @@ -163,6 +168,26 @@ vector App::query ( const char *q, bool log_query, bool replace_separato } +void App::open_database () +{ + try { + if ( !db_ ) + db_ = new SQLite3::SQLite3( get_config("db/file_main").c_str() ); + else{ + db_->close(); + db_->open(get_config("db/file_main").c_str()); + } + } + catch (SQLite3::CantOpenDatabase &e){ + log_e( "Aoi: Can't open database '" + string(e.what()) + "'."); + return; + } + std::stringstream ss; + ss << "ATTACH DATABASE '" << get_config("db/file_user") << "'as user;"; + db_->query(ss.str().c_str()); +} + + void App::cb_set_components () { if ( curr_components_.empty() ) @@ -424,6 +449,72 @@ void App::check_indexes () } +void App::load_dbscript ( const char *fname ) +{ + const char *TEMP_DBSCRIPT = "dbscript.temp"; + const char *TEMP_DATABASE = "temp.db"; + const int LINE_BUFFER = 4096; + + // hide manage db_dialog if visible + auto *d = ui_->dlg_manage_db(); + if ( d && d->visible() ) + d->hide(); + + log("Loading dbscript: "+string(fname)); + + log("Decompressing file (if necessary)..."); + utils::gzip_decompress_file( fname, TEMP_DBSCRIPT); + + log("Opening temporary database."); + remove(TEMP_DATABASE); + SQLite3::SQLite3 db(TEMP_DATABASE); + + log("Loading..."); + std::ifstream f; + char line[LINE_BUFFER]; + f.open(TEMP_DBSCRIPT); + // n lines should be > 2e6 -> percent=n*2e6/100 + size_t n = 0; + while ( f.good() ){ + if ( n % 5000 == 0 ){ + char b[64]; + snprintf( b, 64, "Loading line: %d", n); + ui_->progress(n/float(2.5e4), b); + } + f.getline( line, LINE_BUFFER ); + db.query(line); + n++; + } + f.close(); + + log("Closing temporary database..."); + db.close(); + remove(TEMP_DBSCRIPT); + + log("Closing old database."); + db_->close(); + + string dbfile = get_config("db/file_main"); + + log("Renaming old database to main.db.bckp."); + rename( dbfile.c_str(), DB_BACKUP_FILE ); + + log("Renaming new database."); + rename( TEMP_DATABASE, dbfile.c_str() ); + + log("Switching to the new database"); + open_database(); + + ui_->progress(90, "Checking tables..."); + check_tables(); + ui_->progress(95, "Checking indexes..."); + check_indexes(); + + // show informations about db + cb_manage_db(); +} + + void App::cb_dic_input () { parse_dic_input( ui_->get_dic_input() ); @@ -516,13 +607,12 @@ void App::parse_dic_input ( const char *str ) qq = p.parse(s); if ( p.warning() ){ - int res = fl_choice( + int res = ui_->choice( "Too broad search.\n"\ "Your computer may become unresponsible for a long time.\n"\ "Proceed?", "Proceed", - "Cancel", - 0 + "Cancel" ); if ( res == 1 ) // Cancel return; diff --git a/src/aoi.hxx b/src/aoi.hxx index fa919ee..88761a2 100755 --- a/src/aoi.hxx +++ b/src/aoi.hxx @@ -82,7 +82,6 @@ struct DicViewItem { - /*! * Main class of the program. Singleton. Manages database, logger, config and UI. * Provides functions for UI's callbacks. @@ -166,6 +165,9 @@ class App //! Returns pointer to Romanization. inline Romanization *rmn () const { return rmn_; }; + //! Opens the main database and attach the user database. + void open_database (); + //! Log message. inline void log ( const string &s ) { logger_.msg(s); }; //! Log error. @@ -269,7 +271,11 @@ class App */ void save_config ( const std::map &newmap={}); - //! Loads config from database. + /*! + * Loads config from database. + * \todo Compare loaded and default config. Drop keys which exists in loaded + * but dont in default (i.e. keys from previous versions). + */ void load_config (); /*! @@ -295,6 +301,11 @@ class App */ void check_indexes (); + /*! + * Loads database stored as SQLite script. File may be GZipped. + */ + void load_dbscript ( const char *fname ); + // Dictionary functions void cb_dic_input (); void on_dic_selected ( int id ); diff --git a/src/gui.cxx b/src/gui.cxx index d5f5ea7..4f08926 100755 --- a/src/gui.cxx +++ b/src/gui.cxx @@ -230,9 +230,6 @@ GUI::GUI ( aoi::App *parent ):parent_(parent) main_window_->b_menu_->labeltype(FL_NORMAL_LABEL); init_fonts(); - main_window_->show(); - dlg_progress_->show(); - main_window_->dic_input_->take_focus(); } @@ -301,8 +298,6 @@ void GUI::dicview_menu ( int did, const vector &v, bool notes, bool exam Fl_Menu_Button menu(Fl::event_x(), Fl::event_y(), 80, 1); menu.textfont(FONT_KANJI); menu.textsize( 1.5*font_base_size_ ); -// XXX: copy all will be in edit -// menu.add("Copy all",0,0,0,FL_MENU_DIVIDER); for ( string s: v ){ menu.add( (s+"/Copy").c_str(), 0, scb_copy, (void*)s.c_str()); menu.add( (s+"/Show").c_str() ); diff --git a/src/gui.hxx b/src/gui.hxx index 10f2f8c..5a57088 100755 --- a/src/gui.hxx +++ b/src/gui.hxx @@ -250,6 +250,17 @@ class GUI */ void init_colors(); + /*! + * Displays simple window with the text s and 2 buttons + * (default: Yes and No). String s may contain + * newlines ('\n'). + * \return pressed button number (0 for the first, 1 for the second) + */ + inline int choice ( const string &s, const string &btn1="Yes", + const string &btn2="No" ){ + return fl_choice( s.c_str(), btn1.c_str(), btn2.c_str(), 0); + } + //! Shows MainWindow and returns Fl::run() int run ( int argc, char **argv ); @@ -261,6 +272,8 @@ class GUI * Shows and sets modal dialog with progress. */ inline void progress ( float percent, const string &message ){ + if ( ! dlg_progress_->visible() ) + dlg_progress_->show(); center_window( dlg_progress_ ); dlg_progress_->progress( percent, message ); } diff --git a/src/main.cxx b/src/main.cxx index cc7b331..cada244 100755 --- a/src/main.cxx +++ b/src/main.cxx @@ -35,6 +35,21 @@ using utils::to_string; const char *TEMP_JMDICT = "gztemp.jmdict"; const char *TEMP_KANJIDIC = "gztemp.kanjidic"; +const char *DBSCRIPT_LICENSE = +"--This file is based on the JMDICT and KANJIDIC dictionary files. These files \ +are the property of the Electronic Dictionary Research and Development \ +Group, and are used in conformance with the Group's licence.\ +--http://www.csse.monash.edu.au/~jwb/jmdict.html\n\ +--http://www.csse.monash.edu.au/~jwb/kanjidic2\n\ +--http://www.edrdg.org/edrdg/licence.html\n\ +--Decompositions of the kanji to radicals are taken from the KRADFILE-U \ +- Copyright is held by Jim Rose. (http://www.kanjicafe.com/kradfile_license.htm)\n\ +--The SKIP (System of Kanji Indexing by Patterns) system for ordering kanji \ +used in this program was developed by Jack Halpern (Kanji Dictionary \ +Publishing Society at http://www.kanji.org/, and is used with his \ +permission.\n\ +--See http://aoi.souko.cz for more details.\n"; + /*! * Parses JMDict. File may be GZipped. * \see parsers::JmdictParser @@ -45,6 +60,7 @@ void parse_jmdict ( const char *fname ) { printf("Loading JMdict file '%s'.\n", fname); std::stringstream ss; + ss << DBSCRIPT_LICENSE; ss << "BEGIN TRANSACTION;\n"; // create parser @@ -263,6 +279,19 @@ int main ( int argc, char **argv ) } return 1; } + else if ( !strncmp( argv[i], "-loaddb", 7) ){ + if ( i==argc-1 ) { + printf("Missing file: -loaddb FILE\n"); + return 0; + } + if ( !utils::file_exists(argv[i+1]) ){ + printf("File does not exist: %s\n", argv[i+1]); + return 0; + } + App::get()->load_dbscript( argv[i+1] ); + return 1; + } + // argv[i] not recognized else { printf("argv[%d] : %s -> FLTK\n", i, argv[i]); // pass unparsed arguments to FLTK -- 2.11.4.GIT