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

  if (m_localAddon || !m_item->HasAddonInfo())
    return;

  std::string addonId = m_item->GetAddonInfo()->ID();
  std::vector<std::pair<AddonVersion, std::string>> versions;

  CAddonDatabase database;
  if (!database.Open() || !database.GetAvailableVersions(addonId, versions) || versions.empty())
  {
    CLog::Log(LOGERROR, "ADDON: no available versions of %s", addonId.c_str());
    return;
  }

  int i = versions.size() == 1 ? 0 : AskForVersion(versions);
  if (i != -1)
  {
    Close();
    CAddonInstaller::GetInstance().Install(addonId, versions[i].first, versions[i].second);
  }
}
Exemple #2
0
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);
        }
      }
    }
  }
}
Exemple #3
0
void CGUIDialogAddonInfo::OnRollback()
{
  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)
  {
    CStdString label(m_rollbackVersions[i]);
    if (m_rollbackVersions[i].Equals(m_localAddon->Version().c_str()))
     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
    for (unsigned int j=choice+1;j<m_rollbackVersions.size();++j)
      database.BlacklistAddon(m_localAddon->ID(),m_rollbackVersions[j]);
    CStdString path = "special://home/addons/packages/";
    path += m_localAddon->ID()+"-"+m_rollbackVersions[choice]+".zip";
    // needed as cpluff won't downgrade
    if (!m_localAddon->IsType(ADDON_SERVICE))
      //we will handle this for service addons in CAddonInstallJob::OnPostInstall
      CAddonMgr::Get().RemoveAddon(m_localAddon->ID());
    CAddonInstaller::Get().InstallFromZip(path);
    database.RemoveAddonFromBlacklist(m_localAddon->ID(),m_rollbackVersions[choice]);
    Close();
  }
}
Exemple #4
0
void CAddonUnInstallJob::OnPostUnInstall()
{
  if (m_addon->Type() == ADDON_REPOSITORY)
  {
    CAddonDatabase database;
    database.Open();
    database.DeleteRepository(m_addon->ID());
  }

  bool bSave(false);
  CFileItemList items;
  XFILE::CFavouritesDirectory::Load(items);
  for (int i=0; i < items.Size(); ++i)
  {
    if (items[i]->GetPath().find(m_addon->ID()) != std::string::npos)
    {
      items.Remove(items[i].get());
      bSave = true;
    }
  }

  if (bSave)
    CFavouritesDirectory::Save(items);

  if (m_addon->Type() == ADDON_PVRDLL)
  {
    if (CSettings::Get().GetBool("pvrmanager.enabled"))
      PVR::CPVRManager::Get().Start(true);
  }
}
Exemple #5
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.
  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)));

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

  ADDON::OnPostUnInstall(m_addon);
  return true;
}
Exemple #6
0
bool CAddonInstaller::Install(const std::string &addonID, bool force, const std::string &referer, bool background)
{
  AddonPtr addon;
  bool addonInstalled = CAddonMgr::Get().GetAddon(addonID, addon, ADDON_UNKNOWN, false);
  if (addonInstalled && !force)
    return true;

  if (referer.empty())
  {
    if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
      return false;
  }

  // check whether we have it available in a repository
  CAddonDatabase database;
  database.Open();
  if (database.GetAddon(addonID, addon))
  {
    std::string repo;
    database.GetRepoForAddon(addonID,repo);
    AddonPtr ptr;
    CAddonMgr::Get().GetAddon(repo,ptr);
    RepositoryPtr therepo = boost::dynamic_pointer_cast<CRepository>(ptr);
    std::string hash;
    if (therepo)
      hash = therepo->GetAddonHash(addon);
    return DoInstall(addon, hash, addonInstalled, referer, background);
  }
  return false;
}
void CGUIDialogAddonInfo::OnUninstall()
{
  if (!m_localAddon.get())
    return;

  // ensure the addon is not a dependency of other installed addons
  VECADDONS addons;
  CStdStringArray deps;
  CAddonMgr::Get().GetAllAddons(addons);
  for (VECADDONS::iterator it  = addons.begin();
                           it != addons.end();++it)
  {
    if ((*it)->GetDeps().find(m_localAddon->ID()) != (*it)->GetDeps().end())
      deps.push_back((*it)->Name());
  }

  if (!CAddonInstaller::Get().CheckDependencies(m_localAddon) && deps.size())
  {
    CStdString strLine0, strLine1;
    StringUtils::JoinString(deps, ", ", strLine1);
    strLine0.Format(g_localizeStrings.Get(24046), m_localAddon->Name().c_str());
    CGUIDialogOK::ShowAndGetInput(24037, strLine0, strLine1, 24047);
    return;
  }

  // ensure the addon isn't disabled in our database
  CAddonDatabase database;
  database.Open();
  database.DisableAddon(m_localAddon->ID(), false);
  CJobManager::GetInstance().AddJob(new CAddonUnInstallJob(m_localAddon),
                                    &CAddonInstaller::Get());
  CAddonMgr::Get().RemoveAddon(m_localAddon->ID());
  Close();
}
Exemple #8
0
bool CAddonInstaller::CheckDependencies(const AddonPtr &addon)
{
  assert(addon.get());
  ADDONDEPS deps = addon->GetDeps();
  CAddonDatabase database;
  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());
        return false;
      }
    }
    // at this point we have our dep, so check that it's OK as well
    // TODO: should we assume that installed deps are OK?
    if (!CheckDependencies(dep))
      return false;
  }
  return true;
}
bool CAddonInstallJob::OnPreInstall()
{
  // check whether this is an active skin - we need to unload it if so
  if (g_guiSettings.GetString("lookandfeel.skin") == m_addon->ID())
  {
    CApplicationMessenger::Get().ExecBuiltIn("UnloadSkin", true);
    return true;
  }

  if (m_addon->Type() == ADDON_SERVICE)
  {
    CAddonDatabase database;
    database.Open();
    bool running = !database.IsAddonDisabled(m_addon->ID()); //grab a current state
    database.DisableAddon(m_addon->ID(),false); // enable it so we can remove it??
    // regrab from manager to have the correct path set
    AddonPtr addon;
    ADDON::CAddonMgr::Get().GetAddon(m_addon->ID(), addon);
    boost::shared_ptr<CService> service = boost::dynamic_pointer_cast<CService>(addon);
    if (service)
      service->Stop();
    CAddonMgr::Get().RemoveAddon(m_addon->ID()); // remove it
    return running;
  }

  if (m_addon->Type() == ADDON_PVRDLL)
  {
    // stop the pvr manager, so running pvr add-ons are stopped and closed
    PVR::CPVRManager::Get().Stop();
  }
  return false;
}
void CAddonsDirectory::GenerateListing(CURL &path, VECADDONS& addons, CFileItemList &items, bool reposAsFolders)
{
  CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc/addons");
  items.ClearItems();
  CAddonDatabase db;
  db.Open();
  for (unsigned i=0; i < addons.size(); i++)
  {
    AddonPtr addon = addons[i];
    CFileItemPtr pItem;
    if (reposAsFolders && addon->Type() == ADDON_REPOSITORY)
      pItem = FileItemFromAddon(addon, "addons://", true);
    else
      pItem = FileItemFromAddon(addon, path.Get(), false);
    AddonPtr addon2;
    if (CAddonMgr::Get().GetAddon(addon->ID(),addon2))
      pItem->SetProperty("Addon.Status",g_localizeStrings.Get(305));
    else if (db.IsOpen() && db.IsAddonDisabled(addon->ID()))
      pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24023));

    if (!addon->Props().broken.IsEmpty())
      pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24098));
    if (addon2 && addon2->Version() < addon->Version())
    {
      pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24068));
      pItem->SetProperty("Addon.UpdateAvail", true);
    }
    CAddonDatabase::SetPropertiesFromAddon(addon,pItem);
    items.Add(pItem);
  }
  db.Close();
}
Exemple #11
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);
    g_application.m_guiDialogKaiToast.QueueNotification(
                                                        addon->Icon(),
                                                        addon->Name(),
                                                        g_localizeStrings.Get(addon2 ? 113 : 114),
                                                        TOAST_DISPLAY_TIME, false);
  }
  else
  {
    g_application.m_guiDialogKaiToast.QueueNotification(
                                                        CGUIDialogKaiToast::Error,
                                                        fileName,
                                                        g_localizeStrings.Get(114),
                                                        TOAST_DISPLAY_TIME, false);
  }
}
bool CRetroPlayerDialogs::InstallGameClient(const string &strId, const CFileItem &file, GameClientPtr &result)
{
  // First, make sure the game client isn't installed
  CLog::Log(LOGDEBUG, "RetroPlayer: Trying to install game client %s", strId.c_str());
  AddonPtr addon;
  bool installed = CAddonMgr::Get().GetAddon(strId, addon, ADDON_GAMEDLL, false);
  if (installed && addon)
    return false;

  // Now make sure it exists in a remote repository
  CAddonDatabase database;
  if (database.Open() && database.GetAddon(strId, addon))
  {
    GameClientPtr gc = boost::dynamic_pointer_cast<CGameClient>(addon);
    if (gc && gc->CanOpen(file))
    {
      CLog::Log(LOGDEBUG, "RetroPlayer: Installing game client %s", strId.c_str());
      addon.reset();
      if (CAddonInstaller::Get().PromptForInstall(strId, addon))
      {
        gc = boost::dynamic_pointer_cast<CGameClient>(addon);
        if (gc)
        {
          result = gc;
          return true;
        }
      }
    }
  }
  return false;
}
Exemple #13
0
bool CAddonInstaller::InstallModal(const std::string &addonID, ADDON::AddonPtr &addon, bool promptForInstall /* = true */)
{
  if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
    return false;

  // we assume that addons that are enabled don't get to this routine (i.e. that GetAddon() has been called)
  if (CAddonMgr::GetInstance().GetAddon(addonID, addon, ADDON_UNKNOWN, false))
    return false; // addon is installed but disabled, and the user has specifically activated something that needs
                  // the addon - should we enable it?

  // check we have it available
  CAddonDatabase database;
  database.Open();
  if (!database.GetAddon(addonID, addon))
    return false;

  // if specified ask the user if he wants it installed
  if (promptForInstall)
  {
    if (HELPERS::ShowYesNoDialogLines(CVariant{24076}, CVariant{24100}, CVariant{addon->Name()}, CVariant{24101}) !=
      DialogResponse::YES)
    {
      return false;
    }
  }

  if (!InstallOrUpdate(addonID, false, true))
    return false;

  return CAddonMgr::GetInstance().GetAddon(addonID, addon);
}
Exemple #14
0
void CAddonUnInstallJob::OnPostUnInstall()
{
  if (m_addon->Type() == ADDON_REPOSITORY)
  {
    CAddonDatabase database;
    database.Open();
    database.DeleteRepository(m_addon->ID());
  }
}
VECSOURCES& CGUIViewStateAddonBrowser::GetSources()
{
  m_sources.clear();

  // we always have some enabled addons
  {
    CMediaSource share;
    share.strPath = "addons://enabled/";
    share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
    share.strName = g_localizeStrings.Get(24062);
    m_sources.push_back(share);
  }
  CAddonDatabase db;
  if (db.Open() && db.HasDisabledAddons())
  {
    CMediaSource share;
    share.strPath = "addons://disabled/";
    share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
    share.strName = g_localizeStrings.Get(24039);
    m_sources.push_back(share);
  }
  if (CAddonMgr::Get().HasOutdatedAddons())
  {
    CMediaSource share;
    share.strPath = "addons://outdated/";
    share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
    share.strName = g_localizeStrings.Get(24043);
    m_sources.push_back(share);
  }
  if (CAddonMgr::Get().HasAddons(ADDON_REPOSITORY,true))
  {
    CMediaSource share;
    share.strPath = "addons://repos/";
    share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
    share.strName = g_localizeStrings.Get(24033);
    m_sources.push_back(share);
  }
  // add "install from zip"
  {
    CMediaSource share;
    share.strPath = "addons://install/";
    share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
    share.strName = g_localizeStrings.Get(24041);
    m_sources.push_back(share);
  }
  // add "search"
  {
    CMediaSource share;
    share.strPath = "addons://search/";
    share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
    share.strName = g_localizeStrings.Get(137);
    m_sources.push_back(share);
  }

  return CGUIViewState::GetSources();
}
void CGUIDialogAddonInfo::OnUpdate()
{
  if (!m_localAddon)
    return;

  std::vector<std::pair<AddonVersion, std::string>> versions;

  CAddonDatabase database;
  database.Open();
  database.GetAvailableVersions(m_localAddon->ID(), versions);

  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));
          }
        }
      }
    }
  }

  if (versions.empty())
    CGUIDialogOK::ShowAndGetInput(CVariant{21341}, CVariant{21342});
  else
  {
    int i = AskForVersion(versions);
    if (i != -1)
    {
      Close();
      //turn auto updating off if downgrading
      if (m_localAddon->Version() > versions[i].first)
        CAddonMgr::GetInstance().AddToUpdateBlacklist(m_localAddon->ID());

      if (versions[i].second == LOCAL_CACHE)
        CAddonInstaller::GetInstance().InstallFromZip(StringUtils::Format(
            "special://home/addons/packages/%s-%s.zip", m_localAddon->ID().c_str(),
            versions[i].first.asString().c_str()));
      else
        CAddonInstaller::GetInstance().Install(m_localAddon->ID(), versions[i].first, versions[i].second);
    }
  }
}
void CAddonInstallJob::OnPostInstall(bool reloadAddon)
{
  if (m_addon->Type() < ADDON_VIZ_LIBRARY && g_settings.m_bAddonNotifications)
  {
    CGUIDialogKaiToast::QueueNotification(m_addon->Icon(),
                                          m_addon->Name(),
                                          g_localizeStrings.Get(m_update ? 24065 : 24064),
                                          TOAST_DISPLAY_TIME,false,
                                          TOAST_DISPLAY_TIME);
  }
  if (m_addon->Type() == ADDON_SKIN)
  {
    if (reloadAddon || (!m_update && CGUIDialogYesNo::ShowAndGetInput(m_addon->Name(),
                                                        g_localizeStrings.Get(24099),"","")))
    {
      g_guiSettings.SetString("lookandfeel.skin",m_addon->ID().c_str());
      CGUIDialogKaiToast *toast = (CGUIDialogKaiToast *)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST);
      if (toast)
      {
        toast->ResetTimer();
        toast->Close(true);
      }
      CApplicationMessenger::Get().ExecBuiltIn("ReloadSkin");
    }
  }

  if (m_addon->Type() == ADDON_SERVICE)
  {
    CAddonDatabase database;
    database.Open();
    database.DisableAddon(m_addon->ID(),!reloadAddon); //return it into state it was before OnPreInstall()
    if (reloadAddon) // reload/start it if it was running
    {
      // regrab from manager to have the correct path set
      AddonPtr addon; 
      CAddonMgr::Get().GetAddon(m_addon->ID(), addon);
      boost::shared_ptr<CService> service = boost::dynamic_pointer_cast<CService>(addon);
      if (service)
        service->Start();
    }
  }

  if (m_addon->Type() == ADDON_REPOSITORY)
  {
    VECADDONS addons;
    addons.push_back(m_addon);
    CJobManager::GetInstance().AddJob(new CRepositoryUpdateJob(addons), &CAddonInstaller::Get());
  }

  if (m_addon->Type() == ADDON_PVRDLL)
  {
    // (re)start the pvr manager
    PVR::CPVRManager::Get().Start(true);
  }
}
Exemple #18
0
void CPVRDatabase::UpdateTables(int iVersion)
{
  if (iVersion < 13)
    m_pDS->exec("ALTER TABLE channels ADD idEpg integer;");

  if (iVersion < 14)
    m_pDS->exec("ALTER TABLE channelsettings ADD fCustomVerticalShift float;");

  if (iVersion < 15)
  {
    m_pDS->exec("ALTER TABLE channelsettings ADD bCustomNonLinStretch bool;");
    m_pDS->exec("ALTER TABLE channelsettings ADD bPostProcess bool;");
    m_pDS->exec("ALTER TABLE channelsettings ADD iScalingMethod integer;");
  }
  if (iVersion < 16)
  {
    /* sqlite apparently can't delete columns from an existing table, so just leave the extra column alone */
  }
  if (iVersion < 17)
  {
    m_pDS->exec("ALTER TABLE channelsettings ADD iDeinterlaceMode integer");
    m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 2 WHERE iInterlaceMethod NOT IN (0,1)"); // anything other than none: method auto => mode force
    m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 1 WHERE iInterlaceMethod = 1"); // method auto => mode auto
    m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 0, iInterlaceMethod = 1 WHERE iInterlaceMethod = 0"); // method none => mode off, method auto
  }
  if (iVersion < 19)
  {
    // bit of a hack, but we need to keep the version/contents of the non-pvr databases the same to allow clean upgrades
    ADDON::VECADDONS addons;
    if (!CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true))
      CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__);
    else
    {
      CAddonDatabase database;
      database.Open();
      for (IVECADDONS it = addons.begin(); it != addons.end(); it++)
      {
        if (!database.IsSystemPVRAddonEnabled(it->get()->ID()))
          CAddonMgr::Get().DisableAddon(it->get()->ID());
      }
      database.Close();
    }
  }
  if (iVersion < 20)
    m_pDS->exec("ALTER TABLE channels ADD bIsUserSetIcon bool");

  if (iVersion < 21)
    m_pDS->exec("ALTER TABLE channelgroups ADD iGroupType integer");

  if (iVersion < 22)
    m_pDS->exec("ALTER TABLE channels ADD bIsLocked bool");

  if (iVersion < 23)
    m_pDS->exec("ALTER TABLE channelgroups ADD iLastWatched integer");
}
Exemple #19
0
AddonPtr CAddonInstallJob::GetRepoForAddon(const AddonPtr& addon)
{
  CAddonDatabase database;
  database.Open();
  CStdString repo;
  database.GetRepoForAddon(addon->ID(), repo);
  AddonPtr repoPtr;
  CAddonMgr::Get().GetAddon(repo, repoPtr);

  return repoPtr;
}
void CGUIDialogAddonInfo::OnEnable(bool enable)
{
  if (!m_localAddon.get())
    return;

  CAddonDatabase database;
  database.Open();
  database.DisableAddon(m_localAddon->ID(), !enable);
  SetItem(m_item);
  UpdateControls();
  g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE);
}
Exemple #21
0
void CAddonInstaller::PrunePackageCache()
{
  std::map<std::string,CFileItemList*> packs;
  int64_t size = EnumeratePackageFolder(packs);
  int64_t limit = (int64_t)g_advancedSettings.m_addonPackageFolderSize * 1024 * 1024;
  if (size < limit)
    return;

  // Prune packages
  // 1. Remove the largest packages, leaving at least 2 for each add-on
  CFileItemList items;
  CAddonDatabase db;
  db.Open();
  for (std::map<std::string,CFileItemList*>::const_iterator it = packs.begin(); it != packs.end(); ++it)
  {
    it->second->Sort(SortByLabel, SortOrderDescending);
    for (int j = 2; j < it->second->Size(); j++)
      items.Add(CFileItemPtr(new CFileItem(*it->second->Get(j))));
  }

  items.Sort(SortBySize, SortOrderDescending);
  int i = 0;
  while (size > limit && i < items.Size())
  {
    size -= items[i]->m_dwSize;
    db.RemovePackage(items[i]->GetPath());
    CFileUtils::DeleteItem(items[i++], true);
  }

  if (size > limit)
  {
    // 2. Remove the oldest packages (leaving least 1 for each add-on)
    items.Clear();
    for (std::map<std::string,CFileItemList*>::iterator it = packs.begin(); it != packs.end(); ++it)
    {
      if (it->second->Size() > 1)
        items.Add(CFileItemPtr(new CFileItem(*it->second->Get(1))));
    }

    items.Sort(SortByDate, SortOrderAscending);
    i = 0;
    while (size > limit && i < items.Size())
    {
      size -= items[i]->m_dwSize;
      db.RemovePackage(items[i]->GetPath());
      CFileUtils::DeleteItem(items[i++],true);
    }
  }

  // clean up our mess
  for (std::map<std::string,CFileItemList*>::iterator it = packs.begin(); it != packs.end(); ++it)
    delete it->second;
}
bool CGUIDialogAddonInfo::SetItem(const CFileItemPtr& item)
{
  *m_item = *item;
  m_localAddon.reset();
  m_addon.reset();

  CAddonMgr::GetInstance().GetAddon(item->GetProperty("Addon.ID").asString(), m_localAddon, ADDON_UNKNOWN, false);

  CAddonDatabase database;
  database.Open();
  database.GetAddon(item->GetProperty("Addon.ID").asString(), m_addon);
  return true;
}
Exemple #23
0
bool CAddonInstaller::CheckDependencies(const AddonPtr &addon,
                                        std::vector<std::string>& preDeps, CAddonDatabase &database,
                                        std::pair<std::string, std::string> &failedDep)
{
  if (addon == NULL)
    return true; // a NULL addon has no dependencies

  if (!database.Open())
    return false;

  ADDONDEPS deps = addon->GetDeps();
  for (ADDONDEPS::const_iterator i = deps.begin(); i != deps.end(); ++i)
  {
    const std::string &addonID = i->first;
    const AddonVersion &version = i->second.first;
    bool optional = i->second.second;
    AddonPtr dep;
    bool haveAddon = CAddonMgr::GetInstance().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, "CAddonInstallJob[%s]: requires %s version %s which is not available", addon->ID().c_str(), addonID.c_str(), version.asString().c_str());
        database.Close();

        // fill in the details of the failed dependency
        failedDep.first = addon->ID();
        failedDep.second = version.asString();

        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, failedDep))
      {
        database.Close();
        preDeps.push_back(dep->ID());
        return false;
      }
    }
  }
  database.Close();

  return true;
}
Exemple #24
0
bool CAddonInstaller::PromptForInstall(const std::string &addonID, AddonPtr &addon)
{
  if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
    return false;

  // we assume that addons that are enabled don't get to this routine (i.e. that GetAddon() has been called)
  if (CAddonMgr::Get().GetAddon(addonID, addon, ADDON_UNKNOWN, false))
    return false; // addon is installed but disabled, and the user has specifically activated something that needs
                  // the addon - should we enable it?

  // check we have it available
  CAddonDatabase database;
  database.Open();
  if (database.GetAddon(addonID, addon))
  { // yes - ask user if they want it installed
    if (!CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(24076), g_localizeStrings.Get(24100),
                                          addon->Name().c_str(), g_localizeStrings.Get(24101)))
      return false;
    if (Install(addonID, true))
    {
      CGUIDialogProgress *progress = (CGUIDialogProgress *)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
      if (progress)
      {
        progress->SetHeading(13413); // Downloading
        progress->SetLine(0, "");
        progress->SetLine(1, addon->Name());
        progress->SetLine(2, "");
        progress->SetPercentage(0);
        progress->StartModal();
        while (true)
        {
          progress->Progress();
          unsigned int percent;
          if (progress->IsCanceled())
          {
            Cancel(addonID);
            break;
          }
          if (!GetProgress(addonID, percent))
            break;
          progress->SetPercentage(percent);
        }
        progress->Close();
      }
      return CAddonMgr::Get().GetAddon(addonID, addon);
    }
  }
  return false;
}
Exemple #25
0
CDateTime CAddonInstaller::LastRepoUpdate() const
{
  CDateTime update;
  VECADDONS addons;
  CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons);
  for (unsigned int i=0;i<addons.size();++i)
  {
    CAddonDatabase database;
    database.Open();
    CDateTime lastUpdate = database.GetRepoTimestamp(addons[i]->ID());
    if (lastUpdate.IsValid() && lastUpdate > update)
      update = lastUpdate;
  }
  return update;
}
Exemple #26
0
bool CAddonInstallJob::GetAddonWithHash(const std::string& addonID, const std::string& repoID, ADDON::AddonPtr& addon, std::string& hash)
{
  CAddonDatabase database;
  if (!database.Open())
    return false;

  if (!database.GetAddon(addonID, addon))
    return false;

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

  return std::static_pointer_cast<CRepository>(repo)->GetAddonHash(addon, hash);
}
Exemple #27
0
    Addon::Addon(const char* cid, bool installed) throw (AddonException)
    {
      String id(cid ? cid : emptyString);

      // if the id wasn't passed then get the id from
      //   the global dictionary
      if (id.empty())
        id = getDefaultId();

      // if we still don't have an id then bail
      if (id.empty())
        throw AddonException("No valid addon id could be obtained. None was passed and the script wasn't executed in a normal xbmc manner.");

      bool success = ADDON::CAddonMgr::Get().GetAddon(id.c_str(), pAddon);
      if (!success && !installed)
      {
        CAddonDatabase addondb;
        addondb.Open();
        success = addondb.GetAddon(id, pAddon);
      }

      // if we still fail we MAY be able to recover.
      if (!success)
      {
        // we need to check the version prior to trying a bw compatibility trick
        ADDON::AddonVersion version(getAddonVersion());
        ADDON::AddonVersion allowable("1.0");

        if (version <= allowable)
        {
          // try the default ...
          id = getDefaultId();

          if (id.empty() || !ADDON::CAddonMgr::Get().GetAddon(id.c_str(), pAddon))
            throw AddonException("Could not get AddonPtr!");
          else
            CLog::Log(LOGERROR,"Use of deprecated functionality. Please to not assume that \"os.getcwd\" will return the script directory.");
        }
        else
        {
          throw AddonException("Could not get AddonPtr given a script id of %s."
                               "If you are trying to use 'os.getcwd' to set the path, you cannot do that in a version %s plugin.",
                               id.c_str(), version.asString().c_str());
        }
      }

      CAddonMgr::Get().AddToUpdateableAddons(pAddon);
    }
