Ejemplo n.º 1
0
int CGUIWindowAddonBrowser::SelectAddonID(const std::vector<ADDON::TYPE> &types, std::vector<std::string> &addonIDs, bool showNone /* = false */, bool showDetails /* = true */, bool multipleSelection /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */)
{
  // if we shouldn't show neither installed nor installable addons the list will be empty
  if (!showInstalled && !showInstallable)
    return 0;

  // can't show the "Get More" button if we already show installable addons
  if (showInstallable)
    showMore = false;

  CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
  if (!dialog)
    return 0;

  // get rid of any invalid addon types
  std::vector<ADDON::TYPE> validTypes(types.size());
  std::copy_if(types.begin(), types.end(), validTypes.begin(), [](ADDON::TYPE type) { return type != ADDON_UNKNOWN; });

  if (validTypes.empty())
    return 0;

  // get all addons to show
  VECADDONS addons;
  if (showInstalled)
  {
    for (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type)
    {
      VECADDONS typeAddons;
      if (*type == ADDON_AUDIO)
        CAddonsDirectory::GetScriptsAndPlugins("audio", typeAddons);
      else if (*type == ADDON_EXECUTABLE)
        CAddonsDirectory::GetScriptsAndPlugins("executable", typeAddons);
      else if (*type == ADDON_IMAGE)
        CAddonsDirectory::GetScriptsAndPlugins("image", typeAddons);
      else if (*type == ADDON_VIDEO)
        CAddonsDirectory::GetScriptsAndPlugins("video", typeAddons);
      else
        CAddonMgr::GetInstance().GetAddons(*type, typeAddons);

      addons.insert(addons.end(), typeAddons.begin(), typeAddons.end());
    }
  }

  if (showInstallable || showMore)
  {
    VECADDONS installableAddons;
    CAddonDatabase database;
    if (database.Open() && database.GetAddons(installableAddons))
    {
      for (ADDON::IVECADDONS addon = installableAddons.begin(); addon != installableAddons.end();)
      {
        AddonPtr pAddon = *addon;
        
        // check if the addon matches one of the provided addon types
        bool matchesType = false;
        for (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type)
        {
          if (pAddon->IsType(*type))
          {
            matchesType = true;
            break;
          }
        }

        // only show addons that match one of the provided addon types and that aren't disabled
        if (matchesType && !CAddonMgr::GetInstance().IsAddonDisabled(pAddon->ID()))
        {
          // check if the addon is installed
          bool isInstalled = CAddonMgr::GetInstance().IsAddonInstalled(pAddon->ID());

          // check if the addon is installed or can be installed
          if ((showInstallable || showMore) && !isInstalled && CAddonMgr::GetInstance().CanAddonBeInstalled(pAddon))
          {
            ++addon;
            continue;
          }
        }

        addon = installableAddons.erase(addon);
      }

      if (showInstallable)
        addons.insert(addons.end(), installableAddons.begin(), installableAddons.end());
      else if (showMore)
        showMore = !installableAddons.empty();
    }
  }

  if (addons.empty() && !showNone)
    return 0;

  // turn the addons into items
  std::map<std::string, AddonPtr> addonMap;
  CFileItemList items;
  for (ADDON::IVECADDONS addon = addons.begin(); addon != addons.end(); ++addon)
  {
    CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addon, (*addon)->ID()));
    if (!items.Contains(item->GetPath()))
    {
#if defined(TARGET_ANDROID)
      // only show "skin.re-touched" on fire tables and iOS.
      if ((*addon)->ID() == "skin.re-touched")
      {
        if (!CAndroidFeatures::HasTouchScreen())
          continue;
      }
#endif
      items.Add(item);
      addonMap.insert(std::make_pair(item->GetPath(), *addon));
    }
  }

  if (items.IsEmpty() && !showNone)
    return 0;

  std::string heading;
  for (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type)
  {
    if (!heading.empty())
      heading += ", ";
    heading += TranslateType(*type, true);
  }

  dialog->SetHeading(CVariant{std::move(heading)});
  dialog->Reset();
  dialog->SetUseDetails(showDetails);

  if (multipleSelection)
  {
    showNone = false;
    showMore = false;
    dialog->EnableButton(true, 186);
  }
  else if (showMore)
    dialog->EnableButton(true, 21452);

  if (showNone)
  {
    CFileItemPtr item(new CFileItem("", false));
    item->SetLabel(g_localizeStrings.Get(231));
    item->SetLabel2(g_localizeStrings.Get(24040));
    item->SetIconImage("DefaultAddonNone.png");
    item->SetSpecialSort(SortSpecialOnTop);
    items.Add(item);
  }
  items.Sort(SortByLabel, SortOrderAscending);

  if (addonIDs.size() > 0)
  {
    for (std::vector<std::string>::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; ++it)
    {
      CFileItemPtr item = items.Get(*it);
      if (item)
        item->Select(true);
    }
  }
  dialog->SetItems(items);
  dialog->SetMultiSelection(multipleSelection);
  dialog->Open();

  // if the "Get More" button has been pressed and we haven't shown the
  // installable addons so far show a list of installable addons
  if (showMore&& dialog->IsButtonPressed())
    return SelectAddonID(types, addonIDs, showNone, showDetails, multipleSelection, false, true, false);

  if (!dialog->IsConfirmed())
    return 0;

  addonIDs.clear();
  for (int i : dialog->GetSelectedItems())
  {
    const CFileItemPtr& item = items.Get(i);

    // check if one of the selected addons needs to be installed
    if (showInstallable)
    {
      std::map<std::string, AddonPtr>::const_iterator itAddon = addonMap.find(item->GetPath());
      if (itAddon != addonMap.end())
      {
        const AddonPtr& addon = itAddon->second;

        // if the addon isn't installed we need to install it
        if (!CAddonMgr::GetInstance().IsAddonInstalled(addon->ID()))
        {
          AddonPtr installedAddon;
          if (!CAddonInstaller::GetInstance().InstallModal(addon->ID(), installedAddon, false))
            continue;
        }

        // if the addon is disabled we need to enable it
        if (CAddonMgr::GetInstance().IsAddonDisabled(addon->ID()))
          CAddonMgr::GetInstance().EnableAddon(addon->ID());
      }
    }

    addonIDs.push_back(item->GetPath());
  }
  return 1;
}
Ejemplo n.º 2
0
void CPVRDatabase::UpdateTables(int iVersion)
{
  if (iVersion < 13)
    m_pDS->exec("ALTER TABLE channels ADD idEpg integer;");

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

  if (iVersion < 24)
    m_pDS->exec("ALTER TABLE channels ADD bIsUserSetName bool");
  
  if (iVersion < 25)
    m_pDS->exec("DROP TABLE IF EXISTS channelsettings");

  if (iVersion < 26)
  {
    m_pDS->exec("ALTER TABLE channels ADD iClientSubChannelNumber integer");
    m_pDS->exec("UPDATE channels SET iClientSubChannelNumber = 0");
    m_pDS->exec("ALTER TABLE map_channelgroups_channels ADD iSubChannelNumber integer");
    m_pDS->exec("UPDATE map_channelgroups_channels SET iSubChannelNumber = 0");
  }

  if (iVersion < 27)
    m_pDS->exec("ALTER TABLE channelgroups ADD bIsHidden bool");

  if (iVersion < 28)
  {
    VECADDONS addons;
    CAddonDatabase database;
    if (database.Open() && CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true))
    {
      /** find all old client IDs */
      std::string strQuery(PrepareSQL("SELECT idClient, sUid FROM clients"));
      m_pDS->query(strQuery);
      while (!m_pDS->eof() && !addons.empty())
      {
        /** try to find an add-on that matches the sUid */
        for (VECADDONS::iterator it = addons.begin(); it != addons.end(); ++it)
        {
          if ((*it)->ID() == m_pDS->fv(1).get_asString())
          {
            /** try to get the current ID from the database */
            int iAddonId = database.GetAddonId(*it);
            /** register a new id if it didn't exist */
            if (iAddonId <= 0)
              iAddonId = database.AddAddon(*it, 0);
            if (iAddonId > 0)
            {
              // this fails when an id becomes the id of one that's being replaced next iteration
              // but since almost everyone only has 1 add-on enabled...
              /** update the iClientId in the channels table */
              strQuery = PrepareSQL("UPDATE channels SET iClientId = %u WHERE iClientId = %u", iAddonId, m_pDS->fv(0).get_asInt());
              m_pDS->exec(strQuery);

              /** no need to check this add-on again */
              it = addons.erase(it);
              break;
            }
          }
        }
        m_pDS->next();
      }
    }
    m_pDS->exec("DROP TABLE clients");
  }

  if (iVersion < 29)
    m_pDS->exec("ALTER TABLE channelgroups ADD iPosition integer");
}
Ejemplo n.º 3
0
bool CPVRClients::UpdateAndInitialiseClients(bool bInitialiseAllClients /* = false */)
{
  bool bReturn(true);
  VECADDONS map;
  VECADDONS disableAddons;
  {
    CSingleLock lock(m_critSection);
    map = m_addons;
  }

  if (map.empty())
    return false;

  for (VECADDONS::iterator it = map.begin(); it != map.end(); ++it)
  {
    bool bEnabled = (*it)->Enabled() &&
        !CAddonMgr::GetInstance().IsAddonDisabled((*it)->ID());

    if (!bEnabled && IsKnownClient(*it))
    {
      CSingleLock lock(m_critSection);
      /* stop the client and remove it from the db */
      StopClient(*it, false);
      disableAddons.push_back(*it);

    }
    else if (bEnabled && (bInitialiseAllClients || !IsKnownClient(*it) || !IsConnectedClient(*it)))
    {
      bool bDisabled(false);

      // register the add-on in the pvr db, and create the CPVRClient instance
      int iClientId = RegisterClient(*it);
      if (iClientId <= 0)
      {
        // failed to register or create the add-on, disable it
        CLog::Log(LOGWARNING, "%s - failed to register add-on %s, disabling it", __FUNCTION__, (*it)->Name().c_str());
        disableAddons.push_back(*it);
        bDisabled = true;
      }
      else
      {
        ADDON_STATUS status(ADDON_STATUS_UNKNOWN);
        PVR_CLIENT addon;
        {
          CSingleLock lock(m_critSection);
          if (!GetClient(iClientId, addon))
          {
            CLog::Log(LOGWARNING, "%s - failed to find add-on %s, disabling it", __FUNCTION__, (*it)->Name().c_str());
            disableAddons.push_back(*it);
            bDisabled = true;
          }
        }

        // throttle connection attempts, no more than 1 attempt per 5 seconds
        if (!bDisabled && addon->Enabled())
        {
          time_t now;
          CDateTime::GetCurrentDateTime().GetAsTime(now);
          std::map<int, time_t>::iterator it = m_connectionAttempts.find(iClientId);
          if (it != m_connectionAttempts.end() && now < it->second)
            continue;
          m_connectionAttempts[iClientId] = now + 5;
        }

        // re-check the enabled status. newly installed clients get disabled when they're added to the db
        if (!bDisabled && addon->Enabled() && (status = addon->Create(iClientId)) != ADDON_STATUS_OK)
        {
          CLog::Log(LOGWARNING, "%s - failed to create add-on %s, status = %d", __FUNCTION__, (*it)->Name().c_str(), status);
          if (!addon.get() || !addon->DllLoaded() || status == ADDON_STATUS_PERMANENT_FAILURE)
          {
            // failed to load the dll of this add-on, disable it
            CLog::Log(LOGWARNING, "%s - failed to load the dll for add-on %s, disabling it", __FUNCTION__, (*it)->Name().c_str());
            disableAddons.push_back(*it);
            bDisabled = true;
          }
        }
      }

      if (bDisabled && (g_PVRManager.IsStarted() || g_PVRManager.IsInitialising()))
        CGUIDialogOK::ShowAndGetInput(CVariant{24070}, CVariant{16029});
    }
  }

  // disable add-ons that failed to initialise
  if (!disableAddons.empty())
  {
    CSingleLock lock(m_critSection);
    for (VECADDONS::iterator it = disableAddons.begin(); it != disableAddons.end(); ++it)
    {
      // disable in the add-on db
      CAddonMgr::GetInstance().DisableAddon((*it)->ID());

      // remove from the pvr add-on list
      VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), *it);
      if (addonPtr != m_addons.end())
        m_addons.erase(addonPtr);
    }
  }

  return bReturn;
}
Ejemplo n.º 4
0
bool CPVRClients::AutoconfigureClients(void)
{
  bool bReturn(false);
  std::vector<PVR_CLIENT> autoConfigAddons;
  PVR_CLIENT addon;
  VECADDONS map;
  CAddonMgr::GetInstance().GetAddons(ADDON_PVRDLL, map, false);

  /** get the auto-configurable add-ons */
  for (VECADDONS::iterator it = map.begin(); it != map.end(); ++it)
  {
    if (CAddonMgr::GetInstance().IsAddonDisabled((*it)->ID()))
    {
      addon = std::dynamic_pointer_cast<CPVRClient>(*it);
      if (addon->CanAutoconfigure())
        autoConfigAddons.push_back(addon);
    }
  }

  /** no configurable add-ons found */
  if (autoConfigAddons.size() == 0)
    return bReturn;

  /** display a progress bar while trying to auto-configure add-ons */
  CGUIDialogExtendedProgressBar *loadingProgressDialog = (CGUIDialogExtendedProgressBar *)g_windowManager.GetWindow(WINDOW_DIALOG_EXT_PROGRESS);
  CGUIDialogProgressBarHandle* progressHandle = loadingProgressDialog->GetHandle(g_localizeStrings.Get(19688)); // Scanning for PVR services
  progressHandle->SetPercentage(0);
  progressHandle->SetText(g_localizeStrings.Get(19688)); //Scanning for PVR services

  /** start zeroconf and wait a second to get some responses */
  CZeroconfBrowser::GetInstance()->Start();
  for (std::vector<PVR_CLIENT>::iterator it = autoConfigAddons.begin(); !bReturn && it != autoConfigAddons.end(); ++it)
    (*it)->AutoconfigureRegisterType();

  unsigned iIterations(0);
  float percentage(0.0f);
  float percentageStep(100.0f / PVR_CLIENT_AVAHI_SCAN_ITERATIONS);
  progressHandle->SetPercentage(percentage);

  /** while no add-ons were configured within 20 iterations */
  while (!bReturn && iIterations++ < PVR_CLIENT_AVAHI_SCAN_ITERATIONS)
  {
    /** check each disabled add-on */
    for (std::vector<PVR_CLIENT>::iterator it = autoConfigAddons.begin(); !bReturn && it != autoConfigAddons.end(); ++it)
    {
      if (addon->Autoconfigure())
      {
        progressHandle->SetPercentage(100.0f);
        progressHandle->MarkFinished();

        /** enable the add-on */
        CAddonMgr::GetInstance().EnableAddon((*it)->ID());
        CSingleLock lock(m_critSection);
        m_addons.push_back(*it);
        bReturn = true;
      }
    }

    /** wait a while and try again */
    if (!bReturn)
    {
      percentage += percentageStep;
      progressHandle->SetPercentage(percentage);
      Sleep(PVR_CLIENT_AVAHI_SLEEP_TIME_MS);
    }
  }

  progressHandle->SetPercentage(100.0f);
  progressHandle->MarkFinished();
  return bReturn;
}
Ejemplo n.º 5
0
JSONRPC_STATUS CAddonsOperations::GetAddons(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
  vector<TYPE> addonTypes;
  TYPE addonType = TranslateType(parameterObject["type"].asString());
  CPluginSource::Content content = CPluginSource::Translate(parameterObject["content"].asString());
  CVariant enabled = parameterObject["enabled"];

  // ignore the "content" parameter if the type is specified but not a plugin or script
  if (addonType != ADDON_UNKNOWN && addonType != ADDON_PLUGIN && addonType != ADDON_SCRIPT)
    content = CPluginSource::UNKNOWN;

  if (addonType >= ADDON_VIDEO && addonType <= ADDON_EXECUTABLE)
  {
    addonTypes.push_back(ADDON_PLUGIN);
    addonTypes.push_back(ADDON_SCRIPT);

    switch (addonType)
    {
    case ADDON_VIDEO:
      content = CPluginSource::VIDEO;
      break;
    case ADDON_AUDIO:
      content = CPluginSource::AUDIO;
      break;
    case ADDON_IMAGE:
      content = CPluginSource::IMAGE;
      break;
    case ADDON_EXECUTABLE:
      content = CPluginSource::EXECUTABLE;
      break;

    default:
      break;
    }
  }
  else
    addonTypes.push_back(addonType);

  VECADDONS addons;
  for (vector<TYPE>::const_iterator typeIt = addonTypes.begin(); typeIt != addonTypes.end(); ++typeIt)
  {
    VECADDONS typeAddons;
    if (*typeIt == ADDON_UNKNOWN)
    {
      if (!enabled.isBoolean())
      {
        CAddonMgr::Get().GetAllAddons(typeAddons, false);
        CAddonMgr::Get().GetAllAddons(typeAddons, true);
      }
      else
        CAddonMgr::Get().GetAllAddons(typeAddons, enabled.asBoolean());
    }
    else
    {
      if (!enabled.isBoolean())
      {
        CAddonMgr::Get().GetAddons(*typeIt, typeAddons, false);
        VECADDONS enabledAddons;
        CAddonMgr::Get().GetAddons(*typeIt, enabledAddons, true);
        typeAddons.insert(typeAddons.end(), enabledAddons.begin(), enabledAddons.end());
      }
      else
        CAddonMgr::Get().GetAddons(*typeIt, typeAddons, enabled.asBoolean());
    }

    addons.insert(addons.end(), typeAddons.begin(), typeAddons.end());
  }

  // remove library addons
  for (int index = 0; index < (int)addons.size(); index++)
  {
    PluginPtr plugin;
    if (content != CPluginSource::UNKNOWN)
      plugin = boost::dynamic_pointer_cast<CPluginSource>(addons.at(index));

    if ((addons.at(index)->Type() <= ADDON_UNKNOWN || addons.at(index)->Type() >= ADDON_MAX) ||
       ((content != CPluginSource::UNKNOWN && plugin == NULL) || (plugin != NULL && !plugin->Provides(content))))
    {
      addons.erase(addons.begin() + index);
      index--;
    }
  }

  int start, end;
  HandleLimits(parameterObject, result, addons.size(), start, end);
  
  CAddonDatabase addondb;
  for (int index = start; index < end; index++)
    FillDetails(addons.at(index), parameterObject["properties"], result["addons"], addondb, true);
  
  return OK;
}