1 #include <cstdio>
2 #include <QtGlobal>
3
4 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
5 #include <QtWidgets>
6 #else
7 #include <QtGui>
8 #endif
9 #include <QTimer>
10 #include <QPixmap>
11 #include <QFile>
12 #include <QFileInfo>
13 #include <QCoreApplication>
14
15 #include "seafile-applet.h"
16 #include "utils/utils.h"
17 #include "configurator.h"
18 #include "settings-mgr.h"
19 #include "api/requests.h"
20 #include "api/api-error.h"
21 #include "rpc/rpc-client.h"
22 #include "rpc/local-repo.h"
23 #include "rpc/clone-task.h"
24
25 #include "init-vdrive-dialog.h"
26
27 namespace {
28
29 const int kCheckDownloadInterval = 2000;
30
31 } // namespace
32
33
InitVirtualDriveDialog(const Account & account,QWidget * parent)34 InitVirtualDriveDialog::InitVirtualDriveDialog(const Account& account, QWidget *parent)
35 : QDialog(parent),
36 account_(account)
37 {
38 setupUi(this);
39 mLogo->setPixmap(QPixmap(":/images/seafile-32.png"));
40 setWindowTitle(tr("Download Default Library"));
41 setWindowIcon(QIcon(":/images/seafile.png"));
42 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
43
44 mStatusText->setText(
45 tr("%1 organizes files by libraries.\nDo you like to download your "
46 "default library?").arg(getBrand()));
47 setStatusIcon(":/images/download-48.png");
48
49 create_default_repo_req_ = NULL;
50 download_default_repo_req_ = NULL;
51
52 check_download_timer_ = NULL;
53 connect(mYesBtn, SIGNAL(clicked()), this, SLOT(start()));
54 connect(mNoBtn, SIGNAL(clicked()), this, SLOT(onCancel()));
55
56 mRunInBackgroundBtn->setVisible(false);
57 mFinishBtn->setVisible(false);
58 mOpenBtn->setVisible(false);
59 }
60
start()61 void InitVirtualDriveDialog::start()
62 {
63 // mYesBtn->setEnabled(false);
64 // mNoBtn->setEnabled(false);
65 mYesBtn->setVisible(false);
66 mNoBtn->setVisible(false);
67 getDefaultRepo();
68 }
69
onCancel()70 void InitVirtualDriveDialog::onCancel()
71 {
72 reject();
73 }
74
getDefaultRepo()75 void InitVirtualDriveDialog::getDefaultRepo()
76 {
77 setStatusText(tr("Checking your default library..."));
78 get_default_repo_req_ = new GetDefaultRepoRequest(account_);
79
80 connect(get_default_repo_req_, SIGNAL(success(bool, const QString&)),
81 this, SLOT(onGetDefaultRepoSuccess(bool, const QString&)));
82
83 connect(get_default_repo_req_, SIGNAL(failed(const ApiError&)),
84 this, SLOT(onGetDefaultRepoFailure(const ApiError&)));
85
86 get_default_repo_req_->send();
87 }
88
createDefaultRepo()89 void InitVirtualDriveDialog::createDefaultRepo()
90 {
91 setStatusText(tr("Creating the default library..."));
92 create_default_repo_req_ = new CreateDefaultRepoRequest(account_);
93
94 connect(create_default_repo_req_, SIGNAL(success(const QString&)),
95 this, SLOT(onCreateDefaultRepoSuccess(const QString&)));
96
97 connect(create_default_repo_req_, SIGNAL(failed(const ApiError&)),
98 this, SLOT(onCreateDefaultRepoFailure(const ApiError&)));
99
100 create_default_repo_req_->send();
101 }
102
startDownload(const QString & repo_id)103 void InitVirtualDriveDialog::startDownload(const QString& repo_id)
104 {
105 default_repo_id_ = repo_id;
106
107 LocalRepo repo;
108
109 seafApplet->rpcClient()->getLocalRepo(repo_id, &repo);
110 if (repo.isValid()) {
111 // This repo is already here
112 qDebug("The default library has already been downloaded");
113 default_repo_path_ = repo.worktree;
114 finish();
115 return;
116 }
117
118 download_default_repo_req_ = new DownloadRepoRequest(account_, repo_id, false);
119
120 connect(download_default_repo_req_, SIGNAL(success(const RepoDownloadInfo&)),
121 this, SLOT(onDownloadRepoSuccess(const RepoDownloadInfo&)));
122
123 connect(download_default_repo_req_, SIGNAL(failed(const ApiError&)),
124 this, SLOT(onDownloadRepoFailure(const ApiError&)));
125
126 download_default_repo_req_->send();
127 }
128
onGetDefaultRepoSuccess(bool exists,const QString & repo_id)129 void InitVirtualDriveDialog::onGetDefaultRepoSuccess(bool exists, const QString& repo_id)
130 {
131 if (!exists) {
132 createDefaultRepo();
133 } else {
134 startDownload(repo_id);
135 }
136 }
137
onGetDefaultRepoFailure(const ApiError & error)138 void InitVirtualDriveDialog::onGetDefaultRepoFailure(const ApiError& error)
139 {
140 if (error.type() == ApiError::HTTP_ERROR && error.httpErrorCode() == 404) {
141 fail(tr("Failed to create default library:\n\n"
142 "The server version must be 2.1 or higher to support this."));
143 } else {
144 fail(tr("Failed to get default library:\n%1").arg(error.toString()));
145 }
146 }
147
148
onCreateDefaultRepoSuccess(const QString & repo_id)149 void InitVirtualDriveDialog::onCreateDefaultRepoSuccess(const QString& repo_id)
150 {
151 startDownload(repo_id);
152 }
153
onCreateDefaultRepoFailure(const ApiError & error)154 void InitVirtualDriveDialog::onCreateDefaultRepoFailure(const ApiError& error)
155 {
156 if (error.type() == ApiError::HTTP_ERROR && error.httpErrorCode() == 404) {
157 fail(tr("Failed to create default library:\n\n"
158 "The server version must be 2.1 or higher to support this."));
159 } else {
160 fail(tr("Failed to create default library:\n%1").arg(error.toString()));
161 }
162 }
163
onDownloadRepoSuccess(const RepoDownloadInfo & info)164 void InitVirtualDriveDialog::onDownloadRepoSuccess(const RepoDownloadInfo& info)
165 {
166 int ret;
167 QString worktree = seafApplet->configurator()->worktreeDir();
168 QString error;
169
170 ret = seafApplet->rpcClient()->downloadRepo(info.repo_id,
171 info.repo_version, info.repo_name,
172 worktree, info.token,
173 QString(), info.magic,
174 info.email, info.random_key,
175 info.enc_version, info.more_info,
176 &error);
177
178 if (ret < 0) {
179 fail(tr("Failed to download default library:\n %1").arg(error));
180 } else {
181 check_download_timer_ = new QTimer(this);
182 connect(check_download_timer_, SIGNAL(timeout()), this, SLOT(checkDownloadProgress()));
183 check_download_timer_->start(kCheckDownloadInterval);
184
185 setStatusText(tr("Downloading default library..."));
186
187 mRunInBackgroundBtn->setVisible(true);
188 connect(mRunInBackgroundBtn, SIGNAL(clicked()), this, SLOT(hide()));
189 }
190 }
191
onDownloadRepoFailure(const ApiError & error)192 void InitVirtualDriveDialog::onDownloadRepoFailure(const ApiError& error)
193 {
194 fail(tr("Failed to download default library:\n%1").arg(error.toString()));
195 }
196
openVirtualDisk()197 void InitVirtualDriveDialog::openVirtualDisk()
198 {
199 QDesktopServices::openUrl(QUrl::fromLocalFile(default_repo_path_));
200 accept();
201 }
202
finish()203 void InitVirtualDriveDialog::finish()
204 {
205 QString msg = tr("The default library has been downloaded.\n"
206 "You can click the \"Open\" button to view it.");
207 setStatusText(msg);
208 setStatusIcon(":/images/sync/done@2x.png");
209
210 mFinishBtn->setVisible(true);
211 mOpenBtn->setVisible(true);
212
213 connect(mFinishBtn, SIGNAL(clicked()), this, SLOT(accept()));
214 connect(mOpenBtn, SIGNAL(clicked()), this, SLOT(openVirtualDisk()));
215 }
216
fail(const QString & reason)217 void InitVirtualDriveDialog::fail(const QString& reason)
218 {
219 ensureVisible();
220
221 setStatusText(reason);
222 mFinishBtn->setVisible(true);
223 connect(mFinishBtn, SIGNAL(clicked()), this, SLOT(reject()));
224 }
225
checkDownloadProgress()226 void InitVirtualDriveDialog::checkDownloadProgress()
227 {
228 // First check for error
229 std::vector<CloneTask> tasks;
230 if (seafApplet->rpcClient()->getCloneTasks(&tasks) < 0) {
231 return;
232 }
233
234 CloneTask task;
235 for (size_t i = 0; i < tasks.size(); i++) {
236 if (tasks[i].repo_id == default_repo_id_) {
237 task = tasks[i];
238 break;
239 }
240 }
241
242 if (!task.isValid()) {
243 return;
244 }
245
246 if (task.state != "done" && task.state != "error") {
247 return;
248 }
249
250 check_download_timer_->stop();
251
252 mRunInBackgroundBtn->setVisible(false);
253 ensureVisible();
254
255 if (task.state == "error") {
256 fail(tr("Error when downloading the default library: %1").arg(task.error_str));
257 return;
258 }
259
260 // Download is finished.
261 LocalRepo repo;
262 seafApplet->rpcClient()->getLocalRepo(default_repo_id_, &repo);
263 default_repo_path_ = repo.worktree;
264 finish();
265 }
266
267
setStatusText(const QString & status)268 void InitVirtualDriveDialog::setStatusText(const QString& status)
269 {
270 mStatusText->setText(status);
271 }
272
setStatusIcon(const QString & path)273 void InitVirtualDriveDialog::setStatusIcon(const QString& path)
274 {
275 mStatusIcon->setPixmap(QPixmap(path));
276 }
277
ensureVisible()278 void InitVirtualDriveDialog::ensureVisible()
279 {
280 show();
281 raise();
282 activateWindow();
283 }
284