added config and tests
This commit is contained in:
parent
5a6b00494f
commit
9187ffde68
|
@ -1,49 +1,66 @@
|
|||
from typing import List
|
||||
|
||||
from dynaconf import Dynaconf, Validator
|
||||
|
||||
from mobilizon_bots.config import strategies, publishers, notifiers
|
||||
from mobilizon_bots.config.notifiers import notifier_names
|
||||
from mobilizon_bots.config.publishers import publisher_names
|
||||
|
||||
SETTINGS_FILE = [
|
||||
"mobilizon_bots/settings.toml",
|
||||
"mobilizon_bots/.secrets.toml",
|
||||
"/etc/mobilizon_bots.toml",
|
||||
"/etc/mobilizon_bots_secrets.toml",
|
||||
]
|
||||
ENVVAR_PREFIX = "MOBILIZON_BOTS"
|
||||
base_validators = (
|
||||
[Validator("selection.strategy", must_exist=True)]
|
||||
+ [
|
||||
Validator(
|
||||
f"publisher.{publisher_name}.active", must_exist=True, is_type_of=bool
|
||||
)
|
||||
for publisher_name in publisher_names
|
||||
|
||||
def build_settings(
|
||||
settings_files: List[str] = None, validators: List[Validator] = None
|
||||
):
|
||||
|
||||
SETTINGS_FILE = settings_files or [
|
||||
"mobilizon_bots/settings.toml",
|
||||
"mobilizon_bots/.secrets.toml",
|
||||
"/etc/mobilizon_bots.toml",
|
||||
"/etc/mobilizon_bots_secrets.toml",
|
||||
]
|
||||
+ [
|
||||
Validator(f"notifier.{notifier_name}.active", must_exist=True, is_type_of=bool)
|
||||
for notifier_name in notifier_names
|
||||
]
|
||||
)
|
||||
ENVVAR_PREFIX = "MOBILIZON_BOTS"
|
||||
|
||||
raw_settings = Dynaconf(
|
||||
environments=True,
|
||||
envvar_prefix=ENVVAR_PREFIX,
|
||||
settings_files=SETTINGS_FILE,
|
||||
validators=base_validators,
|
||||
)
|
||||
return Dynaconf(
|
||||
environments=True,
|
||||
envvar_prefix=ENVVAR_PREFIX,
|
||||
settings_files=SETTINGS_FILE,
|
||||
validators=validators or [],
|
||||
)
|
||||
|
||||
strategy_validators = strategies.get_validators(raw_settings)
|
||||
publisher_validators = publishers.get_validators(raw_settings)
|
||||
notifier_validators = notifiers.get_validators(raw_settings)
|
||||
|
||||
settings = Dynaconf(
|
||||
environments=True,
|
||||
envvar_prefix=ENVVAR_PREFIX,
|
||||
settings_files=SETTINGS_FILE,
|
||||
validators=base_validators
|
||||
+ strategy_validators
|
||||
+ publisher_validators
|
||||
+ notifier_validators,
|
||||
)
|
||||
# TODO use validation control in dynaconf 3.2.0 once released
|
||||
settings.validators.validate()
|
||||
def build_and_validate_settings(settings_files: List[str] = None):
|
||||
|
||||
base_validators = (
|
||||
[
|
||||
Validator("selection.strategy", must_exist=True),
|
||||
Validator("source.mobilizon.url", must_exist=True),
|
||||
]
|
||||
+ [
|
||||
Validator(
|
||||
f"publisher.{publisher_name}.active", must_exist=True, is_type_of=bool
|
||||
)
|
||||
for publisher_name in publisher_names
|
||||
]
|
||||
+ [
|
||||
Validator(
|
||||
f"notifier.{notifier_name}.active", must_exist=True, is_type_of=bool
|
||||
)
|
||||
for notifier_name in notifier_names
|
||||
]
|
||||
)
|
||||
raw_settings = build_settings(settings_files=settings_files)
|
||||
strategy_validators = strategies.get_validators(raw_settings)
|
||||
publisher_validators = publishers.get_validators(raw_settings)
|
||||
notifier_validators = notifiers.get_validators(raw_settings)
|
||||
settings = build_settings(
|
||||
settings_files,
|
||||
base_validators
|
||||
+ strategy_validators
|
||||
+ publisher_validators
|
||||
+ notifier_validators,
|
||||
)
|
||||
# TODO use validation control in dynaconf 3.2.0 once released
|
||||
settings.validators.validate()
|
||||
return settings
|
||||
|
||||
|
||||
settings = build_and_validate_settings()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from dataclasses import dataclass, asdict
|
||||
from dataclasses import dataclass, asdict, field
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
|
@ -18,19 +18,20 @@ class MobilizonEvent:
|
|||
"""Class representing an event retrieved from Mobilizon."""
|
||||
|
||||
name: str
|
||||
description: str
|
||||
begin_datetime: arrow.Arrow
|
||||
end_datetime: arrow.Arrow
|
||||
last_accessed: arrow.Arrow
|
||||
mobilizon_link: str
|
||||
description: Optional[str]
|
||||
begin_datetime: Optional[arrow.Arrow]
|
||||
end_datetime: Optional[arrow.Arrow]
|
||||
mobilizon_link: Optional[str]
|
||||
mobilizon_id: str
|
||||
thumbnail_link: Optional[str] = None
|
||||
location: Optional[str] = None
|
||||
publication_time: Optional[arrow.Arrow] = None
|
||||
publication_status: PublicationStatus = PublicationStatus.WAITING
|
||||
last_accessed: arrow.Arrow = field(compare=False, default=None)
|
||||
|
||||
def __post_init__(self):
|
||||
assert self.begin_datetime < self.end_datetime
|
||||
if self.begin_datetime and self.end_datetime:
|
||||
assert self.begin_datetime < self.end_datetime
|
||||
if self.publication_time:
|
||||
assert self.publication_status in [
|
||||
PublicationStatus.COMPLETED,
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from mobilizon_bots.event.event import MobilizonEvent, PublicationStatus
|
||||
import requests
|
||||
import arrow
|
||||
import requests
|
||||
|
||||
from mobilizon_bots.config.config import settings
|
||||
from mobilizon_bots.event.event import MobilizonEvent, PublicationStatus
|
||||
|
||||
|
||||
def parse_location(data):
|
||||
|
@ -19,11 +21,11 @@ def parse_picture(data):
|
|||
def parse_event(data):
|
||||
return MobilizonEvent(
|
||||
name=data["title"],
|
||||
description=data["description"],
|
||||
begin_datetime=arrow.get(data["beginsOn"]),
|
||||
end_datetime=arrow.get(data["endsOn"]),
|
||||
description=data.get("description", None),
|
||||
begin_datetime=arrow.get(data["beginsOn"]) if "beginsOn" in data else None,
|
||||
end_datetime=arrow.get(data["endsOn"]) if "endsOn" in data else None,
|
||||
last_accessed=arrow.now(),
|
||||
mobilizon_link=data["url"],
|
||||
mobilizon_link=data.get("url", None),
|
||||
mobilizon_id=data["uuid"],
|
||||
thumbnail_link=parse_picture(data),
|
||||
location=parse_location(data),
|
||||
|
@ -64,15 +66,12 @@ query_future_events = """{{
|
|||
def get_mobilizon_future_events(
|
||||
page: int = 1, from_date: Optional[arrow.Arrow] = None
|
||||
) -> List[MobilizonEvent]:
|
||||
url = "https://apero.bzh/api"
|
||||
|
||||
url = settings["source"]["mobilizon"]["url"]
|
||||
query = query_future_events.format(
|
||||
group="test", page=page, afterDatetime=from_date or arrow.now().isoformat()
|
||||
)
|
||||
|
||||
r = requests.post(url, json={"query": query})
|
||||
return list(
|
||||
map(parse_event, r.json()["data"]["group"]["organizedEvents"]["elements"])
|
||||
)
|
||||
|
||||
|
||||
get_mobilizon_future_events()
|
||||
|
|
|
@ -6,6 +6,9 @@ log_dir = "/var/log/mobots"
|
|||
db_name = "events.db"
|
||||
db_path = "@format {this.local_state_dir}/{this.db_name}"
|
||||
|
||||
[default.source.mobilizon]
|
||||
url="https://some_mobilizon"
|
||||
|
||||
[default.selection]
|
||||
strategy = "next_event"
|
||||
|
||||
|
|
|
@ -234,6 +234,22 @@ urllib3 = ">=1.21.1,<1.27"
|
|||
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
|
||||
|
||||
[[package]]
|
||||
name = "responses"
|
||||
version = "0.13.3"
|
||||
description = "A utility library for mocking out the `requests` Python library."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.dependencies]
|
||||
requests = ">=2.0"
|
||||
six = "*"
|
||||
urllib3 = ">=1.25.10"
|
||||
|
||||
[package.extras]
|
||||
tests = ["coverage (>=3.7.1,<6.0.0)", "pytest-cov", "pytest-localserver", "flake8", "pytest (>=4.6,<5.0)", "pytest (>=4.6)", "mypy"]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
|
@ -295,7 +311,7 @@ python-versions = "*"
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "75f5eb1e5eda7daba1871ae4f550e72075894e1152c8ee34686c5164bc36580a"
|
||||
content-hash = "be81df312539b9c6d1020d05e5001c8819f5ca47435a84e398b35cd39020e7bf"
|
||||
|
||||
[metadata.files]
|
||||
aiosqlite = [
|
||||
|
@ -412,6 +428,10 @@ requests = [
|
|||
{file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
|
||||
{file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"},
|
||||
]
|
||||
responses = [
|
||||
{file = "responses-0.13.3-py2.py3-none-any.whl", hash = "sha256:b54067596f331786f5ed094ff21e8d79e6a1c68ef625180a7d34808d6f36c11b"},
|
||||
{file = "responses-0.13.3.tar.gz", hash = "sha256:18a5b88eb24143adbf2b4100f328a2f5bfa72fbdacf12d97d41f07c26c45553d"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
|
|
|
@ -15,6 +15,7 @@ arrow = "^1.1.0"
|
|||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^5.3"
|
||||
responses = "^0.13.3"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import arrow
|
||||
import pkg_resources
|
||||
import pytest
|
||||
from dynaconf import settings
|
||||
|
||||
from mobilizon_bots.config.config import build_and_validate_settings
|
||||
from mobilizon_bots.event.event import MobilizonEvent, PublicationStatus
|
||||
|
||||
|
||||
|
@ -8,6 +11,16 @@ def generate_publication_status(published):
|
|||
return PublicationStatus.COMPLETED if published else PublicationStatus.WAITING
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def set_test_settings():
|
||||
config_file = pkg_resources.resource_filename(
|
||||
"tests.resources", "test_settings.toml"
|
||||
)
|
||||
|
||||
settings.configure(FORCE_ENV_FOR_DYNACONF="testing")
|
||||
build_and_validate_settings([config_file])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def event_generator():
|
||||
def _event_generator(
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import pytest
|
||||
import responses
|
||||
|
||||
from mobilizon_bots.config.config import settings
|
||||
|
||||
|
||||
@responses.activate
|
||||
@pytest.fixture
|
||||
def mock_mobilizon_success_answer(mobilizon_answer):
|
||||
with responses.RequestsMock() as rsps:
|
||||
|
||||
rsps.add(
|
||||
responses.POST,
|
||||
settings["source"]["mobilizon"]["url"],
|
||||
json=mobilizon_answer,
|
||||
status=200,
|
||||
)
|
||||
yield
|
|
@ -0,0 +1,54 @@
|
|||
import pytest
|
||||
|
||||
from mobilizon_bots.event.event import PublicationStatus, MobilizonEvent
|
||||
from mobilizon_bots.mobilizon.events import get_mobilizon_future_events
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mobilizon_answer", [{"data": {"group": {"organizedEvents": {"elements": []}}}}]
|
||||
)
|
||||
def test_get_mobilizon_future_events(mock_mobilizon_success_answer):
|
||||
"""
|
||||
Testing a response with no content
|
||||
"""
|
||||
assert get_mobilizon_future_events() == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mobilizon_answer",
|
||||
[
|
||||
{
|
||||
"data": {
|
||||
"group": {
|
||||
"organizedEvents": {
|
||||
"elements": [
|
||||
{
|
||||
"id": "57194",
|
||||
"title": "test event",
|
||||
"uuid": "1e2e5943-4a5c-497a-b65d-90457b715d7b",
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
)
|
||||
def test_simple_event(mock_mobilizon_success_answer):
|
||||
"""
|
||||
Testing a minimal event that is valid in Mobilizon
|
||||
"""
|
||||
assert get_mobilizon_future_events() == [
|
||||
MobilizonEvent(
|
||||
name="test event",
|
||||
description=None,
|
||||
begin_datetime=None,
|
||||
end_datetime=None,
|
||||
mobilizon_link=None,
|
||||
mobilizon_id="1e2e5943-4a5c-497a-b65d-90457b715d7b",
|
||||
thumbnail_link=None,
|
||||
location=None,
|
||||
publication_time=None,
|
||||
publication_status=PublicationStatus.WAITING,
|
||||
)
|
||||
]
|
|
@ -0,0 +1,39 @@
|
|||
[default]
|
||||
debug = true
|
||||
default = true
|
||||
local_state_dir = "/var/mobots"
|
||||
log_dir = "/var/log/mobots"
|
||||
db_name = "events.db"
|
||||
db_path = "@format {this.local_state_dir}/{this.db_name}"
|
||||
|
||||
[default.source.mobilizon]
|
||||
url=""
|
||||
|
||||
[default.selection]
|
||||
strategy = "next_event"
|
||||
|
||||
[default.selection.strategy_options]
|
||||
break_between_events_in_minutes =5
|
||||
|
||||
[default.publisher.telegram]
|
||||
active=true
|
||||
chat_id="xxx"
|
||||
[default.publisher.facebook]
|
||||
active=false
|
||||
[default.publisher.zulip]
|
||||
active=false
|
||||
[default.publisher.twitter]
|
||||
active=false
|
||||
[default.publisher.mastodon]
|
||||
active=false
|
||||
|
||||
[default.notifier.telegram]
|
||||
active=true
|
||||
chat_id="xxx"
|
||||
[default.notifier.zulip]
|
||||
active=false
|
||||
[default.notifier.twitter]
|
||||
active=false
|
||||
[default.notifier.mastodon]
|
||||
active=false
|
||||
|
Loading…
Reference in New Issue