From 0a3910311ba6c33c2b70daeb9f5f465a55a55d27 Mon Sep 17 00:00:00 2001 From: APTX Date: Sun, 13 Feb 2011 14:42:13 +0100 Subject: [PATCH 1/1] AniAdd CLI --- AniAddCLI.pro | 16 +++ aniaddcli.cpp | 158 ++++++++++++++++++++++++++++ aniaddcli.h | 41 ++++++++ main.cpp | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 497 insertions(+) create mode 100644 AniAddCLI.pro create mode 100644 aniaddcli.cpp create mode 100644 aniaddcli.h create mode 100644 main.cpp diff --git a/AniAddCLI.pro b/AniAddCLI.pro new file mode 100644 index 0000000..bc45f0c --- /dev/null +++ b/AniAddCLI.pro @@ -0,0 +1,16 @@ +# ------------------------------------------------- +# Project created by QtCreator 2009-08-19T13:01:04 +# ------------------------------------------------- +QT -= gui +CONFIG += qxt console +QXT += core +TARGET = aniaddcli +DESTDIR = ./build +TEMPLATE = app +SOURCES += main.cpp \ + aniaddcli.cpp + +include(../../anidbudpclient/anidbudpclient.pri) + +HEADERS += \ + aniaddcli.h diff --git a/aniaddcli.cpp b/aniaddcli.cpp new file mode 100644 index 0000000..ead8f34 --- /dev/null +++ b/aniaddcli.cpp @@ -0,0 +1,158 @@ +#include "aniaddcli.h" + +#include +#include +#include +#include + +AniAddCli::AniAddCli(QObject *parent) : + QObject(parent), printHash(false) +{ + AniDBUdpClient::Client::instance()->setIdlePolicy(AniDBUdpClient::ImmediateLogoutIdlePolicy);; + connect(AniDBUdpClient::Client::instance(), SIGNAL(connectionError()), this, SLOT(handleError())); + + connect(this, SIGNAL(finished(int)), this, SLOT(exit(int)), Qt::QueuedConnection); +} + +AniAddCli::~AniAddCli() +{ + AniDBUdpClient::Client::destroy(); + qDeleteAll(m_files); +} + +AniDBUdpClient::MyListState AniAddCli::state() const +{ + return m_state; +} + +void AniAddCli::setState(const AniDBUdpClient::MyListState &state) +{ + m_state = state; +} + +void AniAddCli::process(const QStringList &files, bool rename, bool add, bool setState, bool hash) +{ + foreach(const QString &fileName, files) + { + QFileInfo fileInfo(fileName); + if (!fileInfo.exists()) + { + std::cout << "[FAIL] File " << fileInfo.absoluteFilePath().toUtf8().data() << " does not exist" << std::endl; + continue; + } + + AniDBUdpClient::File *file = new AniDBUdpClient::File(fileInfo); + connect(file, SIGNAL(statusUpdate(AniDBUdpClient::File::Action,AniDBUdpClient::File::ActionState,int)), this, SLOT(handleStatusUpdate(AniDBUdpClient::File::Action,AniDBUdpClient::File::ActionState,int))); + + file->setState(m_state); + + if (hash) + { + file->hash(); + printHash = true; + } + if (rename) + file->rename(); + if (add) + file->addToMyList(); + if (setState) + file->updateState(); + + m_files << file; + } + + if (m_files.isEmpty()) + { + std::cout << "No files to process" << std::endl; + emit finished(1); + return; + } + std::cout << "Processing " << m_files.count() << " files" << std::endl; +} + +void AniAddCli::handleStatusUpdate(AniDBUdpClient::File::Action action, AniDBUdpClient::File::ActionState state, int progress) +{ + AniDBUdpClient::File *file = (AniDBUdpClient::File *) sender(); + qDebug() << (action == AniDBUdpClient::File::All) << "ALLL"; + if (state == AniDBUdpClient::File::InProgress && progress) // Just show once per InProgress + return; + + if (action == AniDBUdpClient::File::All) + { + m_files.removeAll(file); + file->deleteLater(); + + if (!m_files.isEmpty()) + return; + + emit finished(0); + return; + } + + switch (state) + { + case AniDBUdpClient::File::Success: + std::cout << "[WIN!] "; + break; + case AniDBUdpClient::File::Failure: + std::cout << "[FAIL] "; + break; + case AniDBUdpClient::File::InProgress: + default: + std::cout << "[INFO] "; + break; + } + + switch (action) + { + case AniDBUdpClient::File::Hashing: + std::cout << "Hashing "; + break; + case AniDBUdpClient::File::Renaming: + std::cout << "Renaming "; + break; + case AniDBUdpClient::File::Adding: + std::cout << "Adding "; + break; + case AniDBUdpClient::File::SettingState: + std::cout << "Set State "; + break; + default: + std::cout << "Unknown Operation "; + break; + } + std::cout << "of file " << file->file().fileName().toUtf8().data(); + + switch (state) + { + case AniDBUdpClient::File::Success: + case AniDBUdpClient::File::Finished: + std::cout << " finished successfully!"; + break; + case AniDBUdpClient::File::Failure: + std::cout << " failed"; + break; + case AniDBUdpClient::File::InProgress: + default: + std::cout << " started"; + break; + } + std::cout << std::endl; + + if (printHash && action == AniDBUdpClient::File::Hashing && state == AniDBUdpClient::File::Success) + std::cout << "[HASH] " << file->file().fileName().toUtf8().constData() << " - " << file->ed2k().constData() << std::endl; +} + +void AniAddCli::handleError() +{ + std::cout << "[FAIL] Connection error: " << AniDBUdpClient::Client::instance()->errorString().toUtf8().data() + << std::endl; + emit finished(1); +} + +void AniAddCli::exit(int code) +{ + if (!code) + std::cout << "[INFO] Done" << std::endl; + qApp->exit(code); +} diff --git a/aniaddcli.h b/aniaddcli.h new file mode 100644 index 0000000..784760a --- /dev/null +++ b/aniaddcli.h @@ -0,0 +1,41 @@ +#ifndef RENAMETOOL_H +#define RENAMETOOL_H + +#include +#include +#include +#include + +class AniAddCli : public QObject +{ +Q_OBJECT +public: + explicit AniAddCli(QObject *parent = 0); + ~AniAddCli(); + + AniDBUdpClient::MyListState state() const; + void setState(const AniDBUdpClient::MyListState &state); + + void process(const QStringList &files, bool rename = true, bool add = true, bool setState = true, bool hash = false); + + + +signals: + void finished(int code = 0); + +public slots: + void handleStatusUpdate(AniDBUdpClient::File::Action action, AniDBUdpClient::File::ActionState state, int progress); + void handleError(); + + void exit(int code); + +private: + QString m_user; + QString m_pass; + QList m_files; + AniDBUdpClient::MyListState m_state; + + bool printHash; +}; + +#endif // RENAMETOOL_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..e010854 --- /dev/null +++ b/main.cpp @@ -0,0 +1,282 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include "aniaddcli.h" + +QString State2String(AniDBUdpClient::State state) +{ + using namespace AniDBUdpClient; + + QMap map; + map[StateUnknown] = "unknown"; + map[StateOnHdd] = "hdd"; + map[StateOnCd] = "cd"; + map[StateDeleted] = "deleted"; + + return map.value(state, "unknown"); +} + +AniDBUdpClient::State String2State(const QString &string) +{ + using namespace AniDBUdpClient; + + QMap map; + map["unknown"] = StateUnknown; + map["hdd"] = StateOnHdd; + map["cd"] = StateOnCd; + map["deleted"] = StateDeleted; + return map.value(string, StateUnknown); +} + +QString ViewedState2String(AniDBUdpClient::MyListState::ViewedState state) +{ + using namespace AniDBUdpClient; + + QMap map; + map[MyListState::Unset] = "unset"; + map[MyListState::Viewed] = "watched"; + map[MyListState::NotViewed] = "unwatched"; + + return map.value(state, "unknown"); +} + +AniDBUdpClient::MyListState::ViewedState String2ViewedState(const QString &string) +{ + using namespace AniDBUdpClient; + + QMap map; + map["unset"] = MyListState::Unset; + map["watched"] = MyListState::Viewed; + map["unwatched"] = MyListState::NotViewed; + return map.value(string, MyListState::Unset); +} + +int main(int argc, char *argv[]) +{ + qsrand(QTime().msecsTo(QTime::currentTime())); + + QCoreApplication a(argc, argv); + + QCoreApplication::setApplicationName(QLatin1String("AniAdd CLI")); + QCoreApplication::setOrganizationName(QLatin1String("APTX")); + QCoreApplication::setApplicationVersion(QLatin1String("1.0.0B1")); + + QSettings::setDefaultFormat(QSettings::IniFormat); + + AniDBUdpClient::MyListState state; + QxtCommandOptions opts; + + opts.setFlagStyle(QxtCommandOptions::SingleDash); + opts.setParamStyle(QxtCommandOptions::SpaceAndEquals); + + opts.addSection("Common options"); + opts.add("help", "Print this message"); + opts.alias("help", "h"); +// opts.add("config", "Use this config file", QxtCommandOptions::ValueRequired); +// opts.alias("config", "c"); + opts.add("no-config", "Do not read config file"); + opts.add("print-settings", "Print currently used settings. This takes into account the config settings + commandline settings"); + opts.alias("print-settings", "p"); + opts.add("write-config", "Write config file based on command line settings and exit"); + opts.alias("write-config", "w"); + + opts.addSection("Actions"); + opts.add("add", "Add file to MyList", QxtCommandOptions::NoValue, 1); + opts.add("no-add", "No not add file to MyList", QxtCommandOptions::NoValue, 1); + opts.add("rename", "Rename file", QxtCommandOptions::NoValue, 2); + opts.add("no-rename", "Do not rename file", QxtCommandOptions::NoValue, 2); + opts.add("update-state", "Update state even if file already added to MyList", QxtCommandOptions::NoValue, 3); + opts.add("no-update-state", "Do not update state", QxtCommandOptions::NoValue, 3); + opts.add("hash", "Print hash", QxtCommandOptions::NoValue, 4); + opts.add("no-hash", "Do not print hash", QxtCommandOptions::NoValue, 4); + + opts.addSection("Account settings"); + opts.add("user", "AniDB user name", QxtCommandOptions::ValueRequired); + opts.add("pass", "AniDB password", QxtCommandOptions::ValueRequired); + + opts.addSection("Connecton settings"); + opts.add("host", "AniDB UDP API host name", QxtCommandOptions::ValueRequired); + opts.add("host-port", "AniDB UDP API host port", QxtCommandOptions::ValueRequired); + opts.add("local-port", "Local port. WARNING: DO NOT CHANGE!", QxtCommandOptions::ValueRequired); + + opts.addSection("MyList settings"); + opts.add("state", "File state: hdd, cd, deleted or unknown", QxtCommandOptions::ValueRequired); + opts.alias("state", "s"); + opts.add("mark", "Mark file as watched, unwatched or unset", QxtCommandOptions::ValueRequired); + opts.alias("mark", "m"); + opts.add("source", "File source", QxtCommandOptions::ValueRequired); + opts.add("storage", "File storage", QxtCommandOptions::ValueRequired); + opts.add("other", "Other file info", QxtCommandOptions::ValueRequired); + + opts.parse(a.arguments()); + + if (opts.count("help")) { + std::cout << QCoreApplication::applicationName().toUtf8().constData() << " v" << QCoreApplication::applicationVersion().toUtf8().constData() + << " by " << QCoreApplication::organizationName().toUtf8().constData() << std::endl << std::endl; + opts.showUsage(); + return -1; + } + + bool rename = true; + bool add = true; + bool setState = true; + bool hash = false; + + // Read settings from config + if (!opts.count("no-config")) + { + AniDBUdpClient::Client *c = AniDBUdpClient::Client::instance(); + bool ok; + QSettings s; + s.beginGroup("actions"); + rename = s.value("rename", rename).toBool(); + add = s.value("add", add).toBool(); + setState = s.value("setState", setState).toBool(); + hash = s.value("hash", hash).toBool(); + s.endGroup(); + s.beginGroup("account"); + c->setUser(s.value("user", "").toString()); + c->setPass(s.value("pass", "").toString()); + s.endGroup(); + s.beginGroup("connection"); + c->setHost(s.value("host", c->host()).toString()); + uint hostPort = s.value("hostPort", c->hostPort()).toUInt(&ok); + if (ok) + c->setHostPort(quint16(hostPort)); + uint localPort = s.value("localPort", c->localPort()).toUInt(&ok); + if (ok) + c->setLocalPort(quint16(localPort)); + s.endGroup(); + s.beginGroup("myListState"); + state.setState(String2State(s.value("state", State2String(AniDBUdpClient::StateUnknown)).toString())); + state.setViewed(String2ViewedState(s.value("viewed", ViewedState2String(AniDBUdpClient::MyListState::Unset)).toString())); + state.setSource(s.value("source", QString()).toString()); + state.setStorage(s.value("storage", QString()).toString()); + state.setOther(s.value("other", QString()).toString()); + s.endGroup(); + } + + // Read config from commandline + { + AniDBUdpClient::Client *c = AniDBUdpClient::Client::instance(); + bool ok; + + if (opts.count("add")) + add = true; + if (opts.count("no-add")) + add = false; + if (opts.count("rename")) + rename = true; + if (opts.count("no-rename")) + rename = false; + if (opts.count("update-state")) + setState = true; + if (opts.count("no-update-state")) + setState = false; + if (opts.count("hash")) + hash = true; + if (opts.count("no-hash")) + hash = false; + + if (opts.count("user")) + c->setUser(opts.value("user").toString()); + if (opts.count("pass")) + c->setPass(opts.value("pass").toString()); + if (opts.count("host")) + c->setHost(opts.value("host").toString()); + if (opts.count("host-port")) + { + uint hostPort = opts.value("hostPort").toUInt(&ok); + if (ok) + c->setHostPort(quint16(hostPort)); + } + if (opts.count("local-port")) + { + uint localPort = opts.value("localPort").toUInt(&ok); + if (ok) + c->setLocalPort(quint16(localPort)); + } + if (opts.count("state")) + { + state.setState(String2State(opts.value("state").toString())); + } + if (opts.count("mark")) + state.setViewed(String2ViewedState(opts.value("mark").toString())); + if (opts.count("source")) + state.setSource(opts.value("source").toString()); + if (opts.count("storage")) + state.setStorage(opts.value("storage").toString()); + if (opts.count("other")) + state.setOther(opts.value("other").toString()); + } + + if (opts.count("print-settings")) + { + AniDBUdpClient::Client *c = AniDBUdpClient::Client::instance(); + using namespace std; + cout << "Actions:" << endl; + cout << " Add: " << (add ? "Yes" : "No") << endl; + cout << " Rename: " << (rename ? "Yes" : "No") << endl; + cout << " Update State: " << (setState ? "Yes" : "No") << endl; + cout << " Print Hash: " << (hash ? "Yes" : "No") << endl << endl; + + cout << "Account settings:" << endl; + cout << " User: " << c->user().toUtf8().constData() << endl; + cout << " Pass: " << (c->pass().isEmpty() ? "" : "****") << endl << endl; + + cout << "Connection settings:" << endl; + cout << " Host: " << c->host().toUtf8().constData() << endl; + cout << " Host port: " << c->hostPort() << endl; + cout << " Local port: " << c->localPort() << endl << endl; + + cout << "MyList settings:" << endl; + cout << " State: " << State2String(state.state()).toUtf8().constData() << endl; + cout << " Watched: " << ViewedState2String(state.viewed()).toUtf8().constData() << endl; + cout << " Source: " << state.source().toUtf8().constData() << endl; + cout << " Storage: " << state.storage().toUtf8().constData() << endl; + cout << " Other: " << state.other().toUtf8().constData() << endl; + cout << endl; + } + + if (opts.count("write-config")) + { + AniDBUdpClient::Client *c = AniDBUdpClient::Client::instance(); + QSettings s; + s.beginGroup("actions"); + s.setValue("rename", rename); + s.setValue("add", add); + s.setValue("setState", setState); + s.setValue("hash", hash); + s.endGroup(); + s.beginGroup("account"); + s.setValue("user", c->user()); + s.setValue("pass", c->pass()); + s.endGroup(); + s.beginGroup("connection"); + s.setValue("host", c->host()); + s.setValue("hostPort", c->hostPort()); + s.setValue("localPort", c->localPort()); + s.endGroup(); + s.beginGroup("myListState"); + s.setValue("state", State2String(state.state())); + s.setValue("viewed", ViewedState2String(state.viewed())); + s.setValue("source", state.source()); + s.setValue("storage", state.storage()); + s.setValue("other", state.other()); + s.endGroup(); + return 0; + } + + AniAddCli t; + t.setState(state); + + t.process(opts.positional(), rename, add, setState, hash); + + return a.exec(); +} -- 2.52.0