updated web library with new style and features

added remote reading from iOS
This commit is contained in:
Luis Ángel San Martín
2014-07-29 17:40:00 +02:00
parent 39d7ae6ce5
commit 7020a48a2e
76 changed files with 1077 additions and 628 deletions

View File

@ -44,14 +44,28 @@ void CoverController::service(HttpRequest& request, HttpResponse& response)
QImage img(libraries.getPath(libraryName)+"/.yacreaderlibrary/covers/"+fileName);
if (!img.isNull()) {
int width = 80;
if(session.getDisplayType()=="retina")
int width = 80, height = 120;
if(session.getDisplayType()=="@2x")
{
width = 160;
img = img.scaledToWidth(width,Qt::SmoothTransformation);
height = 240;
}
if(float(img.width())/img.height() < 0.66666)
img = img.scaledToWidth(width,Qt::SmoothTransformation);
else
img = img.scaledToHeight(height,Qt::SmoothTransformation);
QImage destImg(width,height,QImage::Format_RGB32);
destImg.fill(Qt::black);
QPainter p(&destImg);
p.drawImage((width-img.width())/2,(height-img.height())/2,img);
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
img.save(&buffer, "JPG");
destImg.save(&buffer, "JPG");
response.write(ba,true);
}
//DONE else, hay que devolver un 404

View File

