comparison src/gui/pages/torrents.cc @ 367:8d45d892be88 default tip

*: instead of pugixml, use Qt XML features this means we have one extra Qt dependency though...
author Paper <paper@tflc.us>
date Sun, 17 Nov 2024 22:55:47 -0500
parents a0aa8c8c4307
children
comparison
equal deleted inserted replaced
366:886f66775f31 367:8d45d892be88
14 #include <QToolBar> 14 #include <QToolBar>
15 #include <QTreeView> 15 #include <QTreeView>
16 #include <QVBoxLayout> 16 #include <QVBoxLayout>
17 #include <QtGlobal> 17 #include <QtGlobal>
18 18
19 #include <QDomDocument>
20
19 #include <algorithm> 21 #include <algorithm>
20 #include <fstream> 22 #include <fstream>
21 #include <iostream> 23 #include <iostream>
22 #include <sstream> 24 #include <sstream>
23 25
24 #include "anitomy/anitomy.h" 26 #include "anitomy/anitomy.h"
25 #include "pugixml.hpp"
26 27
27 /* This file is very, very similar to the anime list page. 28 /* This file is very, very similar to the anime list page.
28 * 29 *
29 * It differs from Taiga in that it uses tabs instead of 30 * It differs from Taiga in that it uses tabs instead of
30 * those "groups", but those are custom painted and a pain in the ass to 31 * those "groups", but those are custom painted and a pain in the ass to
124 } 125 }
125 } 126 }
126 } 127 }
127 128
128 void TorrentsPageListModel::ParseTorrentList(const QByteArray& ba) { 129 void TorrentsPageListModel::ParseTorrentList(const QByteArray& ba) {
129 std::istringstream stdstream(Strings::ToUtf8String(ba)); 130 QDomDocument doc;
130 131 QDomNode node;
131 pugi::xml_document doc; 132 QDomNodeList node_nodes;
132 if (!doc.load(stdstream)) 133 {
133 return; // peace out 134 QString err;
135 int err_ln;
136 int err_col;
137
138 if (!doc.setContent(ba, &err, &err_ln, &err_col)) {
139 session.SetStatusBar(Strings::ToUtf8String(tr("Torrents: Failed to parse XML with error %1 at line %2, column %3").arg(err, QString::number(err_ln), QString::number(err_col))));
140 return; // peace out
141 }
142 }
134 143
135 /* my extra special dumb hack. */ 144 /* my extra special dumb hack. */
136 if (!rowCount(index(0))) { 145 if (!rowCount(index(0))) {
137 beginInsertRows(QModelIndex(), 0, 0); 146 beginInsertRows(QModelIndex(), 0, 0);
138 endInsertRows(); 147 endInsertRows();
139 } 148 }
140 149
141 beginResetModel(); 150 beginResetModel();
142 151
143 list.clear(); 152 list.clear();
144 /* this is just an rss parser; it should be in a separate class... */ 153
145 for (pugi::xml_node item : doc.child("rss").child("channel").children("item")) { 154 node = doc;
155
156 for (const auto& n : {"rss", "channel"}) {
157 node = node.namedItem(n);
158 if (node.isNull()) { std::cout << n << std::endl; goto end; }
159 }
160
161 if (!node.hasChildNodes()) { std::cout << "no child nodes" << std::endl; goto end; }
162
163 node_nodes = node.childNodes();
164
165 for (int c = 0; c < node_nodes.count(); c++) {
166 const QDomNode item = node_nodes.at(c);
167 if (!item.isElement() || item.nodeName() != "item")
168 continue;
169
170 const QDomNode title = item.namedItem("title");
171 if (!title.isElement()) continue;
172 const QDomNode description = item.namedItem("description");
173 if (!description.isElement()) continue;
174 const QDomNode link = item.namedItem("link");
175 if (!link.isElement()) continue;
176 const QDomNode guid = item.namedItem("guid");
177 if (!guid.isElement()) continue;
178 const QDomNode pubDate = item.namedItem("pubDate");
179 if (!pubDate.isElement()) continue;
180
146 TorrentModelItem torrent; 181 TorrentModelItem torrent;
147 torrent.SetFilename(item.child_value("title")); /* "title" == filename */ 182 torrent.SetFilename(Strings::ToUtf8String(title.toElement().text())); /* "title" == filename */
148 { 183 {
149 anitomy::Anitomy anitomy; 184 anitomy::Anitomy anitomy;
150 anitomy.Parse(torrent.GetFilename()); 185 anitomy.Parse(torrent.GetFilename());
151 186
152 const auto& elements = anitomy.elements(); 187 const auto& elements = anitomy.elements();
158 torrent.SetEpisode(episode); 193 torrent.SetEpisode(episode);
159 torrent.SetGroup(Strings::ToUtf8String(elements.get(anitomy::kElementReleaseGroup))); 194 torrent.SetGroup(Strings::ToUtf8String(elements.get(anitomy::kElementReleaseGroup)));
160 torrent.SetResolution(Strings::ToUtf8String(elements.get(anitomy::kElementVideoResolution))); 195 torrent.SetResolution(Strings::ToUtf8String(elements.get(anitomy::kElementVideoResolution)));
161 } 196 }
162 197
163 std::string description = item.child_value("description"); 198 std::string description_s = Strings::ToUtf8String(description.toElement().text());
164 Strings::TextifySynopsis(description); 199 Strings::TextifySynopsis(description_s);
165 ParseFeedDescription(description, torrent); 200 ParseFeedDescription(description_s, torrent);
166 201
167 torrent.SetLink(item.child_value("link")); 202 torrent.SetLink(Strings::ToUtf8String(link.toElement().text()));
168 torrent.SetGuid(item.child_value("guid")); 203 torrent.SetGuid(Strings::ToUtf8String(guid.toElement().text()));
169 { 204 torrent.SetDate(QDateTime::fromString(pubDate.toElement().text(), "ddd, dd MMM yyyy HH:mm:ss t"));
170 const QString date_str = Strings::ToQString(item.child_value("pubDate"));
171 torrent.SetDate(QDateTime::fromString(date_str, "ddd, dd MMM yyyy HH:mm:ss t"));
172 }
173 list.push_back(torrent); 205 list.push_back(torrent);
174 } 206 }
175 207
208 end:
176 endResetModel(); 209 endResetModel();
177 } 210 }
178 211
179 void TorrentsPageListModel::RefreshTorrentList() { 212 void TorrentsPageListModel::RefreshTorrentList() {
180 ParseTorrentList(DownloadTorrentList()); 213 ParseTorrentList(DownloadTorrentList());