Ticket #3842: 3842-head-v4.patch
File 3842-head-v4.patch, 34.0 KB (added by , 17 years ago) |
---|
-
libs/libmythtv/videosource.h
21 21 class DiSEqCDevTree; 22 22 class DiSEqCDevSettings; 23 23 24 static inline bool is_grabber_external(const QString &grabber) 25 { 26 return !(grabber == "datadirect" || 27 grabber == "eitonly" || 28 grabber == "schedulesdirect1" || 29 grabber == "/bin/true"); 30 } 31 32 static inline bool is_grabber_datadirect(const QString &grabber) 33 { 34 return (grabber == "datadirect") || (grabber == "schedulesdirect1"); 35 } 36 37 static inline bool is_grabber_labs(const QString &grabber) 38 { 39 return grabber == "datadirect"; 40 } 41 24 42 class VideoSourceDBStorage : public SimpleDBStorage 25 43 { 26 44 protected: … … 110 128 { 111 129 Q_OBJECT 112 130 public: 113 DataDirect_config(const VideoSource& _parent, int _ source = DD_ZAP2IT);131 DataDirect_config(const VideoSource& _parent, int _ddsource); 114 132 115 133 virtual void load(void); 116 134 -
libs/libmythtv/dbcheck.cpp
8 8 9 9 #include "mythcontext.h" 10 10 #include "mythdbcon.h" 11 #include "datadirect.h" // for DataDirectProcessor::FixProgramIDs 11 12 12 13 /// This is the DB schema version expected by the running MythTV instance. 13 14 const QString currentDatabaseVersion = "1195"; … … 467 468 468 469 bool ret = doUpgradeTVDatabaseSchema(); 469 470 471 if (!gContext->GetNumSetting("MythFillFixProgramIDsHasRunOnce", 0)) 472 DataDirectProcessor::FixProgramIDs(); 473 470 474 if (ret) 471 475 VERBOSE(VB_IMPORTANT, "Database Schema upgrade complete, unlocking."); 472 476 else -
libs/libmythtv/datadirect.h
13 13 14 14 enum DD_PROVIDERS 15 15 { 16 DD_ZAP2IT = 0, 17 DD_PROVIDER_COUNT, 16 DD_ZAP2IT = 0, 17 DD_SCHEDULES_DIRECT = 1, 18 DD_PROVIDER_COUNT = 2, 18 19 }; 19 20 20 21 class DataDirectURLs … … 254 255 QString userid = "", QString password = ""); 255 256 ~DataDirectProcessor(); 256 257 258 QString CreateTempDirectory(void); 259 257 260 // web service commands 258 261 bool GrabData(const QDateTime pstartdate, const QDateTime penddate); 259 262 bool GrabNextSuggestedTime(void); … … 303 306 RawLineup GetRawLineup( const QString &lineupid) const; 304 307 305 308 // sets 306 void SetUserID( QString uid) { userid = uid; }307 void SetPassword( QString pwd) { password = pwd; }309 void SetUserID(const QString &uid); 310 void SetPassword(const QString &pwd); 308 311 void SetListingsProvider(uint i) 309 312 { listings_provider = i % DD_PROVIDER_COUNT; } 310 void SetInputFile(const QString &file) { inputfilename = file; }311 313 314 void SetInputFile(const QString &file); 315 void SetCacheData(bool cd) { cachedata = cd; } 316 312 317 // static commands (these update temp DB tables) 313 318 static void UpdateStationViewTable(QString lineupid); 314 319 static void UpdateProgramViewTable(uint sourceid); … … 318 323 static bool UpdateChannelsUnsafe(uint sourceid); 319 324 static void DataDirectProgramUpdate(void); 320 325 326 // static command, makes Labs and Schedules Direct ProgramIDs compatible. 327 static void FixProgramIDs(void); 328 321 329 private: 322 330 void CreateTempTables(void); 323 331 void CreateATempTable(const QString &ptablename, … … 326 334 bool ParseLineups(const QString &documentFile); 327 335 bool ParseLineup(const QString &lineupid, const QString &documentFile); 328 336 337 QString GetPostFilename(void) const; 338 QString GetResultFilename(void) const; 339 QString GetCookieFilename(void) const; 340 329 341 void SetAll(const QString &lineupid, bool val); 330 342 void SetDDProgramsStartAt(QDateTime begts) { actuallistingsfrom = begts; } 331 343 void SetDDProgramsEndAt(QDateTime endts) { actuallistingsto = endts; } … … 346 358 347 359 QString userid; 348 360 QString password; 361 QString tmpDir; 362 bool cachedata; 349 363 350 364 QDateTime actuallistingsfrom; 351 365 QDateTime actuallistingsto; … … 356 370 DDLineupList lineups; 357 371 DDLineupMap lineupmaps; 358 372 359 RawLineupMap rawlineups;360 QStringtmpPostFile;361 QStringtmpResultFile;362 QStringcookieFile;363 QDateTime cookieFileDT;373 RawLineupMap rawlineups; 374 mutable QString tmpPostFile; 375 mutable QString tmpResultFile; 376 mutable QString cookieFile; 377 QDateTime cookieFileDT; 364 378 }; 365 379 366 380 #endif -
libs/libmythtv/datadirect.cpp
6 6 7 7 // Qt headers 8 8 #include <qmap.h> 9 #include <qdir.h> 9 10 #include <qfile.h> 10 11 #include <qstring.h> 11 12 #include <qregexp.h> … … 25 26 #define SHOW_WGET_OUTPUT 0 26 27 27 28 #define LOC QString("DataDirect: ") 29 #define LOC_WARN QString("DataDirect, Warning: ") 28 30 #define LOC_ERR QString("DataDirect, Error: ") 29 31 30 32 static QMutex lineup_type_lock; … … 511 513 return true; 512 514 } 513 515 514 static QString makeTempFile(QString name_template)515 {516 const char *tmp = name_template.ascii();517 char *ctemplate = strdup(tmp);518 int ret = mkstemp(ctemplate);519 QString tmpFileName(ctemplate);520 free(ctemplate);521 522 if (ret == -1)523 {524 VERBOSE(VB_IMPORTANT, LOC_ERR + "Creating temp file from " +525 QString("template '%1'").arg(name_template) + ENO);526 return name_template;527 }528 close(ret);529 530 return tmpFileName;531 }532 533 516 DataDirectProcessor::DataDirectProcessor(uint lp, QString user, QString pass) : 534 517 listings_provider(lp % DD_PROVIDER_COUNT), 535 userid(user), password(pass), 536 inputfilename(""), tmpPostFile(""), 537 tmpResultFile(""), cookieFile(""), 518 userid(user), password(pass), 519 tmpDir("/tmp"), cachedata(false), 520 inputfilename(""), tmpPostFile(QString::null), 521 tmpResultFile(QString::null), cookieFile(QString::null), 538 522 cookieFileDT() 539 523 { 540 524 DataDirectURLs urls0( … … 542 526 "http://datadirect.webservices.zap2it.com/tvlistings/xtvdService", 543 527 "http://labs.zap2it.com", 544 528 "/ztvws/ztvws_login/1,1059,TMS01-1,00.html"); 529 DataDirectURLs urls1( 530 "Schedules Direct", 531 "http://webservices.schedulesdirect.tmsdatadirect.com" 532 "/schedulesdirect/tvlistings/xtvdService", 533 "http://schedulesdirect.org", 534 "/login/index.php"); 545 535 providers.push_back(urls0); 546 547 QString tmpDir = "/tmp"; 548 tmpPostFile = makeTempFile(tmpDir + "/mythtv_post_XXXXXX"); 549 tmpResultFile = makeTempFile(tmpDir + "/mythtv_result_XXXXXX"); 550 cookieFile = makeTempFile(tmpDir + "/mythtv_cookies_XXXXXX"); 536 providers.push_back(urls1); 551 537 } 552 538 553 539 DataDirectProcessor::~DataDirectProcessor() 554 540 { 555 unlink(tmpPostFile.ascii()); 556 unlink(tmpResultFile.ascii()); 557 unlink(cookieFile.ascii()); 541 VERBOSE(VB_GENERAL, LOC + "Deleting temporary files"); 542 543 if (!tmpPostFile.isEmpty()) 544 unlink(tmpPostFile.ascii()); 545 546 if (!tmpResultFile.isEmpty()) 547 unlink(tmpResultFile.ascii()); 548 549 if (!cookieFile.isEmpty()) 550 unlink(cookieFile.ascii()); 551 552 QDir d(tmpDir, "mythtv_dd_cache_*", QDir::Name, 553 QDir::Files | QDir::NoSymLinks); 554 555 for (uint i = 0; i < d.count(); i++) 556 { 557 //cout<<"deleting '"<<tmpDir<<"/"<<d[i]<<"'"<<endl; 558 unlink((tmpDir + "/" + d[i]).ascii()); 559 } 560 561 if (tmpDir != "/tmp") 562 rmdir(tmpDir.ascii()); 558 563 } 559 564 565 QString DataDirectProcessor::CreateTempDirectory(void) 566 { 567 if (tmpDir == "/tmp") 568 tmpDir = createTempFile("/tmp/mythtv_ddp_XXXXXX", true); 569 return QDeepCopy<QString>(tmpDir); 570 } 571 560 572 void DataDirectProcessor::UpdateStationViewTable(QString lineupid) 561 573 { 562 574 MSqlQuery query(MSqlQuery::DDCon()); … … 805 817 //cerr << "Done...\n"; 806 818 } 807 819 820 void DataDirectProcessor::FixProgramIDs(void) 821 { 822 VERBOSE(VB_GENERAL, "DataDirectProcessor::FixProgramIDs() -- begin"); 823 824 MSqlQuery query(MSqlQuery::DDCon()); 825 query.prepare( 826 "UPDATE recorded " 827 "SET programid=CONCAT(SUBSTRING(programid, 1, 2), " 828 " '00', SUBSTRING(programid, 3)) " 829 "WHERE length(programid) = 12"); 830 831 if (!query.exec()) 832 { 833 MythContext::DBError("Fixing program ids in recorded", query); 834 return; 835 } 836 837 query.prepare( 838 "UPDATE oldrecorded " 839 "SET programid=CONCAT(SUBSTRING(programid, 1, 2), " 840 " '00', SUBSTRING(programid, 3)) " 841 "WHERE length(programid) = 12"); 842 843 if (!query.exec()) 844 { 845 MythContext::DBError("Fixing program ids in oldrecorded", query); 846 return; 847 } 848 849 gContext->SetSetting("MythFillFixProgramIDsHasRunOnce", "1"); 850 851 VERBOSE(VB_GENERAL, "DataDirectProcessor::FixProgramIDs() -- end"); 852 } 853 808 854 FILE *DataDirectProcessor::DDPost( 809 855 QString ddurl, 810 856 QString postFilename, QString inputFile, … … 870 916 VERBOSE(VB_GENERAL, "Grabbing next suggested grabbing time"); 871 917 872 918 QString ddurl = providers[listings_provider].webServiceURL; 873 874 QFile postfile( tmpPostFile);919 920 QFile postfile(GetPostFilename()); 875 921 if (!postfile.open(IO_WriteOnly)) 876 922 { 877 923 VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Opening '%1'") 878 .arg( tmpPostFile) + ENO);924 .arg(GetPostFilename()) + ENO); 879 925 return false; 880 926 } 881 927 … … 896 942 897 943 QString command = QString("wget --http-user='%1' --http-passwd='%2' " 898 944 "--post-file='%3' %4 --output-document='%5'") 899 .arg(GetUserID()).arg(GetPassword()).arg( tmpPostFile)900 .arg(ddurl).arg( tmpResultFile);945 .arg(GetUserID()).arg(GetPassword()).arg(GetPostFilename()) 946 .arg(ddurl).arg(GetResultFilename()); 901 947 902 948 if (SHOW_WGET_OUTPUT) 903 949 VERBOSE(VB_GENERAL, "command: "<<command<<endl); … … 909 955 QDateTime NextSuggestedTime; 910 956 QDateTime BlockedTime; 911 957 912 QFile file( tmpResultFile);958 QFile file(GetResultFilename()); 913 959 914 960 bool GotNextSuggestedTime = false; 915 961 bool GotBlockedTime = false; … … 994 1040 995 1041 QString err = ""; 996 1042 QString ddurl = providers[listings_provider].webServiceURL; 1043 QString inputfile = inputfilename; 1044 QString cache_dd_data = QString::null; 997 1045 998 FILE *fp = DDPost(ddurl, tmpPostFile, inputfilename, 1046 if (cachedata) 1047 { 1048 cache_dd_data = tmpDir + QString("/mythtv_dd_cache_%1_%2_%3_%4") 1049 .arg(GetListingsProvider()) 1050 .arg(GetUserID().ascii()) 1051 .arg(pstartDate.toString()) 1052 .arg(pendDate.toString()); 1053 1054 if (QFile(cache_dd_data).exists() && inputfilename.isEmpty()) 1055 { 1056 VERBOSE(VB_GENERAL, LOC + "Copying from DD cache"); 1057 inputfile = cache_dd_data; 1058 } 1059 } 1060 1061 FILE *fp = DDPost(ddurl, GetPostFilename(), inputfile, 999 1062 GetUserID(), GetPassword(), 1000 1063 pstartDate, pendDate, err); 1001 1064 if (!fp) … … 1005 1068 return false; 1006 1069 } 1007 1070 1071 if (cachedata && (inputfile != cache_dd_data)) 1072 { 1073 QFile in, out(cache_dd_data); 1074 bool ok = out.open(IO_WriteOnly); 1075 if (!ok) 1076 { 1077 VERBOSE(VB_IMPORTANT, LOC_WARN + 1078 "Can not open DD cache file in '" + 1079 tmpDir + "' for writing!"); 1080 } 1081 else 1082 { 1083 VERBOSE(VB_GENERAL, LOC + "Saving listings to DD cache"); 1084 ok = in.open(IO_ReadOnly, fp); 1085 out.close(); // let copy routine handle dst file 1086 } 1087 1088 if (ok) 1089 { 1090 if (copy(out, in)) 1091 { 1092 pclose(fp); 1093 fp = fopen(cache_dd_data.ascii(), "r"); 1094 } 1095 else 1096 { 1097 VERBOSE(VB_IMPORTANT, 1098 LOC_ERR + "Failed to save DD cache! " 1099 "redownloading data..."); 1100 cachedata = false; 1101 pclose(fp); 1102 fp = DDPost(ddurl, GetPostFilename(), inputfile, 1103 GetUserID(), GetPassword(), 1104 pstartDate, pendDate, err); 1105 } 1106 } 1107 } 1108 1008 1109 QFile f; 1009 1110 if (f.open(IO_ReadOnly, fp)) 1010 1111 { … … 1083 1184 " channelMinor char(3) )"; 1084 1185 1085 1186 dd_tables["dd_schedule"] = 1086 "( programid char( 12), stationid char(12), "1187 "( programid char(40), stationid char(12), " 1087 1188 " scheduletime datetime, duration time, " 1088 1189 " isrepeat bool, stereo bool, " 1089 1190 " subtitled bool, hdtv bool, " … … 1093 1194 "INDEX progidx (programid) )"; 1094 1195 1095 1196 dd_tables["dd_program"] = 1096 "( programid char( 12) NOT NULL, seriesid char(12), "1197 "( programid char(40) NOT NULL, seriesid char(12), " 1097 1198 " title varchar(120), subtitle varchar(150), " 1098 1199 " description text, mpaarating char(5), " 1099 1200 " starrating char(5), runtime time, " … … 1115 1216 " partnumber int, parttotal int, " 1116 1217 " seriesid char(12), originalairdate date, " 1117 1218 " showtype varchar(30), colorcode varchar(20), " 1118 " syndicatedepisodenumber varchar(20), programid char( 12), "1219 " syndicatedepisodenumber varchar(20), programid char(40), " 1119 1220 " tvrating char(5), mpaarating char(5), " 1120 1221 "INDEX progidx (programid))"; 1121 1222 1122 1223 dd_tables["dd_productioncrew"] = 1123 "( programid char( 12), role char(30), "1224 "( programid char(40), role char(30), " 1124 1225 " givenname char(20), surname char(20), " 1125 1226 " fullname char(41), " 1126 1227 "INDEX progidx (programid), " 1127 1228 "INDEX nameidx (fullname))"; 1128 1229 1129 1230 dd_tables["dd_genre"] = 1130 "( programid char( 12) NOT NULL, class char(30), "1231 "( programid char(40) NOT NULL, class char(30), " 1131 1232 " relevance char(1), " 1132 1233 "INDEX progidx (programid))"; 1133 1234 … … 1148 1249 QString labsURL = providers[listings_provider].webURL; 1149 1250 QString loginPage = providers[listings_provider].loginPage; 1150 1251 1151 bool ok = Post(labsURL + loginPage, list, tmpResultFile, "", cookieFile); 1252 bool ok = Post(labsURL + loginPage, list, GetResultFilename(), "", 1253 GetCookieFilename()); 1152 1254 1153 bool got_cookie = QFileInfo( cookieFile).size() > 100;1255 bool got_cookie = QFileInfo(GetCookieFilename()).size() > 100; 1154 1256 1155 ok &= got_cookie && (!parse_lineups || ParseLineups( tmpResultFile));1257 ok &= got_cookie && (!parse_lineups || ParseLineups(GetResultFilename())); 1156 1258 if (ok) 1157 1259 cookieFileDT = QDateTime::currentDateTime(); 1158 1260 … … 1175 1277 list.push_back(PostItem("submit", "Modify")); 1176 1278 1177 1279 QString labsURL = providers[listings_provider].webURL; 1178 bool ok = Post(labsURL + (*it).get_action, list, tmpResultFile,1179 cookieFile, "");1280 bool ok = Post(labsURL + (*it).get_action, list, GetResultFilename(), 1281 GetCookieFilename(), ""); 1180 1282 1181 return ok && ParseLineup(lineupid, tmpResultFile);1283 return ok && ParseLineup(lineupid, GetResultFilename()); 1182 1284 } 1183 1285 1184 1286 void DataDirectProcessor::SetAll(const QString &lineupid, bool val) … … 1457 1559 .arg(lineupid).arg(list.size() - 1)); 1458 1560 1459 1561 QString labsURL = providers[listings_provider].webURL; 1460 return Post(labsURL + lineup.set_action, list, "", cookieFile, ""); 1562 return Post(labsURL + lineup.set_action, list, "", 1563 GetCookieFilename(), ""); 1461 1564 } 1462 1565 1463 1566 bool DataDirectProcessor::UpdateListings(uint sourceid) … … 1534 1637 return (*it); 1535 1638 } 1536 1639 1640 QString DataDirectProcessor::GetPostFilename(void) const 1641 { 1642 if (tmpPostFile.isEmpty()) 1643 tmpPostFile = createTempFile(tmpDir + "/mythtv_post_XXXXXX"); 1644 return QDeepCopy<QString>(tmpPostFile); 1645 } 1646 1647 QString DataDirectProcessor::GetResultFilename(void) const 1648 { 1649 if (tmpResultFile.isEmpty()) 1650 tmpResultFile = createTempFile(tmpDir + "/mythtv_result_XXXXXX"); 1651 return QDeepCopy<QString>(tmpResultFile); 1652 } 1653 1654 QString DataDirectProcessor::GetCookieFilename(void) const 1655 { 1656 if (cookieFile.isEmpty()) 1657 cookieFile = createTempFile(tmpDir + "/mythtv_cookies_XXXXXX"); 1658 return QDeepCopy<QString>(cookieFile); 1659 } 1660 1661 void DataDirectProcessor::SetUserID(const QString &uid) 1662 { 1663 userid = QDeepCopy<QString>(uid); 1664 } 1665 1666 void DataDirectProcessor::SetPassword(const QString &pwd) 1667 { 1668 password = QDeepCopy<QString>(pwd); 1669 } 1670 1671 void DataDirectProcessor::SetInputFile(const QString &file) 1672 { 1673 inputfilename = QDeepCopy<QString>(file); 1674 } 1675 1537 1676 bool DataDirectProcessor::Post(QString url, const PostList &list, 1538 1677 QString documentFile, 1539 1678 QString inCookieFile, QString outCookieFile) -
libs/libmythtv/videosource.cpp
20 20 #include <qmap.h> 21 21 #include <qdir.h> 22 22 #include <qprocess.h> 23 #include <qdatetime.h> 23 24 24 25 // MythTV headers 25 26 #include "mythconfig.h" … … 295 296 { 296 297 public: 297 298 DataDirectPassword(const VideoSource &parent) : 298 LineEditSetting(this), VideoSourceDBStorage(this, parent, "password") 299 LineEditSetting(this, true), 300 VideoSourceDBStorage(this, parent, "password") 299 301 { 302 SetPasswordEcho(true); 300 303 setLabel(QObject::tr("Password")); 301 304 } 302 305 }; … … 307 310 { 308 311 (void) uid; 309 312 (void) pwd; 310 (void) _source;311 313 #ifdef USING_BACKEND 312 314 if (uid.isEmpty() || pwd.isEmpty()) 313 315 return; … … 348 350 void DataDirect_config::load() 349 351 { 350 352 VerticalConfigurationGroup::load(); 351 if ((userid->getValue() != lastloadeduserid) || 352 (password->getValue() != lastloadedpassword)) 353 bool is_sd_userid = userid->getValue().contains("@") > 0; 354 bool match = ((is_sd_userid && (source == DD_SCHEDULES_DIRECT)) || 355 (!is_sd_userid && (source == DD_ZAP2IT))); 356 if (((userid->getValue() != lastloadeduserid) || 357 (password->getValue() != lastloadedpassword)) && match) 353 358 { 354 359 lineupselector->fillSelections(userid->getValue(), 355 360 password->getValue(), … … 442 447 "instead of just 'mythfilldatabase'.\nYour grabber does not provide " 443 448 "channel numbers, so you have to set them manually."); 444 449 445 if (grabber != "datadirect" && grabber != "eitonly" && 446 grabber != "/bin/true") 450 if (is_grabber_external(grabber)) 447 451 { 448 452 VERBOSE(VB_IMPORTANT, "\n" << err_msg); 449 453 MythPopupBox::showOkPopup( … … 508 512 // only save settings for the selected grabber 509 513 setSaveAll(false); 510 514 511 addTarget("datadirect", new DataDirect_config(parent)); 512 grabber->addSelection("North America (DataDirect) (Internal)", "datadirect"); 515 addTarget("schedulesdirect1", 516 new DataDirect_config(parent, DD_SCHEDULES_DIRECT)); 517 grabber->addSelection("North America (SchedulesDirect.org) " 518 "(Internal)", "schedulesdirect1"); 513 519 520 #if 1 521 addTarget("datadirect", new DataDirect_config(parent, DD_ZAP2IT)); 522 grabber->addSelection( 523 "North America (TMS Labs) (Internal)", "datadirect"); 524 #endif 525 514 526 addTarget("eitonly", new EITOnly_config(parent)); 515 527 grabber->addSelection("Transmitted guide only (EIT)", "eitonly"); 516 528 -
libs/libmyth/settings.cpp
639 639 connect(edit, SIGNAL(changeHelpText(QString)), cg, 640 640 SIGNAL(changeHelpText(QString))); 641 641 642 edit->setRW(rw); 642 setRW(rw); 643 SetPasswordEcho(password_echo); 643 644 644 645 return widget; 645 646 } … … 664 665 } 665 666 } 666 667 668 void LineEditSetting::SetPasswordEcho(bool b) 669 { 670 password_echo = b; 671 if (edit) 672 edit->setEchoMode(b ? QLineEdit::Password : QLineEdit::Normal); 673 } 674 667 675 QWidget* SliderSetting::configWidget(ConfigurationGroup *cg, QWidget* parent, 668 676 const char* widgetName) { 669 677 QHBox* widget; -
libs/libmyth/util.cpp
32 32 #include <qpainter.h> 33 33 #include <qpixmap.h> 34 34 #include <qfont.h> 35 #include <qfile.h> 35 36 36 37 // Myth headers 37 38 #include "mythconfig.h" … … 603 604 604 605 return false; 605 606 } 607 608 /** \fn Copy(QFile&,QFile&,uint) 609 * \brief Copies src file to dst file. 610 * 611 * If the dst file is open, it must be open for writing. 612 * If the src file is open, if must be open for reading. 613 * 614 * The files will be in the same open or close state after 615 * this function runs as they were prior to this function being called. 616 * 617 * This function does not care if the files are actual files. 618 * For compatibility with pipes and socket streams the file location 619 * will not be reset to 0 at the end of this function. If the function 620 * is succesful the file pointers will be at the end of the copied 621 * data. 622 * 623 * \param dst Destination QFile 624 * \param src Source QFile 625 * \param block_size Optional block size in bytes, must be at least 1024, 626 * otherwise the default of 16 KB will be used. 627 * \return bytes copied on success, -1 on failure. 628 */ 629 long long copy(QFile &dst, QFile &src, uint block_size) 630 { 631 uint buflen = (block_size < 1024) ? (16 * 1024) : block_size; 632 char *buf = new char[buflen]; 633 bool odst = false, osrc = false; 634 635 if (!buf) 636 return -1LL; 637 638 if (!dst.isWritable() && !dst.isOpen()) 639 odst = dst.open(IO_Raw|IO_WriteOnly|IO_Truncate); 640 641 if (!src.isReadable() && !src.isOpen()) 642 osrc = src.open(IO_Raw|IO_ReadOnly); 643 644 bool ok = dst.isWritable() && src.isReadable(); 645 long long total_bytes = 0LL; 646 while (ok) 647 { 648 long long rlen, wlen, off = 0; 649 rlen = src.readBlock(buf, buflen); 650 if (rlen<0) 651 { 652 ok = false; 653 break; 654 } 655 if (rlen==0) 656 break; 657 658 total_bytes += (long long) rlen; 659 660 while ((rlen-off>0) && ok) 661 { 662 wlen = dst.writeBlock(buf + off, rlen - off); 663 if (wlen>=0) 664 off+= wlen; 665 if (wlen<0) 666 ok = false; 667 } 668 } 669 delete[] buf; 670 671 if (odst) 672 dst.close(); 673 674 if (osrc) 675 src.close(); 676 677 return (ok) ? total_bytes : -1LL; 678 } 679 680 QString createTempFile(QString name_template, bool dir) 681 { 682 const char *tmp = name_template.ascii(); 683 char *ctemplate = strdup(tmp); 684 int ret = -1; 685 686 if (dir) 687 { 688 ret = (mkdtemp(ctemplate)) ? 0 : -1; 689 } 690 else 691 { 692 ret = mkstemp(ctemplate); 693 } 694 695 QString tmpFileName(ctemplate); 696 free(ctemplate); 697 698 if (ret == -1) 699 { 700 VERBOSE(VB_IMPORTANT, QString("createTempFile(%1), Error ") 701 .arg(name_template) + ENO); 702 return name_template; 703 } 704 705 if (!dir && (ret >= 0)) 706 close(ret); 707 708 return tmpFileName; 709 } 710 -
libs/libmyth/util.h
16 16 class QImage; 17 17 class QPainter; 18 18 class QFont; 19 class QFile; 19 20 20 21 class MPUBLIC MythTimer 21 22 { … … 73 74 MPUBLIC bool ping(const QString &host, int timeout); 74 75 MPUBLIC bool telnet(const QString &host, int port); 75 76 77 MPUBLIC long long copy(QFile &dst, QFile &src, uint block_size = 0); 78 MPUBLIC QString createTempFile(QString name_template = "/tmp/mythtv_XXXXX", 79 bool dir = false); 80 76 81 #endif // UTIL_H_ -
libs/libmyth/mythcontext.h
208 208 209 209 /// Update this whenever the plug-in API changes. 210 210 /// Including changes in the libmythtv class methods used by plug-ins. 211 #define MYTH_BINARY_VERSION "0.20.20070 717-1"211 #define MYTH_BINARY_VERSION "0.20.20070817-1" 212 212 213 213 /** \brief Increment this whenever the MythTV network protocol changes. 214 214 * -
libs/libmyth/settings.h
200 200 { 201 201 protected: 202 202 LineEditSetting(Storage *_storage, bool readwrite = true) : 203 Setting(_storage), edit(NULL), rw(readwrite) { }203 Setting(_storage), edit(NULL), rw(readwrite), password_echo(false) { } 204 204 205 205 public: 206 206 virtual QWidget* configWidget(ConfigurationGroup *cg, QWidget* parent, … … 217 217 218 218 virtual void setEnabled(bool b); 219 219 virtual void setVisible(bool b); 220 virtual void SetPasswordEcho(bool b); 220 221 221 222 private: 222 223 MythLineEdit* edit; 223 224 bool rw; 225 bool password_echo; 224 226 }; 225 227 226 228 // TODO: set things up so that setting the value as a string emits -
programs/mythfilldatabase/filldata.cpp
23 23 #include "mythcontext.h" 24 24 #include "mythdbcon.h" 25 25 26 // libmythtv headers 27 #include "videosource.h" // for is_grabber.. 28 26 29 // filldata headers 27 30 #include "filldata.h" 28 31 … … 44 47 icon_data.UpdateSourceIcons(source.id); 45 48 46 49 // Unselect channels not in users lineup for DVB, HDTV 47 if (!insert_channels && (new_channels > 0)) 50 if (!insert_channels && (new_channels > 0) && 51 is_grabber_labs(source.xmltvgrabber)) 48 52 { 49 53 bool ok0 = (logged_in == source.userid); 50 54 bool ok1 = (raw_lineup == source.id); … … 69 73 70 74 bool FillData::DataDirectUpdateChannels(Source source) 71 75 { 76 if (!is_grabber_labs(source.xmltvgrabber)) 77 { 78 VERBOSE(VB_IMPORTANT, "FillData: We only support " 79 "DataDirectUpdateChannels with TMS Labs channel editor"); 80 return false; 81 } 82 72 83 ddprocessor.SetListingsProvider(DD_ZAP2IT); 73 84 ddprocessor.SetUserID(source.userid); 74 85 ddprocessor.SetPassword(source.password); … … 87 98 bool FillData::grabDDData(Source source, int poffset, 88 99 QDate pdate, int ddSource) 89 100 { 101 if (source.dd_dups.empty()) 102 ddprocessor.SetCacheData(false); 103 else 104 { 105 VERBOSE(VB_GENERAL, QString( 106 "This DataDirect listings source is " 107 "shared by %1 MythTV lineups") 108 .arg(source.dd_dups.size()+1)); 109 if (source.id > source.dd_dups[0]) 110 { 111 VERBOSE(VB_IMPORTANT, "We should use cached data for this one"); 112 } 113 else if (source.id < source.dd_dups[0]) 114 { 115 VERBOSE(VB_IMPORTANT, "We should keep data around after this one"); 116 } 117 ddprocessor.SetCacheData(true); 118 } 119 90 120 ddprocessor.SetListingsProvider(ddSource); 91 121 ddprocessor.SetUserID(source.userid); 92 122 ddprocessor.SetPassword(source.password); … … 251 281 252 282 if (xmltv_grabber == "datadirect") 253 283 return grabDDData(source, offset, *qCurrentDate, DD_ZAP2IT); 284 if (xmltv_grabber == "schedulesdirect1") 285 return grabDDData(source, offset, *qCurrentDate, DD_SCHEDULES_DIRECT); 254 286 255 287 char tempfilename[] = "/tmp/mythXXXXXX"; 256 288 if (mkstemp(tempfilename) == -1) … … 389 421 bool FillData::fillData(QValueList<Source> &sourcelist) 390 422 { 391 423 QValueList<Source>::Iterator it; 424 QValueList<Source>::Iterator it2; 392 425 393 426 QString status, querystr; 394 427 MSqlQuery query(MSqlQuery::InitCon()); … … 402 435 403 436 need_post_grab_proc = false; 404 437 int nonewdata = 0; 438 bool has_dd_source = false; 405 439 440 // find all DataDirect duplicates, so we only data download once. 406 441 for (it = sourcelist.begin(); it != sourcelist.end(); ++it) 407 442 { 443 if (!is_grabber_datadirect((*it).xmltvgrabber)) 444 continue; 408 445 446 has_dd_source = true; 447 for (it2 = sourcelist.begin(); it2 != sourcelist.end(); ++it2) 448 { 449 if (((*it).id != (*it2).id) && 450 ((*it).xmltvgrabber == (*it2).xmltvgrabber) && 451 ((*it).userid == (*it2).userid) && 452 ((*it).password == (*it2).password)) 453 { 454 (*it).dd_dups.push_back((*it2).id); 455 } 456 } 457 } 458 if (has_dd_source) 459 ddprocessor.CreateTempDirectory(); 460 461 for (it = sourcelist.begin(); it != sourcelist.end(); ++it) 462 { 463 409 464 query.prepare("SELECT MAX(endtime) FROM program p LEFT JOIN channel c " 410 465 "ON p.chanid=c.chanid WHERE c.sourceid= :SRCID " 411 466 "AND manualid = 0;"); … … 427 482 428 483 if (xmltv_grabber == "eitonly") 429 484 { 430 VERBOSE(VB_IMPORTANT, "Source configured to use only the " 431 "broadcasted guide data. Skipping."); 485 VERBOSE(VB_GENERAL, 486 QString("Source %1 configured to use only the " 487 "broadcasted guide data. Skipping.") 488 .arg((*it).id)); 489 432 490 externally_handled++; 433 491 query.exec(QString("UPDATE settings SET data ='%1' " 434 492 "WHERE value='mythfilldatabaseLastRunStart' OR " … … 440 498 xmltv_grabber == "none" || 441 499 xmltv_grabber == "") 442 500 { 443 VERBOSE(VB_IMPORTANT, 444 "Source configured with no grabber. Nothing to do."); 501 VERBOSE(VB_GENERAL, 502 QString("Source %1 configured with no grabber. " 503 "Nothing to do.").arg((*it).id)); 504 445 505 externally_handled++; 446 506 query.exec(QString("UPDATE settings SET data ='%1' " 447 507 "WHERE value='mythfilldatabaseLastRunStart' OR " … … 486 546 487 547 bool hasprefmethod = false; 488 548 489 if ( xmltv_grabber != "datadirect")549 if (is_grabber_external(xmltv_grabber)) 490 550 { 491 551 492 552 QProcess grabber_capabilities_proc(xmltv_grabber); … … 584 644 } 585 645 } 586 646 587 need_post_grab_proc |= (xmltv_grabber != "datadirect");647 need_post_grab_proc |= !is_grabber_datadirect(xmltv_grabber); 588 648 589 if ( (xmltv_grabber == "datadirect") && dd_grab_all)649 if (is_grabber_labs(xmltv_grabber) && dd_grab_all) 590 650 { 591 651 if (only_update_channels) 592 652 DataDirectUpdateChannels(*it); … … 601 661 if (!grabData(*it, 0)) 602 662 ++failures; 603 663 } 604 else if ((*it).xmltvgrabber_baseline || xmltv_grabber == "datadirect") 664 else if ((*it).xmltvgrabber_baseline || 665 is_grabber_datadirect(xmltv_grabber)) 605 666 { 606 667 607 668 QDate qCurrentDate = QDate::currentDate(); … … 612 673 613 674 if (maxDays > 0) // passed with --max-days 614 675 grabdays = maxDays; 615 else if ( xmltv_grabber == "datadirect")676 else if (is_grabber_datadirect(xmltv_grabber)) 616 677 grabdays = 14; 617 678 618 679 grabdays = (only_update_channels) ? 1 : grabdays; … … 620 681 if (grabdays == 1) 621 682 refresh_today = true; 622 683 623 if ( (xmltv_grabber == "datadirect") && only_update_channels)684 if (is_grabber_labs(xmltv_grabber) && only_update_channels) 624 685 { 625 686 DataDirectUpdateChannels(*it); 626 687 grabdays = 0; -
programs/mythfilldatabase/main.cpp
16 16 // libmythtv headers 17 17 #include "scheduledrecording.h" 18 18 #include "remoteutil.h" 19 #include "videosource.h" // for is_grabber.. 19 20 20 21 // filldata headers 21 22 #include "filldata.h" … … 34 35 bool from_file = false; 35 36 bool mark_repeats = true; 36 37 37 bool usingDataDirect = false ;38 bool usingDataDirect = false, usingDataDirectLabs = false; 38 39 bool grab_data = true; 39 40 40 41 bool export_iconmap = false; … … 579 580 newsource.xmltvgrabber_prefmethod = ""; 580 581 581 582 sourcelist.append(newsource); 582 if (newsource.xmltvgrabber == "datadirect") 583 usingDataDirect = true; 583 usingDataDirect |= 584 is_grabber_datadirect(newsource.xmltvgrabber); 585 usingDataDirectLabs |= 586 is_grabber_labs(newsource.xmltvgrabber); 584 587 } 585 588 } 586 589 else … … 814 817 fill_data.ddprocessor.GrabNextSuggestedTime(); 815 818 } 816 819 820 if (usingDataDirectLabs || 821 !gContext->GetNumSetting("MythFillFixProgramIDsHasRunOnce", 0)) 822 { 823 DataDirectProcessor::FixProgramIDs(); 824 } 825 817 826 VERBOSE(VB_GENERAL, "\n" 818 827 "===============================================================\n" 819 828 "| Attempting to contact the master backend for rescheduling. |\n" -
programs/mythfilldatabase/filldata.h
26 26 bool xmltvgrabber_manualconfig; 27 27 bool xmltvgrabber_cache; 28 28 QString xmltvgrabber_prefmethod; 29 vector<int> dd_dups; 29 30 }; 30 31 31 32 class FillData