File indexing completed on 2024-04-28 07:36:31

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 
0032     /** scan the folder for documents, and record what is found */
0033     void rescan();
0034 
0035     /** list of all files found */
0036     QStringList m_fileList;
0037 
0038     /** list of all files titles found */
0039     QStringList m_titleList;
0040 
0041     /** list of file comments */
0042     QStringList m_commentList;
0043 
0044     /** map of files by language key */
0045     QMap<QString, QStringList> m_filesByLang;
0046 };
0047 
0048 Q_GLOBAL_STATIC(SharedKvtmlFilesPrivate, sharedKvtmlFilesPrivate)
0049 
0050 void SharedKvtmlFilesPrivate::rescan()
0051 {
0052     this->m_titleList.clear();
0053     this->m_commentList.clear();
0054     this->m_filesByLang.clear();
0055     this->m_fileList.clear();
0056 
0057     // Get all kvtml paths
0058     QStringList nameFilter;
0059     nameFilter.append(QStringLiteral("*.kvtml"));
0060     const QStringList dataPaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("apps/kvtml"), QStandardPaths::LocateDirectory);
0061     for (const QString &path : dataPaths) {
0062         qDebug() << "Checking path " << path << " for kvtml files";
0063         const QStringList locales = QDir(path).entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
0064         for (const QString &locale : locales) {
0065             const QStringList files = QDir(path + '/' + locale).entryList(nameFilter, QDir::Files);
0066             for (const QString &filename : files) {
0067                 QString filePath = path + '/' + locale + '/' + filename;
0068                 this->m_fileList << filePath;
0069                 this->m_filesByLang[locale].append(filePath);
0070             }
0071         }
0072     }
0073 
0074     KEduVocDocument *doc = new KEduVocDocument();
0075     for (int i = 0; i < this->m_fileList.size(); ++i) {
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 }