@ -1,4 +1,6 @@
#include "foldercontroller.h"
#include "controllers/errorcontroller.h"
#include "db_helper.h" //get libraries
#include "comic_db.h"
@ -36,7 +38,16 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
int libraryId = pathElements.at(2).toInt();
QString libraryName = DBHelper::getLibraryName(libraryId);
qulonglong parentId = pathElements.at(4).toULongLong();
parentId = qMax<qulonglong>(1,parentId);
QString folderName = DBHelper::getFolderName(libraryName,parentId);
if(folderName.isEmpty())
{
ErrorController(300).service(request,response);
return;
}
if(parentId!=1)
t.setVariable("folder.name",folderName);
else
@ -70,7 +81,21 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
int upPage = 0;
if(parentId == 1)
session.clearFoldersPath();
else
{
if(fromUp)
session.popFolder();
else
if(session.getFoldersPath().contains(parentId))
{
while(session.topFolder()!=parentId)
session.popFolder();
}
else
session.pushFolder(parentId);
}
if(backId == 1 && parentId == 1)
{
@ -83,7 +108,7 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
if(fromUp)
{
session.popPage();
upPage = session.topPage();
upPage = session.topPage();
page = upPage;
}
else //este nivel puede haberse cargado por primera vez <20> puede que estemos navegando horizontalmente
@ -116,7 +141,7 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
//t.loop("element",folderContent.length());
int elementsPerPage = 18;
int elementsPerPage = 24;
int numFolders = folderContent.length();
//int numComics = folderComics.length();
@ -135,9 +160,16 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
int indexCurrentPage = page*elementsPerPage;
int numFoldersAtCurrentPage = qMax(0,qMin(numFolders - indexCurrentPage, elementsPerPage));
//response.writeText(QString("indexCurrentPage : %1 <br/>").arg(indexCurrentPage));
//response.writeText(QString("numFoldersAtCurrentPage : %1 <br/>").arg(numFoldersAtCurrentPage));
//response.writeText(QString("foldersLength : %1 <br/>").arg(folderContent.length()));
//PATH
QStack<int> foldersPath = session.getFoldersPath();
t.setVariable(QString("library.name"),libraryName);
t.setVariable(QString("library.url"),QString("/library/%1/folder/1").arg(libraryId));
t.loop("path",foldersPath.length());
for(int i = 0; i < foldersPath.length(); i++){
t.setVariable(QString("path%1.url").arg(i),QString("/library/%1/folder/%2").arg(libraryId).arg(foldersPath[i]));
t.setVariable(QString("path%1.name").arg(i),DBHelper::getFolderName(libraryName,foldersPath[i]));
}
t.loop("element",numFoldersAtCurrentPage);
int i = 0;
@ -148,7 +180,6 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
if(item->isDir())
{
t.setVariable(QString("element%1.class").arg(i),"folder");
t.setVariable(QString("element%1.image.width").arg(i),"89px");
t.setVariable(QString("element%1.image.url").arg(i),"/images/f.png");
t.setVariable(QString("element%1.browse").arg(i),QString("<a class =\"browseButton\" href=\"%1\">browse</a>").arg(QString("/library/%1/folder/%2").arg(libraryId).arg(item->id)));
@ -157,13 +188,17 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
//t.setVariable(QString("element%1.downloadurl").arg(i),"/library/"+libraryName+"/folder/"+QString("%1/info").arg(folderContent.at(i + (page*elementsPerPage))->id));
t.setVariable(QString("element%1.download").arg(i),QString("<a onclick=\"this.innerHTML='importing';this.className='importedButton';\" class =\"importButton\" href=\"%1\">import</a>").arg("/library/"+QString::number(libraryId)+"/folder/"+QString("%1/info").arg(folderContent.at(i + (page*elementsPerPage))->id)));
}
t.setVariable(QString("element%1.read").arg(i),"");
t.setVariable(QString("element%1.size").arg(i),"");
t.setVariable(QString("element%1.pages").arg(i),"");
t.setVariable(QString("element%1.status").arg(i),"");
}
else
{
t.setVariable(QString("element%1.class").arg(i),"cover");
const ComicDB * comic = (ComicDB *)item;
t.setVariable(QString("element%1.browse").arg(i),"");
t.setVariable(QString("element%1.image.width").arg(i),"80px");
//t.setVariable(QString("element%1.downloadurl").arg(i),"/library/"+libraryName+"/comic/"+QString("%1").arg(comic->id));
if(!session.isComicOnDevice(comic->info.hash) && !session.isComicDownloaded(comic->info.hash))
t.setVariable(QString("element%1.download").arg(i),QString("<a onclick=\"this.innerHTML='importing';this.className='importedButton';\" class =\"importButton\" href=\"%1\">import</a>").arg("/library/"+QString::number(libraryId)+"/comic/"+QString("%1").arg(comic->id)));
@ -174,56 +209,28 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
//t.setVariable(QString("element%1.image.url").arg(i),"/images/f.png");
t.setVariable(QString("element%1.read").arg(i),QString("<a class =\"readButton\" href=\"%1\">read</a>").arg("/library/"+QString::number(libraryId)+"/comic/"+QString("%1").arg(comic->id)+"/remote"));
t.setVariable(QString("element%1.image.url").arg(i),QString("/library/%1/cover/%2.jpg").arg(libraryId).arg(comic->info.hash));
t.setVariable(QString("element%1.size").arg(i),"<span class=\"comicSize\">" + QString::number(comic->info.hash.right(comic->info.hash.length()-40).toInt()/1024.0/1024.0,'f',2)+"Mb</span>");
if(comic->info.hasBeenOpened)
t.setVariable(QString("element%1.pages").arg(i),QString("<span class=\"numPages\">%1/%2 pages</span>").arg(comic->info.currentPage).arg(comic->info.numPages.toInt()));
else
t.setVariable(QString("element%1.pages").arg(i),QString("<span class=\"numPages\">%1</span>").arg(comic->info.numPages.toInt()));
if(comic->info.read)
t.setVariable(QString("element%1.status").arg(i), QString("<div class=\"mark\"><img src=\"/images/readMark.png\" style = \"width: 15px\"/> </div>"));
else if(comic->info.hasBeenOpened)
t.setVariable(QString("element%1.status").arg(i), QString("<div class=\"mark\"><img src=\"/images/readingMark.png\" style = \"width: 15px\"/> </div>"));
else
t.setVariable(QString("element%1.status").arg(i),"");
}
i++;
}
//int comicsOffset;// = qMax(0,((page - (numFolderPages - 1)) * 10) - (numFolders%10));
//int comicPage = numFolderPages!=0?page-(numFolderPages - 1):page;
//if(comicPage > 0)
//{
// comicsOffset = elementsPerPage - (numFolders%elementsPerPage);
// comicsOffset += (comicPage-1) *elementsPerPage;
//}
//else
// comicsOffset = 0;
//
//int globalComicsOffset = elementsPerPage - (numFolders%elementsPerPage);
//int numComicsAtCurrentPage = 0;
//if(comicPage == 0) //primera p<>gina de los c<>mics
// numComicsAtCurrentPage = qMin(globalComicsOffset,numComics);
// else if (page == (numPages-1)) //<2F>ltima p<>gina de los c<>mics
// numComicsAtCurrentPage = elementsPerPage-globalComicsOffset + (numComics%elementsPerPage);
// else
// numComicsAtCurrentPage = elementsPerPage - numFoldersAtCurrentPage;
//if(numComics == 0)
// numComicsAtCurrentPage = 0;
////response.writeText(QString("numComicsAtCurrentPage : %1 <br/>").arg(numComicsAtCurrentPage));
////response.writeText(QString("comicsOffset : %1 <br/>").arg(comicsOffset));
//t.loop("elementcomic",numComicsAtCurrentPage);
////
//int j = 0;
//while(j<numComicsAtCurrentPage)
//{
// const ComicDB * comic = (ComicDB *)folderComics.at(j+comicsOffset);
// //if(comic->info.title == 0 || comic->info.title->isEmpty())
// t.setVariable(QString("elementcomic%1.name").arg(j),comic->name);
// //else
// // t.setVariable(QString("elementcomic%1.name").arg(i),*comic->info.title);
// t.setVariable(QString("elementcomic%1.url").arg(j),"/library/"+QUrl::toPercentEncoding(libraryName)+"/comic/"+QString("%1").arg(comic->id));
// t.setVariable(QString("elementcomic%1.coverulr").arg(j),"/library/"+QUrl::toPercentEncoding(libraryName)+"/cover/"+QString("%1").arg(comic->info.hash + ".jpg"));
// j++;
//}
if(numPages > 1)
{
t.setCondition("pageIndex",true);
@ -267,7 +274,6 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
i++;
count += indexCount.value(*itr);
indexPage = count/elementsPerPage;
}
}
else
@ -295,12 +301,14 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
t.setVariable("page.previous",QString("/library/%1/folder/%2?page=%3").arg(libraryId).arg(parentId).arg((page==0)?page:page-1));
t.setVariable("page.next",QString("/library/%1/folder/%2?page=%3").arg(libraryId).arg(parentId).arg((page==numPages-1)?page:page+1));
t.setVariable("page.last",QString("/library/%1/folder/%2?page=%3").arg(libraryId).arg(parentId).arg(numPages-1));
t.setCondition("index", true);
}
else
{
t.loop("page",0);
t.loop("index",0);
t.setCondition("index", false);
t.setCondition("pageIndex",false);
t.setCondition("alphaIndex",false);
}
@ -310,4 +318,4 @@ void FolderController::service(HttpRequest& request, HttpResponse& response)
response.write(t.toLatin1(),true);
}
}

