From 4dbfeff967b1cb4aca4825c1ffc268c3b282e69d Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Fri, 31 Jul 2026 15:14:11 +0100 Subject: [PATCH 01/14] add clickable links --- django_code/apps/website_redirection/admin.py | 13 +++++++++---- django_code/apps/website_redirection/models.py | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/django_code/apps/website_redirection/admin.py b/django_code/apps/website_redirection/admin.py index b3172de..92aebb7 100644 --- a/django_code/apps/website_redirection/admin.py +++ b/django_code/apps/website_redirection/admin.py @@ -2,6 +2,8 @@ from django.contrib import admin from .models import historicalData,redirectData from .utils import redirect_method from import_export.admin import ImportExportModelAdmin +from django.utils.html import format_html + # Register your models here. @@ -18,14 +20,17 @@ def re_redirect(modeladmin, request, queryset): request, output_generated ) - @admin.register(historicalData) class historicalAdmin(ImportExportModelAdmin): - list_display = [field.name for field in historicalData._meta.fields if field.name != 'id'] + list_input = (field.name for field in historicalData._meta.fields if field.name != 'id' or field.name != 'url') + list_display = ["clickable_links"] + list_display.extend(list_input) actions = [re_redirect] - + + def clickable_links(self, obj): + return format_html('{}', obj.url,obj.url) + @admin.register(redirectData) class redirectAdmin(ImportExportModelAdmin): list_display = [field.name for field in redirectData._meta.fields if field.name != 'id'] - \ No newline at end of file diff --git a/django_code/apps/website_redirection/models.py b/django_code/apps/website_redirection/models.py index 3aa5857..e31c8bc 100644 --- a/django_code/apps/website_redirection/models.py +++ b/django_code/apps/website_redirection/models.py @@ -1,4 +1,6 @@ from django.db import models +from django.contrib import admin +from django.utils.html import format_html class historicalData(models.Model): url = models.CharField(max_length=1000) -- 2.54.0 From 2e5e3b0a26cade5b57b61adfe828d46cf058d499 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Mon, 3 Aug 2026 14:22:48 +0100 Subject: [PATCH 02/14] trying the netdata logging --- django_code/apps/netdata_logging/__init__.py | 0 django_code/apps/netdata_logging/apps.py | 7 +++ .../apps/netdata_logging/credentials.py | 23 ++++++++++ django_code/apps/netdata_logging/logger.py | 44 +++++++++++++++++++ django_code/apps/netdata_logging/views.py | 8 ++++ django_code/core/settings.py | 1 + django_code/core/urls.py | 3 ++ requirements.txt | 1 + 8 files changed, 87 insertions(+) create mode 100644 django_code/apps/netdata_logging/__init__.py create mode 100644 django_code/apps/netdata_logging/apps.py create mode 100644 django_code/apps/netdata_logging/credentials.py create mode 100644 django_code/apps/netdata_logging/logger.py create mode 100644 django_code/apps/netdata_logging/views.py diff --git a/django_code/apps/netdata_logging/__init__.py b/django_code/apps/netdata_logging/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django_code/apps/netdata_logging/apps.py b/django_code/apps/netdata_logging/apps.py new file mode 100644 index 0000000..e450ec8 --- /dev/null +++ b/django_code/apps/netdata_logging/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + + +class NetdataLoggingConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.netdata_logging' + label = 'netdata_logging' diff --git a/django_code/apps/netdata_logging/credentials.py b/django_code/apps/netdata_logging/credentials.py new file mode 100644 index 0000000..3594c27 --- /dev/null +++ b/django_code/apps/netdata_logging/credentials.py @@ -0,0 +1,23 @@ +# ===================================================================== +# NETDATA CONNECTION CONFIG - TEMPORARY / HARDCODED +# +# These values are kept in plaintext here ONLY until they are moved into +# the secret manager (see apps/bitwarden). Treat everything below as +# something that must be migrated before this app is used beyond a local +# hello-world test. +# +# Current status: logger.py logs structured JSON to stdout, which is the +# supported way for Netdata's log collectors (systemd-journal / generic +# log source) to pick up application logs - it does NOT push over the +# network, so `room_token` below is not consumed by any code yet. +# +# `agent_host` / `agent_port` point at the Netdata Agent's dashboard/API +# port (read-only, no push support). They're recorded here so the values +# are in one obvious place, ready to be reused once a real push mechanism +# (StatsD or an OpenTelemetry log receiver, on their own ports - NOT +# agent_port) is confirmed enabled on this agent. +# ===================================================================== +class netdata: + agent_host = "netdata-agent.netdata.svc" + agent_port = 19999 # Netdata Agent dashboard/API port - read-only, not used to push logs + room_token = "" # Netdata Cloud room token - NOT currently used by any code in this app diff --git a/django_code/apps/netdata_logging/logger.py b/django_code/apps/netdata_logging/logger.py new file mode 100644 index 0000000..bf2dd7b --- /dev/null +++ b/django_code/apps/netdata_logging/logger.py @@ -0,0 +1,44 @@ +""" +Structured logging helper for Netdata. + +Netdata does not expose a generic "push a log line" API reachable with +just a room token from outside an Agent (see credentials.py). Until a +real push mechanism (StatsD or an OpenTelemetry log receiver) is +confirmed enabled on the agent, the supported path is the standard one: +emit structured JSON lines to stdout, which Netdata's log collectors +(systemd-journal / generic log source) are built to tail and parse. +""" +import logging +import sys + +from pythonjsonlogger import jsonlogger + +from .credentials import netdata + +_LOGGER_NAME = "netdata" + + +def get_netdata_logger() -> logging.Logger: + logger = logging.getLogger(_LOGGER_NAME) + + if not logger.handlers: + handler = logging.StreamHandler(stream=sys.stdout) + handler.setFormatter( + jsonlogger.JsonFormatter("%(asctime)s %(levelname)s %(name)s %(message)s") + ) + logger.addHandler(handler) + logger.setLevel(logging.INFO) + logger.propagate = False + + return logger + + +def log_event(message, level="info", **fields): + """Log a structured event intended to be picked up by Netdata. + + Extra keyword arguments are attached as structured fields on the JSON + log line, e.g. log_event("hello world", source="netdata_logging.hello"). + """ + logger = get_netdata_logger() + log_fn = getattr(logger, level.lower(), logger.info) + log_fn(message, extra={"netdata_agent_host": netdata.agent_host, **fields}) diff --git a/django_code/apps/netdata_logging/views.py b/django_code/apps/netdata_logging/views.py new file mode 100644 index 0000000..1cb4dce --- /dev/null +++ b/django_code/apps/netdata_logging/views.py @@ -0,0 +1,8 @@ +from django.http import HttpResponse + +from .logger import log_event + + +def hello(request): + log_event("Hello world from netdata_logging!", source="netdata_logging.hello") + return HttpResponse('

