Mercurial > minori
comparison src/gui/pages/torrents.cc @ 258:862d0d8619f6
*: HUUUGE changes
animia has been renamed to animone, so instead of thinking of a
health condition, you think of a beautiful flower :)
I've also edited some of the code for animone, but I have no idea
if it even works or not because I don't have a mac or windows
machine lying around. whoops!
... anyway, all of the changes divergent from Anisthesia are now
licensed under BSD. it's possible that I could even rewrite most
of the code to where I don't even have to keep the MIT license,
but that's thinking too far into the future
I've been slacking off on implementing the anime seasons page,
mostly out of laziness. I think I'd have to create another db file
specifically for the seasons
anyway, this code is being pushed *primarily* because the hard drive
it's on is failing! yay :)
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Mon, 01 Apr 2024 02:43:44 -0400 |
parents | c130f47f6f48 |
children | dd211ff68b36 |
comparison
equal
deleted
inserted
replaced
257:699a20c57dc8 | 258:862d0d8619f6 |
---|---|
1 #include "gui/pages/torrents.h" | 1 #include "gui/pages/torrents.h" |
2 #include "core/strings.h" | 2 #include "core/filesystem.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 "core/strings.h" |
6 #include "gui/widgets/text.h" | 6 #include "gui/widgets/text.h" |
7 #include "track/media.h" | 7 #include "track/media.h" |
8 | 8 |
9 #include <QByteArray> | |
10 #include <QDataStream> | |
11 #include <QDebug> | |
9 #include <QHeaderView> | 12 #include <QHeaderView> |
10 #include <QVBoxLayout> | 13 #include <QThread> |
11 #include <QToolBar> | 14 #include <QToolBar> |
12 #include <QTreeView> | 15 #include <QTreeView> |
13 #include <QByteArray> | 16 #include <QVBoxLayout> |
14 #include <QDataStream> | 17 |
15 #include <QThread> | 18 #include <algorithm> |
16 #include <QDebug> | 19 #include <fstream> |
17 | |
18 #include <iostream> | 20 #include <iostream> |
19 #include <sstream> | 21 #include <sstream> |
20 #include <fstream> | 22 |
21 #include <algorithm> | 23 #include "anitomy/anitomy.h" |
22 | |
23 #include "pugixml.hpp" | 24 #include "pugixml.hpp" |
24 #include "anitomy/anitomy.h" | |
25 | 25 |
26 /* This file is very, very similar to the anime list page. | 26 /* This file is very, very similar to the anime list page. |
27 * | 27 * |
28 * It differs from Taiga in that it uses tabs instead of | 28 * It differs from Taiga in that it uses tabs instead of |
29 * those "groups", but those are custom painted and a pain in the ass to | 29 * those "groups", but those are custom painted and a pain in the ass to |
30 * maintain over multiple platforms. | 30 * maintain over multiple platforms. |
31 */ | 31 */ |
32 | 32 |
33 TorrentsPageListSortFilter::TorrentsPageListSortFilter(QObject* parent) : QSortFilterProxyModel(parent) { | 33 TorrentsPageListSortFilter::TorrentsPageListSortFilter(QObject* parent) : QSortFilterProxyModel(parent) { |
34 } | 34 } |
35 | 35 |
36 bool TorrentsPageListSortFilter::lessThan(const QModelIndex& l, const QModelIndex& r) const { | 36 bool TorrentsPageListSortFilter::lessThan(const QModelIndex& l, const QModelIndex& r) const { |
84 return HTTP::Get(session.config.torrents.feed_link); | 84 return HTTP::Get(session.config.torrents.feed_link); |
85 } | 85 } |
86 | 86 |
87 void TorrentsPageListModel::ParseFeedDescription(const std::string& description, Torrent& torrent) { | 87 void TorrentsPageListModel::ParseFeedDescription(const std::string& description, Torrent& torrent) { |
88 /* Parse description... */ | 88 /* Parse description... */ |
89 enum class Keys { SIZE, AUTHORIZED, SUBMITTER, COMMENT }; | 89 enum class Keys { |
90 SIZE, | |
91 AUTHORIZED, | |
92 SUBMITTER, | |
93 COMMENT | |
94 }; | |
90 | 95 |
91 const std::unordered_map<std::string, Keys> KeyMap = { | 96 const std::unordered_map<std::string, Keys> KeyMap = { |
92 {"Size", Keys::SIZE}, | 97 {"Size", Keys::SIZE }, |
93 {"Authorized", Keys::AUTHORIZED}, | 98 {"Authorized", Keys::AUTHORIZED}, |
94 {"Submitter", Keys::SUBMITTER}, | 99 {"Submitter", Keys::SUBMITTER }, |
95 {"Comment", Keys::COMMENT} | 100 {"Comment", Keys::COMMENT } |
96 }; | 101 }; |
97 | 102 |
98 /* Parse size from description */ | 103 /* Parse size from description */ |
99 std::istringstream descstream(description); | 104 std::istringstream descstream(description); |
100 | 105 |
101 for (std::string line; std::getline(descstream, line);) { | 106 for (std::string line; std::getline(descstream, line);) { |
105 | 110 |
106 const std::string key = line.substr(0, pos); | 111 const std::string key = line.substr(0, pos); |
107 const std::string value = line.substr(line.find_first_not_of(": ", pos)); | 112 const std::string value = line.substr(line.find_first_not_of(": ", pos)); |
108 | 113 |
109 switch (KeyMap.at(key)) { | 114 switch (KeyMap.at(key)) { |
110 case Keys::COMMENT: | 115 case Keys::COMMENT: torrent.SetDescription(value); break; |
111 torrent.SetDescription(value); | 116 case Keys::SIZE: torrent.SetSize(Strings::HumanReadableSizeToBytes(value)); break; |
112 break; | |
113 case Keys::SIZE: | |
114 torrent.SetSize(Strings::HumanReadableSizeToBytes(value)); | |
115 break; | |
116 case Keys::AUTHORIZED: | 117 case Keys::AUTHORIZED: |
117 if (torrent.GetGroup().empty() && value != "N/A") | 118 if (torrent.GetGroup().empty() && value != "N/A") |
118 torrent.SetGroup(value); | 119 torrent.SetGroup(value); |
119 break; | 120 break; |
120 default: | 121 default: break; |
121 break; | |
122 } | 122 } |
123 } | 123 } |
124 } | 124 } |
125 | 125 |
126 void TorrentsPageListModel::ParseTorrentList(const QByteArray& ba) { | 126 void TorrentsPageListModel::ParseTorrentList(const QByteArray& ba) { |
149 | 149 |
150 const auto& elements = anitomy.elements(); | 150 const auto& elements = anitomy.elements(); |
151 | 151 |
152 /* todo: patch Anitomy so that it doesn't use wide strings */ | 152 /* todo: patch Anitomy so that it doesn't use wide strings */ |
153 torrent.SetTitle(Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle))); | 153 torrent.SetTitle(Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle))); |
154 torrent.SetEpisode(Strings::RemoveLeadingChars(Strings::ToUtf8String(elements.get(anitomy::kElementEpisodeNumber)), '0')); | 154 torrent.SetEpisode( |
155 Strings::RemoveLeadingChars(Strings::ToUtf8String(elements.get(anitomy::kElementEpisodeNumber)), '0')); | |
155 torrent.SetGroup(Strings::ToUtf8String(elements.get(anitomy::kElementReleaseGroup))); | 156 torrent.SetGroup(Strings::ToUtf8String(elements.get(anitomy::kElementReleaseGroup))); |
156 torrent.SetResolution(Strings::ToUtf8String(elements.get(anitomy::kElementVideoResolution))); | 157 torrent.SetResolution(Strings::ToUtf8String(elements.get(anitomy::kElementVideoResolution))); |
157 } | 158 } |
158 | 159 |
159 ParseFeedDescription(Strings::TextifySynopsis(item.child_value("description")), torrent); | 160 ParseFeedDescription(Strings::TextifySynopsis(item.child_value("description")), torrent); |
227 bool TorrentsPageListModel::setData(const QModelIndex& index, const QVariant& value, int role) { | 228 bool TorrentsPageListModel::setData(const QModelIndex& index, const QVariant& value, int role) { |
228 TorrentModelItem& item = list.at(index.row()); | 229 TorrentModelItem& item = list.at(index.row()); |
229 | 230 |
230 if (index.column() == 0) { | 231 if (index.column() == 0) { |
231 switch (role) { | 232 switch (role) { |
232 case Qt::EditRole: | 233 case Qt::EditRole: return false; |
233 return false; | |
234 case Qt::CheckStateRole: | 234 case Qt::CheckStateRole: |
235 item.SetChecked(value.toBool()); | 235 item.SetChecked(value.toBool()); |
236 emit dataChanged(index, index); | 236 emit dataChanged(index, index); |
237 return true; | 237 return true; |
238 } | 238 } |
267 case Qt::UserRole: | 267 case Qt::UserRole: |
268 switch (index.column()) { | 268 switch (index.column()) { |
269 case TL_EPISODE: return Strings::ToInt(item.GetEpisode(), -1); | 269 case TL_EPISODE: return Strings::ToInt(item.GetEpisode(), -1); |
270 /* We have to use this to work around some stupid | 270 /* We have to use this to work around some stupid |
271 * "conversion ambiguous" error on Linux | 271 * "conversion ambiguous" error on Linux |
272 */ | 272 */ |
273 case TL_SIZE: return QVariant::fromValue(item.GetSize()); | 273 case TL_SIZE: return QVariant::fromValue(item.GetSize()); |
274 default: return data(index, Qt::DisplayRole); | 274 default: return data(index, Qt::DisplayRole); |
275 } | 275 } |
276 break; | 276 break; |
277 case Qt::SizeHintRole: { | 277 case Qt::SizeHintRole: { |
329 toolbar->setMovable(false); | 329 toolbar->setMovable(false); |
330 | 330 |
331 { | 331 { |
332 /* this needs to be stored somewhere to replicate Taiga's | 332 /* this needs to be stored somewhere to replicate Taiga's |
333 "timer" feature */ | 333 "timer" feature */ |
334 toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("&Check new torrents"), [this] { | 334 toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("&Check new torrents"), |
335 Refresh(); | 335 [this] { Refresh(); }); |
336 }); | |
337 } | 336 } |
338 | 337 |
339 toolbar->addSeparator(); | 338 toolbar->addSeparator(); |
340 | 339 |
341 { | 340 { |
342 toolbar->addAction(QIcon(":/icons/16x16/navigation-270-button.png"), tr("Download &marked torrents"), [this] { | 341 toolbar->addAction(QIcon(":/icons/16x16/navigation-270-button.png"), tr("Download &marked torrents"), |
343 DownloadSelection(); | 342 [this] { DownloadSelection(); }); |
344 }); | 343 } |
345 } | 344 |
346 | 345 { toolbar->addAction(QIcon(":/icons/16x16/cross-button.png"), tr("&Discard all")); } |
347 { | |
348 toolbar->addAction(QIcon(":/icons/16x16/cross-button.png"), tr("&Discard all")); | |
349 } | |
350 | 346 |
351 toolbar->addSeparator(); | 347 toolbar->addSeparator(); |
352 | 348 |
353 { | 349 { toolbar->addAction(QIcon(":/icons/16x16/gear.png"), tr("&Settings")); } |
354 toolbar->addAction(QIcon(":/icons/16x16/gear.png"), tr("&Settings")); | |
355 } | |
356 | 350 |
357 layout->addWidget(toolbar); | 351 layout->addWidget(toolbar); |
358 } | 352 } |
359 | 353 |
360 { | 354 { |
385 sort_model->setSortCaseSensitivity(Qt::CaseInsensitive); | 379 sort_model->setSortCaseSensitivity(Qt::CaseInsensitive); |
386 treeview->setModel(sort_model); | 380 treeview->setModel(sort_model); |
387 } | 381 } |
388 | 382 |
389 // set column sizes | 383 // set column sizes |
390 treeview->setColumnWidth(TorrentsPageListModel::TL_TITLE, 240); | 384 treeview->setColumnWidth(TorrentsPageListModel::TL_TITLE, 240); |
391 treeview->setColumnWidth(TorrentsPageListModel::TL_EPISODE, 60); | 385 treeview->setColumnWidth(TorrentsPageListModel::TL_EPISODE, 60); |
392 treeview->setColumnWidth(TorrentsPageListModel::TL_GROUP, 100); | 386 treeview->setColumnWidth(TorrentsPageListModel::TL_GROUP, 100); |
393 treeview->setColumnWidth(TorrentsPageListModel::TL_SIZE, 70); | 387 treeview->setColumnWidth(TorrentsPageListModel::TL_SIZE, 70); |
394 treeview->setColumnWidth(TorrentsPageListModel::TL_RESOLUTION, 100); | 388 treeview->setColumnWidth(TorrentsPageListModel::TL_RESOLUTION, 100); |
395 treeview->setColumnWidth(TorrentsPageListModel::TL_SEEDERS, 20); | 389 treeview->setColumnWidth(TorrentsPageListModel::TL_SEEDERS, 20); |
396 treeview->setColumnWidth(TorrentsPageListModel::TL_LEECHERS, 20); | 390 treeview->setColumnWidth(TorrentsPageListModel::TL_LEECHERS, 20); |
397 treeview->setColumnWidth(TorrentsPageListModel::TL_DOWNLOADS, 20); | 391 treeview->setColumnWidth(TorrentsPageListModel::TL_DOWNLOADS, 20); |
398 treeview->setColumnWidth(TorrentsPageListModel::TL_DESCRIPTION, 200); | 392 treeview->setColumnWidth(TorrentsPageListModel::TL_DESCRIPTION, 200); |
399 treeview->setColumnWidth(TorrentsPageListModel::TL_FILENAME, 200); | 393 treeview->setColumnWidth(TorrentsPageListModel::TL_FILENAME, 200); |
400 treeview->setColumnWidth(TorrentsPageListModel::TL_RELEASEDATE, 190); | 394 treeview->setColumnWidth(TorrentsPageListModel::TL_RELEASEDATE, 190); |
401 | 395 |
402 treeview->header()->setStretchLastSection(false); | 396 treeview->header()->setStretchLastSection(false); |
403 | 397 |
404 layout->addWidget(treeview); | 398 layout->addWidget(treeview); |
421 HTTP::GetThread* thread = new HTTP::GetThread(session.config.torrents.feed_link); | 415 HTTP::GetThread* thread = new HTTP::GetThread(session.config.torrents.feed_link); |
422 | 416 |
423 connect(thread, &HTTP::GetThread::ReceivedData, this, [&](const QByteArray& ba) { | 417 connect(thread, &HTTP::GetThread::ReceivedData, this, [&](const QByteArray& ba) { |
424 /* This is to make sure we aren't in a different thread | 418 /* This is to make sure we aren't in a different thread |
425 * messing around with GUI stuff | 419 * messing around with GUI stuff |
426 */ | 420 */ |
427 treeview->setUpdatesEnabled(false); | 421 treeview->setUpdatesEnabled(false); |
428 model->ParseTorrentList(ba); | 422 model->ParseTorrentList(ba); |
429 treeview->setUpdatesEnabled(true); | 423 treeview->setUpdatesEnabled(true); |
430 }); | 424 }); |
431 connect(thread, &QThread::finished, thread, &QThread::deleteLater); | 425 connect(thread, &QThread::finished, thread, &QThread::deleteLater); |