Skip to content

Commit

Permalink
jsonrpc: add Addons namespace with GetAddons, GetAddonDetails, SetAdd…
Browse files Browse the repository at this point in the history
…onEnabled and ExecuteAddon
  • Loading branch information
Montellese committed Oct 2, 2012
1 parent 269b42f commit 592fb3e
Show file tree
Hide file tree
Showing 13 changed files with 562 additions and 8 deletions.
2 changes: 2 additions & 0 deletions project/VS2010Express/XBMC.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,7 @@
<ClCompile Include="..\..\xbmc\interfaces\http-api\XBMChttp.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\info\InfoBool.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\info\SkinVariable.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\json-rpc\AddonsOperations.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\json-rpc\ApplicationOperations.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\json-rpc\AudioLibrary.cpp" />
<ClCompile Include="..\..\xbmc\interfaces\json-rpc\FileItemHandler.cpp" />
Expand Down Expand Up @@ -1194,6 +1195,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Testsuite|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release (DirectX)|Win32'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\xbmc\interfaces\json-rpc\AddonsOperations.h" />
<ClCompile Include="..\..\xbmc\ThumbLoader.cpp" />
<ClCompile Include="..\..\xbmc\ThumbnailCache.cpp" />
<ClCompile Include="..\..\xbmc\URL.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions project/VS2010Express/XBMC.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -2933,6 +2933,9 @@
<ClCompile Include="..\..\xbmc\interfaces\python\test\TestSwig.cpp">
<Filter>interfaces\python\test</Filter>
</ClCompile>
<ClCompile Include="..\..\xbmc\interfaces\json-rpc\AddonsOperations.cpp">
<Filter>interfaces\json-rpc</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\xbmc\win32\pch.h">
Expand Down Expand Up @@ -5740,6 +5743,9 @@
<ClInclude Include="..\..\xbmc\music\tags\MusicInfoTagLoaderWav.h">
<Filter>music\tags</Filter>
</ClInclude>
<ClInclude Include="..\..\xbmc\interfaces\json-rpc\AddonsOperations.h">
<Filter>interfaces\json-rpc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc">
Expand Down
54 changes: 54 additions & 0 deletions xbmc/addons/Addon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,60 @@ AddonProps::AddonProps(const cp_plugin_info_t *plugin)
BuildDependencies(plugin);
}

void AddonProps::Serialize(CVariant &variant)
{
variant["addonid"] = id;
variant["type"] = TranslateType(type);
variant["version"] = version.c_str();
variant["minversion"] = minversion.c_str();
variant["name"] = name;
variant["parent"] = parent;
variant["license"] = license;
variant["summary"] = summary;
variant["description"] = description;
variant["path"] = path;
variant["libname"] = libname;
variant["author"] = author;
variant["source"] = source;

if (CURL::IsFullPath(icon))
variant["icon"] = icon;
else
variant["icon"] = URIUtils::AddFileToFolder(path, icon);

variant["thumbnail"] = variant["icon"];
variant["disclaimer"] = disclaimer;
variant["changelog"] = changelog;

if (CURL::IsFullPath(fanart))
variant["fanart"] = fanart;
else
variant["fanart"] = URIUtils::AddFileToFolder(path, fanart);

variant["dependencies"] = CVariant(CVariant::VariantTypeArray);
for (ADDONDEPS::const_iterator it = dependencies.begin(); it != dependencies.end(); it++)
{
CVariant dep(CVariant::VariantTypeObject);
dep["addonid"] = it->first;
dep["version"] = it->second.first.c_str();
dep["optional"] = it->second.second;
variant["dependencies"].push_back(dep);
}
if (broken.empty())
variant["broken"] = false;
else
variant["broken"] = broken;
variant["extrainfo"] = CVariant(CVariant::VariantTypeArray);
for (InfoMap::const_iterator it = extrainfo.begin(); it != extrainfo.end(); it++)
{
CVariant info(CVariant::VariantTypeObject);
info["key"] = it->first;
info["value"] = it->second;
variant["extrainfo"].push_back(info);
}
variant["rating"] = stars;
}