Hello Netdata logging!

') diff --git a/django_code/core/settings.py b/django_code/core/settings.py index e9ff76f..127fba5 100644 --- a/django_code/core/settings.py +++ b/django_code/core/settings.py @@ -49,6 +49,7 @@ INSTALLED_APPS = [ 'apps.job_dashboard.apps.JobDashboardConfig', 'apps.telegram_communication.apps.TelegramCommunicationConfig', 'apps.podcast_aggregator.apps.PodcastAggregatorConfig', + 'apps.netdata_logging.apps.NetdataLoggingConfig', 'import_export', 'djangoql', ] diff --git a/django_code/core/urls.py b/django_code/core/urls.py index c8bb224..9307f6a 100644 --- a/django_code/core/urls.py +++ b/django_code/core/urls.py @@ -27,6 +27,7 @@ from apps.stash_management import apps as stashapp from apps.stash_management import views as stashview from apps.website_redirection import views as website_redirectionapp from apps.podcast_aggregator import views as podcast_views +from apps.netdata_logging import views as netdata_logging_views urlpatterns = [ @@ -93,5 +94,7 @@ urlpatterns = [ ################### cloudmanager ################### path('podcast/', podcast_views.execute_podcast), + ################### netdata_logging ################### + path('netdata/hello/', netdata_logging_views.hello), ] diff --git a/requirements.txt b/requirements.txt index 137d398..6bd0bf5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,3 +19,4 @@ bitwarden_sdk xmltodict whitenoise djangoql +python-json-logger -- 2.54.0 From d38cea53f8c0a4d849be1ef010d52c6872bde5d2 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Mon, 3 Aug 2026 14:33:25 +0100 Subject: [PATCH 03/14] try another build method --- .gitea/workflows/dockerfile_testing_runner.yaml | 1 + infra/testing/dockerfile | 14 +++++++------- infra/testing/entrypoint.sh | 8 ++------ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.gitea/workflows/dockerfile_testing_runner.yaml b/.gitea/workflows/dockerfile_testing_runner.yaml index 1d5b24a..d344493 100644 --- a/.gitea/workflows/dockerfile_testing_runner.yaml +++ b/.gitea/workflows/dockerfile_testing_runner.yaml @@ -52,6 +52,7 @@ jobs: build-args: | ALLOWED_HOSTS='django-testing.tryton.geeraert.eu' DEBUG='True' + CACHE_BUST=${{ env.next_version }} tags: | gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:latest gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:${{ env.next_version }} diff --git a/infra/testing/dockerfile b/infra/testing/dockerfile index ff5bd1c..6746664 100644 --- a/infra/testing/dockerfile +++ b/infra/testing/dockerfile @@ -15,19 +15,19 @@ RUN apt-get update && \ apt-get install -y git nano && \ rm -rf /var/lib/apt/lists/* +# CACHE_BUST forces this layer (and everything after it) to re-run on every +# build, otherwise Docker reuses a cached clone from a previous build and the +# image silently keeps stale code. +ARG CACHE_BUST=1 +RUN echo "cache bust: ${CACHE_BUST}" && \ + git clone --depth 1 -b testing https://gitea.tryton.geeraert.eu/pi-ux-ce/Django_kube.git . -# Copy only the requirements file first (Changes infrequently) -COPY requirements.txt ./ - -RUN pip install --cache-dir=/opt/hostedtoolcache/pip --upgrade pip +RUN pip install --cache-dir=/opt/hostedtoolcache/pip --upgrade pip RUN pip list --cache-dir=/opt/hostedtoolcache/pip --outdated RUN pip install --cache-dir=/opt/hostedtoolcache/pip --upgrade wheel RUN pip install --cache-dir=/opt/hostedtoolcache/pip --upgrade setuptools RUN pip install --cache-dir=/opt/hostedtoolcache/pip -r requirements.txt -# Copy the rest of your application code (Changes frequently, invalidates subsequent cache) -COPY . ./ - COPY infra/testing/entrypoint.sh /code/entrypoint.sh RUN chmod +x /code/entrypoint.sh diff --git a/infra/testing/entrypoint.sh b/infra/testing/entrypoint.sh index c8440e4..62593e6 100644 --- a/infra/testing/entrypoint.sh +++ b/infra/testing/entrypoint.sh @@ -1,11 +1,7 @@ #!/bin/bash +set -e -cd Django_kube - -#another methid but needs to rm -rf before -#git clone --depth 1 -b main https://gitea.tryton.geeraert.eu/pi-ux-ce/Django_kube.git -git stash -git pull +git pull origin testing pip install -r requirements.txt -- 2.54.0 From 21e77ab0b398ede6074d12bb4e6b44815fc6b912 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Mon, 3 Aug 2026 14:43:56 +0100 Subject: [PATCH 04/14] try again --- .gitea/workflows/dockerfile_testing_runner.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitea/workflows/dockerfile_testing_runner.yaml b/.gitea/workflows/dockerfile_testing_runner.yaml index d344493..d7e7519 100644 --- a/.gitea/workflows/dockerfile_testing_runner.yaml +++ b/.gitea/workflows/dockerfile_testing_runner.yaml @@ -56,8 +56,6 @@ jobs: tags: | gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:latest gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:${{ env.next_version }} - cache-from: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:buildcache - cache-to: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:buildcache,mode=max - name: update version in the variable run: | -- 2.54.0 From 822c42bd62826b0afff6af6312b3c9d3cf1ea347 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 13:01:06 +0100 Subject: [PATCH 05/14] add new streaming app --- README.md | 4 ++ django_code/apps/netdata_logging/apps.py | 7 --- .../apps/netdata_logging/credentials.py | 23 ---------- django_code/apps/netdata_logging/logger.py | 44 ------------------- django_code/apps/netdata_logging/views.py | 8 ---- .../__init__.py | 0 django_code/apps/streaming/admin.py | 3 ++ django_code/apps/streaming/apps.py | 6 +++ .../apps/streaming/migrations/0001_initial.py | 26 +++++++++++ .../apps/streaming/migrations/__init__.py | 0 django_code/apps/streaming/models.py | 10 +++++ django_code/apps/streaming/tests.py | 3 ++ django_code/apps/streaming/views.py | 3 ++ django_code/core/routers.py | 15 +++++-- django_code/core/settings.py | 10 ++++- django_code/core/urls.py | 4 -- 16 files changed, 76 insertions(+), 90 deletions(-) delete mode 100644 django_code/apps/netdata_logging/apps.py delete mode 100644 django_code/apps/netdata_logging/credentials.py delete mode 100644 django_code/apps/netdata_logging/logger.py delete mode 100644 django_code/apps/netdata_logging/views.py rename django_code/apps/{netdata_logging => streaming}/__init__.py (100%) create mode 100644 django_code/apps/streaming/admin.py create mode 100644 django_code/apps/streaming/apps.py create mode 100644 django_code/apps/streaming/migrations/0001_initial.py create mode 100644 django_code/apps/streaming/migrations/__init__.py create mode 100644 django_code/apps/streaming/models.py create mode 100644 django_code/apps/streaming/tests.py create mode 100644 django_code/apps/streaming/views.py diff --git a/README.md b/README.md index c2e17a3..ce385ad 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ python django_code/manage.py makemigrations simpsons python django_code/manage.py makemigrations job python django_code/manage.py makemigrations telegram python django_code/manage.py makemigrations podcast +python django_code/manage.py makemigrations streaming python django_code/manage.py migrate python django_code/manage.py migrate --database=cloudmanager_db @@ -19,6 +20,7 @@ python django_code/manage.py migrate --database=redirect_db python django_code/manage.py migrate --database=job_db python django_code/manage.py migrate --database=telegram_db python django_code/manage.py migrate --database=podcast_db +python django_code/manage.py migrate --database=streaming_db ``` ### Database debug @@ -30,6 +32,7 @@ create database simpsons; create database job; create database telegram; create database podcast; +create database streaming; @@ -39,6 +42,7 @@ drop database simpsons; drop database job; drop database telegram; drop database podcast; +drop database streaming; ``` diff --git a/django_code/apps/netdata_logging/apps.py b/django_code/apps/netdata_logging/apps.py deleted file mode 100644 index e450ec8..0000000 --- a/django_code/apps/netdata_logging/apps.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.apps import AppConfig - - -class NetdataLoggingConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'apps.netdata_logging' - label = 'netdata_logging' diff --git a/django_code/apps/netdata_logging/credentials.py b/django_code/apps/netdata_logging/credentials.py deleted file mode 100644 index 3594c27..0000000 --- a/django_code/apps/netdata_logging/credentials.py +++ /dev/null @@ -1,23 +0,0 @@ -# ===================================================================== -# NETDATA CONNECTION CONFIG - TEMPORARY / HARDCODED -# -# These values are kept in plaintext here ONLY until they are moved into -# the secret manager (see apps/bitwarden). Treat everything below as -# something that must be migrated before this app is used beyond a local -# hello-world test. -# -# Current status: logger.py logs structured JSON to stdout, which is the -# supported way for Netdata's log collectors (systemd-journal / generic -# log source) to pick up application logs - it does NOT push over the -# network, so `room_token` below is not consumed by any code yet. -# -# `agent_host` / `agent_port` point at the Netdata Agent's dashboard/API -# port (read-only, no push support). They're recorded here so the values -# are in one obvious place, ready to be reused once a real push mechanism -# (StatsD or an OpenTelemetry log receiver, on their own ports - NOT -# agent_port) is confirmed enabled on this agent. -# ===================================================================== -class netdata: - agent_host = "netdata-agent.netdata.svc" - agent_port = 19999 # Netdata Agent dashboard/API port - read-only, not used to push logs - room_token = "" # Netdata Cloud room token - NOT currently used by any code in this app diff --git a/django_code/apps/netdata_logging/logger.py b/django_code/apps/netdata_logging/logger.py deleted file mode 100644 index bf2dd7b..0000000 --- a/django_code/apps/netdata_logging/logger.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -Structured logging helper for Netdata. - -Netdata does not expose a generic "push a log line" API reachable with -just a room token from outside an Agent (see credentials.py). Until a -real push mechanism (StatsD or an OpenTelemetry log receiver) is -confirmed enabled on the agent, the supported path is the standard one: -emit structured JSON lines to stdout, which Netdata's log collectors -(systemd-journal / generic log source) are built to tail and parse. -""" -import logging -import sys - -from pythonjsonlogger import jsonlogger - -from .credentials import netdata - -_LOGGER_NAME = "netdata" - - -def get_netdata_logger() -> logging.Logger: - logger = logging.getLogger(_LOGGER_NAME) - - if not logger.handlers: - handler = logging.StreamHandler(stream=sys.stdout) - handler.setFormatter( - jsonlogger.JsonFormatter("%(asctime)s %(levelname)s %(name)s %(message)s") - ) - logger.addHandler(handler) - logger.setLevel(logging.INFO) - logger.propagate = False - - return logger - - -def log_event(message, level="info", **fields): - """Log a structured event intended to be picked up by Netdata. - - Extra keyword arguments are attached as structured fields on the JSON - log line, e.g. log_event("hello world", source="netdata_logging.hello"). - """ - logger = get_netdata_logger() - log_fn = getattr(logger, level.lower(), logger.info) - log_fn(message, extra={"netdata_agent_host": netdata.agent_host, **fields}) diff --git a/django_code/apps/netdata_logging/views.py b/django_code/apps/netdata_logging/views.py deleted file mode 100644 index 1cb4dce..0000000 --- a/django_code/apps/netdata_logging/views.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.http import HttpResponse - -from .logger import log_event - - -def hello(request): - log_event("Hello world from netdata_logging!", source="netdata_logging.hello") - return HttpResponse('

Hello Netdata logging!

') diff --git a/django_code/apps/netdata_logging/__init__.py b/django_code/apps/streaming/__init__.py similarity index 100% rename from django_code/apps/netdata_logging/__init__.py rename to django_code/apps/streaming/__init__.py diff --git a/django_code/apps/streaming/admin.py b/django_code/apps/streaming/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/django_code/apps/streaming/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/django_code/apps/streaming/apps.py b/django_code/apps/streaming/apps.py new file mode 100644 index 0000000..85d22eb --- /dev/null +++ b/django_code/apps/streaming/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class StreamingConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.streaming' diff --git a/django_code/apps/streaming/migrations/0001_initial.py b/django_code/apps/streaming/migrations/0001_initial.py new file mode 100644 index 0000000..a8da596 --- /dev/null +++ b/django_code/apps/streaming/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.30 on 2026-08-05 12:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='streamingData', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('url', models.CharField(max_length=1000)), + ('addedDate', models.DateField(auto_now_add=True, null=True, verbose_name='Published')), + ('status', models.CharField(blank=True, max_length=1000, null=True)), + ], + options={ + 'db_table': 'streaming', + }, + ), + ] diff --git a/django_code/apps/streaming/migrations/__init__.py b/django_code/apps/streaming/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django_code/apps/streaming/models.py b/django_code/apps/streaming/models.py new file mode 100644 index 0000000..15b638f --- /dev/null +++ b/django_code/apps/streaming/models.py @@ -0,0 +1,10 @@ +from django.db import models + +# Create your models here. +class streamingData(models.Model): + url = models.CharField(max_length=1000) + addedDate = models.DateField('Published', blank=True, null=True, auto_now_add=True) + status = models.CharField(max_length=1000, blank=True, null=True) + + class Meta: + db_table = 'streaming' diff --git a/django_code/apps/streaming/tests.py b/django_code/apps/streaming/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/django_code/apps/streaming/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/django_code/apps/streaming/views.py b/django_code/apps/streaming/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/django_code/apps/streaming/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/django_code/core/routers.py b/django_code/core/routers.py index 6199a21..cc62513 100644 --- a/django_code/core/routers.py +++ b/django_code/core/routers.py @@ -27,6 +27,9 @@ class ProjectDatabaseRouter: if model._meta.app_label == 'podcast': return 'podcast_db' + if model._meta.app_label == 'streaming': + return 'streaming_db' + return 'default' def db_for_write(self, model, **hints): @@ -50,14 +53,17 @@ class ProjectDatabaseRouter: if model._meta.app_label == 'podcast': return 'podcast_db' + if model._meta.app_label == 'streaming': + return 'streaming_db' + return 'default' def allow_relation(self, obj1, obj2, **hints): """Allow relations if both models are in the same database.""" # Prevents accidental foreign key relationships across different physical DBs if ( - obj1._meta.app_label in ['cloudmanager', 'simpsons', 'redirect', 'job', 'telegram', 'podcast'] or - obj2._meta.app_label in ['cloudmanager', 'simpsons', 'redirect', 'job', 'telegram', 'podcast'] + obj1._meta.app_label in ['cloudmanager', 'simpsons', 'redirect', 'job', 'telegram', 'podcast', 'streaming'] or + obj2._meta.app_label in ['cloudmanager', 'simpsons', 'redirect', 'job', 'telegram', 'podcast', 'streaming'] ): return obj1._meta.app_label == obj2._meta.app_label return None @@ -83,8 +89,11 @@ class ProjectDatabaseRouter: if app_label == 'podcast': return db == 'podcast_db' + if app_label == 'streaming': + return db == 'streaming_db' + # Ensure default Django apps (auth, sessions, etc.) don't migrate into simpsons/cloudmanager - if db in ['cloudmanager_db', 'simpsons_db', 'redirect_db', 'job_db', 'telegram_db', 'podcast_db']: + if db in ['cloudmanager_db', 'simpsons_db', 'redirect_db', 'job_db', 'telegram_db', 'podcast_db', 'streaming_db']: return False return None diff --git a/django_code/core/settings.py b/django_code/core/settings.py index 127fba5..a1d45b5 100644 --- a/django_code/core/settings.py +++ b/django_code/core/settings.py @@ -49,7 +49,7 @@ INSTALLED_APPS = [ 'apps.job_dashboard.apps.JobDashboardConfig', 'apps.telegram_communication.apps.TelegramCommunicationConfig', 'apps.podcast_aggregator.apps.PodcastAggregatorConfig', - 'apps.netdata_logging.apps.NetdataLoggingConfig', + 'apps.streaming.apps.StreamingConfig', 'import_export', 'djangoql', ] @@ -154,6 +154,14 @@ DATABASES = { 'HOST': os.environ.get('DB_HOST'), 'PORT': os.environ.get('DB_PORT'), }, + 'streaming_db': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'streaming', + 'USER': os.environ.get('DB_USERNAME'), + 'PASSWORD': os.environ.get('DB_PASSWORD'), + 'HOST': os.environ.get('DB_HOST'), + 'PORT': os.environ.get('DB_PORT'), + }, } DATABASE_ROUTERS = ['core.routers.ProjectDatabaseRouter'] #DATABASE_ROUTERS = [] diff --git a/django_code/core/urls.py b/django_code/core/urls.py index 9307f6a..25d64ce 100644 --- a/django_code/core/urls.py +++ b/django_code/core/urls.py @@ -27,7 +27,6 @@ from apps.stash_management import apps as stashapp from apps.stash_management import views as stashview from apps.website_redirection import views as website_redirectionapp from apps.podcast_aggregator import views as podcast_views -from apps.netdata_logging import views as netdata_logging_views urlpatterns = [ @@ -94,7 +93,4 @@ urlpatterns = [ ################### cloudmanager ################### path('podcast/', podcast_views.execute_podcast), - ################### netdata_logging ################### - path('netdata/hello/', netdata_logging_views.hello), - ] -- 2.54.0 From 749c971e1fbb068bf4a1de12753aadcb27fbfc38 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 13:08:06 +0100 Subject: [PATCH 06/14] data structure --- django_code/apps/streaming/admin.py | 6 ++++++ django_code/apps/streaming/utils.py | 0 2 files changed, 6 insertions(+) create mode 100644 django_code/apps/streaming/utils.py diff --git a/django_code/apps/streaming/admin.py b/django_code/apps/streaming/admin.py index 8c38f3f..48327d7 100644 --- a/django_code/apps/streaming/admin.py +++ b/django_code/apps/streaming/admin.py @@ -1,3 +1,9 @@ from django.contrib import admin +from import_export.admin import ImportExportModelAdmin +from .models import streamingData + # Register your models here. +@admin.register(streamingData) +class streamingAdmin(ImportExportModelAdmin): + list_display = [field.name for field in streamingData._meta.fields if field.name != 'id'] \ No newline at end of file diff --git a/django_code/apps/streaming/utils.py b/django_code/apps/streaming/utils.py new file mode 100644 index 0000000..e69de29 -- 2.54.0 From 1a8b54b7184a7676de04d058e81da7a42fe66c93 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 13:10:11 +0100 Subject: [PATCH 07/14] add new entrypoint --- infra/testing/entrypoint.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/infra/testing/entrypoint.sh b/infra/testing/entrypoint.sh index 62593e6..44f6586 100644 --- a/infra/testing/entrypoint.sh +++ b/infra/testing/entrypoint.sh @@ -5,6 +5,8 @@ git pull origin testing pip install -r requirements.txt + + python django_code/manage.py makemigrations python django_code/manage.py makemigrations redirect python django_code/manage.py makemigrations cloudmanager @@ -12,6 +14,7 @@ python django_code/manage.py makemigrations simpsons python django_code/manage.py makemigrations job python django_code/manage.py makemigrations telegram python django_code/manage.py makemigrations podcast +python django_code/manage.py makemigrations streaming python django_code/manage.py migrate python django_code/manage.py migrate --database=cloudmanager_db @@ -20,6 +23,7 @@ python django_code/manage.py migrate --database=redirect_db python django_code/manage.py migrate --database=job_db python django_code/manage.py migrate --database=telegram_db python django_code/manage.py migrate --database=podcast_db +python django_code/manage.py migrate --database=streaming_db python django_code/manage.py runserver "0.0.0.0:8000" -- 2.54.0 From 12078b14395c88b2ea55ea3a81f8885da1d04f31 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 14:05:59 +0100 Subject: [PATCH 08/14] global settings and work on test website --- django_code/apps/streaming/utils.py | 22 ++++++++++++++++++++++ django_code/core/settings.py | 21 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/django_code/apps/streaming/utils.py b/django_code/apps/streaming/utils.py index e69de29..2727e64 100644 --- a/django_code/apps/streaming/utils.py +++ b/django_code/apps/streaming/utils.py @@ -0,0 +1,22 @@ +import requests +from django.conf import settings +import sys + + + + +def test_website(url_website,bool_proxy=False): + try: + if bool_proxy: + status = requests.get(url_website,proxies=settings.PROXIES) + else: + status = requests.get(url_website).status_code + + except requests.exceptions.ConnectionError: + status = "ConnectionError" + + #identify the exception name + except Exception as err: + print(f"{type(err).__name__} was raised: {err}") + status = "exception not targeted" + return status \ No newline at end of file diff --git a/django_code/core/settings.py b/django_code/core/settings.py index a1d45b5..7ff2b56 100644 --- a/django_code/core/settings.py +++ b/django_code/core/settings.py @@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.2/ref/settings/ """ import os from pathlib import Path +from urllib import request as urllib_request # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -223,3 +224,23 @@ CELERY_IMPORTS = [ 'apps.random_simpsons.utils' # Add other app tasks here if needed ] + + + +########################################################################################### +# +# Custom settings +# +########################################################################################### + + +PROXY_URL = 'http://gluetun-svc.gluetun.svc:8888' +PROXY = urllib_request.ProxyHandler({ + 'http': PROXY_URL, + 'https': PROXY_URL # Add the handler for HTTPS +}) + +PROXIES = { + "http" : PROXY_URL, + "https" : PROXY_URL +} -- 2.54.0 From 54fd66196e363d5e38fff99dcae2ef3d987e5550 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 14:34:06 +0100 Subject: [PATCH 09/14] test working --- django_code/apps/streaming/admin.py | 28 ++++++++++++++++++++++++++-- django_code/apps/streaming/utils.py | 13 ++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/django_code/apps/streaming/admin.py b/django_code/apps/streaming/admin.py index 48327d7..3e8d552 100644 --- a/django_code/apps/streaming/admin.py +++ b/django_code/apps/streaming/admin.py @@ -1,9 +1,33 @@ from django.contrib import admin from import_export.admin import ImportExportModelAdmin from .models import streamingData +from .utils import full_testing -# Register your models here. + +@admin.action(description="check the URLs") +def check(modeladmin, request, queryset): + for query in queryset: + print(query) + website_url = query.url + status=full_testing(website_url) + print(status) + query.status = status + query.save(update_fields=["status"]) + + +# modeladmin.message_user( +# request, +# ngettext( +# "%d episode was successfully marked as seen.", +# "%d episodes were successfully marked as seen.", +# updated, +# ) +# % updated, +# messages.SUCCESS, +# ) + @admin.register(streamingData) class streamingAdmin(ImportExportModelAdmin): - list_display = [field.name for field in streamingData._meta.fields if field.name != 'id'] \ No newline at end of file + list_display = [field.name for field in streamingData._meta.fields if field.name != 'id'] + actions = [check] \ No newline at end of file diff --git a/django_code/apps/streaming/utils.py b/django_code/apps/streaming/utils.py index 2727e64..a695230 100644 --- a/django_code/apps/streaming/utils.py +++ b/django_code/apps/streaming/utils.py @@ -1,8 +1,19 @@ import requests from django.conf import settings -import sys +def full_testing(url_website): + status = "unknown" + + #step 1 : test without VPN + status = test_website(url_website) + + + #step 2 : test with VPN + #if status != 200: + # status = test_website(url_website,bool_proxy=True) + + return status def test_website(url_website,bool_proxy=False): -- 2.54.0 From 943781d54d1a1fe77d9ddff92ad8c1f0bbe00b1c Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 14:34:20 +0100 Subject: [PATCH 10/14] enable vpn --- django_code/apps/streaming/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/django_code/apps/streaming/utils.py b/django_code/apps/streaming/utils.py index a695230..f2fe74e 100644 --- a/django_code/apps/streaming/utils.py +++ b/django_code/apps/streaming/utils.py @@ -10,8 +10,8 @@ def full_testing(url_website): #step 2 : test with VPN - #if status != 200: - # status = test_website(url_website,bool_proxy=True) + if status != 200: + status = test_website(url_website,bool_proxy=True) return status -- 2.54.0 From b4ab48be0857e139ff4f6ccdf31d482a1e4cdadc Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 14:38:06 +0100 Subject: [PATCH 11/14] display status code --- django_code/apps/streaming/admin.py | 2 +- django_code/apps/streaming/utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/django_code/apps/streaming/admin.py b/django_code/apps/streaming/admin.py index 3e8d552..6dbe2a0 100644 --- a/django_code/apps/streaming/admin.py +++ b/django_code/apps/streaming/admin.py @@ -8,9 +8,9 @@ from .utils import full_testing @admin.action(description="check the URLs") def check(modeladmin, request, queryset): for query in queryset: - print(query) website_url = query.url status=full_testing(website_url) + print(query.url) print(status) query.status = status query.save(update_fields=["status"]) diff --git a/django_code/apps/streaming/utils.py b/django_code/apps/streaming/utils.py index f2fe74e..f8f6447 100644 --- a/django_code/apps/streaming/utils.py +++ b/django_code/apps/streaming/utils.py @@ -19,7 +19,7 @@ def full_testing(url_website): def test_website(url_website,bool_proxy=False): try: if bool_proxy: - status = requests.get(url_website,proxies=settings.PROXIES) + status = requests.get(url_website,proxies=settings.PROXIES).status_code else: status = requests.get(url_website).status_code -- 2.54.0 From 3b2f77df35440fe5c8b0e320d0591f432d38ce0c Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 14:45:52 +0100 Subject: [PATCH 12/14] add a result for the method of use --- django_code/apps/streaming/admin.py | 9 +++++---- .../migrations/0002_streamingdata_result.py | 18 ++++++++++++++++++ django_code/apps/streaming/models.py | 1 + django_code/apps/streaming/utils.py | 13 +++++++++---- 4 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 django_code/apps/streaming/migrations/0002_streamingdata_result.py diff --git a/django_code/apps/streaming/admin.py b/django_code/apps/streaming/admin.py index 6dbe2a0..f12c9f6 100644 --- a/django_code/apps/streaming/admin.py +++ b/django_code/apps/streaming/admin.py @@ -9,11 +9,12 @@ from .utils import full_testing def check(modeladmin, request, queryset): for query in queryset: website_url = query.url - status=full_testing(website_url) - print(query.url) - print(status) + status=full_testing(website_url)[0] + result= full_testing(website_url)[1] + print(str(query.url)+": "+str(status)+" -> "+str(result)) query.status = status - query.save(update_fields=["status"]) + query.result = result + query.save(update_fields=["status","result"]) # modeladmin.message_user( diff --git a/django_code/apps/streaming/migrations/0002_streamingdata_result.py b/django_code/apps/streaming/migrations/0002_streamingdata_result.py new file mode 100644 index 0000000..ef814da --- /dev/null +++ b/django_code/apps/streaming/migrations/0002_streamingdata_result.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.30 on 2026-08-05 13:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('streaming', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='streamingdata', + name='result', + field=models.CharField(blank=True, max_length=1000, null=True), + ), + ] diff --git a/django_code/apps/streaming/models.py b/django_code/apps/streaming/models.py index 15b638f..640f865 100644 --- a/django_code/apps/streaming/models.py +++ b/django_code/apps/streaming/models.py @@ -5,6 +5,7 @@ class streamingData(models.Model): url = models.CharField(max_length=1000) addedDate = models.DateField('Published', blank=True, null=True, auto_now_add=True) status = models.CharField(max_length=1000, blank=True, null=True) + result = models.CharField(max_length=1000, blank=True, null=True) class Meta: db_table = 'streaming' diff --git a/django_code/apps/streaming/utils.py b/django_code/apps/streaming/utils.py index f8f6447..b873d5f 100644 --- a/django_code/apps/streaming/utils.py +++ b/django_code/apps/streaming/utils.py @@ -7,13 +7,18 @@ def full_testing(url_website): #step 1 : test without VPN status = test_website(url_website) - - #step 2 : test with VPN - if status != 200: + if status == 200: + result = "REACHABLE" + else: + #step 2 : test with VPN status = test_website(url_website,bool_proxy=True) + if status != 200: + result = "UNREACHABLE" + else: + result = "VPN REQUIRED" - return status + return status,result def test_website(url_website,bool_proxy=False): -- 2.54.0 From cbaf675f09e926c4929d3340715fc487bee3b698 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 15:28:07 +0100 Subject: [PATCH 13/14] only edit the URL --- django_code/apps/streaming/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/django_code/apps/streaming/admin.py b/django_code/apps/streaming/admin.py index f12c9f6..ce2f06f 100644 --- a/django_code/apps/streaming/admin.py +++ b/django_code/apps/streaming/admin.py @@ -30,5 +30,6 @@ def check(modeladmin, request, queryset): @admin.register(streamingData) class streamingAdmin(ImportExportModelAdmin): - list_display = [field.name for field in streamingData._meta.fields if field.name != 'id'] + list_display = ['url','result','status'] + fields = ['url'] actions = [check] \ No newline at end of file -- 2.54.0 From b496c8ee02c74c222f030026af43217f5a978917 Mon Sep 17 00:00:00 2001 From: pierregeeraert Date: Wed, 5 Aug 2026 15:28:47 +0100 Subject: [PATCH 14/14] add the migrate step for the prod entrypoint --- infra/production/entrypoint.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/infra/production/entrypoint.sh b/infra/production/entrypoint.sh index 40ab7be..f501c9e 100644 --- a/infra/production/entrypoint.sh +++ b/infra/production/entrypoint.sh @@ -7,6 +7,7 @@ python django_code/manage.py makemigrations simpsons python django_code/manage.py makemigrations job python django_code/manage.py makemigrations telegram python django_code/manage.py makemigrations podcast +python django_code/manage.py makemigrations streaming python django_code/manage.py migrate python django_code/manage.py migrate --database=cloudmanager_db @@ -15,6 +16,8 @@ python django_code/manage.py migrate --database=redirect_db python django_code/manage.py migrate --database=job_db python django_code/manage.py migrate --database=telegram_db python django_code/manage.py migrate --database=podcast_db +python django_code/manage.py migrate --database=streaming_db + python django_code/manage.py runserver "0.0.0.0:8000" -- 2.54.0