roboherd 0.1.8__py3-none-any.whl → 0.1.10__py3-none-any.whl
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/__main__.py +26 -5
- roboherd/examples/rooster.py +1 -0
- roboherd/herd/__init__.py +23 -6
- roboherd/herd/manager/__init__.py +1 -2
- roboherd/herd/processor.py +4 -1
- roboherd/herd/scheduler.py +19 -4
- roboherd/herd/test_herd.py +2 -2
- roboherd/register.py +4 -2
- roboherd/util.py +2 -2
- roboherd-0.1.10.dist-info/METADATA +78 -0
- {roboherd-0.1.8.dist-info → roboherd-0.1.10.dist-info}/RECORD +13 -13
- roboherd-0.1.8.dist-info/METADATA +0 -27
- {roboherd-0.1.8.dist-info → roboherd-0.1.10.dist-info}/WHEEL +0 -0
- {roboherd-0.1.8.dist-info → roboherd-0.1.10.dist-info}/entry_points.txt +0 -0
roboherd/__main__.py
CHANGED
|
@@ -13,6 +13,7 @@ from roboherd.register import register as run_register
|
|
|
13
13
|
from roboherd.validators import validators
|
|
14
14
|
|
|
15
15
|
logging.basicConfig(level=logging.INFO)
|
|
16
|
+
logging.captureWarnings(True)
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
@click.group()
|
|
@@ -28,7 +29,7 @@ logging.basicConfig(level=logging.INFO)
|
|
|
28
29
|
)
|
|
29
30
|
@click.option("--config_file", default="roboherd.toml", help="Configuration file")
|
|
30
31
|
@click.pass_context
|
|
31
|
-
def main(ctx, connection_string, base_url, config_file):
|
|
32
|
+
def main(ctx: click.Context, connection_string: str, base_url: str, config_file: str):
|
|
32
33
|
"""Configuration is usually loaded from the config_file. These options can be overwritten by passing as a command line argument."""
|
|
33
34
|
settings = dynaconf.Dynaconf(
|
|
34
35
|
settings_files=[config_file],
|
|
@@ -43,17 +44,37 @@ def main(ctx, connection_string, base_url, config_file):
|
|
|
43
44
|
if connection_string:
|
|
44
45
|
ctx.obj["connection_string"] = connection_string
|
|
45
46
|
else:
|
|
46
|
-
ctx.obj["connection_string"] = settings.connection_string
|
|
47
|
+
ctx.obj["connection_string"] = settings.connection_string # type: ignore
|
|
47
48
|
|
|
48
49
|
if base_url:
|
|
49
50
|
ctx.obj["base_url"] = base_url
|
|
50
51
|
else:
|
|
51
|
-
ctx.obj["base_url"] = settings.base_url
|
|
52
|
+
ctx.obj["base_url"] = settings.base_url # type: ignore
|
|
52
53
|
|
|
53
54
|
|
|
54
55
|
@main.command()
|
|
56
|
+
@click.option("--fail", is_flag=True, default=False, help="Fail if actors do not exist")
|
|
55
57
|
@click.pass_context
|
|
56
|
-
def
|
|
58
|
+
def check(ctx: click.Context, fail: bool):
|
|
59
|
+
"""Checks that the connection is configured correctly"""
|
|
60
|
+
|
|
61
|
+
create_connection(ctx)
|
|
62
|
+
|
|
63
|
+
herd = RoboHerd(base_url=ctx.obj["base_url"])
|
|
64
|
+
|
|
65
|
+
settings = ctx.obj["settings"]
|
|
66
|
+
|
|
67
|
+
if settings.get("cow"):
|
|
68
|
+
herd.manager = HerdManager.from_settings(settings)
|
|
69
|
+
asyncio.run(herd.check(ctx.obj["connection"], raise_if_cows_to_create=fail))
|
|
70
|
+
else:
|
|
71
|
+
click.echo("No cows specified")
|
|
72
|
+
exit(1)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@main.command()
|
|
76
|
+
@click.pass_context
|
|
77
|
+
def run(ctx: click.Context):
|
|
57
78
|
"""Runs the roboherd by connecting to the server."""
|
|
58
79
|
|
|
59
80
|
create_connection(ctx)
|
|
@@ -90,7 +111,7 @@ def watch(ctx):
|
|
|
90
111
|
prompt=True,
|
|
91
112
|
)
|
|
92
113
|
@click.option("--fediverse", help="Fediverse handle", prompt=True)
|
|
93
|
-
def register(ctx, name, password, fediverse):
|
|
114
|
+
def register(ctx: click.Context, name: str, password: str, fediverse: str):
|
|
94
115
|
"""Registers a new account on dev.bovine.social. All three options are required. If not provided, you will be prompted for them."""
|
|
95
116
|
|
|
96
117
|
if os.path.exists(ctx.obj["config_file"]):
|
roboherd/examples/rooster.py
CHANGED
roboherd/herd/__init__.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
|
-
from typing import List, Tuple
|
|
5
4
|
from dataclasses import dataclass, field
|
|
6
5
|
|
|
7
6
|
from roboherd.cow import RoboCow, CronEntry
|
|
@@ -20,7 +19,7 @@ class RoboHerd:
|
|
|
20
19
|
base_url: str = "http://abel"
|
|
21
20
|
|
|
22
21
|
manager: HerdManager = field(default_factory=HerdManager)
|
|
23
|
-
cows:
|
|
22
|
+
cows: list[RoboCow] = field(default_factory=list) # type: ignore
|
|
24
23
|
|
|
25
24
|
async def run(self, connection: Almabtrieb):
|
|
26
25
|
async with connection:
|
|
@@ -28,12 +27,26 @@ class RoboHerd:
|
|
|
28
27
|
await self.startup(connection)
|
|
29
28
|
await self.process(connection)
|
|
30
29
|
|
|
30
|
+
async def check(
|
|
31
|
+
self, connection: Almabtrieb, raise_if_cows_to_create: bool = False
|
|
32
|
+
):
|
|
33
|
+
async with connection:
|
|
34
|
+
if not connection.information:
|
|
35
|
+
raise Exception("Could not get information from server")
|
|
36
|
+
self.validate(connection)
|
|
37
|
+
cows_to_create = self.manager.cows_to_create(connection.information.actors)
|
|
38
|
+
|
|
39
|
+
if len(cows_to_create) > 0:
|
|
40
|
+
print("Missing cows: " + ", ".join([x.name for x in cows_to_create]))
|
|
41
|
+
|
|
42
|
+
if raise_if_cows_to_create:
|
|
43
|
+
raise Exception("Missing cows")
|
|
44
|
+
|
|
31
45
|
async def startup(self, connection: Almabtrieb):
|
|
32
46
|
if not connection.information:
|
|
33
47
|
raise Exception("Could not get information from server")
|
|
34
48
|
|
|
35
49
|
self.cows = self.manager.existing_cows(connection.information.actors)
|
|
36
|
-
|
|
37
50
|
cows_to_create = self.manager.cows_to_create(connection.information.actors)
|
|
38
51
|
|
|
39
52
|
for cow_config in cows_to_create:
|
|
@@ -63,8 +76,12 @@ class RoboHerd:
|
|
|
63
76
|
scheduler = HerdScheduler(self.cron_entries(), connection)
|
|
64
77
|
scheduler.create_task(tg)
|
|
65
78
|
|
|
66
|
-
|
|
79
|
+
connection.add_on_disconnect(scheduler.stop)
|
|
80
|
+
|
|
81
|
+
def validate(self, connection: Almabtrieb):
|
|
67
82
|
result = connection.information
|
|
83
|
+
if result is None:
|
|
84
|
+
raise ValueError("information not retrieved from connection")
|
|
68
85
|
|
|
69
86
|
logger.info("Got base urls: %s", ",".join(result.base_urls))
|
|
70
87
|
|
|
@@ -76,7 +93,7 @@ class RoboHerd:
|
|
|
76
93
|
)
|
|
77
94
|
raise ValueError("Incorrectly configured base url")
|
|
78
95
|
|
|
79
|
-
def cron_entries(self) ->
|
|
96
|
+
def cron_entries(self) -> list[tuple[RoboCow, CronEntry]]:
|
|
80
97
|
"""Returns the cron entries of all cows"""
|
|
81
98
|
|
|
82
99
|
result = []
|
|
@@ -86,7 +103,7 @@ class RoboHerd:
|
|
|
86
103
|
|
|
87
104
|
return result
|
|
88
105
|
|
|
89
|
-
def incoming_handlers(self) ->
|
|
106
|
+
def incoming_handlers(self) -> list[RoboCow]:
|
|
90
107
|
result = []
|
|
91
108
|
for cow in self.cows:
|
|
92
109
|
if cow.internals.handlers.has_handlers:
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
|
-
from typing import List
|
|
4
3
|
from dataclasses import dataclass, field
|
|
5
4
|
|
|
6
5
|
from almabtrieb.model import ActorInformation
|
|
@@ -21,7 +20,7 @@ class HerdManager:
|
|
|
21
20
|
def from_settings(settings):
|
|
22
21
|
return HerdManager(herd_config=HerdConfig.from_settings(settings))
|
|
23
22
|
|
|
24
|
-
def existing_cows(self, actors:
|
|
23
|
+
def existing_cows(self, actors: list[ActorInformation]) -> list[RoboCow]:
|
|
25
24
|
existing_cows = []
|
|
26
25
|
|
|
27
26
|
for info in actors:
|
roboherd/herd/processor.py
CHANGED
|
@@ -28,12 +28,15 @@ class HerdProcessor:
|
|
|
28
28
|
for cow in self.incoming_handlers:
|
|
29
29
|
actor_id_to_cow_map[cow.internals.actor_id] = cow
|
|
30
30
|
|
|
31
|
+
logger.info("Incoming processing started for %s cows", len(actor_id_to_cow_map))
|
|
32
|
+
|
|
31
33
|
async for msg in connection.incoming():
|
|
32
34
|
actor_id = msg["actor"]
|
|
33
35
|
|
|
34
36
|
cow = actor_id_to_cow_map.get(actor_id)
|
|
35
|
-
logger.info(cow)
|
|
36
37
|
if cow:
|
|
37
38
|
await cow.internals.handlers.handle(
|
|
38
39
|
msg, "incoming", connection, actor_id, cow=cow
|
|
39
40
|
)
|
|
41
|
+
|
|
42
|
+
logger.warning("Process incoming ended")
|
roboherd/herd/scheduler.py
CHANGED
|
@@ -19,22 +19,30 @@ logger = logging.getLogger(__name__)
|
|
|
19
19
|
class HerdScheduler:
|
|
20
20
|
entries: List[Tuple[RoboCow, CronEntry]]
|
|
21
21
|
connection: Almabtrieb
|
|
22
|
+
scheduler: AsyncIOScheduler | None = None
|
|
23
|
+
task: asyncio.Task | None = None
|
|
22
24
|
|
|
23
25
|
def create_task(self, task_group: asyncio.TaskGroup):
|
|
24
26
|
if len(self.entries) == 0:
|
|
25
27
|
logger.info("No tasks to schedule")
|
|
26
28
|
return
|
|
27
|
-
|
|
29
|
+
if self.task:
|
|
30
|
+
raise Exception("Task already running")
|
|
31
|
+
|
|
32
|
+
self.task = task_group.create_task(self.run())
|
|
28
33
|
|
|
29
34
|
async def run(self):
|
|
30
35
|
if len(self.entries) == 0:
|
|
31
36
|
return
|
|
32
37
|
|
|
33
|
-
scheduler
|
|
38
|
+
if self.scheduler:
|
|
39
|
+
raise Exception("Scheduler already exists")
|
|
40
|
+
|
|
41
|
+
self.scheduler = AsyncIOScheduler()
|
|
34
42
|
|
|
35
43
|
for cow, entry in self.entries:
|
|
36
44
|
trigger = CronTrigger.from_crontab(entry.crontab)
|
|
37
|
-
scheduler.add_job(
|
|
45
|
+
self.scheduler.add_job(
|
|
38
46
|
inject(entry.func),
|
|
39
47
|
trigger=trigger,
|
|
40
48
|
kwargs={
|
|
@@ -44,7 +52,14 @@ class HerdScheduler:
|
|
|
44
52
|
},
|
|
45
53
|
)
|
|
46
54
|
|
|
47
|
-
scheduler.start()
|
|
55
|
+
self.scheduler.start()
|
|
48
56
|
|
|
49
57
|
while True:
|
|
50
58
|
await asyncio.sleep(60 * 60)
|
|
59
|
+
|
|
60
|
+
async def stop(self):
|
|
61
|
+
logger.warning("Stopping scheduler")
|
|
62
|
+
if self.scheduler:
|
|
63
|
+
self.scheduler.shutdown()
|
|
64
|
+
if self.task:
|
|
65
|
+
self.task.cancel()
|
roboherd/herd/test_herd.py
CHANGED
|
@@ -6,11 +6,11 @@ from roboherd.examples.dev_null import bot as dev_null
|
|
|
6
6
|
|
|
7
7
|
from roboherd.cow import CronEntry
|
|
8
8
|
|
|
9
|
-
from . import RoboHerd
|
|
9
|
+
from . import RoboHerd, RoboCow
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@pytest.mark.parametrize("cow, length", [(moocow, 0), (bot, 1)])
|
|
13
|
-
def test_cron_entries(cow, length):
|
|
13
|
+
def test_cron_entries(cow: RoboCow, length: int):
|
|
14
14
|
manager = RoboHerd(cows=[cow])
|
|
15
15
|
|
|
16
16
|
assert len(manager.cron_entries()) == length
|
roboherd/register.py
CHANGED
|
@@ -2,7 +2,9 @@ import aiohttp
|
|
|
2
2
|
import tomli_w
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
def create_config(
|
|
5
|
+
def create_config(
|
|
6
|
+
name: str, password: str, domain: str = "dev.bovine.social"
|
|
7
|
+
) -> dict[str, bool | str]:
|
|
6
8
|
"""
|
|
7
9
|
|
|
8
10
|
```
|
|
@@ -21,7 +23,7 @@ def create_config(name, password, domain="dev.bovine.social"):
|
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
|
|
24
|
-
async def register(config_file, name, password, fediverse):
|
|
26
|
+
async def register(config_file: str, name: str, password: str, fediverse: str):
|
|
25
27
|
async with aiohttp.ClientSession() as session:
|
|
26
28
|
result = await session.post(
|
|
27
29
|
"https://dev.bovine.social/register",
|
roboherd/util.py
CHANGED
|
@@ -8,7 +8,7 @@ from almabtrieb import Almabtrieb
|
|
|
8
8
|
logger = logging.getLogger(__name__)
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
def parse_connection_string(connection_string: str) -> dict:
|
|
11
|
+
def parse_connection_string(connection_string: str) -> dict[str, str | int | None]:
|
|
12
12
|
"""
|
|
13
13
|
Parse a connection string into a dictionary of connection parameters.
|
|
14
14
|
|
|
@@ -43,7 +43,7 @@ def parse_connection_string(connection_string: str) -> dict:
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
def create_connection(ctx):
|
|
46
|
+
def create_connection(ctx: click.Context):
|
|
47
47
|
connection_string = ctx.obj["connection_string"]
|
|
48
48
|
base_url = ctx.obj["base_url"]
|
|
49
49
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: roboherd
|
|
3
|
+
Version: 0.1.10
|
|
4
|
+
Summary: A Fediverse bot framework
|
|
5
|
+
Project-URL: Documentation, https://bovine.codeberg.page/roboherd/
|
|
6
|
+
Project-URL: Repository, https://codeberg.org/bovine/roboherd
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Requires-Dist: aiohttp>=3.11.12
|
|
9
|
+
Requires-Dist: almabtrieb[mqtt]>=0.2
|
|
10
|
+
Requires-Dist: apscheduler>=3.11.0
|
|
11
|
+
Requires-Dist: click>=8.1.8
|
|
12
|
+
Requires-Dist: cron-descriptor>=1.4.5
|
|
13
|
+
Requires-Dist: dynaconf>=3.2.6
|
|
14
|
+
Requires-Dist: fast-depends>=2.4.12
|
|
15
|
+
Requires-Dist: tomli-w>=1.1.0
|
|
16
|
+
Requires-Dist: watchfiles>=1.0.4
|
|
17
|
+
Provides-Extra: bovine
|
|
18
|
+
Requires-Dist: bovine>=0.5.15; extra == 'bovine'
|
|
19
|
+
Requires-Dist: markdown>=3.7; extra == 'bovine'
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# Roboherd
|
|
23
|
+
|
|
24
|
+
Roboherd is a framework for building Fediverse bots
|
|
25
|
+
using the [Cattle Drive Protocol](https://bovine.codeberg.page/cattle_grid/cattle_drive/).
|
|
26
|
+
|
|
27
|
+
For more information, see the [documentation](https://bovine.codeberg.page/roboherd/) or the [repository](https://codeberg.org/bovine/roboherd/).
|
|
28
|
+
|
|
29
|
+
## Developping with cattle_grid
|
|
30
|
+
|
|
31
|
+
In your catle_grid `config` directory add a roboherd user, e.g.
|
|
32
|
+
a file `testing.toml` with content
|
|
33
|
+
|
|
34
|
+
```toml
|
|
35
|
+
[testing]
|
|
36
|
+
enable = true
|
|
37
|
+
|
|
38
|
+
[[testing.accounts]]
|
|
39
|
+
name = "herd"
|
|
40
|
+
password = "pass"
|
|
41
|
+
permissions = ["admin"]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Configure roboherd via `roboherd.toml`, e.g.
|
|
45
|
+
|
|
46
|
+
```toml
|
|
47
|
+
base_url = "http://abel"
|
|
48
|
+
connection_string = "ws://herd:pass@localhost:3000/ws/"
|
|
49
|
+
|
|
50
|
+
[cow.rooster]
|
|
51
|
+
bot = "roboherd.examples.rooster:bot"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This will trigger a periodic message to cattle_grid.
|
|
55
|
+
|
|
56
|
+
### nginx for cattle_grid
|
|
57
|
+
|
|
58
|
+
The nginx in the `cattle_grid` configuration should forward the path `/ws/` to
|
|
59
|
+
rabbitmq (supporting mqtt over websockets)
|
|
60
|
+
|
|
61
|
+
```nginx
|
|
62
|
+
server {
|
|
63
|
+
listen 80;
|
|
64
|
+
|
|
65
|
+
location /ws/ {
|
|
66
|
+
proxy_pass http://rabbitmq:15675;
|
|
67
|
+
proxy_http_version 1.1;
|
|
68
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
69
|
+
proxy_set_header Connection $connection_upgrade;
|
|
70
|
+
proxy_read_timeout 86400; # neccessary to avoid websocket timeout disconnect
|
|
71
|
+
proxy_send_timeout 86400; # neccessary to avoid websocket timeout disconnect
|
|
72
|
+
proxy_redirect off;
|
|
73
|
+
proxy_buffering off;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
similarly `nginx` should forward port 80 to 3000 (in the docker compose file).
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
roboherd/__init__.py,sha256=E89YtYyL77iJDJJkHS4Pn0JdTbmkmQS7Cp_XPqpRgx8,533
|
|
2
|
-
roboherd/__main__.py,sha256=
|
|
3
|
-
roboherd/register.py,sha256=
|
|
2
|
+
roboherd/__main__.py,sha256=DxxPrubMXNp_rqE-1S-S7pCn065CfQo2uHmxP1FWZU4,3655
|
|
3
|
+
roboherd/register.py,sha256=jnnHv-epeyXHcmmulxJoHqT7uWmb_efFnCbdxojKOBM,1044
|
|
4
4
|
roboherd/test_validators.py,sha256=UiFgJkutmXBLjGpdLP2IBYCEf75quwnRHX7Z51G8Xqo,222
|
|
5
|
-
roboherd/util.py,sha256=
|
|
5
|
+
roboherd/util.py,sha256=gG8Scht1xRfauUOdL7GrLf9e3UO-j88X2wEdc1Ymm3o,1748
|
|
6
6
|
roboherd/validators.py,sha256=2mc43ZGwFazp4f3B9J4RxZCU4Y_ErSNotib8MnYVtmY,140
|
|
7
7
|
roboherd/annotations/__init__.py,sha256=BrP5UWiVnh8FwmHc6wEY3G69BStidGUpF8uP4Ea5-dg,1140
|
|
8
8
|
roboherd/annotations/bovine.py,sha256=cFLUSFzTulikNjZb1lLq5v4tGjL1i7_dR3H6wimegCg,2322
|
|
@@ -23,22 +23,22 @@ roboherd/examples/json_echo.py,sha256=TB7sdshsTj7KKOxIc1DzkGeacA9JmIOhNOHwGzyRrV
|
|
|
23
23
|
roboherd/examples/meta.py,sha256=tFhHe-DJn2J13Mm22f-gFm5I8_3uQwLU4mAkrK2xzEM,170
|
|
24
24
|
roboherd/examples/moocow.py,sha256=2bZ8oZOpysuf7l3DP3zM4YiaALQHFbWpbP3h_Xlok6E,974
|
|
25
25
|
roboherd/examples/number.py,sha256=c4zALxrKR5POuAUTmzAF4wHVgXMPfrP736N7dgn4xzo,1845
|
|
26
|
-
roboherd/examples/rooster.py,sha256=
|
|
26
|
+
roboherd/examples/rooster.py,sha256=ItPBpxhz72agkzFf13nv6csYVUJCZRabtUaGyKwUKRg,501
|
|
27
27
|
roboherd/examples/scarecrow.py,sha256=jUnBaDJ2w9LQNIJAAfA53oJyRvKPJoKHtvHbeW-Pex0,626
|
|
28
|
-
roboherd/herd/__init__.py,sha256=
|
|
28
|
+
roboherd/herd/__init__.py,sha256=_JC0GK1sXSeY5nIwZ9Sd7XWuG6ZteHRcK3N8q5Awt3k,3825
|
|
29
29
|
roboherd/herd/builder.py,sha256=MSVPRF0Jsxure9kdyCoYJHQ7nYilGAD0_uQaGQ-rQyE,619
|
|
30
|
-
roboherd/herd/processor.py,sha256=
|
|
31
|
-
roboherd/herd/scheduler.py,sha256=
|
|
32
|
-
roboherd/herd/test_herd.py,sha256=
|
|
30
|
+
roboherd/herd/processor.py,sha256=4wZUp4xND9ZhxLIedUN7Yu3jxKWuuFqJent7wRiaAE0,1153
|
|
31
|
+
roboherd/herd/scheduler.py,sha256=4zAPJkWs1ZGHlwTweHdhYb5xrHnpiSTpTEQ64drA-oE,1735
|
|
32
|
+
roboherd/herd/test_herd.py,sha256=9Gf_Yh2a58EsSq3KYbR6IJBqM9JOueO6unzPwe-ciJ4,868
|
|
33
33
|
roboherd/herd/test_scheduler.py,sha256=wLisqRMSl734P_rjbqMNH5WTQKepwihgr7ZC32nEj80,424
|
|
34
34
|
roboherd/herd/types.py,sha256=_EidQbglm0jpsKX1EsL6U2qm_J5wCPhwUi6Avac22Ow,210
|
|
35
|
-
roboherd/herd/manager/__init__.py,sha256=
|
|
35
|
+
roboherd/herd/manager/__init__.py,sha256=7GcH0AZwLjNX7kLK-CXTvnaM3ZMWdstlTEqAY3IstZA,1440
|
|
36
36
|
roboherd/herd/manager/config.py,sha256=8m-313_wn_-b4ivPSoPyyTQh0ONNLcd-Zz3pgWh8p1c,2429
|
|
37
37
|
roboherd/herd/manager/load.py,sha256=BoeBID2UGP--sIKwITABQkQv2lMc9Y8pyp7_nleu2bw,351
|
|
38
38
|
roboherd/herd/manager/test_config.py,sha256=I2EP7nEUdBVO8Wqot7SRhzp5UZFr5oGIuFS7cNB2iFk,1745
|
|
39
39
|
roboherd/herd/manager/test_load.py,sha256=zyu5LIChMfTnxu_tYK63-bSOHYn1K1zUlbDY5DkE3GY,514
|
|
40
40
|
roboherd/herd/manager/test_manager.py,sha256=9pSMaH7zmN-zagYCIBpQcV3Q0sBT7XZSCvsmLVC0rOI,1047
|
|
41
|
-
roboherd-0.1.
|
|
42
|
-
roboherd-0.1.
|
|
43
|
-
roboherd-0.1.
|
|
44
|
-
roboherd-0.1.
|
|
41
|
+
roboherd-0.1.10.dist-info/METADATA,sha256=rYVd_FKmmzULegTCdV9Xvp8W4Vn-DcKn_xokqfoUPPA,2206
|
|
42
|
+
roboherd-0.1.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
43
|
+
roboherd-0.1.10.dist-info/entry_points.txt,sha256=WebdVUmh8Ot-FupKJY6Du8LuFbmezt9yoy2UICqV3bE,52
|
|
44
|
+
roboherd-0.1.10.dist-info/RECORD,,
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: roboherd
|
|
3
|
-
Version: 0.1.8
|
|
4
|
-
Summary: A Fediverse bot framework
|
|
5
|
-
Project-URL: Documentation, https://bovine.codeberg.page/roboherd/
|
|
6
|
-
Project-URL: Repository, https://codeberg.org/bovine/roboherd
|
|
7
|
-
Requires-Python: >=3.11
|
|
8
|
-
Requires-Dist: aiohttp>=3.11.12
|
|
9
|
-
Requires-Dist: almabtrieb[mqtt]>=0.1.0a1
|
|
10
|
-
Requires-Dist: apscheduler>=3.11.0
|
|
11
|
-
Requires-Dist: click>=8.1.8
|
|
12
|
-
Requires-Dist: cron-descriptor>=1.4.5
|
|
13
|
-
Requires-Dist: dynaconf>=3.2.6
|
|
14
|
-
Requires-Dist: fast-depends>=2.4.12
|
|
15
|
-
Requires-Dist: tomli-w>=1.1.0
|
|
16
|
-
Requires-Dist: watchfiles>=1.0.4
|
|
17
|
-
Provides-Extra: bovine
|
|
18
|
-
Requires-Dist: bovine>=0.5.15; extra == 'bovine'
|
|
19
|
-
Requires-Dist: markdown>=3.7; extra == 'bovine'
|
|
20
|
-
Description-Content-Type: text/markdown
|
|
21
|
-
|
|
22
|
-
# Roboherd
|
|
23
|
-
|
|
24
|
-
Roboherd is a framework for building Fediverse bots
|
|
25
|
-
using the [Cattle Drive Protocol](https://bovine.codeberg.page/cattle_grid/cattle_drive/).
|
|
26
|
-
|
|
27
|
-
For more information, see the [documentation](https://bovine.codeberg.page/roboherd/) or the [repository](https://codeberg.org/bovine/roboherd/).
|
|
File without changes
|
|
File without changes
|