pheme-reviews 0.1.0__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.
Files changed (89) hide show
  1. pheme_reviews-0.1.0/.env.example +43 -0
  2. pheme_reviews-0.1.0/.forgejo/workflows/python.yml +40 -0
  3. pheme_reviews-0.1.0/.forgejo/workflows/react.yml +25 -0
  4. pheme_reviews-0.1.0/.forgejo/workflows/release.yml +94 -0
  5. pheme_reviews-0.1.0/.gitignore +22 -0
  6. pheme_reviews-0.1.0/.python-version +1 -0
  7. pheme_reviews-0.1.0/.theia/settings.json +5 -0
  8. pheme_reviews-0.1.0/PKG-INFO +605 -0
  9. pheme_reviews-0.1.0/README.md +585 -0
  10. pheme_reviews-0.1.0/app/__init__.py +0 -0
  11. pheme_reviews-0.1.0/app/activitypub/__init__.py +0 -0
  12. pheme_reviews-0.1.0/app/activitypub/actor.py +54 -0
  13. pheme_reviews-0.1.0/app/activitypub/delivery.py +91 -0
  14. pheme_reviews-0.1.0/app/activitypub/fetchguard.py +93 -0
  15. pheme_reviews-0.1.0/app/activitypub/signing.py +234 -0
  16. pheme_reviews-0.1.0/app/auth.py +68 -0
  17. pheme_reviews-0.1.0/app/bootstrap.py +171 -0
  18. pheme_reviews-0.1.0/app/config.py +107 -0
  19. pheme_reviews-0.1.0/app/db/__init__.py +99 -0
  20. pheme_reviews-0.1.0/app/db/actors.py +154 -0
  21. pheme_reviews-0.1.0/app/db/connection.py +129 -0
  22. pheme_reviews-0.1.0/app/db/follows.py +103 -0
  23. pheme_reviews-0.1.0/app/db/invites.py +90 -0
  24. pheme_reviews-0.1.0/app/db/reviews.py +198 -0
  25. pheme_reviews-0.1.0/app/forms.py +69 -0
  26. pheme_reviews-0.1.0/app/main.py +167 -0
  27. pheme_reviews-0.1.0/app/models.py +107 -0
  28. pheme_reviews-0.1.0/app/ratelimit.py +11 -0
  29. pheme_reviews-0.1.0/app/routes/__init__.py +0 -0
  30. pheme_reviews-0.1.0/app/routes/activitypub/__init__.py +43 -0
  31. pheme_reviews-0.1.0/app/routes/activitypub/actor.py +20 -0
  32. pheme_reviews-0.1.0/app/routes/activitypub/collections.py +79 -0
  33. pheme_reviews-0.1.0/app/routes/activitypub/helpers.py +190 -0
  34. pheme_reviews-0.1.0/app/routes/activitypub/inbox.py +246 -0
  35. pheme_reviews-0.1.0/app/routes/activitypub/webfinger.py +37 -0
  36. pheme_reviews-0.1.0/app/routes/admin.py +235 -0
  37. pheme_reviews-0.1.0/app/routes/api.py +433 -0
  38. pheme_reviews-0.1.0/app/routes/follow.py +123 -0
  39. pheme_reviews-0.1.0/app/routes/web.py +246 -0
  40. pheme_reviews-0.1.0/app/static/style.css +52 -0
  41. pheme_reviews-0.1.0/app/templates/base.html +13 -0
  42. pheme_reviews-0.1.0/app/templates/login.html +117 -0
  43. pheme_reviews-0.1.0/app/templates/register.html +62 -0
  44. pheme_reviews-0.1.0/app/templates/review.html +18 -0
  45. pheme_reviews-0.1.0/pyproject.toml +76 -0
  46. pheme_reviews-0.1.0/react-app/SPEC.md +88 -0
  47. pheme_reviews-0.1.0/react-app/dist/assets/index-BXKCOgss.js +43 -0
  48. pheme_reviews-0.1.0/react-app/dist/assets/index-D8fh2yR3.css +1 -0
  49. pheme_reviews-0.1.0/react-app/dist/index.html +36 -0
  50. pheme_reviews-0.1.0/react-app/index.html +35 -0
  51. pheme_reviews-0.1.0/react-app/package-lock.json +1926 -0
  52. pheme_reviews-0.1.0/react-app/package.json +25 -0
  53. pheme_reviews-0.1.0/react-app/src/App.tsx +67 -0
  54. pheme_reviews-0.1.0/react-app/src/api.ts +414 -0
  55. pheme_reviews-0.1.0/react-app/src/components/AdminPanel.tsx +311 -0
  56. pheme_reviews-0.1.0/react-app/src/components/FollowPanel.tsx +89 -0
  57. pheme_reviews-0.1.0/react-app/src/components/LogoutButton.tsx +29 -0
  58. pheme_reviews-0.1.0/react-app/src/components/MapPage.tsx +549 -0
  59. pheme_reviews-0.1.0/react-app/src/components/MapView.tsx +354 -0
  60. pheme_reviews-0.1.0/react-app/src/components/NominatimSearch.tsx +153 -0
  61. pheme_reviews-0.1.0/react-app/src/components/PlacePanel.tsx +99 -0
  62. pheme_reviews-0.1.0/react-app/src/components/ProfilePage.tsx +166 -0
  63. pheme_reviews-0.1.0/react-app/src/components/ReviewCard.tsx +73 -0
  64. pheme_reviews-0.1.0/react-app/src/components/ReviewForm.tsx +76 -0
  65. pheme_reviews-0.1.0/react-app/src/components/ReviewList.tsx +65 -0
  66. pheme_reviews-0.1.0/react-app/src/components/SearchBox.tsx +29 -0
  67. pheme_reviews-0.1.0/react-app/src/components/StarRating.tsx +39 -0
  68. pheme_reviews-0.1.0/react-app/src/components/Stars.tsx +31 -0
  69. pheme_reviews-0.1.0/react-app/src/components/ThemeToggle.tsx +50 -0
  70. pheme_reviews-0.1.0/react-app/src/hooks/useBottomSheet.ts +78 -0
  71. pheme_reviews-0.1.0/react-app/src/hooks/useMediaQuery.ts +16 -0
  72. pheme_reviews-0.1.0/react-app/src/main.tsx +14 -0
  73. pheme_reviews-0.1.0/react-app/src/places.ts +88 -0
  74. pheme_reviews-0.1.0/react-app/src/styles.css +1200 -0
  75. pheme_reviews-0.1.0/react-app/src/theme.ts +77 -0
  76. pheme_reviews-0.1.0/react-app/src/types.ts +117 -0
  77. pheme_reviews-0.1.0/react-app/tsconfig.json +20 -0
  78. pheme_reviews-0.1.0/react-app/vite.config.ts +29 -0
  79. pheme_reviews-0.1.0/release/pheme-v0.1.0.tar.gz +0 -0
  80. pheme_reviews-0.1.0/release/pheme-v0.1.0.zip +0 -0
  81. pheme_reviews-0.1.0/tests/__init__.py +24 -0
  82. pheme_reviews-0.1.0/tests/base.py +116 -0
  83. pheme_reviews-0.1.0/tests/test_activitypub.py +349 -0
  84. pheme_reviews-0.1.0/tests/test_admin.py +547 -0
  85. pheme_reviews-0.1.0/tests/test_api.py +732 -0
  86. pheme_reviews-0.1.0/tests/test_db.py +371 -0
  87. pheme_reviews-0.1.0/tests/test_signing.py +252 -0
  88. pheme_reviews-0.1.0/tests/test_web.py +445 -0
  89. pheme_reviews-0.1.0/uv.lock +963 -0
