From: APTX Date: Tue, 2 Apr 2013 16:10:57 +0000 (+0200) Subject: Add basic support for mapping file paths between hosts. X-Git-Url: https://gitweb.tyo.aptx.org/?a=commitdiff_plain;h=3f996dcfb949e568557166b94dd7f6d76f93dcd3;p=localmylist.git Add basic support for mapping file paths between hosts. OpenFileData has a new field, localPath, which holds the path from file_location. path now holds a mapped path, if any. All getOpenFile* methods will try return a file location with a mapped path that is accessible from the current host. --- diff --git a/localmylist/database.cpp b/localmylist/database.cpp index eac20af..045f82d 100644 --- a/localmylist/database.cpp +++ b/localmylist/database.cpp @@ -122,7 +122,7 @@ return false; OpenFileData Database::firstUnwatchedByTitle(const QString &title) { QSqlQuery &q = prepare( - "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path FROM file f " + "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path, fl.host_id FROM file f " " LEFT JOIN anime a ON f.aid = a.aid " " LEFT JOIN anime_title at ON f.aid = at.aid " " LEFT JOIN episode e ON f.eid = e.eid " @@ -130,9 +130,8 @@ OpenFileData Database::firstUnwatchedByTitle(const QString &title) " WHERE f.my_watched IS NULL " " AND lower(at.title) = :title " " AND fl.path IS NOT NULL " - " AND fl.host_id = :hostId " "UNION " - "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path FROM file f " + "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path, fl.host_id FROM file f " " LEFT JOIN anime a ON f.aid = a.aid " " LEFT JOIN anime_title at ON f.aid = at.aid " " LEFT JOIN episode e ON f.eid = e.eid " @@ -140,12 +139,10 @@ OpenFileData Database::firstUnwatchedByTitle(const QString &title) " WHERE f.my_watched IS NULL " " AND at.title ILIKE :fuzzyTitle " " AND fl.path IS NOT NULL " - " AND fl.host_id = :hostId " - "GROUP BY f.fid, a.title_romaji, e.title_english, e.epno, fl.path " + "GROUP BY f.fid, a.title_romaji, e.title_english, e.epno, fl.path, fl.host_id " "ORDER BY epno ASC "); q.bindValue(":title", title); q.bindValue(":fuzzyTitle", "%" + title + "%"); - q.bindValue(":hostId", MyList::instance()->hostId()); return readOpenFileData(q); } @@ -153,17 +150,15 @@ OpenFileData Database::firstUnwatchedByTitle(const QString &title) OpenFileData Database::firstUnwatchedByAid(int aid) { QSqlQuery &q = prepare( - "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path FROM file f " + "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path, fl.host_id FROM file f " " LEFT JOIN anime a ON f.aid = a.aid " " LEFT JOIN episode e ON f.eid = e.eid " " LEFT JOIN file_location fl ON fl.fid = f.fid " " WHERE f.my_watched IS NULL " " AND f.aid = :aid " " AND fl.path IS NOT NULL " - " AND fl.host_id = :hostId " "ORDER BY e.epno ASC "); q.bindValue(":aid", aid); - q.bindValue(":hostId", MyList::instance()->hostId()); return readOpenFileData(q); } @@ -174,7 +169,7 @@ OpenFileData Database::openFileByTitle(const QString &title, int epno) return firstUnwatchedByTitle(title); QSqlQuery &q = prepare( - "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path FROM file f " + "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path, fl.host_id FROM file f " " LEFT JOIN anime a ON f.aid = a.aid " " LEFT JOIN anime_title at ON f.aid = at.aid " " LEFT JOIN episode e ON f.eid = e.eid " @@ -182,9 +177,8 @@ OpenFileData Database::openFileByTitle(const QString &title, int epno) " WHERE lower(at.title) = :title " " AND e.epno = :epno " " AND fl.path IS NOT NULL " - " AND fl.host_id = :hostId " "UNION " - "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path FROM file f " + "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path, fl.host_id FROM file f " " LEFT JOIN anime a ON f.aid = a.aid " " LEFT JOIN anime_title at ON f.aid = at.aid " " LEFT JOIN episode e ON f.eid = e.eid " @@ -192,12 +186,10 @@ OpenFileData Database::openFileByTitle(const QString &title, int epno) " WHERE at.title ILIKE :fuzzyTitle " " AND e.epno = :epno " " AND fl.path IS NOT NULL " - " AND fl.host_id = :hostId " - "GROUP BY f.fid, a.title_romaji, e.title_english, e.epno, fl.path "); + "GROUP BY f.fid, a.title_romaji, e.title_english, e.epno, fl.path, fl.host_id "); q.bindValue(":title", title); q.bindValue(":fuzzyTitle", "%" + title + "%"); q.bindValue(":epno", epno); - q.bindValue(":hostId", MyList::instance()->hostId()); return readOpenFileData(q); } @@ -205,15 +197,13 @@ OpenFileData Database::openFileByTitle(const QString &title, int epno) OpenFileData Database::openFileByEid(int eid) { QSqlQuery &q = prepare( - "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path FROM file f " + "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path, fl.host_id FROM file f " " LEFT JOIN anime a ON f.aid = a.aid " " LEFT JOIN episode e ON f.eid = e.eid " " LEFT JOIN file_location fl ON fl.fid = f.fid " " WHERE f.eid = :eid " " AND fl.path IS NOT NULL " - " AND fl.host_id = :hostId" " ORDER BY f.version DESC "); - q.bindValue(":hostId", MyList::instance()->hostId()); q.bindValue(":eid", eid); return readOpenFileData(q); @@ -222,14 +212,12 @@ OpenFileData Database::openFileByEid(int eid) OpenFileData Database::openFile(int fid) { QSqlQuery &q = prepare( - "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path FROM file f " + "SELECT f.fid, a.title_romaji, e.title_english, e.epno, fl.path, fl.host_id FROM file f " " LEFT JOIN anime a ON f.aid = a.aid " " LEFT JOIN episode e ON f.eid = e.eid " " LEFT JOIN file_location fl ON fl.fid = f.fid " " WHERE f.fid = :fid " - " AND fl.path IS NOT NULL " - " AND fl.host_id = :hostId "); - q.bindValue(":hostId", MyList::instance()->hostId()); + " AND fl.path IS NOT NULL "); q.bindValue(":fid", fid); return readOpenFileData(q); @@ -1093,6 +1081,36 @@ QStringList Database::getWatchedDirectories(int hostId) return ret; } +QList Database::getMappingsToHost(int hostId) +{ + QSqlQuery &q = prepare( + "SELECT map_id, source_host, destination_host, source_prefix, destination_prefix " + " FROM path_map " + " WHERE destination_host = :hostId"); + q.bindValue(":hostId", hostId); + + QList ret; + + if (!exec(q)) + return ret; + + while (q.next()) + { + PathMapping pm; + pm.mapId = q.value(0).toInt(); + pm.sourceHost = q.value(1).toInt(); + pm.destinationHost = q.value(2).toInt(); + pm.sourcePrefix = q.value(3).toString(); + pm.destinationPrefix = q.value(4).toString(); + + ret << pm; + } + + q.finish(); + + return ret; +} + QList Database::getReports() { QList reports; @@ -1489,18 +1507,20 @@ OpenFileData Database::readOpenFileData(QSqlQuery &q) if (!exec(q)) return data; - if (!q.next()) + while (q.next()) { - q.finish(); - return data; - } + data.fid = q.value(0).toInt(); + data.animeTitle = q.value(1).toString(); + data.episodeTitle = q.value(2).toString(); + data.epno = q.value(3).toInt(); - data.fid = q.value(0).toInt(); - data.animeTitle = q.value(1).toString(); - data.episodeTitle = q.value(2).toString(); - data.epno = q.value(3).toInt(); - data.path = q.value(4).toString(); + data.hostId = q.value(5).toInt(); + data.localPath = q.value(4).toString(); + data.path = MyList::instance()->mapPath(data.hostId, data.localPath); + if (!data.path.isEmpty()) + break; + } q.finish(); return data; diff --git a/localmylist/database.h b/localmylist/database.h index 8493437..6a879ef 100644 --- a/localmylist/database.h +++ b/localmylist/database.h @@ -95,6 +95,8 @@ public slots: QStringList getWatchedDirectories(int hostId); + QList getMappingsToHost(int hostId); + QList getReports(); bool addReport(const LocalMyList::Report &report); bool setReport(const LocalMyList::Report &report); diff --git a/localmylist/databaseclasses.cpp b/localmylist/databaseclasses.cpp index 06fe50e..831e850 100644 --- a/localmylist/databaseclasses.cpp +++ b/localmylist/databaseclasses.cpp @@ -114,6 +114,13 @@ Report::Report() reportId = 0; } +PathMapping::PathMapping() +{ + mapId = 0; + sourceHost = 0; + destinationHost = 0; +} + DatabaseConnectionSettings::DatabaseConnectionSettings() { port = 0; diff --git a/localmylist/databaseclasses.h b/localmylist/databaseclasses.h index 282d031..1db2259 100644 --- a/localmylist/databaseclasses.h +++ b/localmylist/databaseclasses.h @@ -200,6 +200,11 @@ struct LOCALMYLISTSHARED_EXPORT OpenFileData QString animeTitle; QString episodeTitle; int epno; + + int hostId; + QString localPath; + + // Mapped to current host QString path; OpenFileData(); @@ -214,6 +219,17 @@ struct LOCALMYLISTSHARED_EXPORT Report Report(); }; +struct LOCALMYLISTSHARED_EXPORT PathMapping +{ + int mapId; + int sourceHost; + int destinationHost; + QString sourcePrefix; + QString destinationPrefix; + + PathMapping(); +}; + struct LOCALMYLISTSHARED_EXPORT DatabaseConnectionSettings { QString host; @@ -271,6 +287,10 @@ Q_DECLARE_METATYPE(LocalMyList::Report) Q_DECLARE_METATYPE(LocalMyList::Report*) Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(LocalMyList::PathMapping) +Q_DECLARE_METATYPE(LocalMyList::PathMapping*) +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(LocalMyList::DatabaseConnectionSettings) Q_DECLARE_METATYPE(LocalMyList::DatabaseConnectionSettings*) Q_DECLARE_METATYPE(QList) diff --git a/localmylist/mylist.cpp b/localmylist/mylist.cpp index 21f6b5a..7fe57c9 100644 --- a/localmylist/mylist.cpp +++ b/localmylist/mylist.cpp @@ -284,6 +284,36 @@ void MyList::executeTask(AbstractTask *task) emit taskCountChanged(); } +QString MyList::mapPath(int sourceHost, const QString &path) +{ + if (sourceHost == hostId()) + return path; + + QList mappings = db->getMappingsToHost(hostId()); + + foreach(const PathMapping &pm, mappings) + { + if (pm.sourceHost != sourceHost) + continue; + + QString prefix = pm.sourcePrefix; + if (!prefix.endsWith(QChar('/'))) + prefix.append(QChar('/')); + + if (!path.startsWith(prefix)) + continue; + + QString ret = pm.destinationPrefix; + + if (!ret.endsWith(QChar('/'))) + ret.append(QChar('/')); + ret.append(path.mid(prefix.length())); + + return ret; + } + return QString(); +} + void MyList::taskFinished() { AbstractTask *task = qobject_cast(sender()); diff --git a/localmylist/mylist.h b/localmylist/mylist.h index 5b9b27d..36d2cc6 100644 --- a/localmylist/mylist.h +++ b/localmylist/mylist.h @@ -58,6 +58,8 @@ public slots: AbstractTask *importMyList(const QFileInfo &file); void executeTask(AbstractTask *task); + QString mapPath(int sourceHost, const QString &path); + void setupUdpClient(); void setupRequestHandler(); void setupRenameHandler();