Skip to content
This repository
Browse code

Merge pull request #1840 from Montellese/jsonrpc_artist_mess

jsonrpc: add "genreid", "artistid", "albumartistid" and "displayartist" to songs and albums and fix "albumartist" for songs
  • Loading branch information...
commit f00ff50ec98445ac922a87662931751eccbd5651 2 parents 9fe57ce + a8c055c
Sascha Montellese authored November 26, 2012
182  xbmc/interfaces/json-rpc/AudioLibrary.cpp
@@ -157,6 +157,10 @@ JSONRPC_STATUS CAudioLibrary::GetAlbums(const CStdString &method, ITransportLaye
157 157
   if (!musicdatabase.GetAlbumsNav(musicUrl.ToString(), items, genreID, artistID, CDatabase::Filter(), sorting))
158 158
     return InternalError;
159 159
 
  160
+  JSONRPC_STATUS ret = GetAdditionalAlbumDetails(parameterObject, items, musicdatabase);
  161
+  if (ret != OK)
  162
+    return ret;
  163
+
160 164
   int size = items.Size();
161 165
   if (items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
162 166
     size = (int)items.GetProperty("total").asInteger();
@@ -181,9 +185,16 @@ JSONRPC_STATUS CAudioLibrary::GetAlbumDetails(const CStdString &method, ITranspo
181 185
   if (!musicdatabase.GetAlbumPath(albumID, path))
182 186
     return InternalError;
183 187
 
184  
-  CFileItemPtr m_albumItem;
185  
-  FillAlbumItem(album, path, m_albumItem);
186  
-  HandleFileItem("albumid", false, "albumdetails", m_albumItem, parameterObject, parameterObject["properties"], result, false);
  188
+  CFileItemPtr albumItem;
  189
+  FillAlbumItem(album, path, albumItem);
  190
+
  191
+  CFileItemList items;
  192
+  items.Add(albumItem);
  193
+  JSONRPC_STATUS ret = GetAdditionalAlbumDetails(parameterObject, items, musicdatabase);
  194
+  if (ret != OK)
  195
+    return ret;
  196
+  
  197
+  HandleFileItem("albumid", false, "albumdetails", items[0], parameterObject, parameterObject["properties"], result, false);
187 198
 
188 199
   return OK;
189 200
 }
@@ -228,6 +239,10 @@ JSONRPC_STATUS CAudioLibrary::GetSongs(const CStdString &method, ITransportLayer
228 239
   if (!musicdatabase.GetSongsNav(musicUrl.ToString(), items, genreID, artistID, albumID, sorting))
229 240
     return InternalError;
230 241
 
  242
+  JSONRPC_STATUS ret = GetAdditionalSongDetails(parameterObject, items, musicdatabase);
  243
+  if (ret != OK)
  244
+    return ret;
  245
+
231 246
   int size = items.Size();
232 247
   if (items.HasProperty("total") && items.GetProperty("total").asInteger() > size)
233 248
     size = (int)items.GetProperty("total").asInteger();
@@ -248,7 +263,13 @@ JSONRPC_STATUS CAudioLibrary::GetSongDetails(const CStdString &method, ITranspor
248 263
   if (!musicdatabase.GetSongById(idSong, song))
249 264
     return InvalidParams;
250 265
 
251  
-  HandleFileItem("songid", false, "songdetails", CFileItemPtr( new CFileItem(song) ), parameterObject, parameterObject["properties"], result, false);
  266
+  CFileItemList items;
  267
+  items.Add(CFileItemPtr(new CFileItem(song)));
  268
+  JSONRPC_STATUS ret = GetAdditionalSongDetails(parameterObject, items, musicdatabase);
  269
+  if (ret != OK)
  270
+    return ret;
  271
+
  272
+  HandleFileItem("songid", false, "songdetails", items[0], parameterObject, parameterObject["properties"], result, false);
252 273
   return OK;
253 274
 }
254 275
 
@@ -273,6 +294,10 @@ JSONRPC_STATUS CAudioLibrary::GetRecentlyAddedAlbums(const CStdString &method, I
273 294
     items.Add(item);
274 295
   }
275 296
 
  297
+  JSONRPC_STATUS ret = GetAdditionalAlbumDetails(parameterObject, items, musicdatabase);
  298
+  if (ret != OK)
  299
+    return ret;
  300
+
276 301
   HandleFileItemList("albumid", false, "albums", items, parameterObject, result);
277 302
   return OK;
278 303
 }
@@ -291,6 +316,10 @@ JSONRPC_STATUS CAudioLibrary::GetRecentlyAddedSongs(const CStdString &method, IT
291 316
   if (!musicdatabase.GetRecentlyAddedAlbumSongs("musicdb://", items, (unsigned int)amount))
292 317
     return InternalError;
293 318
 
  319
+  JSONRPC_STATUS ret = GetAdditionalSongDetails(parameterObject, items, musicdatabase);
  320
+  if (ret != OK)
  321
+    return ret;
  322
+
294 323
   HandleFileItemList("songid", true, "songs", items, parameterObject, result);
295 324
   return OK;
296 325
 }
@@ -316,6 +345,10 @@ JSONRPC_STATUS CAudioLibrary::GetRecentlyPlayedAlbums(const CStdString &method,
316 345
     items.Add(item);
317 346
   }
318 347
 
  348
+  JSONRPC_STATUS ret = GetAdditionalAlbumDetails(parameterObject, items, musicdatabase);
  349
+  if (ret != OK)
  350
+    return ret;
  351
+
319 352
   HandleFileItemList("albumid", false, "albums", items, parameterObject, result);
320 353
   return OK;
321 354
 }
@@ -330,6 +363,10 @@ JSONRPC_STATUS CAudioLibrary::GetRecentlyPlayedSongs(const CStdString &method, I
330 363
   if (!musicdatabase.GetRecentlyPlayedAlbumSongs("musicdb://", items))
331 364
     return InternalError;
332 365
 
  366
+  JSONRPC_STATUS ret = GetAdditionalSongDetails(parameterObject, items, musicdatabase);
  367
+  if (ret != OK)
  368
+    return ret;
  369
+
333 370
   HandleFileItemList("songid", true, "songs", items, parameterObject, result);
334 371
   return OK;
335 372
 }
@@ -520,7 +557,7 @@ JSONRPC_STATUS CAudioLibrary::Clean(const CStdString &method, ITransportLayer *t
520 557
   return ACK;
521 558
 }
522 559
 
523  
-bool CAudioLibrary::FillFileItem(const CStdString &strFilename, CFileItem &item)
  560
+bool CAudioLibrary::FillFileItem(const CStdString &strFilename, CFileItem &item, const CVariant &parameterObject /* = CVariant(CVariant::VariantTypeArray) */)
524 561
 {
525 562
   CMusicDatabase musicdatabase;
526 563
   if (strFilename.empty() || !musicdatabase.Open())
@@ -534,6 +571,11 @@ bool CAudioLibrary::FillFileItem(const CStdString &strFilename, CFileItem &item)
534 571
       return false;
535 572
 
536 573
     item.SetFromAlbum(album);
  574
+
  575
+    CFileItemList items;
  576
+    items.Add(CFileItemPtr(&item));
  577
+    if (GetAdditionalAlbumDetails(parameterObject, items, musicdatabase) != OK)
  578
+      return false;
537 579
   }
538 580
   else
539 581
   {
@@ -542,6 +584,11 @@ bool CAudioLibrary::FillFileItem(const CStdString &strFilename, CFileItem &item)
542 584
       return false;
543 585
 
544 586
     item.SetFromSong(song);
  587
+
  588
+    CFileItemList items;
  589
+    items.Add(CFileItemPtr(&item));
  590
+    if (GetAdditionalSongDetails(parameterObject, items, musicdatabase) != OK)
  591
+      return false;
545 592
   }
546 593
 
547 594
   return true;
@@ -560,7 +607,7 @@ bool CAudioLibrary::FillFileItemList(const CVariant &parameterObject, CFileItemL
560 607
 
561 608
   bool success = false;
562 609
   CFileItem fileItem;
563  
-  if (FillFileItem(file, fileItem))
  610
+  if (FillFileItem(file, fileItem, parameterObject))
564 611
   {
565 612
     success = true;
566 613
     list.Add(CFileItemPtr(new CFileItem(fileItem)));
@@ -603,3 +650,126 @@ void CAudioLibrary::FillAlbumItem(const CAlbum &album, const CStdString &path, C
603 650
 {
604 651
   item = CFileItemPtr(new CFileItem(path, album));
605 652
 }
  653
+
  654
+JSONRPC_STATUS CAudioLibrary::GetAdditionalAlbumDetails(const CVariant &parameterObject, CFileItemList &items, CMusicDatabase &musicdatabase)
  655
+{
  656
+  if (!musicdatabase.Open())
  657
+    return InternalError;
  658
+
  659
+  std::set<std::string> checkProperties;
  660
+  checkProperties.insert("genreid");
  661
+  checkProperties.insert("artistid");
  662
+  std::set<std::string> additionalProperties;
  663
+  if (!CheckForAdditionalProperties(parameterObject["properties"], checkProperties, additionalProperties))
  664
+    return OK;
  665
+
  666
+  for (int i = 0; i < items.Size(); i++)
  667
+  {
  668
+    CFileItemPtr item = items[i];
  669
+    if (additionalProperties.find("genreid") != additionalProperties.end())
  670
+    {
  671
+      std::vector<int> genreids;
  672
+      if (musicdatabase.GetGenresByAlbum(item->GetMusicInfoTag()->GetDatabaseId(), genreids))
  673
+      {
  674
+        CVariant genreidObj(CVariant::VariantTypeArray);
  675
+        for (std::vector<int>::const_iterator genreid = genreids.begin(); genreid != genreids.end(); genreid++)
  676
+          genreidObj.push_back(*genreid);
  677
+
  678
+        item->SetProperty("genreid", genreidObj);
  679
+      }
  680
+    }
  681
+    if (additionalProperties.find("artistid") != additionalProperties.end())
  682
+    {
  683
+      std::vector<int> artistids;
  684
+      if (musicdatabase.GetArtistsByAlbum(item->GetMusicInfoTag()->GetDatabaseId(), true, artistids))
  685
+      {
  686
+        CVariant artistidObj(CVariant::VariantTypeArray);
  687
+        for (std::vector<int>::const_iterator artistid = artistids.begin(); artistid != artistids.end(); artistid++)
  688
+          artistidObj.push_back(*artistid);
  689
+
  690
+        item->SetProperty("artistid", artistidObj);
  691
+      }
  692
+    }
  693
+  }
  694
+
  695
+  return OK;
  696
+}
  697
+
  698
+JSONRPC_STATUS CAudioLibrary::GetAdditionalSongDetails(const CVariant &parameterObject, CFileItemList &items, CMusicDatabase &musicdatabase)
  699
+{
  700
+  if (!musicdatabase.Open())
  701
+    return InternalError;
  702
+
  703
+  std::set<std::string> checkProperties;
  704
+  checkProperties.insert("genreid");
  705
+  checkProperties.insert("artistid");
  706
+  checkProperties.insert("albumartistid");
  707
+  std::set<std::string> additionalProperties;
  708
+  if (!CheckForAdditionalProperties(parameterObject["properties"], checkProperties, additionalProperties))
  709
+    return OK;
  710
+
  711
+  for (int i = 0; i < items.Size(); i++)
  712
+  {
  713
+    CFileItemPtr item = items[i];
  714
+    if (additionalProperties.find("genreid") != additionalProperties.end())
  715
+    {
  716
+      std::vector<int> genreids;
  717
+      if (musicdatabase.GetGenresBySong(item->GetMusicInfoTag()->GetDatabaseId(), genreids))
  718
+      {
  719
+        CVariant genreidObj(CVariant::VariantTypeArray);
  720
+        for (std::vector<int>::const_iterator genreid = genreids.begin(); genreid != genreids.end(); genreid++)
  721
+          genreidObj.push_back(*genreid);
  722
+
  723
+        item->SetProperty("genreid", genreidObj);
  724
+      }
  725
+    }
  726
+    if (additionalProperties.find("artistid") != additionalProperties.end())
  727
+    {
  728
+      std::vector<int> artistids;
  729
+      if (musicdatabase.GetArtistsBySong(item->GetMusicInfoTag()->GetDatabaseId(), true, artistids))
  730
+      {
  731
+        CVariant artistidObj(CVariant::VariantTypeArray);
  732
+        for (std::vector<int>::const_iterator artistid = artistids.begin(); artistid != artistids.end(); artistid++)
  733
+          artistidObj.push_back(*artistid);
  734
+
  735
+        item->SetProperty("artistid", artistidObj);
  736
+      }
  737
+    }
  738
+    if (additionalProperties.find("albumartistid") != additionalProperties.end() && item->GetMusicInfoTag()->GetAlbumId() > 0)
  739
+    {
  740
+      std::vector<int> albumartistids;
  741
+      if (musicdatabase.GetArtistsByAlbum(item->GetMusicInfoTag()->GetAlbumId(), true, albumartistids))
  742
+      {
  743
+        CVariant albumartistidObj(CVariant::VariantTypeArray);
  744
+        for (std::vector<int>::const_iterator albumartistid = albumartistids.begin(); albumartistid != albumartistids.end(); albumartistid++)
  745
+          albumartistidObj.push_back(*albumartistid);
  746
+
  747
+        item->SetProperty("albumartistid", albumartistidObj);
  748
+      }
  749
+    }
  750
+  }
  751
+
  752
+  return OK;
  753
+}
  754
+
  755
+bool CAudioLibrary::CheckForAdditionalProperties(const CVariant &properties, const std::set<std::string> &checkProperties, std::set<std::string> &foundProperties)
  756
+{
  757
+  if (!properties.isArray() || properties.empty())
  758
+    return false;
  759
+
  760
+  std::set<std::string> checkingProperties = checkProperties;
  761
+  for (CVariant::const_iterator_array itr = properties.begin_array(); itr != properties.end_array() && !checkingProperties.empty(); itr++)
  762
+  {
  763
+    if (!itr->isString())
  764
+      continue;
  765
+
  766
+    std::string property = itr->asString();
  767
+    if (checkingProperties.find(property) != checkingProperties.end())
  768
+    {
  769
+      checkingProperties.erase(property);
  770
+      foundProperties.insert(property);
  771
+    }
  772
+  }
  773
+
  774
+  return !foundProperties.empty();
  775
+}
11  xbmc/interfaces/json-rpc/AudioLibrary.h
@@ -19,10 +19,14 @@
19 19
  *
20 20
  */
21 21
 
  22
+#include <set>
  23
+
22 24
 #include "utils/StdString.h"
23 25
 #include "JSONRPC.h"
24 26
 #include "FileItemHandler.h"
25 27
 
  28
+class CMusicDatabase;
  29
+
26 30
 namespace JSONRPC
27 31
 {
28 32
   class CAudioLibrary : public CFileItemHandler
@@ -49,10 +53,15 @@ namespace JSONRPC
49 53
     static JSONRPC_STATUS Export(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
50 54
     static JSONRPC_STATUS Clean(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
51 55
 
52  
-    static bool FillFileItem(const CStdString &strFilename, CFileItem &item);
  56
+    static bool FillFileItem(const CStdString &strFilename, CFileItem &item, const CVariant &parameterObject = CVariant(CVariant::VariantTypeArray));
53 57
     static bool FillFileItemList(const CVariant &parameterObject, CFileItemList &list);
54 58
 
  59
+    static JSONRPC_STATUS GetAdditionalAlbumDetails(const CVariant &parameterObject, CFileItemList &items, CMusicDatabase &musicdatabase);
  60
+    static JSONRPC_STATUS GetAdditionalSongDetails(const CVariant &parameterObject, CFileItemList &items, CMusicDatabase &musicdatabase);
  61
+
55 62
   private:
56 63
     static void FillAlbumItem(const CAlbum &album, const CStdString &path, CFileItemPtr &item);
  64
+    
  65
+    static bool CheckForAdditionalProperties(const CVariant &properties, const std::set<std::string> &checkProperties, std::set<std::string> &foundProperties);
57 66
   };
58 67
 }
6  xbmc/interfaces/json-rpc/FileItemHandler.cpp
@@ -164,6 +164,12 @@ bool CFileItemHandler::GetField(const std::string &field, const CVariant &info,
164 164
       result[field] = item->m_dateTime.GetAsLocalizedDateTime();
165 165
       return true;
166 166
     }
  167
+
  168
+    if (item->HasProperty(field))
  169
+    {
  170
+      result[field] = item->GetProperty(field);
  171
+      return true;
  172
+    }
167 173
   }
168 174
 
169 175
   return false;
10  xbmc/interfaces/json-rpc/FileOperations.cpp
@@ -139,7 +139,7 @@ JSONRPC_STATUS CFileOperations::GetDirectory(const CStdString &method, ITranspor
139 139
       else
140 140
       {
141 141
         CFileItem fileItem;
142  
-        if (FillFileItem(items[i], fileItem, media))
  142
+        if (FillFileItem(items[i], fileItem, media, parameterObject))
143 143
         {
144 144
           if (items[i]->m_bIsFolder)
145 145
             filteredDirectories.Add(CFileItemPtr(new CFileItem(fileItem)));
@@ -214,7 +214,7 @@ JSONRPC_STATUS CFileOperations::GetFileDetails(const CStdString &method, ITransp
214 214
 
215 215
   CFileItemPtr item = items.Get(file);
216 216
   if (!URIUtils::IsUPnP(file))
217  
-    FillFileItem(item, *item.get(), parameterObject["media"].asString());
  217
+    FillFileItem(item, *item.get(), parameterObject["media"].asString(), parameterObject);
218 218
 
219 219
   // Check if the "properties" list exists
220 220
   // and make sure it contains the "file"
@@ -263,7 +263,7 @@ JSONRPC_STATUS CFileOperations::Download(const CStdString &method, ITransportLay
263 263
   return transport->Download(parameterObject["path"].asString().c_str(), result) ? OK : InvalidParams;
264 264
 }
265 265
 
266  
-bool CFileOperations::FillFileItem(const CFileItemPtr &originalItem, CFileItem &item, CStdString media /* = "" */)
  266
+bool CFileOperations::FillFileItem(const CFileItemPtr &originalItem, CFileItem &item, CStdString media /* = "" */, const CVariant &parameterObject /* = CVariant(CVariant::VariantTypeArray) */)
267 267
 {
268 268
   if (originalItem.get() == NULL)
269 269
     return false;
@@ -278,7 +278,7 @@ bool CFileOperations::FillFileItem(const CFileItemPtr &originalItem, CFileItem &
278 278
     if (media.Equals("video"))
279 279
       status = CVideoLibrary::FillFileItem(strFilename, item);
280 280
     else if (media.Equals("music"))
281  
-      status = CAudioLibrary::FillFileItem(strFilename, item);
  281
+      status = CAudioLibrary::FillFileItem(strFilename, item, parameterObject);
282 282
 
283 283
     if (status && item.GetLabel().empty())
284 284
     {
@@ -364,7 +364,7 @@ bool CFileOperations::FillFileItemList(const CVariant &parameterObject, CFileIte
364 364
           else
365 365
           {
366 366
             CFileItem fileItem;
367  
-            if (FillFileItem(items[i], fileItem, media))
  367
+            if (FillFileItem(items[i], fileItem, media, parameterObject))
368 368
               list.Add(CFileItemPtr(new CFileItem(fileItem)));
369 369
             else if (media == "files")
370 370
               list.Add(items[i]);
2  xbmc/interfaces/json-rpc/FileOperations.h
@@ -35,7 +35,7 @@ namespace JSONRPC
35 35
     static JSONRPC_STATUS PrepareDownload(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
36 36
     static JSONRPC_STATUS Download(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
37 37
 
38  
-    static bool FillFileItem(const CFileItemPtr &originalItem, CFileItem &item, CStdString media = "");
  38
+    static bool FillFileItem(const CFileItemPtr &originalItem, CFileItem &item, CStdString media = "", const CVariant &parameterObject = CVariant(CVariant::VariantTypeArray));
39 39
     static bool FillFileItemList(const CVariant &parameterObject, CFileItemList &list);
40 40
   };
41 41
 }
18  xbmc/interfaces/json-rpc/PlayerOperations.cpp
@@ -37,6 +37,7 @@
37 37
 #include "filesystem/File.h"
38 38
 #include "PartyModeManager.h"
39 39
 #include "epg/EpgInfoTag.h"
  40
+#include "music/MusicDatabase.h"
40 41
 #include "pvr/PVRManager.h"
41 42
 #include "pvr/channels/PVRChannel.h"
42 43
 #include "pvr/channels/PVRChannelGroupsContainer.h"
@@ -125,7 +126,7 @@ JSONRPC_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLa
125 126
         }
126 127
         else
127 128
         {
128  
-          if (!CAudioLibrary::FillFileItem(g_application.CurrentFile(), tmpItem))
  129
+          if (!CAudioLibrary::FillFileItem(g_application.CurrentFile(), tmpItem, parameterObject))
129 130
           {
130 131
             tmpItem = CFileItem(*g_infoManager.GetCurrentSongTag());
131 132
             tmpItem.SetPath(g_application.CurrentFileItem().GetPath());
@@ -137,7 +138,10 @@ JSONRPC_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLa
137 138
       else
138 139
         fileItem = CFileItemPtr(new CFileItem(g_application.CurrentFileItem()));
139 140
 
140  
-      if (player == Video && !IsPVRChannel())
  141
+      if (IsPVRChannel())
  142
+        break;
  143
+
  144
+      if (player == Video)
141 145
       {
142 146
         bool additionalInfo = false;
143 147
         for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
@@ -176,6 +180,16 @@ JSONRPC_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLa
176 180
           }
177 181
         }
178 182
       }
  183
+      else if (player == Audio)
  184
+      {
  185
+        if (fileItem->IsMusicDb())
  186
+        {
  187
+          CMusicDatabase musicdb;
  188
+          CFileItemList items;
  189
+          items.Add(fileItem);
  190
+          CAudioLibrary::GetAdditionalSongDetails(parameterObject, items, musicdb);
  191
+        }
  192
+      }
179 193
       break;
180 194
     }
181 195
 
26  xbmc/interfaces/json-rpc/ServiceDescription.h
@@ -419,22 +419,25 @@ namespace JSONRPC
419 419
     "\"Audio.Fields.Album\": {"
420 420
       "\"extends\": \"Item.Fields.Base\","
421 421
       "\"items\": { \"type\": \"string\","
  422
+        "\"description\": \"Requesting the genreid and/or artistid field will result in increased response times\","
422 423
         "\"enum\": [ \"title\", \"description\", \"artist\", \"genre\","
423 424
                   "\"theme\", \"mood\", \"style\", \"type\", \"albumlabel\","
424 425
                   "\"rating\", \"year\", \"musicbrainzalbumid\","
425 426
                   "\"musicbrainzalbumartistid\", \"fanart\", \"thumbnail\","
426  
-                  "\"playcount\" ]"
  427
+                  "\"playcount\", \"genreid\", \"artistid\", \"displayartist\" ]"
427 428
       "}"
428 429
     "}",
429 430
     "\"Audio.Fields.Song\": {"
430 431
       "\"extends\": \"Item.Fields.Base\","
431 432
       "\"items\": { \"type\": \"string\","
  433
+        "\"description\": \"Requesting the genreid, artistid and/or albumartistid field will result in increased response times\","
432 434
         "\"enum\": [ \"title\", \"artist\", \"albumartist\", \"genre\", \"year\","
433 435
                   "\"rating\", \"album\", \"track\", \"duration\", \"comment\","
434 436
                   "\"lyrics\", \"musicbrainztrackid\", \"musicbrainzartistid\","
435 437
                   "\"musicbrainzalbumid\", \"musicbrainzalbumartistid\","
436  
-                  "\"playcount\", \"fanart\", \"thumbnail\", \"file\","
437  
-                  "\"albumid\", \"lastplayed\", \"disc\" ]"
  438
+                  "\"playcount\", \"fanart\", \"thumbnail\", \"file\", \"albumid\","
  439
+                  "\"lastplayed\", \"disc\", \"genreid\", \"artistid\", \"displayartist\","
  440
+                  "\"albumartistid\" ]"
438 441
       "}"
439 442
     "}",
440 443
     "\"Audio.Details.Base\": {"
@@ -451,7 +454,10 @@ namespace JSONRPC
451 454
         "\"year\": { \"type\": \"integer\" },"
452 455
         "\"rating\": { \"type\": \"integer\" },"
453 456
         "\"musicbrainzalbumid\": { \"type\": \"string\" },"
454  
-        "\"musicbrainzalbumartistid\": { \"type\": \"string\" }"
  457
+        "\"musicbrainzalbumartistid\": { \"type\": \"string\" },"
  458
+        "\"genreid\": { \"$ref\": \"Array.Integer\" },"
  459
+        "\"artistid\": { \"$ref\": \"Array.Integer\" },"
  460
+        "\"displayartist\": { \"type\" : \"string\" }"
455 461
       "}"
456 462
     "}",
457 463
     "\"Audio.Details.Artist\": {"
@@ -500,7 +506,8 @@ namespace JSONRPC
500 506
         "\"musicbrainzartistid\": { \"type\": \"string\" },"
501 507
         "\"albumid\": { \"$ref\": \"Library.Id\" },"
502 508
         "\"lastplayed\": { \"type\": \"string\" },"
503  
-        "\"disc\": { \"type\": \"integer\" }"
  509
+        "\"disc\": { \"type\": \"integer\" },"
  510
+        "\"albumartistid\": { \"$ref\": \"Array.Integer\" }"
504 511
       "}"
505 512
     "}",
506 513
     "\"Video.Fields.Movie\": {"
@@ -1043,7 +1050,8 @@ namespace JSONRPC
1043 1050
         "\"tvshowid\": { \"$ref\": \"Library.Id\" },"
1044 1051
         "\"watchedepisodes\": { \"type\": \"integer\" },"
1045 1052
         "\"disc\": { \"type\": \"integer\" },"
1046  
-        "\"tag\": { \"$ref\": \"Array.String\" }"
  1053
+        "\"tag\": { \"$ref\": \"Array.String\" },"
  1054
+        "\"albumartistid\": { \"$ref\": \"Array.Integer\" }"
1047 1055
       "}"
1048 1056
     "}",
1049 1057
     "\"List.Fields.All\": {"
@@ -1059,7 +1067,8 @@ namespace JSONRPC
1059 1067
                   "\"firstaired\", \"season\", \"episode\", \"showtitle\", \"thumbnail\", \"file\","
1060 1068
                   "\"resume\", \"artistid\", \"albumid\", \"tvshowid\", \"setid\", \"watchedepisodes\","
1061 1069
                   "\"disc\", \"tag\", \"art\", \"channel\", \"channeltype\", \"hidden\", \"locked\","
1062  
-                  "\"channelnumber\", \"starttime\", \"endtime\" ]"
  1070
+                  "\"channelnumber\", \"starttime\", \"endtime\", \"genreid\", \"displayartist\","
  1071
+                  "\"albumartistid\" ]"
1063 1072
       "}"
1064 1073
     "}",
1065 1074
     "\"List.Item.All\": {"
@@ -1086,7 +1095,8 @@ namespace JSONRPC
1086 1095
                   "\"runtime\", \"set\", \"showlink\", \"streamdetails\", \"top250\", \"votes\","
1087 1096
                   "\"firstaired\", \"season\", \"episode\", \"showtitle\", \"thumbnail\", \"file\","
1088 1097
                   "\"resume\", \"artistid\", \"albumid\", \"tvshowid\", \"setid\", \"watchedepisodes\","
1089  
-                  "\"disc\", \"tag\", \"art\", \"size\", \"lastmodified\", \"mimetype\" ]"
  1098
+                  "\"disc\", \"tag\", \"art\", \"size\", \"lastmodified\", \"mimetype\", \"genreid\","
  1099
+                  "\"displayartist\", \"albumartistid\" ]"
1090 1100
       "}"
1091 1101
     "}",
1092 1102
     "\"List.Item.File\": {"
26  xbmc/interfaces/json-rpc/types.json
@@ -392,22 +392,25 @@
392 392
   "Audio.Fields.Album": {
393 393
     "extends": "Item.Fields.Base",
394 394
     "items": { "type": "string",
  395
+      "description": "Requesting the genreid and/or artistid field will result in increased response times",
395 396
       "enum": [ "title", "description", "artist", "genre",
396 397
                 "theme", "mood", "style", "type", "albumlabel",
397 398
                 "rating", "year", "musicbrainzalbumid",
398 399
                 "musicbrainzalbumartistid", "fanart", "thumbnail",
399  
-                "playcount" ]
  400
+                "playcount", "genreid", "artistid", "displayartist" ]
400 401
     }
401 402
   },
402 403
   "Audio.Fields.Song": {
403 404
     "extends": "Item.Fields.Base",
404 405
     "items": { "type": "string",
  406
+      "description": "Requesting the genreid, artistid and/or albumartistid field will result in increased response times",
405 407
       "enum": [ "title", "artist", "albumartist", "genre", "year",
406 408
                 "rating", "album", "track", "duration", "comment",
407 409
                 "lyrics", "musicbrainztrackid", "musicbrainzartistid",
408 410
                 "musicbrainzalbumid", "musicbrainzalbumartistid",
409  
-                "playcount", "fanart", "thumbnail", "file",
410  
-                "albumid", "lastplayed", "disc" ]
  411
+                "playcount", "fanart", "thumbnail", "file", "albumid",
  412
+                "lastplayed", "disc", "genreid", "artistid", "displayartist",
  413
+                "albumartistid" ]
411 414
     }
412 415
   },
413 416
   "Audio.Details.Base": {
@@ -424,7 +427,10 @@
424 427
       "year": { "type": "integer" },
425 428
       "rating": { "type": "integer" },
426 429
       "musicbrainzalbumid": { "type": "string" },
427  
-      "musicbrainzalbumartistid": { "type": "string" }
  430
+      "musicbrainzalbumartistid": { "type": "string" },
  431
+      "genreid": { "$ref": "Array.Integer" },
  432
+      "artistid": { "$ref": "Array.Integer" },
  433
+      "displayartist": { "type" : "string" }
428 434
     }
429 435
   },
430 436
   "Audio.Details.Artist": {
@@ -473,7 +479,8 @@
473 479
       "musicbrainzartistid": { "type": "string" },
474 480
       "albumid": { "$ref": "Library.Id" },
475 481
       "lastplayed": { "type": "string" },
476  
-      "disc": { "type": "integer" }
  482
+      "disc": { "type": "integer" },
  483
+      "albumartistid": { "$ref": "Array.Integer" }
477 484
     }
478 485
   },
479 486
   "Video.Fields.Movie": {
@@ -1016,7 +1023,8 @@
1016 1023
       "tvshowid": { "$ref": "Library.Id" },
1017 1024
       "watchedepisodes": { "type": "integer" },
1018 1025
       "disc": { "type": "integer" },
1019  
-      "tag": { "$ref": "Array.String" }
  1026
+      "tag": { "$ref": "Array.String" },
  1027
+      "albumartistid": { "$ref": "Array.Integer" }
1020 1028
     }
1021 1029
   },
1022 1030
   "List.Fields.All": {
@@ -1032,7 +1040,8 @@
1032 1040
                 "firstaired", "season", "episode", "showtitle", "thumbnail", "file",
1033 1041
                 "resume", "artistid", "albumid", "tvshowid", "setid", "watchedepisodes",
1034 1042
                 "disc", "tag", "art", "channel", "channeltype", "hidden", "locked",
1035  
-                "channelnumber", "starttime", "endtime" ]
  1043
+                "channelnumber", "starttime", "endtime", "genreid", "displayartist",
  1044
+                "albumartistid" ]
1036 1045
     }
1037 1046
   },
1038 1047
   "List.Item.All": {
@@ -1059,7 +1068,8 @@
1059 1068
                 "runtime", "set", "showlink", "streamdetails", "top250", "votes",
1060 1069
                 "firstaired", "season", "episode", "showtitle", "thumbnail", "file",
1061 1070
                 "resume", "artistid", "albumid", "tvshowid", "setid", "watchedepisodes",
1062  
-                "disc", "tag", "art", "size", "lastmodified", "mimetype" ]
  1071
+                "disc", "tag", "art", "size", "lastmodified", "mimetype", "genreid",
  1072
+                "displayartist", "albumartistid" ]
1063 1073
     }
1064 1074
   },
