nixify and fixify
This commit is contained in:
parent
29c6f5c4ef
commit
6f125fdb1f
|
@ -0,0 +1,6 @@
|
||||||
|
# PVV Calendar -> Matrix bot
|
||||||
|
|
||||||
|
This bot scrapes https://pvv.ntnu.no/hendelser/, fetches todays events and sends announcement messages in matrix.
|
||||||
|
|
||||||
|
Packaged as a nix flake, see ./module.nix for options.
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1692986144,
|
||||||
|
"narHash": "sha256-M4VFpy7Av9j+33HF5nIGm0k2+DXXW4qSSKdidIKg5jY=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "74e5bdc5478ebbe7ba5849f0d765f92757bb9dbf",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-23.05",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "nixpkgs/nixos-23.05";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs }: let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
in {
|
||||||
|
packages.${system} = {
|
||||||
|
default = self.packages.${system}.pvv-calendar-bot;
|
||||||
|
pvv-calendar-bot = pkgs.python3Packages.buildPythonPackage {
|
||||||
|
name = "pvv-calendar-bot";
|
||||||
|
src = ./.;
|
||||||
|
format = "pyproject";
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkgs.python3Packages.setuptools
|
||||||
|
];
|
||||||
|
|
||||||
|
propagatedBuildInputs = with pkgs.python3Packages; [
|
||||||
|
beautifulsoup4
|
||||||
|
markdown2
|
||||||
|
matrix-nio
|
||||||
|
requests
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nixosModules.default = ./module.nix;
|
||||||
|
|
||||||
|
overlays.${system}.default = prevPackages: finalPackages: {
|
||||||
|
inherit (self.packages.${system}) pvv-calendar-bot;
|
||||||
|
};
|
||||||
|
|
||||||
|
nixosConfigurations."test" = nixpkgs.lib.nixosSystem {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
modules = [
|
||||||
|
self.nixosModules.default
|
||||||
|
{ nixpkgs.overlays = [ self.overlays."x86_64-linux".default ]; }
|
||||||
|
{
|
||||||
|
boot.isContainer = true;
|
||||||
|
|
||||||
|
services.pvv-calendar-bot = {
|
||||||
|
enable = true;
|
||||||
|
settings.matrix = {
|
||||||
|
channel = "testchannel";
|
||||||
|
user = "testuser";
|
||||||
|
homeserver = "pvv.ntnu.no";
|
||||||
|
};
|
||||||
|
settings.secretsFile = pkgs.writeText "calendarSecrets" "snakeoil";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.services.pvv-calendar-bot;
|
||||||
|
inherit (lib) mkDefault mkEnableOption mkPackageOption mkIf mkOption types mdDoc;
|
||||||
|
in {
|
||||||
|
|
||||||
|
options.services.pvv-calendar-bot = {
|
||||||
|
enable = mkEnableOption (lib.mdDoc "Enable pvv-calendar-bot to post to matrix");
|
||||||
|
|
||||||
|
package = mkPackageOption pkgs "pvv-calendar-bot" {};
|
||||||
|
settings = {
|
||||||
|
onCalendar = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "9 0 * * *";
|
||||||
|
description = mdDoc "OnCalendar string for the systemd service(e.g. crontab format)";
|
||||||
|
};
|
||||||
|
|
||||||
|
matrix = {
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = mdDoc "Matrix username to authenticate with";
|
||||||
|
example = "@bot_calendar:pvv.ntnu.no";
|
||||||
|
};
|
||||||
|
channel = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = mdDoc "Room ID of the channel to post announcements in";
|
||||||
|
example = "!abcdef:matrix.org";
|
||||||
|
};
|
||||||
|
homeserver = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = mdDoc "Matrix homeserver URL to connect to";
|
||||||
|
example = "https://matrix.org";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
secretsFile = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = mdDoc "Path to secrets file that defines MATRIX_ACCESS_TOKEN";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.timers."pvv-calendar-bot" = {
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = cfg.settings.onCalendar;
|
||||||
|
Unit = "pvv-calendar-bot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."pvv-calendar-bot" = {
|
||||||
|
preStart = let
|
||||||
|
envFile = pkgs.writeText "pvv-calendar-bot-env" ''
|
||||||
|
MATRIX_URL=${cfg.settings.matrix.homeserver}
|
||||||
|
MATRIX_USER=${cfg.settings.matrix.user}
|
||||||
|
ANNOUNCEMENT_CHANNEL=${cfg.settings.matrix.channel}
|
||||||
|
MATRIX_TOKEN=@MATRIX_ACCESS_TOKEN@
|
||||||
|
'';
|
||||||
|
in ''
|
||||||
|
${pkgs.replace-secret}/bin/replace-secret '@MATRIX_ACCESS_TOKEN@' ${cfg.settings.secretsFile} /run/pvv-calendar-bot/env
|
||||||
|
'';
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${cfg.package}/bin/pvv-calendar-bot";
|
||||||
|
RuntimeDirectory = "pvv-calendar-bot";
|
||||||
|
DynamicUser = true;
|
||||||
|
EnvironmentFile = [ "-/run/pvv-calendar-bot/env" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools", "setuptools-scm"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "pvv-calendar-bot"
|
||||||
|
authors = [
|
||||||
|
{name = "Felix Albrigtsen", email = "felix@albrigtsen.it"},
|
||||||
|
{name = "Fredrik Robertsen", email = "fredrikrobertsen7@gmail.com"}
|
||||||
|
]
|
||||||
|
version = "1.0.0"
|
||||||
|
description = "PVV Calendar -> Matrix bot"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
keywords = []
|
||||||
|
license = {text = "MIT"}
|
||||||
|
dependencies = [
|
||||||
|
"beautifulsoup4",
|
||||||
|
"markdown2",
|
||||||
|
"matrix-nio",
|
||||||
|
"requests"
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
where = ["src"]
|
||||||
|
include = ["*"]
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
pvv-calendar-bot = "pvv_calendar_bot:main"
|
|
@ -0,0 +1 @@
|
||||||
|
from pvv_calendar_bot.main import main
|
|
@ -1,4 +1,7 @@
|
||||||
from event import Event
|
#! /usr/bin/env python
|
||||||
|
|
||||||
|
from .event import Event
|
||||||
|
from .scraping import get_soup, process_soup, get_events_today
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from nio import AsyncClient
|
from nio import AsyncClient
|
||||||
|
@ -7,8 +10,6 @@ from markdown2 import Markdown
|
||||||
import asyncio
|
import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from scraping import get_soup, process_soup, get_events_today
|
|
||||||
|
|
||||||
MATRIX_URL=os.environ["MATRIX_URL"]
|
MATRIX_URL=os.environ["MATRIX_URL"]
|
||||||
MATRIX_USER=os.environ["MATRIX_USER"]
|
MATRIX_USER=os.environ["MATRIX_USER"]
|
||||||
MATRIX_TOKEN=os.environ["MATRIX_TOKEN"]
|
MATRIX_TOKEN=os.environ["MATRIX_TOKEN"]
|
||||||
|
@ -44,18 +45,21 @@ async def sendMatrixAnnouncement(event: Event, channel: str = ANNOUNCEMENT_CHANN
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def sendCalendarEvents() -> None:
|
||||||
async def main() -> None:
|
|
||||||
global client
|
global client
|
||||||
client = AsyncClient(MATRIX_URL, MATRIX_USER)
|
client = AsyncClient(MATRIX_URL, MATRIX_USER)
|
||||||
client.access_token = MATRIX_TOKEN
|
client.access_token = MATRIX_TOKEN
|
||||||
|
|
||||||
s = get_soup()
|
scrapeData = get_soup()
|
||||||
es = get_events_today(process_soup(s))
|
eventsToday = get_events_today(process_soup(scrapeData))
|
||||||
|
|
||||||
for e in es:
|
for event in eventsToday:
|
||||||
await sendMatrixAnnouncement(e, ANNOUNCEMENT_CHANNEL, False)
|
await sendMatrixAnnouncement(event, ANNOUNCEMENT_CHANNEL, False)
|
||||||
|
|
||||||
await client.close()
|
await client.close()
|
||||||
|
|
||||||
asyncio.run(main())
|
def main():
|
||||||
|
asyncio.run(sendCalendarEvents())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -1,11 +1,11 @@
|
||||||
|
from .event import Event
|
||||||
|
|
||||||
from typing import List
|
from typing import List
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
import requests
|
import requests
|
||||||
from operator import add
|
from operator import add
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
import datetime
|
import datetime
|
||||||
from event import Event
|
|
||||||
|
|
||||||
|
|
||||||
def get_soup() -> BeautifulSoup:
|
def get_soup() -> BeautifulSoup:
|
||||||
r = requests.get("http://www.pvv.ntnu.no/hendelser/")
|
r = requests.get("http://www.pvv.ntnu.no/hendelser/")
|
Loading…
Reference in New Issue