--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/QTfrontend/ui/dialog/upload_video.cpp Thu Jul 26 21:58:25 2012 +0400
@@ -0,0 +1,245 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * 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; version 2 of the License
+ *
+ * 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 program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <QLineEdit>
+#include <QDialogButtonBox>
+#include <QPushButton>
+#include <QGridLayout>
+#include <QCheckBox>
+#include <QLabel>
+#include <QFrame>
+#include <QPlainTextEdit>
+#include <QSslError>
+#include <QUrl>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+
+#include "upload_video.h"
+#include "hwconsts.h"
+
+// User-agent string used in http requests.
+static const QByteArray UserAgent = ("Hedgewars-QtFrontend/" + *cVersionString).toAscii();
+
+// This is developer key obtained from http://code.google.com/apis/youtube/dashboard/
+// If you are reusing this code outside Hedgewars, don't use this developer key,
+// obtain you own at http://code.google.com/apis/youtube/dashboard/
+static const QByteArray devKey = "AI39si5pKjxR0XgNIlmrEFF-LyYD31rps4g2O5dZTxLgD0fvJ2rHxrMrNFY8FYTZrzeI3VlaFVQLKfFnSBugvdZmy8vFzRDefQ";
+
+HWUploadVideoDialog::HWUploadVideoDialog(QWidget* parent, const QString &filename, QNetworkAccessManager* netManager) : QDialog(parent)
+{
+ this->filename = filename;
+ this->netManager = netManager;
+
+ setWindowTitle(tr("Upload video"));
+
+ // Google requires us to display this, see https://developers.google.com/youtube/terms
+ QString GoogleNotice =
+ "By clicking 'upload,' you certify that you own all rights to the content or that\n"
+ "you are authorized by the owner to make the content publicly available on YouTube,\n"
+ "and that it otherwise complies with the YouTube Terms of Service located at\n"
+ "http://www.youtube.com/t/terms.";
+
+ QGridLayout * layout = new QGridLayout(this);
+
+ QLabel * lbLabel = new QLabel(this);
+ lbLabel->setText(QLabel::tr(
+ "Please provide either the YouTube account name\n"
+ "or the email address associated with the Google Account."));
+ layout->addWidget(lbLabel, 0, 0, 1, 2);
+
+ lbLabel = new QLabel(this);
+ lbLabel->setText(QLabel::tr("Account name (or email): "));
+ layout->addWidget(lbLabel, 1, 0);
+
+ leAccount = new QLineEdit(this);
+ layout->addWidget(leAccount, 1, 1);
+
+ lbLabel = new QLabel(this);
+ lbLabel->setText(QLabel::tr("Password: "));
+ layout->addWidget(lbLabel, 2, 0);
+
+ lePassword = new QLineEdit(this);
+ lePassword->setEchoMode(QLineEdit::Password);
+ layout->addWidget(lePassword, 2, 1);
+
+ cbSave = new QCheckBox(this);
+ cbSave->setText(QCheckBox::tr("Save account name and password"));
+ layout->addWidget(cbSave, 3, 0, 1, 2);
+
+ QFrame * hr = new QFrame(this);
+ hr->setFrameStyle(QFrame::HLine);
+ hr->setLineWidth(3);
+ hr->setFixedHeight(10);
+ layout->addWidget(hr, 4, 0, 1, 2);
+
+ lbLabel = new QLabel(this);
+ lbLabel->setText(QLabel::tr("Video title: "));
+ layout->addWidget(lbLabel, 5, 0);
+
+ leTitle = new QLineEdit(this);
+ leTitle->setText(filename);
+ layout->addWidget(leTitle, 5, 1);
+
+ lbLabel = new QLabel(this);
+ lbLabel->setText(QLabel::tr("Video description: "));
+ layout->addWidget(lbLabel, 6, 0, 1, 2);
+
+ teDescription = new QPlainTextEdit(this);
+ layout->addWidget(teDescription, 7, 0, 1, 2);
+
+ hr = new QFrame(this);
+ hr->setFrameStyle(QFrame::HLine);
+ hr->setLineWidth(3);
+ hr->setFixedHeight(10);
+ layout->addWidget(hr, 8, 0, 1, 2);
+
+ lbLabel = new QLabel(this);
+ lbLabel->setText(GoogleNotice);
+ layout->addWidget(lbLabel, 9, 0, 1, 2);
+
+ labelLog = new QLabel(this);
+ layout->addWidget(labelLog, 10, 0, 1, 2);
+
+ QDialogButtonBox* dbbButtons = new QDialogButtonBox(this);
+ btnUpload = dbbButtons->addButton(tr("Upload"), QDialogButtonBox::ActionRole);
+ QPushButton * pbCancel = dbbButtons->addButton(QDialogButtonBox::Cancel);
+ layout->addWidget(dbbButtons, 11, 0, 1, 2);
+
+ connect(btnUpload, SIGNAL(clicked()), this, SLOT(upload()));
+ connect(pbCancel, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+void HWUploadVideoDialog::log(const QString& text)
+{
+ labelLog->setText(labelLog->text() + text);
+}
+
+void HWUploadVideoDialog::setEditable(bool editable)
+{
+ leTitle->setEnabled(editable);
+ leAccount->setEnabled(editable);
+ lePassword->setEnabled(editable);
+ btnUpload->setEnabled(editable);
+}
+
+void HWUploadVideoDialog::upload()
+{
+ setEditable(false);
+
+ labelLog->clear();
+ log(tr("Authenticating at www.google.com... "));
+
+ // Documentation is at https://developers.google.com/youtube/2.0/developers_guide_protocol_clientlogin#ClientLogin_Authentication
+ QNetworkRequest request;
+ request.setUrl(QUrl("https://www.google.com/accounts/ClientLogin"));
+ request.setRawHeader("User-Agent", UserAgent);
+ request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
+
+ QString account(QUrl::toPercentEncoding(leAccount->text()));
+ QString pass(QUrl::toPercentEncoding(lePassword->text()));
+ QByteArray data = QString("Email=%1&Passwd=%2&service=youtube&source=Hedgewars").arg(account).arg(pass).toAscii();
+
+ QNetworkReply *reply = netManager->post(request, data);
+ connect(reply, SIGNAL(finished()), this, SLOT(authFinished()));
+}
+
+QString XmlEscape(const QString& str)
+{
+ QString str2 = str;
+ return "<![CDATA[" + str2.replace("]]>", "]]]]><![CDATA[>") + "]]>";
+}
+
+void HWUploadVideoDialog::authFinished()
+{
+ QNetworkReply *reply = (QNetworkReply*)sender();
+ reply->deleteLater();
+
+ QByteArray answer = reply->readAll();
+ QString authToken = "";
+ QList<QByteArray> lines = answer.split('\n');
+ foreach (const QByteArray& line, lines)
+ {
+ QString str(line);
+ if (!str.startsWith("Auth=", Qt::CaseInsensitive))
+ continue;
+ str.remove(0, 5);
+ authToken = str;
+ break;
+ }
+ if (authToken.isEmpty())
+ {
+ log(tr("failed\n"));
+ log(reply->errorString() + "\n");
+ setEditable(true);
+ return;
+ }
+ log(tr("Ok\n"));
+
+ log(tr("Sending metadata... "));
+
+ QByteArray auth = ("GoogleLogin auth=" + authToken).toAscii();
+
+ // We have authenticated, now we can send metadata and start upload
+ // Documentation is here: https://developers.google.com/youtube/2.0/developers_guide_protocol_resumable_uploads#Resumable_uploads
+ QByteArray body =
+ "<?xml version=\"1.0\"?>"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\" "
+ "xmlns:media=\"http://search.yahoo.com/mrss/\" "
+ "xmlns:yt=\"http://gdata.youtube.com/schemas/2007\">"
+ "<media:group>"
+ "<yt:incomplete/>"
+ "<media:category "
+ "scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\">Games"
+ "</media:category>"
+ "<media:title type=\"plain\">"
+ + XmlEscape(leTitle->text()).toUtf8() +
+ "</media:title>"
+ "</media:group>"
+ "</entry>";
+
+ QNetworkRequest request;
+ request.setUrl(QUrl("http://uploads.gdata.youtube.com/resumable/feeds/api/users/default/uploads"));
+ request.setRawHeader("User-Agent", UserAgent);
+ request.setRawHeader("Authorization", auth);
+ request.setRawHeader("GData-Version", "2");
+ request.setRawHeader("X-GData-Key", "key=" + devKey);
+ request.setRawHeader("Slug", filename.toUtf8());
+ request.setRawHeader("Content-Type", "application/atom+xml; charset=UTF-8");
+
+ reply = netManager->post(request, body);
+ connect(reply, SIGNAL(finished()), this, SLOT(startUpload()));
+}
+
+void HWUploadVideoDialog::startUpload()
+{
+ QNetworkReply *reply = (QNetworkReply*)sender();
+ reply->deleteLater();
+
+ location = QString::fromAscii(reply->rawHeader("Location"));
+ if (location.isEmpty())
+ {
+ log(tr("failed\n"));
+ log(reply->errorString() + "\n");
+ setEditable(true);
+ return;
+ }
+
+ log(tr("Ok\n"));
+ accept();
+}