3
0
Fork 0

Compare commits

..

4 commits

20 changed files with 76 additions and 43 deletions

View file

@ -2,4 +2,8 @@
[MESSAGES CONTROL]
disable=all
enable=dangerous-default-value
enable=dangerous-default-value,
inconsistent-return-statements,
redefined-argument-from-local,
unspecified-encoding,
unused-import,

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -24,7 +24,6 @@
WuttJamaican - app handler
"""
import datetime
import importlib
import logging
import os
@ -230,7 +229,7 @@ class AppHandler:
If ``obj`` is *not* specified, this behaves a bit differently.
It first will look for a :term:`config setting` named
``wutta.app_dist`` (or similar, dpending on :attr:`appname`).
``wutta.app_dist`` (or similar, depending on :attr:`appname`).
If there is such a config value, it is returned. Otherwise
the "auto-locate" logic described above happens, but using
``self`` instead of ``obj``.
@ -281,8 +280,7 @@ class AppHandler:
return dist
# fall back to configured dist, if obj lookup failed
if obj is not None:
return self.config.get(f'{self.appname}.app_dist')
return self.config.get(f'{self.appname}.app_dist')
def get_version(self, dist=None, obj=None):
"""
@ -302,6 +300,7 @@ class AppHandler:
dist = self.get_distribution(obj=obj)
if dist:
return version(dist)
return None
def get_model(self):
"""
@ -464,7 +463,7 @@ class AppHandler:
"""
output = template.render(**context)
if output_path:
with open(output_path, 'wt') as f:
with open(output_path, 'wt', encoding='utf_8') as f:
f.write(output)
return output

View file