void AddonProps::BuildDependencies(const cp_plugin_info_t *plugin)
{
if (!plugin)
Expand Down
5 changes: 4 additions & 1 deletion xbmc/addons/Addon.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "addons/AddonVersion.h"
#include "utils/XBMCTinyXML.h"
#include "guilib/LocalizeStrings.h"
#include "utils/ISerializable.h"

class TiXmlElement;
class CAddonCallbacksAddon;
Expand All @@ -42,7 +43,7 @@ const CStdString GetIcon(const TYPE &type);
const CStdString UpdateVideoScraper(const CStdString &scraper);
const CStdString UpdateMusicScraper(const CStdString &scraper);

class AddonProps
class AddonProps : public ISerializable
{
public:
AddonProps(const CStdString &id, TYPE type, const CStdString &versionstr, const CStdString &minversionstr)
Expand All @@ -63,6 +64,8 @@ class AddonProps
&& (*this).type == rhs.type
&& (*this).version == rhs.version;
}

void Serialize(CVariant &variant);

CStdString id;
TYPE type;
Expand Down
195 changes: 195 additions & 0 deletions xbmc/interfaces/json-rpc/AddonsOperations.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
* Copyright (C) 2011 Team XBMC
* http://www.xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/

#include "AddonsOperations.h"
#include "JSONUtils.h"
#include "addons/AddonManager.h"
#include "addons/AddonDatabase.h"
#include "ApplicationMessenger.h"
#include "TextureCache.h"

using namespace std;
using namespace JSONRPC;
using namespace ADDON;

JSONRPC_STATUS CAddonsOperations::GetAddons(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
TYPE addonType = TranslateType(parameterObject["type"].asString());
CVariant enabled = parameterObject["enabled"];
VECADDONS addons;
if (addonType == ADDON_UNKNOWN)
{
if (!enabled.isBoolean())
{
CAddonMgr::Get().GetAllAddons(addons, false);
CAddonMgr::Get().GetAllAddons(addons, true);
}
else
CAddonMgr::Get().GetAllAddons(addons, enabled.asBoolean());
}
else
{
if (!enabled.isBoolean())
{
CAddonMgr::Get().GetAddons(addonType, addons, false);
VECADDONS enabledAddons;
CAddonMgr::Get().GetAddons(addonType, enabledAddons, true);
addons.insert(addons.begin(), enabledAddons.begin(), enabledAddons.end());
}
else
CAddonMgr::Get().GetAddons(addonType, addons, enabled.asBoolean());
}

// remove library addons
for (int index = 0; index < (int)addons.size(); index++)
{
if (addons.at(index)->Type() <= ADDON_UNKNOWN || addons.at(index)->Type() >= ADDON_VIZ_LIBRARY)
{
addons.erase(addons.begin() + index);
index--;
}
}

int start, end;
HandleLimits(parameterObject, result, addons.size(), start, end);

CAddonDatabase addondb;
for (int index = start; index < end; index++)
FillDetails(addons.at(index), parameterObject["properties"], result["addons"], addondb, true);

return OK;
}

JSONRPC_STATUS CAddonsOperations::GetAddonDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
string id = parameterObject["addonid"].asString();
AddonPtr addon;
if (!CAddonMgr::Get().GetAddon(id, addon, ADDON::ADDON_UNKNOWN, false) || addon.get() == NULL ||
addon->Type() <= ADDON_UNKNOWN || addon->Type() >= ADDON_VIZ_LIBRARY)
return InvalidParams;

CAddonDatabase addondb;
FillDetails(addon, parameterObject["properties"], result["addon"], addondb);

return OK;
}

