Skip to content
Newer
Older
100644 723 lines (648 sloc) 19.8 KB
074db86 merged: addons-fw branch
elupus authored
1 /*
2 * Copyright (C) 2005-2009 Team XBMC
3 * http://www.xbmc.org
4 *
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 */
21 #include "AddonManager.h"
22 #include "Addon.h"
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
23 #include "AddonDatabase.h"
074db86 merged: addons-fw branch
elupus authored
24 #include "StringUtils.h"
25 #include "RegExp.h"
26 #include "XMLUtils.h"
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
27 #include "utils/JobManager.h"
28 #include "utils/SingleLock.h"
074db86 merged: addons-fw branch
elupus authored
29 #include "FileItem.h"
30 #include "Settings.h"
31 #include "GUISettings.h"
32 #include "DownloadQueueManager.h"
dacdca0 changed: moved CAddonStatusHandler to separate files
alcoheca authored
33 #include "log.h"
074db86 merged: addons-fw branch
elupus authored
34
35 #ifdef HAS_VISUALISATION
055f806 cosmetic/tidyup move all addon classes to /xbmc/addons/
alcoheca authored
36 #include "DllVisualisation.h"
37 #include "Visualisation.h"
074db86 merged: addons-fw branch
elupus authored
38 #endif
39 #ifdef HAS_SCREENSAVER
055f806 cosmetic/tidyup move all addon classes to /xbmc/addons/
alcoheca authored
40 #include "DllScreenSaver.h"
41 #include "ScreenSaver.h"
074db86 merged: addons-fw branch
elupus authored
42 #endif
43 //#ifdef HAS_SCRAPERS
055f806 cosmetic/tidyup move all addon classes to /xbmc/addons/
alcoheca authored
44 #include "Scraper.h"
074db86 merged: addons-fw branch
elupus authored
45 //#endif
606248f added: addon repository class
spiff_ authored
46 #include "Repository.h"
af8cb2a Revert "wip"
alcoheca authored
47
88e9b6f changed: expand std namespace
spiff_ authored
48 using namespace std;
49
074db86 merged: addons-fw branch
elupus authored
50 namespace ADDON
51 {
52
53
54 /**********************************************************
55 * CAddonMgr
56 *
57 */
58
59 CAddonMgr* CAddonMgr::m_pInstance = NULL;
88e9b6f changed: expand std namespace
spiff_ authored
60 map<TYPE, IAddonMgrCallback*> CAddonMgr::m_managers;
074db86 merged: addons-fw branch
elupus authored
61
62 CAddonMgr::CAddonMgr()
63 {
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
64 FindAddons();
65 m_watch.StartZero();
074db86 merged: addons-fw branch
elupus authored
66 }
67
68 CAddonMgr::~CAddonMgr()
69 {
70 }
71
72 CAddonMgr* CAddonMgr::Get()
73 {
74 if (!m_pInstance)
75 {
76 m_pInstance = new CAddonMgr();
77 }
78 return m_pInstance;
79 }
80
81 IAddonMgrCallback* CAddonMgr::GetCallbackForType(TYPE type)
82 {
83 if (m_managers.find(type) == m_managers.end())
84 return NULL;
85 else
86 return m_managers[type];
87 }
88
89 bool CAddonMgr::RegisterAddonMgrCallback(const TYPE type, IAddonMgrCallback* cb)
90 {
91 if (cb == NULL)
92 return false;
93
94 m_managers.erase(type);
95 m_managers[type] = cb;
96
97 return true;
98 }
99
100 void CAddonMgr::UnregisterAddonMgrCallback(TYPE type)
101 {
102 m_managers.erase(type);
103 }
104
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
105 bool CAddonMgr::HasAddons(const TYPE &type, const CONTENT_TYPE &content/*= CONTENT_NONE*/, bool enabledOnly/*= true*/)
074db86 merged: addons-fw branch
elupus authored
106 {
af8cb2a Revert "wip"
alcoheca authored
107 if (m_addons.empty())
108 {
109 VECADDONS add;
110 GetAllAddons(add,false);
111 }
112
113 if (content == CONTENT_NONE)
114 return (m_addons.find(type) != m_addons.end());
074db86 merged: addons-fw branch
elupus authored
115
116 VECADDONS addons;
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
117 return GetAddons(type, addons, content, enabledOnly);
074db86 merged: addons-fw branch
elupus authored
118 }
119
120 bool CAddonMgr::GetAllAddons(VECADDONS &addons, bool enabledOnly/*= true*/)
121 {
af8cb2a Revert "wip"
alcoheca authored
122 VECADDONS temp;
123 if (CAddonMgr::Get()->GetAddons(ADDON_PLUGIN, temp, CONTENT_NONE, enabledOnly))
124 addons.insert(addons.end(), temp.begin(), temp.end());
125 if (CAddonMgr::Get()->GetAddons(ADDON_SCRAPER, temp, CONTENT_NONE, enabledOnly))
126 addons.insert(addons.end(), temp.begin(), temp.end());
127 if (CAddonMgr::Get()->GetAddons(ADDON_SCREENSAVER, temp, CONTENT_NONE, enabledOnly))
128 addons.insert(addons.end(), temp.begin(), temp.end());
129 if (CAddonMgr::Get()->GetAddons(ADDON_SCRIPT, temp, CONTENT_NONE, enabledOnly))
130 addons.insert(addons.end(), temp.begin(), temp.end());
131 if (CAddonMgr::Get()->GetAddons(ADDON_VIZ, temp, CONTENT_NONE, enabledOnly))
132 addons.insert(addons.end(), temp.begin(), temp.end());
133 return !addons.empty();
074db86 merged: addons-fw branch
elupus authored
134 }
135
136 bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, const CONTENT_TYPE &content/*= CONTENT_NONE*/, bool enabledOnly/*= true*/)
137 {
4e5b98a added: locks to addon manager
spiff_ authored
138 CSingleLock lock(m_critSection);
af8cb2a Revert "wip"
alcoheca authored
139 addons.clear();
140 if (m_addons.find(type) != m_addons.end())
141 {
142 IVECADDONS itr = m_addons[type].begin();
143 while (itr != m_addons[type].end())
144 { // filter out what we're not looking for
dea84cb changed: Disabled() -> Enabled() - more intuitive
spiff_ authored
145 if ((enabledOnly && !(*itr)->Enabled())
af8cb2a Revert "wip"
alcoheca authored
146 || (content != CONTENT_NONE && !(*itr)->Supports(content)))
147 {
148 ++itr;
149 continue;
150 }
151 addons.push_back(*itr);
152 ++itr;
153 }
154 }
155 return !addons.empty();
074db86 merged: addons-fw branch
elupus authored
156 }
157
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
158 bool CAddonMgr::GetAddon(const CStdString &str, AddonPtr &addon, const TYPE &type/*=ADDON_UNKNOWN*/, bool enabledOnly/*= true*/)
074db86 merged: addons-fw branch
elupus authored
159 {
4e5b98a added: locks to addon manager
spiff_ authored
160 CSingleLock lock(m_critSection);
2ca76f9 changed: all addons should be store below either special://home/addon…
alcoheca authored
161 if (type != ADDON_UNKNOWN && m_addons.find(type) == m_addons.end())
074db86 merged: addons-fw branch
elupus authored
162 return false;
163
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
164 if (m_idMap[str])
165 {
166 addon = m_idMap[str];
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
167 if(enabledOnly)
dea84cb changed: Disabled() -> Enabled() - more intuitive
spiff_ authored
168 return addon->Enabled();
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
169 else
170 return true;
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
171 }
074db86 merged: addons-fw branch
elupus authored
172
173 VECADDONS &addons = m_addons[type];
174 IVECADDONS adnItr = addons.begin();
175 while (adnItr != addons.end())
176 {
177 //FIXME scrapers were previously registered by filename
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
178 if ((*adnItr)->Name() == str || (type == ADDON_SCRAPER && (*adnItr)->LibName() == str))
074db86 merged: addons-fw branch
elupus authored
179 {
180 addon = (*adnItr);
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
181 if(enabledOnly)
dea84cb changed: Disabled() -> Enabled() - more intuitive
spiff_ authored
182 return addon->Enabled();
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
183 else
184 return true;
074db86 merged: addons-fw branch
elupus authored
185 }
186 adnItr++;
187 }
188
189 return false;
190 }
191
192 //TODO handle all 'default' cases here, not just scrapers & vizs
193 bool CAddonMgr::GetDefault(const TYPE &type, AddonPtr &addon, const CONTENT_TYPE &content)
194 {
195 if (type != ADDON_SCRAPER && type != ADDON_VIZ)
196 return false;
197
198 CStdString setting;
199 if (type == ADDON_VIZ)
200 setting = g_guiSettings.GetString("musicplayer.visualisation");
201 else
202 {
203 switch (content)
204 {
205 case CONTENT_MOVIES:
206 {
207 setting = g_guiSettings.GetString("scrapers.moviedefault");
208 break;
209 }
210 case CONTENT_TVSHOWS:
211 {
212 setting = g_guiSettings.GetString("scrapers.tvshowdefault");
213 break;
214 }
215 case CONTENT_MUSICVIDEOS:
216 {
217 setting = g_guiSettings.GetString("scrapers.musicvideodefault");
218 break;
219 }
220 case CONTENT_ALBUMS:
221 case CONTENT_ARTISTS:
222 {
223 setting = g_guiSettings.GetString("musiclibrary.scraper");
224 break;
225 }
226 default:
227 return false;
228 }
229 }
2ca76f9 changed: all addons should be store below either special://home/addon…
alcoheca authored
230 return GetAddon(setting, addon, type);
074db86 merged: addons-fw branch
elupus authored
231 }
232
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
233 CStdString CAddonMgr::GetString(const CStdString &id, const int number)
074db86 merged: addons-fw branch
elupus authored
234 {
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
235 AddonPtr addon = m_idMap[id];
074db86 merged: addons-fw branch
elupus authored
236 if (addon)
237 return addon->GetString(number);
238
239 return "";
240 }
241
af8cb2a Revert "wip"
alcoheca authored
242 void CAddonMgr::FindAddons()
243 {
4e5b98a added: locks to addon manager
spiff_ authored
244 CSingleLock lock(m_critSection);
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
245 m_addons.clear();
246 m_idMap.clear();
535b4e7 changed: load addons from user directory first, then load from system…
elupus authored
247 LoadAddons("special://home/addons");
248 LoadAddons("special://xbmc/addons");
249 }
250
251 void CAddonMgr::LoadAddons(const CStdString &path)
252 {
af8cb2a Revert "wip"
alcoheca authored
253 // parse the user & system dirs for addons of the requested type
254 CFileItemList items;
535b4e7 changed: load addons from user directory first, then load from system…
elupus authored
255 CDirectory::GetDirectory(path, items);
af8cb2a Revert "wip"
alcoheca authored
256
257 // store any addons with unresolved deps, then recheck at the end
258 VECADDONS unresolved;
259
260 // for all folders found
261 for (int i = 0; i < items.Size(); ++i)
262 {
263 CFileItemPtr item = items[i];
264
265 if(!item->m_bIsFolder)
266 continue;
267
268 // read description.xml and populate the addon
269 AddonPtr addon;
270 if (!AddonFromInfoXML(item->m_strPath, addon))
271 continue;
272
535b4e7 changed: load addons from user directory first, then load from system…
elupus authored
273 // only load if addon with same id isn't already loaded
274 if(m_idMap.find(addon->ID()) != m_idMap.end())
275 {
276 CLog::Log(LOGDEBUG, "ADDON: already loaded id %s, bypassing package", addon->ID().c_str());
277 continue;
278 }
279
af8cb2a Revert "wip"
alcoheca authored
280 // refuse to store addons with missing library
281 CStdString library(CUtil::AddFileToFolder(addon->Path(), addon->LibName()));
282 if (!CFile::Exists(library))
283 {
284 CLog::Log(LOGDEBUG, "ADDON: Missing library file %s, bypassing package", library.c_str());
285 continue;
286 }
287
288 // check for/cache icon thumbnail
289 //TODO cache one thumb per addon id instead
290 CFileItem item2(CUtil::AddFileToFolder(addon->Path(), addon->LibName()), false);
291 item2.SetCachedProgramThumb();
292 if (!item2.HasThumbnail())
293 item2.SetUserProgramThumb();
294 if (!item2.HasThumbnail())
295 item2.SetThumbnailImage(addon->Icon());
296 if (item2.HasThumbnail())
297 {
298 XFILE::CFile::Cache(item2.GetThumbnailImage(),item->GetCachedProgramThumb());
299 }
300
301 if (!DependenciesMet(addon))
302 {
303 unresolved.push_back(addon);
304 continue;
305 }
306 else
307 { // everything ok, add to available addons if new
308 if (UpdateIfKnown(addon))
309 continue;
310 else
311 {
312 m_addons[addon->Type()].push_back(addon);
88e9b6f changed: expand std namespace
spiff_ authored
313 m_idMap.insert(make_pair(addon->ID(), addon));
af8cb2a Revert "wip"
alcoheca authored
314 }
315 }
316 }
317
318 for (unsigned i = 0; i < unresolved.size(); i++)
319 {
320 AddonPtr& addon = unresolved[i];
321 if (DependenciesMet(addon))
322 {
323 if (!UpdateIfKnown(addon))
324 {
325 m_addons[addon->Type()].push_back(addon);
88e9b6f changed: expand std namespace
spiff_ authored
326 m_idMap.insert(make_pair(addon->ID(), addon));
af8cb2a Revert "wip"
alcoheca authored
327 }
328 }
329 }
330 // CLog::Log(LOGINFO, "ADDON: Found %"PRIuS" addons", m_addons.find(type) == m_addons.end() ? 0: m_addons[type].size(), TranslateType(type).c_str());
331 }
332
333 bool CAddonMgr::UpdateIfKnown(AddonPtr &addon)
334 {
335 if (m_addons.find(addon->Type()) != m_addons.end())
336 {
337 for (unsigned i = 0; i < m_addons[addon->Type()].size(); i++)
338 {
339 if (m_addons[addon->Type()][i]->ID() == addon->ID())
340 {
341 //TODO inform any manager first, and request removal
342 //TODO choose most recent version if varying
343 m_addons[addon->Type()][i] = addon;
344 CStdString id = addon->ID();
345 m_idMap.erase(id);
88e9b6f changed: expand std namespace
spiff_ authored
346 m_idMap.insert(make_pair(addon->ID(), addon));
af8cb2a Revert "wip"
alcoheca authored
347 return true;
348 }
349 }
350 }
351 return false;
352 }
353
354 bool CAddonMgr::DependenciesMet(AddonPtr &addon)
355 {
356 // As remote repos are not functioning,
357 // this will fail if a dependency is not found locally
358 if (!addon)
359 return false;
360
4e5b98a added: locks to addon manager
spiff_ authored
361 CSingleLock lock(m_critSection);
af8cb2a Revert "wip"
alcoheca authored
362 ADDONDEPS deps = addon->GetDeps();
363 ADDONDEPS::iterator itr = deps.begin();
364 while (itr != deps.end())
365 {
366 CStdString id;
367 id = (*itr).first;
368 AddonVersion min = (*itr).second.first;
369 AddonVersion max = (*itr).second.second;
370 if (m_idMap.count(id))
371 {
372 AddonPtr dep = m_idMap[id];
373 // we're guaranteed to have at least max OR min here
374 if (!min.str.IsEmpty() && !max.str.IsEmpty())
375 return (dep->Version() >= min && dep->Version() <= max);
376 else if (!min.str.IsEmpty())
377 return (dep->Version() >= min);
378 else
379 return (dep->Version() <= max);
380 }
381 itr++;
382 }
383 return deps.empty();
384 }
385
386 bool CAddonMgr::AddonFromInfoXML(const CStdString &path, AddonPtr &addon)
387 {
388 // First check that we can load description.xml
389 CStdString strPath(CUtil::AddFileToFolder(path, ADDON_METAFILE));
390 if(!CFile::Exists(strPath))
391 return false;
392
393 TiXmlDocument xmlDoc;
394 if (!xmlDoc.LoadFile(strPath))
395 {
396 CLog::Log(LOGERROR, "Unable to load: %s, Line %d\n%s", strPath.c_str(), xmlDoc.ErrorRow(), xmlDoc.ErrorDesc());
397 return false;
398 }
399
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
400 const TiXmlElement *element = xmlDoc.RootElement();
af8cb2a Revert "wip"
alcoheca authored
401 if (!element || strcmpi(element->Value(), "addoninfo") != 0)
402 {
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
403 CLog::Log(LOGERROR, "ADDON: Error loading %s: cannot find <addon> root element", xmlDoc.Value());
af8cb2a Revert "wip"
alcoheca authored
404 return false;
405 }
406
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
407 return AddonFromInfoXML(element, addon, strPath);
408 }
409
410 bool CAddonMgr::AddonFromInfoXML(const TiXmlElement *rootElement,
411 AddonPtr &addon, const CStdString &strPath)
412 {
af8cb2a Revert "wip"
alcoheca authored
413 /* Steps required to meet package requirements
414 * 1. id exists and is valid
415 * 2. type exists and is valid
416 * 3. version exists
417 * 4. a license is specified
418 * 5. operating system matches ours
419 * 6. summary exists
420 * 7. for scrapers & plugins, support at least one type of content
421 *
422 * NOTE: addon dependencies are handled in ::FindAddons()
423 */
424
425 /* Validate id */
426 CStdString id;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
427 const TiXmlElement *element = rootElement->FirstChildElement("id");
af8cb2a Revert "wip"
alcoheca authored
428 if (!element)
429 {
430 CLog::Log(LOGERROR, "ADDON: %s missing <id> element, ignoring", strPath.c_str());
431 return false;
432 }
433 id = element->GetText();
434 //FIXME since we no longer required uuids, should we bother validating anything?
435 if (id.IsEmpty())
436 {
437 CLog::Log(LOGERROR, "ADDON: %s has invalid <id> element, ignoring", strPath.c_str());
438 return false;
439 }
440
441 /* Validate type */
442 TYPE type;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
443 element = rootElement->FirstChildElement("type");
af8cb2a Revert "wip"
alcoheca authored
444 if (!element)
445 {
f6bc944 fixed: typo
spiff_ authored
446 CLog::Log(LOGERROR, "ADDON: %s missing <type> element, ignoring", strPath.c_str());
af8cb2a Revert "wip"
alcoheca authored
447 return false;
448 }
449 type = TranslateType(element->GetText());
450 if (type == ADDON_UNKNOWN)
451 {
452 CLog::Log(LOGERROR, "ADDON: %s has invalid type identifier: '%d'", strPath.c_str(), type);
453 return false;
454 }
455
456 /* Retrieve Name */
457 CStdString name;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
458 element = rootElement->FirstChildElement("title");
af8cb2a Revert "wip"
alcoheca authored
459 if (!element)
460 {
461 CLog::Log(LOGERROR, "ADDON: %s missing <title> element, ignoring", strPath.c_str());
462 return false;
463 }
464 name = element->GetText();
465
466 /* Retrieve version */
467 CStdString version;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
468 element = rootElement->FirstChildElement("version");
af8cb2a Revert "wip"
alcoheca authored
469 if (!element)
470 {
471 CLog::Log(LOGERROR, "ADDON: %s missing <version> element, ignoring", strPath.c_str());
472 return false;
473 }
474 /* Validate version */
475 version = element->GetText();
476 CRegExp versionRE;
477 versionRE.RegComp(ADDON_VERSION_RE.c_str());
478 if (versionRE.RegFind(version.c_str()) != 0)
479 {
480 CLog::Log(LOGERROR, "ADDON: %s has invalid <version> element, ignoring", strPath.c_str());
481 return false;
482 }
483
484 /* Path, ID & Version are valid */
485 AddonProps addonProps(id, type, version);
486 addonProps.name = name;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
487 CUtil::GetDirectory(strPath,addonProps.path);
488 addonProps.icon = CUtil::AddFileToFolder(addonProps.path, "default.tbn");
af8cb2a Revert "wip"
alcoheca authored
489
490 /* Retrieve license */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
491 element = rootElement->FirstChildElement("license");
af8cb2a Revert "wip"
alcoheca authored
492 /* if (!element)
493 {
494 CLog::Log(LOGERROR, "ADDON: %s missing <license> element, ignoring", strPath.c_str());
495 return false;
496 }
497 addonProps.license = element->GetText();*/
498
499 /* Retrieve platforms which this addon supports */
500 CStdString platform;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
501 element = rootElement->FirstChildElement("platforms")->FirstChildElement("platform");
af8cb2a Revert "wip"
alcoheca authored
502 if (!element)
503 {
504 CLog::Log(LOGERROR, "ADDON: %s missing <platforms> element, ignoring", strPath.c_str());
505 return false;
506 }
507
508 bool all(false);
88e9b6f changed: expand std namespace
spiff_ authored
509 set<CStdString> platforms;
af8cb2a Revert "wip"
alcoheca authored
510 do
511 {
512 CStdString platform = element->GetText();
513 if (platform == "all")
514 {
515 all = true;
516 break;
517 }
518 platforms.insert(platform);
519 element = element->NextSiblingElement("platform");
520 } while (element != NULL);
521
522 if (!all)
523 {
524 #if defined(_LINUX) && !defined(__APPLE__)
525 if (!platforms.count("linux"))
526 {
527 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under Linux, ignoring", strPath.c_str());
528 return false;
529 }
78d5324 added: separate addon platforms for windows+dx and windows+opengl
spiff_ authored
530 #elif defined(_WIN32) && defined(HAS_SDL_OPENGL)
531 if (!platforms.count("windows-gl") && !platforms.count("windows"))
af8cb2a Revert "wip"
alcoheca authored
532 {
78d5324 added: separate addon platforms for windows+dx and windows+opengl
spiff_ authored
533 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under Windows/OpenGL, ignoring", strPath.c_str());
534 return false;
535 }
536 #elif defined(_WIN32) && defined(HAS_DX)
537 if (!platforms.count("windows-dx") && !platforms.count("windows"))
538 {
539 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under Windows/DirectX, ignoring", strPath.c_str());
af8cb2a Revert "wip"
alcoheca authored
540 return false;
541 }
542 #elif defined(__APPLE__)
543 if (!platforms.count("osx"))
544 {
545 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under OSX, ignoring", strPath.c_str());
546 return false;
547 }
548 #elif defined(_XBOX)
549 if (!platforms.count("xbox"))
550 {
551 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under XBOX, ignoring", strPath.c_str());
552 return false;
553 }
554 #endif
555 }
556
557 /* Retrieve summary */
558 CStdString summary;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
559 element = rootElement->FirstChildElement("summary");
af8cb2a Revert "wip"
alcoheca authored
560 if (!element)
561 {
562 CLog::Log(LOGERROR, "ADDON: %s missing <summary> element, ignoring", strPath.c_str());
563 return false;
564 }
565 addonProps.summary = element->GetText();
566
567 if (addonProps.type == ADDON_SCRAPER || addonProps.type == ADDON_PLUGIN)
568 {
569 /* Retrieve content types that this addon supports */
570 CStdString platform;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
571 if (rootElement->FirstChildElement("supportedcontent"))
af8cb2a Revert "wip"
alcoheca authored
572 {
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
573 element = rootElement->FirstChildElement("supportedcontent")->FirstChildElement("content");
af8cb2a Revert "wip"
alcoheca authored
574 }
575 if (!element)
576 {
577 CLog::Log(LOGERROR, "ADDON: %s missing <supportedcontent> element, ignoring", strPath.c_str());
578 return false;
579 }
580
88e9b6f changed: expand std namespace
spiff_ authored
581 set<CONTENT_TYPE> contents;
af8cb2a Revert "wip"
alcoheca authored
582 do
583 {
584 CONTENT_TYPE content = TranslateContent(element->GetText());
585 if (content != CONTENT_NONE)
586 {
587 contents.insert(content);
588 }
589 element = element->NextSiblingElement("content");
590 } while (element != NULL);
591
592 if (contents.empty())
593 {
594 CLog::Log(LOGERROR, "ADDON: %s %s supports no available content-types, ignoring", TranslateType(addonProps.type).c_str(), addonProps.name.c_str());
595 return false;
596 }
597 else
598 {
599 addonProps.contents = contents;
600 }
601 }
602
603 /*** Beginning of optional fields ***/
604 /* Retrieve description */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
605 element = rootElement->FirstChildElement("description");
af8cb2a Revert "wip"
alcoheca authored
606 if (element)
607 addonProps.description = element->GetText();
608
609 /* Retrieve author */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
610 element = rootElement->FirstChildElement("author");
af8cb2a Revert "wip"
alcoheca authored
611 if (element)
612 addonProps.author = element->GetText();
613
614 /* Retrieve disclaimer */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
615 element = rootElement->FirstChildElement("disclaimer");
af8cb2a Revert "wip"
alcoheca authored
616 if (element)
617 addonProps.disclaimer = element->GetText();
618
619 /* Retrieve library file name */
620 // will be replaced with default library name if unspecified
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
621 element = rootElement->FirstChildElement("library");
af8cb2a Revert "wip"
alcoheca authored
622 if (element)
623 addonProps.libname = element->GetText();
624
625 //TODO move this to addon specific class, if it's needed at all..
626 #ifdef _WIN32
627 /* Retrieve WIN32 library file name in case it is present
628 * This is required for no overwrite to the fixed WIN32 add-on's
629 * during compile time
630 */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
631 element = rootElement->FirstChildElement("librarywin32");
af8cb2a Revert "wip"
alcoheca authored
632 if (element) // If it is found overwrite standard library name
633 addonProps.libname = element->GetText();
634 #endif
635
636 /* Retrieve dependencies that this addon requires */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
637 element = rootElement->FirstChildElement("dependencies");
af8cb2a Revert "wip"
alcoheca authored
638 if (element)
639 {
640 element = element->FirstChildElement("dependency");
641 if (!element)
642 CLog::Log(LOGDEBUG, "ADDON: %s missing at least one <dependency> element, will ignore this dependency", strPath.c_str());
643 else
644 {
645 do
646 {
8a457f5 fixed: somebody must have had a blond moment - you can't check a stds…
spiff_ authored
647 const char* min = element->Attribute("minversion");
648 const char* max = element->Attribute("maxversion");
649 const char* id = element->GetText();
650 if (!id || (!min && !max))
af8cb2a Revert "wip"
alcoheca authored
651 {
652 CLog::Log(LOGDEBUG, "ADDON: %s malformed <dependency> element, will ignore this dependency", strPath.c_str());
8a457f5 fixed: somebody must have had a blond moment - you can't check a stds…
spiff_ authored
653 element = element->NextSiblingElement("dependency");
af8cb2a Revert "wip"
alcoheca authored
654 continue;
655 }
8a457f5 fixed: somebody must have had a blond moment - you can't check a stds…
spiff_ authored
656 addonProps.dependencies.insert(make_pair(CStdString(id), make_pair(AddonVersion(min?min:""), AddonVersion(max?max:""))));
af8cb2a Revert "wip"
alcoheca authored
657 element = element->NextSiblingElement("dependency");
658 } while (element != NULL);
659 }
660 }
661
662 /*** end of optional fields ***/
663
664 /* Create an addon object and store in a shared_ptr */
eca3c5b changed: refactor
spiff_ authored
665 addon = AddonFromProps(addonProps);
666
667 return addon.get() != NULL;
668 }
669
670 AddonPtr CAddonMgr::AddonFromProps(AddonProps& addonProps)
671 {
672 switch (addonProps.type)
af8cb2a Revert "wip"
alcoheca authored
673 {
674 case ADDON_PLUGIN:
675 case ADDON_SCRIPT:
eca3c5b changed: refactor
spiff_ authored
676 return AddonPtr(new CAddon(addonProps));
af8cb2a Revert "wip"
alcoheca authored
677 case ADDON_SCRAPER:
eca3c5b changed: refactor
spiff_ authored
678 return AddonPtr(new CScraper(addonProps));
af8cb2a Revert "wip"
alcoheca authored
679 case ADDON_VIZ:
eca3c5b changed: refactor
spiff_ authored
680 return AddonPtr(new CVisualisation(addonProps));
af8cb2a Revert "wip"
alcoheca authored
681 case ADDON_SCREENSAVER:
eca3c5b changed: refactor
spiff_ authored
682 return AddonPtr(new CScreenSaver(addonProps));
af8cb2a Revert "wip"
alcoheca authored
683 case ADDON_SCRAPER_LIBRARY:
684 case ADDON_VIZ_LIBRARY:
eca3c5b changed: refactor
spiff_ authored
685 return AddonPtr(new CAddonLibrary(addonProps));
606248f added: addon repository class
spiff_ authored
686 case ADDON_REPOSITORY:
687 return AddonPtr(new CRepository(addonProps));
af8cb2a Revert "wip"
alcoheca authored
688 default:
eca3c5b changed: refactor
spiff_ authored
689 break;
af8cb2a Revert "wip"
alcoheca authored
690 }
eca3c5b changed: refactor
spiff_ authored
691 return AddonPtr();
af8cb2a Revert "wip"
alcoheca authored
692 }
693
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
694 void CAddonMgr::UpdateRepos()
695 {
696 CSingleLock lock(m_critSection);
697 if (m_watch.GetElapsedSeconds() < 600)
698 return;
699 m_watch.StartZero();
700 VECADDONS addons;
701 GetAddons(ADDON_REPOSITORY,addons);
702 for (unsigned int i=0;i<addons.size();++i)
703 {
704 RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(addons[i]);
705 if (repo->LastUpdate()+CDateTimeSpan(0,6,0,0) < CDateTime::GetCurrentDateTime())
706 {
707 CLog::Log(LOGDEBUG,"Checking repository %s for updates",repo->Name().c_str());
708 CJobManager::GetInstance().AddJob(new CRepositoryUpdateJob(repo),this);
709 }
710 }
711 }
712
713 void CAddonMgr::OnJobComplete(unsigned int jobID, bool success, CJob* job)
714 {
715 if (!success)
716 return;
717
718 ((CRepositoryUpdateJob*)job)->m_repo->SetUpdated(CDateTime::GetCurrentDateTime());
719 }
720
074db86 merged: addons-fw branch
elupus authored
721 } /* namespace ADDON */
722
Something went wrong with that request. Please try again.