Skip to content

Commit

Permalink
[addons] fix and move the rollback feature into the new update dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
tamland committed Oct 4, 2015
1 parent 58142ec commit dfc693d
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 124 deletions.
14 changes: 4 additions & 10 deletions addons/resource.language.en_gb/resources/strings.po
Expand Up @@ -13395,10 +13395,7 @@ msgctxt "#24047"
msgid "This add-on can't be uninstalled"
msgstr ""

#: skin.confluence
msgctxt "#24048"
msgid "Rollback"
msgstr ""
#empty string with id 24048

#: xbmc/filesystem/AddonsDirectory.cpp
msgctxt "#24049"
Expand Down Expand Up @@ -13636,14 +13633,11 @@ msgctxt "#24093"
msgid "Checking %s..."
msgstr ""

#: xbmc/addons/guidialogaddoninfo.cpp
msgctxt "#24094"
msgid "(current)"
msgstr ""
#empty string with id 24094

#: xbmc/addons/guidialogaddoninfo.cpp
#: xbmc/addons/GUIDialogAddonInfo.cpp
msgctxt "#24095"
msgid "(blacklisted)"
msgid "Local package cache"
msgstr ""

#: xbmc/addons/Repository.cpp
Expand Down
8 changes: 0 additions & 8 deletions addons/skin.confluence/720p/DialogAddonInfo.xml
Expand Up @@ -321,14 +321,6 @@
<align>center</align>
<font>font12_title</font>
</control>
<control type="button" id="11">
<description>Rollback button</description>
<width>220</width>
<height>43</height>
<label>24048</label>
<align>center</align>
<font>font12_title</font>
</control>
<control type="button" id="10">
<description>Changelog button</description>
<width>220</width>
Expand Down
2 changes: 2 additions & 0 deletions xbmc/addons/AddonInstaller.cpp
Expand Up @@ -259,6 +259,8 @@ bool CAddonInstaller::InstallFromZip(const std::string &path)
if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
return false;

CLog::Log(LOGDEBUG, "CAddonInstaller: installing from zip '%s'", CURL::GetRedacted(path).c_str());

// grab the descriptive XML document from the zip, and read it in
CFileItemList items;
// BUG: some zip files return a single item (root folder) that we think is stored, so we don't use the zip:// protocol
Expand Down
156 changes: 55 additions & 101 deletions xbmc/addons/GUIDialogAddonInfo.cpp
Expand Up @@ -51,7 +51,6 @@
#define CONTROL_BTN_UPDATE 8
#define CONTROL_BTN_SETTINGS 9
#define CONTROL_BTN_CHANGELOG 10
#define CONTROL_BTN_ROLLBACK 11
#define CONTROL_BTN_SELECT 12

using namespace ADDON;
Expand Down Expand Up @@ -140,11 +139,6 @@ bool CGUIDialogAddonInfo::OnMessage(CGUIMessage& message)
OnChangeLog();
return true;
}
else if (iControl == CONTROL_BTN_ROLLBACK)
{
OnRollback();
return true;
}
}
break;
default:
Expand Down Expand Up @@ -175,9 +169,6 @@ void CGUIDialogAddonInfo::UpdateControls()
{
bool isInstalled = NULL != m_localAddon.get();
bool isEnabled = isInstalled && m_item->GetProperty("Addon.Enabled").asBoolean();
if (isInstalled)
GrabRollbackVersions();

bool canDisable = isInstalled && CAddonMgr::GetInstance().CanAddonBeDisabled(m_localAddon->ID());
bool canInstall = !isInstalled && m_item->GetProperty("Addon.Broken").empty();
bool isRepo = (isInstalled && m_localAddon->Type() == ADDON_REPOSITORY) || (m_addon && m_addon->Type() == ADDON_REPOSITORY);
Expand All @@ -196,9 +187,15 @@ void CGUIDialogAddonInfo::UpdateControls()

CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_SETTINGS, isInstalled && m_localAddon->HasSettings());
CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_CHANGELOG, !isRepo);
CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_ROLLBACK, m_rollbackVersions.size() > 1);
}

static const std::string LOCAL_CACHE = "special_local_cache";

static bool CompareVersion(const std::pair<AddonVersion, std::string>& lhs, const std::pair<AddonVersion, std::string>& rhs)
{
return lhs.first > rhs.first;
};