JSONRPC_STATUS CAddonsOperations::SetAddonEnabled(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
CAddonDatabase addondatabase;
if (!addondatabase.Open())
return InternalError;

string id = parameterObject["addonid"].asString();
bool disabled = false;
if (parameterObject["enabled"].isBoolean())
disabled = !parameterObject["enabled"].asBoolean();
// we need to toggle the current disabled state of the addon
else if (parameterObject["enabled"].isString())
disabled = !addondatabase.IsAddonDisabled(id);
else
return InvalidParams;

if (!addondatabase.DisableAddon(id, disabled))
return InvalidParams;

return ACK;
}

JSONRPC_STATUS CAddonsOperations::ExecuteAddon(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
string id = parameterObject["addonid"].asString();
AddonPtr addon;
if (!CAddonMgr::Get().GetAddon(id, addon) || addon.get() == NULL ||
addon->Type() < ADDON_VIZ || addon->Type() >= ADDON_VIZ_LIBRARY)
return InvalidParams;

string argv;
CVariant params = parameterObject["params"];
if (params.isObject())
{
for (CVariant::const_iterator_map it = params.begin_map(); it != params.end_map(); it++)
argv += it->first + "=" + it->second.asString() + ",";
argv = argv.erase(argv.size() - 1);
}
else if (params.isArray())
{
for (CVariant::const_iterator_array it = params.begin_array(); it != params.end_array(); it++)
argv += it->asString() + ",";
argv = argv.erase(argv.size() - 1);
}

CStdString cmd;
if (params.size() == 0)
cmd.Format("RunAddon(%s)", id.c_str());
else
cmd.Format("RunAddon(%s, %s)", id.c_str(), argv.c_str());
CApplicationMessenger::Get().ExecBuiltIn(cmd, parameterObject["wait"].asBoolean());

return ACK;
}

void CAddonsOperations::FillDetails(AddonPtr addon, const CVariant& fields, CVariant &result, CAddonDatabase &addondb, bool append /* = false */)
{
if (addon.get() == NULL)
return;

CVariant addonInfo;
addon->Props().Serialize(addonInfo);

CVariant object;
object["addonid"] = addonInfo["addonid"];
object["type"] = addonInfo["type"];

for (unsigned int index = 0; index < fields.size(); index++)
{
string field = fields[index].asString();

// we need to manually retrieve the enabled state of every addon
// from the addon database because it can't be read from addon.xml
if (field == "enabled")
{
if (!addondb.IsOpen() && !addondb.Open())
return;
object[field] = !addondb.IsAddonDisabled(addon->ID());
}
else if (field == "fanart" || field == "thumbnail")
{
CStdString url = addonInfo[field].asString();
bool needsRecaching;
CStdString image = CTextureCache::Get().CheckCachedImage(url, false, needsRecaching);
if (image.empty())
image = CTextureCache::Get().CacheImage(url);

if (!image.empty())
object[field] = CTextureCache::Get().GetWrappedImageURL(url);
else
object[field] = "";
}
else if (addonInfo.isMember(field))
object[field] = addonInfo[field];
}

if (append)
result.append(object);
else
result = object;
}
43 changes: 43 additions & 0 deletions xbmc/interfaces/json-rpc/AddonsOperations.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once
/*
* Copyright (C) 2011 Team XBMC
* http://www.xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/

#include "utils/StdString.h"
#include "JSONRPC.h"
#include "addons/IAddon.h"

class CAddonDatabase;

namespace JSONRPC
{
class CAddonsOperations : public CJSONUtils
{
public:
static JSONRPC_STATUS GetAddons(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
static JSONRPC_STATUS GetAddonDetails(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);

static JSONRPC_STATUS SetAddonEnabled(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);
static JSONRPC_STATUS ExecuteAddon(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result);

private:
static void FillDetails(ADDON::AddonPtr addon, const CVariant& fields, CVariant &result, CAddonDatabase &addondb, bool append = false);
};
}
Loading

0 comments on commit 592fb3e

Please sign in to comment.