File indexing completed on 2022-10-04 13:56:37

0001 /*
0002  * scan a group of KVTML documents to get information from them
0003  * SPDX-FileCopyrightText: 2007 Jeremy Whiting <jpwhiting@kde.org>
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "sharedkvtmlfiles.h"
0007 
0008 #include "keduvocdocument.h"
0009 
0010 #include <KLocalizedString>
0011 
0012 #include <QDir>
0013 #include <QFile>
0014 #include <QStandardPaths>
0015 
0016 #include <QDebug>
0017 
0018 class SharedKvtmlFilesPrivate
0019 {
0020 public:
0021     /** default constructor calls rescan*/
0022     SharedKvtmlFilesPrivate()
0023     {
0024         rescan();
0025     }
0026 
0027     /** default destructor */
0028     ~SharedKvtmlFilesPrivate()
0029     {}
0030 
0031     /** scan the folder for documents, and record what is found */
0032     void rescan();
0033 
0034     /** list of all files found */
0035     QStringList m_fileList;
0036 
0037     /** list of all files titles found */
0038     QStringList m_titleList;
0039 
0040     /** list of file comments */
0041     QStringList m_commentList;
0042 
0043     /** map of files by language key */
0044     QMap<QString, QStringList> m_filesByLang;
0045 };
0046 
0047 Q_GLOBAL_STATIC( SharedKvtmlFilesPrivate, sharedKvtmlFilesPrivate )
0048 
0049 void SharedKvtmlFilesPrivate::rescan()
0050 {
0051     this->m_titleList.clear();
0052     this->m_commentList.clear();
0053     this->m_filesByLang.clear();
0054     this->m_fileList.clear();
0055 
0056     // Get all kvtml paths
0057     QStringList nameFilter;
0058     nameFilter.append(QStringLiteral("*.kvtml"));
0059     const QStringList dataPaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("apps/kvtml"), QStandardPaths::LocateDirectory);
0060     for (const QString &path : dataPaths) {
0061         qDebug() << "Checking path " << path << " for kvtml files";
0062         const QStringList locales = QDir( path ).entryList( QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name );
0063         for (const QString &locale : locales) {
0064             const QStringList files = QDir( path + '/' + locale ).entryList(nameFilter, QDir::Files );
0065             for (const QString &filename : files) {
0066                 QString filePath = path + '/' + locale + '/' + filename;
0067                 this->m_fileList << filePath;
0068                 this->m_filesByLang[locale].append( filePath );
0069             }
0070         }
0071     }
0072 
0073     KEduVocDocument *doc = new KEduVocDocument();
0074     for ( int i = 0; i < this->m_fileList.size(); ++i ) {
0075 
0076         // open the file
0077         doc->open( QUrl::fromLocalFile( this->m_fileList[i] ),  KEduVocDocument::FileIgnoreLock );
0078 
0079         // add it's title to the title list
0080         this->m_titleList.append( doc->title() );
0081 
0082         // add it's comment to the comment list
0083         this->m_commentList.append( doc->documentComment() );
0084     }
0085     delete doc;
0086 }
0087 
0088 void SharedKvtmlFiles::rescan()
0089 {
0090     sharedKvtmlFilesPrivate->rescan();
0091 }
0092 
0093 QStringList SharedKvtmlFiles::languages()
0094 {
0095     return sharedKvtmlFilesPrivate->m_filesByLang.keys();
0096 }
0097 
0098 QStringList SharedKvtmlFiles::fileNames( const QString &language )
0099 {
0100     // return files by language for given language if it's not empty
0101     // otherwise return all filenames
0102     return language.isEmpty() ? sharedKvtmlFilesPrivate->m_fileList : sharedKvtmlFilesPrivate->m_filesByLang.value( language );
0103 }
0104 
0105 QStringList SharedKvtmlFiles::titles( const QString &language )
0106 {
0107     QStringList retlist;
0108 
0109     if ( language.isEmpty() ) {
0110         retlist = sharedKvtmlFilesPrivate->m_titleList;
0111     } else {
0112         QStringList filenames = sharedKvtmlFilesPrivate->m_filesByLang.value( language );
0113         for ( int i = 0; i < filenames.size(); ++i ) {
0114             retlist.append( sharedKvtmlFilesPrivate->m_titleList[sharedKvtmlFilesPrivate->m_fileList.indexOf( filenames[i] )] );
0115         }
0116     }
0117 
0118     return retlist;
0119 }
0120 
0121 QStringList SharedKvtmlFiles::comments( const QString &language )
0122 {
0123     QStringList retlist;
0124 
0125     if ( language.isEmpty() ) {
0126         retlist = sharedKvtmlFilesPrivate->m_commentList;
0127     } else {
0128         QStringList filenames = sharedKvtmlFilesPrivate->m_filesByLang.value( language );
0129         for ( int i = 0; i < filenames.size(); ++i ) {
0130             retlist.append( sharedKvtmlFilesPrivate->m_commentList[sharedKvtmlFilesPrivate->m_fileList.indexOf( filenames[i] )] );
0131         }
0132     }
0133 
0134     return retlist;
0135 }
0136 
0137 void SharedKvtmlFiles::sortDownloadedFiles()
0138 {
0139     QStringList nameFilter;
0140     nameFilter.append(QStringLiteral("*.kvtml"));
0141     const QStringList dataPaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("apps/kvtml"), QStandardPaths::LocateDirectory);
0142     QStringList unsortedFiles;
0143     for (const QString &path : dataPaths) {
0144         const QStringList files = QDir( path ).entryList(nameFilter, QDir::Files | QDir::NoDotAndDotDot );
0145         for (const QString &filename : files) {
0146             unsortedFiles.append( path + '/' + filename);
0147         }
0148     }
0149 
0150     KEduVocDocument doc;
0151 
0152     while ( !unsortedFiles.isEmpty() ) {
0153         QUrl fileUrl( QUrl::fromLocalFile( unsortedFiles.first() ) );
0154         // find the file's locale
0155         // open the file
0156         doc.open( fileUrl );
0157 
0158         if (doc.identifierCount() == 1) {
0159             QString locale = doc.identifier( 0 ).locale();
0160 
0161             // make sure the locale sub-folder exists
0162             QUrl pathUrl = QUrl( fileUrl );
0163             pathUrl = QUrl( pathUrl.toString(QUrl::RemoveFilename) + '/' + locale );
0164             QDir dir;
0165             if (!dir.mkpath(pathUrl.toLocalFile())) {
0166                 // Unable to create destination path, so skip
0167                 continue;
0168             }
0169 
0170             pathUrl = QUrl( pathUrl.toString() + '/' + fileUrl.fileName());
0171 
0172             // move the file into the locale sub-folder
0173             bool moved = QFile(fileUrl.toLocalFile()).rename(pathUrl.toLocalFile());
0174             if (!moved) {
0175                 qDebug() << "Unable to move " << fileUrl << " to " << pathUrl;
0176             }
0177         }
0178 
0179         // take off the one we just did
0180         unsortedFiles.removeFirst();
0181     }
0182 
0183     nameFilter = QStringList(QStringLiteral("*.txt"));
0184     QStringList khangmanFiles;
0185     for (const QString &path : dataPaths) {
0186         const QStringList files = QDir( path ).entryList(nameFilter, QDir::Files );
0187         for (const QString &filename : files) {
0188             khangmanFiles.append( path + '/' + filename);
0189         }
0190     }
0191 
0192     // move khangman files into
0193     while ( !khangmanFiles.isEmpty() ) {
0194         QUrl fileUrl( QUrl::fromLocalFile( khangmanFiles.first() ) );
0195         QUrl destDir = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/khangman/data/");
0196         QUrl destUrl = QUrl::fromLocalFile(destDir.toString() + fileUrl.fileName());
0197 
0198         QDir dir;
0199         if (!dir.mkpath(destDir.toLocalFile())) {
0200             // Unable to create destination path, so skip
0201             continue;
0202         }
0203 
0204         // do this better with KStandardDirs stuff
0205         bool worked = QFile(fileUrl.toLocalFile()).rename(destUrl.toLocalFile());
0206         if (!worked) {
0207             qDebug() << "Unable to move " << fileUrl << " to " << destUrl;
0208         }
0209         khangmanFiles.removeFirst();
0210     }
0211 
0212     rescan();
0213 }