Ticket #3842: 3842-head-v3.patch

File 3842-head-v3.patch, 31.2 KB (added by danielk, 18 years ago)

Updated patch, this version should maintain the DD cache across local day boundaries.

  • libs/libmythtv/videosource.h

     
    110110{
    111111    Q_OBJECT
    112112  public:
    113     DataDirect_config(const VideoSource& _parent, int _source = DD_ZAP2IT);
     113    DataDirect_config(const VideoSource& _parent, int _ddsource);
    114114
    115115    virtual void load(void);
    116116
  • libs/libmythtv/datadirect.h

     
    1313
    1414enum DD_PROVIDERS
    1515{
    16     DD_ZAP2IT = 0,
    17     DD_PROVIDER_COUNT,
     16    DD_ZAP2IT           = 0,
     17    DD_SCHEDULES_DIRECT = 1,
     18    DD_PROVIDER_COUNT   = 2,
    1819};
    1920
    2021class DataDirectURLs
     
    254255                        QString userid = "", QString password = "");
    255256   ~DataDirectProcessor();
    256257
     258    QString CreateTempDirectory(void);
     259
    257260    // web service commands
    258261    bool GrabData(const QDateTime pstartdate, const QDateTime penddate);
    259262    bool GrabNextSuggestedTime(void);
     
    303306    RawLineup GetRawLineup( const QString &lineupid) const;
    304307
    305308    // 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);
    308311    void SetListingsProvider(uint i)
    309312        { listings_provider = i % DD_PROVIDER_COUNT; }
    310     void SetInputFile(const QString &file)      { inputfilename      = file; }
    311313
     314    void SetInputFile(const QString &file);
     315    void SetCacheData(bool cd) { cachedata = cd; }
     316
    312317    // static commands (these update temp DB tables)
    313318    static void UpdateStationViewTable(QString lineupid);
    314319    static void UpdateProgramViewTable(uint sourceid);
     
    326331    bool ParseLineups(const QString &documentFile);
    327332    bool ParseLineup(const QString &lineupid, const QString &documentFile);
    328333
     334    QString GetPostFilename(void) const;
     335    QString GetResultFilename(void) const;
     336    QString GetCookieFilename(void) const;
     337
    329338    void SetAll(const QString &lineupid, bool val);
    330339    void SetDDProgramsStartAt(QDateTime begts)  { actuallistingsfrom = begts; }
    331340    void SetDDProgramsEndAt(QDateTime endts)    { actuallistingsto   = endts; }
     
    346355
    347356    QString       userid;
    348357    QString       password;
     358    QString       tmpDir;
     359    bool          cachedata;
    349360
    350361    QDateTime     actuallistingsfrom;
    351362    QDateTime     actuallistingsto;
     
    356367    DDLineupList  lineups;
    357368    DDLineupMap   lineupmaps;
    358369
    359     RawLineupMap  rawlineups;
    360     QString      tmpPostFile;
    361     QString      tmpResultFile;
    362     QString      cookieFile;
    363     QDateTime     cookieFileDT;
     370    RawLineupMap    rawlineups;
     371    mutable QString tmpPostFile;
     372    mutable QString tmpResultFile;
     373    mutable QString cookieFile;
     374    QDateTime       cookieFileDT;
    364375};
    365376
    366377#endif
  • libs/libmythtv/datadirect.cpp

     
    66
    77// Qt headers
    88#include <qmap.h>
     9#include <qdir.h>
    910#include <qfile.h>
    1011#include <qstring.h>
    1112#include <qregexp.h>
     
    2526#define SHOW_WGET_OUTPUT 0
    2627
    2728#define LOC QString("DataDirect: ")
     29#define LOC_WARN QString("DataDirect, Warning: ")
    2830#define LOC_ERR QString("DataDirect, Error: ")
    2931
    3032static QMutex lineup_type_lock;
     
    511513    return true;
    512514}
    513515
    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 
    533516DataDirectProcessor::DataDirectProcessor(uint lp, QString user, QString pass) :
    534517    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),
    538522    cookieFileDT()
    539523{
    540524    DataDirectURLs urls0(
     
    542526        "http://datadirect.webservices.zap2it.com/tvlistings/xtvdService",
    543527        "http://labs.zap2it.com",
    544528        "/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");
    545535    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);
    551537}
    552538
    553539DataDirectProcessor::~DataDirectProcessor()
    554540{
    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());
    558563}
    559564
     565QString DataDirectProcessor::CreateTempDirectory(void)
     566{
     567    if (tmpDir == "/tmp")
     568        tmpDir = createTempFile("/tmp/mythtv_ddp_XXXXXX", true);
     569    return QDeepCopy<QString>(tmpDir);
     570}
     571
    560572void DataDirectProcessor::UpdateStationViewTable(QString lineupid)
    561573{
    562574    MSqlQuery query(MSqlQuery::DDCon());
     
    870882    VERBOSE(VB_GENERAL, "Grabbing next suggested grabbing time");
    871883
    872884    QString ddurl = providers[listings_provider].webServiceURL;
    873          
    874     QFile postfile(tmpPostFile);
     885
     886    QFile postfile(GetPostFilename());
    875887    if (!postfile.open(IO_WriteOnly))
    876888    {
    877889        VERBOSE(VB_IMPORTANT, LOC_ERR + QString("Opening '%1'")
    878                 .arg(tmpPostFile) + ENO);
     890                .arg(GetPostFilename()) + ENO);
    879891        return false;
    880892    }
    881893
     
    896908
    897909    QString command = QString("wget --http-user='%1' --http-passwd='%2' "
    898910                              "--post-file='%3' %4 --output-document='%5'")
    899         .arg(GetUserID()).arg(GetPassword()).arg(tmpPostFile)
    900         .arg(ddurl).arg(tmpResultFile);
     911        .arg(GetUserID()).arg(GetPassword()).arg(GetPostFilename())
     912        .arg(ddurl).arg(GetResultFilename());
    901913
    902914    if (SHOW_WGET_OUTPUT)
    903915        VERBOSE(VB_GENERAL, "command: "<<command<<endl);
     
    909921    QDateTime NextSuggestedTime;
    910922    QDateTime BlockedTime;
    911923
    912     QFile file(tmpResultFile);
     924    QFile file(GetResultFilename());
    913925
    914926    bool GotNextSuggestedTime = false;
    915927    bool GotBlockedTime = false;
     
    9941006
    9951007    QString err = "";
    9961008    QString ddurl = providers[listings_provider].webServiceURL;
     1009    QString inputfile = inputfilename;
     1010    QString cache_dd_data = QString::null;
    9971011
    998     FILE *fp = DDPost(ddurl, tmpPostFile, inputfilename,
     1012    if (cachedata)
     1013    {
     1014        cache_dd_data = tmpDir + QString("/mythtv_dd_cache_%1_%2_%3_%4")
     1015            .arg(GetListingsProvider())
     1016            .arg(GetUserID().ascii())
     1017            .arg(pstartDate.toString())
     1018            .arg(pendDate.toString());
     1019
     1020        if (QFile(cache_dd_data).exists() && inputfilename.isEmpty())
     1021        {
     1022            VERBOSE(VB_GENERAL, LOC + "Copying from DD cache");
     1023            inputfile = cache_dd_data;
     1024        }
     1025    }
     1026
     1027    FILE *fp = DDPost(ddurl, GetPostFilename(), inputfile,
    9991028                      GetUserID(), GetPassword(),
    10001029                      pstartDate, pendDate, err);
    10011030    if (!fp)
     
    10051034        return false;
    10061035    }
    10071036
     1037    if (cachedata && (inputfile != cache_dd_data))
     1038    {
     1039        QFile in, out(cache_dd_data);
     1040        bool ok = out.open(IO_WriteOnly);
     1041        if (!ok)
     1042        {
     1043            VERBOSE(VB_IMPORTANT, LOC_WARN +
     1044                    "Can not open DD cache file in '" +
     1045                    tmpDir + "' for writing!");
     1046        }
     1047        else
     1048        {
     1049            VERBOSE(VB_GENERAL, LOC + "Saving listings to DD cache");
     1050            ok = in.open(IO_ReadOnly, fp);
     1051            out.close(); // let copy routine handle dst file
     1052        }
     1053
     1054        if (ok)
     1055        {
     1056            if (copy(out, in))
     1057            {
     1058                pclose(fp);
     1059                fp = fopen(cache_dd_data.ascii(), "r");
     1060            }
     1061            else
     1062            {
     1063                VERBOSE(VB_IMPORTANT,
     1064                        LOC_ERR + "Failed to save DD cache! "
     1065                        "redownloading data...");
     1066                cachedata = false;
     1067                pclose(fp);
     1068                fp = DDPost(ddurl, GetPostFilename(), inputfile,
     1069                            GetUserID(), GetPassword(),
     1070                            pstartDate, pendDate, err);
     1071            }
     1072        }
     1073    }
     1074
    10081075    QFile f;
    10091076    if (f.open(IO_ReadOnly, fp))
    10101077    {
     
    10831150        "  channelMinor char(3) )";
    10841151
    10851152    dd_tables["dd_schedule"] =
    1086         "( programid char(12),           stationid char(12), "
     1153        "( programid char(40),           stationid char(12), "
    10871154        "  scheduletime datetime,        duration time,      "
    10881155        "  isrepeat bool,                stereo bool,        "
    10891156        "  subtitled bool,               hdtv bool,          "
     
    10931160        "INDEX progidx (programid) )";
    10941161
    10951162    dd_tables["dd_program"] =
    1096         "( programid char(12) NOT NULL,  seriesid char(12),     "
     1163        "( programid char(40) NOT NULL,  seriesid char(12),     "
    10971164        "  title varchar(120),           subtitle varchar(150), "
    10981165        "  description text,             mpaarating char(5),    "
    10991166        "  starrating char(5),           runtime time,          "
     
    11151182        "  partnumber int,               parttotal int,               "
    11161183        "  seriesid char(12),            originalairdate date,        "
    11171184        "  showtype varchar(30),         colorcode varchar(20),       "
    1118         "  syndicatedepisodenumber varchar(20), programid char(12),   "
     1185        "  syndicatedepisodenumber varchar(20), programid char(40),   "
    11191186        "  tvrating char(5),             mpaarating char(5),          "
    11201187        "INDEX progidx (programid))";
    11211188
    11221189    dd_tables["dd_productioncrew"] =
    1123         "( programid char(12),           role char(30),    "
     1190        "( programid char(40),           role char(30),    "
    11241191        "  givenname char(20),           surname char(20), "
    11251192        "  fullname char(41), "
    11261193        "INDEX progidx (programid), "
    11271194        "INDEX nameidx (fullname))";
    11281195
    11291196    dd_tables["dd_genre"] =
    1130         "( programid char(12) NOT NULL,  class char(30), "
     1197        "( programid char(40) NOT NULL,  class char(30), "
    11311198        "  relevance char(1), "
    11321199        "INDEX progidx (programid))";
    11331200
     
    11481215    QString labsURL   = providers[listings_provider].webURL;
    11491216    QString loginPage = providers[listings_provider].loginPage;
    11501217
    1151     bool ok = Post(labsURL + loginPage, list, tmpResultFile, "", cookieFile);
     1218    bool ok = Post(labsURL + loginPage, list, GetResultFilename(), "",
     1219                   GetCookieFilename());
    11521220
    1153     bool got_cookie = QFileInfo(cookieFile).size() > 100;
     1221    bool got_cookie = QFileInfo(GetCookieFilename()).size() > 100;
    11541222
    1155     ok &= got_cookie && (!parse_lineups || ParseLineups(tmpResultFile));
     1223    ok &= got_cookie && (!parse_lineups || ParseLineups(GetResultFilename()));
    11561224    if (ok)
    11571225        cookieFileDT = QDateTime::currentDateTime();
    11581226
     
    11751243    list.push_back(PostItem("submit",    "Modify"));
    11761244
    11771245    QString labsURL = providers[listings_provider].webURL;
    1178     bool ok = Post(labsURL + (*it).get_action, list, tmpResultFile,
    1179                    cookieFile, "");
     1246    bool ok = Post(labsURL + (*it).get_action, list, GetResultFilename(),
     1247                   GetCookieFilename(), "");
    11801248
    1181     return ok && ParseLineup(lineupid, tmpResultFile);
     1249    return ok && ParseLineup(lineupid, GetResultFilename());
    11821250}
    11831251
    11841252void DataDirectProcessor::SetAll(const QString &lineupid, bool val)
     
    14571525            .arg(lineupid).arg(list.size() - 1));
    14581526
    14591527    QString labsURL = providers[listings_provider].webURL;
    1460     return Post(labsURL + lineup.set_action, list, "", cookieFile, "");
     1528    return Post(labsURL + lineup.set_action, list, "",
     1529                GetCookieFilename(), "");
    14611530}
    14621531
    14631532bool DataDirectProcessor::UpdateListings(uint sourceid)
     
    15341603    return (*it);
    15351604}
    15361605
     1606QString DataDirectProcessor::GetPostFilename(void) const
     1607{
     1608    if (tmpPostFile.isEmpty())
     1609        tmpPostFile = createTempFile(tmpDir + "/mythtv_post_XXXXXX");
     1610    return QDeepCopy<QString>(tmpPostFile);
     1611}
     1612
     1613QString DataDirectProcessor::GetResultFilename(void) const
     1614{
     1615    if (tmpResultFile.isEmpty())
     1616        tmpResultFile = createTempFile(tmpDir + "/mythtv_result_XXXXXX");
     1617    return QDeepCopy<QString>(tmpResultFile);
     1618}
     1619
     1620QString DataDirectProcessor::GetCookieFilename(void) const
     1621{
     1622    if (cookieFile.isEmpty())
     1623        cookieFile = createTempFile(tmpDir + "/mythtv_cookies_XXXXXX");
     1624    return QDeepCopy<QString>(cookieFile);
     1625}
     1626
     1627void DataDirectProcessor::SetUserID(const QString &uid)
     1628{
     1629    userid = QDeepCopy<QString>(uid);
     1630}
     1631
     1632void DataDirectProcessor::SetPassword(const QString &pwd)
     1633{
     1634    password = QDeepCopy<QString>(pwd);
     1635}
     1636
     1637void DataDirectProcessor::SetInputFile(const QString &file)
     1638{
     1639    inputfilename = QDeepCopy<QString>(file);
     1640}
     1641
    15371642bool DataDirectProcessor::Post(QString url, const PostList &list,
    15381643                               QString documentFile,
    15391644                               QString inCookieFile, QString outCookieFile)
  • libs/libmythtv/videosource.cpp

     
    2020#include <qmap.h>
    2121#include <qdir.h>
    2222#include <qprocess.h>
     23#include <qdatetime.h>
    2324
    2425// MythTV headers
    2526#include "mythconfig.h"
     
    4445#include "videodev_myth.h"
    4546#endif
    4647
     48static bool is_grabber_external(const QString &grabber)
     49{
     50    return !(grabber == "datadirect" ||
     51             grabber == "eitonly" ||
     52             grabber == "schedulesdirect1" ||
     53             grabber == "/bin/true");
     54}
     55
    4756VideoSourceSelector::VideoSourceSelector(uint           _initial_sourceid,
    4857                                         const QString &_card_types,
    4958                                         bool           _must_have_mplexid) :
     
    295304{
    296305  public:
    297306    DataDirectPassword(const VideoSource &parent) :
    298         LineEditSetting(this), VideoSourceDBStorage(this, parent, "password")
     307        LineEditSetting(this, true),
     308        VideoSourceDBStorage(this, parent, "password")
    299309    {
     310        SetPasswordEcho(true);
    300311        setLabel(QObject::tr("Password"));
    301312    }
    302313};
     
    307318{
    308319    (void) uid;
    309320    (void) pwd;
    310     (void) _source;
    311321#ifdef USING_BACKEND
    312322    if (uid.isEmpty() || pwd.isEmpty())
    313323        return;
     
    348358void DataDirect_config::load()
    349359{
    350360    VerticalConfigurationGroup::load();
    351     if ((userid->getValue() != lastloadeduserid) ||
    352         (password->getValue() != lastloadedpassword))
     361    bool is_sd_userid = userid->getValue().contains("@") > 0;
     362    bool match = ((is_sd_userid  && (source == DD_SCHEDULES_DIRECT)) ||
     363                  (!is_sd_userid && (source == DD_ZAP2IT)));
     364    if (((userid->getValue() != lastloadeduserid) ||
     365         (password->getValue() != lastloadedpassword)) && match)
    353366    {
    354367        lineupselector->fillSelections(userid->getValue(),
    355368                                       password->getValue(),
     
    442455        "instead of just 'mythfilldatabase'.\nYour grabber does not provide "
    443456        "channel numbers, so you have to set them manually.");
    444457
    445     if (grabber != "datadirect" && grabber != "eitonly" &&
    446         grabber != "/bin/true")
     458    if (is_grabber_external(grabber))
    447459    {
    448460        VERBOSE(VB_IMPORTANT, "\n" << err_msg);
    449461        MythPopupBox::showOkPopup(
     
    508520    // only save settings for the selected grabber
    509521    setSaveAll(false);
    510522
    511     addTarget("datadirect", new DataDirect_config(parent));
    512     grabber->addSelection("North America (DataDirect) (Internal)", "datadirect");
     523    addTarget("schedulesdirect1",
     524              new DataDirect_config(parent, DD_SCHEDULES_DIRECT));
     525    grabber->addSelection("North America (SchedulesDirect.org) "
     526                          "(Internal)", "schedulesdirect1");
    513527
     528#if 1
     529    addTarget("datadirect", new DataDirect_config(parent, DD_ZAP2IT));
     530    grabber->addSelection(
     531        "North America (TMS Labs) (Internal)", "datadirect");
     532#endif
     533
    514534    addTarget("eitonly", new EITOnly_config(parent));
    515535    grabber->addSelection("Transmitted guide only (EIT)", "eitonly");
    516536
  • libs/libmyth/settings.cpp

     
    639639        connect(edit, SIGNAL(changeHelpText(QString)), cg,
    640640                SIGNAL(changeHelpText(QString)));
    641641
    642     edit->setRW(rw);
     642    setRW(rw);
     643    SetPasswordEcho(password_echo);
    643644
    644645    return widget;
    645646}
     
    664665    }
    665666}
    666667
     668void LineEditSetting::SetPasswordEcho(bool b)
     669{
     670    password_echo = b;
     671    if (edit)
     672        edit->setEchoMode(b ? QLineEdit::Password : QLineEdit::Normal);
     673}
     674
    667675QWidget* SliderSetting::configWidget(ConfigurationGroup *cg, QWidget* parent,
    668676                                     const char* widgetName) {
    669677    QHBox* widget;
  • libs/libmyth/util.cpp

     
    3232#include <qpainter.h>
    3333#include <qpixmap.h>
    3434#include <qfont.h>
     35#include <qfile.h>
    3536
    3637// Myth headers
    3738#include "mythconfig.h"
     
    603604
    604605    return false;
    605606}
     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 */
     629long 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
     680QString 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

     
    1616class QImage;
    1717class QPainter;
    1818class QFont;
     19class QFile;
    1920
    2021class MPUBLIC MythTimer
    2122{
     
    7374MPUBLIC bool ping(const QString &host, int timeout);
    7475MPUBLIC bool telnet(const QString &host, int port);
    7576
     77MPUBLIC long long copy(QFile &dst, QFile &src, uint block_size = 0);
     78MPUBLIC QString createTempFile(QString name_template = "/tmp/mythtv_XXXXX",
     79                               bool dir = false);
     80
    7681#endif // UTIL_H_
  • libs/libmyth/mythcontext.h

     
    208208
    209209/// Update this whenever the plug-in API changes.
    210210/// Including changes in the libmythtv class methods used by plug-ins.
    211 #define MYTH_BINARY_VERSION "0.20.20070717-1"
     211#define MYTH_BINARY_VERSION "0.20.20070817-1"
    212212
    213213/** \brief Increment this whenever the MythTV network protocol changes.
    214214 *
  • libs/libmyth/settings.h

     
    200200{
    201201  protected:
    202202    LineEditSetting(Storage *_storage, bool readwrite = true) :
    203         Setting(_storage), edit(NULL), rw(readwrite) { }
     203        Setting(_storage), edit(NULL), rw(readwrite), password_echo(false) { }
    204204
    205205  public:
    206206    virtual QWidget* configWidget(ConfigurationGroup *cg, QWidget* parent,
     
    217217
    218218    virtual void setEnabled(bool b);
    219219    virtual void setVisible(bool b);
     220    virtual void SetPasswordEcho(bool b);
    220221
    221222private:
    222223    MythLineEdit* edit;
    223224    bool rw;
     225    bool password_echo;
    224226};
    225227
    226228// TODO: set things up so that setting the value as a string emits
  • programs/mythfilldatabase/filldata.cpp

     
    2626// filldata headers
    2727#include "filldata.h"
    2828
     29bool is_grabber_external(const QString &grabber)
     30{
     31    return !(grabber == "datadirect" ||
     32             grabber == "eitonly" ||
     33             grabber == "schedulesdirect1" ||
     34             grabber == "/bin/true");
     35}
     36
     37bool is_grabber_datadirect(const QString &grabber)
     38{
     39    return (grabber == "datadirect") || (grabber == "schedulesdirect1");
     40}
     41
     42bool is_grabber_labs(const QString &grabber)
     43{
     44    return grabber == "datadirect";
     45}
     46
    2947// DataDirect stuff
    3048void FillData::DataDirectStationUpdate(Source source, bool update_icons)
    3149{
     
    4462        icon_data.UpdateSourceIcons(source.id);
    4563
    4664    // Unselect channels not in users lineup for DVB, HDTV
    47     if (!insert_channels && (new_channels > 0))
     65    if (!insert_channels && (new_channels > 0) &&
     66        is_grabber_labs(source.xmltvgrabber))
    4867    {
    4968        bool ok0 = (logged_in == source.userid);
    5069        bool ok1 = (raw_lineup == source.id);
     
    6988
    7089bool FillData::DataDirectUpdateChannels(Source source)
    7190{
     91    if (!is_grabber_labs(source.xmltvgrabber))
     92    {
     93        VERBOSE(VB_IMPORTANT, "FillData: We only support "
     94                "DataDirectUpdateChannels with TMS Labs channel editor");
     95        return false;
     96    }
     97
    7298    ddprocessor.SetListingsProvider(DD_ZAP2IT);
    7399    ddprocessor.SetUserID(source.userid);
    74100    ddprocessor.SetPassword(source.password);
     
    87113bool FillData::grabDDData(Source source, int poffset,
    88114                          QDate pdate, int ddSource)
    89115{
     116    if (source.dd_dups.empty())
     117        ddprocessor.SetCacheData(false);
     118    else
     119    {
     120        VERBOSE(VB_GENERAL, QString(
     121                    "This DataDirect listings source is "
     122                    "shared by %1 MythTV lineups")
     123                .arg(source.dd_dups.size()+1));
     124        if (source.id > source.dd_dups[0])
     125        {
     126            VERBOSE(VB_IMPORTANT, "We should use cached data for this one");
     127        }
     128        else if (source.id < source.dd_dups[0])
     129        {
     130            VERBOSE(VB_IMPORTANT, "We should keep data around after this one");
     131        }
     132        ddprocessor.SetCacheData(true);
     133    }
     134
    90135    ddprocessor.SetListingsProvider(ddSource);
    91136    ddprocessor.SetUserID(source.userid);
    92137    ddprocessor.SetPassword(source.password);
     
    251296
    252297    if (xmltv_grabber == "datadirect")
    253298        return grabDDData(source, offset, *qCurrentDate, DD_ZAP2IT);
     299    if (xmltv_grabber == "schedulesdirect1")
     300        return grabDDData(source, offset, *qCurrentDate, DD_SCHEDULES_DIRECT);
    254301
    255302    char tempfilename[] = "/tmp/mythXXXXXX";
    256303    if (mkstemp(tempfilename) == -1)
     
    389436bool FillData::fillData(QValueList<Source> &sourcelist)
    390437{
    391438    QValueList<Source>::Iterator it;
     439    QValueList<Source>::Iterator it2;
    392440
    393441    QString status, querystr;
    394442    MSqlQuery query(MSqlQuery::InitCon());
     
    402450
    403451    need_post_grab_proc = false;
    404452    int nonewdata = 0;
     453    bool has_dd_source = false;
    405454
     455    // find all DataDirect duplicates, so we only data download once.
    406456    for (it = sourcelist.begin(); it != sourcelist.end(); ++it)
    407457    {
     458        if (!is_grabber_datadirect((*it).xmltvgrabber))
     459            continue;
    408460
     461        has_dd_source = true;
     462        for (it2 = sourcelist.begin(); it2 != sourcelist.end(); ++it2)
     463        {
     464            if (((*it).id           != (*it2).id)           &&
     465                ((*it).xmltvgrabber == (*it2).xmltvgrabber) &&
     466                ((*it).userid       == (*it2).userid)       &&
     467                ((*it).password     == (*it2).password))
     468            {
     469                (*it).dd_dups.push_back((*it2).id);
     470            }
     471        }
     472    }
     473    if (has_dd_source)
     474        ddprocessor.CreateTempDirectory();
     475
     476    for (it = sourcelist.begin(); it != sourcelist.end(); ++it)
     477    {
     478
    409479        query.prepare("SELECT MAX(endtime) FROM program p LEFT JOIN channel c "
    410480                      "ON p.chanid=c.chanid WHERE c.sourceid= :SRCID "
    411481                      "AND manualid = 0;");
     
    427497
    428498        if (xmltv_grabber == "eitonly")
    429499        {
    430             VERBOSE(VB_IMPORTANT, "Source configured to use only the "
    431                     "broadcasted guide data. Skipping.");
     500            VERBOSE(VB_GENERAL,
     501                    QString("Source %1 configured to use only the "
     502                            "broadcasted guide data. Skipping.")
     503                    .arg((*it).id));
     504
    432505            externally_handled++;
    433506            query.exec(QString("UPDATE settings SET data ='%1' "
    434507                               "WHERE value='mythfilldatabaseLastRunStart' OR "
     
    440513                 xmltv_grabber == "none" ||
    441514                 xmltv_grabber == "")
    442515        {
    443             VERBOSE(VB_IMPORTANT,
    444                     "Source configured with no grabber. Nothing to do.");
     516            VERBOSE(VB_GENERAL,
     517                    QString("Source %1 configured with no grabber. "
     518                            "Nothing to do.").arg((*it).id));
     519
    445520            externally_handled++;
    446521            query.exec(QString("UPDATE settings SET data ='%1' "
    447522                               "WHERE value='mythfilldatabaseLastRunStart' OR "
     
    486561
    487562        bool hasprefmethod = false;
    488563
    489         if (xmltv_grabber != "datadirect")
     564        if (is_grabber_external(xmltv_grabber))
    490565        {
    491566
    492567            QProcess grabber_capabilities_proc(xmltv_grabber);
     
    584659            }
    585660        }
    586661
    587         need_post_grab_proc |= (xmltv_grabber != "datadirect");
     662        need_post_grab_proc |= !is_grabber_datadirect(xmltv_grabber);
    588663
    589         if ((xmltv_grabber == "datadirect") && dd_grab_all)
     664        if (is_grabber_labs(xmltv_grabber) && dd_grab_all)
    590665        {
    591666            if (only_update_channels)
    592667                DataDirectUpdateChannels(*it);
     
    601676            if (!grabData(*it, 0))
    602677                ++failures;
    603678        }
    604         else if ((*it).xmltvgrabber_baseline || xmltv_grabber == "datadirect")
     679        else if ((*it).xmltvgrabber_baseline ||
     680                 is_grabber_datadirect(xmltv_grabber))
    605681        {
    606682
    607683            QDate qCurrentDate = QDate::currentDate();
     
    612688
    613689            if (maxDays > 0) // passed with --max-days
    614690                grabdays = maxDays;
    615             else if (xmltv_grabber == "datadirect")
     691            else if (is_grabber_datadirect(xmltv_grabber))
    616692                grabdays = 14;
    617693
    618694            grabdays = (only_update_channels) ? 1 : grabdays;
     
    620696            if (grabdays == 1)
    621697                refresh_today = true;
    622698
    623             if ((xmltv_grabber == "datadirect") && only_update_channels)
     699            if (is_grabber_labs(xmltv_grabber) && only_update_channels)
    624700            {
    625701                DataDirectUpdateChannels(*it);
    626702                grabdays = 0;
  • programs/mythfilldatabase/main.cpp

     
    579579                       newsource.xmltvgrabber_prefmethod = "";
    580580
    581581                       sourcelist.append(newsource);
    582                        if (newsource.xmltvgrabber == "datadirect")
    583                            usingDataDirect = true;
     582                       usingDataDirect =
     583                           ((newsource.xmltvgrabber == "datadirect") ||
     584                            (newsource.xmltvgrabber == "schedulesdirect1"));
    584585                  }
    585586             }
    586587             else
  • programs/mythfilldatabase/filldata.h

     
    2626    bool    xmltvgrabber_manualconfig;
    2727    bool    xmltvgrabber_cache;
    2828    QString xmltvgrabber_prefmethod;
     29    vector<int> dd_dups;
    2930};
    3031
    3132class FillData