How to import modules from another Python program or Kodi library.
#1
Hello, I am new here. I am trying to code a add-on to run Tribler in the background to get resources.

I am quite confused about importing modules from another add-on.

I name put the origin tribler program under script.tribler/lib, and write <extension point="xbmc.python.module" library="lib" /> in addon.xml

From the add-on I am coding, I put <import addon="script.tribler" version="0.0.1"/> in the xml and try import it from the script. It cannot find the module whether I import tribler or import lib.tribler

What is more, as twisted is a dependency of Tribler, I wirte <import addon="script.module.twisted" version="13.2.0"/> in addon.xml, but it isn't installed automatically.

My question is:
1. What is the correct way to import something from another addon
2. How to use the official libraries like twisted or zope.interface
3. When I import twisted in my code, does kodi try to find it in the add-on folder or in my python directory

Thx a lot for any help.
Reply
#2
1. Set up `script.tribler` so that the main library `__init__.py` script is at script.tribler/lib/tribler/__init__.py, then import with import tribler. Also make sure that this add-on is enabled, as Kodi Krypton doesn't enable add-ons placed directly to the addons directory by default.

2. You've got the twisted dependency correct, but Kodi will only install dependencies when you "install" your add-on, either from a zip file or repository, not when an already installed add-on is modified in place. You can grab the zip file from the official repo here and install it.

3. Python will first look in your add-on directory, then addon.xml imported add-on library directories, then Python system directories*. Kodi sets `sys.path` to these directories then Python's standard behavior takes over.

* For some platforms (Windows and Android, maybe all but Linux?) Kodi uses its own internal Python rather than that installed on the system, so any additional Python libraries should be created as additional xmbc.python.module add-ons or included directly into your main add-on.
Reply
#3
(2017-02-08, 00:27)rmrector Wrote: 1. Set up `script.tribler` so that the main library `__init__.py` script is at script.tribler/lib/tribler/__init__.py, then import with import tribler. Also make sure that this add-on is enabled, as Kodi Krypton doesn't enable add-ons placed directly to the addons directory by default.

2. You've got the twisted dependency correct, but Kodi will only install dependencies when you "install" your add-on, either from a zip file or repository, not when an already installed add-on is modified in place. You can grab the zip file from the official repo here and install it.

3. Python will first look in your add-on directory, then addon.xml imported add-on library directories, then Python system directories*. Kodi sets `sys.path` to these directories then Python's standard behavior takes over.

* For some platforms (Windows and Android, maybe all but Linux?) Kodi uses its own internal Python rather than that installed on the system, so any additional Python libraries should be created as additional xmbc.python.module add-ons or included directly into your main add-on.
Thanks a lot.
May I ask another question? Is there a way to execute some "core engine" continuously in the background? It seems that the main function will be executed every time I click something in the menu. Is it possible to have something running in the background downloading resource or seeding or whatever?
Reply
#4
(2017-02-10, 17:35)EinNarr Wrote: May I ask another question? Is there a way to execute some "core engine" continuously in the background? It seems that the main function will be executed every time I click something in the menu. Is it possible to have something running in the background downloading resource or seeding or whatever?

You need to make a service addon. However, a service addon must check for Kodi exit event to be gracefully shut down, so third-party packages that run some event loops or open blocking sockets must be modified to work correctly in Kodi.
Reply
#5
(2017-02-10, 19:27)Roman_V_M Wrote:
(2017-02-10, 17:35)EinNarr Wrote: May I ask another question? Is there a way to execute some "core engine" continuously in the background? It seems that the main function will be executed every time I click something in the menu. Is it possible to have something running in the background downloading resource or seeding or whatever?

You need to make a service addon. However, a service addon must check for Kodi exit event to be gracefully shut down, so third-party packages that run some event loops or open blocking sockets must be modified to work correctly in Kodi.

Thx for your advice. I have already been trying service add-on.
Quick question, what in a service add-on could cause the failure of loading any other add-ons? I set my code to run with starting up Kodi, but all other add-ons can not be opened any more. It would be "working..." all the time. There is not any error recorded in the log. Kinda spent long time already without finding the reason.
Reply
#6
"There are no psychics" © "The Mentalist". Please show what your service exactly does.
Reply
#7
(2017-02-15, 13:29)Roman_V_M Wrote: "There are no psychics" © "The Mentalist". Please show what your service exactly does.
Thx
It is a P2P software called Tribler as I mentioned. I tried to invoke the core of that using multiprocessing, without launching its GUI. I might got the wrong way to invoke it, but as Tribler just became weird and even cannot shut itself down properly without "kill" and leaves no log at all, I cannot tell which part goes wrong.
Reply
#8
(2017-02-15, 13:29)Roman_V_M Wrote: "There are no psychics" © "The Mentalist". Please show what your service exactly does.

Let's say, if there is a deadlock in one of the service add-ons, would it cause the failure of launching any other add-ons?
Reply
#9
(2017-02-15, 13:29)Roman_V_M Wrote: "There are no psychics" © "The Mentalist". Please show what your service exactly does.

Currently I am running a http sever using port 8085 to communicate. It is still in very early phase that I can run the sever but not shutting it down. I shut it down by sending a http request(requests.put("http://localhost:8085/shutdown")). I tried it in terminal, one running the server and the other sends the request. It works as expected.

However, when running it in Kodi, the request sender ends in a deadlock. It probably means that it finds someone on 8085, but cannot receive any reply. And on the Kodi side, it will no longer response after clicking exit(, probably due to the server is not properly closed?).

