Plugin: MP2Extended (3 Viewers)

FreakyJ

Retired Team Member
  • Premium Supporter
  • July 25, 2010
    4,024
    1,420
    Home Country
    Germany Germany
    Very nice! So are you done with merging? Take your time. Just push or let me know where the latest branch is once you are done :)

    I also started to implement a debug access service which for now only provides the implemented api functions as a html page. Basically inbuilt documentation generated on the fly from the src :)
     

    MrTechno

    Retired Team Member
  • Premium Supporter
  • February 27, 2011
    1,256
    511
    London
    Home Country
    United Kingdom United Kingdom
    I've done the solution files and most of the project files. Still have the source conflicts inside DLNA and MPExtended to go (already fixed the slimtv stuff)
     

    FreakyJ

    Retired Team Member
  • Premium Supporter
  • July 25, 2010
    4,024
    1,420
    Home Country
    Germany Germany
    @Developers
    As written above I am working on an inbuilt documentation. I tried to get as much as possible from the src directly, but for the function parameters I need to use Attributes, at least this is the way I've choosen and would like to know your opinion on that.

    Here is an example:

    namespace MediaPortal.Plugins.MP2Extended.ResourceAccess.MAS.FileSystem
    {
    internal class GetFileSystemDrives : BaseDriveBasic, IRequestMicroModuleHandler
    {
    [ApiFunctionDescription(Type = ApiFunctionDescription.FunctionType.Json, Summary = "")]

    [ApiFunctionParam(Name = "sort", Type = typeof(string), Nullable = true)]

    [ApiFunctionParam(Name = "order", Type = typeof(string), Nullable = true)]

    public dynamic Process(IHttpRequest request)
    {
    List<WebDriveBasic> output = DriveBasic();

    // sort and filter
    HttpParam httpParam = request.Param;
    string sort = httpParam["sort"].Value;
    string order = httpParam["order"].Value;
    if (sort != null && order != null)
    {
    WebSortField webSortField = (WebSortField)JsonConvert.DeserializeObject(sort, typeof(WebSortField));
    WebSortOrder webSortOrder = (WebSortOrder)JsonConvert.DeserializeObject(order, typeof(WebSortOrder));

    output = output.AsQueryable().SortMediaItemList(webSortField, webSortOrder).ToList();
    }

    return output;
    }

    internal static ILogger Logger
    {
    get { return ServiceRegistration.Get<ILogger>(); }
    }
    }
    }

    So it is some work to add the documentation and it can lead to errors once somebody forgets to change the Attributes. But I don't know a better way. Any suggestions or thoughts on that? :)
     

    johanj

    MP Donator
  • Premium Supporter
  • January 31, 2009
    781
    398
    46
    Home Country
    Sweden Sweden
    @FreakyJ Have you checked out
    http://swagger.io

    You can try Emby api, they seem to be using this. Just install their server and it will be a link to the swagger urls somewhere in the web based server config.
     

    FreakyJ

    Retired Team Member
  • Premium Supporter
  • July 25, 2010
    4,024
    1,420
    Home Country
    Germany Germany
    You can try Emby api, they seem to be using this. Just install their server and it will be a link to the swagger urls somewhere in the web based server config.
    It is easy to say that, but implementing it is complete different story... I looked at it and it doesn't look so easy as you might think.
    Here: https://github.com/MediaBrowser/Emb...d5d91c7e0c635edaee1b4/ThirdParty/ServiceStack
    Is the Swagger.Ui which they are using. But I don't know where the API information comes from. If you can help there I might change my mind, but I don't feel like I want to brows through the whole Emby code to figure out how they implemented the Swagger Api.
     

    MrTechno

    Retired Team Member
  • Premium Supporter
  • February 27, 2011
    1,256
    511
    London
    Home Country
    United Kingdom United Kingdom
    @FreakyJ my first thought would be to split the method in two:
    Code:
        public dynamic Process(IHttpRequest request)
        {
          // sort and filter
          HttpParam httpParam = request.Param;
          WebSortField? sort = GetHttpParam<WebSortField>(httpParam, "sort");
          WebSortOrder? order = GetHttpParam<WebSortOrder>(httpParam, "order");
    
          return Process(sort, order);
        }
    
        [ApiFunctionDescription(Type = ApiFunctionDescription.FunctionType.Json, Summary = "")]
        [ApiFunctionParam(Name = "sort", Type = typeof(WebSortField), Nullable = true)]
        [ApiFunctionParam(Name = "order", Type = typeof(WebSortOrder), Nullable = true)]
        public List<WebDriveBasic> Process(WebSortField? sort, WebSortOrder? order)
        {
          List<WebDriveBasic> output = DriveBasic();
          if (sort != null && order != null)
          {
            output = output.AsQueryable().SortMediaItemList(sort.Value, order.Value).ToList();
          }
          return output;
        }
    Now it's a bit more obvious which ApiFunctionParam annotations belong to which parameter. Depending on the complexity of your documentation generator you might be able to get a lot of the information from the parameters themselves.

    My second thought which would require a lot more work up front but could be better in the long run would be to define the whole web API in RAML or Swagger and generate code stubs from the definition.
     

    FreakyJ

    Retired Team Member
  • Premium Supporter
  • July 25, 2010
    4,024
    1,420
    Home Country
    Germany Germany
    Now it's a bit more obvious which ApiFunctionParam annotations belong to which parameter. Depending on the complexity of your documentation generator you might be able to get a lot of the information from the parameters themselves.
    I was thinking the same, but thought there might be also some problems:
    the name "sort" and "order" is case sensitive. So if one uses a different spelling in the second function or even different names, the Api is messed up. The only benefit is in getting the return type, because you can't really get the type of a dynamic function except you invoke the function which in turn needs acceptable parameters to prevent an exception.
    I already added everything to every api call so adding the return type would result in less work than spelitting the functions and probably less human errors.

    My second thought which would require a lot more work up front but could be better in the long run would be to define the whole web API in RAML or Swagger and generate code stubs from the definition.
    To use swagger would be nice, but I only found it for ASP.Net and I would like that the documentation grows with the src without running different tools etc. I hate if there is too much overhead...

    My current approach is this:
    I start at the MainRequestHandler, from there I get all Service hanlder (Mas, Tas, Wss, Das) than I go through every api function and get my information. I tried to get as much as possible from the Src, but sadly that is not possible for everything :/
    I think so it is really easy to add new functions and it is obvious that you have to change something once you changed the code. But it doesn't protect completely against human errors, but I think it makes it a bit more obvious.
    This is how it looks right now (not everything is exposed yet):
    Api.PNG
     

    Users who are viewing this thread

    Top Bottom