fix crash in eventview
authorKonrad Rosenbaum <konrad@silmor.de>
Mon, 11 Jul 2016 22:00:40 +0000 (00:00 +0200)
committerKonrad Rosenbaum <konrad@silmor.de>
Mon, 11 Jul 2016 22:00:40 +0000 (00:00 +0200)
commonlib/widgets/eventview.cpp
commonlib/widgets/eventview.h

index e77bb5a..1f22532 100644 (file)
@@ -24,6 +24,7 @@
 #include <QNetworkRequest>
 #include <QTimer>
 #include <QUrlQuery>
+#include <QDir>
 #include <QMessageBox>
 #include <QDesktopServices>
 
@@ -37,8 +38,31 @@ MEventView::MEventView ( QWidget* parent ) : QTextBrowser ( parent )
        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 )
 {
@@ -47,21 +71,38 @@ 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();
@@ -71,28 +112,33 @@ void MEventView::clearEvent()
 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();
@@ -103,7 +149,7 @@ void MEventView::setEvent ( MOEvent event )
                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;
@@ -111,9 +157,9 @@ void MEventView::setEvent ( MOEvent event )
        }
        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
index d336860..525b5e1 100644 (file)
@@ -19,6 +19,9 @@
 
 #include "commonexport.h"
 
+class QNetworkAccessManager;
+class QNetworkReply;
+
 ///Event Viewer
 class MAGICSMOKE_COMMON_EXPORT MEventView:public QTextBrowser
 {
@@ -40,7 +43,13 @@ signals:
        /**order ticket from event tab*/
        void eventOrderTicket(qint64,qint64);
 private:
-       QString mPattern;
+       QString mPattern,mCacheDir;
+       QNetworkAccessManager*mNam;
+       MOEvent mCurrentEvent;
+
+       void initCacheDir();
+       void saveReply(QNetworkReply*,QString);
+       void renderEvent();
 };