Ejemplo n.º 1
0
bool CSMBDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  // We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]]

  /* samba isn't thread safe with old interface, always lock */
  CSingleLock lock(smb);

  smb.Init();

  //Separate roots for the authentication and the containing items to allow browsing to work correctly
  std::string strRoot = url.Get();
  std::string strAuth;

  lock.Leave(); // OpenDir is locked
  int fd = OpenDir(url, strAuth);
  if (fd < 0)
    return false;

  URIUtils::AddSlashAtEnd(strRoot);
  URIUtils::AddSlashAtEnd(strAuth);

  std::string strFile;

  // need to keep the samba lock for as short as possible.
  // so we first cache all directory entries and then go over them again asking for stat
  // "stat" is locked each time. that way the lock is freed between stat requests
  vector<CachedDirEntry> vecEntries;
  struct smbc_dirent* dirEnt;

  lock.Enter();
  while ((dirEnt = smbc_readdir(fd)))
  {
    CachedDirEntry aDir;
    aDir.type = dirEnt->smbc_type;
    aDir.name = dirEnt->name;
    vecEntries.push_back(aDir);
  }
  smbc_closedir(fd);
  lock.Leave();

  for (size_t i=0; i<vecEntries.size(); i++)
  {
    CachedDirEntry aDir = vecEntries[i];

    // We use UTF-8 internally, as does SMB
    strFile = aDir.name;

    if (!strFile.empty() && strFile != "." && strFile != ".."
      && strFile != "lost+found"
      && aDir.type != SMBC_PRINTER_SHARE && aDir.type != SMBC_IPC_SHARE)
    {
     int64_t iSize = 0;
      bool bIsDir = true;
      int64_t lTimeDate = 0;
      bool hidden = false;

      if(StringUtils::EndsWith(strFile, "$") && aDir.type == SMBC_FILE_SHARE )
        continue;

      // only stat files that can give proper responses
      if ( aDir.type == SMBC_FILE ||
           aDir.type == SMBC_DIR )
      {
        // set this here to if the stat should fail
        bIsDir = (aDir.type == SMBC_DIR);

        struct stat info = {0};
        if ((m_flags & DIR_FLAG_NO_FILE_INFO)==0 && g_advancedSettings.m_sambastatfiles)
        {
          // make sure we use the authenticated path wich contains any default username
          const std::string strFullName = strAuth + smb.URLEncode(strFile);

          lock.Enter();

          if( smbc_stat(strFullName.c_str(), &info) == 0 )
          {

            char value[20];
            // We poll for extended attributes which symbolizes bits but split up into a string. Where 0x02 is hidden and 0x12 is hidden directory.
            // According to the libsmbclient.h it's supposed to return 0 if ok, or the length of the string. It seems always to return the length wich is 4
            if (smbc_getxattr(strFullName.c_str(), "system.dos_attr.mode", value, sizeof(value)) > 0)
            {
              long longvalue = strtol(value, NULL, 16);
              if (longvalue & SMBC_DOS_MODE_HIDDEN)
                hidden = true;
            }
            else
              CLog::Log(LOGERROR, "Getting extended attributes for the share: '%s'\nunix_err:'%x' error: '%s'", CURL::GetRedacted(strFullName).c_str(), errno, strerror(errno));

            bIsDir = S_ISDIR(info.st_mode);
            lTimeDate = info.st_mtime;
            if(lTimeDate == 0) // if modification date is missing, use create date
              lTimeDate = info.st_ctime;
            iSize = info.st_size;
          }
          else
            CLog::Log(LOGERROR, "%s - Failed to stat file %s", __FUNCTION__, CURL::GetRedacted(strFullName).c_str());

          lock.Leave();
        }
      }

      FILETIME fileTime, localTime;
      TimeTToFileTime(lTimeDate, &fileTime);
      FileTimeToLocalFileTime(&fileTime, &localTime);

      if (bIsDir)
      {
        CFileItemPtr pItem(new CFileItem(strFile));
        std::string path(strRoot);

        // needed for network / workgroup browsing
        // skip if root if we are given a server
        if (aDir.type == SMBC_SERVER)
        {
          /* create url with same options, user, pass.. but no filename or host*/
          CURL rooturl(strRoot);
          rooturl.SetFileName("");
          rooturl.SetHostName("");
          path = smb.URLEncode(rooturl);
        }
        path = URIUtils::AddFileToFolder(path,aDir.name);
        URIUtils::AddSlashAtEnd(path);
        pItem->SetPath(path);
        pItem->m_bIsFolder = true;
        pItem->m_dateTime=localTime;
        if (hidden)
          pItem->SetProperty("file:hidden", true);
        items.Add(pItem);
      }
      else
      {
        CFileItemPtr pItem(new CFileItem(strFile));
        pItem->SetPath(strRoot + aDir.name);
        pItem->m_bIsFolder = false;
        pItem->m_dwSize = iSize;
        pItem->m_dateTime=localTime;
        if (hidden)
          pItem->SetProperty("file:hidden", true);
        items.Add(pItem);
      }
    }
  }

  return true;
}
Ejemplo n.º 2
0
void PLAYLIST::CPlayListPlayer::OnApplicationMessage(KODI::MESSAGING::ThreadMessage* pMsg)
{
  switch (pMsg->dwMessage)
  {
  case TMSG_PLAYLISTPLAYER_PLAY:
    if (pMsg->param1 != -1)
      Play(pMsg->param1, "");
    else
      Play();
    break;

  case TMSG_PLAYLISTPLAYER_PLAY_SONG_ID:
    if (pMsg->param1 != -1)
    {
      bool *result = (bool*)pMsg->lpVoid;
      *result = PlaySongId(pMsg->param1);
    }
    else
      Play();
    break;

  case TMSG_PLAYLISTPLAYER_NEXT:
    PlayNext();
    break;

  case TMSG_PLAYLISTPLAYER_PREV:
    PlayPrevious();
    break;

  case TMSG_PLAYLISTPLAYER_ADD:
    if (pMsg->lpVoid)
    {
      CFileItemList *list = (CFileItemList *)pMsg->lpVoid;

      Add(pMsg->param1, (*list));
      delete list;
    }
    break;

  case TMSG_PLAYLISTPLAYER_INSERT:
    if (pMsg->lpVoid)
    {
      CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
      Insert(pMsg->param1, (*list), pMsg->param2);
      delete list;
    }
    break;

  case TMSG_PLAYLISTPLAYER_REMOVE:
    if (pMsg->param1 != -1)
      Remove(pMsg->param1, pMsg->param2);
    break;

  case TMSG_PLAYLISTPLAYER_CLEAR:
    ClearPlaylist(pMsg->param1);
    break;

  case TMSG_PLAYLISTPLAYER_SHUFFLE:
    SetShuffle(pMsg->param1, pMsg->param2 > 0);
    break;

  case TMSG_PLAYLISTPLAYER_REPEAT:
    SetRepeat(pMsg->param1, (PLAYLIST::REPEAT_STATE)pMsg->param2);
    break;

  case TMSG_PLAYLISTPLAYER_GET_ITEMS:
    if (pMsg->lpVoid)
    {
      PLAYLIST::CPlayList playlist = GetPlaylist(pMsg->param1);
      CFileItemList *list = static_cast<CFileItemList*>(pMsg->lpVoid);

      for (int i = 0; i < playlist.size(); i++)
        list->Add(std::make_shared<CFileItem>(*playlist[i]));
    }
    break;

  case TMSG_PLAYLISTPLAYER_SWAP:
    if (pMsg->lpVoid)
    {
      auto indexes = static_cast<std::vector<int>*>(pMsg->lpVoid);
      if (indexes->size() == 2)
        Swap(pMsg->param1, indexes->at(0), indexes->at(1));
      delete indexes;
    }
    break;

  case TMSG_MEDIA_PLAY:
  {
    // first check if we were called from the PlayFile() function
    if (pMsg->lpVoid && pMsg->param2 == 0)
    {
      CFileItem *item = (CFileItem *)pMsg->lpVoid;
      g_application.PlayFile(*item, "", pMsg->param1 != 0);
      delete item;
      return;
    }
    // restore to previous window if needed
    if (g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
      g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
      g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION)
      g_windowManager.PreviousWindow();

    g_application.ResetScreenSaver();
    g_application.WakeUpScreenSaverAndDPMS();

    //g_application.StopPlaying();
    // play file
    if (pMsg->lpVoid)
    {
      CFileItemList *list = (CFileItemList *)pMsg->lpVoid;

      if (list->Size() > 0)
      {
        int playlist = PLAYLIST_MUSIC;
        for (int i = 0; i < list->Size(); i++)
        {
          if ((*list)[i]->IsVideo())
          {
            playlist = PLAYLIST_VIDEO;
            break;
          }
        }

        ClearPlaylist(playlist);
        SetCurrentPlaylist(playlist);
        //For single item lists try PlayMedia. This covers some more cases where a playlist is not appropriate
        //It will fall through to PlayFile
        if (list->Size() == 1 && !(*list)[0]->IsPlayList())
          g_application.PlayMedia(*((*list)[0]), pMsg->strParam, playlist);
        else
        {
          // Handle "shuffled" option if present
          if (list->HasProperty("shuffled") && list->GetProperty("shuffled").isBoolean())
            SetShuffle(playlist, list->GetProperty("shuffled").asBoolean(), false);
          // Handle "repeat" option if present
          if (list->HasProperty("repeat") && list->GetProperty("repeat").isInteger())
            SetRepeat(playlist, (PLAYLIST::REPEAT_STATE)list->GetProperty("repeat").asInteger(), false);

          Add(playlist, (*list));
          Play(pMsg->param1, pMsg->strParam);
        }
      }

      delete list;
    }
    else if (pMsg->param1 == PLAYLIST_MUSIC || pMsg->param1 == PLAYLIST_VIDEO)
    {
      if (GetCurrentPlaylist() != pMsg->param1)
        SetCurrentPlaylist(pMsg->param1);

      CApplicationMessenger::GetInstance().SendMsg(TMSG_PLAYLISTPLAYER_PLAY, pMsg->param2);
    }
  }
  break;

  case TMSG_MEDIA_RESTART:
    g_application.Restart(true);
    break;

  case TMSG_MEDIA_STOP:
  {
    // restore to previous window if needed
    bool stopSlideshow = true;
    bool stopVideo = true;
    bool stopMusic = true;
    if (pMsg->param1 >= PLAYLIST_MUSIC && pMsg->param1 <= PLAYLIST_PICTURE)
    {
      stopSlideshow = (pMsg->param1 == PLAYLIST_PICTURE);
      stopVideo = (pMsg->param1 == PLAYLIST_VIDEO);
      stopMusic = (pMsg->param1 == PLAYLIST_MUSIC);
    }

    if ((stopSlideshow && g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW) ||
      (stopVideo && g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO) ||
      (stopMusic && g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION))
      g_windowManager.PreviousWindow();

    g_application.ResetScreenSaver();
    g_application.WakeUpScreenSaverAndDPMS();

    // stop playing file
    if (g_application.m_pPlayer->IsPlaying()) g_application.StopPlaying();
  }
  break;

  case TMSG_MEDIA_PAUSE:
    if (g_application.m_pPlayer->HasPlayer())
    {
      g_application.ResetScreenSaver();
      g_application.WakeUpScreenSaverAndDPMS();
      g_application.m_pPlayer->Pause();
    }
    break;

  case TMSG_MEDIA_UNPAUSE:
    if (g_application.m_pPlayer->IsPausedPlayback())
    {
      g_application.ResetScreenSaver();
      g_application.WakeUpScreenSaverAndDPMS();
      g_application.m_pPlayer->Pause();
    }
    break;

  case TMSG_MEDIA_PAUSE_IF_PLAYING:
    if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
    {
      g_application.ResetScreenSaver();
      g_application.WakeUpScreenSaverAndDPMS();
      g_application.m_pPlayer->Pause();
    }
    break;
  default:
    break;
  }
}
Ejemplo n.º 3
0
//  Add an "* All ..." folder to the CFileItemList
//  depending on the child node
void CDirectoryNode::AddQueuingFolder(CFileItemList& items) const
{
  CFileItemPtr pItem;

  // always hide "all" items
  if (g_advancedSettings.m_bVideoLibraryHideAllItems)
    return;

  // no need for "all" item when only one item
  if (items.GetObjectCount() <= 1)
    return;

  // hack - as the season node might return episodes
  auto_ptr<CDirectoryNode> pNode(ParseURL(items.GetPath()));

  switch (pNode->GetChildType())
  {
    case NODE_TYPE_SEASONS:
      {
        CStdString strLabel = g_localizeStrings.Get(20366);
        pItem.reset(new CFileItem(strLabel));  // "All Seasons"
        pItem->SetPath(BuildPath() + "-1/");
        // set the number of watched and unwatched items accordingly
        int watched = 0;
        int unwatched = 0;
        for (int i = 0; i < items.Size(); i++)
        {
          CFileItemPtr item = items[i];
          watched += (int)item->GetProperty("watchedepisodes").asInteger();
          unwatched += (int)item->GetProperty("unwatchedepisodes").asInteger();
        }
        pItem->SetProperty("totalepisodes", watched + unwatched);
        pItem->SetProperty("numepisodes", watched + unwatched); // will be changed later to reflect watchmode setting
        pItem->SetProperty("watchedepisodes", watched);
        pItem->SetProperty("unwatchedepisodes", unwatched);
        if (items.Size() && items[0]->GetVideoInfoTag())
        {
          *pItem->GetVideoInfoTag() = *items[0]->GetVideoInfoTag();
          pItem->GetVideoInfoTag()->m_iSeason = -1;
        }
        pItem->GetVideoInfoTag()->m_strTitle = strLabel;
        pItem->GetVideoInfoTag()->m_iEpisode = watched + unwatched;
        pItem->GetVideoInfoTag()->m_playCount = (unwatched == 0) ? 1 : 0;
        CVideoDatabase db;
        if (db.Open())
        {
          pItem->GetVideoInfoTag()->m_iDbId = db.GetSeasonId(pItem->GetVideoInfoTag()->m_iIdShow, -1);
          db.Close();
        }
        pItem->GetVideoInfoTag()->m_type = "season";
      }
      break;
    default:
      break;
  }

  if (pItem)
  {
    pItem->m_bIsFolder = true;
    pItem->SetSpecialSort(g_advancedSettings.m_bVideoLibraryAllItemsOnBottom ? SortSpecialOnBottom : SortSpecialOnTop);
    pItem->SetCanQueue(false);
    items.Add(pItem);
  }
}
Ejemplo n.º 4
0
bool CGUIWindowVideoNav::GetDirectory(const CStdString &strDirectory, CFileItemList &items)
{
    if (m_thumbLoader.IsLoading())
        m_thumbLoader.StopThread();

    items.ClearProperties();

    bool bResult = CGUIWindowVideoBase::GetDirectory(strDirectory, items);
    if (bResult)
    {
        if (items.IsVideoDb())
        {
            XFILE::CVideoDatabaseDirectory dir;
            CQueryParams params;
            dir.GetQueryParams(items.GetPath(),params);
            VIDEODATABASEDIRECTORY::NODE_TYPE node = dir.GetDirectoryChildType(items.GetPath());

            // perform the flattening logic for tvshows with a single (unwatched) season (+ optional special season)
            if (node == NODE_TYPE_SEASONS)
            {
                int itemsSize = items.GetObjectCount();
                int firstIndex = items.Size() - itemsSize;
                // check if the last item is the "All seasons" item which should be ignored for flattening
                if (items[items.Size() - 1]->GetVideoInfoTag()->m_iSeason < 0)
                    itemsSize -= 1;

                int iFlatten = CSettings::Get().GetInt("videolibrary.flattentvshows");
                bool bFlatten = (itemsSize == 1 && iFlatten == 1) || iFlatten == 2 ||                              // flatten if one one season or if always flatten is enabled
                                (itemsSize == 2 && iFlatten == 1 &&                                                // flatten if one season + specials
                                 (items[firstIndex]->GetVideoInfoTag()->m_iSeason == 0 || items[firstIndex + 1]->GetVideoInfoTag()->m_iSeason == 0));

                if (iFlatten > 0 && !bFlatten && (WatchedMode)CMediaSettings::Get().GetWatchedMode("tvshows") == WatchedModeUnwatched)
                {
                    int count = 0;
                    for(int i = 0; i < items.Size(); i++)
                    {
                        const CFileItemPtr item = items.Get(i);
                        if (item->GetProperty("unwatchedepisodes").asInteger() != 0 && item->GetVideoInfoTag()->m_iSeason > 0)
                            count++;
                    }
                    bFlatten = (count < 2); // flatten if there is only 1 unwatched season (not counting specials)
                }

                if (bFlatten)
                {   // flatten if one season or flatten always
                    items.Clear();

                    CVideoDbUrl videoUrl;
                    if (!videoUrl.FromString(items.GetPath()))
                        return false;

                    videoUrl.AppendPath("-2/");
                    return GetDirectory(videoUrl.ToString(), items);
                }
            }

            items.SetArt("thumb", "");
            if (node == VIDEODATABASEDIRECTORY::NODE_TYPE_EPISODES ||
                    node == NODE_TYPE_SEASONS                          ||
                    node == NODE_TYPE_RECENTLY_ADDED_EPISODES)
            {
                CLog::Log(LOGDEBUG, "WindowVideoNav::GetDirectory");
                // grab the show thumb
                CVideoInfoTag details;
                m_database.GetTvShowInfo("", details, params.GetTvShowId());
                map<string, string> art;
                if (m_database.GetArtForItem(details.m_iDbId, details.m_type, art))
                {
                    items.AppendArt(art, "tvshow");
                    items.SetArtFallback("fanart", "tvshow.fanart");
                    if (node == NODE_TYPE_SEASONS)
                    {   // set an art fallback for "thumb"
                        if (items.HasArt("tvshow.poster"))
                            items.SetArtFallback("thumb", "tvshow.poster");
                        else if (items.HasArt("tvshow.banner"))
                            items.SetArtFallback("thumb", "tvshow.banner");
                    }
                }

                // Grab fanart data
                items.SetProperty("fanart_color1", details.m_fanart.GetColor(0));
                items.SetProperty("fanart_color2", details.m_fanart.GetColor(1));
                items.SetProperty("fanart_color3", details.m_fanart.GetColor(2));

                // save the show description (showplot)
                items.SetProperty("showplot", details.m_strPlot);

                // the container folder thumb is the parent (i.e. season or show)
                if (node == NODE_TYPE_EPISODES || node == NODE_TYPE_RECENTLY_ADDED_EPISODES)
                {
                    items.SetContent("episodes");
                    // grab the season thumb as the folder thumb
                    int seasonID = m_database.GetSeasonId(details.m_iDbId, params.GetSeason());
                    CGUIListItem::ArtMap seasonArt;
                    if (m_database.GetArtForItem(seasonID, "season", seasonArt))
                    {
                        items.AppendArt(art, "season");
                        // set an art fallback for "thumb"
                        if (items.HasArt("season.poster"))
                            items.SetArtFallback("thumb", "season.poster");
                        else if (items.HasArt("season.banner"))
                            items.SetArtFallback("thumb", "season.banner");
                    }
                }
                else
                    items.SetContent("seasons");
            }
            else if (node == NODE_TYPE_TITLE_MOVIES ||
                     node == NODE_TYPE_RECENTLY_ADDED_MOVIES)
                items.SetContent("movies");
            else if (node == NODE_TYPE_TITLE_TVSHOWS)
                items.SetContent("tvshows");
            else if (node == NODE_TYPE_TITLE_MUSICVIDEOS ||
                     node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
                items.SetContent("musicvideos");
            else if (node == NODE_TYPE_GENRE)
                items.SetContent("genres");
            else if (node == NODE_TYPE_COUNTRY)
                items.SetContent("countries");
            else if (node == NODE_TYPE_ACTOR)
            {
                if (params.GetContentType() == VIDEODB_CONTENT_MUSICVIDEOS)
                    items.SetContent("artists");
                else
                    items.SetContent("actors");
            }
            else if (node == NODE_TYPE_DIRECTOR)
                items.SetContent("directors");
            else if (node == NODE_TYPE_STUDIO)
                items.SetContent("studios");
            else if (node == NODE_TYPE_YEAR)
                items.SetContent("years");
            else if (node == NODE_TYPE_MUSICVIDEOS_ALBUM)
                items.SetContent("albums");
            else if (node == NODE_TYPE_SETS)
                items.SetContent("sets");
            else if (node == NODE_TYPE_TAGS)
                items.SetContent("tags");
            else
                items.SetContent("");
        }
        else if (!items.IsVirtualDirectoryRoot())
        {   // load info from the database
            CStdString label;
            if (items.GetLabel().empty() && m_rootDir.IsSource(items.GetPath(), CMediaSourceSettings::Get().GetSources("video"), &label))
                items.SetLabel(label);
            if (!items.IsSourcesPath())
                LoadVideoInfo(items);
        }

        CVideoDbUrl videoUrl;
        if (videoUrl.FromString(items.GetPath()) && items.GetContent() == "tags" &&
                !items.Contains("newtag://" + videoUrl.GetType()))
        {
            CFileItemPtr newTag(new CFileItem("newtag://" + videoUrl.GetType(), false));
            newTag->SetLabel(g_localizeStrings.Get(20462));
            newTag->SetLabelPreformated(true);
            newTag->SetSpecialSort(SortSpecialOnTop);
            items.Add(newTag);
        }
    }
    return bResult;
}
Ejemplo n.º 5
0
/// \brief Add unique file and folders and its subfolders to playlist
/// \param pItem The file item to add
void CGUIWindowMusicBase::AddItemToPlayList(const CFileItemPtr &pItem, CFileItemList &queuedItems)
{
  if (!pItem->CanQueue() || pItem->IsRAR() || pItem->IsZIP() || pItem->IsParentFolder()) // no zip/rar enques thank you!
    return;

  // fast lookup is needed here
  queuedItems.SetFastLookup(true);

  if (pItem->IsMusicDb() && pItem->m_bIsFolder && !pItem->IsParentFolder())
  { // we have a music database folder, just grab the "all" item underneath it
    CMusicDatabaseDirectory dir;
    if (!dir.ContainsSongs(pItem->GetPath()))
    { // grab the ALL item in this category
      // Genres will still require 2 lookups, and queuing the entire Genre folder
      // will require 3 lookups (genre, artist, album)
      CMusicDbUrl musicUrl;
      if (musicUrl.FromString(pItem->GetPath()))
      {
        musicUrl.AppendPath("-1/");
        CFileItemPtr item(new CFileItem(musicUrl.ToString(), true));
        item->SetCanQueue(true); // workaround for CanQueue() check above
        AddItemToPlayList(item, queuedItems);
      }
      return;
    }
  }
  if (pItem->m_bIsFolder || (g_windowManager.GetActiveWindow() == WINDOW_MUSIC_NAV && pItem->IsPlayList()))
  {
    // Check if we add a locked share
    if ( pItem->m_bIsShareOrDrive )
    {
      CFileItem item = *pItem;
      if ( !g_passwordManager.IsItemUnlocked( &item, "music" ) )
        return ;
    }

    // recursive
    CFileItemList items;
    GetDirectory(pItem->GetPath(), items);
    //OnRetrieveMusicInfo(items);
    FormatAndSort(items);
    for (int i = 0; i < items.Size(); ++i)
      AddItemToPlayList(items[i], queuedItems);
  }
  else
  {
    if (pItem->IsPlayList())
    {
      std::unique_ptr<CPlayList> pPlayList (CPlayListFactory::Create(*pItem));
      if (pPlayList.get())
      {
        // load it
        if (!pPlayList->Load(pItem->GetPath()))
        {
          CGUIDialogOK::ShowAndGetInput(CVariant{6}, CVariant{477});
          return; //hmmm unable to load playlist?
        }

        CPlayList playlist = *pPlayList;
        for (int i = 0; i < (int)playlist.size(); ++i)
        {
          AddItemToPlayList(playlist[i], queuedItems);
        }
        return;
      }
    }
    else if(pItem->IsInternetStream())
    { // just queue the internet stream, it will be expanded on play
      queuedItems.Add(pItem);
    }
    else if (pItem->IsPlugin() && pItem->GetProperty("isplayable") == "true")
    {
      // python files can be played
      queuedItems.Add(pItem);
    }
    else if (!pItem->IsNFO() && (pItem->IsAudio() || pItem->IsVideo()))
    {
      CFileItemPtr itemCheck = queuedItems.Get(pItem->GetPath());
      if (!itemCheck || itemCheck->m_lStartOffset != pItem->m_lStartOffset)
      { // add item
        CFileItemPtr item(new CFileItem(*pItem));
        m_musicdatabase.SetPropertiesForFileItem(*item);
        queuedItems.Add(item);
      }
    }
  }
}
Ejemplo n.º 6
0
bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
  CFileCurl http;
  CURL url(strPath);

  CStdString strName, strLink;
  CStdString strBasePath = url.GetFileName();

  if(!http.Open(url, false))
  {
    CLog::Log(LOGERROR, "%s - Unable to get http directory", __FUNCTION__);
    return false;
  }

  CRegExp reItem;
  reItem.RegComp("<a href=\"(.*)\">(.*)</a>");

  /* read response from server into string buffer */
  char buffer[MAX_PATH + 1024];
  while(http.ReadString(buffer, sizeof(buffer)-1))
  {
    CStdString strBuffer = buffer;
    StringUtils::RemoveCRLF(strBuffer);

    if (reItem.RegFind(strBuffer.c_str()) >= 0)
    {
      strLink = reItem.GetReplaceString("\\1");
      strName = reItem.GetReplaceString("\\2");
 
      if(strLink[0] == '/')
        strLink = strLink.Mid(1);
 
      CStdString strNameTemp = strName.Trim();
      CStdString strLinkTemp = strLink;
      CUtil::RemoveSlashAtEnd(strLinkTemp);
      CUtil::RemoveSlashAtEnd(strNameTemp);
      CUtil::UrlDecode(strLinkTemp);
 
      if (strNameTemp == strLinkTemp)
      {
        g_charsetConverter.stringCharsetToUtf8(strName);
        CUtil::RemoveSlashAtEnd(strName);
       
        CFileItemPtr pItem(new CFileItem(strName));
        pItem->m_strPath = strBasePath + strLink;
       
        if(CUtil::HasSlashAtEnd(pItem->m_strPath))
          pItem->m_bIsFolder = true;
       
        url.SetFileName(pItem->m_strPath);
        url.GetURL(pItem->m_strPath);

        if (!pItem->m_bIsFolder && g_advancedSettings.m_bHTTPDirectoryStatFilesize)
        {
          CFileCurl file;
          file.Open(url, false);
          pItem->m_dwSize= file.GetLength();
          file.Close();
        }

        if (!pItem->m_bIsFolder && pItem->m_dwSize == 0)
        {
          CRegExp reSize;
          reSize.RegComp(">([0-9.]+)(K|M|G)</td>");
          if (reSize.RegFind(strBuffer.c_str()) >= 0)
          {
            double Size = atof(reSize.GetReplaceString("\\1"));
            CStdString strUnit = reSize.GetReplaceString("\\2");
        
            if (strUnit == "M")
              Size = Size * 1024;
            else if (strUnit == "G")
              Size = Size * 1000 * 1024;
        
            pItem->m_dwSize = (__int64)(Size * 1024);
          }
        }
       
        items.Add(pItem);
      }
    }
  }
  http.Close();

  return true;
}
Ejemplo n.º 7
0
bool CDAVDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
  CFileCurl dav;
  CURL url(strPath);
  CStdString strRequest = "PROPFIND";

  dav.SetCustomRequest(strRequest);
  dav.SetMimeType("text/xml; charset=\"utf-8\"");
  dav.SetRequestHeader("depth", 1);
  dav.SetPostData(
    "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
    " <D:propfind xmlns:D=\"DAV:\">"
    "   <D:prop>"
    "     <D:resourcetype/>"
    "     <D:getcontentlength/>"
    "     <D:getlastmodified/>"
    "     <D:creationdate/>"
    "     <D:displayname/>"
    "    </D:prop>"
    "  </D:propfind>");

  if (!dav.Open(url))
  {
    CLog::Log(LOGERROR, "%s - Unable to get dav directory (%s)", __FUNCTION__, strPath.c_str());
    return false;
  }

  char buffer[MAX_PATH + 1024];
  CStdString strResponse;
  CStdString strHeader;
  while (dav.ReadString(buffer, sizeof(buffer)))
  {
    if (strstr(buffer, "<D:response") != NULL)
    {
      // The header should contain the xml version/utf encoding line
      // followed by the <multistatus> tag
      if (strHeader.IsEmpty())
        strHeader = strResponse;
      
      strResponse = strHeader;
    }
    strResponse.append(buffer, strlen(buffer));

    if (strstr(buffer, "</D:response") != NULL)
    {
      // Close the multistatus tag from the header
      if (strHeader.Find("<D:multistatus"))
        strResponse+="</D:multistatus>\n";
      
      TiXmlDocument davResponse;

      if (!davResponse.Parse(strResponse))
      {
        CLog::Log(LOGERROR, "%s - Unable to process dav directory (%s)", __FUNCTION__, strPath.c_str());
        dav.Close();
        return false;
      }

      TiXmlNode *pChild;
      // Iterate over all responses
      for (pChild = davResponse.RootElement()->FirstChild(); pChild != 0; pChild = pChild->NextSibling())
      {
        if (ValueWithoutNamespace(pChild, "response"))
        {
          CFileItem item;
          ParseResponse(pChild->ToElement(), item);
          CURL url2(strPath);
          CURL url3(item.m_strPath);

          URIUtils::AddFileToFolder(url2.GetWithoutFilename(), url3.GetFileName(), item.m_strPath);

          if (item.GetLabel().IsEmpty())
          {
            CStdString name(item.m_strPath);
            URIUtils::RemoveSlashAtEnd(name);
            CURL::Decode(name);
            item.SetLabel(URIUtils::GetFileName(name));
          }

          if (item.m_bIsFolder)
            URIUtils::AddSlashAtEnd(item.m_strPath);

          // Add back protocol options
          if (!url2.GetProtocolOptions().IsEmpty())
            item.m_strPath += "|" + url2.GetProtocolOptions();

          if (!item.m_strPath.Equals(strPath))
          {
            CFileItemPtr pItem(new CFileItem(item));
            items.Add(pItem);
          }
        }
      }
      strResponse.clear();
    }
  }

  dav.Close();

  return true;
}
Ejemplo n.º 8
0
int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, vector<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
  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 (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 (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()))
    {
      items.Add(item);
      addonMap.insert(std::make_pair(item->GetPath(), *addon));
    }
  }

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

  std::string heading;
  for (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 (vector<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.º 9
0
bool CGUIControlListSetting::GetIntegerItems(const CSetting *setting, CFileItemList &items)
{
  const CSettingInt *pSettingInt = NULL;
  std::set<int> values;
  if (setting->GetType() == SettingTypeInteger)
  {
    pSettingInt = static_cast<const CSettingInt*>(setting);
    values.insert(pSettingInt->GetValue());
  }
  else if (setting->GetType() == SettingTypeList)
  {
    const CSettingList *settingList = static_cast<const CSettingList*>(setting);
    if (settingList->GetElementType() != SettingTypeInteger)
      return false;

    pSettingInt = static_cast<const CSettingInt*>(settingList->GetDefinition());
    std::vector<CVariant> list = CSettingUtils::GetList(settingList);
    for (std::vector<CVariant>::const_iterator itValue = list.begin(); itValue != list.end(); ++itValue)
    {
      if (!itValue->isInteger())
        return false;
      values.insert((int)itValue->asInteger());
    }
  }
  else
    return false;

  switch (pSettingInt->GetOptionsType())
  {
    case SettingOptionsTypeStatic:
    {
      const StaticIntegerSettingOptions& options = pSettingInt->GetOptions();
      for (StaticIntegerSettingOptions::const_iterator it = options.begin(); it != options.end(); ++it)
      {
        CFileItemPtr pItem = GetItem(g_localizeStrings.Get(it->first), it->second);

        if (values.find(it->second) != values.end())
          pItem->Select(true);

        items.Add(pItem);
      }
      break;
    }

    case SettingOptionsTypeDynamic:
    {
      DynamicIntegerSettingOptions options = const_cast<CSettingInt*>(pSettingInt)->UpdateDynamicOptions();
      for (DynamicIntegerSettingOptions::const_iterator option = options.begin(); option != options.end(); ++option)
      {
        CFileItemPtr pItem = GetItem(option->first, option->second);

        if (values.find(option->second) != values.end())
          pItem->Select(true);

        items.Add(pItem);
      }
      break;
    }

    case SettingOptionsTypeNone:
    default:
      return false;
  }

  return true;
}
Ejemplo n.º 10
0
int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, CStdStringArray &addonIDs, bool showNone /*= false*/, bool multipleSelection /*= true*/)
{
  CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
  if (!dialog)
    return 0;

  CFileItemList items;
  CStdString heading;
  int iTypes = 0;
  for (vector<ADDON::TYPE>::const_iterator it = types.begin(); it != types.end(); ++it)
  {
    if (*it == ADDON_UNKNOWN)
      continue;
    ADDON::VECADDONS addons;
    iTypes++;
    if (*it == ADDON_AUDIO)
      CAddonsDirectory::GetScriptsAndPlugins("audio",addons);
    else if (*it == ADDON_EXECUTABLE)
      CAddonsDirectory::GetScriptsAndPlugins("executable",addons);
    else if (*it == ADDON_IMAGE)
      CAddonsDirectory::GetScriptsAndPlugins("image",addons);
    else if (*it == ADDON_VIDEO)
      CAddonsDirectory::GetScriptsAndPlugins("video",addons);
    else
      CAddonMgr::Get().GetAddons(*it, addons);
    for (ADDON::IVECADDONS it2 = addons.begin() ; it2 != addons.end() ; ++it2)
    {
      CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*it2, ""));
      if (!items.Contains(item->GetPath()))
        items.Add(item);
    }

    if (!heading.IsEmpty())
      heading += ", ";
    heading += TranslateType(*it, true);
  }

  if (iTypes == 0)
    return 0;

  dialog->SetHeading(heading);
  dialog->Reset();
  dialog->SetUseDetails(true);
  if (multipleSelection)
    showNone = false;
  if (multipleSelection || iTypes > 1)
    dialog->EnableButton(true, 186);
  else
    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(SORT_METHOD_LABEL, SortOrderAscending);

  if (addonIDs.size() > 0)
  {
    for (CStdStringArray::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->DoModal();
  if (!multipleSelection && iTypes == 1 && dialog->IsButtonPressed())
  { // switch to the addons browser.
    vector<CStdString> params;
    params.push_back("addons://all/"+TranslateType(types[0],false)+"/");
    params.push_back("return");
    g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params);
    return 2;
  }
  if (!dialog->IsConfirmed())
    return 0;
  addonIDs.clear();
  const CFileItemList& list = dialog->GetSelectedItems();
  for (int i = 0 ; i < list.Size() ; i++)
    addonIDs.push_back(list.Get(i)->GetPath());
  return 1;
}
Ejemplo n.º 11
0
bool CGUIWindowAddonBrowser::GetDirectory(const std::string& strDirectory, CFileItemList& items)
{
  bool result;
  if (URIUtils::PathEquals(strDirectory, "addons://downloading/"))
  {
    VECADDONS addons;
    CAddonInstaller::GetInstance().GetInstallList(addons);

    CURL url(strDirectory);
    CAddonsDirectory::GenerateAddonListing(url, addons, items, g_localizeStrings.Get(24067));
    result = true;
    items.SetPath(strDirectory);

    if (m_guiState.get() && !m_guiState->HideParentDirItems())
    {
      CFileItemPtr pItem(new CFileItem(".."));
      pItem->SetPath(m_history.GetParentPath());
      pItem->m_bIsFolder = true;
      pItem->m_bIsShareOrDrive = false;
      items.AddFront(pItem, 0);
    }

  }
  else
  {
    result = CGUIMediaWindow::GetDirectory(strDirectory, items);

    if (result && CAddonsDirectory::IsRepoDirectory(CURL(strDirectory)))
    {
      if (CSettings::GetInstance().GetBool(CSettings::SETTING_GENERAL_ADDONFOREIGNFILTER))
      {
        int i = 0;
        while (i < items.Size())
        {
          auto prop = items[i]->GetProperty("Addon.Language");
          if (!prop.isNull() && IsForeign(prop.asString()))
            items.Remove(i);
          else
            ++i;
        }
      }
      if (CSettings::GetInstance().GetBool(CSettings::SETTING_GENERAL_ADDONBROKENFILTER))
      {
        for (int i = items.Size() - 1; i >= 0; i--)
        {
          if (!items[i]->GetProperty("Addon.Broken").empty())
          {
            //check if it's installed
            AddonPtr addon;
            if (!CAddonMgr::GetInstance().GetAddon(items[i]->GetProperty("Addon.ID").asString(), addon))
              items.Remove(i);
          }
        }
      }
    }
  }

  if (strDirectory.empty() && CAddonInstaller::GetInstance().IsDownloading())
  {
    CFileItemPtr item(new CFileItem("addons://downloading/", true));
    item->SetLabel(g_localizeStrings.Get(24067));
    item->SetLabelPreformated(true);
    item->SetIconImage("DefaultNetwork.png");
    items.Add(item);
  }

  items.SetContent("addons");

  for (int i = 0; i < items.Size(); ++i)
    SetItemLabel2(items[i]);

  return result;
}
Ejemplo n.º 12
0
bool CGUIWindowAddonBrowser::GetDirectory(const CStdString& strDirectory,
                                          CFileItemList& items)
{
  bool result;
  if (strDirectory.Equals("addons://downloading/"))
  {
    VECADDONS addons;
    CAddonInstaller::Get().GetInstallList(addons);

    CURL url(strDirectory);
    CAddonsDirectory::GenerateListing(url,addons,items);
    result = true;
    items.SetProperty("reponame",g_localizeStrings.Get(24067));
    items.SetPath(strDirectory);

    if (m_guiState.get() && !m_guiState->HideParentDirItems())
    {
      CFileItemPtr pItem(new CFileItem(".."));
      pItem->SetPath(m_history.GetParentPath());
      pItem->m_bIsFolder = true;
      pItem->m_bIsShareOrDrive = false;
      items.AddFront(pItem, 0);
    }

  }
  else
  {
    result = CGUIMediaWindow::GetDirectory(strDirectory,items);
    if (CSettings::Get().GetBool("general.addonforeignfilter"))
    {
      int i=0;
      while (i < items.Size())
      {
        if (!FilterVar(CSettings::Get().GetBool("general.addonforeignfilter"),
                      items[i]->GetProperty("Addon.Language"), "en") ||
            !FilterVar(CSettings::Get().GetBool("general.addonforeignfilter"),
                      items[i]->GetProperty("Addon.Language"),
                      g_langInfo.GetLanguageLocale()))
        {
          i++;
        }
        else
          items.Remove(i);
      }
    }
  }

  if (strDirectory.IsEmpty() && CAddonInstaller::Get().IsDownloading())
  {
    CFileItemPtr item(new CFileItem("addons://downloading/",true));
    item->SetLabel(g_localizeStrings.Get(24067));
    item->SetLabelPreformated(true);
    item->SetIconImage("DefaultNetwork.png");
    items.Add(item);
  }

  items.SetContent("addons");

  for (int i=0;i<items.Size();++i)
    SetItemLabel2(items[i]);

  return result;
}
Ejemplo n.º 13
0
bool CPVRRecordings::ChangeRecordingsPlayCount(const CFileItemPtr &item, int count)
{
  bool bResult = false;

  if (m_database.IsOpen())
  {
    bResult = true;

    CLog::Log(LOGDEBUG, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str());
    CFileItemList items;
    if (item->m_bIsFolder)
    {
      XFILE::CDirectory::GetDirectory(item->GetPath(), items);
    }
    else
      items.Add(item);

    CLog::Log(LOGDEBUG, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size());
    for (int i=0;i<items.Size();++i)
    {
      CLog::Log(LOGDEBUG, "CPVRRecordings - %s - setting watched for item %d", __FUNCTION__, i);

      CFileItemPtr pItem=items[i];
      if (pItem->m_bIsFolder)
      {
        CLog::Log(LOGDEBUG, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str());
        if (pItem->GetLabel() != "..")
        {
          ChangeRecordingsPlayCount(pItem, count);
        }
        continue;
      }

      if (!pItem->HasPVRRecordingInfoTag())
        continue;

      const CPVRRecordingPtr recording = pItem->GetPVRRecordingInfoTag();
      if (recording)
      {
        if (count == INCREMENT_PLAY_COUNT)
          recording->IncrementPlayCount();
        else
          recording->SetPlayCount(count);

        // Clear resume bookmark
        if (recording->m_playCount > 0)
        {
          m_database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME);
          recording->SetLastPlayedPosition(0);
        }

        if (count == INCREMENT_PLAY_COUNT)
          m_database.IncrementPlayCount(*pItem);
        else
          m_database.SetPlayCount(*pItem, count);
      }
    }
  }

  return bResult;
}
Ejemplo n.º 14
0
bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &items)
{
  CSingleLock lock(m_critSection);

  bool bGrouped = false;
  const CURL url(strPath);
  if (url.HasOption("view"))
  {
    const std::string view(url.GetOption("view"));
    if (view == "grouped")
      bGrouped = true;
    else if (view == "flat")
      bGrouped = false;
    else
    {
      CLog::Log(LOGERROR, "CPVRRecordings - %s - unsupported value '%s' for url parameter 'view'", __FUNCTION__, view.c_str());
      return false;
    }
  }
  else
  {
    bGrouped = CSettings::GetInstance().GetBool(CSettings::SETTING_PVRRECORD_GROUPRECORDINGS);
  }

  CPVRRecordingsPath recPath(url.GetWithoutOptions());
  if (recPath.IsValid())
  {
    // Get the directory structure if in non-flatten mode
    // Deleted view is always flatten. So only for an active view
    std::string strDirectory(recPath.GetDirectoryPath());
    if (!recPath.IsDeleted() && bGrouped)
      GetSubDirectories(recPath, &items);

    // get all files of the currrent directory or recursively all files starting at the current directory if in flatten mode
    for (const auto recording : m_recordings)
    {
      CPVRRecordingPtr current = recording.second;

      // Omit recordings not matching criteria
      if (!IsDirectoryMember(strDirectory, current->m_strDirectory, bGrouped) ||
          current->IsDeleted() != recPath.IsDeleted() ||
          current->IsRadio() != recPath.IsRadio())
        continue;

      if (m_database.IsOpen())
        current->UpdateMetadata(m_database);
      CFileItemPtr pFileItem(new CFileItem(current));
      pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false));
      pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();
      pFileItem->SetPath(current->m_strFileNameAndPath);

      // Set art
      if (!current->m_strIconPath.empty())
      {
        pFileItem->SetIconImage(current->m_strIconPath);
        pFileItem->SetArt("icon", current->m_strIconPath);
      }

      if (!current->m_strThumbnailPath.empty())
        pFileItem->SetArt("thumb", current->m_strThumbnailPath);

      if (!current->m_strFanartPath.empty())
        pFileItem->SetArt("fanart", current->m_strFanartPath);

      // Use the channel icon as a fallback when a thumbnail is not available
      pFileItem->SetArtFallback("thumb", "icon");

      pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pFileItem->GetPVRRecordingInfoTag()->m_playCount > 0);

      items.Add(pFileItem);
    }
  }

  if (items.IsEmpty())
  {
    // Note: Do not change the ".." label. It has very special meaning/logic.
    //       CFileItem::IsParentFolder() and and other code depends on this.
    const CFileItemPtr item(new CFileItem(".."));
    items.Add(item);
  }

  return recPath.IsValid();
}
Ejemplo n.º 15
0
void CGUIDialogBoxeeChannelFilter::OnInitWindow()
{
  CGUIDialog::OnInitWindow();

  CStdString sourcesUrl = "boxee://sources/";
  int activeWindow = g_windowManager.GetActiveWindow();

  if (activeWindow == WINDOW_BOXEE_BROWSE_MOVIES)
  {
    sourcesUrl += "movies";
  }
  else
  {
    sourcesUrl += "shows";
  }

  CLog::Log(LOGDEBUG,"CGUIDialogBoxeeChannelFilter::OnInitWindow - build source list for [url=%s] (cf)",sourcesUrl.c_str());

  CFileItemList sourceList;
  DIRECTORY::CDirectory::GetDirectory(sourcesUrl,sourceList);

  if (sourceList.Size() < 1)
  {
    CLog::Log(LOGERROR,"CGUIDialogBoxeeChannelFilter::OnInitWindow - FAILED to get sources. [size=%d] (cf)",sourceList.Size());
    Close();
    return;
  }

  if (!LoadExcludedChannels())
  {
    CLog::Log(LOGERROR,"CGUIDialogBoxeeChannelFilter::OnInitWindow - FAILED to load excluded sources (cf)");
    Close();
    return;
  }

  CLog::Log(LOGDEBUG,"CGUIDialogBoxeeChannelFilter::OnInitWindow - [NumOfSources=%d][NumOfExcludedSources=%zu] (cf)",sourceList.Size(),m_excludedChannels.size());

  CGUIMessage winmsgResetPremium(GUI_MSG_LABEL_RESET, GetID(), CHANNEL_LIST);
  OnMessage(winmsgResetPremium);

  CFileItemList channelItemList;
  CFileItemList freeChannelItemList;

  for (int i=0; i<sourceList.Size(); i++)
  {
    CFileItemPtr sourceItem = sourceList.Get(i);
    std::string sourceId = sourceItem->GetProperty("sourceid");
    std::string sourceOffer = sourceItem->GetProperty("sourceoffer");

    if (sourceOffer.empty())
    {
      CLog::Log(LOGWARNING,"CGUIDialogBoxeeChannelFilter::OnInitWindow - [%d/%d] - for sources [id=%s] the attribute offer is EMPTY. [offer=%s] (cf)",i+1,sourceList.Size(),sourceId.c_str(),sourceOffer.c_str());
      continue;
    }

    CFileItemPtr source(new CFileItem(*(sourceItem.get())));
    source->SetProperty("channelthumb",source->GetProperty("sourcethumb"));
    source->Select(m_excludedChannels.find(sourceId) == m_excludedChannels.end());

    if (stricmp(sourceOffer.c_str(),FREE_OFFER_STRING))
    {
      if (channelItemList.IsEmpty())
      {
        // add PREMIUM separator
        CFileItemPtr seperator(new CFileItem(g_localizeStrings.Get(53581)));
        seperator->SetProperty("isseparator",true);
        channelItemList.Add(seperator);
      }

      CLog::Log(LOGDEBUG,"CGUIDialogBoxeeChannelFilter::OnInitWindow - [%d/%d] - [sourceoffer=%s] -> adding PREMIUM source [id=%s] (cf)",i+1,sourceList.Size(),sourceOffer.c_str(),sourceId.c_str());
      channelItemList.Add(source);
    }
    else
    {
      CLog::Log(LOGDEBUG,"CGUIDialogBoxeeChannelFilter::OnInitWindow - [%d/%d] - [sourceoffer=%s] -> adding FREE source [id=%s] (cf)",i+1,sourceList.Size(),sourceOffer.c_str(),sourceId.c_str());
      freeChannelItemList.Add(source);
    }
  }

  for (int i=0; i<freeChannelItemList.Size(); i++)
  {
    if (i == 0 && !channelItemList.IsEmpty())
    {
      // add FREE separator
      CFileItemPtr seperator(new CFileItem(g_localizeStrings.Get(53582)));
      seperator->SetProperty("isseparator",true);
      channelItemList.Add(seperator);
    }

    CFileItemPtr source(new CFileItem(*(freeChannelItemList.Get(i))));
    source->SetProperty("channelthumb",source->GetProperty("sourcethumb"));
    channelItemList.Add(source);
  }

  CGUIMessage msgBindToChannelList(GUI_MSG_LABEL_BIND, GetID(), CHANNEL_LIST, 0, 0, &channelItemList);
  OnMessage(msgBindToChannelList);

  SET_CONTROL_FOCUS(CHANNEL_LIST, 0);

  m_dirty = false;
}
Ejemplo n.º 16
0
//  Add an "* All ..." folder to the CFileItemList
//  depending on the child node
void CDirectoryNode::AddQueuingFolder(CFileItemList& items) const
{
  CFileItemPtr pItem;

  // always hide "all" items
  if (g_advancedSettings.m_bMusicLibraryHideAllItems)
    return;

  // no need for "all" item when only one item
  if (items.GetObjectCount() <= 1)
    return;

  switch (GetChildType())
  {
    //  Have no queuing folder
  case NODE_TYPE_ROOT:
  case NODE_TYPE_OVERVIEW:
  case NODE_TYPE_TOP100:
    break;

  /* no need for all genres
  case NODE_TYPE_GENRE:
    pItem.reset(new CFileItem(g_localizeStrings.Get(15105)));  // "All Genres"
    pItem->GetPath() = BuildPath() + "-1/";
    break;
  */

  case NODE_TYPE_ARTIST:
    if (GetType() == NODE_TYPE_OVERVIEW) return;
    pItem.reset(new CFileItem(g_localizeStrings.Get(15103)));  // "All Artists"
    pItem->SetPath(BuildPath() + "-1/");
    break;

    //  All album related nodes
  case NODE_TYPE_ALBUM:
    if (GetType() == NODE_TYPE_OVERVIEW) return;
  case NODE_TYPE_ALBUM_RECENTLY_PLAYED:
  case NODE_TYPE_ALBUM_RECENTLY_ADDED:
  case NODE_TYPE_ALBUM_COMPILATIONS:
  case NODE_TYPE_ALBUM_TOP100:
  case NODE_TYPE_YEAR_ALBUM:
    pItem.reset(new CFileItem(g_localizeStrings.Get(15102)));  // "All Albums"
    pItem->SetPath(BuildPath() + "-1/");
    break;

    //  All song related nodes
/*  case NODE_TYPE_ALBUM_RECENTLY_PLAYED_SONGS:
  case NODE_TYPE_ALBUM_RECENTLY_ADDED_SONGS:
  case NODE_TYPE_ALBUM_COMPILATIONS_SONGS:
  case NODE_TYPE_ALBUM_TOP100_SONGS:
  case NODE_TYPE_SONG_TOP100:
  case NODE_TYPE_SONG:
    pItem = new CFileItem(g_localizeStrings.Get(15104));  // "All Songs"
    pItem->GetPath() = BuildPath() + "-1/";
    break;*/
  default:
    break;
  }

  if (pItem)
  {
    pItem->m_bIsFolder = true;
    pItem->SetSpecialSort(g_advancedSettings.m_bMusicLibraryAllItemsOnBottom ? SortSpecialOnBottom : SortSpecialOnTop);
    pItem->SetCanQueue(false);
    pItem->SetLabelPreformated(true);
    if (g_advancedSettings.m_bMusicLibraryAllItemsOnBottom)
      items.Add(pItem);
    else
      items.AddFront(pItem, (items.Size() > 0 && items[0]->IsParentFolder()) ? 1 : 0);
  }
}
Ejemplo n.º 17
0
bool CPosixDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  std::string root = url.Get();

  if (IsAliasShortcut(root))
    TranslateAliasShortcut(root);

  DIR *dir = opendir(root.c_str());
  if (!dir)
    return false;

  struct dirent* entry;
  while ((entry = readdir(dir)) != NULL)
  {
    if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
      continue;

    CFileItemPtr pItem(new CFileItem(entry->d_name));
    std::string itemPath(URIUtils::AddFileToFolder(root, entry->d_name));

    bool bStat = false;
    struct stat buffer;

    // Unix-based readdir implementations may return an incorrect dirent.d_ino value that
    // is not equal to the (correct) stat() obtained one. In this case the file type
    // could not be determined and the value of dirent.d_type is set to DT_UNKNOWN.
    // In order to get a correct value we have to incur the cost of calling stat.
    if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK)
    {
      if (stat(itemPath.c_str(), &buffer) == 0)
        bStat = true;
    }

    if (entry->d_type == DT_DIR || (bStat && buffer.st_mode & S_IFDIR))
    {
      pItem->m_bIsFolder = true;
      URIUtils::AddSlashAtEnd(itemPath);
    }
    else
    {
      pItem->m_bIsFolder = false;
    }

    if (StringUtils::StartsWith(entry->d_name, "."))
      pItem->SetProperty("file:hidden", true);

    pItem->SetPath(itemPath);

    if (!(m_flags & DIR_FLAG_NO_FILE_INFO))
    {
      if (bStat || stat(pItem->GetPath(), &buffer) == 0)
      {
        FILETIME fileTime, localTime;
        TimeTToFileTime(buffer.st_mtime, &fileTime);
        FileTimeToLocalFileTime(&fileTime, &localTime);
        pItem->m_dateTime = localTime;

        if (!pItem->m_bIsFolder)
          pItem->m_dwSize = buffer.st_size;
      }
    }
    items.Add(pItem);
  }
  closedir(dir);
  return true;
}
Ejemplo n.º 18
0
bool CZeroconfDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  assert(url.IsProtocol("zeroconf"));
  std::string strPath = url.Get();
  std::string path = strPath.substr(11, strPath.length());
  URIUtils::RemoveSlashAtEnd(path);
  if(path.empty())
  {
    std::vector<CZeroconfBrowser::ZeroconfService> found_services = CZeroconfBrowser::GetInstance()->GetFoundServices();
    for(std::vector<CZeroconfBrowser::ZeroconfService>::iterator it = found_services.begin(); it != found_services.end(); ++it)
    {
      //only use discovered services we can connect to through directory
      std::string tmp;
      if(GetXBMCProtocol(it->GetType(), tmp))
      {
        CFileItemPtr item(new CFileItem("", true));
        CURL url;
        url.SetProtocol("zeroconf");
        std::string service_path(CURL::Encode(CZeroconfBrowser::ZeroconfService::toPath(*it)));
        url.SetFileName(service_path);
        item->SetPath(url.Get());

        //now do the formatting
        std::string protocol = GetHumanReadableProtocol(it->GetType());
        item->SetLabel(it->GetName() + " (" + protocol  + ")");
        item->SetLabelPreformated(true);
        //just set the default folder icon
        item->FillInDefaultIcon();
        items.Add(item);
      }
    }
    return true;
  } 
  else
  {
    //decode the path first
    std::string decoded(CURL::Decode(path));
    try
    {
      CZeroconfBrowser::ZeroconfService zeroconf_service = CZeroconfBrowser::ZeroconfService::fromPath(decoded);

      if(!CZeroconfBrowser::GetInstance()->ResolveService(zeroconf_service))
      {
        CLog::Log(LOGINFO, "CZeroconfDirectory::GetDirectory service ( %s ) could not be resolved in time", zeroconf_service.GetName().c_str());
        return false;
      }
      else
      {
        assert(!zeroconf_service.GetIP().empty());
        CURL service;
        service.SetPort(zeroconf_service.GetPort());
        service.SetHostName(zeroconf_service.GetIP());
        //do protocol conversion (_smb._tcp -> smb)
        //ToDo: try automatic conversion -> remove leading '_' and '._tcp'?
        std::string protocol;
        if(!GetXBMCProtocol(zeroconf_service.GetType(), protocol))
        {
          CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory Unknown service type (%s), skipping; ", zeroconf_service.GetType().c_str());
          return false;
        }
        
        service.SetProtocol(protocol);
        
        //first try to show the txt-record defined path if any
        if(GetDirectoryFromTxtRecords(zeroconf_service, service, items))
        {
          return true;
        }
        else//no txt record path - so let the CDirectory handler show the folders
        {
          // CDirectory::GetDirectory returns false if authorization is required
          // The target vfs directory will call RequireAuthentication but that is
          // is not good enough as we can be running as a job and not under main thread,
          // so authentication dialog does not get called. Set it again here so
          // authentication dialog gets called and we will get called again with user/pass setup.
          bool status = CDirectory::GetDirectory(service, items, "", DIR_FLAG_ALLOW_PROMPT);
          if(!status)
            RequireAuthentication(service);
          return status;
        }
      }
    } catch (std::runtime_error& e) {
      CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory failed getting directory: '%s'. Error: '%s'", decoded.c_str(), e.what());
      return false;
    }
  }
}
Ejemplo n.º 19
0
//*********************************************************************************************
bool CRTVDirectory::GetDirectory(const CURL& url2, CFileItemList &items)
{
  CURL url(url2);
  std::string strRoot = url.Get();
  URIUtils::AddSlashAtEnd(strRoot);

  // Host name is "*" so we try to discover all ReplayTVs.  This requires some trickery but works.
  if (url.GetHostName() == "*")
  {
    // Check to see whether the URL's path is blank or "Video"
    if (url.GetFileName() == "" || url.GetFileName() == "Video")
    {
      int iOldSize=items.Size();
      struct RTV * rtv = NULL;
      int numRTV;

      // Request that all ReplayTVs on the LAN identify themselves.  Each ReplayTV
      // is given 3000ms to respond to the request.  rtv_discovery returns an array
      // of structs containing the IP and friendly name of all ReplayTVs found on the LAN.
      // For some reason, DVArchive doesn't respond to this request (probably only responds
      // to requests from an IP address of a real ReplayTV).
      numRTV = rtv_discovery(&rtv, 3000);

      // Run through the array and add the ReplayTVs found as folders in XBMC.
      // We must add the IP of each ReplayTV as if it is a file name at the end of a the
      // auto-discover URL--e.g. rtv://*/192.168.1.100--because XBMC does not permit
      // dyamically added shares and will not play from them.  This little trickery is
      // the best workaround I could come up with.
      for (int i = 0; i < numRTV; i++)
      {
        CFileItemPtr pItem(new CFileItem(rtv[i].friendlyName));
        // This will keep the /Video or / and allow one to set up an auto ReplayTV
        // share of either type--simple file listing or ReplayGuide listing.
        pItem->SetPath(strRoot + rtv[i].hostname);
        pItem->m_bIsFolder = true;
        pItem->SetLabelPreformated(true);
        items.Add(pItem);
      }
      free(rtv);
      return (items.Size()>iOldSize);
      // Else the URL's path should be an IP address of the ReplayTV
    }
    else
    {
      std::string strURL, strRTV;
      size_t pos;

      // Isolate the IP from the URL and replace the "*" with the real IP
      // of the ReplayTV.  E.g., rtv://*/Video/192.168.1.100/ becomes
      // rtv://192.168.1.100/Video/ .  This trickery makes things work.
      strURL = StringUtils::TrimRight(strRoot, "/");
      pos = strURL.rfind('/');
      strRTV = strURL.substr(0, pos + 1);
      StringUtils::Replace(strRTV, "*", strURL.substr(pos + 1));
      CURL tmpURL(strRTV);

      // Force the newly constructed share into the right variables to
      // be further processed by the remainder of GetDirectory.
      url = tmpURL;
      strRoot = strRTV;
    }
  }

  // Allow for ReplayTVs on ports other than 80
  std::string strHostAndPort = url.GetHostName();
  if (url.HasPort())
  {
    char buffer[10];
    sprintf(buffer,"%i",url.GetPort());
    strHostAndPort += ':';
    strHostAndPort += buffer;
  }

  // No path given, list shows from ReplayGuide
  if (url.GetFileName() == "")
  {
    unsigned char * data = NULL;

    // Get the RTV guide data in XML format
    rtv_get_guide_xml(&data, strHostAndPort.c_str());

    // Begin parsing the XML data
    CXBMCTinyXML xmlDoc;
    xmlDoc.Parse( (const char *) data );
    if ( xmlDoc.Error() )
    {
      free(data);
      return false;
    }
    TiXmlElement* pRootElement = xmlDoc.RootElement();
    if (!pRootElement)
    {
      free(data);
      return false;
    }

    const TiXmlNode *pChild = pRootElement->FirstChild();
    while (pChild > 0)
    {
      std::string strTagName = pChild->ValueStr();

      if ( !strcmpi(strTagName.c_str(), "ITEM") )
      {
        const TiXmlNode *nameNode = pChild->FirstChild("DISPLAYNAME");
//        const TiXmlNode *qualityNode = pChild->FirstChild("QUALITY");
        const TiXmlNode *recordedNode = pChild->FirstChild("RECORDED");
        const TiXmlNode *pathNode = pChild->FirstChild("PATH");
//        const TiXmlNode *durationNode = pChild->FirstChild("DURATION");
        const TiXmlNode *sizeNode = pChild->FirstChild("SIZE");
        const TiXmlNode *atrbNode = pChild->FirstChild("ATTRIB");

        SYSTEMTIME dtDateTime;
        DWORD dwFileSize = 0;
        memset(&dtDateTime, 0, sizeof(dtDateTime));

        // DISPLAYNAME
        const char* szName = NULL;
        if (nameNode)
        {
          szName = nameNode->FirstChild()->Value() ;
        }
        else
        {
          // Something went wrong, the recording has no name
          free(data);
          return false;
        }

        // QUALITY
//        const char* szQuality = NULL;
//        if (qualityNode)
//        {
//          szQuality = qualityNode->FirstChild()->Value() ;
//        }

        // RECORDED
        if (recordedNode && recordedNode->FirstChild())
        {
          std::string strRecorded = recordedNode->FirstChild()->ValueStr();

          if (strRecorded.size() >= 19)
          {
            /* TODO:STRING_CLEANUP */
            int iYear, iMonth, iDay;
            iYear = atoi(strRecorded.substr(0, 4).c_str());
            iMonth = atoi(strRecorded.substr(5, 2).c_str());
            iDay = atoi(strRecorded.substr(8, 2).c_str());
            dtDateTime.wYear = iYear;
            dtDateTime.wMonth = iMonth;
            dtDateTime.wDay = iDay;

            int iHour, iMin, iSec;
            iHour = atoi(strRecorded.substr(11, 2).c_str());
            iMin = atoi(strRecorded.substr(14, 2).c_str());
            iSec = atoi(strRecorded.substr(17, 2).c_str());
            dtDateTime.wHour = iHour;
            dtDateTime.wMinute = iMin;
            dtDateTime.wSecond = iSec;
          }
        }

        // PATH
        const char* szPath = NULL;
        if (pathNode)
        {
          szPath = pathNode->FirstChild()->Value() ;
        }
        else
        {
          // Something went wrong, the recording has no filename
          free(data);
          return false;
        }

        // DURATION
//        const char* szDuration = NULL;
//        if (durationNode)
//        {
//          szDuration = durationNode->FirstChild()->Value() ;
//        }

        // SIZE
        // NOTE: Size here is actually just duration in minutes because
        // filesize is not reported by the stripped down GuideParser I use
        if (sizeNode)
        {
          dwFileSize = atol( sizeNode->FirstChild()->Value() );
        }

        // ATTRIB
        // NOTE: Not currently reported in the XML guide data, nor is it particularly
        // needed unless someone wants to add the ability to sub-divide the recordings
        // into categories, as on a real RTV.
        int attrib = 0;
        if (atrbNode)
        {
          attrib = atoi( atrbNode->FirstChild()->Value() );
        }

        bool bIsFolder(false);
        if (attrib & FILE_ATTRIBUTE_DIRECTORY)
          bIsFolder = true;

        CFileItemPtr pItem(new CFileItem(szName));
        pItem->m_dateTime=dtDateTime;
        pItem->SetPath(strRoot + szPath);
        // Hack to show duration of show in minutes as KB in XBMC because
        // it doesn't currently permit showing duration in minutes.
        // E.g., a 30 minute show will show as 29.3 KB in XBMC.
        pItem->m_dwSize = dwFileSize * 1000;
        pItem->m_bIsFolder = bIsFolder;
        pItem->SetLabelPreformated(true);
        items.Add(pItem);
      }

      pChild = pChild->NextSibling();
    }

    free(data);

    // Path given (usually Video), list filenames only
  }
  else
  {

    unsigned char * data;
    char * p, * q;
    unsigned long status;

    // Return a listing of all files in the given path
    status = rtv_list_files(&data, strHostAndPort.c_str(), url.GetFileName().c_str());
    if (status == 0)
    {
      return false;
    }

    // Loop through the file list using pointers p and q, where p will point to the current
    // filename and q will point to the next filename
    p = (char *) data;
    while (p)
    {
      // Look for the end of the current line of the file listing
      q = strchr(p, '\n');
      // If found, replace the newline character with the NULL terminator
      if (q)
      {
        *q = '\0';
        // Increment q so that it points to the next filename
        q++;
        // *p should be the current null-terminated filename in the list
        if (*p)
        {
          // Only display MPEG files in XBMC (but not circular.mpg, as that is the RTV
          // video buffer and XBMC may cause problems if it tries to play it)
          if (strstr(p, ".mpg") && !strstr(p, "circular"))
          {
            CFileItemPtr pItem(new CFileItem(p));
            pItem->SetPath(strRoot + p);
            pItem->m_bIsFolder = false;
            // The list returned by the RTV doesn't include file sizes, unfortunately
            //pItem->m_dwSize = atol(szSize);
            pItem->SetLabelPreformated(true);
            items.Add(pItem);
          }
        }
      }
      // Point p to the next filename in the list and loop
      p = q;
    }

    free(data);
  }

  return true;
}
Ejemplo n.º 20
0
bool GetDirectoryFromTxtRecords(CZeroconfBrowser::ZeroconfService zeroconf_service, CURL& url, CFileItemList &items)
{
  bool ret = false;

  //get the txt-records from this service
  CZeroconfBrowser::ZeroconfService::tTxtRecordMap txtRecords=zeroconf_service.GetTxtRecords();

  //if we have some records
  if(!txtRecords.empty())
  {
    std::string path;
    std::string username;
    std::string password;
  
    //search for a path key entry
    CZeroconfBrowser::ZeroconfService::tTxtRecordMap::iterator it = txtRecords.find(TXT_RECORD_PATH_KEY);

    //if we found the key - be sure there is a value there
    if( it != txtRecords.end() && !it->second.empty() )
    {
      //from now on we treat the value as a path - everything else would mean
      //a missconfigured zeroconf server.
      path=it->second;
    }
    
    //search for a username key entry
    it = txtRecords.find(TXT_RECORD_USERNAME_KEY);

    //if we found the key - be sure there is a value there
    if( it != txtRecords.end() && !it->second.empty() )
    {
      username=it->second;
      url.SetUserName(username);
    }
    
    //search for a password key entry
    it = txtRecords.find(TXT_RECORD_PASSWORD_KEY);

    //if we found the key - be sure there is a value there
    if( it != txtRecords.end() && !it->second.empty() )
    {
      password=it->second;
      url.SetPassword(password);
    }
    
    //if we got a path - add a item - else at least we maybe have set username and password to theurl
    if( !path.empty())
    {
      CFileItemPtr item(new CFileItem("", true));
      std::string urlStr(url.Get());
      //if path has a leading slash (sure it should have one)
      if( path.at(0) == '/' )
      {
        URIUtils::RemoveSlashAtEnd(urlStr);//we don't need the slash at and of url then
      }
      else//path doesn't start with slash - 
      {//this is some kind of missconfiguration - we fix it by adding a slash to the url
        URIUtils::AddSlashAtEnd(urlStr);
      }
      
      //add slash at end of path since it has to be a folder
      URIUtils::AddSlashAtEnd(path);
      //this is the full path includeing remote stuff (e.x. nfs://ip/path
      item->SetPath(urlStr + path);
      //remove the slash at the end of the path or GetFileName will not give the last dir
      URIUtils::RemoveSlashAtEnd(path);
      //set the label to the last directory in path
      if( !URIUtils::GetFileName(path).empty() )
        item->SetLabel(URIUtils::GetFileName(path));
      else
        item->SetLabel("/");

      item->SetLabelPreformated(true);
      //just set the default folder icon
      item->FillInDefaultIcon();
      item->m_bIsShareOrDrive=true;
      items.Add(item);
      ret = true;
    }
  }
  return ret;
}
Ejemplo n.º 21
0
/**
 * This method tries to determine what type of disc is located in the given drive and starts to play the content appropriately.
 */
