aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2015-06-14 20:18:59 +0200
committerJavier <dev.git@javispedro.com>2015-06-14 20:18:59 +0200
commitfb55ea21c891a75f2e7e06d336faa9b5b8b105a3 (patch)
tree4c8d677ea98027576f44b8acfbc60b34675fe215
parent3a17eeddaf005a5e9fe48f1207978d0a0da0ae9d (diff)
downloadscribiu-fb55ea21c891a75f2e7e06d336faa9b5b8b105a3.tar.gz
scribiu-fb55ea21c891a75f2e7e06d336faa9b5b8b105a3.zip
improve sync locking and status messages
-rw-r--r--mainwindow.cc14
-rw-r--r--mainwindow.h2
-rw-r--r--notebookmodel.cc22
-rw-r--r--notebookmodel.h1
-rw-r--r--smartpenmanager.cc14
-rw-r--r--smartpenmanager.h1
-rw-r--r--smartpensyncer.cc145
-rw-r--r--smartpensyncer.h2
8 files changed, 166 insertions, 35 deletions
diff --git a/mainwindow.cc b/mainwindow.cc
index 0610993..5d4f503 100644
--- a/mainwindow.cc
+++ b/mainwindow.cc
@@ -56,6 +56,10 @@ MainWindow::MainWindow(QWidget *parent) :
this, SLOT(handleNotebookRowsInserted(QModelIndex,int,int)));
connect(_manager, SIGNAL(pensBeingSynchronizedChanged()),
this, SLOT(handlePensBeingSynchronizedChanged()));
+ connect(_manager, SIGNAL(syncComplete(QString)),
+ this, SLOT(handlePenSyncComplete(QString)));
+ connect(_manager, SIGNAL(syncFailed(QString)),
+ this, SLOT(handlePenSyncFailed(QString)));
connect(_media, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
this, SLOT(handleMediaStateChange(Phonon::State)));
connect(_media, SIGNAL(totalTimeChanged(qint64)),
@@ -278,6 +282,16 @@ void MainWindow::handlePensBeingSynchronizedChanged()
}
}
+void MainWindow::handlePenSyncComplete(const QString &penName)
+{
+ ui->statusBar->showMessage(tr("Completed synchronization with %1").arg(penName), 10000);
+}
+
+void MainWindow::handlePenSyncFailed(const QString &penName)
+{
+ ui->statusBar->showMessage(tr("Failed synchronization with %1").arg(penName), 10000);
+}
+
void MainWindow::handleExport()
{
if (_curNotebookName == PAPER_REPLAY) {
diff --git a/mainwindow.h b/mainwindow.h
index e176122..6689795 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -59,6 +59,8 @@ private slots:
void handleMediaTotalTimeChanged(qint64 time);
void handleMediaTick(qint64 time);
void handlePensBeingSynchronizedChanged();
+ void handlePenSyncComplete(const QString &penName);
+ void handlePenSyncFailed(const QString &penName);
void handleExport();
void handleAbout();
diff --git a/notebookmodel.cc b/notebookmodel.cc
index dc72931..e52d3f4 100644
--- a/notebookmodel.cc
+++ b/notebookmodel.cc
@@ -139,8 +139,14 @@ QVariant NotebookModel::data(const QModelIndex &index, int role) const
case 1:
return QVariant();
case 2:
- if (isNotebookLocked(penName, notebookName)) {
- return QApplication::style()->standardIcon(QStyle::SP_BrowserReload);
+ if (notebookName != PAPER_REPLAY) {
+ if (isNotebookLocked(penName, notebookName)) {
+ return QApplication::style()->standardIcon(QStyle::SP_BrowserReload);
+ }
+ } else {
+ if (isPaperReplayLocked(penName)) {
+ return QApplication::style()->standardIcon(QStyle::SP_BrowserReload);
+ }
}
break;
}
@@ -385,7 +391,17 @@ bool NotebookModel::isNotebookLocked(const QString &pen, const QString &notebook
{
QDir dir = notebookDir(pen, notebook);
if (dir.exists(".sync.lck")) {
- return true; // TODO check if stale
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool NotebookModel::isPaperReplayLocked(const QString &pen) const
+{
+ QDir dir(paperReplayDirectory(pen));
+ if (dir.exists(".sync.lck")) {
+ return true;
} else {
return false;
}
diff --git a/notebookmodel.h b/notebookmodel.h
index 17b5211..1d69e14 100644
--- a/notebookmodel.h
+++ b/notebookmodel.h
@@ -60,6 +60,7 @@ private:
QIcon getNotebookIcon(const QString &pen, const QString &notebook) const;
bool isPenLocked(const QString &pen) const;
bool isNotebookLocked(const QString &pen, const QString &notebook) const;
+ bool isPaperReplayLocked(const QString &pen) const;
int estimatePagesOfNotebook(const QString &pen, const QString &notebook) const;
diff --git a/smartpenmanager.cc b/smartpenmanager.cc
index 1750589..0ac56e2 100644
--- a/smartpenmanager.cc
+++ b/smartpenmanager.cc
@@ -65,7 +65,7 @@ QStringList SmartpenManager::pensBeingSynchronized() const
QString name = it.value()->penName();
if (name.isEmpty()) {
Smartpen::Address addr = it.value()->penAddress();
- name = QString("%1-%2").arg(addr.first, addr.second);
+ name = QString("%1-%2").arg(addr.first).arg(addr.second);
}
pens.append(name);
}
@@ -89,10 +89,20 @@ void SmartpenManager::handleSyncerFinished()
{
SmartpenSyncer *syncer = static_cast<SmartpenSyncer*>(sender());
Smartpen::Address addr = syncer->penAddress();
+
qDebug() << "Finished synchronization with pen with address:" << addr;
+
_syncers.remove(addr);
- syncer->deleteLater();
emit pensBeingSynchronizedChanged();
+
+ if (syncer->hasErrors()) {
+ qWarning() << "Synchronization with address" << addr << "failed";
+ emit syncFailed(syncer->penName());
+ } else {
+ emit syncComplete(syncer->penName());
+ }
+
+ syncer->deleteLater();
}
void SmartpenManager::processDevice(udev_device *dev)
diff --git a/smartpenmanager.h b/smartpenmanager.h
index d9c349e..42bdc06 100644
--- a/smartpenmanager.h
+++ b/smartpenmanager.h
@@ -41,6 +41,7 @@ public:
signals:
void syncComplete(const QString &penName);
+ void syncFailed(const QString &penName);
void pensBeingSynchronizedChanged();
public slots:
diff --git a/smartpensyncer.cc b/smartpensyncer.cc
index 551162e..cdf9bc6 100644
--- a/smartpensyncer.cc
+++ b/smartpensyncer.cc
@@ -21,6 +21,7 @@
#include <QtCore/QThread>
#include <QtCore/QDebug>
#include <quazip/quazipfile.h>
+#include <cstdio>
#include "paperreplay.h"
#include "notebookmodel.h"
#include "smartpensyncer.h"
@@ -28,33 +29,98 @@
#define BUFFER_SIZE 16 * 1024
namespace {
-static QDateTime getTimestampFileDate(const QString &path)
+class LockFile
{
- QFileInfo info(path);
- qDebug() << "Checking timestamp" << info.filePath();
+public:
+ LockFile(const QString &path);
+ ~LockFile();
+
+ bool lock();
+
+private:
+ QString _path;
+ FILE * _file;
+ bool _locked;
+};
+
+class TimestampFile
+{
+public:
+ TimestampFile(const QString &path);
+
+ QDateTime get();
+ void set();
+
+private:
+ QFileInfo _fi;
+};
+
+LockFile::LockFile(const QString &path)
+ : _path(path), _file(0), _locked(false)
+{
+
+}
+
+LockFile::~LockFile()
+{
+ if (_file) {
+ fclose(_file);
+ }
+ if (_locked) {
+ if (!QFile::remove(_path)) {
+ qWarning() << "Cannot remove lock file:" << _path;
+ }
+ }
+}
+
+bool LockFile::lock()
+{
+ Q_ASSERT(!_locked);
+
+ QFileInfo info(_path);
if (info.exists()) {
- return info.lastModified();
+ if (info.created().secsTo(QDateTime::currentDateTime()) > 10 * 60) {
+ if (QFile::remove(info.filePath())) {
+ qDebug() << "Removing stale lock file:" << info.absoluteFilePath();
+ }
+ } else {
+ return false;
+ }
+ }
+
+ _file = ::fopen(info.absoluteFilePath().toLocal8Bit().data(), "wx");
+ if (_file) {
+ _locked = true;
+ return true;
} else {
- return QDateTime();
+ return false;
}
}
-static void setTimestampFileDate(const QString &path)
+TimestampFile::TimestampFile(const QString &path)
+ : _fi(path)
{
- QFile f(path);
- if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
- qWarning() << "Could not set timestamp file:" << path;
- return;
+}
+
+QDateTime TimestampFile::get()
+{
+ qDebug() << "Checking timestamp" << _fi.filePath();
+ if (_fi.exists()) {
+ return _fi.lastModified();
+ } else {
+ return QDateTime();
}
- f.close();
}
-void removeTimestampFile(const QString &path)
+void TimestampFile::set()
{
- QFile f(path);
- if (!f.remove()) {
- qWarning() << "Cannot remove timestamp file:" << path;
+ QFile f(_fi.filePath());
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ qWarning() << "Could not set timestamp file:" << _fi.absoluteFilePath();
+ return;
}
+ f.close();
+ _fi.refresh();
}
}
@@ -81,6 +147,11 @@ QString SmartpenSyncer::penName() const
return _penName;
}
+bool SmartpenSyncer::hasErrors() const
+{
+ return _errored;
+}
+
void SmartpenSyncer::abort()
{
_aborted = true;
@@ -123,10 +194,14 @@ void SmartpenSyncer::run()
bool SmartpenSyncer::syncPen()
{
- QDateTime lastSyncTime = getTimestampFileDate(_penDataDir.filePath(".lastsync"));
- QList<Smartpen::ChangeReport> changes = _pen->getChangeList(lastSyncTime);
+ LockFile lock(_penDataDir.filePath(".sync.lck"));
+ if (!lock.lock()) {
+ qWarning() << "Pen is already being synchronized; delete this file if it is not:" << _penDataDir.absoluteFilePath(".sync.lck");
+ return false;
+ }
- setTimestampFileDate(_penDataDir.filePath(".sync.lck"));
+ TimestampFile lastSync(_penDataDir.filePath(".lastsync"));
+ QList<Smartpen::ChangeReport> changes = _pen->getChangeList(lastSync.get());
foreach(const Smartpen::ChangeReport &change, changes) {
if (!change.guid.isEmpty()) {
@@ -140,10 +215,14 @@ bool SmartpenSyncer::syncPen()
return false;
}
}
+
+ if (_aborted) {
+ qWarning() << "Aborting sync";
+ return false;
+ }
}
- setTimestampFileDate(_penDataDir.filePath(".lastsync"));
- removeTimestampFile(_penDataDir.filePath(".sync.lck"));
+ lastSync.set();
return true;
}
@@ -157,17 +236,20 @@ bool SmartpenSyncer::syncNotebook(const Smartpen::ChangeReport &change)
}
}
- setTimestampFileDate(notebookDir.filePath(".sync.lck"));
+ LockFile lock(notebookDir.filePath(".sync.lck"));
+ if (!lock.lock()) {
+ qWarning() << "Notebook is already being synchronized; delete this file if it is not:" << notebookDir.absoluteFilePath(".sync.lck");
+ return false;
+ }
- QDateTime lastSyncTime = getTimestampFileDate(notebookDir.filePath(".lastsync"));
- QByteArray lspData = _pen->getLspData(change.guid, lastSyncTime);
+ TimestampFile lastSync(notebookDir.filePath(".lastsync"));
+ QByteArray lspData = _pen->getLspData(change.guid, lastSync.get());
if (!extractZip(lspData, notebookDir)) {
return false;
}
- setTimestampFileDate(notebookDir.filePath(".lastsync"));
- removeTimestampFile(notebookDir.filePath(".sync.lck"));
+ lastSync.set();
return true;
}
@@ -181,17 +263,20 @@ bool SmartpenSyncer::syncPaperReplay()
}
}
- setTimestampFileDate(replayDir.filePath(".sync.lck"));
+ LockFile lock(replayDir.filePath(".sync.lck"));
+ if (!lock.lock()) {
+ qWarning() << "Paper replay is already being synchronized; delete this file if it is not:" << replayDir.absoluteFilePath(".sync.lck");
+ return false;
+ }
- QDateTime lastSyncTime = getTimestampFileDate(replayDir.filePath(".lastsync"));
- QByteArray replayData = _pen->getPaperReplay(lastSyncTime);
+ TimestampFile lastSync(replayDir.filePath(".lastsync"));
+ QByteArray replayData = _pen->getPaperReplay(lastSync.get());
if (!extractZip(replayData, replayDir)) {
return false;
}
- setTimestampFileDate(replayDir.filePath(".lastsync"));
- removeTimestampFile(replayDir.filePath(".sync.lck"));
+ lastSync.set();
return true;
}
diff --git a/smartpensyncer.h b/smartpensyncer.h
index 9577bff..57ac6d7 100644
--- a/smartpensyncer.h
+++ b/smartpensyncer.h
@@ -33,6 +33,8 @@ public:
Smartpen::Address penAddress() const;
QString penName() const;
+ bool hasErrors() const;
+
signals:
void penNameChanged();