mirror of
https://github.com/YACReader/yacreader
synced 2025-05-28 03:10:27 -04:00
merged develop
This commit is contained in:
commit
581592909d
@ -5,8 +5,8 @@
|
||||
|
||||
#include "QsLog.h"
|
||||
|
||||
ComicsRemover::ComicsRemover(QModelIndexList & il, QList<QString> & ps, QObject *parent)
|
||||
:QObject(parent),indexList(il), paths(ps)
|
||||
ComicsRemover::ComicsRemover(QModelIndexList & il, QList<QString> & ps, qulonglong parentId, QObject *parent)
|
||||
:QObject(parent),indexList(il), paths(ps), parentId(parentId)
|
||||
{
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ void ComicsRemover::process()
|
||||
}
|
||||
|
||||
emit finished();
|
||||
emit removedItemsFromFolder(parentId);
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,12 +10,13 @@ class ComicsRemover : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ComicsRemover(QModelIndexList & indexList, QList<QString> & paths, QObject *parent = 0);
|
||||
explicit ComicsRemover(QModelIndexList & indexList, QList<QString> & paths, qulonglong parentId, QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
void remove(int);
|
||||
void removeError();
|
||||
void finished();
|
||||
void removedItemsFromFolder(qulonglong);
|
||||
|
||||
public slots:
|
||||
void process();
|
||||
@ -23,6 +24,7 @@ public slots:
|
||||
private:
|
||||
QModelIndexList indexList;
|
||||
QList<QString> paths;
|
||||
qulonglong parentId;
|
||||
};
|
||||
|
||||
class FoldersRemover : public QObject
|
||||
|
@ -981,7 +981,7 @@ void ComicModel::removeInTransaction(int row)
|
||||
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
/*
|
||||
void ComicModel::remove(ComicDB * comic, int row)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(),row,row);
|
||||
@ -997,7 +997,7 @@ void ComicModel::remove(ComicDB * comic, int row)
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
*/
|
||||
/*ComicDB TableModel::getComic(int row)
|
||||
{
|
||||
return getComic(index(row,0));
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
//setComicInfoForSelectedComis(QList<QModelIndex> list); -->inserta la información común para los comics seleccionados
|
||||
QVector<YACReaderComicReadStatus> setComicsRead(QList<QModelIndex> list,YACReaderComicReadStatus read);
|
||||
qint64 asignNumbers(QList<QModelIndex> list,int startingNumber);
|
||||
void remove(ComicDB * comic, int row);
|
||||
//void remove(ComicDB * comic, int row);
|
||||
void removeInTransaction(int row);
|
||||
void reload(const ComicDB & comic);
|
||||
void resetComicRating(const QModelIndex & mi);
|
||||
|
@ -126,21 +126,7 @@ bool DataBaseManagement::createTables(QSqlDatabase & database)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
//FOLDER (representa una carpeta en disco)
|
||||
{
|
||||
QSqlQuery queryFolder(database);
|
||||
queryFolder.prepare("CREATE TABLE folder ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"parentId INTEGER NOT NULL,"
|
||||
"name TEXT NOT NULL,"
|
||||
"path TEXT NOT NULL,"
|
||||
//new 7.1 fields
|
||||
"finished BOOLEAN DEFAULT 0," //reading
|
||||
"completed BOOLEAN DEFAULT 1," //collecting
|
||||
//--
|
||||
"FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)");
|
||||
success = success && queryFolder.exec();
|
||||
|
||||
//COMIC INFO (representa la información de un cómic, cada cómic tendrá un idéntificador único formado por un hash sha1'de los primeros 512kb' + su tamaño en bytes)
|
||||
QSqlQuery queryComicInfo(database);
|
||||
queryComicInfo.prepare("CREATE TABLE comic_info ("
|
||||
@ -199,6 +185,23 @@ bool DataBaseManagement::createTables(QSqlDatabase & database)
|
||||
success = success && queryComicInfo.exec();
|
||||
//queryComicInfo.finish();
|
||||
|
||||
//FOLDER (representa una carpeta en disco)
|
||||
QSqlQuery queryFolder(database);
|
||||
queryFolder.prepare("CREATE TABLE folder ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"parentId INTEGER NOT NULL,"
|
||||
"name TEXT NOT NULL,"
|
||||
"path TEXT NOT NULL,"
|
||||
//new 7.1 fields
|
||||
"finished BOOLEAN DEFAULT 0," //reading
|
||||
"completed BOOLEAN DEFAULT 1," //collecting
|
||||
//new 8.6 fields
|
||||
"numChildren INTEGER,"
|
||||
"firstChildHash TEXT,"
|
||||
"customImage TEXT,"
|
||||
"FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)");
|
||||
success = success && queryFolder.exec();
|
||||
|
||||
//COMIC (representa un cómic en disco, contiene el nombre de fichero)
|
||||
QSqlQuery queryComic(database);
|
||||
queryComic.prepare("CREATE TABLE comic (id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, comicInfoId INTEGER NOT NULL, fileName TEXT NOT NULL, path TEXT, FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE, FOREIGN KEY(comicInfoId) REFERENCES comic_info(id))");
|
||||
@ -216,7 +219,6 @@ bool DataBaseManagement::createTables(QSqlDatabase & database)
|
||||
|
||||
//8.0> tables
|
||||
success = success && DataBaseManagement::createV8Tables(database);
|
||||
|
||||
}
|
||||
|
||||
return success;
|
||||
@ -616,6 +618,19 @@ bool DataBaseManagement::addColumns(const QString &tableName, const QStringList
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
bool DataBaseManagement::addConstraint(const QString &tableName, const QString &constraint, const QSqlDatabase &db)
|
||||
{
|
||||
QString sql = "ALTER TABLE %1 ADD %2";
|
||||
bool returnValue = true;
|
||||
|
||||
QSqlQuery alterTable(db);
|
||||
alterTable.prepare(sql.arg(tableName).arg(constraint));
|
||||
alterTable.exec();
|
||||
returnValue = returnValue && (alterTable.numRowsAffected() > 0);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void DataBaseManagement::bindString(const QString & name, const QSqlRecord & record, QSqlQuery & query)
|
||||
{
|
||||
if(!record.value(name).isNull())
|
||||
@ -686,6 +701,7 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath)
|
||||
bool pre7 = false;
|
||||
bool pre7_1 = false;
|
||||
bool pre8 = false;
|
||||
bool pre8_6 = false;
|
||||
|
||||
if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"7.0.0")<0)
|
||||
pre7 = true;
|
||||
@ -693,6 +709,8 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath)
|
||||
pre7_1 = true;
|
||||
if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"8.0.0")<0)
|
||||
pre8 = true;
|
||||
if(compareVersions(DataBaseManagement::checkValidDB(fullPath),"8.6.0")<0)
|
||||
pre8_6 = true;
|
||||
|
||||
QSqlDatabase db = loadDatabaseFromFile(fullPath);
|
||||
bool returnValue = false;
|
||||
@ -745,6 +763,16 @@ bool DataBaseManagement::updateToCurrentVersion(const QString & fullPath)
|
||||
{
|
||||
returnValue = returnValue && createV8Tables(db);
|
||||
}
|
||||
|
||||
if(pre8_6)
|
||||
{
|
||||
QStringList columnDefs;
|
||||
//TODO
|
||||
columnDefs << "numChildren INTEGER";
|
||||
columnDefs << "firstChildHash TEXT";
|
||||
columnDefs << "customImage TEXT";
|
||||
//returnValue = returnValue && addColumns("folder", columnDefs, db);
|
||||
}
|
||||
}
|
||||
|
||||
db.close();
|
||||
|
@ -38,6 +38,7 @@ private:
|
||||
static void bindValuesFromRecord(const QSqlRecord & record, QSqlQuery & query);
|
||||
|
||||
static bool addColumns(const QString & tableName, const QStringList & columnDefs, const QSqlDatabase & db);
|
||||
static bool addConstraint(const QString &tableName, const QString & constraint, const QSqlDatabase & db);
|
||||
|
||||
public:
|
||||
DataBaseManagement();
|
||||
|
@ -172,11 +172,12 @@ QVariant FolderModel::data(const QModelIndex &index, int role) const
|
||||
if(role == FolderModel::FinishedRole)
|
||||
return item->data(FolderModel::Finished);
|
||||
|
||||
if(role == FolderModel::IdRole)
|
||||
return item->id;
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
|
||||
|
||||
return item->data(index.column());
|
||||
}
|
||||
//! [3]
|
||||
@ -537,6 +538,7 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod
|
||||
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
newFolder.id = DBHelper::insert(&newFolder, db);
|
||||
DBHelper::updateChildrenInfo(parentItem->id, db);
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
int destRow = 0;
|
||||
@ -575,11 +577,18 @@ void FolderModel::deleteFolder(const QModelIndex &mi)
|
||||
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
DBHelper::removeFromDB(&f,db);
|
||||
DBHelper::updateChildrenInfo(item->parent()->id, db);
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
void FolderModel::updateFolderChildrenInfo(qulonglong folderId)
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
|
||||
DBHelper::updateChildrenInfo(folderId, db);
|
||||
QSqlDatabase::removeDatabase(_databasePath);
|
||||
}
|
||||
|
||||
//PROXY
|
||||
|
||||
|
@ -127,11 +127,13 @@ public:
|
||||
|
||||
enum Roles {
|
||||
FinishedRole = Qt::UserRole + 1,
|
||||
CompletedRole
|
||||
CompletedRole,
|
||||
IdRole
|
||||
};
|
||||
|
||||
public slots:
|
||||
void deleteFolder(const QModelIndex & mi);
|
||||
void updateFolderChildrenInfo(qulonglong folderId);
|
||||
|
||||
private:
|
||||
void setupModelData( QSqlQuery &sqlquery, FolderItem *parent);
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "reading_list_item.h"
|
||||
#include "library_item.h"
|
||||
#include "comic_db.h"
|
||||
#include "data_base_management.h"
|
||||
@ -58,6 +59,38 @@ QList<LibraryItem *> DBHelper::getFolderComicsFromLibrary(qulonglong libraryId,
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
return list;
|
||||
}
|
||||
|
||||
quint32 DBHelper::getNumChildrenFromFolder(qulonglong libraryId, qulonglong folderId)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
quint32 result = 0;
|
||||
|
||||
{
|
||||
QSqlQuery selectQuery(db);
|
||||
selectQuery.prepare("SELECT count(*) FROM folder WHERE parentId = :parentId and id <> 1");
|
||||
selectQuery.bindValue(":parentId", folderId);
|
||||
selectQuery.exec();
|
||||
|
||||
result += selectQuery.record().value(0).toULongLong();
|
||||
}
|
||||
|
||||
{
|
||||
QSqlQuery selectQuery(db);
|
||||
selectQuery.prepare("SELECT count(*) FROM comic c WHERE c.parentId = :parentId");
|
||||
selectQuery.bindValue(":parentId", folderId);
|
||||
selectQuery.exec();
|
||||
|
||||
result += selectQuery.record().value(0).toULongLong();
|
||||
}
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
qulonglong DBHelper::getParentFromComicFolderId(qulonglong libraryId, qulonglong id)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
|
||||
@ -376,6 +409,51 @@ void DBHelper::update(const Folder & folder, QSqlDatabase &db)
|
||||
updateFolderInfo.exec();
|
||||
}
|
||||
|
||||
void DBHelper::updateChildrenInfo(const Folder & folder, QSqlDatabase & db)
|
||||
{
|
||||
QSqlQuery updateFolderInfo(db);
|
||||
updateFolderInfo.prepare("UPDATE folder SET "
|
||||
"numChildren = :numChildren, "
|
||||
"firstChildHash = :firstChildHash "
|
||||
"WHERE id = :id ");
|
||||
updateFolderInfo.bindValue(":numChildren", folder.getNumChildren());
|
||||
updateFolderInfo.bindValue(":firstChildHash", folder.getFirstChildHash());
|
||||
updateFolderInfo.bindValue(":id", folder.id);
|
||||
updateFolderInfo.exec();
|
||||
}
|
||||
|
||||
void DBHelper::updateChildrenInfo(qulonglong folderId, QSqlDatabase & db)
|
||||
{
|
||||
QList<LibraryItem *> subfolders = DBHelper::getFoldersFromParent(folderId,db,false);
|
||||
QList<LibraryItem *> comics = DBHelper::getComicsFromParent(folderId,db,true);
|
||||
|
||||
ComicDB * firstComic = NULL;
|
||||
if(comics.count() > 0)
|
||||
firstComic = static_cast<ComicDB *>(comics.first());
|
||||
|
||||
QSqlQuery updateFolderInfo(db);
|
||||
updateFolderInfo.prepare("UPDATE folder SET "
|
||||
"numChildren = :numChildren, "
|
||||
"firstChildHash = :firstChildHash "
|
||||
"WHERE id = :id ");
|
||||
updateFolderInfo.bindValue(":numChildren", subfolders.count() + comics.count());
|
||||
updateFolderInfo.bindValue(":firstChildHash", firstComic != NULL ? firstComic->info.hash : "");
|
||||
updateFolderInfo.bindValue(":id", folderId);
|
||||
updateFolderInfo.exec();
|
||||
}
|
||||
|
||||
void DBHelper::updateChildrenInfo(QSqlDatabase & db)
|
||||
{
|
||||
QSqlQuery selectQuery(db); //TODO check
|
||||
selectQuery.prepare("SELECT id FROM folder");
|
||||
selectQuery.exec();
|
||||
|
||||
while (selectQuery.next())
|
||||
{
|
||||
DBHelper::updateChildrenInfo(selectQuery.record().value(0).toULongLong(), db);
|
||||
}
|
||||
}
|
||||
|
||||
void DBHelper::updateProgress(qulonglong libraryId, const ComicInfo &comicInfo)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
|
||||
@ -548,6 +626,7 @@ qulonglong DBHelper::insert(Folder * folder, QSqlDatabase & db)
|
||||
query.bindValue(":name", folder->name);
|
||||
query.bindValue(":path", folder->path);
|
||||
query.exec();
|
||||
|
||||
return query.lastInsertId().toULongLong();
|
||||
}
|
||||
|
||||
@ -575,6 +654,7 @@ qulonglong DBHelper::insert(ComicDB * comic, QSqlDatabase & db)
|
||||
query.bindValue(":name", comic->name);
|
||||
query.bindValue(":path", comic->path);
|
||||
query.exec();
|
||||
|
||||
return query.lastInsertId().toULongLong();
|
||||
}
|
||||
|
||||
@ -701,6 +781,12 @@ QList<LibraryItem *> DBHelper::getFoldersFromParent(qulonglong parentId, QSqlDat
|
||||
data << record.value(i);
|
||||
//TODO sort by sort indicator and name
|
||||
currentItem = new Folder(record.value("id").toULongLong(),record.value("parentId").toULongLong(),record.value("name").toString(),record.value("path").toString());
|
||||
|
||||
if(!record.value("numChildren").isNull() && record.value("numChildren").isValid())
|
||||
currentItem->setNumChildren(record.value("numChildren").toInt());
|
||||
currentItem->setFirstChildHash(record.value("firstChildHash").toString());
|
||||
currentItem->setCustomImage(record.value("customImage").toString());
|
||||
|
||||
int lessThan = 0;
|
||||
|
||||
if(list.isEmpty() || !sort)
|
||||
@ -876,6 +962,59 @@ QList<LibraryItem *> DBHelper::getComicsFromParent(qulonglong parentId, QSqlData
|
||||
return list;
|
||||
}
|
||||
|
||||
QList<LabelItem *> DBHelper::getLabelItems(qulonglong libraryId)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary");
|
||||
|
||||
QSqlQuery selectQuery("SELECT * FROM label ORDER BY ordering,name",db); //TODO add some kind of
|
||||
QList<LabelItem *> labels;
|
||||
|
||||
while(selectQuery.next())
|
||||
{
|
||||
QSqlRecord record = selectQuery.record();
|
||||
LabelItem *item = new LabelItem(QList<QVariant>()
|
||||
<< record.value("name")
|
||||
<< record.value("color")
|
||||
<< record.value("id")
|
||||
<< record.value("ordering"));
|
||||
|
||||
if(labels.isEmpty())
|
||||
{
|
||||
labels << item;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (i < labels.count() && (labels.at(i)->colorid() < item->colorid()) )
|
||||
i++;
|
||||
|
||||
if(i < labels.count())
|
||||
{
|
||||
if(labels.at(i)->colorid() == item->colorid()) //sort by name
|
||||
{
|
||||
while( i < labels.count() && labels.at(i)->colorid() == item->colorid() && naturalSortLessThanCI(labels.at(i)->name(),item->name()))
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if(i >= labels.count())
|
||||
{
|
||||
labels << item;
|
||||
}
|
||||
else
|
||||
{
|
||||
labels.insert(i,item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
db.close();
|
||||
QSqlDatabase::removeDatabase(libraryPath);
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
//loads
|
||||
Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase & db)
|
||||
{
|
||||
@ -897,6 +1036,11 @@ Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase & db)
|
||||
//new 7.1
|
||||
folder.setFinished(record.value("finished").toBool());
|
||||
folder.setCompleted(record.value("completed").toBool());
|
||||
//new 8.6
|
||||
if(!record.value("numChildren").isNull() && record.value("numChildren").isValid())
|
||||
folder.setNumChildren(record.value("numChildren").toInt());
|
||||
folder.setFirstChildHash(record.value("firstChildHash").toString());
|
||||
folder.setCustomImage(record.value("customImage").toString());
|
||||
}
|
||||
|
||||
return folder;
|
||||
@ -925,6 +1069,12 @@ Folder DBHelper::loadFolder(const QString &folderName, qulonglong parentId, QSql
|
||||
//new 7.1
|
||||
folder.setFinished(record.value("finished").toBool());
|
||||
folder.setCompleted(record.value("completed").toBool());
|
||||
//new 8.6
|
||||
if(!record.value("numChildren").isNull() && record.value("numChildren").isValid())
|
||||
folder.setNumChildren(record.value("numChildren").toInt());
|
||||
folder.setFirstChildHash(record.value("firstChildHash").toString());
|
||||
folder.setCustomImage(record.value("customImage").toString());
|
||||
|
||||
QLOG_DEBUG() << "FOUND!!";
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ class QString;
|
||||
class ComicDB;
|
||||
class Folder;
|
||||
class LibraryItem;
|
||||
class LabelItem;
|
||||
class QSqlDatabase;
|
||||
class ComicInfo;
|
||||
class QSqlRecord;
|
||||
@ -23,6 +24,7 @@ public:
|
||||
static QList<LibraryItem *> getFolderSubfoldersFromLibrary(qulonglong libraryId, qulonglong folderId);
|
||||
static QList<LibraryItem *> getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId);
|
||||
static QList<LibraryItem *> getFolderComicsFromLibrary(qulonglong libraryId, qulonglong folderId, bool sort);
|
||||
static quint32 getNumChildrenFromFolder(qulonglong libraryId, qulonglong folderId);
|
||||
static qulonglong getParentFromComicFolderId(qulonglong libraryId, qulonglong id);
|
||||
static ComicDB getComicInfo(qulonglong libraryId, qulonglong id);
|
||||
static QList<ComicDB> getSiblings(qulonglong libraryId, qulonglong parentId);
|
||||
@ -56,6 +58,9 @@ public:
|
||||
static void update(ComicInfo * comicInfo, QSqlDatabase & db);
|
||||
static void updateRead(ComicInfo * comicInfo, QSqlDatabase & db);
|
||||
static void update(const Folder & folder, QSqlDatabase & db);
|
||||
static void updateChildrenInfo(const Folder & folder, QSqlDatabase & db);
|
||||
static void updateChildrenInfo(qulonglong folderId, QSqlDatabase & db);
|
||||
static void updateChildrenInfo(QSqlDatabase & db);
|
||||
static void updateProgress(qulonglong libraryId,const ComicInfo & comicInfo);
|
||||
static void updateReadingRemoteProgress(const ComicInfo & comicInfo, QSqlDatabase & db);
|
||||
static void updateFromRemoteClient(qulonglong libraryId,const ComicInfo & comicInfo);
|
||||
@ -69,6 +74,7 @@ public:
|
||||
static QList<LibraryItem *> getFoldersFromParent(qulonglong parentId, QSqlDatabase & db, bool sort = true);
|
||||
static QList<ComicDB> getSortedComicsFromParent(qulonglong parentId, QSqlDatabase & db);
|
||||
static QList<LibraryItem *> getComicsFromParent(qulonglong parentId, QSqlDatabase & db, bool sort = true);
|
||||
static QList<LabelItem *> getLabelItems(qulonglong libraryId);
|
||||
//load
|
||||
static Folder loadFolder(qulonglong id, QSqlDatabase & db);
|
||||
static Folder loadFolder(const QString & folderName, qulonglong parentId, QSqlDatabase & db);
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "console_ui_library_creator.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "QsLog.h"
|
||||
#include "QsLogDest.h"
|
||||
|
||||
@ -118,7 +120,7 @@ int main( int argc, char ** argv )
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(QCoreApplication::tr("\nYACReaderLibraryServer is the headless (no gui) version of YACReaderLibrary"));
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
const QCommandLineOption versionOption = parser.addVersionOption();
|
||||
parser.addPositionalArgument("command", "The command to execute. [start, create-library, update-library, add-library, remove-library, list-libraries]");
|
||||
|
||||
parser.parse(QCoreApplication::arguments());
|
||||
@ -126,6 +128,13 @@ int main( int argc, char ** argv )
|
||||
const QStringList args = parser.positionalArguments();
|
||||
const QString command = args.isEmpty() ? QString() : args.first();
|
||||
|
||||
if(parser.isSet(versionOption))
|
||||
{
|
||||
qout << "YACReaderLibraryServer" << " " << VERSION << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(command == "start")
|
||||
{
|
||||
QString destLog = YACReader::getSettingsPath()+"/yacreaderlibrary.log";
|
||||
|
@ -162,6 +162,9 @@ void LibraryCreator::run()
|
||||
_database.transaction();
|
||||
//se crea la librería
|
||||
create(QDir(_source));
|
||||
|
||||
DBHelper::updateChildrenInfo(_database);
|
||||
|
||||
_database.commit();
|
||||
_database.close();
|
||||
QSqlDatabase::removeDatabase(_database.connectionName());
|
||||
@ -199,6 +202,12 @@ void LibraryCreator::run()
|
||||
{
|
||||
update(QDir(_source));
|
||||
}
|
||||
|
||||
if(partialUpdate)
|
||||
DBHelper::updateChildrenInfo(folderDestinationModelIndex.data(FolderModel::IdRole).toULongLong(),_database);
|
||||
else
|
||||
DBHelper::updateChildrenInfo(_database);
|
||||
|
||||
_database.commit();
|
||||
_database.close();
|
||||
QSqlDatabase::removeDatabase(_target);
|
||||
|
@ -2420,7 +2420,7 @@ void LibraryWindow::deleteComicsFromDisk()
|
||||
QLOG_TRACE() << comic.parentId;
|
||||
}
|
||||
|
||||
ComicsRemover * remover = new ComicsRemover(indexList,paths);
|
||||
ComicsRemover * remover = new ComicsRemover(indexList,paths,comics.at(0).parentId);
|
||||
QThread * thread = NULL;
|
||||
|
||||
thread = new QThread(this);
|
||||
@ -2433,6 +2433,8 @@ void LibraryWindow::deleteComicsFromDisk()
|
||||
connect(remover, SIGNAL(remove(int)), comicsModel, SLOT(remove(int)));
|
||||
connect(remover, SIGNAL(removeError()),this,SLOT(setRemoveError()));
|
||||
connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction()));
|
||||
connect(remover, SIGNAL(finished()), comicsModel, SLOT(finishTransaction()));
|
||||
connect(remover, SIGNAL(removedItemsFromFolder(qulonglong)), foldersModel, SLOT(updateFolderChildrenInfo(qulonglong)));
|
||||
|
||||
connect(remover, SIGNAL(finished()),this,SLOT(checkEmptyFolder()));
|
||||
connect(remover, SIGNAL(finished()),this,SLOT(checkRemoveError()));
|
||||
|
@ -79,7 +79,7 @@ void ComicController::service(HttpRequest& request, HttpResponse& response)
|
||||
session.setCurrentComic(comic.id, comicFile);
|
||||
}
|
||||
|
||||
response.setHeader("Content-Type", "plain/text; charset=utf-8");
|
||||
response.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
//TODO this field is not used by the client!
|
||||
response.writeText(QString("library:%1\r\n").arg(libraryName));
|
||||
response.writeText(QString("libraryId:%1\r\n").arg(libraryId));
|
||||
|
@ -10,7 +10,7 @@ ComicDownloadInfoController::ComicDownloadInfoController() {}
|
||||
|
||||
void ComicDownloadInfoController::service(HttpRequest& request, HttpResponse& response)
|
||||
{
|
||||
response.setHeader("Content-Type", "plain/text; charset=utf-8");
|
||||
response.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
|
||||
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
|
||||
QStringList pathElements = path.split('/');
|
||||
|
@ -0,0 +1,70 @@
|
||||
#include "foldercontentcontroller.h"
|
||||
|
||||
#include <QUrl>
|
||||
|
||||
#include "db_helper.h"
|
||||
#include "comic_db.h"
|
||||
#include "folder.h"
|
||||
|
||||
#include "qnaturalsorting.h"
|
||||
|
||||
#include <ctime>
|
||||
using namespace std;
|
||||
|
||||
struct LibraryItemSorter
|
||||
{
|
||||
bool operator()(const LibraryItem * a,const LibraryItem * b) const
|
||||
{
|
||||
return naturalSortLessThanCI(a->name,b->name);
|
||||
}
|
||||
};
|
||||
|
||||
FolderContentController::FolderContentController() {}
|
||||
|
||||
void FolderContentController::service(HttpRequest& request, HttpResponse& response)
|
||||
{
|
||||
response.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
|
||||
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
|
||||
QStringList pathElements = path.split('/');
|
||||
int libraryId = pathElements.at(2).toInt();
|
||||
qulonglong parentId = pathElements.at(4).toULongLong();
|
||||
|
||||
serviceContent(libraryId, parentId, response);
|
||||
|
||||
response.writeText("",true);
|
||||
}
|
||||
|
||||
void FolderContentController::serviceContent(const int &library, const qulonglong &folderId, HttpResponse &response)
|
||||
{
|
||||
clock_t begin = clock();
|
||||
|
||||
QList<LibraryItem *> folderContent = DBHelper::getFolderSubfoldersFromLibrary(library,folderId);
|
||||
QList<LibraryItem *> folderComics = DBHelper::getFolderComicsFromLibrary(library,folderId);
|
||||
|
||||
folderContent.append(folderComics);
|
||||
qSort(folderContent.begin(),folderContent.end(),LibraryItemSorter());
|
||||
|
||||
folderComics.clear();
|
||||
|
||||
ComicDB * currentComic;
|
||||
Folder * currentFolder;
|
||||
for(QList<LibraryItem *>::const_iterator itr = folderContent.constBegin();itr!=folderContent.constEnd();itr++)
|
||||
{
|
||||
if((*itr)->isDir())
|
||||
{
|
||||
currentFolder = (Folder *)(*itr);
|
||||
response.writeText(QString("f\t%1\t%2\t%3\t%4\t%5\r\n").arg(library).arg(currentFolder->id).arg(currentFolder->name).arg(currentFolder->getNumChildren()).arg(currentFolder->getFirstChildHash()));
|
||||
}
|
||||
else
|
||||
{
|
||||
currentComic = (ComicDB *)(*itr);
|
||||
response.writeText(QString("c\t%1\t%2\t%3\t%4\t%5\r\n").arg(library).arg(currentComic->id).arg(currentComic->getFileName()).arg(currentComic->getFileSize()).arg(currentComic->info.hash));
|
||||
}
|
||||
}
|
||||
|
||||
clock_t end = clock();
|
||||
double msecs = double(end - begin);
|
||||
|
||||
response.writeText(QString("%1ms").arg(msecs));
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#ifndef FOLDERCONTENTCONTROLLER_H
|
||||
#define FOLDERCONTENTCONTROLLER_H
|
||||
|
||||
#include "httprequest.h"
|
||||
#include "httpresponse.h"
|
||||
#include "httprequesthandler.h"
|
||||
|
||||
class FolderContentController : public HttpRequestHandler {
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(FolderContentController);
|
||||
public:
|
||||
/** Constructor */
|
||||
FolderContentController();
|
||||
|
||||
/** Generates the response */
|
||||
void service(HttpRequest& request, HttpResponse& response);
|
||||
|
||||
private:
|
||||
void serviceContent(const int &library, const qulonglong &folderId, HttpResponse &response);
|
||||
};
|
||||
|
||||
#endif // FOLDERCONTENTCONTROLLER_H
|
@ -167,11 +167,11 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
|
||||
{
|
||||
t.setVariable(QString("element%1.class").arg(i),"folder");
|
||||
|
||||
QList<LibraryItem *> children = DBHelper::getFolderComicsFromLibrary(libraryId, item->id);
|
||||
if(children.length()>0)
|
||||
const Folder * folder = static_cast<Folder*>(item);
|
||||
|
||||
if(folder->getFirstChildHash().length()>0)
|
||||
{
|
||||
const ComicDB * comic = static_cast<ComicDB*>(children.at(0));
|
||||
t.setVariable(QString("element%1.image.url").arg(i),QString("/library/%1/cover/%2.jpg?folderCover=true").arg(libraryId).arg(comic->info.hash));
|
||||
t.setVariable(QString("element%1.image.url").arg(i),QString("/library/%1/cover/%2.jpg?folderCover=true").arg(libraryId).arg(folder->getFirstChildHash()));
|
||||
}
|
||||
else
|
||||
t.setVariable(QString("element%1.image.url").arg(i),"/images/f.png");
|
||||
|
@ -12,7 +12,7 @@ FolderInfoController::FolderInfoController() {}
|
||||
|
||||
void FolderInfoController::service(HttpRequest& request, HttpResponse& response)
|
||||
{
|
||||
response.setHeader("Content-Type", "plain/text; charset=utf-8");
|
||||
response.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
|
||||
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
|
||||
QStringList pathElements = path.split('/');
|
||||
|
30
YACReaderLibrary/server/controllers/tagscontroller.cpp
Normal file
30
YACReaderLibrary/server/controllers/tagscontroller.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "tagscontroller.h"
|
||||
|
||||
#include "db_helper.h"
|
||||
#include "yacreader_libraries.h"
|
||||
|
||||
#include "reading_list_item.h"
|
||||
#include "../static.h"
|
||||
#include "yacreader_global.h"
|
||||
|
||||
#include "QsLog.h"
|
||||
|
||||
TagsController::TagsController() {}
|
||||
|
||||
void TagsController::service(HttpRequest& request, HttpResponse& response)
|
||||
{
|
||||
response.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
|
||||
QString path = QUrl::fromPercentEncoding(request.getPath()).toUtf8();
|
||||
QStringList pathElements = path.split('/');
|
||||
int libraryId = pathElements.at(2).toInt();
|
||||
|
||||
QList<LabelItem *> tags = DBHelper::getLabelItems(libraryId);
|
||||
|
||||
foreach(LabelItem * tag, tags)
|
||||
{
|
||||
response.writeText(QString("%1\t%2\t%3\r\n").arg(tag->getId()).arg(tag->name()).arg(labelColorToRGBString(tag->colorid())));
|
||||
}
|
||||
|
||||
response.writeText("",true);
|
||||
}
|
22
YACReaderLibrary/server/controllers/tagscontroller.h
Normal file
22
YACReaderLibrary/server/controllers/tagscontroller.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef TAGSCONTROLLER_H
|
||||
#define TAGSCONTROLLER_H
|
||||
|
||||
#include "httprequest.h"
|
||||
#include "httpresponse.h"
|
||||
#include "httprequesthandler.h"
|
||||
|
||||
|
||||
|
||||
class TagsController : public HttpRequestHandler {
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(TagsController)
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
TagsController();
|
||||
|
||||
/** Generates the response */
|
||||
void service(HttpRequest& request, HttpResponse& response);
|
||||
};
|
||||
|
||||
#endif // TAGSCONTROLLER_H
|
10
YACReaderLibrary/server/controllers/versioncontroller.cpp
Normal file
10
YACReaderLibrary/server/controllers/versioncontroller.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "versioncontroller.h"
|
||||
|
||||
VersionController::VersionController() {}
|
||||
|
||||
void VersionController::service(HttpRequest& request, HttpResponse& response)
|
||||
{
|
||||
Q_UNUSED(request);
|
||||
|
||||
response.writeText(SERVER_VERSION_NUMBER,true);
|
||||
}
|
21
YACReaderLibrary/server/controllers/versioncontroller.h
Normal file
21
YACReaderLibrary/server/controllers/versioncontroller.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef VERSIONCONTROLLER_H
|
||||
#define VERSIONCONTROLLER_H
|
||||
|
||||
#include "httprequest.h"
|
||||
#include "httpresponse.h"
|
||||
#include "httprequesthandler.h"
|
||||
|
||||
#include <QThread>
|
||||
|
||||
class VersionController : public HttpRequestHandler {
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(VersionController);
|
||||
public:
|
||||
/** Constructor */
|
||||
VersionController();
|
||||
|
||||
/** Generates the response */
|
||||
void service(HttpRequest& request, HttpResponse& response);
|
||||
};
|
||||
|
||||
#endif // VERSIONCONTROLLER_H
|
@ -22,6 +22,9 @@
|
||||
#include "controllers/errorcontroller.h"
|
||||
#include "controllers/comicdownloadinfocontroller.h"
|
||||
#include "controllers/synccontroller.h"
|
||||
#include "controllers/versioncontroller.h"
|
||||
#include "controllers/foldercontentcontroller.h"
|
||||
#include "controllers/tagscontroller.h"
|
||||
|
||||
#include "db_helper.h"
|
||||
#include "yacreader_libraries.h"
|
||||
@ -105,6 +108,9 @@ void RequestMapper::service(HttpRequest& request, HttpResponse& response) {
|
||||
QRegExp cover("/library/.+/cover/[0-9a-f]+.jpg"); //get comic cover (navigation)
|
||||
QRegExp comicPage("/library/.+/comic/[0-9]+/page/[0-9]+/?"); //get comic page
|
||||
QRegExp comicPageRemote("/library/.+/comic/[0-9]+/page/[0-9]+/remote?"); //get comic page (remote reading)
|
||||
QRegExp serverVersion("/version/?");
|
||||
QRegExp folderContent("/library/.+/folder/[0-9]+/content/?");
|
||||
QRegExp tags("/library/.+/tags/?");
|
||||
|
||||
QRegExp sync("/sync");
|
||||
|
||||
@ -122,8 +128,14 @@ void RequestMapper::service(HttpRequest& request, HttpResponse& response) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sync.exactMatch(path))
|
||||
if(serverVersion.exactMatch(path))
|
||||
{
|
||||
VersionController().service(request, response);
|
||||
}
|
||||
else if(sync.exactMatch(path))
|
||||
{
|
||||
SyncController().service(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
//se comprueba que la sesión sea la correcta con el fin de evitar accesos no autorizados
|
||||
@ -161,6 +173,14 @@ void RequestMapper::service(HttpRequest& request, HttpResponse& response) {
|
||||
{
|
||||
UpdateComicController().service(request, response);
|
||||
}
|
||||
else if(folderContent.exactMatch(path))
|
||||
{
|
||||
FolderContentController().service(request, response);
|
||||
}
|
||||
else if(tags.exactMatch(path))
|
||||
{
|
||||
TagsController().service(request, response);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -15,7 +15,11 @@ HEADERS += \
|
||||
$$PWD/controllers/covercontroller.h \
|
||||
$$PWD/controllers/updatecomiccontroller.h \
|
||||
$$PWD/controllers/comicdownloadinfocontroller.h \
|
||||
$$PWD/controllers/synccontroller.h
|
||||
$$PWD/controllers/synccontroller.h \
|
||||
#v2
|
||||
$$PWD/controllers/versioncontroller.h \
|
||||
$$PWD/controllers/foldercontentcontroller.h \
|
||||
$$PWD/controllers/tagscontroller.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/static.cpp \
|
||||
@ -31,8 +35,14 @@ SOURCES += \
|
||||
$$PWD/controllers/covercontroller.cpp \
|
||||
$$PWD/controllers/updatecomiccontroller.cpp \
|
||||
$$PWD/controllers/comicdownloadinfocontroller.cpp \
|
||||
$$PWD/controllers/synccontroller.cpp
|
||||
$$PWD/controllers/synccontroller.cpp \
|
||||
#v2
|
||||
$$PWD/controllers/versioncontroller.cpp \
|
||||
$$PWD/controllers/foldercontentcontroller.cpp \
|
||||
$$PWD/controllers/tagscontroller.cpp
|
||||
|
||||
include(lib/bfLogging/bfLogging.pri)
|
||||
include(lib/bfHttpServer/bfHttpServer.pri)
|
||||
include(lib/bfTemplateEngine/bfTemplateEngine.pri)
|
||||
|
||||
DEFINES += SERVER_VERSION_NUMBER=\\\"2.0\\\"
|
||||
|
@ -16,7 +16,7 @@ ComicDB::ComicDB(const ComicDB &comicDB)
|
||||
operator=(comicDB);
|
||||
}
|
||||
|
||||
bool ComicDB::isDir()
|
||||
bool ComicDB::isDir() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ public:
|
||||
ComicDB();
|
||||
ComicDB(const ComicDB & comicDB);
|
||||
|
||||
bool isDir();
|
||||
bool isDir() const;
|
||||
|
||||
bool _hasCover;
|
||||
|
||||
|
@ -1,6 +1,23 @@
|
||||
|
||||
#include "folder.h"
|
||||
|
||||
Folder::Folder()
|
||||
:knownParent(false),
|
||||
knownId(false),
|
||||
numChildren(-1)
|
||||
{}
|
||||
|
||||
Folder::Folder(qulonglong folderId, qulonglong parentId, const QString &folderName, const QString &folderPath)
|
||||
:knownParent(true),
|
||||
knownId(true),
|
||||
numChildren(-1)
|
||||
{
|
||||
this->id = folderId;
|
||||
this->parentId = parentId;
|
||||
this->name = folderName;
|
||||
this->path = folderPath;
|
||||
}
|
||||
|
||||
|
||||
Folder::Folder(const Folder &folder)
|
||||
{
|
||||
operator=(folder);
|
||||
@ -17,3 +34,11 @@ Folder &Folder::operator =(const Folder &other)
|
||||
|
||||
return *this;
|
||||
}
|
||||
Folder::Folder(const QString & folderName, const QString & folderPath)
|
||||
:knownParent(false),
|
||||
knownId(false),
|
||||
numChildren(-1)
|
||||
{
|
||||
this->name = folderName;
|
||||
this->path = folderPath;
|
||||
}
|
||||
|
@ -11,22 +11,86 @@ public:
|
||||
bool knownParent;
|
||||
bool knownId;
|
||||
|
||||
Folder():knownParent(false), knownId(false){}
|
||||
Folder(qulonglong sid, qulonglong pid,QString fn, QString fp):knownParent(true), knownId(true){id = sid; parentId = pid;name = fn; path = fp;}
|
||||
Folder(QString fn, QString fp):knownParent(false), knownId(false){name = fn; path = fp;}
|
||||
Folder();
|
||||
Folder(qulonglong folderId, qulonglong parentId,const QString & folderName, const QString & folderPath);
|
||||
Folder(const QString & folderName, const QString & folderPath);
|
||||
Folder(const Folder &folder);
|
||||
Folder &operator =(const Folder & other);
|
||||
void setId(qulonglong sid){id = sid;knownId = true;}
|
||||
void setFather(qulonglong pid){parentId = pid;knownParent = true;}
|
||||
bool isDir() {return true;}
|
||||
bool isFinished() const {return finished;}
|
||||
bool isCompleted() const {return completed;}
|
||||
void setFinished(bool b) {finished = b;}
|
||||
void setCompleted(bool b) {completed = b;}
|
||||
|
||||
inline void setId(qulonglong sid)
|
||||
{
|
||||
id = sid;
|
||||
knownId = true;
|
||||
}
|
||||
inline void setFather(qulonglong pid)
|
||||
{
|
||||
parentId = pid;
|
||||
knownParent = true;
|
||||
}
|
||||
|
||||
inline bool isDir() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool isFinished() const
|
||||
{
|
||||
return finished;
|
||||
}
|
||||
|
||||
inline bool isCompleted() const
|
||||
{
|
||||
return completed;
|
||||
}
|
||||
|
||||
inline void setFinished(bool b)
|
||||
{
|
||||
finished = b;
|
||||
}
|
||||
|
||||
inline void setCompleted(bool b)
|
||||
{
|
||||
completed = b;
|
||||
}
|
||||
|
||||
inline qint32 getNumChildren() const
|
||||
{
|
||||
return numChildren;
|
||||
}
|
||||
|
||||
inline void setNumChildren(const qint32 v)
|
||||
{
|
||||
numChildren = v;
|
||||
}
|
||||
|
||||
inline QString getFirstChildHash() const
|
||||
{
|
||||
return firstChildHash;
|
||||
}
|
||||
|
||||
inline void setFirstChildHash(const QString & v)
|
||||
{
|
||||
firstChildHash = v;
|
||||
}
|
||||
|
||||
inline QString getCustomImage() const
|
||||
{
|
||||
return customImage;
|
||||
}
|
||||
|
||||
inline void setCustomImage(const QString & s)
|
||||
{
|
||||
customImage = s;
|
||||
}
|
||||
|
||||
private:
|
||||
bool finished;
|
||||
bool completed;
|
||||
|
||||
qint32 numChildren; //-1 for unknown number of children
|
||||
QString firstChildHash; //empty for unknown first child
|
||||
QString customImage; //empty for none custom image
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@ class LibraryItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual bool isDir() = 0;
|
||||
virtual bool isDir() const = 0;
|
||||
LibraryItem & operator=(const LibraryItem & other);
|
||||
QString name;
|
||||
QString path;
|
||||
|
Loading…
Reference in New Issue
Block a user