1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "XBDateTime.h" 12 #include "addons/AddonVersion.h" 13 #include "addons/addoninfo/AddonType.h" 14 15 #include <map> 16 #include <memory> 17 #include <string> 18 #include <unordered_map> 19 #include <utility> 20 #include <vector> 21 22 namespace ADDON 23 { 24 25 class CAddonBuilder; 26 class CAddonInfo; 27 typedef std::shared_ptr<CAddonInfo> AddonInfoPtr; 28 typedef std::vector<AddonInfoPtr> AddonInfos; 29 30 enum class AddonDisabledReason 31 { 32 /// @brief Special reason for returning all disabled addons. 33 /// 34 /// Only used as an actual value when an addon is enabled. 35 NONE = 0, 36 USER = 1, 37 INCOMPATIBLE = 2, 38 PERMANENT_FAILURE = 3 39 }; 40 41 enum class AddonOriginType 42 { 43 /// @brief The type of the origin of an addon. 44 /// 45 /// Represents where an addon was installed from. 46 SYSTEM = 0, /// The addon is a system addon 47 REPOSITORY = 1, /// The addon origin is a repository 48 MANUAL = 2 /// The addon origin is a zip file, package or development build 49 }; 50 51 //! @brief Reasons why an addon is not updateable 52 enum class AddonUpdateRule 53 { 54 ANY = 0, //!< used internally, not to be explicitly set 55 USER_DISABLED_AUTO_UPDATE = 1, //!< automatic updates disabled via AddonInfo dialog 56 PIN_OLD_VERSION = 2 //!< user downgraded to an older version 57 }; 58 59 /*! 60 * @brief Add-on state defined within addon.xml to report about the current addon 61 * lifecycle state. 62 * 63 * E.g. the add-on is broken and can no longer be used. 64 * 65 * XML examples: 66 * ~~~~~~~~~~~~~{.xml} 67 * <lifecyclestate type="broken" lang="en_GB">SOME TEXT</lifecyclestate> 68 * ~~~~~~~~~~~~~ 69 */ 70 enum class AddonLifecycleState 71 { 72 NORMAL = 0, //!< Used if an add-on has no special lifecycle state which is the default state 73 DEPRECATED = 1, //!< the add-on should be marked as deprecated but is still usable 74 BROKEN = 2, //!< the add-on should marked as broken in the repository 75 }; 76 77 struct DependencyInfo 78 { 79 std::string id; 80 AddonVersion versionMin, version; 81 bool optional; DependencyInfoDependencyInfo82 DependencyInfo(std::string id, 83 const AddonVersion& versionMin, 84 const AddonVersion& version, 85 bool optional) 86 : id(std::move(id)), 87 versionMin(versionMin.empty() ? version : versionMin), 88 version(version), 89 optional(optional) 90 { 91 } 92 93 bool operator==(const DependencyInfo& rhs) const 94 { 95 return id == rhs.id && versionMin == rhs.versionMin && version == rhs.version && 96 optional == rhs.optional; 97 } 98 99 bool operator!=(const DependencyInfo& rhs) const 100 { 101 return !(rhs == *this); 102 } 103 }; 104 105 typedef std::map<std::string, std::string> InfoMap; 106 typedef std::map<std::string, std::string> ArtMap; 107 108 class CAddonInfoBuilder; 109 110 class CAddonInfo 111 { 112 public: 113 CAddonInfo() = default; 114 CAddonInfo(std::string id, TYPE type); 115 SetMainType(TYPE type)116 void SetMainType(TYPE type) { m_mainType = type; } SetBinary(bool isBinary)117 void SetBinary(bool isBinary) { m_isBinary = isBinary; } SetLibName(const std::string & libname)118 void SetLibName(const std::string& libname) { m_libname = libname; } SetPath(const std::string & path)119 void SetPath(const std::string& path) { m_path = path; } AddExtraInfo(const std::string & idName,const std::string & value)120 void AddExtraInfo(const std::string& idName, const std::string& value) { m_extrainfo[idName] = value; } SetLastUsed(const CDateTime & dateTime)121 void SetLastUsed(const CDateTime& dateTime) { m_lastUsed = dateTime; } 122 ID()123 const std::string& ID() const { return m_id; } 124 125 /** 126 * @brief To get the main type of this addon 127 * 128 * This is the first type defined in addon.xml. 129 * 130 * @return The used main type of addon 131 */ MainType()132 TYPE MainType() const { return m_mainType; } 133 134 /** 135 * @brief To check addon contains a type 136 * 137 * @param[in] type The to checked type identifier 138 * @param[in] mainOnly to check only in first defined main addon inside addon.xml 139 * @return true in case the wanted type is supported, false if not 140 */ 141 bool HasType(TYPE type, bool mainOnly = false) const; 142 143 /** 144 * @brief To get all available types inside the addon 145 * 146 * To have all `<extension point="..." />` defined in addon.xml inside a list. 147 * 148 * @return List of all supported types 149 */ Types()150 const std::vector<CAddonType>& Types() const { return m_types; } 151 152 /** 153 * @brief The get for given addon type information and extension data 154 * 155 * @param[in] type The wanted type data 156 * @return addon type class with @ref CAddonExtensions as information 157 * 158 * @note This function return never a "nullptr", in case the wanted type is 159 * not supported, becomes a dummy of @ref CAddonType given. 160 * 161 * ------------------------------------------------------------------------ 162 * 163 * **Example:** 164 * ~~~~~~~~~~~~~{.cpp} 165 * // To get <extension ... name="blablabla" /> from addon.xml 166 * std::string name = Type(ADDON_...)->GetValue("@name").asString(); 167 * ~~~~~~~~~~~~~ 168 * 169 */ 170 const CAddonType* Type(TYPE type) const; 171 172 bool ProvidesSubContent(const TYPE& content, const TYPE& mainType = ADDON_UNKNOWN) const; 173 bool ProvidesSeveralSubContents() const; 174 Version()175 const AddonVersion& Version() const { return m_version; } MinVersion()176 const AddonVersion& MinVersion() const { return m_minversion; } IsBinary()177 bool IsBinary() const { return m_isBinary; } 178 const AddonVersion& DependencyMinVersion(const std::string& dependencyID) const; 179 const AddonVersion& DependencyVersion(const std::string& dependencyID) const; Name()180 const std::string& Name() const { return m_name; } License()181 const std::string& License() const { return m_license; } Summary()182 const std::string& Summary() const { return GetTranslatedText(m_summary); } Description()183 const std::string& Description() const { return GetTranslatedText(m_description); } LibName()184 const std::string& LibName() const { return m_libname; } Author()185 const std::string& Author() const { return m_author; } Source()186 const std::string& Source() const { return m_source; } Website()187 const std::string& Website() const { return m_website; } Forum()188 const std::string& Forum() const { return m_forum; } EMail()189 const std::string& EMail() const { return m_email; } Path()190 const std::string& Path() const { return m_path; } ChangeLog()191 const std::string& ChangeLog() const { return GetTranslatedText(m_changelog); } Icon()192 const std::string& Icon() const { return m_icon; } Art()193 const ArtMap& Art() const { return m_art; } Screenshots()194 const std::vector<std::string>& Screenshots() const { return m_screenshots; } Disclaimer()195 const std::string& Disclaimer() const { return GetTranslatedText(m_disclaimer); } GetDependencies()196 const std::vector<DependencyInfo>& GetDependencies() const { return m_dependencies; } LifecycleState()197 AddonLifecycleState LifecycleState() const { return m_lifecycleState; } LifecycleStateDescription()198 const std::string& LifecycleStateDescription() const 199 { 200 return GetTranslatedText(m_lifecycleStateDescription); 201 } Origin()202 const std::string& Origin() const { return m_origin; } 203 const std::string& OriginName() const; 204 ExtraInfo()205 const InfoMap& ExtraInfo() const { return m_extrainfo; } 206 207 bool MeetsVersion(const AddonVersion& versionMin, const AddonVersion& version) const; PackageSize()208 uint64_t PackageSize() const { return m_packageSize; } InstallDate()209 CDateTime InstallDate() const { return m_installDate; } LastUpdated()210 CDateTime LastUpdated() const { return m_lastUpdated; } LastUsed()211 CDateTime LastUsed() const { return m_lastUsed; } 212 213 /*! 214 * @brief Utilities to translate add-on parts to his requested part. 215 */ 216 //@{ 217 static std::string TranslateType(TYPE type, bool pretty = false); 218 static std::string TranslateIconType(TYPE type); 219 static TYPE TranslateType(const std::string& string); 220 static TYPE TranslateSubContent(const std::string& content); 221 //@} 222 223 private: 224 friend class CAddonInfoBuilder; 225 226 std::string m_id; 227 TYPE m_mainType = ADDON_UNKNOWN; 228 std::vector<CAddonType> m_types; 229 230 AddonVersion m_version; 231 AddonVersion m_minversion; 232 bool m_isBinary = false; 233 std::string m_name; 234 std::string m_license; 235 std::unordered_map<std::string, std::string> m_summary; 236 std::unordered_map<std::string, std::string> m_description; 237 std::string m_author; 238 std::string m_source; 239 std::string m_website; 240 std::string m_forum; 241 std::string m_email; 242 std::string m_path; 243 std::unordered_map<std::string, std::string> m_changelog; 244 std::string m_icon; 245 ArtMap m_art; 246 std::vector<std::string> m_screenshots; 247 std::unordered_map<std::string, std::string> m_disclaimer; 248 std::vector<DependencyInfo> m_dependencies; 249 AddonLifecycleState m_lifecycleState = AddonLifecycleState::NORMAL; 250 std::unordered_map<std::string, std::string> m_lifecycleStateDescription; 251 CDateTime m_installDate; 252 CDateTime m_lastUpdated; 253 CDateTime m_lastUsed; 254 std::string m_origin; 255 mutable std::unique_ptr<std::string> m_originName; // @todo use std::optional once we use c++17 256 uint64_t m_packageSize = 0; 257 std::string m_libname; 258 InfoMap m_extrainfo; 259 std::vector<std::string> m_platforms; 260 261 const std::string& GetTranslatedText(const std::unordered_map<std::string, std::string>& locales) const; 262 }; 263 264 } /* namespace ADDON */ 265