Example #1
0
        bool SqlLexer::ExpectNextToken(TokenType::Type typ, const char* expected)
        {
            OdbcExpected<bool> hasNext = Shift();

            if (!hasNext.IsOk() || !*hasNext)
                return false;

            const SqlToken& token = GetCurrentToken();

            return token.GetType() == typ && token.ToLower() == expected;
        }
Example #2
0
bool UPnpCDSVideo::LoadVideos(const UPnpCDSRequest* pRequest,
                              UPnpCDSExtensionResults* pResults,
                              IDTokenMap tokens)
{
    QString sId = pRequest->m_sParentId;
     if (GetCurrentToken(pRequest->m_sParentId).first != "video")
         sId.append("/Video");
    sId.append("=%1");

    uint16_t nCount = pRequest->m_nRequestedCount;
    uint16_t nOffset = pRequest->m_nStartingIndex;

    // We must use a dedicated connection to get an acccurate value from
    // FOUND_ROWS()
    MSqlQuery query(MSqlQuery::InitCon(MSqlQuery::kDedicatedConnection));

    QString sql = "SELECT SQL_CALC_FOUND_ROWS "
                  "v.intid, title, subtitle, filename, director, plot, "
                  "rating, year, userrating, length, "
                  "season, episode, coverfile, insertdate, host, "
                  "g.genre, studio, collectionref, contenttype "
                  "FROM videometadata v "
                  "LEFT JOIN videogenre g ON g.intid=v.category "
                  "%1 " //
                  "ORDER BY title, season, episode "
                  "LIMIT :OFFSET,:COUNT ";

    QStringList clauses;
    QString whereString = BuildWhereClause(clauses, tokens);

    query.prepare(sql.arg(whereString));

    BindValues(query, tokens);

    query.bindValue(":OFFSET", nOffset);
    query.bindValue(":COUNT", nCount);

    if (!query.exec())
        return false;

    while (query.next())
    {

        int            nVidID       = query.value( 0).toInt();
        QString        sTitle       = query.value( 1).toString();
        QString        sSubtitle    = query.value( 2).toString();
        QString        sFilePath    = query.value( 3).toString();
        QString        sDirector    = query.value( 4).toString();
        QString        sPlot        = query.value( 5).toString();
        // QString        sRating      = query.value( 6).toString();
        int            nYear        = query.value( 7).toInt();
        // int             nUserRating  = query.value( 8).toInt();

        uint32_t       nLength      = query.value( 9).toUInt();
        // Convert from minutes to milliseconds
        nLength = (nLength * 60 *1000);

        int            nSeason      = query.value(10).toInt();
        int            nEpisode     = query.value(11).toInt();
        QString        sCoverArt    = query.value(12).toString();
        QDateTime      dtInsertDate =
            MythDate::as_utc(query.value(13).toDateTime());
        QString        sHostName    = query.value(14).toString();
        QString        sGenre       = query.value(15).toString();
    //    QString        sStudio      = query.value(16).toString();
    //    QString        sCollectionRef    = query.value(17).toString();
        QString        sContentType = query.value(18).toString();

        // ----------------------------------------------------------------------
        // Cache Host ip Address & Port
        // ----------------------------------------------------------------------

        // If the host-name is empty then we assume it is our local host
        // otherwise, we look up the host's IP address and port.  When the
        // client then trys to play the video it will be directed to the
        // host which actually has the content.
        if (!m_mapBackendIp.contains( sHostName ))
        {
            if (sHostName.isEmpty())
            {
                m_mapBackendIp[sHostName] =
                    gCoreContext->GetBackendServerIP4();
            }
            else
            {
                m_mapBackendIp[sHostName] =
                    gCoreContext->GetBackendServerIP4(sHostName);
            }
        }

        if (!m_mapBackendPort.contains( sHostName ))
        {
            if (sHostName.isEmpty())
            {
                m_mapBackendPort[sHostName] =
                    gCoreContext->GetBackendStatusPort();
            }
            else
            {
                m_mapBackendPort[sHostName] =
                    gCoreContext->GetBackendStatusPort(sHostName);
            }
        }


        // ----------------------------------------------------------------------
        // Build Support Strings
        // ----------------------------------------------------------------------

        QString sName      = sTitle;
        if( !sSubtitle.isEmpty() )
        {
            sName += " - " + sSubtitle;
        }

        QUrl URIBase;
        URIBase.setScheme("http");
        URIBase.setHost(m_mapBackendIp[sHostName]);
        URIBase.setPort(m_mapBackendPort[sHostName]);

        CDSObject *pItem;
        if (sContentType == "MOVIE")
        {
            pItem = CDSObject::CreateMovie( sId.arg(nVidID),
                                            sTitle,
                                            pRequest->m_sParentId );
        }
        else
        {
            pItem = CDSObject::CreateVideoItem( sId.arg(nVidID),
                                                sName,
                                                pRequest->m_sParentId );
        }

        if (!sSubtitle.isEmpty())
            pItem->SetPropValue( "description", sSubtitle );
        else
            pItem->SetPropValue( "description", sPlot.left(128).append(" ..."));
        pItem->SetPropValue( "longDescription", sPlot );
        pItem->SetPropValue( "director"       , sDirector );

        if (nEpisode > 0 || nSeason > 0) // There has got to be a better way
        {
            pItem->SetPropValue( "seriesTitle"  , sTitle );
            pItem->SetPropValue( "programTitle"  , sSubtitle );
            pItem->SetPropValue( "episodeNumber"  , QString::number(nEpisode));
            //pItem->SetPropValue( "episodeCount"  , nEpisodeCount);
        }

        pItem->SetPropValue( "genre"       , sGenre );
        if (nYear > 1830 && nYear < 9999)
            pItem->SetPropValue( "date",  QDate(nYear,1,1).toString(Qt::ISODate));
        else
            pItem->SetPropValue( "date", UPnPDateTime::DateTimeFormat(dtInsertDate) );

        // HACK: Windows Media Centre Compat (Not a UPnP or DLNA requirement, should only be done for WMC)
//         pItem->SetPropValue( "genre"          , "[Unknown Genre]"     );
//         pItem->SetPropValue( "actor"          , "[Unknown Author]"    );
//         pItem->SetPropValue( "creator"        , "[Unknown Creator]"   );
//         pItem->SetPropValue( "album"          , "[Unknown Album]"     );
        ////

        //pItem->SetPropValue( "producer"       , );
        //pItem->SetPropValue( "rating"         , );
        //pItem->SetPropValue( "actor"          , );
        //pItem->SetPropValue( "publisher"      , );
        //pItem->SetPropValue( "language"       , );
        //pItem->SetPropValue( "relation"       , );
        //pItem->SetPropValue( "region"         , );

        // Only add the reference ID for items which are not in the
        // 'All Videos' container
        QString sRefIDBase = QString("%1/Video").arg(m_sExtensionId);
        if ( pRequest->m_sParentId != sRefIDBase )
        {
            QString sRefId = QString( "%1=%2")
                                .arg( sRefIDBase )
                                .arg( nVidID );

            pItem->SetPropValue( "refID", sRefId );
        }

        // FIXME - If the slave or storage hosting this video is offline we
        //         won't find it. We probably shouldn't list it, but better
        //         still would be storing the filesize in the database so we
        //         don't waste time re-checking it constantly
        QString sFullFileName = sFilePath;
        if (!QFile::exists( sFullFileName ))
        {
            StorageGroup sgroup("Videos");
            sFullFileName = sgroup.FindFile( sFullFileName );
        }
        QFileInfo fInfo( sFullFileName );

        // ----------------------------------------------------------------------
        // Add Video Resource Element based on File extension (HTTP)
        // ----------------------------------------------------------------------

        QString sMimeType = HTTPRequest::GetMimeType( QFileInfo(sFilePath).suffix() );

        // HACK: If we are dealing with a Sony Blu-ray player then we fake the
        // MIME type to force the video to appear
//         if ( pRequest->m_eClient == CDS_ClientSonyDB )
//         {
//             sMimeType = "video/avi";
//         }

        QUrl    resURI    = URIBase;
        resURI.setPath("Content/GetVideo");
        resURI.addQueryItem("Id", QString::number(nVidID));

        QString sProtocol = DLNA::ProtocolInfoString(UPNPProtocol::kHTTP,
                                                     sMimeType);

        Resource *pRes = pItem->AddResource( sProtocol, resURI.toEncoded() );
        pRes->AddAttribute( "size"    , QString("%1").arg(fInfo.size()) );
        pRes->AddAttribute( "duration", UPnPDateTime::resDurationFormat(nLength) );

        // ----------------------------------------------------------------------
        // Add Artwork
        // ----------------------------------------------------------------------
        if (!sCoverArt.isEmpty() && (sCoverArt != "No Cover"))
        {
            PopulateArtworkURIS(pItem, nVidID, URIBase);
        }

        pResults->Add( pItem );
        pItem->DecrRef();
    }

    // Just in case FOUND_ROWS() should fail, ensure m_nTotalMatches contains
    // at least the size of this result set
    if (query.size() >= 0)
        pResults->m_nTotalMatches = query.size();

    // Fetch the total number of matches ignoring any LIMITs
    query.prepare("SELECT FOUND_ROWS()");
    if (query.exec() && query.next())
            pResults->m_nTotalMatches = query.value(0).toUInt();

    return true;
}