]> Some of my projects - localmylist.git/commitdiff
Add basic support for mapping file paths between hosts.
authorAPTX <marek321@gmail.com>
Tue, 2 Apr 2013 16:10:57 +0000 (18:10 +0200)
committerAPTX <marek321@gmail.com>
Tue, 2 Apr 2013 16:10:57 +0000 (18:10 +0200)
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.

localmylist/database.cpp
localmylist/database.h
localmylist/databaseclasses.cpp
localmylist/databaseclasses.h
localmylist/mylist.cpp
localmylist/mylist.h

index eac20af293b00814d7764408559349336a44270a..045f82d6def890bf5bd29162bf7707f3e8ff9e77 100644 (file)
@@ -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<PathMapping> 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<PathMapping> 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<Report> Database::getReports()
 {
        QList<Report> 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;
index 849343700d302e559ed594918229960920ac6a42..6a879efa1d02a208514e2602d9059886fae96cac 100644 (file)
@@ -95,6 +95,8 @@ public slots:
 
        QStringList getWatchedDirectories(int hostId);
 
+       QList<LocalMyList::PathMapping> getMappingsToHost(int hostId);
+
        QList<LocalMyList::Report> getReports();
        bool addReport(const LocalMyList::Report &report);
        bool setReport(const LocalMyList::Report &report);
index 06fe50eb2859cf98a4f2b63888eefc6378c962e9..831e8509e10630289791d5836a666b1febe6a0b8 100644 (file)
@@ -114,6 +114,13 @@ Report::Report()
        reportId = 0;
 }
 
+PathMapping::PathMapping()
+{
+       mapId = 0;
+       sourceHost = 0;
+       destinationHost = 0;
+}
+
 DatabaseConnectionSettings::DatabaseConnectionSettings()
 {
        port = 0;
index 282d0316efb161045004af996857d1fd5d3430a8..1db2259d498d6ade030d35dca0a8cc9d813a9355 100644 (file)
@@ -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<LocalMyList::Report>)
 Q_DECLARE_METATYPE(QList<LocalMyList::Report*>)
+Q_DECLARE_METATYPE(LocalMyList::PathMapping)
+Q_DECLARE_METATYPE(LocalMyList::PathMapping*)
+Q_DECLARE_METATYPE(QList<LocalMyList::PathMapping>)
+Q_DECLARE_METATYPE(QList<LocalMyList::PathMapping*>)
 Q_DECLARE_METATYPE(LocalMyList::DatabaseConnectionSettings)
 Q_DECLARE_METATYPE(LocalMyList::DatabaseConnectionSettings*)
 Q_DECLARE_METATYPE(QList<LocalMyList::DatabaseConnectionSettings>)
index 21f6b5a8be7fdfa36286662925107f49c5eb5b24..7fe57c995cc94320840ae2778a588b76f6e26826 100644 (file)
@@ -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<PathMapping> 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<AbstractTask *>(sender());
index 5b9b27d8644ca4bb27b50d2928e61b0118d5090c..36d2cc685756b30f0bd339159897a58fb263a2c3 100644 (file)
@@ -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();