Sunil Mohan Adapa 4100d36381
Introduce webserver component for managing Apache configuration
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2019-06-13 20:17:49 -04:00

142 lines
4.1 KiB
Python

#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Base class for all Freedombox applications.
"""
import collections
class App:
"""Implement common functionality for an app.
An app is composed of components which actually performs various tasks. App
itself delegates tasks for individual components. Applications can show a
variation their behavior by choosing which components to have and by
customizing the components themselves.
"""
def __init__(self):
"""Initialize the app object."""
self.components = collections.OrderedDict()
def add(self, component):
"""Add a component to an app."""
self.components[component.component_id] = component
return self
def remove(self, component_id):
"""Remove a component from the app."""
component = self.components[component_id]
del self.components[component_id]
return component
def get(self, component_id):
"""Return a component given the component's ID."""
return self.components[component_id]
def enable(self):
"""Enable all the components of the app."""
for component in self.components.values():
component.enable()
def disable(self):
"""Enable all the components of the app."""
for component in reversed(self.components.values()):
component.disable()
def is_enabled(self):
"""Return whether all the leader components are enabled."""
return all((component.is_enabled()
for component in self.components.values()
if component.is_leader))
def set_enabled(self, enabled):
"""Update the status of all follower components.
Do not query or update the status of the leader components.
"""
for component in self.components.values():
if not component.is_leader:
component.set_enabled(enabled)
class Component:
"""Interface for an app component."""
is_leader = False
def __init__(self, component_id):
"""Intialize the component."""
if not component_id:
raise ValueError('Invalid component ID')
self.component_id = component_id
def enable(self):
"""Run operations to enable the component."""
def disable(self):
"""Run operations to disable the component."""
class FollowerComponent(Component):
"""Interface for an app component that follows other components.
These components of the app don't determine if the app is enabled or not.
"""
is_leader = False
def __init__(self, component_id, is_enabled=False):
"""Intialize the component."""
super().__init__(component_id)
self._is_enabled = is_enabled
def is_enabled(self):
"""Return whether the component is enabled."""
return self._is_enabled
def set_enabled(self, enabled):
"""Update the internal enabled state of the component."""
self._is_enabled = enabled
def enable(self):
"""Run operations to enable the component."""
self._is_enabled = True
def disable(self):
"""Run operations to disable the component."""
self._is_enabled = False
class LeaderComponent(Component):
"""Interface for an app component that decides the state of the app.
These components determine if the app is enabled or not.
"""
is_leader = True
def is_enabled(self):
"""Return if the component is enabled."""
raise NotImplementedError