From 9d11b08ad61b1f0d6d7023ce403285d8662efaed Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 4 Mar 2015 00:23:39 +0100 Subject: sync with upstream --- xbmc/addons/Addon.cpp | 653 -------------------------------------------------- 1 file changed, 653 deletions(-) delete mode 100644 xbmc/addons/Addon.cpp (limited to 'xbmc/addons/Addon.cpp') diff --git a/xbmc/addons/Addon.cpp b/xbmc/addons/Addon.cpp deleted file mode 100644 index 2aa849f..0000000 --- a/xbmc/addons/Addon.cpp +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://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, see - * . - * - */ - -#include "Addon.h" -#include "AddonManager.h" -#include "settings/Settings.h" -#include "filesystem/Directory.h" -#include "filesystem/File.h" -#include "system.h" -#ifdef HAS_PYTHON -#include "interfaces/python/XBPython.h" -#endif -#if defined(TARGET_DARWIN) -#include "../osx/OSXGNUReplacements.h" -#endif -#ifdef TARGET_FREEBSD -#include "freebsd/FreeBSDGNUReplacements.h" -#endif -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "utils/URIUtils.h" -#include "URL.h" -#include "Util.h" -#include -#include -#include - -using XFILE::CDirectory; -using XFILE::CFile; -using namespace std; - -namespace ADDON -{ - -/** - * helper functions - * - */ - -typedef struct -{ - const char* name; - TYPE type; - int pretty; - const char* icon; -} TypeMapping; - -static const TypeMapping types[] = - {{"unknown", ADDON_UNKNOWN, 0, "" }, - {"xbmc.metadata.scraper.albums", ADDON_SCRAPER_ALBUMS, 24016, "DefaultAddonAlbumInfo.png" }, - {"xbmc.metadata.scraper.artists", ADDON_SCRAPER_ARTISTS, 24017, "DefaultAddonArtistInfo.png" }, - {"xbmc.metadata.scraper.movies", ADDON_SCRAPER_MOVIES, 24007, "DefaultAddonMovieInfo.png" }, - {"xbmc.metadata.scraper.musicvideos", ADDON_SCRAPER_MUSICVIDEOS, 24015, "DefaultAddonMusicVideoInfo.png" }, - {"xbmc.metadata.scraper.tvshows", ADDON_SCRAPER_TVSHOWS, 24014, "DefaultAddonTvInfo.png" }, - {"xbmc.metadata.scraper.library", ADDON_SCRAPER_LIBRARY, 24083, "DefaultAddonInfoLibrary.png" }, - {"xbmc.ui.screensaver", ADDON_SCREENSAVER, 24008, "DefaultAddonScreensaver.png" }, - {"xbmc.player.musicviz", ADDON_VIZ, 24010, "DefaultAddonVisualization.png" }, - {"visualization-library", ADDON_VIZ_LIBRARY, 24084, "" }, - {"xbmc.python.pluginsource", ADDON_PLUGIN, 24005, "" }, - {"xbmc.python.script", ADDON_SCRIPT, 24009, "" }, - {"xbmc.python.weather", ADDON_SCRIPT_WEATHER, 24027, "DefaultAddonWeather.png" }, - {"xbmc.python.lyrics", ADDON_SCRIPT_LYRICS, 24013, "DefaultAddonLyrics.png" }, - {"xbmc.python.library", ADDON_SCRIPT_LIBRARY, 24081, "DefaultAddonHelper.png" }, - {"xbmc.python.module", ADDON_SCRIPT_MODULE, 24082, "DefaultAddonLibrary.png" }, - {"xbmc.subtitle.module", ADDON_SUBTITLE_MODULE, 24012, "DefaultAddonSubtitles.png" }, - {"kodi.context.item", ADDON_CONTEXT_ITEM, 24025, "DefaultAddonContextItem.png" }, - {"xbmc.gui.skin", ADDON_SKIN, 166, "DefaultAddonSkin.png" }, - {"xbmc.webinterface", ADDON_WEB_INTERFACE, 199, "DefaultAddonWebSkin.png" }, - {"xbmc.addon.repository", ADDON_REPOSITORY, 24011, "DefaultAddonRepository.png" }, - {"xbmc.pvrclient", ADDON_PVRDLL, 24019, "DefaultAddonPVRClient.png" }, - {"xbmc.addon.video", ADDON_VIDEO, 1037, "DefaultAddonVideo.png" }, - {"xbmc.addon.audio", ADDON_AUDIO, 1038, "DefaultAddonMusic.png" }, - {"xbmc.addon.image", ADDON_IMAGE, 1039, "DefaultAddonPicture.png" }, - {"xbmc.addon.executable", ADDON_EXECUTABLE, 1043, "DefaultAddonProgram.png" }, - {"xbmc.audioencoder", ADDON_AUDIOENCODER, 200, "DefaultAddonAudioEncoder.png" }, - {"xbmc.service", ADDON_SERVICE, 24018, "DefaultAddonService.png" }}; - -const std::string TranslateType(const ADDON::TYPE &type, bool pretty/*=false*/) -{ - for (unsigned int index=0; index < ARRAY_SIZE(types); ++index) - { - const TypeMapping &map = types[index]; - if (type == map.type) - { - if (pretty && map.pretty) - return g_localizeStrings.Get(map.pretty); - else - return map.name; - } - } - return ""; -} - -TYPE TranslateType(const std::string &string) -{ - for (unsigned int index=0; index < ARRAY_SIZE(types); ++index) - { - const TypeMapping &map = types[index]; - if (string == map.name) - return map.type; - } - - return ADDON_UNKNOWN; -} - -const std::string GetIcon(const ADDON::TYPE& type) -{ - for (unsigned int index=0; index < ARRAY_SIZE(types); ++index) - { - const TypeMapping &map = types[index]; - if (type == map.type) - return map.icon; - } - return ""; -} - -#define EMPTY_IF(x,y) \ - { \ - std::string fan=CAddonMgr::Get().GetExtValue(metadata->configuration, x); \ - if (fan == "true") \ - y.clear(); \ - } - -#define SS(x) (x) ? x : "" - -AddonProps::AddonProps(const cp_extension_t *ext) - : id(SS(ext->plugin->identifier)) - , version(SS(ext->plugin->version)) - , minversion(SS(ext->plugin->abi_bw_compatibility)) - , name(SS(ext->plugin->name)) - , path(SS(ext->plugin->plugin_path)) - , author(SS(ext->plugin->provider_name)) - , stars(0) -{ - if (ext->ext_point_id) - type = TranslateType(ext->ext_point_id); - - icon = "icon.png"; - fanart = URIUtils::AddFileToFolder(path, "fanart.jpg"); - changelog = URIUtils::AddFileToFolder(path, "changelog.txt"); - // Grab more detail from the props... - const cp_extension_t *metadata = CAddonMgr::Get().GetExtension(ext->plugin, "xbmc.addon.metadata"); //plugin, "kodi.addon.metadata"); - if (metadata) - { - summary = CAddonMgr::Get().GetTranslatedString(metadata->configuration, "summary"); - description = CAddonMgr::Get().GetTranslatedString(metadata->configuration, "description"); - disclaimer = CAddonMgr::Get().GetTranslatedString(metadata->configuration, "disclaimer"); - license = CAddonMgr::Get().GetExtValue(metadata->configuration, "license"); - std::string language; - language = CAddonMgr::Get().GetExtValue(metadata->configuration, "language"); - if (!language.empty()) - extrainfo.insert(make_pair("language",language)); - broken = CAddonMgr::Get().GetExtValue(metadata->configuration, "broken"); - EMPTY_IF("nofanart",fanart) - EMPTY_IF("noicon",icon) - EMPTY_IF("nochangelog",changelog) - } - BuildDependencies(ext->plugin); -} - -AddonProps::AddonProps(const cp_plugin_info_t *plugin) - : id(SS(plugin->identifier)) - , type(ADDON_UNKNOWN) - , version(SS(plugin->version)) - , minversion(SS(plugin->abi_bw_compatibility)) - , name(SS(plugin->name)) - , path(SS(plugin->plugin_path)) - , author(SS(plugin->provider_name)) - , stars(0) -{ - BuildDependencies(plugin); -} - -void AddonProps::Serialize(CVariant &variant) const -{ - variant["addonid"] = id; - variant["type"] = TranslateType(type); - variant["version"] = version.asString(); - variant["minversion"] = minversion.asString(); - variant["name"] = name; - 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.asString(); - 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) - return; - for (unsigned int i = 0; i < plugin->num_imports; ++i) - dependencies.insert(make_pair(std::string(plugin->imports[i].plugin_id), - make_pair(AddonVersion(SS(plugin->imports[i].version)), plugin->imports[i].optional != 0))); -} - -/** - * CAddon - * - */ - -CAddon::CAddon(const cp_extension_t *ext) - : m_props(ext) -{ - BuildLibName(ext); - Props().libname = m_strLibName; - BuildProfilePath(); - m_userSettingsPath = URIUtils::AddFileToFolder(Profile(), "settings.xml"); - m_enabled = true; - m_hasSettings = true; - m_hasStrings = false; - m_checkedStrings = false; - m_settingsLoaded = false; - m_userSettingsLoaded = false; -} - -CAddon::CAddon(const cp_plugin_info_t *plugin) - : m_props(plugin) -{ - m_enabled = true; - m_hasSettings = false; - m_hasStrings = false; - m_checkedStrings = true; - m_settingsLoaded = false; - m_userSettingsLoaded = false; -} - -CAddon::CAddon(const AddonProps &props) - : m_props(props) -{ - if (props.libname.empty()) BuildLibName(); - else m_strLibName = props.libname; - BuildProfilePath(); - m_userSettingsPath = URIUtils::AddFileToFolder(Profile(), "settings.xml"); - m_enabled = true; - m_hasSettings = true; - m_hasStrings = false; - m_checkedStrings = false; - m_settingsLoaded = false; - m_userSettingsLoaded = false; -} - -CAddon::CAddon(const CAddon &rhs) - : m_props(rhs.Props()), - m_settings(rhs.m_settings) -{ - m_addonXmlDoc = rhs.m_addonXmlDoc; - m_settingsLoaded = rhs.m_settingsLoaded; - m_userSettingsLoaded = rhs.m_userSettingsLoaded; - m_hasSettings = rhs.m_hasSettings; - BuildProfilePath(); - m_userSettingsPath = URIUtils::AddFileToFolder(Profile(), "settings.xml"); - m_strLibName = rhs.m_strLibName; - m_enabled = rhs.Enabled(); - m_hasStrings = false; - m_checkedStrings = false; -} - -AddonPtr CAddon::Clone() const -{ - return AddonPtr(new CAddon(*this)); -} - -bool CAddon::MeetsVersion(const AddonVersion &version) const -{ - return m_props.minversion <= version && version <= m_props.version; -} - -//TODO platform/path crap should be negotiated between the addon and -// the handler for it's type -void CAddon::BuildLibName(const cp_extension_t *extension) -{ - if (!extension) - { - m_strLibName = "default"; - std::string ext; - switch (m_props.type) - { - case ADDON_SCRAPER_ALBUMS: - case ADDON_SCRAPER_ARTISTS: - case ADDON_SCRAPER_MOVIES: - case ADDON_SCRAPER_MUSICVIDEOS: - case ADDON_SCRAPER_TVSHOWS: - case ADDON_SCRAPER_LIBRARY: - ext = ADDON_SCRAPER_EXT; - break; - case ADDON_SCREENSAVER: - ext = ADDON_SCREENSAVER_EXT; - break; - case ADDON_SKIN: - m_strLibName = "skin.xml"; - return; - case ADDON_VIZ: - ext = ADDON_VIS_EXT; - break; - case ADDON_PVRDLL: - ext = ADDON_PVRDLL_EXT; - break; - case ADDON_SCRIPT: - case ADDON_SCRIPT_LIBRARY: - case ADDON_SCRIPT_LYRICS: - case ADDON_SCRIPT_WEATHER: - case ADDON_SUBTITLE_MODULE: - case ADDON_PLUGIN: - case ADDON_SERVICE: - case ADDON_CONTEXT_ITEM: - ext = ADDON_PYTHON_EXT; - break; - default: - m_strLibName.clear(); - return; - } - // extensions are returned as *.ext - // so remove the asterisk - ext.erase(0,1); - m_strLibName.append(ext); - } - else - { - switch (m_props.type) - { - case ADDON_SCREENSAVER: - case ADDON_SCRIPT: - case ADDON_SCRIPT_LIBRARY: - case ADDON_SCRIPT_LYRICS: - case ADDON_SCRIPT_WEATHER: - case ADDON_SCRIPT_MODULE: - case ADDON_SUBTITLE_MODULE: - case ADDON_SCRAPER_ALBUMS: - case ADDON_SCRAPER_ARTISTS: - case ADDON_SCRAPER_MOVIES: - case ADDON_SCRAPER_MUSICVIDEOS: - case ADDON_SCRAPER_TVSHOWS: - case ADDON_SCRAPER_LIBRARY: - case ADDON_PVRDLL: - case ADDON_PLUGIN: - case ADDON_WEB_INTERFACE: - case ADDON_SERVICE: - case ADDON_REPOSITORY: - case ADDON_AUDIOENCODER: - case ADDON_CONTEXT_ITEM: - { - std::string temp = CAddonMgr::Get().GetExtValue(extension->configuration, "@library"); - m_strLibName = temp; - } - break; - default: - m_strLibName.clear(); - break; - } - } -} - -/** - * Language File Handling - */ -bool CAddon::LoadStrings() -{ - // Path where the language strings reside - std::string chosenPath = URIUtils::AddFileToFolder(m_props.path, "resources/language/"); - - m_hasStrings = m_strings.Load(chosenPath, CSettings::Get().GetString("locale.language")); - return m_checkedStrings = true; -} - -void CAddon::ClearStrings() -{ - // Unload temporary language strings - m_strings.Clear(); - m_hasStrings = false; -} - -std::string CAddon::GetString(uint32_t id) -{ - if (!m_hasStrings && ! m_checkedStrings && !LoadStrings()) - return ""; - - return m_strings.Get(id); -} - -/** - * Settings Handling - */ -bool CAddon::HasSettings() -{ - return LoadSettings(); -} - -bool CAddon::LoadSettings(bool bForce /* = false*/) -{ - if (m_settingsLoaded && !bForce) - return true; - if (!m_hasSettings) - return false; - std::string addonFileName = URIUtils::AddFileToFolder(m_props.path, "resources/settings.xml"); - - if (!m_addonXmlDoc.LoadFile(addonFileName)) - { - if (CFile::Exists(addonFileName)) - CLog::Log(LOGERROR, "Unable to load: %s, Line %d\n%s", addonFileName.c_str(), m_addonXmlDoc.ErrorRow(), m_addonXmlDoc.ErrorDesc()); - m_hasSettings = false; - return false; - } - - // Make sure that the addon XML has the settings element - TiXmlElement *setting = m_addonXmlDoc.RootElement(); - if (!setting || strcmpi(setting->Value(), "settings") != 0) - { - CLog::Log(LOGERROR, "Error loading Settings %s: cannot find root element 'settings'", addonFileName.c_str()); - return false; - } - SettingsFromXML(m_addonXmlDoc, true); - LoadUserSettings(); - m_settingsLoaded = true; - return true; -} - -bool CAddon::HasUserSettings() -{ - if (!LoadSettings()) - return false; - - return m_userSettingsLoaded; -} - -bool CAddon::ReloadSettings() -{ - return LoadSettings(true); -} - -bool CAddon::LoadUserSettings() -{ - m_userSettingsLoaded = false; - CXBMCTinyXML doc; - if (doc.LoadFile(m_userSettingsPath)) - m_userSettingsLoaded = SettingsFromXML(doc); - return m_userSettingsLoaded; -} - -void CAddon::SaveSettings(void) -{ - if (m_settings.empty()) - return; // no settings to save - - // break down the path into directories - std::string strAddon = URIUtils::GetDirectory(m_userSettingsPath); - URIUtils::RemoveSlashAtEnd(strAddon); - std::string strRoot = URIUtils::GetDirectory(strAddon); - URIUtils::RemoveSlashAtEnd(strRoot); - - // create the individual folders - if (!CDirectory::Exists(strRoot)) - CDirectory::Create(strRoot); - if (!CDirectory::Exists(strAddon)) - CDirectory::Create(strAddon); - - // create the XML file - CXBMCTinyXML doc; - SettingsToXML(doc); - doc.SaveFile(m_userSettingsPath); - m_userSettingsLoaded = true; - - CAddonMgr::Get().ReloadSettings(ID());//push the settings changes to the running addon instance -#ifdef HAS_PYTHON - g_pythonParser.OnSettingsChanged(ID()); -#endif -} - -std::string CAddon::GetSetting(const std::string& key) -{ - if (!LoadSettings()) - return ""; // no settings available - - map::const_iterator i = m_settings.find(key); - if (i != m_settings.end()) - return i->second; - return ""; -} - -void CAddon::UpdateSetting(const std::string& key, const std::string& value) -{ - LoadSettings(); - if (key.empty()) return; - m_settings[key] = value; -} - -bool CAddon::SettingsFromXML(const CXBMCTinyXML &doc, bool loadDefaults /*=false */) -{ - if (!doc.RootElement()) - return false; - - if (loadDefaults) - m_settings.clear(); - - const TiXmlElement* category = doc.RootElement()->FirstChildElement("category"); - if (!category) - category = doc.RootElement(); - - bool foundSetting = false; - while (category) - { - const TiXmlElement *setting = category->FirstChildElement("setting"); - while (setting) - { - const char *id = setting->Attribute("id"); - const char *value = setting->Attribute(loadDefaults ? "default" : "value"); - if (id && value) - { - m_settings[id] = value; - foundSetting = true; - } - setting = setting->NextSiblingElement("setting"); - } - category = category->NextSiblingElement("category"); - } - return foundSetting; -} - -void CAddon::SettingsToXML(CXBMCTinyXML &doc) const -{ - TiXmlElement node("settings"); - doc.InsertEndChild(node); - for (map::const_iterator i = m_settings.begin(); i != m_settings.end(); ++i) - { - TiXmlElement nodeSetting("setting"); - nodeSetting.SetAttribute("id", i->first.c_str()); - nodeSetting.SetAttribute("value", i->second.c_str()); - doc.RootElement()->InsertEndChild(nodeSetting); - } - doc.SaveFile(m_userSettingsPath); -} - -TiXmlElement* CAddon::GetSettingsXML() -{ - return m_addonXmlDoc.RootElement(); -} - -void CAddon::BuildProfilePath() -{ - m_profile = StringUtils::Format("special://profile/addon_data/%s/", ID().c_str()); -} - -const std::string CAddon::Icon() const -{ - if (CURL::IsFullPath(m_props.icon)) - return m_props.icon; - return URIUtils::AddFileToFolder(m_props.path, m_props.icon); -} - -const std::string CAddon::LibPath() const -{ - return URIUtils::AddFileToFolder(m_props.path, m_strLibName); -} - -AddonVersion CAddon::GetDependencyVersion(const std::string &dependencyID) const -{ - const ADDON::ADDONDEPS &deps = GetDeps(); - ADDONDEPS::const_iterator it = deps.find(dependencyID); - if (it != deps.end()) - return it->second.first; - return AddonVersion("0.0.0"); -} - -/** - * CAddonLibrary - * - */ - -CAddonLibrary::CAddonLibrary(const cp_extension_t *ext) - : CAddon(ext) - , m_addonType(SetAddonType()) -{ -} - -CAddonLibrary::CAddonLibrary(const AddonProps& props) - : CAddon(props) - , m_addonType(SetAddonType()) -{ -} - -AddonPtr CAddonLibrary::Clone() const -{ - return AddonPtr(new CAddonLibrary(*this)); -} - -TYPE CAddonLibrary::SetAddonType() -{ - if (Type() == ADDON_VIZ_LIBRARY) - return ADDON_VIZ; - else - return ADDON_UNKNOWN; -} - -} /* namespace ADDON */ - -- cgit v1.2.3