void CGUIDialogAddonInfo::OnUpdate()
{
Close();
Expand All @@ -214,25 +211,54 @@ void CGUIDialogAddonInfo::OnUpdate()
if (!database.GetAvailableVersions(m_localAddon->ID(), versions))
return;

CFileItemList items;
if (XFILE::CDirectory::GetDirectory("special://home/addons/packages/", items, ".zip", DIR_FLAG_NO_FILE_DIRS))
{
for (int i = 0; i < items.Size(); ++i)
{
std::string packageId;
std::string versionString;
if (AddonVersion::SplitFileName(packageId, versionString, items[i]->GetLabel()))
{
if (packageId == m_localAddon->ID())
{
std::string hash;
std::string path(items[i]->GetPath());
if (database.GetPackageHash(m_localAddon->ID(), items[i]->GetPath(), hash))
{
std::string md5 = CUtil::GetFileMD5(path);
if (md5 == hash)
versions.push_back(std::make_pair(AddonVersion(versionString), LOCAL_CACHE));
}
}
}
}
}

auto* dialog = static_cast<CGUIDialogSelect*>(g_windowManager.GetWindow(WINDOW_DIALOG_SELECT));
dialog->Reset();
dialog->SetHeading(CVariant{21338});
dialog->SetUseDetails(true);

std::sort(versions.begin(), versions.end(), std::greater<std::pair<AddonVersion, std::string>>());
std::stable_sort(versions.begin(), versions.end(), CompareVersion);

for (const auto& version : versions)
for (const auto& versionInfo : versions)
{
CFileItem item(StringUtils::Format(g_localizeStrings.Get(21339).c_str(), versionInfo.first.asString().c_str()));
if (versionInfo.first == m_localAddon->Version())
item.Select(true);

AddonPtr repo;
if (CAddonMgr::GetInstance().GetAddon(version.second, repo, ADDON_REPOSITORY))
if (versionInfo.second == LOCAL_CACHE)
{
item.SetProperty("Addon.Summary", g_localizeStrings.Get(24095));
item.SetIconImage("DefaultAddonRepository.png");
dialog->Add(item);
}
else if (CAddonMgr::GetInstance().GetAddon(versionInfo.second, repo, ADDON_REPOSITORY))
{
CFileItem item(StringUtils::Format(g_localizeStrings.Get(21339).c_str(), version.first.asString().c_str()));
item.SetProperty("Addon.Summary", repo->Name());
item.SetIconImage(repo->Icon());

if (m_localAddon->Version() == version.first)
item.Select(true);

dialog->Add(item);
}
}
Expand All @@ -241,17 +267,19 @@ void CGUIDialogAddonInfo::OnUpdate()
if (dialog->IsConfirmed())
{
auto selected = versions.at(dialog->GetSelectedLabel());
if (!selected.second.empty())
{
//add or remove from blacklist to toggle auto updating. if downgrading
//turn off, if upgrading to latest turn it back on
if (selected.first < m_localAddon->Version())
database.BlacklistAddon(m_localAddon->ID());
if (selected.first == versions.at(0).first)
database.RemoveAddonFromBlacklist(m_localAddon->ID());

//add or remove from blacklist to toggle auto updating. if downgrading
//turn off, if upgrading to latest turn it back on
if (selected.first < m_localAddon->Version())
database.BlacklistAddon(m_localAddon->ID());
if (selected.first == versions.at(0).first)
database.RemoveAddonFromBlacklist(m_localAddon->ID());

if (selected.second == LOCAL_CACHE)
CAddonInstaller::GetInstance().InstallFromZip(StringUtils::Format("special://home/addons/packages/%s-%s.zip",
m_localAddon->ID().c_str(), selected.first.asString().c_str()));
else
CAddonInstaller::GetInstance().Install(m_addon->ID(), selected.first, selected.second);
}
}
}

Expand Down Expand Up @@ -403,47 +431,6 @@ void CGUIDialogAddonInfo::OnChangeLog()
m_changelog = false;
}

