diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/addons/FilesystemInstaller.cpp | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/addons/FilesystemInstaller.cpp')
-rw-r--r-- | xbmc/addons/FilesystemInstaller.cpp | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/xbmc/addons/FilesystemInstaller.cpp b/xbmc/addons/FilesystemInstaller.cpp new file mode 100644 index 0000000..0f7b32d --- /dev/null +++ b/xbmc/addons/FilesystemInstaller.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2016-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ +#include "FilesystemInstaller.h" + +#include "FileItem.h" +#include "filesystem/Directory.h" +#include "filesystem/File.h" +#include "filesystem/SpecialProtocol.h" +#include "utils/FileOperationJob.h" +#include "utils/StringUtils.h" +#include "utils/URIUtils.h" +#include "utils/log.h" + +using namespace XFILE; + +CFilesystemInstaller::CFilesystemInstaller() + : m_addonFolder(CSpecialProtocol::TranslatePath("special://home/addons/")), + m_tempFolder(CSpecialProtocol::TranslatePath("special://home/addons/temp/")) +{ +} + +bool CFilesystemInstaller::InstallToFilesystem(const std::string& archive, const std::string& addonId) +{ + auto addonFolder = URIUtils::AddFileToFolder(m_addonFolder, addonId); + auto newAddonData = URIUtils::AddFileToFolder(m_tempFolder, StringUtils::CreateUUID()); + auto oldAddonData = URIUtils::AddFileToFolder(m_tempFolder, StringUtils::CreateUUID()); + + if (!CDirectory::Create(newAddonData)) + return false; + + if (!UnpackArchive(archive, newAddonData)) + { + CLog::Log(LOGERROR, "Failed to unpack archive '{}' to '{}'", archive, newAddonData); + return false; + } + + bool hasOldData = CDirectory::Exists(addonFolder); + if (hasOldData) + { + if (!CFile::Rename(addonFolder, oldAddonData)) + { + CLog::Log(LOGERROR, "Failed to move old addon files from '{}' to '{}'", addonFolder, + oldAddonData); + return false; + } + } + + if (!CFile::Rename(newAddonData, addonFolder)) + { + CLog::Log(LOGERROR, "Failed to move new addon files from '{}' to '{}'", newAddonData, + addonFolder); + return false; + } + + if (hasOldData) + { + if (!CDirectory::RemoveRecursive(oldAddonData)) + { + CLog::Log(LOGWARNING, "Failed to delete old addon files in '{}'", oldAddonData); + } + } + return true; +} + +bool CFilesystemInstaller::UnInstallFromFilesystem(const std::string& addonFolder) +{ + auto tempFolder = URIUtils::AddFileToFolder(m_tempFolder, StringUtils::CreateUUID()); + if (!CFile::Rename(addonFolder, tempFolder)) + { + CLog::Log(LOGERROR, "Failed to move old addon files from '{}' to '{}'", addonFolder, + tempFolder); + return false; + } + + if (!CDirectory::RemoveRecursive(tempFolder)) + { + CLog::Log(LOGWARNING, "Failed to delete old addon files in '{}'", tempFolder); + } + return true; +} + +bool CFilesystemInstaller::UnpackArchive(std::string path, const std::string& dest) +{ + if (!URIUtils::IsProtocol(path, "zip")) + path = URIUtils::CreateArchivePath("zip", CURL(path), "").Get(); + + CFileItemList files; + if (!CDirectory::GetDirectory(path, files, "", DIR_FLAG_DEFAULTS)) + return false; + + if (files.Size() == 1 && files[0]->m_bIsFolder) + { + path = files[0]->GetPath(); + files.Clear(); + if (!CDirectory::GetDirectory(path, files, "", DIR_FLAG_DEFAULTS)) + return false; + } + CLog::Log(LOGDEBUG, "Unpacking {} to {}", path, dest); + + for (auto i = 0; i < files.Size(); ++i) + files[i]->Select(true); + + CFileOperationJob job(CFileOperationJob::ActionCopy, files, dest); + return job.DoWork(); +} |