Skip to content

Commit

Permalink
Add /api/system endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
ccrisan committed Oct 11, 2020
1 parent 9a2f3c5 commit 0de97f8
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 0 deletions.
3 changes: 3 additions & 0 deletions qtoggleserver/commands/__init__.py
Expand Up @@ -2,6 +2,7 @@
import argparse
import asyncio
import logging.config
import os
import signal
import sys
import types
Expand Down Expand Up @@ -93,6 +94,8 @@ def init_settings() -> None:
sys.stderr.write(f'failed to load config file "{options.config_file}": {e}\n')
sys.exit(-1)

settings.source = os.path.abspath(options.config_file)

else:
parsed_config = {}

Expand Down
2 changes: 2 additions & 0 deletions qtoggleserver/conf/settings.py
Expand Up @@ -2,6 +2,8 @@
import typing as _typing


source: _typing.Optional[str] = None # Full path to the configuration file, automatically set at startup

debug: bool = False

public_url: _typing.Optional[str] = None
Expand Down
1 change: 1 addition & 0 deletions qtoggleserver/system/__init__.py
Expand Up @@ -7,6 +7,7 @@
from qtoggleserver.conf import settings

from . import battery
from . import conf
from . import date
from . import dns
from . import fwupdate
Expand Down
Empty file.
20 changes: 20 additions & 0 deletions qtoggleserver/system/api/funcs.py
@@ -0,0 +1,20 @@

from qtoggleserver.conf import settings
from qtoggleserver.core import api as core_api
from qtoggleserver.core.typing import GenericJSONDict
from qtoggleserver.system import conf as system_conf
from qtoggleserver.utils import conf as conf_utils


@core_api.api_call(core_api.ACCESS_LEVEL_ADMIN)
async def get_system(request: core_api.APIRequest) -> GenericJSONDict:
return conf_utils.config_from_file(settings.source)


@core_api.api_call(core_api.ACCESS_LEVEL_ADMIN)
async def put_system(request: core_api.APIRequest, params: GenericJSONDict) -> None:
# Update in-memory settings (no effect guaranteed without a restart, though)
conf_utils.update_obj_from_dict(settings, params)

# Update config file
system_conf.conf_file_from_dict(params)
38 changes: 38 additions & 0 deletions qtoggleserver/system/conf.py
@@ -0,0 +1,38 @@

from typing import Any, Dict

import logging
import os

from qtoggleserver.conf import settings
from qtoggleserver.utils import conf as conf_utils


logger = logging.getLogger(__name__)


def can_write_conf_file() -> bool:
if not settings.source:
return False

return os.access(settings.source, os.W_OK)


def conf_file_to_dict() -> Dict[str, Any]:
if not can_write_conf_file():
raise Exception('Configuration file not available')

return conf_utils.config_from_file(settings.source)


def conf_file_from_dict(d: Dict[str, Any]) -> None:
if not can_write_conf_file():
raise Exception('Configuration file not available')

logger.debug('updating configuration file %s', settings.source)

config = conf_utils.config_from_dict(d)
config_str = conf_utils.config_to_str(config)

with open(settings.source, 'wt') as f:
f.write(config_str)
4 changes: 4 additions & 0 deletions qtoggleserver/utils/conf.py
Expand Up @@ -45,6 +45,10 @@ def config_from_dict(d: Dict[str, Any]) -> pyhocon.ConfigTree:
return _config_factory.from_dict(d)


def config_to_str(config: pyhocon.ConfigTree) -> str:
return pyhocon.HOCONConverter.to_hocon(config, indent=4, compact=False)


def config_to_dict(config: pyhocon.ConfigTree) -> OrderedDict:
return config.as_plain_ordered_dict()

Expand Down
9 changes: 9 additions & 0 deletions qtoggleserver/web/handlers.py
Expand Up @@ -15,6 +15,7 @@
from qtoggleserver.core.api import funcs as core_api_funcs
from qtoggleserver.core.device import attrs as core_device_attrs
from qtoggleserver.slaves.api import funcs as slaves_api_funcs
from qtoggleserver.system.api import funcs as system_api_funcs
from qtoggleserver.ui.api import funcs as ui_api_funcs
from qtoggleserver.utils import json as json_utils

Expand Down Expand Up @@ -356,3 +357,11 @@ async def get(self) -> None:

async def put(self) -> None:
await self.call_api_func(ui_api_funcs.put_prefs, default_status=204)


class SystemHandler(APIHandler):
async def get(self) -> None:
await self.call_api_func(system_api_funcs.get_system)

async def put(self) -> None:
await self.call_api_func(system_api_funcs.put_system, default_status=204)
9 changes: 9 additions & 0 deletions qtoggleserver/web/server.py
Expand Up @@ -6,6 +6,7 @@
from tornado.web import Application, RequestHandler, URLSpec
from qui.web import tornado as qui_tornado

from qtoggleserver import system
from qtoggleserver.conf import settings
from qtoggleserver.slaves.discover import is_enabled as is_discover_enabled
from qtoggleserver.web import handlers
Expand Down Expand Up @@ -104,6 +105,14 @@ def _make_routing_table() -> List[URLSpec]:
URLSpec(r'^/api/reverse/?$', handlers.ReverseHandler)
]

# System API calls
if system.conf.can_write_conf_file():
handlers_list += [
URLSpec(r'^/api/system/?$', handlers.SystemHandler)
]

# Default 404 API handler

handlers_list += [
URLSpec(r'^/api/.*$', handlers.NoSuchFunctionHandler)
]
Expand Down

0 comments on commit 0de97f8

Please sign in to comment.