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" |