@@ -0,0 +1,43 @@
1
+ # ── Server ──────────────────────────────────────────────────────────────
2
+ # Public URL of this server (used in all ActivityPub IDs)
3
+ BASE_URL=http://localhost:8000
4
+
5
+ # Bind address and port for uvicorn
6
+ HOST=127.0.0.1
7
+ PORT=8000
8
+
9
+ # Enable uvicorn auto-reload (set to false in production)
10
+ RELOAD=true
11
+
12
+ # Trust X-Forwarded-* headers from a reverse proxy on this machine
13
+ # (Caddy/nginx) so rate limiting sees real client IPs instead of 127.0.0.1.
14
+ # Set to true in production behind a proxy; leave false when the app is
15
+ # exposed directly.
16
+ PROXY_HEADERS=false
17
+
18
+ # Comma-separated IPs allowed to set X-Forwarded-For.
19
+ # Default 127.0.0.1 is correct when the proxy runs on the same machine.
20
+ # FORWARDED_ALLOW_IPS=127.0.0.1
21
+
22
+ # ── Database ────────────────────────────────────────────────────────────
23
+ # Path to the SQLite database file
24
+ DATABASE_PATH=data/reviews.db
25
+
26
+ # ── Security ────────────────────────────────────────────────────────────
27
+ # Secret key for session signing — REQUIRED in production.
28
+ # Generate one with: python -c "import secrets; print(secrets.token_hex(32))"
29
+ SECRET_KEY=
30
+
31
+ # Session cookie lifetime in seconds (default: 30 days = 2592000)
32
+ SESSION_MAX_AGE=2592000
33
+
34
+ # Minimum password length for new accounts (default: 8)
35
+ PASSWORD_MIN_LENGTH=8
36
+
37
+ # ── Registration ────────────────────────────────────────────────────────
38
+ # Registration policy:
39
+ # open — anyone can register at /register (default; fine for dev)
40
+ # invite — /register requires a one-time invite code; admins create codes
41
+ # via POST /api/admin/invites and share /register?code=... links
42
+ # closed — no self-registration; admins create accounts via POST /api/admin/users
43
+ REGISTRATION_MODE=open
@@ -0,0 +1,40 @@
1
+ # Forgejo Actions — Python pipeline (lint, type check, unittest suite).
2
+ #
3
+ # Runs on the runner labelled `node-22`, which provides the node:22 image:
4
+ # uv bootstraps a managed Python ≥ 3.13 there (the image's system Python is
5
+ # 3.11, too old for requires-python >= 3.13).
6
+
7
+ name: Python
8
+
9
+ on: [push]
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: node-22
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ with:
17
+ fetch-depth: 1
18
+
19
+ - name: Install uv
20
+ uses: https://github.com/astral-sh/setup-uv@v7.1.4
21
+ with:
22
+ enable-cache: true
23
+ prune-cache: false
24
+ cache-dependency-glob: "uv.lock"
25
+ github-token: ${{ secrets.GITHUBAUTH }}
26
+
27
+ - name: Install Python dependencies
28
+ run: uv sync --group dev
29
+
30
+ - name: Ruff Check
31
+ run: uv run ruff check app/ tests/
32
+
33
+ - name: Ruff Format Check
34
+ run: uv run ruff format --check app/ tests/
35
+
36
+ - name: Type check (basedpyright)
37
+ run: uv run basedpyright app/ tests/
38
+
39
+ - name: Run tests (unittest)
40
+ run: uv run python -m unittest discover -s tests -v
@@ -0,0 +1,25 @@
1
+ # Forgejo Actions — React pipeline (production build of react-app/).
2
+ #
3
+ # Runs on the runner labelled `node-22`, which provides the node:22 image
4
+ # and its npm.
5
+
6
+ name: React
7
+
8
+ on: [push]
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: node-22
13
+ steps:
14
+ - name: Checkout
15
+ uses: actions/checkout@v7
16
+
17
+ - name: Install dependencies
18
+ run: |
19
+ cd react-app
20
+ npm ci
21
+
22
+ - name: Build React app
23
+ run: |
24
+ cd react-app
25
+ npm run build
@@ -0,0 +1,94 @@
1
+ # Forgejo Actions — release pipeline.
2
+ #
3
+ # Pushing a tag (`git tag v0.2.0 && git push origin v0.2.0`) runs this
4
+ # workflow, which does two things:
5
+ #
6
+ # 1. Packages a source snapshot of the tagged tree (git archive → release/)
7
+ # and uploads it to a Forgejo release for the tag via the forgejo-release
8
+ # action.
9
+ # 2. Builds the React frontend (`npm ci && npm run build`) and the sdist +
10
+ # wheel with hatchling (`uv build` — the wheel bundles react-app/dist,
11
+ # see the force-include in pyproject.toml), then publishes to PyPI
12
+ # (`uv publish`) using the PYPI_API_TOKEN repo secret. The publish step
13
+ # is skipped until that secret exists.
14
+ #
15
+ # The published version is the static `version` in pyproject.toml — bump it
16
+ # before tagging. The PyPI project name is `[project] name` ("pheme-reviews";
17
+ # plain "pheme" is already taken on PyPI by an unrelated project). To derive
18
+ # the version from the tag instead, switch pyproject.toml to
19
+ # dynamic = ["version"] + hatch-vcs later.
20
+ #
21
+ # Runs on the runner labelled `node-22` (provides git + node for the action).
22
+ # The forgejo-release token defaults to the automatic forgejo token, which has
23
+ # write access on push events.
24
+
25
+ name: Release
26
+
27
+ on:
28
+ push:
29
+ tags:
30
+ - "v*"
31
+
32
+ jobs:
33
+ release:
34
+ runs-on: node-22
35
+ steps:
36
+ # Install git BEFORE checkout if the runner image lacks it: without git,
37
+ # actions/checkout falls back to downloading a tarball, which leaves no
38
+ # .git directory — and then `git archive` below fails. Use apt-get with
39
+ # update first (a fresh image has empty package lists, which is what made
40
+ # `apt install git` fail with "Unable to locate package git").
41
+ - name: Ensure git is installed
42
+ run: |
43
+ if ! command -v git >/dev/null 2>&1; then
44
+ apt-get update && apt-get install -y git
45
+ fi
46
+
47
+ - uses: actions/checkout@v4
48
+
49
+ - name: Package a source snapshot of the tagged tree
50
+ run: |
51
+ mkdir -p release
52
+ git archive --format=tar.gz --prefix="pheme-${{ forgejo.ref_name }}/" \
53
+ -o "release/pheme-${{ forgejo.ref_name }}.tar.gz" HEAD
54
+ git archive --format=zip --prefix="pheme-${{ forgejo.ref_name }}/" \
55
+ -o "release/pheme-${{ forgejo.ref_name }}.zip" HEAD
56
+ ls -la release
57
+
58
+ - uses: https://code.forgejo.org/actions/forgejo-release@v2.7.3
59
+ with:
60
+ url: "https://forge.mielle.dev"
61
+ repo: "${{ forgejo.repository }}"
62
+ direction: upload
63
+ tag: "${{ forgejo.ref_name }}"
64
+ sha: "${{ forgejo.sha }}"
65
+ release-dir: release
66
+ override: false
67
+ verbose: false
68
+ hide-archive-link: true
69
+ release-notes-assistant: false
70
+
71
+ - name: Install uv
72
+ uses: https://github.com/astral-sh/setup-uv@v7.1.4
73
+ with:
74
+ enable-cache: true
75
+ prune-cache: false
76
+ cache-dependency-glob: "uv.lock"
77
+ github-token: ${{ secrets.GITHUBAUTH }}
78
+
79
+ - name: Build the React frontend (bundled into the wheel)
80
+ run: |
81
+ cd react-app
82
+ npm ci
83
+ npm run build
84
+
85
+ - name: Build sdist + wheel (hatchling)
86
+ run: |
87
+ uv build --out-dir dist
88
+ ls -la dist
89
+
90
+ - name: Publish to PyPI
91
+ if: ${{ secrets.PYPI_API_TOKEN != '' }}
92
+ env:
93
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
94
+ run: uv publish dist/*
@@ -0,0 +1,22 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ /dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+ data/
12
+
13
+ # Environment files
14
+ .env
15
+
16
+ # React app (react-app/) — JS toolchain artifacts
17
+ react-app/node_modules/
18
+ # Ignore the built frontend, but keep the directory itself tracked (via the
19
+ # .gitkeep placeholder): hatchling prunes gitignored directories during file
20
+ # selection, and the wheel must bundle react-app/dist when it is built.
21
+ react-app/dist/*
22
+ !react-app/dist/.gitkeep
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,5 @@
1
+ {
2
+ "[markdown]": {
3
+ "editor.defaultFormatter": "davidanson.vscode-markdownlint"
4
+ }
5
+ }