Get every episode from a Season

Discussion in 'Plugin Development' started by FreakyJ, October 2, 2015.

  1. FreakyJ
    • Team MediaPortal

    FreakyJ Development Group

    Joined:
    July 25, 2010
    Messages:
    4,021
    Likes Received:
    839
    Gender:
    Male
    Ratings:
    +1,424 / 1
    Home Country:
    Germany Germany
    @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 (C):
    1. // subViewSpecification contains "Series S01" pattern, here we only want to show the season number.
    2.       string season = subViewSpecification.ViewDisplayName ?? string.Empty;
    3.       season = season.Substring(season.LastIndexOf("S") + 1);
    4.       return LocalizationHelper.Translate(_navbarSubViewNavigationDisplayLabel, season);
    I guess this is pretty much option 2
     
  2. Google AdSense Guest Advertisement



    to hide all adverts.
  3. morpheus_xx
    • Team MediaPortal

    morpheus_xx Lead Dev MP2

    Joined:
    March 24, 2007
    Messages:
    10,918
    Likes Received:
    4,704
    Ratings:
    +6,742 / 11
    Home Country:
    Germany Germany
    Show System Specs
    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.
     
    • Thank You! Thank You! x 1
  4. FreakyJ
    • Team MediaPortal

    FreakyJ Development Group

    Joined:
    July 25, 2010
    Messages:
    4,021
    Likes Received:
    839
    Gender:
    Male
    Ratings:
    +1,424 / 1
    Home Country:
    Germany Germany
    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").

    Do you mean something like this:
    Code (C):
    1. internal static IList<MediaItem> GetMediaItemsByString(string name, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, MediaItemAspectMetadata.AttributeSpecification attributeSpecification,  uint limit)
    2.     {
    3.       IFilter searchFilter = new RelationalFilter(attributeSpecification, RelationalOperator.EQ, name);
    4.       MediaItemQuery searchQuery = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, searchFilter) { Limit = limit };
    5.  
    6.       return ServiceRegistration.Get<IMediaLibrary>().Search(searchQuery, false);
    7.     }
    I think I can manager this than :)
     
  5. morpheus_xx
    • Team MediaPortal

    morpheus_xx Lead Dev MP2

    Joined:
    March 24, 2007
    Messages:
    10,918
    Likes Received:
    4,704
    Ratings:
    +6,742 / 11
    Home Country:
    Germany Germany
    Show System Specs
    Yes, this should do it. Use the EQ filter for Series name and load all items. Not sure if there exists a "GetCount" method somewhere?
     
    • Thank You! Thank You! x 1
  6. FreakyJ
    • Team MediaPortal

    FreakyJ Development Group

    Joined:
    July 25, 2010
    Messages:
    4,021
    Likes Received:
    839
    Gender:
    Male
    Ratings:
    +1,424 / 1
    Home Country:
    Germany Germany
    In case anybody should ever have the same problem :)

    Code (C):
    1. HttpParam httpParam = request.Param;
    2.       if (httpParam["id"].Value == null)
    3.         throw new BadRequestException("GetMediaItem: no id is null");
    4.  
    5.       ISet<Guid> necessaryMIATypes = new HashSet<Guid>();
    6.       necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
    7.  
    8.       // this is the MediaItem from the Season
    9.       MediaItem item = GetMediaItems.GetMediaItemById(httpParam["id"].Value, necessaryMIATypes);
    10.  
    11.       if (item == null)
    12.         throw new BadRequestException(String.Format("GetTVEpisodeCountForSeason: No MediaItem found with id: {0}", httpParam["id"].Value));
    13.  
    14.       int seasonNumer;
    15.       try
    16.       {
    17.         seasonNumer = Convert.ToInt32(((string)item[MediaAspect.ASPECT_ID][MediaAspect.ATTR_TITLE]).Split(' ')[1]);
    18.       }
    19.       catch (Exception ex)
    20.       {
    21.         throw new BadRequestException(String.Format("GetTVEpisodeCountForSeason: Couldn't convert Title to int: {0}", ex.Message));
    22.       }
    23.  
    24.       // Get all episodes for this season
    25.       ISet<Guid> necessaryMIATypesEpisodes = new HashSet<Guid>();
    26.       necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
    27.       necessaryMIATypes.Add(SeriesAspect.ASPECT_ID);
    28.  
    29.       IList<MediaItem> episodes = GetMediaItems.GetMediaItemsByInt(seasonNumer, necessaryMIATypesEpisodes, null, SeriesAspect.ATTR_SEASON, null);
    30.  
    31.       WebIntResult webIntResult = new WebIntResult { Result = episodes.Count };
    32.  
    33.       return webIntResult;
    Code (C):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using MediaPortal.Backend.MediaLibrary;
    7. using MediaPortal.Common;
    8. using MediaPortal.Common.MediaManagement;
    9. using MediaPortal.Common.MediaManagement.DefaultItemAspects;
    10. using MediaPortal.Common.MediaManagement.MLQueries;
    11.  
    12. namespace MediaPortal.Plugins.MP2Extended.ResourceAccess
    13. {
    14.   internal class GetMediaItems
    15.   {
    16.     #region ById
    17.  
    18.     internal static MediaItem GetMediaItemById(string id, ISet<Guid> necessaryMIATypes)
    19.     {
    20.       return GetMediaItemById(id, necessaryMIATypes, null);
    21.     }
    22.    
    23.     internal static MediaItem GetMediaItemById(string id, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes)
    24.     {
    25.       return GetMediaItemById(Guid.Parse(id), necessaryMIATypes, optionalMIATypes);
    26.     }
    27.  
    28.     internal static MediaItem GetMediaItemById(Guid id, ISet<Guid> necessaryMIATypes)
    29.     {
    30.       return GetMediaItemById(id, necessaryMIATypes, null);
    31.     }
    32.  
    33.     internal static MediaItem GetMediaItemById(Guid id, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes)
    34.     {
    35.       IList<MediaItem> items = GetMediaItemsById(id, necessaryMIATypes, optionalMIATypes, 1);
    36.       if (items.Count != 0)
    37.         return items[0];
    38.       return null;
    39.     }
    40.  
    41.     internal static IList<MediaItem> GetMediaItemsById(string id, ISet<Guid> necessaryMIATypes, uint limit)
    42.     {
    43.       return GetMediaItemsById(id, necessaryMIATypes, null, limit);
    44.     }
    45.  
    46.     internal static IList<MediaItem> GetMediaItemsById(string id, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, uint limit)
    47.     {
    48.       return GetMediaItemsById(Guid.Parse(id), necessaryMIATypes, optionalMIATypes, limit);
    49.     }
    50.  
    51.     internal static IList<MediaItem> GetMediaItemsById(Guid id, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, uint limit)
    52.     {
    53.       IFilter searchFilter = new MediaItemIdFilter(id);
    54.       MediaItemQuery searchQuery = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, searchFilter) { Limit = limit };
    55.  
    56.       return ServiceRegistration.Get<IMediaLibrary>().Search(searchQuery, false);
    57.     }
    58.  
    59.     #endregion ByID
    60.  
    61.     #region ByName
    62.  
    63.     internal static MediaItem GetMediaItemByName(string name, ISet<Guid> necessaryMIATypes)
    64.     {
    65.       return GetMediaItemByName(name, necessaryMIATypes, null);
    66.     }
    67.  
    68.  
    69.     /// <summary>
    70.     /// Filters by MediaAspect.ATTR_TITLE
    71.     /// </summary>
    72.     /// <param name="name"></param>
    73.     /// <param name="necessaryMIATypes">Must contain MediaAspect</param>
    74.     /// <param name="optionalMIATypes"></param>
    75.     /// <returns></returns>
    76.     internal static MediaItem GetMediaItemByName(string name, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes)
    77.     {
    78.       IList<MediaItem> items = GetMediaItemsByName(name, necessaryMIATypes, optionalMIATypes, 1);
    79.       if (items.Count != 0)
    80.         return items[0];
    81.       return null;
    82.     }
    83.  
    84.     internal static IList<MediaItem> GetMediaItemsByName(string name, ISet<Guid> necessaryMIATypes, uint limit)
    85.     {
    86.       if (necessaryMIATypes == null)
    87.       {
    88.         necessaryMIATypes = new HashSet<Guid> { MediaAspect.ASPECT_ID };
    89.       }
    90.  
    91.       return GetMediaItemsByName(name, necessaryMIATypes, null, limit);
    92.     }
    93.  
    94.     /// <summary>
    95.     /// Filters by MediaAspect.ATTR_TITLE
    96.     /// </summary>
    97.     /// <param name="name"></param>
    98.     /// <param name="necessaryMIATypes">Must contain MediaAspect</param>
    99.     /// <param name="optionalMIATypes"></param>
    100.     /// <param name="limit"></param>
    101.     /// <returns></returns>
    102.     internal static IList<MediaItem> GetMediaItemsByName(string name, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, uint? limit)
    103.     {
    104.       return GetMediaItemsByString(name, necessaryMIATypes, optionalMIATypes, MediaAspect.ATTR_TITLE, limit);
    105.     }
    106.  
    107.     internal static IList<MediaItem> GetMediaItemsByString(string name, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, MediaItemAspectMetadata.AttributeSpecification attributeSpecification,  uint? limit)
    108.     {
    109.       IFilter searchFilter = new RelationalFilter(attributeSpecification, RelationalOperator.EQ, name);
    110.       MediaItemQuery searchQuery = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, searchFilter) { Limit = limit };
    111.  
    112.       return ServiceRegistration.Get<IMediaLibrary>().Search(searchQuery, false);
    113.     }
    114.  
    115.     internal static IList<MediaItem> GetMediaItemsByInt(int number, ISet<Guid> necessaryMIATypes, ISet<Guid> optionalMIATypes, MediaItemAspectMetadata.AttributeSpecification attributeSpecification, uint? limit)
    116.     {
    117.       IFilter searchFilter = new RelationalFilter(attributeSpecification, RelationalOperator.EQ, number);
    118.       MediaItemQuery searchQuery = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, searchFilter) { Limit = limit };
    119.  
    120.       return ServiceRegistration.Get<IMediaLibrary>().Search(searchQuery, false);
    121.     }
    122.  
    123.     #endregion ByName
    124.   }
    125. }
    126.  
     
  7. morpheus_xx
    • Team MediaPortal

    morpheus_xx Lead Dev MP2

    Joined:
    March 24, 2007
    Messages:
    10,918
    Likes Received:
    4,704
    Ratings:
    +6,742 / 11
    Home Country:
    Germany Germany
    Show System Specs
    Some remarks:
    1) --> please introduce a variable for it, it will be accessed twice

    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)
     
  8. FreakyJ
    • Team MediaPortal

    FreakyJ Development Group

    Joined:
    July 25, 2010
    Messages:
    4,021
    Likes Received:
    839
    Gender:
    Male
    Ratings:
    +1,424 / 1
    Home Country:
    Germany Germany
    I can agree with this :)

    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.

    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 (C):
    1. {"GetMediaItem", new GetMediaItem()},
    2.       { "TestConnection", new TestConnection()},
    3.       // TvShow
    4.       { "GetTVEpisodeBasicById", new GetTVEpisodeBasicById()},
    5.       { "GetTVEpisodeCountForSeason", new GetTVEpisodeCountForSeason()},
    6.       { "GetTVEpisodeCountForTVShow", new GetTVEpisodeCountForTVShow()},
    7.       { "GetTVEpisodeDetailedById", new GetTVEpisodeDetailedById()},
    8.       { "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 :)
     
Loading...

Users Viewing Thread (Users: 0, Guests: 0)

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice
  • About The Project

    The vision of the MediaPortal project is to create a free open source media centre application, which supports all advanced media centre functions, and is accessible to all Windows users.

    In reaching this goal we are working every day to make sure our software is one of the best.

             

  • Support MediaPortal!

    The team works very hard to make sure the community is running the best HTPC-software. We give away MediaPortal for free but hosting and software is not for us.

    Care to support our work with a few bucks? We'd really appreciate it!