Skip to content

Commit

Permalink
Unified service class user config checking
Browse files Browse the repository at this point in the history
Signed-off-by: Jim Easterbrook <jim@jim-easterbrook.me.uk>
  • Loading branch information
jim-easterbrook committed Aug 24, 2018
1 parent 7049972 commit 4bd88f3
Show file tree
Hide file tree
Showing 16 changed files with 154 additions and 200 deletions.
4 changes: 2 additions & 2 deletions src/pywws/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = '18.8.0'
_release = '1593'
_commit = '82498d3'
_release = '1594'
_commit = '7049972'
21 changes: 9 additions & 12 deletions src/pywws/examples/modules/aws_api_gw_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@

class ToService(pywws.service.CatchupDataService):
catchup = 100
fixed_data = {}
config = {
'http headers': (None, False, None),
'api url' : ('', True, None),
}
interval = timedelta(seconds=300)
logger = logger
service_name = service_name
Expand All @@ -82,21 +85,15 @@ class ToService(pywws.service.CatchupDataService):
"""

def __init__(self, context):
def __init__(self, context, check_params=True):
super(ToService, self).__init__(context, check_params)
# initialise rain history
last_update = context.status.get_datetime('last update', service_name)
if last_update:
last_update = context.calib_data.nearest(last_update)
self.last_rain = context.calib_data[last_update]['rain']
else:
self.last_rain = None
# get service params (headers are optional)
self.params = {
'headers' : context.params.get(service_name, 'http headers', None),
'api_url' : context.params.get(service_name, 'api url', ''),
}
# base class init
super(ToService, self).__init__(context)

@contextmanager
def session(self):
Expand All @@ -105,10 +102,10 @@ def session(self):

def upload_data(self, session, prepared_data={}, live=False):
try:
if self.params['headers'] is not None:
for header in eval(self.params['headers']):
if self.params['http headers']:
for header in eval(self.params['http headers']):
session.headers.update({header[0]: header[1]})
rsp = session.get(self.params['api_url'], params=prepared_data,
rsp = session.get(self.params['api url'], params=prepared_data,
timeout=60)
except Exception as ex:
return False, str(ex)
Expand Down
31 changes: 26 additions & 5 deletions src/pywws/service/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,31 @@ def full(self):


class ServiceBase(threading.Thread):
config = {}
interval = timedelta(seconds=40)

def __init__(self, context):
def __init__(self, context, check_params=True):
super(ServiceBase, self).__init__()
self.context = context
self.queue = Queue(self.start)
# get user configuration
self.params = {}
check = []
for key, (default, required, fixed_key) in self.config.items():
self.params[key] = context.params.get(
self.service_name, key, default)
if required:
check.append(key)
if fixed_key and self.params[key]:
self.fixed_data[fixed_key] = self.params[key]
# check values
if check_params:
self.check_params(*check)

def check_params(self, *keys):
for key in keys:
if not self.params[key]:
raise RuntimeError('"{}" not set in weather.ini'.format(key))

def run(self):
self.logger.debug('thread started ' + self.name)
Expand Down Expand Up @@ -101,9 +120,10 @@ def log(self, message):

class DataServiceBase(ServiceBase):
catchup = 7
fixed_data = {}

def __init__(self, context):
super(DataServiceBase, self).__init__(context)
def __init__(self, context, check_params=True):
super(DataServiceBase, self).__init__(context, check_params)
# check config
template = context.params.get(self.service_name, 'template')
if template == 'default':
Expand All @@ -117,7 +137,7 @@ def __init__(self, context):
self.templater = pywws.template.Template(context, use_locale=False)
self.template_file = StringIO(self.template)
# get time stamp of last uploaded data
self.last_update = self.context.status.get_datetime(
self.last_update = context.status.get_datetime(
'last update', self.service_name)
if not self.last_update:
self.last_update = datetime.utcnow() - timedelta(days=self.catchup)
Expand Down Expand Up @@ -304,11 +324,12 @@ def main(class_, argv=None):
args = parser.parse_args(argv[1:])
pywws.logger.setup_handler(args.verbose or 0)
with pywws.storage.pywws_context(args.data_dir) as context:
uploader = class_(context)
if 'register' in args and args.register:
uploader = class_(context, check_params=False)
uploader.register()
context.flush()
return 0
uploader = class_(context)
if issubclass(class_, FileService):
for file in args.file:
uploader.upload(option=os.path.abspath(file))
Expand Down
15 changes: 4 additions & 11 deletions src/pywws/service/copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,19 @@


class ToService(pywws.service.FileService):
config = {'directory' : ('', True, None)}
logger = logger
service_name = service_name

def __init__(self, context):
# base class init
super(ToService, self).__init__(context)
# get config
self.directory = context.params.get(service_name, 'directory', '')
if not self.directory:
raise RuntimeError('No directory specified in weather.ini')

@contextmanager
def session(self):
yield None

def upload_file(self, session, path):
try:
if not os.path.isdir(self.directory):
os.makedirs(self.directory)
shutil.copy(path, self.directory)
if not os.path.isdir(self.params['directory']):
os.makedirs(self.params['directory'])
shutil.copy(path, self.params['directory'])
except Exception as ex:
return False, str(ex)
return True, 'OK'
Expand Down
31 changes: 9 additions & 22 deletions src/pywws/service/cwop.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@


class ToService(pywws.service.LiveDataService):
config = {
'designator': ('', True, 'designator'),
'passcode' : ('-1', True, 'passcode'),
'latitude' : ('', True, 'latitude'),
'longitude' : ('', True, 'longitude'),
}
fixed_data = {'version': pywws.__version__}
interval = timedelta(seconds=290)
logger = logger
Expand All @@ -90,32 +96,13 @@ class ToService(pywws.service.LiveDataService):
'rain_24hr' : #calc "100.0*rain_inch(rain_24hr(data))" "'%03.0f'," "'...',"#
"""

