GEOFFREY v0.1.2 Documentation

geoffrey.server

Contents

Source code for geoffrey.server

import asyncio
import configparser
import logging
import os
import signal
from sys import platform

import websockets

from .project import Project
from geoffrey import defaults
from geoffrey import hub
from geoffrey import utils
from geoffrey.websocket import WebsocketServer

from geoffrey.webserver import WebServer


DEFAULT_CONFIG_ROOT = os.path.join(os.path.expanduser('~'), '.geoffrey')
DEFAULT_CONFIG_FILENAME = os.path.join(DEFAULT_CONFIG_ROOT, 'geoffrey.conf')
STATES_FILE = os.path.join(DEFAULT_CONFIG_ROOT, 'states.pickle')

logger = logging.getLogger(__name__)


[docs]class Server: """The Geoffrey server.""" def __init__(self, config=DEFAULT_CONFIG_FILENAME): logger.info("Starting Geoffrey server!") self.configfile = config self.config = self.read_main_config(filename=self.configfile) if not os.path.isdir(self.projects_root): os.makedirs(self.projects_root) self.loop = asyncio.get_event_loop() self.projects = self._get_projects() self.hub = hub.get_hub() # Strong references of the server's tasks to prevent garbage # collection. self.tasks = [] self.consumers = {} if os.path.isfile(STATES_FILE): self.hub.restore_states(STATES_FILE) @property
[docs] def projects_root(self): """Returns the projects directory.""" return self.config.get( 'projects', 'root', fallback=os.path.join(os.path.dirname(self.configfile), 'projects'))
def _get_projects(self): """Gets all the projects.""" projects = {} for name in os.listdir(self.projects_root): project_root = os.path.join(self.projects_root, name) if os.path.isdir(project_root): project_config = os.path.join(project_root, 'project.conf') if os.path.isfile(project_config): projects[name] = Project(name=name, config=project_config) return projects @staticmethod
[docs] def read_main_config(filename=DEFAULT_CONFIG_FILENAME): """Read server configuration.""" config = configparser.ConfigParser() if os.path.exists(filename): if not os.path.isfile(filename): raise TypeError('Config file is not a regular file.') else: # Config does not exists. Create the default one. root = os.path.dirname(filename) if not os.path.exists(root): os.makedirs(root) utils.write_template(filename, defaults.GEOFFREY_CONFIG_DEFAULT) config.read(filename) return config
[docs] def handle_ctrl_c(self): """Control Ctrl-C to the server.""" logger.warning("Pressed Ctrl-C. Exiting.") self.hub.save_states(STATES_FILE) self.loop.stop()
[docs] def run(self): """Run the server.""" websocket_server_host = self.config.get( 'geoffrey', 'websocket_server_host', fallback='127.0.0.1') websocket_server_port = self.config.getint( 'geoffrey', 'websocket_server_port', fallback=8701) # WEBSERVER web_app = WebServer(server=self) web_app.start() # WEBSOCKET SERVER wss = websockets.serve(WebsocketServer(self.consumers).server, websocket_server_host, websocket_server_port) self.tasks.append(asyncio.Task(wss)) # HUB self.tasks.append(asyncio.Task(self.hub.run())) logger.debug("Starting the main loop.") if platform == 'win32': try: self.loop.run_forever() except KeyboardInterrupt: self.handle_ctrl_c() else: self.loop.add_signal_handler(signal.SIGINT, self.handle_ctrl_c) self.loop.run_forever()
[docs] def create_project(self, project_name): """Create a new project.""" project_root = os.path.join(self.projects_root, project_name) os.makedirs(project_root) project_config = os.path.join(project_root, 'project.conf') self.projects[project_name] = Project(name=project_name, config=project_config)
[docs] def delete_project(self, project_name): """Delete a project.""" if project_name in self.projects: project = self.projects.pop(project_name) project.remove() else: raise RuntimeError("Geoffrey can't delete unmanaged projects.")

Contents