structables 0.3.5__tar.gz → 0.3.7__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 (54) hide show
  1. structables-0.3.7/.env.example +3 -0
  2. structables-0.3.7/.forgejo/workflows/docker.yml +33 -0
  3. {structables-0.3.5 → structables-0.3.7}/.gitignore +7 -4
  4. structables-0.3.7/Dockerfile +17 -0
  5. {structables-0.3.5 → structables-0.3.7}/PKG-INFO +20 -5
  6. {structables-0.3.5 → structables-0.3.7}/README.md +18 -4
  7. structables-0.3.7/docker-compose-example.yml +18 -0
  8. structables-0.3.7/entrypoint.sh +18 -0
  9. {structables-0.3.5 → structables-0.3.7}/pyproject.toml +2 -1
  10. {structables-0.3.5 → structables-0.3.7}/src/structables/config.py +1 -1
  11. structables-0.3.7/src/structables/main.py +42 -0
  12. {structables-0.3.5 → structables-0.3.7}/src/structables/routes/main.py +15 -1
  13. structables-0.3.5/src/structables/main.py +0 -23
  14. structables-0.3.5/src/structables/static/dist/css/bootstrap.min.css +0 -6
  15. structables-0.3.5/src/structables/static/dist/css/bootstrap.min.css.map +0 -1
  16. structables-0.3.5/src/structables/static/dist/js/bootstrap.bundle.min.js +0 -7
  17. structables-0.3.5/src/structables/static/dist/js/bootstrap.bundle.min.js.map +0 -1
  18. {structables-0.3.5 → structables-0.3.7}/.forgejo/workflows/release.yml +0 -0
  19. {structables-0.3.5 → structables-0.3.7}/LICENSE +0 -0
  20. {structables-0.3.5 → structables-0.3.7}/cronjob.txt +0 -0
  21. {structables-0.3.5 → structables-0.3.7}/src/structables/__init__.py +0 -0
  22. {structables-0.3.5 → structables-0.3.7}/src/structables/routes/__init__.py +0 -0
  23. {structables-0.3.5 → structables-0.3.7}/src/structables/routes/category.py +0 -0
  24. {structables-0.3.5 → structables-0.3.7}/src/structables/routes/contest.py +0 -0
  25. {structables-0.3.5 → structables-0.3.7}/src/structables/routes/member.py +0 -0
  26. {structables-0.3.5 → structables-0.3.7}/src/structables/routes/proxy.py +0 -0
  27. {structables-0.3.5 → structables-0.3.7}/src/structables/static/css/style.css +0 -0
  28. {structables-0.3.5 → structables-0.3.7}/src/structables/static/img/logo.png +0 -0
  29. {structables-0.3.5 → structables-0.3.7}/src/structables/static/img/logo_lg.png +0 -0
  30. {structables-0.3.5 → structables-0.3.7}/src/structables/static/img/magnifying-glass-solid.svg +0 -0
  31. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/400.html +0 -0
  32. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/404.html +0 -0
  33. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/429.html +0 -0
  34. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/500.html +0 -0
  35. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/archives.html +0 -0
  36. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/article-review.html +0 -0
  37. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/article.html +0 -0
  38. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/base.html +0 -0
  39. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/category.html +0 -0
  40. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/collection.html +0 -0
  41. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/contest.html +0 -0
  42. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/contests.html +0 -0
  43. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/footer.html +0 -0
  44. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/header.html +0 -0
  45. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/iframe.html +0 -0
  46. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/index.html +0 -0
  47. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/member-instructables.html +0 -0
  48. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/member.html +0 -0
  49. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/privacypolicy.html +0 -0
  50. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/projects.html +0 -0
  51. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/sitemap.html +0 -0
  52. {structables-0.3.5 → structables-0.3.7}/src/structables/templates/style.html +0 -0
  53. {structables-0.3.5 → structables-0.3.7}/src/structables/utils/data.py +0 -0
  54. {structables-0.3.5 → structables-0.3.7}/src/structables/utils/helpers.py +0 -0