def __init__(self, context):
# get configurable "fixed data"
self.fixed_data.update({
'designator': context.params.get(
service_name, 'designator', ''),
'passcode': context.params.get(
service_name, 'passcode', '-1'),
'latitude': context.params.get(
service_name, 'latitude', ''),
'longitude': context.params.get(
service_name, 'longitude', ''),
})
# set server
self.params = {}
if self.fixed_data['passcode'] == '-1':
self.params['server'] = 'cwop.aprs.net', 14580
else:
self.params['server'] = 'rotate.aprs.net', 14580
# base class init
super(ToService, self).__init__(context)

@contextmanager
def session(self):
session = socket.socket()
session.settimeout(20)
session.connect(self.params['server'])
server = ('rotate.aprs.net',
'cwop.aprs.net')[self.fixed_data['passcode'] == '-1']
session.connect((server, 14580))
response = session.recv(4096)
logger.debug('server software: %s', response.strip())
try:
Expand Down
21 changes: 10 additions & 11 deletions src/pywws/service/ftp.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,19 @@


class ToService(pywws.service.FileService):
config = {
'site' : ('', True, None),
'user' : ('', True, None),
'password' : ('', True, None),
'directory' : ('', True, None),
'port' : ('21', True, None),
}
logger = logger
service_name = service_name

def __init__(self, context):
# base class init
super(ToService, self).__init__(context)
# get config
self.params = {}
for key in ('site', 'user', 'password', 'directory'):
self.params[key] = context.params.get(service_name, key, '')
self.params['port'] = eval(context.params.get(service_name, 'port', '21'))
for key in self.params:
if not self.params[key]:
raise RuntimeError('No {} specified in weather.ini'.format(key))
def __init__(self, context, check_params=True):
super(ToService, self).__init__(context, check_params)
self.params['port'] = eval(self.params['port'])

@contextmanager
def session(self):
Expand Down
26 changes: 10 additions & 16 deletions src/pywws/service/mastodon.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,28 +167,23 @@


class ToService(pywws.service.FileService):
config = {
'handle' : ('', True, None),
'access_token': (None, True, None),
}
logger = logger
service_name = service_name

def __init__(self, context):
# check config
handle = context.params.get(service_name, 'handle', '')
if not handle:
raise RuntimeError('No user handle specified in weather.ini')
def __init__(self, context, check_params=True):
super(ToService, self).__init__(context, check_params)
# get default character encoding of template output
self.encoding = context.params.get(
'config', 'template encoding', 'iso-8859-1')
# base class init
super(ToService, self).__init__(context)

@contextmanager
def session(self):
handle = self.context.params.get(service_name, 'handle')
api_base_url = handle.split('@')[-1]
access_token = self.context.params.get(service_name, 'access_token')
if not access_token:
raise RuntimeError('Authentication data not found')
yield Mastodon(access_token=access_token, api_base_url=api_base_url)
yield Mastodon(access_token=self.params['access_token'],
api_base_url=self.params['handle'].split('@')[-1])

