MythTV  master
netutils.cpp
Go to the documentation of this file.
1 #include <QDir>
2 #include <QFileInfo>
3 
4 #include "mythdirs.h"
5 #include "mythdb.h"
6 #include "mythcontext.h"
7 #include "mythdate.h"
8 
9 #include "netutils.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").arg(GetShareDir())
73  .arg(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").arg(GetShareDir())
105  .arg(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").arg(GetShareDir())
136  .arg(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").arg(GetShareDir())
171  .arg(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").arg(GetShareDir())
206  .arg(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  query.prepare("DELETE FROM internetcontent WHERE commandline = :COMMAND "
295  "AND host = :HOST AND search = 1;");
296  else
297  query.prepare("DELETE FROM internetcontent WHERE commandline = :COMMAND "
298  "AND host = :HOST AND search = 0;");
299  QFileInfo fi(commandline);
300  query.bindValue(":COMMAND", fi.fileName());
301  query.bindValue(":HOST", gCoreContext->GetHostName());
302  if (!query.exec() || !query.isActive()) {
303  MythDB::DBError("netcontent: delete from db", query);
304  return false;
305  }
306 
307  return (query.numRowsAffected() > 0);
308 }
309 
310 bool markTreeUpdated(GrabberScript* script, const QDateTime& curTime)
311 {
312  MSqlQuery query(MSqlQuery::InitCon());
313  query.prepare("UPDATE internetcontent SET updated = :UPDATED "
314  "WHERE commandline = :COMMAND AND tree = 1;");
315  query.bindValue(":UPDATED", curTime);
316  QFileInfo fi(script->GetCommandline());
317  query.bindValue(":COMMAND", fi.fileName());
318  if (!query.exec() || !query.isActive()) {
319  MythDB::DBError("netcontent: update db time", query);
320  return false;
321  }
322 
323  return (query.numRowsAffected() > 0);
324 }
325 
326 bool needsUpdate(GrabberScript* script, uint updateFreq)
327 {
328  QDateTime now = MythDate::current();
329  QDateTime then = lastUpdate(script);
330 
331  return then.addSecs(updateFreq * 60 * 60) < now;
332 }
333 
334 QDateTime lastUpdate(GrabberScript* script)
335 {
336  QDateTime updated;
337  MSqlQuery query(MSqlQuery::InitCon());
338  query.prepare("SELECT updated "
339  "FROM internetcontent "
340  "WHERE commandline = :COMMAND ORDER "
341  "BY updated DESC LIMIT 1;");
342  QFileInfo fi(script->GetCommandline());
343  query.bindValue(":COMMAND", fi.fileName());
344  if (!query.exec() || !query.isActive())
345  {
346  MythDB::DBError("Tree last update in db", query);
347  }
348  else if (query.next())
349  {
350  updated = MythDate::as_utc(query.value(0).toDateTime());
351  }
352 
353  return updated;
354 }
355 
356 bool clearTreeItems(const QString &feedcommand)
357 {
358  if (feedcommand.isEmpty())
359  return false;
360 
361  MSqlQuery query(MSqlQuery::InitCon());
362  query.prepare("DELETE FROM internetcontentarticles "
363  "WHERE feedtitle = :FEEDTITLE AND podcast = 0;");
364  query.bindValue(":FEEDTITLE", feedcommand);
365 
366  if (!query.exec() || !query.isActive())
367  {
368  MythDB::DBError("netcontent: clearing DB", query);
369  return false;
370  }
371 
372  return (query.numRowsAffected() > 0);
373 }
374 
375 bool isTreeInUse(const QString &feedcommand)
376 {
377  if (feedcommand.isEmpty())
378  return false;
379 
380  MSqlQuery query(MSqlQuery::InitCon());
381  query.prepare("SELECT * FROM internetcontent "
382  "WHERE commandline = :COMMAND;");
383  QFileInfo fi(feedcommand);
384  query.bindValue(":COMMAND", fi.fileName());
385 
386  if (!query.exec() || !query.isActive())
387  {
388  MythDB::DBError("netcontent: isTreeInUse", query);
389  return false;
390  }
391 
392  return query.next();
393 }
394 
395 bool insertTreeArticleInDB(const QString &feedtitle, const QString &path,
396  const QString &paththumb, ResultItem *item,
398 {
399  if (!item || feedtitle.isEmpty() || path.isEmpty())
400  return false;
401 
402  MSqlQuery query(MSqlQuery::InitCon());
403  query.prepare("INSERT INTO internetcontentarticles (feedtitle, path, paththumb, "
404  " title, subtitle, description, url, type, thumbnail, mediaURL, author, "
405  "date, time, rating, filesize, player, playerargs, download, "
406  "downloadargs, width, height, language, podcast, downloadable, "
407  "customhtml, countries, season, episode) "
408  "VALUES( :FEEDTITLE, :PATH, :PATHTHUMB, :TITLE, :SUBTITLE, :DESCRIPTION, "
409  ":URL, :TYPE, :THUMBNAIL, :MEDIAURL, :AUTHOR, :DATE, :TIME, :RATING, "
410  ":FILESIZE, :PLAYER, :PLAYERARGS, :DOWNLOAD, :DOWNLOADARGS, :WIDTH, :HEIGHT, "
411  ":LANGUAGE, :PODCAST, :DOWNLOADABLE, :CUSTOMHTML, :COUNTRIES, :SEASON, "
412  ":EPISODE);");
413  query.bindValue(":FEEDTITLE", feedtitle);
414  query.bindValue(":PATH", path);
415  query.bindValue(":PATHTHUMB", paththumb);
416  query.bindValue(":TITLE", item->GetTitle());
417  query.bindValue(":SUBTITLE", item->GetSubtitle().isNull() ? "" : item->GetSubtitle());
418  query.bindValue(":DESCRIPTION", item->GetDescription());
419  query.bindValue(":URL", item->GetURL());
420  query.bindValue(":TYPE", type);
421  query.bindValue(":THUMBNAIL", item->GetThumbnail());
422  query.bindValue(":MEDIAURL", item->GetMediaURL());
423  query.bindValue(":AUTHOR", item->GetAuthor());
424  query.bindValue(":DATE", item->GetDate());
425  QString time;
426  if (item->GetTime().isEmpty())
427  time = QString::number(0);
428  else
429  time = item->GetTime();
430  query.bindValue(":TIME", time);
431  query.bindValue(":RATING", item->GetRating());
432  query.bindValue(":FILESIZE", (qulonglong)item->GetFilesize());
433  query.bindValue(":PLAYER", item->GetPlayer().isNull() ? "" : item->GetPlayer());
434  query.bindValue(":PLAYERARGS", !item->GetPlayerArguments().count() ? "" :
435  item->GetPlayerArguments().join(" "));
436  query.bindValue(":DOWNLOAD", item->GetDownloader().isNull() ? "" :
437  item->GetDownloader());
438  query.bindValue(":DOWNLOADARGS", !item->GetDownloaderArguments().count() ? "" :
439  item->GetDownloaderArguments().join(" "));
440  query.bindValue(":WIDTH", item->GetWidth());
441  query.bindValue(":HEIGHT", item->GetHeight());
442  query.bindValue(":LANGUAGE", item->GetLanguage().isNull() ? "" : item->GetLanguage());
443  query.bindValue(":PODCAST", false);
444  query.bindValue(":DOWNLOADABLE", item->GetDownloadable());
445  query.bindValue(":CUSTOMHTML", item->GetCustomHTML());
446  query.bindValue(":COUNTRIES", !item->GetCountries().count() ? "" :
447  item->GetCountries().join(" "));
448  query.bindValue(":SEASON", item->GetSeason());
449  query.bindValue(":EPISODE", item->GetEpisode());
450 
451  if (!query.exec() || !query.isActive())
452  {
453  MythDB::DBError("netcontent: inserting article in DB", query);
454  return false;
455  }
456 
457  return (query.numRowsAffected() > 0);
458 }
459 
460 QMultiMap<QPair<QString,QString>, ResultItem*> getTreeArticles(const QString &feedtitle,
462 {
463  QMultiMap<QPair<QString,QString>, ResultItem*> ret;
464 
465  MSqlQuery query(MSqlQuery::InitCon());
466  query.prepare("SELECT title, subtitle, description, url, "
467  "type, thumbnail, mediaURL, author, date, time, "
468  "rating, filesize, player, playerargs, download, "
469  "downloadargs, width, height, language, "
470  "downloadable, customhtml, countries, season, episode, "
471  "path, paththumb FROM internetcontentarticles "
472  "WHERE feedtitle = :FEEDTITLE AND podcast = 0 "
473  "AND type = :TYPE ORDER BY title DESC;");
474  query.bindValue(":FEEDTITLE", feedtitle);
475  query.bindValue(":TYPE", type);
476  if (!query.exec() || !query.isActive())
477  {
478  MythDB::DBError("Tree find in db", query);
479  return ret;
480  }
481 
482  while (query.next())
483  {
484  QString title = query.value(0).toString();
485  QString subtitle = query.value(1).toString();
486  QString desc = query.value(2).toString();
487  QString URL = query.value(3).toString();
488  QString feedtype = query.value(4).toString();
489  QString thumbnail = query.value(5).toString();
490  QString mediaURL = query.value(6).toString();
491  QString author = query.value(7).toString();
492  QDateTime date = MythDate::as_utc(query.value(8).toDateTime());
493  QString time = query.value(9).toString();
494  QString rating = query.value(10).toString();
495  off_t filesize = query.value(11).toULongLong();
496  QString player = query.value(12).toString();
497  QStringList playerargs = query.value(13).toString().split(" ");
498  QString download = query.value(14).toString();
499  QStringList downloadargs = query.value(15).toString().split(" ");
500  uint width = query.value(16).toUInt();
501  uint height = query.value(17).toUInt();
502  QString language = query.value(18).toString();
503  bool downloadable = query.value(19).toBool();
504  bool customhtml = query.value(20).toBool();
505  QStringList countries = query.value(21).toString().split(" ");
506  uint season = query.value(22).toUInt();
507  uint episode = query.value(23).toUInt();
508 
509  QString path = query.value(24).toString();
510  QString paththumb = query.value(25).toString();
511 
512  QPair<QString,QString> pair(path,paththumb);
513  ret.insert(pair, new ResultItem(title, QString(),
514  subtitle, QString(), desc, URL,
515  thumbnail, mediaURL, author, date, time, rating, filesize,
516  player, playerargs, download, downloadargs,
517  width, height, language, downloadable, countries,
518  season, episode, customhtml));
519  }
520 
521  return ret;
522 }
523 
524 bool findInDB(const QString& url, ArticleType type)
525 {
526  MSqlQuery query(MSqlQuery::InitCon());
527  query.prepare("SELECT commandline FROM internetcontent WHERE commandline = :URL AND "
528  "type = :TYPE AND podcast = 1;");
529  query.bindValue(":URL", url);
530  query.bindValue(":TYPE", type);
531  if (!query.exec() || !query.isActive()) {
532  MythDB::DBError("RSS find in db", query);
533  return false;
534  }
535 
536  return query.size() > 0;
537 }
538 
539 RSSSite* findByURL(const QString& url, ArticleType type)
540 {
541  RSSSite *tmp = nullptr;
542  MSqlQuery query(MSqlQuery::InitCon());
543  query.prepare("SELECT name,thumbnail,author,description,"
544  "commandline,download,updated FROM internetcontent "
545  "WHERE commandline = :URL AND type = :TYPE "
546  "AND podcast = 1;");
547  query.bindValue(":URL", url);
548  query.bindValue(":TYPE", type);
549  if (!query.exec() || !query.next())
550  {
551  MythDB::DBError("RSS find in db", query);
552  tmp = new RSSSite(QString(), QString(),
553  QString(), (ArticleType)0, QString(),
554  QString(), QString(), false,
555  QDateTime());
556  }
557  else
558  {
559  QString title = query.value(0).toString();
560  QString image = query.value(1).toString();
561  QString author = query.value(2).toString();
562  QString description = query.value(3).toString();
563  QString outurl = query.value(4).toString();
564  bool download = query.value(5).toBool();
565  QDateTime updated; query.value(6).toDate();
566 
567  tmp = new RSSSite(title, QString(), image, type, description,
568  outurl, author, download, updated);
569  }
570 
571  return tmp;
572 }
573 
575 {
577 
578  MSqlQuery query(MSqlQuery::InitCon());
579  query.prepare(
580  "SELECT name, thumbnail, description, commandline, author, "
581  "download, updated FROM internetcontent WHERE podcast = 1 "
582  "AND type = :TYPE ORDER BY name");
583 
584  query.bindValue(":TYPE", type);
585 
586  if (!query.exec())
587  {
588  return tmp;
589  }
590 
591  while (query.next())
592  {
593  QString title = query.value(0).toString();
594  QString image = query.value(1).toString();
595  QString description = query.value(2).toString();
596  QString url = query.value(3).toString();
597  QString author = query.value(4).toString();
598  bool download = query.value(5).toBool();
599  QDateTime updated; query.value(6).toDate();
600  tmp.append(new RSSSite(title, QString(), image, type, description, url,
601  author, download, updated));
602  }
603 
604  return tmp;
605 }
606 
608 {
610 
611  MSqlQuery query(MSqlQuery::InitCon());
612  query.prepare(
613  "SELECT name, thumbnail, type, description, commandline, author, "
614  "download, updated FROM internetcontent WHERE podcast = 1 "
615  "ORDER BY name");
616 
617  if (!query.exec())
618  {
619  return tmp;
620  }
621 
622  while (query.next())
623  {
624  QString title = query.value(0).toString();
625  QString image = query.value(1).toString();
626  ArticleType type = (ArticleType)query.value(2).toInt();
627  QString description = query.value(3).toString();
628  QString url = query.value(4).toString();
629  QString author = query.value(5).toString();
630  bool download = query.value(6).toBool();
631  QDateTime updated; query.value(7).toDate();
632  tmp.append(new RSSSite(title, QString(),
633  image, type, description, url,
634  author, download, updated));
635  }
636 
637  return tmp;
638 }
639 
640 bool insertInDB(RSSSite* site)
641 {
642  if (!site) return false;
643 
644  return insertInDB(site->GetTitle(), site->GetSortTitle(), site->GetImage(),
645  site->GetDescription(), site->GetURL(),
646  site->GetAuthor(), site->GetDownload(),
647  site->GetUpdated(), site->GetType());
648 }
649 
650 bool insertInDB(const QString &name, const QString &sortname,
651  const QString &thumbnail,
652  const QString &description, const QString &url,
653  const QString &author, const bool &download,
654  const QDateTime &updated, ArticleType type)
655 {
656  if (findInDB(name, type))
657  return false;
658 
659  MSqlQuery query(MSqlQuery::InitCon());
660  query.prepare("INSERT INTO internetcontent (name,thumbnail,description,"
661  "commandline,author,download,updated,podcast, type) "
662  "VALUES( :NAME, :THUMBNAIL, :DESCRIPTION, :URL, :AUTHOR, :DOWNLOAD, "
663  ":UPDATED, :PODCAST, :TYPE);");
664  query.bindValue(":NAME", name);
665  Q_UNUSED(sortname); // query.bindValue(":SORTNAME", sortname);
666  query.bindValue(":THUMBNAIL", thumbnail);
667  query.bindValue(":DESCRIPTION", description);
668  query.bindValue(":URL", url);
669  query.bindValue(":AUTHOR", author);
670  query.bindValue(":DOWNLOAD", download);
671  query.bindValue(":UPDATED", updated);
672  query.bindValue(":PODCAST", true);
673  query.bindValue(":TYPE", type);
674  if (!query.exec() || !query.isActive()) {
675  MythDB::DBError("netcontent: inserting in DB", query);
676  return false;
677  }
678 
679  return (query.numRowsAffected() > 0);
680 }
681 
683 {
684  if (!site) return false;
685 
686  return removeFromDB(site->GetURL(), site->GetType());
687 }
688 
689 bool removeFromDB(const QString &url, ArticleType type)
690 {
691  MSqlQuery query(MSqlQuery::InitCon());
692  query.prepare("DELETE FROM internetcontent WHERE commandline = :URL "
693  "AND type = :TYPE;");
694  query.bindValue(":URL", url);
695  query.bindValue(":TYPE", type);
696  if (!query.exec() || !query.isActive()) {
697  MythDB::DBError("netcontent: delete from db", query);
698  return false;
699  }
700 
701  return (query.numRowsAffected() > 0);
702 }
703 
704 void markUpdated(RSSSite *site)
705 {
706  QDateTime now = MythDate::current();
707 
708  MSqlQuery query(MSqlQuery::InitCon());
709  query.prepare("UPDATE internetcontent SET updated = :UPDATED "
710  "WHERE commandline = :URL AND type = :TYPE;");
711  query.bindValue(":UPDATED", now);
712  query.bindValue(":URL", site->GetURL());
713  query.bindValue(":TYPE", site->GetType());
714  if (!query.exec() || !query.isActive())
715  MythDB::DBError("netcontent update time", query);
716 }
717 
718 bool clearRSSArticles(const QString &feedtitle, ArticleType type)
719 {
720  if (feedtitle.isEmpty())
721  return false;
722 
723  MSqlQuery query(MSqlQuery::InitCon());
724  query.prepare("DELETE FROM internetcontentarticles "
725  "WHERE feedtitle = :FEEDTITLE AND podcast = 1 "
726  "AND type = :TYPE ;");
727  query.bindValue(":FEEDTITLE", feedtitle);
728  query.bindValue(":TYPE", type);
729 
730  if (!query.exec() || !query.isActive()) {
731  MythDB::DBError("netcontent: clearing DB", query);
732  return false;
733  }
734 
735  return (query.numRowsAffected() > 0);
736 }
737 
738 bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item,
740 {
741  if (!item || feedtitle.isEmpty())
742  return false;
743 
744  MSqlQuery query(MSqlQuery::InitCon());
745  query.prepare("INSERT INTO internetcontentarticles (feedtitle, title, "
746  "description, url, type, thumbnail, mediaURL, author, date, time, "
747  "rating, filesize, player, playerargs, download, "
748  "downloadargs, width, height, language, downloadable, countries, "
749  "podcast) "
750  "VALUES( :FEEDTITLE, :TITLE, :DESCRIPTION, :URL, :TYPE, :THUMBNAIL, "
751  ":MEDIAURL, :AUTHOR, :DATE, :TIME, :RATING, :FILESIZE, :PLAYER, "
752  ":PLAYERARGS, :DOWNLOAD, :DOWNLOADARGS, :WIDTH, :HEIGHT, "
753  ":LANGUAGE, :DOWNLOADABLE, :COUNTRIES, :PODCAST);");
754  query.bindValue(":FEEDTITLE", feedtitle);
755  query.bindValue(":TITLE", item->GetTitle());
756  //RSS articles don't have subtitles
757  query.bindValue(":DESCRIPTION", item->GetDescription());
758  query.bindValue(":URL", item->GetURL());
759  query.bindValue(":TYPE", type);
760  query.bindValue(":THUMBNAIL", item->GetThumbnail());
761  query.bindValue(":MEDIAURL", item->GetMediaURL());
762  query.bindValue(":AUTHOR", item->GetAuthor());
763  query.bindValue(":DATE", item->GetDate());
764  QString time;
765  if (item->GetTime().isEmpty())
766  time = QString::number(0);
767  else
768  time = item->GetTime();
769  query.bindValue(":TIME", time);
770  query.bindValue(":RATING", item->GetRating());
771  query.bindValue(":FILESIZE", (qulonglong)item->GetFilesize());
772  query.bindValue(":PLAYER", item->GetPlayer().isNull() ? "" : item->GetPlayer());
773  query.bindValue(":PLAYERARGS", !item->GetPlayerArguments().count() ? "" :
774  item->GetPlayerArguments().join(" "));
775  query.bindValue(":DOWNLOAD", item->GetDownloader().isNull() ? "" :
776  item->GetDownloader());
777  query.bindValue(":DOWNLOADARGS", !item->GetDownloaderArguments().count() ? "" :
778  item->GetDownloaderArguments().join(" "));
779  query.bindValue(":WIDTH", item->GetWidth());
780  query.bindValue(":HEIGHT", item->GetHeight());
781  query.bindValue(":LANGUAGE", item->GetLanguage().isNull() ? "" : item->GetLanguage());
782  query.bindValue(":DOWNLOADABLE", item->GetDownloadable());
783  query.bindValue(":COUNTRIES", item->GetCountries());
784  query.bindValue(":PODCAST", true);
785 
786  if (!query.exec() || !query.isActive()) {
787  MythDB::DBError("netcontent: inserting article in DB", query);
788  return false;
789  }
790 
791  return (query.numRowsAffected() > 0);
792 }
793 
794 ResultItem::resultList getRSSArticles(const QString &feedtitle,
796 {
798 
799  MSqlQuery query(MSqlQuery::InitCon());
800  query.prepare("SELECT title, description, url, "
801  "thumbnail, mediaURL, author, date, time, "
802  "rating, filesize, player, playerargs, download, "
803  "downloadargs, width, height, language, "
804  "downloadable, countries, season, episode "
805  "FROM internetcontentarticles "
806  "WHERE feedtitle = :FEEDTITLE AND podcast = 1 "
807  "AND type = :TYPE ORDER BY date DESC;");
808  query.bindValue(":FEEDTITLE", feedtitle);
809  query.bindValue(":TYPE", type);
810  if (!query.exec() || !query.isActive()) {
811  MythDB::DBError("RSS find in db", query);
812  return ret;
813  }
814 
815  while (query.next())
816  {
817  QString title = query.value(0).toString();
818  //RSS articles don't have subtitles
819  QString desc = query.value(1).toString();
820  QString URL = query.value(2).toString();
821  QString thumbnail = query.value(3).toString();
822  QString mediaURL = query.value(4).toString();
823  QString author = query.value(5).toString();
824  QDateTime date = MythDate::as_utc(query.value(6).toDateTime());
825  QString time = query.value(7).toString();
826  QString rating = query.value(8).toString();
827  off_t filesize = query.value(9).toULongLong();
828  QString player = query.value(10).toString();
829  QStringList playerargs = query.value(11).toString().split(" ");
830  QString download = query.value(12).toString();
831  QStringList downloadargs = query.value(13).toString().split(" ");
832  uint width = query.value(14).toUInt();
833  uint height = query.value(15).toUInt();
834  QString language = query.value(16).toString();
835  bool downloadable = query.value(17).toBool();
836  QStringList countries = query.value(18).toString().split(" ");
837  uint season = query.value(19).toUInt();
838  uint episode = query.value(20).toUInt();
839 
840  ret.append(new ResultItem(title, QString(), QString(),
841  QString(), desc, URL, thumbnail,
842  mediaURL, author, date, time, rating, filesize,
843  player, playerargs, download, downloadargs,
844  width, height, language, downloadable, countries,
845  season, episode, false));
846  }
847 
848  return ret;
849 }
850 
851 QString GetDownloadFilename(const QString& title, const QString& url)
852 {
853  QByteArray urlarr(url.toLatin1());
854  quint16 urlChecksum = qChecksum(urlarr.data(), urlarr.length());
855  QByteArray titlearr(title.toLatin1());
856  quint16 titleChecksum = qChecksum(titlearr.data(), titlearr.length());
857  QUrl qurl(url);
858  QString ext = QFileInfo(qurl.path()).suffix();
859  QString basefilename = QString("download_%1_%2.%3")
860  .arg(QString::number(urlChecksum))
861  .arg(QString::number(titleChecksum)).arg(ext);
862 
863  return basefilename;
864 }
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:782
const QString & GetSubtitle() const
Definition: rssparse.h:136
const QString & GetLanguage() const
Definition: rssparse.h:153
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:863
const uint & GetSeason() const
Definition: rssparse.h:156
bool insertTreeInDB(GrabberScript *script, ArticleType type)
Definition: netutils.cpp:230
RSSSite::rssList findAllDBRSS()
Definition: netutils.cpp:607
bool insertTreeArticleInDB(const QString &feedtitle, const QString &path, const QString &paththumb, ResultItem *item, ArticleType type)
Definition: netutils.cpp:395
QDateTime lastUpdate(GrabberScript *script)
Definition: netutils.cpp:334
bool clearRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:718
bool removeGrabberFromDB(const QString &commandline, const bool &search)
Definition: netutils.cpp:290
const QString & GetURL() const
Definition: rssparse.h:139
bool insertInDB(RSSSite *site)
Definition: netutils.cpp:640
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
const QString & GetTitle() const
const QDateTime & GetUpdated() const
const QString & GetDescription() const
Definition: rssparse.h:138
int size(void) const
Definition: mythdbcon.h:203
const QStringList & GetPlayerArguments() const
Definition: rssparse.h:148
static const char URL[]
Definition: cddb.cpp:29
const uint & GetEpisode() const
Definition: rssparse.h:157
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
GrabberScript::scriptList findAllDBTreeGrabbers()
Definition: netutils.cpp:115
const QString & GetCommandline() const
static guint32 * tmp
Definition: goom_core.c:35
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:23
#define off_t
const QStringList & GetDownloaderArguments() const
Definition: rssparse.h:150
bool insertSearchInDB(GrabberScript *script, ArticleType type)
Definition: netutils.cpp:219
QList< ResultItem * > resultList
Definition: rssparse.h:114
QVariant value(int i) const
Definition: mythdbcon.h:198
QMultiMap< QPair< QString, QString >, ResultItem * > getTreeArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:460
const QString & GetMediaURL() const
Definition: rssparse.h:141
const QString & GetSortTitle() const
const ArticleType & GetType() const
ArticleType
Definition: rssparse.h:20
def rating(profile, smoonURL, gate)
Definition: scan.py:39
QString GetDownloadFilename(const QString &title, const QString &url)
Definition: netutils.cpp:851
const off_t & GetFilesize() const
Definition: rssparse.h:146
QList< GrabberScript * > scriptList
RSSSite * findByURL(const QString &url, ArticleType type)
Definition: netutils.cpp:539
const bool & GetDownloadable() const
Definition: rssparse.h:154
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
QString GetShareDir(void)
Definition: mythdirs.cpp:222
const uint & GetHeight() const
Definition: rssparse.h:152
bool isActive(void) const
Definition: mythdbcon.h:204
GrabberScript::scriptList findAllDBTreeGrabbersByHost(ArticleType type)
Definition: netutils.cpp:149
const QString & GetImage() const
unsigned int uint
Definition: compat.h:140
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
const QString & GetPlayer() const
Definition: rssparse.h:147
GrabberScript::scriptList findAllDBSearchGrabbers(ArticleType type)
Definition: netutils.cpp:184
const QString & GetImage() const
const QString & GetURL() const
QList< RSSSite * > rssList
const bool & GetCustomHTML() const
Definition: rssparse.h:158
GrabberScript * findTreeGrabberByCommand(const QString &commandline, ArticleType type)
Definition: netutils.cpp:51
bool needsUpdate(GrabberScript *script, uint updateFreq)
Definition: netutils.cpp:326
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
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:807
const QString & GetTitle() const
bool clearTreeItems(const QString &feedcommand)
Definition: netutils.cpp:356
const QStringList & GetCountries() const
Definition: rssparse.h:155
const QString & GetAuthor() const
const QString & GetDescription() const
const QString & GetTitle() const
Definition: rssparse.h:134
bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item, ArticleType type)
Definition: netutils.cpp:738
bool findInDB(const QString &url, ArticleType type)
Definition: netutils.cpp:524
bool removeTreeFromDB(GrabberScript *script)
Definition: netutils.cpp:276
bool findTreeGrabberInDB(const QString &commandline, ArticleType type)
Definition: netutils.cpp:11
int numRowsAffected() const
Definition: mythdbcon.h:206
bool removeFromDB(RSSSite *site)
Definition: netutils.cpp:682
const QString & GetDescription() const
const QString & GetAuthor() const
const QString & GetAuthor() const
Definition: rssparse.h:142
const QString & GetRating() const
Definition: rssparse.h:145
void markUpdated(RSSSite *site)
Definition: netutils.cpp:704
bool isTreeInUse(const QString &feedcommand)
Definition: netutils.cpp:375
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
const uint & GetWidth() const
Definition: rssparse.h:151
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:179
ResultItem::resultList getRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:794
bool findSearchGrabberInDB(const QString &commandline, ArticleType type)
Definition: netutils.cpp:31
GrabberScript * findSearchGrabberByCommand(const QString &commandline, ArticleType type)
Definition: netutils.cpp:83
QString GetHostName(void)
bool markTreeUpdated(GrabberScript *script, const QDateTime &curTime)
Definition: netutils.cpp:310
RSSSite::rssList findAllDBRSSByType(ArticleType type)
Definition: netutils.cpp:574
const bool & GetDownload() const
const double & GetVersion() const
bool removeSearchFromDB(GrabberScript *script)
Definition: netutils.cpp:283
const QString & GetThumbnail() const
Definition: rssparse.h:140
const QString & GetDownloader() const
Definition: rssparse.h:149
const QString & GetTime() const
Definition: rssparse.h:144
const QDateTime & GetDate() const
Definition: rssparse.h:143