@ -93,6 +93,7 @@ class AuthHandler(GenericHandler):
if user and user.active and user.password:
if self.check_user_password(user, password):
return user
return None
def authenticate_user_token(self, session, token):
"""
@ -122,6 +123,7 @@ class AuthHandler(GenericHandler):
user = token.user
if user.active:
return user
return None
def check_user_password(self, user, password, **kwargs):
"""
@ -158,7 +160,7 @@ class AuthHandler(GenericHandler):
model = self.app.model
if not key:
return
return None
# maybe it is a uuid
if isinstance(key, _uuid.UUID):
@ -188,6 +190,7 @@ class AuthHandler(GenericHandler):
session=session)
if key:
return self.get_role(session, key)
return None
def get_user(self, obj, session=None, **kwargs):
"""
@ -256,6 +259,7 @@ class AuthHandler(GenericHandler):
person = self.app.get_person(obj)
if person:
return person.user
return None
def make_person(self, **kwargs):
"""

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -25,7 +25,6 @@ WuttJamaican - app configuration
"""
import configparser
import importlib
import logging
import logging.config
import os
@ -274,7 +273,7 @@ class WuttaConfig:
# re-write as temp file with "final" values
fd, temp_path = tempfile.mkstemp(suffix='.ini')
os.close(fd)
with open(temp_path, 'wt') as f:
with open(temp_path, 'wt', encoding='utf_8') as f:
temp_config.write(f)
# and finally, load that into our main config
@ -286,14 +285,14 @@ class WuttaConfig:
# bring in any "required" files
requires = config.get(f'{self.appname}.config.require')
if requires:
for path in self.parse_list(requires):
self._load_ini_configs(path, configs, require=True)
for p in self.parse_list(requires):
self._load_ini_configs(p, configs, require=True)
# bring in any "included" files
includes = config.get(f'{self.appname}.config.include')
if includes:
for path in self.parse_list(includes):
self._load_ini_configs(path, configs, require=False)
for p in self.parse_list(includes):
self._load_ini_configs(p, configs, require=False)
def get_prioritized_files(self):
"""
@ -467,6 +466,8 @@ class WuttaConfig:
if default is not UNSPECIFIED:
return default
return None
def get_from_db(self, key, session=None, **kwargs):
"""
Retrieve a config value from database settings table.
@ -511,6 +512,7 @@ class WuttaConfig:
value = self.get(*args, **kwargs)
if value is not None:
return int(value)
return None
def get_list(self, *args, **kwargs):
"""
@ -525,6 +527,7 @@ class WuttaConfig:
value = self.get(*args, **kwargs)
if value is not None:
return self.parse_list(value)
return None
def get_dict(self, prefix):
"""
@ -611,7 +614,7 @@ class WuttaConfig:
# write INI file and return path
fd, path = tempfile.mkstemp(suffix='.conf')
os.close(fd)
with open(path, 'wt') as f:
with open(path, 'wt', encoding='utf_8') as f:
parser.write(f)
return path

View file

@ -45,7 +45,7 @@ import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.ext.associationproxy import association_proxy
from .base import Base, uuid_column, uuid_fk_column
from . import Base, uuid_column, uuid_fk_column
class Role(Base):

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -36,8 +36,7 @@ import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.ext.associationproxy import association_proxy
from wuttjamaican.db.util import (naming_convention, ModelBase,
uuid_column, uuid_fk_column)
from wuttjamaican.db.util import naming_convention, ModelBase, uuid_column
class WuttaModelBase(ModelBase):
@ -215,3 +214,4 @@ class Person(Base):
if self.users:
return self.users[0]
return None

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -31,7 +31,7 @@ from sqlalchemy import orm
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.orderinglist import ordering_list
from wuttjamaican.db.model import uuid_column, uuid_fk_column, User
from wuttjamaican.db.model import uuid_column, User
from wuttjamaican.db.util import UUID
@ -263,6 +263,7 @@ class BatchMixin:
"""
if self.id:
return f'{self.id:08d}'
return None
class BatchRowMixin:

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -29,7 +29,7 @@ import datetime
import sqlalchemy as sa
from sqlalchemy import orm
from .base import Base, uuid_column, uuid_fk_column
from . import Base, uuid_column, uuid_fk_column
from wuttjamaican.enum import UpgradeStatus
from wuttjamaican.db.util import UUID
from wuttjamaican.util import make_true_uuid

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -66,6 +66,7 @@ class ModelBase:
state = sa.inspect(self)
if hasattr(state.attrs, key):
return getattr(self, key)
raise KeyError(f"model instance has no attr with key: {key}")
class UUID(sa.types.TypeDecorator):

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -358,6 +358,7 @@ class EmailHandler(GenericHandler):
if instance:
setting = setting(self.config)
return setting
return None
def make_message(self, **kwargs):
"""
@ -573,6 +574,7 @@ class EmailHandler(GenericHandler):
if template:
context = context or {}
return template.render(**context)
return None
def get_auto_html_body(self, key, context=None):
"""
@ -585,6 +587,7 @@ class EmailHandler(GenericHandler):
if template:
context = context or {}
return template.render(**context)
return None
def get_auto_body_template(self, key, mode):
""" """
@ -601,6 +604,7 @@ class EmailHandler(GenericHandler):
return templates.get_template(f'{key}.{mode}.mako')
except TopLevelLookupException:
pass
return None
def get_notes(self, key):
"""
@ -652,8 +656,8 @@ class EmailHandler(GenericHandler):
:returns: True if this email type is enabled, otherwise false.
"""
for key in set([key, 'default']):
enabled = self.config.get_bool(f'{self.config.appname}.email.{key}.enabled')
for k in set([key, 'default']):
enabled = self.config.get_bool(f'{self.config.appname}.email.{k}.enabled')
if enabled is not None:
return enabled
return True

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -25,7 +25,6 @@ Install Handler
"""
import os
import shutil
import stat
import subprocess
import sys
@ -255,6 +254,7 @@ class InstallHandler(GenericHandler):
sa.inspect(engine).has_table('whatever')
except Exception as error:
return str(error)
return None
def make_template_context(self, dbinfo, **kwargs):
"""

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -88,3 +88,5 @@ class PeopleHandler(GenericHandler):
user = obj
if user.person:
return user.person
return None

