File indexing completed on 2024-04-14 03:46:37

0001 /*
0002  * create a KEduVocDocument from a Vokabeln file
0003  *
0004  * SPDX-FileCopyrightText: 2005, 2007 Peter Hedlund <peter.hedlund@kdemail.net>
0005  * SPDX-FileCopyrightText: 2007 Frederik Gladhorn <frederik.gladhorn@kdemail.net>
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #include "keduvocvokabelnreader.h"
0010 
0011 #include <KLocalizedString>
0012 #include <QIODevice>
0013 
0014 #include <QDebug>
0015 
0016 #include "keduvocexpression.h"
0017 
0018 KEduVocVokabelnReader::KEduVocVokabelnReader(QIODevice &file)
0019     : m_inputFile(&file)
0020 {
0021     m_errorMessage = QLatin1String("");
0022 }
0023 
0024 bool KEduVocVokabelnReader::isParsable()
0025 {
0026     QTextStream ts(m_inputFile);
0027     QString line1(ts.readLine());
0028     QString line2(ts.readLine());
0029     /*
0030      * Vokabeln.de files:
0031     The header seems to be something like this:
0032 
0033     "Name
0034     Lang1 - Lang2",123,234,456
0035     0
0036 
0037     or something longer:
0038 
0039     "Name
0040     Lang1 - Lang2
0041     [..]
0042     Blah, blah, blah...",123,234,456
0043     0
0044     */
0045 
0046     QString tmp;
0047     bool isgood = false;
0048 
0049     if (line1.startsWith(QChar::fromLatin1('"'))) {
0050         ts.seek(0);
0051         tmp = ts.readLine();
0052         // There shouldn't be headers longer than 10 lines.
0053         for (int x = 0; x < 10; x++) {
0054             if (tmp.contains(QLatin1String("\","))) {
0055                 tmp = ts.readLine();
0056                 if (tmp.endsWith('0')) {
0057                     isgood = true;
0058                     break;
0059                 }
0060             }
0061             tmp = ts.readLine();
0062         }
0063     }
0064 
0065     m_inputFile->seek(0);
0066     return isgood;
0067 }
0068 
0069 KEduVocDocument::FileType KEduVocVokabelnReader::fileTypeHandled()
0070 {
0071     return KEduVocDocument::Vokabeln;
0072 }
0073 
0074 KEduVocDocument::ErrorCode KEduVocVokabelnReader::read(KEduVocDocument &doc)
0075 {
0076     qDebug() << "Reading vokabeln.de document...";
0077     m_doc = &doc;
0078 
0079     m_doc->setAuthor(QStringLiteral("http://www.vokabeln.de"));
0080 
0081     QTextStream inputStream(m_inputFile);
0082 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // TODO fix in qt6!
0083     inputStream.setCodec("ISO-8859-1");
0084 #else
0085     qWarning() << " Need to fix inputStream.setCodec( ISO-8859-1 );";
0086 #endif
0087     inputStream.setAutoDetectUnicode(false);
0088     inputStream.seek(0);
0089 
0090     QString title;
0091     QString lang1;
0092     QString expression;
0093     QString original;
0094     QString translation;
0095     QString temp;
0096     QString comment;
0097 
0098     int i;
0099     int wordCount;
0100     int lessonNumber;
0101     int maxLessonNumber = -1;
0102 
0103     int lines = 10000;
0104 
0105     QStringList titles;
0106     QStringList languages;
0107     QStringList words;
0108 
0109     temp = inputStream.readLine();
0110 
0111     if (temp.startsWith(QChar::fromLatin1('"'))) {
0112         while (temp != QChar::fromLatin1('0')) {
0113             if (title.isEmpty()) {
0114                 title = temp;
0115             } else {
0116                 comment.append(temp.append('\n'));
0117             }
0118 
0119             if (inputStream.atEnd()) {
0120                 m_errorMessage = i18n("Error while reading file: Truncated header");
0121                 return KEduVocDocument::FileReaderFailed;
0122             }
0123 
0124             temp = inputStream.readLine();
0125         }
0126     } else {
0127         m_errorMessage = i18n("Error while reading file: No title");
0128         return KEduVocDocument::FileReaderFailed;
0129     }
0130 
0131     // 1 line header
0132     if (comment.isEmpty()) {
0133         titles = title.split(QStringLiteral("\","));
0134         m_doc->setTitle(titles[0].mid(1));
0135         qDebug() << "TitleA " << m_doc->title();
0136     }
0137     // longer header
0138     else {
0139         titles = comment.split(QStringLiteral("\","));
0140         m_doc->setDocumentComment(titles[0]);
0141         m_doc->setTitle(title.mid(1));
0142         qDebug() << "TitleB " << m_doc->title();
0143     }
0144 
0145     wordCount = titles[1].section(',', 0, 0).toInt();
0146     qDebug() << "WordCount " << wordCount;
0147 
0148     inputStream.readLine();
0149 
0150     lang1 = inputStream.readLine();
0151     languages = lang1.split(QStringLiteral("\","));
0152 
0153     if (languages.size() < 2) {
0154         m_errorMessage = i18n("Error while reading file: Didn't find two languages in %1", lang1);
0155         return KEduVocDocument::FileReaderFailed;
0156     }
0157 
0158     m_doc->appendIdentifier();
0159     QString language = languages[0].mid(1);
0160     m_doc->identifier(0).setLocale(language);
0161     m_doc->identifier(0).setName(language);
0162     qDebug() << "First language: " << language;
0163 
0164     m_doc->appendIdentifier();
0165     language = languages[1].mid(1);
0166     m_doc->identifier(1).setLocale(language);
0167     m_doc->identifier(1).setName(language);
0168     qDebug() << "Second language: " << language;
0169 
0170     QString section8Header(QStringLiteral("8. Lernhilfe")); // DO NOT translate
0171     while (!temp.contains(section8Header)) {
0172         if (inputStream.atEnd()) {
0173             m_errorMessage = i18n("Error while reading file: Missing \"%1\"", section8Header);
0174             return KEduVocDocument::FileReaderFailed;
0175         }
0176         temp = inputStream.readLine();
0177     }
0178 
0179     for (i = 0; i <= 14; ++i) {
0180         inputStream.readLine();
0181     }
0182 
0183     for (i = 0; i < wordCount - 1; ++i) {
0184         int c = 0;
0185         expression.clear();
0186 
0187         while (c < 2) {
0188             if (inputStream.atEnd()) {
0189                 m_errorMessage = i18n("Error while reading file: Expecting something like \"dog\",\"Hund\",1");
0190                 return KEduVocDocument::FileReaderFailed;
0191             }
0192             temp = inputStream.readLine();
0193             c += temp.count(QStringLiteral("\","), Qt::CaseSensitive);
0194             expression.append(temp);
0195             if (c < 2) {
0196                 expression.append(' ');
0197             }
0198         }
0199 
0200         words = expression.split(QStringLiteral("\","));
0201         original = words[0].mid(1);
0202         translation = words[1].mid(1);
0203         lessonNumber = words[2].toInt() - 1;
0204         maxLessonNumber = qMax(lessonNumber, maxLessonNumber);
0205 
0206         qDebug() << "Reading entry: " << original << " - " << translation << " Lesson: " << lessonNumber;
0207 
0208         // fallback if it's not read correctly
0209         if (lessonNumber < 0) {
0210             qDebug() << "Warning, invalid lesson found!";
0211             lessonNumber = 0;
0212         }
0213 
0214         while (m_doc->lesson()->childContainerCount() <= lessonNumber) {
0215             KEduVocLesson *lesson = new KEduVocLesson(i18n("Lesson %1", lessonNumber), m_doc->lesson());
0216             m_doc->lesson()->appendChildContainer(lesson);
0217             qDebug() << "Created lesson " << lessonNumber;
0218         }
0219 
0220         KEduVocExpression *kve = new KEduVocExpression;
0221         kve->setTranslation(0, original);
0222         kve->setTranslation(1, translation);
0223 
0224         static_cast<KEduVocLesson *>(m_doc->lesson()->childContainer(lessonNumber))->appendEntry(kve);
0225 
0226         inputStream.readLine();
0227         inputStream.readLine();
0228     }
0229 
0230     inputStream.readLine();
0231     inputStream.readLine();
0232     inputStream.readLine();
0233 
0234     int ii = 0;
0235     while (!inputStream.atEnd() && ii < lines && ii <= maxLessonNumber) {
0236         QString lessonDescr = inputStream.readLine();
0237         qDebug() << "Found lesson description " << lessonDescr;
0238         lessonDescr = lessonDescr.mid(1, lessonDescr.length() - 2);
0239         m_doc->lesson()->childContainer(ii)->setName(lessonDescr);
0240         if (lessonDescr.isEmpty()) {
0241             break;
0242         }
0243         inputStream.readLine();
0244         ++ii;
0245     }
0246 
0247     return KEduVocDocument::NoError;
0248 }