Ticket #8801: 0001-Added-patch-from-8801-redo-upnp-video.patch

File 0001-Added-patch-from-8801-redo-upnp-video.patch, 37.4 KB (added by beirdo, 10 years ago)
  • mythtv/programs/mythbackend/main_helpers.cpp

    From 971d6d40e356dc2750242fa4ee6b7764d4e824b3 Mon Sep 17 00:00:00 2001
    From: Gavin Hurlbut <gjhurlbu@gmail.com>
    Date: Sat, 21 Aug 2010 23:29:02 -0700
    Subject: [PATCH] Added patch from #8801 - redo upnp + video
    
    Modified to include subtitle where applicable
    
    diff --git a/mythtv/programs/mythbackend/main_helpers.cpp b/mythtv/programs/mythbackend/main_helpers.cpp
    index 190fbf2..d022bfe 100644
    a b void log_rotate_handler(int) 
    305305    log_rotate(0);
    306306}
    307307
    308 void upnp_rebuild(int)
    309 {
    310     if (gCoreContext->IsMasterHost())
    311     {
    312         g_pUPnp->RebuildMediaMap();
    313     }
    314 
    315 }
    316 
    317308void showUsage(const MythCommandLineParser &cmdlineparser, const QString &version)
    318309{
    319310    QString    help  = cmdlineparser.GetHelpString(false);
    int handle_command(const MythCommandLineParser &cmdline) 
    432423
    433424    if (cmdline.WantUPnPRebuild())
    434425    {
    435         VERBOSE(VB_GENERAL, "Rebuilding UPNP Media Map");
    436 
    437         UPnpMedia *rebuildit = new UPnpMedia(false,false);
    438         rebuildit->BuildMediaMap();
     426        VERBOSE(VB_GENERAL, "Rebuilding UPNP Media Map is no longer supported");
    439427
    440428        return BACKEND_EXIT_OK;
    441429    }
    int run_backend(const MythCommandLineParser &cmdline) 
    757745            pHS->RegisterExtension(httpStatus);
    758746    }
    759747
    760     if (ismaster)
    761     {
    762         // kill -USR1 mythbackendpid will force a upnpmedia rebuild
    763         signal(SIGUSR1, &upnp_rebuild);
    764     }
    765 
    766748    VERBOSE(VB_IMPORTANT, QString("Enabled verbose msgs: %1")
    767749            .arg(verboseString));
    768750
  • mythtv/programs/mythbackend/mediaserver.cpp

    diff --git a/mythtv/programs/mythbackend/mediaserver.cpp b/mythtv/programs/mythbackend/mediaserver.cpp
    index b7a6fd4..5d8e4c7 100644
    a b  
    1515#include "upnpcdstv.h"
    1616#include "upnpcdsmusic.h"
    1717#include "upnpcdsvideo.h"
    18 #include "upnpmedia.h"
    1918
    2019//////////////////////////////////////////////////////////////////////////////
    2120//////////////////////////////////////////////////////////////////////////////
    MediaServer::MediaServer( bool bIsMaster, bool bDisableUPnp /* = FALSE */ ) 
    177176            VERBOSE(VB_UPNP, "MediaServer::Registering UPnpCDSVideo Extension");
    178177
    179178            RegisterExtension(new UPnpCDSVideo());
    180 
    181             upnpMedia = new UPnpMedia(true,true);
    182             //upnpMedia->BuildMediaMap();
    183179        }
    184180
    185181        // VERBOSE(VB_UPNP, QString( "MediaServer::Adding Context Listener" ));
  • mythtv/programs/mythbackend/mediaserver.h

    diff --git a/mythtv/programs/mythbackend/mediaserver.h b/mythtv/programs/mythbackend/mediaserver.h
    index 12fbda5..de48b25 100644
    a b  
    1717#include "upnpcds.h"
    1818#include "upnpcmgr.h"
    1919#include "upnpmsrr.h"
    20 #include "upnpmedia.h"
    2120
    2221//////////////////////////////////////////////////////////////////////////////
    2322//////////////////////////////////////////////////////////////////////////////
    class MediaServer : public UPnp 
    3433
    3534        UPnpCDS         *m_pUPnpCDS;     // Do not delete (auto deleted)
    3635        UPnpCMGR        *m_pUPnpCMGR;    // Do not delete (auto deleted)
    37         UPnpMedia       *upnpMedia;
    3836
    3937        QString          m_sSharePath;
    4038
    class MediaServer : public UPnp 
    4341
    4442        virtual ~MediaServer();
    4543
    46         void RebuildMediaMap(void) { upnpMedia->BuildMediaMap(); };
    47 
    4844        void     RegisterExtension  ( UPnpCDSExtension    *pExtension );
    4945        void     UnregisterExtension( UPnpCDSExtension    *pExtension );
    5046
  • mythtv/programs/mythbackend/mythbackend.pro

    diff --git a/mythtv/programs/mythbackend/mythbackend.pro b/mythtv/programs/mythbackend/mythbackend.pro
    index 6bc4cac..226fa91 100644
    a b QMAKE_CLEAN += $(TARGET) 
    2121HEADERS += autoexpire.h encoderlink.h filetransfer.h httpstatus.h mainserver.h
    2222HEADERS += playbacksock.h scheduler.h server.h housekeeper.h backendutil.h
    2323HEADERS += upnpcdstv.h upnpcdsmusic.h upnpcdsvideo.h mediaserver.h
    24 HEADERS += mythxml.h upnpmedia.h main_helpers.h backendcontext.h
     24HEADERS += mythxml.h main_helpers.h backendcontext.h
    2525
    2626SOURCES += autoexpire.cpp encoderlink.cpp filetransfer.cpp httpstatus.cpp
    2727SOURCES += main.cpp mainserver.cpp playbacksock.cpp scheduler.cpp server.cpp
    2828SOURCES += housekeeper.cpp backendutil.cpp
    2929SOURCES += upnpcdstv.cpp upnpcdsmusic.cpp upnpcdsvideo.cpp mediaserver.cpp
    30 SOURCES += mythxml.cpp upnpmedia.cpp main_helpers.cpp backendcontext.cpp
     30SOURCES += mythxml.cpp main_helpers.cpp backendcontext.cpp
    3131
    3232using_oss:DEFINES += USING_OSS
    3333
  • mythtv/programs/mythbackend/mythxml.cpp

    diff --git a/mythtv/programs/mythbackend/mythxml.cpp b/mythtv/programs/mythbackend/mythxml.cpp
    index 5e1bde2..43fee8c 100644
    a b void MythXML::GetVideoArt( HTTPRequest *pRequest ) 
    862862
    863863    MSqlQuery query(MSqlQuery::InitCon());
    864864
    865     query.prepare("SELECT coverart FROM upnpmedia WHERE intid = :ITEMID");
     865    query.prepare("SELECT coverfile FROM videometadata WHERE intid = :ITEMID");
    866866    query.bindValue(":ITEMID", sId);
    867867
    868868    if (!query.exec())
    void MythXML::GetVideoArt( HTTPRequest *pRequest ) 
    885885        return;
    886886    }
    887887
     888    // ----------------------------------------------------------------------
     889    // Not there? Perhaps we need to look in a storage group?
     890    // ----------------------------------------------------------------------
     891    StorageGroup sgroup("Coverart");
     892    sFileName = sgroup.FindRecordingFile( sFileName );
     893
     894    if (sFileName != "")
     895    {
     896        VERBOSE(VB_IMPORTANT, QString("Found coverart '%1'").arg(sFileName));
     897
     898        pRequest->m_eResponseType   = ResponseTypeFile;
     899        pRequest->m_nResponseStatus = 200;
     900        pRequest->m_sFileName = sFileName;
     901        return;
     902    }
     903
     904    VERBOSE(VB_IMPORTANT, QString("Not found '%1'").arg(sFileName));
     905
    888906}
    889907
    890908void MythXML::GetAlbumArt( HTTPRequest *pRequest )
    void MythXML::GetVideo( HttpWorkerThread *pThread, 
    17181736
    17191737    if (pData == NULL)
    17201738    {
    1721         QString sBasePath = "";
    1722 
    17231739        // ------------------------------------------------------------------
    17241740        // Load Track's FileName
    17251741        // ------------------------------------------------------------------
    void MythXML::GetVideo( HttpWorkerThread *pThread, 
    17281744
    17291745        if (query.isConnected())
    17301746        {
    1731             query.prepare("SELECT filepath FROM upnpmedia WHERE intid = :KEY" );
     1747            query.prepare("SELECT filename FROM videometadata WHERE intid = :KEY" );
    17321748            query.bindValue(":KEY", sId );
    17331749
    17341750            if (!query.exec())
    void MythXML::GetVideo( HttpWorkerThread *pThread, 
    17391755
    17401756            if (query.next())
    17411757            {
    1742                 pRequest->m_sFileName = QString( "%1/%2" ).arg( sBasePath )
    1743                                         .arg( query.value(0).toString() );
     1758                QString sFileName = query.value(0).toString();
     1759
     1760                if (!QFile::exists( sFileName ))
     1761                {
     1762                    StorageGroup sgroup("Videos");
     1763                    sFileName = sgroup.FindRecordingFile( sFileName );
     1764                }
     1765
     1766                pRequest->m_sFileName = sFileName;
    17441767            }
    17451768        }
    17461769
  • mythtv/programs/mythbackend/upnpcdsvideo.cpp

    diff --git a/mythtv/programs/mythbackend/upnpcdsvideo.cpp b/mythtv/programs/mythbackend/upnpcdsvideo.cpp
    index d204e21..52b7c10 100644
    a b  
    11// Program Name: upnpcdsvideo.cpp
    2 //
    3 // Purpose - uPnp Content Directory Extension for MythVideo Videos
    4 //
     2//                                                                           
     3// Purpose - UPnP Content Directory Extension for MythVideo Videos
     4//                                                                           
    55//////////////////////////////////////////////////////////////////////////////
    66
    77// POSIX headers
     
    1313// MythTV headers
    1414#include "upnpcdsvideo.h"
    1515#include "httprequest.h"
    16 #include "upnpmedia.h"
    1716#include "util.h"
    1817#include "mythcorecontext.h"
     18#include "storagegroup.h"
    1919
    2020#define LOC QString("UPnpCDSVideo: ")
    2121#define LOC_WARN QString("UPnpCDSVideo, Warning: ")
    2222#define LOC_ERR QString("UPnpCDSVideo, Error: ")
    2323
    24 UPnpCDSRootInfo UPnpCDSVideo::g_RootNodes[] =
     24UPnpCDSRootInfo UPnpCDSVideo::g_RootNodes[] = 
    2525{
    26     {   "VideoRoot",
     26    {   "All Videos",
    2727        "*",
    2828        "SELECT 0 as key, "
    2929          "title as name, "
    3030          "1 as children "
    31             "FROM upnpmedia "
     31            "FROM videometadata "
    3232            "%1 "
    3333            "ORDER BY title",
    3434        "" }
    int UPnpCDSVideo::g_nRootCount = 1; 
    4747UPnpCDSRootInfo *UPnpCDSVideo::GetRootInfo( int nIdx )
    4848{
    4949    if ((nIdx >=0 ) && ( nIdx < g_nRootCount ))
    50         return &(g_RootNodes[ nIdx ]);
     50        return &(g_RootNodes[ nIdx ]); 
    5151
    5252    return NULL;
    5353}
    int UPnpCDSVideo::GetRootCount() 
    6767
    6868QString UPnpCDSVideo::GetTableName( QString sColumn )
    6969{
    70     return "upnpmedia";
     70    return "videometadata";
    7171}
    7272
    7373/////////////////////////////////////////////////////////////////////////////
    QString UPnpCDSVideo::GetTableName( QString sColumn ) 
    7676
    7777QString UPnpCDSVideo::GetItemListSQL( QString sColumn )
    7878{
    79     return "SELECT intid, title, filepath, " \
    80            "itemtype, itemproperties, parentid, "\
    81            "coverart FROM upnpmedia WHERE class = 'VIDEO'";
     79    return "SELECT intid, title, subtitle, filename, director, plot, "
     80            "rating, year, userrating, length, "
     81            "season, episode, coverfile, insertdate, host FROM videometadata";
     82
    8283}
    8384
    8485/////////////////////////////////////////////////////////////////////////////
    void UPnpCDSVideo::BuildItemQuery( MSqlQuery &query, const QStringMap &mapParams 
    8990{
    9091    int nVideoID = mapParams[ "Id" ].toInt();
    9192
    92     QString sSQL = QString( "%1 AND intid=:VIDEOID ORDER BY title DESC" )
    93                                                     .arg( GetItemListSQL( ) );
     93    QString sSQL = QString( "WHERE %1 AND intid=:VIDEOID ORDER BY title DESC" )
     94                    .arg( GetItemListSQL( ) );
    9495
    9596    query.prepare( sSQL );
    9697
    97     query.bindValue( ":VIDEOID", (int)nVideoID    );
     98    query.bindValue( ":VIDEOID", (int)nVideoID );
    9899}
    99100
    100101/////////////////////////////////////////////////////////////////////////////
    int UPnpCDSVideo::GetDistinctCount( UPnpCDSRootInfo *pInfo ) 
    213214
    214215    MSqlQuery query(MSqlQuery::InitCon());
    215216
    216     query.prepare("SELECT COUNT(*) FROM upnpmedia WHERE class = 'VIDEO' "
    217                     "AND parentid = :ROOTID");
    218 
    219     query.bindValue(":ROOTID", STARTING_VIDEO_OBJECTID);
     217    query.prepare("SELECT COUNT(*) FROM videometadata");
    220218
    221219    if (query.exec() && query.next())
    222220    {
    int UPnpCDSVideo::GetDistinctCount( UPnpCDSRootInfo *pInfo ) 
    226224    return nCount;
    227225}
    228226
     227
    229228/////////////////////////////////////////////////////////////////////////////
    230229//
    231230/////////////////////////////////////////////////////////////////////////////
    232231
    233 UPnpCDSExtensionResults *UPnpCDSVideo::ProcessItem( UPnpCDSRequest          *pRequest,
    234                                                     UPnpCDSExtensionResults *pResults,
    235                                                     QStringList             &idPath )
     232void UPnpCDSVideo::AddItem( const UPnpCDSRequest    *pRequest,
     233                            const QString           &sObjectId,
     234                            UPnpCDSExtensionResults *pResults,
     235                            bool                     bAddRef,
     236                            MSqlQuery               &query )
    236237{
    237     pResults->m_nTotalMatches   = 0;
    238     pResults->m_nUpdateID       = 1;
    239238
    240     if (pRequest->m_sObjectId.length() == 0)
    241         return pResults;
    242 
    243     QStringList tokens = pRequest->m_sObjectId
    244         .split('/', QString::SkipEmptyParts);
    245     QString     sId    = tokens.last();
     239    int            nVidID       = query.value( 0).toInt();
     240    QString        sTitle       = query.value( 1).toString();
     241    QString        sSubtitle    = query.value( 2).toString();
     242    QString        sFilePath    = query.value( 3).toString();
     243    QString        sDirector    = query.value( 4).toString();
     244    QString        sPlot        = query.value( 5).toString();
     245    QString        sRating      = query.value( 6).toString();
     246    // int             nYear        = query.value( 7).toInt();
     247    // int             nUserRating  = query.value( 8).toInt();
     248    int            nLength      = query.value( 9).toInt();
     249    // int             nSeason      = query.value(10).toInt();
     250    // int             nEpisode     = query.value(11).toInt();
     251    QString        sCoverArt    = query.value(12).toString();
     252    QDateTime      dtInsertDate = query.value(13).toDateTime();
     253    QString        sHostName    = query.value(14).toString();
    246254
    247     if (sId.startsWith("Id"))
    248         sId = sId.right( sId.length() - 2);
     255    // ----------------------------------------------------------------------
     256    // Cache Host ip Address & Port
     257    // ----------------------------------------------------------------------
    249258
    250     switch( pRequest->m_eBrowseFlag )
     259    // If the host-name is empty then we assume it is our local host
     260    // otherwise, we look up the host's IP address and port.  When the
     261    // client then trys to play the video it will be directed to the
     262    // host which actually has the content.
     263    if (!m_mapBackendIp.contains( sHostName ))
    251264    {
    252         case CDS_BrowseMetadata:
     265        if (sHostName.isEmpty())
    253266        {
    254             // --------------------------------------------------------------
    255             // Return 1 Item
    256             // --------------------------------------------------------------
    257 
    258             QStringMap  mapParams;
    259 
    260             mapParams.insert( "Id", sId );
    261 
    262             MSqlQuery query(MSqlQuery::InitCon());
    263 
    264             if (query.isConnected())
    265             {
    266                 BuildItemQuery( query, mapParams );
    267 
    268                 if (query.exec() && query.next())
    269                 {
    270                         AddItem( pRequest, pRequest->m_sParentId, pResults, false, query );
    271                         pResults->m_nTotalMatches = 1;
    272                 }
    273             }
    274 
    275             break;
     267            m_mapBackendIp[sHostName] =
     268                gCoreContext->GetSetting( "BackendServerIP" );
    276269        }
    277 
    278         case CDS_BrowseDirectChildren:
     270        else
    279271        {
    280             pRequest->m_sParentId = sId;
    281 
    282             CreateItems( pRequest, pResults, 0, "", false );
    283 
    284             break;
     272            m_mapBackendIp[sHostName] =
     273                gCoreContext->GetSettingOnHost( "BackendServerIp", sHostName);
    285274        }
    286275    }
    287276
    288     return pResults;
    289 }
    290 
    291 /////////////////////////////////////////////////////////////////////////////
    292 //
    293 /////////////////////////////////////////////////////////////////////////////
    294 
    295 void UPnpCDSVideo::CreateItems( UPnpCDSRequest          *pRequest,
    296                                 UPnpCDSExtensionResults *pResults,
    297                                 int                      nNodeIdx,
    298                                 const QString           &sKey,
    299                                 bool                     bAddRef )
    300 {
    301     pResults->m_nTotalMatches = 0;
    302     pResults->m_nUpdateID     = 1;
    303 
    304     UPnpCDSRootInfo *pInfo = GetRootInfo( nNodeIdx );
    305 
    306     if (pInfo == NULL)
    307         return;
    308 
    309     if (pRequest->m_nRequestedCount == 0)
    310         pRequest->m_nRequestedCount = SHRT_MAX;
    311 
    312     MSqlQuery query(MSqlQuery::InitCon());
    313 
    314     if (query.isConnected())
     277    if (!m_mapBackendPort.contains( sHostName ))
    315278    {
    316         QString ParentClause;
    317         QString sWhere;
    318 
    319         if ( sKey.length() > 0)
     279        if (sHostName.isEmpty())
    320280        {
    321            sWhere = QString( "WHERE %1=:KEY " )
    322                        .arg( pInfo->column );
    323         }
    324 
    325         if (pRequest->m_sObjectId.startsWith("Videos"))
    326         {
    327             if (!pRequest->m_sParentId.isEmpty())
    328             {
    329                 if (pRequest->m_sParentId == "Videos/0")
    330                 {
    331                     pRequest->m_sParentId = QString("%1")
    332                                 .arg(STARTING_VIDEO_OBJECTID);
    333                 }
    334             }
    335             else
    336             {
    337                 QStringList tokens =
    338                     pRequest->m_sObjectId.split('=', QString::SkipEmptyParts);
    339                 pRequest->m_sParentId = tokens.last();
    340             }
    341 
    342             if (pRequest->m_sSearchClass.isEmpty())
    343                 ParentClause = " AND parentid = \"" + pRequest->m_sParentId + "\"";
    344             else
    345                 pRequest->m_sParentId = '8';
    346 
    347             if (pRequest->m_sObjectId.startsWith("Videos/0"))
    348             {
    349                 pRequest->m_sObjectId = "Videos/0";
    350             }
    351 
    352             /*
    353             VERBOSE(VB_UPNP, QString("pRequest->m_sParentId=:%1: , "
    354                                      "pRequest->m_sObjectId=:%2:, sKey=:%3:")
    355                                                  .arg(pRequest->m_sParentId)
    356                                                  .arg(pRequest->m_sObjectId)
    357                                                  .arg(sKey));
    358              */
    359 
    360             if ((!pRequest->m_sParentId.isEmpty()) && (pRequest->m_sParentId != "8"))
    361                 pResults->m_nTotalMatches = GetCount( "parentid", pRequest->m_sParentId );
     281            m_mapBackendPort[sHostName] =
     282                gCoreContext->GetSetting( "BackendStatusPort" );
    362283        }
    363284        else
    364             VERBOSE( VB_UPNP, QString( "UPnpCDSVideo::CreateItems: ******* ParentID Does NOT Start with 'Videos' ParentId = {0}" )
    365                                   .arg( pRequest->m_sParentId ));
    366 
    367         QString sSQL = QString( "%1 %2 LIMIT %3, %4" )
    368                           .arg( GetItemListSQL( pInfo->column )  )
    369                           .arg( sWhere + ParentClause )
    370                           .arg( pRequest->m_nStartingIndex  )
    371                           .arg( pRequest->m_nRequestedCount );
    372 
    373         query.prepare  ( sSQL );
    374         //VERBOSE(VB_UPNP, QString("sSQL = %1").arg(sSQL));
    375         if ( sKey.length() )
    376             query.bindValue(":KEY", sKey );
    377 
    378         if (query.exec())
    379285        {
    380             while(query.next())
    381                 AddItem( pRequest, pRequest->m_sObjectId, pResults, bAddRef, query );
    382 
     286            m_mapBackendPort[sHostName] =
     287                gCoreContext->GetSettingOnHost("BackendStatusPort", sHostName);
    383288        }
    384289    }
    385 }
    386 
    387 /////////////////////////////////////////////////////////////////////////////
    388 //
    389 /////////////////////////////////////////////////////////////////////////////
    390 
    391 void UPnpCDSVideo::AddItem( const UPnpCDSRequest    *pRequest,
    392                             const QString           &sObjectId,
    393                             UPnpCDSExtensionResults *pResults,
    394                             bool                     bAddRef,
    395                             MSqlQuery               &query )
    396 {
    397     int            nVidID       = query.value( 0).toInt();
    398     QString        sTitle       = query.value( 1).toString();
    399     QString        sFileName    = query.value( 2).toString();
    400     QString        sItemType    = query.value( 3).toString();
    401     QString        sParentID    = query.value( 5).toString();
    402     QString        sCoverArt    = query.value( 6).toString();
    403 
    404     // VERBOSE(VB_UPNP,QString("ID = %1, Title = %2, fname = %3 sObjectId = %4").arg(nVidID).arg(sTitle).arg(sFileName).arg(sObjectId));
    405 
    406     // ----------------------------------------------------------------------
    407     // Cache Host ip Address & Port
    408     // ----------------------------------------------------------------------
    409     QString sServerIp = gCoreContext->GetSetting("BackendServerIp"   );
    410     QString sPort     = gCoreContext->GetSetting("BackendStatusPort" );
    411 
     290   
     291   
    412292    // ----------------------------------------------------------------------
    413293    // Build Support Strings
    414294    // ----------------------------------------------------------------------
    415295
    416296    QString sName      = sTitle;
     297    if( not sSubtitle.isEmpty() )
     298    {
     299        sName += " - " + sSubtitle;
     300    }
    417301
    418302    QString sURIBase   = QString( "http://%1:%2/Myth/" )
    419                             .arg( sServerIp )
    420                             .arg( sPort    );
     303                            .arg( m_mapBackendIp  [sHostName] )
     304                            .arg( m_mapBackendPort[sHostName] );
    421305
    422306    QString sURIParams = QString( "/Id%1" ).arg( nVidID );
    423307    QString sId        = QString( "Videos/0/item%1").arg( sURIParams );
    424308
    425     if (sParentID == QString("%1").arg(STARTING_VIDEO_OBJECTID))
    426     {
    427         sParentID = "Videos/0";
    428     }
    429     else
    430     {
    431         sParentID = QString( "Videos/0/item/Id%1")
    432                        .arg( sParentID );
    433     }
     309    QString sParentID = "Videos/0";
    434310
    435311    QString sAlbumArtURI= QString( "%1GetVideoArt%2")
    436312                        .arg( sURIBase   )
    437313                        .arg( sURIParams );
    438314
    439     CDSObject *pItem = NULL;
    440 
    441     if (sItemType == "FOLDER")
    442     {
    443         pItem   = CDSObject::CreateStorageFolder( sId, sName, sParentID);
    444         pItem->SetChildCount( GetCount( "parentid",QString( "%1" ).arg( nVidID )) );
    445 
    446         pItem->SetPropValue( "storageUsed", "0" );  //-=>TODO: need proper value
    447     }
    448     else if (sItemType == "FILE" )
    449         pItem   = CDSObject::CreateVideoItem( sId, sName, sParentID );
    450 
    451     if (!pItem)
    452     {
    453         VERBOSE(VB_IMPORTANT, LOC_ERR + "AddItem(): " +
    454         QString("sItemType has unknown type '%1'").arg(sItemType));
    455 
    456         return;
    457     }
     315    CDSObject *pItem = CDSObject::CreateVideoItem( sId, sName, sParentID );
    458316
    459317    pItem->m_bRestricted  = false;
    460318    pItem->m_bSearchable  = true;
    461319    pItem->m_sWriteStatus = "WRITABLE";
    462320
     321    pItem->SetPropValue( "longDescription", sPlot );
     322    // ?? pItem->SetPropValue( "description"    , sTitle );
     323    pItem->SetPropValue( "director"       , sDirector );
     324
    463325    pItem->SetPropValue( "genre"          , "[Unknown Genre]"     );
    464326    pItem->SetPropValue( "actor"          , "[Unknown Author]"    );
    465     pItem->SetPropValue( "creator"        , "[Unknown Author]"    );
    466     pItem->SetPropValue( "album"          , "[Unknown Series]"    );
    467 
    468     if ((!sCoverArt.isEmpty()) && (sCoverArt != "No Cover"))
     327    pItem->SetPropValue( "creator"        , "[Unknown Creator]"   );
     328    pItem->SetPropValue( "album"          , "[Unknown Album]"     );
     329
     330    //pItem->SetPropValue( "producer"       , );
     331    //pItem->SetPropValue( "rating"         , );
     332    //pItem->SetPropValue( "actor"          , );
     333    //pItem->SetPropValue( "publisher"      , );
     334    //pItem->SetPropValue( "language"       , );
     335    //pItem->SetPropValue( "relation"       , );
     336    //pItem->SetPropValue( "region"         , );
     337
     338    if ((sCoverArt != "") && (sCoverArt != "No Cover"))
    469339        pItem->SetPropValue( "albumArtURI"    , sAlbumArtURI);
    470340
    471341    if ( bAddRef )
    void UPnpCDSVideo::AddItem( const UPnpCDSRequest *pRequest, 
    476346        pItem->SetPropValue( "refID", sRefId );
    477347    }
    478348
    479     QFileInfo fInfo( sFileName );
    480     QDateTime fDate = fInfo.lastModified();
     349    QString sFullFileName = sFilePath;
     350    if (!QFile::exists( sFullFileName ))
     351    {
     352        StorageGroup sgroup("Videos");
     353        sFullFileName = sgroup.FindRecordingFile( sFullFileName );
     354    }
     355    QFileInfo fInfo( sFullFileName );
    481356
    482     pItem->SetPropValue( "date", fDate.toString( "yyyy-MM-dd"));
     357    pItem->SetPropValue( "date", dtInsertDate.toString( "yyyy-MM-dd"));
    483358    pResults->Add( pItem );
    484359
    485360    // ----------------------------------------------------------------------
    void UPnpCDSVideo::AddItem( const UPnpCDSRequest *pRequest, 
    496371    Resource *pRes = pItem->AddResource( sProtocol, sURI );
    497372
    498373    pRes->AddAttribute( "size"      , QString("%1").arg(fInfo.size()) );
    499     pRes->AddAttribute( "duration"  , "0:01:00.000"      );
    500374
    501 }
     375    QString sDur;
     376    sDur.sprintf("%02d:%02d:00", (nLength / 60), nLength % 60 );
    502377
    503 // vim:ts=4:sw=4:ai:et:si:sts=4
     378    pRes->AddAttribute( "duration"  , sDur      );
     379}
  • mythtv/programs/mythbackend/upnpcdsvideo.h

    diff --git a/mythtv/programs/mythbackend/upnpcdsvideo.h b/mythtv/programs/mythbackend/upnpcdsvideo.h
    index 074e344..56e98d5 100644
    a b  
    11//////////////////////////////////////////////////////////////////////////////
    2 // Program Name: upnpcdstv.h
    3 //
    4 // Purpose - uPnp Content Directory Extension for Video
    5 //
     2// Program Name: upnpcdsvideo.h
     3//                                                                           
     4// Purpose - UPnP Content Directory Extention for Videos
     5//                                                                           
    66// Created By  : David Blain                    Created On : Jan. 24, 2005
    7 // Modified By :                                Modified On:
    8 //
     7// Modified By :                                Modified On:                 
     8//                                                                           
    99//////////////////////////////////////////////////////////////////////////////
    1010
    1111#ifndef UPnpCDSVIDEO_H_
    1212#define UPnpCDSVIDEO_H_
    1313
     14#include "mainserver.h"
    1415#include "upnpcds.h"
    15 
     16             
    1617typedef QMap<int, QString> IntMap;
    1718
    1819//////////////////////////////////////////////////////////////////////////////
    class UPnpCDSVideo : public UPnpCDSExtension 
    3132
    3233    protected:
    3334
    34         virtual UPnpCDSExtensionResults *ProcessItem( UPnpCDSRequest          *pRequest,
    35                                                       UPnpCDSExtensionResults *pResults,
    36                                                       QStringList             &idPath );
    37 
    38         virtual void             CreateItems   ( UPnpCDSRequest          *pRequest,
    39                                                  UPnpCDSExtensionResults *pResults,
    40                                                  int                      nNodeIdx,
    41                                                  const QString           &sKey,
    42                                                  bool                     bAddRef );
    43 
    4435        virtual bool             IsBrowseRequestForUs( UPnpCDSRequest *pRequest );
    4536        virtual bool             IsSearchRequestForUs( UPnpCDSRequest *pRequest );
    4637
    class UPnpCDSVideo : public UPnpCDSExtension 
    5142        virtual QString          GetTableName  ( QString sColumn );
    5243        virtual QString          GetItemListSQL( QString sColumn = "");
    5344
    54         virtual void             BuildItemQuery( MSqlQuery        &query,
     45        virtual void             BuildItemQuery( MSqlQuery        &query, 
    5546                                                 const QStringMap &mapParams );
    5647
    57                                                  
    5848        virtual void             AddItem( const UPnpCDSRequest    *pRequest,
    5949                                          const QString           &sObjectId,
    6050                                          UPnpCDSExtensionResults *pResults,
    61                                           bool                     bAddRef,
     51                                          bool                     bAddRef, 
    6252                                          MSqlQuery               &query );
    6353
    6454    public:
  • deleted file mythtv/programs/mythbackend/upnpmedia.cpp

    diff --git a/mythtv/programs/mythbackend/upnpmedia.cpp b/mythtv/programs/mythbackend/upnpmedia.cpp
    deleted file mode 100644
    index 732ec62..0000000
    + -  
    1 #include <limits.h>
    2 #include <unistd.h>
    3 
    4 #include <cstdlib>
    5 
    6 #include <QFileInfo>
    7 #include <QDir>
    8 
    9 #include "mythcorecontext.h"
    10 #include "httprequest.h"
    11 #include "upnpmedia.h"
    12 #include "mythdb.h"
    13 #include "util.h"
    14 #include "pthread.h"
    15 
    16 #define LOC QString("UPnpMedia: ")
    17 
    18 /////////////////////////////////////////////////////////////////////////////
    19 //
    20 /////////////////////////////////////////////////////////////////////////////
    21 
    22 UPnpMedia::UPnpMedia(bool runthread, bool ismaster)
    23 {
    24 
    25     if (gCoreContext->GetNumSetting("UPnP/RebuildDelay",30) > 0)
    26     {
    27         VERBOSE(VB_GENERAL,"Enabling Upnpmedia rebuild thread.");
    28         if ((runthread) && (ismaster))
    29         {
    30             pthread_t upnpmediathread;
    31             pthread_create(&upnpmediathread, NULL, doUPnpMediaThread, this);
    32         }
    33     }
    34     else
    35     {
    36         VERBOSE(VB_GENERAL,"Upnpmedia rebuild disabled.");
    37     }
    38 
    39 }
    40 
    41 void UPnpMedia::RunRebuildLoop(void)
    42 {
    43 
    44     // Sleep a few seconds to wait for other stuff to settle down.
    45     sleep(10);
    46 
    47     int irebuildDelay = 1800;
    48 
    49     irebuildDelay = gCoreContext->GetNumSetting("UPnP/RebuildDelay",30) * 60;
    50 
    51     if (irebuildDelay < 60)
    52         irebuildDelay = 60;
    53 
    54     while (1)
    55     {
    56         //VERBOSE(VB_UPNP, "UPnpMedia::RunRebuildLoop Calling BuildMediaMap");
    57         BuildMediaMap();
    58 
    59         sleep(irebuildDelay + (random()%8));
    60     }
    61 }
    62 
    63 void *UPnpMedia::doUPnpMediaThread(void *param)
    64 {
    65     UPnpMedia *upnpmedia = static_cast<UPnpMedia*>(param);
    66     upnpmedia->RunRebuildLoop();
    67 
    68     return NULL;
    69 }
    70 
    71 QString UPnpMedia::GetTitleName(QString fPath, QString fName)
    72 {
    73     if (!m_mapTitleNames[fPath].isNull())
    74     {
    75         return m_mapTitleNames[fPath];
    76     }
    77     else
    78         return fName;
    79 }
    80 
    81 QString UPnpMedia::GetCoverArt(QString fPath)
    82 {
    83     if (!m_mapCoverArt[fPath].isNull())
    84     {
    85         return m_mapCoverArt[fPath];
    86     }
    87     else
    88         return "";
    89 }
    90 
    91 /////////////////////////////////////////////////////////////////////////////
    92 //
    93 /////////////////////////////////////////////////////////////////////////////
    94 
    95 // this should dynamically generate the SQL query and such
    96 void UPnpMedia::FillMetaMaps(void)
    97 {
    98     MSqlQuery query(MSqlQuery::InitCon());
    99 
    100     QString sSQL = "SELECT filename, title, coverfile FROM videometadata";
    101 
    102     query.prepare  ( sSQL );
    103 
    104     if (query.exec() && query.size() > 0)
    105     {
    106         while(query.next())
    107         {
    108             m_mapTitleNames[query.value(0).toString()] = query.value(1)
    109                                                                 .toString();
    110             m_mapCoverArt[query.value(0).toString()] = query.value(2)
    111                                                                 .toString();
    112         }
    113     }
    114 
    115 }
    116 
    117 
    118 int UPnpMedia::buildFileList(QString directory, int rootID, int itemID, MSqlQuery &query)
    119 {
    120 
    121     int parentid;
    122     QDir vidDir(directory);
    123     //VERBOSE(VB_UPNP, QString("buildFileList = %1, rootID = %2, itemID =
    124     //%3").arg(directory).arg(rootID).arg(itemID));
    125 
    126     if (rootID > 0)
    127         parentid = rootID;
    128     else
    129         parentid = itemID;
    130 
    131     vidDir.setSorting( QDir::DirsFirst | QDir::Name );
    132     QFileInfoList List = vidDir.entryInfoList();
    133     // If we can't read it's contents move on
    134     if (List.isEmpty())
    135         return itemID;
    136 
    137     for (QFileInfoList::iterator it = List.begin(); it != List.end(); ++it)
    138     {
    139         QFileInfo Info(*it);
    140         QString fName = Info.fileName();
    141         QString fPath = Info.filePath();
    142 
    143         if (fName == "." ||
    144             fName == "..")
    145         {
    146             continue;
    147         }
    148 
    149         if (Info.isDir())
    150         {
    151             itemID++;
    152 
    153             query.prepare("INSERT INTO upnpmedia "
    154                         "(intid, class, itemtype, parentid, itemproperties, "
    155             "filepath, filename, title, coverart) "
    156             "VALUES (:ITEMID, :ITEMCLASS, 'FOLDER', :PARENTID, '', "
    157             ":FILEPATH, :FILENAME, :TITLE, :COVERART)");
    158 
    159             query.bindValue(":ITEMCLASS", sMediaType);
    160             query.bindValue(":ITEMID", itemID);
    161             query.bindValue(":PARENTID", parentid);
    162             query.bindValue(":FILEPATH", fPath);
    163             query.bindValue(":FILENAME", fName);
    164 
    165             query.bindValue(":TITLE", GetTitleName(fPath,fName));
    166             query.bindValue(":COVERART", GetCoverArt(fPath));
    167 
    168             if (!query.exec())
    169                 MythDB::DBError("UPnpMedia::buildFileList", query);
    170 
    171             itemID = buildFileList(Info.filePath(), 0, itemID, query);
    172             continue;
    173 
    174         }
    175         else
    176         {
    177 /*
    178             if (handler->validextensions.count() > 0)
    179             {
    180                 QRegExp r;
    181 
    182                 r.setPattern("^" + Info.suffix() + "$");
    183                 r.setCaseSensitive(false);
    184                 QStringList result = handler->validextensions.grep(r);
    185                 if (result.isEmpty()) {
    186                     continue;
    187                 }
    188             }
    189 */
    190 
    191             itemID++;
    192 
    193 //            VERBOSE(VB_UPNP, QString("UPnpMedia Video File : (%1) (%2)")
    194 //                      .arg(itemID)
    195 //                                .arg(fName));
    196 
    197             query.prepare("INSERT INTO upnpmedia "
    198                         "(intid, class, itemtype, parentid, itemproperties, "
    199                         "filepath, filename, title, coverart) "
    200                         "VALUES (:ITEMID, :ITEMCLASS, 'FILE', :PARENTID, '', "
    201                         ":FILEPATH, :FILENAME, :TITLE, :COVERART)");
    202 
    203             query.bindValue(":ITEMCLASS", sMediaType);
    204             query.bindValue(":ITEMID", itemID);
    205             query.bindValue(":PARENTID", parentid);
    206             query.bindValue(":FILEPATH", fPath);
    207             query.bindValue(":FILENAME", fName);
    208 
    209             query.bindValue(":TITLE", GetTitleName(fPath,fName));
    210             query.bindValue(":COVERART", GetCoverArt(fPath));
    211 
    212             if (!query.exec())
    213                 MythDB::DBError("UPnpMedia::buildFileList", query);
    214 
    215         }
    216     }
    217 
    218     return itemID;
    219 }
    220 
    221 void UPnpMedia::BuildMediaMap(void)
    222 {
    223     MSqlQuery query(MSqlQuery::InitCon());
    224 
    225     // For now this class only does the video stuff, but eventually other media too
    226     sMediaType = "VIDEO";
    227 
    228     if (sMediaType == "VIDEO")
    229     {
    230         QString RootVidDir = gCoreContext->GetSetting("VideoStartupDir");
    231 
    232         if (!RootVidDir.isEmpty())
    233         {
    234 
    235             FillMetaMaps();
    236 
    237             query.prepare("DELETE FROM upnpmedia WHERE class = :ITEMCLASS");
    238             query.bindValue(":ITEMCLASS", sMediaType);
    239             if (!query.exec())
    240             {
    241                 MythDB::DBError("BuildMediaMap -- clearing table upnpmedia", query);
    242                 VERBOSE(VB_IMPORTANT, LOC + "BuildMediaMap - aborting");
    243                 return;
    244             }
    245 
    246             if (!query.exec("LOCK TABLES upnpmedia WRITE"))
    247                 MythDB::DBError("BuildMediaMap -- lock tables", query);
    248 
    249             VERBOSE(VB_UPNP, LOC + QString("VideoStartupDir = %1")
    250                                             .arg(RootVidDir));
    251 
    252             QStringList parts = RootVidDir.split(':', QString::SkipEmptyParts);
    253 
    254             int nextID = STARTING_VIDEO_OBJECTID;
    255 
    256             for ( QStringList::Iterator it = parts.begin(); it != parts.end();
    257                                                                         ++it )
    258             {
    259                 int filecount = nextID;
    260 
    261                 VERBOSE(VB_GENERAL, LOC + QString("BuildMediaMap %1 scan "
    262                                                 "starting in :%2:")
    263                                                     .arg(sMediaType)
    264                                                     .arg(*it));
    265 
    266                 nextID = buildFileList(*it,STARTING_VIDEO_OBJECTID, nextID,
    267                                                                         query);
    268 
    269                 if (!gCoreContext->GetSetting("UPnP/RecordingsUnderVideos").isEmpty())
    270                 {
    271                     VERBOSE(VB_ALL, "uPnP Unspecified error line 275, "
    272                                     "upnpmedia.cpp");
    273                     //   nextID = buildRecordingList(*it,STARTING_VIDEO_OBJECTID,
    274                     //                                        nextID,query);
    275                 }
    276 
    277                 filecount = (filecount - nextID) * -1;
    278 
    279                 VERBOSE(VB_GENERAL, LOC + QString("BuildMediaMap Done. Found "
    280                                                 "%1 objects").arg(filecount));
    281 
    282             }
    283 
    284             if (!query.exec("UNLOCK TABLES"))
    285                 MythDB::DBError("BuildMediaMap -- unlock tables", query);
    286 
    287         }
    288         else
    289         {
    290             VERBOSE(VB_GENERAL, LOC + "BuildMediaMap - no VideoStartupDir set, "
    291                                 " skipping scan.");
    292         }
    293 
    294     }
    295     else
    296     {
    297         VERBOSE(VB_GENERAL, LOC + QString("BuildMediaMap UNKNOWN MediaType %1 "
    298                             ", skipping scan.").arg(sMediaType));
    299     }
    300 
    301 }
    302 
    303 
  • deleted file mythtv/programs/mythbackend/upnpmedia.h

    diff --git a/mythtv/programs/mythbackend/upnpmedia.h b/mythtv/programs/mythbackend/upnpmedia.h
    deleted file mode 100644
    index a4db394..0000000
    + -  
    1 #ifndef UPnpMEDIA_H_
    2 #define UPnpMEDIA_H_
    3 
    4 #include <QString>
    5 
    6 #include "upnputil.h" // for QStringMap
    7 
    8 #define STARTING_VIDEO_OBJECTID 100000
    9 
    10 //////////////////////////////////////////////////////////////////////////////
    11 //
    12 //////////////////////////////////////////////////////////////////////////////
    13 
    14 class MSqlQuery;
    15 class UPnpMedia
    16 {
    17   private:
    18     QStringMap           m_mapTitleNames;
    19     QStringMap           m_mapCoverArt;
    20     //QString              sMediaType;
    21 
    22     void FillMetaMaps(void);
    23     int GetBaseCount(void);
    24     QString GetTitleName(QString fPath, QString fName);
    25     QString GetCoverArt(QString fPath);
    26 
    27     int buildFileList(QString directory, int rootID, int itemID,
    28                       MSqlQuery &query);
    29 
    30     void RunRebuildLoop(void);
    31     static void *doUPnpMediaThread(void *param);
    32 
    33   public:
    34     UPnpMedia(bool runthread, bool master);
    35     ~UPnpMedia() {};
    36 
    37     void SetMediaType(QString mediatype) { sMediaType = mediatype; }
    38 
    39     void BuildMediaMap(void);
    40     QString sMediaType;
    41 };
    42 
    43 #endif