bool CAutorun::RunDisc(IDirectory* pDir, const CStdString& strDrive, int& nAddedToPlaylist, bool bRoot, bool bypassSettings /* = false */, bool startFromBeginning /* = false */)
{
  bool bPlaying(false);
  CFileItemList vecItems;

  const CURL pathToUrl(strDrive);
  if ( !pDir->GetDirectory( pathToUrl, vecItems ) )
  {
    return false;
  }

  // Sorting necessary for easier HDDVD handling
  vecItems.Sort(SortByLabel, SortOrderAscending);

  bool bAllowVideo = true;
//  bool bAllowPictures = true;
  bool bAllowMusic = true;
  if (!g_passwordManager.IsMasterLockUnlocked(false))
  {
    bAllowVideo = !CProfilesManager::Get().GetCurrentProfile().videoLocked();
//    bAllowPictures = !CProfilesManager::Get().GetCurrentProfile().picturesLocked();
    bAllowMusic = !CProfilesManager::Get().GetCurrentProfile().musicLocked();
  }

  // is this a root folder we have to check the content to determine a disc type
  if( bRoot )
  {
    CStdString hddvdname = "";
    CFileItemPtr phddvdItem;

    // check root folders next, for normal structured dvd's
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr pItem = vecItems[i];

      // is the current item a (non system) folder?
      if (pItem->m_bIsFolder && pItem->GetPath() != "." && pItem->GetPath() != "..")
      {
        CStdString name = pItem->GetPath();
        URIUtils::RemoveSlashAtEnd(name);
        name = URIUtils::GetFileName(name);

        // Check if the current foldername indicates a DVD structure (name is "VIDEO_TS")
        if (name.Equals("VIDEO_TS") && bAllowVideo
        && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          CStdString path = URIUtils::AddFileToFolder(pItem->GetPath(), "VIDEO_TS.IFO");
          if(!CFile::Exists(path))
            path = URIUtils::AddFileToFolder(pItem->GetPath(), "video_ts.ifo");
          CFileItemPtr item(new CFileItem(path, false));
          item->SetLabel(g_mediaManager.GetDiskLabel(strDrive));
          item->GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive);

          if (!startFromBeginning && !item->GetVideoInfoTag()->m_strFileNameAndPath.empty())
            item->m_lStartOffset = STARTOFFSET_RESUME;

          g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false);
          g_playlistPlayer.Add(PLAYLIST_VIDEO, item);
          g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.Play(0);
          return true;
        }

        // Check if the current foldername indicates a Blu-Ray structure (default is "BDMV").
        // A BR should also include an "AACS" folder for encryption, Sony-BRs can also include update folders for PS3 (PS3_UPDATE / PS3_VPRM).
        // ToDo: for the time beeing, the DVD autorun settings are used to determine if the BR should be started automatically.
        if (name.Equals("BDMV") && bAllowVideo
        && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          CFileItemPtr item(new CFileItem(URIUtils::AddFileToFolder(pItem->GetPath(), "index.bdmv"), false));
          item->SetLabel(g_mediaManager.GetDiskLabel(strDrive));
          item->GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive);

          if (!startFromBeginning && !item->GetVideoInfoTag()->m_strFileNameAndPath.empty())
            item->m_lStartOffset = STARTOFFSET_RESUME;

          g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false);
          if (!CGUIWindowVideoBase::ShowPlaySelection(item))
            return false;
          g_playlistPlayer.Add(PLAYLIST_VIDEO, item);
          g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.Play(0);
          return true;
        }

        // Check if the current foldername indicates a HD DVD structure (default is "HVDVD_TS").
        // Most HD DVD will also include an "ADV_OBJ" folder for advanced content. This folder should be handled first.
        // ToDo: for the time beeing, the DVD autorun settings are used to determine if the HD DVD should be started automatically.
        CFileItemList items, sitems;
        
        // Advanced Content HD DVD (most discs?)
        if (name.Equals("ADV_OBJ"))
        {
          CLog::Log(LOGINFO,"HD DVD: Checking for playlist.");
          // find playlist file
          CDirectory::GetDirectory(pItem->GetPath(), items, "*.xpl");
          if (items.Size())
          {
            // HD DVD Standard says the highest numbered playlist has to be handled first.
            CLog::Log(LOGINFO,"HD DVD: Playlist found. Set filetypes to *.xpl for external player.");
            items.Sort(SortByLabel, SortOrderDescending);
            phddvdItem = pItem; 
            hddvdname = URIUtils::GetFileName(items[0]->GetPath());
            CLog::Log(LOGINFO,"HD DVD: %s", items[0]->GetPath().c_str());
          }
        }

        // Standard Content HD DVD (few discs?)
        if (name.Equals("HVDVD_TS") && bAllowVideo
        && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          if (hddvdname == "")
          {
            CLog::Log(LOGINFO,"HD DVD: Checking for ifo.");
            // find Video Manager or Title Set Information
            CDirectory::GetDirectory(pItem->GetPath(), items, "HV*.ifo");
            if (items.Size())
            {
              // HD DVD Standard says the lowest numbered ifo has to be handled first.
              CLog::Log(LOGINFO,"HD DVD: IFO found. Set filename to HV* and filetypes to *.ifo for external player.");
              items.Sort(SortByLabel, SortOrderAscending);
              phddvdItem = pItem; 
              hddvdname = URIUtils::GetFileName(items[0]->GetPath());
              CLog::Log(LOGINFO,"HD DVD: %s",items[0]->GetPath().c_str());
            }
          }
          // Find and sort *.evo files for internal playback.
          // While this algorithm works for all of my HD DVDs, it may fail on other discs. If there are very large extras which are
          // alphabetically before the main movie they will be sorted to the top of the playlist and get played first.
          CDirectory::GetDirectory(pItem->GetPath(), items, "*.evo");
          if (items.Size())
          {
            // Sort *.evo files in alphabetical order.
            items.Sort(SortByLabel, SortOrderAscending);
            int64_t asize = 0;
            int ecount = 0;
            // calculate average size of elements above 1gb
            for (int j = 0; j < items.Size(); j++)
              if (items[j]->m_dwSize > 1000000000)
              {
                ecount++;
                asize = asize + items[j]->m_dwSize;
              }
            asize = asize / ecount;
            // Put largest files in alphabetical order to top of new list.
            for (int j = 0; j < items.Size(); j++)
              if (items[j]->m_dwSize >= asize)
                sitems.Add (items[j]);
            // Sort *.evo files by size.
            items.Sort(SortBySize, SortOrderDescending);
            // Add other files with descending size to bottom of new list.
            for (int j = 0; j < items.Size(); j++)
              if (items[j]->m_dwSize < asize)
                sitems.Add (items[j]);
            // Replace list with optimized list.
            items.Clear();
            items.Copy (sitems);
            sitems.Clear();
          }
          if (hddvdname != "")
          {
            CFileItem item(URIUtils::AddFileToFolder(phddvdItem->GetPath(), hddvdname), false);
            item.SetLabel(g_mediaManager.GetDiskLabel(strDrive));
            item.GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive);

            if (!startFromBeginning && !item.GetVideoInfoTag()->m_strFileNameAndPath.empty())
            item.m_lStartOffset = STARTOFFSET_RESUME;

            // get playername
            CStdString hddvdplayer = CPlayerCoreFactory::Get().GetPlayerName(CPlayerCoreFactory::Get().GetDefaultPlayer(item));
            
            // Single *.xpl or *.ifo files require an external player to handle playback.
            // If no matching rule was found, DVDPlayer will be default player.
            if (hddvdplayer != "DVDPlayer")
            {
              CLog::Log(LOGINFO,"HD DVD: External singlefile playback initiated: %s",hddvdname.c_str());
              g_application.PlayFile(item, false);
              return true;
            } else
              CLog::Log(LOGINFO,"HD DVD: No external player found. Fallback to internal one.");
          }

          //  internal *.evo playback.
          CLog::Log(LOGINFO,"HD DVD: Internal multifile playback initiated.");
          g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false);
          g_playlistPlayer.Add(PLAYLIST_VIDEO, items);
          g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.Play(0);
          return true;
        }
				
        // Video CDs can have multiple file formats. First we need to determine which one is used on the CD
        CStdString strExt;
        if (name.Equals("MPEGAV"))
          strExt = ".dat";
        if (name.Equals("MPEG2"))
          strExt = ".mpg";

        // If a file format was extracted we are sure this is a VCD. Autoplay if settings indicate we should.
        if (!strExt.empty() && bAllowVideo
             && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          CFileItemList items;
          CDirectory::GetDirectory(pItem->GetPath(), items, strExt);
          if (items.Size())
          {
            items.Sort(SortByLabel, SortOrderAscending);
            g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
            g_playlistPlayer.Add(PLAYLIST_VIDEO, items);
            g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
            g_playlistPlayer.Play(0);
            return true;
          }
        }
        /* Probably want this if/when we add some automedia action dialog...
        else if (pItem->GetPath().Find("PICTURES") != -1 && bAllowPictures
              && (bypassSettings))
        {
          bPlaying = true;
          CStdString strExec = StringUtils::Format("RecursiveSlideShow(%s)", pItem->GetPath().c_str());
          CBuiltins::Execute(strExec);
          return true;
        }
        */
      }
    }
  }

  // check video first
  if (!nAddedToPlaylist && !bPlaying && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
  {
    // stack video files
    CFileItemList tempItems;
    tempItems.Append(vecItems);
    if (CSettings::Get().GetBool("myvideos.stackvideos"))
      tempItems.Stack();
    CFileItemList itemlist;

    for (int i = 0; i < tempItems.Size(); i++)
    {
      CFileItemPtr pItem = tempItems[i];
      if (!pItem->m_bIsFolder && pItem->IsVideo())
      {
        bPlaying = true;
        if (pItem->IsStack())
        {
          // TODO: remove this once the app/player is capable of handling stacks immediately
          CStackDirectory dir;
          CFileItemList items;
          dir.GetDirectory(pItem->GetURL(), items);
          itemlist.Append(items);
        }
        else
          itemlist.Add(pItem);
      }
    }
    if (itemlist.Size())
    {
      if (!bAllowVideo)
      {
        if (!bypassSettings)
          return false;

        if (g_windowManager.GetActiveWindow() != WINDOW_VIDEO_FILES)
          if (!g_passwordManager.IsMasterLockUnlocked(true))
            return false;
      }
      g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
      g_playlistPlayer.Add(PLAYLIST_VIDEO, itemlist);
      g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
      g_playlistPlayer.Play(0);
    }
  }
  // then music
  if (!bPlaying && (bypassSettings || CSettings::Get().GetInt("audiocds.autoaction") == AUTOCD_PLAY) && bAllowMusic)
  {
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr pItem = vecItems[i];
      if (!pItem->m_bIsFolder && pItem->IsAudio())
      {
        nAddedToPlaylist++;
        g_playlistPlayer.Add(PLAYLIST_MUSIC, pItem);
      }
    }
  }
  /* Probably want this if/when we add some automedia action dialog...
  // and finally pictures
  if (!nAddedToPlaylist && !bPlaying && bypassSettings && bAllowPictures)
  {
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr pItem = vecItems[i];
      if (!pItem->m_bIsFolder && pItem->IsPicture())
      {
        bPlaying = true;
        CStdString strExec = StringUtils::Format("RecursiveSlideShow(%s)", strDrive.c_str());
        CBuiltins::Execute(strExec);
        break;
      }
    }
  }
  */

  // check subdirs if we are not playing yet
  if (!bPlaying)
  {
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr  pItem = vecItems[i];
      if (pItem->m_bIsFolder)
      {
        if (pItem->GetPath() != "." && pItem->GetPath() != ".." )
        {
          if (RunDisc(pDir, pItem->GetPath(), nAddedToPlaylist, false, bypassSettings, startFromBeginning))
          {
            bPlaying = true;
            break;
          }
        }
      } // if (non system) folder
    } // for all items in directory
  } // if root folder

  return bPlaying;
}
Ejemplo n.º 22
0
bool CPVRChannelGroupsContainer::GetDirectory(const std::string& strPath, CFileItemList &results) const
{
  std::string strBase(strPath);
  URIUtils::RemoveSlashAtEnd(strBase);

  /* get the filename from curl */
  CURL url(strPath);
  std::string fileName = url.GetFileName();
  URIUtils::RemoveSlashAtEnd(fileName);

  if (fileName == "channels")
  {
    CFileItemPtr item;

    /* all tv channels */
    item.reset(new CFileItem(strBase + "/tv/", true));
    item->SetLabel(g_localizeStrings.Get(19020));
    item->SetLabelPreformatted(true);
    results.Add(item);

    /* all radio channels */
    item.reset(new CFileItem(strBase + "/radio/", true));
    item->SetLabel(g_localizeStrings.Get(19021));
    item->SetLabelPreformatted(true);
    results.Add(item);

    return true;
  }
  else if (fileName == "channels/tv")
  {
    return GetGroupsDirectory(&results, false);
  }
  else if (fileName == "channels/radio")
  {
    return GetGroupsDirectory(&results, true);
  }
  else if (StringUtils::StartsWith(fileName, "channels/tv/"))
  {
    std::string strGroupName(fileName.substr(12));
    URIUtils::RemoveSlashAtEnd(strGroupName);

    CPVRChannelGroupPtr group;
    if (strGroupName == "*") // all channels
      group = GetGroupAllTV();
    else
      group = GetTV()->GetByName(strGroupName);

    if (group)
    {
      group->GetMembers(results, !StringUtils::EndsWithNoCase(fileName, ".hidden"));
    }
    else
    {
      CLog::Log(LOGERROR, "CPVRChannelGroupsContainer - %s - unable to obtain members of channel group '%s'", __FUNCTION__, strGroupName.c_str());
      return false;
    }

    FilterDirectory(url, results);
    return true;
  }
  else if (StringUtils::StartsWith(fileName, "channels/radio/"))
  {
    std::string strGroupName(fileName.substr(15));
    URIUtils::RemoveSlashAtEnd(strGroupName);

    CPVRChannelGroupPtr group;
    if (strGroupName == "*") // all channels
      group = GetGroupAllRadio();
    else
      group = GetRadio()->GetByName(strGroupName);

    if (group)
    {
      group->GetMembers(results, !StringUtils::EndsWithNoCase(fileName, ".hidden"));
    }
    else
    {
      CLog::Log(LOGERROR, "CPVRChannelGroupsContainer - %s - unable to obtain members of channel group '%s'", __FUNCTION__, strGroupName.c_str());
      return false;
    }

    FilterDirectory(url, results);
    return true;
  }

  return false;
}
Ejemplo n.º 23
0
bool CGUIWindowMusicBase::GetDirectory(const std::string &strDirectory, CFileItemList &items)
{
  items.ClearArt();
  bool bResult = CGUIMediaWindow::GetDirectory(strDirectory, items);
  if (bResult)
  {
    CMusicThumbLoader loader;
    loader.FillThumb(items);

    CQueryParams params;
    CDirectoryNode::GetDatabaseInfo(items.GetPath(), params);

    if (params.GetAlbumId() > 0)
    {
      std::map<std::string, std::string> artistArt;
      if (m_musicdatabase.GetArtistArtForItem(params.GetAlbumId(), MediaTypeAlbum, artistArt))
        items.AppendArt(artistArt, MediaTypeArtist);

      std::map<std::string, std::string> albumArt;
      if (m_musicdatabase.GetArtForItem(params.GetAlbumId(), MediaTypeAlbum, albumArt))
        items.AppendArt(albumArt, MediaTypeAlbum);
    }
    if (params.GetArtistId() > 0)
    {
      std::map<std::string, std::string> artistArt;
      if (m_musicdatabase.GetArtForItem(params.GetArtistId(), "artist", artistArt))
        items.AppendArt(artistArt, MediaTypeArtist);
    }

    // add in the "New Playlist" item if we're in the playlists folder
    if ((items.GetPath() == "special://musicplaylists/") && !items.Contains("newplaylist://"))
    {
      CFileItemPtr newPlaylist(new CFileItem(CProfilesManager::GetInstance().GetUserDataItem("PartyMode.xsp"),false));
      newPlaylist->SetLabel(g_localizeStrings.Get(16035));
      newPlaylist->SetLabelPreformated(true);
      newPlaylist->m_bIsFolder = true;
      items.Add(newPlaylist);

      newPlaylist.reset(new CFileItem("newplaylist://", false));
      newPlaylist->SetLabel(g_localizeStrings.Get(525));
      newPlaylist->SetIconImage("DefaultPlaylist.png");
      newPlaylist->SetLabelPreformated(true);
      newPlaylist->SetSpecialSort(SortSpecialOnBottom);
      newPlaylist->SetCanQueue(false);
      items.Add(newPlaylist);

      newPlaylist.reset(new CFileItem("newsmartplaylist://music", false));
      newPlaylist->SetLabel(g_localizeStrings.Get(21437));
      newPlaylist->SetIconImage("DefaultPlaylist.png");
      newPlaylist->SetLabelPreformated(true);
      newPlaylist->SetSpecialSort(SortSpecialOnBottom);
      newPlaylist->SetCanQueue(false);
      items.Add(newPlaylist);
    }

    // check for .CUE files here.
    items.FilterCueItems();

    std::string label;
    if (items.GetLabel().empty() && m_rootDir.IsSource(items.GetPath(), CMediaSourceSettings::GetInstance().GetSources("music"), &label))
      items.SetLabel(label);
  }

  return bResult;
}
Ejemplo n.º 24
0
//  Add an "* All ..." folder to the CFileItemList
//  depending on the child node
void CVideoFileItemListModifier::AddQueuingFolder(CFileItemList& items)
{
  if (!items.IsVideoDb())
    return;

  auto directoryNode = CDirectoryNode::ParseURL(items.GetPath());

  CFileItemPtr pItem;

  // always show "all" items by default
  if (!CServiceBroker::GetSettings().GetBool(CSettings::SETTING_VIDEOLIBRARY_SHOWALLITEMS))
    return;

  // no need for "all" item when only one item
  if (items.GetObjectCount() <= 1)
    return;

  CVideoDbUrl videoUrl;
  if (!videoUrl.FromString(directoryNode->BuildPath()))
    return;

  // hack - as the season node might return episodes
  std::unique_ptr<CDirectoryNode> pNode(directoryNode);

  switch (pNode->GetChildType())
  {
  case NODE_TYPE_SEASONS:
  {
    std::string strLabel = g_localizeStrings.Get(20366);
    pItem.reset(new CFileItem(strLabel));  // "All Seasons"
    videoUrl.AppendPath("-1/");
    pItem->SetPath(videoUrl.ToString());
    // set the number of watched and unwatched items accordingly
    int watched = 0;
    int unwatched = 0;
    for (int i = 0; i < items.Size(); i++)
    {
      CFileItemPtr item = items[i];
      watched += static_cast<int>(item->GetProperty("watchedepisodes").asInteger());
      unwatched += static_cast<int>(item->GetProperty("unwatchedepisodes").asInteger());
    }
    pItem->SetProperty("totalepisodes", watched + unwatched);
    pItem->SetProperty("numepisodes", watched + unwatched); // will be changed later to reflect watchmode setting
    pItem->SetProperty("watchedepisodes", watched);
    pItem->SetProperty("unwatchedepisodes", unwatched);
    if (items.Size() && items[0]->GetVideoInfoTag())
    {
      *pItem->GetVideoInfoTag() = *items[0]->GetVideoInfoTag();
      pItem->GetVideoInfoTag()->m_iSeason = -1;
    }
    pItem->GetVideoInfoTag()->m_strTitle = strLabel;
    pItem->GetVideoInfoTag()->m_iEpisode = watched + unwatched;
    pItem->GetVideoInfoTag()->SetPlayCount((unwatched == 0) ? 1 : 0);
    CVideoDatabase db;
    if (db.Open())
    {
      pItem->GetVideoInfoTag()->m_iDbId = db.GetSeasonId(pItem->GetVideoInfoTag()->m_iIdShow, -1);
      db.Close();
    }
    pItem->GetVideoInfoTag()->m_type = MediaTypeSeason;
  }
  break;
  case NODE_TYPE_MUSICVIDEOS_ALBUM:
    pItem.reset(new CFileItem(g_localizeStrings.Get(15102)));  // "All Albums"
    videoUrl.AppendPath("-1/");
    pItem->SetPath(videoUrl.ToString());
    break;
  default:
    break;
  }

  if (pItem)
  {
    pItem->m_bIsFolder = true;
    pItem->SetSpecialSort(g_advancedSettings.m_bVideoLibraryAllItemsOnBottom ? SortSpecialOnBottom : SortSpecialOnTop);
    pItem->SetCanQueue(false);
    items.Add(pItem);
  }
}
Ejemplo n.º 25
0
//! @todo Currently no support for "embedded thumb" as there is no easy way to grab it
//!       without sending a file that has this as it's album to this class
void CGUIDialogSongInfo::OnGetThumb()
{
  CFileItemList items;


  // Grab the thumbnail from the web
  /*
  std::string thumbFromWeb;
  thumbFromWeb = URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath, "allmusicThumb.jpg");
  if (DownloadThumbnail(thumbFromWeb))
  {
    CFileItemPtr item(new CFileItem("thumb://allmusic.com", false));
    item->SetArt("thumb", thumbFromWeb);
    item->SetLabel(g_localizeStrings.Get(20055));
    items.Add(item);
  }*/

  // Current thumb
  if (CFile::Exists(m_song->GetArt("thumb")))
  {
    CFileItemPtr item(new CFileItem("thumb://Current", false));
    item->SetArt("thumb", m_song->GetArt("thumb"));
    item->SetLabel(g_localizeStrings.Get(20016));
    items.Add(item);
  }

  // local thumb
  std::string cachedLocalThumb;
  std::string localThumb(m_song->GetUserMusicThumb(true));
  if (m_song->IsMusicDb())
  {
    CFileItem item(m_song->GetMusicInfoTag()->GetURL(), false);
    localThumb = item.GetUserMusicThumb(true);
  }
  if (CFile::Exists(localThumb))
  {
    CFileItemPtr item(new CFileItem("thumb://Local", false));
    item->SetArt("thumb", localThumb);
    item->SetLabel(g_localizeStrings.Get(20017));
    items.Add(item);
  }
  else
  { // no local thumb exists, so we are just using the allmusic.com thumb or cached thumb
    // which is probably the allmusic.com thumb.  These could be wrong, so allow the user
    // to delete the incorrect thumb
    CFileItemPtr item(new CFileItem("thumb://None", false));
    item->SetArt("thumb", "DefaultAlbumCover.png");
    item->SetLabel(g_localizeStrings.Get(20018));
    items.Add(item);
  }

  std::string result;
  VECSOURCES sources(*CMediaSourceSettings::GetInstance().GetSources("music"));
  CGUIDialogMusicInfo::AddItemPathToFileBrowserSources(sources, *m_song);
  g_mediaManager.GetLocalDrives(sources);
  if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(1030), result))
    return;   // user cancelled

  if (result == "thumb://Current")
    return;   // user chose the one they have

  // delete the thumbnail if that's what the user wants, else overwrite with the
  // new thumbnail

  std::string newThumb;
  if (result == "thumb://None")
    newThumb = "-";
  else if (result == "thumb://allmusic.com")
    newThumb.clear();
  else if (result == "thumb://Local")
    newThumb = localThumb;
  else
    newThumb = result;

  // update thumb in the database
  CMusicDatabase db;
  if (db.Open())
  {
    db.SetArtForItem(m_song->GetMusicInfoTag()->GetDatabaseId(), m_song->GetMusicInfoTag()->GetType(), "thumb", newThumb);
    db.Close();
  }

  m_song->SetArt("thumb", newThumb);

  // tell our GUI to completely reload all controls (as some of them
  // are likely to have had this image in use so will need refreshing)
  CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
  g_windowManager.SendMessage(msg);

