diff 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
line wrap: on
line diff
--- a/src/gui/pages/torrents.cc	Wed Jan 10 21:23:57 2024 -0500
+++ b/src/gui/pages/torrents.cc	Sat Jan 13 09:42:02 2024 -0500
@@ -2,6 +2,7 @@
 #include "core/strings.h"
 #include "core/http.h"
 #include "core/session.h"
+#include "core/filesystem.h"
 #include "gui/widgets/text.h"
 #include "track/media.h"
 
@@ -11,11 +12,12 @@
 #include <QMainWindow>
 #include <QByteArray>
 #include <QDataStream>
-#include <QThreadPool>
+#include <QThread>
 #include <QDebug>
 
 #include <iostream>
 #include <sstream>
+#include <fstream>
 #include <algorithm>
 
 #include "pugixml.hpp"
@@ -50,6 +52,28 @@
 TorrentsPageListModel::TorrentsPageListModel(QObject* parent) : QAbstractListModel(parent) {
 }
 
+void TorrentsPageListModel::DownloadTorrents(QItemSelection selection) {
+	const auto indexes = selection.indexes();
+
+	for (const auto& index : indexes) {
+		/* a torrent file IS literally text... */
+		const std::string link = list.at(index.row()).GetLink();
+		const std::string filename = list.at(index.row()).GetFilename() + ".torrent";
+
+		const std::filesystem::path torrents_dir = Filesystem::GetTorrentsPath();
+		std::filesystem::create_directories(torrents_dir);
+
+		std::ofstream file(torrents_dir / filename, std::ofstream::out | std::ofstream::trunc);
+		if (!file)
+			return; // wat
+
+		const QByteArray data = HTTP::Get(link);
+		file.write(data.data(), data.size());
+
+		file.close();
+	}
+}
+
 QByteArray TorrentsPageListModel::DownloadTorrentList() {
 	return HTTP::Get(session.config.torrents.feed_link);
 }
@@ -231,14 +255,15 @@
 				case TL_DESCRIPTION: return Strings::ToQString(item.GetDescription());
 				case TL_FILENAME: return Strings::ToQString(item.GetFilename());
 				case TL_RELEASEDATE: return item.GetDate();
-				default: return "";
+				default: return {};
 			}
 			break;
 		case Qt::UserRole:
 			switch (index.column()) {
 				case TL_EPISODE: return Strings::ToInt(item.GetEpisode(), -1);
 				/* We have to use this to work around some stupid
-				   "conversion ambiguous" error on Linux */
+				 * "conversion ambiguous" error on Linux
+				*/
 				case TL_SIZE: return QVariant::fromValue(item.GetSize());
 				default: return data(index, Qt::DisplayRole);
 			}
@@ -300,17 +325,17 @@
 		{
 			/* this needs to be stored somewhere to replicate Taiga's
 			   "timer" feature */
-			toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("&Check new torrents"), [this]{
-				QThreadPool::globalInstance()->start([this] {
-					Refresh();
-				});
+			toolbar->addAction(QIcon(":/icons/16x16/arrow-circle-315.png"), tr("&Check new torrents"), [this] {
+				Refresh();
 			});
 		}
 
 		toolbar->addSeparator();
 
 		{
-			toolbar->addAction(QIcon(":/icons/16x16/navigation-270-button.png"), tr("Download &marked torrents"));
+			toolbar->addAction(QIcon(":/icons/16x16/navigation-270-button.png"), tr("Download &marked torrents"), [this] {
+				DownloadSelection();
+			});
 		}
 
 		{
@@ -335,7 +360,7 @@
 	}
 
 	{
-		QTreeView* treeview = new QTreeView(this);
+		treeview = new QTreeView(this);
 		treeview->setUniformRowHeights(true);
 		treeview->setAllColumnsShowFocus(false);
 		treeview->setAlternatingRowColors(true);
@@ -359,10 +384,44 @@
 	}
 }
 
+void TorrentsPage::DownloadSelection() {
+	/* we only want one of these at a time, because if we don't
+	 * we have the possibility of going into Multithreading Hell
+	*/
+	static QThread* thread = nullptr;
+
+	if (!model || thread)
+		return;
+
+	const QItemSelection selection = sort_model->mapSelectionToSource(treeview->selectionModel()->selection());
+
+	thread = QThread::create([this, selection] {
+		model->DownloadTorrents(selection);
+	});
+
+	connect(thread, &QThread::finished, thread, &QThread::deleteLater);
+	connect(thread, &QThread::finished, this, [&] { thread = nullptr; });
+
+	thread->start();
+}
+
 void TorrentsPage::Refresh() {
 	if (!model)
 		return;
-	model->RefreshTorrentList();
+
+	HTTP::GetThread* thread = new HTTP::GetThread(session.config.torrents.feed_link);
+
+	connect(thread, &HTTP::GetThread::ReceivedData, this, [&](const QByteArray& ba) {
+		/* This is to make sure we aren't in a different thread
+		 * messing around with GUI stuff
+		*/
+		treeview->setUpdatesEnabled(false);
+		model->ParseTorrentList(ba);
+		treeview->setUpdatesEnabled(true);
+	});
+	connect(thread, &QThread::finished, thread, &QThread::deleteLater);
+
+	thread->start();
 }
 
 #include "gui/pages/moc_torrents.cpp"