@@ -90,193 +90,192 @@ class BaseDbModel(object):
for k, val in _json_attr.items():
d[k] = val
return d
def get_appstruct(self):
"""return list with keys and values tuples corresponding
to this model data """
return [
(k, getattr(self, k))
for k in self._get_keys()
]
def populate_obj(self, populate_dict):
"""populate model with data from given populate_dict"""
for k in self._get_keys():
if k in populate_dict:
setattr(self, k, populate_dict[k])
@classmethod
def query(cls):
return Session().query(cls)
def get(cls, id_):
if id_:
return cls.query().get(id_)
def guess_instance(cls, value, callback=None):
"""Haphazardly attempt to convert `value` to a `cls` instance.
If `value` is None or already a `cls` instance, return it. If `value`
is a number (or looks like one if you squint just right), assume it's
a database primary key and let SQLAlchemy sort things out. Otherwise,
fall back to resolving it using `callback` (if specified); this could
e.g. be a function that looks up instances by name (though that won't
work if the name begins with a digit). Otherwise, raise Exception.
"""
if value is None:
return None
if isinstance(value, cls):
return value
if isinstance(value, int):
return cls.get(value)
if isinstance(value, str) and value.isdigit():
return cls.get(int(value))
if callback is not None:
return callback(value)
raise Exception(
'given object must be int, long or Instance of %s '
'got %s, no callback provided' % (cls, type(value))
)
def get_or_404(cls, id_):
try:
id_ = int(id_)
except (TypeError, ValueError):
raise HTTPNotFound
res = cls.query().get(id_)
if res is None:
return res
def delete(cls, id_):
obj = cls.query().get(id_)
Session().delete(obj)
def __repr__(self):
return '<DB:%s>' % (self.__class__.__name__)
_table_args_default_dict = {'extend_existing': True,
'mysql_engine': 'InnoDB',
'sqlite_autoincrement': True,
}
class Setting(Base, BaseDbModel):
__tablename__ = 'settings'
__table_args__ = (
_table_args_default_dict,
SETTINGS_TYPES = {
'str': safe_bytes,
'int': safe_int,
'unicode': safe_str,
'bool': asbool,
'list': functools.partial(aslist, sep=',')
DEFAULT_UPDATE_URL = ''
app_settings_id = Column(Integer(), primary_key=True)
app_settings_name = Column(String(255), nullable=False, unique=True)
_app_settings_value = Column("app_settings_value", Unicode(4096), nullable=False)
_app_settings_type = Column("app_settings_type", String(255), nullable=True) # FIXME: not nullable?
def __init__(self, key='', val='', type='unicode'):
self.app_settings_name = key
self.app_settings_value = val
self.app_settings_type = type
@validates('_app_settings_value')
def validate_settings_value(self, key, val):
assert isinstance(val, str)
return val
@hybrid_property
def app_settings_value(self):
v = self._app_settings_value
_type = self.app_settings_type
converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode']
return converter(v)
@app_settings_value.setter
def app_settings_value(self, val):
Setter that will always make sure we use str in app_settings_value
self._app_settings_value = safe_str(val)
def app_settings_type(self):
return self._app_settings_type
@app_settings_type.setter
def app_settings_type(self, val):
if val not in self.SETTINGS_TYPES:
raise Exception('type must be one of %s got %s'
% (list(self.SETTINGS_TYPES), val))
self._app_settings_type = val
return "<%s %s.%s=%r>" % (
self.__class__.__name__,
self.app_settings_name, self.app_settings_type, self.app_settings_value
def get_by_name(cls, key):
return cls.query() \
.filter(cls.app_settings_name == key).scalar()
def get_by_name_or_create(cls, key, val='', type='unicode'):
res = cls.get_by_name(key)
res = cls(key, val, type)
def create_or_update(cls, key, val=Optional(''), type=Optional('unicode')):
Creates or updates Kallithea setting. If updates are triggered, it will only
update parameters that are explicitly set. Optional instance will be skipped.
:param key:
:param val:
:param type:
:return:
val = Optional.extract(val)
type = Optional.extract(type)
Session().add(res)
else:
res.app_settings_name = key
if not isinstance(val, Optional):
# update if set
res.app_settings_value = val
if not isinstance(type, Optional):
res.app_settings_type = type
def get_app_settings(cls):
ret = cls.query()
if ret is None:
raise Exception('Could not get application settings !')
settings = {}
for each in ret:
settings[each.app_settings_name] = \
each.app_settings_value
Status change: