wnox 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
wnox/__init__.py ADDED
@@ -0,0 +1,145 @@
1
+ #%%
2
+ import asyncio
3
+ import nest_asyncio
4
+ import logging
5
+ from slixmpp import ClientXMPP
6
+ import ssl
7
+ import json
8
+ from bson import ObjectId # If you need ObjectId validation
9
+ import requests as r
10
+
11
+ nest_asyncio.apply()
12
+ # logging.basicConfig(level=logging.DEBUG)
13
+ class EventEmitter:
14
+ def __init__(self):
15
+ self._events = {}
16
+
17
+ def on(self, event_name, callback):
18
+ if event_name not in self._events:
19
+ self._events[event_name] = []
20
+ self._events[event_name].append(callback)
21
+
22
+ async def emit(self, event_name, *args, **kwargs):
23
+ if event_name in self._events:
24
+ # Collect the results of all event handlers
25
+ results = []
26
+ for callback in self._events[event_name]:
27
+ result = callback(*args, **kwargs)
28
+ if asyncio.iscoroutinefunction(callback): # If callback is async
29
+ results.append(await result)
30
+ else: # If callback is sync
31
+ results.append(result)
32
+ return results[0]
33
+
34
+ class __WebSocketXMPP(ClientXMPP, EventEmitter):
35
+ def __init__(self, jid, password):
36
+
37
+
38
+ ClientXMPP.__init__(self, jid, password)
39
+ EventEmitter.__init__(self)
40
+ print(f"connecting to {jid} - {password}")
41
+ # self.jid = jid
42
+ self.password = password
43
+ # self.callback = callback # Store the callback function
44
+ self.add_event_handler("session_start", self.start)
45
+ self.add_event_handler("failed_auth", self.on_failed_auth)
46
+ self.add_event_handler("disconnected", self.on_disconnect)
47
+ self.add_event_handler("message", self.on_message) # Add event handler for incoming messages
48
+
49
+ async def start(self, event):
50
+ """Handle session start."""
51
+ print("[bridge] connected.")
52
+ self.send_presence()
53
+ await self.get_roster()
54
+
55
+ # Send a test message
56
+ self.send_message(mto="ethan@qepal.com", mbody="Hello via WebSocket!")
57
+ print("[📩] Message sent to ethan@qepal.com")
58
+
59
+ def on_failed_auth(self, event):
60
+ """Handle authentication failure."""
61
+ # print("[❌] Authentication failed. Check username/password.")
62
+
63
+ def on_disconnect(self, event):
64
+ """Handle disconnection and attempt reconnection."""
65
+ # print("[❌] Disconnected from server. Attempting to reconnect...")
66
+ asyncio.create_task(self.reconnect())
67
+
68
+ async def reconnect(self):
69
+ await asyncio.sleep(5) # Wait before reconnecting
70
+ print("[🔄] Reconnecting...")
71
+ self.connect(address=("direct.qepal.com", 5222), disable_starttls=False, force_starttls=True)
72
+ self.process(forever=False)
73
+
74
+ async def on_message(self, stanza):
75
+ """Handle incoming messages."""
76
+ if stanza.tag == "{jabber:client}message":
77
+ body = str(stanza['body'])
78
+ from_jid = str(stanza['from'])
79
+ itsme = from_jid and f"{self.boundjid.bare.split('@')[0]}-{self.boundjid.bare.split('@')[1]}" in from_jid
80
+ itsbro = not itsme and f"{self.boundjid.bare.split('@')[0]}-" in from_jid
81
+ delayed = "urn:xmpp:delay" in str(stanza)
82
+
83
+ if body and not delayed:
84
+ user_uid = from_jid.split('@')[0]
85
+ is_app = False
86
+ if len(user_uid) != 24 or not ObjectId.is_valid(user_uid):
87
+ user_uid = user_uid.split("-")[-1]
88
+ is_app = True
89
+
90
+ if body.startswith("{"):
91
+ try:
92
+ json_data = json.loads(body)
93
+ if "api" in json_data:
94
+ data = {key: val for key, val in json_data.items() if key != "api"}
95
+ data = {key: val for key, val in data.items() if key != "mid"}
96
+
97
+ if True or len(user_uid) == 24 and ObjectId.is_valid(user_uid):
98
+ result = await self.emit(json_data["api"], data)
99
+ if result == None:
100
+ result = {}
101
+ self.send_message(
102
+ mto=from_jid,
103
+ mbody=json.dumps({**result, "mid": json_data.get("mid")})
104
+ )
105
+ else:
106
+ await self.emit("message", {"from": from_jid, "body": body, "itsme": itsme, "itsbro": itsbro, "is_app":is_app})
107
+ except json.JSONDecodeError:
108
+ pass
109
+ else:
110
+ await self.emit("message", {"from": from_jid, "body": body, "itsme": itsme, "itsbro": itsbro, "is_app":is_app})
111
+
112
+
113
+
114
+ class App:
115
+ def __init__(self, *, app:str, resource:str, securekey:str, image:str, public:bool=False):
116
+ self.app = app
117
+ self.resource = resource
118
+ self.securekey = securekey
119
+ self.image = image
120
+ self.public = public
121
+
122
+ json = r.post("https://qepal.com/api/bridge/worker/init", json={
123
+ "app":app, "resource":resource, "securekey":securekey, "image":image, "public":public}).json()
124
+
125
+ self.uid = json["uid"]
126
+ self.myjid = self.app + "-" + str(self.uid) + "@qepal.com/" + self.resource
127
+ self.password = json["password"]
128
+ self.xmpp = __WebSocketXMPP(self.myjid, self.password)
129
+
130
+ def on(self, api:str, cb:callable):
131
+ self.xmpp.on(api, cb)
132
+
133
+
134
+ async def loop(self):
135
+ # print("[🔄] Initializing connection...")
136
+ ssl_ctx = ssl.create_default_context()
137
+ ssl_ctx.check_hostname = False # Disable hostname verification
138
+ ssl_ctx.verify_mode = ssl.CERT_NONE # Ignore SSL certificate validation
139
+ self.xmpp.ssl_context = ssl_ctx
140
+
141
+ self.xmpp.connect(address=("direct.qepal.com", 5222), disable_starttls=False, force_starttls=True)
142
+ self.xmpp.process(forever=True) # Keep the connection alive
143
+
144
+
145
+
File without changes
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.2
2
+ Name: wnox
3
+ Version: 0.1.0
4
+ Summary: A short description of your package
5
+ Home-page: https://github.com/arminkardan/pywnox
6
+ Author: Ethan (Armin) Cardan
7
+ Author-email: "Ethan (Armin) Cardan" <armin.fire@gmail.com>
8
+ Project-URL: homepage, https://github.com/arminkardan/pywnox
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE.txt
15
+ Requires-Dist: asyncio
16
+ Requires-Dist: nest_asyncio
17
+ Requires-Dist: logging
18
+ Requires-Dist: slixmpp
19
+ Requires-Dist: ssl
20
+ Requires-Dist: bson
21
+ Requires-Dist: json
22
+ Requires-Dist: requests
23
+ Dynamic: author
24
+ Dynamic: home-page
25
+ Dynamic: requires-python
26
+
27
+ QE nexus client.
@@ -0,0 +1,6 @@
1
+ wnox/__init__.py,sha256=j7NZA4FZiwhE4EAUumAR-8pWweC7Fw-Dt2QHbPCgJu4,6128
2
+ wnox-0.1.0.dist-info/LICENSE.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ wnox-0.1.0.dist-info/METADATA,sha256=xCsnfct854waMtW1yW5vfrWwWcBQzEChG7QC5vFv8mg,812
4
+ wnox-0.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
5
+ wnox-0.1.0.dist-info/top_level.txt,sha256=Xm9SC1bx_o6zjvo2FI-3QiZX2PZ_0UBQkGlvfYsnkwc,5
6
+ wnox-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ wnox