View File

@ -10,32 +10,53 @@ LibrariesController::LibrariesController() {}
void LibrariesController::service(HttpRequest& request, HttpResponse& response)
{
HttpSession session=Static::sessionStore->getSession(request,response);
session.set("ySession","ok");
session.clearNavigationPath();
response.setHeader("Content-Type", "text/html; charset=ISO-8859-1");
response.setHeader("Connection","close");
QString postData = QString::fromUtf8(request.getBody());
//response.writeText(postData);
HttpSession session=Static::sessionStore->getSession(request,response);
if(session.contains("ySession")) //session is already alive check if it is needed to update comics
{
QString postData = QString::fromUtf8(request.getBody());
if(postData.length()>0) {
QList<QString> data = postData.split("\n");
if(data.length() > 2) {
//ONLY COMICS ARE UPDATED, DEVICE CHARACTERISTICS ARE INMUTABLE
QList<QString> comics = data.at(2).split(":").at(1).split("\t");
foreach(QString hash,comics) {
session.setComicOnDevice(hash);
}
}
}
}
else
{
session.set("ySession","ok");
QList<QString> data = postData.split("\n");
if(data.length() > 2)
{
session.setDeviceType(data.at(0).split(":").at(1));
session.setDisplayType(data.at(1).split(":").at(1));
QList<QString> comics = data.at(2).split(":").at(1).split("\t");
foreach(QString hash,comics)
{
session.setComicOnDevice(hash);
}
}
else //valores por defecto, con propositos de depuraci<63>n
{
session.setDeviceType("ipad");
session.setDisplayType("retina");
}
session.clearNavigationPath();
session.clearFoldersPath();
response.setHeader("Content-Type", "text/html; charset=ISO-8859-1");
response.setHeader("Connection","close");
QString postData = QString::fromUtf8(request.getBody());
//response.writeText(postData);
QList<QString> data = postData.split("\n");
if(data.length() > 2)
{
session.setDeviceType(data.at(0).split(":").at(1));
session.setDisplayType(data.at(1).split(":").at(1));
QList<QString> comics = data.at(2).split(":").at(1).split("\t");
foreach(QString hash,comics)
{
session.setComicOnDevice(hash);
}
}
else //values by default, only for debug purposes.
{
session.setDeviceType("iphone");
session.setDisplayType("@2x");
}
}
Template t=Static::templateLoader->getTemplate("libraries_"+session.getDeviceType(),request.getHeader("Accept-Language"));
t.enableWarnings();
@ -54,6 +75,6 @@ void LibrariesController::service(HttpRequest& request, HttpResponse& response)
i++;
}
response.setStatus(200,"OK");
response.write(t.toLatin1(),true);
}

