Compare commits
No commits in common. "b112b69f52516c7a64294224e2f74603b644c27f" and "119a8b70947f7e636b33a66df825ba857bfa640f" have entirely different histories.
b112b69f52
...
119a8b7094
7 changed files with 52 additions and 154 deletions
31
.env.example
31
.env.example
|
|
@ -1,31 +0,0 @@
|
||||||
# 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
|
|
||||||
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "Python Debugger: Django",
|
|
||||||
"type": "debugpy",
|
|
||||||
"request": "launch",
|
|
||||||
"args": [
|
|
||||||
"runserver"
|
|
||||||
],
|
|
||||||
"django": true,
|
|
||||||
"autoStartBrowser": false,
|
|
||||||
"program": "${workspaceFolder}/manage.py"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
88
README.md
88
README.md
|
|
@ -2,66 +2,40 @@
|
||||||
|
|
||||||
_A seed vault for your feeds._
|
_A seed vault for your feeds._
|
||||||
|
|
||||||
[FeedVault](https://feedvault.se/) is an free and open-source archive of RSS/Atom 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
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Feel free to contribute with anything. If you have any questions, please open an issue or reach out to me directly.
|
Feel free to contribute to the project. If you have any questions, please open an issue.
|
||||||
|
|
||||||
I can be reached at [tlovinator@gmail.com](mailto:tlovinator@gmail.com) or on Discord: `TheLovinator#9276`
|
## Contact
|
||||||
|
|
||||||
## Deployment
|
If you have any questions, please open an issue.
|
||||||
|
|
||||||
```bash
|
I can also be reached at [hello@panso.se](mailto:hello@panso.se) or on Discord: `TheLovinator#9276`
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
```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
|
|
||||||
```
|
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,11 @@
|
||||||
import os
|
import os
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from celery import Celery
|
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.
|
# Set the default Django settings module for the 'celery' program.
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
|
||||||
|
|
||||||
app: Celery[Task[Any, Any]] = Celery("config")
|
app = Celery("config")
|
||||||
|
|
||||||
# Using a string here means the worker doesn't have to serialize
|
# Using a string here means the worker doesn't have to serialize
|
||||||
# the configuration object to child processes.
|
# the configuration object to child processes.
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,23 @@
|
||||||
from typing import TYPE_CHECKING
|
"""URL configuration for config project.
|
||||||
|
|
||||||
from django.conf import settings
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
from django.conf.urls.static import static
|
https://docs.djangoproject.com/en/6.0/topics/http/urls/
|
||||||
from django.urls import include
|
|
||||||
|
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.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
urlpatterns = [
|
||||||
from django.urls import URLPattern
|
path("admin/", admin.site.urls),
|
||||||
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()]
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
|
"""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
|
import os
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
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")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
|
||||||
|
|
||||||
application: WSGIHandler = get_wsgi_application()
|
application = get_wsgi_application()
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ dependencies = [
|
||||||
"django-celery-beat",
|
"django-celery-beat",
|
||||||
"django-celery-results",
|
"django-celery-results",
|
||||||
"django-debug-toolbar",
|
"django-debug-toolbar",
|
||||||
"django-silk[formatting]",
|
"django-silk",
|
||||||
"django",
|
"django",
|
||||||
"flower",
|
"flower",
|
||||||
"gunicorn",
|
"gunicorn",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue