MythTV master
netutils.cpp
Go to the documentation of this file.
1#include "netutils.h"
2
3#include <QDir>
4#include <QFileInfo>
5
6#include "libmythbase/mythcorecontext.h" // for GetHostName
10
11bool findTreeGrabberInDB(const QString& commandline,
13{
15 query.prepare("SELECT * FROM internetcontent WHERE "
16 "commandline = :COMMAND AND host = :HOST "
17 "AND type = :TYPE AND tree = 1;");
18 QFileInfo fi(commandline);
19 query.bindValue(":COMMAND", fi.fileName());
20 query.bindValue(":HOST", gCoreContext->GetHostName());
21 query.bindValue(":TYPE", type);
22 if (!query.exec() || !query.isActive())
23 {
24 MythDB::DBError("Tree find in db", query);
25 return false;
26 }
27
28 return query.size() > 0;
29}
30
31bool findSearchGrabberInDB(const QString& commandline,
33{
35 query.prepare("SELECT * FROM internetcontent WHERE "
36 "commandline = :COMMAND AND host = :HOST "
37 "AND type = :TYPE AND search = 1;");
38 QFileInfo fi(commandline);
39 query.bindValue(":COMMAND", fi.fileName());
40 query.bindValue(":HOST", gCoreContext->GetHostName());
41 query.bindValue(":TYPE", type);
42 if (!query.exec() || !query.isActive())
43 {
44 MythDB::DBError("Search find in db", query);
45 return false;
46 }
47
48 return query.size() > 0;
49}
50
51GrabberScript* findTreeGrabberByCommand(const QString& commandline,
53{
55 query.prepare("SELECT name,thumbnail,author,description,commandline,"
56 "version,search,tree FROM internetcontent "
57 "WHERE commandline = :COMMAND AND "
58 "host = :HOST AND type = :TYPE "
59 "AND tree = 1;");
60 QFileInfo fi(commandline);
61 query.bindValue(":COMMAND", fi.fileName());
62 query.bindValue(":HOST", gCoreContext->GetHostName());
63 query.bindValue(":TYPE", type);
64 if (!query.exec() || !query.isActive()) {
65 MythDB::DBError("Tree find in db", query);
66 }
67
68 QString title = query.value(0).toString();
69 QString image = query.value(1).toString();
70 QString author = query.value(2).toString();
71 QString desc = query.value(3).toString();
72 QString command = QString("%1/internetcontent/%2")
73 .arg(GetShareDir(), query.value(4).toString());
74 double ver = query.value(5).toDouble();
75 bool search = query.value(6).toBool();
76 bool tree = query.value(7).toBool();
77
78 auto *tmp = new GrabberScript(title, image, type, author, search,
79 tree, desc, command, ver);
80 return tmp;
81}
82
83GrabberScript* findSearchGrabberByCommand(const QString& commandline,
85{
87 query.prepare("SELECT name,thumbnail,author,description,commandline,"
88 "version,search,tree FROM internetcontent "
89 "WHERE commandline = :COMMAND AND "
90 "type = :TYPE AND host = :HOST AND "
91 "search = 1;");
92 QFileInfo fi(commandline);
93 query.bindValue(":COMMAND", fi.fileName());
94 query.bindValue(":HOST", gCoreContext->GetHostName());
95 query.bindValue(":TYPE", type);
96 if (!query.exec() || !query.isActive()) {
97 MythDB::DBError("Search find in db", query);
98 }
99
100 QString title = query.value(0).toString();
101 QString image = query.value(1).toString();
102 QString author = query.value(2).toString();
103 QString desc = query.value(3).toString();
104 QString command = QString("%1/internetcontent/%2")
105 .arg(GetShareDir(), query.value(4).toString());
106 double ver = query.value(5).toDouble();
107 bool search = query.value(6).toBool();
108 bool tree = query.value(7).toBool();
109
110 auto *tmp = new GrabberScript(title, image, type, author, search,
111 tree, desc, command, ver);
112 return tmp;
113}
114
116{
118 query.prepare("SELECT DISTINCT name,thumbnail,type,"
119 "author,description,commandline,"
120 "version,search,tree FROM internetcontent "
121 "where tree = 1 ORDER BY name;");
122 if (!query.exec() || !query.isActive()) {
123 MythDB::DBError("Tree find in db", query);
124 }
125
127
128 while (query.next())
129 {
130 QString title = query.value(0).toString();
131 QString image = query.value(1).toString();
132 ArticleType type = (ArticleType)query.value(2).toInt();
133 QString author = query.value(3).toString();
134 QString desc = query.value(4).toString();
135 QString commandline = QString("%1/internetcontent/%2")
136 .arg(GetShareDir(), query.value(5).toString());
137 double ver = query.value(6).toDouble();
138 bool search = query.value(7).toBool();
139 bool tree = query.value(8).toBool();
140
141 auto *script = new GrabberScript(title, image, type, author, search,
142 tree, desc, commandline, ver);
143 tmp.append(script);
144 }
145
146 return tmp;
147}
148
150{
152 query.prepare("SELECT name,thumbnail,author,description,commandline,"
153 "version,search,tree FROM internetcontent "
154 "WHERE host = :HOST AND type = :TYPE "
155 "AND tree = 1 ORDER BY name;");
156 query.bindValue(":HOST", gCoreContext->GetHostName());
157 query.bindValue(":TYPE", type);
158 if (!query.exec() || !query.isActive()) {
159 MythDB::DBError("Tree find in db", query);
160 }
161
163
164 while (query.next())
165 {
166 QString title = query.value(0).toString();
167 QString image = query.value(1).toString();
168 QString author = query.value(2).toString();
169 QString desc = query.value(3).toString();
170 QString commandline = QString("%1/internetcontent/%2")
171 .arg(GetShareDir(), query.value(4).toString());
172 double ver = query.value(5).toDouble();
173 bool search = query.value(6).toBool();
174 bool tree = query.value(7).toBool();
175
176 auto *script = new GrabberScript(title, image, type, author, search,
177 tree, desc, commandline, ver);
178 tmp.append(script);
179 }
180
181 return tmp;
182}
183
185{
187 query.prepare("SELECT name,thumbnail,author,description,commandline,"
188 "version,search,tree FROM internetcontent "
189 "WHERE host = :HOST AND type = :TYPE "
190 "AND search = 1 ORDER BY name;");
191 query.bindValue(":HOST", gCoreContext->GetHostName());
192 query.bindValue(":TYPE", type);
193 if (!query.exec() || !query.isActive()) {
194 MythDB::DBError("Search find in db", query);
195 }
196
198
199 while (query.next())
200 {
201 QString title = query.value(0).toString();
202 QString image = query.value(1).toString();
203 QString author = query.value(2).toString();
204 QString desc = query.value(3).toString();
205 QString commandline = QString("%1/internetcontent/%2")
206 .arg(GetShareDir(), query.value(4).toString());
207 double ver = query.value(5).toDouble();
208 bool search = query.value(6).toBool();
209 bool tree = query.value(7).toBool();
210
211 auto *script = new GrabberScript(title, image, type, author, search,
212 tree, desc, commandline, ver);
213 tmp.append(script);
214 }
215
216 return tmp;
217}
218
220{
221 if (!script)
222 return false;
223
224 return insertGrabberInDB(script->GetTitle(), script->GetImage(),
225 type, script->GetAuthor(), script->GetDescription(),
226 script->GetCommandline(), script->GetVersion(),
227 true, false, false);
228}
229
231{
232 if (!script)
233 return false;
234
235 return insertGrabberInDB(script->GetTitle(), script->GetImage(),
236 type, script->GetAuthor(), script->GetDescription(),
237 script->GetCommandline(), script->GetVersion(),
238 false, true, false);
239}
240
241bool insertGrabberInDB(const QString &name, const QString &thumbnail,
242 ArticleType type, const QString &author,
243 const QString &description, const QString &commandline,
244 const double version, bool search, bool tree,
245 bool podcast)
246{
247 QFileInfo fi(thumbnail);
248 QString thumbbase = fi.fileName();
249
251 query.prepare("INSERT INTO internetcontent (name,thumbnail,type,author,"
252 "description,commandline,version,search,tree,podcast,"
253 "host) "
254 "VALUES( :NAME, :THUMBNAIL, :TYPE, :AUTHOR, :DESCRIPTION, :COMMAND, "
255 ":VERSION, :SEARCH, :TREE, :PODCAST, :HOST);");
256 query.bindValue(":NAME", name);
257 query.bindValue(":THUMBNAIL", thumbbase);
258 query.bindValue(":TYPE", type);
259 query.bindValue(":AUTHOR", author);
260 query.bindValue(":DESCRIPTION", description);
261 QFileInfo cmd(commandline);
262 query.bindValue(":COMMAND", cmd.fileName());
263 query.bindValue(":VERSION", version);
264 query.bindValue(":SEARCH", search);
265 query.bindValue(":TREE", tree);
266 query.bindValue(":PODCAST", podcast);
267 query.bindValue(":HOST", gCoreContext->GetHostName());
268 if (!query.exec() || !query.isActive()) {
269 MythDB::DBError("netcontent: inserting in DB", query);
270 return false;
271 }
272
273 return (query.numRowsAffected() > 0);
274}
275
277{
278 if (!script) return false;
279
280 return removeGrabberFromDB(script->GetCommandline(), false);
281}
282
284{
285 if (!script) return false;
286
287 return removeGrabberFromDB(script->GetCommandline(), true);
288}
289
290bool removeGrabberFromDB(const QString &commandline, const bool search)
291{
293 if (search)
294 {
295 query.prepare("DELETE FROM internetcontent WHERE commandline = :COMMAND "
296 "AND host = :HOST AND search = 1;");
297 }
298 else
299 {
300 query.prepare("DELETE FROM internetcontent WHERE commandline = :COMMAND "
301 "AND host = :HOST AND search = 0;");
302 }
303 QFileInfo fi(commandline);
304 query.bindValue(":COMMAND", fi.fileName());
305 query.bindValue(":HOST", gCoreContext->GetHostName());
306 if (!query.exec() || !query.isActive()) {
307 MythDB::DBError("netcontent: delete from db", query);
308 return false;
309 }
310
311 return (query.numRowsAffected() > 0);
312}
313
314bool markTreeUpdated(GrabberScript* script, const QDateTime& curTime)
315{
317 query.prepare("UPDATE internetcontent SET updated = :UPDATED "
318 "WHERE commandline = :COMMAND AND tree = 1;");
319 query.bindValue(":UPDATED", curTime);
320 QFileInfo fi(script->GetCommandline());
321 query.bindValue(":COMMAND", fi.fileName());
322 if (!query.exec() || !query.isActive()) {
323 MythDB::DBError("netcontent: update db time", query);
324 return false;
325 }
326
327 return (query.numRowsAffected() > 0);
328}
329
330bool needsUpdate(GrabberScript* script, std::chrono::hours updateFreq)
331{
332 QDateTime now = MythDate::current();
333 QDateTime then = lastUpdate(script);
334
335 return then.addSecs(duration_cast<std::chrono::seconds>(updateFreq).count()) < now;
336}
337
338QDateTime lastUpdate(GrabberScript* script)
339{
340 QDateTime updated;
342 query.prepare("SELECT updated "
343 "FROM internetcontent "
344 "WHERE commandline = :COMMAND ORDER "
345 "BY updated DESC LIMIT 1;");
346 QFileInfo fi(script->GetCommandline());
347 query.bindValue(":COMMAND", fi.fileName());
348 if (!query.exec() || !query.isActive())
349 {
350 MythDB::DBError("Tree last update in db", query);
351 }
352 else if (query.next())
353 {
354 updated = MythDate::as_utc(query.value(0).toDateTime());
355 }
356
357 return updated;
358}
359
360bool clearTreeItems(const QString &feedcommand)
361{
362 if (feedcommand.isEmpty())
363 return false;
364
366 query.prepare("DELETE FROM internetcontentarticles "
367 "WHERE feedtitle = :FEEDTITLE AND podcast = 0;");
368 query.bindValue(":FEEDTITLE", feedcommand);
369
370 if (!query.exec() || !query.isActive())
371 {
372 MythDB::DBError("netcontent: clearing DB", query);
373 return false;
374 }
375
376 return (query.numRowsAffected() > 0);
377}
378
379bool isTreeInUse(const QString &feedcommand)
380{
381 if (feedcommand.isEmpty())
382 return false;
383
385 query.prepare("SELECT * FROM internetcontent "
386 "WHERE commandline = :COMMAND;");
387 QFileInfo fi(feedcommand);
388 query.bindValue(":COMMAND", fi.fileName());
389
390 if (!query.exec() || !query.isActive())
391 {
392 MythDB::DBError("netcontent: isTreeInUse", query);
393 return false;
394 }
395
396 return query.next();
397}
398
399bool insertTreeArticleInDB(const QString &feedtitle, const QString &path,
400 const QString &paththumb, ResultItem *item,
402{
403 if (!item || feedtitle.isEmpty() || path.isEmpty())
404 return false;
405
407 query.prepare("INSERT INTO internetcontentarticles (feedtitle, path, paththumb, "
408 " title, subtitle, description, url, type, thumbnail, mediaURL, author, "
409 "date, time, rating, filesize, player, playerargs, download, "
410 "downloadargs, width, height, language, podcast, downloadable, "
411 "customhtml, countries, season, episode) "
412 "VALUES( :FEEDTITLE, :PATH, :PATHTHUMB, :TITLE, :SUBTITLE, :DESCRIPTION, "
413 ":URL, :TYPE, :THUMBNAIL, :MEDIAURL, :AUTHOR, :DATE, :TIME, :RATING, "
414 ":FILESIZE, :PLAYER, :PLAYERARGS, :DOWNLOAD, :DOWNLOADARGS, :WIDTH, :HEIGHT, "
415 ":LANGUAGE, :PODCAST, :DOWNLOADABLE, :CUSTOMHTML, :COUNTRIES, :SEASON, "
416 ":EPISODE);");
417 query.bindValue(":FEEDTITLE", feedtitle);
418 query.bindValue(":PATH", path);
419 query.bindValue(":PATHTHUMB", paththumb);
420 query.bindValue(":TITLE", item->GetTitle());
421 query.bindValueNoNull(":SUBTITLE", item->GetSubtitle());
422 query.bindValue(":DESCRIPTION", item->GetDescription());
423 query.bindValue(":URL", item->GetURL());
424 query.bindValue(":TYPE", type);
425 query.bindValue(":THUMBNAIL", item->GetThumbnail());
426 query.bindValue(":MEDIAURL", item->GetMediaURL());
427 query.bindValue(":AUTHOR", item->GetAuthor());
428 query.bindValue(":DATE", item->GetDate());
429 QString time;
430 if (item->GetTime().isEmpty())
431 time = QString::number(0);
432 else
433 time = item->GetTime();
434 query.bindValue(":TIME", time);
435 query.bindValue(":RATING", item->GetRating());
436 query.bindValue(":FILESIZE", (qulonglong)item->GetFilesize());
437 query.bindValueNoNull(":PLAYER", item->GetPlayer());
438 query.bindValue(":PLAYERARGS", item->GetPlayerArguments().isEmpty() ? "" :
439 item->GetPlayerArguments().join(" "));
440 query.bindValueNoNull(":DOWNLOAD", item->GetDownloader());
441 query.bindValue(":DOWNLOADARGS", item->GetDownloaderArguments().isEmpty() ? "" :
442 item->GetDownloaderArguments().join(" "));
443 query.bindValue(":WIDTH", item->GetWidth());
444 query.bindValue(":HEIGHT", item->GetHeight());
445 query.bindValueNoNull(":LANGUAGE", item->GetLanguage());
446 query.bindValue(":PODCAST", false);
447 query.bindValue(":DOWNLOADABLE", item->GetDownloadable());
448 query.bindValue(":CUSTOMHTML", item->GetCustomHTML());
449 query.bindValue(":COUNTRIES", item->GetCountries().isEmpty() ? "" :
450 item->GetCountries().join(" "));
451 query.bindValue(":SEASON", item->GetSeason());
452 query.bindValue(":EPISODE", item->GetEpisode());
453
454 if (!query.exec() || !query.isActive())
455 {
456 MythDB::DBError("netcontent: inserting article in DB", query);
457 return false;
458 }
459
460 return (query.numRowsAffected() > 0);
461}
462
463QMultiMap<QPair<QString,QString>, ResultItem*> getTreeArticles(const QString &feedtitle,
465{
466 QMultiMap<QPair<QString,QString>, ResultItem*> ret;
467
469 query.prepare("SELECT title, subtitle, description, url, "
470 "type, thumbnail, mediaURL, author, date, time, "
471 "rating, filesize, player, playerargs, download, "
472 "downloadargs, width, height, language, "
473 "downloadable, customhtml, countries, season, episode, "
474 "path, paththumb FROM internetcontentarticles "
475 "WHERE feedtitle = :FEEDTITLE AND podcast = 0 "
476 "AND type = :TYPE ORDER BY title DESC;");
477 query.bindValue(":FEEDTITLE", feedtitle);
478 query.bindValue(":TYPE", type);
479 if (!query.exec() || !query.isActive())
480 {
481 MythDB::DBError("Tree find in db", query);
482 return ret;
483 }
484
485 while (query.next())
486 {
487 QString title = query.value(0).toString();
488 QString subtitle = query.value(1).toString();
489 QString desc = query.value(2).toString();
490 QString URL = query.value(3).toString();
491// QString feedtype = query.value(4).toString();
492 QString thumbnail = query.value(5).toString();
493 QString mediaURL = query.value(6).toString();
494 QString author = query.value(7).toString();
495 QDateTime date = MythDate::as_utc(query.value(8).toDateTime());
496 QString time = query.value(9).toString();
497 QString rating = query.value(10).toString();
498 off_t filesize = query.value(11).toULongLong();
499 QString player = query.value(12).toString();
500 QStringList playerargs = query.value(13).toString().split(" ");
501 QString download = query.value(14).toString();
502 QStringList downloadargs = query.value(15).toString().split(" ");
503 uint width = query.value(16).toUInt();
504 uint height = query.value(17).toUInt();
505 QString language = query.value(18).toString();
506 bool downloadable = query.value(19).toBool();
507 bool customhtml = query.value(20).toBool();
508 QStringList countries = query.value(21).toString().split(" ");
509 uint season = query.value(22).toUInt();
510 uint episode = query.value(23).toUInt();
511
512 QString path = query.value(24).toString();
513 QString paththumb = query.value(25).toString();
514
515 QPair<QString,QString> pair(path,paththumb);
516 ret.insert(pair, new ResultItem(title, QString(),
517 subtitle, QString(), desc, URL,
518 thumbnail, mediaURL, author, date, time, rating, filesize,
519 player, playerargs, download, downloadargs,
520 width, height, language, downloadable, countries,
521 season, episode, customhtml));
522 }
523
524 return ret;
525}
526
527bool findInDB(const QString& url, ArticleType type)
528{
530 query.prepare("SELECT commandline FROM internetcontent WHERE commandline = :URL AND "
531 "type = :TYPE AND podcast = 1;");
532 query.bindValue(":URL", url);
533 query.bindValue(":TYPE", type);
534 if (!query.exec() || !query.isActive()) {
535 MythDB::DBError("RSS find in db", query);
536 return false;
537 }
538
539 return query.size() > 0;
540}
541
542RSSSite* findByURL(const QString& url, ArticleType type)
543{
544 RSSSite *tmp = nullptr;
546 query.prepare("SELECT name,thumbnail,author,description,"
547 "commandline,download,updated FROM internetcontent "
548 "WHERE commandline = :URL AND type = :TYPE "
549 "AND podcast = 1;");
550 query.bindValue(":URL", url);
551 query.bindValue(":TYPE", type);
552 if (!query.exec() || !query.next())
553 {
554 MythDB::DBError("RSS find in db", query);
555 tmp = new RSSSite(QString(), QString(),
556 QString(), (ArticleType)0, QString(),
557 QString(), QString(), false,
558 QDateTime());
559 }
560 else
561 {
562 QString title = query.value(0).toString();
563 QString image = query.value(1).toString();
564 QString author = query.value(2).toString();
565 QString description = query.value(3).toString();
566 QString outurl = query.value(4).toString();
567 bool download = query.value(5).toBool();
568 QDateTime updated; query.value(6).toDate();
569
570 tmp = new RSSSite(title, QString(), image, type, description,
571 outurl, author, download, updated);
572 }
573
574 return tmp;
575}
576
578{
580
582 query.prepare(
583 "SELECT name, thumbnail, description, commandline, author, "
584 "download, updated FROM internetcontent WHERE podcast = 1 "
585 "AND type = :TYPE ORDER BY name");
586
587 query.bindValue(":TYPE", type);
588
589 if (!query.exec())
590 {
591 return tmp;
592 }
593
594 while (query.next())
595 {
596 QString title = query.value(0).toString();
597 QString image = query.value(1).toString();
598 QString description = query.value(2).toString();
599 QString url = query.value(3).toString();
600 QString author = query.value(4).toString();
601 bool download = query.value(5).toBool();
602 QDateTime updated; query.value(6).toDate();
603 tmp.append(new RSSSite(title, QString(), image, type, description, url,
604 author, download, updated));
605 }
606
607 return tmp;
608}
609
611{
613
615 query.prepare(
616 "SELECT name, thumbnail, type, description, commandline, author, "
617 "download, updated FROM internetcontent WHERE podcast = 1 "
618 "ORDER BY name");
619
620 if (!query.exec())
621 {
622 return tmp;
623 }
624
625 while (query.next())
626 {
627 QString title = query.value(0).toString();
628 QString image = query.value(1).toString();
629 ArticleType type = (ArticleType)query.value(2).toInt();
630 QString description = query.value(3).toString();
631 QString url = query.value(4).toString();
632 QString author = query.value(5).toString();
633 bool download = query.value(6).toBool();
634 QDateTime updated; query.value(7).toDate();
635 tmp.append(new RSSSite(title, QString(),
636 image, type, description, url,
637 author, download, updated));
638 }
639
640 return tmp;
641}
642
644{
645 if (!site) return false;
646
647 return insertInDB(site->GetTitle(), site->GetSortTitle(), site->GetImage(),
648 site->GetDescription(), site->GetURL(),
649 site->GetAuthor(), site->GetDownload(),
650 site->GetUpdated(), site->GetType());
651}
652
653bool insertInDB(const QString &name,
654 [[maybe_unused]] const QString &sortname,
655 const QString &thumbnail,
656 const QString &description, const QString &url,
657 const QString &author, const bool download,
658 const QDateTime &updated, ArticleType type)
659{
660 if (findInDB(name, type))
661 return false;
662
664 query.prepare("INSERT INTO internetcontent (name,thumbnail,description,"
665 "commandline,author,download,updated,podcast, type) "
666 "VALUES( :NAME, :THUMBNAIL, :DESCRIPTION, :URL, :AUTHOR, :DOWNLOAD, "
667 ":UPDATED, :PODCAST, :TYPE);");
668 query.bindValue(":NAME", name);
669 // query.bindValue(":SORTNAME", sortname);
670 query.bindValue(":THUMBNAIL", thumbnail);
671 query.bindValue(":DESCRIPTION", description);
672 query.bindValue(":URL", url);
673 query.bindValue(":AUTHOR", author);
674 query.bindValue(":DOWNLOAD", download);
675 query.bindValue(":UPDATED", updated);
676 query.bindValue(":PODCAST", true);
677 query.bindValue(":TYPE", type);
678 if (!query.exec() || !query.isActive()) {
679 MythDB::DBError("netcontent: inserting in DB", query);
680 return false;
681 }
682
683 return (query.numRowsAffected() > 0);
684}
685
687{
688 if (!site) return false;
689
690 return removeFromDB(site->GetURL(), site->GetType());
691}
692
693bool removeFromDB(const QString &url, ArticleType type)
694{
696 query.prepare("DELETE FROM internetcontent WHERE commandline = :URL "
697 "AND type = :TYPE;");
698 query.bindValue(":URL", url);
699 query.bindValue(":TYPE", type);
700 if (!query.exec() || !query.isActive()) {
701 MythDB::DBError("netcontent: delete from db", query);
702 return false;
703 }
704
705 return (query.numRowsAffected() > 0);
706}
707
709{
710 QDateTime now = MythDate::current();
711
713 query.prepare("UPDATE internetcontent SET updated = :UPDATED "
714 "WHERE commandline = :URL AND type = :TYPE;");
715 query.bindValue(":UPDATED", now);
716 query.bindValue(":URL", site->GetURL());
717 query.bindValue(":TYPE", site->GetType());
718 if (!query.exec() || !query.isActive())
719 MythDB::DBError("netcontent update time", query);
720}
721
722bool clearRSSArticles(const QString &feedtitle, ArticleType type)
723{
724 if (feedtitle.isEmpty())
725 return false;
726
728 query.prepare("DELETE FROM internetcontentarticles "
729 "WHERE feedtitle = :FEEDTITLE AND podcast = 1 "
730 "AND type = :TYPE ;");
731 query.bindValue(":FEEDTITLE", feedtitle);
732 query.bindValue(":TYPE", type);
733
734 if (!query.exec() || !query.isActive()) {
735 MythDB::DBError("netcontent: clearing DB", query);
736 return false;
737 }
738
739 return (query.numRowsAffected() > 0);
740}
741
742bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item,
744{
745 if (!item || feedtitle.isEmpty())
746 return false;
747
749 query.prepare("INSERT INTO internetcontentarticles (feedtitle, title, "
750 "description, url, type, thumbnail, mediaURL, author, date, time, "
751 "rating, filesize, player, playerargs, download, "
752 "downloadargs, width, height, language, downloadable, countries, "
753 "podcast) "
754 "VALUES( :FEEDTITLE, :TITLE, :DESCRIPTION, :URL, :TYPE, :THUMBNAIL, "
755 ":MEDIAURL, :AUTHOR, :DATE, :TIME, :RATING, :FILESIZE, :PLAYER, "
756 ":PLAYERARGS, :DOWNLOAD, :DOWNLOADARGS, :WIDTH, :HEIGHT, "
757 ":LANGUAGE, :DOWNLOADABLE, :COUNTRIES, :PODCAST);");
758 query.bindValue(":FEEDTITLE", feedtitle);
759 query.bindValue(":TITLE", item->GetTitle());
760 //RSS articles don't have subtitles
761 query.bindValue(":DESCRIPTION", item->GetDescription());
762 query.bindValue(":URL", item->GetURL());
763 query.bindValue(":TYPE", type);
764 query.bindValue(":THUMBNAIL", item->GetThumbnail());
765 query.bindValue(":MEDIAURL", item->GetMediaURL());
766 query.bindValue(":AUTHOR", item->GetAuthor());
767 query.bindValue(":DATE", item->GetDate());
768 QString time;
769 if (item->GetTime().isEmpty())
770 time = QString::number(0);
771 else
772 time = item->GetTime();
773 query.bindValue(":TIME", time);
774 query.bindValue(":RATING", item->GetRating());
775 query.bindValue(":FILESIZE", (qulonglong)item->GetFilesize());
776 query.bindValueNoNull(":PLAYER", item->GetPlayer());
777 query.bindValue(":PLAYERARGS", item->GetPlayerArguments().isEmpty() ? "" :
778 item->GetPlayerArguments().join(" "));
779 query.bindValueNoNull(":DOWNLOAD", item->GetDownloader());
780 query.bindValue(":DOWNLOADARGS", item->GetDownloaderArguments().isEmpty() ? "" :
781 item->GetDownloaderArguments().join(" "));
782 query.bindValue(":WIDTH", item->GetWidth());
783 query.bindValue(":HEIGHT", item->GetHeight());
784 query.bindValueNoNull(":LANGUAGE", item->GetLanguage());
785 query.bindValue(":DOWNLOADABLE", item->GetDownloadable());
786 query.bindValue(":COUNTRIES", item->GetCountries());
787 query.bindValue(":PODCAST", true);
788
789 if (!query.exec() || !query.isActive()) {
790 MythDB::DBError("netcontent: inserting article in DB", query);
791 return false;
792 }
793
794 return (query.numRowsAffected() > 0);
795}
796
797ResultItem::resultList getRSSArticles(const QString &feedtitle,
799{
801
803 query.prepare("SELECT title, description, url, "
804 "thumbnail, mediaURL, author, date, time, "
805 "rating, filesize, player, playerargs, download, "
806 "downloadargs, width, height, language, "
807 "downloadable, countries, season, episode "
808 "FROM internetcontentarticles "
809 "WHERE feedtitle = :FEEDTITLE AND podcast = 1 "
810 "AND type = :TYPE ORDER BY date DESC;");
811 query.bindValue(":FEEDTITLE", feedtitle);
812 query.bindValue(":TYPE", type);
813 if (!query.exec() || !query.isActive()) {
814 MythDB::DBError("RSS find in db", query);
815 return ret;
816 }
817
818 while (query.next())
819 {
820 QString title = query.value(0).toString();
821 //RSS articles don't have subtitles
822 QString desc = query.value(1).toString();
823 QString URL = query.value(2).toString();
824 QString thumbnail = query.value(3).toString();
825 QString mediaURL = query.value(4).toString();
826 QString author = query.value(5).toString();
827 QDateTime date = MythDate::as_utc(query.value(6).toDateTime());
828 QString time = query.value(7).toString();
829 QString rating = query.value(8).toString();
830 off_t filesize = query.value(9).toULongLong();
831 QString player = query.value(10).toString();
832 QStringList playerargs = query.value(11).toString().split(" ");
833 QString download = query.value(12).toString();
834 QStringList downloadargs = query.value(13).toString().split(" ");
835 uint width = query.value(14).toUInt();
836 uint height = query.value(15).toUInt();
837 QString language = query.value(16).toString();
838 bool downloadable = query.value(17).toBool();
839 QStringList countries = query.value(18).toString().split(" ");
840 uint season = query.value(19).toUInt();
841 uint episode = query.value(20).toUInt();
842
843 ret.append(new ResultItem(title, QString(), QString(),
844 QString(), desc, URL, thumbnail,
845 mediaURL, author, date, time, rating, filesize,
846 player, playerargs, download, downloadargs,
847 width, height, language, downloadable, countries,
848 season, episode, false));
849 }
850
851 return ret;
852}
853
854QString GetDownloadFilename(const QString& title, const QString& url)
855{
856 QByteArray urlarr(url.toLatin1());
857 QByteArray titlearr(title.toLatin1());
858#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
859 quint16 urlChecksum = qChecksum(urlarr.data(), urlarr.length());
860 quint16 titleChecksum = qChecksum(titlearr.data(), titlearr.length());
861#else
862 quint16 urlChecksum = qChecksum(urlarr);
863 quint16 titleChecksum = qChecksum(titlearr);
864#endif
865 QUrl qurl(url);
866 QString ext = QFileInfo(qurl.path()).suffix();
867 QString basefilename = QString("download_%1_%2.%3")
868 .arg(QString::number(urlChecksum), QString::number(titleChecksum), ext);
869
870 return basefilename;
871}
const double & GetVersion() const
const QString & GetAuthor() const
QList< GrabberScript * > scriptList
const QString & GetCommandline() const
const QString & GetDescription() const
const QString & GetImage() const
const QString & GetTitle() const
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837
QVariant value(int i) const
Definition: mythdbcon.h:204
int size(void) const
Definition: mythdbcon.h:214
int numRowsAffected() const
Definition: mythdbcon.h:217
bool isActive(void) const
Definition: mythdbcon.h:215
void bindValueNoNull(const QString &placeholder, const QVariant &val)
Add a single binding, taking care not to set a NULL value.
Definition: mythdbcon.cpp:902
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
QString GetHostName(void)
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
const QString & GetImage() const
Definition: rssmanager.h:57
QList< RSSSite * > rssList
Definition: rssmanager.h:53
const ArticleType & GetType() const
Definition: rssmanager.h:58
const QString & GetAuthor() const
Definition: rssmanager.h:61
const QString & GetTitle() const
Definition: rssmanager.h:55
const QDateTime & GetUpdated() const
Definition: rssmanager.h:63
const bool & GetDownload() const
Definition: rssmanager.h:62
const QString & GetSortTitle() const
Definition: rssmanager.h:56
const QString & GetDescription() const
Definition: rssmanager.h:59
const QString & GetURL() const
Definition: rssmanager.h:60
const QString & GetDownloader() const
Definition: rssparse.h:149
const QString & GetPlayer() const
Definition: rssparse.h:147
const bool & GetCustomHTML() const
Definition: rssparse.h:158
const uint & GetWidth() const
Definition: rssparse.h:151
const QString & GetURL() const
Definition: rssparse.h:139
const QString & GetThumbnail() const
Definition: rssparse.h:140
const QString & GetDescription() const
Definition: rssparse.h:138
const QString & GetAuthor() const
Definition: rssparse.h:142
const QString & GetMediaURL() const
Definition: rssparse.h:141
const QString & GetLanguage() const
Definition: rssparse.h:153
const uint & GetHeight() const
Definition: rssparse.h:152
const QDateTime & GetDate() const
Definition: rssparse.h:143
const QStringList & GetPlayerArguments() const
Definition: rssparse.h:148
const QString & GetTime() const
Definition: rssparse.h:144
const QString & GetRating() const
Definition: rssparse.h:145
const QStringList & GetCountries() const
Definition: rssparse.h:155
const uint & GetEpisode() const
Definition: rssparse.h:157
const QString & GetTitle() const
Definition: rssparse.h:134
const QStringList & GetDownloaderArguments() const
Definition: rssparse.h:150
const off_t & GetFilesize() const
Definition: rssparse.h:146
const bool & GetDownloadable() const
Definition: rssparse.h:154
const QString & GetSubtitle() const
Definition: rssparse.h:136
const uint & GetSeason() const
Definition: rssparse.h:156
QList< ResultItem * > resultList
Definition: rssparse.h:114
unsigned int uint
Definition: compat.h:68
static guint32 * tmp
Definition: goom_core.cpp:26
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString GetShareDir(void)
Definition: mythdirs.cpp:261
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:28
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
string version
Definition: giantbomb.py:185
def rating(profile, smoonURL, gate)
Definition: scan.py:36
GrabberScript::scriptList findAllDBSearchGrabbers(ArticleType type)
Definition: netutils.cpp:184
bool removeGrabberFromDB(const QString &commandline, const bool search)
Definition: netutils.cpp:290
bool markTreeUpdated(GrabberScript *script, const QDateTime &curTime)
Definition: netutils.cpp:314
bool findTreeGrabberInDB(const QString &commandline, ArticleType type)
Definition: netutils.cpp:11
bool removeFromDB(RSSSite *site)
Definition: netutils.cpp:686
QMultiMap< QPair< QString, QString >, ResultItem * > getTreeArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:463
bool insertGrabberInDB(const QString &name, const QString &thumbnail, ArticleType type, const QString &author, const QString &description, const QString &commandline, const double version, bool search, bool tree, bool podcast)
Definition: netutils.cpp:241
GrabberScript * findSearchGrabberByCommand(const QString &commandline, ArticleType type)
Definition: netutils.cpp:83
RSSSite * findByURL(const QString &url, ArticleType type)
Definition: netutils.cpp:542
bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item, ArticleType type)
Definition: netutils.cpp:742
ResultItem::resultList getRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:797
bool removeTreeFromDB(GrabberScript *script)
Definition: netutils.cpp:276
bool needsUpdate(GrabberScript *script, std::chrono::hours updateFreq)
Definition: netutils.cpp:330
GrabberScript * findTreeGrabberByCommand(const QString &commandline, ArticleType type)
Definition: netutils.cpp:51
bool insertTreeArticleInDB(const QString &feedtitle, const QString &path, const QString &paththumb, ResultItem *item, ArticleType type)
Definition: netutils.cpp:399
bool clearTreeItems(const QString &feedcommand)
Definition: netutils.cpp:360
GrabberScript::scriptList findAllDBTreeGrabbersByHost(ArticleType type)
Definition: netutils.cpp:149
GrabberScript::scriptList findAllDBTreeGrabbers()
Definition: netutils.cpp:115
bool isTreeInUse(const QString &feedcommand)
Definition: netutils.cpp:379
bool findInDB(const QString &url, ArticleType type)
Definition: netutils.cpp:527
RSSSite::rssList findAllDBRSSByType(ArticleType type)
Definition: netutils.cpp:577
QString GetDownloadFilename(const QString &title, const QString &url)
Definition: netutils.cpp:854
RSSSite::rssList findAllDBRSS()
Definition: netutils.cpp:610
bool insertInDB(RSSSite *site)
Definition: netutils.cpp:643
void markUpdated(RSSSite *site)
Definition: netutils.cpp:708
bool findSearchGrabberInDB(const QString &commandline, ArticleType type)
Definition: netutils.cpp:31
QDateTime lastUpdate(GrabberScript *script)
Definition: netutils.cpp:338
bool removeSearchFromDB(GrabberScript *script)
Definition: netutils.cpp:283
bool insertTreeInDB(GrabberScript *script, ArticleType type)
Definition: netutils.cpp:230
bool clearRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:722
bool insertSearchInDB(GrabberScript *script, ArticleType type)
Definition: netutils.cpp:219
ArticleType
Definition: rssparse.h:20