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, const QString &sortname,
654  const QString &thumbnail,
655  const QString &description, const QString &url,
656  const QString &author, const bool download,
657  const QDateTime &updated, ArticleType type)
658 {
659  if (findInDB(name, type))
660  return false;
661 
662  MSqlQuery query(MSqlQuery::InitCon());
663  query.prepare("INSERT INTO internetcontent (name,thumbnail,description,"
664  "commandline,author,download,updated,podcast, type) "
665  "VALUES( :NAME, :THUMBNAIL, :DESCRIPTION, :URL, :AUTHOR, :DOWNLOAD, "
666  ":UPDATED, :PODCAST, :TYPE);");
667  query.bindValue(":NAME", name);
668  Q_UNUSED(sortname); // query.bindValue(":SORTNAME", sortname);
669  query.bindValue(":THUMBNAIL", thumbnail);
670  query.bindValue(":DESCRIPTION", description);
671  query.bindValue(":URL", url);
672  query.bindValue(":AUTHOR", author);
673  query.bindValue(":DOWNLOAD", download);
674  query.bindValue(":UPDATED", updated);
675  query.bindValue(":PODCAST", true);
676  query.bindValue(":TYPE", type);
677  if (!query.exec() || !query.isActive()) {
678  MythDB::DBError("netcontent: inserting in DB", query);
679  return false;
680  }
681 
682  return (query.numRowsAffected() > 0);
683 }
684 
686 {
687  if (!site) return false;
688 
689  return removeFromDB(site->GetURL(), site->GetType());
690 }
691 
692 bool removeFromDB(const QString &url, ArticleType type)
693 {
694  MSqlQuery query(MSqlQuery::InitCon());
695  query.prepare("DELETE FROM internetcontent WHERE commandline = :URL "
696  "AND type = :TYPE;");
697  query.bindValue(":URL", url);
698  query.bindValue(":TYPE", type);
699  if (!query.exec() || !query.isActive()) {
700  MythDB::DBError("netcontent: delete from db", query);
701  return false;
702  }
703 
704  return (query.numRowsAffected() > 0);
705 }
706 
707 void markUpdated(RSSSite *site)
708 {
709  QDateTime now = MythDate::current();
710 
711  MSqlQuery query(MSqlQuery::InitCon());
712  query.prepare("UPDATE internetcontent SET updated = :UPDATED "
713  "WHERE commandline = :URL AND type = :TYPE;");
714  query.bindValue(":UPDATED", now);
715  query.bindValue(":URL", site->GetURL());
716  query.bindValue(":TYPE", site->GetType());
717  if (!query.exec() || !query.isActive())
718  MythDB::DBError("netcontent update time", query);
719 }
720 
721 bool clearRSSArticles(const QString &feedtitle, ArticleType type)
722 {
723  if (feedtitle.isEmpty())
724  return false;
725 
726  MSqlQuery query(MSqlQuery::InitCon());
727  query.prepare("DELETE FROM internetcontentarticles "
728  "WHERE feedtitle = :FEEDTITLE AND podcast = 1 "
729  "AND type = :TYPE ;");
730  query.bindValue(":FEEDTITLE", feedtitle);
731  query.bindValue(":TYPE", type);
732 
733  if (!query.exec() || !query.isActive()) {
734  MythDB::DBError("netcontent: clearing DB", query);
735  return false;
736  }
737 
738  return (query.numRowsAffected() > 0);
739 }
740 
741 bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item,
743 {
744  if (!item || feedtitle.isEmpty())
745  return false;
746 
747  MSqlQuery query(MSqlQuery::InitCon());
748  query.prepare("INSERT INTO internetcontentarticles (feedtitle, title, "
749  "description, url, type, thumbnail, mediaURL, author, date, time, "
750  "rating, filesize, player, playerargs, download, "
751  "downloadargs, width, height, language, downloadable, countries, "
752  "podcast) "
753  "VALUES( :FEEDTITLE, :TITLE, :DESCRIPTION, :URL, :TYPE, :THUMBNAIL, "
754  ":MEDIAURL, :AUTHOR, :DATE, :TIME, :RATING, :FILESIZE, :PLAYER, "
755  ":PLAYERARGS, :DOWNLOAD, :DOWNLOADARGS, :WIDTH, :HEIGHT, "
756  ":LANGUAGE, :DOWNLOADABLE, :COUNTRIES, :PODCAST);");
757  query.bindValue(":FEEDTITLE", feedtitle);
758  query.bindValue(":TITLE", item->GetTitle());
759  //RSS articles don't have subtitles
760  query.bindValue(":DESCRIPTION", item->GetDescription());
761  query.bindValue(":URL", item->GetURL());
762  query.bindValue(":TYPE", type);
763  query.bindValue(":THUMBNAIL", item->GetThumbnail());
764  query.bindValue(":MEDIAURL", item->GetMediaURL());
765  query.bindValue(":AUTHOR", item->GetAuthor());
766  query.bindValue(":DATE", item->GetDate());
767  QString time;
768  if (item->GetTime().isEmpty())
769  time = QString::number(0);
770  else
771  time = item->GetTime();
772  query.bindValue(":TIME", time);
773  query.bindValue(":RATING", item->GetRating());
774  query.bindValue(":FILESIZE", (qulonglong)item->GetFilesize());
775  query.bindValueNoNull(":PLAYER", item->GetPlayer());
776  query.bindValue(":PLAYERARGS", item->GetPlayerArguments().isEmpty() ? "" :
777  item->GetPlayerArguments().join(" "));
778  query.bindValueNoNull(":DOWNLOAD", item->GetDownloader());
779  query.bindValue(":DOWNLOADARGS", item->GetDownloaderArguments().isEmpty() ? "" :
780  item->GetDownloaderArguments().join(" "));
781  query.bindValue(":WIDTH", item->GetWidth());
782  query.bindValue(":HEIGHT", item->GetHeight());
783  query.bindValueNoNull(":LANGUAGE", item->GetLanguage());
784  query.bindValue(":DOWNLOADABLE", item->GetDownloadable());
785  query.bindValue(":COUNTRIES", item->GetCountries());
786  query.bindValue(":PODCAST", true);
787 
788  if (!query.exec() || !query.isActive()) {
789  MythDB::DBError("netcontent: inserting article in DB", query);
790  return false;
791  }
792 
793  return (query.numRowsAffected() > 0);
794 }
795 
796 ResultItem::resultList getRSSArticles(const QString &feedtitle,
798 {
800 
801  MSqlQuery query(MSqlQuery::InitCon());
802  query.prepare("SELECT title, description, url, "
803  "thumbnail, mediaURL, author, date, time, "
804  "rating, filesize, player, playerargs, download, "
805  "downloadargs, width, height, language, "
806  "downloadable, countries, season, episode "
807  "FROM internetcontentarticles "
808  "WHERE feedtitle = :FEEDTITLE AND podcast = 1 "
809  "AND type = :TYPE ORDER BY date DESC;");
810  query.bindValue(":FEEDTITLE", feedtitle);
811  query.bindValue(":TYPE", type);
812  if (!query.exec() || !query.isActive()) {
813  MythDB::DBError("RSS find in db", query);
814  return ret;
815  }
816 
817  while (query.next())
818  {
819  QString title = query.value(0).toString();
820  //RSS articles don't have subtitles
821  QString desc = query.value(1).toString();
822  QString URL = query.value(2).toString();
823  QString thumbnail = query.value(3).toString();
824  QString mediaURL = query.value(4).toString();
825  QString author = query.value(5).toString();
826  QDateTime date = MythDate::as_utc(query.value(6).toDateTime());
827  QString time = query.value(7).toString();
828  QString rating = query.value(8).toString();
829  off_t filesize = query.value(9).toULongLong();
830  QString player = query.value(10).toString();
831  QStringList playerargs = query.value(11).toString().split(" ");
832  QString download = query.value(12).toString();
833  QStringList downloadargs = query.value(13).toString().split(" ");
834  uint width = query.value(14).toUInt();
835  uint height = query.value(15).toUInt();
836  QString language = query.value(16).toString();
837  bool downloadable = query.value(17).toBool();
838  QStringList countries = query.value(18).toString().split(" ");
839  uint season = query.value(19).toUInt();
840  uint episode = query.value(20).toUInt();
841 
842  ret.append(new ResultItem(title, QString(), QString(),
843  QString(), desc, URL, thumbnail,
844  mediaURL, author, date, time, rating, filesize,
845  player, playerargs, download, downloadargs,
846  width, height, language, downloadable, countries,
847  season, episode, false));
848  }
849 
850  return ret;
851 }
852 
853 QString GetDownloadFilename(const QString& title, const QString& url)
854 {
855  QByteArray urlarr(url.toLatin1());
856  QByteArray titlearr(title.toLatin1());
857 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
858  quint16 urlChecksum = qChecksum(urlarr.data(), urlarr.length());
859  quint16 titleChecksum = qChecksum(titlearr.data(), titlearr.length());
860 #else
861  quint16 urlChecksum = qChecksum(urlarr);
862  quint16 titleChecksum = qChecksum(titlearr);
863 #endif
864  QUrl qurl(url);
865  QString ext = QFileInfo(qurl.path()).suffix();
866  QString basefilename = QString("download_%1_%2.%3")
867  .arg(QString::number(urlChecksum), QString::number(titleChecksum), ext);
868 
869  return basefilename;
870 }
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:216
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:811
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
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:901
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:215
GrabberScript::GetAuthor
const QString & GetAuthor() const
Definition: netgrabbermanager.h:45
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:853
RSSSite::GetDownload
const bool & GetDownload() const
Definition: rssmanager.h:66
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:49
mythdb.h
RSSSite::GetSortTitle
const QString & GetSortTitle() const
Definition: rssmanager.h:60
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:27
ResultItem::GetPlayer
const QString & GetPlayer() const
Definition: rssparse.h:147
markUpdated
void markUpdated(RSSSite *site)
Definition: netutils.cpp:707
ResultItem::GetTitle
const QString & GetTitle() const
Definition: rssparse.h:134
GrabberScript::GetImage
const QString & GetImage() const
Definition: netgrabbermanager.h:43
RSSSite::GetType
const ArticleType & GetType() const
Definition: rssmanager.h:62
ResultItem::GetCustomHTML
const bool & GetCustomHTML() const
Definition: rssparse.h:158
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:617
GrabberScript::GetDescription
const QString & GetDescription() const
Definition: netgrabbermanager.h:48
RSSSite::GetDescription
const QString & GetDescription() const
Definition: rssmanager.h:63
GrabberScript::GetTitle
const QString & GetTitle() const
Definition: netgrabbermanager.h:42
findAllDBRSSByType
RSSSite::rssList findAllDBRSSByType(ArticleType type)
Definition: netutils.cpp:577
insertRSSArticleInDB
bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item, ArticleType type)
Definition: netutils.cpp:741
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:14
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:54
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:685
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:549
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:227
GetShareDir
QString GetShareDir(void)
Definition: mythdirs.cpp:222
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:39
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:19
isTreeInUse
bool isTreeInUse(const QString &feedcommand)
Definition: netutils.cpp:379
ResultItem::GetSubtitle
const QString & GetSubtitle() const
Definition: rssparse.h:136
uint
unsigned int uint
Definition: compat.h:81
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
RSSSite::GetAuthor
const QString & GetAuthor() const
Definition: rssmanager.h:65
ArticleType
ArticleType
Definition: rssparse.h:20
GrabberScript::GetVersion
const double & GetVersion() const
Definition: netgrabbermanager.h:50
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
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:67
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:61
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:887
RSSSite::GetTitle
const QString & GetTitle() const
Definition: rssmanager.h:59
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:218
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:836
removeTreeFromDB
bool removeTreeFromDB(GrabberScript *script)
Definition: netutils.cpp:276
clearRSSArticles
bool clearRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:721
getRSSArticles
ResultItem::resultList getRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:796
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:64
removeSearchFromDB
bool removeSearchFromDB(GrabberScript *script)
Definition: netutils.cpp:283
RSSSite
Definition: rssmanager.h:25
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:57
ResultItem::GetMediaURL
const QString & GetMediaURL() const
Definition: rssparse.h:141
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:836