2 * Copyright (C) 2005-2008 Team XBMC
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)
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, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
23 #include "AddonsDirectory.h"
24 #include "addons/AddonDatabase.h"
25 #include "FactoryDirectory.h"
26 #include "Directory.h"
27 #include "DirectoryCache.h"
29 #include "addons/Repository.h"
30 #include "addons/AddonInstaller.h"
31 #include "addons/PluginSource.h"
32 #include "guilib/TextureManager.h"
34 #include "utils/URIUtils.h"
36 using namespace ADDON;
41 CAddonsDirectory::CAddonsDirectory(void)
43 m_allowPrompting = true;
44 m_cacheDirectory = DIR_CACHE_ONCE;
47 CAddonsDirectory::~CAddonsDirectory(void)
50 bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
52 CStdString path1(strPath);
53 URIUtils::RemoveSlashAtEnd(path1);
55 items.ClearProperties();
57 items.SetContent("addons");
60 // get info from repository
61 bool reposAsFolders = true;
62 if (path.GetHostName().Equals("enabled"))
64 CAddonMgr::Get().GetAllAddons(addons, true);
65 items.SetProperty("reponame",g_localizeStrings.Get(24062));
67 else if (path.GetHostName().Equals("disabled"))
68 { // grab all disabled addons, including disabled repositories
69 reposAsFolders = false;
70 CAddonMgr::Get().GetAllAddons(addons, false, true);
71 items.SetProperty("reponame",g_localizeStrings.Get(24039));
73 else if (path.GetHostName().Equals("outdated"))
75 reposAsFolders = false;
76 CAddonMgr::Get().GetAllOutdatedAddons(addons);
77 items.SetProperty("reponame",g_localizeStrings.Get(24043));
79 else if (path.GetHostName().Equals("repos"))
81 CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true);
83 else if (path.GetHostName().Equals("sources"))
85 return GetScriptsAndPlugins(path.GetFileName(), items);
87 else if (path.GetHostName().Equals("all"))
89 CAddonDatabase database;
91 database.GetAddons(addons);
92 items.SetProperty("reponame",g_localizeStrings.Get(24032));
96 reposAsFolders = false;
98 CAddonMgr::Get().GetAddon(path.GetHostName(),addon);
102 // ensure our repos are up to date
103 CAddonInstaller::Get().UpdateRepos(false, true);
104 CAddonDatabase database;
106 database.GetRepository(addon->ID(),addons);
107 items.SetProperty("reponame",addon->Name());
110 if (path.GetFileName().IsEmpty())
112 if (!path.GetHostName().Equals("repos"))
114 for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i)
116 for (unsigned int j=0;j<addons.size();++j)
118 if (addons[j]->IsType((TYPE)i))
120 CFileItemPtr item(new CFileItem(TranslateType((TYPE)i,true)));
121 item->m_strPath = URIUtils::AddFileToFolder(strPath,TranslateType((TYPE)i,false));
122 item->m_bIsFolder = true;
123 CStdString thumb = GetIcon((TYPE)i);
124 if (!thumb.IsEmpty() && g_TextureManager.HasTexture(thumb))
125 item->SetThumbnailImage(thumb);
131 items.m_strPath = strPath;
137 TYPE type = TranslateType(path.GetFileName());
138 items.SetProperty("addoncategory",TranslateType(type, true));
139 items.m_strPath = strPath;
141 // FIXME: Categorisation of addons needs adding here
142 for (unsigned int j=0;j<addons.size();++j)
144 if (!addons[j]->IsType(type))
145 addons.erase(addons.begin()+j--);
149 items.m_strPath = strPath;
150 GenerateListing(path, addons, items, reposAsFolders);
151 // check for available updates
152 if (path.GetHostName().Equals("enabled"))
154 CAddonDatabase database;
156 for (int i=0;i<items.Size();++i)
159 database.GetAddon(items[i]->GetProperty("Addon.ID"),addon2);
160 if (addon2 && addon2->Version() > AddonVersion(items[i]->GetProperty("Addon.Version")))
162 items[i]->SetProperty("Addon.Status",g_localizeStrings.Get(24068));
163 items[i]->SetProperty("Addon.UpdateAvail","true");
167 if (path.GetHostName().Equals("repos") && items.Size() > 1)
169 CFileItemPtr item(new CFileItem("addons://all/",true));
170 item->SetLabel(g_localizeStrings.Get(24032));
177 void CAddonsDirectory::GenerateListing(CURL &path, VECADDONS& addons, CFileItemList &items, bool reposAsFolders)
180 for (unsigned i=0; i < addons.size(); i++)
182 AddonPtr addon = addons[i];
184 if (reposAsFolders && addon->Type() == ADDON_REPOSITORY)
185 pItem = FileItemFromAddon(addon, "addons://", true);
187 pItem = FileItemFromAddon(addon, path.Get(), false);
189 if (CAddonMgr::Get().GetAddon(addon->ID(),addon2))
190 pItem->SetProperty("Addon.Status",g_localizeStrings.Get(305));
191 if (!addon->Props().broken.IsEmpty())
192 pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24098));
193 if (addon2 && addon2->Version() < addon->Version())
195 pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24068));
196 pItem->SetProperty("Addon.UpdateAvail","true");
198 CAddonDatabase::SetPropertiesFromAddon(addon,pItem);
203 CFileItemPtr CAddonsDirectory::FileItemFromAddon(AddonPtr &addon, const CStdString &basePath, bool folder)
206 return CFileItemPtr();
208 // TODO: This can probably be done more efficiently
210 url.SetFileName(addon->ID());
211 CStdString path(url.Get());
213 URIUtils::AddSlashAtEnd(path);
215 CFileItemPtr item(new CFileItem(path, folder));
216 item->SetLabel(addon->Name());
217 if (!(basePath.Equals("addons://") && addon->Type() == ADDON_REPOSITORY))
218 item->SetLabel2(addon->Version().c_str());
219 item->SetThumbnailImage(addon->Icon());
220 item->SetLabelPreformated(true);
221 item->SetIconImage("DefaultAddon.png");
222 if (!addon->FanArt().IsEmpty() &&
223 (URIUtils::IsInternetStream(addon->FanArt()) ||
224 CFile::Exists(addon->FanArt())))
226 item->SetProperty("fanart_image", addon->FanArt());
228 CAddonDatabase::SetPropertiesFromAddon(addon, item);
232 bool CAddonsDirectory::GetScriptsAndPlugins(const CStdString &content, VECADDONS &addons)
234 CPluginSource::Content type = CPluginSource::Translate(content);
235 if (type == CPluginSource::UNKNOWN)
238 VECADDONS tempAddons;
239 CAddonMgr::Get().GetAddons(ADDON_PLUGIN, tempAddons);
240 for (unsigned i=0; i<tempAddons.size(); i++)
242 PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(tempAddons[i]);
243 if (plugin && plugin->Provides(type))
244 addons.push_back(tempAddons[i]);
247 CAddonMgr::Get().GetAddons(ADDON_SCRIPT, tempAddons);
248 for (unsigned i=0; i<tempAddons.size(); i++)
250 PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(tempAddons[i]);
251 if (plugin && plugin->Provides(type))
252 addons.push_back(tempAddons[i]);
257 bool CAddonsDirectory::GetScriptsAndPlugins(const CStdString &content, CFileItemList &items)
262 if (!GetScriptsAndPlugins(content, addons))
265 for (unsigned i=0; i<addons.size(); i++)
267 if (addons[i]->Type() == ADDON_PLUGIN)
268 items.Add(FileItemFromAddon(addons[i], "plugin://", true));
270 items.Add(FileItemFromAddon(addons[i], "script://", false));
273 items.Add(GetMoreItem(content));
275 items.SetContent("addons");
277 return items.Size() > 0;
280 CFileItemPtr CAddonsDirectory::GetMoreItem(const CStdString &content)
282 CFileItemPtr item(new CFileItem("addons://more/"+content,false));
283 item->SetLabelPreformated(true);
284 item->SetLabel(g_localizeStrings.Get(21452));
285 item->SetIconImage("DefaultAddon.png");
286 item->SetSpecialSort(SORT_ON_BOTTOM);