323 lines
11 KiB
C++
323 lines
11 KiB
C++
/*
|
|
blueROCK - for digital rock
|
|
Copyright (C) 2019 Dorian Zedler
|
|
|
|
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 3 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 program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "headers/bluerockbackend.h"
|
|
|
|
BlueRockBackend::BlueRockBackend(QObject *parent) : QObject(parent), _pendingIntentsChecked(false)
|
|
{
|
|
this->_shareUtils = new ShareUtils(this);
|
|
connect(this->_shareUtils, &ShareUtils::otherUrlReceived, this, &BlueRockBackend::openedViaUrl);
|
|
|
|
#if defined(Q_OS_ANDROID)
|
|
connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onApplicationStateChanged(Qt::ApplicationState)));
|
|
#elif defined Q_OS_IOS
|
|
this->_iosPermissionUtils = new IosPermissionUtils();
|
|
#endif
|
|
}
|
|
|
|
QVariant BlueRockBackend::getWidgetData(QVariantMap params) {
|
|
QString requestUrl = "https://www.digitalrock.de/egroupware/ranking/json.php?";
|
|
QStringList nations = {"ICC", "GER", "SUI"};
|
|
if(params["nation"].toString() == "ICC") {
|
|
params["nation"] = "";
|
|
}
|
|
else if(params["nation"].toString() == "") {
|
|
params.remove("nation");
|
|
}
|
|
else if(!nations.contains(params["nation"].toString())) {
|
|
// a non-empty nation which ist not one of the above is invalid
|
|
return QVariantMap({{"status", 404}});
|
|
}
|
|
|
|
for(QVariantMap::const_iterator iter = params.begin(); iter != params.end(); ++iter) {
|
|
requestUrl += iter.key() + "=" + iter.value().toString() + "&";
|
|
}
|
|
|
|
requestUrl = requestUrl.left(requestUrl.length() - 1); // remove last '&'
|
|
|
|
qWarning() << requestUrl;
|
|
|
|
QVariantMap ret = this->_senddata(QUrl(requestUrl));
|
|
|
|
if(ret["status"] != 200) {
|
|
// request was a failure
|
|
return QVariantMap({{"status", ret["status"]}, {"data", ""}});
|
|
}
|
|
|
|
QJsonDocument jsonReply = QJsonDocument::fromJson(ret["text"].toString().toUtf8());
|
|
|
|
QVariantMap data = {{"status", 200}, {"data", jsonReply.toVariant()}};
|
|
|
|
return data;
|
|
}
|
|
|
|
|
|
QVariantMap BlueRockBackend::getParamsFromUrl(QString stringUrl) {
|
|
stringUrl = stringUrl.replace("#!", "?");
|
|
QUrl url(stringUrl);
|
|
|
|
if(!url.isValid() || url.isEmpty() || url.host().isEmpty())
|
|
return {{"valid", false},{"params", QVariantMap()}} ;
|
|
|
|
QStringList domainFragments = url.host().split(".");
|
|
QString tld = domainFragments.takeLast();
|
|
QString domainName = domainFragments.takeLast();
|
|
QString baseDomain = domainName + "." + tld;
|
|
|
|
if(!this->_validBaseDomains.contains(baseDomain))
|
|
return {{"valid", false},{"params", QVariantMap()}};
|
|
|
|
QUrlQuery query(url.query());
|
|
|
|
QVariantMap params;
|
|
|
|
for(QPair<QString, QString> pair : query.queryItems()) {
|
|
if(params.contains(pair.first))
|
|
params[pair.first] = pair.second;
|
|
else
|
|
params.insert(pair.first, pair.second);
|
|
}
|
|
|
|
return {{"valid", true},{"params",params}};
|
|
}
|
|
|
|
void BlueRockBackend::shareResultsAsUrl(QString url, QString compName) {
|
|
//% "Check out the results of %1 over here:"
|
|
this->_shareUtils->shareText(qtTrId("#shareResultsLinkText").arg(compName) + " \n", url);
|
|
}
|
|
|
|
void BlueRockBackend::shareResultsAsPoster(QString url, QString compName) {
|
|
QString path = this->_shareUtils->getTemporaryFileLocationPath(); //QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
|
|
if (!QDir(path).exists()) {
|
|
if (QDir("").mkpath(path)) {
|
|
qDebug() << "Created app data /files directory. " << path;
|
|
} else {
|
|
qWarning() << "Failed to create app data /files directory. " << path;
|
|
return;
|
|
}
|
|
}
|
|
|
|
QString rawCompName = compName;
|
|
QString escapedCompName = compName.replace("/", " ");
|
|
path += "/" + escapedCompName + ".pdf";
|
|
|
|
QFile file(path);
|
|
file.remove();
|
|
if(!file.open(QIODevice::ReadWrite)) {
|
|
qWarning("Could not open File for writing!!");
|
|
return;
|
|
}
|
|
|
|
// dimensions
|
|
QRect qrCodeRect = QRect(414, 414, 1650, 1650);
|
|
|
|
int compNameTextLineHeight = 64;
|
|
QFont compNameTextFont("OpenSans-Light");
|
|
compNameTextFont.setPixelSize(compNameTextLineHeight);
|
|
QRect compNameTextRect = QRect(
|
|
324,
|
|
2500,
|
|
1835,
|
|
150
|
|
);
|
|
|
|
QPdfWriter writer(&file);
|
|
writer.setPageSize(QPageSize(QPageSize::A4));
|
|
writer.setPageMargins(QMargins(0, 0, 0, 0));
|
|
writer.setResolution(300);
|
|
|
|
QPainter painter(&writer);
|
|
QPixmap posterTemplate(":/PosterTemplate.png");
|
|
painter.drawPixmap(0,0, writer.width(), writer.height(), posterTemplate);
|
|
|
|
QPixmap barcode;
|
|
QZXingEncoderConfig encoderConfig(QZXing::EncoderFormat_QR_CODE, qrCodeRect.size(), QZXing::EncodeErrorCorrectionLevel_H, false, false);
|
|
barcode.convertFromImage(QZXing::encodeData(url, encoderConfig));
|
|
painter.drawPixmap(qrCodeRect, barcode);
|
|
|
|
painter.setFont(compNameTextFont);
|
|
painter.setPen(Qt::black);
|
|
painter.drawText(compNameTextRect, Qt::AlignLeft|Qt::AlignBottom|Qt::TextWordWrap, rawCompName);
|
|
|
|
painter.end();
|
|
file.close();
|
|
|
|
this->_shareUtils->sendFile(path, escapedCompName, "application/pdf", 1);
|
|
}
|
|
|
|
bool BlueRockBackend::isCameraPermissionGranted() {
|
|
#ifdef Q_OS_ANDROID
|
|
QtAndroid::PermissionResult cameraAccess = QtAndroid::checkPermission("android.permission.CAMERA");
|
|
return cameraAccess == QtAndroid::PermissionResult::Granted;
|
|
#elif defined Q_OS_IOS
|
|
return this->_iosPermissionUtils->isCameraPermissionGranted();
|
|
#else
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
bool BlueRockBackend::requestCameraPermission() {
|
|
if(this->isCameraPermissionGranted())
|
|
return true;
|
|
|
|
#ifdef Q_OS_ANDROID
|
|
// try to get permission
|
|
QtAndroid::PermissionResultMap resultMap = QtAndroid::requestPermissionsSync({"android.permission.CAMERA"});
|
|
bool resultBool = true;
|
|
for(QtAndroid::PermissionResult result : resultMap) {
|
|
if(result != QtAndroid::PermissionResult::Granted) {
|
|
resultBool = false;
|
|
}
|
|
}
|
|
|
|
if(resultBool) {
|
|
return true;
|
|
}
|
|
|
|
// getting permission the traditional way failed -> open the settings app
|
|
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
|
|
if (activity.isValid())
|
|
{
|
|
// get the package name
|
|
QAndroidJniObject context = QtAndroid::androidContext();
|
|
QAndroidJniObject applicationPackageName = context.callObjectMethod<jstring>("getPackageName");
|
|
|
|
QAndroidJniObject param = QAndroidJniObject::fromString("package:" + applicationPackageName.toString());
|
|
|
|
// Equivalent to Jave code: 'Uri uri = Uri::parse("...");'
|
|
QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", param.object<jstring>());
|
|
if (!uri.isValid()) {
|
|
qWarning("ERROR: Unable to create Uri object");
|
|
return false;
|
|
}
|
|
QAndroidJniObject packageName = QAndroidJniObject::fromString("android.settings.APPLICATION_DETAILS_SETTINGS");
|
|
|
|
QAndroidJniObject intent("android/content/Intent","(Ljava/lang/String;)V", packageName.object<jstring>());
|
|
if (!intent.isValid()) {
|
|
qWarning("ERROR: Unable to create Intent object");
|
|
return false;
|
|
}
|
|
intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("android.intent.category.DEFAULT").object<jstring>());
|
|
intent.callObjectMethod("setData", "(Landroid/net/Uri;)Landroid/content/Intent;", uri.object<jobject>());
|
|
|
|
activity.callMethod<void>("startActivity","(Landroid/content/Intent;)V",intent.object<jobject>());
|
|
}
|
|
else {
|
|
qWarning() << "ERROR: Activity not valid!";
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
#elif defined Q_OS_IOS
|
|
return this->_iosPermissionUtils->requestCameraPermission();
|
|
#else
|
|
return true;
|
|
#endif
|
|
|
|
}
|
|
|
|
// ------------------------
|
|
// --- Helper functions ---
|
|
// ------------------------
|
|
|
|
QVariantMap BlueRockBackend::_senddata(QUrl serviceUrl, QUrlQuery pdata)
|
|
{
|
|
// create network manager
|
|
QNetworkAccessManager * networkManager = new QNetworkAccessManager();
|
|
|
|
QVariantMap ret; //this is a custom type to store the return-data
|
|
|
|
// Create network request
|
|
QNetworkRequest request(serviceUrl);
|
|
request.setHeader(QNetworkRequest::ContentTypeHeader,
|
|
"application/x-www-form-urlencoded");
|
|
|
|
//QSslConfiguration config = QSslConfiguration::defaultConfiguration();
|
|
//config.setProtocol(QSsl::TlsV1_2);
|
|
//request.setSslConfiguration(config);
|
|
|
|
//send a POST request with the given url and data to the server
|
|
|
|
QNetworkReply *reply;
|
|
|
|
if(pdata.isEmpty()) {
|
|
// if no post data is given -> send a GET request
|
|
reply = networkManager->get(request);
|
|
}
|
|
else {
|
|
// if post data is given -> send POST request
|
|
reply = networkManager->post(request, pdata.toString(QUrl::FullyEncoded).toUtf8());
|
|
}
|
|
|
|
// loop to wait until the request has finished before processing the data
|
|
QEventLoop loop;
|
|
// timer to cancel the request after 3 seconds
|
|
QTimer timer;
|
|
timer.setSingleShot(true);
|
|
|
|
// quit the loop when the request finised
|
|
loop.connect(networkManager, SIGNAL(finished(QNetworkReply*)), SLOT(quit()));
|
|
// or the timer timed out
|
|
loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
|
|
// start the timer
|
|
timer.start(10000);
|
|
// start the loop
|
|
loop.exec();
|
|
|
|
//get the status code
|
|
QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
|
|
|
ret.insert("status", status_code.toInt());
|
|
|
|
//get the full text response
|
|
ret.insert("text", QString::fromUtf8(reply->readAll()));
|
|
|
|
// delete the reply object
|
|
delete reply;
|
|
|
|
// delete the newtwork access manager object
|
|
delete networkManager;
|
|
|
|
//return the data
|
|
return(ret);
|
|
}
|
|
|
|
#if defined(Q_OS_ANDROID)
|
|
void BlueRockBackend::onApplicationStateChanged(Qt::ApplicationState applicationState)
|
|
{
|
|
qDebug() << "S T A T E changed into: " << applicationState;
|
|
if(applicationState == Qt::ApplicationState::ApplicationSuspended) {
|
|
// nothing to do
|
|
return;
|
|
}
|
|
if(applicationState == Qt::ApplicationState::ApplicationActive) {
|
|
// if App was launched from VIEW or SEND Intent
|
|
// there's a race collision: the event will be lost,
|
|
// because App and UI wasn't completely initialized
|
|
// workaround: QShareActivity remembers that an Intent is pending
|
|
if(!_pendingIntentsChecked) {
|
|
_pendingIntentsChecked = true;
|
|
_shareUtils->checkPendingIntents(this->_shareUtils->getTemporaryFileLocationPath());
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// -------------------------
|
|
// --- Functions for QML ---
|
|
// -------------------------
|