Skip to content
Browse files

Merge remote-tracking branch 'upstream-ro/master'

  • Loading branch information...
2 parents d2042a8 + bb8c4fa commit 18abdbeaef66f43452edb093dc2aad4bc297b384 @opdenkamp committed Aug 8, 2012
Showing with 1,056 additions and 578 deletions.
  1. +1 −1 XBMC-ATV2.xcodeproj/project.pbxproj
  2. +1 −1 XBMC-IOS.xcodeproj/project.pbxproj
  3. +2 −2 XBMC.xcodeproj/project.pbxproj
  4. +1 −0 docs/README.ios
  5. +3 −1 docs/README.linux
  6. +2 −0 docs/README.osx
  7. +8 −3 xbmc/Application.cpp
  8. +13 −24 xbmc/FileItem.cpp
  9. +1 −1 xbmc/GUIInfoManager.cpp
  10. +2 −1 xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
  11. +20 −10 xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp
  12. +1 −1 xbmc/cores/VideoRenderers/BaseRenderer.cpp
  13. +2 −1 xbmc/cores/dvdplayer/DVDInputStreams/DVDFactoryInputStream.cpp
  14. +14 −1 xbmc/cores/dvdplayer/DVDPlayer.cpp
  15. +3 −6 xbmc/dialogs/GUIDialogKeyboardGeneric.cpp
  16. +2 −2 xbmc/dialogs/GUIDialogKeyboardGeneric.h
  17. +2 −0 xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp
  18. +1 −1 xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
  19. +1 −1 xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeArtist.cpp
  20. +8 −1 xbmc/guilib/GUIKeyboardFactory.cpp
  21. +20 −147 xbmc/guilib/Geometry.h
  22. +5 −9 xbmc/interfaces/Builtins.cpp
  23. +3 −3 xbmc/interfaces/http-api/XBMChttp.cpp
  24. +58 −16 xbmc/interfaces/json-rpc/AudioLibrary.cpp
  25. +2 −4 xbmc/interfaces/json-rpc/FileItemHandler.cpp
  26. +125 −65 xbmc/interfaces/json-rpc/ServiceDescription.h
  27. +101 −24 xbmc/interfaces/json-rpc/VideoLibrary.cpp
  28. +0 −1 xbmc/interfaces/json-rpc/VideoLibrary.h
  29. +79 −17 xbmc/interfaces/json-rpc/methods.json
  30. +2 −2 xbmc/interfaces/json-rpc/notifications.json
  31. +43 −46 xbmc/interfaces/json-rpc/types.json
  32. +2 −2 xbmc/interfaces/python/xbmcmodule/xbmcmodule.cpp
  33. +84 −27 xbmc/music/MusicDatabase.cpp
  34. +1 −1 xbmc/music/MusicDatabase.h
  35. +1 −1 xbmc/music/infoscanner/MusicInfoScanner.cpp
  36. +6 −6 xbmc/music/tags/MusicInfoTag.cpp
  37. +1 −1 xbmc/network/websocket/WebSocketV13.cpp
  38. +4 −0 xbmc/osx/IOSScreenManager.mm
  39. +3 −3 xbmc/osx/ios/IOSKeyboardView.h
  40. +6 −0 xbmc/pictures/GUIDialogPictureInfo.cpp
  41. +6 −1 xbmc/playlists/PlayListFactory.cpp
  42. +117 −0 xbmc/playlists/PlayListM3U.cpp
  43. +7 −1 xbmc/playlists/PlayListM3U.h
  44. +40 −16 xbmc/playlists/SmartPlayList.cpp
  45. +1 −1 xbmc/settings/Settings.cpp
  46. +2 −0 xbmc/utils/DatabaseUtils.cpp
  47. +1 −1 xbmc/utils/DatabaseUtils.h
  48. +207 −82 xbmc/video/VideoDatabase.cpp
  49. +12 −12 xbmc/video/VideoDatabase.h
  50. +19 −24 xbmc/video/VideoInfoTag.cpp
  51. +2 −2 xbmc/video/VideoInfoTag.h
  52. +6 −0 xbmc/windowing/windows/WinEventsWin32.cpp
  53. +2 −5 xbmc/windowing/windows/WinSystemWin32.cpp