View File

@ -12,8 +12,8 @@ HttpRequest::HttpRequest(QSettings* settings) {
status=waitForRequest;
currentSize=0;
expectedBodySize=0;
maxSize=settings->value("maxRequestSize","16000000").toInt();
maxMultiPartSize=settings->value("maxMultiPartSize","1000000").toInt();
maxSize=settings->value("maxRequestSize","32000000").toInt();
maxMultiPartSize=settings->value("maxMultiPartSize","32000000").toInt();
}
void HttpRequest::readRequest(QTcpSocket& socket) {

View File

@ -307,3 +307,36 @@ int HttpSession::topPage()
return dataPtr->yacreaderSessionData.navigationPath.top();
return 0;
}
void HttpSession::clearFoldersPath()
{
if(dataPtr)
dataPtr->yacreaderSessionData.foldersPath.clear();
}
int HttpSession::popFolder()
{
if(dataPtr && !(dataPtr->yacreaderSessionData.foldersPath.isEmpty()))
return dataPtr->yacreaderSessionData.foldersPath.pop();
return 0;
}
void HttpSession::pushFolder(int page)
{
if(dataPtr)
dataPtr->yacreaderSessionData.foldersPath.push(page);
}
int HttpSession::topFolder()
{
if(dataPtr)
return dataPtr->yacreaderSessionData.foldersPath.top();
return 0;
}
QStack<int> HttpSession::getFoldersPath()
{
if(dataPtr)
return dataPtr->yacreaderSessionData.foldersPath;
return QStack<int>();
}

View File

@ -119,6 +119,12 @@ public:
void pushPage(int page);
int topPage();
void clearFoldersPath();
int popFolder();
void pushFolder(int page);
int topFolder();
QStack<int> getFoldersPath();
private:
struct YACReaderSessionData {
@ -132,6 +138,7 @@ private:
qulonglong comicId;
QStack<int> navigationPath;
QStack<int> foldersPath;
Comic * comic;
};

