Murgeye / teamspeak3-python-api

A simple wrapper for the TeamSpeak 3 Server Query API in python.
Apache License 2.0
19 stars 9 forks source link

Using ts3conn in event_listener of register_for_channel_event(id, event_listener) #16

Closed Jan3kk closed 3 years ago

Jan3kk commented 3 years ago

How can I use or pass ts3connection to the function that is called whenever certain event hits? Example:

main.py

ts3conn.register_for_channel_events(1, channel_event)

module.py

def channel_event(sender, **kw): here I want to use the same ts3conn used in main

Murgeye commented 3 years ago

Hey,

I think I never added a way to do that easily sadly. In the bot based on the API I saved the ts3conn as a global variable to reuse (see for example https://github.com/Murgeye/teamspeak3-python-bot/blob/master/modules/phrasendrescher.py).

Another way would be something like this:

ts3conn = "asdf"
sender = None
def ts3conn_var(ts3conn):
    def decorate(func):
        func.ts3conn = ts3conn
        return func
    return decorate

def event_handler(sender, **kw):
    print(event_handler.ts3conn)

h = ts3conn_var(ts3conn)(event_handler)
h(sender)

which prints:

asdf

I would change this in the API if I wrote it from scratch, but sadly, I cannot do so without breaking event handlers without **kw.

Jan3kk commented 3 years ago

So if I create connection in ts3conn and use your code, then after ts3conn.register_for_channel_events(1, event_handler) every time the event is fired then it would print the connection ? (assuming it's now the connection instead of "asdf") But I'm a beginner so I think I will just make it global if I won't be able to solve this problem :/

Murgeye commented 3 years ago

That should work, yes. Don't forget to call ts3conn_var(ts3conn)(event_handler) though. This will setup the static variable event_handler.ts3conn.

Global would be fine to in this case IMHO.

Murgeye commented 3 years ago

Another possibility would be to wrap this in a class:

class event_handler(object):
    def __init__(self, ts3conn):
        self.ts3conn = ts3conn

    def handle_event(self, sender):
        print(self.ts3conn)

# in main
handler = event_handler(ts3conn)
ts3conn.register_for_channel_events(1, handler.handle_event)
Jan3kk commented 3 years ago

Okay, this way seems quite nice to me. Will reply when I will implement this :)

Jan3kk commented 3 years ago

@Murgeye Thank you a lot for help, I managed to remake your example so it fits my code and it works :) Now instead of importing just the event handler function, I import the class you made (but with handle_event(self, sender, **kw) changed to my event handler) and create an object in the main so the event handler has access to ts3conn.

Murgeye commented 3 years ago

Great that it works! Keep learning, and if you have any more questions, feel free to ask!