@@ -0,0 +1,3 @@
1
+ PORT=8002
2
+ UWSGI_PROCESSES=4
3
+ UWSGI_THREADS=4
@@ -0,0 +1,33 @@
1
+ name: Docker CI/CD
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "*"
7
+
8
+ jobs:
9
+ docker:
10
+ name: Docker Build and Push to Docker Hub
11
+ container:
12
+ image: node:20-bookworm
13
+ steps:
14
+ - name: Install dependencies
15
+ run: |
16
+ apt update
17
+ apt install -y docker.io
18
+ - name: Set up QEMU
19
+ uses: docker/setup-qemu-action@v3
20
+ - name: Set up Docker Buildx
21
+ uses: docker/setup-buildx-action@v3
22
+ - name: Login to Docker Hub
23
+ uses: docker/login-action@v3
24
+ with:
25
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
26
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
27
+ - name: Build and push to Docker Hub
28
+ uses: docker/build-push-action@v5
29
+ with:
30
+ push: true
31
+ tags: |
32
+ privatecoffee/structables:latest
33
+ privatecoffee/structables:${{ env.GITHUB_REF_NAME }}
@@ -1,6 +1,9 @@
1
- venv/
2
- *.pyc
3
- __pycache__/
1
+ .env
4
2
  .vscode
3
+ __pycache__/
4
+ dist/
5
+ docker-compose.yml
6
+ privacy.md
5
7
  privacy.txt
