From: APTX Date: Sat, 10 Nov 2012 03:03:40 +0000 (+0100) Subject: Make it possible to update anime titles directly from anidb. X-Git-Url: https://gitweb.tyo.aptx.org/?a=commitdiff_plain;h=cb4da1878c3141fb54c82878123f7eff7c0e016a;p=localmylist.git Make it possible to update anime titles directly from anidb. --- diff --git a/import-titles/main.cpp b/import-titles/main.cpp index eee5d95..99f856d 100644 --- a/import-titles/main.cpp +++ b/import-titles/main.cpp @@ -2,7 +2,9 @@ #include #include +#include #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(); diff --git a/localmylist/animetitleparsetask.cpp b/localmylist/animetitleparsetask.cpp index 28a6ec7..552bb09 100644 --- a/localmylist/animetitleparsetask.cpp +++ b/localmylist/animetitleparsetask.cpp @@ -3,60 +3,49 @@ #include #include "database.h" +#include +#include +#include + #include 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 diff --git a/localmylist/animetitleparsetask.h b/localmylist/animetitleparsetask.h index 1f8d19f..cb39ea0 100644 --- a/localmylist/animetitleparsetask.h +++ b/localmylist/animetitleparsetask.h @@ -4,30 +4,74 @@ #include "abstracttask.h" #include +#include +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 diff --git a/localmylist/mylist.cpp b/localmylist/mylist.cpp index 0fc4cc3..b123d27 100644 --- a/localmylist/mylist.cpp +++ b/localmylist/mylist.cpp @@ -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(); diff --git a/localmylist/mylist.h b/localmylist/mylist.h index 41c4701..b36054c 100644 --- a/localmylist/mylist.h +++ b/localmylist/mylist.h @@ -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); diff --git a/localmylist/share/schema/default_config.sql b/localmylist/share/schema/default_config.sql index c0d587e..ff72524 100644 --- a/localmylist/share/schema/default_config.sql +++ b/localmylist/share/schema/default_config.sql @@ -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);