]> Some of my projects - localmylist.git/commitdiff
Make it possible to update anime titles directly from anidb.
authorAPTX <marek321@gmail.com>
Sat, 10 Nov 2012 03:03:40 +0000 (04:03 +0100)
committerAPTX <marek321@gmail.com>
Sat, 10 Nov 2012 03:03:40 +0000 (04:03 +0100)
import-titles/main.cpp
localmylist/animetitleparsetask.cpp
localmylist/animetitleparsetask.h
localmylist/mylist.cpp
localmylist/mylist.h
localmylist/share/schema/default_config.sql

index eee5d95bb566a24f318da8355260c9ab9ddc23e4..99f856dafac4a2b8a608bc1afa70dc264db11782 100644 (file)
@@ -2,7 +2,9 @@
 
 #include <QStringList>
 #include <QTextStream>
+#include <QUrl>
 #include "mylist.h"
+#include "settings.h"
 #include "abstracttask.h"
 
 using namespace LocalMyList;
@@ -11,12 +13,12 @@ int main(int argc, char *argv[])
 {
        QCoreApplication a(argc, argv);
        QTextStream cout(stdout);
-       if (a.arguments().count() < 2)
+/*     if (a.arguments().count() < 2)
        {
                cout << "Usage: " << a.arguments()[0] << " FILE";
                return 1;
        }
-
+*/
        LocalMyList::instance()->loadLocalSettings();
        if (!LocalMyList::instance()->database()->connect())
        {
@@ -24,7 +26,11 @@ int main(int argc, char *argv[])
                return 1;
        }
 
-       AbstractTask *t = LocalMyList::instance()->importTitles(a.arguments()[1]);
+       AbstractTask *t;
+       if (a.arguments().count() == 1)
+               t = LocalMyList::instance()->importTitlesFromUrl(QUrl::fromUserInput(LocalMyList::instance()->settings()->get("anidbTitleUrl").toString()));
+       else
+               t = LocalMyList::instance()->importTitles(a.arguments()[1]);
        QObject::connect(t, SIGNAL(finished()), &a, SLOT(quit()));
 
        return a.exec();
index 28a6ec7be6b986e38c3cdd2458e11ff02347484c..552bb093bcd5375a69ef55aba6b91ce78929cfae 100644 (file)
@@ -3,60 +3,49 @@
 #include <QStringList>
 #include "database.h"
 
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+
 #include <QDebug>
 
 namespace LocalMyList {
 
-AnimeTitleParseTask::AnimeTitleParseTask(QObject *parent) :
+AnimeTitleParseTaskBase::AnimeTitleParseTaskBase(QObject *parent) :
        AbstractTask(parent)
 {
 }
 
-QFileInfo AnimeTitleParseTask::file() const
-{
-       return m_file;
-}
 
-QString AnimeTitleParseTask::taskSubject() const
-{
-       return QString("Anime Title Parse (from file: %1)").arg(m_file.fileName());
-}
 
-bool AnimeTitleParseTask::canUseThreads() const
+bool AnimeTitleParseTaskBase::canUseThreads() const
 {
        return true;
 }
 
-void AnimeTitleParseTask::start()
-{
-       QFile f(m_file.absoluteFilePath());
-       if (!f.open(QIODevice::ReadOnly))
-       {
-               emit finished();
-               qWarning("AnimeTitleParseTask failed to open file");
-               return;
-       }
-
-       parse(&f);
-       emit finished();
-}
-
-void AnimeTitleParseTask::setFile(const QFileInfo &file)
-{
-       m_file = file;
-}
-
-void AnimeTitleParseTask::parse(QIODevice *device)
+void AnimeTitleParseTaskBase::setup()
 {
        db->transaction();
        db->truncateTitleData();
+       bytesRead = 0;
+       titles = 0;
+       buf.clear();
+}
 
-       int titles = 0;
-       QByteArray buf;
+void AnimeTitleParseTaskBase::parse(QIODevice *device)
+{
        while (!device->atEnd())
        {
-               buf = device->readLine();
-               QString s = QString::fromUtf8(buf);
+               QByteArray line = device->readLine();
+               buf += line;
+               bytesRead += line.length();
+
+               if (line.indexOf('\n') == -1)
+                       continue;
+               line = buf; // Buf has at most one line
+               buf.clear();
+
+               QString s = QString::fromUtf8(line);
                s = s.trimmed();
                if (s.startsWith(QChar('#')))
                        continue;
@@ -81,11 +70,108 @@ void AnimeTitleParseTask::parse(QIODevice *device)
                if (titles % 100 != 0)
                        continue;
                qDebug() << "Read" << titles << "titles";
-               emit progress(device->pos(), device->size());
+               emit progress(bytesRead, device->size());
        }
-       qDebug() << "Done. Read" << titles << "titles";
+}
 
+void AnimeTitleParseTaskBase::finalize()
+{
+       qDebug() << "Done. Read" << titles << "titles";
        db->commit();
 }
 
+void AnimeTitleParseTaskBase::fail()
+{
+       qDebug() << "Read error";
+       db->rollback();
+}
+
+// ----
+
+QFileInfo AnimeTitleParseFileTask::file() const
+{
+       return m_file;
+}
+
+QString AnimeTitleParseFileTask::taskSubject() const
+{
+       return QString("Anime Title Parse (from file: %1)").arg(m_file.fileName());
+}
+
+void AnimeTitleParseFileTask::start()
+{
+       QFile f(m_file.absoluteFilePath());
+       if (!f.open(QIODevice::ReadOnly))
+       {
+               emit finished();
+               qWarning("AnimeTitleParseTask failed to open file");
+               return;
+       }
+
+       setup();
+       parse(&f);
+       finalize();
+       emit finished();
+}
+
+void AnimeTitleParseFileTask::setFile(const QFileInfo &file)
+{
+       m_file = file;
+}
+
+// ----
+
+AnimeTitleParseNetworkTask::AnimeTitleParseNetworkTask(QObject *parent) : AnimeTitleParseTaskBase(parent), nam(0), reply(0)
+{
+}
+
+QUrl AnimeTitleParseNetworkTask::url() const
+{
+       return m_url;
+}
+
+QString AnimeTitleParseNetworkTask::taskSubject() const
+{
+       return  QString("Anime Title Parse (from url: %1)").arg(m_url.toString());
+}
+
+void AnimeTitleParseNetworkTask::start()
+{
+       nam = new QNetworkAccessManager(this);
+       QNetworkRequest request(m_url);
+       reply = nam->get(request);
+       reply->ignoreSslErrors();
+       connect(reply, SIGNAL(readyRead()), this, SLOT(readSome()));
+       connect(reply, SIGNAL(finished()), this, SLOT(handleFinished()));
+       setup();
+}
+
+void AnimeTitleParseNetworkTask::setUrl(const QUrl &url)
+{
+       m_url = url;
+}
+
+void AnimeTitleParseNetworkTask::readSome()
+{
+       parse(reply);
+}
+
+void AnimeTitleParseNetworkTask::handleFinished()
+{
+       if (reply->error() == QNetworkReply::NoError)
+               finalize();
+       else
+               fail();
+       reply->deleteLater();
+       nam->deleteLater();
+       reply = 0;
+       nam = 0;
+
+       emit finished();
+}
+
+AnimeTitleParseFileTask::AnimeTitleParseFileTask(QObject *parent) : AnimeTitleParseTaskBase(parent)
+{
+}
+
 } // namespace LocalMyList
index 1f8d19f15a02a643a4638a3ddb0240d91c8d698d..cb39ea0c3789f23cf446216bcefde6e436a0b250 100644 (file)
@@ -4,30 +4,74 @@
 #include "abstracttask.h"
 #include <QFileInfo>
 
+#include <QUrl>
+class QNetworkAccessManager;
+class QNetworkReply;
+
 namespace LocalMyList {
 
-class LOCALMYLISTSHARED_EXPORT AnimeTitleParseTask : public AbstractTask
+class LOCALMYLISTSHARED_EXPORT AnimeTitleParseTaskBase : public AbstractTask
 {
        Q_OBJECT
+protected:
+       explicit AnimeTitleParseTaskBase(QObject *parent = 0);
+
 public:
-       explicit AnimeTitleParseTask(QObject *parent = 0);
-       
-       QFileInfo file() const;
-       QString taskSubject() const;
        bool canUseThreads() const;
 
+       void start() = 0;
+
+protected:
+       void setup();
+       void parse(QIODevice *device);
+       void finalize();
+       void fail();
+
+       QByteArray buf;
+       qint64 bytesRead;
+       int titles;
+};
+
+class LOCALMYLISTSHARED_EXPORT AnimeTitleParseFileTask : public AnimeTitleParseTaskBase
+{
+       Q_OBJECT
+public:
+       explicit AnimeTitleParseFileTask(QObject *parent = 0);
+       QFileInfo file() const;
+       QString taskSubject() const;
        void start();
 
 public slots:
        void setFile(const QFileInfo &file);
 
-private:
-       void parse(QIODevice *device);
-
+protected:
        QFileInfo m_file;
-       
 };
 
+class LOCALMYLISTSHARED_EXPORT AnimeTitleParseNetworkTask : public AnimeTitleParseTaskBase
+{
+       Q_OBJECT
+public:
+       explicit AnimeTitleParseNetworkTask(QObject *parent = 0);
+       QUrl url() const;
+       QString taskSubject() const;
+
+       void start();
+
+public slots:
+       void setUrl(const QUrl &url);
+
+private slots:
+       void readSome();
+       void handleFinished();
+
+private:
+       QUrl m_url;
+       QNetworkAccessManager *nam;
+       QNetworkReply *reply;
+};
+
+
 } // namespace LocalMyList
 
 #endif // ANIMETITLEPARSETASK_H
index 0fc4cc3a27f5240efe7bd61d5938f2d412f7f6df..b123d2757d9b138775a0304fb4cd9104c3993545 100644 (file)
@@ -215,12 +215,20 @@ AbstractTask *MyList::addDirectory(const QDir &directory)
 
 AbstractTask *MyList::importTitles(const QFileInfo &file)
 {
-       AnimeTitleParseTask *task = new AnimeTitleParseTask();
+       AnimeTitleParseFileTask *task = new AnimeTitleParseFileTask();
        task->setFile(file);
        executeTask(task);
        return task;
 }
 
+AbstractTask *MyList::importTitlesFromUrl(const QUrl &url)
+{
+       AnimeTitleParseNetworkTask *task = new AnimeTitleParseNetworkTask();
+       task->setUrl(url);
+       executeTask(task);
+       return task;
+}
+
 AbstractTask *MyList::importMyList(const QFileInfo &file)
 {
        MyListExportParseTask *task = new MyListExportParseTask();
index 41c47015bf244e9d77ce802936a55b4bac2d0a03..b36054cfb077dafed6ad3f16189f9eb5020ea488 100644 (file)
@@ -52,6 +52,7 @@ public slots:
        AbstractTask *addFile(const QFileInfo &file);
        AbstractTask *addDirectory(const QDir &directory);
        AbstractTask *importTitles(const QFileInfo &file);
+       AbstractTask *importTitlesFromUrl(const QUrl &url);
        AbstractTask *importMyList(const QFileInfo &file);
        void executeTask(AbstractTask *task);
 
index c0d587e0ba43eae9bba2c238dd75d8edce234622..ff7252409bfdea5511bb8c75595ce22aa7208c24 100644 (file)
@@ -25,6 +25,7 @@ INSERT INTO config VALUES ('enableRename', '0', true);
 
 INSERT INTO config VALUES ('fileFilters', '*.mkv *.mp4 *.ogg *.ogm *.wmv *.avi *.mpg *.flv', true);
 
+INSERT INTO config VALUES ('anidbTitleUrl', 'http://anidb.net/api/animetitles.dat.gz', true);
 
 -- Episode types
 INSERT INTO episode_type VALUES ('', 'Normal', 0);