File indexing completed on 2024-04-21 14:53:27

0001 //  -*- c-basic-offset:4; indent-tabs-mode:nil -*-
0002 /*
0003     This file is part of the KDE libraries
0004     SPDX-FileCopyrightText: 2002-2003 Alexander Kellett <lypanov@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #include "kbookmarkimporter_ie.h"
0010 #include "kbookmarkimporter.h"
0011 #include "kbookmarks_debug.h"
0012 
0013 #include <QFileDialog>
0014 
0015 #include <QApplication>
0016 #include <QRegularExpression>
0017 
0018 #include <qplatformdefs.h>
0019 
0020 
0021 /**
0022  * A class for importing IE bookmarks
0023  * @deprecated
0024  */
0025 class KIEBookmarkImporter : public QObject
0026 {
0027     Q_OBJECT
0028 public:
0029     KIEBookmarkImporter(const QString &fileName)
0030         : m_fileName(fileName)
0031     {
0032     }
0033     ~KIEBookmarkImporter() override
0034     {
0035     }
0036 
0037     void parseIEBookmarks();
0038 
0039     // Usual place for IE bookmarks
0040     static QString IEBookmarksDir();
0041 
0042 Q_SIGNALS:
0043     void newBookmark(const QString &text, const QString &url, const QString &additionalInfo);
0044     void newFolder(const QString &text, bool open, const QString &additionalInfo);
0045     void newSeparator();
0046     void endFolder();
0047 
0048 protected:
0049     void parseIEBookmarks_dir(const QString &dirname, const QString &name = QString());
0050     void parseIEBookmarks_url_file(const QString &filename, const QString &name);
0051 
0052     const QString m_fileName;
0053 };
0054 
0055 void KIEBookmarkImporter::parseIEBookmarks_url_file(const QString &filename, const QString &name)
0056 {
0057     static const int g_lineLimit = 16 * 1024;
0058 
0059     QFile f(filename);
0060 
0061     if (f.open(QIODevice::ReadOnly)) {
0062         QByteArray s(g_lineLimit, 0);
0063 
0064         while (f.readLine(s.data(), g_lineLimit) >= 0) {
0065             if (s[s.length() - 1] != '\n') { // Gosh, this line is longer than g_lineLimit. Skipping.
0066                 qCWarning(KBOOKMARKS_LOG) << "IE bookmarks contain a line longer than " << g_lineLimit << ". Skipping.";
0067                 continue;
0068             }
0069             const QString t = QString::fromUtf8(s.trimmed());
0070             QRegularExpression rx(QStringLiteral("URL=(.*)"));
0071             auto match = rx.match(t);
0072             if (match.hasMatch()) {
0073                 Q_EMIT newBookmark(name, match.captured(1), QLatin1String(""));
0074             }
0075         }
0076 
0077         f.close();
0078     }
0079 }
0080 
0081 void KIEBookmarkImporter::parseIEBookmarks_dir(const QString &dirname, const QString &foldername)
0082 {
0083     QDir dir(dirname);
0084     dir.setFilter(QDir::Files | QDir::Dirs | QDir::AllDirs);
0085     dir.setSorting(QFlags<QDir::SortFlag>(QDir::Name | QDir::DirsFirst));
0086     dir.setNameFilters(QStringList(QStringLiteral("*.url"))); // AK - possibly add ";index.ini" ?
0087 
0088     const QFileInfoList list = dir.entryInfoList();
0089     if (list.isEmpty()) {
0090         return;
0091     }
0092 
0093     if (dirname != m_fileName) {
0094         Q_EMIT newFolder(foldername, false, QLatin1String(""));
0095     }
0096 
0097     for (const QFileInfo &fi : list) {
0098         if (fi.fileName() == QLatin1String(".") || fi.fileName() == QLatin1String("..")) {
0099             continue;
0100         }
0101 
0102         if (fi.isDir()) {
0103             parseIEBookmarks_dir(fi.absoluteFilePath(), fi.fileName());
0104 
0105         } else if (fi.isFile()) {
0106             if (fi.fileName().endsWith(QLatin1String(".url"))) {
0107                 QString name = fi.fileName();
0108                 name.truncate(name.length() - 4); // .url
0109                 parseIEBookmarks_url_file(fi.absoluteFilePath(), name);
0110             }
0111             // AK - add index.ini
0112         }
0113     }
0114 
0115     if (dirname != m_fileName) {
0116         Q_EMIT endFolder();
0117     }
0118 }
0119 
0120 void KIEBookmarkImporter::parseIEBookmarks()
0121 {
0122     parseIEBookmarks_dir(m_fileName);
0123 }
0124 
0125 QString KIEBookmarkImporter::IEBookmarksDir()
0126 {
0127     static KIEBookmarkImporterImpl *p = nullptr;
0128     if (!p) {
0129         p = new KIEBookmarkImporterImpl;
0130     }
0131     return p->findDefaultLocation();
0132 }
0133 
0134 void KIEBookmarkImporterImpl::parse()
0135 {
0136     KIEBookmarkImporter importer(m_fileName);
0137     setupSignalForwards(&importer, this);
0138     importer.parseIEBookmarks();
0139 }
0140 
0141 QString KIEBookmarkImporterImpl::findDefaultLocation(bool) const
0142 {
0143     // notify user that they must give a new dir such
0144     // as "Favourites" as otherwise it'll just place
0145     // lots of .url files in the given dir and gui
0146     // stuff in the exporter is ugly so that exclues
0147     // the possibility of just writing to Favourites
0148     // and checking if overwriting...
0149     return QFileDialog::getExistingDirectory(QApplication::activeWindow());
0150 }
0151 
0152 /////////////////////////////////////////////////
0153 
0154 class IEExporter : private KBookmarkGroupTraverser
0155 {
0156 public:
0157     IEExporter(const QString &);
0158     void write(const KBookmarkGroup &grp)
0159     {
0160         traverse(grp);
0161     }
0162 
0163 private:
0164     void visit(const KBookmark &) override;
0165     void visitEnter(const KBookmarkGroup &) override;
0166     void visitLeave(const KBookmarkGroup &) override;
0167 
0168 private:
0169     QDir m_currentDir;
0170 };
0171 
0172 static QString ieStyleQuote(const QString &str)
0173 {
0174     QString s(str);
0175     s.replace(QRegularExpression(QStringLiteral("[/\\:*?\"<>|]")), QStringLiteral("_"));
0176     return s;
0177 }
0178 
0179 IEExporter::IEExporter(const QString &dname)
0180 {
0181     m_currentDir.setPath(dname);
0182 }
0183 
0184 void IEExporter::visit(const KBookmark &bk)
0185 {
0186     const QString fname = m_currentDir.path() + QLatin1Char('/') + ieStyleQuote(bk.fullText()) + QLatin1String(".url");
0187     // qCDebug(KBOOKMARKS_LOG) << "visit(" << bk.text() << "), fname == " << fname;
0188     QFile file(fname);
0189     if (file.open(QIODevice::WriteOnly)) {
0190         QTextStream ts(&file);
0191         ts << "[InternetShortcut]\r\n";
0192         ts << "URL=" << bk.url().toString().toUtf8() << "\r\n";
0193     }
0194 }
0195 
0196 void IEExporter::visitEnter(const KBookmarkGroup &grp)
0197 {
0198     const QString dname = m_currentDir.path() + QLatin1Char('/') + ieStyleQuote(grp.fullText());
0199     // qCDebug(KBOOKMARKS_LOG) << "visitEnter(" << grp.text() << "), dname == " << dname;
0200     m_currentDir.mkdir(dname);
0201     m_currentDir.cd(dname);
0202 }
0203 
0204 void IEExporter::visitLeave(const KBookmarkGroup &)
0205 {
0206     // qCDebug(KBOOKMARKS_LOG) << "visitLeave()";
0207     m_currentDir.cdUp();
0208 }
0209 
0210 void KIEBookmarkExporterImpl::write(const KBookmarkGroup &parent)
0211 {
0212     IEExporter exporter(m_fileName);
0213     exporter.write(parent);
0214 }
0215 
0216 #include "kbookmarkimporter_ie.moc"
0217 #include "moc_kbookmarkimporter_ie.cpp"