62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
import json
|
|
from .data import SourcePoint # So we don't have to import this in profiles
|
|
from . import etree
|
|
|
|
|
|
class ProfileException(Exception):
|
|
"""An exception class for the Profile instance."""
|
|
def __init__(self, attr, desc):
|
|
super().__init__('Field missing in profile: {} ({})'.format(attr, desc))
|
|
|
|
|
|
class Profile:
|
|
"""A wrapper for a profile.
|
|
|
|
A profile is a python script that sets a few local variables.
|
|
These variables become properties of the profile, accessible with
|
|
a "get" method. If something is a function, it will be called,
|
|
optional parameters might be passed to it.
|
|
|
|
You can compile a list of all supported variables by grepping through
|
|
this code, or by looking at a few example profiles. If something
|
|
is required, you will be notified of that.
|
|
"""
|
|
def __init__(self, fileobj, par=None):
|
|
global param
|
|
param = par
|
|
if isinstance(fileobj, dict):
|
|
self.profile = fileobj
|
|
elif hasattr(fileobj, 'read'):
|
|
s = fileobj.read().replace('\r', '')
|
|
if s[0] == '{':
|
|
self.profile = json.loads(s)
|
|
else:
|
|
self.profile = {}
|
|
exec(s, globals(), self.profile)
|
|
else:
|
|
# Got a class
|
|
self.profile = {name: getattr(fileobj, name)
|
|
for name in dir(fileobj) if not name.startswith('_')}
|
|
self.max_distance = self.get('max_distance', 100)
|
|
|
|
def has(self, attr):
|
|
return attr in self.profile
|
|
|
|
def get(self, attr, default=None, required=None, args=None):
|
|
if attr in self.profile:
|
|
value = self.profile[attr]
|
|
if callable(value):
|
|
if args is None:
|
|
return value()
|
|
else:
|
|
return value(*args)
|
|
else:
|
|
return value
|
|
if required is not None:
|
|
raise ProfileException(attr, required)
|
|
return default
|
|
|
|
def get_raw(self, attr, default=None):
|
|
if attr in self.profile:
|
|
return self.profile[attr]
|
|
return default
|