wnox 0.1.0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
wnox-0.1.0/LICENSE.txt ADDED
File without changes
wnox-0.1.0/PKG-INFO ADDED
@@ -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.
wnox-0.1.0/README.md ADDED
@@ -0,0 +1 @@
1
+ QE nexus client.
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "wnox"
7
+ version = "0.1.0"
8
+ authors = [{ name = "Ethan (Armin) Cardan", email = "armin.fire@gmail.com" }]
9
+ description = "A short description of your package"
10
+ readme = "README.md"
11
+ license = { file = "LICENSE" }
12
+ dependencies = ["asyncio","nest_asyncio","logging","slixmpp","ssl","bson","json","requests"]
13
+ requires-python = ">=3.6"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent"
18
+ ]
19
+
20
+
21
+ [project.urls]
22
+ homepage = "https://github.com/arminkardan/pywnox"
23
+
wnox-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
wnox-0.1.0/setup.py ADDED
@@ -0,0 +1,20 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="wnox",
5
+ version="0.1.0",
6
+ packages=find_packages(),
7
+ install_requires=[],
8
+ author="Ethan (Armin) Cardan",
9
+ author_email="armin.fire@gmail.com",
10
+ description="QE nexus client.",
11
+ long_description=open("README.md").read(),
12
+ long_description_content_type="text/markdown",
13
+ url="https://github.com/arminkardan/pywnox",
14
+ classifiers=[
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ],
19
+ python_requires=">=3.6",
20
+ )
@@ -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
+
@@ -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,10 @@
1
+ LICENSE.txt
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ wnox/__init__.py
6
+ wnox.egg-info/PKG-INFO
7
+ wnox.egg-info/SOURCES.txt
8
+ wnox.egg-info/dependency_links.txt
9
+ wnox.egg-info/requires.txt
10
+ wnox.egg-info/top_level.txt
@@ -0,0 +1,8 @@
1
+ asyncio
2
+ nest_asyncio
3
+ logging
4
+ slixmpp
5
+ ssl
6
+ bson
7
+ json
8
+ requests
@@ -0,0 +1 @@
1
+ wnox