Merge pull request #4594 from FernetMenta/paplayer
[xbmc.git] / xbmc / filesystem / AddonsDirectory.cpp
blob71a717537a3dc6e9fea231c295566bf7cd7c9da0
1 /*
2 * Copyright (C) 2005-2013 Team XBMC
3 * http://xbmc.org
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.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
22 #include "AddonsDirectory.h"
23 #include "addons/AddonDatabase.h"
24 #include "DirectoryFactory.h"
25 #include "Directory.h"
26 #include "DirectoryCache.h"
27 #include "FileItem.h"
28 #include "addons/Repository.h"
29 #include "addons/AddonInstaller.h"
30 #include "addons/PluginSource.h"
31 #include "guilib/TextureManager.h"
32 #include "File.h"
33 #include "SpecialProtocol.h"
34 #include "utils/URIUtils.h"
35 #include "utils/StringUtils.h"
36 #include "URL.h"
38 using namespace ADDON;
40 namespace XFILE
43 CAddonsDirectory::CAddonsDirectory(void)
47 CAddonsDirectory::~CAddonsDirectory(void)
50 bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
52 CStdString path1(strPath);
53 URIUtils::RemoveSlashAtEnd(path1);
54 CURL path(path1);
55 items.ClearProperties();
57 items.SetContent("addons");
59 VECADDONS addons;
60 // get info from repository
61 bool groupAddons = true;
62 bool reposAsFolders = true;
63 if (path.GetHostName().Equals("enabled"))
65 CAddonMgr::Get().GetAllAddons(addons, true);
66 items.SetProperty("reponame",g_localizeStrings.Get(24062));
67 items.SetLabel(g_localizeStrings.Get(24062));
69 else if (path.GetHostName().Equals("disabled"))
70 { // grab all disabled addons, including disabled repositories
71 reposAsFolders = false;
72 groupAddons = false;
73 CAddonMgr::Get().GetAllAddons(addons, false, true);
74 items.SetProperty("reponame",g_localizeStrings.Get(24039));
75 items.SetLabel(g_localizeStrings.Get(24039));
77 else if (path.GetHostName().Equals("outdated"))
79 reposAsFolders = false;
80 groupAddons = false;
81 CAddonMgr::Get().GetAllOutdatedAddons(addons);
82 items.SetProperty("reponame",g_localizeStrings.Get(24043));
83 items.SetLabel(g_localizeStrings.Get(24043));
85 else if (path.GetHostName().Equals("repos"))
87 groupAddons = false;
88 CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true);
89 items.SetLabel(g_localizeStrings.Get(24033)); // Get Add-ons
91 else if (path.GetHostName().Equals("sources"))
93 return GetScriptsAndPlugins(path.GetFileName(), items);
95 else if (path.GetHostName().Equals("all"))
97 CAddonDatabase database;
98 database.Open();
99 database.GetAddons(addons);
100 items.SetProperty("reponame",g_localizeStrings.Get(24032));
101 items.SetLabel(g_localizeStrings.Get(24032));
103 else if (path.GetHostName().Equals("search"))
105 CStdString search(path.GetFileName());
106 if (search.empty() && !GetKeyboardInput(16017, search))
107 return false;
109 items.SetProperty("reponame",g_localizeStrings.Get(283));
110 items.SetLabel(g_localizeStrings.Get(283));
112 CAddonDatabase database;
113 database.Open();
114 database.Search(search, addons);
115 GenerateListing(path, addons, items, true);
117 path.SetFileName(search);
118 items.SetPath(path.Get());
119 return true;
121 else
123 reposAsFolders = false;
124 AddonPtr addon;
125 CAddonMgr::Get().GetAddon(path.GetHostName(),addon);
126 if (!addon)
127 return false;
129 // ensure our repos are up to date
130 CAddonInstaller::Get().UpdateRepos(false, true);
131 CAddonDatabase database;
132 database.Open();
133 database.GetRepository(addon->ID(),addons);
134 items.SetProperty("reponame",addon->Name());
135 items.SetLabel(addon->Name());
138 if (path.GetFileName().empty())
140 if (groupAddons)
142 for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i)
144 for (unsigned int j=0;j<addons.size();++j)
146 if (addons[j]->IsType((TYPE)i))
148 CFileItemPtr item(new CFileItem(TranslateType((TYPE)i,true)));
149 item->SetPath(URIUtils::AddFileToFolder(strPath,TranslateType((TYPE)i,false)));
150 item->m_bIsFolder = true;
151 CStdString thumb = GetIcon((TYPE)i);
152 if (!thumb.empty() && g_TextureManager.HasTexture(thumb))
153 item->SetArt("thumb", thumb);
154 items.Add(item);
155 break;
159 items.SetPath(strPath);
160 return true;
163 else
165 TYPE type = TranslateType(path.GetFileName());
166 items.SetProperty("addoncategory",TranslateType(type, true));
167 items.SetLabel(TranslateType(type, true));
168 items.SetPath(strPath);
170 // FIXME: Categorisation of addons needs adding here
171 for (unsigned int j=0;j<addons.size();++j)
173 if (!addons[j]->IsType(type))
174 addons.erase(addons.begin()+j--);
178 items.SetPath(strPath);
179 GenerateListing(path, addons, items, reposAsFolders);
180 // check for available updates
181 if (path.GetHostName().Equals("enabled"))
183 CAddonDatabase database;
184 database.Open();
185 for (int i=0;i<items.Size();++i)
187 AddonPtr addon2;
188 database.GetAddon(items[i]->GetProperty("Addon.ID").asString(),addon2);
189 if (addon2 && addon2->Version() > AddonVersion(items[i]->GetProperty("Addon.Version").asString())
190 && !database.IsAddonBlacklisted(addon2->ID(),addon2->Version().c_str()))
192 items[i]->SetProperty("Addon.Status",g_localizeStrings.Get(24068));
193 items[i]->SetProperty("Addon.UpdateAvail", true);
197 if (path.GetHostName().Equals("repos") && items.Size() > 1)
199 CFileItemPtr item(new CFileItem("addons://all/",true));
200 item->SetLabel(g_localizeStrings.Get(24032));
201 items.Add(item);
203 else if (path.GetHostName().Equals("outdated") && items.Size() > 1)
205 CFileItemPtr item(new CFileItem("addons://update_all/", true));
206 item->SetLabel(g_localizeStrings.Get(24122));
207 item->SetSpecialSort(SortSpecialOnTop);
208 items.Add(item);
211 return true;
214 void CAddonsDirectory::GenerateListing(CURL &path, VECADDONS& addons, CFileItemList &items, bool reposAsFolders)
216 CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc/addons");
217 items.ClearItems();
218 for (unsigned i=0; i < addons.size(); i++)
220 AddonPtr addon = addons[i];
221 CFileItemPtr pItem;
222 if (reposAsFolders && addon->Type() == ADDON_REPOSITORY)
223 pItem = FileItemFromAddon(addon, "addons://", true);
224 else
225 pItem = FileItemFromAddon(addon, path.Get(), false);
226 AddonPtr addon2;
227 if (CAddonMgr::Get().GetAddon(addon->ID(),addon2))
228 pItem->SetProperty("Addon.Status",g_localizeStrings.Get(305));
229 else if (CAddonMgr::Get().IsAddonDisabled(addon->ID()))
230 pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24023));
232 if (addon->Props().broken == "DEPSNOTMET")
233 pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24049));
234 else if (!addon->Props().broken.empty())
235 pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24098));
236 if (addon2 && addon2->Version() < addon->Version())
238 pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24068));
239 pItem->SetProperty("Addon.UpdateAvail", true);
241 CAddonDatabase::SetPropertiesFromAddon(addon,pItem);
242 items.Add(pItem);
246 CFileItemPtr CAddonsDirectory::FileItemFromAddon(const AddonPtr &addon, const CStdString &basePath, bool folder)
248 if (!addon)
249 return CFileItemPtr();
251 // TODO: This can probably be done more efficiently
252 CURL url(basePath);
253 url.SetFileName(addon->ID());
254 CStdString path(url.Get());
255 if (folder)
256 URIUtils::AddSlashAtEnd(path);
258 CFileItemPtr item(new CFileItem(path, folder));
260 CStdString strLabel(addon->Name());
261 if (url.GetHostName().Equals("search"))
262 strLabel = StringUtils::Format("%s - %s", TranslateType(addon->Type(), true).c_str(), addon->Name().c_str());
264 item->SetLabel(strLabel);
266 if (!(basePath.Equals("addons://") && addon->Type() == ADDON_REPOSITORY))
267 item->SetLabel2(addon->Version().c_str());
268 item->SetArt("thumb", addon->Icon());
269 item->SetLabelPreformated(true);
270 item->SetIconImage("DefaultAddon.png");
271 if (URIUtils::IsInternetStream(addon->FanArt()) || CFile::Exists(addon->FanArt()))
272 item->SetArt("fanart", addon->FanArt());
273 CAddonDatabase::SetPropertiesFromAddon(addon, item);
274 return item;
277 bool CAddonsDirectory::GetScriptsAndPlugins(const CStdString &content, VECADDONS &addons)
279 CPluginSource::Content type = CPluginSource::Translate(content);
280 if (type == CPluginSource::UNKNOWN)
281 return false;
283 VECADDONS tempAddons;
284 CAddonMgr::Get().GetAddons(ADDON_PLUGIN, tempAddons);
285 for (unsigned i=0; i<tempAddons.size(); i++)
287 PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(tempAddons[i]);
288 if (plugin && plugin->Provides(type))
289 addons.push_back(tempAddons[i]);
291 tempAddons.clear();
292 CAddonMgr::Get().GetAddons(ADDON_SCRIPT, tempAddons);
293 for (unsigned i=0; i<tempAddons.size(); i++)
295 PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(tempAddons[i]);
296 if (plugin && plugin->Provides(type))
297 addons.push_back(tempAddons[i]);
299 return true;
302 bool CAddonsDirectory::GetScriptsAndPlugins(const CStdString &content, CFileItemList &items)
304 items.Clear();
306 VECADDONS addons;
307 if (!GetScriptsAndPlugins(content, addons))
308 return false;
310 for (unsigned i=0; i<addons.size(); i++)
312 CFileItemPtr item(FileItemFromAddon(addons[i],
313 addons[i]->Type()==ADDON_PLUGIN?"plugin://":"script://",
314 addons[i]->Type() == ADDON_PLUGIN));
315 PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(addons[i]);
316 if (plugin->ProvidesSeveral())
318 CURL url = item->GetAsUrl();
319 CStdString opt = StringUtils::Format("?content_type=%s",content.c_str());
320 url.SetOptions(opt);
321 item->SetPath(url.Get());
323 items.Add(item);
326 items.Add(GetMoreItem(content));
328 items.SetContent("addons");
329 items.SetLabel(g_localizeStrings.Get(24001)); // Add-ons
331 return items.Size() > 0;
334 CFileItemPtr CAddonsDirectory::GetMoreItem(const CStdString &content)
336 CFileItemPtr item(new CFileItem("addons://more/"+content,false));
337 item->SetLabelPreformated(true);
338 item->SetLabel(g_localizeStrings.Get(21452));
339 item->SetIconImage("DefaultAddon.png");
340 item->SetSpecialSort(SortSpecialOnBottom);
341 return item;