Commit 7492ce5a authored by Nico Alt's avatar Nico Alt

Improve all components of API wrapper

parent a417fad5
......@@ -2,8 +2,10 @@
# SPDX-License-Identifier: AGPL-3.0-only
# License-Filename: LICENSE.md
from briar.api.constants import Constants
from briar.api.constants import BASE_HTTP_URL, BRIAR_AUTH_TOKEN, BRIAR_DB
from briar.api.models.socket_listener import SocketListener
from os.path import isfile
from subprocess import Popen, PIPE, STDOUT
from threading import Thread
from time import sleep
......@@ -14,18 +16,17 @@ from urllib.request import urlopen
class Api:
auth_token = None
socket_listener = None
_process = None
def __init__(self, headless_jar):
self._command = ['java', '-jar', headless_jar]
self.constants = Constants()
self._load_auth_token()
self._command = ["java", "-jar", headless_jar]
self.socket_listener = SocketListener(self)
def has_account(self):
from pathlib import Path
home = str(Path.home())
from os.path import isdir, join
return isdir(join(home, ".briar", "db"))
return isfile(BRIAR_DB)
def is_running(self):
return (self._process is not None) and (self._process.poll() is None)
......@@ -61,22 +62,22 @@ class Api:
def _watch_thread(self, callback):
while self.is_running():
try:
urlopen(BASE_HTTP_URL)
sleep(0.1)
print(urlopen(self.constants.get_base_url()).getcode())
except HTTPError as e:
if(e.code == 404):
except HTTPError as http_error:
if(http_error.code == 404):
self._load_auth_token()
callback(True)
return
except URLError as e:
if not isinstance(e.reason, ConnectionRefusedError):
raise e
except URLError as url_error:
if not isinstance(url_error.reason, ConnectionRefusedError):
raise url_error
callback(False)
def _login(self, password):
if not self.is_running():
raise Exception("Can't login; API not running")
self._process.communicate((password + '\n').encode("utf-8"))
self._process.communicate(("%s\n" % password).encode("utf-8"))
def _register(self, credentials):
if not self.is_running():
......@@ -87,7 +88,7 @@ class Api:
def _load_auth_token(self):
if not self.has_account():
return
with open(self.constants.get_auth_token(), 'r') as file:
raise Exception("Can't load authentication token")
with open(BRIAR_AUTH_TOKEN, 'r') as file:
self.auth_token = file.read()
......@@ -6,17 +6,13 @@ from os.path import join
from pathlib import Path
from urllib.parse import urljoin
_BRIAR_DIR = ".briar"
class Constants:
_HOST = "%s://localhost:7000"
_VERSION_SUFFIX = "v1/"
_BRIAR_AUTH_TOKEN = 'auth_token'
_BRIAR_DIR = '.briar'
BRIAR_AUTH_TOKEN = join(Path.home(), _BRIAR_DIR, "auth_token")
BRIAR_DB = join(Path.home(), _BRIAR_DIR, "db", "db.mv.db")
_HOST = 'http://localhost:7000'
_VERSION_SUFFIX = 'v1/'
def get_auth_token(self):
return join(Path.home(), self._BRIAR_DIR, self._BRIAR_AUTH_TOKEN)
def get_base_url(self):
return urljoin(self._HOST, self._VERSION_SUFFIX)
BASE_HTTP_URL = urljoin(_HOST % "http", _VERSION_SUFFIX)
WEBSOCKET_URL = urljoin(_HOST % "ws", "%s/ws" % _VERSION_SUFFIX)
......@@ -2,6 +2,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
# License-Filename: LICENSE.md
from briar.api.constants import BASE_HTTP_URL
from briar.api.models.model import Model
from requests import get as _get
......@@ -11,7 +12,6 @@ from urllib.parse import urljoin
class Contacts(Model):
def get(self):
headers = {'Authorization': 'Bearer ' + self._api.auth_token}
url = urljoin(self._constants.get_base_url(), 'contacts')
r = _get(url, headers=headers)
url = urljoin(BASE_HTTP_URL, 'contacts')
r = _get(url, headers=self._headers)
return r.json()
......@@ -5,6 +5,11 @@
class Model:
_headers = {}
def __init__(self, api):
self._api = api
self._constants = api.constants
self._initialize_headers()
def _initialize_headers(self):
self._headers['Authorization'] = 'Bearer %s' % self._api.auth_token
......@@ -2,8 +2,8 @@
# SPDX-License-Identifier: AGPL-3.0-only
# License-Filename: LICENSE.md
from briar.api.constants import BASE_HTTP_URL
from briar.api.models.model import Model
from briar.api.models.socket_listener import SocketListener
from requests import get as _get
from requests import post as _post
......@@ -13,17 +13,15 @@ from urllib.parse import urljoin
class PrivateChat(Model):
def get(self, contact_id):
headers = {'Authorization': 'Bearer ' + self._api.auth_token}
url = urljoin(self._constants.get_base_url(), 'messages/%i' % contact_id)
r = _get(url, headers=headers)
return r.json()
url = urljoin(BASE_HTTP_URL, 'messages/%i' % contact_id)
request = _get(url, headers=self._headers)
return request.json()
def watch_messages(self, contact_id, callback):
socket_listener = SocketListener(self._api)
socket_listener.watch(callback, "ConversationMessageReceivedEvent",
contact_id=contact_id)
self._api.socket_listener.watch(callback,
"ConversationMessageReceivedEvent",
contact_id=contact_id)
def send(self, contact_id, message):
headers = {'Authorization': 'Bearer ' + self._api.auth_token}
url = urljoin(self._constants.get_base_url(), 'messages/%s' % contact_id)
_post(url, headers=headers, json={'text': message})
url = urljoin(BASE_HTTP_URL, 'messages/%s' % contact_id)
_post(url, headers=self._headers, json={'text': message})
......@@ -2,6 +2,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
# License-Filename: LICENSE.md
from briar.api.constants import WEBSOCKET_URL
from briar.api.models.model import Model
import asyncio
......@@ -10,6 +11,7 @@ from threading import Thread
import websockets
# TODO: Make more general; currently very specific to private messages
class SocketListener(Model):
def watch(self, callback, event, contact_id="0"):
......@@ -26,16 +28,17 @@ class SocketListener(Model):
loop.close()
async def _start_websocket(self, callback, event, contact_id="0"):
async with websockets.connect('ws://localhost:7000/v1/ws') as websocket:
async with websockets.connect(WEBSOCKET_URL) as websocket:
await websocket.send(self._api.auth_token)
await self._watch_messages(websocket, callback)
await self._watch_messages(websocket, event, callback)
async def _watch_messages(self, websocket, callback):
while not websocket.closed and not asyncio.get_event_loop().is_closed():
async def _watch_messages(self, websocket, event, callback):
while not websocket.closed and not\
asyncio.get_event_loop().is_closed():
message = await websocket.recv()
m = json.loads(message)
if m['name'] == 'ConversationMessageReceivedEvent':
callback(m['data'])
message = json.loads(message)
if message['name'] == event:
callback(message['data'])
if not asyncio.get_event_loop().is_closed():
asyncio.get_event_loop().create_task(
self._watch_messages(websocket, callback))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment