diff -r 13fa53bb3134 -r 01b599d6f72d QTfrontend/ui/dialog/upload_video.cpp --- a/QTfrontend/ui/dialog/upload_video.cpp Thu Aug 30 22:41:22 2012 +0400 +++ b/QTfrontend/ui/dialog/upload_video.cpp Thu Aug 30 20:42:29 2012 +0200 @@ -1,297 +1,297 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2012 Andrey Korotaev - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "upload_video.h" -#include "hwconsts.h" - -// User-agent string used in http requests. -// Don't make it a global varibale - crash on linux because of cVersionString -#define USER_AGENT ("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 " - "you are authorized by the owner to make the content publicly available on YouTube, " - "and that it otherwise complies with the YouTube Terms of Service located at " - "http://www.youtube.com/t/terms.

"; - - // youtube doesn't understand this characters, even when they are properly escaped - // (either with CDATA or with < or >) - QRegExp rx("[^<>]*"); - - int row = 0; - - QGridLayout * layout = new QGridLayout(this); - layout->setColumnStretch(0, 1); - layout->setColumnStretch(1, 2); - - QLabel * lbLabel = new QLabel(this); - lbLabel->setWordWrap(true); - lbLabel->setText(QLabel::tr( - "Please provide either the YouTube account name " - "or the email address associated with the Google Account.")); - layout->addWidget(lbLabel, row++, 0, 1, 2); - - lbLabel = new QLabel(this); - lbLabel->setText(QLabel::tr("Account name (or email): ")); - layout->addWidget(lbLabel, row, 0); - - leAccount = new QLineEdit(this); - layout->addWidget(leAccount, row++, 1); - - lbLabel = new QLabel(this); - lbLabel->setText(QLabel::tr("Password: ")); - layout->addWidget(lbLabel, row, 0); - - lePassword = new QLineEdit(this); - lePassword->setEchoMode(QLineEdit::Password); - layout->addWidget(lePassword, row++, 1); - - cbSave = new QCheckBox(this); - cbSave->setText(QCheckBox::tr("Save account name and password")); - layout->addWidget(cbSave, row++, 0, 1, 2); - - QFrame * hr = new QFrame(this); - hr->setFrameStyle(QFrame::HLine); - hr->setLineWidth(3); - hr->setFixedHeight(10); - layout->addWidget(hr, row++, 0, 1, 2); - - lbLabel = new QLabel(this); - lbLabel->setText(QLabel::tr("Video title: ")); - layout->addWidget(lbLabel, row, 0); - - leTitle = new QLineEdit(this); - leTitle->setText(filename); - leTitle->setValidator(new QRegExpValidator(rx, leTitle)); - layout->addWidget(leTitle, row++, 1); - - lbLabel = new QLabel(this); - lbLabel->setText(QLabel::tr("Video description: ")); - layout->addWidget(lbLabel, row++, 0, 1, 2); - - teDescription = new QPlainTextEdit(this); - layout->addWidget(teDescription, row++, 0, 1, 2); - - lbLabel = new QLabel(this); - lbLabel->setText(QLabel::tr("Tags (comma separated): ")); - layout->addWidget(lbLabel, row, 0); - - leTags = new QLineEdit(this); - leTags->setText("hedgewars"); - leTags->setMaxLength(500); - leTags->setValidator(new QRegExpValidator(rx, leTags)); - layout->addWidget(leTags, row++, 1); - - cbPrivate = new QCheckBox(this); - cbPrivate->setText(QCheckBox::tr("Video is private")); - layout->addWidget(cbPrivate, row++, 0, 1, 2); - - hr = new QFrame(this); - hr->setFrameStyle(QFrame::HLine); - hr->setLineWidth(3); - hr->setFixedHeight(10); - layout->addWidget(hr, row++, 0, 1, 2); - - lbLabel = new QLabel(this); - lbLabel->setWordWrap(true); - lbLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse); - lbLabel->setTextFormat(Qt::RichText); - lbLabel->setOpenExternalLinks(true); - lbLabel->setText(GoogleNotice); - layout->addWidget(lbLabel, row++, 0, 1, 2); - - QDialogButtonBox* dbbButtons = new QDialogButtonBox(this); - btnUpload = dbbButtons->addButton(tr("Upload"), QDialogButtonBox::ActionRole); - QPushButton * pbCancel = dbbButtons->addButton(QDialogButtonBox::Cancel); - layout->addWidget(dbbButtons, row++, 0, 1, 2); - - /* hr = new QFrame(this); - hr->setFrameStyle(QFrame::HLine); - hr->setLineWidth(3); - hr->setFixedHeight(10); - layout->addWidget(hr, row++, 0, 1, 2);*/ - - connect(btnUpload, SIGNAL(clicked()), this, SLOT(upload())); - connect(pbCancel, SIGNAL(clicked()), this, SLOT(reject())); -} - -void HWUploadVideoDialog::showEvent(QShowEvent * event) -{ - QDialog::showEvent(event); - - // set width to the same value as height (otherwise dialog has too small width) - QSize s = size(); - QPoint p = pos(); - resize(s.height(), s.height()); - move(p.x() - (s.height() - s.width())/2, p.y()); -} - -void HWUploadVideoDialog::setEditable(bool editable) -{ - leTitle->setEnabled(editable); - leAccount->setEnabled(editable); - lePassword->setEnabled(editable); - btnUpload->setEnabled(editable); -} - -void HWUploadVideoDialog::upload() -{ - setEditable(false); - - // 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", USER_AGENT); - 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())); -} - -static QString XmlEscape(const QString& str) -{ - QString str2 = str; - // youtube doesn't understand this characters, even when they are properly escaped - // (either with CDATA or with < >) - str2.replace('<', ' ').replace('>', ' '); - return "", "]]]]>") + "]]>"; -} - -void HWUploadVideoDialog::authFinished() -{ - QNetworkReply *reply = (QNetworkReply*)sender(); - reply->deleteLater(); - - int HttpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - - QByteArray answer = reply->readAll(); - QString authToken = ""; - QList 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()) - { - QString errorStr = QMessageBox::tr("Error while authenticating at google.com:\n"); - if (HttpCode == 403) - errorStr += QMessageBox::tr("Login or password is incorrect"); - else - errorStr += reply->errorString(); - QMessageBox::warning(this, QMessageBox::tr("Error"), errorStr); - setEditable(true); - return; - } - - 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 = - "" - "" - "" - // "" - "Games" - "" - "" - + XmlEscape(leTitle->text()).toUtf8() + - "" - "" - + XmlEscape(teDescription->toPlainText()).toUtf8() + - "" - "" - + XmlEscape(leTags->text()).toUtf8() + - "" - + (cbPrivate->isChecked()? "" : "") + - "" - ""; - - QNetworkRequest request; - request.setUrl(QUrl("http://uploads.gdata.youtube.com/resumable/feeds/api/users/default/uploads")); - request.setRawHeader("User-Agent", USER_AGENT); - 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()) - { - QString errorStr = QMessageBox::tr("Error while sending metadata to youtube.com:\n"); - errorStr += reply->errorString(); - QMessageBox::warning(this, QMessageBox::tr("Error"), errorStr); - setEditable(true); - return; - } - - accept(); -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "upload_video.h" +#include "hwconsts.h" + +// User-agent string used in http requests. +// Don't make it a global varibale - crash on linux because of cVersionString +#define USER_AGENT ("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 " + "you are authorized by the owner to make the content publicly available on YouTube, " + "and that it otherwise complies with the YouTube Terms of Service located at " + "http://www.youtube.com/t/terms.

"; + + // youtube doesn't understand this characters, even when they are properly escaped + // (either with CDATA or with < or >) + QRegExp rx("[^<>]*"); + + int row = 0; + + QGridLayout * layout = new QGridLayout(this); + layout->setColumnStretch(0, 1); + layout->setColumnStretch(1, 2); + + QLabel * lbLabel = new QLabel(this); + lbLabel->setWordWrap(true); + lbLabel->setText(QLabel::tr( + "Please provide either the YouTube account name " + "or the email address associated with the Google Account.")); + layout->addWidget(lbLabel, row++, 0, 1, 2); + + lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr("Account name (or email): ")); + layout->addWidget(lbLabel, row, 0); + + leAccount = new QLineEdit(this); + layout->addWidget(leAccount, row++, 1); + + lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr("Password: ")); + layout->addWidget(lbLabel, row, 0); + + lePassword = new QLineEdit(this); + lePassword->setEchoMode(QLineEdit::Password); + layout->addWidget(lePassword, row++, 1); + + cbSave = new QCheckBox(this); + cbSave->setText(QCheckBox::tr("Save account name and password")); + layout->addWidget(cbSave, row++, 0, 1, 2); + + QFrame * hr = new QFrame(this); + hr->setFrameStyle(QFrame::HLine); + hr->setLineWidth(3); + hr->setFixedHeight(10); + layout->addWidget(hr, row++, 0, 1, 2); + + lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr("Video title: ")); + layout->addWidget(lbLabel, row, 0); + + leTitle = new QLineEdit(this); + leTitle->setText(filename); + leTitle->setValidator(new QRegExpValidator(rx, leTitle)); + layout->addWidget(leTitle, row++, 1); + + lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr("Video description: ")); + layout->addWidget(lbLabel, row++, 0, 1, 2); + + teDescription = new QPlainTextEdit(this); + layout->addWidget(teDescription, row++, 0, 1, 2); + + lbLabel = new QLabel(this); + lbLabel->setText(QLabel::tr("Tags (comma separated): ")); + layout->addWidget(lbLabel, row, 0); + + leTags = new QLineEdit(this); + leTags->setText("hedgewars"); + leTags->setMaxLength(500); + leTags->setValidator(new QRegExpValidator(rx, leTags)); + layout->addWidget(leTags, row++, 1); + + cbPrivate = new QCheckBox(this); + cbPrivate->setText(QCheckBox::tr("Video is private")); + layout->addWidget(cbPrivate, row++, 0, 1, 2); + + hr = new QFrame(this); + hr->setFrameStyle(QFrame::HLine); + hr->setLineWidth(3); + hr->setFixedHeight(10); + layout->addWidget(hr, row++, 0, 1, 2); + + lbLabel = new QLabel(this); + lbLabel->setWordWrap(true); + lbLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse); + lbLabel->setTextFormat(Qt::RichText); + lbLabel->setOpenExternalLinks(true); + lbLabel->setText(GoogleNotice); + layout->addWidget(lbLabel, row++, 0, 1, 2); + + QDialogButtonBox* dbbButtons = new QDialogButtonBox(this); + btnUpload = dbbButtons->addButton(tr("Upload"), QDialogButtonBox::ActionRole); + QPushButton * pbCancel = dbbButtons->addButton(QDialogButtonBox::Cancel); + layout->addWidget(dbbButtons, row++, 0, 1, 2); + + /* hr = new QFrame(this); + hr->setFrameStyle(QFrame::HLine); + hr->setLineWidth(3); + hr->setFixedHeight(10); + layout->addWidget(hr, row++, 0, 1, 2);*/ + + connect(btnUpload, SIGNAL(clicked()), this, SLOT(upload())); + connect(pbCancel, SIGNAL(clicked()), this, SLOT(reject())); +} + +void HWUploadVideoDialog::showEvent(QShowEvent * event) +{ + QDialog::showEvent(event); + + // set width to the same value as height (otherwise dialog has too small width) + QSize s = size(); + QPoint p = pos(); + resize(s.height(), s.height()); + move(p.x() - (s.height() - s.width())/2, p.y()); +} + +void HWUploadVideoDialog::setEditable(bool editable) +{ + leTitle->setEnabled(editable); + leAccount->setEnabled(editable); + lePassword->setEnabled(editable); + btnUpload->setEnabled(editable); +} + +void HWUploadVideoDialog::upload() +{ + setEditable(false); + + // 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", USER_AGENT); + 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())); +} + +static QString XmlEscape(const QString& str) +{ + QString str2 = str; + // youtube doesn't understand this characters, even when they are properly escaped + // (either with CDATA or with < >) + str2.replace('<', ' ').replace('>', ' '); + return "", "]]]]>") + "]]>"; +} + +void HWUploadVideoDialog::authFinished() +{ + QNetworkReply *reply = (QNetworkReply*)sender(); + reply->deleteLater(); + + int HttpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + QByteArray answer = reply->readAll(); + QString authToken = ""; + QList 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()) + { + QString errorStr = QMessageBox::tr("Error while authenticating at google.com:\n"); + if (HttpCode == 403) + errorStr += QMessageBox::tr("Login or password is incorrect"); + else + errorStr += reply->errorString(); + QMessageBox::warning(this, QMessageBox::tr("Error"), errorStr); + setEditable(true); + return; + } + + 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 = + "" + "" + "" + // "" + "Games" + "" + "" + + XmlEscape(leTitle->text()).toUtf8() + + "" + "" + + XmlEscape(teDescription->toPlainText()).toUtf8() + + "" + "" + + XmlEscape(leTags->text()).toUtf8() + + "" + + (cbPrivate->isChecked()? "" : "") + + "" + ""; + + QNetworkRequest request; + request.setUrl(QUrl("http://uploads.gdata.youtube.com/resumable/feeds/api/users/default/uploads")); + request.setRawHeader("User-Agent", USER_AGENT); + 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()) + { + QString errorStr = QMessageBox::tr("Error while sending metadata to youtube.com:\n"); + errorStr += reply->errorString(); + QMessageBox::warning(this, QMessageBox::tr("Error"), errorStr); + setEditable(true); + return; + } + + accept(); +}