Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 1056 lines (946 sloc) 30.09 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"
1b2781c added: basic cpluff support
alcoheca authored
24 #include "DllLibCPluff.h"
074db86 merged: addons-fw branch
elupus authored
25 #include "StringUtils.h"
26 #include "RegExp.h"
27 #include "XMLUtils.h"
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
28 #include "utils/JobManager.h"
29 #include "utils/SingleLock.h"
074db86 merged: addons-fw branch
elupus authored
30 #include "FileItem.h"
822ca91 added: translatable <description>, <title>, <summary> and <disclaimer> i...
spiff_ authored
31 #include "LangInfo.h"
074db86 merged: addons-fw branch
elupus authored
32 #include "Settings.h"
33 #include "GUISettings.h"
34 #include "DownloadQueueManager.h"
1b2781c added: basic cpluff support
alcoheca authored
35 #include "AdvancedSettings.h"
dacdca0 changed: moved CAddonStatusHandler to separate files
alcoheca authored
36 #include "log.h"
074db86 merged: addons-fw branch
elupus authored
37
38 #ifdef HAS_VISUALISATION
055f806 cosmetic/tidyup move all addon classes to /xbmc/addons/
alcoheca authored
39 #include "DllVisualisation.h"
40 #include "Visualisation.h"
074db86 merged: addons-fw branch
elupus authored
41 #endif
42 #ifdef HAS_SCREENSAVER
055f806 cosmetic/tidyup move all addon classes to /xbmc/addons/
alcoheca authored
43 #include "DllScreenSaver.h"
44 #include "ScreenSaver.h"
074db86 merged: addons-fw branch
elupus authored
45 #endif
46 //#ifdef HAS_SCRAPERS
055f806 cosmetic/tidyup move all addon classes to /xbmc/addons/
alcoheca authored
47 #include "Scraper.h"
074db86 merged: addons-fw branch
elupus authored
48 //#endif
606248f added: addon repository class
spiff_ authored
49 #include "Repository.h"
553d213 changed: finished moving skins to addon framework
alcoheca authored
50 #include "Skin.h"
af8cb2a Revert "wip"
alcoheca authored
51
88e9b6f changed: expand std namespace
spiff_ authored
52 using namespace std;
53
074db86 merged: addons-fw branch
elupus authored
54 namespace ADDON
55 {
56
b6f0f59 cleanup: Don't expose the AddonManager's privates when not required.
jmarshallnz authored
57 cp_log_severity_t clog_to_cp(int lvl);
58 void cp_fatalErrorHandler(const char *msg);
59 void cp_logger(cp_log_severity_t level, const char *msg, const char *apid, void *user_data);
074db86 merged: addons-fw branch
elupus authored
60
61 /**********************************************************
62 * CAddonMgr
63 *
64 */
65
88e9b6f changed: expand std namespace
spiff_ authored
66 map<TYPE, IAddonMgrCallback*> CAddonMgr::m_managers;
074db86 merged: addons-fw branch
elupus authored
67
c14bf20 changed: moved addonptr factory to CAddonMgr.
alcoheca authored
68 AddonPtr CAddonMgr::Factory(const cp_extension_t *props)
1b2781c added: basic cpluff support
alcoheca authored
69 {
bb4e01c Support creating userdirs in addons. This also has the benefit of being ...
ceros7 authored
70 /* Check if user directories need to be created */
71 const cp_cfg_element_t *settings = GetExtElement(props->plugin->extensions->configuration, "settings");
72 if (settings)
73 CheckUserDirs(settings);
74
1b2781c added: basic cpluff support
alcoheca authored
75 const TYPE type = TranslateType(props->ext_point_id);
76 switch (type)
77 {
78 case ADDON_PLUGIN:
79 case ADDON_SCRIPT:
80 return AddonPtr(new CAddon(props->plugin));
81 case ADDON_SCRAPER:
82 return AddonPtr(new CScraper(props->plugin));
83 case ADDON_VIZ:
84 case ADDON_SCREENSAVER:
c14bf20 changed: moved addonptr factory to CAddonMgr.
alcoheca authored
85 { // begin temporary platform handling for Dlls
86 // ideally platforms issues will be handled by C-Pluff
87 // this is not an attempt at a solution
88 CStdString value;
89 #if defined(_LINUX) && !defined(__APPLE__)
90 if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_linux")) && value.empty())
91 break;
92 #elif defined(_WIN32) && defined(HAS_SDL_OPENGL)
93 if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_wingl")) && value.empty())
94 break;
95 #elif defined(_WIN32) && defined(HAS_DX)
96 if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_windx")) && value.empty())
97 break;
98 #elif defined(__APPLE__)
99 if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_osx")) && value.empty())
100 break;
101 #elif defined(_XBOX)
102 if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_xbox")) && value.empty())
103 break;
104 #endif
105 if (type == ADDON_VIZ)
07e5742 [arm] merge arm-camelot into trunk, thanks to mcgeagh for all his hard w...
davilla authored
106 {
107 #if defined(HAS_VISUALISATION)
c14bf20 changed: moved addonptr factory to CAddonMgr.
alcoheca authored
108 return AddonPtr(new CVisualisation(props->plugin));
07e5742 [arm] merge arm-camelot into trunk, thanks to mcgeagh for all his hard w...
davilla authored
109 #endif
110 }
c14bf20 changed: moved addonptr factory to CAddonMgr.
alcoheca authored
111 else
112 return AddonPtr(new CScreenSaver(props->plugin));
113 }
5ff028a added: skin support via cpluff
alcoheca authored
114 case ADDON_SKIN:
115 return AddonPtr(new CSkinInfo(props->plugin));
1b2781c added: basic cpluff support
alcoheca authored
116 case ADDON_SCRAPER_LIBRARY:
117 case ADDON_VIZ_LIBRARY:
118 return AddonPtr(new CAddonLibrary(props->plugin));
9ea9065 changed: Move repositories to cpluff
jmarshallnz authored
119 case ADDON_REPOSITORY:
120 return AddonPtr(new CRepository(props->plugin));
1b2781c added: basic cpluff support
alcoheca authored
121 default:
c14bf20 changed: moved addonptr factory to CAddonMgr.
alcoheca authored
122 break;
1b2781c added: basic cpluff support
alcoheca authored
123 }
c14bf20 changed: moved addonptr factory to CAddonMgr.
alcoheca authored
124 return AddonPtr();
1b2781c added: basic cpluff support
alcoheca authored
125 }
126
bb4e01c Support creating userdirs in addons. This also has the benefit of being ...
ceros7 authored
127 bool CAddonMgr::CheckUserDirs(const cp_cfg_element_t *settings)
128 {
129 if (!settings)
130 return false;
131
132 const cp_cfg_element_t *userdirs = GetExtElement((cp_cfg_element_t *)settings, "userdirs");
133 if (!userdirs)
134 return false;
135
136 DEQUEELEMENTS elements;
137 bool status = GetExtElementDeque(elements, (cp_cfg_element_t *)userdirs, "userdir");
138 if (!status)
139 return false;
140
141 IDEQUEELEMENTS itr = elements.begin();
142 while (itr != elements.end())
143 {
144 CStdString path = GetExtValue(*itr++, "@path");
145 if (!CFile::Exists(path))
146 {
147 if (!CUtil::CreateDirectoryEx(path))
148 {
149 CLog::Log(LOGERROR, "CAddonMgr::CheckUserDirs: Unable to create directory %s.", path.c_str());
150 return false;
151 }
152 }
153 }
154
155 return true;
156 }
157
074db86 merged: addons-fw branch
elupus authored
158 CAddonMgr::CAddonMgr()
159 {
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
160 FindAddons();
161 m_watch.StartZero();
074db86 merged: addons-fw branch
elupus authored
162 }
163
164 CAddonMgr::~CAddonMgr()
165 {
37a994e added: Deinit to the addons manager to ensure we unload cpluff prior to ...
jmarshallnz authored
166 DeInit();
074db86 merged: addons-fw branch
elupus authored
167 }
168
47a8196 changed: matched other singelton calls
alcoheca authored
169 CAddonMgr &CAddonMgr::Get()
074db86 merged: addons-fw branch
elupus authored
170 {
47a8196 changed: matched other singelton calls
alcoheca authored
171 static CAddonMgr sAddonMgr;
172 return sAddonMgr;
074db86 merged: addons-fw branch
elupus authored
173 }
174
175 IAddonMgrCallback* CAddonMgr::GetCallbackForType(TYPE type)
176 {
177 if (m_managers.find(type) == m_managers.end())
178 return NULL;
179 else
180 return m_managers[type];
181 }
182
183 bool CAddonMgr::RegisterAddonMgrCallback(const TYPE type, IAddonMgrCallback* cb)
184 {
185 if (cb == NULL)
186 return false;
187
188 m_managers.erase(type);
189 m_managers[type] = cb;
190
191 return true;
192 }
193
194 void CAddonMgr::UnregisterAddonMgrCallback(TYPE type)
195 {
196 m_managers.erase(type);
197 }
198
1b2781c added: basic cpluff support
alcoheca authored
199 bool CAddonMgr::Init()
200 {
201 m_cpluff = new DllLibCPluff;
202 m_cpluff->Load();
203
204 if (!m_cpluff->IsLoaded())
205 {
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
206 CLog::Log(LOGERROR, "ADDONS: Fatal Error, could not load libcpluff");
207 return false;
1b2781c added: basic cpluff support
alcoheca authored
208 }
209
210 m_cpluff->set_fatal_error_handler(cp_fatalErrorHandler);
211
212 cp_status_t status;
213 status = m_cpluff->init();
214 if (status != CP_OK)
215 {
216 CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_init() returned status: %i", status);
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
217 return false;
1b2781c added: basic cpluff support
alcoheca authored
218 }
219
220 //TODO could separate addons into different contexts
221 // would allow partial unloading of addon framework
222 m_cp_context = m_cpluff->create_context(&status);
223 assert(m_cp_context);
224 if (!CSpecialProtocol::XBMCIsHome())
225 {
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
226 status = m_cpluff->register_pcollection(m_cp_context, _P("special://home/addons"));
227 }
228 status = m_cpluff->register_pcollection(m_cp_context, _P("special://xbmc/addons"));
229 if (status != CP_OK)
230 {
231 CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_pcollection() returned status: %i", status);
232 return false;
1b2781c added: basic cpluff support
alcoheca authored
233 }
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
234
185686a added: even more missing from r29798
alcoheca authored
235 status = m_cpluff->register_logger(m_cp_context, cp_logger,
7188808 changed: bail out immeditaly if CAddonMgr::Init returns false
alcoheca authored
236 &CAddonMgr::Get(), clog_to_cp(g_advancedSettings.m_logLevel));
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
237 if (status != CP_OK)
238 {
239 CLog::Log(LOGERROR, "ADDONS: Fatal Error, cp_register_logger() returned status: %i", status);
240 return false;
241 }
1b2781c added: basic cpluff support
alcoheca authored
242
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
243 status = m_cpluff->scan_plugins(m_cp_context, 0);
244 return true;
1b2781c added: basic cpluff support
alcoheca authored
245 }
246
37a994e added: Deinit to the addons manager to ensure we unload cpluff prior to ...
jmarshallnz authored
247 void CAddonMgr::DeInit()
248 {
249 if (m_cpluff)
250 m_cpluff->destroy();
251 m_cpluff = NULL;
252 }
253
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
254 bool CAddonMgr::HasAddons(const TYPE &type, const CONTENT_TYPE &content/*= CONTENT_NONE*/, bool enabledOnly/*= true*/)
074db86 merged: addons-fw branch
elupus authored
255 {
2122c0b fixed: need to provide new lib names to Dll Addons
alcoheca authored
256 if (type == ADDON_SCREENSAVER || type == ADDON_SKIN || type == ADDON_VIZ)
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
257 {
258 cp_status_t status;
259 int num;
260 CStdString ext_point(TranslateType(type));
2ff4a7d fixed: didn't release all ref counted objects returned from cpluff
alcoheca authored
261 cp_extension_t **exts = m_cpluff->get_extensions_info(m_cp_context, ext_point.c_str(), &status, &num);
262 m_cpluff->release_info(m_cp_context, exts);
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
263 if (status == CP_OK)
264 return (num > 0);
265 }
266
af8cb2a Revert "wip"
alcoheca authored
267 if (m_addons.empty())
268 {
269 VECADDONS add;
270 GetAllAddons(add,false);
271 }
272
273 if (content == CONTENT_NONE)
274 return (m_addons.find(type) != m_addons.end());
074db86 merged: addons-fw branch
elupus authored
275
276 VECADDONS addons;
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
277 return GetAddons(type, addons, content, enabledOnly);
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
278
074db86 merged: addons-fw branch
elupus authored
279 }
280
281 bool CAddonMgr::GetAllAddons(VECADDONS &addons, bool enabledOnly/*= true*/)
282 {
af8cb2a Revert "wip"
alcoheca authored
283 VECADDONS temp;
7188808 changed: bail out immeditaly if CAddonMgr::Init returns false
alcoheca authored
284 if (CAddonMgr::Get().GetAddons(ADDON_PLUGIN, temp, CONTENT_NONE, enabledOnly))
af8cb2a Revert "wip"
alcoheca authored
285 addons.insert(addons.end(), temp.begin(), temp.end());
7188808 changed: bail out immeditaly if CAddonMgr::Init returns false
alcoheca authored
286 if (CAddonMgr::Get().GetAddons(ADDON_SCRAPER, temp, CONTENT_NONE, enabledOnly))
af8cb2a Revert "wip"
alcoheca authored
287 addons.insert(addons.end(), temp.begin(), temp.end());
7188808 changed: bail out immeditaly if CAddonMgr::Init returns false
alcoheca authored
288 if (CAddonMgr::Get().GetAddons(ADDON_SCREENSAVER, temp, CONTENT_NONE, enabledOnly))
af8cb2a Revert "wip"
alcoheca authored
289 addons.insert(addons.end(), temp.begin(), temp.end());
7188808 changed: bail out immeditaly if CAddonMgr::Init returns false
alcoheca authored
290 if (CAddonMgr::Get().GetAddons(ADDON_SCRIPT, temp, CONTENT_NONE, enabledOnly))
af8cb2a Revert "wip"
alcoheca authored
291 addons.insert(addons.end(), temp.begin(), temp.end());
7188808 changed: bail out immeditaly if CAddonMgr::Init returns false
alcoheca authored
292 if (CAddonMgr::Get().GetAddons(ADDON_SKIN, temp, CONTENT_NONE, enabledOnly))
553d213 changed: finished moving skins to addon framework
alcoheca authored
293 addons.insert(addons.end(), temp.begin(), temp.end());
7188808 changed: bail out immeditaly if CAddonMgr::Init returns false
alcoheca authored
294 if (CAddonMgr::Get().GetAddons(ADDON_VIZ, temp, CONTENT_NONE, enabledOnly))
af8cb2a Revert "wip"
alcoheca authored
295 addons.insert(addons.end(), temp.begin(), temp.end());
296 return !addons.empty();
074db86 merged: addons-fw branch
elupus authored
297 }
298
299 bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, const CONTENT_TYPE &content/*= CONTENT_NONE*/, bool enabledOnly/*= true*/)
300 {
4e5b98a added: locks to addon manager
spiff_ authored
301 CSingleLock lock(m_critSection);
af8cb2a Revert "wip"
alcoheca authored
302 addons.clear();
9ea9065 changed: Move repositories to cpluff
jmarshallnz authored
303 if (type == ADDON_SCREENSAVER || type == ADDON_SKIN || type == ADDON_VIZ || type == ADDON_REPOSITORY)
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
304 {
305 cp_status_t status;
306 int num;
307 CStdString ext_point(TranslateType(type));
308 cp_extension_t **exts = m_cpluff->get_extensions_info(m_cp_context, ext_point.c_str(), &status, &num);
309 for(int i=0; i <num; i++)
310 {
c14bf20 changed: moved addonptr factory to CAddonMgr.
alcoheca authored
311 AddonPtr addon(Factory(exts[i]));
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
312 if (addon)
313 addons.push_back(addon);
314 }
315 m_cpluff->release_info(m_cp_context, exts);
6933a8d fixed: compile warning
jmarshallnz authored
316 return addons.size() > 0;
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
317 }
318
af8cb2a Revert "wip"
alcoheca authored
319 if (m_addons.find(type) != m_addons.end())
320 {
321 IVECADDONS itr = m_addons[type].begin();
322 while (itr != m_addons[type].end())
323 { // filter out what we're not looking for
dea84cb changed: Disabled() -> Enabled() - more intuitive
spiff_ authored
324 if ((enabledOnly && !(*itr)->Enabled())
af8cb2a Revert "wip"
alcoheca authored
325 || (content != CONTENT_NONE && !(*itr)->Supports(content)))
326 {
327 ++itr;
328 continue;
329 }
330 addons.push_back(*itr);
331 ++itr;
332 }
333 }
334 return !addons.empty();
074db86 merged: addons-fw branch
elupus authored
335 }
336
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
337 bool CAddonMgr::GetAddon(const CStdString &str, AddonPtr &addon, const TYPE &type/*=ADDON_UNKNOWN*/, bool enabledOnly/*= true*/)
074db86 merged: addons-fw branch
elupus authored
338 {
4e5b98a added: locks to addon manager
spiff_ authored
339 CSingleLock lock(m_critSection);
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
340 if (type != ADDON_UNKNOWN
341 && type != ADDON_SCREENSAVER
5ff028a added: skin support via cpluff
alcoheca authored
342 && type != ADDON_SKIN
f14b201 changed: support visualizations via cpluff
alcoheca authored
343 && type != ADDON_VIZ
9ea9065 changed: Move repositories to cpluff
jmarshallnz authored
344 && type != ADDON_REPOSITORY
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
345 && m_addons.find(type) == m_addons.end())
074db86 merged: addons-fw branch
elupus authored
346 return false;
347
c22f535 cosmetics
alcoheca authored
348 cp_status_t status;
349 cp_plugin_info_t *cpaddon = NULL;
350 cpaddon = m_cpluff->get_plugin_info(m_cp_context, str.c_str(), &status);
351 if (status == CP_OK && cpaddon->extensions)
352 {
353 addon = Factory(cpaddon->extensions);
354 m_cpluff->release_info(m_cp_context, cpaddon);
355 return true;
356 }
357 if (cpaddon)
358 m_cpluff->release_info(m_cp_context, cpaddon);
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
359
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
360 if (m_idMap[str])
361 {
362 addon = m_idMap[str];
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
363 if(enabledOnly)
dea84cb changed: Disabled() -> Enabled() - more intuitive
spiff_ authored
364 return addon->Enabled();
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
365 else
366 return true;
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
367 }
074db86 merged: addons-fw branch
elupus authored
368
369 VECADDONS &addons = m_addons[type];
370 IVECADDONS adnItr = addons.begin();
371 while (adnItr != addons.end())
372 {
373 //FIXME scrapers were previously registered by filename
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
374 if ((*adnItr)->Name() == str || (type == ADDON_SCRAPER && (*adnItr)->LibName() == str))
074db86 merged: addons-fw branch
elupus authored
375 {
376 addon = (*adnItr);
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
377 if(enabledOnly)
dea84cb changed: Disabled() -> Enabled() - more intuitive
spiff_ authored
378 return addon->Enabled();
cc3b982 fixed: don't crash if an (visualization) addon is disabled
elupus authored
379 else
380 return true;
074db86 merged: addons-fw branch
elupus authored
381 }
382 adnItr++;
383 }
384
385 return false;
386 }
387
388 //TODO handle all 'default' cases here, not just scrapers & vizs
389 bool CAddonMgr::GetDefault(const TYPE &type, AddonPtr &addon, const CONTENT_TYPE &content)
390 {
391 if (type != ADDON_SCRAPER && type != ADDON_VIZ)
392 return false;
393
394 CStdString setting;
395 if (type == ADDON_VIZ)
396 setting = g_guiSettings.GetString("musicplayer.visualisation");
397 else
398 {
399 switch (content)
400 {
401 case CONTENT_MOVIES:
402 {
403 setting = g_guiSettings.GetString("scrapers.moviedefault");
404 break;
405 }
406 case CONTENT_TVSHOWS:
407 {
408 setting = g_guiSettings.GetString("scrapers.tvshowdefault");
409 break;
410 }
411 case CONTENT_MUSICVIDEOS:
412 {
413 setting = g_guiSettings.GetString("scrapers.musicvideodefault");
414 break;
415 }
416 case CONTENT_ALBUMS:
417 case CONTENT_ARTISTS:
418 {
419 setting = g_guiSettings.GetString("musiclibrary.scraper");
420 break;
421 }
422 default:
423 return false;
424 }
425 }
2ca76f9 changed: all addons should be store below either special://home/addons o...
alcoheca authored
426 return GetAddon(setting, addon, type);
074db86 merged: addons-fw branch
elupus authored
427 }
428
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
429 CStdString CAddonMgr::GetString(const CStdString &id, const int number)
074db86 merged: addons-fw branch
elupus authored
430 {
7411555 changed: renamed UUID to ID. we now accept any string as an identifier,
alcoheca authored
431 AddonPtr addon = m_idMap[id];
074db86 merged: addons-fw branch
elupus authored
432 if (addon)
433 return addon->GetString(number);
434
435 return "";
436 }
437
af8cb2a Revert "wip"
alcoheca authored
438 void CAddonMgr::FindAddons()
439 {
4e5b98a added: locks to addon manager
spiff_ authored
440 CSingleLock lock(m_critSection);
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
441 m_addons.clear();
442 m_idMap.clear();
c8f3bba fixed: dependency resolving
spiff_ authored
443
444 // store any addons with unresolved deps, then recheck at the end
445 map<CStdString, AddonPtr> unresolved;
446
28831ed fixed: don't check special://xbmc/addons twice when running with -p
alcoheca authored
447 if (!CSpecialProtocol::XBMCIsHome())
c8f3bba fixed: dependency resolving
spiff_ authored
448 LoadAddons("special://home/addons",unresolved);
449 LoadAddons("special://xbmc/addons",unresolved);
450
451 for (map<CStdString,AddonPtr>::iterator it = unresolved.begin();
452 it != unresolved.end(); ++it)
453 {
454 if (DependenciesMet(it->second))
455 {
456 if (!UpdateIfKnown(it->second))
457 {
458 m_addons[it->second->Type()].push_back(it->second);
459 m_idMap.insert(make_pair(it->first,it->second));
460 }
461 }
462 }
535b4e7 changed: load addons from user directory first, then load from system di...
elupus authored
463 }
464
c8f3bba fixed: dependency resolving
spiff_ authored
465 void CAddonMgr::LoadAddons(const CStdString &path,
466 map<CStdString, AddonPtr>& unresolved)
535b4e7 changed: load addons from user directory first, then load from system di...
elupus authored
467 {
af8cb2a Revert "wip"
alcoheca authored
468 // parse the user & system dirs for addons of the requested type
469 CFileItemList items;
535b4e7 changed: load addons from user directory first, then load from system di...
elupus authored
470 CDirectory::GetDirectory(path, items);
af8cb2a Revert "wip"
alcoheca authored
471
472 // for all folders found
473 for (int i = 0; i < items.Size(); ++i)
474 {
475 CFileItemPtr item = items[i];
476
477 if(!item->m_bIsFolder)
478 continue;
479
480 // read description.xml and populate the addon
481 AddonPtr addon;
482 if (!AddonFromInfoXML(item->m_strPath, addon))
483 continue;
484
535b4e7 changed: load addons from user directory first, then load from system di...
elupus authored
485 // only load if addon with same id isn't already loaded
c8f3bba fixed: dependency resolving
spiff_ authored
486 if(m_idMap.find(addon->ID()) != m_idMap.end() ||
487 unresolved.find(addon->ID()) != unresolved.end())
535b4e7 changed: load addons from user directory first, then load from system di...
elupus authored
488 {
489 CLog::Log(LOGDEBUG, "ADDON: already loaded id %s, bypassing package", addon->ID().c_str());
490 continue;
491 }
492
af8cb2a Revert "wip"
alcoheca authored
493 // refuse to store addons with missing library
494 CStdString library(CUtil::AddFileToFolder(addon->Path(), addon->LibName()));
495 if (!CFile::Exists(library))
496 {
497 CLog::Log(LOGDEBUG, "ADDON: Missing library file %s, bypassing package", library.c_str());
498 continue;
499 }
500
501 if (!DependenciesMet(addon))
502 {
c8f3bba fixed: dependency resolving
spiff_ authored
503 unresolved.insert(make_pair(addon->ID(),addon));
af8cb2a Revert "wip"
alcoheca authored
504 continue;
505 }
506 else
507 { // everything ok, add to available addons if new
508 if (UpdateIfKnown(addon))
509 continue;
510 else
511 {
512 m_addons[addon->Type()].push_back(addon);
88e9b6f changed: expand std namespace
spiff_ authored
513 m_idMap.insert(make_pair(addon->ID(), addon));
af8cb2a Revert "wip"
alcoheca authored
514 }
515 }
516 }
517 }
518
519 bool CAddonMgr::UpdateIfKnown(AddonPtr &addon)
520 {
521 if (m_addons.find(addon->Type()) != m_addons.end())
522 {
523 for (unsigned i = 0; i < m_addons[addon->Type()].size(); i++)
524 {
525 if (m_addons[addon->Type()][i]->ID() == addon->ID())
526 {
527 //TODO inform any manager first, and request removal
528 //TODO choose most recent version if varying
529 m_addons[addon->Type()][i] = addon;
530 CStdString id = addon->ID();
531 m_idMap.erase(id);
88e9b6f changed: expand std namespace
spiff_ authored
532 m_idMap.insert(make_pair(addon->ID(), addon));
af8cb2a Revert "wip"
alcoheca authored
533 return true;
534 }
535 }
536 }
537 return false;
538 }
539
540 bool CAddonMgr::DependenciesMet(AddonPtr &addon)
541 {
542 if (!addon)
543 return false;
544
4e5b98a added: locks to addon manager
spiff_ authored
545 CSingleLock lock(m_critSection);
af8cb2a Revert "wip"
alcoheca authored
546 ADDONDEPS deps = addon->GetDeps();
547 ADDONDEPS::iterator itr = deps.begin();
548 while (itr != deps.end())
549 {
550 CStdString id;
551 id = (*itr).first;
552 AddonVersion min = (*itr).second.first;
553 AddonVersion max = (*itr).second.second;
554 if (m_idMap.count(id))
555 {
556 AddonPtr dep = m_idMap[id];
557 // we're guaranteed to have at least max OR min here
558 if (!min.str.IsEmpty() && !max.str.IsEmpty())
c8f3bba fixed: dependency resolving
spiff_ authored
559 {
560 if (dep->Version() < min || dep->Version() > max)
561 return false;
562 }
af8cb2a Revert "wip"
alcoheca authored
563 else if (!min.str.IsEmpty())
c8f3bba fixed: dependency resolving
spiff_ authored
564 {
565 if (dep->Version() < min)
566 return false;
567 }
af8cb2a Revert "wip"
alcoheca authored
568 else
c8f3bba fixed: dependency resolving
spiff_ authored
569 {
570 if (dep->Version() > max)
571 return false;
572 }
af8cb2a Revert "wip"
alcoheca authored
573 }
574 itr++;
575 }
c8f3bba fixed: dependency resolving
spiff_ authored
576 return true;
af8cb2a Revert "wip"
alcoheca authored
577 }
578
579 bool CAddonMgr::AddonFromInfoXML(const CStdString &path, AddonPtr &addon)
580 {
581 // First check that we can load description.xml
582 CStdString strPath(CUtil::AddFileToFolder(path, ADDON_METAFILE));
583 if(!CFile::Exists(strPath))
584 return false;
585
586 TiXmlDocument xmlDoc;
587 if (!xmlDoc.LoadFile(strPath))
588 {
589 CLog::Log(LOGERROR, "Unable to load: %s, Line %d\n%s", strPath.c_str(), xmlDoc.ErrorRow(), xmlDoc.ErrorDesc());
590 return false;
591 }
592
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
593 const TiXmlElement *element = xmlDoc.RootElement();
af8cb2a Revert "wip"
alcoheca authored
594 if (!element || strcmpi(element->Value(), "addoninfo") != 0)
595 {
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
596 CLog::Log(LOGERROR, "ADDON: Error loading %s: cannot find <addon> root element", xmlDoc.Value());
af8cb2a Revert "wip"
alcoheca authored
597 return false;
598 }
599
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
600 return AddonFromInfoXML(element, addon, strPath);
601 }
602
603 bool CAddonMgr::AddonFromInfoXML(const TiXmlElement *rootElement,
604 AddonPtr &addon, const CStdString &strPath)
605 {
af8cb2a Revert "wip"
alcoheca authored
606 /* Steps required to meet package requirements
607 * 1. id exists and is valid
608 * 2. type exists and is valid
609 * 3. version exists
610 * 4. a license is specified
611 * 5. operating system matches ours
612 * 6. summary exists
613 * 7. for scrapers & plugins, support at least one type of content
614 *
615 * NOTE: addon dependencies are handled in ::FindAddons()
616 */
617
618 /* Validate id */
619 CStdString id;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
620 const TiXmlElement *element = rootElement->FirstChildElement("id");
af8cb2a Revert "wip"
alcoheca authored
621 if (!element)
622 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
623 CLog::Log(LOGERROR, "ADDON: %s missing <id> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
624 return false;
625 }
626 id = element->GetText();
627 //FIXME since we no longer required uuids, should we bother validating anything?
628 if (id.IsEmpty())
629 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
630 CLog::Log(LOGERROR, "ADDON: %s has invalid <id> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
631 return false;
632 }
633
634 /* Validate type */
635 TYPE type;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
636 element = rootElement->FirstChildElement("type");
af8cb2a Revert "wip"
alcoheca authored
637 if (!element)
638 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
639 CLog::Log(LOGERROR, "ADDON: %s missing <type> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
640 return false;
641 }
642 type = TranslateType(element->GetText());
643 if (type == ADDON_UNKNOWN)
644 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
645 CLog::Log(LOGERROR, "ADDON: %s has invalid type identifier: '%d'", rootElement->GetDocument()->Value(), type);
af8cb2a Revert "wip"
alcoheca authored
646 return false;
647 }
648
649 /* Retrieve Name */
650 CStdString name;
822ca91 added: translatable <description>, <title>, <summary> and <disclaimer> i...
spiff_ authored
651 if (!GetTranslatedString(rootElement,"title",name))
af8cb2a Revert "wip"
alcoheca authored
652 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
653 CLog::Log(LOGERROR, "ADDON: %s missing <title> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
654 return false;
655 }
656
657 /* Retrieve version */
658 CStdString version;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
659 element = rootElement->FirstChildElement("version");
af8cb2a Revert "wip"
alcoheca authored
660 if (!element)
661 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
662 CLog::Log(LOGERROR, "ADDON: %s missing <version> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
663 return false;
664 }
665 /* Validate version */
666 version = element->GetText();
667 CRegExp versionRE;
668 versionRE.RegComp(ADDON_VERSION_RE.c_str());
669 if (versionRE.RegFind(version.c_str()) != 0)
670 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
671 CLog::Log(LOGERROR, "ADDON: %s has invalid <version> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
672 return false;
673 }
674
675 /* Path, ID & Version are valid */
676 AddonProps addonProps(id, type, version);
677 addonProps.name = name;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
678 CUtil::GetDirectory(strPath,addonProps.path);
a594abe changed: move addon thumbs back to a fixed image (icon.png). We still h...
jmarshallnz authored
679 /* Set Icon */
680 addonProps.icon = "icon.png";
e90479d added: addon changelog support
spiff_ authored
681 /* Set Changelog */
682 addonProps.changelog = CUtil::AddFileToFolder(addonProps.path,"changelog.txt");
d9e6ddf added: fanart support for addons
spiff_ authored
683 /* Set Fanart */
d3c62cd fixed: Addon changelogs weren't being read.
jmarshallnz authored
684 addonProps.fanart = CUtil::AddFileToFolder(addonProps.path,"fanart.jpg");
af8cb2a Revert "wip"
alcoheca authored
685
686 /* Retrieve license */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
687 element = rootElement->FirstChildElement("license");
af8cb2a Revert "wip"
alcoheca authored
688 /* if (!element)
689 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
690 CLog::Log(LOGERROR, "ADDON: %s missing <license> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
691 return false;
692 }
693 addonProps.license = element->GetText();*/
694
695 /* Retrieve platforms which this addon supports */
696 CStdString platform;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
697 element = rootElement->FirstChildElement("platforms")->FirstChildElement("platform");
af8cb2a Revert "wip"
alcoheca authored
698 if (!element)
699 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
700 CLog::Log(LOGERROR, "ADDON: %s missing <platforms> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
701 return false;
702 }
703
704 bool all(false);
88e9b6f changed: expand std namespace
spiff_ authored
705 set<CStdString> platforms;
af8cb2a Revert "wip"
alcoheca authored
706 do
707 {
708 CStdString platform = element->GetText();
709 if (platform == "all")
710 {
711 all = true;
712 break;
713 }
714 platforms.insert(platform);
715 element = element->NextSiblingElement("platform");
716 } while (element != NULL);
717
718 if (!all)
719 {
720 #if defined(_LINUX) && !defined(__APPLE__)
721 if (!platforms.count("linux"))
722 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
723 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under Linux, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
724 return false;
725 }
78d5324 added: separate addon platforms for windows+dx and windows+opengl
spiff_ authored
726 #elif defined(_WIN32) && defined(HAS_SDL_OPENGL)
727 if (!platforms.count("windows-gl") && !platforms.count("windows"))
af8cb2a Revert "wip"
alcoheca authored
728 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
729 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under Windows/OpenGL, ignoring", rootElement->GetDocument()->Value());
78d5324 added: separate addon platforms for windows+dx and windows+opengl
spiff_ authored
730 return false;
731 }
732 #elif defined(_WIN32) && defined(HAS_DX)
733 if (!platforms.count("windows-dx") && !platforms.count("windows"))
734 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
735 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under Windows/DirectX, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
736 return false;
737 }
738 #elif defined(__APPLE__)
739 if (!platforms.count("osx"))
740 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
741 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under OSX, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
742 return false;
743 }
744 #elif defined(_XBOX)
745 if (!platforms.count("xbox"))
746 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
747 CLog::Log(LOGNOTICE, "ADDON: %s is not supported under XBOX, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
748 return false;
749 }
750 #endif
751 }
752
753 /* Retrieve summary */
d10c108 fixed: missing addon summary.
jmarshallnz authored
754 if (!GetTranslatedString(rootElement,"summary",addonProps.summary))
af8cb2a Revert "wip"
alcoheca authored
755 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
756 CLog::Log(LOGERROR, "ADDON: %s missing <summary> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
757 return false;
758 }
759
760 if (addonProps.type == ADDON_SCRAPER || addonProps.type == ADDON_PLUGIN)
761 {
762 /* Retrieve content types that this addon supports */
763 CStdString platform;
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
764 if (rootElement->FirstChildElement("supportedcontent"))
af8cb2a Revert "wip"
alcoheca authored
765 {
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
766 element = rootElement->FirstChildElement("supportedcontent")->FirstChildElement("content");
af8cb2a Revert "wip"
alcoheca authored
767 }
768 if (!element)
769 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
770 CLog::Log(LOGERROR, "ADDON: %s missing <supportedcontent> element, ignoring", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
771 return false;
772 }
773
88e9b6f changed: expand std namespace
spiff_ authored
774 set<CONTENT_TYPE> contents;
af8cb2a Revert "wip"
alcoheca authored
775 do
776 {
777 CONTENT_TYPE content = TranslateContent(element->GetText());
778 if (content != CONTENT_NONE)
779 {
780 contents.insert(content);
781 }
782 element = element->NextSiblingElement("content");
783 } while (element != NULL);
784
785 if (contents.empty())
786 {
787 CLog::Log(LOGERROR, "ADDON: %s %s supports no available content-types, ignoring", TranslateType(addonProps.type).c_str(), addonProps.name.c_str());
788 return false;
789 }
790 else
791 {
792 addonProps.contents = contents;
793 }
794 }
795
796 /*** Beginning of optional fields ***/
309adab changed: Read addon icon from the <icon> tag rather than assuming defaul...
jmarshallnz authored
797 /* Retrieve icon */
798 element = rootElement->FirstChildElement("icon");
799 if (element)
800 addonProps.icon = element->GetText();
801
af8cb2a Revert "wip"
alcoheca authored
802 /* Retrieve description */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
803 element = rootElement->FirstChildElement("description");
822ca91 added: translatable <description>, <title>, <summary> and <disclaimer> i...
spiff_ authored
804 GetTranslatedString(rootElement,"description",addonProps.description);
af8cb2a Revert "wip"
alcoheca authored
805
806 /* Retrieve author */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
807 element = rootElement->FirstChildElement("author");
af8cb2a Revert "wip"
alcoheca authored
808 if (element)
809 addonProps.author = element->GetText();
810
811 /* Retrieve disclaimer */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
812 element = rootElement->FirstChildElement("disclaimer");
822ca91 added: translatable <description>, <title>, <summary> and <disclaimer> i...
spiff_ authored
813 GetTranslatedString(rootElement,"disclaimer",addonProps.disclaimer);
af8cb2a Revert "wip"
alcoheca authored
814
815 /* Retrieve library file name */
816 // will be replaced with default library name if unspecified
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
817 element = rootElement->FirstChildElement("library");
af8cb2a Revert "wip"
alcoheca authored
818 if (element)
819 addonProps.libname = element->GetText();
820
821 //TODO move this to addon specific class, if it's needed at all..
822 #ifdef _WIN32
823 /* Retrieve WIN32 library file name in case it is present
824 * This is required for no overwrite to the fixed WIN32 add-on's
825 * during compile time
826 */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
827 element = rootElement->FirstChildElement("librarywin32");
af8cb2a Revert "wip"
alcoheca authored
828 if (element) // If it is found overwrite standard library name
829 addonProps.libname = element->GetText();
830 #endif
831
832 /* Retrieve dependencies that this addon requires */
4ccec44 changed: refactor addon info loading to make it reusable elsewhere
spiff_ authored
833 element = rootElement->FirstChildElement("dependencies");
af8cb2a Revert "wip"
alcoheca authored
834 if (element)
835 {
836 element = element->FirstChildElement("dependency");
837 if (!element)
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
838 CLog::Log(LOGDEBUG, "ADDON: %s missing at least one <dependency> element, will ignore this dependency", rootElement->GetDocument()->Value());
af8cb2a Revert "wip"
alcoheca authored
839 else
840 {
841 do
842 {
8a457f5 fixed: somebody must have had a blond moment - you can't check a stdstri...
spiff_ authored
843 const char* min = element->Attribute("minversion");
844 const char* max = element->Attribute("maxversion");
845 const char* id = element->GetText();
846 if (!id || (!min && !max))
af8cb2a Revert "wip"
alcoheca authored
847 {
349765e cleanup: Removed unnecessary code and changed logging code in addons to ...
jmarshallnz authored
848 CLog::Log(LOGDEBUG, "ADDON: %s malformed <dependency> element, will ignore this dependency", rootElement->GetDocument()->Value());
8a457f5 fixed: somebody must have had a blond moment - you can't check a stdstri...
spiff_ authored
849 element = element->NextSiblingElement("dependency");
af8cb2a Revert "wip"
alcoheca authored
850 continue;
851 }
8a457f5 fixed: somebody must have had a blond moment - you can't check a stdstri...
spiff_ authored
852 addonProps.dependencies.insert(make_pair(CStdString(id), make_pair(AddonVersion(min?min:""), AddonVersion(max?max:""))));
af8cb2a Revert "wip"
alcoheca authored
853 element = element->NextSiblingElement("dependency");
854 } while (element != NULL);
855 }
856 }
857
858 /*** end of optional fields ***/
859
860 /* Create an addon object and store in a shared_ptr */
eca3c5b changed: refactor
spiff_ authored
861 addon = AddonFromProps(addonProps);
862
863 return addon.get() != NULL;
864 }
865
822ca91 added: translatable <description>, <title>, <summary> and <disclaimer> i...
spiff_ authored
866 bool CAddonMgr::GetTranslatedString(const TiXmlElement *xmldoc, const char *tag, CStdString& data)
867 {
868 const TiXmlElement *element = xmldoc->FirstChildElement(tag);
869 const TiXmlElement *enelement = NULL;
870 while (element)
871 {
872 const char* lang = element->Attribute("lang");
873 if (lang && strcmp(lang,g_langInfo.GetDVDAudioLanguage().c_str()) == 0)
874 break;
875 if (!lang || strcmp(lang,"en") == 0)
876 enelement = element;
877 element = element->NextSiblingElement(tag);
878 }
879 if (!element)
880 element = enelement;
881 if (element)
882 data = element->GetText();
883
884 return element != NULL;
885 }
886
096e8a3 changed: Move description information into addon.xml via the xbmc.addon....
jmarshallnz authored
887 const char *CAddonMgr::GetTranslatedString(const cp_cfg_element_t *root, const char *tag)
888 {
889 if (!root)
890 return NULL;
891
892 const cp_cfg_element_t *eng = NULL;
893 for (unsigned int i = 0; i < root->num_children; i++)
894 {
895 const cp_cfg_element_t &child = root->children[i];
896 if (strcmp(tag, child.name) == 0)
897 { // see if we have a "lang" attribute
898 const char *lang = m_cpluff->lookup_cfg_value((cp_cfg_element_t*)&child, "@lang");
899 if (lang && 0 == strcmp(lang,g_langInfo.GetDVDAudioLanguage().c_str()))
900 return child.value;
901 if (!lang || 0 == strcmp(lang, "en"))
902 eng = &child;
903 }
904 }
905 return (eng) ? eng->value : NULL;
906 }
907
eca3c5b changed: refactor
spiff_ authored
908 AddonPtr CAddonMgr::AddonFromProps(AddonProps& addonProps)
909 {
910 switch (addonProps.type)
af8cb2a Revert "wip"
alcoheca authored
911 {
912 case ADDON_PLUGIN:
913 case ADDON_SCRIPT:
eca3c5b changed: refactor
spiff_ authored
914 return AddonPtr(new CAddon(addonProps));
af8cb2a Revert "wip"
alcoheca authored
915 case ADDON_SCRAPER:
eca3c5b changed: refactor
spiff_ authored
916 return AddonPtr(new CScraper(addonProps));
553d213 changed: finished moving skins to addon framework
alcoheca authored
917 case ADDON_SKIN:
918 return AddonPtr(new CSkinInfo(addonProps));
07e5742 [arm] merge arm-camelot into trunk, thanks to mcgeagh for all his hard w...
davilla authored
919 #if defined(HAS_VISUALISATION)
af8cb2a Revert "wip"
alcoheca authored
920 case ADDON_VIZ:
eca3c5b changed: refactor
spiff_ authored
921 return AddonPtr(new CVisualisation(addonProps));
07e5742 [arm] merge arm-camelot into trunk, thanks to mcgeagh for all his hard w...
davilla authored
922 #endif
af8cb2a Revert "wip"
alcoheca authored
923 case ADDON_SCREENSAVER:
eca3c5b changed: refactor
spiff_ authored
924 return AddonPtr(new CScreenSaver(addonProps));
af8cb2a Revert "wip"
alcoheca authored
925 case ADDON_SCRAPER_LIBRARY:
926 case ADDON_VIZ_LIBRARY:
6433385 added: script-library addon-type
spiff_ authored
927 case ADDON_SCRIPT_LIBRARY:
eca3c5b changed: refactor
spiff_ authored
928 return AddonPtr(new CAddonLibrary(addonProps));
606248f added: addon repository class
spiff_ authored
929 case ADDON_REPOSITORY:
930 return AddonPtr(new CRepository(addonProps));
af8cb2a Revert "wip"
alcoheca authored
931 default:
eca3c5b changed: refactor
spiff_ authored
932 break;
af8cb2a Revert "wip"
alcoheca authored
933 }
eca3c5b changed: refactor
spiff_ authored
934 return AddonPtr();
af8cb2a Revert "wip"
alcoheca authored
935 }
936
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
937 void CAddonMgr::UpdateRepos()
938 {
939 CSingleLock lock(m_critSection);
940 if (m_watch.GetElapsedSeconds() < 600)
941 return;
942 m_watch.StartZero();
943 VECADDONS addons;
944 GetAddons(ADDON_REPOSITORY,addons);
945 for (unsigned int i=0;i<addons.size();++i)
946 {
947 RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(addons[i]);
948 if (repo->LastUpdate()+CDateTimeSpan(0,6,0,0) < CDateTime::GetCurrentDateTime())
949 {
950 CLog::Log(LOGDEBUG,"Checking repository %s for updates",repo->Name().c_str());
9617e5e cosmetics
spiff_ authored
951 CJobManager::GetInstance().AddJob(new CRepositoryUpdateJob(repo),this);
639b314 changed: move addonbrowser to a mediawindow derivate
spiff_ authored
952 }
953 }
954 }
955
956 void CAddonMgr::OnJobComplete(unsigned int jobID, bool success, CJob* job)
957 {
958 if (!success)
959 return;
960
961 ((CRepositoryUpdateJob*)job)->m_repo->SetUpdated(CDateTime::GetCurrentDateTime());
962 }
963
1b2781c added: basic cpluff support
alcoheca authored
964 /*
965 * libcpluff interaction
966 */
967
bb4e01c Support creating userdirs in addons. This also has the benefit of being ...
ceros7 authored
968 const cp_cfg_element_t *CAddonMgr::GetExtElement(cp_cfg_element_t *base, const char *path)
969 {
970 const cp_cfg_element_t *element = NULL;
971 if (base)
972 element = m_cpluff->lookup_cfg_element(base, path);
973 return element;
974 }
975
976 /* Returns all duplicate elements from a base element */
977 bool CAddonMgr::GetExtElementDeque(DEQUEELEMENTS &elements, cp_cfg_element_t *base, const char *path)
978 {
979 if (!base)
980 return false;
981
982 unsigned int i = 0;
983 while (true)
984 {
985 if (i >= base->num_children)
986 break;
987 CStdString temp = (base->children+i)->name;
988 if (!temp.compare(path))
989 elements.push_back(base->children+i);
990 i++;
991 }
992
993 if (elements.empty()) return false;
994 return true;
995 }
996
096e8a3 changed: Move description information into addon.xml via the xbmc.addon....
jmarshallnz authored
997 const cp_extension_t *CAddonMgr::GetExtension(const cp_plugin_info_t *props, const char *extension)
998 {
999 if (!props)
1000 return NULL;
1001 for (unsigned int i = 0; i < props->num_extensions; ++i)
1002 {
1003 if (0 == strcmp(props->extensions[i].ext_point_id, extension))
1004 return &props->extensions[i];
1005 }
1006 return NULL;
1007 }
1008
b6076e5 changed: screensavers are now supported via cpluff schema
alcoheca authored
1009 CStdString CAddonMgr::GetExtValue(cp_cfg_element_t *base, const char *path)
1010 {
1011 const char *value = NULL;
1012 if (base && (value = m_cpluff->lookup_cfg_value(base, path)))
1013 return CStdString(value);
1014 else return CStdString();
1015 }
1016
1b2781c added: basic cpluff support
alcoheca authored
1017 int cp_to_clog(cp_log_severity_t lvl)
1018 {
1019 if( lvl == CP_LOG_DEBUG )
1020 return 0;
1021 else if (lvl == CP_LOG_INFO)
1022 return 1;
1023 else if (lvl == CP_LOG_WARNING)
1024 return 3;
1025 else
1026 return 4;
1027 }
1028
1029 cp_log_severity_t clog_to_cp(int lvl)
1030 {
1031 if (lvl >= 4)
1032 return CP_LOG_ERROR;
1033 else if (lvl == 3)
1034 return CP_LOG_WARNING;
1035 else if (lvl >= 1)
1036 return CP_LOG_INFO;
1037 else
1038 return CP_LOG_DEBUG;
1039 }
1040
b6f0f59 cleanup: Don't expose the AddonManager's privates when not required.
jmarshallnz authored
1041 void cp_fatalErrorHandler(const char *msg)
1042 {
1043 CLog::Log(LOGERROR, "ADDONS: CPluffFatalError(%s)", msg);
1044 }
1045
1046 void cp_logger(cp_log_severity_t level, const char *msg, const char *apid, void *user_data)
1b2781c added: basic cpluff support
alcoheca authored
1047 {
1048 if(!apid)
5b793b6 added: missing change from r29798
alcoheca authored
1049 CLog::Log(cp_to_clog(level), "ADDON: cpluff: '%s'", msg);
1b2781c added: basic cpluff support
alcoheca authored
1050 else
5b793b6 added: missing change from r29798
alcoheca authored
1051 CLog::Log(cp_to_clog(level), "ADDON: cpluff: '%s' reports '%s'", apid, msg);
1b2781c added: basic cpluff support
alcoheca authored
1052 }
1053
074db86 merged: addons-fw branch
elupus authored
1054 } /* namespace ADDON */
1055
Something went wrong with that request. Please try again.