void CGUIDialogAddonInfo::OnRollback()
{
if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
return;

CGUIDialogContextMenu* dlg = (CGUIDialogContextMenu*)g_windowManager.GetWindow(WINDOW_DIALOG_CONTEXT_MENU);
CAddonDatabase database;
database.Open();

CContextButtons buttons;
for (unsigned int i=0;i<m_rollbackVersions.size();++i)
{
std::string label(m_rollbackVersions[i]);
if (m_rollbackVersions[i] == m_localAddon->Version().asString())
label += " "+g_localizeStrings.Get(24094);
if (database.IsAddonBlacklisted(m_localAddon->ID(),label))
label += " "+g_localizeStrings.Get(24095);

buttons.Add(i,label);
}
int choice;
if ((choice=dlg->ShowAndGetChoice(buttons)) > -1)
{
// blacklist everything newer
//FIXME: broken. never been possible to have multiple versions in the blacklist
for (unsigned int j=choice+1;j<m_rollbackVersions.size();++j)
database.BlacklistAddon(m_localAddon->ID(),m_rollbackVersions[j]);
std::string path = "special://home/addons/packages/";
path += m_localAddon->ID()+"-"+m_rollbackVersions[choice]+".zip";

//FIXME: this is probably broken
// needed as cpluff won't downgrade
if (!m_localAddon->IsType(ADDON_SERVICE))
//we will handle this for service addons in CAddonInstallJob::OnPostInstall
CAddonMgr::GetInstance().UnregisterAddon(m_localAddon->ID());
CAddonInstaller::GetInstance().InstallFromZip(path);
database.RemoveAddonFromBlacklist(m_localAddon->ID(),m_rollbackVersions[choice]);
Close();
}
}

bool CGUIDialogAddonInfo::ShowForItem(const CFileItemPtr& item)
{
CGUIDialogAddonInfo* dialog = (CGUIDialogAddonInfo*)g_windowManager.GetWindow(WINDOW_DIALOG_ADDON_INFO);
Expand All @@ -459,7 +446,6 @@ bool CGUIDialogAddonInfo::ShowForItem(const CFileItemPtr& item)
bool CGUIDialogAddonInfo::SetItem(const CFileItemPtr& item)
{
*m_item = *item;
m_rollbackVersions.clear();

// grab the local addon, if it's available
m_localAddon.reset();
Expand Down Expand Up @@ -528,35 +514,3 @@ void CGUIDialogAddonInfo::OnJobComplete(unsigned int jobID, bool success,
CGUIMessage msg(GUI_MSG_NOTIFY_ALL, WINDOW_DIALOG_TEXT_VIEWER, 0, GUI_MSG_UPDATE);
g_windowManager.SendThreadMessage(msg);
}

void CGUIDialogAddonInfo::GrabRollbackVersions()
{
CFileItemList items;
XFILE::CDirectory::GetDirectory("special://home/addons/packages/",items,".zip",DIR_FLAG_NO_FILE_DIRS);
items.Sort(SortByLabel, SortOrderAscending);
CAddonDatabase db;
db.Open();
for (int i=0;i<items.Size();++i)
{
if (items[i]->m_bIsFolder)
continue;
std::string ID, version;
AddonVersion::SplitFileName(ID,version,items[i]->GetLabel());
if (ID == m_localAddon->ID())
{
std::string hash, path(items[i]->GetPath());
if (db.GetPackageHash(m_localAddon->ID(), path, hash))
{
std::string md5 = CUtil::GetFileMD5(path);
if (md5 == hash)
m_rollbackVersions.push_back(version);
else /* The package has been corrupted */
{
CLog::Log(LOGWARNING, "%s: Removing corrupt addon package %s.", __FUNCTION__, path.c_str());
CFile::Delete(path);
db.RemovePackage(path);
}
}
}
}
}
5 changes: 0 additions & 5 deletions xbmc/addons/GUIDialogAddonInfo.h
Expand Up @@ -58,7 +58,6 @@ class CGUIDialogAddonInfo :
void OnEnable(bool enable);
void OnSettings();
void OnChangeLog();
void OnRollback();
void OnSelect();

/*! Returns true if current addon can be opened (i.e is a plugin)*/
Expand All @@ -84,9 +83,5 @@ class CGUIDialogAddonInfo :
ADDON::AddonPtr m_localAddon;
unsigned int m_jobid;
bool m_changelog;

// rollback data
void GrabRollbackVersions();
std::vector<std::string> m_rollbackVersions;
};

0 comments on commit dfc693d

Please sign in to comment.