django-rss-filter 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.
@@ -0,0 +1,20 @@
1
+ name: Unit tests
2
+
3
+ on:
4
+ push:
5
+ branches: ["*"]
6
+ pull_request:
7
+ branches: ["*"]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ max-parallel: 4
14
+
15
+ steps:
16
+ - uses: actions/checkout@v3
17
+ - uses: astral-sh/setup-uv@v3
18
+ - run: uv python install
19
+ - run: uv sync --group dev
20
+ - run: uv run pytest
@@ -0,0 +1,9 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+ .venv
9
+ example/db.sqlite3
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Loopwerk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-rss-filter
3
+ Version: 0.1.0
4
+ Summary: Filter public RSS feeds, remove articles that contain certain keywords or categories.
5
+ Project-URL: Homepage, https://github.com/loopwerk/django-rss-filter/issues
6
+ Project-URL: Repository, https://github.com/loopwerk/django-rss-filter.git
7
+ Project-URL: Issues, https://github.com/loopwerk/django-rss-filter/issues
8
+ Author-email: Kevin Renskers <kevin@loopwerk.io>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: atom,django,feed,filter,mute,rss
12
+ Requires-Python: >=3.9
13
+ Requires-Dist: django>=3.2.0
14
+ Requires-Dist: fastfeedparser>=0.3.7
15
+ Requires-Dist: feedgen>=1.0.0
16
+ Requires-Dist: httpx>=0.28.1
17
+ Description-Content-Type: text/markdown
18
+
19
+ # django-rss-filter
20
+
21
+ This is a Django app that creates filtered RSS feeds. It does this by filtering exsiting RSS feeds, removing articles that match filtered words and/or filtered categories. It's what powers https://www.rssfilter.com.
22
+
23
+ It comes with one view that returns the filtered feed XML, as well as Django Admin configuration to make it possible and easy to self-host your own instance of django-rss-filter. It does not come with views to create or edit filtered feeds; this can be done using the Django Admin.
24
+
25
+ ## Getting started
26
+
27
+ All instructions use [uv](https://docs.astral.sh/uv/), but should work just as well with pip or Poetry for example.
28
+
29
+ In an existing Django project:
30
+
31
+ 1. Install: `uv add django-rss-filter`
32
+ 2. Add `rssfilter` to `INSTALLED_APPS`
33
+ 3. `uv run ./manage.py migrate`
34
+ 4. Include the URL config: `path("", include("rssfilter.urls"))`
35
+
36
+ If you don't have a Django project yet, these are the steps to get started:
37
+
38
+ 1. `uv init my-django-project`
39
+ 2. `cd my-django-project`
40
+ 3. `uv add django`
41
+ 4. `uv run django-admin startproject my_django_app .`
42
+ 5. `uv run ./manage.py migrate`
43
+ 6. `uv run ./manage.py createsuperuser`
44
+ 7. `uv run ./manage.py runserver`
45
+
46
+ This will get you up and running with a working Admin site at http://127.0.0.1:8000/admin/.
47
+
48
+ Then follow the first four steps to add django-rss-filter to your Django project.
49
+
50
+ ## Example project
51
+
52
+ There's an example Django project using django-rss-filter under `example/`.
53
+
54
+ 1. `cd example`
55
+ 2. `uv run ./manage.py migrate`
56
+ 3. `uv run ./manage.py createsuperuser`
57
+ 4. `uv run ./manage.py runserver`
58
+
59
+ You can then go to http://127.0.0.1:8000/admin/ to create a feed, which you can then access at http://127.0.0.1:8000/[feed_uuid]/.
60
+
61
+ ## Settings
62
+
63
+ There is one setting that can be configured: `RSS_FILTER_CACHE_SECONDS`. The default value is 300 (5 minutes).
64
+
65
+ This setting controls how long a feed will be cached before it's fetched, filtered, and stored again.
66
+
67
+ ## Tests
68
+
69
+ Unit tests can be run with `uv run pytest`.
@@ -0,0 +1,51 @@
1
+ # django-rss-filter
2
+
3
+ This is a Django app that creates filtered RSS feeds. It does this by filtering exsiting RSS feeds, removing articles that match filtered words and/or filtered categories. It's what powers https://www.rssfilter.com.
4
+
5
+ It comes with one view that returns the filtered feed XML, as well as Django Admin configuration to make it possible and easy to self-host your own instance of django-rss-filter. It does not come with views to create or edit filtered feeds; this can be done using the Django Admin.
6
+
7
+ ## Getting started
8
+
9
+ All instructions use [uv](https://docs.astral.sh/uv/), but should work just as well with pip or Poetry for example.
10
+
11
+ In an existing Django project:
12
+
13
+ 1. Install: `uv add django-rss-filter`
14
+ 2. Add `rssfilter` to `INSTALLED_APPS`
15
+ 3. `uv run ./manage.py migrate`
16
+ 4. Include the URL config: `path("", include("rssfilter.urls"))`
17
+
18
+ If you don't have a Django project yet, these are the steps to get started:
19
+
20
+ 1. `uv init my-django-project`
21
+ 2. `cd my-django-project`
22
+ 3. `uv add django`
23
+ 4. `uv run django-admin startproject my_django_app .`
24
+ 5. `uv run ./manage.py migrate`
25
+ 6. `uv run ./manage.py createsuperuser`
26
+ 7. `uv run ./manage.py runserver`
27
+
28
+ This will get you up and running with a working Admin site at http://127.0.0.1:8000/admin/.
29
+
30
+ Then follow the first four steps to add django-rss-filter to your Django project.
31
+
32
+ ## Example project
33
+
34
+ There's an example Django project using django-rss-filter under `example/`.
35
+
36
+ 1. `cd example`
37
+ 2. `uv run ./manage.py migrate`
38
+ 3. `uv run ./manage.py createsuperuser`
39
+ 4. `uv run ./manage.py runserver`
40
+
41
+ You can then go to http://127.0.0.1:8000/admin/ to create a feed, which you can then access at http://127.0.0.1:8000/[feed_uuid]/.
42
+
43
+ ## Settings
44
+
45
+ There is one setting that can be configured: `RSS_FILTER_CACHE_SECONDS`. The default value is 300 (5 minutes).
46
+
47
+ This setting controls how long a feed will be cached before it's fetched, filtered, and stored again.
48
+
49
+ ## Tests
50
+
51
+ Unit tests can be run with `uv run pytest`.
@@ -0,0 +1 @@
1
+ 3.13
File without changes
@@ -0,0 +1,16 @@
1
+ """
2
+ ASGI config for config project.
3
+
4
+ It exposes the ASGI callable as a module-level variable named ``application``.
5
+
6
+ For more information on this file, see
7
+ https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/
8
+ """
9
+
10
+ import os
11
+
12
+ from django.core.asgi import get_asgi_application
13
+
14
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
15
+
16
+ application = get_asgi_application()
@@ -0,0 +1,124 @@
1
+ """
2
+ Django settings for config project.
3
+
4
+ Generated by 'django-admin startproject' using Django 5.1.7.
5
+
6
+ For more information on this file, see
7
+ https://docs.djangoproject.com/en/5.1/topics/settings/
8
+
9
+ For the full list of settings and their values, see
10
+ https://docs.djangoproject.com/en/5.1/ref/settings/
11
+ """
12
+
13
+ from pathlib import Path
14
+
15
+ # Build paths inside the project like this: BASE_DIR / 'subdir'.
16
+ BASE_DIR = Path(__file__).resolve().parent.parent
17
+
18
+
19
+ # Quick-start development settings - unsuitable for production
20
+ # See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
21
+
22
+ # SECURITY WARNING: keep the secret key used in production secret!
23
+ SECRET_KEY = "django-insecure-26+#r2)29f3+2-%_%5_9=4&-h-b#2e0wa7@xj8q($c(92r)-_x"
24
+
25
+ # SECURITY WARNING: don't run with debug turned on in production!
26
+ DEBUG = True
27
+
28
+ ALLOWED_HOSTS = []
29
+
30
+
31
+ # Application definition
32
+
33
+ INSTALLED_APPS = [
34
+ "django.contrib.admin",
35
+ "django.contrib.auth",
36
+ "django.contrib.contenttypes",
37
+ "django.contrib.sessions",
38
+ "django.contrib.messages",
39
+ "django.contrib.staticfiles",
40
+ "rssfilter",
41
+ ]
42
+
43
+ MIDDLEWARE = [
44
+ "django.middleware.security.SecurityMiddleware",
45
+ "django.contrib.sessions.middleware.SessionMiddleware",
46
+ "django.middleware.common.CommonMiddleware",
47
+ "django.middleware.csrf.CsrfViewMiddleware",
48
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
49
+ "django.contrib.messages.middleware.MessageMiddleware",
50
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
51
+ ]
52
+
53
+ ROOT_URLCONF = "config.urls"
54
+
55
+ TEMPLATES = [
56
+ {
57
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
58
+ "DIRS": [],
59
+ "APP_DIRS": True,
60
+ "OPTIONS": {
61
+ "context_processors": [
62
+ "django.template.context_processors.debug",
63
+ "django.template.context_processors.request",
64
+ "django.contrib.auth.context_processors.auth",
65
+ "django.contrib.messages.context_processors.messages",
66
+ ],
67
+ },
68
+ },
69
+ ]
70
+
71
+ WSGI_APPLICATION = "config.wsgi.application"
72
+
73
+
74
+ # Database
75
+ # https://docs.djangoproject.com/en/5.1/ref/settings/#databases
76
+
77
+ DATABASES = {
78
+ "default": {
79
+ "ENGINE": "django.db.backends.sqlite3",
80
+ "NAME": BASE_DIR / "db.sqlite3",
81
+ }
82
+ }
83
+
84
+
85
+ # Password validation
86
+ # https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
87
+
88
+ AUTH_PASSWORD_VALIDATORS = [
89
+ {
90
+ "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
91
+ },
92
+ {
93
+ "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
94
+ },
95
+ {
96
+ "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
97
+ },
98
+ {
99
+ "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
100
+ },
101
+ ]
102
+
103
+
104
+ # Internationalization
105
+ # https://docs.djangoproject.com/en/5.1/topics/i18n/
106
+
107
+ LANGUAGE_CODE = "en-us"
108
+
109
+ TIME_ZONE = "UTC"
110
+
111
+ USE_I18N = True
112
+
113
+ USE_TZ = True
114
+
115
+
116
+ # Static files (CSS, JavaScript, Images)
117
+ # https://docs.djangoproject.com/en/5.1/howto/static-files/
118
+
119
+ STATIC_URL = "static/"
120
+
121
+ # Default primary key field type
122
+ # https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
123
+
124
+ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
@@ -0,0 +1,24 @@
1
+ """
2
+ URL configuration for config project.
3
+
4
+ The `urlpatterns` list routes URLs to views. For more information please see:
5
+ https://docs.djangoproject.com/en/5.1/topics/http/urls/
6
+ Examples:
7
+ Function views
8
+ 1. Add an import: from my_app import views
9
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
10
+ Class-based views
11
+ 1. Add an import: from other_app.views import Home
12
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
13
+ Including another URLconf
14
+ 1. Import the include() function: from django.urls import include, path
15
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
16
+ """
17
+
18
+ from django.contrib import admin
19
+ from django.urls import include, path
20
+
21
+ urlpatterns = [
22
+ path("", include("rssfilter.urls")),
23
+ path("admin/", admin.site.urls),
24
+ ]
@@ -0,0 +1,16 @@
1
+ """
2
+ WSGI config for config project.
3
+
4
+ It exposes the WSGI callable as a module-level variable named ``application``.
5
+
6
+ For more information on this file, see
7
+ https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/
8
+ """
9
+
10
+ import os
11
+
12
+ from django.core.wsgi import get_wsgi_application
13
+
14
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
15
+
16
+ application = get_wsgi_application()
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env python
2
+ """Django's command-line utility for administrative tasks."""
3
+
4
+ import os
5
+ import sys
6
+
7
+
8
+ def main():
9
+ """Run administrative tasks."""
10
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
11
+ try:
12
+ from django.core.management import execute_from_command_line
13
+ except ImportError as exc:
14
+ raise ImportError(
15
+ "Couldn't import Django. Are you sure it's installed and "
16
+ "available on your PYTHONPATH environment variable? Did you "
17
+ "forget to activate a virtual environment?"
18
+ ) from exc
19
+ execute_from_command_line(sys.argv)
20
+
21
+
22
+ if __name__ == "__main__":
23
+ main()
@@ -0,0 +1,17 @@
1
+ [project]
2
+ name = "django-rss-filter-example"
3
+ version = "0.1.0"
4
+ description = "A simple Django project using django-rss-filter"
5
+ authors = [
6
+ {name = "Kevin Renskers", email = "kevin@loopwerk.io"},
7
+ ]
8
+ license = "MIT"
9
+ readme = "README.md"
10
+ requires-python = ">=3.13"
11
+ dependencies = [
12
+ "django>=5.1.7",
13
+ "django-rss-filter",
14
+ ]
15
+
16
+ [tool.uv.sources]
17
+ django-rss-filter = { path = "../", editable = true }