void ScreenCloudUploader::replyFinished(QNetworkReply *reply)
{
    QString replyText = reply->readAll();
    INFO(replyText);
    if(reply->error() != QNetworkReply::NoError)
    {
        //There was an error
        QDomDocument doc("error");
        if (!doc.setContent(replyText)) {
            emit uploadingError("Failed to parse response from server");
            return;
        }
        QDomElement docElem = doc.documentElement();
        QDomElement message = docElem.firstChildElement("message");
        emit uploadingError(message.text());
    }else
    {
        //No errors
        QDomDocument doc("reply");
        if (!doc.setContent(replyText)) {
            emit uploadingError("Failed to parse response from server");
            return;
        }
        QDomElement docElem = doc.documentElement();
        QDomElement url = docElem.firstChildElement("url");

        emit uploadingFinished(url.text());
        emit finished();
    }
    buffer->close();
    bufferArray.clear();
}
void FileUploader::upload(QImage *screenshot)
{
    if(dateTimeAsPrefix)
    {
        prefix = QDateTime::currentDateTime().toString(dateTimeFormatPrefix);
    }
    if(dateTimeAsSuffix)
    {
        suffix = QDateTime::currentDateTime().toString(dateTimeFormatSuffix);
    }
    if(!filenameSetExternally)
    {
        filename = validateFilename(prefix + screenshotName + suffix + QString(".") + format);
    }
    QString fullFilePath = uploadPath + QDir::separator() + filename;
    qDebug() << "Saving screenshot to file: " << fullFilePath;
    QFileInfo fileInfo(uploadPath);
    if(!fileInfo.permission(QFile::WriteUser) || !QDir(uploadPath).exists())
    {
        qDebug() << "No write permissions, or directory does not exist. Popping open a file dialog";
        uploadPath = openDirectoryBrowser(uploadPath); //Probably in sandbox, pop open a diretory dialog
        if(uploadPath.isEmpty())
        {
            emit uploadingError("Failed to save screenshot. No directory selected.");
            return;
        }
        fullFilePath = uploadPath + QDir::separator() + filename;
        //Save the new path
        QSettings settings("screencloud", "ScreenCloud");
        settings.beginGroup("uploaders");
        settings.beginGroup(shortname);
        settings.setValue("path", uploadPath);
        settings.endGroup();
        settings.endGroup();
    }
    if(format == "jpg")
    {
        if(!screenshot->save(fullFilePath, format.toAscii(), jpegQuality))
        {
            emit uploadingError("Failed to save screenshot to file. Please make sure that your account has write permissions to " + uploadPath);
        }
    }else
    {
        if(!screenshot->save(fullFilePath, format.toAscii()))
        {
                emit uploadingError("Failed to save screenshot to file. Please make sure that your account has write permissions to " + uploadPath);
        }
    }
    emit uploadingFinished("");

}
void PythonUploader::upload(const QImage &screenshot, QString name)
{
    connect(PythonQt::self(), SIGNAL(pythonStdErr(QString)), this, SLOT(pythonError(QString)));
    QVariantList args;
    args << screenshot;
    args << name;
    QVariant result = pythonContext.call(shortname + "_u.upload", args);
    if(hadPythonErr)
    {
        PythonQt::self()->handleError();
        WARNING("Failed to call upload() in " + this->className);
        emit uploadingError("Failed to call " + this->className + ".upload()" + "\n" + lastPythonErr);
        lastPythonErr.clear();
        hadPythonErr = false;
        disconnect(PythonQt::self(), SIGNAL(pythonStdErr(QString)), this, SLOT(pythonError(QString)));
        return;
    }
    bool success = result.toBool();
    if(success)
    {
        QString url = moduleObj.getVariable("ScreenCloud.clipboardUrl").toString();
        emit uploadingFinished(url);
    }else
    {
        QString errorString = moduleObj.getVariable("ScreenCloud.uploadingError").toString();
        if(errorString.isEmpty())
        {
            errorString = tr("Unknown error");
        }
        emit uploadingError(errorString);
    }
    //Clean up
    disconnect(PythonQt::self(), SIGNAL(pythonStdErr(QString)), this, SLOT(pythonError(QString)));
    moduleObj.evalScript("ScreenCloud.clipboardUrl = None");
    moduleObj.evalScript("ScreenCloud.uploadingError = None");
    emit finished();
}
void SystemTrayIcon::screenshotSavingError(QString errorMessage)
{
    setIcon(systrayIconNormal);
    uploading = false;

    QMessageBox msgBox;
    msgBox.setWindowTitle("ScreenCloud upload");
    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setText(activeUploader->getName() + " upload failed!\nError was: " + errorMessage);
    msgBox.exec();

    //Disconnect slots
    disconnect(activeUploader, SIGNAL(uploadingFinished(QString)), this, SLOT(screenshotSaved(QString)));
    disconnect(activeUploader, SIGNAL(uploadingError(QString)), this, SLOT(screenshotSavingError(QString)));
}
void SystemTrayIcon::screenshotSaved(QString url)
{
    setIcon(systrayIconNormal);
    uploading = false;
    //Disconnect slots
    disconnect(activeUploader, SIGNAL(uploadingFinished(QString)), this, SLOT(screenshotSaved(QString)));
    disconnect(activeUploader, SIGNAL(uploadingError(QString)), this, SLOT(screenshotSavingError(QString)));
    if(!url.isEmpty())
    {
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(url);
        if(showNotifications)
        {
            showMessage("Upload finished", activeUploader->getFilename() + " was saved. Link copied to clipboard");
        }
    }else
    {
        if(showNotifications)
        {
            showMessage("Upload finished", activeUploader->getFilename() + " was saved!");
        }
    }
    notifier.play("sfx/notification.wav");
}
void SystemTrayIcon::saveScreenshot(QPixmap* screenshot)
{
    loadSettings();
    if(activeUploaderIndex == -1 || activeUploaderIndex >= uploaders.size())
    {
        //Ask me
        showSaveDialog = true;
    }else
    {
        showSaveDialog = false;
    }
    QString name;
    if(showSaveDialog)
    {
        SaveScreenshotDialog save(0, screenshot, &uploaders, activeUploader);
        int selection = save.exec();
        if(selection == QMessageBox::Accepted)
        {
            activeUploader = uploaders.at(save.getUploaderIndex());
            name = save.getName();
        }else
        {
            activeUploader = NULL;
        }

    }else
    {
        if(activeUploaderIndex > -1 && activeUploaderIndex < uploaders.size())
        {
            activeUploader = uploaders.at(activeUploaderIndex);
        }else
        {
            qDebug() << "activeUploaderIndex >= uploaders.size()";
        }
    }
    loadSettings();
    updateSystrayMenu();
    //Upload
    if(activeUploader != NULL && !uploading)
    {
        uploading = true;
        //Set the uploading trayicon
        setIcon(systrayIconUploading);
        show();
        if(screenshot->isNull())
        {
            QMessageBox msgBox;
            msgBox.setIcon(QMessageBox::Critical);
            msgBox.setText("Failed to take screenshot :(");
            msgBox.exec();
        }
        connect(activeUploader, SIGNAL(uploadingFinished(QString)), this, SLOT(screenshotSaved(QString)));
        connect(activeUploader, SIGNAL(uploadingError(QString)), this, SLOT(screenshotSavingError(QString)));
        QImage img = screenshot->toImage();
        activeUploader->loadSettings();
        if(!name.isEmpty())
        {
            activeUploader->setFilename(name);
        }
        activeUploader->upload(&img);
    }

}
void ScreenCloudUploader::upload(const QImage &screenshot, QString name)
{
    loadSettings();
    //Save to a buffer
    buffer->open(QIODevice::WriteOnly);
    if(format == "jpg")
    {
        if(!screenshot.save(buffer, format.toLatin1(), jpegQuality))
        {
            emit uploadingError("Failed to save screenshot to buffer. Format=" + format);
        }
    }else
    {
        if(!screenshot.save(buffer, format.toLatin1()))
        {
                emit uploadingError("Failed to save screenshot to buffer. Format=" + format);
        }
    }
    //Upload to screencloud
    QUrl url( "https://api.screencloud.net/1.0/screenshots/upload.xml" );

    // create request parameters
    url.addQueryItem( "name", QUrl::toPercentEncoding(name) );
    url.addQueryItem( "description", QUrl::toPercentEncoding("Taken on " + QDate::currentDate().toString("yyyy-MM-dd") + " at " + QTime::currentTime().toString("hh:mm") + " with the " + OPERATING_SYSTEM + " version of ScreenCloud") );
    url.addQueryItem("oauth_version", "1.0");
    url.addQueryItem("oauth_signature_method", "PLAINTEXT");
    url.addQueryItem("oauth_token", token);
    url.addQueryItem("oauth_consumer_key", CONSUMER_KEY_SCREENCLOUD);
    url.addQueryItem("oauth_signature", CONSUMER_SECRET_SCREENCLOUD + QString("&") + tokenSecret);
    url.addQueryItem("oauth_timestamp", QString::number(QDateTime::currentDateTimeUtc().toTime_t()));
    url.addQueryItem("oauth_nonce", NetworkUtils::generateNonce(15));

    QString mimetype = "image/" + format;
    if(format == "jpg")
    {
        mimetype = "image/jpeg";
    }
    //Add post file
    QString boundaryData = QVariant(qrand()).toString()+QVariant(qrand()).toString()+QVariant(qrand()).toString();
    QByteArray boundary;

    boundary="-----------------------------" + boundaryData.toLatin1();

    QByteArray body = "\r\n--" + boundary + "\r\n";

    //Name
    body += "Content-Disposition: form-data; name=\"name\"\r\n\r\n";
    body += QUrl::toPercentEncoding(name) + "\r\n";

    body += QString("--" + boundary + "\r\n").toLatin1();
    body += "Content-Disposition: form-data; name=\"description\"\r\n\r\n";
    body += QUrl::toPercentEncoding("Taken on " + QDate::currentDate().toString("yyyy-MM-dd") + " at " + QTime::currentTime().toString("hh:mm") + " with the " + OPERATING_SYSTEM + " version of ScreenCloud") + "\r\n";

    body += QString("--" + boundary + "\r\n").toLatin1();
    body += "Content-Disposition: form-data; name=\"file\"; filename=\" " + QUrl::toPercentEncoding(name + boundary + "." + format) + "\"\r\n";
    body += "Content-Type: " + mimetype + "\r\n\r\n";
    body += bufferArray;

    body += "\r\n--" + boundary + "--\r\n";

    QNetworkRequest request;
    request.setUrl(QUrl(url));
    request.setRawHeader("Content-Type","multipart/form-data; boundary=" + boundary);
    request.setHeader(QNetworkRequest::ContentLengthHeader,body.size());
    manager->post(request, body);
}
void ScreencloudUploader::upload(QImage *screenshot)
{
    //Save to a buffer
    buffer = new QBuffer(&bufferArray, this);
    buffer->open(QIODevice::WriteOnly);
    if(format == "jpg")
    {
        if(!screenshot->save(buffer, format.toAscii(), jpegQuality))
        {
            emit uploadingError("Failed to save screenshot to " + QDir::tempPath());
        }
    }else
    {
        if(!screenshot->save(buffer, format.toAscii()))
        {
                emit uploadingError("Failed to save screenshot to " + QDir::tempPath());
        }
    }
    //Upload to screencloud
    QOAuth::Interface *qoauth = new QOAuth::Interface;
    qoauth->setConsumerKey(CONSUMER_KEY_SCREENCLOUD);
    qoauth->setConsumerSecret(CONSUMER_SECRET_SCREENCLOUD);
    QByteArray url( "http://screencloud.net/1.0/screenshots/upload.xml" );

    // create a request parameters map
    QOAuth::ParamMap map;
    map.insert( "name", QUrl::toPercentEncoding(screenshotName) );
    map.insert( "description", QUrl::toPercentEncoding("Taken on " + QDate::currentDate().toString("yyyy-MM-dd") + " at " + QTime::currentTime().toString("hh:mm") + " with the " + OPERATING_SYSTEM + " version of ScreenCloud") );

    QString mimetype = "image/" + format;
    if(format == "jpg")
    {
        mimetype = "image/jpeg";
    }
    QByteArray header =
    qoauth->createParametersString( uploadUrl, QOAuth::POST,
                                        token, tokenSecret,QOAuth::HMAC_SHA1, map,
                                        QOAuth::ParseForHeaderArguments );
    //Add post file
    QString boundaryData = QVariant(qrand()).toString()+QVariant(qrand()).toString()+QVariant(qrand()).toString();
    QByteArray boundary;
    QByteArray dataToSend; // byte array to be sent in POST

    boundary="-----------------------------" + boundaryData.toAscii();

    QByteArray body = "\r\n--" + boundary + "\r\n";

    //Name
    body += "Content-Disposition: form-data; name=\"name\"\r\n\r\n";
    body += QUrl::toPercentEncoding(screenshotName) + "\r\n";

    body += QString("--" + boundary + "\r\n").toAscii();
    body += "Content-Disposition: form-data; name=\"description\"\r\n\r\n";
    body += QUrl::toPercentEncoding("Taken on " + QDate::currentDate().toString("yyyy-MM-dd") + " at " + QTime::currentTime().toString("hh:mm") + " with the " + OPERATING_SYSTEM + " version of ScreenCloud") + "\r\n";

    body += QString("--" + boundary + "\r\n").toAscii();
    body += "Content-Disposition: form-data; name=\"file\"; filename=\" " + QUrl::toPercentEncoding(screenshotName + boundary + "." + format) + "\"\r\n";
    body += "Content-Type: " + mimetype + "\r\n\r\n";
    body += bufferArray;

    body += "\r\n--" + boundary + "--\r\n";

    url.append( qoauth->inlineParameters( map, QOAuth::ParseForInlineQuery ) );
    qDebug() << url;
    QNetworkRequest request;
    request.setUrl(QUrl(url));
    request.setRawHeader( "Authorization", header );
    request.setRawHeader("Content-Type","multipart/form-data; boundary=" + boundary);
    request.setHeader(QNetworkRequest::ContentLengthHeader,body.size());
    manager->post(request, body);
}