Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
18 KB
Referenced Files
None
Subscribers
None
diff --git a/lightscreen.pro b/lightscreen.pro
index 0a8b704..801799b 100644
--- a/lightscreen.pro
+++ b/lightscreen.pro
@@ -1,78 +1,80 @@
TEMPLATE = app
TARGET = lightscreen
HEADERS += dialogs/areadialog.h \
dialogs/historydialog.h \
dialogs/namingdialog.h \
dialogs/optionsdialog.h \
dialogs/previewdialog.h \
dialogs/updaterdialog.h \
lightscreenwindow.h \
tools/os.h \
tools/screenshot.h \
tools/screenshotmanager.h \
tools/uploader.h \
tools/windowpicker.h \
updater/updater.h \
widgets/hotkeywidget.h \
tools/qtsingleapplication/qtlockedfile.h \
tools/qtsingleapplication/qtsinglecoreapplication.h \
tools/uploader/imageuploader.h \
tools/uploader/imguruploader.h \
tools/uploader/uploader.h \
+ tools/qtimgur.h \
tools/qtwin.h
SOURCES += dialogs/areadialog.cpp \
dialogs/historydialog.cpp \
dialogs/namingdialog.cpp \
dialogs/optionsdialog.cpp \
dialogs/previewdialog.cpp \
dialogs/updaterdialog.cpp \
lightscreenwindow.cpp \
main.cpp \
tools/os.cpp \
tools/screenshot.cpp \
tools/screenshotmanager.cpp \
tools/windowpicker.cpp \
updater/updater.cpp \
widgets/hotkeywidget.cpp \
tools/qtsingleapplication/qtlockedfile.cpp \
tools/qtsingleapplication/qtlockedfile_unix.cpp \
tools/qtsingleapplication/qtlockedfile_win.cpp \
tools/qtsingleapplication/qtsinglecoreapplication.cpp \
tools/uploader/imageuploader.cpp \
tools/uploader/imguruploader.cpp \
tools/uploader/uploader.cpp \
+ tools/qtimgur.cpp \
tools/qtwin.cpp
FORMS += dialogs/historydialog.ui \
dialogs/namingdialog.ui \
dialogs/optionsdialog.ui \
lightscreenwindow.ui
RESOURCES += lightscreen.qrc
RC_FILE += lightscreen.rc
CODECFORSRC = UTF-8
-QT += network core gui sql multimedia winextras
+QT += network core gui xml sql multimedia winextras
include($$PWD/tools/globalshortcut/globalshortcut.pri)
include($$PWD/tools/qtsingleapplication/qtsingleapplication.pri)
windows{
contains(QMAKE_CC, gcc){
LIBS += libgdi32 libgcc libuser32 libole32 libshell32 libshlwapi libcomctl32
QMAKE_CXXFLAGS = -Wextra -Wall -Wpointer-arith
}
contains(QMAKE_CC, cl){
LIBS += gdi32.lib user32.lib ole32.lib shell32.lib shlwapi.lib comctl32.lib
}
}
unix:LIBS += -lX11
OTHER_FILES += TODO.txt
diff --git a/tools/qtimgur.cpp b/tools/qtimgur.cpp
new file mode 100644
index 0000000..5fcd6a1
--- /dev/null
+++ b/tools/qtimgur.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2014 Christian Kaiser
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include "qtimgur.h"
+
+#include <QFile>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+#include <QXmlStreamReader>
+
+QtImgur::QtImgur(const QString &APIKey, QObject *parent) : QObject(parent), mAPIKey(APIKey), directUrl(false)
+{
+ mNetworkManager = new QNetworkAccessManager(this);
+
+ connect(mNetworkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(reply(QNetworkReply*)));
+}
+
+void QtImgur::cancelAll()
+{
+ foreach (QNetworkReply *reply, mFiles.keys()) {
+ reply->abort();
+ }
+
+ mFiles.clear();
+}
+
+void QtImgur::cancel(const QString &fileName)
+{
+ QNetworkReply *reply = mFiles.key(fileName);
+
+ if (!reply) {
+ return;
+ }
+
+ mFiles.remove(reply);
+ reply->abort();
+}
+
+void QtImgur::upload(const QString &fileName)
+{
+ QFile file(fileName);
+
+ if (!file.open(QIODevice::ReadOnly)) {
+ emit error(fileName, QtImgur::ErrorFile);
+ return;
+ }
+
+ QByteArray data;
+ data.append(QString("key=").toUtf8());
+ data.append(QUrl::toPercentEncoding(mAPIKey));
+ data.append(QString("&image=").toUtf8());
+ data.append(QUrl::toPercentEncoding(file.readAll().toBase64()));
+ file.close();
+
+ QNetworkRequest request(QUrl("http://api.imgur.com/2/upload"));
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+
+ QNetworkReply *reply = mNetworkManager->post(request, data);
+ connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(progress(qint64, qint64)));
+
+ mFiles.insert(reply, fileName);
+}
+
+void QtImgur::progress(qint64 bytesSent, qint64 bytesTotal)
+{
+ qint64 totalSent, totalTotal;
+
+ QNetworkReply *senderReply = qobject_cast<QNetworkReply*>(sender());
+
+ senderReply->setProperty("bytesSent", bytesSent);
+ senderReply->setProperty("bytesTotal", bytesTotal);
+
+ totalSent = bytesSent;
+ totalTotal = bytesTotal;
+
+ foreach (QNetworkReply *reply, mFiles.keys()) {
+ if (reply != senderReply) {
+ totalSent += reply->property("bytesSent").toLongLong();
+ totalTotal += reply->property("bytesTotal").toLongLong();
+ }
+ }
+
+ emit uploadProgress(totalSent, totalTotal);
+}
+
+void QtImgur::reply(QNetworkReply *reply)
+{
+ QString fileName = mFiles[reply];
+
+ mFiles.remove(reply);
+
+ if (reply->error() != QNetworkReply::NoError) {
+ if (reply->error() == QNetworkReply::OperationCanceledError)
+ emit error(fileName, QtImgur::ErrorCancel);
+ else
+ emit error(fileName, QtImgur::ErrorNetwork);
+
+ reply->deleteLater();
+ return;
+ }
+
+ if (reply->rawHeader("X-RateLimit-Remaining") == "0") {
+ emit error(fileName, QtImgur::ErrorCredits);
+ reply->deleteLater();
+ return;
+ }
+
+ QXmlStreamReader reader(reply->readAll());
+
+ QString url_option = "imgur_page";
+
+ if (directUrl)
+ url_option = "original";
+
+ QString url;
+ QString deleteHash;
+
+
+ bool hasError = false;
+
+ while (!reader.atEnd()) {
+ reader.readNext();
+
+ if (reader.isStartElement()) {
+ if (reader.name() == "error") {
+ hasError = true;
+ }
+
+ if (reader.name() == "deletehash") {
+ deleteHash = reader.readElementText();
+ }
+
+ if (reader.name() == url_option) {
+ url = reader.readElementText();
+ }
+ }
+ }
+
+ if (deleteHash.isEmpty() || url.isEmpty() || hasError) {
+ emit error(fileName, QtImgur::ErrorUpload);
+ }
+ else {
+ emit uploaded(fileName, url, deleteHash);
+ }
+
+
+ reply->deleteLater();
+}
diff --git a/tools/qtimgur.h b/tools/qtimgur.h
new file mode 100644
index 0000000..2786be0
--- /dev/null
+++ b/tools/qtimgur.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 Christian Kaiser
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef QTIMGUR_H
+#define QTIMGUR_H
+
+#include <QObject>
+#include <QHash>
+#include <QNetworkReply>
+#include <QPointer>
+
+class QNetworkAccessManager;
+
+class QtImgur: public QObject {
+ Q_OBJECT
+
+public:
+ enum Error {
+ ErrorFile,
+ ErrorNetwork,
+ ErrorCredits,
+ ErrorUpload,
+ ErrorCancel
+ };
+
+ QtImgur(const QString &APIKey, QObject *parent);
+ bool directUrl;
+
+public slots:
+ void cancelAll();
+ void cancel(const QString &fileName);
+ void upload(const QString &fileName);
+
+protected slots:
+ void progress(qint64, qint64);
+ void reply(QNetworkReply* reply);
+
+signals:
+ void error(QString, QtImgur::Error);
+ void uploadProgress(qint64, qint64);
+ void uploaded(QString file, QString url, QString deleteHash);
+
+private:
+ QString mAPIKey;
+ QNetworkAccessManager *mNetworkManager;
+ QHash<QNetworkReply*, QString> mFiles;
+};
+
+#endif // QTIMGUR_H
diff --git a/tools/uploader/imguruploader.cpp b/tools/uploader/imguruploader.cpp
index 37131f1..595eda4 100644
--- a/tools/uploader/imguruploader.cpp
+++ b/tools/uploader/imguruploader.cpp
@@ -1,120 +1,128 @@
#include "imguruploader.h"
#include <QNetworkAccessManager>
#include <QtNetwork>
-ImgurUploader::ImgurUploader(QVariantHash &options) : ImageUploader(options) {}
-
-void ImgurUploader::upload(const QString &fileName)
+ImgurUploader::ImgurUploader(QVariantHash &options, QString fileName) : ImageUploader(options)
{
-
- if (mOptions.value("anonymous", true).toBool()) {
- uploadAnonymous(fileName);
- }
- else {
- //uploadOAuth(fileName);
- }
+ upload(fileName);
}
-void ImgurUploader::uploadAnonymous(const QString &fileName)
+void ImgurUploader::upload(const QString &fileName)
{
- QFile *file = new QFile(fileName);
+ QFile file(fileName);
- if (!file->open(QIODevice::ReadOnly)) {
+ if (!file.open(QIODevice::ReadOnly)) {
emit error(ImageUploader::FileError, fileName);
- file->deleteLater();
return;
}
- QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
+ QByteArray data;
+ data.append(QString("key=").toUtf8());
+ data.append(QUrl::toPercentEncoding(mOptions.value("APIKey", "6920a141451d125b3e1357ce0e432409").toString()));
+ data.append(QString("&image=").toUtf8());
+ data.append(QUrl::toPercentEncoding(file.readAll().toBase64()));
+ file.close();
- QHttpPart imagePart;
- imagePart.setHeader(QNetworkRequest::ContentTypeHeader, "image/png");
- imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\""));
-
- imagePart.setBodyDevice(file);
- file->setParent(multiPart);
- multiPart->append(imagePart);
-
- QNetworkRequest request(QUrl("https://api.imgur.com/3/upload"));
- request.setRawHeader("Authorization", "Client-ID 3ebe94c791445c1");
-
- QNetworkReply *reply = mOptions.value("networkManager").value<QNetworkAccessManager*>()->post(request, multiPart);
+ QNetworkRequest request(QUrl("http://api.imgur.com/2/upload"));
+ request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+ QNetworkReply *reply = mOptions.value("networkManager").value<QNetworkAccessManager*>()->post(request, data);
reply->setProperty("fileName", fileName);
this->setProperty("fileName", fileName);
connect(reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64)));
connect(this , SIGNAL(cancelRequest()), reply, SLOT(abort()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(networkError(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(finished()), this, SLOT(finished()));
}
void ImgurUploader::cancel()
{
emit cancelRequest();
deleteLater();
}
void ImgurUploader::networkError(QNetworkReply::NetworkError code)
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
QString fileName = reply->property("fileName").toString();
reply->deleteLater();
switch (code)
{
case QNetworkReply::OperationCanceledError:
emit error(ImageUploader::CancelError, fileName);
break;
default:
emit error(ImageUploader::NetworkError, fileName);
}
}
void ImgurUploader::finished()
{
- qDebug() << "ImgurUploader::finished()";
-
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
QString fileName = reply->property("fileName").toString();
+ reply->deleteLater();
if (reply->error() != QNetworkReply::NoError) {
if (reply->error() == QNetworkReply::OperationCanceledError) {
emit error(ImageUploader::CancelError, fileName);
}
else {
- qDebug() << reply->errorString();
-
emit error(ImageUploader::NetworkError, fileName);
}
return;
}
if (reply->rawHeader("X-RateLimit-Remaining") == "0") {
emit error(ImageUploader::HostError, fileName);
return;
}
- QJsonObject imgurResponse = QJsonDocument::fromJson(reply->readAll()).object();
+ QXmlStreamReader reader(reply->readAll());
- if (imgurResponse.value("success").toBool() == true) {
- QJsonObject imageData = imgurResponse.value("data").toObject();
+ QString url_option = "imgur_page";
- emit uploaded(fileName, imageData["link"].toString(), imageData["deletehash"].toString());
+ if (mOptions.value("directUrl", false).toBool())
+ url_option = "original";
+
+ QString url;
+ QString deleteHash;
+
+ bool hasError = false;
+
+ while (!reader.atEnd()) {
+ reader.readNext();
+
+ if (reader.isStartElement()) {
+ if (reader.name() == "error") {
+ hasError = true;
+ }
+
+ if (reader.name() == "deletehash") {
+ deleteHash = reader.readElementText();
+ }
+
+ if (reader.name() == url_option) {
+ url = reader.readElementText();
+ }
+ }
}
- else {
+
+ if (deleteHash.isEmpty() || url.isEmpty() || hasError) {
emit error(ImageUploader::HostError, fileName);
}
-
- reply->deleteLater();
+ else {
+ emit uploaded(fileName, url, deleteHash);
+ }
}
void ImgurUploader::uploadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
float b = (float) bytesReceived/bytesTotal;
int p = qRound(b*100);
setProgress(p);
emit progressChange(p);
}
diff --git a/tools/uploader/imguruploader.h b/tools/uploader/imguruploader.h
index 18353fc..ac41628 100644
--- a/tools/uploader/imguruploader.h
+++ b/tools/uploader/imguruploader.h
@@ -1,33 +1,30 @@
#ifndef IMGURUPLOADER_H
#define IMGURUPLOADER_H
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include "imageuploader.h"
class ImgurUploader : public ImageUploader
{
Q_OBJECT
public:
- ImgurUploader(QVariantHash &options);
+ ImgurUploader(QVariantHash &options, QString fileName = "");
public slots:
void upload(const QString &fileName);
void cancel();
private slots:
void finished();
void uploadProgress(qint64 bytesReceived, qint64 bytesTotal);
void networkError(QNetworkReply::NetworkError code);
signals:
void cancelRequest();
-private:
- void uploadAnonymous(const QString &fileName);
-
};
#endif // IMGURUPLOADER_H
diff --git a/tools/uploader/uploader.cpp b/tools/uploader/uploader.cpp
index be5884a..025310a 100644
--- a/tools/uploader/uploader.cpp
+++ b/tools/uploader/uploader.cpp
@@ -1,119 +1,117 @@
/*
* Copyright (C) 2014 Christian Kaiser
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "uploader.h"
#include "../screenshotmanager.h"
#include "imguruploader.h"
#include <QtNetwork>
#include <QSettings>
Uploader* Uploader::mInstance = 0;
Uploader::Uploader(QObject *parent) : QObject(parent)
{
mNetworkAccessManager = new QNetworkAccessManager(this);
}
Uploader *Uploader::instance()
{
if (!mInstance)
mInstance = new Uploader();
return mInstance;
}
int Uploader::progress() const
{
return mProgress;
}
QString Uploader::lastUrl() const
{
return mLastUrl;
}
void Uploader::cancel()
{
mUploaders.clear();
emit cancelAll();
}
void Uploader::upload(const QString &fileName)
{
if (fileName.isEmpty()) {
return;
}
QVariantHash options;
options["networkManager"].setValue(mNetworkAccessManager);
options["directUrl"] = ScreenshotManager::instance()->settings()->value("options/uploadDirectLink", false).toBool();
- options["anonymous"] = true; //TODO: Settings
- ImgurUploader *uploader = new ImgurUploader(options);
+ ImgurUploader *uploader = new ImgurUploader(options, fileName);
connect(uploader, &ImgurUploader::uploaded , this, &Uploader::uploaded);
connect(uploader, &ImgurUploader::error , this, &Uploader::uploaderError);
connect(uploader, &ImgurUploader::progressChange, this, &Uploader::progressChange);
connect(this , SIGNAL(cancelAll()), uploader, SLOT(cancel()));
- uploader->upload(fileName);
mUploaders.append(uploader);
}
void Uploader::uploaded(const QString &file, const QString &url, const QString &deleteHash)
{
mLastUrl = url;
mUploaders.removeAll(qobject_cast<ImageUploader*>(sender()));
sender()->deleteLater();
emit done(file, url, deleteHash);
}
void Uploader::uploaderError(ImageUploader::Error error, QString fileName)
{
Q_UNUSED(error)
mUploaders.removeAll(qobject_cast<ImageUploader*>(sender()));
sender()->deleteLater();
emit done(fileName, "", "");
}
int Uploader::uploading()
{
return mUploaders.count();
}
void Uploader::progressChange(int p)
{
if (mUploaders.size() <= 0) {
emit progress(p);
return;
}
int totalProgress = 0;
for (int i = 0; i < mUploaders.size(); ++i) {
totalProgress += mUploaders[i]->progress();
}
mProgress = totalProgress / mUploaders.size();
emit progress(mProgress);
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 16, 12:58 AM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
69995
Default Alt Text
(18 KB)

Event Timeline