hashproducer.cpp \\r
hashconsumer.cpp \\r
clientsentcommandsmodel.cpp \\r
- clientqueuedcommandsmodel.cpp\r
+ clientqueuedcommandsmodel.cpp \\r
+ filerenamedelegate.cpp\r
\r
HEADERS += client.h \\r
anidbudpclient_global.h \\r
hashconsumer.h \\r
circularbuffer.h \\r
clientsentcommandsmodel.h \\r
- clientqueuedcommandsmodel.h\r
+ clientqueuedcommandsmodel.h \\r
+ filerenamedelegate.h\r
\r
CONV_HEADERS += include/AniDBUdpClient/Client \\r
include/AniDBUdpClient/AbstractCommand \\r
include/AniDBUdpClient/File \\r
include/AniDBUdpClient/Hash \\r
include/AniDBUdpClient/ClientSentCommandsModel \\r
- include/AniDBUdpClient/ClientQueuedCommandsModel\r
+ include/AniDBUdpClient/ClientQueuedCommandsModel \\r
+ include/AniDBUdpClient/FileRenameDelegate\r
\r
# RenameParser Files\r
\r
Q_FLAGS(FileAnimeFlag::FileAnimeFlag);
Q_DECLARE_FLAGS(FileAnimeFlags, FileAnimeFlag::FileAnimeFlag);
Q_DECLARE_OPERATORS_FOR_FLAGS(FileAnimeFlags);
- typedef FileAnimeFlag::FileAnimeFlag FileAMask;
+ typedef FileAnimeFlags FileAMask;
namespace AnimeFlag {
static const qint64 CategoryWeightList = Q_INT64_C(0x0000000000000001);
#include <QRegExp>
#include "client.h"
#include "hash.h"
+#include "filerenamedelegate.h"
#include <QDebug>
return m_markingState;
}
+void File::setRenameDelegate(FileRenameDelegate *renameHelper)
+{
+ m_renameDelegate = renameHelper;
+}
+
+FileRenameDelegate *File::renameDelegate() const
+{
+ return m_renameDelegate;
+}
+
void File::hash()
{
if (name.isEmpty())
name = fileReply->value(FileAnimeFlag::EnglishName).toString();
- QString newFileName = tr("%1 - %2 - %3 - [%4](%5).%6")
+ QString newFileName, newFilePath;
+
+ if (m_renameDelegate)
+ {
+ m_renameDelegate->rename(fileReply, newFileName, newFilePath);
+ }
+ else
+ {
+ newFileName = tr("%1 - %2 - %3 - [%4](%5).%6")
.arg(name)
.arg(fileReply->value(FileAnimeFlag::EpNo).toString())
.arg(fileReply->value(FileAnimeFlag::EpName).toString())
.arg(fileReply->value(FileAnimeFlag::GroupShortName).toString())
.arg(fileReply->value(FileFlag::Crc32).toString())
.arg(fileReply->value(FileFlag::FileType).toString());
-
+ }
newFileName.replace('"', "'");
newFileName.replace(QRegExp("[\\/]"), "-");
newFileName.replace(QRegExp("[\\/:*?\"<>|]"), "");
| FileAnimeFlag::EpNo
| FileAnimeFlag::EpName
| FileAnimeFlag::GroupShortName);
+
+
+ if (m_renameDelegate)
+ {
+ fileCommand.setAmask(m_renameDelegate->requiredAMask());
+ fileCommand.setFmask(m_renameDelegate->requiredFMask());
+ }
+
fileReply = Client::instance()->send(fileCommand);
connect(fileReply, SIGNAL(replyReady(bool)), this, SLOT(finishRenaming(bool)));
m_hashingState = m_renamingState = m_addingState = m_markingState = NotStarted;
notWorking = true;
+ m_renameDelegate = 0;
+
connect(this, SIGNAL(statusUpdate(AniDBUdpClient::File::Action,AniDBUdpClient::File::ActionState)), this, SLOT(workOnFinished(AniDBUdpClient::File::Action,AniDBUdpClient::File::ActionState)));
}
class MyListCommand;
class HashResult;
+class FileRenameDelegate;
+
class ANIDBUDPCLIENTSHARED_EXPORT File : public QObject
{
Q_OBJECT
ActionState addingState() const;
ActionState markingState() const;
+ void setRenameDelegate(FileRenameDelegate *renameDelegate);
+ FileRenameDelegate *renameDelegate() const;
+
public slots:
void hash();
bool rename();
MyListAddReply *addReply;
MyListAddReply *markReply;
+ FileRenameDelegate *m_renameDelegate;
+
};
} // namespace AniDBUdpClient
Q_PROPERTY(int fid READ fid);
public:
+
+ enum State
+ {
+ CrcOk = 0x00000001,
+ CrcErr = 0x00000002,
+ IsV2 = 0x00000004,
+ IsV3 = 0x00000008,
+ IsV4 = 0x00000010,
+ IsV5 = 0x00000020,
+ Uncensored = 0x00000040,
+ Censored = 0x00000080,
+ };
+
int fid() const;
QVariant value(FileFlags f) const;
--- /dev/null
+#include "filerenamedelegate.h"
+
+#include "filecommand.h"
+
+namespace AniDBUdpClient {
+
+FileRenameDelegate::FileRenameDelegate(RenameParser::RenameEngine *renameEngine, QObject *parent) :
+ QObject(parent), m_renameEngine(0), fMask(FileFlags()), aMask(FileAnimeFlags())
+{
+ setRenameEngine(renameEngine);
+}
+
+FileRenameDelegate::~FileRenameDelegate()
+{
+ if (m_renameEngine)
+ delete m_renameEngine;
+}
+
+RenameParser::RenameEngine *FileRenameDelegate::renameEngine() const
+{
+ return m_renameEngine;
+}
+
+void FileRenameDelegate::setRenameEngine(RenameParser::RenameEngine *renameEngine)
+{
+ if (m_renameEngine)
+ {
+ m_renameEngine->disconnect(this);
+ m_renameEngine->deleteLater();
+ }
+
+ m_renameEngine = renameEngine;
+ if (!m_renameEngine)
+ return;
+
+ connect(m_renameEngine, SIGNAL(renameStringChanged()), this, SLOT(updateMasks()));
+}
+
+
+FileAMask FileRenameDelegate::requiredAMask() const
+{
+ return aMask;
+}
+
+FMask FileRenameDelegate::requiredFMask() const
+{
+ return fMask;
+}
+
+void FileRenameDelegate::rename(const AniDBUdpClient::FileReply *reply, QString &fileName, QString &filePath)
+{
+ if (!m_renameEngine || !reply)
+ return;
+
+ RenameParser::Environment env;
+
+ env["ATr"] = reply->value(FileAnimeFlag::RomajiName).toString();
+ env["ATe"] = reply->value(FileAnimeFlag::EnglishName).toString();
+ env["ATk"] = reply->value(FileAnimeFlag::KanjiName).toString();
+
+ env["ETr"] = reply->value(FileAnimeFlag::EpRomajiName).toString();
+ env["ETe"] = reply->value(FileAnimeFlag::EpName).toString();
+ env["ETk"] = reply->value(FileAnimeFlag::EpKanjiName).toString();
+
+ env["GTs"] = reply->value(FileAnimeFlag::GroupName).toString();
+ env["GTl"] = reply->value(FileAnimeFlag::GroupShortName).toString();
+
+ env["EpNo"] = reply->value( FileAnimeFlag::EpNo).toString();
+ env["EpHiNo"] = reply->value(FileAnimeFlag::AnimeTotalEpisodes).toString();
+ env["EpCount"] = reply->value(FileAnimeFlag::HighestEpisodeNumber).toString();
+
+ QString airDate = reply->value(FileFlag::AiredDate).toString();
+ if (!airDate.contains('-'))
+ {
+ env["AYearBegin"] = airDate;
+ env["AYearEnd"] = "";
+ }
+ else
+ {
+ QStringList years = airDate.split('-');
+ env["AYearBegin"] = years[0].trimmed();
+ env["AYearEnd"] = years[1].trimmed();
+ }
+
+
+ env["Type"] = reply->value(FileFlag::FileType).toString();
+ env["Depr"] = reply->value(FileFlag::IsDeprecated).toInt() ? "1" : "";
+
+ const int state = reply->value(FileFlag::State).toInt();
+
+ env["Cen"] = state & FileReply::Censored ? "1" : "0";
+
+ int version = 1;
+ if (state & FileReply::IsV2)
+ version = 2;
+ if (state & FileReply::IsV3)
+ version = 3;
+ if (state & FileReply::IsV4)
+ version = 4;
+ if (state & FileReply::IsV5)
+ version = 5;
+
+ env["Ver"] = QString::number(version);
+ env["Source"] = reply->value(FileFlag::Source).toString();
+ env["Quality"] = reply->value(FileFlag::Quality).toString();
+ env["FCrc"] = reply->value(FileFlag::Crc32).toString();
+ env["FVideoRes"] = reply->value(FileFlag::VideoResolution).toString();
+ env["FALng"] = reply->value(FileFlag::DubLanguage).toString();
+ env["FSLng"] = reply->value(FileFlag::SubLanguage).toString();
+
+ m_renameEngine->evaluate(env);
+
+ fileName = env.value("FileName", "");
+ filePath = env.value("FilePath", "");
+}
+
+void FileRenameDelegate::updateMasks()
+{
+ static bool init = true;
+ static QMap<QString, FMask> fMaskVars;
+ static QMap<QString, FileAMask> aMaskVars;
+
+ if (init)
+ {
+ fMaskVars["Type"] = FileFlag::FileType;
+ fMaskVars["Depr"] = FileFlag::IsDeprecated;
+ fMaskVars["Cen"] = FileFlag::State;
+ fMaskVars["Ver"] = FileFlag::State;
+ fMaskVars["Source"] = FileFlag::Source;
+ fMaskVars["Quality"] = FileFlag::Quality;
+ fMaskVars["AYearBegin"] = FileFlag::AiredDate;
+ fMaskVars["AYearEnd"] = FileFlag::AiredDate;
+ fMaskVars["FCrc"] = FileFlag::Crc32;
+ fMaskVars["FVideoRes"] = FileFlag::VideoResolution;
+ fMaskVars["FALng"] = FileFlag::DubLanguage;
+ fMaskVars["FSLng"] = FileFlag::SubLanguage;
+// Not implemented in FileCommand.
+// fMaskVars["Watched"] = FileFlag::;
+
+ aMaskVars["ATr"] = FileAnimeFlag::RomajiName;
+ aMaskVars["ATe"] = FileAnimeFlag::EnglishName;
+ aMaskVars["ATk"] = FileAnimeFlag::KanjiName;
+
+ aMaskVars["ETr"] = FileAnimeFlag::EpRomajiName;
+ aMaskVars["ETe"] = FileAnimeFlag::EpName;
+ aMaskVars["ETk"] = FileAnimeFlag::EpKanjiName;
+
+ aMaskVars["GTs"] = FileAnimeFlag::GroupName;
+ aMaskVars["GTl"] = FileAnimeFlag::GroupShortName;
+
+ aMaskVars["EpNo"] = FileAnimeFlag::EpNo;
+ aMaskVars["EpHiNo"] = FileAnimeFlag::AnimeTotalEpisodes;
+ aMaskVars["EpCount"] = FileAnimeFlag::HighestEpisodeNumber;
+
+ init = false;
+ }
+
+ if (!m_renameEngine)
+ return;
+
+ QStringList usedVars = m_renameEngine->usedVariables();
+
+ fMask = 0;
+ aMask = 0;
+
+ foreach (const QString &var, usedVars)
+ {
+ if (fMaskVars.contains(var))
+ fMask |= fMaskVars[var];
+ if (aMaskVars.contains(var))
+ aMask |= aMaskVars[var];
+ }
+}
+
+} // namespace AniDBUdpClient
--- /dev/null
+#ifndef FILERENAMEDELEGATE_H
+#define FILERENAMEDELEGATE_H
+
+#include "anidbudpclient_global.h"
+#include "renameparser/renameengine.h"
+
+#include <QObject>
+#include <QStringList>
+
+namespace AniDBUdpClient {
+
+class FileReply;
+
+class ANIDBUDPCLIENTSHARED_EXPORT FileRenameDelegate : public QObject
+{
+ Q_OBJECT
+public:
+ explicit FileRenameDelegate(RenameParser::RenameEngine *renameEngine = 0, QObject *parent = 0);
+ ~FileRenameDelegate();
+
+ RenameParser::RenameEngine *renameEngine() const;
+ void setRenameEngine(RenameParser::RenameEngine *renameEngine);
+
+ FileAMask requiredAMask() const;
+ FMask requiredFMask() const;
+
+ void rename(const FileReply *reply, QString &fileName, QString &filePath);
+
+private slots:
+ void updateMasks();
+
+private:
+ RenameParser::RenameEngine *m_renameEngine;
+
+ FMask fMask;
+ FileAMask aMask;
+};
+
+} // namespace AniDBUdpClient
+
+#endif // FILERENAMEDELEGATE_H
--- /dev/null
+#include "../../filerenamedelegate.h"
\ No newline at end of file
namespace RenameFunctions
{
- QString _max(const QStringList &args);
+#ifdef max
+#undef max
+#endif
+ QString max(const QStringList &args);
QString len(const QStringList &args);
QString pad(const QStringList &args);
QString repl(const QStringList &args);
void RenameEngine::setCurrentParserType(ParserType parserType)
{
+ if (m_parserType == parserType)
+ return;
m_parserType = parserType;
delete parser;
parser = createParser(parserType);
#ifdef PARSER_DEBUG
qDebug() << "-----------------------------------------------------------------";
#endif
-return b;
+ emit renameStringChanged();
+ return b;
}
QString RenameEngine::evaluate(Environment &env)
return parser->column();
}
+QStringList RenameEngine::usedVariables() const
+{
+ return parser->usedVariables();
+}
+
AbstractParser *RenameEngine::createParser(ParserType type) const
{
switch (type)
typedef QString (*RenameFunction)(const QStringList &args);
-class ANIDBUDPCLIENTSHARED_EXPORT RenameEngine
+class ANIDBUDPCLIENTSHARED_EXPORT RenameEngine : public QObject
{
+ Q_OBJECT
+
public:
enum ParserType {
AniAdd,
int line() const;
int column() const;
+ QStringList usedVariables() const;
+
+signals:
+ void renameStringChanged();
+
private:
AbstractParser *createParser(ParserType type) const;
} // namespace
+Q_DECLARE_METATYPE(RenameParser::RenameEngine::ParserType)
+
#endif // RENAMEENGINE_H