6
- /dist/
8
+ *.pyc
9
+ venv/
@@ -0,0 +1,17 @@
1
+ FROM alpine:3.20
2
+
3
+ ENV APP_ENV=/opt/venv
4
+ ENV PATH="${APP_ENV}/bin:$PATH"
5
+
6
+ RUN apk add --no-cache py3-pip uwsgi-python3 && \
7
+ python3 -m venv $APP_ENV && \
8
+ $APP_ENV/bin/pip install --no-cache-dir pip structables && \
9
+ adduser -S -D -H structables
10
+
11
+ COPY entrypoint.sh /entrypoint.sh
12
+
13
+ EXPOSE 8002
14
+
15
+ USER structables
16
+
17
+ ENTRYPOINT ["/entrypoint.sh"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: structables
3
- Version: 0.3.5
3
+ Version: 0.3.7
4
4
  Summary: A simple frontend for Instructables
5
5
  Project-URL: Homepage, https://git.private.coffee/privatecoffee/structables
6
6
  Project-URL: Bug Tracker, https://git.private.coffee/privatecoffee/structables/issues
@@ -674,6 +674,7 @@ Classifier: Programming Language :: Python :: 3
674
674
  Requires-Python: >=3.10
675
675
  Requires-Dist: bs4
676
676
  Requires-Dist: flask
677
+ Requires-Dist: markdown2[all]
677
678
  Description-Content-Type: text/markdown
678
679
 
679
680
  <img align="right" src="src/structables/static/img/logo.png">
@@ -691,9 +692,10 @@ An open source alternative front-end to Instructables. This is a fork of <a href
691
692
 
692
693
  ## Instances
693
694
 
694
- | URL | Provided by | Country | Comments |
695
- | -------------------------------------------------------------------------- | ----------------------------------------- | ------- | -------- |
696
- | [https://structables.private.coffee/](https://structables.private.coffee/) | [Private.coffee](https://private.coffee/) | Austria | |
695
+ | URL | Provided by | Country | Comments |
696
+ | ----------------------------------------------------------------- | ----------------------------------------- | ------- | -------- |
697
+ | [structables.private.coffee](https://structables.private.coffee/) | [Private.coffee](https://private.coffee/) | Austria | |
698
+ | [structables.bloat.cat](https://structables.bloat.cat/) | [Bloat.cat](https://bloat.cat) | Romania | |
697
699
 
698
700
  To add your own instance to this list, please open a pull request or issue.
699
701
 
@@ -705,7 +707,7 @@ Of course, you can also join our [Matrix room](https://matrix.pcof.fi/#/#structa
705
707
 
706
708
  ## Run your own instance
707
709
 
708
- ### Production
710
+ ### Production: Manual
709
711
 
710
712
  1. Create a virtual environment: `python3 -m venv venv`
711
713
  2. Activate the virtual environment: `source venv/bin/activate`
@@ -714,6 +716,19 @@ Of course, you can also join our [Matrix room](https://matrix.pcof.fi/#/#structa
714
716
  5. Point your reverse proxy to http://localhost:8002 and (optionally) serve static files from the `venv/lib/pythonX.XX/site-packages/structables/static` directory
715
717
  6. Connect to your instance under your domain
716
718
 
719
+ ### Production: Docker
720
+
721
+ 1. Copy `.env.example` to `.env` and adjust the settings as necessary
722
+ 2. Copy `docker-compose-example.yml` to `docker-compose.yml` and adjust it as necessary, for example modifying resource limits or changing the port/host configuration
723
+ 3. Build and run the Docker container:
724
+
725
+ ```sh
726
+ docker-compose up [-d]
727
+ ```
728
+
729
+ 4. Point your reverse proxy to http://127.0.0.1:8002 (or your chosen port, if you modified it) and (optionally) serve static files from `structables/static`
730
+ 5. Connect to your instance under your domain
731
+
717
732
  ### Development
718
733
 
719
734
  1. Clone the repository: `git clone https://git.private.coffee/privatecoffee/structables.git && cd structables`
@@ -13,9 +13,10 @@ An open source alternative front-end to Instructables. This is a fork of <a href
13
13
 
14
14
  ## Instances
15
15
 
16
- | URL | Provided by | Country | Comments |
17
- | -------------------------------------------------------------------------- | ----------------------------------------- | ------- | -------- |
18
- | [https://structables.private.coffee/](https://structables.private.coffee/) | [Private.coffee](https://private.coffee/) | Austria | |
16
+ | URL | Provided by | Country | Comments |
17
+ | ----------------------------------------------------------------- | ----------------------------------------- | ------- | -------- |
18
+ | [structables.private.coffee](https://structables.private.coffee/) | [Private.coffee](https://private.coffee/) | Austria | |
19
+ | [structables.bloat.cat](https://structables.bloat.cat/) | [Bloat.cat](https://bloat.cat) | Romania | |
19
20
 
20
21
  To add your own instance to this list, please open a pull request or issue.
21
22
 
@@ -27,7 +28,7 @@ Of course, you can also join our [Matrix room](https://matrix.pcof.fi/#/#structa
27
28
 
28
29
  ## Run your own instance
29
30
 
30
- ### Production
31
+ ### Production: Manual
31
32
 
32
33
  1. Create a virtual environment: `python3 -m venv venv`
33
34
  2. Activate the virtual environment: `source venv/bin/activate`
@@ -36,6 +37,19 @@ Of course, you can also join our [Matrix room](https://matrix.pcof.fi/#/#structa
36
37
  5. Point your reverse proxy to http://localhost:8002 and (optionally) serve static files from the `venv/lib/pythonX.XX/site-packages/structables/static` directory
37
38
  6. Connect to your instance under your domain
38
39
 
40
+ ### Production: Docker
41
+
42
+ 1. Copy `.env.example` to `.env` and adjust the settings as necessary
43
+ 2. Copy `docker-compose-example.yml` to `docker-compose.yml` and adjust it as necessary, for example modifying resource limits or changing the port/host configuration
44
+ 3. Build and run the Docker container:
45
+
46
+ ```sh
47
+ docker-compose up [-d]
48
+ ```
49
+
50
+ 4. Point your reverse proxy to http://127.0.0.1:8002 (or your chosen port, if you modified it) and (optionally) serve static files from `structables/static`
51
+ 5. Connect to your instance under your domain
52
+
39
53
  ### Development
40
54
 
41
55
  1. Clone the repository: `git clone https://git.private.coffee/privatecoffee/structables.git && cd structables`
@@ -0,0 +1,18 @@
1
+ services:
2
+ structables:
3
+ container_name: structables
4
+ restart: unless-stopped
5
+ build: .
6
+ ports:
7
+ - "127.0.0.1:8002:8002"
8
+ env_file: .env
9
+ security_opt:
10
+ - no-new-privileges:true
11
+ cap_drop:
12
+ - ALL
13
+ read_only: true
14
+ deploy:
15
+ resources:
16
+ limits:
17
+ cpus: '0.5'
18
+ memory: 300M
@@ -0,0 +1,18 @@
1
+ #!/bin/sh
2
+ args="--plugin python3 \
3
+ --http-socket 0.0.0.0:$PORT \
4
+ --master \
5
+ --module structables.main:app \
6
+ -H /opt/venv"
7
+
8
+ if [ "$UWSGI_PROCESSES" ]
9
+ then
10
+ args="$args --processes $UWSGI_PROCESSES"
11
+ fi
12
+
13
+ if [ "$UWSGI_THREADS" ]
14
+ then
15
+ args="$args --threads $UWSGI_THREADS"
16
+ fi
17
+
18
+ exec /usr/sbin/uwsgi $args
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "structables"
7
- version = "0.3.5"
7
+ version = "0.3.7"
8
8
  authors = [
9
9
  { name="Private.coffee Team", email="support@private.coffee" },
10
10
  ]
@@ -20,6 +20,7 @@ classifiers = [
20
20
  dependencies = [
21
21
  "flask",
22
22
  "bs4",
23
+ "markdown2[all]",
23
24
  ]
24
25
 
25
26
  [project.scripts]
@@ -6,7 +6,7 @@ class Config:
6
6
  LISTEN_HOST = os.environ.get("STRUCTABLES_LISTEN_HOST", "127.0.0.1")
7
7
  INVIDIOUS = os.environ.get("STRUCTABLES_INVIDIOUS")
8
8
  UNSAFE = os.environ.get("STRUCTABLES_UNSAFE", False)
9
- PRIVACY_FILE = os.environ.get("STRUCTABLES_PRIVACY_FILE", "privacy.txt")
9
+ PRIVACY_FILE = os.environ.get("STRUCTABLES_PRIVACY_FILE")
10
10
 
11
11
  @staticmethod
12
12
  def init_app(app):
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env python
2
+
3
+ from flask import Flask
4
+ import threading
5
+ import time
6
+
7
+ from .config import Config
8
+ from .routes import init_routes
9
+ from .utils.data import update_data
10
+ from .utils.helpers import get_typesense_api_key
11
+
12
+ app = Flask(__name__, template_folder="templates", static_folder="static")
13
+ app.config.from_object(Config)
14
+ app.typesense_api_key = get_typesense_api_key()
15
+
16
+ init_routes(app)
17
+
18
+
19
+ def background_update_data(app):
20
+ """Runs the update_data function every 5 minutes.
21
+
22
+ This replaces the need for a cron job to update the data.
23
+
24
+ Args:
25
+ app (Flask): The Flask app instance.
26
+ """
27
+ while True:
28
+ update_data(app)
29
+ time.sleep(300)
30
+
31
+
32
+ def main():
33
+ threading.Thread(target=background_update_data, args=(app,), daemon=True).start()
34
+ app.run(
35
+ port=app.config["PORT"],
36
+ host=app.config["LISTEN_HOST"],
37
+ debug=app.config["DEBUG"],
38
+ )
39
+
40
+
41
+ if __name__ == "__main__":
42
+ main()
@@ -4,6 +4,7 @@ from urllib.error import HTTPError
4
4
  from bs4 import BeautifulSoup
5
5
  from urllib.parse import quote
6
6
  from werkzeug.exceptions import InternalServerError
7
+ from markdown2 import Markdown
7
8
  from traceback import print_exc
8
9
  import pathlib
9
10
  import json
@@ -342,11 +343,24 @@ def init_main_routes(app):
342
343
 
343
344
  content = "No privacy policy found."
344
345
 
345
- path = app.config.get("PRIVACY_FILE", "privacy.txt")
346
+ path = app.config.get("PRIVACY_FILE")
347
+
348
+ if not path:
349
+ if pathlib.Path("privacy.md").exists():
350
+ path = "privacy.md"
351
+
352
+ elif pathlib.Path("privacy.txt").exists():
353
+ path = "privacy.txt"
346
354
 
347
355
  try:
348
356
  with pathlib.Path(path).open() as f:
349
357
  content = f.read()
358
+
359
+ print(path, content)
360
+
361
+ if path.endswith(".md"):
362
+ content = Markdown().convert(content)
363
+
350
364
  except OSError:
351
365
  pass
352
366
 
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env python
2
-
3
- from flask import Flask
4
-
5
- from .config import Config
6
- from .routes import init_routes
7
- from .utils.data import update_data
8
- from .utils.helpers import get_typesense_api_key
9
-
10
- app = Flask(__name__, template_folder="templates", static_folder="static")
11
- app.config.from_object(Config)
12
- app.typesense_api_key = get_typesense_api_key()
13
-
14
- init_routes(app)
15
-
16
- def main():
17
- app.run(port=app.config['PORT'], host=app.config['LISTEN_HOST'], debug=app.config['DEBUG'])
18
-
19
- if __name__ == "__main__":
20
- main()
21
-
22
- # Initialize data when the server starts
23
- update_data(app)