bool RemoteRecordPending(uint cardid, const ProgramInfo *pginfo,
                         int secsleft, bool hasLater)
{
    if (gCoreContext->IsBackend())
    {
        TVRec *rec = TVRec::GetTVRec(cardid);
        if (rec)
        {
            rec->RecordPending(pginfo, secsleft, hasLater);
            return true;
        }
    }

    QStringList strlist(QString("QUERY_REMOTEENCODER %1").arg(cardid));
    strlist << "RECORD_PENDING";
    strlist << QString::number(secsleft);
    strlist << QString::number(hasLater);
    pginfo->ToStringList(strlist);

    if (!gCoreContext->SendReceiveStringList(strlist) || strlist.empty())
        return false;

    return strlist[0].toUpper() == "OK";
}
RemoteEncoder *RemoteRequestFreeRecorderFromList
(const QStringList &qualifiedRecorders, const vector<uint> &excluded_cardids)
{
#if 0
    QStringList strlist( "GET_FREE_RECORDER_LIST" );

    if (!gCoreContext->SendReceiveStringList(strlist, true))
        return NULL;

    for (QStringList::const_iterator recIter = qualifiedRecorders.begin();
         recIter != qualifiedRecorders.end(); ++recIter)
    {
        if (!strlist.contains(*recIter))
        {
            // did not find it in the free recorder list. We
            // move on to check the next recorder
            continue;
        }
        // at this point we found a free recorder that fulfills our request
        return RemoteGetExistingRecorder((*recIter).toInt());
    }
    // didn't find anything. just return NULL.
    return NULL;
#endif
    vector<uint> freeRecorders =
        RemoteRequestFreeRecorderList(excluded_cardids);
    for (QStringList::const_iterator recIter = qualifiedRecorders.begin();
         recIter != qualifiedRecorders.end(); ++recIter)
    {
        if (find(freeRecorders.begin(),
                 freeRecorders.end(),
                 (*recIter).toUInt()) != freeRecorders.end())
            return RemoteGetExistingRecorder((*recIter).toInt());
    }
    return NULL;
}
Exemple #3
0
/// Download preview & get timestamp if newer than cachefile's
/// last modified time, otherwise just get the timestamp
QDateTime RemoteGetPreviewIfModified(
    const ProgramInfo &pginfo, const QString &cachefile)
{
    QString loc("RemoteGetPreviewIfModified: ");
    QDateTime cacheLastModified;
    QFileInfo cachefileinfo(cachefile);
    if (cachefileinfo.exists())
        cacheLastModified = cachefileinfo.lastModified();

    QStringList strlist("QUERY_PIXMAP_GET_IF_MODIFIED");
    strlist << ((cacheLastModified.isValid()) ? // unix secs, UTC
                QString::number(cacheLastModified.toTime_t()) : QString("-1"));
    strlist << QString::number(200 * 1024); // max size of preview file
    pginfo.ToStringList(strlist);

    if (!gCoreContext->SendReceiveStringList(strlist) ||
        strlist.isEmpty() || strlist[0] == "ERROR")
    {
        LOG(VB_GENERAL, LOG_ERR, loc + "Remote error" +
            ((strlist.size() >= 2) ? (":\n\t\t\t" + strlist[1]) : ""));

        return QDateTime();
    }

    if (strlist[0] == "WARNING")
    {
        LOG(VB_NETWORK, LOG_WARNING, loc + "Remote warning" +
                 ((strlist.size() >= 2) ? (":\n\t\t\t" + strlist[1]) : ""));

        return QDateTime();
    }

    QDateTime retdatetime;
    qlonglong timet = strlist[0].toLongLong();
    if (timet >= 0)
        retdatetime = MythDate::fromTime_t(timet);

    if (strlist.size() < 4)
    {
        return retdatetime;
    }

    size_t  length     = strlist[1].toULongLong();
    quint16 checksum16 = strlist[2].toUInt();
    QByteArray data = QByteArray::fromBase64(strlist[3].toLatin1());
    if ((size_t) data.size() < length)
    { // (note data.size() may be up to 3 bytes longer after decoding
        LOG(VB_GENERAL, LOG_ERR, loc +
            QString("Preview size check failed %1 < %2")
                .arg(data.size()).arg(length));
        return QDateTime();
    }
    data.resize(length);

    if (checksum16 != qChecksum(data.constData(), data.size()))
    {
        LOG(VB_GENERAL, LOG_ERR, loc + "Preview checksum failed");
        return QDateTime();
    }

    QString pdir(cachefile.section("/", 0, -2));
    QDir cfd(pdir);
    if (!cfd.exists() && !cfd.mkdir(pdir))
    {
        LOG(VB_GENERAL, LOG_ERR, loc +
            QString("Unable to create remote cache directory '%1'")
                .arg(pdir));

        return QDateTime();
    }

    QFile file(cachefile);
    if (!file.open(QIODevice::WriteOnly|QIODevice::Truncate))
    {
        LOG(VB_GENERAL, LOG_ERR, loc +
            QString("Unable to open cached preview file for writing '%1'")
                .arg(cachefile));

        return QDateTime();
    }

    off_t offset = 0;
    size_t remaining = length;
    uint failure_cnt = 0;
    while ((remaining > 0) && (failure_cnt < 5))
    {
        ssize_t written = file.write(data.data() + offset, remaining);
        if (written < 0)
        {
            failure_cnt++;
            usleep(50000);
            continue;
        }

        failure_cnt  = 0;
        offset      += written;
        remaining   -= written;
    }

    if (remaining)
    {
        LOG(VB_GENERAL, LOG_ERR, loc +
            QString("Failed to write cached preview file '%1'")
                .arg(cachefile));

        file.resize(0); // in case unlink fails..
        file.remove();  // closes fd
        return QDateTime();
    }

    file.close();

    return retdatetime;
}