Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • briar/python-briar-wrapper
1 result
Show changes
Commits on Source (2)
......@@ -23,8 +23,6 @@ class Api:
def __init__(self, headless_jar):
self._command = ["java", "-jar", headless_jar]
self.socket_listener = SocketListener(self)
@staticmethod
def has_account():
return isfile(BRIAR_DB)
......@@ -67,14 +65,17 @@ class Api:
sleep(0.1)
except HTTPError as http_error:
if http_error.code == 404:
self._load_auth_token()
callback(True)
return
return self._on_successful_startup(callback)
except URLError as url_error:
if not isinstance(url_error.reason, ConnectionRefusedError):
raise url_error
callback(False)
def _on_successful_startup(self, callback):
self._load_auth_token()
self.socket_listener = SocketListener(self)
callback(True)
def _login(self, password):
if not self.is_running():
raise Exception("Can't login; API not running")
......
......@@ -2,6 +2,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
# License-Filename: LICENSE.md
from operator import itemgetter
from urllib.parse import urljoin
from requests import get as _get
......@@ -24,18 +25,12 @@ class Contacts(Model):
def get(self):
url = urljoin(BASE_HTTP_URL, self.API_ENDPOINT)
request = _get(url, headers=self._headers)
return request.json()
contacts = request.json()
contacts.sort(key=itemgetter("lastChatActivity"),
reverse=True)
return contacts
def get_link(self):
url = urljoin(BASE_HTTP_URL, self.API_ENDPOINT + "add/" + "link/")
request = _get(url, headers=self._headers).json()
return request['link']
def watch_contacts(self, callback):
self._on_contact_added_callback = callback
self._api.socket_listener.watch("ContactAddedEvent",
self._on_contact_added)
# pylint: disable=unused-argument
def _on_contact_added(self, event):
self._on_contact_added_callback()
......@@ -28,14 +28,6 @@ class PrivateChat(Model):
request = _get(url, headers=self._headers)
return request.json()
def watch_messages(self, callback):
self._on_message_received_callback = callback
self._api.socket_listener.watch("ConversationMessageReceivedEvent",
self._on_message_received)
def _on_message_received(self, event):
self._on_message_received_callback(event['data'])
def send(self, message):
url = urljoin(BASE_HTTP_URL,
self.API_ENDPOINT + "/%i" % self._contact_id)
......
......@@ -4,7 +4,7 @@
import asyncio
import json
from threading import Thread
from threading import Thread, Lock
import websockets
......@@ -12,33 +12,55 @@ from briar_wrapper.constants import WEBSOCKET_URL
from briar_wrapper.model import Model
class SocketListener(Model): # pylint: disable=too-few-public-methods
class SocketListener(): # pylint: disable=too-few-public-methods
def watch(self, event, callback):
def __init__(self, api):
self._api = api
self._signals = list()
self._signals_lock = Lock()
self._start_websocket_thread()
def connect(self, event, callback):
self._signals_lock.acquire()
# TODO: Signal ID should be stable after disconnects
signal_id = len(self._signals)
self._signals.append({
"event": event,
"callback": callback
})
self._signals_lock.release()
return signal_id
def _start_websocket_thread(self):
websocket_thread = Thread(target=self._start_watch_loop,
args=(event, callback),
daemon=True)
websocket_thread.start()
def _start_watch_loop(self, event, callback):
def _start_watch_loop(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.create_task(self._start_websocket(event, callback))
loop.create_task(self._start_websocket())
loop.run_forever()
loop.close()
async def _start_websocket(self, event, callback):
async def _start_websocket(self):
async with websockets.connect(WEBSOCKET_URL) as websocket:
await websocket.send(self._api.auth_token)
await self._watch_messages(websocket, event, callback)
await self._watch_messages(websocket)
async def _watch_messages(self, websocket, event, callback):
async def _watch_messages(self, websocket):
while not websocket.closed and not\
asyncio.get_event_loop().is_closed():
message_json = await websocket.recv()
message = json.loads(message_json)
if message['name'] == event:
callback(message)
self._call_signal_callbacks(message)
if not asyncio.get_event_loop().is_closed():
asyncio.get_event_loop().create_task(
self._watch_messages(websocket, event, callback))
self._watch_messages(websocket))
def _call_signal_callbacks(self, message):
self._signals_lock.acquire()
for signal in self._signals:
if signal["event"] == message['name']:
signal["callback"](message)
self._signals_lock.release()