2012-02-20 21:47:14 +00:00
|
|
|
/* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org>
|
2009-04-30 15:29:03 +00:00
|
|
|
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
|
|
|
|
|
|
|
#include "loaddictionaries.hh"
|
|
|
|
#include "initializing.hh"
|
2023-04-17 20:55:34 +00:00
|
|
|
#include "dict/bgl.hh"
|
|
|
|
#include "dict/stardict.hh"
|
|
|
|
#include "dict/lsa.hh"
|
|
|
|
#include "dict/dsl.hh"
|
|
|
|
#include "dict/mediawiki.hh"
|
|
|
|
#include "dict/sounddir.hh"
|
|
|
|
#include "dict/hunspell.hh"
|
2009-04-30 15:29:03 +00:00
|
|
|
#include "dictdfiles.hh"
|
2023-04-17 20:55:34 +00:00
|
|
|
#include "dict/romaji.hh"
|
|
|
|
#include "dict/russiantranslit.hh"
|
|
|
|
#include "dict/german.hh"
|
|
|
|
#include "dict/greektranslit.hh"
|
|
|
|
#include "dict/belarusiantranslit.hh"
|
|
|
|
#include "dict/website.hh"
|
|
|
|
#include "dict/forvo.hh"
|
|
|
|
#include "dict/programs.hh"
|
|
|
|
#include "dict/voiceengines.hh"
|
2013-11-16 18:34:09 +00:00
|
|
|
#include "gddebug.hh"
|
2023-04-17 20:55:34 +00:00
|
|
|
#include "dict/xdxf.hh"
|
|
|
|
#include "dict/sdict.hh"
|
|
|
|
#include "dict/aard.hh"
|
|
|
|
#include "dict/zipsounds.hh"
|
|
|
|
#include "dict/mdx.hh"
|
|
|
|
#include "dict/zim.hh"
|
2014-04-30 12:55:53 +00:00
|
|
|
#include "dictserver.hh"
|
2023-04-17 20:55:34 +00:00
|
|
|
#include "dict/slob.hh"
|
|
|
|
#include "dict/gls.hh"
|
2023-04-17 20:12:27 +00:00
|
|
|
#include "dict/lingualibre.hh"
|
2009-04-30 15:29:03 +00:00
|
|
|
|
2014-05-20 13:59:56 +00:00
|
|
|
#ifndef NO_EPWING_SUPPORT
|
2023-04-17 22:36:29 +00:00
|
|
|
#include "dict/epwing.hh"
|
2014-05-20 13:59:56 +00:00
|
|
|
#endif
|
|
|
|
|
2015-10-25 13:54:38 +00:00
|
|
|
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
|
2023-04-17 22:18:28 +00:00
|
|
|
#include "dict/chinese.hh"
|
2015-10-19 13:52:23 +00:00
|
|
|
#endif
|
|
|
|
|
2009-04-30 15:29:03 +00:00
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QDir>
|
|
|
|
|
|
|
|
#include <set>
|
|
|
|
|
|
|
|
using std::set;
|
|
|
|
|
|
|
|
using std::string;
|
|
|
|
using std::vector;
|
|
|
|
|
|
|
|
LoadDictionaries::LoadDictionaries( Config::Class const & cfg ):
|
2009-05-06 14:39:08 +00:00
|
|
|
paths( cfg.paths ), soundDirs( cfg.soundDirs ), hunspell( cfg.hunspell ),
|
2009-08-31 12:58:29 +00:00
|
|
|
transliteration( cfg.transliteration ),
|
2012-12-07 11:59:29 +00:00
|
|
|
exceptionText( "Load did not finish" ), // Will be cleared upon success
|
2013-01-11 09:58:14 +00:00
|
|
|
maxPictureWidth( cfg.maxPictureWidth ),
|
2017-10-25 14:37:39 +00:00
|
|
|
maxHeadwordSize( cfg.maxHeadwordSize ),
|
|
|
|
maxHeadwordToExpand( cfg.maxHeadwordsToExpand )
|
2009-04-30 15:29:03 +00:00
|
|
|
{
|
2009-05-17 15:30:43 +00:00
|
|
|
// Populate name filters
|
|
|
|
|
|
|
|
nameFilters << "*.bgl" << "*.ifo" << "*.lsa" << "*.dat"
|
2012-02-09 12:49:41 +00:00
|
|
|
<< "*.dsl" << "*.dsl.dz" << "*.index" << "*.xdxf"
|
2013-04-23 12:07:05 +00:00
|
|
|
<< "*.xdxf.dz" << "*.dct" << "*.aar" << "*.zips"
|
2017-03-06 15:07:39 +00:00
|
|
|
<< "*.mdx" << "*.gls" << "*.gls.dz"
|
2013-09-14 16:17:32 +00:00
|
|
|
#ifdef MAKE_ZIM_SUPPORT
|
2015-01-22 15:17:05 +00:00
|
|
|
<< "*.zim" << "*.zimaa" << "*.slob"
|
2013-09-14 16:17:32 +00:00
|
|
|
#endif
|
2014-05-20 13:59:56 +00:00
|
|
|
#ifndef NO_EPWING_SUPPORT
|
|
|
|
<< "*catalogs"
|
|
|
|
#endif
|
2013-09-14 16:17:32 +00:00
|
|
|
;
|
2009-04-30 15:29:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void LoadDictionaries::run()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2022-12-25 14:05:30 +00:00
|
|
|
for(const auto & path : paths)
|
|
|
|
handlePath( path );
|
2009-04-30 15:29:03 +00:00
|
|
|
|
|
|
|
// Make soundDirs
|
|
|
|
{
|
|
|
|
vector< sptr< Dictionary::Class > > soundDirDictionaries =
|
2023-04-13 10:08:32 +00:00
|
|
|
SoundDir::makeDictionaries( soundDirs, Config::getIndexDir().toStdString(), *this );
|
2009-04-30 15:29:03 +00:00
|
|
|
|
|
|
|
dictionaries.insert( dictionaries.end(), soundDirDictionaries.begin(),
|
|
|
|
soundDirDictionaries.end() );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make hunspells
|
|
|
|
{
|
|
|
|
vector< sptr< Dictionary::Class > > hunspellDictionaries =
|
|
|
|
HunspellMorpho::makeDictionaries( hunspell );
|
|
|
|
|
|
|
|
dictionaries.insert( dictionaries.end(), hunspellDictionaries.begin(),
|
|
|
|
hunspellDictionaries.end() );
|
|
|
|
}
|
2009-08-31 12:58:29 +00:00
|
|
|
|
|
|
|
exceptionText.clear();
|
2009-04-30 15:29:03 +00:00
|
|
|
}
|
|
|
|
catch( std::exception & e )
|
|
|
|
{
|
|
|
|
exceptionText = e.what();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-25 14:05:30 +00:00
|
|
|
void LoadDictionaries::addDicts( const std::vector< sptr< Dictionary::Class > >& dicts ) {
|
|
|
|
std::move(dicts.begin(), dicts.end(), std::back_inserter(dictionaries));
|
|
|
|
}
|
|
|
|
|
2009-04-30 15:29:03 +00:00
|
|
|
void LoadDictionaries::handlePath( Config::Path const & path )
|
|
|
|
{
|
|
|
|
vector< string > allFiles;
|
|
|
|
|
|
|
|
QDir dir( path.path );
|
|
|
|
|
2009-05-17 15:30:43 +00:00
|
|
|
QFileInfoList entries = dir.entryInfoList( nameFilters, QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot );
|
2009-04-30 15:29:03 +00:00
|
|
|
|
|
|
|
for( QFileInfoList::const_iterator i = entries.constBegin();
|
|
|
|
i != entries.constEnd(); ++i )
|
|
|
|
{
|
2019-02-13 20:58:29 +00:00
|
|
|
QString fullName = i->absoluteFilePath();
|
2009-04-30 15:29:03 +00:00
|
|
|
|
|
|
|
if ( path.recursive && i->isDir() )
|
2009-05-17 15:37:36 +00:00
|
|
|
{
|
|
|
|
// Make sure the path doesn't look like with dsl resources
|
|
|
|
if ( !fullName.endsWith( ".dsl.files", Qt::CaseInsensitive ) &&
|
|
|
|
!fullName.endsWith( ".dsl.dz.files", Qt::CaseInsensitive ) )
|
|
|
|
handlePath( Config::Path( fullName, true ) );
|
|
|
|
}
|
2009-04-30 15:29:03 +00:00
|
|
|
|
2013-09-20 16:24:59 +00:00
|
|
|
if ( !i->isDir() )
|
2023-04-13 10:08:32 +00:00
|
|
|
allFiles.push_back( QDir::toNativeSeparators( fullName ).toStdString() );
|
2009-04-30 15:29:03 +00:00
|
|
|
}
|
|
|
|
|
2023-04-13 10:08:32 +00:00
|
|
|
addDicts( Bgl::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
|
|
|
|
addDicts( Stardict::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this, maxHeadwordToExpand ) );
|
|
|
|
addDicts( Lsa::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
|
|
|
|
addDicts(
|
|
|
|
Dsl::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this, maxPictureWidth, maxHeadwordSize ) );
|
|
|
|
addDicts( DictdFiles::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
|
|
|
|
addDicts( Xdxf::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
|
|
|
|
addDicts( Sdict::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
|
|
|
|
addDicts( Aard::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this, maxHeadwordToExpand ) );
|
|
|
|
addDicts( ZipSounds::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
|
|
|
|
addDicts( Mdx::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
|
|
|
|
addDicts( Gls::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
|
2009-04-30 15:29:03 +00:00
|
|
|
|
2013-09-14 16:17:32 +00:00
|
|
|
#ifdef MAKE_ZIM_SUPPORT
|
2023-04-13 10:08:32 +00:00
|
|
|
addDicts( Zim::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this, maxHeadwordToExpand ) );
|
|
|
|
addDicts( Slob::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this, maxHeadwordToExpand ) );
|
2013-09-14 16:17:32 +00:00
|
|
|
#endif
|
2014-05-20 13:59:56 +00:00
|
|
|
#ifndef NO_EPWING_SUPPORT
|
2023-04-13 10:08:32 +00:00
|
|
|
addDicts( Epwing::makeDictionaries( allFiles, Config::getIndexDir().toStdString(), *this ) );
|
2014-05-20 13:59:56 +00:00
|
|
|
#endif
|
2009-04-30 15:29:03 +00:00
|
|
|
}
|
|
|
|
|
2022-06-03 13:28:41 +00:00
|
|
|
void LoadDictionaries::indexingDictionary( string const & dictionaryName ) noexcept
|
2009-04-30 15:29:03 +00:00
|
|
|
{
|
|
|
|
emit indexingDictionarySignal( QString::fromUtf8( dictionaryName.c_str() ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void loadDictionaries( QWidget * parent, bool showInitially,
|
|
|
|
Config::Class const & cfg,
|
|
|
|
std::vector< sptr< Dictionary::Class > > & dictionaries,
|
2009-05-17 22:02:54 +00:00
|
|
|
QNetworkAccessManager & dictNetMgr,
|
|
|
|
bool doDeferredInit_ )
|
2009-04-30 15:29:03 +00:00
|
|
|
{
|
|
|
|
dictionaries.clear();
|
2009-05-06 18:17:13 +00:00
|
|
|
|
2009-04-30 15:29:03 +00:00
|
|
|
::Initializing init( parent, showInitially );
|
|
|
|
|
|
|
|
// Start a thread to load all the dictionaries
|
|
|
|
|
|
|
|
LoadDictionaries loadDicts( cfg );
|
|
|
|
|
2022-12-26 02:08:17 +00:00
|
|
|
QObject::connect( &loadDicts, &LoadDictionaries::indexingDictionarySignal, &init, &Initializing::indexing );
|
2009-04-30 15:29:03 +00:00
|
|
|
|
|
|
|
QEventLoop localLoop;
|
|
|
|
|
2022-12-26 02:08:17 +00:00
|
|
|
QObject::connect( &loadDicts, &QThread::finished, &localLoop, &QEventLoop::quit );
|
2009-04-30 15:29:03 +00:00
|
|
|
|
|
|
|
loadDicts.start();
|
|
|
|
|
|
|
|
localLoop.exec();
|
|
|
|
|
|
|
|
loadDicts.wait();
|
|
|
|
|
|
|
|
if ( loadDicts.getExceptionText().size() )
|
|
|
|
{
|
|
|
|
QMessageBox::critical( parent, QCoreApplication::translate( "LoadDictionaries", "Error loading dictionaries" ),
|
|
|
|
QString::fromUtf8( loadDicts.getExceptionText().c_str() ) );
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dictionaries = loadDicts.getDictionaries();
|
|
|
|
|
2022-12-25 14:05:30 +00:00
|
|
|
// Helper function that will add a vector of dictionary::Class to the dictionary list
|
|
|
|
// Implemented as lambda to access method's `dictionaries` variable
|
|
|
|
auto static addDicts = [&dictionaries](const vector< sptr< Dictionary::Class >> &dicts) {
|
|
|
|
std::move(dicts.begin(), dicts.end(), std::back_inserter(dictionaries));
|
|
|
|
};
|
|
|
|
|
2018-07-07 09:33:15 +00:00
|
|
|
///// We create transliterations synchronously since they are very simple
|
2009-05-18 10:46:53 +00:00
|
|
|
|
2015-10-25 13:54:38 +00:00
|
|
|
#ifdef MAKE_CHINESE_CONVERSION_SUPPORT
|
2022-12-25 14:05:30 +00:00
|
|
|
addDicts(Chinese::makeDictionaries( cfg.transliteration.chinese ));
|
2015-10-25 13:54:38 +00:00
|
|
|
#endif
|
2015-10-19 13:52:23 +00:00
|
|
|
|
2022-12-25 14:05:30 +00:00
|
|
|
addDicts(Romaji::makeDictionaries( cfg.transliteration.romaji ));
|
2009-05-18 10:46:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Make Russian transliteration
|
|
|
|
if ( cfg.transliteration.enableRussianTransliteration )
|
|
|
|
dictionaries.push_back( RussianTranslit::makeDictionary() );
|
|
|
|
|
|
|
|
// Make German transliteration
|
|
|
|
if ( cfg.transliteration.enableGermanTransliteration )
|
|
|
|
dictionaries.push_back( GermanTranslit::makeDictionary() );
|
|
|
|
|
2010-05-29 09:22:08 +00:00
|
|
|
// Make Greek transliteration
|
|
|
|
if ( cfg.transliteration.enableGreekTransliteration )
|
|
|
|
dictionaries.push_back( GreekTranslit::makeDictionary() );
|
|
|
|
|
2013-01-18 19:21:56 +00:00
|
|
|
// Make Belarusian transliteration
|
|
|
|
if ( cfg.transliteration.enableBelarusianTransliteration )
|
|
|
|
{
|
2022-12-25 14:05:30 +00:00
|
|
|
addDicts(BelarusianTranslit::makeDictionaries());
|
2009-05-16 18:04:21 +00:00
|
|
|
}
|
|
|
|
|
2022-12-25 14:05:30 +00:00
|
|
|
addDicts(MediaWiki::makeDictionaries( loadDicts, cfg.mediawikis, dictNetMgr ));
|
|
|
|
addDicts(WebSite::makeDictionaries( cfg.webSites, dictNetMgr ));
|
|
|
|
addDicts(Forvo::makeDictionaries( loadDicts, cfg.forvo, dictNetMgr ));
|
|
|
|
addDicts(Lingua::makeDictionaries( loadDicts, cfg.lingua, dictNetMgr ));
|
|
|
|
addDicts(Programs::makeDictionaries( cfg.programs ));
|
|
|
|
addDicts(VoiceEngines::makeDictionaries( cfg.voiceEngines ));
|
|
|
|
addDicts(DictServer::makeDictionaries( cfg.dictServers ));
|
2010-06-12 20:16:35 +00:00
|
|
|
|
2014-04-30 12:55:53 +00:00
|
|
|
|
2014-05-10 21:02:31 +00:00
|
|
|
GD_DPRINTF( "Load done\n" );
|
2009-05-17 13:35:19 +00:00
|
|
|
|
2009-04-30 15:29:03 +00:00
|
|
|
// Remove any stale index files
|
|
|
|
|
|
|
|
set< string > ids;
|
2013-11-16 19:03:36 +00:00
|
|
|
std::pair< std::set< string >::iterator, bool > ret;
|
|
|
|
|
2009-04-30 15:29:03 +00:00
|
|
|
for( unsigned x = dictionaries.size(); x--; )
|
2013-11-16 19:03:36 +00:00
|
|
|
{
|
|
|
|
ret = ids.insert( dictionaries[ x ]->getId() );
|
|
|
|
if( !ret.second )
|
|
|
|
{
|
2022-12-24 22:01:50 +00:00
|
|
|
gdWarning( R"(Duplicate dictionary ID found: ID=%s, name="%s", path="%s")",
|
2013-11-16 19:03:36 +00:00
|
|
|
dictionaries[ x ]->getId().c_str(),
|
|
|
|
dictionaries[ x ]->getName().c_str(),
|
|
|
|
dictionaries[ x ]->getDictionaryFilenames().empty() ?
|
|
|
|
"" : dictionaries[ x ]->getDictionaryFilenames()[ 0 ].c_str()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2009-04-30 15:29:03 +00:00
|
|
|
|
|
|
|
QDir indexDir( Config::getIndexDir() );
|
|
|
|
|
2022-10-07 09:08:10 +00:00
|
|
|
QStringList allIdxFiles = indexDir.entryList( QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks );
|
2009-04-30 15:29:03 +00:00
|
|
|
|
2023-04-13 10:08:32 +00:00
|
|
|
for( const auto & file : allIdxFiles)
|
2009-04-30 15:29:03 +00:00
|
|
|
{
|
2023-04-13 10:08:32 +00:00
|
|
|
if ( file.size() >= 32 && ids.find( file.left( 32 ).toStdString() ) == ids.end() ) {
|
|
|
|
if( QFile::exists( file ) )
|
2022-10-07 09:08:10 +00:00
|
|
|
{
|
2023-04-13 10:08:32 +00:00
|
|
|
indexDir.remove( file );
|
2022-10-07 09:08:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// must be folder .
|
2023-04-13 10:08:32 +00:00
|
|
|
auto dirPath = Utils::Path::combine( Config::getIndexDir(), file );
|
2022-10-07 09:08:10 +00:00
|
|
|
QDir t( dirPath );
|
|
|
|
t.removeRecursively();
|
|
|
|
}
|
|
|
|
}
|
2009-04-30 15:29:03 +00:00
|
|
|
}
|
2009-05-17 13:35:19 +00:00
|
|
|
|
|
|
|
// Run deferred inits
|
|
|
|
|
2009-05-17 22:02:54 +00:00
|
|
|
if ( doDeferredInit_ )
|
|
|
|
doDeferredInit( dictionaries );
|
|
|
|
}
|
|
|
|
|
|
|
|
void doDeferredInit( std::vector< sptr< Dictionary::Class > > & dictionaries )
|
|
|
|
{
|
2009-05-17 13:35:19 +00:00
|
|
|
for( unsigned x = 0; x < dictionaries.size(); ++x )
|
|
|
|
dictionaries[ x ]->deferredInit();
|
2009-04-30 15:29:03 +00:00
|
|
|
}
|