From 63a9b8f301076b03582c699539e00d7669fe990d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Helle=C5=9Ben?= Date: Mon, 23 Mar 2026 22:14:56 +0100 Subject: [PATCH 1/9] Add example environment configuration file --- .env.example | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..779d5af --- /dev/null +++ b/.env.example @@ -0,0 +1,31 @@ +# Django Configuration +# Set to False in production +DEBUG=True + +# Django Secret Key +# Generate a new secret key for production: python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())' +DJANGO_SECRET_KEY=your-secret-key-here + +# Email Configuration +# SMTP Host (examples below) +EMAIL_HOST=smtp.gmail.com + +# SMTP Port (common ports: 587 for TLS, 465 for SSL, 25 for unencrypted) +EMAIL_PORT=587 + +# Email credentials +EMAIL_HOST_USER=your-email@gmail.com +EMAIL_HOST_PASSWORD=your-app-password-here + +# Connection security +# Use TLS (True for most providers like Gmail, Outlook) +EMAIL_USE_TLS=True +# Use SSL (False for most providers, True for some older configurations) +EMAIL_USE_SSL=False + +# Connection timeout in seconds +EMAIL_TIMEOUT=10 + +# Redis Configuration +REDIS_URL_CACHE=unix:///var/run/redis/redis.sock?db=2 +REDIS_URL_CELERY=unix:///var/run/redis/redis.sock?db=3 From f9505da731a603783449e42ba2b22d0fde389de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Helle=C5=9Ben?= Date: Mon, 23 Mar 2026 22:15:02 +0100 Subject: [PATCH 2/9] Update README.md --- README.md | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 9594164..bee0b69 100644 --- a/README.md +++ b/README.md @@ -2,40 +2,10 @@ _A seed vault for your feeds._ -[FeedVault](https://feedvault.se/) is an open-source web application that allows users to archive and search their favorite RSS, Atom, and JSON feeds. With FeedVault, users can effortlessly add their favorite feeds, ensuring they have a centralized location for accessing and preserving valuable content. - -## Features - -_Note: Some features are currently in development._ - -- **Unified Feed Archiving**: Archive RSS (0.90 to 2.0), Atom (0.3, 1.0), JSON (1.0, 1.1), Dublin Core, and ITunes feeds seamlessly in one centralized location. -- **Content Search**: Easily search your archive for specific content. -- **Export Options**: Export your archive to various formats, including JSON, CSV, HTML, ODS, RST, TSV, XLS, XLSX, or YAML. -- **API**: Access your archive programmatically through a API. -- **Self-Hosting**: Host FeedVault on your own server for complete control over your data. -- **Privacy-Focused**: FeedVault respects user privacy by not tracking or collecting any personal data. It is an ad-free platform that prioritizes user security. - -## Usage - -- [Visit the FeedVault website](https://feedvault.se/). -- Sign up for an account or log in if you already have one. -- Add your favorite feeds to start archiving content. -- Explore, manage, and enjoy your centralized feed archive. - -### CLI - -There is a CLI available for FeedVault. You can run the CLI with the following command: - -```bash -python -m cli -``` +[FeedVault](https://feedvault.se/) is an free and open-source archive of RSS/Atom feeds. ## Contributing -Feel free to contribute to the project. If you have any questions, please open an issue. +Feel free to contribute with anything. If you have any questions, please open an issue or reach out to me directly. -## Contact - -If you have any questions, please open an issue. - -I can also be reached at [hello@panso.se](mailto:hello@panso.se) or on Discord: `TheLovinator#9276` +I can be reached at [tlovinator@gmail.com](mailto:tlovinator@gmail.com) or on Discord: `TheLovinator#9276` From 0bf088832437f9cc8f1c542a34494a88622b6766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Helle=C5=9Ben?= Date: Mon, 23 Mar 2026 23:30:20 +0100 Subject: [PATCH 3/9] Update django-silk dependency to include formatting support --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3d0952e..3660414 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ "django-celery-beat", "django-celery-results", "django-debug-toolbar", - "django-silk", + "django-silk[formatting]", "django", "flower", "gunicorn", From 649689eada037386e0fa0109b7fdb786733affaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Helle=C5=9Ben?= Date: Mon, 23 Mar 2026 23:30:29 +0100 Subject: [PATCH 4/9] Update README.md with deployment instructions --- README.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/README.md b/README.md index bee0b69..b790701 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,61 @@ _A seed vault for your feeds._ Feel free to contribute with anything. If you have any questions, please open an issue or reach out to me directly. I can be reached at [tlovinator@gmail.com](mailto:tlovinator@gmail.com) or on Discord: `TheLovinator#9276` + +## Deployment + +```bash +sudo pacman -S postgresql +sudo -u postgres initdb -D /var/lib/postgres/data +sudo systemctl enable --now postgresql +``` + +Create a local role and database: + +```bash +sudo -u postgres createuser -P feedvault +sudo -u postgres createdb -O feedvault feedvault +``` + +Point Django at the unix socket used by Arch (`/run/postgresql`): + +```bash +POSTGRES_USER=feedvault +POSTGRES_PASSWORD=your_password +POSTGRES_DB=feedvault +POSTGRES_HOST=/run/postgresql +POSTGRES_PORT=5432 +``` + +### Linux (Systemd) + +```bash +sudo useradd --create-home --home-dir /home/feedvault --shell /bin/fish feedvault +sudo passwd feedvault +# sudo usermod -aG wheel feedvault +su - feedvault +git clone https://git.lovinator.space/TheLovinator/feedvault.se.git feedvault +cd feedvault +uv sync --no-dev + +# Modify .env with the correct database credentials and other settings, then run migrations: +uv run python manage.py migrate +``` + +Install the systemd service from the repo: + +```bash +sudo install -m 0644 tools/systemd/feedvault.socket /etc/systemd/system/feedvault.socket +sudo install -m 0644 tools/systemd/feedvault.service /etc/systemd/system/feedvault.service +``` + +Enable and start the service: + +```bash +sudo systemctl daemon-reload +sudo systemctl enable --now feedvault.socket +sudo systemctl enable --now feedvault.service + +# Add to Nginx config and test with: +curl --unix-socket /run/feedvault/feedvault.sock https://feedvault.se +``` From 8def159a7285095eada62e1180f07ab4df435d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Helle=C5=9Ben?= Date: Mon, 23 Mar 2026 23:30:34 +0100 Subject: [PATCH 5/9] Add launch configuration for Django debugging in VSCode --- .vscode/launch.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..a5e1158 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Django", + "type": "debugpy", + "request": "launch", + "args": [ + "runserver" + ], + "django": true, + "autoStartBrowser": false, + "program": "${workspaceFolder}/manage.py" + } + ] +} From 827f94bce364242ba5d6c76bbfdd79d1f2a3da58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Helle=C5=9Ben?= Date: Mon, 23 Mar 2026 23:31:55 +0100 Subject: [PATCH 6/9] Remove unnecessary section header for Linux (Systemd) in README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index b790701..0232612 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,6 @@ POSTGRES_HOST=/run/postgresql POSTGRES_PORT=5432 ``` -### Linux (Systemd) - ```bash sudo useradd --create-home --home-dir /home/feedvault --shell /bin/fish feedvault sudo passwd feedvault From dfcb8975b8c27c1b763723da458a817f0681cb63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Helle=C5=9Ben?= Date: Mon, 23 Mar 2026 23:32:24 +0100 Subject: [PATCH 7/9] Refactor celery.py to enhance type hinting --- config/celery.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/config/celery.py b/config/celery.py index 68e4383..79d3e5b 100644 --- a/config/celery.py +++ b/config/celery.py @@ -1,11 +1,43 @@ import os +from typing import TYPE_CHECKING from celery import Celery +from celery import Signature +from celery.app.task import Task +from celery.contrib.abortable import AbortableAsyncResult +from celery.contrib.abortable import AbortableTask +from celery.contrib.django.task import DjangoTask +from celery.local import class_property +from celery.result import AsyncResult +from celery.utils.objects import FallbackContext + +if TYPE_CHECKING: + from config.settings import Any + + +classes = [ + Celery, + Task, + DjangoTask, + AbortableTask, + AsyncResult, + AbortableAsyncResult, + Signature, + FallbackContext, + class_property, +] + +for cls in classes: + setattr( # noqa: B010 + cls, + "__class_getitem__", + classmethod(lambda cls, *args, **kwargs: cls), # noqa: ARG005 + ) # Set the default Django settings module for the 'celery' program. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") -app = Celery("config") +app: Celery[Task[Any, Any]] = Celery("config") # Using a string here means the worker doesn't have to serialize # the configuration object to child processes. From 232f1b7f6686148e4f77d244120d8f4c48d9181d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Helle=C5=9Ben?= Date: Mon, 23 Mar 2026 23:32:32 +0100 Subject: [PATCH 8/9] Refactor wsgi.py to improve type hinting and remove unnecessary docstring --- config/wsgi.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/config/wsgi.py b/config/wsgi.py index cd6eab5..9634b0a 100644 --- a/config/wsgi.py +++ b/config/wsgi.py @@ -1,15 +1,11 @@ -"""WSGI config for config project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/6.0/howto/deployment/wsgi/ -""" - import os +from typing import TYPE_CHECKING from django.core.wsgi import get_wsgi_application +if TYPE_CHECKING: + from django.core.handlers.wsgi import WSGIHandler + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") -application = get_wsgi_application() +application: WSGIHandler = get_wsgi_application() From b112b69f52516c7a64294224e2f74603b644c27f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Helle=C5=9Ben?= Date: Mon, 23 Mar 2026 23:33:07 +0100 Subject: [PATCH 9/9] Add silk and django-debug-toolbar --- config/urls.py | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/config/urls.py b/config/urls.py index 825bdc2..aa99a5d 100644 --- a/config/urls.py +++ b/config/urls.py @@ -1,23 +1,24 @@ -"""URL configuration for config project. +from typing import TYPE_CHECKING -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/6.0/topics/http/urls/ - -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" - -from django.contrib import admin +from django.conf import settings +from django.conf.urls.static import static +from django.urls import include from django.urls import path -urlpatterns = [ - path("admin/", admin.site.urls), +if TYPE_CHECKING: + from django.urls import URLPattern + from django.urls.resolvers import URLResolver + +urlpatterns: list[URLPattern | URLResolver] = [ + path(route="silk/", view=include("silk.urls", namespace="silk")), ] +if settings.DEBUG: + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + +if not settings.TESTING: + from debug_toolbar.toolbar import ( # pyright: ignore[reportMissingTypeStubs] + debug_toolbar_urls, + ) + + urlpatterns += [path("silk/", include("silk.urls", namespace="silk"))] + urlpatterns = [*urlpatterns, *debug_toolbar_urls()]