#include <QNetworkRequest>
#include <QTimer>
#include <QUrlQuery>
+#include <QDir>
#include <QMessageBox>
#include <QDesktopServices>
qDebug()<<"Setting path"<<req->parentUrl()<<"for URL"<<req->url();
setSearchPaths(QStringList()<<req->parentUrl().toString());
resetPattern();
+ mNam=new QNetworkAccessManager(this);
+ connect(mNam,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), req,SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
+ initCacheDir();
}
+void MEventView::initCacheDir()
+{
+ mCacheDir=req->dataDir()+"/eventcache";
+ QDir d(req->dataDir());
+ if(!d.exists("eventcache")){
+ if(!d.mkdir("eventcache"))
+ qDebug()<<"Warning: cannot create event data cache"<<mCacheDir;
+ }
+ d.setPath(mCacheDir);
+ QDateTime old=QDateTime::currentDateTime().addDays(-2);
+ for(auto entry:d.entryInfoList(QDir::Files)){
+ if(entry.lastModified()<old)
+ d.remove(entry.fileName());
+ }
+}
+
+inline QString url2base64(QUrl url)
+{
+ return url.toEncoded().toBase64(QByteArray::OmitTrailingEquals|QByteArray::Base64UrlEncoding);
+}
QVariant MEventView::loadResource ( int type, const QUrl& name )
{
if(name.isRelative()||name.scheme()=="http"||name.scheme()=="https"){
QUrl url(name);
if(name.isRelative())url=req->url().resolved(name);
- QNetworkAccessManager nam;
- connect(&nam,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),req,SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
- QNetworkReply*rpl= nam.get(QNetworkRequest(url));
+ QString encoded=url2base64(url);
+ //find in cache
+ if(QDir(mCacheDir).exists(encoded)){
+ qDebug()<<"Found resource"<<url.toString()<<"in cache as"<<encoded;
+ QFile fd(mCacheDir+"/"+encoded);
+ fd.open(QIODevice::ReadOnly);
+ return fd.readAll();
+ }
+ //schedule retrieval
+ QNetworkReply*rpl= mNam->get(QNetworkRequest(url));
qDebug()<<"Trying to GET"<<url;
- QEventLoop loop;
- connect(rpl,SIGNAL(finished()),&loop,SLOT(quit()));
- QTimer::singleShot(15000,&loop,SLOT(quit()));
- loop.exec();
- QByteArray data=rpl->readAll();
- qDebug()<<"...got"<<data.size()<<"bytes";
- return data;
+ connect(rpl,&QNetworkReply::finished, this,[=]{saveReply(rpl,encoded);});
+ //return dummy
+ return QByteArray();
}else
return QTextBrowser::loadResource ( type, name );
}
+void MEventView::saveReply ( QNetworkReply*rpl, QString fname)
+{
+ QFile fd(mCacheDir+"/"+fname);
+ if(fd.open(QIODevice::WriteOnly|QIODevice::Truncate)){
+ fd.write(rpl->readAll());
+ qDebug()<<"...got"<<fd.size()<<"bytes for cache file"<<fname;
+ fd.close();
+ rpl->deleteLater();
+ renderEvent();
+ }
+
+}
+
+
void MEventView::clearEvent()
{
clearHistory();
void MEventView::setEvent ( MOEvent event )
{
clearEvent();
+ mCurrentEvent=event;
+ renderEvent();
+}
+void MEventView::renderEvent()
+{
//generate HTML
- QString detail="<h1>"+htmlize(event.title())+"</h1>\n";
- detail+=tr("Artist: %1").arg(htmlize(event.artist().value().name()))+"<p>\n";
- detail+=tr("Starttime: %1").arg(htmlize(event.startTimeString()))+"<br>\n";
- detail+=tr("Endtime: %1").arg(htmlize(event.endTimeString()))+"<p>\n";
- detail+=tr("Room: %1").arg(htmlize(event.room()))+"<br>\n";
- detail+=tr("Seats: %1 max. (%2 sold out; %3 reserved; %4 free)").arg(event.capacity()).arg(event.amountSold()).arg(event.amountReserved()).arg(event.amountFree())+"<p>\n";
+ QString detail="<h1>"+htmlize(mCurrentEvent.title())+"</h1>\n";
+ detail+=tr("Artist: %1").arg(htmlize(mCurrentEvent.artist().value().name()))+"<p>\n";
+ detail+=tr("Starttime: %1").arg(htmlize(mCurrentEvent.startTimeString()))+"<br>\n";
+ detail+=tr("Endtime: %1").arg(htmlize(mCurrentEvent.endTimeString()))+"<p>\n";
+ detail+=tr("Room: %1").arg(htmlize(mCurrentEvent.room()))+"<br>\n";
+ detail+=tr("Seats: %1 max. (%2 sold out; %3 reserved; %4 free)").arg(mCurrentEvent.capacity()).arg(mCurrentEvent.amountSold()).arg(mCurrentEvent.amountReserved()).arg(mCurrentEvent.amountFree())+"<p>\n";
const QString bgsold=tr("<div style=\"background-color:#ff8080\">Sold Out!</div>","Colored display for sold out tickets");
const QString bgavail=tr("<table border=1 style=\"border-style:groove; background-color:#00ff00\"><tr><td><div style=\"background-color:#80ff80\"><a href=\"%1\">Order Tickets...</a></div></td></tr></table>","Colored display for ordering tickets");
const QString bghide=tr("<div style=\"background-color:#c0c0c0\">Unable to sell.</div>","Colored display for tickets unavailable to this user");
- const bool showevent=req->checkFlags(event.flags());
+ const bool showevent=req->checkFlags(mCurrentEvent.flags());
if(showevent)
- detail+=event.amountFree()>0?bgavail.arg(QString("order:?ev=%1").arg(event.id())):bgsold;
+ detail+=mCurrentEvent.amountFree()>0?bgavail.arg(QString("order:?ev=%1").arg(mCurrentEvent.id())):bgsold;
else
detail+=bghide;
detail+="<h2>"+tr("Prices")+"</h2>\n";
detail+="<table frame=1 border=1>"
"<thead><tr><th>"+tr("Category")+"</th><th>"+tr("Price")+"</th><th>"+tr("Available")+"</th><th>"+tr("Max. Seats")+"</th><th>"+tr("Order")+"</th></tr></thead>\n";
- QList<MOEventPrice>prices=event.price();
+ QList<MOEventPrice>prices=mCurrentEvent.price();
qSort(prices.begin(),prices.end(),[](const MOEventPrice&p1,const MOEventPrice&p2){return p1.prio()<p2.prio();});
for(MOEventPrice ctg:prices){
detail+="<tr><td>"+ctg.pricecategory().value().name();
if(showevent && req->checkFlags(ctg.flags()))
detail+="</td><td>"+
(avail>0?
- bgavail.arg(QString("order:?ev=%1&pr=%2").arg(event.id()).arg(ctg.pricecategoryid()))
+ bgavail.arg(QString("order:?ev=%1&pr=%2").arg(mCurrentEvent.id()).arg(ctg.pricecategoryid()))
:bgsold);
else
detail+="</td><td>"+bghide;
}
detail+="</table><p>\n";
- detail+="<h2>"+tr("Description")+"</h2>\n"+event.description()+"<p>\n";
+ detail+="<h2>"+tr("Description")+"</h2>\n"+mCurrentEvent.description()+"<p>\n";
detail+="<h2>"+tr("Comment")+"</h2>\n";
- QString comment=event.comment();
+ QString comment=mCurrentEvent.comment();
if(!comment.trimmed().startsWith("<html>"))comment=htmlize(comment);
detail+=comment;
//set value