def upload_file(self, session, filename):
with codecs.open(filename, 'r', encoding=self.encoding) as toot_file:
Expand All @@ -213,9 +208,8 @@ def upload_file(self, session, filename):
def register(self):
import webbrowser

# get user handle
handle = self.context.params.get(service_name, 'handle')
api_base_url = handle.split('@')[-1]
self.check_params('handle')
api_base_url = self.params['handle'].split('@')[-1]
# get client data
client_id = self.context.params.get(service_name, 'client_id')
client_secret = self.context.params.get(service_name, 'client_secret')
Expand Down
16 changes: 6 additions & 10 deletions src/pywws/service/metoffice.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@


class ToService(pywws.service.CatchupDataService):
config = {
'site id': ('', True, 'siteid'),
'aws pin': ('', True, 'siteAuthenticationKey'),
}
fixed_data = {'softwaretype': 'pywws-' + pywws.__version__}
interval = timedelta(seconds=300)
logger = logger
Expand All @@ -82,23 +86,15 @@ class ToService(pywws.service.CatchupDataService):
#calc "temp_f(dew_point(data['temp_out'], data['hum_out']))" "'dewptf': '%.1f',"#
"""

def __init__(self, context):
def __init__(self, context, check_params=True):
super(ToService, self).__init__(context, check_params)
# initialise rain history
last_update = context.status.get_datetime('last update', service_name)
if last_update:
last_update = context.calib_data.nearest(last_update)
self.last_rain = context.calib_data[last_update]['rain']
else:
self.last_rain = None
# get configurable "fixed data"
self.fixed_data.update({
'siteid' : context.params.get(
service_name, 'site id', ''),
'siteAuthenticationKey': context.params.get(
service_name, 'aws pin', ''),
})
# base class init
super(ToService, self).__init__(context)

@contextmanager
def session(self):
Expand Down
43 changes: 17 additions & 26 deletions src/pywws/service/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,18 @@


class ToService(pywws.service.LiveDataService):
fixed_data = {}
interval = timedelta(seconds=40)
config = {
'topic' : ('/weather/pywws', True, None),
'hostname' : ('localhost', True, None),
'port' : ('1883', True, None),
'client_id' : ('pywws', True, None),
'retain' : ('False', True, None),
'user' : ('', False, None),
'password' : ('', False, None),
'tls_cert' : ('', False, None),
'tls_ver' : ('1', True, None),
'multi_topic': ('False', True, None),
}
logger = logger
service_name = service_name
template = """
Expand All @@ -154,33 +164,16 @@ class ToService(pywws.service.LiveDataService):
"""

def __init__(self, context):
# get configurable data
self.params = {
'topic' : context.params.get(
service_name, 'topic', '/weather/pywws'),
'hostname' : context.params.get(
service_name, 'hostname', 'localhost'),
'port' : eval(context.params.get(
service_name, 'port', '1883')),
'client_id' : context.params.get(
service_name, 'client_id', 'pywws'),
'retain' : eval(context.params.get(
service_name, 'retain', 'False')),
'user' : context.params.get(service_name, 'user', ''),
'password' : context.params.get(service_name, 'password', ''),
'tls_cert' : context.params.get(service_name, 'tls_cert', ''),
'tls_ver' : eval(context.params.get(service_name, 'tls_ver', '1')),
'multi_topic': eval(context.params.get(
service_name, 'multi_topic', 'False')),
}
def __init__(self, context, check_params=True):
super(ToService, self).__init__(context, check_params)
# get template text
template = eval(context.params.get(
service_name, 'template_txt', pprint.pformat(self.template)))
logger.log(logging.DEBUG - 1, 'template:\n' + template)
self.template = "#live#" + template
# base class init
super(ToService, self).__init__(context)
# convert some params from string
for key in ('port', 'retain', 'tls_ver', 'multi_topic'):
self.params[key] = eval(self.params[key])

@contextmanager
def session(self):
Expand All @@ -193,10 +186,8 @@ def session(self):
session.username_pw_set(self.params['user'])
logger.debug(('connecting to host {hostname:s}:{port:d} '
'with client_id "{client_id:s}"').format(**self.params))

if self.params['tls_cert']:
session.tls_set(self.params['tls_cert'], tls_version=self.params['tls_ver'])

session.connect(self.params['hostname'], self.params['port'])
try:
yield session
Expand Down

0 comments on commit 4bd88f3

Please sign in to comment.