1 /* 2 * Copyright (C) 2005-2020 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 <map> 12 #include <memory> 13 #include <string> 14 #include <vector> 15 16 namespace ADDON 17 { 18 19 class AddonVersion; 20 class CAddonDatabase; 21 class CAddonMgr; 22 class CRepository; 23 class IAddon; 24 enum class AddonCheckType; 25 26 enum class CheckAddonPath 27 { 28 YES, 29 NO, 30 }; 31 32 /** 33 * Struct - CAddonWithUpdate 34 */ 35 struct CAddonWithUpdate 36 { 37 std::shared_ptr<IAddon> m_installed; 38 std::shared_ptr<IAddon> m_update; 39 }; 40 41 /** 42 * Class - CAddonRepos 43 * Reads information about installed official/third party repos and their contained add-ons from the database. 44 * Used to check for updates for installed add-ons and dependencies while obeying permission rules. 45 * Note that this class is not responsible for refreshing the repo data stored in the database. 46 */ 47 class CAddonRepos 48 { 49 public: CAddonRepos(const CAddonMgr & addonMgr)50 CAddonRepos(const CAddonMgr& addonMgr) : m_addonMgr(addonMgr){}; 51 52 /*! 53 * \brief Load the map of all available addon versions in any installed repository 54 * \param database reference to the database to load addons from 55 * \return true on success, false otherwise 56 */ 57 bool LoadAddonsFromDatabase(const CAddonDatabase& database); 58 59 /*! 60 * \brief Load the map of all available versions of an addonId in any installed repository 61 * \param database reference to the database to load addons from 62 * \param addonId the addon id we want to retrieve versions for 63 * \return true on success, false otherwise 64 */ 65 bool LoadAddonsFromDatabase(const CAddonDatabase& database, const std::string& addonId); 66 67 /*! 68 * \brief Load the map of all available versions in one installed repository 69 * \param database reference to the database to load addons from 70 * \param repoAddon pointer to the repo we want to retrieve versions from 71 * note this is of type AddonPtr, not RepositoryPtr 72 * \return true on success, false otherwise 73 */ 74 bool LoadAddonsFromDatabase(const CAddonDatabase& database, 75 const std::shared_ptr<IAddon>& repoAddon); 76 77 /*! 78 * \brief Build the list of addons to be updated depending on defined rules 79 * or the list of outdated addons 80 * \param installed vector of all addons installed on the system that are 81 * checked for an update 82 * \param[in] addonCheckType build list of OUTDATED or UPDATES 83 * \param[out] result list of addon versions that are going to be installed 84 * or are outdated 85 */ 86 void BuildUpdateOrOutdatedList(const std::vector<std::shared_ptr<IAddon>>& installed, 87 std::vector<std::shared_ptr<IAddon>>& result, 88 AddonCheckType addonCheckType) const; 89 90 91 /*! 92 * \brief Build the list of outdated addons and their available updates. 93 * \param installed vector of all addons installed on the system that are 94 * checked for an update 95 * \param[out] addonsWithUpdate target map 96 */ 97 void BuildAddonsWithUpdateList(const std::vector<std::shared_ptr<IAddon>>& installed, 98 std::map<std::string, CAddonWithUpdate>& addonsWithUpdate) const; 99 100 /*! 101 * \brief Checks if the origin-repository of a given addon is defined as official repo 102 * and can also verify if the origin-path (e.g. https://mirrors.kodi.tv ...) 103 * is matching 104 * \note if this function is called on locally installed add-ons, for instance when populating 105 * 'My add-ons', the local installation path is returned as origin. 106 * thus parameter CheckAddonPath::NO needs to be passed in such cases 107 * \param addon pointer to addon to be checked 108 * \param checkAddonPath also check origin path 109 * \return true if the repository id of a given addon is defined as official 110 * and the addons origin matches the defined official origin of the repo id 111 */ 112 static bool IsFromOfficialRepo(const std::shared_ptr<IAddon>& addon, 113 CheckAddonPath checkAddonPath); 114 115 /*! 116 * \brief Checks if the passed in repository is defined as official repo 117 * which includes ORIGIN_SYSTEM 118 * \param repoId repository id to check 119 * \return true if the repository id is defined as official, false otherwise 120 */ 121 static bool IsOfficialRepo(const std::string& repoId); 122 123 /*! 124 * \brief Check if an update is available for a single addon 125 * \param addon that is checked for an update 126 * \param[out] update pointer to the found update 127 * \return true if an installable update was found, false otherwise 128 */ 129 bool DoAddonUpdateCheck(const std::shared_ptr<IAddon>& addon, 130 std::shared_ptr<IAddon>& update) const; 131 132 /*! 133 * \brief Retrieves the latest version of an addon from all installed repositories 134 * follows addon origin restriction rules 135 * \param addonId addon id we're looking the latest version for 136 * \param[out] addon pointer to the found addon 137 * \return true if a version was found, false otherwise 138 */ 139 bool GetLatestAddonVersionFromAllRepos(const std::string& addonId, 140 std::shared_ptr<IAddon>& addon) const; 141 142 /*! 143 * \brief Retrieves the latest official versions of addons to vector. 144 * Private versions are added obeying updateMode. 145 * (either OFFICIAL_ONLY or ANY_REPOSITORY) 146 * \param[out] addonList retrieved addon list in a vector 147 */ 148 void GetLatestAddonVersions(std::vector<std::shared_ptr<IAddon>>& addonList) const; 149 150 /*! 151 * \brief Retrieves the latest official versions of addons to vector. 152 * Private versions (latest per repository) are added obeying updateMode. 153 * (either OFFICIAL_ONLY or ANY_REPOSITORY) 154 * \param[out] addonList retrieved addon list in a vector 155 */ 156 void GetLatestAddonVersionsFromAllRepos(std::vector<std::shared_ptr<IAddon>>& addonList) const; 157 158 /*! 159 * \brief Find a dependency to install during an addon install or update 160 * If the dependency cannot be found in official versions we look in the 161 * installing/updating addon's (the parent's) origin repository 162 * \param dependsId addon id of the dependency we're looking for 163 * \param parentRepoId origin repository of the dependee 164 * \param [out] dependencyToInstall pointer to the found dependency, only use 165 * if function returns true 166 * \param [out] repoForDep the repository that dependency will install from finally 167 * \return true if the dependency was found, false otherwise 168 */ 169 bool FindDependency(const std::string& dependsId, 170 const std::string& parentRepoId, 171 std::shared_ptr<IAddon>& dependencyToInstall, 172 std::shared_ptr<CRepository>& repoForDep) const; 173 174 /*! 175 * \brief Find a dependency addon in the repository of its parent 176 * \param dependsId addon id of the dependency we're looking for 177 * \param parentRepoId origin repository of the dependee 178 * \param [out] dependencyToInstall pointer to the found dependency, only use 179 * if function returns true 180 * \return true if the dependency was found, false otherwise 181 */ 182 bool FindDependencyByParentRepo(const std::string& dependsId, 183 const std::string& parentRepoId, 184 std::shared_ptr<IAddon>& dependencyToInstall) const; 185 186 /*! 187 * \brief Build compatible versions list based on the contents of m_allAddons 188 * \note content of m_allAddons depends on the preceding call to @ref LoadAddonsFromDatabase() 189 * \param[out] compatibleVersions target vector to be filled 190 */ 191 void BuildCompatibleVersionsList(std::vector<std::shared_ptr<IAddon>>& compatibleVersions) const; 192 193 private: 194 /*! 195 * \brief Load the map of addons 196 * \note this function should only by called from publicly exposed wrappers 197 * \return true on success, false otherwise 198 */ 199 bool LoadAddonsFromDatabase(const CAddonDatabase& database, 200 const std::string& addonId, 201 const std::shared_ptr<IAddon>& repoAddon); 202 203 /*! 204 * \brief Looks up an addon in a given repository map and 205 * checks if an update is available 206 * \param addonToCheck the addon we want to find and version check 207 * \param map the repository map we want to check against 208 * \param[out] pointer to the found update. if the addon is 209 * up-to-date on our system, this param will return 'nullptr' 210 * \return true if the addon was found in the desired map, 211 * either up-to-date or newer version. 212 * false if the addon does NOT exist in the map 213 */ 214 bool FindAddonAndCheckForUpdate(const std::shared_ptr<IAddon>& addonToCheck, 215 const std::map<std::string, std::shared_ptr<IAddon>>& map, 216 std::shared_ptr<IAddon>& update) const; 217 218 /*! 219 * \brief Sets up latest version maps from scratch 220 */ 221 void SetupLatestVersionMaps(); 222 223 /*! 224 * \brief Adds the latest version of an addon to the desired map 225 * \param addonToAdd the addon whose latest version should be added 226 * \param map target map, e.g. latestOfficialVersions or latestPrivateVersions 227 */ 228 void AddAddonIfLatest(const std::shared_ptr<IAddon>& addonToAdd, 229 std::map<std::string, std::shared_ptr<IAddon>>& map) const; 230 231 /*! 232 * \brief Adds the latest version of an addon to the desired map per repository 233 * used to populate 'latestVersionsByRepo' 234 * \param repoId the repository that addon comes from 235 * \param addonToAdd the addon whose latest version should be added 236 * \param map target map, latestVersionsByRepo 237 */ 238 void AddAddonIfLatest( 239 const std::string& repoId, 240 const std::shared_ptr<IAddon>& addonToAdd, 241 std::map<std::string, std::map<std::string, std::shared_ptr<IAddon>>>& map) const; 242 243 /*! 244 * \brief Looks up an addon entry in a specific map 245 * \param addonId addon we want to retrieve 246 * \param map the map we're looking into for the wanted addon 247 * \param[out] addon pointer to the found addon, only use when function returns true 248 * \return true if the addon was found in the map, false otherwise 249 */ 250 bool GetLatestVersionByMap(const std::string& addonId, 251 const std::map<std::string, std::shared_ptr<IAddon>>& map, 252 std::shared_ptr<IAddon>& addon) const; 253 254 const CAddonMgr& m_addonMgr; 255 256 std::vector<std::shared_ptr<IAddon>> m_allAddons; 257 258 std::map<std::string, std::shared_ptr<IAddon>> m_latestOfficialVersions; 259 std::map<std::string, std::shared_ptr<IAddon>> m_latestPrivateVersions; 260 std::map<std::string, std::map<std::string, std::shared_ptr<IAddon>>> m_latestVersionsByRepo; 261 std::map<std::string, std::multimap<std::string, std::shared_ptr<IAddon>>> m_addonsByRepoMap; 262 }; 263 264 }; /* namespace ADDON */ 265