View
2 XBMC-ATV2.xcodeproj/project.pbxproj
@@ -6598,7 +6598,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ ${XCODE_VERSION_MINOR} -gt 400 ]\nthen\n TARGET_OUTPUT_DIR=\"${PROJECT_DIR}/build/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}\"\n mkdir -p \"${TARGET_OUTPUT_DIR}\"\n\n ln -sf \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\" \"${TARGET_OUTPUT_DIR}/\"\n ln -sf \"${BUILT_PRODUCTS_DIR}/${DWARF_DSYM_FILE_NAME}\" \"${TARGET_OUTPUT_DIR}/\"\nfi";
+ shellScript = "if [ ${XCODE_VERSION_MINOR} -gt 400 ]\nthen\n TARGET_OUTPUT_DIR=\"${PROJECT_DIR}/build/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}\"\n mkdir -p \"${TARGET_OUTPUT_DIR}\"\n if [ \"${BUILT_PRODUCTS_DIR}\" != \"${TARGET_OUTPUT_DIR}\" ]\n then\n rm -rf \"${TARGET_OUTPUT_DIR}/${FULL_PRODUCT_NAME}\"\n rm -rf \"${TARGET_OUTPUT_DIR}/${DWARF_DSYM_FILE_NAME}\"\n ln -s \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\" \"${TARGET_OUTPUT_DIR}/\" || true\n ln -s \"${BUILT_PRODUCTS_DIR}/${DWARF_DSYM_FILE_NAME}\" \"${TARGET_OUTPUT_DIR}/\" || true\n fi\nfi";
};
F589B48B128A696700D8079E /* copy root files */ = {
isa = PBXShellScriptBuildPhase;
View
2 XBMC-IOS.xcodeproj/project.pbxproj
@@ -6586,7 +6586,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ ${XCODE_VERSION_MINOR} -gt 400 ]\nthen\n TARGET_OUTPUT_DIR=\"${PROJECT_DIR}/build/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}\"\n mkdir -p \"${TARGET_OUTPUT_DIR}\"\n\n ln -sf \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\" \"${TARGET_OUTPUT_DIR}/\"\n ln -sf \"${BUILT_PRODUCTS_DIR}/${DWARF_DSYM_FILE_NAME}\" \"${TARGET_OUTPUT_DIR}/\"\nfi";
+ shellScript = "if [ ${XCODE_VERSION_MINOR} -gt 400 ]\nthen\n TARGET_OUTPUT_DIR=\"${PROJECT_DIR}/build/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}\"\n mkdir -p \"${TARGET_OUTPUT_DIR}\"\n\n if [ \"${BUILT_PRODUCTS_DIR}\" != \"${TARGET_OUTPUT_DIR}\" ]\n then\n rm -rf \"${TARGET_OUTPUT_DIR}/${FULL_PRODUCT_NAME}\"\n rm -rf \"${TARGET_OUTPUT_DIR}/${DWARF_DSYM_FILE_NAME}\"\n ln -s \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\" \"${TARGET_OUTPUT_DIR}/\" || true\n ln -s \"${BUILT_PRODUCTS_DIR}/${DWARF_DSYM_FILE_NAME}\" \"${TARGET_OUTPUT_DIR}/\" || true\n fi\nfi";
};
3234980612AF0B3400657FF1 /* codesign */ = {
isa = PBXShellScriptBuildPhase;
View
4 XBMC.xcodeproj/project.pbxproj
@@ -6631,7 +6631,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ ${XCODE_VERSION_MINOR} -gt 400 ]\nthen\n TARGET_OUTPUT_DIR=\"${PROJECT_DIR}/build/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}\"\n mkdir -p \"${TARGET_OUTPUT_DIR}\"\n\n ln -sf \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\" \"${TARGET_OUTPUT_DIR}/\"\n ln -sf \"${BUILT_PRODUCTS_DIR}/${DWARF_DSYM_FILE_NAME}\" \"${TARGET_OUTPUT_DIR}/\"\nfi";
+ shellScript = "if [ ${XCODE_VERSION_MINOR} -gt 400 ]\nthen\n TARGET_OUTPUT_DIR=\"${PROJECT_DIR}/build/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}\"\n mkdir -p \"${TARGET_OUTPUT_DIR}\"\n\n if [ \"${BUILT_PRODUCTS_DIR}\" != \"${TARGET_OUTPUT_DIR}\" ]\n then\n rm -rf \"${TARGET_OUTPUT_DIR}/${FULL_PRODUCT_NAME}\"\n rm -rf \"${TARGET_OUTPUT_DIR}/${DWARF_DSYM_FILE_NAME}\"\n ln -s \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\" \"${TARGET_OUTPUT_DIR}/\" || true\n ln -s \"${BUILT_PRODUCTS_DIR}/${DWARF_DSYM_FILE_NAME}\" \"${TARGET_OUTPUT_DIR}/\" || true\n fi\nfi";
};
1D64E5FC157BD76F001ACEBE /* genoutputdirlink */ = {
isa = PBXShellScriptBuildPhase;
@@ -6645,7 +6645,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ ${XCODE_VERSION_MINOR} -gt 400 ]\nthen\n TARGET_OUTPUT_DIR=\"${PROJECT_DIR}/build/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}\"\n mkdir -p \"${TARGET_OUTPUT_DIR}\"\n\n ln -sf \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" \"${TARGET_OUTPUT_DIR}/\"\n ln -sf \"${BUILT_PRODUCTS_DIR}/${PROJECT_NAME}${DWARF_DSYM_FILE_NAME}\" \"${TARGET_OUTPUT_DIR}/\"\nfi";
+ shellScript = "if [ ${XCODE_VERSION_MINOR} -gt 400 ]\nthen\n TARGET_OUTPUT_DIR=\"${PROJECT_DIR}/build/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}\"\n mkdir -p \"${TARGET_OUTPUT_DIR}\"\n\n if [ \"${BUILT_PRODUCTS_DIR}\" != \"${TARGET_OUTPUT_DIR}\" ]\n then\n rm -rf \"${TARGET_OUTPUT_DIR}/${PRODUCT_NAME}\"\n rm -rf \"${TARGET_OUTPUT_DIR}/${PROJECT_NAME}${DWARF_DSYM_FILE_NAME}\"\n ln -s \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}\" \"${TARGET_OUTPUT_DIR}/\" || true\n ln -s \"${BUILT_PRODUCTS_DIR}/${PROJECT_NAME}${DWARF_DSYM_FILE_NAME}\" \"${TARGET_OUTPUT_DIR}/\" || true\n fi\nfi";
};
6E2FACC70E26E22400DF79EA /* copy frameworks */ = {
isa = PBXShellScriptBuildPhase;
View
1 docs/README.ios
@@ -80,6 +80,7 @@ from the step 3.1.
$ make -C tools/darwin/depends/xbmc
$ make clean
$ make xcode_depends
+ $ make -C lib/addons/script.module.pil
-----------------------------------------------------------------------------
4.1 Using Xcode
View
4 docs/README.linux
@@ -98,7 +98,9 @@ Tip: by adding -j<number> to the make command, you describe how many
$ make -j2
-.3 $ make install
+.3 $ make -C lib/addons/script.module.pil
+
+.4 $ make install
This will install XBMC in the prefix provided in 4.1 as well as a launcher script.
View
2 docs/README.osx
@@ -94,6 +94,7 @@ first. This is a simple step and involves the following:
$ make -C tools/darwin/depends/xbmc
$ make clean
$ make xcode_depends
+ $ make -C lib/addons/script.module.pil
4.b Compilation by using command-line building via make (experimental)
@@ -175,6 +176,7 @@ developers).
$ cd $HOME/XBMC
$ export XBMC_HOME=`pwd`
$ make xcode_depends
+ $ make -C lib/addons/script.module.pil
$ xcodebuild -sdk macosx10.7 -project XBMC.xcodeproj -target XBMC.app ONLY_ACTIVE_ARCH=YES \
ARCHS=x86_64 VALID_ARCHS=x86_64 -configuration Release build
View
11 xbmc/Application.cpp
@@ -1367,7 +1367,7 @@ bool CApplication::Initialize()
CLog::Log(LOGINFO, "removing tempfiles");
CUtil::RemoveTempFiles();
- // if the user shutoff the xbox during music scan
+ // if the user shutoff the system during music scan
// restore the settings
if (g_settings.m_bMyMusicIsScanning)
{
@@ -5688,8 +5688,13 @@ float CApplication::GetPercentage() const
float CApplication::GetCachePercentage() const
{
if (IsPlaying() && m_pPlayer)
- return m_pPlayer->GetCachePercentage();
-
+ {
+ // Note that the player returns a relative cache percentage and we want an absolute percentage
+ // We also need to take into account the stack's total time vs. currently playing file's total time
+ float stackedTotalTime = (float) GetTotalTime();
+ if (stackedTotalTime > 0.0f)
+ return min( 100.0f, GetPercentage() + (m_pPlayer->GetCachePercentage() * m_pPlayer->GetTotalTime() / stackedTotalTime ) );
+ }
return 0.0f;
}
View
37 xbmc/FileItem.cpp
@@ -1530,8 +1530,7 @@ void CFileItemList::SetFastLookup(bool fastLookup)
for (unsigned int i=0; i < m_items.size(); i++)
{
CFileItemPtr pItem = m_items[i];
- CStdString path(pItem->GetPath()); path.ToLower();
- m_map.insert(MAPFILEITEMSPAIR(path, pItem));
+ m_map.insert(MAPFILEITEMSPAIR(pItem->GetPath(), pItem));
}
}
if (!fastLookup && m_fastLookup)
@@ -1543,15 +1542,14 @@ bool CFileItemList::Contains(const CStdString& fileName) const
{
CSingleLock lock(m_lock);
- // checks case insensitive
- CStdString checkPath(fileName); checkPath.ToLower();
if (m_fastLookup)
- return m_map.find(checkPath) != m_map.end();
+ return m_map.find(fileName) != m_map.end();
+
// slow method...
for (unsigned int i = 0; i < m_items.size(); i++)
{
const CFileItemPtr pItem = m_items[i];
- if (pItem->GetPath().Equals(checkPath))
+ if (pItem->GetPath().Equals(fileName))
return true;
}
return false;
@@ -1592,9 +1590,7 @@ void CFileItemList::Add(const CFileItemPtr &pItem)
m_items.push_back(pItem);
if (m_fastLookup)
{
- CStdString path(pItem->GetPath());
- path.ToLower();
- m_map.insert(MAPFILEITEMSPAIR(path, pItem));
+ m_map.insert(MAPFILEITEMSPAIR(pItem->GetPath(), pItem));
}
}
@@ -1612,8 +1608,7 @@ void CFileItemList::AddFront(const CFileItemPtr &pItem, int itemPosition)
}
if (m_fastLookup)
{
- CStdString path(pItem->GetPath()); path.ToLower();
- m_map.insert(MAPFILEITEMSPAIR(path, pItem));
+ m_map.insert(MAPFILEITEMSPAIR(pItem->GetPath(), pItem));
}
}
@@ -1628,8 +1623,7 @@ void CFileItemList::Remove(CFileItem* pItem)
m_items.erase(it);
if (m_fastLookup)
{
- CStdString path(pItem->GetPath()); path.ToLower();
- m_map.erase(path);
+ m_map.erase(pItem->GetPath());
}
break;
}
@@ -1645,8 +1639,7 @@ void CFileItemList::Remove(int iItem)
CFileItemPtr pItem = *(m_items.begin() + iItem);
if (m_fastLookup)
{
- CStdString path(pItem->GetPath()); path.ToLower();
- m_map.erase(path);
+ m_map.erase(pItem->GetPath());
}
m_items.erase(m_items.begin() + iItem);
}
@@ -1724,11 +1717,9 @@ CFileItemPtr CFileItemList::Get(const CStdString& strPath)
{
CSingleLock lock(m_lock);
- CStdString pathToCheck(strPath); pathToCheck.ToLower();
-
if (m_fastLookup)
{
- IMAPFILEITEMS it=m_map.find(pathToCheck);
+ IMAPFILEITEMS it=m_map.find(strPath);
if (it != m_map.end())
return it->second;
@@ -1738,7 +1729,7 @@ CFileItemPtr CFileItemList::Get(const CStdString& strPath)
for (unsigned int i = 0; i < m_items.size(); i++)
{
CFileItemPtr pItem = m_items[i];
- if (pItem->GetPath().Equals(pathToCheck))
+ if (pItem->GetPath().Equals(strPath))
return pItem;
}
@@ -1748,12 +1739,10 @@ CFileItemPtr CFileItemList::Get(const CStdString& strPath)
const CFileItemPtr CFileItemList::Get(const CStdString& strPath) const
{
CSingleLock lock(m_lock);
-
- CStdString pathToCheck(strPath); pathToCheck.ToLower();
-
+
if (m_fastLookup)
{
- map<CStdString, CFileItemPtr>::const_iterator it=m_map.find(pathToCheck);
+ map<CStdString, CFileItemPtr>::const_iterator it=m_map.find(strPath);
if (it != m_map.end())
return it->second;
@@ -1763,7 +1752,7 @@ const CFileItemPtr CFileItemList::Get(const CStdString& strPath) const
for (unsigned int i = 0; i < m_items.size(); i++)
{
CFileItemPtr pItem = m_items[i];
- if (pItem->GetPath().Equals(pathToCheck))
+ if (pItem->GetPath().Equals(strPath))
return pItem;
}
View
2 xbmc/GUIInfoManager.cpp
@@ -2005,7 +2005,7 @@ bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListI
if (item && condition >= LISTITEM_START && condition < LISTITEM_END)
bReturn = GetItemBool(item, condition);
// Ethernet Link state checking
- // Will check if the Xbox has a Ethernet Link connection! [Cable in!]
+ // Will check if system has a Ethernet Link connection! [Cable in!]
// This can used for the skinner to switch off Network or Inter required functions
else if ( condition == SYSTEM_ALWAYS_TRUE)
bReturn = true;
View
3 xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
@@ -644,8 +644,9 @@ void CAESinkDirectSound::CheckPlayStatus()
if (!(status & DSBSTATUS_PLAYING) && m_CacheLen != 0) // If we have some data, see if we can start playback
{
HRESULT hr = m_pBuffer->Play(0, 0, DSBPLAY_LOOPING);
- dserr2str(hr);
CLog::Log(LOGDEBUG,__FUNCTION__ ": Resuming Playback");
+ if (FAILED(hr))
+ CLog::Log(LOGERROR, __FUNCTION__": Failed to play the DirectSound buffer: %s", dserr2str(hr));
}
}
View
30 xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp
@@ -64,16 +64,26 @@ static const uint32_t DTSSampleRates[DTS_SFREQ_COUNT] =
};
CAEStreamInfo::CAEStreamInfo() :
- m_bufferSize(0),
- m_skipBytes (0),
- m_coreOnly (false),
- m_needBytes (0),
- m_syncFunc (&CAEStreamInfo::DetectType),
- m_hasSync (false),
- m_sampleRate(0),
- m_dtsBlocks (0),
- m_dataType (STREAM_TYPE_NULL),
- m_packFunc (NULL)
+ m_bufferSize (0),
+ m_skipBytes (0),
+ m_coreOnly (false),
+ m_needBytes (0),
+ m_syncFunc (&CAEStreamInfo::DetectType),
+ m_hasSync (false),
+ m_sampleRate (0),
+ m_outputRate (0),
+ m_outputChannels(0),
+ m_channelMap (CAEChannelInfo()),
+ m_channels (0),
+ m_coreSize (0),
+ m_dtsBlocks (0),
+ m_dtsPeriod (0),
+ m_fsize (0),
+ m_repeat (0),
+ m_substreams (0),
+ m_dataType (STREAM_TYPE_NULL),
+ m_dataIsLE (false),
+ m_packFunc (NULL)
{
m_dllAvUtil.Load();
m_dllAvUtil.av_crc_init(m_crcTrueHD, 0, 16, 0x2D, sizeof(m_crcTrueHD));
View
2 xbmc/cores/VideoRenderers/BaseRenderer.cpp
@@ -276,7 +276,7 @@ inline void CBaseRenderer::ReorderDrawPoints()
}
- int diff = (m_destRect.Height() - m_destRect.Width()) / 2;
+ int diff = (int) ((m_destRect.Height() - m_destRect.Width()) / 2);
for (int destIdx=0, srcIdx=pointOffset; destIdx < 4; destIdx++)
{
View
3 xbmc/cores/dvdplayer/DVDInputStreams/DVDFactoryInputStream.cpp
@@ -66,7 +66,8 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IDVDPlayer* pPlayer,
|| file.substr(0, 6) == "tcp://"
|| file.substr(0, 6) == "mms://"
|| file.substr(0, 7) == "mmst://"
- || file.substr(0, 7) == "mmsh://")
+ || file.substr(0, 7) == "mmsh://"
+ || (item.IsInternetStream() && item.IsType(".m3u8")))
return new CDVDInputStreamFFmpeg();
else if(file.substr(0, 8) == "sling://"
|| file.substr(0, 7) == "myth://"
View
15 xbmc/cores/dvdplayer/DVDPlayer.cpp
@@ -78,6 +78,7 @@
#include "storage/MediaManager.h"
#include "dialogs/GUIDialogBusy.h"
#include "dialogs/GUIDialogKaiToast.h"
+#include "xbmc/playlists/PlayListM3U.h"
#include "utils/StringUtils.h"
#include "Util.h"
#include "LangInfo.h"
@@ -551,6 +552,18 @@ bool CDVDPlayer::OpenInputStream()
m_filename = g_mediaManager.TranslateDevicePath("");
}
retry:
+ // before creating the input stream, if this is an HLS playlist then get the
+ // most appropriate bitrate based on our network settings
+ if (filename.Left(7) == "http://" && filename.Right(5) == ".m3u8")
+ {
+ // get the available bandwidth (as per user settings)
+ int maxrate = g_guiSettings.GetInt("network.bandwidth");
+ if(maxrate <= 0)
+ maxrate = INT_MAX;
+
+ // determine the most appropriate stream
+ m_filename = PLAYLIST::CPlayListM3U::GetBestBandwidthStream(m_filename, (size_t)maxrate);
+ }
m_pInputStream = CDVDFactoryInputStream::CreateInputStream(this, m_filename, m_mimetype);
if(m_pInputStream == NULL)
{
@@ -2600,7 +2613,7 @@ float CDVDPlayer::GetPercentage()
float CDVDPlayer::GetCachePercentage()
{
CSingleLock lock(m_StateSection);
- return min(100.0, GetPercentage() + m_State.cache_offset * 100);
+ return m_State.cache_offset * 100; // NOTE: Percentage returned is relative
}
void CDVDPlayer::SetAVDelay(float fValue)
View
9 xbmc/dialogs/GUIDialogKeyboardGeneric.cpp
@@ -86,7 +86,7 @@ void CGUIDialogKeyboardGeneric::OnInitWindow()
}
// set heading
- if (!m_strHeading.IsEmpty())
+ if (!m_strHeading.empty())
{
SET_CONTROL_LABEL(CTL_LABEL_HEADING, m_strHeading);
SET_CONTROL_VISIBLE(CTL_LABEL_HEADING);
@@ -616,12 +616,9 @@ void CGUIDialogKeyboardGeneric::OnOK()
Close();
}
-void CGUIDialogKeyboardGeneric::SetHeading(const CVariant &heading)
+void CGUIDialogKeyboardGeneric::SetHeading(const std::string &heading)
{
- if (heading.isString())
- m_strHeading = heading.asString();
- else if (heading.isInteger() && heading.asInteger())
- m_strHeading = g_localizeStrings.Get((uint32_t)heading.asInteger());
+ m_strHeading = heading;
}
int CGUIDialogKeyboardGeneric::GetWindowId() const
View
4 xbmc/dialogs/GUIDialogKeyboardGeneric.h
@@ -38,7 +38,7 @@ class CGUIDialogKeyboardGeneric : public CGUIDialog, public CGUIKeyboard
//CGUIDialog Interface
virtual void FrameMove();
- void SetHeading(const CVariant& heading);
+ void SetHeading(const std::string& heading);
void SetText(const CStdString& aTextString);
CStdString GetText() const;
bool IsConfirmed() { return m_bIsConfirmed; };
@@ -78,7 +78,7 @@ class CGUIDialogKeyboardGeneric : public CGUIDialog, public CGUIKeyboard
unsigned int m_lastRemoteClickTime;
WORD m_lastRemoteKeyClicked;
int m_indexInSeries;
- CStdString m_strHeading;
+ std::string m_strHeading;
static const char* s_charsSeries[10];
View
2 xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp
@@ -496,6 +496,8 @@ bool CGUIDialogSmartPlaylistEditor::EditPlaylist(const CStdString &path, const C
}
editor->m_playlist = playlist;
+ if (editor->m_playlist.m_playlistRules.size() <= 0)
+ editor->m_playlist.m_playlistRules.push_back(CSmartPlaylistRule());
editor->m_path = path;
editor->Initialize();
editor->DoModal(g_windowManager.GetActiveWindow());
View
2 xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
@@ -135,7 +135,7 @@ void CGUIDialogSmartPlaylistRule::OnBrowse()
else if (m_rule.m_field == FieldArtist || m_rule.m_field == FieldAlbumArtist)
{
if (m_type.Equals("songs") || m_type.Equals("mixed") || m_type.Equals("albums"))
- database.GetArtistsNav("musicdb://2/",items,-1,m_rule.m_field == FieldAlbumArtist);
+ database.GetArtistsNav("musicdb://2/", items, m_rule.m_field == FieldAlbumArtist, -1);
if (m_type.Equals("musicvideos") || m_type.Equals("mixed"))
{
CFileItemList items2;
View
2 xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeArtist.cpp
@@ -56,7 +56,7 @@ bool CDirectoryNodeArtist::GetContent(CFileItemList& items) const
CQueryParams params;
CollectQueryParams(params);
- bool bSuccess = musicdatabase.GetArtistsNav(BuildPath(), items, params.GetGenreId(), !g_guiSettings.GetBool("musiclibrary.showcompilationartists"));
+ bool bSuccess = musicdatabase.GetArtistsNav(BuildPath(), items, !g_guiSettings.GetBool("musiclibrary.showcompilationartists"), params.GetGenreId());
musicdatabase.Close();
View
9 xbmc/guilib/GUIKeyboardFactory.cpp
@@ -78,6 +78,13 @@ bool CGUIKeyboardFactory::ShowAndGetInput(CStdString& aTextString, const CVarian
bool confirmed = false;
CGUIKeyboard *kb = NULL;
bool needsFreeing = true;
+ //heading can be a string or a localization id
+ std::string headingStr;
+ if (heading.isString())
+ headingStr = heading.asString();
+ else if (heading.isInteger() && heading.asInteger())
+ headingStr = g_localizeStrings.Get((uint32_t)heading.asInteger());
+
#if defined(TARGET_DARWIN_IOS) && !defined(TARGET_DARWIN_IOS_ATV2)
kb = new CIOSKeyboard();
#endif
@@ -88,7 +95,7 @@ bool CGUIKeyboardFactory::ShowAndGetInput(CStdString& aTextString, const CVarian
needsFreeing = false;
}
- confirmed = kb->ShowAndGetInput(keyTypedCB, aTextString, aTextString, heading.asString(), hiddenInput);
+ confirmed = kb->ShowAndGetInput(keyTypedCB, aTextString, aTextString, headingStr, hiddenInput);
if(needsFreeing)
delete kb;
View
167 xbmc/guilib/Geometry.h
@@ -158,159 +158,32 @@ class CRect
std::vector<CRect> SubtractRect(CRect splitterRect)
{
- #define ADD_RECT_ABOVE_INTERSECTION(add) \
- { \
- add = CRect(x1, y1, x2, intersection.y1);\
- newRectaglesList.push_back(add);\
- }
- #define ADD_RECT_BELOW_INTERSECTION(add) \
- {\
- add = CRect(x1, intersection.y2, x2, y2);\
- newRectaglesList.push_back(add);\
- }
- #define ADD_RECT_LEFT_OF_INTERSECTION(add) \
- {\
- add = CRect(x1, intersection.y1, intersection.x1, intersection.y2);\
- newRectaglesList.push_back(add);\
- }
- #define ADD_RECT_RIGHT_OF_INTERSECTION(add) \
- {\
- add = CRect(intersection.x2, intersection.y1, x2, intersection.y2);\
- newRectaglesList.push_back(add);\
- }
-
std::vector<CRect> newRectaglesList;
CRect intersection = splitterRect.Intersect(*this);
if (!intersection.IsEmpty())
{
CRect add;
- // intersection rect upper edge
- if (intersection.y1 == y1) // y starts with baserect
- {
- // intersection rect lower edge
- if (intersection.y2 == y2) // y goes down to baserect
- {
- if (intersection.x1 == x1) // x starts with baserect
- {
- if (intersection.x2 == x2) // x ends with baserect
- { // result 100% covered
- // add nothing
- }
- else // x ends in baserect
- { // results in 1 rect
- ADD_RECT_RIGHT_OF_INTERSECTION(add);
- }
- }
- else // x starts in baserect
- {
- if (intersection.x2 == x2) // x ends with baserect
- { // results in 1 rect
- ADD_RECT_LEFT_OF_INTERSECTION(add);
- }
- else // x ends in baserect
- { //results in 2 rects
- ADD_RECT_LEFT_OF_INTERSECTION(add);
- ADD_RECT_RIGHT_OF_INTERSECTION(add);
- }
- }
- }
- else // y ends in baserect
- {
- if (intersection.x1 == x1) // x starts with baserect
- {
- if (intersection.x2 == x2) // x ends with baserect
- { //results in 1 rect, below intersection
- ADD_RECT_BELOW_INTERSECTION(add);
- }
- else // x ends in baserect
- { // results in 2 rects
- ADD_RECT_BELOW_INTERSECTION(add);
- ADD_RECT_RIGHT_OF_INTERSECTION(add);
- }
- }
- else // x starts in baserect
- {
- if (intersection.x2 == x2) // x ends with baserect
- { //results in 2 rects
- ADD_RECT_BELOW_INTERSECTION(add);
- ADD_RECT_LEFT_OF_INTERSECTION(add);
- }
- else // x ends in baserect
- { //results in 3 rects
- ADD_RECT_BELOW_INTERSECTION(add);
- ADD_RECT_LEFT_OF_INTERSECTION(add);
- ADD_RECT_RIGHT_OF_INTERSECTION(add);
- }
- }
- }
- }
- else // y starts in baserect
- {
- // intersection rect lower edge
- if (intersection.y2 == y2) // y goes down to baserect
- {
- if (intersection.x1 == x1) // xstarts with baserect
- {
- if (intersection.x2 == x2) // x ends with baserect
- { //results in 1 rect above intersection
- ADD_RECT_ABOVE_INTERSECTION(add);
- }
- else // x ends in baserect
- { // results in 2 rects
- ADD_RECT_ABOVE_INTERSECTION(add);
- ADD_RECT_RIGHT_OF_INTERSECTION(add);
- }
- }
- else // x starts in baserect
- {
- if (intersection.x2 == x2) // x ends with baserect
- { // results in 2 rects
- ADD_RECT_ABOVE_INTERSECTION(add);
- ADD_RECT_LEFT_OF_INTERSECTION(add);
- }
- else // x ends in baserect
- { // results in 3 rects
- ADD_RECT_ABOVE_INTERSECTION(add);
- ADD_RECT_LEFT_OF_INTERSECTION(add);
- ADD_RECT_RIGHT_OF_INTERSECTION(add);
- }
- }
- }
- else // y ends in baserect
- {
- if (intersection.x1 == x1) // x starts with baserect
- {
- if (intersection.x2 == x2) // x ends with baserect
- { // results in 2 rects
- ADD_RECT_ABOVE_INTERSECTION(add);
- ADD_RECT_BELOW_INTERSECTION(add);
- }
- else // x ends in baserect
- { // results in 3 rects
- ADD_RECT_ABOVE_INTERSECTION(add);
- ADD_RECT_BELOW_INTERSECTION(add);
- ADD_RECT_RIGHT_OF_INTERSECTION(add);
- }
- }
- else // x starts in baserect
- {
- if (intersection.x2 == x2) // x ends with baserect
- { // results in 3 rects
- ADD_RECT_ABOVE_INTERSECTION(add);
- ADD_RECT_BELOW_INTERSECTION(add);
- ADD_RECT_LEFT_OF_INTERSECTION(add);
- }
- else // x ends in baserect
- { // results in 4 rects
- ADD_RECT_ABOVE_INTERSECTION(add);
- ADD_RECT_BELOW_INTERSECTION(add);
- ADD_RECT_LEFT_OF_INTERSECTION(add);
- ADD_RECT_RIGHT_OF_INTERSECTION(add);
- }
- }
- }
- }
+
+ // add rect above intersection if not empty
+ add = CRect(x1, y1, x2, intersection.y1);
+ if (!add.IsEmpty())
+ newRectaglesList.push_back(add);
+
+ // add rect below intersection if not empty
+ add = CRect(x1, intersection.y2, x2, y2);
+ if (!add.IsEmpty())
+ newRectaglesList.push_back(add);
+
+ // add rect left intersection if not empty
+ add = CRect(x1, intersection.y1, intersection.x1, intersection.y2);
+ if (!add.IsEmpty())
+ newRectaglesList.push_back(add);
+
+ // add rect right intersection if not empty
+ add = CRect(intersection.x2, intersection.y1, x2, intersection.y2);
+ if (!add.IsEmpty())
+ newRectaglesList.push_back(add);
}
else
{
View
14 xbmc/interfaces/Builtins.cpp
@@ -107,9 +107,9 @@ typedef struct
const BUILT_IN commands[] = {
{ "Help", false, "This help message" },
- { "Reboot", false, "Reboot the xbox (power cycle)" },
- { "Restart", false, "Restart the xbox (power cycle)" },
- { "ShutDown", false, "Shutdown the xbox" },
+ { "Reboot", false, "Reboot the system" },
+ { "Restart", false, "Restart the system (same as reboot)" },
+ { "ShutDown", false, "Shutdown the system" },
{ "Powerdown", false, "Powerdown system" },
{ "Quit", false, "Quit XBMC" },
{ "Hibernate", false, "Hibernates the system" },
@@ -118,7 +118,7 @@ const BUILT_IN commands[] = {
{ "AllowIdleShutdown", false, "Allow idle shutdown" },
{ "RestartApp", false, "Restart XBMC" },
{ "Minimize", false, "Minimize XBMC" },
- { "Reset", false, "Reset the xbox (warm reboot)" },
+ { "Reset", false, "Reset the system (same as reboot)" },
{ "Mastermode", false, "Control master mode" },
{ "ActivateWindow", true, "Activate the specified window" },
{ "ActivateWindowAndFocus", true, "Activate the specified window and sets focus to the specified id" },
@@ -251,7 +251,7 @@ int CBuiltins::Execute(const CStdString& execString)
CStdString parameter = params.size() ? params[0] : "";
CStdString strParameterCaseIntact = parameter;
- if (execute.Equals("reboot") || execute.Equals("restart")) //Will reboot the xbox, aka cold reboot
+ if (execute.Equals("reboot") || execute.Equals("restart") || execute.Equals("reset")) //Will reboot the system
{
CApplicationMessenger::Get().Restart();
}
@@ -324,10 +324,6 @@ int CBuiltins::Execute(const CStdString& execString)
{
CUtil::TakeScreenshot();
}
- else if (execute.Equals("reset")) //Will reset the xbox, aka soft reset
- {
- CApplicationMessenger::Get().Reset();
- }
else if (execute.Equals("activatewindow") || execute.Equals("replacewindow"))
{
// get the parameters
View
6 xbmc/interfaces/http-api/XBMChttp.cpp
@@ -2394,7 +2394,7 @@ int CXbmcHttp::xbmcSetFile(int numParas, CStdString paras[])
int CXbmcHttp::xbmcCopyFile(int numParas, CStdString paras[])
//parameter = srcFilename ; destFilename
-// both file names are relative to the XBox not the calling client
+// both file names are relative to the server, not the calling client
{
if (numParas<2)
return SetResponse(openTag+"Error:Missing parameter");
@@ -3002,8 +3002,8 @@ int CXbmcHttp::xbmcHelp()
{
CStdString output;
output="<p><b>XBMC HTTP API Commands</b></p><p>There are two alternative but equivalent syntax forms:</p>";
- output+="<p><b>Syntax 1: http://xbox/xbmcCmds/xbmcHttp?command=</b>command<b>&ampparameter=</b>first_parameter<b>;</b>second_parameter<b>;...</b></p>";
- output+="<p><b>Syntax 2: http://xbox/xbmcCmds/xbmcHttp?command=</b>command<b>(</b>first_parameter<b>;</b>second_parameter<b>;...</b><b>)</b></p>";
+ output+="<p><b>Syntax 1: http://xbmc-host/xbmcCmds/xbmcHttp?command=</b>command<b>&ampparameter=</b>first_parameter<b>;</b>second_parameter<b>;...</b></p>";
+ output+="<p><b>Syntax 2: http://xbmc-host/xbmcCmds/xbmcHttp?command=</b>command<b>(</b>first_parameter<b>;</b>second_parameter<b>;...</b><b>)</b></p>";
output+="<p>Note the use of the semi colon to separate multiple parameters.</p><p>The commands are case insensitive.</p>";
output+= "<p>The full documentation can be found here: <a href=\"http://wiki.xbmc.org/index.php?title=WebServerHTTP-API\">http://wiki.xbmc.org/index.php?title=WebServerHTTP-API</a></p>";
return SetResponse(output);
View
74 xbmc/interfaces/json-rpc/AudioLibrary.cpp
@@ -44,22 +44,35 @@ JSONRPC_STATUS CAudioLibrary::GetArtists(const CStdString &method, ITransportLay
if (!musicdatabase.Open())
return InternalError;
- int genreID = (int)parameterObject["genreid"].asInteger();
-
- // Add "artist" to "properties" array by default
- CVariant param = parameterObject;
- if (!param.isMember("properties"))
- param["properties"] = CVariant(CVariant::VariantTypeArray);
- param["properties"].append("artist");
+ CMusicDbUrl musicUrl;
+ musicUrl.FromString("musicdb://2/");
+ int genreID = -1, albumID = -1, songID = -1;
+ const CVariant &filter = parameterObject["filter"];
+ if (filter.isMember("genreid"))
+ genreID = (int)filter["genreid"].asInteger();
+ if (filter.isMember("genre"))
+ musicUrl.AddOption("genre", filter["genre"].asString());
+ if (filter.isMember("albumid"))
+ albumID = (int)filter["albumid"].asInteger();
+ if (filter.isMember("album"))
+ musicUrl.AddOption("album", filter["album"].asString());
+ if (filter.isMember("songid"))
+ songID = (int)filter["songid"].asInteger();
bool albumArtistsOnly = !g_guiSettings.GetBool("musiclibrary.showcompilationartists");
if (parameterObject["albumartistsonly"].isBoolean())
albumArtistsOnly = parameterObject["albumartistsonly"].asBoolean();
CFileItemList items;
- if (!musicdatabase.GetArtistsNav("musicdb://2/", items, genreID, albumArtistsOnly))
+ if (!musicdatabase.GetArtistsNav(musicUrl.ToString(), items, albumArtistsOnly, genreID, albumID, songID))
return InternalError;
+ // Add "artist" to "properties" array by default
+ CVariant param = parameterObject;
+ if (!param.isMember("properties"))
+ param["properties"] = CVariant(CVariant::VariantTypeArray);
+ param["properties"].append("artist");
+
HandleFileItemList("artistid", false, "artists", items, param, result);
return OK;
}
@@ -83,7 +96,13 @@ JSONRPC_STATUS CAudioLibrary::GetArtistDetails(const CStdString &method, ITransp
if (!musicdatabase.GetArtistsByWhere(musicUrl.ToString(), filter, items) || items.Size() != 1)
return InvalidParams;
- HandleFileItem("artistid", false, "artistdetails", items[0], parameterObject, parameterObject["properties"], result, false);
+ // Add "artist" to "properties" array by default
+ CVariant param = parameterObject;
+ if (!param.isMember("properties"))
+ param["properties"] = CVariant(CVariant::VariantTypeArray);
+ param["properties"].append("artist");
+
+ HandleFileItem("artistid", false, "artistdetails", items[0], parameterObject, param["properties"], result, false);
return OK;
}
@@ -93,16 +112,26 @@ JSONRPC_STATUS CAudioLibrary::GetAlbums(const CStdString &method, ITransportLaye
if (!musicdatabase.Open())
return InternalError;
- int artistID = (int)parameterObject["artistid"].asInteger();
- int genreID = (int)parameterObject["genreid"].asInteger();
+ CMusicDbUrl musicUrl;
+ musicUrl.FromString("musicdb://3/");
+ int artistID = -1, genreID = -1;
+ const CVariant &filter = parameterObject["filter"];
+ if (filter.isMember("artistid"))
+ artistID = (int)filter["artistid"].asInteger();
+ if (filter.isMember("artist"))
+ musicUrl.AddOption("artist", filter["artist"].asString());
+ if (filter.isMember("genreid"))
+ genreID = (int)filter["genreid"].asInteger();
+ if (filter.isMember("genre"))
+ musicUrl.AddOption("genre", filter["genre"].asString());
SortDescription sorting;
ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
return InvalidParams;
CFileItemList items;
- if (!musicdatabase.GetAlbumsNav("musicdb://3/", items, genreID, artistID, sorting))
+ if (!musicdatabase.GetAlbumsNav(musicUrl.ToString(), items, genreID, artistID, sorting))
return InternalError;
int size = items.Size();
@@ -142,17 +171,30 @@ JSONRPC_STATUS CAudioLibrary::GetSongs(const CStdString &method, ITransportLayer
if (!musicdatabase.Open())
return InternalError;
- int artistID = (int)parameterObject["artistid"].asInteger();
- int albumID = (int)parameterObject["albumid"].asInteger();
- int genreID = (int)parameterObject["genreid"].asInteger();
+ CMusicDbUrl musicUrl;
+ musicUrl.FromString("musicdb://4/");
+ int genreID = -1, albumID = -1, artistID = -1;
+ const CVariant &filter = parameterObject["filter"];
+ if (filter.isMember("artistid"))
+ artistID = (int)filter["artistid"].asInteger();
+ if (filter.isMember("artist"))
+ musicUrl.AddOption("artist", filter["artist"].asString());
+ if (filter.isMember("genreid"))
+ genreID = (int)filter["genreid"].asInteger();
+ if (filter.isMember("genre"))
+ musicUrl.AddOption("genre", filter["genre"].asString());
+ if (filter.isMember("albumid"))
+ albumID = (int)filter["albumid"].asInteger();
+ if (filter.isMember("album"))
+ musicUrl.AddOption("album", filter["album"].asString());
SortDescription sorting;
ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
return InvalidParams;
CFileItemList items;
- if (!musicdatabase.GetSongsNav("musicdb://4/", items, genreID, artistID, albumID, sorting))
+ if (!musicdatabase.GetSongsNav(musicUrl.ToString(), items, genreID, artistID, albumID, sorting))
return InternalError;
int size = items.Size();
View
6 xbmc/interfaces/json-rpc/FileItemHandler.cpp
@@ -67,25 +67,23 @@ void CFileItemHandler::FillDetails(ISerializable* info, CFileItemPtr item, const
result["albumlabel"] = item->GetProperty("album_label");
continue;
}
- /* This would break backwards compatibility to JSON-RPC API v4
if (item->HasProperty("album_" + field + "_array"))
{
result[field] = item->GetProperty("album_" + field + "_array");
continue;
- }*/
+ }
if (item->HasProperty("album_" + field))
{
result[field] = item->GetProperty("album_" + field);
continue;
}
}
- /* This would break backwards compatibility to JSON-RPC API v4
if (item->HasProperty("artist_" + field + "_array"))
{
result[field] = item->GetProperty("artist_" + field + "_array");
continue;
- }*/
+ }
if (item->HasProperty("artist_" + field))
{
result[field] = item->GetProperty("artist_" + field);
View
190 xbmc/interfaces/json-rpc/ServiceDescription.h
@@ -32,15 +32,15 @@ namespace JSONRPC
"\"default\": null"
"}",
"\"Optional.String\": {"
- "\"type\": [ \"null\", \"string\" ], "
+ "\"type\": [ \"null\", \"string\" ],"
"\"default\": null"
"}",
"\"Optional.Integer\": {"
- "\"type\": [ \"null\", \"integer\" ], "
+ "\"type\": [ \"null\", \"integer\" ],"
"\"default\": null"
"}",
"\"Optional.Number\": {"
- "\"type\": [ \"null\", \"number\" ], "
+ "\"type\": [ \"null\", \"number\" ],"
"\"default\": null"
"}",
"\"Array.String\": {"
@@ -79,6 +79,8 @@ namespace JSONRPC
"\"System\": { \"type\": \"boolean\", \"required\": true },"
"\"VideoLibrary\": { \"type\": \"boolean\", \"required\": true },"
"\"AudioLibrary\": { \"type\": \"boolean\", \"required\": true },"
+ "\"Application\": { \"type\": \"boolean\", \"required\": true },"
+ "\"Input\": { \"type\": \"boolean\", \"required\": true },"
"\"Other\": { \"type\": \"boolean\", \"required\": true }"
"},"
"\"additionalProperties\": false"
@@ -364,14 +366,14 @@ namespace JSONRPC
"\"Audio.Details.Base\": {"
"\"extends\": \"Media.Details.Base\","
"\"properties\": {"
- "\"genre\": { \"type\": \"string\" }"
+ "\"genre\": { \"$ref\": \"Array.String\" }"
"}"
"}",
"\"Audio.Details.Media\": {"
"\"extends\": \"Audio.Details.Base\","
"\"properties\": {"
"\"title\": { \"type\": \"string\" },"
- "\"artist\": { \"type\": \"string\" },"
+ "\"artist\": { \"$ref\": \"Array.String\" },"
"\"year\": { \"type\": \"integer\" },"
"\"rating\": { \"type\": \"integer\" },"
"\"musicbrainzalbumid\": { \"type\": \"string\" },"
@@ -383,15 +385,15 @@ namespace JSONRPC
"\"properties\": {"
"\"artistid\": { \"$ref\": \"Library.Id\", \"required\": true },"
"\"artist\": { \"type\": \"string\", \"required\": true },"
- "\"instrument\": { \"type\": \"string\" },"
- "\"style\": { \"type\": \"string\" },"
- "\"mood\": { \"type\": \"string\" },"
+ "\"instrument\": { \"$ref\": \"Array.String\" },"
+ "\"style\": { \"$ref\": \"Array.String\" },"
+ "\"mood\": { \"$ref\": \"Array.String\" },"
"\"born\": { \"type\": \"string\" },"
"\"formed\": { \"type\": \"string\" },"
"\"description\": { \"type\": \"string\" },"
"\"died\": { \"type\": \"string\" },"
"\"disbanded\": { \"type\": \"string\" },"
- "\"yearsactive\": { \"type\": \"string\" },"
+ "\"yearsactive\": { \"$ref\": \"Array.String\" },"
"\"musicbrainzartistid\": { \"type\": \"string\" }"
"}"
"}",
@@ -400,20 +402,19 @@ namespace JSONRPC
"\"properties\": {"
"\"albumid\": { \"$ref\": \"Library.Id\", \"required\": true },"
"\"description\": { \"type\": \"string\" },"
- "\"theme\": { \"type\": \"string\" },"
- "\"mood\": { \"type\": \"string\" },"
- "\"style\": { \"type\": \"string\" },"
+ "\"theme\": { \"$ref\": \"Array.String\" },"
+ "\"mood\": { \"$ref\": \"Array.String\" },"
+ "\"style\": { \"$ref\": \"Array.String\" },"
"\"type\": { \"type\": \"string\" },"
- "\"albumlabel\": { \"type\": \"string\" },"
- "\"artistid\": { \"$ref\": \"Library.Id\" }"
+ "\"albumlabel\": { \"type\": \"string\" }"
"}"
"}",
"\"Audio.Details.Song\": {"
"\"extends\": \"Audio.Details.Media\","
"\"properties\": {"
"\"songid\": { \"$ref\": \"Library.Id\", \"required\": true },"
"\"file\": { \"type\": \"string\" },"
- "\"albumartist\": { \"type\": \"string\" },"
+ "\"albumartist\": { \"$ref\": \"Array.String\" },"
"\"album\": { \"type\": \"string\" },"
"\"track\": { \"type\": \"integer\" },"
"\"duration\": { \"type\": \"integer\" },"
@@ -422,7 +423,6 @@ namespace JSONRPC
"\"playcount\": { \"type\": \"integer\" },"
"\"musicbrainztrackid\": { \"type\": \"string\" },"
"\"musicbrainzartistid\": { \"type\": \"string\" },"
- "\"artistid\": { \"$ref\": \"Library.Id\" },"
"\"albumid\": { \"$ref\": \"Library.Id\" },"
"\"lastplayed\": { \"type\": \"string\" },"
"\"disc\": { \"type\": \"integer\" }"
@@ -431,13 +431,13 @@ namespace JSONRPC
"\"Video.Fields.Movie\": {"
"\"extends\": \"Item.Fields.Base\","
"\"items\": { \"type\": \"string\","
- "\"description\": \"Requesting the cast, set, showlink and/or resume field will result in increased response times\","
+ "\"description\": \"Requesting the cast, showlink and/or resume field will result in increased response times\","
"\"enum\": [ \"title\", \"genre\", \"year\", \"rating\", \"director\", \"trailer\","
"\"tagline\", \"plot\", \"plotoutline\", \"originaltitle\", \"lastplayed\","
"\"playcount\", \"writer\", \"studio\", \"mpaa\", \"cast\", \"country\","
- "\"imdbnumber\", \"premiered\", \"productioncode\", \"runtime\", \"set\","
- "\"showlink\", \"streamdetails\", \"top250\", \"votes\", \"fanart\","
- "\"thumbnail\", \"file\", \"sorttitle\", \"resume\", \"setid\", \"dateadded\" ]"
+ "\"imdbnumber\", \"runtime\", \"set\", \"showlink\", \"streamdetails\","
+ "\"top250\", \"votes\", \"fanart\", \"thumbnail\", \"file\", \"sorttitle\","
+ "\"resume\", \"setid\", \"dateadded\", \"tag\" ]"
"}"
"}",
"\"Video.Fields.MovieSet\": {"
@@ -566,7 +566,7 @@ namespace JSONRPC
"\"extends\": \"Video.Details.Item\","
"\"properties\": {"
"\"runtime\": { \"type\": \"string\" },"
- "\"director\": { \"type\": \"string\" },"
+ "\"director\": { \"$ref\": \"Array.String\" },"
"\"streamdetails\": { \"$ref\": \"Video.Streams\" },"
"\"resume\": { \"$ref\": \"Video.Resume\" }"
"}"
@@ -575,27 +575,26 @@ namespace JSONRPC
"\"extends\": \"Video.Details.File\","
"\"properties\": {"
"\"movieid\": { \"$ref\": \"Library.Id\", \"required\": true },"
- "\"genre\": { \"type\": \"string\" },"
+ "\"genre\": { \"$ref\": \"Array.String\" },"
"\"year\": { \"type\": \"integer\" },"
"\"rating\": { \"type\": \"number\" },"
"\"trailer\": { \"type\": \"string\" },"
"\"tagline\": { \"type\": \"string\" },"
"\"plotoutline\": { \"type\": \"string\" },"
"\"originaltitle\": { \"type\": \"string\" },"
"\"sorttitle\": { \"type\": \"string\" },"
- "\"writer\": { \"type\": \"string\" },"
- "\"studio\": { \"type\": \"string\" },"
+ "\"writer\": { \"$ref\": \"Array.String\" },"
+ "\"studio\": { \"$ref\": \"Array.String\" },"
"\"mpaa\": { \"type\": \"string\" },"
"\"cast\": { \"$ref\": \"Video.Cast\" },"
- "\"country\": { \"type\": \"string\" },"
+ "\"country\": { \"$ref\": \"Array.String\" },"
"\"imdbnumber\": { \"type\": \"string\" },"
- "\"premiered\": { \"type\": \"string\" },"
- "\"productioncode\": { \"type\": \"string\" },"
- "\"set\": { \"$ref\": \"Array.String\" },"
- "\"showlink\": { \"type\": \"string\" },"
+ "\"set\": { \"type\": \"string\" },"
+ "\"showlink\": { \"$ref\": \"Array.String\" },"
"\"top250\": { \"type\": \"integer\" },"
"\"votes\": { \"type\": \"string\" },"
- "\"setid\": { \"$ref\": \"Array.Integer\" }"
+ "\"setid\": { \"$ref\": \"Library.Id\" },"
+ "\"tag\": { \"$ref\": \"Array.String\" }"
"}"
"}",
"\"Video.Details.MovieSet\": {"
@@ -616,12 +615,12 @@ namespace JSONRPC
"\"extends\": \"Video.Details.Item\","
"\"properties\": {"
"\"tvshowid\": { \"$ref\": \"Library.Id\", \"required\": true },"
- "\"genre\": { \"type\": \"string\" },"
+ "\"genre\": { \"$ref\": \"Array.String\" },"
"\"year\": { \"type\": \"integer\" },"
"\"rating\": { \"type\": \"number\" },"
"\"originaltitle\": { \"type\": \"string\" },"
"\"sorttitle\": { \"type\": \"string\" },"
- "\"studio\": { \"type\": \"string\" },"
+ "\"studio\": { \"$ref\": \"Array.String\" },"
"\"mpaa\": { \"type\": \"string\" },"
"\"cast\": { \"$ref\": \"Video.Cast\" },"
"\"episode\": { \"type\": \"integer\" },"
@@ -649,7 +648,7 @@ namespace JSONRPC
"\"episodeid\": { \"$ref\": \"Library.Id\", \"required\": true },"
"\"votes\": { \"type\": \"string\" },"
"\"rating\": { \"type\": \"number\" },"
- "\"writer\": { \"type\": \"string\" },"
+ "\"writer\": { \"$ref\": \"Array.String\" },"
"\"firstaired\": { \"type\": \"string\" },"
"\"productioncode\": { \"type\": \"string\" },"
"\"season\": { \"type\": \"integer\" },"
@@ -664,11 +663,11 @@ namespace JSONRPC
"\"extends\": \"Video.Details.File\","
"\"properties\": {"
"\"musicvideoid\": { \"$ref\": \"Library.Id\", \"required\": true },"
- "\"studio\": { \"type\": \"string\" },"
+ "\"studio\": { \"$ref\": \"Array.String\" },"
"\"year\": { \"type\": \"integer\" },"
"\"album\": { \"type\": \"string\" },"
- "\"artist\": { \"type\": \"string\" },"
- "\"genre\": { \"type\": \"string\" },"
+ "\"artist\": { \"$ref\": \"Array.String\" },"
+ "\"genre\": { \"$ref\": \"Array.String\" },"
"\"track\": { \"type\": \"integer\" }"
"}"
"}",
@@ -723,15 +722,15 @@ namespace JSONRPC
"\"runtime\", \"set\", \"showlink\", \"streamdetails\", \"top250\", \"votes\","
"\"firstaired\", \"season\", \"episode\", \"showtitle\", \"thumbnail\", \"file\","
"\"resume\", \"artistid\", \"albumid\", \"tvshowid\", \"setid\", \"watchedepisodes\","
- "\"disc\" ]"
+ "\"disc\", \"tag\" ]"
"}"
"}",
"\"List.Item.All\": {"
"\"extends\": [ \"Video.Details.File\", \"Audio.Details.Media\" ],"
"\"properties\": {"
"\"id\": { \"$ref\": \"Library.Id\" },"
"\"type\": { \"type\": \"string\", \"enum\": [ \"unknown\", \"movie\", \"episode\", \"musicvideo\", \"song\", \"picture\" ] },"
- "\"albumartist\": { \"type\": \"string\" },"
+ "\"albumartist\": { \"$ref\": \"Array.String\" },"
"\"album\": { \"type\": \"string\" },"
"\"track\": { \"type\": \"integer\" },"
"\"duration\": { \"type\": \"integer\" },"
@@ -743,28 +742,28 @@ namespace JSONRPC
"\"tagline\": { \"type\": \"string\" },"
"\"plotoutline\": { \"type\": \"string\" },"
"\"originaltitle\": { \"type\": \"string\" },"
- "\"writer\": { \"type\": \"string\" },"
- "\"studio\": { \"type\": \"string\" },"
+ "\"writer\": { \"$ref\": \"Array.String\" },"
+ "\"studio\": { \"$ref\": \"Array.String\" },"
"\"mpaa\": { \"type\": \"string\" },"
"\"cast\": { \"$ref\": \"Video.Cast\" },"
"\"country\": { \"type\": \"string\" },"
"\"imdbnumber\": { \"type\": \"string\" },"
"\"premiered\": { \"type\": \"string\" },"
"\"productioncode\": { \"type\": \"string\" },"
- "\"set\": { \"$ref\": \"Array.String\" },"
- "\"showlink\": { \"type\": \"string\" },"
+ "\"set\": { \"type\": \"string\" },"
+ "\"showlink\": { \"$ref\": \"Array.String\" },"
"\"top250\": { \"type\": \"integer\" },"
"\"votes\": { \"type\": \"string\" },"
"\"firstaired\": { \"type\": \"string\" },"
"\"season\": { \"type\": \"integer\" },"
"\"episode\": { \"type\": \"integer\" },"
"\"showtitle\": { \"type\": \"string\" },"
- "\"artistid\": { \"$ref\": \"Library.Id\" },"
"\"albumid\": { \"$ref\": \"Library.Id\" },"
- "\"setid\": { \"$ref\": \"Array.Integer\" },"
+ "\"setid\": { \"$ref\": \"Library.Id\" },"
"\"tvshowid\": { \"$ref\": \"Library.Id\" },"
"\"watchedepisodes\": { \"type\": \"integer\" },"
- "\"disc\": { \"type\": \"integer\" }"
+ "\"disc\": { \"type\": \"integer\" },"
+ "\"tag\": { \"$ref\": \"Array.String\" }"
"}"
"}",
"\"List.Fields.Files\": {"
@@ -944,7 +943,6 @@ namespace JSONRPC
"\"AudioLibrary\": { \"$ref\": \"Optional.Boolean\" },"
"\"VideoLibrary\": { \"$ref\": \"Optional.Boolean\" },"
"\"Application\": { \"$ref\": \"Optional.Boolean\" },"
- "\"Input\": { \"$ref\": \"Optional.Boolean\" },"
"\"Other\": { \"$ref\": \"Optional.Boolean\" }"
"}"
"}"
@@ -1455,10 +1453,18 @@ namespace JSONRPC
"\"permission\": \"ReadData\","
"\"params\": ["
"{ \"name\": \"albumartistsonly\", \"$ref\": \"Optional.Boolean\", \"description\": \"Whether or not to include artists only appearing in compilations. If the parameter is not passed or is passed as null the GUI setting will be used\" },"
- "{ \"name\": \"genreid\", \"$ref\": \"Library.Id\" },"
"{ \"name\": \"properties\", \"$ref\": \"Audio.Fields.Artist\" },"
"{ \"name\": \"limits\", \"$ref\": \"List.Limits\" },"
- "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
+ "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" },"
+ "{ \"name\": \"filter\","
+ "\"type\": ["
+ "{ \"type\": \"object\", \"properties\": { \"genreid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"genre\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"albumid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"album\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"songid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false }"
+ "]"
+ "}"
"],"
"\"returns\": {"
"\"type\": \"object\","
@@ -1491,11 +1497,17 @@ namespace JSONRPC
"\"transport\": \"Response\","
"\"permission\": \"ReadData\","
"\"params\": ["
- "{ \"name\": \"artistid\", \"$ref\": \"Library.Id\" },"
- "{ \"name\": \"genreid\", \"$ref\": \"Library.Id\" },"
"{ \"name\": \"properties\", \"$ref\": \"Audio.Fields.Album\" },"
"{ \"name\": \"limits\", \"$ref\": \"List.Limits\" },"
- "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
+ "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" },"
+ "{ \"name\": \"filter\","
+ "\"type\": ["
+ "{ \"type\": \"object\", \"properties\": { \"genreid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"genre\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"artistid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"artist\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false }"
+ "]"
+ "}"
"],"
"\"returns\": {"
"\"type\": \"object\","
@@ -1528,12 +1540,19 @@ namespace JSONRPC
"\"transport\": \"Response\","
"\"permission\": \"ReadData\","
"\"params\": ["
- "{ \"name\": \"artistid\", \"$ref\": \"Library.Id\" },"
- "{ \"name\": \"albumid\", \"$ref\": \"Library.Id\" },"
- "{ \"name\": \"genreid\", \"$ref\": \"Library.Id\" },"
"{ \"name\": \"properties\", \"$ref\": \"Audio.Fields.Song\" },"
"{ \"name\": \"limits\", \"$ref\": \"List.Limits\" },"
- "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
+ "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" },"
+ "{ \"name\": \"filter\","
+ "\"type\": ["
+ "{ \"type\": \"object\", \"properties\": { \"genreid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"genre\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"artistid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"artist\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"albumid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"album\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false }"
+ "]"
+ "}"
"],"
"\"returns\": {"
"\"type\": \"object\","
@@ -1777,7 +1796,21 @@ namespace JSONRPC
"\"params\": ["
"{ \"name\": \"properties\", \"$ref\": \"Video.Fields.Movie\" },"
"{ \"name\": \"limits\", \"$ref\": \"List.Limits\" },"
- "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
+ "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" },"
+ "{ \"name\": \"filter\","
+ "\"type\": ["
+ "{ \"type\": \"object\", \"properties\": { \"genreid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"genre\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"year\": { \"type\": \"integer\", \"minimum\": 0, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"actor\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"director\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"studio\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"country\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"setid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"set\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"tag\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false }"
+ "]"
+ "}"
"],"
"\"returns\": {"
"\"type\": \"object\","
@@ -1853,7 +1886,16 @@ namespace JSONRPC
"\"params\": ["
"{ \"name\": \"properties\", \"$ref\": \"Video.Fields.TVShow\" },"
"{ \"name\": \"limits\", \"$ref\": \"List.Limits\" },"
- "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
+ "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" },"
+ "{ \"name\": \"filter\","
+ "\"type\": ["
+ "{ \"type\": \"object\", \"properties\": { \"genreid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"genre\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"year\": { \"type\": \"integer\", \"minimum\": 0, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"actor\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"studio\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false }"
+ "]"
+ "}"
"],"
"\"returns\": { \"type\": \"object\","
"\"properties\": {"
@@ -1909,7 +1951,16 @@ namespace JSONRPC
"{ \"name\": \"season\", \"type\": \"integer\", \"minimum\": 0, \"default\": -1 },"
"{ \"name\": \"properties\", \"$ref\": \"Video.Fields.Episode\" },"
"{ \"name\": \"limits\", \"$ref\": \"List.Limits\" },"
- "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
+ "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" },"
+ "{ \"name\": \"filter\","
+ "\"type\": ["
+ "{ \"type\": \"object\", \"properties\": { \"genreid\": { \"$ref\": \"Library.Id\", \"required\": true, \"description\": \"Requires tvshowid to be set\" } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"genre\": { \"type\": \"string\", \"minLength\": 1, \"required\": true, \"description\": \"Requires tvshowid to be set\" } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"year\": { \"type\": \"integer\", \"minimum\": 0, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"actor\": { \"type\": \"string\", \"minLength\": 1, \"required\": true, \"description\": \"Requires tvshowid to be set\" } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"director\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false }"
+ "]"
+ "}"
"],"
"\"returns\": { \"type\": \"object\","
"\"properties\": {"
@@ -1941,11 +1992,19 @@ namespace JSONRPC
"\"transport\": \"Response\","
"\"permission\": \"ReadData\","
"\"params\": ["
- "{ \"name\": \"artistid\", \"$ref\": \"Library.Id\" },"
- "{ \"name\": \"albumid\", \"$ref\": \"Library.Id\" },"
"{ \"name\": \"properties\", \"$ref\": \"Video.Fields.MusicVideo\" },"
"{ \"name\": \"limits\", \"$ref\": \"List.Limits\" },"
- "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" }"
+ "{ \"name\": \"sort\", \"$ref\": \"List.Sort\" },"
+ "{ \"name\": \"filter\","
+ "\"type\": ["
+ "{ \"type\": \"object\", \"properties\": { \"artist\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"genreid\": { \"$ref\": \"Library.Id\", \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"genre\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"year\": { \"type\": \"integer\", \"minimum\": 0, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"director\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false },"
+ "{ \"type\": \"object\", \"properties\": { \"studio\": { \"type\": \"string\", \"minLength\": 1, \"required\": true } }, \"additionalProperties\": false }"
+ "]"
+ "}"
"],"
"\"returns\": { \"type\": \"object\","
"\"properties\": {"
@@ -2077,10 +2136,11 @@ namespace JSONRPC
"{ \"name\": \"country\", \"type\": [ \"null\", { \"$ref\": \"Array.String\", \"required\": true } ], \"default\": null },"
"{ \"name\": \"top250\", \"$ref\": \"Optional.Integer\" },"
"{ \"name\": \"sorttitle\", \"$ref\": \"Optional.String\" },"
- "{ \"name\": \"set\", \"type\": [ \"null\", { \"$ref\": \"Array.String\", \"required\": true } ], \"default\": null },"
+ "{ \"name\": \"set\", \"$ref\": \"Optional.String\" },"
"{ \"name\": \"showlink\", \"type\": [ \"null\", { \"$ref\": \"Array.String\", \"required\": true } ], \"default\": null },"
"{ \"name\": \"thumbnail\", \"$ref\": \"Optional.String\" },"
- "{ \"name\": \"fanart\", \"$ref\": \"Optional.String\" }"
+ "{ \"name\": \"fanart\", \"$ref\": \"Optional.String\" },"
+ "{ \"name\": \"tag\", \"type\": [ \"null\", { \"$ref\": \"Array.String\", \"required\": true } ], \"default\": null }"
"],"
"\"returns\": \"string\""
"}",
@@ -2612,7 +2672,7 @@ namespace JSONRPC
"\"description\": \"Playback of a media item has been stopped. If there is no ID available extra information will be provided.\","
"\"params\": ["
"{ \"name\": \"sender\", \"type\": \"string\", \"required\": true },"
- "{ \"name\": \"data\", \"type\": \"object\", \"required\": true, "
+ "{ \"name\": \"data\", \"type\": \"object\", \"required\": true,"
"\"properties\": {"
"\"item\": { \"$ref\": \"Player.Notifications.Item\" },"
"\"end\": { \"type\": \"boolean\", \"required\": true, \"description\": \"Whether the player has reached the end of the playable item(s) or not\" }"
@@ -2635,7 +2695,7 @@ namespace JSONRPC
"\"description\": \"The playback position has been changed. If there is no ID available extra information will be provided.\","
"\"params\": ["
"{ \"name\": \"sender\", \"type\": \"string\", \"required\": true },"
- "{ \"name\": \"data\", \"type\": \"object\", \"required\": true, "
+ "{ \"name\": \"data\", \"type\": \"object\", \"required\": true,"
"\"properties\": {"
"\"item\": { \"$ref\": \"Player.Notifications.Item\" },"
"\"player\": { \"$ref\": \"Player.Notifications.Player.Seek\", \"required\": true }"
View
125 xbmc/interfaces/json-rpc/VideoLibrary.cpp
@@ -33,12 +33,45 @@ JSONRPC_STATUS CVideoLibrary::GetMovies(const CStdString &method, ITransportLaye
if (!videodatabase.Open())
return InternalError;
+ SortDescription sorting;
+ ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
+ if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
+ return InvalidParams;
+
+ CVideoDbUrl videoUrl;
+ videoUrl.FromString("videodb://1/2/");
+ int genreID = -1, year = -1, setID = 0;
+ const CVariant &filter = parameterObject["filter"];
+ if (filter.isMember("genreid"))
+ genreID = (int)filter["genreid"].asInteger();
+ if (filter.isMember("genre"))
+ videoUrl.AddOption("genre", filter["genre"].asString());
+ if (filter.isMember("year"))
+ year = (int)filter["year"].asInteger();
+ if (filter.isMember("actor"))
+ videoUrl.AddOption("actor", filter["actor"].asString());
+ if (filter.isMember("director"))
+ videoUrl.AddOption("director", filter["director"].asString());
+ if (filter.isMember("studio"))
+ videoUrl.AddOption("studio", filter["studio"].asString());
+ if (filter.isMember("country"))
+ videoUrl.AddOption("country", filter["country"].asString());
+ if (filter.isMember("setid"))
+ setID = (int)filter["setid"].asInteger();
+ if (filter.isMember("set"))
+ videoUrl.AddOption("set", filter["set"].asString());
+ if (filter.isMember("tag"))
+ videoUrl.AddOption("tag", filter["tag"].asString());
+
+ // setID must not be -1 otherwise GetMoviesNav() will return sets
+ if (setID < 0)
+ setID = 0;
+
CFileItemList items;
- JSONRPC_STATUS ret = OK;
- if ((ret = GetVideos(MediaTypeMovie, "videodb://1/2/", parameterObject, items, result, videodatabase)) == OK)
- ret = GetAdditionalMovieDetails(parameterObject, items, result, videodatabase);
+ if (!videodatabase.GetMoviesNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, setID, -1, sorting))
+ return InvalidParams;
- return ret;
+ return GetAdditionalMovieDetails(parameterObject, items, result, videodatabase);
}
JSONRPC_STATUS CVideoLibrary::GetMovieDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
@@ -110,10 +143,29 @@ JSONRPC_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLay
if (!videodatabase.Open())
return InternalError;
+ SortDescription sorting;
+ ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
+ if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
+ return InvalidParams;
+
+ CVideoDbUrl videoUrl;
+ videoUrl.FromString("videodb://2/2/");
+ int genreID = -1, year = -1;
+ const CVariant &filter = parameterObject["filter"];
+ if (filter.isMember("genreid"))
+ genreID = (int)filter["genreid"].asInteger();
+ if (filter.isMember("genre"))
+ videoUrl.AddOption("genre", filter["genre"].asString());
+ if (filter.isMember("year"))
+ year = (int)filter["year"].asInteger();
+ if (filter.isMember("actor"))
+ videoUrl.AddOption("actor", filter["actor"].asString());
+ if (filter.isMember("studio"))
+ videoUrl.AddOption("studio", filter["studio"].asString());
+
CFileItemList items;
- JSONRPC_STATUS ret = OK;
- if ((ret = GetVideos(MediaTypeTvShow, "videodb://2/2/", parameterObject, items, result, videodatabase)) != OK)
- return ret;
+ if (!videodatabase.GetTvShowsNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, sorting))
+ return InvalidParams;
bool additionalInfo = false;
for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++)
@@ -134,7 +186,7 @@ JSONRPC_STATUS CVideoLibrary::GetTVShows(const CStdString &method, ITransportLay
size = (int)items.GetProperty("total").asInteger();
HandleFileItemList("tvshowid", true, "tvshows", items, parameterObject, result, size, false);
- return ret;
+ return OK;
}
JSONRPC_STATUS CVideoLibrary::GetTVShowDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
@@ -184,11 +236,30 @@ JSONRPC_STATUS CVideoLibrary::GetEpisodes(const CStdString &method, ITransportLa
int tvshowID = (int)parameterObject["tvshowid"].asInteger();
int season = (int)parameterObject["season"].asInteger();
-
+
CStdString strPath;
strPath.Format("videodb://2/2/%i/%i/", tvshowID, season);
+
+ CVideoDbUrl videoUrl;
+ videoUrl.FromString(strPath);
+ int genreID = -1, year = -1;
+ const CVariant &filter = parameterObject["filter"];
+ if (filter.isMember("genreid"))
+ genreID = (int)filter["genreid"].asInteger();
+ if (filter.isMember("genre"))
+ videoUrl.AddOption("genre", filter["genre"].asString());
+ if (filter.isMember("year"))
+ year = (int)filter["year"].asInteger();
+ if (filter.isMember("actor"))
+ videoUrl.AddOption("actor", filter["actor"].asString());
+ if (filter.isMember("director"))
+ videoUrl.AddOption("director", filter["director"].asString());
+
+ if (tvshowID <= 0 && (genreID > 0 || filter.isMember("actor")))
+ return InvalidParams;
+
CFileItemList items;
- if (!videodatabase.GetEpisodesNav(strPath, items, -1, -1, -1, -1, tvshowID, season, sorting))
+ if (!videodatabase.GetEpisodesNav(videoUrl.ToString(), items, genreID, year, -1, -1, tvshowID, season, sorting))
return InternalError;
return GetAdditionalEpisodeDetails(parameterObject, items, result, videodatabase);
@@ -240,11 +311,25 @@ JSONRPC_STATUS CVideoLibrary::GetMusicVideos(const CStdString &method, ITranspor
if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
return InvalidParams;
- int artistID = (int)parameterObject["artistid"].asInteger();
- int albumID = (int)parameterObject["albumid"].asInteger();
+ CVideoDbUrl videoUrl;
+ videoUrl.FromString("videodb://3/2/");
+ int genreID = -1, year = -1;
+ const CVariant &filter = parameterObject["filter"];
+ if (filter.isMember("artist"))
+ videoUrl.AddOption("artist", filter["artist"].asString());
+ if (filter.isMember("genreid"))
+ genreID = (int)filter["genreid"].asInteger();
+ if (filter.isMember("genre"))
+ videoUrl.AddOption("genre", filter["genre"].asString());
+ if (filter.isMember("year"))
+ year = (int)filter["year"].asInteger();
+ if (filter.isMember("director"))
+ videoUrl.AddOption("director", filter["director"].asString());
+ if (filter.isMember("studio"))
+ videoUrl.AddOption("studio", filter["studio"].asString());
CFileItemList items;
- if (!videodatabase.GetMusicVideosNav("videodb://3/2/", items, -1, -1, artistID, -1, -1, albumID, sorting))
+ if (!videodatabase.GetMusicVideosNav(videoUrl.ToString(), items, genreID, year, -1, -1, -1, -1, sorting))
return InternalError;
return GetAdditionalMusicVideoDetails(parameterObject, items, result, videodatabase);
@@ -630,16 +715,6 @@ bool CVideoLibrary::FillFileItemList(const CVariant &parameterObject, CFileItemL
return success;
}
-JSONRPC_STATUS CVideoLibrary::GetVideos(MediaType mediaType, const CStdString &strBaseDir, const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase)
-{
- SortDescription sorting;
- ParseLimits(parameterObject, sorting.limitStart, sorting.limitEnd);
- if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes))
- return InvalidParams;
-
- return videodatabase.GetSortedVideos(mediaType, strBaseDir, sorting, items) ? OK : InternalError;
-}
-
JSONRPC_STATUS CVideoLibrary::GetAdditionalMovieDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase)
{
if (!videodatabase.Open())
@@ -825,11 +900,13 @@ void CVideoLibrary::UpdateVideoTag(const CVariant &parameterObject, CVideoInfoTa
if (ParameterNotNull(parameterObject, "episodeguide"))
details.m_strEpisodeGuide = parameterObject["episodeguide"].asString();
if (ParameterNotNull(parameterObject, "set"))
- CopyStringArray(parameterObject["set"], details.m_set);
+ details.m_strSet = parameterObject["set"].asString();
if (ParameterNotNull(parameterObject, "showlink"))
CopyStringArray(parameterObject["showlink"], details.m_showLink);
if (ParameterNotNull(parameterObject, "thumbnail"))
artwork["thumb"] = parameterObject["thumbnail"].asString();
if (ParameterNotNull(parameterObject, "fanart"))
artwork["fanart"] = parameterObject["fanart"].asString();
+ if (ParameterNotNull(parameterObject, "tag"))
+ CopyStringArray(parameterObject["tag"], details.m_tags);
}
View
1 xbmc/interfaces/json-rpc/VideoLibrary.h
@@ -70,7 +70,6 @@ namespace JSONRPC
static bool FillFileItemList(const CVariant &parameterObject, CFileItemList &list);
private:
- static JSONRPC_STATUS GetVideos(MediaType mediaType, const CStdString &strBaseDir, const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
static JSONRPC_STATUS GetAdditionalMovieDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
static JSONRPC_STATUS GetAdditionalEpisodeDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
static JSONRPC_STATUS GetAdditionalMusicVideoDetails(const CVariant &parameterObject, CFileItemList &items, CVariant &result, CVideoDatabase &videodatabase);
View
96 xbmc/interfaces/json-rpc/methods.json
@@ -589,10 +589,18 @@
"permission": "ReadData",
"params": [
{ "name": "albumartistsonly", "$ref": "Optional.Boolean", "description": "Whether or not to include artists only appearing in compilations. If the parameter is not passed or is passed as null the GUI setting will be used" },
- { "name": "genreid", "$ref": "Library.Id" },
{ "name": "properties", "$ref": "Audio.Fields.Artist" },
{ "name": "limits", "$ref": "List.Limits" },
- { "name": "sort", "$ref": "List.Sort" }
+ { "name": "sort", "$ref": "List.Sort" },
+ { "name": "filter",
+ "type": [
+ { "type": "object", "properties": { "genreid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "genre": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "albumid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "album": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "songid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false }
+ ]
+ }
],
"returns": {
"type": "object",
@@ -625,11 +633,17 @@
"transport": "Response",
"permission": "ReadData",
"params": [
- { "name": "artistid", "$ref": "Library.Id" },
- { "name": "genreid", "$ref": "Library.Id" },
{ "name": "properties", "$ref": "Audio.Fields.Album" },
{ "name": "limits", "$ref": "List.Limits" },
- { "name": "sort", "$ref": "List.Sort" }
+ { "name": "sort", "$ref": "List.Sort" },
+ { "name": "filter",
+ "type": [
+ { "type": "object", "properties": { "genreid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "genre": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "artistid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "artist": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false }
+ ]
+ }
],
"returns": {
"type": "object",
@@ -662,12 +676,19 @@
"transport": "Response",
"permission": "ReadData",
"params": [
- { "name": "artistid", "$ref": "Library.Id" },
- { "name": "albumid", "$ref": "Library.Id" },
- { "name": "genreid", "$ref": "Library.Id" },
{ "name": "properties", "$ref": "Audio.Fields.Song" },
{ "name": "limits", "$ref": "List.Limits" },
- { "name": "sort", "$ref": "List.Sort" }
+ { "name": "sort", "$ref": "List.Sort" },
+ { "name": "filter",
+ "type": [
+ { "type": "object", "properties": { "genreid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "genre": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "artistid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "artist": { "type": "string", "minLength": 1, "required": true } }, "additionalProperties": false },
+ { "type": "object", "properties": { "albumid": { "$ref": "Library.Id", "required": true } }, "additionalProperties": false },
+ { "type": "object