I am using Twisted to run the server, and it is started a separate process. Could you plz give any suggestion? Is Kodi somehow blocking http request/reply?
Reply
#10
What I said before:

(2017-02-10, 19:27)Roman_V_M Wrote: However, a service addon must check for Kodi exit event to be gracefully shut down, so third-party packages that run some event loops or open blocking sockets must be modified to work correctly in Kodi.
Reply
#11
(2017-02-16, 22:28)Roman_V_M Wrote: What I said before:

(2017-02-10, 19:27)Roman_V_M Wrote: However, a service addon must check for Kodi exit event to be gracefully shut down, so third-party packages that run some event loops or open blocking sockets must be modified to work correctly in Kodi.
Thx for your help.

I checked for Kodi exit and send a request to shut my server addon down.
It's like :

Process(start_server).start()
while not monitor.abortRequested():
pass
requests.put("http://localhost:8085/shutdown")

If I run this server in terminal, it can be proper shut down. But it will deadlock when run in Kodi.

Could this still be the problem of socket?
Reply
#12
*Sighs*

a) You need to show your real code, not just some vague descriptions.

b) Once again: third-party packages that run some event loops or open blocking sockets must be modified to work correctly in Kodi! You mentioned Twisted server, so you need to properly shut-down Twisted server on Kodi abort evernt (xbmc.Monitor.abortRequested). I'm talking about the server itself, not your addon. This means that you need to modify Twisted server so that it behaves correctly inside Kodi.
Reply
#13
(2017-02-17, 14:41)Roman_V_M Wrote: *Sighs*

a) You need to show your real code, not just some vague descriptions.

b) Once again: third-party packages that run some event loops or open blocking sockets must be modified to work correctly in Kodi! You mentioned Twisted server, so you need to properly shut-down Twisted server on Kodi abort evernt (xbmc.Monitor.abortRequested). I'm talking about the server itself, not your addon. This means that you need to modify Twisted server so that it behaves correctly inside Kodi.

I am sorry for not show the real code. but Tribler is about 150,000 lines in total, I couldn't wish you to go through that. I am just kinda rewriting the UI to port it to tribler.
It is properly working with its own GUI, and the http request is how its own GUI shut the server down. On receiving that request, the server process will shut down itself and the twisted reactor.
like this:
session.shutdown().addCallback(reactor.stop)

I am new to Kodi add-on. I apologize if my question is so much messed up.

Is it the right way to put the shutdown request after:
while not monitor.abortRequested():
pass
?

As I mentioned, the same code works in terminal but not in Kodi, so I am seeking for the reason to this.

Thx for your kind help.

Whole main program is attached.
PHP Code:
import time
import xbmc
import sys
import signal
from os
.path import abspathjoindirname
sys
.path.insert(0join(abspath(dirname('__file__')), 'tribler'))

from twisted.internet import reactor

from Tribler
.Core.Session import Session
from Tribler
.Core.Modules.process_checker import ProcessChecker
from Tribler
.Core.Session import Session
from Tribler
.Core.SessionConfig import SessionStartupConfig

def start_tribler_core
():
    
"""
    This method is invoked by multiprocessing when the Tribler core is started and will start a Tribler session.
    Note that there is no direct communication between the GUI process and the core: all communication is performed
    through the HTTP API.
    """
    
from twisted.internet import reactor

    def on_tribler_shutdown
(_):
        
reactor.stop()

    
def shutdown(session, *_):
        
logging.info("Stopping Tribler core")
        
session.shutdown().addCallback(on_tribler_shutdown)

    
def start_tribler():
        
config SessionStartupConfig().load()
        
config.set_http_api_port(8085)
        
config.set_http_api_enabled(True)

        
# Check if we are already running a Tribler instance
        
process_checker ProcessChecker()
        if 
process_checker.already_running:
            return

        
session Session(config)

        
signal.signal(signal.SIGTERMlambda signumstackshutdown(sessionsignumstack))
        
session.start()
    
reactor.callWhenRunning(start_tribler)
    
reactor.run()

if 
__name__ == '__main__':
    
import thread
    from multiprocessing
.dummy import Process
    process
=Process(target=start_tribler_core)
    
process.start()

    while 
not monitor.abortRequested():
        
pass
    import requests
    r 
requests.put("http://localhost:8085/shutdown"
Reply
#14
I agree that analyzing potential problems for third-party Python libraries may be difficult, even impossible, especially for a novice developer. Python inside Kodi has some peculiarities and running a script in the stand-alone mode does not guarantee that it will work properly in Kodi. Since you are running some kind of a server, I can only recommend to run it outside Kodi and communicate with it from your addon (via http as I understand).
Reply
#15
@Einarr

Firstly i would advise not to invoke tribler core with Thread module, or threading.Thread module (even though you haven't), in general, dont invoke any threads from kodi addons unless you know what you are dealing with. Kodi dispatches internal python interpreter, in very fancy ways and can be very rude to its memory allocs in C level. You will face, memleaks, deadlock, uncleaned garbage etc eventually, at least my experince was like that, i dont advise you to experience this in the hard way. There are several examples of this in the forums wehre Roman gave the insights

And also i would not spawn the core in another process also, because Kodi expects an addon to be executed in a certain time frame (5 seconds as far as i remeber). And when it is done it clears the memory, it is very likely that your process will stay orphan after several execution whenever something goes wrong.

Kodi already handles service addons and it is a perfect fit for your application. Your code example shows that it is not a service addon.If you upload your code to github i can also check in more detail.
Reply

Logout Mark Read Team Forum Stats Members Help
How to import modules from another Python program or Kodi library.0