View file

@ -308,14 +308,14 @@ class ProblemHandler(GenericHandler):
if not self.is_enabled(check):
log.debug("problem check is not enabled: %s", key)
if not force:
return
return None
weekday = datetime.date.today().weekday()
if not self.should_run_for_weekday(check, weekday):
log.debug("problem check is not scheduled for %s: %s",
calendar.day_name[weekday], key)
if not force:
return
return None
check_instance = check(self.config)
problems = self.find_problems(check_instance)

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -196,6 +196,7 @@ class ReportHandler(GenericHandler):
if instance:
report = report(self.config)
return report
return None
def make_report_data(self, report, params=None, progress=None, **kwargs):
"""

View file

@ -95,7 +95,7 @@ class FileTestCase(TestCase):
myconf = self.write_file('my.conf', '<file contents>')
"""
path = os.path.join(self.tempdir, filename)
with open(path, 'wt') as f:
with open(path, 'wt', encoding='utf_8') as f:
f.write(content)
return path

View file

@ -2,7 +2,7 @@
################################################################################
#
# WuttJamaican -- Base package for Wutta Framework
# Copyright © 2023-2024 Lance Edgar
# Copyright © 2023-2025 Lance Edgar
#
# This file is part of Wutta Framework.
#
@ -256,11 +256,11 @@ def parse_list(value):
parser.whitespace += ','
parser.whitespace_split = True
values = list(parser)
for i, value in enumerate(values):
if value.startswith('"') and value.endswith('"'):
values[i] = value[1:-1]
elif value.startswith("'") and value.endswith("'"):
values[i] = value[1:-1]
for i, val in enumerate(values):
if val.startswith('"') and val.endswith('"'):
values[i] = val[1:-1]
elif val.startswith("'") and val.endswith("'"):
values[i] = val[1:-1]
return values
@ -354,8 +354,8 @@ def resource_path(path):
package, filename = path.split(':')
ref = files(package) / filename
with as_file(ref) as path:
return str(path)
with as_file(ref) as p:
return str(p)
return path

View file

@ -27,6 +27,10 @@ else:
batch = MyBatch(id=42, uuid=_uuid.UUID('0675cdac-ffc9-7690-8000-6023de1c8cfd'))
self.assertEqual(repr(batch), "MyBatch(uuid=UUID('0675cdac-ffc9-7690-8000-6023de1c8cfd'))")
self.assertEqual(str(batch), "00000042")
self.assertEqual(batch.id_str, "00000042")
batch2 = MyBatch()
self.assertIsNone(batch2.id_str)
class TestBatchRowMixin(DataTestCase):

View file

@ -22,9 +22,11 @@ else:
def test_dict_behavior(self):
setting = Setting()
self.assertEqual(list(iter(setting)), [('name', None), ('value', None)])
self.assertIsNone(setting.name)
self.assertIsNone(setting['name'])
setting.name = 'foo'
self.assertEqual(setting['name'], 'foo')
self.assertRaises(KeyError, lambda: setting['notfound'])
class TestUUID(TestCase):

View file

@ -375,6 +375,10 @@ app_title = WuttaTest
ver = self.app.get_version(obj=query)
self.assertEqual(ver, version('SQLAlchemy'))
# random object will not yield a dist nor version
ver = self.app.get_version(obj=42)
self.assertIsNone(ver)
# can override dist via config
self.config.setdefault('wuttatest.app_dist', 'python-configuration')
ver = self.app.get_version()

View file

@ -94,6 +94,10 @@ class TestReportHandler(ConfigTestCase):
self.assertTrue(issubclass(report, mod.Report))
self.assertIs(report, MockFooReport)
# not found
report = handler.get_report('unknown')
self.assertIsNone(report)
def test_make_report_data(self):
providers = {
'wuttatest': MagicMock(report_modules=['tests.test_reports']),