diff --git a/sylk/applications/conference/configuration.py b/sylk/applications/conference/configuration.py index b341048..ea57d3f 100644 --- a/sylk/applications/conference/configuration.py +++ b/sylk/applications/conference/configuration.py @@ -1,132 +1,132 @@ # Copyright (C) 2010-2011 AG Projects. See LICENSE for details. # __all__ = ['ConferenceConfig', 'get_room_config'] import re from application.configuration import ConfigFile, ConfigSection, ConfigSetting from application.configuration.datatypes import StringList, Hostname from application.system import host from sylk.configuration.datatypes import IPAddress, Path, Port -from sylk.resources import Resources +from sylk.resources import Resources, VarResources # Datatypes class AccessPolicyValue(str): allowed_values = ('allow,deny', 'deny,allow') def __new__(cls, value): value = re.sub('\s', '', value) if value not in cls.allowed_values: raise ValueError('invalid value, allowed values are: %s' % ' | '.join(cls.allowed_values)) return str.__new__(cls, value) class Domain(str): domain_re = re.compile(r"^[a-zA-Z0-9\-_]+(\.[a-zA-Z0-9\-_]+)*$") def __new__(cls, value): value = str(value) if not cls.domain_re.match(value): raise ValueError("illegal domain: %s" % value) return str.__new__(cls, value) class SIPAddress(str): def __new__(cls, address): address = str(address) address = address.replace('@', '%40', address.count('@')-1) try: username, domain = address.split('@') Domain(domain) except ValueError: raise ValueError("illegal SIP address: %s, must be in user@domain format" % address) return str.__new__(cls, address) class PolicySettingValue(list): def __init__(self, value): if isinstance(value, (tuple, list)): l = [str(x) for x in value] elif isinstance(value, basestring): if value.lower() in ('none', ''): return list.__init__(self, []) elif value.lower() in ('any', 'all', '*'): return list.__init__(self, ['*']) else: l = re.split(r'\s*,\s*', value) else: raise TypeError("value must be a string, list or tuple") values = [] for item in l: if '@' in item: values.append(SIPAddress(item)) else: values.append(Domain(item)) return list.__init__(self, values) def match(self, uri): if self == ['*']: return True domain = uri.host uri = re.sub('^(sip:|sips:)', '', str(uri)) return uri in self or domain in self # Configuration objects class ConferenceConfig(ConfigSection): __cfgfile__ = 'conference.ini' __section__ = 'Conference' history_size = 20 access_policy = ConfigSetting(type=AccessPolicyValue, value=AccessPolicyValue('allow, deny')) allow = ConfigSetting(type=PolicySettingValue, value=PolicySettingValue('all')) deny = ConfigSetting(type=PolicySettingValue, value=PolicySettingValue('none')) - file_transfer_dir = ConfigSetting(type=Path, value=Path('var/spool/sylkserver')) + file_transfer_dir = ConfigSetting(type=Path, value=Path(VarResources.get('spool/sylkserver'))) push_file_transfer = False - screen_sharing_dir = ConfigSetting(type=Path, value=Path('var/spool/sylkserver/screensharing')) + screen_sharing_dir = ConfigSetting(type=Path, value=Path(VarResources.get('spool/sylkserver/screensharing'))) screen_sharing_ip = ConfigSetting(type=IPAddress, value=IPAddress(host.default_ip)) screen_sharing_hostname = ConfigSetting(type=Hostname, value=IPAddress(host.default_ip)) screen_sharing_port = ConfigSetting(type=Port, value=0) screen_sharing_use_https = True screen_sharing_certificate = ConfigSetting(type=Path, value=Path(Resources.get('tls/default.crt'))) advertise_xmpp_support = True pstn_access_numbers = ConfigSetting(type=StringList, value='') class RoomConfig(ConfigSection): __cfgfile__ = 'conference.ini' access_policy = ConfigSetting(type=AccessPolicyValue, value=AccessPolicyValue('allow, deny')) allow = ConfigSetting(type=PolicySettingValue, value=PolicySettingValue('all')) deny = ConfigSetting(type=PolicySettingValue, value=PolicySettingValue('none')) pstn_access_numbers = ConferenceConfig.pstn_access_numbers advertise_xmpp_support = ConferenceConfig.advertise_xmpp_support class Configuration(object): def __init__(self, data): self.__dict__.update(data) def get_room_config(room): config_file = ConfigFile(RoomConfig.__cfgfile__) section = config_file.get_section(room) if section is not None: RoomConfig.read(section=room) config = Configuration(dict(RoomConfig)) RoomConfig.reset() else: # Apply general policy config = Configuration(dict(RoomConfig)) return config diff --git a/sylk/configuration/__init__.py b/sylk/configuration/__init__.py index 02ec556..5a978d0 100644 --- a/sylk/configuration/__init__.py +++ b/sylk/configuration/__init__.py @@ -1,78 +1,78 @@ # Copyright (C) 2010-2011 AG Projects. See LICENSE for details. # from application.configuration import ConfigSection, ConfigSetting from application.configuration.datatypes import NetworkRangeList, StringList from application.system import host from sipsimple.configuration.datatypes import NonNegativeInteger, SampleRate from sylk import configuration_filename from sylk.configuration.datatypes import AudioCodecs, IPAddress, Path, Port, PortRange, SIPProxyAddress, SRTPEncryption -from sylk.resources import Resources +from sylk.resources import Resources, VarResources from sylk.tls import Certificate, PrivateKey class ServerConfig(ConfigSection): __cfgfile__ = configuration_filename __section__ = 'Server' ca_file = ConfigSetting(type=Path, value=Path(Resources.get('tls/ca.crt'))) certificate = ConfigSetting(type=Path, value=Path(Resources.get('tls/default.crt'))) verify_server = False enable_bonjour = False default_application = 'conference' application_map = ConfigSetting(type=StringList, value=['echo:echo']) disabled_applications = ConfigSetting(type=StringList, value='') extra_applications_dir = ConfigSetting(type=Path, value=None) - trace_dir = ConfigSetting(type=Path, value=Path('var/log/sylkserver')) + trace_dir = ConfigSetting(type=Path, value=Path(VarResources.get('log/sylkserver'))) trace_core = False trace_sip = False trace_msrp = False trace_notifications = False class SIPConfig(ConfigSection): __cfgfile__ = configuration_filename __section__ = 'SIP' local_ip = ConfigSetting(type=IPAddress, value=IPAddress(host.default_ip)) local_udp_port = ConfigSetting(type=Port, value=5060) local_tcp_port = ConfigSetting(type=Port, value=5060) local_tls_port = ConfigSetting(type=Port, value=5061) advertised_ip = ConfigSetting(type=IPAddress, value=None) outbound_proxy = ConfigSetting(type=SIPProxyAddress, value=None) trusted_peers = ConfigSetting(type=NetworkRangeList, value=NetworkRangeList('any')) enable_ice = False class MSRPConfig(ConfigSection): __cfgfile__ = configuration_filename __section__ = 'MSRP' use_tls = True class RTPConfig(ConfigSection): __cfgfile__ = configuration_filename __section__ = 'RTP' audio_codecs = ConfigSetting(type=AudioCodecs, value=['opus', 'speex', 'G722', 'PCMA', 'PCMU']) port_range = ConfigSetting(type=PortRange, value=PortRange('50000:50500')) srtp_encryption = ConfigSetting(type=SRTPEncryption, value='opportunistic') timeout = ConfigSetting(type=NonNegativeInteger, value=30) sample_rate = ConfigSetting(type=SampleRate, value=32000) - zrtp_cache_dir = ConfigSetting(type=Path, value=Path('var/spool/sylkserver')) + zrtp_cache_dir = ConfigSetting(type=Path, value=Path(VarResources.get('spool/sylkserver'))) class ThorNodeConfig(ConfigSection): __cfgfile__ = configuration_filename __section__ = 'ThorNetwork' enabled = False domain = "sipthor.net" multiply = 1000 certificate = ConfigSetting(type=Certificate, value=None) private_key = ConfigSetting(type=PrivateKey, value=None) ca = ConfigSetting(type=Certificate, value=None) diff --git a/sylk/resources.py b/sylk/resources.py index 2dcdd23..c01b53b 100644 --- a/sylk/resources.py +++ b/sylk/resources.py @@ -1,32 +1,52 @@ # Copyright (C) 2015 AG Projects. See LICENSE for details. # import os import sys from application.python.descriptor import classproperty class Resources(object): """Provide access to SylkServer's resources""" _cached_directory = None @classproperty def directory(cls): if cls._cached_directory is None: - script = sys.argv[0] - binary_directory = os.path.dirname(os.path.realpath(script)) + binary_directory = os.path.dirname(os.path.realpath(sys.argv[0])) if os.path.basename(binary_directory) == 'bin': application_directory = os.path.dirname(binary_directory) resources_component = 'share/sylkserver' else: application_directory = binary_directory resources_component = 'resources' cls._cached_directory = os.path.join(application_directory, resources_component).decode(sys.getfilesystemencoding()) return cls._cached_directory @classmethod def get(cls, resource): return os.path.join(cls.directory, resource or u'') + +class VarResources(object): + """Provide access to SylkServer's resources that should go in /var""" + + _cached_directory = None + + @classproperty + def directory(cls): + if cls._cached_directory is None: + binary_directory = os.path.dirname(os.path.realpath(sys.argv[0])) + if os.path.basename(binary_directory) == 'bin': + path = '/var' + else: + path = 'var' + cls._cached_directory = os.path.abspath(path).decode(sys.getfilesystemencoding()) + return cls._cached_directory + + @classmethod + def get(cls, resource): + return os.path.join(cls.directory, resource or u'') +