mirror of
https://github.com/Tech-Workers-Coalition-Italia/mobilizon-reshare.git
synced 2025-02-06 04:13:27 +01:00
Merge pull request #6 from Tech-Workers-Coalition-Italia/event_selector
Event selector
This commit is contained in:
commit
23be6d8812
44
mobilizon_bots/event/event.py
Normal file
44
mobilizon_bots/event/event.py
Normal file
@ -0,0 +1,44 @@
|
||||
from dataclasses import dataclass, asdict
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
|
||||
class PublicationStatus(Enum):
|
||||
WAITING = 1
|
||||
FAILED = 2
|
||||
PARTIAL = 3
|
||||
COMPLETED = 4
|
||||
|
||||
|
||||
@dataclass
|
||||
class MobilizonEvent:
|
||||
"""Class representing an event retrieved from Mobilizon."""
|
||||
|
||||
name: str
|
||||
description: str
|
||||
begin_datetime: datetime
|
||||
end_datetime: datetime
|
||||
last_accessed: datetime
|
||||
mobilizon_link: str
|
||||
mobilizon_id: str
|
||||
thumbnail_link: Optional[str] = None
|
||||
location: Optional[str] = None
|
||||
publication_time: Optional[datetime] = None
|
||||
publication_status: PublicationStatus = PublicationStatus.WAITING
|
||||
|
||||
def __post_init__(self):
|
||||
assert self.begin_datetime < self.end_datetime
|
||||
if self.publication_time:
|
||||
assert self.publication_status in [
|
||||
PublicationStatus.COMPLETED,
|
||||
PublicationStatus.PARTIAL,
|
||||
]
|
||||
|
||||
def _fill_template(self, pattern: Template) -> str:
|
||||
return pattern.render(**asdict(self))
|
||||
|
||||
def format(self, pattern: Template) -> str:
|
||||
return self._fill_template(pattern)
|
@ -1,5 +1,5 @@
|
||||
from tortoise.models import Model
|
||||
from tortoise import fields
|
||||
from tortoise.models import Model
|
||||
|
||||
|
||||
class Event(Model):
|
||||
|
@ -1,4 +1,5 @@
|
||||
from pathlib import Path
|
||||
|
||||
from tortoise import Tortoise
|
||||
|
||||
|
||||
|
168
poetry.lock
generated
168
poetry.lock
generated
@ -1,3 +1,14 @@
|
||||
[[package]]
|
||||
name = "aiosqlite"
|
||||
version = "0.16.1"
|
||||
description = "asyncio bridge to the standard sqlite3 module"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
typing_extensions = ">=3.7.2"
|
||||
|
||||
[[package]]
|
||||
name = "atomicwrites"
|
||||
version = "1.4.0"
|
||||
@ -28,6 +39,53 @@ category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "dynaconf"
|
||||
version = "3.1.4"
|
||||
description = "The dynamic configurator for your Python Project"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.extras]
|
||||
all = ["redis", "ruamel.yaml", "configobj", "hvac"]
|
||||
configobj = ["configobj"]
|
||||
ini = ["configobj"]
|
||||
redis = ["redis"]
|
||||
toml = ["toml"]
|
||||
vault = ["hvac"]
|
||||
yaml = ["ruamel.yaml"]
|
||||
|
||||
[[package]]
|
||||
name = "iso8601"
|
||||
version = "0.1.14"
|
||||
description = "Simple module to parse ISO 8601 dates"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "2.11.3"
|
||||
description = "A very fast and expressive template engine."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=0.23"
|
||||
|
||||
[package.extras]
|
||||
i18n = ["Babel (>=0.8)"]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "1.1.1"
|
||||
description = "Safely add untrusted strings to HTML/XML markup."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "more-itertools"
|
||||
version = "8.7.0"
|
||||
@ -74,6 +132,14 @@ category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "pypika-tortoise"
|
||||
version = "0.1.0"
|
||||
description = "Forked from pypika and streamline just for tortoise-orm"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7,<4.0"
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "5.4.3"
|
||||
@ -96,6 +162,43 @@ wcwidth = "*"
|
||||
checkqa-mypy = ["mypy (==v0.761)"]
|
||||
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2020.5"
|
||||
description = "World timezone definitions, modern and historical"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "tortoise-orm"
|
||||
version = "0.17.2"
|
||||
description = "Easy async ORM for python, built with relations in mind"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7,<4.0"
|
||||
|
||||
[package.dependencies]
|
||||
aiosqlite = ">=0.16.0,<0.17.0"
|
||||
iso8601 = ">=0.1.13,<0.2.0"
|
||||
pypika-tortoise = ">=0.1.0,<0.2.0"
|
||||
pytz = ">=2020.4,<2021.0"
|
||||
|
||||
[package.extras]
|
||||
docs = ["pygments", "cloud-sptheme", "docutils", "sphinx"]
|
||||
aiomysql = ["aiomysql"]
|
||||
asyncmy = ["asyncmy"]
|
||||
asyncpg = ["asyncpg"]
|
||||
accel = ["ciso8601 (>=2.1.2,<3.0.0)", "python-rapidjson", "uvloop (>=0.14.0,<0.15.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "3.10.0.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.5+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "wcwidth"
|
||||
version = "0.2.5"
|
||||
@ -107,9 +210,13 @@ python-versions = "*"
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "4d1de49710d78bd295469a572576efe3d5b96e6e8760458e870affe880e8d10e"
|
||||
content-hash = "2a9d2f27ed4c4197d4dd022c2e1f8968ef7fff2ab73145a4bd74712f35d88855"
|
||||
|
||||
[metadata.files]
|
||||
aiosqlite = [
|
||||
{file = "aiosqlite-0.16.1-py3-none-any.whl", hash = "sha256:1df802815bb1e08a26c06d5ea9df589bcb8eec56e5f3378103b0f9b223c6703c"},
|
||||
{file = "aiosqlite-0.16.1.tar.gz", hash = "sha256:2e915463164efa65b60fd1901aceca829b6090082f03082618afca6fb9c8fdf7"},
|
||||
]
|
||||
atomicwrites = [
|
||||
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
|
||||
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
|
||||
@ -122,6 +229,48 @@ colorama = [
|
||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||
]
|
||||
dynaconf = [
|
||||
{file = "dynaconf-3.1.4-py2.py3-none-any.whl", hash = "sha256:e6f383b84150b70fc439c8b2757581a38a58d07962aa14517292dcce1a77e160"},
|
||||
{file = "dynaconf-3.1.4.tar.gz", hash = "sha256:b2f472d83052f809c5925565b8a2ba76a103d5dc1dbb9748b693ed67212781b9"},
|
||||
]
|
||||
iso8601 = [
|
||||
{file = "iso8601-0.1.14-py2.py3-none-any.whl", hash = "sha256:e7e1122f064d626e17d47cd5106bed2c620cb38fe464999e0ddae2b6d2de6004"},
|
||||
{file = "iso8601-0.1.14.tar.gz", hash = "sha256:8aafd56fa0290496c5edbb13c311f78fa3a241f0853540da09d9363eae3ebd79"},
|
||||
]
|
||||
jinja2 = [
|
||||
{file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"},
|
||||
{file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"},
|
||||
]
|
||||
markupsafe = [
|
||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"},
|
||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"},
|
||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"},
|
||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"},
|
||||
{file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"},
|
||||
{file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"},
|
||||
{file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"},
|
||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"},
|
||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"},
|
||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"},
|
||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"},
|
||||
{file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"},
|
||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"},
|
||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"},
|
||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"},
|
||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"},
|
||||
{file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"},
|
||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"},
|
||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"},
|
||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"},
|
||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"},
|
||||
{file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"},
|
||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"},
|
||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"},
|
||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"},
|
||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
|
||||
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
|
||||
{file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
|
||||
]
|
||||
more-itertools = [
|
||||
{file = "more-itertools-8.7.0.tar.gz", hash = "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713"},
|
||||
{file = "more_itertools-8.7.0-py3-none-any.whl", hash = "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced"},
|
||||
@ -142,10 +291,27 @@ pyparsing = [
|
||||
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
|
||||
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
||||
]
|
||||
pypika-tortoise = [
|
||||
{file = "pypika-tortoise-0.1.0.tar.gz", hash = "sha256:7176e98ff0cf7c311d4ba58f28f1755956265dee2f9781e65e1304a67a3e5aa5"},
|
||||
{file = "pypika_tortoise-0.1.0-py3-none-any.whl", hash = "sha256:ec83b0b2964be01ef563f5f019b0332a18177604e841c47ad39d798798c6dfe9"},
|
||||
]
|
||||
pytest = [
|
||||
{file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"},
|
||||
{file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"},
|
||||
]
|
||||
pytz = [
|
||||
{file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"},
|
||||
{file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"},
|
||||
]
|
||||
tortoise-orm = [
|
||||
{file = "tortoise-orm-0.17.2.tar.gz", hash = "sha256:1a742b2f15a31d47a8dea7706b478cc9a7ce9af268b61d77d0fa22cfbaea271a"},
|
||||
{file = "tortoise_orm-0.17.2-py3-none-any.whl", hash = "sha256:b0c02be3800398053058377ddca91fa051eb98eebb704d2db2a3ab1c6a58e347"},
|
||||
]
|
||||
typing-extensions = [
|
||||
{file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"},
|
||||
{file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"},
|
||||
{file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"},
|
||||
]
|
||||
wcwidth = [
|
||||
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
|
||||
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
|
||||
|
@ -7,8 +7,9 @@ authors = ["Simone Robutti <simone.robutti@protonmail.com>"]
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.9"
|
||||
dynaconf = "^3.1.4"
|
||||
tortoise-orm = "^0.16.21"
|
||||
aiosqlite = "^0.17.0"
|
||||
tortoise-orm = "^0.17"
|
||||
aiosqlite = "^0.16"
|
||||
Jinja2 = "^2.11.3"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^5.2"
|
||||
|
@ -1,14 +0,0 @@
|
||||
import pytest
|
||||
from dynaconf import settings
|
||||
from tortoise.contrib.test import finalizer, initializer
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def initialize_tests(request):
|
||||
settings.configure(FORCE_ENV_FOR_DYNACONF="testing")
|
||||
initializer(
|
||||
["tests.test_models"],
|
||||
db_url=f"sqlite:///{settings.DB_PATH}",
|
||||
app_label="models",
|
||||
)
|
||||
request.addfinalizer(finalizer)
|
50
tests/conftest.py
Normal file
50
tests/conftest.py
Normal file
@ -0,0 +1,50 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pytest
|
||||
|
||||
from mobilizon_bots.event.event import MobilizonEvent, PublicationStatus
|
||||
|
||||
|
||||
def generate_publication_status(published):
|
||||
return PublicationStatus.COMPLETED if published else PublicationStatus.WAITING
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def event_generator():
|
||||
def _event_generator(
|
||||
begin_date=datetime(year=2021, month=1, day=1, hour=11, minute=30),
|
||||
published=False,
|
||||
publication_time=None,
|
||||
):
|
||||
|
||||
return MobilizonEvent(
|
||||
name="test event",
|
||||
description="description of the event",
|
||||
begin_datetime=begin_date,
|
||||
end_datetime=begin_date + timedelta(hours=2),
|
||||
last_accessed=datetime.now(),
|
||||
mobilizon_link="http://some_link.com/123",
|
||||
mobilizon_id="12345",
|
||||
thumbnail_link="http://some_link.com/123.jpg",
|
||||
location="location",
|
||||
publication_status=generate_publication_status(published),
|
||||
publication_time=publication_time
|
||||
or (begin_date - timedelta(days=1) if published else None),
|
||||
)
|
||||
|
||||
return _event_generator
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def event() -> MobilizonEvent:
|
||||
return MobilizonEvent(
|
||||
name="test event",
|
||||
description="description of the event",
|
||||
begin_datetime=datetime(year=2021, month=1, day=1, hour=11, minute=30),
|
||||
end_datetime=datetime(year=2021, month=1, day=1, hour=12, minute=30),
|
||||
last_accessed=datetime.now(),
|
||||
mobilizon_link="http://some_link.com/123",
|
||||
mobilizon_id="12345",
|
||||
thumbnail_link="http://some_link.com/123.jpg",
|
||||
location="location",
|
||||
)
|
0
tests/event/__init__.py
Normal file
0
tests/event/__init__.py
Normal file
59
tests/event/event_selector.py
Normal file
59
tests/event/event_selector.py
Normal file
@ -0,0 +1,59 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from datetime import timedelta, datetime
|
||||
from typing import List, Optional
|
||||
|
||||
from mobilizon_bots.event.event import MobilizonEvent
|
||||
|
||||
|
||||
class EventSelectionStrategy(ABC):
|
||||
@abstractmethod
|
||||
def select(
|
||||
self,
|
||||
published_events: List[MobilizonEvent],
|
||||
unpublished_events: List[MobilizonEvent],
|
||||
) -> Optional[MobilizonEvent]:
|
||||
pass
|
||||
|
||||
|
||||
class SelectNextEventStrategy(EventSelectionStrategy):
|
||||
def __init__(self, minimum_break_between_events: timedelta = timedelta(days=0)):
|
||||
self.minimum_break_between_events = minimum_break_between_events
|
||||
|
||||
def select(
|
||||
self,
|
||||
published_events: List[MobilizonEvent],
|
||||
unpublished_events: List[MobilizonEvent],
|
||||
) -> Optional[MobilizonEvent]:
|
||||
|
||||
last_published_event = published_events[-1]
|
||||
first_unpublished_event = unpublished_events[0]
|
||||
assert last_published_event.publication_time < datetime.now(), (
|
||||
f"Last published event has been published in the future\n"
|
||||
f"{last_published_event.publication_time}\n"
|
||||
f"{datetime.now()}"
|
||||
)
|
||||
|
||||
if (
|
||||
last_published_event.publication_time + self.minimum_break_between_events
|
||||
> datetime.now()
|
||||
):
|
||||
return None
|
||||
|
||||
return first_unpublished_event
|
||||
|
||||
|
||||
class EventSelector:
|
||||
def __init__(
|
||||
self,
|
||||
published_events: List[MobilizonEvent],
|
||||
unpublished_events: List[MobilizonEvent],
|
||||
):
|
||||
self.published_events = published_events.sort(key=lambda x: x.begin_datetime)
|
||||
self.unpublished_events = unpublished_events.sort(
|
||||
key=lambda x: x.begin_datetime
|
||||
)
|
||||
|
||||
def select_event_to_publish(
|
||||
self, strategy: EventSelectionStrategy
|
||||
) -> Optional[MobilizonEvent]:
|
||||
return strategy.select(self.published_events, self.unpublished_events)
|
23
tests/event/test_event.py
Normal file
23
tests/event/test_event.py
Normal file
@ -0,0 +1,23 @@
|
||||
import pytest
|
||||
from jinja2 import Template
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def simple_template():
|
||||
return Template(
|
||||
"{{name}}|{{description}}|{{location}}|{{begin_datetime.strftime('%Y-%m-%d, %H:%M')}}"
|
||||
)
|
||||
|
||||
|
||||
def test_fill_template(event, simple_template):
|
||||
assert (
|
||||
event._fill_template(simple_template)
|
||||
== "test event|description of the event|location|2021-01-01, 11:30"
|
||||
)
|
||||
|
||||
|
||||
def test_format(event, simple_template):
|
||||
assert (
|
||||
event.format(simple_template)
|
||||
== "test event|description of the event|location|2021-01-01, 11:30"
|
||||
)
|
104
tests/event/test_strategies.py
Normal file
104
tests/event/test_strategies.py
Normal file
@ -0,0 +1,104 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.event.event_selector import SelectNextEventStrategy
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"desired_break_window,days_passed_from_publication", [[2, 1], [3, 2]]
|
||||
)
|
||||
def test_window_simple_no_event(
|
||||
event_generator, desired_break_window, days_passed_from_publication
|
||||
):
|
||||
"Testing that the break between events is respected"
|
||||
unpublished_events = [
|
||||
event_generator(
|
||||
published=False,
|
||||
begin_date=datetime(year=2021, month=1, day=5, hour=11, minute=30),
|
||||
)
|
||||
]
|
||||
published_events = [
|
||||
event_generator(
|
||||
published=True,
|
||||
publication_time=datetime.now()
|
||||
- timedelta(days=days_passed_from_publication),
|
||||
)
|
||||
]
|
||||
|
||||
selected_event = SelectNextEventStrategy(
|
||||
minimum_break_between_events=timedelta(days=desired_break_window)
|
||||
).select(published_events, unpublished_events)
|
||||
assert selected_event is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"desired_break_window,days_passed_from_publication", [[1, 2], [2, 10], [4, 4]]
|
||||
)
|
||||
def test_window_simple_event_found(
|
||||
event_generator, desired_break_window, days_passed_from_publication,
|
||||
):
|
||||
"Testing that the break between events is respected and an event is found"
|
||||
unpublished_events = [
|
||||
event_generator(
|
||||
published=False,
|
||||
begin_date=datetime(year=2021, month=1, day=5, hour=11, minute=30),
|
||||
)
|
||||
]
|
||||
published_events = [
|
||||
event_generator(
|
||||
published=True,
|
||||
publication_time=datetime.now()
|
||||
- timedelta(days=days_passed_from_publication),
|
||||
)
|
||||
]
|
||||
|
||||
selected_event = SelectNextEventStrategy(
|
||||
minimum_break_between_events=timedelta(days=desired_break_window)
|
||||
).select(published_events, unpublished_events)
|
||||
assert selected_event is unpublished_events[0]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"desired_break_window,days_passed_from_publication", [[1, 2], [2, 10], [4, 4]]
|
||||
)
|
||||
def test_window_multi_event_found(
|
||||
event_generator, desired_break_window, days_passed_from_publication,
|
||||
):
|
||||
"Testing that the break between events is respected when there are multiple events"
|
||||
unpublished_events = [
|
||||
event_generator(
|
||||
published=False,
|
||||
begin_date=datetime(year=2022, month=1, day=5, hour=11, minute=30),
|
||||
),
|
||||
event_generator(
|
||||
published=False,
|
||||
begin_date=datetime(year=2022, month=3, day=5, hour=11, minute=30),
|
||||
),
|
||||
event_generator(
|
||||
published=False,
|
||||
begin_date=datetime(year=2021, month=1, day=5, hour=11, minute=30),
|
||||
),
|
||||
]
|
||||
published_events = [
|
||||
event_generator(
|
||||
published=True,
|
||||
publication_time=datetime.now()
|
||||
- timedelta(days=days_passed_from_publication),
|
||||
),
|
||||
event_generator(
|
||||
published=True,
|
||||
publication_time=datetime.now()
|
||||
- timedelta(days=days_passed_from_publication + 2),
|
||||
),
|
||||
event_generator(
|
||||
published=True,
|
||||
publication_time=datetime.now()
|
||||
- timedelta(days=days_passed_from_publication + 4),
|
||||
),
|
||||
]
|
||||
|
||||
selected_event = SelectNextEventStrategy(
|
||||
minimum_break_between_events=timedelta(days=desired_break_window)
|
||||
).select(published_events, unpublished_events)
|
||||
assert selected_event is unpublished_events[0]
|
@ -1,14 +0,0 @@
|
||||
from tortoise.contrib import test
|
||||
|
||||
|
||||
class TestSomething(test.TestCase):
|
||||
async def test_something_async(self):
|
||||
...
|
||||
|
||||
@test.skip("Skip this")
|
||||
def test_skip(self):
|
||||
...
|
||||
|
||||
@test.expectedFailure
|
||||
def test_something(self):
|
||||
...
|
Loading…
x
Reference in New Issue
Block a user