summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2025-03-09 13:48:00 +0100
committerMartin Fischer <martin@push-f.com>2025-03-09 21:36:04 +0100
commit232f1499bb9a2cc85a63abcc1c22776ef77781fb (patch)
tree50b9b429140e6d597090e5d1264496555fd0edf7
parent42c737aa1a7731170e8369482f96b557a1bd7a36 (diff)
build: introduce NixOS package & serviceHEADmaster
-rw-r--r--.gitignore1
-rw-r--r--Makefile2
-rw-r--r--README.md16
-rw-r--r--default.nix27
-rw-r--r--deps/pywikiapi.nix16
-rwxr-xr-xosm_proposals/archived_without_template.py (renamed from find_archived_proposals_without_template.py)4
-rwxr-xr-xosm_proposals/proposals.py (renamed from proposals.py)14
-rw-r--r--pyproject.toml10
-rw-r--r--service.nix52
-rw-r--r--static/index.html (renamed from index.html)0
-rw-r--r--static/script.js (renamed from script.js)0
-rw-r--r--static/style.css (renamed from style.css)0
12 files changed, 126 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 204a590..0000000
--- a/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-proposals.json
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 31de770..0000000
--- a/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-all:
- ./proposals.py > proposals.json
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..eb4eab7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+# osm-proposals
+
+An autogenerated web page listing [OpenStreetMap proposals].
+
+Hosted under https://osm-proposals.push-f.com/.
+
+# Local development
+
+ python -m venv venv
+ . venv/bin/activate
+ pip install -r requirements.txt
+ pip install -e .
+ osm-proposals static/proposals.json
+ python -m http.server --directory static
+
+[OpenStreetMap proposals]: https://wiki.openstreetmap.org/wiki/Proposal
diff --git a/default.nix b/default.nix
new file mode 100644
index 0000000..d923d2e
--- /dev/null
+++ b/default.nix
@@ -0,0 +1,27 @@
+{ pkgs ? import <nixpkgs> {} }:
+with pkgs.python310Packages;
+
+let
+ pywikiapi = import ./deps/pywikiapi.nix { inherit pkgs; };
+in
+buildPythonApplication rec {
+ pname = "osm-proposals";
+ version = "git";
+ src = ./.;
+ pyproject = true;
+
+ build-system = [
+ setuptools
+ ];
+
+ dependencies = [
+ requests
+ mwparserfromhell
+ pywikiapi
+ ];
+
+ postInstall = ''
+ mkdir -p $out/share/osm-proposals
+ cp -r ${./static}/. $out/share/osm-proposals/
+ '';
+}
diff --git a/deps/pywikiapi.nix b/deps/pywikiapi.nix
new file mode 100644
index 0000000..856f0f0
--- /dev/null
+++ b/deps/pywikiapi.nix
@@ -0,0 +1,16 @@
+{ pkgs }:
+with pkgs.python310Packages;
+
+buildPythonPackage rec {
+ pname = "pywikiapi";
+ version = "4.3.0";
+ src = pkgs.fetchPypi {
+ inherit pname;
+ inherit version;
+ hash = "sha256-gynkx98y8Vx/N3i6xoQ7x9MgTW6qACoYcDwy71FDYIE=";
+ };
+
+ dependencies = [
+ requests
+ ];
+}
diff --git a/find_archived_proposals_without_template.py b/osm_proposals/archived_without_template.py
index 6424745..ea026d3 100755
--- a/find_archived_proposals_without_template.py
+++ b/osm_proposals/archived_without_template.py
@@ -32,7 +32,3 @@ def run():
):
if not 'templates' in page:
print(page['title'])
-
-
-if __name__ == "__main__":
- run()
diff --git a/proposals.py b/osm_proposals/proposals.py
index e16412f..c111699 100755
--- a/proposals.py
+++ b/osm_proposals/proposals.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-"""Queries wiki.openstreetmap.org for proposals and outputs a JSON list of them to stdout."""
+"""Queries wiki.openstreetmap.org for proposals and writes a JSON list of them to the given file."""
import argparse
import html
import json
@@ -17,7 +17,8 @@ OSMWIKI_ENDPOINT = 'https://wiki.openstreetmap.org/w/api.php'
def run():
arg_parser = argparse.ArgumentParser(description=__doc__)
- arg_parser.parse_args()
+ arg_parser.add_argument("out_file")
+ args = arg_parser.parse_args()
res = requests.get(
OSMWIKI_ENDPOINT,
@@ -47,9 +48,8 @@ def run():
proposals.sort(key=sort_key, reverse=True)
- json.dump(
- [{k: v for k, v in p.items() if v is not None} for p in proposals], sys.stdout
- )
+ with open(args.out_file, 'w') as f:
+ json.dump([{k: v for k, v in p.items() if v is not None} for p in proposals], f)
def get_template_val(tpl, name):
@@ -185,7 +185,3 @@ def sort_key(proposal):
date = proposal['draft_start'] or ''
return (-STATUSES.get(proposal['status'], 10), date)
-
-
-if __name__ == "__main__":
- run()
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..1bad629
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,10 @@
+[project]
+name = "osm-proposals"
+version = "0.0.0"
+
+[tool.setuptools.packages.find]
+where = ["."]
+
+[project.scripts]
+osm-proposals = "osm_proposals.proposals:run"
+osm-proposals-archived-without-template = "osm_proposals.archived_without_template:run"
diff --git a/service.nix b/service.nix
new file mode 100644
index 0000000..fcd665e
--- /dev/null
+++ b/service.nix
@@ -0,0 +1,52 @@
+{ config, lib, pkgs, ... }:
+
+let
+ osm_proposals = pkgs.callPackage ./default.nix {};
+ cfg = config.services.osm_proposals;
+in
+{
+ options.services.osm_proposals = {
+ enable = lib.mkEnableOption "osm_proposals";
+
+ virtualHost = lib.mkOption {
+ type = lib.types.str;
+ description = "Name of the nginx virtualhost to set up.";
+ };
+
+ nginx = lib.mkOption {
+ type = lib.types.submodule (import <nixpkgs/nixos/modules/services/web-servers/nginx/vhost-options.nix>);
+ default = {};
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.nginx = {
+ enable = true;
+
+ virtualHosts.${cfg.virtualHost} = lib.mkMerge [
+ cfg.nginx
+ {
+ locations."/" = {
+ root = "${osm_proposals}/share/osm-proposals";
+ };
+ locations."=/proposals.json" = {
+ extraConfig = ''
+ alias /var/lib/osm-proposals/proposals.json;
+ '';
+ };
+ }
+ ];
+ };
+
+ systemd.services.osm-proposals = {
+ serviceConfig = {
+ Type = "oneshot";
+ StateDirectory = "osm-proposals"; # creates /var/lib/osm-proposals
+ ExecStart = "${osm_proposals}/bin/osm-proposals /var/lib/osm-proposals/proposals.json";
+ # Not using DynamicUser because then the StateDirectory becomes unreadable
+ # by other users, even when setting StateDirectoryMode for some reason.
+ };
+ startAt = "hourly";
+ };
+ };
+}
diff --git a/index.html b/static/index.html
index 8d7bd7a..8d7bd7a 100644
--- a/index.html
+++ b/static/index.html
diff --git a/script.js b/static/script.js
index 35aa43e..35aa43e 100644
--- a/script.js
+++ b/static/script.js
diff --git a/style.css b/static/style.css
index 66fe28f..66fe28f 100644
--- a/style.css
+++ b/static/style.css