comparison src/main.cpp @ 150:2a8c97753381

Make the backup stuff compile-time optional.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 28 Aug 2017 11:24:42 +0300
parents 665421937ec8
children 753ae3569cb7
comparison
equal deleted inserted replaced
149:fd960e586678 150:2a8c97753381
26 QPoint uiPos; 26 QPoint uiPos;
27 QSize uiSize; 27 QSize uiSize;
28 double uiScale; // Global UI scale factor 28 double uiScale; // Global UI scale factor
29 29
30 QString dataPath; // Application data path/directory 30 QString dataPath; // Application data path/directory
31
32 // Backup related settings
33 int dbBackupMode;
31 QString dbBackupURL; 34 QString dbBackupURL;
32 QString dbBackupSecret; 35 QString dbBackupSecret;
33 } settings; 36 } settings;
34 37
35 38
244 247
245 // Read configuration settings 248 // Read configuration settings
246 settings.uiPos = tmpst.value("pos", QPoint(100, 100)).toPoint(); 249 settings.uiPos = tmpst.value("pos", QPoint(100, 100)).toPoint();
247 settings.uiSize = tmpst.value("size", QSize(1000, 600)).toSize(); 250 settings.uiSize = tmpst.value("size", QSize(1000, 600)).toSize();
248 settings.uiScale = tmpst.value("scale", 1.0f).toDouble(); 251 settings.uiScale = tmpst.value("scale", 1.0f).toDouble();
252 settings.dbBackupMode = BACKUP_NONE;
249 settings.dbBackupURL = tmpst.value("dbBackupURL", QString()).toString(); 253 settings.dbBackupURL = tmpst.value("dbBackupURL", QString()).toString();
250 settings.dbBackupSecret = tmpst.value("dbBackupSecret", QString()).toString(); 254 settings.dbBackupSecret = tmpst.value("dbBackupSecret", QString()).toString();
251 255
252 // Check commandline arguments for configuring backup settings 256 // Check commandline arguments for configuring backup settings
253 if (argc >= 4 && strcmp(argv[1], "config") == 0) 257 if (argc >= 5 && strcmp(argv[1], "config") == 0)
254 { 258 {
255 settings.dbBackupURL = QString(argv[2]); 259 settings.dbBackupMode = QString(argv[2]).toInt();
256 settings.dbBackupSecret = QString(argv[3]); 260 settings.dbBackupURL = QString(argv[3]);
261 settings.dbBackupSecret = QString(argv[4]);
257 } 262 }
258 263
259 // Also possibility of resetting the UI settings 264 // Also possibility of resetting the UI settings
260 if (argc >= 2 && strcmp(argv[1], "reset") == 0) 265 if (argc >= 2 && strcmp(argv[1], "reset") == 0)
261 { 266 {
445 // Commit and close database 450 // Commit and close database
446 QSqlDatabase::database().commit(); 451 QSqlDatabase::database().commit();
447 QSqlDatabase::database().close(); 452 QSqlDatabase::database().close();
448 453
449 // Back up the database 454 // Back up the database
450 backupDatabase(); 455 if (settings.dbBackupMode != BACKUP_NONE)
456 backupDatabase();
451 } 457 }
452 458
453 459
454 void SyntilistaMainWindow::backupDatabase() 460 void SyntilistaMainWindow::backupDatabase()
455 { 461 {
456 QString dbFilename = settings.dataPath + QDir::separator() + APP_SQLITE_FILE; 462 QString dbFilename = settings.dataPath + QDir::separator() + APP_SQLITE_FILE;
457 QString backupFilename = APP_SQLITE_FILE; 463 QString backupFilename = APP_SQLITE_FILE;
458 backupReply = NULL;
459 backupDialog = NULL; 464 backupDialog = NULL;
460 465
461 if (settings.dbBackupURL == QString() || settings.dbBackupURL == "") 466 if (settings.dbBackupURL == QString() || settings.dbBackupURL == "")
462 { 467 {
463 slLog("ERROR", QStringLiteral("Database backup URL not set in configuration.")); 468 slLog("ERROR", QStringLiteral("Database backup URL not set in configuration."));
468 { 473 {
469 slLog("ERROR", QStringLiteral("Database backup secret key not set in configuration.")); 474 slLog("ERROR", QStringLiteral("Database backup secret key not set in configuration."));
470 return; 475 return;
471 } 476 }
472 477
473 // Check for network access 478 if (settings.dbBackupMode == BACKUP_HTTP)
474 QNetworkAccessManager *manager = new QNetworkAccessManager(); 479 {
475 if (manager->networkAccessible() != QNetworkAccessManager::Accessible) 480 #ifdef USE_QTHTTP
476 { 481 // Check for network access
477 slLog("ERROR", QStringLiteral("Network not available, cannot backup the database.")); 482 httpBackupReply = NULL;
483
484 QNetworkAccessManager *manager = new QNetworkAccessManager();
485 if (manager->networkAccessible() != QNetworkAccessManager::Accessible)
486 {
487 slLog("ERROR", QStringLiteral("Network not available, cannot backup the database."));
488 return;
489 }
490
491 // Attempt to open the database file
492 QFile *file = new QFile(dbFilename);
493 if (!file->open(QIODevice::ReadOnly))
494 {
495 slLog("ERROR", QStringLiteral("Failed to open database file '%1' for backup.").arg(dbFilename));
496 return;
497 }
498
499 // Okay, we seem to be "go" ..
500 slLog("INFO",
501 QStringLiteral("Attempting database backup from '%1' to '%2'.").
502 arg(dbFilename).arg(settings.dbBackupURL));
503
504 // Create the HTTP POST request
505 QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
506
507 // The "secret" key as POST parameter
508 QHttpPart postPart;
509 postPart.setHeader(QNetworkRequest::ContentDispositionHeader,
510 QVariant("form-data; name=\"secret\";"));
511 postPart.setBody(QByteArray(settings.dbBackupSecret.toUtf8()));
512
513 // Actual data as binary octet-stream
514 QHttpPart dataPart;
515 dataPart.setHeader(QNetworkRequest::ContentTypeHeader,
516 QVariant("binary/octet-stream"));
517
518 dataPart.setHeader(QNetworkRequest::ContentDispositionHeader,
519 QVariant("form-data; name=\"file\"; filename=\""+ backupFilename +"\""));
520
521 dataPart.setBodyDevice(file);
522 file->setParent(multiPart); // we cannot delete the QFile object now, so delete it with the multiPart
523
524 multiPart->append(postPart);
525 multiPart->append(dataPart);
526
527 // Attempt to POST the whole thing
528 QUrl url(settings.dbBackupURL);
529 QNetworkRequest request(url);
530 httpBackupReply = manager->post(request, multiPart);
531 multiPart->setParent(httpBackupReply);
532
533 connect(
534 httpBackupReply,
535 SIGNAL(finished()),
536 this,
537 SLOT(httpBackupFinished()));
538
539 connect(
540 httpBackupReply,
541 SIGNAL(uploadProgress(qint64, qint64)),
542 this,
543 SLOT(httpBackupProgress(qint64, qint64)));
544
545 connect(
546 httpBackupReply,
547 SIGNAL(error(QNetworkReply::NetworkError)),
548 this,
549 SLOT(httpBackupError(QNetworkReply::NetworkError)));
550 #else
551 slLog("ERROR", QStringLiteral("Backup method is HTTP/HTTPS, but support is not compiled in!"));
478 return; 552 return;
479 } 553 #endif
480 554 }
481 // Attempt to open the database file 555 else
482 QFile *file = new QFile(dbFilename); 556 if (settings.dbBackupMode == BACKUP_CURL_SFTP)
483 if (!file->open(QIODevice::ReadOnly)) 557 {
484 { 558 #ifdef USE_LIBCURL
485 slLog("ERROR", QStringLiteral("Failed to open database file '%1' for backup.").arg(dbFilename)); 559 #else
560 slLog("ERROR", QStringLiteral("Backup method is SFTP via libcurl, but support is not compiled in!"));
486 return; 561 return;
487 } 562 #endif
488 563 }
489 // Okay, we seem to be "go" ..
490 slLog("INFO",
491 QStringLiteral("Attempting database backup from '%1' to '%2'.").
492 arg(dbFilename).arg(settings.dbBackupURL));
493
494 // Create the HTTP POST request
495 QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
496
497 // The "secret" key as POST parameter
498 QHttpPart postPart;
499 postPart.setHeader(QNetworkRequest::ContentDispositionHeader,
500 QVariant("form-data; name=\"secret\";"));
501 postPart.setBody(QByteArray(settings.dbBackupSecret.toUtf8()));
502
503 // Actual data as binary octet-stream
504 QHttpPart dataPart;
505 dataPart.setHeader(QNetworkRequest::ContentTypeHeader,
506 QVariant("binary/octet-stream"));
507
508 dataPart.setHeader(QNetworkRequest::ContentDispositionHeader,
509 QVariant("form-data; name=\"file\"; filename=\""+ backupFilename +"\""));
510
511 dataPart.setBodyDevice(file);
512 file->setParent(multiPart); // we cannot delete the QFile object now, so delete it with the multiPart
513
514 multiPart->append(postPart);
515 multiPart->append(dataPart);
516
517 // Attempt to POST the whole thing
518 QUrl url(settings.dbBackupURL);
519 QNetworkRequest request(url);
520 backupReply = manager->post(request, multiPart);
521 multiPart->setParent(backupReply);
522
523 connect(
524 backupReply,
525 SIGNAL(finished()),
526 this,
527 SLOT(backupFinished()));
528
529 connect(
530 backupReply,
531 SIGNAL(uploadProgress(qint64, qint64)),
532 this,
533 SLOT(backupProgress(qint64, qint64)));
534
535 connect(
536 backupReply,
537 SIGNAL(error(QNetworkReply::NetworkError)),
538 this,
539 SLOT(backupError(QNetworkReply::NetworkError)));
540 564
541 // Create progress dialog 565 // Create progress dialog
542 backupDialog = new QProgressDialog( 566 backupDialog = new QProgressDialog(
543 tr("Varmuuskopioidaan tietokantaa ..."), 567 tr("Varmuuskopioidaan tietokantaa ..."),
544 QString(), 568 QString(),
551 backupDialog->setWindowModality(Qt::ApplicationModal); 575 backupDialog->setWindowModality(Qt::ApplicationModal);
552 backupDialog->exec(); 576 backupDialog->exec();
553 } 577 }
554 578
555 579
556 void SyntilistaMainWindow::backupProgress(qint64 bytesSent, qint64 bytesTotal) 580 #ifdef USE_QTHTTP
581 void SyntilistaMainWindow::httpBackupProgress(qint64 bytesSent, qint64 bytesTotal)
557 { 582 {
558 if (bytesTotal > 0) 583 if (bytesTotal > 0)
559 { 584 {
560 slLog("INFO", 585 slLog("INFO",
561 QStringLiteral("Backup sent %1 / %2 bytes."). 586 QStringLiteral("Backup sent %1 / %2 bytes.").
565 backupDialog->setValue((bytesSent * 100) / bytesTotal); 590 backupDialog->setValue((bytesSent * 100) / bytesTotal);
566 } 591 }
567 } 592 }
568 593
569 594
570 void SyntilistaMainWindow::backupError(QNetworkReply::NetworkError code) 595 void SyntilistaMainWindow::httpBackupError(QNetworkReply::NetworkError code)
571 { 596 {
572 slLog("ERROR", 597 slLog("ERROR",
573 QStringLiteral("Backup failed with network error %1."). 598 QStringLiteral("Backup failed with network error %1.").
574 arg(code) 599 arg(code)
575 ); 600 );
576 } 601 }
577 602
578 603
579 void SyntilistaMainWindow::backupFinished() 604 void SyntilistaMainWindow::httpBackupFinished()
580 { 605 {
581 if (backupReply) 606 if (httpBackupReply)
582 { 607 {
583 QVariant status = backupReply->attribute(QNetworkRequest::HttpStatusCodeAttribute); 608 QVariant status = httpBackupReply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
584 if (status.isValid()) 609 if (status.isValid())
585 { 610 {
586 int code = status.toInt(); 611 int code = status.toInt();
587 switch (code) 612 switch (code)
588 { 613 {
595 break; 620 break;
596 621
597 default: 622 default:
598 slLog("ERROR", 623 slLog("ERROR",
599 QStringLiteral("Backup server responded with error:\n")+ 624 QStringLiteral("Backup server responded with error:\n")+
600 QString::fromUtf8(backupReply->readAll())); 625 QString::fromUtf8(httpBackupReply->readAll()));
601 break; 626 break;
602 } 627 }
603 } 628 }
604 } 629 }
605 else 630 else
607 slLog("WARNING", "Backup finished prematurely (failed)."); 632 slLog("WARNING", "Backup finished prematurely (failed).");
608 } 633 }
609 634
610 backupDialog->close(); 635 backupDialog->close();
611 } 636 }
637 #endif
612 638
613 639
614 // 640 //
615 // Helper function for showing messages in the statusbar/line 641 // Helper function for showing messages in the statusbar/line
616 // 642 //