//  m_hasUpdatedThumb = true;
}
Ejemplo n.º 26
0
bool CLibraryDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  std::string libNode = GetNode(url);
  if (libNode.empty())
    return false;

  if (URIUtils::HasExtension(libNode, ".xml"))
  { // a filter or folder node
    TiXmlElement *node = LoadXML(libNode);
    if (node)
    {
      std::string type = XMLUtils::GetAttribute(node, "type");
      if (type == "filter")
      {
        CSmartPlaylist playlist;
        std::string type, label;
        XMLUtils::GetString(node, "content", type);
        if (type.empty())
        {
          CLog::Log(LOGERROR, "<content> tag must not be empty for type=\"filter\" node '%s'", libNode.c_str());
          return false;
        }
        if (XMLUtils::GetString(node, "label", label))
          label = CGUIControlFactory::FilterLabel(label);
        playlist.SetType(type);
        playlist.SetName(label);
        if (playlist.LoadFromXML(node) &&
            CSmartPlaylistDirectory::GetDirectory(playlist, items))
        {
          items.SetProperty("library.filter", "true");
          items.SetPath(items.GetProperty("path.db").asString());
          return true;
        }
      }
      else if (type == "folder")
      {
        std::string path;
        XMLUtils::GetPath(node, "path", path);
        if (!path.empty())
        {
          URIUtils::AddSlashAtEnd(path);
          return CDirectory::GetDirectory(path, items, m_strFileMask, m_flags);
        }
      }
    }
    return false;
  }

  // just a plain node - read the folder for XML nodes and other folders
  CFileItemList nodes;
  if (!CDirectory::GetDirectory(libNode, nodes, ".xml", DIR_FLAG_NO_FILE_DIRS))
    return false;

  // iterate over our nodes
  std::string basePath = url.Get();
  for (int i = 0; i < nodes.Size(); i++)
  {
    const TiXmlElement *node = NULL;
    std::string xml = nodes[i]->GetPath();
    if (nodes[i]->m_bIsFolder)
      node = LoadXML(URIUtils::AddFileToFolder(xml, "index.xml"));
    else
    {
      node = LoadXML(xml);
      if (node && URIUtils::GetFileName(xml) == "index.xml")
      { // set the label on our items
        std::string label;
        if (XMLUtils::GetString(node, "label", label))
          label = CGUIControlFactory::FilterLabel(label);
        items.SetLabel(label);
        continue;
      }
    }
    if (node)
    {
      std::string label, icon;
      if (XMLUtils::GetString(node, "label", label))
        label = CGUIControlFactory::FilterLabel(label);
      XMLUtils::GetString(node, "icon", icon);
      int order = 0;
      node->Attribute("order", &order);

      // create item
      URIUtils::RemoveSlashAtEnd(xml);
      std::string folder = URIUtils::GetFileName(xml);
      CFileItemPtr item(new CFileItem(URIUtils::AddFileToFolder(basePath, folder), true));

      item->SetLabel(label);
      if (!icon.empty() && g_TextureManager.HasTexture(icon))
        item->SetIconImage(icon);
      item->m_iprogramCount = order;
      items.Add(item);
    }
  }
  items.Sort(SortByPlaylistOrder, SortOrderAscending);
  return true;
}
Ejemplo n.º 27
0
/**
 * This method tries to determine what type of disc is located in the given drive and starts to play the content appropriately.
 */
