Ticket #3842: 3842-head-v2.patch

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

Adds basic caching of DD downloaded data.

  • 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
     
    308309    void SetListingsProvider(uint i)
    309310        { listings_provider = i % DD_PROVIDER_COUNT; }
    310311    void SetInputFile(const QString &file)      { inputfilename      = file; }
     312    void SetCacheData(bool cd)                  { cachedata          = cd; }
    311313
    312314    // static commands (these update temp DB tables)
    313315    static void UpdateStationViewTable(QString lineupid);
     
    346348
    347349    QString       userid;
    348350    QString       password;
     351    bool          cachedata;
    349352
    350353    QDateTime     actuallistingsfrom;
    351354    QDateTime     actuallistingsto;
     
    361364    QString       tmpResultFile;
    362365    QString       cookieFile;
    363366    QDateTime     cookieFileDT;
     367
     368    static QString tmpDir;
    364369};
    365370
    366371#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;
    3133static QMap<QString,uint> lineupid_to_srcid;
    3234static QMap<uint,QString> srcid_to_type;
    3335
     36QString DataDirectProcessor::tmpDir = "/tmp";
     37
    3438static void    set_lineup_type(const QString &lineupid, const QString &type);
    3539static QString get_lineup_type(uint sourceid);
    3640static QString get_setting(QString line, QString key);
     
    533537DataDirectProcessor::DataDirectProcessor(uint lp, QString user, QString pass) :
    534538    listings_provider(lp % DD_PROVIDER_COUNT),
    535539    userid(user),               password(pass),
     540    cachedata(false),
    536541    inputfilename(""),          tmpPostFile(""),
    537542    tmpResultFile(""),          cookieFile(""),
    538543    cookieFileDT()
     
    542547        "http://datadirect.webservices.zap2it.com/tvlistings/xtvdService",
    543548        "http://labs.zap2it.com",
    544549        "/ztvws/ztvws_login/1,1059,TMS01-1,00.html");
     550    DataDirectURLs urls1(
     551        "Schedules Direct",
     552        "http://webservices.schedulesdirect.tmsdatadirect.com"
     553        "/schedulesdirect/tvlistings/xtvdService",
     554        "http://schedulesdirect.org",
     555        "/login/index.php");
    545556    providers.push_back(urls0);
     557    providers.push_back(urls1);
    546558
    547     QString tmpDir = "/tmp";
    548559    tmpPostFile   = makeTempFile(tmpDir + "/mythtv_post_XXXXXX");
    549560    tmpResultFile = makeTempFile(tmpDir + "/mythtv_result_XXXXXX");
    550561    cookieFile    = makeTempFile(tmpDir + "/mythtv_cookies_XXXXXX");
     
    552563
    553564DataDirectProcessor::~DataDirectProcessor()
    554565{
     566    VERBOSE(VB_GENERAL, LOC + "Deleting temporary files");
     567
    555568    unlink(tmpPostFile.ascii());
    556569    unlink(tmpResultFile.ascii());
    557570    unlink(cookieFile.ascii());
     571
     572    QDir d(tmpDir, "mythtv_dd_cache_*", QDir::Name,
     573           QDir::Files | QDir::NoSymLinks);
     574
     575    for (uint i = 0; i < d.count(); i++)
     576    {
     577        //cout<<"deleting '"<<tmpDir<<"/"<<d[i]<<"'"<<endl;
     578        unlink((tmpDir + "/" + d[i]).ascii());
     579    }
    558580}
    559581
    560582void DataDirectProcessor::UpdateStationViewTable(QString lineupid)
     
    9941016
    9951017    QString err = "";
    9961018    QString ddurl = providers[listings_provider].webServiceURL;
     1019    QString inputfile = inputfilename;
     1020    QString cache_dd_data = QString::null;
    9971021
    998     FILE *fp = DDPost(ddurl, tmpPostFile, inputfilename,
     1022    if (cachedata)
     1023    {
     1024        cache_dd_data = tmpDir + QString("/mythtv_dd_cache_%1_%2_%3_%4_%5")
     1025            .arg(QDateTime::currentDateTime().toString("yyMMdd"))
     1026            .arg(GetListingsProvider())
     1027            .arg(GetUserID().ascii())
     1028            .arg(pstartDate.toString())
     1029            .arg(pendDate.toString());
     1030
     1031        if (QFile(cache_dd_data).exists() && inputfilename.isEmpty())
     1032        {
     1033            VERBOSE(VB_GENERAL, LOC + "Copying from DD cache");
     1034            inputfile = cache_dd_data;
     1035        }
     1036    }
     1037
     1038    FILE *fp = DDPost(ddurl, tmpPostFile, inputfile,
    9991039                      GetUserID(), GetPassword(),
    10001040                      pstartDate, pendDate, err);
    10011041    if (!fp)
     
    10051045        return false;
    10061046    }
    10071047
     1048    if (cachedata && (inputfile != cache_dd_data))
     1049    {
     1050        QFile in, out(cache_dd_data);
     1051        bool ok = out.open(IO_WriteOnly);
     1052        if (!ok)
     1053        {
     1054            VERBOSE(VB_IMPORTANT, LOC_WARN +
     1055                    "Can not open DD cache file in '" +
     1056                    tmpDir + "' for writing!");
     1057        }
     1058        else
     1059        {
     1060            VERBOSE(VB_GENERAL, LOC + "Saving listings to DD cache");
     1061            ok = in.open(IO_ReadOnly, fp);
     1062            out.close(); // let copy routine handle dst file
     1063        }
     1064
     1065        if (ok)
     1066        {
     1067            if (Copy(out, in))
     1068            {
     1069                pclose(fp);
     1070                fp = fopen(cache_dd_data.ascii(), "r");
     1071            }
     1072            else
     1073            {
     1074                VERBOSE(VB_IMPORTANT,
     1075                        LOC_ERR + "Failed to save DD cache! "
     1076                        "redownloading data...");
     1077                cachedata = false;
     1078                pclose(fp);
     1079                fp = DDPost(ddurl, tmpPostFile, inputfile,
     1080                            GetUserID(), GetPassword(),
     1081                            pstartDate, pendDate, err);
     1082            }
     1083        }
     1084    }
     1085
    10081086    QFile f;
    10091087    if (f.open(IO_ReadOnly, fp))
    10101088    {
     
    10831161        "  channelMinor char(3) )";
    10841162
    10851163    dd_tables["dd_schedule"] =
    1086         "( programid char(12),           stationid char(12), "
     1164        "( programid char(40),           stationid char(12), "
    10871165        "  scheduletime datetime,        duration time,      "
    10881166        "  isrepeat bool,                stereo bool,        "
    10891167        "  subtitled bool,               hdtv bool,          "
     
    10931171        "INDEX progidx (programid) )";
    10941172
    10951173    dd_tables["dd_program"] =
    1096         "( programid char(12) NOT NULL,  seriesid char(12),     "
     1174        "( programid char(40) NOT NULL,  seriesid char(12),     "
    10971175        "  title varchar(120),           subtitle varchar(150), "
    10981176        "  description text,             mpaarating char(5),    "
    10991177        "  starrating char(5),           runtime time,          "
     
    11151193        "  partnumber int,               parttotal int,               "
    11161194        "  seriesid char(12),            originalairdate date,        "
    11171195        "  showtype varchar(30),         colorcode varchar(20),       "
    1118         "  syndicatedepisodenumber varchar(20), programid char(12),   "
     1196        "  syndicatedepisodenumber varchar(20), programid char(40),   "
    11191197        "  tvrating char(5),             mpaarating char(5),          "
    11201198        "INDEX progidx (programid))";
    11211199
    11221200    dd_tables["dd_productioncrew"] =
    1123         "( programid char(12),           role char(30),    "
     1201        "( programid char(40),           role char(30),    "
    11241202        "  givenname char(20),           surname char(20), "
    11251203        "  fullname char(41), "
    11261204        "INDEX progidx (programid), "
    11271205        "INDEX nameidx (fullname))";
    11281206
    11291207    dd_tables["dd_genre"] =
    1130         "( programid char(12) NOT NULL,  class char(30), "
     1208        "( programid char(40) NOT NULL,  class char(30), "
    11311209        "  relevance char(1), "
    11321210        "INDEX progidx (programid))";
    11331211
  • 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
  • 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);
     78
    7679#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());
     
    403451    need_post_grab_proc = false;
    404452    int nonewdata = 0;
    405453
     454    // find all DataDirect duplicates, so we only data download once.
    406455    for (it = sourcelist.begin(); it != sourcelist.end(); ++it)
    407456    {
     457        if (!is_grabber_datadirect((*it).xmltvgrabber))
     458            continue;
    408459
     460        for (it2 = sourcelist.begin(); it2 != sourcelist.end(); ++it2)
     461        {
     462            if (((*it).id           != (*it2).id)           &&
     463                ((*it).xmltvgrabber == (*it2).xmltvgrabber) &&
     464                ((*it).userid       == (*it2).userid)       &&
     465                ((*it).password     == (*it2).password))
     466            {
     467                (*it).dd_dups.push_back((*it2).id);
     468            }
     469        }
     470    }
     471
     472    for (it = sourcelist.begin(); it != sourcelist.end(); ++it)
     473    {
     474
    409475        query.prepare("SELECT MAX(endtime) FROM program p LEFT JOIN channel c "
    410476                      "ON p.chanid=c.chanid WHERE c.sourceid= :SRCID "
    411477                      "AND manualid = 0;");
     
    427493
    428494        if (xmltv_grabber == "eitonly")
    429495        {
    430             VERBOSE(VB_IMPORTANT, "Source configured to use only the "
    431                     "broadcasted guide data. Skipping.");
     496            VERBOSE(VB_GENERAL,
     497                    QString("Source %1 configured to use only the "
     498                            "broadcasted guide data. Skipping.")
     499                    .arg((*it).id));
     500
    432501            externally_handled++;
    433502            query.exec(QString("UPDATE settings SET data ='%1' "
    434503                               "WHERE value='mythfilldatabaseLastRunStart' OR "
     
    440509                 xmltv_grabber == "none" ||
    441510                 xmltv_grabber == "")
    442511        {
    443             VERBOSE(VB_IMPORTANT,
    444                     "Source configured with no grabber. Nothing to do.");
     512            VERBOSE(VB_GENERAL,
     513                    QString("Source %1 configured with no grabber. "
     514                            "Nothing to do.").arg((*it).id));
     515
    445516            externally_handled++;
    446517            query.exec(QString("UPDATE settings SET data ='%1' "
    447518                               "WHERE value='mythfilldatabaseLastRunStart' OR "
     
    486557
    487558        bool hasprefmethod = false;
    488559
    489         if (xmltv_grabber != "datadirect")
     560        if (is_grabber_external(xmltv_grabber))
    490561        {
    491562
    492563            QProcess grabber_capabilities_proc(xmltv_grabber);
     
    584655            }
    585656        }
    586657
    587         need_post_grab_proc |= (xmltv_grabber != "datadirect");
     658        need_post_grab_proc |= !is_grabber_datadirect(xmltv_grabber);
    588659
    589         if ((xmltv_grabber == "datadirect") && dd_grab_all)
     660        if (is_grabber_labs(xmltv_grabber) && dd_grab_all)
    590661        {
    591662            if (only_update_channels)
    592663                DataDirectUpdateChannels(*it);
     
    601672            if (!grabData(*it, 0))
    602673                ++failures;
    603674        }
    604         else if ((*it).xmltvgrabber_baseline || xmltv_grabber == "datadirect")
     675        else if ((*it).xmltvgrabber_baseline ||
     676                 is_grabber_datadirect(xmltv_grabber))
    605677        {
    606678
    607679            QDate qCurrentDate = QDate::currentDate();
     
    612684
    613685            if (maxDays > 0) // passed with --max-days
    614686                grabdays = maxDays;
    615             else if (xmltv_grabber == "datadirect")
     687            else if (is_grabber_datadirect(xmltv_grabber))
    616688                grabdays = 14;
    617689
    618690            grabdays = (only_update_channels) ? 1 : grabdays;
     
    620692            if (grabdays == 1)
    621693                refresh_today = true;
    622694
    623             if ((xmltv_grabber == "datadirect") && only_update_channels)
     695            if (is_grabber_labs(xmltv_grabber) && only_update_channels)
    624696            {
    625697                DataDirectUpdateChannels(*it);
    626698                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