Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F132691
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
18 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
R63 darkscreen
Attached
Detach File
Event Timeline