00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include <climits>
00012
00013 #include <QFileInfo>
00014
00015 #include "upnpcdsmusic.h"
00016 #include "httprequest.h"
00017 #include "mythcorecontext.h"
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 UPnpCDSRootInfo UPnpCDSMusic::g_RootNodes[] =
00047 {
00048 { "All Music",
00049 "*",
00050 "SELECT song_id as id, "
00051 "name, "
00052 "1 as children "
00053 "FROM music_songs song "
00054 "%1 "
00055 "ORDER BY name",
00056 "", "name" },
00057
00058 #if 0
00059
00060
00061
00062 { "Recently Added",
00063 "*",
00064 "SELECT song_id id, "
00065 "name, "
00066 "1 as children "
00067 "FROM music_songs song "
00068 "%1 "
00069 "ORDER BY name",
00070 "WHERE (DATEDIFF( CURDATE(), date_modified ) <= 30 ) ", "" },
00071 #endif
00072
00073 { "By Album",
00074 "song.album_id",
00075 "SELECT a.album_id as id, "
00076 "a.album_name as name, "
00077 "count( song.album_id ) as children "
00078 "FROM music_songs song join music_albums a on a.album_id = song.album_id "
00079 "%1 "
00080 "GROUP BY a.album_id "
00081 "ORDER BY a.album_name",
00082 "WHERE song.album_id=:KEY", "album.album_name" },
00083
00084 #if 0
00085 { "By Artist",
00086 "artist_id",
00087 "SELECT a.artist_id as id, "
00088 "a.artist_name as name, "
00089 "count( distinct song.artist_id ) as children "
00090 "FROM music_songs song join music_artists a on a.artist_id = song.artist_id "
00091 "%1 "
00092 "GROUP BY a.artist_id "
00093 "ORDER BY a.artist_name",
00094 "WHERE song.artist_id=:KEY", "" },
00095
00096 { "By Genre",
00097 "genre_id",
00098 "SELECT g.genre_id as id, "
00099 "genre as name, "
00100 "count( distinct song.genre_id ) as children "
00101 "FROM music_songs song join music_genres g on g.genre_id = song.genre_id "
00102 "%1 "
00103 "GROUP BY g.genre_id "
00104 "ORDER BY g.genre",
00105 "WHERE song.genre_id=:KEY", "" },
00106 #endif
00107
00108 };
00109
00110 int UPnpCDSMusic::g_nRootCount = sizeof( g_RootNodes ) / sizeof( UPnpCDSRootInfo );
00111
00113
00115
00116 UPnpCDSRootInfo *UPnpCDSMusic::GetRootInfo( int nIdx )
00117 {
00118 if ((nIdx >=0 ) && ( nIdx < g_nRootCount ))
00119 return &(g_RootNodes[ nIdx ]);
00120
00121 return NULL;
00122 }
00123
00125
00127
00128 int UPnpCDSMusic::GetRootCount()
00129 {
00130 return g_nRootCount;
00131 }
00132
00134
00136
00137 QString UPnpCDSMusic::GetTableName( QString sColumn )
00138 {
00139 return "music_songs song";
00140 }
00141
00143
00145
00146 QString UPnpCDSMusic::GetItemListSQL( QString )
00147 {
00148 return "SELECT song.song_id as intid, artist.artist_name as artist, " \
00149 "album.album_name as album, song.name as title, " \
00150 "genre.genre, song.year, song.track as tracknum, " \
00151 "song.description, song.filename, song.length " \
00152 "FROM music_songs song " \
00153 " join music_artists artist on artist.artist_id = song.artist_id " \
00154 " join music_albums album on album.album_id = song.album_id " \
00155 " join music_genres genre on genre.genre_id = song.genre_id ";
00156 }
00157
00159
00161
00162 void UPnpCDSMusic::BuildItemQuery( MSqlQuery &query, const QStringMap &mapParams )
00163 {
00164 int nId = mapParams[ "Id" ].toInt();
00165
00166 QString sSQL = QString( "%1 WHERE song.song_id=:ID " )
00167 .arg( GetItemListSQL() );
00168
00169 query.prepare( sSQL );
00170
00171 query.bindValue( ":ID", (int)nId );
00172 }
00173
00175
00177
00178 bool UPnpCDSMusic::IsBrowseRequestForUs( UPnpCDSRequest *pRequest )
00179 {
00180
00181
00182
00183
00184
00185
00186 if (pRequest->m_eClient == CDS_ClientXBox &&
00187 pRequest->m_sContainerID == "7")
00188 {
00189 pRequest->m_sObjectId = "Music";
00190
00191 LOG(VB_UPNP, LOG_INFO,
00192 "UPnpCDSMusic::IsBrowseRequestForUs - Yes, ContainerId == 7");
00193
00194 return true;
00195 }
00196
00197 if ((pRequest->m_sObjectId.isEmpty()) &&
00198 (!pRequest->m_sContainerID.isEmpty()))
00199 pRequest->m_sObjectId = pRequest->m_sContainerID;
00200
00201 LOG(VB_UPNP, LOG_INFO,
00202 "UPnpCDSMusic::IsBrowseRequestForUs - Not sure... Calling base class.");
00203
00204 return UPnpCDSExtension::IsBrowseRequestForUs( pRequest );
00205 }
00206
00208
00210
00211 bool UPnpCDSMusic::IsSearchRequestForUs( UPnpCDSRequest *pRequest )
00212 {
00213
00214
00215
00216
00217
00218
00219 if (pRequest->m_eClient == CDS_ClientXBox &&
00220 pRequest->m_sContainerID == "7")
00221 {
00222 pRequest->m_sObjectId = "Music/1";
00223 pRequest->m_sSearchCriteria = "object.container.album.musicAlbum";
00224 pRequest->m_sSearchList.append( pRequest->m_sSearchCriteria );
00225
00226 LOG(VB_UPNP, LOG_INFO, "UPnpCDSMusic::IsSearchRequestForUs... Yes.");
00227
00228 return true;
00229 }
00230
00231 if (pRequest->m_sContainerID == "4")
00232 {
00233 pRequest->m_sObjectId = "Music";
00234 pRequest->m_sSearchCriteria = "object.item.audioItem.musicTrack";
00235 pRequest->m_sSearchList.append( pRequest->m_sSearchCriteria );
00236
00237 LOG(VB_UPNP, LOG_INFO, "UPnpCDSMusic::IsSearchRequestForUs... Yes.");
00238
00239 return true;
00240 }
00241
00242 if ((pRequest->m_sObjectId.isEmpty()) &&
00243 (!pRequest->m_sContainerID.isEmpty()))
00244 pRequest->m_sObjectId = pRequest->m_sContainerID;
00245
00246 LOG(VB_UPNP, LOG_INFO,
00247 "UPnpCDSMusic::IsSearchRequestForUs.. Don't know, calling base class.");
00248
00249 return UPnpCDSExtension::IsSearchRequestForUs( pRequest );
00250 }
00251
00253
00255
00256 void UPnpCDSMusic::AddItem( const UPnpCDSRequest *pRequest,
00257 const QString &sObjectId,
00258 UPnpCDSExtensionResults *pResults,
00259 bool bAddRef,
00260 MSqlQuery &query )
00261 {
00262 QString sName;
00263
00264 int nId = query.value( 0).toInt();
00265 QString sArtist = query.value( 1).toString();
00266 QString sAlbum = query.value( 2).toString();
00267 QString sTitle = query.value( 3).toString();
00268 QString sGenre = query.value( 4).toString();
00269
00270 int nTrackNum = query.value( 6).toInt();
00271 QString sDescription = query.value( 7).toString();
00272 QString sFileName = query.value( 8).toString();
00273 uint nLength = query.value( 9).toInt();
00274
00275 #if 0
00276 if ((nNodeIdx == 0) || (nNodeIdx == 1))
00277 {
00278 sName = QString( "%1-%2:%3" )
00279 .arg( sArtist)
00280 .arg( sAlbum )
00281 .arg( sTitle );
00282 }
00283 else
00284 #endif
00285 sName = sTitle;
00286
00287
00288
00289
00290
00291
00292 #if 0
00293 if (!m_mapBackendIp.contains( sHostName ))
00294 m_mapBackendIp[ sHostName ] = gCoreContext->GetSettingOnHost( "BackendServerIp", sHostName);
00295
00296 if (!m_mapBackendPort.contains( sHostName ))
00297 m_mapBackendPort[ sHostName ] = gCoreContext->GetSettingOnHost("BackendStatusPort", sHostName);
00298 #endif
00299
00300 QString sServerIp = gCoreContext->GetSetting( "BackendServerIp" );
00301 QString sPort = gCoreContext->GetSetting( "BackendStatusPort" );
00302
00303
00304
00305
00306
00307 QString sURIBase = QString( "http://%1:%2/Content/" )
00308 .arg( sServerIp )
00309 .arg( sPort );
00310
00311 QString sURIParams = QString( "?Id=%1" )
00312 .arg( nId );
00313
00314
00315 QString sId = QString( "Music/1/item%1")
00316 .arg( sURIParams );
00317
00318 CDSObject *pItem = CDSObject::CreateMusicTrack( sId,
00319 sName,
00320 sObjectId );
00321 pItem->m_bRestricted = true;
00322 pItem->m_bSearchable = true;
00323 pItem->m_sWriteStatus = "NOT_WRITABLE";
00324
00325 if ( bAddRef )
00326 {
00327 QString sRefId = QString( "%1/0/item%2")
00328 .arg( m_sExtensionId )
00329 .arg( sURIParams );
00330
00331 pItem->SetPropValue( "refID", sRefId );
00332 }
00333
00334 pItem->SetPropValue( "genre" , sGenre );
00335 pItem->SetPropValue( "description" , sTitle );
00336 pItem->SetPropValue( "longDescription" , sDescription);
00337
00338 pItem->SetPropValue( "artist" , sArtist );
00339 pItem->SetPropValue( "album" , sAlbum );
00340 pItem->SetPropValue( "originalTrackNumber" , QString::number(nTrackNum));
00341
00342 #if 0
00343 pObject->AddProperty( new Property( "publisher" , "dc" ));
00344 pObject->AddProperty( new Property( "language" , "dc" ));
00345 pObject->AddProperty( new Property( "relation" , "dc" ));
00346 pObject->AddProperty( new Property( "rights" , "dc" ));
00347
00348
00349 pObject->AddProperty( new Property( "playlist" , "upnp" ));
00350 pObject->AddProperty( new Property( "storageMedium" , "upnp" ));
00351 pObject->AddProperty( new Property( "contributor" , "dc" ));
00352 pObject->AddProperty( new Property( "date" , "dc" ));
00353 #endif
00354
00355 pResults->Add( pItem );
00356
00357
00358
00359
00360
00361 QFileInfo fInfo( sFileName );
00362
00363 QString sMimeType = HTTPRequest::GetMimeType( fInfo.suffix() );
00364 QString sProtocol = QString( "http-get:*:%1:DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01500000000000000000000000000000" ).arg( sMimeType );
00365 QString sURI = QString( "%1GetMusic%2").arg( sURIBase )
00366 .arg( sURIParams );
00367
00368 Resource *pRes = pItem->AddResource( sProtocol, sURI );
00369
00370 nLength /= 1000;
00371
00372 QString sDur;
00373
00374 sDur.sprintf("%02d:%02d:%02d",
00375 (nLength / 3600) % 24,
00376 (nLength / 60) % 60,
00377 nLength % 60);
00378
00379 pRes->AddAttribute( "duration" , sDur );
00380 }
00381
00382