1065 1075
   "List.Item.File": {
75  xbmc/music/MusicDatabase.cpp
@@ -225,7 +225,8 @@ void CMusicDatabase::CreateViews()
225 225
               "  strMusicBrainzTRMID, iTimesPlayed, iStartOffset, iEndOffset, lastplayed,"
226 226
               "  rating, comment, song.idAlbum AS idAlbum, strAlbum, strPath,"
227 227
               "  iKaraNumber, iKaraDelay, strKaraEncoding,"
228  
-              "  album.bCompilation AS bCompilation "
  228
+              "  album.bCompilation AS bCompilation,"
  229
+              "  album.strArtists AS strAlbumArtists "
229 230
               "FROM song"
230 231
               "  JOIN album ON"
231 232
               "    song.idAlbum=album.idAlbum"
@@ -641,7 +642,7 @@ bool CMusicDatabase::AddAlbumGenre(int idGenre, int idAlbum, int iOrder)
641 642
   return ExecuteQuery(strSQL);
642 643
 };
643 644
 
644  
-bool CMusicDatabase::GetAlbumsByArtist(int idArtist, bool includeFeatured, std::vector<long> &albums)
  645
+bool CMusicDatabase::GetAlbumsByArtist(int idArtist, bool includeFeatured, std::vector<int> &albums)
645 646
 {
646 647
   try 
647 648
   {
@@ -675,7 +676,7 @@ bool CMusicDatabase::GetAlbumsByArtist(int idArtist, bool includeFeatured, std::
675 676
   return false;
676 677
 }
677 678
 
678  
-bool CMusicDatabase::GetArtistsByAlbum(int idAlbum, bool includeFeatured, std::vector<long> &artists)
  679
+bool CMusicDatabase::GetArtistsByAlbum(int idAlbum, bool includeFeatured, std::vector<int> &artists)
679 680
 {
680 681
   try 
681 682
   {
@@ -709,7 +710,7 @@ bool CMusicDatabase::GetArtistsByAlbum(int idAlbum, bool includeFeatured, std::v
709 710
   return false;
710 711
 }
711 712
 
712  
-bool CMusicDatabase::GetSongsByArtist(int idArtist, bool includeFeatured, std::vector<long> &songs)
  713
+bool CMusicDatabase::GetSongsByArtist(int idArtist, bool includeFeatured, std::vector<int> &songs)
713 714
 {
714 715
   try 
715 716
   {
@@ -743,7 +744,7 @@ bool CMusicDatabase::GetSongsByArtist(int idArtist, bool includeFeatured, std::v
743 744
   return false;
744 745
 };
745 746
 
746  
-bool CMusicDatabase::GetArtistsBySong(int idSong, bool includeFeatured, std::vector<long> &artists)
  747
+bool CMusicDatabase::GetArtistsBySong(int idSong, bool includeFeatured, std::vector<int> &artists)
747 748
 {
748 749
   try 
749 750
   {
@@ -775,7 +776,65 @@ bool CMusicDatabase::GetArtistsBySong(int idSong, bool includeFeatured, std::vec
775 776
     CLog::Log(LOGERROR, "%s(%i) failed", __FUNCTION__, idSong);
776 777
   }
777 778
   return false;
778  
-};
  779
+}
  780
+
  781
+bool CMusicDatabase::GetGenresByAlbum(int idAlbum, std::vector<int>& genres)
  782
+{
  783
+  try
  784
+  {
  785
+    CStdString strSQL = PrepareSQL("select idGenre from album_genre where idAlbum = %i ORDER BY iOrder ASC", idAlbum);
  786
+    if (!m_pDS->query(strSQL.c_str()))
  787
+      return false;
  788
+    if (m_pDS->num_rows() == 0)
  789
+    {
  790
+      m_pDS->close();
  791
+      return true;
  792
+    }
  793
+
  794
+    while (!m_pDS->eof())
  795
+    {
  796
+      genres.push_back(m_pDS->fv("idGenre").get_asInt());
  797
+      m_pDS->next();
  798
+    }
  799
+    m_pDS->close();
  800
+
  801
+    return true;
  802
+  }
  803
+  catch (...)
  804
+  {
  805
+    CLog::Log(LOGERROR, "%s(%i) failed", __FUNCTION__, idAlbum);
  806
+  }
  807
+  return false;
  808
+}
  809
+
  810
+bool CMusicDatabase::GetGenresBySong(int idSong, std::vector<int>& genres)
  811
+{
  812
+  try
  813
+  {
  814
+    CStdString strSQL = PrepareSQL("select idGenre from song_genre where idSong = %i ORDER BY iOrder ASC", idSong);
  815
+    if (!m_pDS->query(strSQL.c_str()))
  816
+      return false;
  817
+    if (m_pDS->num_rows() == 0)
  818
+    {
  819
+      m_pDS->close();
  820
+      return true;
  821
+    }
  822
+
  823
+    while (!m_pDS->eof())
  824
+    {
  825
+      genres.push_back(m_pDS->fv("idGenre").get_asInt());
  826
+      m_pDS->next();
  827
+    }
  828
+    m_pDS->close();
  829
+
  830
+    return true;
  831
+  }
  832
+  catch (...)
  833
+  {
  834
+    CLog::Log(LOGERROR, "%s(%i) failed", __FUNCTION__, idSong);
  835
+  }
  836
+  return false;
  837
+}
779 838
 
780 839
 int CMusicDatabase::AddPath(const CStdString& strPath1)
781 840
 {
@@ -854,6 +913,7 @@ CSong CMusicDatabase::GetSongFromDataset(bool bWithMusicDbPath/*=false*/)
854 913
   song.strKaraokeLyrEncoding = m_pDS->fv(song_strKarEncoding).get_asString();
855 914
   song.iKaraokeDelay = m_pDS->fv(song_iKarDelay).get_asInt();
856 915
   song.bCompilation = m_pDS->fv(song_bCompilation).get_asInt() == 1;
  916
+  song.albumArtist = StringUtils::Split(m_pDS->fv(song_strAlbumArtists).get_asString(), g_advancedSettings.m_musicItemSeparator);
857 917
 
858 918
   // Get filename with full path
859 919
   if (!bWithMusicDbPath)
@@ -905,7 +965,8 @@ void CMusicDatabase::GetFileItemFromDataset(const dbiplus::sql_record* const rec
905 965
   CStdString strRealPath;
906 966
   URIUtils::AddFileToFolder(record->at(song_strPath).get_asString(), record->at(song_strFileName).get_asString(), strRealPath);
907 967
   item->GetMusicInfoTag()->SetURL(strRealPath);
908  
-  item->GetMusicInfoTag()->SetCompilation(m_pDS->fv(song_bCompilation).get_asInt() == 1);
  968
+  item->GetMusicInfoTag()->SetCompilation(record->at(song_bCompilation).get_asInt() == 1);
  969
+  item->GetMusicInfoTag()->SetAlbumArtist(record->at(song_strAlbumArtists).get_asString());
909 970
   item->GetMusicInfoTag()->SetLoaded(true);
910 971
   // Get filename with full path
911 972
   if (strMusicDBbasePath.IsEmpty())
16  xbmc/music/MusicDatabase.h
@@ -128,10 +128,13 @@ class CMusicDatabase : public CDatabase
128 128
   bool GetAlbumFromSong(int idSong, CAlbum &album);
129 129
   bool GetAlbumFromSong(const CSong &song, CAlbum &album);
130 130
   
131  
-  bool GetAlbumsByArtist(int idArtist, bool includeFeatured, std::vector<long>& albums);
132  
-  bool GetArtistsByAlbum(int idAlbum, bool includeFeatured, std::vector<long>& artists);
133  
-  bool GetSongsByArtist(int idArtist, bool includeFeatured, std::vector<long>& songs);
134  
-  bool GetArtistsBySong(int idSong, bool includeFeatured, std::vector<long>& artists);
  131
+  bool GetAlbumsByArtist(int idArtist, bool includeFeatured, std::vector<int>& albums);
  132
+  bool GetArtistsByAlbum(int idAlbum, bool includeFeatured, std::vector<int>& artists);
  133
+  bool GetSongsByArtist(int idArtist, bool includeFeatured, std::vector<int>& songs);
  134
+  bool GetArtistsBySong(int idSong, bool includeFeatured, std::vector<int>& artists);
  135
+
  136
+  bool GetGenresByAlbum(int idAlbum, std::vector<int>& genres);
  137
+  bool GetGenresBySong(int idSong, std::vector<int>& genres);
135 138
 
136 139
   bool GetTop100(const CStdString& strBaseDir, CFileItemList& items);
137 140
   bool GetTop100Albums(VECALBUMS& albums);
@@ -278,7 +281,7 @@ class CMusicDatabase : public CDatabase
278 281
   std::map<CStdString, CAlbum> m_albumCache;
279 282
 
280 283
   virtual bool CreateTables();
281  
-  virtual int GetMinVersion() const { return 30; };
  284
+  virtual int GetMinVersion() const { return 31; };
282 285
   const char *GetBaseDBName() const { return "MyMusic"; };
283 286
 
284 287
   int AddSong(const CSong& song, bool bCheck = true, int idAlbum = -1);
@@ -350,7 +353,8 @@ class CMusicDatabase : public CDatabase
350 353
     song_iKarNumber,
351 354
     song_iKarDelay,
352 355
     song_strKarEncoding,
353  
-    song_bCompilation
  356
+    song_bCompilation,
  357
+    song_strAlbumArtists
354 358
   } SongFields;
355 359
 
356 360
   // Fields should be ordered as they
12  xbmc/music/infoscanner/MusicInfoScanner.cpp
@@ -554,8 +554,8 @@ int CMusicInfoScanner::RetrieveMusicInfo(CFileItemList& items, const CStdString&
554 554
   // finally, add these to the database
555 555
   m_musicDatabase.BeginTransaction();
556 556
   int numAdded = 0;
557  
-  set<long> albumsToScan;
558  
-  set<long> artistsToScan;
  557
+  set<int> albumsToScan;
  558
+  set<int> artistsToScan;
559 559
   for (VECALBUMS::iterator i = albums.begin(); i != albums.end(); ++i)
560 560
   {
561 561
     vector<int> songIDs;
@@ -571,11 +571,11 @@ int CMusicInfoScanner::RetrieveMusicInfo(CFileItemList& items, const CStdString&
571 571
     albumsToScan.insert(idAlbum);
572 572
     for (vector<int>::iterator j = songIDs.begin(); j != songIDs.end(); ++j)
573 573
     {
574  
-      vector<long> songArtists;
  574
+      vector<int> songArtists;
575 575
       m_musicDatabase.GetArtistsBySong(*j, false, songArtists);
576 576
       artistsToScan.insert(songArtists.begin(), songArtists.end());
577 577
     }
578  
-    std::vector<long> albumArtists;
  578
+    std::vector<int> albumArtists;
579 579
     m_musicDatabase.GetArtistsByAlbum(idAlbum, false, albumArtists);
580 580
     artistsToScan.insert(albumArtists.begin(), albumArtists.end());
581 581
   }
@@ -583,7 +583,7 @@ int CMusicInfoScanner::RetrieveMusicInfo(CFileItemList& items, const CStdString&
583 583
 
584 584
   // Download info & artwork
585 585
   bool bCanceled;
586  
-  for (set<long>::iterator it = artistsToScan.begin(); it != artistsToScan.end(); ++it)
  586
+  for (set<int>::iterator it = artistsToScan.begin(); it != artistsToScan.end(); ++it)
587 587
   {
588 588
     bCanceled = false;
589 589
     if (find(m_artistsScanned.begin(),m_artistsScanned.end(), *it) == m_artistsScanned.end())
@@ -608,7 +608,7 @@ int CMusicInfoScanner::RetrieveMusicInfo(CFileItemList& items, const CStdString&
608 608
 
609 609
   if (m_flags & SCAN_ONLINE)
610 610
   {
611  
-    for (set<long>::iterator it = albumsToScan.begin(); it != albumsToScan.end(); ++it)
  611
+    for (set<int>::iterator it = albumsToScan.begin(); it != albumsToScan.end(); ++it)
612 612
     {
613 613
       if (m_bStop)
614 614
         return songsToAdd.size();
1  xbmc/music/tags/MusicInfoTag.cpp
@@ -571,6 +571,7 @@ void CMusicInfoTag::Serialize(CVariant& value) const
571 571
     value["artist"] = m_artist[0];
572 572
   else
573 573
     value["artist"] = m_artist;
  574
+  value["displayartist"] = StringUtils::Join(m_artist, g_advancedSettings.m_musicItemSeparator);
574 575
   value["album"] = m_strAlbum;
575 576
   value["albumartist"] = m_albumArtist;
576 577
   value["genre"] = m_genre;

0 notes on commit f00ff50

Please sign in to comment.
Something went wrong with that request. Please try again.