1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#include "Uploader.h"
#include "XorEncrypter.h"
#include <iostream>
#include <cmath>
using namespace std;
Uploader::Uploader(const QString &ftpServer, const QString &ftpPath, const QString &username, const QString &password, const QByteArray &secretKey, const QHash<const QString, QFileInfo> &fileList, QObject *parent) :
QObject(parent),
m_fileList(fileList),
m_listPositionNumber(0),
m_ftp(this),
m_ftpServer(ftpServer),
m_ftpPath(ftpPath),
m_username(username),
m_password(password),
m_secretKey(secretKey),
m_cdCommand(-1),
m_latestCommand(-1),
m_latestPut(-1),
m_currentFile(0)
{
connect(&m_ftp, SIGNAL(stateChanged(int)), this, SLOT(stateChanged(int)));
connect(&m_ftp, SIGNAL(commandFinished(int,bool)), this, SLOT(commandFinished(int,bool)));
connect(&m_ftp, SIGNAL(listInfo(QUrlInfo)), this, SLOT(listInfo(QUrlInfo)));
connect(&m_ftp, SIGNAL(dataTransferProgress(qint64,qint64)), this, SLOT(dataTransferProgress(qint64,qint64)));
}
void Uploader::begin()
{
cerr << "Setting up." << endl;
m_ftp.connectToHost(m_ftpServer);
}
void Uploader::stateChanged(int state)
{
switch (state) {
case QFtp::Connected:
cerr << "Connected." << endl;
cerr << "Logging in." << endl;
m_ftp.login(m_username, m_password);
break;
case QFtp::LoggedIn:
cerr << "Logged in." << endl;
m_cdCommand = m_ftp.cd(m_ftpPath);
break;
case QFtp::Unconnected:
cerr << "Unconnected." << endl;
break;
case QFtp::HostLookup:
cerr << "Looking up host." << endl;
break;
case QFtp::Connecting:
cerr << "Connecting." << endl;
break;
case QFtp::Closing:
cerr << "Closing." << endl;
emit done();
break;
}
}
void Uploader::commandFinished(int id, bool error)
{
if (id == m_latestPut && m_currentFile) {
m_currentFile->close();
m_currentFile->deleteLater();
}
if (error) {
cerr << m_ftp.errorString().toStdString() << endl;
emit done();
return;
}
if (id == m_cdCommand) {
cerr << "Listing." << endl;
m_latestCommand = m_ftp.list();
} else if (id == m_latestCommand) {
if (!m_fileList.size()) {
cerr << "No files to upload." << endl;
emit done();
return;
}
m_listPosition = m_fileList.constBegin();
uploadNextFile();
} else if (id == m_latestPut) {
cerr << endl;
uploadNextFile();
}
}
void Uploader::listInfo(const QUrlInfo &i)
{
if (m_fileList.contains(i.name())) {
const QFileInfo &info = m_fileList.value(i.name());
if (info.lastModified() < i.lastModified() && info.size() == i.size())
m_fileList.remove(i.name());
} else {
cerr << i.name().toStdString() << " has disappeared locally." << endl;
m_latestCommand = m_ftp.remove(i.name());
}
}
void Uploader::uploadNextFile()
{
if (m_listPosition == m_fileList.constEnd()) {
cerr << "Complete!" << endl;
emit done();
return;
}
++m_listPositionNumber;
cerr << "[" << m_listPositionNumber << " of " << m_fileList.count() << "] Uploading " << m_listPosition.value().absoluteFilePath().toStdString() << endl;
m_currentFile = new QFile(m_listPosition.value().absoluteFilePath());
m_currentFile->open(QIODevice::ReadOnly);
XorEncrypter *xorEncrypter = new XorEncrypter(m_secretKey, m_currentFile);
m_rateCalculator.reset();
m_latestPut = m_ftp.put(xorEncrypter, m_listPosition.key());
++m_listPosition;
}
void Uploader::dataTransferProgress(qint64 done, qint64 total)
{
m_rateCalculator.updateTotalBytes(done);
const double rate = m_rateCalculator.rate(25000);
const qint64 time = (total - done) / rate;
cerr << "\r\033[2K" << static_cast<qint64>(round(done / 1024.0)) << " of " << static_cast<qint64>(round(total / 1024.0)) << " kilobytes transferred at " << static_cast<qint64>(round(rate * 1024.0 / 1000.0)) << " kilobytes per second, " << time / 1000 / 60 << " minutes and " << time / 1000 % 60 << " seconds left.";
}
|