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
7 #include "libmythbase/mythdate.h"
8 #include "libmythbase/mythdb.h"
9 #include "libmythbase/mythdirs.h"
10 
11 bool 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 
31 bool 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 
51 GrabberScript* 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 
83 GrabberScript* 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 {
117  MSqlQuery query(MSqlQuery::InitCon());
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 {
151  MSqlQuery query(MSqlQuery::InitCon());
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 {
186  MSqlQuery query(MSqlQuery::InitCon());
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 
241 bool 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 
250  MSqlQuery query(MSqlQuery::InitCon());
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 
290 bool removeGrabberFromDB(const QString &commandline, const bool search)
291 {
292  MSqlQuery query(MSqlQuery::InitCon());
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 
314 bool markTreeUpdated(GrabberScript* script, const QDateTime& curTime)
315 {
316  MSqlQuery query(MSqlQuery::InitCon());
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 
330 bool 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 
338 QDateTime lastUpdate(GrabberScript* script)
339 {
340  QDateTime updated;
341  MSqlQuery query(MSqlQuery::InitCon());
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 
360 bool clearTreeItems(const QString &feedcommand)
361 {
362  if (feedcommand.isEmpty())
363  return false;
364 
365  MSqlQuery query(MSqlQuery::InitCon());
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 
379 bool isTreeInUse(const QString &feedcommand)
380 {
381  if (feedcommand.isEmpty())
382  return false;
383 
384  MSqlQuery query(MSqlQuery::InitCon());
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 
399 bool 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 
406  MSqlQuery query(MSqlQuery::InitCon());
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 
463 QMultiMap<QPair<QString,QString>, ResultItem*> getTreeArticles(const QString &feedtitle,
465 {
466  QMultiMap<QPair<QString,QString>, ResultItem*> ret;
467 
468  MSqlQuery query(MSqlQuery::InitCon());
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 
527 bool findInDB(const QString& url, ArticleType type)
528 {
529  MSqlQuery query(MSqlQuery::InitCon());
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 
542 RSSSite* findByURL(const QString& url, ArticleType type)
543 {
544  RSSSite *tmp = nullptr;
545  MSqlQuery query(MSqlQuery::InitCon());
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 
581  MSqlQuery query(MSqlQuery::InitCon());
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 
614  MSqlQuery query(MSqlQuery::InitCon());
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 
643 bool insertInDB(RSSSite* site)
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 
653 bool 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 
663  MSqlQuery query(MSqlQuery::InitCon());
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 
693 bool removeFromDB(const QString &url, ArticleType type)
694 {
695  MSqlQuery query(MSqlQuery::InitCon());
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 
708 void markUpdated(RSSSite *site)
709 {
710  QDateTime now = MythDate::current();
711 
712  MSqlQuery query(MSqlQuery::InitCon());
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 
722 bool clearRSSArticles(const QString &feedtitle, ArticleType type)
723 {
724  if (feedtitle.isEmpty())
725  return false;
726 
727  MSqlQuery query(MSqlQuery::InitCon());
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 
742 bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item,
744 {
745  if (!item || feedtitle.isEmpty())
746  return false;
747 
748  MSqlQuery query(MSqlQuery::InitCon());
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 
797 ResultItem::resultList getRSSArticles(const QString &feedtitle,
799 {
801 
802  MSqlQuery query(MSqlQuery::InitCon());
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 
854 QString 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 }
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
needsUpdate
bool needsUpdate(GrabberScript *script, std::chrono::hours updateFreq)
Definition: netutils.cpp:330
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
ResultItem::GetFilesize
const off_t & GetFilesize() const
Definition: rssparse.h:146
MSqlQuery::bindValueNoNull
void bindValueNoNull(const QString &placeholder, const QVariant &val)
Add a single binding, taking care not to set a NULL value.
Definition: mythdbcon.cpp:902
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:214
GrabberScript::GetAuthor
const QString & GetAuthor() const
Definition: netgrabbermanager.h:43
insertTreeArticleInDB
bool insertTreeArticleInDB(const QString &feedtitle, const QString &path, const QString &paththumb, ResultItem *item, ArticleType type)
Definition: netutils.cpp:399
insertInDB
bool insertInDB(RSSSite *site)
Definition: netutils.cpp:643
GetDownloadFilename
QString GetDownloadFilename(const QString &title, const QString &url)
Definition: netutils.cpp:854
RSSSite::GetDownload
const bool & GetDownload() const
Definition: rssmanager.h:62
findTreeGrabberByCommand
GrabberScript * findTreeGrabberByCommand(const QString &commandline, ArticleType type)
Definition: netutils.cpp:51
findInDB
bool findInDB(const QString &url, ArticleType type)
Definition: netutils.cpp:527
GrabberScript::GetCommandline
const QString & GetCommandline() const
Definition: netgrabbermanager.h:47
mythdb.h
RSSSite::GetSortTitle
const QString & GetSortTitle() const
Definition: rssmanager.h:56
findAllDBSearchGrabbers
GrabberScript::scriptList findAllDBSearchGrabbers(ArticleType type)
Definition: netutils.cpp:184
MythDate::as_utc
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:28
ResultItem::GetPlayer
const QString & GetPlayer() const
Definition: rssparse.h:147
markUpdated
void markUpdated(RSSSite *site)
Definition: netutils.cpp:708
ResultItem::GetTitle
const QString & GetTitle() const
Definition: rssparse.h:134
GrabberScript::GetImage
const QString & GetImage() const
Definition: netgrabbermanager.h:41
RSSSite::GetType
const ArticleType & GetType() const
Definition: rssmanager.h:58
ResultItem::GetCustomHTML
const bool & GetCustomHTML() const
Definition: rssparse.h:158
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
GrabberScript::GetDescription
const QString & GetDescription() const
Definition: netgrabbermanager.h:46
RSSSite::GetDescription
const QString & GetDescription() const
Definition: rssmanager.h:59
GrabberScript::GetTitle
const QString & GetTitle() const
Definition: netgrabbermanager.h:40
findAllDBRSSByType
RSSSite::rssList findAllDBRSSByType(ArticleType type)
Definition: netutils.cpp:577
insertRSSArticleInDB
bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item, ArticleType type)
Definition: netutils.cpp:742
ResultItem::GetCountries
const QStringList & GetCountries() const
Definition: rssparse.h:155
mythdirs.h
findSearchGrabberInDB
bool findSearchGrabberInDB(const QString &commandline, ArticleType type)
Definition: netutils.cpp:31
findAllDBTreeGrabbers
GrabberScript::scriptList findAllDBTreeGrabbers()
Definition: netutils.cpp:115
getTreeArticles
QMultiMap< QPair< QString, QString >, ResultItem * > getTreeArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:463
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
markTreeUpdated
bool markTreeUpdated(GrabberScript *script, const QDateTime &curTime)
Definition: netutils.cpp:314
GrabberScript::scriptList
QList< GrabberScript * > scriptList
Definition: netgrabbermanager.h:52
findTreeGrabberInDB
bool findTreeGrabberInDB(const QString &commandline, ArticleType type)
Definition: netutils.cpp:11
ResultItem::GetAuthor
const QString & GetAuthor() const
Definition: rssparse.h:142
mythdate.h
ResultItem::GetRating
const QString & GetRating() const
Definition: rssparse.h:145
ResultItem::GetThumbnail
const QString & GetThumbnail() const
Definition: rssparse.h:140
ResultItem::GetDate
const QDateTime & GetDate() const
Definition: rssparse.h:143
ResultItem::GetWidth
const uint & GetWidth() const
Definition: rssparse.h:151
removeFromDB
bool removeFromDB(RSSSite *site)
Definition: netutils.cpp:686
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
GetShareDir
QString GetShareDir(void)
Definition: mythdirs.cpp:261
insertGrabberInDB
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
hardwareprofile.scan.rating
def rating(profile, smoonURL, gate)
Definition: scan.py:36
ResultItem::GetDownloader
const QString & GetDownloader() const
Definition: rssparse.h:149
netutils.h
ResultItem::GetTime
const QString & GetTime() const
Definition: rssparse.h:144
insertSearchInDB
bool insertSearchInDB(GrabberScript *script, ArticleType type)
Definition: netutils.cpp:219
ResultItem::GetLanguage
const QString & GetLanguage() const
Definition: rssparse.h:153
ResultItem::GetSeason
const uint & GetSeason() const
Definition: rssparse.h:156
GrabberScript
Definition: netgrabbermanager.h:17
isTreeInUse
bool isTreeInUse(const QString &feedcommand)
Definition: netutils.cpp:379
ResultItem::GetSubtitle
const QString & GetSubtitle() const
Definition: rssparse.h:136
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
RSSSite::GetAuthor
const QString & GetAuthor() const
Definition: rssmanager.h:61
GrabberScript::GetVersion
const double & GetVersion() const
Definition: netgrabbermanager.h:48
off_t
#define off_t
Definition: mythiowrapper.cpp:241
removeGrabberFromDB
bool removeGrabberFromDB(const QString &commandline, const bool search)
Definition: netutils.cpp:290
ResultItem::GetDescription
const QString & GetDescription() const
Definition: rssparse.h:138
ArticleType
ArticleType
Definition: rssparse.h:20
findSearchGrabberByCommand
GrabberScript * findSearchGrabberByCommand(const QString &commandline, ArticleType type)
Definition: netutils.cpp:83
ResultItem::GetPlayerArguments
const QStringList & GetPlayerArguments() const
Definition: rssparse.h:148
ResultItem::GetEpisode
const uint & GetEpisode() const
Definition: rssparse.h:157
RSSSite::GetUpdated
const QDateTime & GetUpdated() const
Definition: rssmanager.h:63
findAllDBRSS
RSSSite::rssList findAllDBRSS()
Definition: netutils.cpp:610
lastUpdate
QDateTime lastUpdate(GrabberScript *script)
Definition: netutils.cpp:338
RSSSite::GetImage
const QString & GetImage() const
Definition: rssmanager.h:57
ResultItem::GetURL
const QString & GetURL() const
Definition: rssparse.h:139
clearTreeItems
bool clearTreeItems(const QString &feedcommand)
Definition: netutils.cpp:360
mythcorecontext.h
ResultItem
Definition: rssparse.h:109
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
RSSSite::GetTitle
const QString & GetTitle() const
Definition: rssmanager.h:55
findByURL
RSSSite * findByURL(const QString &url, ArticleType type)
Definition: netutils.cpp:542
insertTreeInDB
bool insertTreeInDB(GrabberScript *script, ArticleType type)
Definition: netutils.cpp:230
ResultItem::resultList
QList< ResultItem * > resultList
Definition: rssparse.h:114
MSqlQuery::numRowsAffected
int numRowsAffected() const
Definition: mythdbcon.h:217
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:844
removeTreeFromDB
bool removeTreeFromDB(GrabberScript *script)
Definition: netutils.cpp:276
clearRSSArticles
bool clearRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:722
getRSSArticles
ResultItem::resultList getRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:797
ResultItem::GetDownloaderArguments
const QStringList & GetDownloaderArguments() const
Definition: rssparse.h:150
ResultItem::GetDownloadable
const bool & GetDownloadable() const
Definition: rssparse.h:154
nv_python_libs.bbciplayer.bbciplayer_api.version
string version
Definition: bbciplayer_api.py:77
RSSSite::GetURL
const QString & GetURL() const
Definition: rssmanager.h:60
removeSearchFromDB
bool removeSearchFromDB(GrabberScript *script)
Definition: netutils.cpp:283
RSSSite
Definition: rssmanager.h:21
findAllDBTreeGrabbersByHost
GrabberScript::scriptList findAllDBTreeGrabbersByHost(ArticleType type)
Definition: netutils.cpp:149
ResultItem::GetHeight
const uint & GetHeight() const
Definition: rssparse.h:152
RSSSite::rssList
QList< RSSSite * > rssList
Definition: rssmanager.h:53
ResultItem::GetMediaURL
const QString & GetMediaURL() const
Definition: rssparse.h:141
uint
unsigned int uint
Definition: freesurround.h:24
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837