defuze.me  Client
source.cpp
00001 #include "source.hpp"
00002 #include "dbcore.hpp"
00003 #include "exception.hpp"
00004 #include "library.hpp"
00005 #include <QDir>
00006 #include <QDirIterator>
00007 
00008 using namespace Library;
00009 
00010 QMap<int, Source*>  Source::sourcesMap;
00011 
00012 Source::Source(Type type, const QString &path, bool recursive, const QString &host,
00013                unsigned short port, const QString &username,
00014                const QString &password, const QString &filename) :
00015     type(type), port(port), host(host), path(path),
00016     username(username), password(password), filename(filename), recursive(recursive)
00017 {
00018     updatedAt = QDateTime::currentDateTime();
00019     status = UNINITIALIZED;
00020     id = 0;
00021     save();
00022 }
00023 
00024 Source::Source(int id)
00025 {
00026     QSqlQuery query;
00027     query.prepare("SELECT type, path, host, port, username, password, filename, updatedAt, status, recursive "
00028                   "FROM sources WHERE id = :id LIMIT 1");
00029     query.bindValue(":id", id);
00030     query.exec();
00031     if (query.first())
00032     {
00033         this->id = id;
00034         type = static_cast<Type>(query.value(0).toInt());
00035         path = query.value(1).toString();
00036         host = query.value(2).toString();
00037         port = query.value(3).toUInt();
00038         username = query.value(4).toString();
00039         password = query.value(5).toString();
00040         filename = query.value(6).toString();
00041         updatedAt = query.value(7).toDateTime();
00042         status = static_cast<Status>(query.value(8).toInt());
00043         recursive = query.value(9).toBool();
00044     }
00045     else
00046         qDebug() << QString("Can't load source with id %1: %2 (%3)").arg(id).arg(query.lastError().text()).arg(query.lastQuery());
00047 }
00048 
00049 
00050 Source* Source::getSource(int id)
00051 {
00052     if (!sourcesMap.contains(id))
00053         sourcesMap[id] = new Source(id);
00054     return sourcesMap[id];
00055 }
00056 
00057 Source::Status Source::update()
00058 {
00059     QMap<QString, int>  collection;
00060     qDebug() << "Update source" << toUrl().toString();
00061     {
00062         QDirIterator filesList(toUrl().toLocalFile(), QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
00063         QSqlQuery query;
00064         query.prepare("SELECT id, path FROM audio_tracks WHERE source = :source");
00065         query.bindValue(":source", id);
00066         query.exec();
00067         while(query.next())
00068         {
00069             int     id = query.value(0).toInt();
00070             QString path = query.value(1).toString();
00071             collection[path] = id;
00072         }
00073         int i = 0;
00074         while (filesList.hasNext())
00075         {
00076             filesList.next();
00077             ++i;
00078         }
00079         emit addToMaximumProgress(i);
00080     }
00081     {
00082         QDirIterator filesList(toUrl().toLocalFile(), QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
00083         int i = 0;
00084         while (filesList.hasNext())
00085         {
00086             i++;
00087             if (i % 10 == 0)
00088                 emit progressValueChange(10);
00089             filesList.next();
00090             if (!filesList.fileInfo().isFile())
00091                 continue;
00092             if (LibraryPlugin::allowedExtension.contains(filesList.fileInfo().suffix(), Qt::CaseInsensitive))
00093             {
00094                 QString relativePath = filesList.fileInfo().filePath();
00095                 relativePath.remove(QRegExp("^"+ QRegExp::escape(toUrl().toLocalFile())));
00096                 if (collection.contains(relativePath))
00097                 {
00098                     collection.remove(relativePath);
00099                 }
00100                 else
00101                 {
00102                     AudioTrack  track(relativePath, this);
00103                     track.save();
00104                 }
00105             }
00106         }
00107     }
00108 
00109     foreach (int i, collection.values())
00110         AudioTrack::getTrack(i)->remove();
00111     return (status = OK);
00112 }
00113 
00114 
00115 bool    Source::newRecord() const
00116 {
00117     return id == 0;
00118 }
00119 
00120 void    Source::save()
00121 {
00122     QSqlQuery query;
00123 
00124     if (newRecord())
00125         query.prepare("INSERT INTO sources(type, path, host, port, username, password, "
00126                       "filename, updatedAt, status, recursive) VALUES (:type, :path, :host, :port, "
00127                       ":username, :password, :filename, :updatedAt, :status, :recursive)");
00128     else
00129         query.prepare("UPDATE sources SET type = :type, path = :path, host = :host"
00130                       "port= :port, username = :username, password = :password, filename = :filename, "
00131                       "updatedAt = :updatedAt, status = :status, recursive = :recursive "
00132                       "WHERE id = :id");
00133     query.bindValue(":type", type);
00134     query.bindValue(":path", path);
00135     query.bindValue(":host", host);
00136     query.bindValue(":port", port);
00137     query.bindValue(":username", username);
00138     query.bindValue(":password", password);
00139     query.bindValue(":filename", filename);
00140     query.bindValue(":updatedAt", updatedAt);
00141     query.bindValue(":status", status);
00142     query.bindValue(":recursive", recursive);
00143 
00144     if (!query.exec())
00145         qDebug() << QString("Can't save source: %1").arg(query.lastError().text());
00146     if (newRecord())
00147     {
00148         id = query.lastInsertId().toInt();
00149         sourcesMap[id] = this;
00150     }
00151 }
00152 
00153 const QString& Source::getPath() const
00154 {
00155     return path;
00156 }
00157 
00158 void Source::merge(Source *oldSource)
00159 {
00160     QString newPrefix = oldSource->getPath();
00161     newPrefix.remove(QRegExp("^" + QRegExp::escape(path)));
00162     QSqlQuery query;
00163     query.prepare("UPDATE audio_tracks SET path = :prefix || path, source = :source_id WHERE source = :old_source_id;");
00164     query.bindValue(":prefix", newPrefix);
00165     query.bindValue(":source_id", getId());
00166     query.bindValue(":old_source_id", oldSource->getId());
00167     if (!query.exec())
00168         throw_exception(0x01, tr("Can't merge source: %1").arg(query.lastError().text()));
00169     const QMap<int, AudioTrack*>& tracks = AudioTrack::getTracksMap();
00170     QMap<int, AudioTrack*>::const_iterator it = tracks.constBegin();
00171     while (it != tracks.constEnd())
00172     {
00173         AudioTrack *track = it.value();
00174         if (track->getSource() == oldSource)
00175         {
00176             track->setSource(this);
00177             track->setPath(QString(newPrefix + track->getPath()));
00178         }
00179         ++it;
00180     }
00181 
00182     //Check username/password modification
00183 }
00184 
00185 void Source::remove()
00186 {
00187     QSqlQuery query;
00188     query.prepare("DELETE FROM sources WHERE id = :id");
00189     query.bindValue(":id", getId());
00190     if (!query.exec())
00191         throw_exception(0x02, tr("Cannot remove source: %1").arg(query.lastError().text()));
00192     sourcesMap.remove(getId());
00193     delete this;
00194 }
00195 
00196 QUrl Source::toUrl() const
00197 {
00198     QString protocol;
00199     QUrl url;
00200 
00201     if (type == HTTP)
00202         protocol = "http://";
00203     else if (type == FTP)
00204         protocol = "ftp://";
00205 
00206     if (port)
00207         url = QUrl::fromUserInput(protocol + host + ":" + QVariant(port).toString() + path + filename);
00208     else
00209         url = QUrl::fromUserInput(protocol + host + path + filename);
00210     if (!username.isEmpty())
00211         url.setUserName(username);
00212     if (!password.isEmpty())
00213         url.setPassword(password);
00214     return url;
00215 }
00216 
00217 bool Source::isRecursive() const
00218 {
00219     return recursive;
00220 }
00221 
00222 int Source::getId() const
00223 {
00224     return id;
00225 }
00226 
00227 Source::Type Source::typeFromScheme(const QString &scheme)
00228 {
00229     if (scheme == "http")
00230         return HTTP;
00231     else if (scheme == "ftp")
00232         return FTP;
00233     else
00234         return LOCAL;
00235 }