added support for remote icons

This commit is contained in:
Patrick von Reth 2014-01-13 12:56:09 +01:00
parent aea46dc42a
commit 6745afa680
10 changed files with 127 additions and 110 deletions

View File

@ -36,7 +36,7 @@ set ( SnoreNotify_HDR ${SnoreNotify_HDR}
add_library( snorecore SHARED ${SnoreNotify_SRCS}) add_library( snorecore SHARED ${SnoreNotify_SRCS})
set_target_properties( snorecore PROPERTIES OUTPUT_NAME "snore" DEFINE_SYMBOL "SNORECORE_DLL" ) set_target_properties( snorecore PROPERTIES OUTPUT_NAME "snore" DEFINE_SYMBOL "SNORECORE_DLL" )
target_link_libraries ( snorecore ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ) target_link_libraries ( snorecore ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTNETWORK_LIBRARY} )
install(TARGETS snorecore RUNTIME DESTINATION bin install(TARGETS snorecore RUNTIME DESTINATION bin

View File

@ -2,6 +2,7 @@ set ( SnoreNotify_SRCS ${SnoreNotify_SRCS}
notification/notification.cpp notification/notification.cpp
notification/notification_p.cpp notification/notification_p.cpp
notification/icon.cpp notification/icon.cpp
notification/icon_p.cpp
PARENT_SCOPE) PARENT_SCOPE)
set ( Notification_HDR set ( Notification_HDR

View File

@ -61,24 +61,34 @@ Icon::~Icon()
const QImage &Icon::image() const{ const QImage &Icon::image() const{
if(d->m_img.isNull()) if(d->m_img.isNull())
{
if(isLocalFile())
{ {
d->m_img = QImage(d->m_url); d->m_img = QImage(d->m_url);
} }
else
{
d->m_img = QImage::fromData(d->m_data,"PNG");
}
}
return d->m_img; return d->m_img;
} }
QString Icon::localUrl()const{ QString Icon::localUrl()const{
if(d->m_localUrl.isEmpty()) if(d->m_localUrl.isEmpty())
{ {
if(m_localImageCache.contains(hash())) if(m_localImageCache.contains(d->m_hash))
{ {
d->m_localUrl = m_localImageCache[hash()]; d->m_localUrl = m_localImageCache[d->m_hash];
}else
{
if(isRemoteFile())
{
d->download();
} }
else d->m_localUrl = QString("%1%2.png").arg(SnoreCorePrivate::snoreTMP(), d->m_hash);
{
d->m_localUrl = QString("%1%2.png").arg(SnoreCorePrivate::snoreTMP(), hash());
image().save(d->m_localUrl ,"PNG"); image().save(d->m_localUrl ,"PNG");
m_localImageCache[hash()] = d->m_localUrl; m_localImageCache[d->m_hash] = d->m_localUrl;
} }
} }
return d->m_localUrl; return d->m_localUrl;
@ -91,17 +101,6 @@ const QByteArray &Icon::imageData() const{
return d->m_data; return d->m_data;
} }
QString Icon::hash() const{
if(d->m_isLocalFile)
{
return "";
}
if(d->m_hash.isEmpty() && !imageData().isNull()){
d->m_hash = IconData::computeHash(imageData());
}
return d->m_hash;
}
bool Icon::isLocalFile() const bool Icon::isLocalFile() const
{ {
return d->m_isLocalFile; return d->m_isLocalFile;
@ -120,3 +119,9 @@ QString Icon::url() const
{ {
return d->m_url; return d->m_url;
} }
bool Snore::Icon::isRemoteFile() const
{
return !d->m_isResource && !isLocalFile();
}

View File

@ -42,8 +42,8 @@ public:
QString localUrl() const; QString localUrl() const;
QString url() const; QString url() const;
const QByteArray &imageData() const ; const QByteArray &imageData() const ;
QString hash() const;
bool isLocalFile() const; bool isLocalFile() const;
bool isRemoteFile() const;
bool isEmpty() const; bool isEmpty() const;
bool isValid() const; bool isValid() const;

View File

@ -0,0 +1,84 @@
/*
SnoreNotify is a Notification Framework based on Qt
Copyright (C) 2013-2014 Patrick von Reth <vonreth@kde.org>
SnoreNotify is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SnoreNotify is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with SnoreNotify. If not, see <http://www.gnu.org/licenses/>.
*/
#include "icon_p.h"
#include <QEventLoop>
#include <QNetworkAccessManager>
#include <QNetworkReply>
using namespace Snore;
IconData::IconData(const QString &url):
m_url(url),
m_isLocalFile(false),
m_isResource(m_url.startsWith(":/")),
m_hash(computeHash(m_url.toLatin1()))
{
if(QFile(url).exists())
{
m_isLocalFile = true;
m_localUrl = url;
}
}
IconData::IconData(const QImage &img):
m_img(img),
m_isLocalFile(false),
m_isResource(false)
{
setImageData();
}
IconData::~IconData()
{
}
void Snore::IconData::setImageData()
{
QBuffer buffer( &m_data );
buffer.open( QBuffer::WriteOnly );
m_img.save( &buffer, "PNG" );
if(m_hash.isEmpty())
{
m_hash = computeHash(m_data);
}
}
QString IconData::computeHash(const QByteArray &data)
{
QCryptographicHash h(QCryptographicHash::Md5);
h.addData(data);
return h.result().toHex();
}
void IconData::download()
{
QNetworkAccessManager manager;
QEventLoop loop;
QNetworkRequest request(m_url);
request.setRawHeader("User-Agent", "SnoreNotify");
QNetworkReply *reply = manager.get(request);
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
m_data = reply->readAll();
}

View File

@ -30,57 +30,23 @@
#include <QFile> #include <QFile>
#include <QDebug> #include <QDebug>
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QUrl>
namespace Snore{ namespace Snore{
class IconData : public QSharedData class IconData : public QSharedData
{ {
public: public:
IconData(const QString &url): IconData(const QString &url);
m_url(url), IconData(const QImage &img);
m_isLocalFile(false) ~IconData();
{
if(m_url.startsWith(":/"))
{
m_hash = computeHash(m_url.toLatin1());
}
else if(QFile(url).exists())
{
m_isLocalFile = true;
m_localUrl = url;
}
}
IconData(const QImage &img):
m_img(img),
m_isLocalFile(false)
{
setImageData();
}
~IconData() static QString computeHash(const QByteArray &data);
{
}
void setImageData() void setImageData();
{ void download();
QBuffer buffer( &m_data );
buffer.open( QBuffer::WriteOnly );
m_img.save( &buffer, "PNG" );
if(m_hash.isEmpty())
{
m_hash = computeHash(m_data);
}
}
static QString computeHash(const QByteArray &data)
{
QCryptographicHash h(QCryptographicHash::Md5);
h.addData(data);
return h.result().toHex();
}
QImage m_img; QImage m_img;
QByteArray m_data; QByteArray m_data;
@ -88,7 +54,7 @@ public:
QString m_url; QString m_url;
QString m_hash; QString m_hash;
bool m_isLocalFile; bool m_isLocalFile;
bool m_isResource;
private: private:
Q_DISABLE_COPY(IconData) Q_DISABLE_COPY(IconData)

View File

@ -214,6 +214,11 @@ void Notification::setDefaultTimeout(int defaultTimeout)
m_defaultTimeout = defaultTimeout; m_defaultTimeout = defaultTimeout;
} }
Notification::Notification(const QString &, const QString &, const QString &, const QString &, const Icon &, int , NotificationEnums::Prioritys::prioritys )
{
}
QDataStream &operator<< ( QDataStream &stream, const Notification &noti ) QDataStream &operator<< ( QDataStream &stream, const Notification &noti )
{ {
stream << "Title: " << noti.title() << " Text: " << noti.text() << " ID: " << noti.id() ; stream << "Title: " << noti.title() << " Text: " << noti.text() << " ID: " << noti.id() ;

View File

@ -57,7 +57,7 @@ public:
public: public:
Notification(); Notification();
Notification(const Application &application,const Alert &alert,const QString &title,const QString &text,const Icon &icon,int timeout=10, NotificationEnums::Prioritys::prioritys priority = NotificationEnums::Prioritys::NORMAL ); explicit Notification(const Application &application,const Alert &alert,const QString &title,const QString &text,const Icon &icon,int timeout=10, NotificationEnums::Prioritys::prioritys priority = NotificationEnums::Prioritys::NORMAL );
Notification(const Notification &other ); Notification(const Notification &other );
Notification &operator=(const Notification &other); Notification &operator=(const Notification &other);
~Notification(); ~Notification();
@ -98,7 +98,8 @@ public:
static void setDefaultTimeout(int defaultTimeout); static void setDefaultTimeout(int defaultTimeout);
private: private:
Notification(const QString &,const QString &,const QString &,const QString &,const Icon &,int, NotificationEnums::Prioritys::prioritys ); explicit Notification(const QString &, const QString &, const QString &, const QString &, const Icon &, int , NotificationEnums::Prioritys::prioritys);
QExplicitlySharedDataPointer<NotificationData> d; QExplicitlySharedDataPointer<NotificationData> d;
static int m_defaultTimeout; static int m_defaultTimeout;

View File

@ -76,7 +76,6 @@ SnarlNotification Parser::parse(QString &msg,QTcpSocket* client){
QString appName; QString appName;
QString title; QString title;
QString text; QString text;
QString sntpIcon;
QString icon; QString icon;
QString alertName; QString alertName;
int timeout=10; int timeout=10;
@ -102,8 +101,7 @@ SnarlNotification Parser::parse(QString &msg,QTcpSocket* client){
text = value; text = value;
break; break;
case ICON: case ICON:
sntpIcon = value; icon = value;
icon = downloadIcon(value);
break; break;
case CLASS: case CLASS:
alertName = value; alertName = value;
@ -146,8 +144,6 @@ SnarlNotification Parser::parse(QString &msg,QTcpSocket* client){
sNotification.notification = Notification(app,alert,title,text,icon,timeout); sNotification.notification = Notification(app,alert,title,text,icon,timeout);
sNotification.notification.setSource(snarl); sNotification.notification.setSource(snarl);
sNotification.notification.hints().setValue("SnarlIcon", sntpIcon);
switch(action){ switch(action){
case NOTIFICATION: case NOTIFICATION:
@ -197,41 +193,3 @@ SnarlNotification Parser::parse(QString &msg,QTcpSocket* client){
return sNotification; return sNotification;
} }
QString Parser::downloadIcon(const QString &address){
if(address=="")
{
return "";
}
if(address.startsWith("file://"))
{
return QString(address.mid(7));
}
QByteArray arr=address.toUtf8();
QUrl url = QUrl::fromEncoded(arr);
QCryptographicHash hash(QCryptographicHash::Md5);
hash.addData(arr);
QString filename=QDir::temp().path()+"/SnoreNotify/"+hash.result().toHex()+address.mid(address.lastIndexOf(".")-1);
QFile file(filename);
if(file.exists())
return filename;
QByteArray reply=download(url);
file.open(QIODevice::WriteOnly);
file.write(reply);
return filename;
}
QByteArray Parser::download(const QUrl &address){
QNetworkAccessManager manager;
QEventLoop loop;
QNetworkRequest request(address);
request.setRawHeader("User-Agent", "SnoreNotify");
QNetworkReply *reply=manager.get(request);
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
return reply->readAll();
}

View File

@ -29,9 +29,6 @@
class Parser:public QObject{ class Parser:public QObject{
Q_OBJECT Q_OBJECT
public:
static class QByteArray download(const QUrl &address);
public: public:
Parser(class SnarlNetworkFrontend* snarl); Parser(class SnarlNetworkFrontend* snarl);
@ -39,7 +36,7 @@ public:
private: private:
class SnarlNetworkFrontend *snarl; class SnarlNetworkFrontend *snarl;
QString downloadIcon(const QString &address);
enum snpTypes{ enum snpTypes{
TYPE, TYPE,
APP, APP,