108902b01SBrad Bishop# Copyright (C) 2018-2019 Garmin Ltd.
219323693SBrad Bishop#
3c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only
419323693SBrad Bishop#
519323693SBrad Bishop
66ce62a20SAndrew Geisslerimport asyncio
7a34c030eSBrad Bishopfrom contextlib import closing
8475cb72dSAndrew Geisslerimport itertools
9475cb72dSAndrew Geisslerimport json
10ac13d5f3SPatrick Williamsfrom collections import namedtuple
11ac13d5f3SPatrick Williamsfrom urllib.parse import urlparse
12*44b3caf2SPatrick Williamsfrom bb.asyncrpc.client import parse_address, ADDR_TYPE_UNIX, ADDR_TYPE_WS
1319323693SBrad Bishop
14ac13d5f3SPatrick WilliamsUser = namedtuple("User", ("username", "permissions"))
15a34c030eSBrad Bishop
16ac13d5f3SPatrick Williamsdef create_server(
17ac13d5f3SPatrick Williams    addr,
18ac13d5f3SPatrick Williams    dbname,
19ac13d5f3SPatrick Williams    *,
20ac13d5f3SPatrick Williams    sync=True,
21ac13d5f3SPatrick Williams    upstream=None,
22ac13d5f3SPatrick Williams    read_only=False,
23ac13d5f3SPatrick Williams    db_username=None,
24ac13d5f3SPatrick Williams    db_password=None,
25ac13d5f3SPatrick Williams    anon_perms=None,
26ac13d5f3SPatrick Williams    admin_username=None,
27ac13d5f3SPatrick Williams    admin_password=None,
28ac13d5f3SPatrick Williams):
29ac13d5f3SPatrick Williams    def sqlite_engine():
30ac13d5f3SPatrick Williams        from .sqlite import DatabaseEngine
31475cb72dSAndrew Geissler
32ac13d5f3SPatrick Williams        return DatabaseEngine(dbname, sync)
33475cb72dSAndrew Geissler
34ac13d5f3SPatrick Williams    def sqlalchemy_engine():
35ac13d5f3SPatrick Williams        from .sqlalchemy import DatabaseEngine
36475cb72dSAndrew Geissler
37ac13d5f3SPatrick Williams        return DatabaseEngine(dbname, db_username, db_password)
38ac13d5f3SPatrick Williams
39a34c030eSBrad Bishop    from . import server
40ac13d5f3SPatrick Williams
41ac13d5f3SPatrick Williams    if "://" in dbname:
42ac13d5f3SPatrick Williams        db_engine = sqlalchemy_engine()
43ac13d5f3SPatrick Williams    else:
44ac13d5f3SPatrick Williams        db_engine = sqlite_engine()
45ac13d5f3SPatrick Williams
46ac13d5f3SPatrick Williams    if anon_perms is None:
47ac13d5f3SPatrick Williams        anon_perms = server.DEFAULT_ANON_PERMS
48ac13d5f3SPatrick Williams
49ac13d5f3SPatrick Williams    s = server.Server(
50ac13d5f3SPatrick Williams        db_engine,
51ac13d5f3SPatrick Williams        upstream=upstream,
52ac13d5f3SPatrick Williams        read_only=read_only,
53ac13d5f3SPatrick Williams        anon_perms=anon_perms,
54ac13d5f3SPatrick Williams        admin_username=admin_username,
55ac13d5f3SPatrick Williams        admin_password=admin_password,
56ac13d5f3SPatrick Williams    )
57a34c030eSBrad Bishop
58a34c030eSBrad Bishop    (typ, a) = parse_address(addr)
59a34c030eSBrad Bishop    if typ == ADDR_TYPE_UNIX:
60a34c030eSBrad Bishop        s.start_unix_server(*a)
61ac13d5f3SPatrick Williams    elif typ == ADDR_TYPE_WS:
62ac13d5f3SPatrick Williams        url = urlparse(a[0])
63ac13d5f3SPatrick Williams        s.start_websocket_server(url.hostname, url.port)
64a34c030eSBrad Bishop    else:
65a34c030eSBrad Bishop        s.start_tcp_server(*a)
66a34c030eSBrad Bishop
67a34c030eSBrad Bishop    return s
68a34c030eSBrad Bishop
69a34c030eSBrad Bishop
70ac13d5f3SPatrick Williamsdef create_client(addr, username=None, password=None):
71a34c030eSBrad Bishop    from . import client
72a34c030eSBrad Bishop
73ac13d5f3SPatrick Williams    c = client.Client(username, password)
74ac13d5f3SPatrick Williams
75ac13d5f3SPatrick Williams    try:
76a34c030eSBrad Bishop        (typ, a) = parse_address(addr)
77a34c030eSBrad Bishop        if typ == ADDR_TYPE_UNIX:
78a34c030eSBrad Bishop            c.connect_unix(*a)
79ac13d5f3SPatrick Williams        elif typ == ADDR_TYPE_WS:
80ac13d5f3SPatrick Williams            c.connect_websocket(*a)
81a34c030eSBrad Bishop        else:
82a34c030eSBrad Bishop            c.connect_tcp(*a)
83a34c030eSBrad Bishop        return c
84ac13d5f3SPatrick Williams    except Exception as e:
85ac13d5f3SPatrick Williams        c.close()
86ac13d5f3SPatrick Williams        raise e
876ce62a20SAndrew Geissler
88ac13d5f3SPatrick Williams
89ac13d5f3SPatrick Williamsasync def create_async_client(addr, username=None, password=None):
906ce62a20SAndrew Geissler    from . import client
916ce62a20SAndrew Geissler
92ac13d5f3SPatrick Williams    c = client.AsyncClient(username, password)
93ac13d5f3SPatrick Williams
94ac13d5f3SPatrick Williams    try:
956ce62a20SAndrew Geissler        (typ, a) = parse_address(addr)
966ce62a20SAndrew Geissler        if typ == ADDR_TYPE_UNIX:
976ce62a20SAndrew Geissler            await c.connect_unix(*a)
98ac13d5f3SPatrick Williams        elif typ == ADDR_TYPE_WS:
99ac13d5f3SPatrick Williams            await c.connect_websocket(*a)
1006ce62a20SAndrew Geissler        else:
1016ce62a20SAndrew Geissler            await c.connect_tcp(*a)
1026ce62a20SAndrew Geissler
1036ce62a20SAndrew Geissler        return c
104ac13d5f3SPatrick Williams    except Exception as e:
105ac13d5f3SPatrick Williams        await c.close()
106ac13d5f3SPatrick Williams        raise e
107