myFileState = 0;
}
+FileLocation::FileLocation()
+{
+ fid = 0;
+ hostId = 0;
+ failedRename = false;
+}
+
FileEpisodeRel::FileEpisodeRel()
{
fid = 0;
return fid;
}
-bool Database::setFileLocation(int fid, int hostId, const QString &location)
+bool Database::addFileLocation(const FileLocation &fileLocation)
+{
+ QSqlQuery q(d->db);
+ q.prepare("INSERT INTO file_location VALUES(:fid, :hostId, :path, DEFAULT, DEFAULT)");
+ q.bindValue(":fid", fileLocation.fid);
+ q.bindValue(":hostId", fileLocation.hostId);
+ q.bindValue(":path", fileLocation.path);
+
+ return exec(q);
+}
+
+bool Database::setFileLocation(const FileLocation &fileLocation)
{
QSqlQuery q(d->db);
- q.prepare("INSERT INTO file_location VALUES(:fid, :hostId, :path)");
- q.bindValue(":fid", fid);
- q.bindValue(":hostId", hostId);
- q.bindValue(":path", location);
+ q.prepare("UPDATE file_location SET host_id = :hostId, path = :path, renamed = :renamed, failed_rename = :failedRename WHERE fid = :fid");
+ q.bindValue(":fid", fileLocation.fid);
+ q.bindValue(":hostId", fileLocation.hostId);
+ q.bindValue(":path", fileLocation.path);
+ q.bindValue(":renamed", fileLocation.renamed);
+ q.bindValue(":failedRename", fileLocation.failedRename);
return exec(q);
}
d->db.driver()->subscribeToNotification("new_pending_request");
d->db.driver()->subscribeToNotification("new_pending_mylist_update");
+ d->db.driver()->subscribeToNotification("rename_data_changed");
}
bool Database::exec(QSqlQuery &query)
return result;
}
+bool Database::notify(const QString ¬ification)
+{
+ return exec("NOTIFY " + notification);
+}
+
void Database::handleNotification(const QString ¬ification)
{
qDebug() << "Recieved notification" << notification;
{
emit newPendingMyListUpdate();
}
+ else if (notification == "rename_data_changed")
+ {
+ emit renameDataChanged();
+ }
}
--- /dev/null
+#include "renamehandler.h"
+
+#include "mylist.h"
+#include "database.h"
+#include "settings.h"
+#include <RenameParser/RenameEngine>
+#include <QSqlQuery>
+#include <QSqlRecord>
+
+#include <QDebug>
+
+namespace LocalMyList {
+
+RenameHandler::RenameHandler(Database *db, QObject *parent) :
+ QObject(parent), renameEngine(0), validScript(false)
+{
+ this->db = db;
+ connect(this, SIGNAL(renameBatchFinished()), this, SLOT(handleRename()), Qt::QueuedConnection);
+ setupRenameEngine();
+}
+
+
+void RenameHandler::handleRename()
+{
+ QSqlQuery q(db->connection());
+
+ q.prepare("SELECT fid, eid, aid, gid, anime_anidb_update, anime_entry_update, anime_my_update, anime_title_english, anime_title_romaji, anime_title_kanji, "
+ " description, year, start_date, end_date, anime_type, anime_rating, anime_votes, temp_rating, temp_votes, anime_my_vote, anime_my_vote_date, my_temp_vote, my_temp_vote_date, "
+ "episode_anidb_update, episode_entry_update, episode_my_update, epno, episode_title_english, episode_title_romaji, episode_title_kanji, episode_length, airdate, state, special, recap, "
+ " opening, ending, rating, votes, my_vote, my_vote_date, "
+ "anidb_update, entry_update, my_update, ed2k, size, length, extension, group_name, group_name_short, crc, release_date, version, censored, type, quality_id, quality, resolution, "
+ " video_codec, audio_codec, audio_language, subtitle_language, aspect_ratio, my_watched, my_state, my_file_state, my_storage, my_source, my_other, host_id, path, renamed "
+ "FROM rename_data "
+ "WHERE host_id = :host_id "
+ "LIMIT :limit");
+
+ q.bindValue(":host_id", MyList::instance()->hostId());
+ q.bindValue(":limit", 10);
+
+ if (!db->exec(q))
+ return;
+
+ qDebug() << "Rename: Got" << q.size() << "rows";
+
+ if (q.size() < 1)
+ return;
+
+ if (!validScript)
+ return;
+
+ while (q.next())
+ {
+ QSqlRecord r = q.record();
+ QFileInfo oldFile(r.value("path").toString());
+
+ RaiiTransaction t(db);
+ t.commit();
+
+ FileLocation fl;
+ fl.fid = q.value(0).toInt();
+ fl.hostId = MyList::instance()->hostId();
+ fl.path = r.value("path").toString();
+ fl.renamed = QDateTime::currentDateTime();
+
+ qDebug() << "Rename: renaming" << oldFile.filePath();
+ if (!oldFile.exists())
+ {
+ db->log(tr("Rename: Failed to rename file <%1>. File does not exist").arg(oldFile.filePath()), 2);
+ fl.failedRename = true;
+ db->setFileLocation(fl);
+ continue;
+ }
+
+ RenameParser::Environment env;
+ env["ATr"] = r.value("anime_title_romaji").toString();
+ env["ATe"] = r.value("anime_title_english").toString();
+ env["ATk"] = r.value("anime_title_kanji").toString();
+
+ env["ETr"] = r.value("episode_title_romaji").toString();
+ env["ETe"] = r.value("episode_title_english").toString();
+ env["ETk"] = r.value("episode_title_kanji").toString();
+
+ env["GTs"] = r.value("group_name_short").toString();
+ env["GTl"] = r.value("group_name").toString();
+
+ env["EpNo"] = r.value("epno").toString();
+ env["EpHiNo"] = r.value("episode_count").toString();
+ env["EpCount"] = "0"; // TODO This is missing from the data
+
+ QString year = r.value("year").toString();
+ if (!year.contains('-'))
+ {
+ env["AYearBegin"] = year;
+ env["AYearEnd"] = "";
+ }
+ else
+ {
+ QStringList years = year.split('-');
+ env["AYearBegin"] = years[0].trimmed();
+ env["AYearEnd"] = years[1].trimmed();
+ }
+
+ env["Type"] = r.value("anime_type").toString();
+ env["Depr"] = /*r.value("")*/ false ? "1" : ""; // Data missing?
+
+ env["Cen"] = r.value("censored").toBool() ? "1" : "0";
+
+ env["Ver"] = r.value("version").toString();
+ env["Source"] = r.value("type").toString(); // TODO This is called source on AniDB
+ env["Quality"] = r.value("quality").toString();
+ env["FCrc"] = r.value("crc").toString();
+ env["FVideoRes"] = r.value("resolution").toString();
+ env["FALng"] = r.value("audio_language").toString();
+ env["FSLng"] = r.value("subtitle_language").toString();
+ env["FACodec"] = r.value("audio_codec").toString();
+ env["FVCodec"] = r.value("video_codec").toString();
+ env["Watched"] = r.value("my_watched").toDateTime().isValid() ? "1" : "0";
+
+ renameEngine->evaluate(env);
+
+ if (env.value("FileName", "").isEmpty())
+ {
+ fl.failedRename = true;
+ db->setFileLocation(fl);
+ db->log(tr("Rename: Failed to rename file <%1>. Rename script did not set a file name.").arg(oldFile.filePath()), 2);
+ continue;
+ }
+
+ QString newFileName = env.value("FileName", "") + "." + r.value("extension").toString();
+ QString newFilePath = env.value("FilePath", "");
+
+ if (newFilePath.isEmpty())
+ newFilePath = oldFile.canonicalPath();
+
+ QString newFileString = newFilePath + "/" + newFileName;
+ QFileInfo newFile(newFileString);
+
+ if (newFile.exists())
+ {
+ fl.failedRename = true;
+ db->setFileLocation(fl);
+ db->log(tr("Rename: Failed to rename file <%1>. Destination <%2> exists.").arg(oldFile.filePath()).arg(newFile.canonicalPath()), 2);
+ continue;
+ }
+
+ if (!newFile.absoluteDir().exists())
+ {
+ if (!QDir().mkpath(newFile.canonicalPath()))
+ {
+ fl.failedRename = true;
+ db->setFileLocation(fl);
+ db->log(tr("Rename: Failed to rename file <%1>. Destination path <%2> does not exists and could not be created.").arg(oldFile.filePath()).arg(newFile.canonicalPath()), 2);
+ continue;
+ }
+ }
+
+ if (oldFile.canonicalPath() != newFileString && !QFile::rename(oldFile.canonicalFilePath(), newFileString))
+ {
+ fl.failedRename = true;
+ db->setFileLocation(fl);
+ db->log(tr("Rename: Failed to rename file <%1>. Failed to rename file to <%2>").arg(oldFile.canonicalFilePath()).arg(newFileString), 2);
+ continue;
+ }
+
+ fl.path = newFileString;
+ fl.failedRename = false;
+ db->setFileLocation(fl);
+
+ db->log(tr("Rename: File <%1> was renamed to <%2>").arg(oldFile.canonicalFilePath()).arg(newFileString));
+ }
+
+ emit renameBatchFinished();
+}
+
+void RenameHandler::setupRenameEngine()
+{
+ if (!renameEngine)
+ renameEngine = new RenameParser::RenameEngine();
+
+ renameEngine->setCurrentParserType(RenameParser::RenameEngine::ParserType(
+ MyList::instance()->settings()->get("renameLanguage").toInt()));
+ validScript = renameEngine->parse(MyList::instance()->settings()->get("renameScript").toString());
+
+ if (validScript)
+ db->log(tr("Rename Current rename script is invalid: %1, line: %2, column: %3").arg(renameEngine->error()).arg(renameEngine->line()).arg(renameEngine->column()), 2);
+}
+
+} // namespace LocalMyList