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), - ]