void CGUIDialogAddonInfo::OnUninstall()
{
  if (!m_localAddon.get())
    return;

  // ensure the addon isn't disabled in our database
  CAddonDatabase database;
  database.Open();
  database.DisableAddon(m_localAddon->ID(), false);

  CFileItemList list;
  list.Add(CFileItemPtr(new CFileItem(m_localAddon->Path(),true)));
  list[0]->Select(true);
  CJobManager::GetInstance().AddJob(new CFileOperationJob(CFileOperationJob::ActionDelete,list,""), &CAddonInstaller::Get());
  CAddonMgr::Get().RemoveAddon(m_localAddon->ID());
  Close();
}
Exemple #29
0
bool CAddonInstaller::GetRepoForAddon(const std::string& addonId, RepositoryPtr& repoPtr)
{
  CAddonDatabase database;
  if (!database.Open())
    return false;

  auto repoId = database.GetAddonVersion(addonId).second;
  if (repoId.empty())
    return false;

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

  repoPtr = std::static_pointer_cast<CRepository>(tmp);
  return true;
}
Exemple #30
0
void CAddonInstaller::Install(const CStdString &addonID, bool force, const CStdString &referer, bool background)
{
  AddonPtr addon;
  bool addonInstalled = CAddonMgr::Get().GetAddon(addonID, addon);
  if (addonInstalled && !force)
    return;

  // 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);

    // check whether we already have the addon installing
    CSingleLock lock(m_critSection);
    if (m_downloadJobs.find(addonID) != m_downloadJobs.end())
      return; // already installing this addon

    if (background)
    {
      unsigned int jobID = CJobManager::GetInstance().AddJob(new CAddonInstallJob(addon, hash, addonInstalled, referer), this);
      m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(jobID)));
    }
    else
    {
      m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(0)));
      lock.Leave();
      CAddonInstallJob job(addon, hash, addonInstalled, referer);
      if (!job.DoWork())
      { // TODO: dump something to debug log?
      }
      lock.Enter();
      JobMap::iterator i = m_downloadJobs.find(addon->ID());
      m_downloadJobs.erase(i);
    }
  }
}