File indexing completed on 2024-04-28 05:49:59

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