View File

@ -14,7 +14,7 @@ HttpSessionStore::HttpSessionStore(QSettings* settings, QObject* parent)
connect(&cleanupTimer,SIGNAL(timeout()),this,SLOT(timerEvent()));
cleanupTimer.start(60000);
cookieName=settings->value("cookieName","sessionid").toByteArray();
expirationTime=settings->value("expirationTime",18000000).toInt();
expirationTime=settings->value("expirationTime",86400000).toInt();
qDebug("HttpSessionStore: Sessions expire after %i milliseconds",expirationTime);
}

View File

@ -56,7 +56,11 @@ void StaticFileController::service(HttpRequest& request, HttpResponse& response)
stringPath.remove(fileName);
HttpSession session=Static::sessionStore->getSession(request,response,false);
QString device = session.getDeviceType();
fileName = getDeviceAwareFileName(fileName, device, request.getHeader("Accept-Language"), stringPath);
QString display = session.getDisplayType();
if(fileName.endsWith(".png"))
fileName = getDeviceAwareFileName(fileName, device, display, request.getHeader("Accept-Language"), stringPath);
else
fileName = getDeviceAwareFileName(fileName, device, request.getHeader("Accept-Language"), stringPath);
QString newPath = stringPath.append(fileName);
path = newPath.toLocal8Bit();
@ -207,5 +211,24 @@ QString StaticFileController::getDeviceAwareFileName(QString fileName, QString d
if(QFile(docroot+"/"+path+completeFileName).exists())
return completeFileName; //existe un archivo espec<65>fico para este dispositivo y locales
else
return getLocalizedFileName(fileName,locales,path); //no hay archivo espec<65>fico para el dispositivo, pero puede haberlo para estas locales
return getLocalizedFileName(fileName,locales,path); //no hay archivo espec<65>fico para el dispositivo, pero puede haberlo para estas locales
}
QString StaticFileController::getDeviceAwareFileName(QString fileName, QString device, QString display, QString locales, QString path) const
{
QFileInfo fi(fileName);
QString baseName = fi.baseName();
QString extension = fi.completeSuffix();
QString completeFileName = completeFileName = baseName+display+"."+extension;
if(QFile(docroot+"/"+path+completeFileName).exists())
return completeFileName;
else
{
completeFileName = baseName+"_"+device+display+"."+extension;
if((QFile(docroot+"/"+path+completeFileName).exists()))
return completeFileName;
}
return fileName;
}

View File

@ -84,6 +84,7 @@ private:
QString getLocalizedFileName(QString fileName, QString locales, QString path) const;
QString getDeviceAwareFileName(QString fileName, QString device, QString locales, QString path) const;
QString getDeviceAwareFileName(QString fileName, QString device, QString display, QString locales, QString path) const;
bool exists(QString localizedName, QString path) const;
};

View File

@ -50,10 +50,10 @@ void RequestMapper::service(HttpRequest& request, HttpResponse& response) {
else
{
//se comprueba que la sesi<73>n sea la correcta con el fin de evitar accesos no autorizados
HttpSession session=Static::sessionStore->getSession(request,response,false);
if(!session.isNull() && session.contains("ySession"))
{
//se comprueba que la sesi<73>n sea la correcta con el fin de evitar accesos no autorizados
HttpSession session=Static::sessionStore->getSession(request,response,false);
if(!session.isNull() && session.contains("ySession"))
{
if(library.indexIn(path)!=-1 && DBHelper::getLibraries().contains(library.cap(1).toInt()) )
{
//listar el contenido del folder
@ -83,11 +83,11 @@ void RequestMapper::service(HttpRequest& request, HttpResponse& response) {
//response.writeText(library.cap(1));
Static::staticFileController->service(request, response);
}
}
else //acceso no autorizado, redirecci<63>n
{
ErrorController(300).service(request,response);
}
}
else //acceso no autorizado, redirecci<63>n
{
ErrorController(300).service(request,response);
}
}
}