Пример #1
0
void CAddonInstaller::GetInstallList(VECADDONS &addons) const
{
  CSingleLock lock(m_critSection);
  std::vector<std::string> addonIDs;
  for (JobMap::const_iterator i = m_downloadJobs.begin(); i != m_downloadJobs.end(); ++i)
  {
    if (i->second.jobID)
      addonIDs.push_back(i->first);
  }
  lock.Leave();

  CAddonDatabase database;
  database.Open();
  for (std::vector<std::string>::iterator it = addonIDs.begin(); it != addonIDs.end(); ++it)
  {
    AddonPtr addon;
    if (database.GetAddon(*it, addon))
      addons.push_back(addon);
  }
}
Пример #2
0
void CAddonInstaller::Install(const std::string& addonId, const AddonVersion& version, const std::string& repoId)
{
  CLog::Log(LOGDEBUG, "CAddonInstaller: installing '%s' version '%s' from repository '%s'",
      addonId.c_str(), version.asString().c_str(), repoId.c_str());

  AddonPtr addon;
  CAddonDatabase database;

  if (!database.Open() || !database.GetAddon(addonId, version, repoId, addon))
    return;

  AddonPtr repo;
  if (!CAddonMgr::GetInstance().GetAddon(repoId, repo, ADDON_REPOSITORY))
    return;

  std::string hash;
  if (!std::static_pointer_cast<CRepository>(repo)->GetAddonHash(addon, hash))
    return;
  DoInstall(addon, std::static_pointer_cast<CRepository>(repo), hash, true, false);
}
Пример #3
0
bool CGUIDialogAddonInfo::SetItem(const CFileItemPtr& item)
{
  *m_item = *item;

  // grab the local addon, if it's available
  m_localAddon.reset();
  if (CAddonMgr::Get().GetAddon(item->GetProperty("Addon.ID"), m_localAddon)) // sets m_addon if installed regardless of enabled state
    m_item->SetProperty("Addon.Enabled", "true");
  else
    m_item->SetProperty("Addon.Enabled", "false");
  m_item->SetProperty("Addon.Installed", m_addon ? "true" : "false");

  CAddonDatabase database;
  database.Open();
  database.GetAddon(item->GetProperty("Addon.ID"),m_addon);

  if (TranslateType(item->GetProperty("Addon.intType")) == ADDON_REPOSITORY)
  {
    CAddonDatabase database;
    database.Open();
    VECADDONS addons;
    if (m_addon)
      database.GetRepository(m_addon->ID(), addons);
    else if (m_localAddon) // sanity
      database.GetRepository(m_localAddon->ID(), addons);
    int tot=0;
    for (int i = ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i)
    {
      int num=0;
      for (unsigned int j=0;j<addons.size();++j)
      {
        if (addons[j]->Type() == (TYPE)i)
          ++num;
      }
      m_item->SetProperty(CStdString("Repo.") + TranslateType((TYPE)i), num);
      tot += num;
    }
    m_item->SetProperty("Repo.Addons", tot);
  }
  return true;
}
Пример #4
0
bool CAddonUnInstallJob::DoWork()
{
  ADDON::OnPreUnInstall(m_addon);

  //TODO: looks broken. it just calls the repo with the most recent version, not the owner
  RepositoryPtr repoPtr;
  CAddonInstaller::GetRepoForAddon(m_addon->ID(), repoPtr);
  if (repoPtr != NULL && !repoPtr->Props().libname.empty())
  {
    CFileItemList dummy;
    std::string s = StringUtils::Format("plugin://%s/?action=uninstall&package=%s", repoPtr->ID().c_str(), m_addon->ID().c_str());
    if (!CDirectory::GetDirectory(s, dummy))
      return false;
  }
  else
  {
    //Unregister addon with the manager to ensure nothing tries
    //to interact with it while we are uninstalling.
    CAddonMgr::GetInstance().UnregisterAddon(m_addon->ID());

    if (!DeleteAddon(m_addon->Path()))
    {
      CLog::Log(LOGERROR, "CAddonUnInstallJob[%s]: could not delete addon data.", m_addon->ID().c_str());
      return false;
    }
  }

  ClearFavourites();

  AddonPtr addon;
  CAddonDatabase database;
  // try to get the addon object from the repository as the local one does not exist anymore
  // if that doesn't work fall back to the local one
  if (!database.Open() || !database.GetAddon(m_addon->ID(), addon) || addon == NULL)
    addon = m_addon;
  CEventLog::GetInstance().Add(EventPtr(new CAddonManagementEvent(addon, 24144)));

  ADDON::OnPostUnInstall(m_addon);
  return true;
}
Пример #5
0
void CAddonInstallJob::ReportInstallError(const std::string& addonID, const std::string& fileName, const std::string& message /* = "" */)
{
  AddonPtr addon;
  CAddonDatabase database;
  if (database.Open())
  {
    database.GetAddon(addonID, addon);
    database.Close();
  }

  MarkFinished();

  std::string msg = message;
  EventPtr activity;
  if (addon != NULL)
  {
    AddonPtr addon2;
    CAddonMgr::GetInstance().GetAddon(addonID, addon2);
    if (msg.empty())
      msg = g_localizeStrings.Get(addon2 != NULL ? 113 : 114);

    activity = EventPtr(new CAddonManagementEvent(addon, EventLevelError, msg));
    if (IsModal())
      CGUIDialogOK::ShowAndGetInput(CVariant{m_addon->Name()}, CVariant{msg});
  }
  else
  {
    activity =
      EventPtr(new CNotificationEvent(EventLevelError, 24045,
                   !msg.empty() ? msg : StringUtils::Format(g_localizeStrings.Get(24143).c_str(),
                   fileName.c_str())));

    if (IsModal())
      CGUIDialogOK::ShowAndGetInput(CVariant{fileName}, CVariant{msg});
  }

  CEventLog::GetInstance().Add(activity, !IsModal(), false);
}
Пример #6
0
bool CAddonInstaller::CheckDependencies(const AddonPtr &addon,
                                        std::vector<std::string>& preDeps, CAddonDatabase &database)
{
  if (!addon.get())
    return true; // a NULL addon has no dependencies
  ADDONDEPS deps = addon->GetDeps();
  database.Open();
  for (ADDONDEPS::const_iterator i = deps.begin(); i != deps.end(); ++i)
  {
    const CStdString &addonID = i->first;
    const AddonVersion &version = i->second.first;
    bool optional = i->second.second;
    AddonPtr dep;
    bool haveAddon = CAddonMgr::Get().GetAddon(addonID, dep);
    if ((haveAddon && !dep->MeetsVersion(version)) || (!haveAddon && !optional))
    { // we have it but our version isn't good enough, or we don't have it and we need it
      if (!database.GetAddon(addonID, dep) || !dep->MeetsVersion(version))
      { // we don't have it in a repo, or we have it but the version isn't good enough, so dep isn't satisfied.
        CLog::Log(LOGDEBUG, "Addon %s requires %s version %s which is not available", addon->ID().c_str(), addonID.c_str(), version.c_str());
        database.Close();
        return false;
      }
    }
    // at this point we have our dep, or the dep is optional (and we don't have it) so check that it's OK as well
    // TODO: should we assume that installed deps are OK?
    if (dep && std::find(preDeps.begin(), preDeps.end(), dep->ID()) == preDeps.end())
    {
      if (!CheckDependencies(dep, preDeps, database))
      {
        database.Close();
        return false;
      }
      preDeps.push_back(dep->ID());
    }
  }
  database.Close();
  return true;
}
Пример #7
0
bool CAddonUnInstallJob::DoWork()
{
  ADDON::OnPreUnInstall(m_addon);

  //Unregister addon with the manager to ensure nothing tries
  //to interact with it while we are uninstalling.
  if (!CAddonMgr::GetInstance().UnloadAddon(m_addon))
  {
    CLog::Log(LOGERROR, "CAddonUnInstallJob[%s]: failed to unload addon.", m_addon->ID().c_str());
    return false;
  }

  CFilesystemInstaller fsInstaller;
  if (!fsInstaller.UnInstallFromFilesystem(m_addon->Path()))
  {
    CLog::Log(LOGERROR, "CAddonUnInstallJob[%s]: could not delete addon data.", m_addon->ID().c_str());
    return false;
  }

  ClearFavourites();
  if (m_removeData)
    CFileUtils::DeleteItem("special://profile/addon_data/"+m_addon->ID()+"/", true);

  AddonPtr addon;
  CAddonDatabase database;
  // try to get the addon object from the repository as the local one does not exist anymore
  // if that doesn't work fall back to the local one
  if (!database.Open() || !database.GetAddon(m_addon->ID(), addon) || addon == NULL)
    addon = m_addon;
  CEventLog::GetInstance().Add(EventPtr(new CAddonManagementEvent(addon, 24144)));

  CAddonMgr::GetInstance().OnPostUnInstall(m_addon->ID());
  database.OnPostUnInstall(m_addon->ID());

  ADDON::OnPostUnInstall(m_addon);
  return true;
}
Пример #8
0
void CAddonInstallJob::ReportInstallError(const CStdString& addonID,
                                                const CStdString& fileName)
{
  AddonPtr addon;
  CAddonDatabase database;
  database.Open();
  database.GetAddon(addonID, addon);
  if (addon)
  {
    AddonPtr addon2;
    CAddonMgr::Get().GetAddon(addonID, addon2);
    CGUIDialogKaiToast::QueueNotification(addon->Icon(),
                                          addon->Name(),
                                          g_localizeStrings.Get(addon2 ? 113 : 114),
                                          TOAST_DISPLAY_TIME, false);
  }
  else
  {
    CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error,
                                          fileName,
                                          g_localizeStrings.Get(114),
                                          TOAST_DISPLAY_TIME, false);
  }
}
Пример #9
0
bool CAddonInstaller::Install(const CStdString &addonID, bool force, const CStdString &referer, bool background)
{
  AddonPtr addon;
  bool addonInstalled = CAddonMgr::Get().GetAddon(addonID, addon, ADDON_UNKNOWN, false);
  if (addonInstalled && !force)
    return true;

  // check whether we have it available in a repository
  CAddonDatabase database;
  database.Open();
  if (database.GetAddon(addonID, addon))
  {
    CStdString repo;
    database.GetRepoForAddon(addonID,repo);
    AddonPtr ptr;
    CAddonMgr::Get().GetAddon(repo,ptr);
    RepositoryPtr therepo = boost::dynamic_pointer_cast<CRepository>(ptr);
    CStdString hash;
    if (therepo)
      hash = therepo->GetAddonHash(addon);
    return DoInstall(addon, hash, addonInstalled, referer, background);
  }
  return false;
}
Пример #10
0
bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
  CStdString path1(strPath);
  URIUtils::RemoveSlashAtEnd(path1);
  CURL path(path1);
  items.ClearProperties();

  items.SetContent("addons");

  VECADDONS addons;
  // get info from repository
  bool reposAsFolders = true;
  if (path.GetHostName().Equals("enabled"))
  {
    CAddonMgr::Get().GetAllAddons(addons, true);
    items.SetProperty("reponame",g_localizeStrings.Get(24062));
    items.SetLabel(g_localizeStrings.Get(24062));
  }
  else if (path.GetHostName().Equals("disabled"))
  { // grab all disabled addons, including disabled repositories
    reposAsFolders = false;
    CAddonMgr::Get().GetAllAddons(addons, false, true);
    items.SetProperty("reponame",g_localizeStrings.Get(24039));
    items.SetLabel(g_localizeStrings.Get(24039));
  }
  else if (path.GetHostName().Equals("outdated"))
  {
    reposAsFolders = false;
    CAddonMgr::Get().GetAllOutdatedAddons(addons);
    items.SetProperty("reponame",g_localizeStrings.Get(24043));
    items.SetLabel(g_localizeStrings.Get(24043));
  }
  else if (path.GetHostName().Equals("repos"))
  {
    CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true);
    items.SetLabel(g_localizeStrings.Get(24033)); // Get Add-ons
  }
  else if (path.GetHostName().Equals("sources"))
  {
    return GetScriptsAndPlugins(path.GetFileName(), items);
  }
  else if (path.GetHostName().Equals("all"))
  {
    CAddonDatabase database;
    database.Open();
    database.GetAddons(addons);
    items.SetProperty("reponame",g_localizeStrings.Get(24032));
    items.SetLabel(g_localizeStrings.Get(24032));
  }
  else if (path.GetHostName().Equals("search"))
  {
    CStdString search(path.GetFileName());
    if (search.IsEmpty() && !GetKeyboardInput(16017, search))
      return false;

    items.SetProperty("reponame",g_localizeStrings.Get(283));
    items.SetLabel(g_localizeStrings.Get(283));

    CAddonDatabase database;
    database.Open();
    database.Search(search, addons);
    GenerateListing(path, addons, items, true);

    path.SetFileName(search);
    items.SetPath(path.Get());
    return true;
  }
  else
  {
    reposAsFolders = false;
    AddonPtr addon;
    CAddonMgr::Get().GetAddon(path.GetHostName(),addon);
    if (!addon)
      return false;

    // ensure our repos are up to date
    CAddonInstaller::Get().UpdateRepos(false, true);
    CAddonDatabase database;
    database.Open();
    database.GetRepository(addon->ID(),addons);
    items.SetProperty("reponame",addon->Name());
    items.SetLabel(addon->Name());
  }

  if (path.GetFileName().IsEmpty())
  {
    if (!path.GetHostName().Equals("repos"))
    {
      for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i)
      {
        for (unsigned int j=0;j<addons.size();++j)
        {
          if (addons[j]->IsType((TYPE)i))
          {
            CFileItemPtr item(new CFileItem(TranslateType((TYPE)i,true)));
            item->SetPath(URIUtils::AddFileToFolder(strPath,TranslateType((TYPE)i,false)));
            item->m_bIsFolder = true;
            CStdString thumb = GetIcon((TYPE)i);
            if (!thumb.IsEmpty() && g_TextureManager.HasTexture(thumb))
              item->SetArt("thumb", thumb);
            items.Add(item);
            break;
          }
        }
      }
      items.SetPath(strPath);
      return true;
    }
  }
  else
  {
    TYPE type = TranslateType(path.GetFileName());
    items.SetProperty("addoncategory",TranslateType(type, true));
    items.SetLabel(TranslateType(type, true));
    items.SetPath(strPath);

    // FIXME: Categorisation of addons needs adding here
    for (unsigned int j=0;j<addons.size();++j)
    {
      if (!addons[j]->IsType(type))
        addons.erase(addons.begin()+j--);
    }
  }

  items.SetPath(strPath);
  GenerateListing(path, addons, items, reposAsFolders);
  // check for available updates
  if (path.GetHostName().Equals("enabled"))
  {
    CAddonDatabase database;
    database.Open();
    for (int i=0;i<items.Size();++i)
    {
      AddonPtr addon2;
      database.GetAddon(items[i]->GetProperty("Addon.ID").asString(),addon2);
      if (addon2 && addon2->Version() > AddonVersion(items[i]->GetProperty("Addon.Version").asString())
                 && !database.IsAddonBlacklisted(addon2->ID(),addon2->Version().c_str()))
      {
        items[i]->SetProperty("Addon.Status",g_localizeStrings.Get(24068));
        items[i]->SetProperty("Addon.UpdateAvail", true);
      }
    }
  }
  if (path.GetHostName().Equals("repos") && items.Size() > 1)
  {
    CFileItemPtr item(new CFileItem("addons://all/",true));
    item->SetLabel(g_localizeStrings.Get(24032));
    items.Add(item);
  }

  return true;
}
Пример #11
0
bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
  CStdString path1(strPath);
  CUtil::RemoveSlashAtEnd(path1);
  CURL path(path1);
  items.ClearProperties();

  items.SetContent("addons");

  VECADDONS addons;
  // get info from repository
  bool reposAsFolders = true;
  if (path.GetHostName().Equals("enabled"))
  {
    CAddonMgr::Get().GetAllAddons(addons, true);
    items.SetProperty("reponame",g_localizeStrings.Get(24062));
  }
  else if (path.GetHostName().Equals("disabled"))
  { // grab all disabled addons, including disabled repositories
    reposAsFolders = false;
    CAddonMgr::Get().GetAllAddons(addons, false, true);
    items.SetProperty("reponame",g_localizeStrings.Get(24039));
  }
  else if (path.GetHostName().Equals("outdated"))
  {
    reposAsFolders = false;
    CAddonMgr::Get().GetAllOutdatedAddons(addons);
    items.SetProperty("reponame",g_localizeStrings.Get(24043));
  }
  else if (path.GetHostName().Equals("repos"))
  {
    CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true);
  }
  else if (path.GetHostName().Equals("sources"))
  {
    return GetScriptsAndPlugins(path.GetFileName(), items);
  }
  else if (path.GetHostName().Equals("all"))
  {
    CAddonDatabase database;
    database.Open();
    database.GetAddons(addons);
    items.SetProperty("reponame",g_localizeStrings.Get(24032));
  }
  else
  {
    AddonPtr addon;
    CAddonMgr::Get().GetAddon(path.GetHostName(),addon);
    if (!addon)
      return false;
    CAddonDatabase database;
    database.Open();
    if (!database.GetRepository(addon->ID(),addons))
    {
      RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(addon);
      addons = CRepositoryUpdateJob::GrabAddons(repo,false);
    }
    items.SetProperty("reponame",addon->Name());
  }

  if (path.GetFileName().IsEmpty())
  {
    if (!path.GetHostName().Equals("repos"))
    {
      for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i)
      {
        for (unsigned int j=0;j<addons.size();++j)
        {
          if (addons[j]->IsType((TYPE)i))
          {
            CFileItemPtr item(new CFileItem(TranslateType((TYPE)i,true)));
            item->m_strPath = CUtil::AddFileToFolder(strPath,TranslateType((TYPE)i,false));
            item->m_bIsFolder = true;
            CStdString thumb = GetIcon((TYPE)i);
            if (!thumb.IsEmpty() && g_TextureManager.HasTexture(thumb))
              item->SetThumbnailImage(thumb);
            items.Add(item);
            break;
          }
        }
      }
      items.m_strPath = strPath;
      return true;
    }
  }
  else
  {
    TYPE type = TranslateType(path.GetFileName());
    items.SetProperty("addoncategory",TranslateType(type, true));
    items.m_strPath = strPath;

    // FIXME: Categorisation of addons needs adding here
    for (unsigned int j=0;j<addons.size();++j)
    {
      if (!addons[j]->IsType(type))
        addons.erase(addons.begin()+j--);
    }
  }

  items.m_strPath = strPath;
  GenerateListing(path, addons, items, reposAsFolders);
  // check for available updates
  if (path.GetHostName().Equals("enabled"))
  {
    CAddonDatabase database;
    database.Open();
    for (int i=0;i<items.Size();++i)
    {
      AddonPtr addon2;
      database.GetAddon(items[i]->GetProperty("Addon.ID"),addon2);
      if (addon2 && addon2->Version() > AddonVersion(items[i]->GetProperty("Addon.Version")))
      {
        items[i]->SetProperty("Addon.Status",g_localizeStrings.Get(24068));
        items[i]->SetProperty("Addon.UpdateAvail","true");
      }
    }
  }
  if (path.GetHostName().Equals("repos") && items.Size() > 1)
  {
    CFileItemPtr item(new CFileItem("addons://all/",true));
    item->SetLabel(g_localizeStrings.Get(24032));
    items.Add(item);
  }

  return true;
}
Пример #12
0
bool CRepositoryUpdateJob::DoWork()
{
  CLog::Log(LOGDEBUG, "CRepositoryUpdateJob[%s] checking for updates.", m_repo->ID().c_str());
  CAddonDatabase database;
  database.Open();

  std::string oldChecksum;
  if (database.GetRepoChecksum(m_repo->ID(), oldChecksum) == -1)
    oldChecksum = "";

  std::string newChecksum;
  VECADDONS addons;
  auto status = m_repo->FetchIfChanged(oldChecksum, newChecksum, addons);

  database.SetLastChecked(m_repo->ID(), m_repo->Version(),
      CDateTime::GetCurrentDateTime().GetAsDBDateTime());

  MarkFinished();

  if (status == CRepository::STATUS_ERROR)
    return false;

  if (status == CRepository::STATUS_NOT_MODIFIED)
  {
    CLog::Log(LOGDEBUG, "CRepositoryUpdateJob[%s] checksum not changed.", m_repo->ID().c_str());
    return true;
  }

  //Invalidate art.
  {
    CTextureDatabase textureDB;
    textureDB.Open();
    textureDB.BeginMultipleExecute();

    for (const auto& addon : addons)
    {
      AddonPtr oldAddon;
      if (database.GetAddon(addon->ID(), oldAddon) && addon->Version() > oldAddon->Version())
      {
        if (!oldAddon->Icon().empty() || !oldAddon->FanArt().empty() || !oldAddon->Screenshots().empty())
          CLog::Log(LOGDEBUG, "CRepository: invalidating cached art for '%s'", addon->ID().c_str());
        if (!oldAddon->Icon().empty())
          textureDB.InvalidateCachedTexture(oldAddon->Icon());
        if (!oldAddon->FanArt().empty())
          textureDB.InvalidateCachedTexture(oldAddon->Icon());
        for (const auto& path : oldAddon->Screenshots())
          textureDB.InvalidateCachedTexture(path);
      }
    }
    textureDB.CommitMultipleExecute();
  }

  database.UpdateRepositoryContent(m_repo->ID(), m_repo->Version(), newChecksum, addons);

  //Notify about broken status changes
  for (const auto& addon : addons)
  {
    AddonPtr localAddon;
    if (!CAddonMgr::GetInstance().GetAddon(addon->ID(), localAddon))
      continue;

    if (localAddon && localAddon->Version() > addon->Version())
      //We have a newer version locally
      continue;

    AddonPtr oldAddon;
    database.GetAddon(addon->ID(), oldAddon);

    if (database.GetAddonVersion(addon->ID()).first > addon->Version())
      //Newer version in db (ie. in a different repo)
      continue;

    std::string broken = addon->Broken();
    bool isBroken = !addon->Broken().empty();
    bool isBrokenInDb = oldAddon && !oldAddon->Broken().empty();
    if (isBroken && !isBrokenInDb)
    {
      //newly broken
      if (HELPERS::ShowYesNoDialogLines(CVariant{addon->Name()}, CVariant{24096}, CVariant{24097}, CVariant{""})
        == DialogResponse::YES)
      {
        CAddonMgr::GetInstance().DisableAddon(addon->ID());
      }

      CLog::Log(LOGDEBUG, "CRepositoryUpdateJob[%s] addon '%s' marked broken. reason: \"%s\"",
           m_repo->ID().c_str(), addon->ID().c_str(), broken.c_str());

      CEventLog::GetInstance().Add(EventPtr(new CAddonManagementEvent(addon, 24096)));
    }
    else if (!isBroken && isBrokenInDb)
    {
      //Unbroken
      CLog::Log(LOGDEBUG, "CRepositoryUpdateJob[%s] addon '%s' unbroken",
          m_repo->ID().c_str(), addon->ID().c_str());
    }
  }
  return true;
}