Mercurial > minori
comparison src/gui/pages/torrents.cc @ 230:2f5a9247e501
torrents: implement download button
erg
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Sat, 13 Jan 2024 09:42:02 -0500 |
parents | 53211cb1e7f5 |
children | 4d461ef7d424 |
comparison
equal
deleted
inserted
replaced
229:adc20fa321c1 | 230:2f5a9247e501 |
---|---|
1 #include "gui/pages/torrents.h" | 1 #include "gui/pages/torrents.h" |
2 #include "core/strings.h" | 2 #include "core/strings.h" |
3 #include "core/http.h" | 3 #include "core/http.h" |
4 #include "core/session.h" | 4 #include "core/session.h" |
5 #include "core/filesystem.h" | |
5 #include "gui/widgets/text.h" | 6 #include "gui/widgets/text.h" |
6 #include "track/media.h" | 7 #include "track/media.h" |
7 | 8 |
8 #include <QVBoxLayout> | 9 #include <QVBoxLayout> |
9 #include <QToolBar> | 10 #include <QToolBar> |
10 #include <QTreeView> | 11 #include <QTreeView> |
11 #include <QMainWindow> | 12 #include <QMainWindow> |
12 #include <QByteArray> | 13 #include <QByteArray> |
13 #include <QDataStream> | 14 #include <QDataStream> |
14 #include <QThreadPool> | 15 #include <QThread> |
15 #include <QDebug> | 16 #include <QDebug> |
16 | 17 |
17 #include <iostream> | 18 #include <iostream> |
18 #include <sstream> | 19 #include <sstream> |
20 #include <fstream> | |
19 #include <algorithm> | 21 #include <algorithm> |
20 | 22 |
21 #include "pugixml.hpp" | 23 #include "pugixml.hpp" |
22 #include "anitomy/anitomy.h" | 24 #include "anitomy/anitomy.h" |
23 | 25 |
46 } | 48 } |
47 | 49 |
48 /* -------------------------------------------- */ | 50 /* -------------------------------------------- */ |
49 | 51 |
50 TorrentsPageListModel::TorrentsPageListModel(QObject* parent) : QAbstractListModel(parent) { | 52 TorrentsPageListModel::TorrentsPageListModel(QObject* parent) : QAbstractListModel(parent) { |
53 } | |
54 | |
55 void TorrentsPageListModel::DownloadTorrents(QItemSelection selection) { | |
56 const auto indexes = selection.indexes(); | |
57 | |
58 for (const auto& index : indexes) { | |
59 /* a torrent file IS literally text... */ | |
60 const std::string link = list.at(index.row()).GetLink(); | |
61 const std::string filename = list.at(index.row()).GetFilename() + ".torrent"; | |
62 | |
63 const std::filesystem::path torrents_dir = Filesystem::GetTorrentsPath(); | |
64 std::filesystem::create_directories(torrents_dir); | |
65 | |
66 std::ofstream file(torrents_dir / filename, std::ofstream::out | std::ofstream::trunc); | |
67 if (!file) | |
68 return; // wat | |
69 | |
70 const QByteArray data = HTTP::Get(link); | |
71 file.write(data.data(), data.size()); | |
72 | |
73 file.close(); | |
74 } | |
51 } | 75 } |
52 | 76 |
53 QByteArray TorrentsPageListModel::DownloadTorrentList() { | 77 QByteArray TorrentsPageListModel::DownloadTorrentList() { |
54 return HTTP::Get(session.config.torrents.feed_link); | 78 return HTTP::Get(session.config.torrents.feed_link); |
55 } | 79 } |
229 case TL_LEECHERS: return item.GetLeechers(); | 253 case TL_LEECHERS: return item.GetLeechers(); |
230 case TL_DOWNLOADERS: return item.GetDownloaders(); | 254 case TL_DOWNLOADERS: return item.GetDownloaders(); |
231 case TL_DESCRIPTION: return Strings::ToQString(item.GetDescription()); | 255 case TL_DESCRIPTION: return Strings::ToQString(item.GetDescription()); |
232 case TL_FILENAME: return Strings::ToQString(item.GetFilename()); | 256 case TL_FILENAME: return Strings::ToQString(item.GetFilename()); |
233 case TL_RELEASEDATE: return item.GetDate(); | 257 case TL_RELEASEDATE: return item.GetDate(); |
234 default: return ""; | 258 default: return {}; |
235 } | 259 } |
236 break; | 260 break; |
237 case Qt::UserRole: | 261 case Qt::UserRole: |
238 switch (index.column()) { | 262 switch (index.column()) { |
239 case TL_EPISODE: return Strings::ToInt(item.GetEpisode(), -1); | 263 case TL_EPISODE: return Strings::ToInt(item.GetEpisode(), -1); |
240 /* We have to use this to work around some stupid | 264 /* We have to use this to work around some stupid |
241 "conversion ambiguous" error on Linux */ | 265 * "conversion ambiguous" error on Linux |
266 */ | |
242 case TL_SIZE: return QVariant::fromValue(item.GetSize()); | 267 case TL_SIZE: return QVariant::fromValue(item.GetSize()); |
243 default: return data(index, Qt::DisplayRole); | 268 default: return data(index, Qt::DisplayRole); |
244 } | 269 } |
245 break; | 270 break; |
246 case Qt::SizeHintRole: { | 271 case Qt::SizeHintRole: { |
298 toolbar->setMovable(false); | 323 toolbar->setMovable(false); |
299 | 324 |
300 { | 325 { |
301 /* this needs to be stored somewhere to replicate Taiga's | 326 /* this needs to be stored somewhere to replicate Taiga's |
302 "timer" feature */ | 327 "timer" feature */ |
303 toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("&Check new torrents"), [this]{ | 328 toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("&Check new torrents"), [this] { |
304 QThreadPool::globalInstance()->start([this] { | 329 Refresh(); |
305 Refresh(); | |
306 }); | |
307 }); | 330 }); |
308 } | 331 } |
309 | 332 |
310 toolbar->addSeparator(); | 333 toolbar->addSeparator(); |
311 | 334 |
312 { | 335 { |
313 toolbar->addAction(QIcon(":/icons/16x16/navigation-270-button.png"), tr("Download &marked torrents")); | 336 toolbar->addAction(QIcon(":/icons/16x16/navigation-270-button.png"), tr("Download &marked torrents"), [this] { |
337 DownloadSelection(); | |
338 }); | |
314 } | 339 } |
315 | 340 |
316 { | 341 { |
317 toolbar->addAction(QIcon(":/icons/16x16/cross-button.png"), tr("&Discard all")); | 342 toolbar->addAction(QIcon(":/icons/16x16/cross-button.png"), tr("&Discard all")); |
318 } | 343 } |
333 line->setLineWidth(1); | 358 line->setLineWidth(1); |
334 layout->addWidget(line); | 359 layout->addWidget(line); |
335 } | 360 } |
336 | 361 |
337 { | 362 { |
338 QTreeView* treeview = new QTreeView(this); | 363 treeview = new QTreeView(this); |
339 treeview->setUniformRowHeights(true); | 364 treeview->setUniformRowHeights(true); |
340 treeview->setAllColumnsShowFocus(false); | 365 treeview->setAllColumnsShowFocus(false); |
341 treeview->setAlternatingRowColors(true); | 366 treeview->setAlternatingRowColors(true); |
342 treeview->setSortingEnabled(true); | 367 treeview->setSortingEnabled(true); |
343 treeview->setSelectionMode(QAbstractItemView::ExtendedSelection); | 368 treeview->setSelectionMode(QAbstractItemView::ExtendedSelection); |
357 | 382 |
358 layout->addWidget(treeview); | 383 layout->addWidget(treeview); |
359 } | 384 } |
360 } | 385 } |
361 | 386 |
387 void TorrentsPage::DownloadSelection() { | |
388 /* we only want one of these at a time, because if we don't | |
389 * we have the possibility of going into Multithreading Hell | |
390 */ | |
391 static QThread* thread = nullptr; | |
392 | |
393 if (!model || thread) | |
394 return; | |
395 | |
396 const QItemSelection selection = sort_model->mapSelectionToSource(treeview->selectionModel()->selection()); | |
397 | |
398 thread = QThread::create([this, selection] { | |
399 model->DownloadTorrents(selection); | |
400 }); | |
401 | |
402 connect(thread, &QThread::finished, thread, &QThread::deleteLater); | |
403 connect(thread, &QThread::finished, this, [&] { thread = nullptr; }); | |
404 | |
405 thread->start(); | |
406 } | |
407 | |
362 void TorrentsPage::Refresh() { | 408 void TorrentsPage::Refresh() { |
363 if (!model) | 409 if (!model) |
364 return; | 410 return; |
365 model->RefreshTorrentList(); | 411 |
412 HTTP::GetThread* thread = new HTTP::GetThread(session.config.torrents.feed_link); | |
413 | |
414 connect(thread, &HTTP::GetThread::ReceivedData, this, [&](const QByteArray& ba) { | |
415 /* This is to make sure we aren't in a different thread | |
416 * messing around with GUI stuff | |
417 */ | |
418 treeview->setUpdatesEnabled(false); | |
419 model->ParseTorrentList(ba); | |
420 treeview->setUpdatesEnabled(true); | |
421 }); | |
422 connect(thread, &QThread::finished, thread, &QThread::deleteLater); | |
423 | |
424 thread->start(); | |
366 } | 425 } |
367 | 426 |
368 #include "gui/pages/moc_torrents.cpp" | 427 #include "gui/pages/moc_torrents.cpp" |