Get every episode from a Season (1 Viewer)

FreakyJ

Development Group
  • Team MediaPortal
  • July 25, 2010
    4,023
    1,420
    Germany Germany
    Country flag
    • Thread starter
    • Moderator
    • #1
    @morpheus_xx
    I need your help again :( I am working on a MAS implementation for MP2 adn for http://wiki.team-mediaportal.com/1_...opers/API_Documentation/MAS#GetTVEpisodeCount
    I need to get all episodes from a season.

    If I take a look into the DB -> M_MEDIAITEM I can see a Mediaitem for the Series, each Season and each episode.
    But there are two questions:
    1) How are they linked together?
    2) The Title for the season is lokalized -> I could use String.Split(' ') and convert the number to an int and than selecting all Items where the SeriesAspect -> Season is equal to that number.

    But this feels like a really dirty hack to me. Any suggestions?

    Looking at the client Side SeriesFilterBySeasonScreenData.cs I found this:
    Code:
    // subViewSpecification contains "Series S01" pattern, here we only want to show the season number.
          string season = subViewSpecification.ViewDisplayName ?? string.Empty;
          season = season.Substring(season.LastIndexOf("S") + 1);
          return LocalizationHelper.Translate(_navbarSubViewNavigationDisplayLabel, season);
    I guess this is pretty much option 2
     

    morpheus_xx

    Lead Dev MP2
  • Team MediaPortal
  • March 24, 2007
    11,391
    6,966
    Germany Germany
    Country flag
    You have to create a media library query: load all episodes for given series name, than count the distinct episode numbers of the given season.

    Your quoted code is a workaround, because we don't have Series / Season aspects as own objects right now, but only depend on querying distinct items attributes. So if you go for an implementation now, you will need to change it again after MIA rework.

    If you plan to implement it, I can prepare some example code for ML query, but this takes some time.
     

    FreakyJ

    Development Group
  • Team MediaPortal
  • July 25, 2010
    4,023
    1,420
    Germany Germany
    Country flag
    • Thread starter
    • Moderator
    • #3
    Thanks for the fast reply, I think I will than go with the work around for now, the reason is that I have to report an ID for a Season/Series.
    So if somebody wants to get All episodes for a season I only have the Season ID and therefore only the title (e.g. "Staffel 01").

    I can prepare some example code for ML query
    Do you mean something like this:
    Code:
    internal static IList<MediaItem> GetMediaItemsByString(string name, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, MediaItemAspectMetadata.AttributeSpecification attributeSpecification,  uint limit)
        {
          IFilter searchFilter = new RelationalFilter(attributeSpecification, RelationalOperator.EQ, name);
          MediaItemQuery searchQuery = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, searchFilter) { Limit = limit };
    
          return ServiceRegistration.Get<IMediaLibrary>().Search(searchQuery, false);
        }
    I think I can manager this than :)
     

    FreakyJ

    Development Group
  • Team MediaPortal
  • July 25, 2010
    4,023
    1,420
    Germany Germany
    Country flag
    • Thread starter
    • Moderator
    • #5
    In case anybody should ever have the same problem :)

    Code:
    HttpParam httpParam = request.Param;
          if (httpParam["id"].Value == null)
            throw new BadRequestException("GetMediaItem: no id is null");
    
          ISet<Guid> necessaryMIATypes = new HashSet<Guid>();
          necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
    
          // this is the MediaItem from the Season
          MediaItem item = GetMediaItems.GetMediaItemById(httpParam["id"].Value, necessaryMIATypes);
    
          if (item == null)
            throw new BadRequestException(String.Format("GetTVEpisodeCountForSeason: No MediaItem found with id: {0}", httpParam["id"].Value));
    
          int seasonNumer;
          try
          {
            seasonNumer = Convert.ToInt32(((string)item[MediaAspect.ASPECT_ID][MediaAspect.ATTR_TITLE]).Split(' ')[1]);
          }
          catch (Exception ex)
          {
            throw new BadRequestException(String.Format("GetTVEpisodeCountForSeason: Couldn't convert Title to int: {0}", ex.Message));
          }
    
          // Get all episodes for this season
          ISet<Guid> necessaryMIATypesEpisodes = new HashSet<Guid>();
          necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
          necessaryMIATypes.Add(SeriesAspect.ASPECT_ID);
    
          IList<MediaItem> episodes = GetMediaItems.GetMediaItemsByInt(seasonNumer, necessaryMIATypesEpisodes, null, SeriesAspect.ATTR_SEASON, null);
    
          WebIntResult webIntResult = new WebIntResult { Result = episodes.Count };
    
          return webIntResult;
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using MediaPortal.Backend.MediaLibrary;
    using MediaPortal.Common;
    using MediaPortal.Common.MediaManagement;
    using MediaPortal.Common.MediaManagement.DefaultItemAspects;
    using MediaPortal.Common.MediaManagement.MLQueries;
    
    namespace MediaPortal.Plugins.MP2Extended.ResourceAccess
    {
      internal class GetMediaItems
      {
        #region ById
    
        internal static MediaItem GetMediaItemById(string id, ISet<Guid> necessaryMIATypes)
        {
          return GetMediaItemById(id, necessaryMIATypes, null);
        }
       
        internal static MediaItem GetMediaItemById(string id, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes)
        {
          return GetMediaItemById(Guid.Parse(id), necessaryMIATypes, optionalMIATypes);
        }
    
        internal static MediaItem GetMediaItemById(Guid id, ISet<Guid> necessaryMIATypes)
        {
          return GetMediaItemById(id, necessaryMIATypes, null);
        }
    
        internal static MediaItem GetMediaItemById(Guid id, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes)
        {
          IList<MediaItem> items = GetMediaItemsById(id, necessaryMIATypes, optionalMIATypes, 1);
          if (items.Count != 0)
            return items[0];
          return null;
        }
    
        internal static IList<MediaItem> GetMediaItemsById(string id, ISet<Guid> necessaryMIATypes, uint limit)
        {
          return GetMediaItemsById(id, necessaryMIATypes, null, limit);
        }
    
        internal static IList<MediaItem> GetMediaItemsById(string id, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, uint limit)
        {
          return GetMediaItemsById(Guid.Parse(id), necessaryMIATypes, optionalMIATypes, limit);
        }
    
        internal static IList<MediaItem> GetMediaItemsById(Guid id, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, uint limit)
        {
          IFilter searchFilter = new MediaItemIdFilter(id);
          MediaItemQuery searchQuery = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, searchFilter) { Limit = limit };
    
          return ServiceRegistration.Get<IMediaLibrary>().Search(searchQuery, false);
        }
    
        #endregion ByID
    
        #region ByName
    
        internal static MediaItem GetMediaItemByName(string name, ISet<Guid> necessaryMIATypes)
        {
          return GetMediaItemByName(name, necessaryMIATypes, null);
        }
    
    
        /// <summary>
        /// Filters by MediaAspect.ATTR_TITLE
        /// </summary>
        /// <param name="name"></param>
        /// <param name="necessaryMIATypes">Must contain MediaAspect</param>
        /// <param name="optionalMIATypes"></param>
        /// <returns></returns>
        internal static MediaItem GetMediaItemByName(string name, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes)
        {
          IList<MediaItem> items = GetMediaItemsByName(name, necessaryMIATypes, optionalMIATypes, 1);
          if (items.Count != 0)
            return items[0];
          return null;
        }
    
        internal static IList<MediaItem> GetMediaItemsByName(string name, ISet<Guid> necessaryMIATypes, uint limit)
        {
          if (necessaryMIATypes == null)
          {
            necessaryMIATypes = new HashSet<Guid> { MediaAspect.ASPECT_ID };
          }
    
          return GetMediaItemsByName(name, necessaryMIATypes, null, limit);
        }
    
        /// <summary>
        /// Filters by MediaAspect.ATTR_TITLE
        /// </summary>
        /// <param name="name"></param>
        /// <param name="necessaryMIATypes">Must contain MediaAspect</param>
        /// <param name="optionalMIATypes"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        internal static IList<MediaItem> GetMediaItemsByName(string name, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, uint? limit)
        {
          return GetMediaItemsByString(name, necessaryMIATypes, optionalMIATypes, MediaAspect.ATTR_TITLE, limit);
        }
    
        internal static IList<MediaItem> GetMediaItemsByString(string name, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, MediaItemAspectMetadata.AttributeSpecification attributeSpecification,  uint? limit)
        {
          IFilter searchFilter = new RelationalFilter(attributeSpecification, RelationalOperator.EQ, name);
          MediaItemQuery searchQuery = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, searchFilter) { Limit = limit };
    
          return ServiceRegistration.Get<IMediaLibrary>().Search(searchQuery, false);
        }
    
        internal static IList<MediaItem> GetMediaItemsByInt(int number, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, MediaItemAspectMetadata.AttributeSpecification attributeSpecification, uint? limit)
        {
          IFilter searchFilter = new RelationalFilter(attributeSpecification, RelationalOperator.EQ, number);
          MediaItemQuery searchQuery = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, searchFilter) { Limit = limit };
    
          return ServiceRegistration.Get<IMediaLibrary>().Search(searchQuery, false);
        }
    
        #endregion ByName
      }
    }
     

    morpheus_xx

    Lead Dev MP2
  • Team MediaPortal
  • March 24, 2007
    11,391
    6,966
    Germany Germany
    Country flag
    Some remarks:
    if (httpParam["id"].Value == null)
    1) --> please introduce a variable for it, it will be accessed twice

    seasonNumer = Convert.ToInt32(((string)item[MediaAspect.ASPECT_ID][MediaAspect.ATTR_TITLE]).Split(' ')[1]);
    2) why do you parse the season from Title? There is the SeriesAspect.Season attribute you can use directly.

    3) Please reduce them number of methods, i.e.:
    internal static MediaItem GetMediaItemById(string id, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes)
    --> if you expect to query always by MediaItem Id, then the Guid version is enough. Parsing (TryParse) the Guid should then be done in step 1)
     

    FreakyJ

    Development Group
  • Team MediaPortal
  • July 25, 2010
    4,023
    1,420
    Germany Germany
    Country flag
    • Thread starter
    • Moderator
    • #7
    1) --> please introduce a variable for it, it will be accessed twice
    I can agree with this :)

    2) why do you parse the season from Title? There is the SeriesAspect.Season attribute you can use directly.
    If you take a look here: http://wiki.team-mediaportal.com/1_...s/MPExtended/Developers/API_Documentation/MAS
    The API has a Id's for seasons and Shows. MP2 doesn't really (yet). So if one requests all episodes for a season, I get the id for the Season item in M_MEDIAITEM.
    Now there is no link to the episodes, that's why I have to pars the name and than take the season number to get the episodes.

    And I think I just found a bug :/ Because it will return all episodes corresponding to a season number and not a special season.

    So I need to create my own ID:
    1) {seariesName:confused:eason} -> base64
    2) {GUID-Seasies:GUID-Season}

    I think I will go with option two. I meant more DB requests, but I think it will have less errors, because GUIDs don't contain ":", names could.

    if you expect to query always by MediaItem Id, then the Guid version is enough. Parsing (TryParse) the Guid should then be done in step 1)
    Actually I use both. I called it MicroModules. and every Api part (e.g. GetTVEpisodeCountForTVShow ) has it's own micro module. And a lot of these use id's. That's why I put the GUID parsing in it's own function, but sometimes I also get the GUID from MP directly. I hope that makes sense :)

    I use your method :)

    Code:
    {"GetMediaItem", new GetMediaItem()},
          { "TestConnection", new TestConnection()},
          // TvShow
          { "GetTVEpisodeBasicById", new GetTVEpisodeBasicById()},
          { "GetTVEpisodeCountForSeason", new GetTVEpisodeCountForSeason()},
          { "GetTVEpisodeCountForTVShow", new GetTVEpisodeCountForTVShow()},
          { "GetTVEpisodeDetailedById", new GetTVEpisodeDetailedById()},
          { "GetTVEpisodesBasic", new GetTVEpisodesBasic()}
    It is like a Switch: I registered a HTTP module for MPExtened this module routes the request to the submodules: MAS, SAS, ?? depending on the second part of the URL, e.g. "MediaAccessService".
    This module than sends the request depending on the last part of the url to one of the micromodules, it get's an answer (dynamic), parsis it with json and sends it to the client :)
     

    Users Who Are Viewing This Thread (Users: 0, Guests: 1)

    OP Similar threads Forum Replies Date
    R Pixellation on live TV every few seconds General Support 11
    BlueMax1916 [confirm] Music: Every 2nd track skipped MediaPortal 2 30
    Requiem HTPC waking up every night General 0
    K MP2 - V2.1 [MP2-763] Interface configuration for RTSP streaming server lost on every restart Older releases 6
    T Mediaportal scheduling recording every show on every channel General Support 4
    G Q about scheduling weekly series when epg lists duplicate back to back episodes each week General Support 2
    cladinshadows85 [solved] TV Recordings episode field blank General 20
    P TV recording not displaying episode titles or going into series General 10
    G MP 1.21 TVserver race condition when cant delete recording triggered by episode management General Support 0
    A cursor.wav or click.wav set in keyboard and keys cause recordings to be set in upcoming episodes 1.20 2
    A "upcoming episodes" arrow key set recording - Ok/rtn doesn't work General Support 9
    R TV Guide No Episode Info Displayed Electronic Program Guide 5
    Alberto83 [no Bug] Watched status not retained when rewatching an episode and stopping. Archive 49
    A Filenaming Season and Episode Numbers not working General Support 1
    B Episodes to Keep and Priority for Schedules in MP2 General 0
    U Parsing invalid episode names My TVSeries 10
    ajs LMH need help! Help plz ... How select episodes in Online Rating sort order My TVSeries 21
    W [solved] [FIXED] Survivor season 40 not automatically matching My TVSeries 1
    Top Bottom