Ejemplo n.º 1
0
static void ParseItemVoddler(CFileItem* item, SResources& resources, TiXmlElement* element, const std::string& name, const std::string& xmlns, const std::string& path)
{
  CVideoInfoTag* vtag = item->GetVideoInfoTag();
  std::string text = GetValue(element);

  if(name == "trailer")
  {
    vtag->m_strTrailer = text;

    SResource res;
    res.tag  = "voddler:trailer";
    res.mime = XMLUtils::GetAttribute(element, "type");
    res.path = text;
    resources.push_back(res);
  }
  else if(name == "year")
    vtag->SetYear(atoi(text.c_str()));
  else if(name == "rating")
    vtag->SetRating((float)atof(text.c_str()));
  else if(name == "tagline")
    vtag->m_strTagLine = text;
  else if(name == "posterwall")
  {
    const char* url = element->Attribute("url");
    if(url)
      item->SetArt("fanart", url);
    else if(IsPathToThumbnail(text))
      item->SetArt("fanart", text);
  }
}
Ejemplo n.º 2
0
int CGUIWindowVideoNav::GetFirstUnwatchedItemIndex(bool includeAllSeasons, bool includeSpecials)
{
  int iIndex = 0;
  int iUnwatchedSeason = INT_MAX;

  // Run through the list of items and find the season number of the first season with unwatched episodes
  for (int i = 0; i < m_vecItems->Size(); ++i)
  {
    CFileItemPtr pItem = m_vecItems->Get(i);
    if (pItem->IsParentFolder() || !pItem->HasVideoInfoTag())
      continue;

    CVideoInfoTag *pTag = pItem->GetVideoInfoTag();

    if ((!includeAllSeasons && pTag->m_iSeason < 0) || (!includeSpecials && pTag->m_iSeason == 0))
      continue;

    // Is the season unwatched, and is its season number lower than the currently identified
    // first unwatched season
    if (pTag->GetPlayCount() == 0 && pTag->m_iSeason < iUnwatchedSeason)
    {
      iUnwatchedSeason = pTag->m_iSeason;
      iIndex = i;
    }
  }

  NODE_TYPE nodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_vecItems->GetPath());
  if (nodeType == NODE_TYPE::NODE_TYPE_EPISODES)
  {
    iIndex = 0;
    int iUnwatchedEpisode = INT_MAX;

    // Now run through the list of items and check episodes from the season identified above
    // to find the first (lowest episode number) unwatched episode.
    for (int i = 0; i < m_vecItems->Size(); ++i)
    {
      CFileItemPtr pItem = m_vecItems->Get(i);
      if (pItem->IsParentFolder() || !pItem->HasVideoInfoTag())
        continue;

      CVideoInfoTag *pTag = pItem->GetVideoInfoTag();

      // Does the episode belong to the unwatched season and Is the episode unwatched, and is its episode number 
      // lower than the currently identified first unwatched episode
      if (pTag->m_iSeason == iUnwatchedSeason && pTag->GetPlayCount() == 0 && pTag->m_iEpisode < iUnwatchedEpisode)
      {
        iUnwatchedEpisode = pTag->m_iEpisode;
        iIndex = i;
      }
    }
  }

  return iIndex;
}
Ejemplo n.º 3
0
JSONRPC_STATUS CVideoLibrary::SetEpisodeDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
    int id = (int)parameterObject["episodeid"].asInteger();

    CVideoDatabase videodatabase;
    if (!videodatabase.Open())
        return InternalError;

    CVideoInfoTag infos;
    videodatabase.GetEpisodeInfo("", infos, id);
    if (infos.m_iDbId <= 0)
    {
        videodatabase.Close();
        return InvalidParams;
    }

    int tvshowid = videodatabase.GetTvShowForEpisode(id);
    if (tvshowid <= 0)
    {
        videodatabase.Close();
        return InvalidParams;
    }

    // get artwork
    std::map<std::string, std::string> artwork;
    videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);

    int playcount = infos.GetPlayCount();
    CDateTime lastPlayed = infos.m_lastPlayed;

    std::set<std::string> removedArtwork;
    std::set<std::string> updatedDetails;
    UpdateVideoTag(parameterObject, infos, artwork, removedArtwork, updatedDetails);

    if (videodatabase.SetDetailsForEpisode(infos.m_strFileNameAndPath, infos, artwork, tvshowid, id) <= 0)
        return InternalError;

    if (!videodatabase.RemoveArtForItem(infos.m_iDbId, MediaTypeEpisode, removedArtwork))
        return InternalError;

    if (playcount != infos.GetPlayCount() || lastPlayed != infos.m_lastPlayed)
    {
        // restore original playcount or the new one won't be announced
        int newPlaycount = infos.GetPlayCount();
        infos.SetPlayCount(playcount);
        videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed);
    }

    UpdateResumePoint(parameterObject, infos, videodatabase);

    CJSONRPCUtils::NotifyItemUpdated();
    return ACK;
}
Ejemplo n.º 4
0
JSONRPC_STATUS CVideoLibrary::SetMusicVideoDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
    int id = (int)parameterObject["musicvideoid"].asInteger();

    CVideoDatabase videodatabase;
    if (!videodatabase.Open())
        return InternalError;

    CVideoInfoTag infos;
    videodatabase.GetMusicVideoInfo("", infos, id);
    if (infos.m_iDbId <= 0)
    {
        videodatabase.Close();
        return InvalidParams;
    }

    // get artwork
    std::map<std::string, std::string> artwork;
    videodatabase.GetArtForItem(infos.m_iDbId, infos.m_type, artwork);

    int playcount = infos.GetPlayCount();
    CDateTime lastPlayed = infos.m_lastPlayed;

    std::set<std::string> removedArtwork;
    std::set<std::string> updatedDetails;
    UpdateVideoTag(parameterObject, infos, artwork, removedArtwork, updatedDetails);

    // we need to manually remove tags/taglinks for now because they aren't replaced
    // due to scrapers not supporting them
    videodatabase.RemoveTagsFromItem(id, MediaTypeMusicVideo);

    if (videodatabase.SetDetailsForMusicVideo(infos.m_strFileNameAndPath, infos, artwork, id) <= 0)
        return InternalError;

    if (!videodatabase.RemoveArtForItem(infos.m_iDbId, MediaTypeMusicVideo, removedArtwork))
        return InternalError;

    if (playcount != infos.GetPlayCount()|| lastPlayed != infos.m_lastPlayed)
    {
        // restore original playcount or the new one won't be announced
        int newPlaycount = infos.GetPlayCount();
        infos.SetPlayCount(playcount);
        videodatabase.SetPlayCount(CFileItem(infos), newPlaycount, infos.m_lastPlayed);
    }

    UpdateResumePoint(parameterObject, infos, videodatabase);

    CJSONRPCUtils::NotifyItemUpdated();
    return ACK;
}
Ejemplo n.º 5
0
bool CIMDB::GetDetails(const CScraperUrl &url, CVideoInfoTag &movieDetails, CGUIDialogProgress *pProgress /* = NULL */)
{
  //CLog::Log(LOGDEBUG,"CIMDB::GetDetails(%s)", url.m_strURL.c_str());
  m_url = url;
  m_movieDetails = movieDetails;
  // load our scraper xml
  if (!m_parser.Load("special://xbmc/system/scrapers/video/"+m_info.strPath))
    return false;

  // fill in the defaults
  movieDetails.Reset();
  if (pProgress)
  { // threaded version
    m_state = GET_DETAILS;
    m_found = 0;
    if (ThreadHandle())
      StopThread();
    Create();
    while (!m_found)
    {
      pProgress->Progress();
      if (pProgress->IsCanceled())
      {
        CloseThread();
        return false;
      }
      Sleep(1);
    }
    movieDetails = m_movieDetails;
    CloseThread();
    return true;
  }
  else  // unthreaded
    return InternalGetDetails(url, movieDetails);
}
Ejemplo n.º 6
0
bool CIMDB::GetEpisodeDetails(const CScraperUrl &url, CVideoInfoTag &movieDetails, CGUIDialogProgress *pProgress /* = NULL */)
{
  //CLog::Log(LOGDEBUG,"CIMDB::GetDetails(%s)", url.m_strURL.c_str());
  m_url = url;
  m_movieDetails = movieDetails;

  // fill in the defaults
  movieDetails.Reset();
  if (pProgress)
  { // threaded version
    m_state = GET_EPISODE_DETAILS;
    m_found = 0;
    if (ThreadHandle())
      StopThread();
    Create();
    while (!m_found)
    {
      pProgress->Progress();
      if (pProgress->IsCanceled())
      {
        CloseThread();
        return false;
      }
      Sleep(1);
    }
    movieDetails = m_movieDetails;
    CloseThread();
    return true;
  }
  else  // unthreaded
    return InternalGetDetails(url, movieDetails, "GetEpisodeDetails");
}
Ejemplo n.º 7
0
bool CVideoInfoDownloader::GetEpisodeDetails(const CScraperUrl &url,
                                             CVideoInfoTag &movieDetails,
                                             CGUIDialogProgress *pProgress /* = NULL */)
{
  //CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails(%s)", url.m_strURL.c_str());
  m_url = url;
  m_movieDetails = movieDetails;

  // fill in the defaults
  movieDetails.Reset();
  if (pProgress)
  { // threaded version
    m_state = GET_EPISODE_DETAILS;
    m_found = 0;
    if (IsRunning())
      StopThread();
    Create();
    while (!m_found)
    {
      pProgress->Progress();
      if (pProgress->IsCanceled())
      {
        CloseThread();
        return false;
      }
      Sleep(1);
    }
    movieDetails = m_movieDetails;
    CloseThread();
    return true;
  }
  else  // unthreaded
    return m_info->GetVideoDetails(*m_http, url, false/*fMovie*/, movieDetails);
}
Ejemplo n.º 8
0
static void ParseItemZink(CFileItem* item, SResources& resources, TiXmlElement* element, const std::string& name, const std::string& xmlns, const std::string& path)
{
  CVideoInfoTag* vtag = item->GetVideoInfoTag();
  std::string text = GetValue(element);
  if     (name == "episode")
    vtag->m_iEpisode = atoi(text.c_str());
  else if(name == "season")
    vtag->m_iSeason = atoi(text.c_str());
  else if(name == "views")
    vtag->m_playCount = atoi(text.c_str());
  else if(name == "airdate")
    vtag->m_firstAired.SetFromDateString(text);
  else if(name == "userrating")
    vtag->SetRating((float)atof(text.c_str()));
  else if(name == "duration")
    vtag->m_duration = atoi(text.c_str());
  else if(name == "durationstr")
    vtag->m_duration = StringUtils::TimeStringToSeconds(text);
}
Ejemplo n.º 9
0
bool CIMDB::LoadXML(const CStdString& strXMLFile, CVideoInfoTag &movieDetails, bool bDownload /* = true */)
{
  TiXmlDocument doc;

  movieDetails.Reset();
  if (doc.LoadFile(strXMLFile) && ParseDetails(doc, movieDetails))
  { // excellent!
    return true;
  }
  if (!bDownload)
    return true;

  return false;
}
Ejemplo n.º 10
0
static void ParseItemItunes(CFileItem* item, SResources& resources, TiXmlElement* item_child, const std::string& name, const std::string& xmlns, const std::string& path)
{
  CVideoInfoTag* vtag = item->GetVideoInfoTag();
  std::string text = GetValue(item_child);

  if(name == "image")
  {
    const char * url = item_child->Attribute("href");
    if(url)
      item->SetArt("thumb", url);
    else
      item->SetArt("thumb", text);
  }
  else if(name == "summary")
    vtag->m_strPlot = text;
  else if(name == "subtitle")
    vtag->m_strPlotOutline = text;
  else if(name == "author")
    vtag->m_writingCredits.push_back(text);
  else if(name == "duration")
    vtag->SetDuration(StringUtils::TimeStringToSeconds(text));
  else if(name == "keywords")
    item->SetProperty("keywords", text);
}
Ejemplo n.º 11
0
static void ParseItemBoxee(CFileItem* item, SResources& resources, TiXmlElement* element, const std::string& name, const std::string& xmlns, const std::string& path)
{
  CVideoInfoTag* vtag = item->GetVideoInfoTag();
  std::string text = GetValue(element);

  if     (name == "image")
    item->SetArt("thumb", text);
  else if(name == "user_agent")
    item->SetProperty("boxee:user_agent", text);
  else if(name == "content_type")
    item->SetMimeType(text);
  else if(name == "runtime")
    vtag->SetDuration(StringUtils::TimeStringToSeconds(text));
  else if(name == "episode")
    vtag->m_iEpisode = atoi(text.c_str());
  else if(name == "season")
    vtag->m_iSeason = atoi(text.c_str());
  else if(name == "view-count")
    vtag->SetPlayCount(atoi(text.c_str()));
  else if(name == "tv-show-title")
    vtag->m_strShowTitle = text;
  else if(name == "release-date")
    item->SetProperty("boxee:releasedate", text);
}
Ejemplo n.º 12
0
bool CVideoLibrary::FillFileItemList(const CVariant &parameterObject, CFileItemList &list)
{
  CVideoDatabase videodatabase;
  if (videodatabase.Open())
  {
    CStdString file = parameterObject["file"].asString();
    int movieID = (int)parameterObject["movieid"].asInteger(-1);
    int episodeID = (int)parameterObject["episodeid"].asInteger(-1);
    int musicVideoID = (int)parameterObject["musicvideoid"].asInteger(-1);

    bool success = false;
    CFileItem fileItem;
    if (FillFileItem(file, fileItem))
    {
      success = true;
      list.Add(CFileItemPtr(new CFileItem(fileItem)));
    }

    if (movieID > 0)
    {
      CVideoInfoTag details;
      videodatabase.GetMovieInfo("", details, movieID);
      if (!details.IsEmpty())
      {
        list.Add(CFileItemPtr(new CFileItem(details)));
        success = true;
      }
    }
    if (episodeID > 0)
    {
      CVideoInfoTag details;
      if (videodatabase.GetEpisodeInfo("", details, episodeID) && !details.IsEmpty())
      {
        list.Add(CFileItemPtr(new CFileItem(details)));
        success = true;
      }
    }
    if (musicVideoID > 0)
    {
      CVideoInfoTag details;
      videodatabase.GetMusicVideoInfo("", details, musicVideoID);
      if (!details.IsEmpty())
      {
        list.Add(CFileItemPtr(new CFileItem(details)));
        success = true;
      }
    }

    videodatabase.Close();
    return success;
  }

  return false;
}
Ejemplo n.º 13
0
bool CIMDB::ParseDetails(TiXmlDocument &doc, CVideoInfoTag &movieDetails)
{
  TiXmlHandle docHandle( &doc );
  TiXmlElement *details = docHandle.FirstChild( "details" ).Element();

  if (!details)
  {
    CLog::Log(LOGERROR, "%s: Invalid xml file",__FUNCTION__);
    return false;
  }

  // set chaining to true here as this is called by our scrapers
  movieDetails.Load(details, true);
  
  CHTMLUtil::RemoveTags(movieDetails.m_strPlot);

  return true;
}
Ejemplo n.º 14
0
bool CVideoLibrary::FillFileItemList(const Value &parameterObject, CFileItemList &list)
{
  CVideoDatabase videodatabase;
  if ((parameterObject["movieid"].isInt() || parameterObject["episodeid"].isInt() || parameterObject["musicvideoid"].isInt()) && videodatabase.Open())
  {
    int movieID       = ParameterAsInt(parameterObject, -1, "movieid");
    int episodeID     = ParameterAsInt(parameterObject, -1, "episodeid");
    int musicVideoID  = ParameterAsInt(parameterObject, -1, "musicvideoid");

    bool success = true;
    if (movieID > 0)
    {
      CVideoInfoTag details;
      videodatabase.GetMovieInfo("", details, movieID);
      if (!details.IsEmpty())
      {
        CFileItemPtr item = CFileItemPtr(new CFileItem(details));
        list.Add(item);
        success &= true;
      }
      success = false;
    }
    if (episodeID > 0)
    {
      CVideoInfoTag details;
      if (videodatabase.GetEpisodeInfo("", details, episodeID) && !details.IsEmpty())
      {
        CFileItemPtr item = CFileItemPtr(new CFileItem(details));
        list.Add(item);
        success &= true;
      }
      success = false;
    }
    if (musicVideoID > 0)
    {
      CVideoInfoTag details;
      videodatabase.GetMusicVideoInfo("", details, musicVideoID);
      if (!details.IsEmpty())
      {
        CFileItemPtr item = CFileItemPtr(new CFileItem(details));
        list.Add(item);
        success &= true;
      }
      success = false;
    }

    videodatabase.Close();
    return success;
  }

  return false;
}
Ejemplo n.º 15
0
static void ParseItem(CFileItem* item, TiXmlElement* root, const std::string& path)
{
  SResources resources;
  ParseItem(item, resources, root, path);

  const char* prio[] = { "media:content", "voddler:trailer", "rss:enclosure", "svtplay:broadcasts", "svtplay:xmllink", "rss:link", "rss:guid", NULL };

  std::string mime;
  if     (FindMime(resources, "video/"))
    mime = "video/";
  else if(FindMime(resources, "audio/"))
    mime = "audio/";
  else if(FindMime(resources, "application/rss"))
    mime = "application/rss";
  else if(FindMime(resources, "image/"))
    mime = "image/";

  int maxrate = CSettings::Get().GetInt(CSettings::SETTING_NETWORK_BANDWIDTH);
  if(maxrate == 0)
    maxrate = INT_MAX;

  SResources::iterator best = resources.end();
  for(const char** type = prio; *type && best == resources.end(); type++)
  {
    for(SResources::iterator it = resources.begin(); it != resources.end(); it++)
    {
      if(!StringUtils::StartsWith(it->mime, mime))
        continue;

      if(it->tag == *type)
      {
        if(best == resources.end())
        {
          best = it;
          continue;
        }

        if(it->bitrate == best->bitrate)
        {
          if(it->width*it->height > best->width*best->height)
            best = it;
          continue;
        }

        if(it->bitrate > maxrate)
        {
          if(it->bitrate < best->bitrate)
            best = it;
          continue;
        }

        if(it->bitrate > best->bitrate)
        {
          best = it;
          continue;
        }
      }
    }
  }

  if(best != resources.end())
  {
    item->SetMimeType(best->mime);
    item->SetPath(best->path);
    item->m_dwSize  = best->size;

    if(best->duration)
      item->SetProperty("duration", StringUtils::SecondsToTimeString(best->duration));    

    /* handling of mimetypes fo directories are sub optimal at best */
    if(best->mime == "application/rss+xml" && StringUtils::StartsWithNoCase(item->GetPath(), "http://"))
      item->SetPath("rss://" + item->GetPath().substr(7));

    if(StringUtils::StartsWithNoCase(item->GetPath(), "rss://"))
      item->m_bIsFolder = true;
    else
      item->m_bIsFolder = false;
  }

  if(!item->m_strTitle.empty())
    item->SetLabel(item->m_strTitle);

  if(item->HasVideoInfoTag())
  {
    CVideoInfoTag* vtag = item->GetVideoInfoTag();

    if(item->HasProperty("duration")    && !vtag->GetDuration())
      vtag->m_duration = StringUtils::TimeStringToSeconds(item->GetProperty("duration").asString());

    if(item->HasProperty("description") && vtag->m_strPlot.empty())
      vtag->m_strPlot = item->GetProperty("description").asString();

    if(vtag->m_strPlotOutline.empty() && !vtag->m_strPlot.empty())
    {
      size_t pos = vtag->m_strPlot.find('\n');
      if(pos != std::string::npos)
        vtag->m_strPlotOutline = vtag->m_strPlot.substr(0, pos);
      else
        vtag->m_strPlotOutline = vtag->m_strPlot;
    }

    if(!vtag->GetDuration())
      item->SetLabel2(StringUtils::SecondsToTimeString(vtag->GetDuration()));
  }
}
Ejemplo n.º 16
0
CNfoFile::NFOResult CNfoFile::Create(const CStdString& strPath, const ScraperPtr& info, int episode, const CStdString& strPath2)
{
  m_info = info; // assume we can use these settings
  m_type = ScraperTypeFromContent(info->Content());
  if (FAILED(Load(strPath)))
    return NO_NFO;

  CFileItemList items;
  bool bNfo=false;

  AddonPtr addon;
  ScraperPtr defaultScraper;
  if (!CAddonMgr::Get().GetDefault(m_type, addon))
    return NO_NFO;
  else
    defaultScraper = boost::dynamic_pointer_cast<CScraper>(addon);

  if (m_type == ADDON_SCRAPER_ALBUMS)
  {
    CAlbum album;
    bNfo = GetDetails(album);
  }
  else if (m_type == ADDON_SCRAPER_ARTISTS)
  {
    CArtist artist;
    bNfo = GetDetails(artist);
  }
  else if (m_type == ADDON_SCRAPER_TVSHOWS || m_type == ADDON_SCRAPER_MOVIES || m_type == ADDON_SCRAPER_MUSICVIDEOS)
  {
    // first check if it's an XML file with the info we need
    CVideoInfoTag details;
    bNfo = GetDetails(details);
    if (episode > -1 && bNfo && m_type == ADDON_SCRAPER_TVSHOWS)
    {
      int infos=0;
      while (m_headofdoc && details.m_iEpisode != episode)
      {
        m_headofdoc = strstr(m_headofdoc+1,"<episodedetails>");
        bNfo  = GetDetails(details);
        infos++;
      }
      if (details.m_iEpisode != episode)
      {
        bNfo = false;
        details.Reset();
        m_headofdoc = m_doc;
        if (infos == 1) // still allow differing nfo/file numbers for single ep nfo's
          bNfo = GetDetails(details);
      }
    }
  }

  vector<ScraperPtr> vecScrapers;

  // add selected scraper
  if (m_info)
    vecScrapers.push_back(m_info);

  VECADDONS addons;
  CAddonMgr::Get().GetAddons(m_type,addons);
  // first pass - add language based scrapers
  if (m_info && g_guiSettings.GetBool("scrapers.langfallback"))
    AddScrapers(addons,vecScrapers);

  // add default scraper
  if ((m_info && m_info->ID() != defaultScraper->ID()) || !m_info)
    vecScrapers.push_back(defaultScraper);

  // search ..
  int res = -1;
  for (unsigned int i=0;i<vecScrapers.size();++i)
    if ((res = Scrape(vecScrapers[i])) == 0 || res == 2)
      break;

  if (res == 2)
    return ERROR_NFO;
  if (bNfo)
    return (m_strImDbUrl.size() > 0) ? COMBINED_NFO:FULL_NFO;

  return   (m_strImDbUrl.size() > 0) ? URL_NFO : NO_NFO;
}
Ejemplo n.º 17
0
static void ParseItem(CFileItem* item, TiXmlElement* root, const CStdString& path)
{
  SResources resources;
  ParseItem(item, resources, root, path);

  const char* prio[] = { "media:content", "voddler:trailer", "rss:enclosure", "svtplay:broadcasts", "svtplay:xmllink", "rss:link", "rss:guid", NULL };

  CStdString mime;
  if     (FindMime(resources, "video/"))
    mime = "video/";
  else if(FindMime(resources, "audio/"))
    mime = "audio/";
  else if(FindMime(resources, "application/rss"))
    mime = "application/rss";
  else if(FindMime(resources, "image/"))
    mime = "image/";

  int maxrate = g_guiSettings.GetInt("network.bandwidth");
  if(maxrate == 0)
    maxrate = INT_MAX;

  SResources::iterator best = resources.end();
  for(const char** type = prio; *type && best == resources.end(); type++)
  {
    for(SResources::iterator it = resources.begin(); it != resources.end(); it++)
    {
      if(it->mime.Left(mime.length()) != mime)
        continue;

      if(it->tag == *type)
      {
        if(best == resources.end())
        {
          best = it;
          continue;
        }

        if(it->bitrate == best->bitrate)
        {
          if(it->width*it->height > best->width*best->height)
            best = it;
          continue;
        }

        if(it->bitrate > maxrate)
        {
          if(it->bitrate < best->bitrate)
            best = it;
          continue;
        }

        if(it->bitrate > best->bitrate)
        {
          best = it;
          continue;
        }
      }
    }
  }

  if(best != resources.end())
  {
    item->SetMimeType(best->mime);
    item->SetPath(best->path);
    item->m_dwSize  = best->size;

    if(best->duration)
      item->SetProperty("duration", StringUtils::SecondsToTimeString(best->duration));    

    /* handling of mimetypes fo directories are sub optimal at best */
    if(best->mime == "application/rss+xml" && item->GetPath().Left(7).Equals("http://"))
      item->SetPath("rss://" + item->GetPath().Mid(7));

    if(item->GetPath().Left(6).Equals("rss://"))
      item->m_bIsFolder = true;
    else
      item->m_bIsFolder = false;
  }

  if(!item->m_strTitle.IsEmpty())
    item->SetLabel(item->m_strTitle);

  if(item->HasVideoInfoTag())
  {
    CVideoInfoTag* vtag = item->GetVideoInfoTag();

    if(item->HasProperty("duration")    && !vtag->GetDuration())
      vtag->m_duration = StringUtils::TimeStringToSeconds(item->GetProperty("duration").asString());

    if(item->HasProperty("description") && vtag->m_strPlot.IsEmpty())
      vtag->m_strPlot = item->GetProperty("description").asString();

    if(vtag->m_strPlotOutline.IsEmpty() && !vtag->m_strPlot.IsEmpty())
    {
      int pos = vtag->m_strPlot.Find('\n');
      if(pos >= 0)
        vtag->m_strPlotOutline = vtag->m_strPlot.Left(pos);
      else
        vtag->m_strPlotOutline = vtag->m_strPlot;
    }

    if(!vtag->GetDuration())
      item->SetLabel2(StringUtils::SecondsToTimeString(vtag->GetDuration()));
  }
}
Ejemplo n.º 18
0
CNfoFile::NFOResult CNfoFile::Create(const CStdString& strPath, const ScraperPtr& info, int episode, const CStdString& strPath2)
{
  m_info = info; // assume we can use these settings
  m_type = ScraperTypeFromContent(info->Content());
  if (FAILED(Load(strPath)))
    return NO_NFO;

  CFileItemList items;
  bool bNfo=false;

  AddonPtr addon;
  ScraperPtr defaultScraper;
  if (CAddonMgr::Get().GetDefault(m_type, addon))
    defaultScraper = boost::dynamic_pointer_cast<CScraper>(addon);

  if (m_type == ADDON_SCRAPER_ALBUMS)
  {
    CAlbum album;
    bNfo = GetDetails(album);
  }
  else if (m_type == ADDON_SCRAPER_ARTISTS)
  {
    CArtist artist;
    bNfo = GetDetails(artist);
  }
  else if (m_type == ADDON_SCRAPER_TVSHOWS || m_type == ADDON_SCRAPER_MOVIES || m_type == ADDON_SCRAPER_MUSICVIDEOS)
  {
    // first check if it's an XML file with the info we need
    CVideoInfoTag details;
    bNfo = GetDetails(details);
    if (episode > -1 && bNfo && m_type == ADDON_SCRAPER_TVSHOWS)
    {
      int infos=0;
      while (m_headofdoc && details.m_iEpisode != episode)
      {
        m_headofdoc = strstr(m_headofdoc+1,"<episodedetails");
        bNfo  = GetDetails(details);
        infos++;
      }
      if (details.m_iEpisode != episode)
      {
        bNfo = false;
        details.Reset();
        m_headofdoc = m_doc;
        if (infos == 1) // still allow differing nfo/file numbers for single ep nfo's
          bNfo = GetDetails(details);
      }
    }
  }

  vector<ScraperPtr> vecScrapers;

  // add selected scraper - first proirity
  if (m_info)
    vecScrapers.push_back(m_info);

  // Add all scrapers except selected and default
  VECADDONS addons;
  CAddonMgr::Get().GetAddons(m_type,addons);

  for (unsigned i = 0; i < addons.size(); ++i)
  {
    ScraperPtr scraper = boost::dynamic_pointer_cast<CScraper>(addons[i]);

    // skip if scraper requires settings and there's nothing set yet
    if (scraper->RequiresSettings() && !scraper->HasUserSettings())
      continue;

    if( (!m_info || m_info->ID() != scraper->ID()) && (!defaultScraper || defaultScraper->ID() != scraper->ID()) )
      vecScrapers.push_back(scraper);
  }

  // add default scraper - not user selectable so it's last priority
  if( defaultScraper && (!m_info || m_info->ID() != defaultScraper->ID()) &&
      ( !defaultScraper->RequiresSettings() || defaultScraper->HasUserSettings() ) )
    vecScrapers.push_back(defaultScraper);

  // search ..
  int res = -1;
  for (unsigned int i=0;i<vecScrapers.size();++i)
    if ((res = Scrape(vecScrapers[i])) == 0 || res == 2)
      break;

  if (res == 2)
    return ERROR_NFO;
  if (bNfo)
    return m_scurl.m_url.empty() ? FULL_NFO : COMBINED_NFO;
  return m_scurl.m_url.empty() ? NO_NFO : URL_NFO;
}
Ejemplo n.º 19
0
bool CThumbExtractor::DoWork()
{
  if (m_item.IsLiveTV()
  // Due to a pvr addon api design flaw (no support for multiple concurrent streams
  // per addon instance), pvr recording thumbnail extraction does not work (reliably).
  ||  URIUtils::IsPVRRecording(m_item.GetDynPath())
  ||  URIUtils::IsUPnP(m_item.GetPath())
  ||  URIUtils::IsBluray(m_item.GetPath())
  ||  m_item.IsBDFile()
  ||  m_item.IsDVD()
  ||  m_item.IsDiscImage()
  ||  m_item.IsDVDFile(false, true)
  ||  m_item.IsInternetStream()
  ||  m_item.IsDiscStub()
  ||  m_item.IsPlayList())
    return false;

  // For HTTP/FTP we only allow extraction when on a LAN
  if (URIUtils::IsRemote(m_item.GetPath()) &&
     !URIUtils::IsOnLAN(m_item.GetPath())  &&
     (URIUtils::IsFTP(m_item.GetPath())    ||
      URIUtils::IsHTTP(m_item.GetPath())))
    return false;

  bool result=false;
  if (m_thumb)
  {
    CLog::Log(LOGDEBUG,"%s - trying to extract thumb from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str());
    // construct the thumb cache file
    CTextureDetails details;
    details.file = CTextureCache::GetCacheFile(m_target) + ".jpg";
    result = CDVDFileInfo::ExtractThumb(m_item, details, m_fillStreamDetails ? &m_item.GetVideoInfoTag()->m_streamDetails : nullptr, m_pos);
    if(result)
    {
      CTextureCache::GetInstance().AddCachedTexture(m_target, details);
      m_item.SetProperty("HasAutoThumb", true);
      m_item.SetProperty("AutoThumbImage", m_target);
      m_item.SetArt("thumb", m_target);

      CVideoInfoTag* info = m_item.GetVideoInfoTag();
      if (info->m_iDbId > 0 && !info->m_type.empty())
      {
        CVideoDatabase db;
        if (db.Open())
        {
          db.SetArtForItem(info->m_iDbId, info->m_type, "thumb", m_item.GetArt("thumb"));
          db.Close();
        }
      }
    }
  }
  else if (!m_item.IsPlugin() &&
           (!m_item.HasVideoInfoTag() ||
           !m_item.GetVideoInfoTag()->HasStreamDetails()))
  {
    // No tag or no details set, so extract them
    CLog::Log(LOGDEBUG,"%s - trying to extract filestream details from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str());
    result = CDVDFileInfo::GetFileStreamDetails(&m_item);
  }

  if (result)
  {
    CVideoInfoTag* info = m_item.GetVideoInfoTag();
    CVideoDatabase db;
    if (db.Open())
    {
      if (URIUtils::IsStack(m_listpath))
      {
        // Don't know the total time of the stack, so set duration to zero to avoid confusion
        info->m_streamDetails.SetVideoDuration(0, 0);

        // Restore original stack path
        m_item.SetPath(m_listpath);
      }

      if (info->m_iFileId < 0)
        db.SetStreamDetailsForFile(info->m_streamDetails, !info->m_strFileNameAndPath.empty() ? info->m_strFileNameAndPath : m_item.GetPath());
      else
        db.SetStreamDetailsForFileId(info->m_streamDetails, info->m_iFileId);

      // overwrite the runtime value if the one from streamdetails is available
      if (info->m_iDbId > 0
          && info->GetStaticDuration() != info->GetDuration())
      {
        info->SetDuration(info->GetDuration());

        // store the updated information in the database
        db.SetDetailsForItem(info->m_iDbId, info->m_type, *info, m_item.GetArt());
      }

      db.Close();
    }
    return true;
  }

  return false;
}
Ejemplo n.º 20
0
static void ParseItemMRSS(CFileItem* item, SResources& resources, TiXmlElement* item_child, const std::string& name, const std::string& xmlns, const std::string& path)
{
  CVideoInfoTag* vtag = item->GetVideoInfoTag();
  std::string text = GetValue(item_child);

  if(name == "content")
  {
    SResource res;
    res.tag = "media:content";
    res.mime    = XMLUtils::GetAttribute(item_child, "type");
    res.path    = XMLUtils::GetAttribute(item_child, "url");
    item_child->Attribute("width", &res.width);
    item_child->Attribute("height", &res.height);
    item_child->Attribute("bitrate", &res.bitrate);
    item_child->Attribute("duration", &res.duration);
    if(item_child->Attribute("fileSize"))
      res.size     = _atoi64(item_child->Attribute("fileSize"));

    resources.push_back(res);
    ParseItem(item, resources, item_child, path);
  }
  else if(name == "group")
  {
    ParseItem(item, resources, item_child, path);
  }
  else if(name == "thumbnail")
  {
    if(!item_child->NoChildren() && IsPathToThumbnail(item_child->FirstChild()->ValueStr()))
      item->SetArt("thumb", item_child->FirstChild()->ValueStr());
    else
    {
      const char * url = item_child->Attribute("url");
      if(url && IsPathToThumbnail(url))
        item->SetArt("thumb", url);
    }
  }
  else if (name == "title")
  {
    if(text.empty())
      return;

    if(text.length() > item->m_strTitle.length())
      item->m_strTitle = text;
  }
  else if(name == "description")
  {
    if(text.empty())
      return;

    std::string description = text;
    if(XMLUtils::GetAttribute(item_child, "type") == "html")
      HTML::CHTMLUtil::RemoveTags(description);
    item->SetProperty("description", description);
  }
  else if(name == "category")
  {
    if(text.empty())
      return;

    std::string scheme = XMLUtils::GetAttribute(item_child, "scheme");

    /* okey this is silly, boxee what did you think?? */
    if     (scheme == "urn:boxee:genre")
      vtag->m_genre.push_back(text);
    else if(scheme == "urn:boxee:title-type")
    {
      if     (text == "tv")
        item->SetProperty("boxee:istvshow", true);
      else if(text == "movie")
        item->SetProperty("boxee:ismovie", true);
    }
    else if(scheme == "urn:boxee:episode")
      vtag->m_iEpisode = atoi(text.c_str());
    else if(scheme == "urn:boxee:season")
      vtag->m_iSeason  = atoi(text.c_str());
    else if(scheme == "urn:boxee:show-title")
      vtag->m_strShowTitle = text.c_str();
    else if(scheme == "urn:boxee:view-count")
      vtag->m_playCount = atoi(text.c_str());
    else if(scheme == "urn:boxee:source")
      item->SetProperty("boxee:provider_source", text);
    else
      vtag->m_genre = StringUtils::Split(text, g_advancedSettings.m_videoItemSeparator);
  }
  else if(name == "rating")
  {
    std::string scheme = XMLUtils::GetAttribute(item_child, "scheme");
    if(scheme == "urn:user")
      vtag->SetRating((float)atof(text.c_str()));
    else
      vtag->m_strMPAARating = text;
  }
  else if(name == "credit")
  {
    std::string role = XMLUtils::GetAttribute(item_child, "role");
    if     (role == "director")
      vtag->m_director.push_back(text);
    else if(role == "author"
         || role == "writer")
      vtag->m_writingCredits.push_back(text);
    else if(role == "actor")
    {
      SActorInfo actor;
      actor.strName = text;
      vtag->m_cast.push_back(actor);
    }
  }
  else if(name == "copyright")
    vtag->m_studio = StringUtils::Split(text, g_advancedSettings.m_videoItemSeparator);
  else if(name == "keywords")
    item->SetProperty("keywords", text);

}
Ejemplo n.º 21
0
void CVideoLibrary::UpdateVideoTag(const CVariant &parameterObject, CVideoInfoTag& details, std::map<std::string, std::string> &artwork, std::set<std::string> &removedArtwork, std::set<std::string> &updatedDetails)
{
  if (ParameterNotNull(parameterObject, "title"))
    details.SetTitle(parameterObject["title"].asString());
  if (ParameterNotNull(parameterObject, "playcount"))
    details.m_playCount = (int)parameterObject["playcount"].asInteger();
  if (ParameterNotNull(parameterObject, "runtime"))
    details.m_duration = (int)parameterObject["runtime"].asInteger();

  std::vector<std::string> director(details.m_director);
  UpdateVideoTagField(parameterObject, "director", director, updatedDetails);
  details.SetDirector(director);

  std::vector<std::string> studio(details.m_studio);
  UpdateVideoTagField(parameterObject, "studio", studio, updatedDetails);
  details.SetStudio(studio);

  if (ParameterNotNull(parameterObject, "year"))
    details.m_iYear = (int)parameterObject["year"].asInteger();
  if (ParameterNotNull(parameterObject, "plot"))
    details.SetPlot(parameterObject["plot"].asString());
  if (ParameterNotNull(parameterObject, "album"))
    details.SetAlbum(parameterObject["album"].asString());

  std::vector<std::string> artist(details.m_artist);
  UpdateVideoTagField(parameterObject, "artist", artist, updatedDetails);
  details.SetArtist(artist);

  std::vector<std::string> genre(details.m_genre);
  UpdateVideoTagField(parameterObject, "genre", genre, updatedDetails);
  details.SetGenre(genre);

  if (ParameterNotNull(parameterObject, "track"))
    details.m_iTrack = (int)parameterObject["track"].asInteger();
  if (ParameterNotNull(parameterObject, "rating"))
  {
    details.SetRating(parameterObject["rating"].asFloat());
    updatedDetails.insert("ratings");
  }
  if (ParameterNotNull(parameterObject, "votes"))
  {
    details.SetVotes(StringUtils::ReturnDigits(parameterObject["votes"].asString()));
    updatedDetails.insert("ratings"); //Votes and ratings both need updates now, this will trigger those
  }
  if (ParameterNotNull(parameterObject, "ratings"))
  {
    CVariant ratings = parameterObject["ratings"];
    for (CVariant::const_iterator_map rIt = ratings.begin_map(); rIt != ratings.end_map(); rIt++)
    {
      if (rIt->second.isArray() && ParameterNotNull(rIt->second, "name") && ParameterNotNull(rIt->second, "rating"))
      {
        details.SetRating(rIt->second["rating"].asFloat(), rIt->second["name"].asString());
        if (ParameterNotNull(rIt->second, "votes"))
          details.SetVotes(StringUtils::ReturnDigits(parameterObject["votes"].asString()), rIt->second["name"].asString());
      }
    }
    updatedDetails.insert("ratings");
  }
  if (ParameterNotNull(parameterObject, "userrating"))
    details.m_iUserRating = parameterObject["userrating"].asInteger();
  if (ParameterNotNull(parameterObject, "mpaa"))
    details.SetMPAARating(parameterObject["mpaa"].asString());
  if (ParameterNotNull(parameterObject, "imdbnumber"))
    details.SetIMDBNumber(parameterObject["imdbnumber"].asString());
  if (ParameterNotNull(parameterObject, "premiered"))
    SetFromDBDate(parameterObject["premiered"], details.m_premiered);
  if (ParameterNotNull(parameterObject, "lastplayed"))
    SetFromDBDateTime(parameterObject["lastplayed"], details.m_lastPlayed);
  if (ParameterNotNull(parameterObject, "firstaired"))
    SetFromDBDate(parameterObject["firstaired"], details.m_firstAired);
  if (ParameterNotNull(parameterObject, "productioncode"))
    details.SetProductionCode(parameterObject["productioncode"].asString());
  if (ParameterNotNull(parameterObject, "season"))
    details.m_iSeason = (int)parameterObject["season"].asInteger();
  if (ParameterNotNull(parameterObject, "episode"))
    details.m_iEpisode = (int)parameterObject["episode"].asInteger();
  if (ParameterNotNull(parameterObject, "originaltitle"))
    details.SetOriginalTitle(parameterObject["originaltitle"].asString());
  if (ParameterNotNull(parameterObject, "trailer"))
    details.SetTrailer(parameterObject["trailer"].asString());
  if (ParameterNotNull(parameterObject, "tagline"))
    details.SetTagLine(parameterObject["tagline"].asString());
  if (ParameterNotNull(parameterObject, "plotoutline"))
    details.SetPlotOutline(parameterObject["plotoutline"].asString());

  std::vector<std::string> credits(details.m_writingCredits);
  UpdateVideoTagField(parameterObject, "writer", credits, updatedDetails);
  details.SetWritingCredits(credits);

  std::vector<std::string> country(details.m_country);
  UpdateVideoTagField(parameterObject, "country", country, updatedDetails);
  details.SetCountry(country);

  if (ParameterNotNull(parameterObject, "top250"))
    details.m_iTop250 = (int)parameterObject["top250"].asInteger();
  if (ParameterNotNull(parameterObject, "sorttitle"))
    details.SetSortTitle(parameterObject["sorttitle"].asString());
  if (ParameterNotNull(parameterObject, "episodeguide"))
    details.SetEpisodeGuide(parameterObject["episodeguide"].asString());
  if (ParameterNotNull(parameterObject, "set"))
  {
    details.SetSet(parameterObject["set"].asString());
    updatedDetails.insert("set");
  }

  std::vector<std::string> showLink(details.m_showLink);
  UpdateVideoTagField(parameterObject, "showlink", showLink, updatedDetails);
  details.SetShowLink(showLink);

  std::vector<std::string> tags(details.m_tags);
  UpdateVideoTagField(parameterObject, "tag", tags, updatedDetails);
  details.SetTags(tags);

  if (ParameterNotNull(parameterObject, "thumbnail"))
  {
    std::string value = parameterObject["thumbnail"].asString();
    artwork["thumb"] = StringUtils::Trim(value);
    updatedDetails.insert("art.altered");
  }
  if (ParameterNotNull(parameterObject, "fanart"))
  {
    std::string value = parameterObject["fanart"].asString();
    artwork["fanart"] = StringUtils::Trim(value);
    updatedDetails.insert("art.altered");
  }

  if (ParameterNotNull(parameterObject, "art"))
  {
    CVariant art = parameterObject["art"];
    for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++)
    {
      if (artIt->second.isString() && !artIt->second.asString().empty())
      {
        artwork[artIt->first] = CTextureUtils::UnwrapImageURL(artIt->second.asString());
        updatedDetails.insert("art.altered");
      }
      else if (artIt->second.isNull())
      {
        artwork.erase(artIt->first);
        removedArtwork.insert(artIt->first);
      }
    }
  }
}
Ejemplo n.º 22
0
bool CThumbExtractor::DoWork()
{
  if (m_item.IsLiveTV()
  ||  URIUtils::IsUPnP(m_item.GetPath())
  ||  m_item.IsDAAP()
  ||  m_item.IsDVD()
  ||  m_item.IsDiscImage()
  ||  m_item.IsDVDFile(false, true)
  ||  m_item.IsInternetStream()
  ||  m_item.IsDiscStub()
  ||  m_item.IsPlayList())
    return false;

  if (URIUtils::IsRemote(m_item.GetPath()) && !URIUtils::IsOnLAN(m_item.GetPath()))
  {
    // A quasi internet filesystem like webdav is generally fast enough for extracting stuff
    if (!URIUtils::IsDAV(m_item.GetPath()))
      return false;
  }

  bool result=false;
  if (m_thumb)
  {
    CLog::Log(LOGDEBUG,"%s - trying to extract thumb from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str());
    // construct the thumb cache file
    CTextureDetails details;
    details.file = CTextureCache::GetCacheFile(m_target) + ".jpg";
    result = CDVDFileInfo::ExtractThumb(m_item.GetPath(), details, &m_item.GetVideoInfoTag()->m_streamDetails);
    if(result)
    {
      CTextureCache::Get().AddCachedTexture(m_target, details);
      m_item.SetProperty("HasAutoThumb", true);
      m_item.SetProperty("AutoThumbImage", m_target);
      m_item.SetArt("thumb", m_target);

      CVideoInfoTag* info = m_item.GetVideoInfoTag();
      if (info->m_iDbId > 0 && !info->m_type.empty())
      {
        CVideoDatabase db;
        if (db.Open())
        {
          db.SetArtForItem(info->m_iDbId, info->m_type, "thumb", m_item.GetArt("thumb"));
          db.Close();
        }
      }
    }
  }
  else if (!m_item.HasVideoInfoTag() || !m_item.GetVideoInfoTag()->HasStreamDetails())
  {
    // No tag or no details set, so extract them
    CLog::Log(LOGDEBUG,"%s - trying to extract filestream details from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str());
    result = CDVDFileInfo::GetFileStreamDetails(&m_item);
  }

  if (result)
  {
    CVideoInfoTag* info = m_item.GetVideoInfoTag();
    CVideoDatabase db;
    if (db.Open())
    {
      if (URIUtils::IsStack(m_listpath))
      {
        // Don't know the total time of the stack, so set duration to zero to avoid confusion
        info->m_streamDetails.SetVideoDuration(0, 0);

        // Restore original stack path
        m_item.SetPath(m_listpath);
      }

      if (info->m_iFileId < 0)
        db.SetStreamDetailsForFile(info->m_streamDetails, !info->m_strFileNameAndPath.empty() ? info->m_strFileNameAndPath : static_cast<const std::string&>(m_item.GetPath()));
      else
        db.SetStreamDetailsForFileId(info->m_streamDetails, info->m_iFileId);

      // overwrite the runtime value if the one from streamdetails is available
      if (info->m_iDbId > 0 && info->m_duration != info->GetDuration())
      {
        info->m_duration = info->GetDuration();

        // store the updated information in the database
        db.SetDetailsForItem(info->m_iDbId, info->m_type, *info, m_item.GetArt());
      }

      db.Close();
    }
    return true;
  }

  return false;
}