roboherd 0.1.2__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of roboherd might be problematic. Click here for more details.
- {roboherd-0.1.2 → roboherd-0.1.4}/.woodpecker/create_release.yml +1 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/.woodpecker/test.yml +13 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/CHANGES.md +11 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/PKG-INFO +2 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/docs/index.md +27 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/pyproject.toml +3 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/resources/docker/Dockerfile +2 -2
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/__main__.py +4 -2
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/annotations/__init__.py +10 -4
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/annotations/bovine.py +8 -8
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/annotations/common.py +2 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/cow/__init__.py +4 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/cow/profile.py +15 -5
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/cow/types.py +10 -8
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/cow/util.py +4 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/examples/json_echo.py +1 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/examples/number.py +1 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/examples/rooster.py +1 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/examples/scarecrow.py +1 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/__init__.py +3 -3
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/manager/__init__.py +3 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/manager/test_config.py +2 -2
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/manager/test_manager.py +1 -1
- roboherd-0.1.4/roboherd/test_validators.py +10 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/util.py +0 -1
- roboherd-0.1.4/roboherd/validators.py +6 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/uv.lock +27 -1
- {roboherd-0.1.2 → roboherd-0.1.4}/.gitignore +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/.woodpecker/publish_docker.yml +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/.woodpecker/publish_pypi.yml +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/.woodpecker/website.yml +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/README.md +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/docs/annotations.md +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/docs/assets/mastodon.png +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/docs/cli.md +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/docs/cow.md +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/docs/herd.md +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/docs/util.md +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/mkdocs.yml +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/resources/docker/build.sh +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/__init__.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/cow/handlers.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/cow/test_handlers.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/cow/test_init.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/cow/test_profile.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/cow/test_util.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/examples/__init__.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/examples/dev_null.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/examples/meta.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/examples/moocow.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/builder.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/manager/config.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/processor.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/scheduler.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/test_herd.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/test_scheduler.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/herd/types.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/register.py +0 -0
- {roboherd-0.1.2 → roboherd-0.1.4}/roboherd/test_util.py +0 -0
|
@@ -2,11 +2,14 @@ when:
|
|
|
2
2
|
- branch: [main]
|
|
3
3
|
event: [pull_request, push]
|
|
4
4
|
|
|
5
|
+
matrix:
|
|
6
|
+
extras: ["--all-extras", ""]
|
|
7
|
+
|
|
5
8
|
steps:
|
|
6
9
|
build:
|
|
7
10
|
image: ghcr.io/astral-sh/uv:python3.11-alpine
|
|
8
11
|
commands:
|
|
9
|
-
- uv sync
|
|
12
|
+
- uv sync ${extras}
|
|
10
13
|
test_format:
|
|
11
14
|
image: ghcr.io/astral-sh/uv:python3.11-alpine
|
|
12
15
|
commands:
|
|
@@ -16,7 +19,16 @@ steps:
|
|
|
16
19
|
image: ghcr.io/astral-sh/uv:python3.11-alpine
|
|
17
20
|
commands:
|
|
18
21
|
- uv run pytest
|
|
22
|
+
test_typing:
|
|
23
|
+
image: ghcr.io/astral-sh/uv:python3.11-alpine
|
|
24
|
+
commands:
|
|
25
|
+
- apk add libstdc++ libgcc
|
|
26
|
+
- uv run pyright roboherd
|
|
27
|
+
when:
|
|
28
|
+
- matrix: { extras: "--all-extras" }
|
|
19
29
|
build_docs:
|
|
20
30
|
image: ghcr.io/astral-sh/uv:python3.11-alpine
|
|
21
31
|
commands:
|
|
22
32
|
- uv run mkdocs build
|
|
33
|
+
when:
|
|
34
|
+
- matrix: { extras: "--all-extras" }
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changes to roboherd
|
|
2
2
|
|
|
3
|
+
## 0.1.4 ([Milestone](https://codeberg.org/bovine/roboherd/milestone/10442))
|
|
4
|
+
|
|
5
|
+
- Type check the project
|
|
6
|
+
- No longer require bovine [roboherd#26](https://codeberg.org/bovine/roboherd/issues/26)
|
|
7
|
+
- Fixed typo in Dockerfile [roboherd#28](https://codeberg.org/bovine/roboherd/issues/28)
|
|
8
|
+
|
|
9
|
+
## 0.1.3 ([Milestone](https://codeberg.org/bovine/roboherd/milestone/10441))
|
|
10
|
+
|
|
11
|
+
- Add information about developement [roboherd#24](https://codeberg.org/bovine/roboherd/issues/24)
|
|
12
|
+
- Repair docker build [roboherd#23](https://codeberg.org/bovine/roboherd/issues/23)
|
|
13
|
+
|
|
3
14
|
## 0.1.1 ([Milestone](https://codeberg.org/bovine/roboherd/milestone/10245))
|
|
4
15
|
|
|
5
16
|
- Document environment variable overrides [roboherd#16](https://codeberg.org/bovine/roboherd/issues/16)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: roboherd
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: A Fediverse bot framework
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
|
+
Requires-Dist: aiohttp>=3.11.12
|
|
6
7
|
Requires-Dist: almabtrieb[mqtt]>=0.1.0a1
|
|
7
8
|
Requires-Dist: apscheduler>=3.11.0
|
|
8
9
|
Requires-Dist: click>=8.1.8
|
|
@@ -295,3 +295,30 @@ the appropriate points in the menu on the left.
|
|
|
295
295
|
The console also allows you to lookup Fediverse
|
|
296
296
|
objects as seen through cattle_grid and perform actions
|
|
297
297
|
manually.
|
|
298
|
+
|
|
299
|
+
## Developing roboherd
|
|
300
|
+
|
|
301
|
+
Roboherd uses [astral-uv](https://docs.astral.sh/uv/) and
|
|
302
|
+
[hatch](https://hatch.pypa.io/latest/) for development. After
|
|
303
|
+
cloning the repository, run
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
uv sync --all-extras
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
to install dependencies using uv. Then one can run tests via
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
uv run pytest
|
|
313
|
+
uv run ruff check .
|
|
314
|
+
uv run ruff format .
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Releasing
|
|
318
|
+
|
|
319
|
+
Releases, packages, documentation, and docker containers are
|
|
320
|
+
build automatically using the CI. For this increase the
|
|
321
|
+
version, have a [milestone](https://codeberg.org/bovine/roboherd/milestones)
|
|
322
|
+
matching the new version, and appropriate entries in
|
|
323
|
+
`CHANGES.md`. Then once a pull request with this is merged,
|
|
324
|
+
the rest happens automatically.
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "roboherd"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.4"
|
|
4
4
|
description = "A Fediverse bot framework"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
7
7
|
dependencies = [
|
|
8
|
+
"aiohttp>=3.11.12",
|
|
8
9
|
"almabtrieb[mqtt]>=0.1.0a1",
|
|
9
10
|
"apscheduler>=3.11.0",
|
|
10
11
|
"click>=8.1.8",
|
|
@@ -37,6 +38,7 @@ dev-dependencies = [
|
|
|
37
38
|
"griffe-fieldz>=0.2.1",
|
|
38
39
|
"mkdocs-click>=0.8.1",
|
|
39
40
|
"ruff>=0.9.6",
|
|
41
|
+
"pyright>=1.1.394",
|
|
40
42
|
]
|
|
41
43
|
|
|
42
44
|
[tool.pytest.ini_options]
|
|
@@ -10,6 +10,7 @@ from roboherd.herd import RoboHerd
|
|
|
10
10
|
from roboherd.herd.manager import HerdManager
|
|
11
11
|
from roboherd.util import create_connection
|
|
12
12
|
from roboherd.register import register as run_register
|
|
13
|
+
from roboherd.validators import validators
|
|
13
14
|
|
|
14
15
|
logging.basicConfig(level=logging.INFO)
|
|
15
16
|
|
|
@@ -32,6 +33,7 @@ def main(ctx, connection_string, base_url, config_file):
|
|
|
32
33
|
settings = dynaconf.Dynaconf(
|
|
33
34
|
settings_files=[config_file],
|
|
34
35
|
envvar_prefix="ROBOHERD",
|
|
36
|
+
validators=validators,
|
|
35
37
|
)
|
|
36
38
|
ctx.ensure_object(dict)
|
|
37
39
|
|
|
@@ -41,12 +43,12 @@ def main(ctx, connection_string, base_url, config_file):
|
|
|
41
43
|
if connection_string:
|
|
42
44
|
ctx.obj["connection_string"] = connection_string
|
|
43
45
|
else:
|
|
44
|
-
ctx.obj["connection_string"] = settings.
|
|
46
|
+
ctx.obj["connection_string"] = settings.connection_string
|
|
45
47
|
|
|
46
48
|
if base_url:
|
|
47
49
|
ctx.obj["base_url"] = base_url
|
|
48
50
|
else:
|
|
49
|
-
ctx.obj["base_url"] = settings.
|
|
51
|
+
ctx.obj["base_url"] = settings.base_url
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
@main.command()
|
|
@@ -5,11 +5,11 @@ from almabtrieb import Almabtrieb
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def get_raw(data: dict) -> dict:
|
|
8
|
-
return data.get("data").get("raw")
|
|
8
|
+
return data.get("data", {}).get("raw")
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def get_parsed(data: dict) -> dict:
|
|
12
|
-
result = data.get("data").get("parsed")
|
|
12
|
+
result = data.get("data", {}).get("parsed")
|
|
13
13
|
if result is None:
|
|
14
14
|
raise ValueError("No parsed data found")
|
|
15
15
|
return result
|
|
@@ -23,11 +23,17 @@ ParsedData = Annotated[dict, Depends(get_parsed)]
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
def get_activity(parsed: ParsedData) -> dict:
|
|
26
|
-
|
|
26
|
+
result = parsed.get("activity")
|
|
27
|
+
if not result:
|
|
28
|
+
raise ValueError("No activity found")
|
|
29
|
+
return result
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
def get_embedded_object(parsed: ParsedData) -> dict:
|
|
30
|
-
|
|
33
|
+
result = parsed.get("embeddedObject")
|
|
34
|
+
if not result:
|
|
35
|
+
raise ValueError("No embedded object found")
|
|
36
|
+
return result
|
|
31
37
|
|
|
32
38
|
|
|
33
39
|
Activity = Annotated[dict, Depends(get_activity)]
|
|
@@ -7,19 +7,19 @@ from .common import Profile
|
|
|
7
7
|
try:
|
|
8
8
|
from bovine.activitystreams import factories_for_actor_object
|
|
9
9
|
from bovine.activitystreams.activity_factory import (
|
|
10
|
-
ActivityFactory as BovineActivityFactory,
|
|
10
|
+
ActivityFactory as BovineActivityFactory, # type: ignore
|
|
11
11
|
)
|
|
12
12
|
from bovine.activitystreams.object_factory import (
|
|
13
|
-
ObjectFactory as BovineObjectFactory,
|
|
13
|
+
ObjectFactory as BovineObjectFactory, # type: ignore
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
def get_activity_factory(profile: Profile) -> BovineActivityFactory:
|
|
16
|
+
def get_activity_factory(profile: Profile) -> BovineActivityFactory: # type: ignore
|
|
17
17
|
activity_factory, _ = factories_for_actor_object(profile)
|
|
18
|
-
return activity_factory
|
|
18
|
+
return activity_factory # type: ignore
|
|
19
19
|
|
|
20
|
-
def get_object_factory(profile: Profile) -> BovineObjectFactory:
|
|
20
|
+
def get_object_factory(profile: Profile) -> BovineObjectFactory: # type: ignore
|
|
21
21
|
_, object_factory = factories_for_actor_object(profile)
|
|
22
|
-
return object_factory
|
|
22
|
+
return object_factory # type: ignore
|
|
23
23
|
|
|
24
24
|
except ImportError:
|
|
25
25
|
|
|
@@ -34,8 +34,8 @@ except ImportError:
|
|
|
34
34
|
raise ImportError("bovine not installed")
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
ActivityFactory = Annotated[BovineActivityFactory, Depends(get_activity_factory)]
|
|
37
|
+
ActivityFactory = Annotated[BovineActivityFactory, Depends(get_activity_factory)] # type: ignore
|
|
38
38
|
"""The activity factory of type [bovine.activitystreams.activity_factory.ActivityFactory][]"""
|
|
39
39
|
|
|
40
|
-
ObjectFactory = Annotated[BovineObjectFactory, Depends(get_object_factory)]
|
|
40
|
+
ObjectFactory = Annotated[BovineObjectFactory, Depends(get_object_factory)] # type: ignore
|
|
41
41
|
"""The object factory of type [bovine.activitystreams.object_factory.ObjectFactory][]"""
|
|
@@ -187,7 +187,11 @@ class RoboCow:
|
|
|
187
187
|
"""Runs when the cow is birthed"""
|
|
188
188
|
|
|
189
189
|
if self.profile is None:
|
|
190
|
+
if not self.actor_id:
|
|
191
|
+
raise ValueError("Actor ID is not set")
|
|
190
192
|
result = await connection.fetch(self.actor_id, self.actor_id)
|
|
193
|
+
if not result.data:
|
|
194
|
+
raise ValueError("Could not retrieve profile")
|
|
191
195
|
self.profile = result.data
|
|
192
196
|
|
|
193
197
|
if self.cron_entries:
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
from urllib.parse import urlparse
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from bovine.activitystreams.utils import as_list
|
|
5
|
+
except ImportError:
|
|
6
|
+
|
|
7
|
+
def as_list(value):
|
|
8
|
+
if isinstance(value, list):
|
|
9
|
+
return value
|
|
10
|
+
|
|
11
|
+
return [value]
|
|
12
|
+
|
|
3
13
|
|
|
4
14
|
from .types import Information
|
|
5
15
|
|
|
@@ -27,7 +37,7 @@ def key_index_from_attachment(attachments: list[dict], key: str) -> int | None:
|
|
|
27
37
|
|
|
28
38
|
|
|
29
39
|
def determine_action_for_key_and_value(
|
|
30
|
-
attachments: list[dict], key: str, value: str
|
|
40
|
+
attachments: list[dict], key: str, value: str | None
|
|
31
41
|
) -> dict | None:
|
|
32
42
|
idx = key_index_from_attachment(attachments, key)
|
|
33
43
|
if idx is None:
|
|
@@ -78,19 +88,19 @@ def determine_actions(information: Information, profile: dict) -> list[dict] | N
|
|
|
78
88
|
"identifier": "acct:"
|
|
79
89
|
+ information.handle
|
|
80
90
|
+ "@"
|
|
81
|
-
+ urlparse(profile.get("id")).netloc,
|
|
91
|
+
+ str(urlparse(profile.get("id")).netloc),
|
|
82
92
|
"primary": True,
|
|
83
93
|
}
|
|
84
94
|
)
|
|
85
95
|
|
|
86
|
-
actions =
|
|
96
|
+
actions = [x for x in actions if x is not None]
|
|
87
97
|
|
|
88
98
|
if len(actions) == 0:
|
|
89
99
|
return None
|
|
90
100
|
return actions
|
|
91
101
|
|
|
92
102
|
|
|
93
|
-
def determine_profile_update(information: Information, profile: dict) -> dict:
|
|
103
|
+
def determine_profile_update(information: Information, profile: dict) -> dict | None:
|
|
94
104
|
"""Returns the update for the profile"""
|
|
95
105
|
|
|
96
106
|
update = {"actor": profile.get("id")}
|
|
@@ -6,13 +6,13 @@ class MetaInformation(BaseModel):
|
|
|
6
6
|
information such as the author and the source repository"""
|
|
7
7
|
|
|
8
8
|
source: str | None = Field(
|
|
9
|
-
None,
|
|
9
|
+
default=None,
|
|
10
10
|
examples=["https://forge.example/repo"],
|
|
11
11
|
description="The source repository",
|
|
12
12
|
)
|
|
13
13
|
|
|
14
14
|
author: str | None = Field(
|
|
15
|
-
None,
|
|
15
|
+
default=None,
|
|
16
16
|
examples=["acct:author@domain.example"],
|
|
17
17
|
description="The author, often a Fediverse handle",
|
|
18
18
|
)
|
|
@@ -22,23 +22,25 @@ class Information(BaseModel):
|
|
|
22
22
|
"""Information about the cow"""
|
|
23
23
|
|
|
24
24
|
type: str = Field(
|
|
25
|
-
|
|
25
|
+
default="Service",
|
|
26
|
+
examples=["Service"],
|
|
27
|
+
description="ActivityPub type of the actor.",
|
|
26
28
|
)
|
|
27
29
|
|
|
28
30
|
handle: str | None = Field(
|
|
29
|
-
None,
|
|
31
|
+
default=None,
|
|
30
32
|
examples=["moocow"],
|
|
31
33
|
description="Used as the handle in `acct:handle@domain.example`",
|
|
32
34
|
)
|
|
33
35
|
|
|
34
36
|
name: str | None = Field(
|
|
35
|
-
None,
|
|
37
|
+
default=None,
|
|
36
38
|
examples=["The mooing cow 🐮"],
|
|
37
39
|
description="The display name of the cow",
|
|
38
40
|
)
|
|
39
41
|
|
|
40
42
|
description: str | None = Field(
|
|
41
|
-
None,
|
|
43
|
+
default=None,
|
|
42
44
|
examples=[
|
|
43
45
|
"I'm a cow that moos.",
|
|
44
46
|
"""<p>An example bot to illustrate Roboherd</p><p>For more information on RoboHerd, see <a href="https://codeberg.org/bovine/roboherd">its repository</a>.</p>""",
|
|
@@ -47,12 +49,12 @@ class Information(BaseModel):
|
|
|
47
49
|
)
|
|
48
50
|
|
|
49
51
|
frequency: str | None = Field(
|
|
50
|
-
None,
|
|
52
|
+
default=None,
|
|
51
53
|
examples=["daily"],
|
|
52
54
|
description="Frequency of posting. Is set automatically if cron expressions are used.",
|
|
53
55
|
)
|
|
54
56
|
|
|
55
57
|
meta_information: MetaInformation = Field(
|
|
56
|
-
MetaInformation(),
|
|
58
|
+
default=MetaInformation(),
|
|
57
59
|
description="Meta information about the cow, such as the source repository",
|
|
58
60
|
)
|
|
@@ -51,7 +51,7 @@ async def post_number(
|
|
|
51
51
|
):
|
|
52
52
|
number = random.randint(0, 1000)
|
|
53
53
|
|
|
54
|
-
note = factory.note(content=f"Number: {number}").as_public().build()
|
|
54
|
+
note = factory.note(content=f"Number: {number}").as_public().build() # type: ignore
|
|
55
55
|
await publisher(note)
|
|
56
56
|
|
|
57
57
|
handle = "even" if number % 2 == 0 else "odd"
|
|
@@ -18,5 +18,5 @@ bot = RoboCow(
|
|
|
18
18
|
@bot.cron("42 * * * *")
|
|
19
19
|
async def crow(publisher: PublishObject, object_factory: ObjectFactory):
|
|
20
20
|
await publisher(
|
|
21
|
-
object_factory.note(content="cock-a-doodle-doo").as_public().build()
|
|
21
|
+
object_factory.note(content="cock-a-doodle-doo").as_public().build() # type: ignore
|
|
22
22
|
)
|
|
@@ -18,4 +18,4 @@ bot = RoboCow(
|
|
|
18
18
|
|
|
19
19
|
@bot.startup
|
|
20
20
|
async def startup(publish_object: PublishObject, object_factory: ObjectFactory):
|
|
21
|
-
await publish_object(object_factory.note(content="Booo! 🐦").as_public().build())
|
|
21
|
+
await publish_object(object_factory.note(content="Booo! 🐦").as_public().build()) # type: ignore
|
|
@@ -29,6 +29,9 @@ class RoboHerd:
|
|
|
29
29
|
await self.process(connection)
|
|
30
30
|
|
|
31
31
|
async def startup(self, connection: Almabtrieb):
|
|
32
|
+
if not connection.information:
|
|
33
|
+
raise Exception("Could not get information from server")
|
|
34
|
+
|
|
32
35
|
self.cows = self.manager.existing_cows(connection.information.actors)
|
|
33
36
|
|
|
34
37
|
cows_to_create = self.manager.cows_to_create(connection.information.actors)
|
|
@@ -60,9 +63,6 @@ class RoboHerd:
|
|
|
60
63
|
scheduler = HerdScheduler(self.cron_entries(), connection)
|
|
61
64
|
scheduler.create_task(tg)
|
|
62
65
|
|
|
63
|
-
def introduce(self, cow: RoboCow):
|
|
64
|
-
self.manager.add_to_herd(cow)
|
|
65
|
-
|
|
66
66
|
def validate(self, connection):
|
|
67
67
|
result = connection.information
|
|
68
68
|
|
|
@@ -43,4 +43,6 @@ class HerdManager:
|
|
|
43
43
|
}
|
|
44
44
|
names_to_create = self.herd_config.names - existing_names
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
cows = {self.herd_config.for_name(name) for name in names_to_create}
|
|
47
|
+
|
|
48
|
+
return {cow for cow in cows if cow}
|
|
@@ -21,7 +21,7 @@ def test_config():
|
|
|
21
21
|
},
|
|
22
22
|
},
|
|
23
23
|
}
|
|
24
|
-
)
|
|
24
|
+
) # type: ignore
|
|
25
25
|
return config
|
|
26
26
|
|
|
27
27
|
|
|
@@ -44,7 +44,7 @@ def test_load_config(test_config):
|
|
|
44
44
|
assert len(herd.cows) == 2
|
|
45
45
|
|
|
46
46
|
moocow = herd.for_name("moocow")
|
|
47
|
-
|
|
47
|
+
assert moocow
|
|
48
48
|
assert moocow.name == "moocow"
|
|
49
49
|
|
|
50
50
|
|
|
@@ -919,6 +919,15 @@ wheels = [
|
|
|
919
919
|
{ url = "https://files.pythonhosted.org/packages/99/b7/b9e70fde2c0f0c9af4cc5277782a89b66d35948ea3369ec9f598358c3ac5/multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506", size = 10051 },
|
|
920
920
|
]
|
|
921
921
|
|
|
922
|
+
[[package]]
|
|
923
|
+
name = "nodeenv"
|
|
924
|
+
version = "1.9.1"
|
|
925
|
+
source = { registry = "https://pypi.org/simple" }
|
|
926
|
+
sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 }
|
|
927
|
+
wheels = [
|
|
928
|
+
{ url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 },
|
|
929
|
+
]
|
|
930
|
+
|
|
922
931
|
[[package]]
|
|
923
932
|
name = "packaging"
|
|
924
933
|
version = "24.2"
|
|
@@ -1195,6 +1204,19 @@ wheels = [
|
|
|
1195
1204
|
{ url = "https://files.pythonhosted.org/packages/eb/f5/b9e2a42aa8f9e34d52d66de87941ecd236570c7ed2e87775ed23bbe4e224/pymdown_extensions-10.14.3-py3-none-any.whl", hash = "sha256:05e0bee73d64b9c71a4ae17c72abc2f700e8bc8403755a00580b49a4e9f189e9", size = 264467 },
|
|
1196
1205
|
]
|
|
1197
1206
|
|
|
1207
|
+
[[package]]
|
|
1208
|
+
name = "pyright"
|
|
1209
|
+
version = "1.1.394"
|
|
1210
|
+
source = { registry = "https://pypi.org/simple" }
|
|
1211
|
+
dependencies = [
|
|
1212
|
+
{ name = "nodeenv" },
|
|
1213
|
+
{ name = "typing-extensions" },
|
|
1214
|
+
]
|
|
1215
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b1/e4/79f4d8a342eed6790fdebdb500e95062f319ee3d7d75ae27304ff995ae8c/pyright-1.1.394.tar.gz", hash = "sha256:56f2a3ab88c5214a451eb71d8f2792b7700434f841ea219119ade7f42ca93608", size = 3809348 }
|
|
1216
|
+
wheels = [
|
|
1217
|
+
{ url = "https://files.pythonhosted.org/packages/d6/4c/50c74e3d589517a9712a61a26143b587dba6285434a17aebf2ce6b82d2c3/pyright-1.1.394-py3-none-any.whl", hash = "sha256:5f74cce0a795a295fb768759bbeeec62561215dea657edcaab48a932b031ddbb", size = 5679540 },
|
|
1218
|
+
]
|
|
1219
|
+
|
|
1198
1220
|
[[package]]
|
|
1199
1221
|
name = "pytest"
|
|
1200
1222
|
version = "8.3.4"
|
|
@@ -1363,9 +1385,10 @@ wheels = [
|
|
|
1363
1385
|
|
|
1364
1386
|
[[package]]
|
|
1365
1387
|
name = "roboherd"
|
|
1366
|
-
version = "0.1.
|
|
1388
|
+
version = "0.1.4"
|
|
1367
1389
|
source = { editable = "." }
|
|
1368
1390
|
dependencies = [
|
|
1391
|
+
{ name = "aiohttp" },
|
|
1369
1392
|
{ name = "almabtrieb", extra = ["mqtt"] },
|
|
1370
1393
|
{ name = "apscheduler" },
|
|
1371
1394
|
{ name = "click" },
|
|
@@ -1387,6 +1410,7 @@ dev = [
|
|
|
1387
1410
|
{ name = "mkdocs-click" },
|
|
1388
1411
|
{ name = "mkdocs-material" },
|
|
1389
1412
|
{ name = "mkdocstrings-python" },
|
|
1413
|
+
{ name = "pyright" },
|
|
1390
1414
|
{ name = "pytest" },
|
|
1391
1415
|
{ name = "pytest-asyncio" },
|
|
1392
1416
|
{ name = "pytest-watcher" },
|
|
@@ -1395,6 +1419,7 @@ dev = [
|
|
|
1395
1419
|
|
|
1396
1420
|
[package.metadata]
|
|
1397
1421
|
requires-dist = [
|
|
1422
|
+
{ name = "aiohttp", specifier = ">=3.11.12" },
|
|
1398
1423
|
{ name = "almabtrieb", extras = ["mqtt"], specifier = ">=0.1.0a1" },
|
|
1399
1424
|
{ name = "apscheduler", specifier = ">=3.11.0" },
|
|
1400
1425
|
{ name = "bovine", marker = "extra == 'bovine'", specifier = ">=0.5.15" },
|
|
@@ -1412,6 +1437,7 @@ dev = [
|
|
|
1412
1437
|
{ name = "mkdocs-click", specifier = ">=0.8.1" },
|
|
1413
1438
|
{ name = "mkdocs-material", specifier = ">=9.5.50" },
|
|
1414
1439
|
{ name = "mkdocstrings-python", specifier = ">=1.13.0" },
|
|
1440
|
+
{ name = "pyright", specifier = ">=1.1.394" },
|
|
1415
1441
|
{ name = "pytest", specifier = ">=8.3.4" },
|
|
1416
1442
|
{ name = "pytest-asyncio", specifier = ">=0.25.2" },
|
|
1417
1443
|
{ name = "pytest-watcher", specifier = ">=0.4.3" },
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|