bool CAutorun::RunDisc(IDirectory* pDir, const CStdString& strDrive, int& nAddedToPlaylist, bool bRoot, bool bypassSettings /* = false */, bool startFromBeginning /* = false */)
{
  bool bPlaying(false);
  CFileItemList vecItems;

  if ( !pDir->GetDirectory( strDrive, vecItems ) )
  {
    return false;
  }

  bool bAllowVideo = true;
//  bool bAllowPictures = true;
  bool bAllowMusic = true;
  if (!g_passwordManager.IsMasterLockUnlocked(false))
  {
    bAllowVideo = !g_settings.GetCurrentProfile().videoLocked();
//    bAllowPictures = !g_settings.GetCurrentProfile().picturesLocked();
    bAllowMusic = !g_settings.GetCurrentProfile().musicLocked();
  }

  // is this a root folder we have to check the content to determine a disc type
  if( bRoot )
  {
    // check root folders next, for normal structured dvd's
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr pItem = vecItems[i];

      // is the current item a (non system) folder?
      if (pItem->m_bIsFolder && pItem->GetPath() != "." && pItem->GetPath() != "..")
      {
        CStdString name = pItem->GetPath();
        URIUtils::RemoveSlashAtEnd(name);
        name = URIUtils::GetFileName(name);

        // Check if the current foldername indicates a DVD structure (name is "VIDEO_TS")
        if (name.Equals("VIDEO_TS") && bAllowVideo
        && (bypassSettings || g_guiSettings.GetBool("dvds.autorun")))
        {
          CStdString path = URIUtils::AddFileToFolder(pItem->GetPath(), "VIDEO_TS.IFO");
          if(!CFile::Exists(path))
            path = URIUtils::AddFileToFolder(pItem->GetPath(), "video_ts.ifo");
          CFileItem item(path, false);
          item.SetLabel(g_mediaManager.GetDiskLabel(strDrive));
          item.GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive);

          if (!startFromBeginning && !item.GetVideoInfoTag()->m_strFileNameAndPath.IsEmpty())
            item.m_lStartOffset = STARTOFFSET_RESUME;

          g_application.PlayFile(item, false);
          bPlaying = true;
          return true;
        }

        // Check if the current foldername indicates a Blu-Ray structure (default is "BDMV").
        // A BR should also include an "AACS" folder for encryption, Sony-BRs can also include update folders for PS3 (PS3_UPDATE / PS3_VPRM).
        // ToDo: for the time beeing, the DVD autorun settings are used to determine if the BR should be started automatically.
        if (name.Equals("BDMV") && bAllowVideo
        && (bypassSettings || g_guiSettings.GetBool("dvds.autorun")))
        {
          CFileItem item(URIUtils::AddFileToFolder(pItem->GetPath(), "index.bdmv"), false);
          item.SetLabel(g_mediaManager.GetDiskLabel(strDrive));
          item.GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive);

          if (!startFromBeginning && !item.GetVideoInfoTag()->m_strFileNameAndPath.IsEmpty())
            item.m_lStartOffset = STARTOFFSET_RESUME;

          g_application.PlayFile(item, false);
          bPlaying = true;
          return true;
        }

        // Video CDs can have multiple file formats. First we need to determine which one is used on the CD
        CStdString strExt;
        if (name.Equals("MPEGAV"))
          strExt = ".dat";
        if (name.Equals("MPEG2"))
          strExt = ".mpg";

        // If a file format was extracted we are sure this is a VCD. Autoplay if settings indicate we should.
        if (!strExt.IsEmpty() && bAllowVideo
             && (bypassSettings || g_guiSettings.GetBool("dvds.autorun")))
        {
          CFileItemList items;
          CDirectory::GetDirectory(pItem->GetPath(), items, strExt);
          if (items.Size())
          {
            items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC);
            g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
            g_playlistPlayer.Add(PLAYLIST_VIDEO, items);
            g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
            g_playlistPlayer.Play(0);
            bPlaying = true;
            return true;
          }
        }
        /* Probably want this if/when we add some automedia action dialog...
        else if (pItem->GetPath().Find("PICTURES") != -1 && bAllowPictures
              && (bypassSettings))
        {
          bPlaying = true;
          CStdString strExec;
          strExec.Format("XBMC.RecursiveSlideShow(%s)", pItem->GetPath().c_str());
          CBuiltins::Execute(strExec);
          return true;
        }
        */
      }
    }
  }

  // check video first
  if (!nAddedToPlaylist && !bPlaying && (bypassSettings || g_guiSettings.GetBool("dvds.autorun")))
  {
    // stack video files
    CFileItemList tempItems;
    tempItems.Append(vecItems);
    if (g_settings.m_videoStacking)
      tempItems.Stack();
    CFileItemList itemlist;

    for (int i = 0; i < tempItems.Size(); i++)
    {
      CFileItemPtr pItem = tempItems[i];
      if (!pItem->m_bIsFolder && pItem->IsVideo())
      {
        bPlaying = true;
        if (pItem->IsStack())
        {
          // TODO: remove this once the app/player is capable of handling stacks immediately
          CStackDirectory dir;
          CFileItemList items;
          dir.GetDirectory(pItem->GetPath(), items);
          itemlist.Append(items);
        }
        else
          itemlist.Add(pItem);
      }
    }
    if (itemlist.Size())
    {
      if (!bAllowVideo)
      {
        if (!bypassSettings)
          return false;

        if (g_windowManager.GetActiveWindow() != WINDOW_VIDEO_FILES)
          if (!g_passwordManager.IsMasterLockUnlocked(true))
            return false;
      }
      g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
      g_playlistPlayer.Add(PLAYLIST_VIDEO, itemlist);
      g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
      g_playlistPlayer.Play(0);
    }
  }
  // then music
  if (!bPlaying && (bypassSettings || g_guiSettings.GetBool("audiocds.autorun")) && bAllowMusic)
  {
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr pItem = vecItems[i];
      if (!pItem->m_bIsFolder && pItem->IsAudio())
      {
        nAddedToPlaylist++;
        g_playlistPlayer.Add(PLAYLIST_MUSIC, pItem);
      }
    }
  }
  /* Probably want this if/when we add some automedia action dialog...
  // and finally pictures
  if (!nAddedToPlaylist && !bPlaying && bypassSettings && bAllowPictures)
  {
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr pItem = vecItems[i];
      if (!pItem->m_bIsFolder && pItem->IsPicture())
      {
        bPlaying = true;
        CStdString strExec;
        strExec.Format("XBMC.RecursiveSlideShow(%s)", strDrive.c_str());
        CBuiltins::Execute(strExec);
        break;
      }
    }
  }
  */

  // check subdirs if we are not playing yet
  if (!bPlaying)
  {
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr  pItem = vecItems[i];
      if (pItem->m_bIsFolder)
      {
        if (pItem->GetPath() != "." && pItem->GetPath() != ".." )
        {
          if (RunDisc(pDir, pItem->GetPath(), nAddedToPlaylist, false, bypassSettings, startFromBeginning))
          {
            bPlaying = true;
            break;
          }
        }
      } // if (non system) folder
    } // for all items in directory
  } // if root folder

  return bPlaying;
}
Ejemplo n.º 28
0
bool CGUIDialogContextMenu::OnContextButton(const CStdString &type, const CFileItemPtr item, CONTEXT_BUTTON button)
{
  // Add Source doesn't require a valid share
  if (button == CONTEXT_BUTTON_ADD_SOURCE)
  {
    if (g_settings.IsMasterUser())
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;
    }
    else if (!g_settings.GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
      return false;

    return CGUIDialogMediaSource::ShowAndAddMediaSource(type);
  }

  // buttons that are available on both sources and autosourced items
  if (!item) return false;

  switch (button)
  {
  case CONTEXT_BUTTON_EJECT_DRIVE:
    return g_mediaManager.Eject(item->m_strPath);

#ifdef HAS_DVD_DRIVE
  case CONTEXT_BUTTON_PLAY_DISC:
    return MEDIA_DETECT::CAutorun::PlayDisc();

  case CONTEXT_BUTTON_EJECT_DISC:
#ifdef _WIN32
    CWIN32Util::ToggleTray(g_mediaManager.TranslateDevicePath(item->m_strPath)[0]);
#else
    CIoSupport::ToggleTray();
#endif
#endif
    return true;
  default:
    break;
  }

  // the rest of the operations require a valid share
  CMediaSource *share = GetShare(type, item.get());
  if (!share) return false;
  switch (button)
  {
  case CONTEXT_BUTTON_EDIT_SOURCE:
    if (g_settings.IsMasterUser())
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;
    }
    else if (!g_passwordManager.IsProfileLockUnlocked())
      return false;

    return CGUIDialogMediaSource::ShowAndEditMediaSource(type, *share);

  case CONTEXT_BUTTON_REMOVE_SOURCE:
  {
    if (g_settings.IsMasterUser())
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;
    }
    else
    {
      if (!g_settings.GetCurrentProfile().canWriteSources() && !g_passwordManager.IsMasterLockUnlocked(false))
        return false;
      if (g_settings.GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
        return false;
    }
    // prompt user if they want to really delete the source
    if (CGUIDialogYesNo::ShowAndGetInput(751, 0, 750, 0))
    { // check default before we delete, as deletion will kill the share object
      CStdString defaultSource(GetDefaultShareNameByType(type));
      if (!defaultSource.IsEmpty())
      {
        if (share->strName.Equals(defaultSource))
          ClearDefault(type);
      }
      g_settings.DeleteSource(type, share->strName, share->strPath);
    }
    return true;
  }
  case CONTEXT_BUTTON_SET_DEFAULT:
    if (g_settings.GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
      return false;
    else if (!g_passwordManager.IsMasterLockUnlocked(true))
      return false;

    // make share default
    SetDefault(type, share->strName);
    return true;

  case CONTEXT_BUTTON_CLEAR_DEFAULT:
    if (g_settings.GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
      return false;
    else if (!g_passwordManager.IsMasterLockUnlocked(true))
      return false;
    // remove share default
    ClearDefault(type);
    return true;

  case CONTEXT_BUTTON_SET_THUMB:
    {
      if (g_settings.GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
        return false;
      else if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      // setup our thumb list
      CFileItemList items;

      // add the current thumb, if available
      if (!share->m_strThumbnailImage.IsEmpty())
      {
        CFileItemPtr current(new CFileItem("thumb://Current", false));
        current->SetThumbnailImage(share->m_strThumbnailImage);
        current->SetLabel(g_localizeStrings.Get(20016));
        items.Add(current);
      }
      else if (item->HasThumbnail())
      { // already have a thumb that the share doesn't know about - must be a local one, so we mayaswell reuse it.
        CFileItemPtr current(new CFileItem("thumb://Current", false));
        current->SetThumbnailImage(item->GetThumbnailImage());
        current->SetLabel(g_localizeStrings.Get(20016));
        items.Add(current);
      }
      // see if there's a local thumb for this item
      CStdString folderThumb = item->GetFolderThumb();
      if (XFILE::CFile::Exists(folderThumb))
      {
        CFileItemPtr local(new CFileItem("thumb://Local", false));
        local->SetThumbnailImage(folderThumb);
        local->SetLabel(g_localizeStrings.Get(20017));
        items.Add(local);
      }
      // and add a "no thumb" entry as well
      CFileItemPtr nothumb(new CFileItem("thumb://None", false));
      nothumb->SetIconImage(item->GetIconImage());
      nothumb->SetLabel(g_localizeStrings.Get(20018));
      items.Add(nothumb);

      CStdString strThumb;
      VECSOURCES shares;
      g_mediaManager.GetLocalDrives(shares);
      if (!CGUIDialogFileBrowser::ShowAndGetImage(items, shares, g_localizeStrings.Get(1030), strThumb))
        return false;

      if (strThumb == "thumb://Current")
        return true;

      if (strThumb == "thumb://Local")
        strThumb = folderThumb;

      if (strThumb == "thumb://None")
        strThumb = "";

      if (!share->m_ignore)
      {
        g_settings.UpdateSource(type,share->strName,"thumbnail",strThumb);
        g_settings.SaveSources();
      }
      else if (!strThumb.IsEmpty())
      { // this is some sort of an auto-share, so we have to cache it based on the criteria we use to retrieve them
        CStdString cachedThumb;
        if (type == "music")
        {
          cachedThumb = item->m_strPath;
          URIUtils::RemoveSlashAtEnd(cachedThumb);
          cachedThumb = CUtil::GetCachedMusicThumb(cachedThumb);
        }
        else if (type == "video")
          cachedThumb = item->GetCachedVideoThumb();
        else  // assume "programs"
        { // store the thumb for this share
          CTextureDatabase db;
          if (db.Open())
          {
            cachedThumb = CTextureCache::GetUniqueImage(item->m_strPath, URIUtils::GetExtension(strThumb));
            db.SetTextureForPath(item->m_strPath, cachedThumb);
          }
        }
        XFILE::CFile::Cache(strThumb, cachedThumb);
      }

      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }

  case CONTEXT_BUTTON_ADD_LOCK:
    {
      // prompt user for mastercode when changing lock settings) only for default user
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      CStdString strNewPassword = "";
      if (!CGUIDialogLockSettings::ShowAndGetLock(share->m_iLockMode,strNewPassword))
        return false;
      // password entry and re-entry succeeded, write out the lock data
      share->m_iHasLock = 2;
      g_settings.UpdateSource(type, share->strName, "lockcode", strNewPassword);
      strNewPassword.Format("%i",share->m_iLockMode);
      g_settings.UpdateSource(type, share->strName, "lockmode", strNewPassword);
      g_settings.UpdateSource(type, share->strName, "badpwdcount", "0");
      g_settings.SaveSources();

      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }
  case CONTEXT_BUTTON_RESET_LOCK:
    {
      // prompt user for profile lock when changing lock settings
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      g_settings.UpdateSource(type, share->strName, "badpwdcount", "0");
      g_settings.SaveSources();
      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }
  case CONTEXT_BUTTON_REMOVE_LOCK:
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      if (!CGUIDialogYesNo::ShowAndGetInput(12335, 0, 750, 0))
        return false;

      share->m_iHasLock = 0;
      g_settings.UpdateSource(type, share->strName, "lockmode", "0");
      g_settings.UpdateSource(type, share->strName, "lockcode", "0");
      g_settings.UpdateSource(type, share->strName, "badpwdcount", "0");
      g_settings.SaveSources();
      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }
  case CONTEXT_BUTTON_REACTIVATE_LOCK:
    {
      bool maxRetryExceeded = false;
      if (g_guiSettings.GetInt("masterlock.maxretries") != 0)
        maxRetryExceeded = (share->m_iBadPwdCount >= g_guiSettings.GetInt("masterlock.maxretries"));
      if (!maxRetryExceeded)
      {
        // don't prompt user for mastercode when reactivating a lock
        g_passwordManager.LockSource(type, share->strName, true);
        return true;
      }
      return false;
    }
  case CONTEXT_BUTTON_CHANGE_LOCK:
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      CStdString strNewPW;
      CStdString strNewLockMode;
      if (CGUIDialogLockSettings::ShowAndGetLock(share->m_iLockMode,strNewPW))
        strNewLockMode.Format("%i",share->m_iLockMode);
      else
        return false;
      // password ReSet and re-entry succeeded, write out the lock data
      g_settings.UpdateSource(type, share->strName, "lockcode", strNewPW);
      g_settings.UpdateSource(type, share->strName, "lockmode", strNewLockMode);
      g_settings.UpdateSource(type, share->strName, "badpwdcount", "0");
      g_settings.SaveSources();
      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }
  default:
    break;
  }
  return false;
}
Ejemplo n.º 29
0
// NB: The rar manager expects paths in rars to be terminated with a "\".
bool CRarManager::GetFilesInRar(CFileItemList& vecpItems, const std::string& strRarPath,
                                bool bMask, const std::string& strPathInRar)
{
#ifdef HAS_FILESYSTEM_RAR
  CSingleLock lock(m_CritSection);

  ArchiveList_struct* pFileList = NULL;
  map<std::string,pair<ArchiveList_struct*,vector<CFileInfo> > >::iterator it = m_ExFiles.find(strRarPath);
  if (it == m_ExFiles.end())
  {
    if( urarlib_list((char*) strRarPath.c_str(), &pFileList, NULL) )
      m_ExFiles.insert(make_pair(strRarPath,make_pair(pFileList,vector<CFileInfo>())));
    else
    {
      if( pFileList ) urarlib_freelist(pFileList);
      return false;
    }
  }
  else
    pFileList = it->second.first;

  CFileItemPtr pFileItem;
  vector<std::string> vec;
  set<std::string> dirSet;
  StringUtils::Tokenize(strPathInRar,vec,"/");
  unsigned int iDepth = vec.size();

  ArchiveList_struct* pIterator;
  std::string strCompare = strPathInRar;
  if (!URIUtils::HasSlashAtEnd(strCompare) && !strCompare.empty())
    strCompare += '/';
  for( pIterator = pFileList; pIterator  ; pIterator ? pIterator = pIterator->next : NULL)
  {
    std::string strName;

    /* convert to utf8 */
    if( pIterator->item.NameW && wcslen(pIterator->item.NameW) > 0)
      g_charsetConverter.wToUTF8(pIterator->item.NameW, strName);
    else
      g_charsetConverter.unknownToUTF8(pIterator->item.Name, strName);

    /* replace back slashes into forward slashes */
    /* this could get us into troubles, file could two different files, one with / and one with \ */
    StringUtils::Replace(strName, '\\', '/');

    if (bMask)
    {
      if (!strstr(strName.c_str(),strCompare.c_str()))
        continue;

      vec.clear();
      StringUtils::Tokenize(strName,vec,"/");
      if (vec.size() < iDepth)
        continue;
    }

    unsigned int iMask = (pIterator->item.HostOS==3 ? 0x0040000:16); // win32 or unix attribs?
    if (((pIterator->item.FileAttr & iMask) == iMask) || (vec.size() > iDepth+1 && bMask)) // we have a directory
    {
      if (!bMask) continue;
      if (vec.size() == iDepth)
        continue; // remove root of listing

      if (dirSet.find(vec[iDepth]) == dirSet.end())
      {
        dirSet.insert(vec[iDepth]);
        pFileItem.reset(new CFileItem(vec[iDepth]));
        pFileItem->SetPath(vec[iDepth] + '/');
        pFileItem->m_bIsFolder = true;
        pFileItem->m_idepth = pIterator->item.Method;
        pFileItem->m_iDriveType = pIterator->item.HostOS;
        //pFileItem->m_lEndOffset = long(pIterator->item.iOffset);
      }
    }
    else
    {
      if (vec.size() == iDepth+1 || !bMask)
      {
        if (vec.size() == 0)
          pFileItem.reset(new CFileItem(strName));
        else
          pFileItem.reset(new CFileItem(vec[iDepth]));
        pFileItem->SetPath(strName.c_str()+strPathInRar.size());
        pFileItem->m_dwSize = pIterator->item.UnpSize;
        pFileItem->m_idepth = pIterator->item.Method;
        pFileItem->m_iDriveType = pIterator->item.HostOS;
        //pFileItem->m_lEndOffset = long(pIterator->item.iOffset);
      }
    }
    if (pFileItem)
      vecpItems.Add(pFileItem);

    pFileItem.reset();
  }
  return vecpItems.Size() > 0;
#else
  return false;
#endif
}
Ejemplo n.º 30
0
bool CZeroconfDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
  assert(strPath.substr(0, 11) == "zeroconf://");
  CStdString path = strPath.substr(11, strPath.length());
  URIUtils::RemoveSlashAtEnd(path);
  if(path.empty())
  {
    std::vector<CZeroconfBrowser::ZeroconfService> found_services = CZeroconfBrowser::GetInstance()->GetFoundServices();
    for(std::vector<CZeroconfBrowser::ZeroconfService>::iterator it = found_services.begin(); it != found_services.end(); ++it)
    {
      //only use discovered services we can connect to through directory
      CStdString tmp;
      if(GetXBMCProtocol(it->GetType(), tmp))
      {
        CFileItemPtr item(new CFileItem("", true));
        CURL url;
        url.SetProtocol("zeroconf");
        CStdString service_path = CZeroconfBrowser::ZeroconfService::toPath(*it);
        CURL::Encode(service_path);
        url.SetFileName(service_path);
        item->SetPath(url.Get());

        //now do the formatting
        CStdString protocol = GetHumanReadableProtocol(it->GetType());
        item->SetLabel(it->GetName() + " (" + protocol  + ")");
        item->SetLabelPreformated(true);
        //just set the default folder icon
        item->FillInDefaultIcon();
        items.Add(item);
      }
    }
    return true;
  } 
  else
  {
    //decode the path first
    CStdString decoded = path;
    CURL::Decode(decoded);
    try
    {
      CZeroconfBrowser::ZeroconfService zeroconf_service = CZeroconfBrowser::ZeroconfService::fromPath(decoded);

      if(!CZeroconfBrowser::GetInstance()->ResolveService(zeroconf_service))
      {
        CLog::Log(LOGINFO, "CZeroconfDirectory::GetDirectory service ( %s ) could not be resolved in time", zeroconf_service.GetName().c_str());
        return false;
      }
      else
      {
        assert(!zeroconf_service.GetIP().empty());
        CURL service;
        service.SetPort(zeroconf_service.GetPort());
        service.SetHostName(zeroconf_service.GetIP());
        //do protocol conversion (_smb._tcp -> smb)
        //ToDo: try automatic conversion -> remove leading '_' and '._tcp'?
        CStdString protocol;
        if(!GetXBMCProtocol(zeroconf_service.GetType(), protocol))
        {
          CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory Unknown service type (%s), skipping; ", zeroconf_service.GetType().c_str());
          return false;
        }
        
        service.SetProtocol(protocol);
        
        //first try to show the txt-record defined path if any
        if(GetDirectoryFromTxtRecords(zeroconf_service, service, items))
        {
          return true;
        }
        else//no txt record path - so let the CDirectory handler show the folders
        {          
          return CDirectory::GetDirectory(service.Get(), items, "", DIR_FLAG_ALLOW_PROMPT); 
        }
      }
    } catch (std::runtime_error& e) {
      CLog::Log(LOGERROR, "CZeroconfDirectory::GetDirectory failed getting directory: '%s'. Error: '%s'", decoded.c_str(), e.what());
      return false;
    }
  }
}