If you have not already, we suggest setting your Plex username to something else rather than email which is displayed on your posts in forum. You can change the username at https://app.plex.tv/desktop#!/account
Welcome to our forums! Please take a few moments to read through our Community Guidelines (also conveniently linked in the header at the top of each page). There, you'll find guidelines on conduct, tips on getting the help you may be searching for, and more!

URL Services useless for more complex cases?

czukowskiczukowski Posts: 141Members ✭✭✭

I know, it's a bit provocative title.

What I really mean is that URL Services are always executed using a ServicePolicy that will not allow to execute bundled libraries. But I've found myself in need of using one, to run some Javascript on the page. It's being included from the Shared Code, so it works just fine in the channel code, but not from the URL Service, even though it actually calls the same Shared Code and doesn't try to use the external library directly.

So what now, do I dump my URL Service altogether or anybody knows of any workarounds?

Comments

  • TwoureTwoure Posts: 583Members ✭✭✭
    edited March 29

    @czukowski said:
    So what now, do I dump my URL Service altogether or anybody knows of any workarounds?

    Here's what I (and others) do: https://github.com/Twoure/KissNetwork.bundle/blob/1fd6bf884109ad0a7679469237a2fb2cbe04e4a7/Contents/Services/Shared Code/domain.pys#L15...L16 and then https://github.com/Twoure/KissNetwork.bundle/blob/1fd6bf884109ad0a7679469237a2fb2cbe04e4a7/Contents/Services/Shared Code/domain.pys#L27...L28

    Do note, if your ever want to submit your channel to be hosted officially by Plex, then you cannot use this method. Otherwise, you're good to go.


    Javascript side note: If using PyExecJS, then you can use node modules. Js2Py does not support the require statement.

    Example (using method above for file path):

    #!/usr/bin/env python
    # This would be a test file located in:
    # "KissNetwork.bundle/Contents/Services/Shared Code/test.pys"
    
    import os, sys
    
    BUNDLE_PATH = os.path.join(os.getcwd().lstrip('\\\?').split('Plug-in Support')[0], 'Plug-ins', 'KissNetwork.bundle')
    MODULE_PATH = os.path.join(BUNDLE_PATH, 'Contents', 'Libraries', 'Shared')
    NODE_MODULES_PATH = os.path.join(BUNDLE_PATH, 'Contents', 'Libraries', 'node_modules')
    
    if MODULE_PATH not in sys.path:
        sys.path.append(MODULE_PATH)
    
    import execjs  #PyExecJS imported from Contents/Libraries/Shared
    
    # using Base64 as example
    # https://www.npmjs.com/package/Base64
    
    code = (
        """
        var Base64 = require('%s/Base64/base64.js');
        var message = Base64.atob('SGkgQGN6dWtvd3NraQ==');
        """ %NODE_MODULES_PATH
        )
    
    runtime = execjs.get()
    context = runtime.compile(code)
    print context.exec_('return message')
    

    If your Node.js is setup to allow setting the module paths, then you can use this for the code instead:

    code = (
        """
        module.paths.push('%s');
        var Base64 = require('Base64');
        var message = Base64.atob('SGkgQGN6dWtvd3NraQ==');
        """ %NODE_MODULES_PATH
        )
    
  • czukowskiczukowski Posts: 141Members ✭✭✭
    edited March 30

    @Twoure, thanks for the info! Looks like I'm already using the 1st method to import Shared Libraries that I have added as git submodules (to save me from figuring out how to "install" them into the channels properly and easier updates in the future), but it just didn't occur to me that I could hack my way like this with the Shared Libraries themselves :)

    And I'm using Js2Py by the way. Works very well to get the media URLs in cases when the website devs try to deter RegExers with obfuscated JavaScript.

    But generally speaking, what was the reason for using Framework.policies.ServicePolicy for all URL Services? As far as I can tell from the Framework source code, there is a separate sandbox for each Service. Why not run them with the same policy as the channel they belong to? What we have now are the URL Services that are able to use Shared Code, that's been introduced just for this reason (again, if my understanding is correct), to share the logic between Channel and URL Service, but as soon as I add Shared Libraries to my channel, the Shared Code effectively cannot be shared anymore, since it wouldn't work in URL Service.

  • czukowskiczukowski Posts: 141Members ✭✭✭

    @Twoure, this seems to work for me as well:

    BUNDLE_PATH = Core.bundle_path
    

    Are you aware of any disadvantages of using it?

  • TwoureTwoure Posts: 583Members ✭✭✭

    @czukowski said:
    @Twoure, this seems to work for me as well:

    BUNDLE_PATH = Core.bundle_path
    

    Are you aware of any disadvantages of using it?

    IIRC the Core functions are not available within the ServiceCode, because the service code runs within it's own separate sandbox and doesn't know what Core your referring.

    To clarify, content from Contents/Code/ accessing the Contents/Services/Shared Code files will have access to the Core functions, but content from Contents/Services/URL/ accessing the Contents/Services/Shared Code files will not.

  • czukowskiczukowski Posts: 141Members ✭✭✭

    @Twoure, hm, I was sure I've put that to a Shared Code that was supposed to be called from a URL service, although that wasn't my channel so I may be missing something, gotta check...

Sign In or Register to comment.