diff --git a/README.MD b/README.MD index c37e79b..ce5ff32 100644 --- a/README.MD +++ b/README.MD @@ -5,108 +5,167 @@ ![Static Badge](https://img.shields.io/badge/Maintained-Yes-green) -#### If you are using Python3, this package can help you to parse all json responses it does all the work for you. - -## How to use this package +## Introduction +If you are using Python3, this package can help you to parse all json responses it does all the work for you. + +## How to install this package +```bash + pip3 install unrealircd_rpc_py +``` +> [!NOTE] +> I recommend installing a virtual environment and then installing the package within it. + +## How to establish the link +```python + # Using requests method + rpc = Loader( + req_method='requests', + url='https://your.irc.domaine.org:8600/api', + username='apiname', + password='apiPASSWORD' + ) - $ pip3 install unrealircd_rpc_py + # Using socket method + rpc = Loader( + req_method='socket', + url='https://your.irc.domaine.org:8600/api', + username='apiname', + password='apiPASSWORD' + ) -## How to work with (remotly) + # Using unixsocket method (Local only) + rpc = Loader( + req_method='unixsocket', + path_to_socket_file='/path/to/unrealircd/data/rpc.socket' + ) -This package allows easy interfacing with UnrealIRCd through regular Python3 code, such as: + # Live Connection (Local only) + LiveRpc = Live( + path_to_socket_file='/path/to/unrealircd/data/rpc.socket', + callback_object_instance=Callback_class_instance, + callback_method_name='your_method_name' + ) - from unrealircd_rpc_py.Loader import Loader +``` - # Initialize your connexion to unrealircd - rpc = Loader( - req_method='requests', # you can also use 'socket' - url='https://your.irc.domaine.org:8600/api', - username='apiname', - password='apiPASSWORD' - ) +## How to work with (remotly) - # Enjoy the power of JSON-RPC +This package allows easy interfacing with UnrealIRCd through regular Python3 code, such as: +```python + from unrealircd_rpc_py.Loader import Loader + + # Initialize your connexion to unrealircd + rpc = Loader( + req_method='requests', # you can also use 'socket' + url='https://your.irc.domaine.org:8600/api', + username='apiname', + password='apiPASSWORD' + ) - User = rpc.User - response = User.get('adator') + # Enjoy the power of JSON-RPC - print(f'Nickname: {response.name}') - print(f'Ip: {response.ip}') + User = rpc.User + response = User.get('adator') - Channels = rpc.Channel - response = Channels.list_(_object_detail_level=3) + print(f'Nickname: {response.name}') + print(f'Ip: {response.ip}') - for chan in Channels.DB_CHANNELS: - print(f'-' * 16) - print(f'Channel: {chan.name}') - print(f'Created on: {chan.creation_time}') - print(f'Bans: {chan.bans}') - print(f'Members: {chan.members}') - print(f'-' * 16) + Channels = rpc.Channel + response = Channels.list_(_object_detail_level=3) + for chan in Channels: + print(f'-' * 16) + print(f'Channel: {chan.name}') + print(f'Created on: {chan.creation_time}') + print(f'Bans: {chan.bans}') + print(f'Members: {chan.members}') + print(f'-' * 16) +``` ## How to work with (using unix socket locally) This package allows easy interfacing with UnrealIRCd through regular Python3 code, such as: +```python + from unrealircd_rpc_py.Loader import Loader - from unrealircd_rpc_py.Loader import Loader - - # Initialize your connexion to unrealircd - rpc = Loader( - req_method='unixsocket', - path_to_socket_file='/path/to/unrealircd/data/rpc.socket' - ) - - # Enjoy the power of JSON-RPC + # Initialize your connexion to unrealircd + rpc = Loader( + req_method='unixsocket', + path_to_socket_file='/path/to/unrealircd/data/rpc.socket' + ) - User = rpc.User - response = User.get('adator') + # Enjoy the power of JSON-RPC - print(f'Nickname: {response.name}') - print(f'Ip: {response.ip}') + User = rpc.User + response = User.get('adator') - Channels = rpc.Channel - response = Channels.list_(_object_detail_level=3) + print(f'Nickname: {response.name}') + print(f'Ip: {response.ip}') - for chan in Channels.DB_CHANNELS: - print(f'-' * 16) - print(f'Channel: {chan.name}') - print(f'Created on: {chan.creation_time}') - print(f'Bans: {chan.bans}') - print(f'Members: {chan.members}') - print(f'-' * 16) + Channels = rpc.Channel + response = Channels.list_(_object_detail_level=3) + # The auto completion should help you to find all available attributes + for chan in Channels: + print(f'-' * 16) + print(f'Channel: {chan.name}') + print(f'Created on: {chan.creation_time}') + print(f'Bans: {chan.bans}') + print(f'Members: {chan.members}') + print(f'-' * 16) +``` ## How to work with (using Live unix socket) +```python + from unrealircd_rpc_py.Live import Live - from unrealircd_rpc_py.Live import Live + # This is un callback class that will recieve the response + from TestObject import TestObject - # This is un callback class that will recieve the response - from TestObject import TestObject + InitCallbackClass = TestObject() - InitCallbackClass = TestObject() + # The Callback method must always have 1 parameter as string + liveRpc = Live( + path_to_socket_file='/path/to/unrealircd/data/rpc.socket', + callback_object_instance=InitCallbackClass, + callback_method_name='your_method_name' + ) - # The Callback method must always have 1 parameter as string - liveRpc = Live( - path_to_socket_file='/path/to/unrealircd/data/rpc.socket', - callback_object_instance=InitCallbackClass, - callback_method_name='your_method_name' - ) - - # This method will run forever and will send to your callback method the response - # in SimpleNameSpace type that you can parse - liveRpc.execute_async_method() + # This method will run forever and will send to your callback method the response + # in SimpleNameSpace type that you can parse + liveRpc.subscribe() +``` ## Exemple of a Callback Class +```python + class CallbackObject: - class CallbackObject: + def __init__(self) -> None: + pass - def __init__(self) -> None: - pass + def run(self, json_response) -> bool: - def run(self, json_response) -> bool: + print(json_response) - print(json_response) + if type(json_response.result) != bool: + print(json_response.result.channel) +``` - if type(json_response.result) != bool: - print(json_response.result.channel) +## Object that you can use in a synchrone mode +```python + from unrealircd_rpc_py.Loader import Loader + + # Initialize your connexion to unrealircd using the unixsocket + rpc = Loader( + req_method='unixsocket', + path_to_socket_file='/path/to/unrealircd/data/rpc.socket' + ) + Channel = rpc.Channel + Name_ban = rpc.Name_ban + Server_ban_exception = rpc.Server_ban_exception + Server_ban = rpc.Server_ban + Spamfilter = rpc.Spamfilter + Stats = rpc.Stats + User = rpc.User + Whowas = rpc.Whowas +``` diff --git a/dist/unrealircd_rpc_py-0.1.0-py3-none-any.whl b/dist/unrealircd_rpc_py-0.1.0-py3-none-any.whl index 9e04454..c917a5e 100644 Binary files a/dist/unrealircd_rpc_py-0.1.0-py3-none-any.whl and b/dist/unrealircd_rpc_py-0.1.0-py3-none-any.whl differ diff --git a/dist/unrealircd_rpc_py-0.1.0.tar.gz b/dist/unrealircd_rpc_py-0.1.0.tar.gz index d3f661b..43d0775 100644 Binary files a/dist/unrealircd_rpc_py-0.1.0.tar.gz and b/dist/unrealircd_rpc_py-0.1.0.tar.gz differ diff --git a/dist/unrealircd_rpc_py-0.1.1-py3-none-any.whl b/dist/unrealircd_rpc_py-0.1.1-py3-none-any.whl new file mode 100644 index 0000000..f656d21 Binary files /dev/null and b/dist/unrealircd_rpc_py-0.1.1-py3-none-any.whl differ diff --git a/dist/unrealircd_rpc_py-0.1.1.tar.gz b/dist/unrealircd_rpc_py-0.1.1.tar.gz new file mode 100644 index 0000000..cbbeec5 Binary files /dev/null and b/dist/unrealircd_rpc_py-0.1.1.tar.gz differ diff --git a/how_to_use_id.py b/how_to_use_id.py index 9295401..530e7a1 100644 --- a/how_to_use_id.py +++ b/how_to_use_id.py @@ -18,7 +18,7 @@ get_user = rpc.User.get('adator') print(get_user.name, get_user.hostname, sep=' / ') - + # Use Channel object Channels = rpc.Channel.list_() for c in Channels: diff --git a/setup.py b/setup.py index a0662a3..03e039b 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='unrealircd_rpc_py', - version='0.1.0', + version='0.1.1', packages=find_packages(), install_requires=[ "requests>=2.25.1" diff --git a/unrealircd_rpc_py/Live.py b/unrealircd_rpc_py/Live.py index 6a55414..4432e2b 100644 --- a/unrealircd_rpc_py/Live.py +++ b/unrealircd_rpc_py/Live.py @@ -30,6 +30,8 @@ def __init__(self, path_to_socket_file: str, callback_object_instance: object, c self.str_response = '' self.json_response = '' + self.connected: bool = True + # Option 2 with Namespaces self.json_response_np: SimpleNamespace @@ -64,14 +66,13 @@ async def __send_to_permanent_unixsocket(self): sock = socket.socket(socket.AddressFamily.AF_UNIX, socket.SocketKind.SOCK_STREAM) sock.connect(self.path_to_socket_file) - connected = True if not self.request: return None sock.sendall(f'{self.request}\r\n'.encode()) - while connected: + while self.connected: # Recieve the data from the rpc server, decode it and split it response = sock.recv(4096).decode().split('\n') @@ -105,8 +106,22 @@ def __init_log_system(self) -> None: encoding='UTF-8', format='%(asctime)s - %(levelname)s - %(filename)s - %(lineno)d - %(funcName)s - %(message)s') - def execute_async_method(self): - asyncio.run(self.query('log.subscribe', param={"sources": ["all"]})) + def subscribe(self, param: dict = {"sources": ["all"]}): + """Subscribe to the rpc server stream + param exemple: + \n ["!debug","all"] would give you all log messages except for debug messages + see: https://www.unrealircd.org/docs/List_of_all_log_messages + Args: + param (dict, optional): The ressources you want to subscribe. Defaults to {"sources": ["all"]}. + """ + asyncio.run(self.query('log.subscribe', param=param)) + + def unsubscribe(self): + """Run a del timer to trigger an event and then unsubscribe from the stream + """ + self.connected = False + asyncio.run(self.query(method='rpc.del_timer', param={"timer_id":"timer_impossible_to_find_as_i_am_not_a_teapot"})) + asyncio.run(self.query(method='log.unsubscribe')) async def query(self, method: Union[Literal['log.subscribe', 'log.unsubscribe'], str], param: dict = {}, id: int = 123, jsonrpc:str = '2.0') -> Union[str, any, None, bool]: """This method will use to run the queries @@ -144,7 +159,6 @@ async def query(self, method: Union[Literal['log.subscribe', 'log.unsubscribe'], self.request = json.dumps(response) await asyncio.gather(self.__send_to_permanent_unixsocket()) - # self.__send_to_permanent_unixsocket() if self.json_response == '': return False @@ -166,4 +180,4 @@ def set_error(self, json_error: dict): except KeyError as ke: self.Logs.error(ke) except Exception as err: - self.Logs.error(err) \ No newline at end of file + self.Logs.error(err) diff --git a/version.json b/version.json index dfba51c..008971a 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "0.1.0" + "version": "0.1.1" } \ No newline at end of file