Merge pull request 'Testing' (#30) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 2m19s

Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/30
This commit was merged in pull request #30.
This commit is contained in:
2026-08-27 13:27:32 +00:00
21 changed files with 353 additions and 45 deletions
+15 -4
View File
@@ -63,18 +63,19 @@ class betaserieUtils():
def identify_episode(self,show_id,episode_number,verbose=False): def identify_episode(self,show_id,episode_number,verbose=False):
# #
# Usage # Usage
# episode_id = beta.identify_episode(show_id,"S01E01",True) # episode_id,episode_seen = beta.identify_episode(show_id,"S01E01",True)
# #
url = "https://api.betaseries.com/episodes/search?show_id="+str(show_id)+"&number="+str(episode_number) url = "https://api.betaseries.com/episodes/search?show_id="+str(show_id)+"&number="+str(episode_number)
response = requests.request("GET", url, headers=self.headers, data=self.payload) response = requests.request("GET", url, headers=self.headers, data=self.payload)
episode_id = response.json()['episode']['id'] episode_id = response.json()['episode']['id']
episode_seen = response.json()['episode']['user']['seen']
if verbose: if verbose:
print("Url request: "+str(url)) print("Url request: "+str(url))
print(response.text) print(response.text)
return episode_id return episode_id,episode_seen
def mark_episodes_watched(self,episode_id,verbose=False): def mark_episodes_watched(self,episode_id,verbose=False):
# #
@@ -112,10 +113,20 @@ class betaserieUtils():
url = "https://api.betaseries.com/shows/display?id="+str(show_id) url = "https://api.betaseries.com/shows/display?id="+str(show_id)
response = requests.request("GET", url, headers=self.headers, data=self.payload) response = requests.request("GET", url, headers=self.headers, data=self.payload)
maximum_number_seasons = response.json()['show']['seasons'] seasons_details = response.json()['show']['seasons_details']
#checking if the first season is season 0, and if so remove this season
if (seasons_details[0]['number']==0):
season_0_to_remove = seasons_details[0]
if verbose : print(season_0_to_remove)
seasons_details.remove(season_0_to_remove)
maximum_number_seasons = len(seasons_details)
if verbose : print("maximum_number_seasons: "+str(maximum_number_seasons)) if verbose : print("maximum_number_seasons: "+str(maximum_number_seasons))
seasons_details = response.json()['show']['seasons_details']
if verbose: if verbose:
print("Url request: "+str(url)) print("Url request: "+str(url))
+1 -1
View File
@@ -3,7 +3,7 @@ from django.http import HttpResponse
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render from django.shortcuts import render
import os import os
import psycopg2 #import psycopg2
from apps.cloudmanager.db_interaction import DB_generation,Check_server_supposed_XXX,Give_current_weekday,Give_current_hour from apps.cloudmanager.db_interaction import DB_generation,Check_server_supposed_XXX,Give_current_weekday,Give_current_hour
@@ -1,4 +1,4 @@
import psycopg2 #import psycopg2
from django.http import HttpResponse from django.http import HttpResponse
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from apps.kubernetes_connection import apps as kubernetes_connection from apps.kubernetes_connection import apps as kubernetes_connection
+5 -9
View File
@@ -22,7 +22,7 @@ def mark_episode_watched(season,episode,action,verbose=False):
#mark episode as seen in betaserie #mark episode as seen in betaserie
episode_number = "S"+str(season)+"E"+str(episode) episode_number = "S"+str(season)+"E"+str(episode)
episode_id = betaserie.identify_episode(simpsons_id,episode_number) episode_id,episode_seen = betaserie.identify_episode(simpsons_id,episode_number)
if action == "watched": if action == "watched":
betaserie.mark_episodes_watched(episode_id) betaserie.mark_episodes_watched(episode_id)
@@ -50,19 +50,15 @@ def generate_new_urls_for_episode(verbose=False):
# example # example
# https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=33&episode=18 # https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=33&episode=18
simpsons_series_information = betaserie.series_information(simpsons_id) seasons_information,maximum_number_season = betaserie.series_information(simpsons_id)
seasons_information = simpsons_series_information[0]
#for the simpsons, there is a season 0 which increase the count of seasons by 1 #for the simpsons, there is a season 0 which increase the count of seasons by 1
# we need to remove this entry , # we need to remove this entry ,
# so we cannot trust the maximum_number_season coming from simpsons_series_information # so we cannot trust the maximum_number_season coming from simpsons_series_information
season_0_to_remove = seasons_information[0] # edit 26/08/2026
# I updated the function betaserie.series_information to remove this season 0
if verbose : print(season_0_to_remove)
seasons_information.remove(season_0_to_remove)
maximum_number_season = len(seasons_information)
for season in range(1,maximum_number_season+1): for season in range(1,maximum_number_season+1):
# the list doesn't start with season 0 anymore so we cannot use the season number as index # the list doesn't start with season 0 anymore so we cannot use the season number as index
+1 -1
View File
@@ -87,6 +87,6 @@ class StreamingRedirectAdmin(ImportExportModelAdmin):
( (
'Information', { 'Information', {
"classes": ["collapse"], "classes": ["collapse"],
'fields': ('seasonInformation','alias','betaserieShowId') 'fields': ('seasonInformation','alias','betaserieShowId','maximumNumberSeason')
}), }),
) )
@@ -0,0 +1,18 @@
# Generated by Django 4.2.30 on 2026-08-26 11:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('streaming', '0012_alter_streamingredirectdata_betaserieshowid'),
]
operations = [
migrations.AddField(
model_name='streamingredirectdata',
name='maximumNumberSeason',
field=models.IntegerField(blank=True, null=True),
),
]
+10
View File
@@ -28,6 +28,7 @@ class StreamingRedirectData(models.Model):
alias = models.CharField(max_length=1000, null=True,blank=True) alias = models.CharField(max_length=1000, null=True,blank=True)
seasonInformation = models.JSONField(default=dict, blank=True) seasonInformation = models.JSONField(default=dict, blank=True)
betaserieShowId = models.IntegerField(null=True,blank=True) betaserieShowId = models.IntegerField(null=True,blank=True)
maximumNumberSeason = models.IntegerField(null=True,blank=True)
randomViewing = models.BooleanField(default=False) randomViewing = models.BooleanField(default=False)
def sanitize(self, name): def sanitize(self, name):
@@ -39,6 +40,12 @@ class StreamingRedirectData(models.Model):
print(betaserie.identify_serie(serie_name)) print(betaserie.identify_serie(serie_name))
return betaserie.series_information(betaserie.identify_serie(serie_name))[0] return betaserie.series_information(betaserie.identify_serie(serie_name))[0]
def maximum_Number_Season(self, serie_name):
betaserie = betaserieUtils()
print(serie_name)
print(betaserie.identify_serie(serie_name))
return betaserie.series_information(betaserie.identify_serie(serie_name))[1]
def betaserie_show_id(self,serie_name): def betaserie_show_id(self,serie_name):
betaserie = betaserieUtils() betaserie = betaserieUtils()
print(serie_name) print(serie_name)
@@ -46,6 +53,7 @@ class StreamingRedirectData(models.Model):
return betaserie.identify_serie(serie_name) return betaserie.identify_serie(serie_name)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.seasonInformation : if not self.seasonInformation :
self.seasonInformation = self.season_information(self.name) self.seasonInformation = self.season_information(self.name)
@@ -53,6 +61,8 @@ class StreamingRedirectData(models.Model):
self.alias = self.sanitize(self.name) self.alias = self.sanitize(self.name)
if not self.betaserieShowId: if not self.betaserieShowId:
self.betaserieShowId = self.betaserie_show_id(self.name) self.betaserieShowId = self.betaserie_show_id(self.name)
if not self.maximumNumberSeason:
self.maximumNumberSeason = self.maximum_Number_Season(self.name)
super().save(*args, **kwargs) super().save(*args, **kwargs)
class Meta: class Meta:
+16 -7
View File
@@ -1,6 +1,7 @@
import requests import requests
from django.conf import settings from django.conf import settings
from apps.betaserie.utils import betaserieUtils
import random
def full_testing(url_website): def full_testing(url_website):
status = "unknown" status = "unknown"
@@ -38,18 +39,26 @@ def test_website(url_website,bool_proxy=False):
return status return status
def randomEpisode(): def randomEpisode(seasonInformation,maximum_number_of_seasons):
return 0,0 random_season = random.randint(1, maximum_number_of_seasons)
print("random season: " + str(random_season))
def followingEpisode(season,episode,seasonInformation): maximum_number_of_episodes = seasonInformation[random_season-1]['episodes']
random_episode = random.randint(1, maximum_number_of_episodes)
print("random episode: " + str(random_episode))
return random_season,random_episode
def followingEpisode(season,episode,seasonInformation,maximum_number_seasons):
lastEpisode = False lastEpisode = False
#check if the episode is the last one of the season #check if the episode is the last one of the season
if (episode < seasonInformation[season]['episodes']): if (episode < seasonInformation[season-1]['episodes']):
#the current episode is not the #the current episode is not the last one of the season
episode += 1 episode += 1
#check if the season is the last one #check if the season is the last one
elif((season+1) < (len(seasonInformation)-1)): elif((season+1) < maximum_number_seasons):
season += 1 season += 1
episode = 1 episode = 1
else: else:
+24 -16
View File
@@ -5,6 +5,7 @@ from .models import StreamingRedirectData
from .utils import randomEpisode,followingEpisode from .utils import randomEpisode,followingEpisode
from apps.betaserie.utils import betaserieUtils from apps.betaserie.utils import betaserieUtils
betaserie = betaserieUtils() betaserie = betaserieUtils()
@@ -19,6 +20,8 @@ def streamingRedirect(request,alias):
episode = streaming_object.values('episode')[0]['episode'] episode = streaming_object.values('episode')[0]['episode']
season = streaming_object.values('season')[0]['season'] season = streaming_object.values('season')[0]['season']
seasonInformation = streaming_object.values('seasonInformation')[0]['seasonInformation'] seasonInformation = streaming_object.values('seasonInformation')[0]['seasonInformation']
maximumNumberSeason = streaming_object.values('maximumNumberSeason')[0]['maximumNumberSeason']
url_prefix = streaming_object.values('prefix')[0]['prefix'] url_prefix = streaming_object.values('prefix')[0]['prefix']
url_infix = streaming_object.values('infix')[0]['infix'] url_infix = streaming_object.values('infix')[0]['infix']
@@ -26,29 +29,35 @@ def streamingRedirect(request,alias):
betaserieShowId = streaming_object.values('betaserieShowId')[0]['betaserieShowId'] betaserieShowId = streaming_object.values('betaserieShowId')[0]['betaserieShowId']
print(url_prefix) print("Last episode seen:")
print("Season: "+str(season))
print(season) print("Episode: "+str(episode))
print(episode)
print(seasonInformation) print(seasonInformation)
value = str(streaming_object.values('url_example'))
print(value)
url_example = str(streaming_object.values('url_example')[0]['url_example']) randomViewing = streaming_object.values('randomViewing')[0]['randomViewing']
print(url_example) print("randomViewing: "+str(randomViewing))
randomViewing =str(streaming_object.values('randomViewing')[0]['randomViewing']) if (randomViewing == True):
print(randomViewing)
if (randomViewing == False):
print('show set to random') print('show set to random')
season,episode = randomEpisode() boolean_restart = True;
while (boolean_restart):
season,episode = randomEpisode(seasonInformation,maximumNumberSeason)
episode_number = "S"+str(season)+"E"+str(episode)
episode_id,episode_seen = betaserie.identify_episode(betaserieShowId,episode_number)
print("episode_seen: "+str(episode_seen))
if not(episode_seen):
boolean_restart = False
else:
print("episode "+str(episode)+" from season "+str(season)+" already seen")
else: else:
print('show set to following episode') print('show set to following episode')
season,episode,lastEpisode = followingEpisode(season,episode,seasonInformation) season,episode,lastEpisode = followingEpisode(season,episode,seasonInformation,maximumNumberSeason)
if (lastEpisode): if (lastEpisode):
return HttpResponse('<h1>You already watched the last episode of the serie!</h1>') return HttpResponse('<h1>You already watched the last episode of the serie!</h1>')
@@ -68,9 +77,8 @@ def streamingRedirect(request,alias):
#mark episode as seen in betaserie #mark episode as seen in betaserie
episode_number = "S"+str(season)+"E"+str(episode) episode_number = "S"+str(season)+"E"+str(episode)
episode_id = betaserie.identify_episode(betaserieShowId,episode_number) episode_id,episode_seen = betaserie.identify_episode(betaserieShowId,episode_number)
betaserie.mark_episodes_watched(episode_id) betaserie.mark_episodes_watched(episode_id)
return redirect(str(url_generated)) return redirect(str(url_generated))
@@ -0,0 +1,85 @@
.djangoql-completion {
position: absolute;
display: none;
border: solid 1px #ccc;
border-radius: 4px;
background: white;
background: var(--body-bg, white);
min-width: 183px;
font-size: 13px;
}
.djangoql-completion .active {
background-color: #79aec8;
color: white;
}
.djangoql-completion ul {
padding: 2px 0;
margin: 0;
max-height: 295px;
overflow: auto;
}
.djangoql-completion li {
list-style: none;
padding: 4px 10px;
cursor: pointer;
}
.djangoql-completion li:hover {
background-color: #c4e9fa;
color: black;
}
.djangoql-completion li i {
font-size: 0.9em;
color: #ccc;
float: right;
font-style: normal;
}
.djangoql-completion .syntax-help {
padding: 4px 10px 6px 10px;
margin: 0;
border-top: solid 1px #ccc;
font-size: inherit;
}
/*
Pure CSS loading icon. Credit: https://loading.io/css/
*/
.djangoql-loading {
display: block;
position: relative;
}
.djangoql-loading:after {
-moz-animation: djangoql-loading 1.2s linear infinite;
-ms-animation: djangoql-loading 1.2s linear infinite;
-webkit-animation: djangoql-loading 1.2s linear infinite;
animation: djangoql-loading 1.2s linear infinite;
border: 2px solid #aaa;
border-color: #aaa transparent #aaa transparent;
border-radius: 50%;
content: " ";
display: block;
height: 12px;
left: 50%;
margin: -8px;
position: absolute;
top: 50%;
width: 12px;
}
@keyframes djangoql-loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/*# sourceMappingURL=completion.css.map*/
@@ -0,0 +1 @@
{"version":3,"sources":["webpack:///./node_modules/djangoql-completion/dist/completion.css"],"names":[],"mappings":"AAAA;EACE,kBAAkB;EAClB,aAAa;EACb,sBAAsB;EACtB,kBAAkB;EAClB,iBAAiB;EACjB,iCAAiC;EACjC,gBAAgB;EAChB,eAAe;AACjB;;AAEA;EACE,yBAAyB;EACzB,YAAY;AACd;;AAEA;EACE,cAAc;EACd,SAAS;EACT,iBAAiB;EACjB,cAAc;AAChB;;AAEA;EACE,gBAAgB;EAChB,iBAAiB;EACjB,eAAe;AACjB;;AAEA;EACE,yBAAyB;EACzB,YAAY;AACd;;AAEA;EACE,gBAAgB;EAChB,WAAW;EACX,YAAY;EACZ,kBAAkB;AACpB;;AAEA;EACE,0BAA0B;EAC1B,SAAS;EACT,0BAA0B;EAC1B,kBAAkB;AACpB;;AAEA;;CAEC;AACD;EACE,cAAc;EACd,kBAAkB;AACpB;;AAEA;EACE,qDAAqD;EACrD,oDAAoD;EACpD,wDAAwD;EACxD,gDAAgD;EAChD,sBAAsB;EACtB,+CAA+C;EAC/C,kBAAkB;EAClB,YAAY;EACZ,cAAc;EACd,YAAY;EACZ,SAAS;EACT,YAAY;EACZ,kBAAkB;EAClB,QAAQ;EACR,WAAW;AACb;;AAEA;EACE;IACE,uBAAuB;EACzB;EACA;IACE,yBAAyB;EAC3B;AACF","file":"css/completion.css","sourcesContent":[".djangoql-completion {\n position: absolute;\n display: none;\n border: solid 1px #ccc;\n border-radius: 4px;\n background: white;\n background: var(--body-bg, white);\n min-width: 183px;\n font-size: 13px;\n}\n\n.djangoql-completion .active {\n background-color: #79aec8;\n color: white;\n}\n\n.djangoql-completion ul {\n padding: 2px 0;\n margin: 0;\n max-height: 295px;\n overflow: auto;\n}\n\n.djangoql-completion li {\n list-style: none;\n padding: 4px 10px;\n cursor: pointer;\n}\n\n.djangoql-completion li:hover {\n background-color: #c4e9fa;\n color: black;\n}\n\n.djangoql-completion li i {\n font-size: 0.9em;\n color: #ccc;\n float: right;\n font-style: normal;\n}\n\n.djangoql-completion .syntax-help {\n padding: 4px 10px 6px 10px;\n margin: 0;\n border-top: solid 1px #ccc;\n font-size: inherit;\n}\n\n/*\nPure CSS loading icon. Credit: https://loading.io/css/\n*/\n.djangoql-loading {\n display: block;\n position: relative;\n}\n\n.djangoql-loading:after {\n -moz-animation: djangoql-loading 1.2s linear infinite;\n -ms-animation: djangoql-loading 1.2s linear infinite;\n -webkit-animation: djangoql-loading 1.2s linear infinite;\n animation: djangoql-loading 1.2s linear infinite;\n border: 2px solid #aaa;\n border-color: #aaa transparent #aaa transparent;\n border-radius: 50%;\n content: \" \";\n display: block;\n height: 12px;\n left: 50%;\n margin: -8px;\n position: absolute;\n top: 50%;\n width: 12px;\n}\n\n@keyframes djangoql-loading {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n"],"sourceRoot":""}
@@ -0,0 +1,31 @@
#changelist #toolbar form textarea#searchbar {
width: 80%;
}
.djangoql-toggle {
margin-right: 10px;
}
.djangoql-help {
display: inline-block;
float: right;
margin-right: 30px;
}
@media (max-width: 1024px) {
.djangoql-help {
margin-right: 20px;
}
}
@media (max-width: 767px) {
.djangoql-help {
margin-right: 5px;
}
}
.clearfix::after {
content: "";
clear: both;
display: table;
}
@@ -0,0 +1,14 @@
code {
background-color: rgba(27, 31, 35, 0.05);
padding: 0.2em;
}
pre {
background-color: rgba(27, 31, 35, 0.05);
padding: 5px 40px;
margin: 0 0 10px 0;
}
table {
margin: 10px 0;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,113 @@
(function (DjangoQL) {
'use strict';
function parseQueryString() {
var qs = window.location.search.substring(1);
var result = {};
var vars = qs.split('&');
var i;
var l = vars.length;
var pair;
var key;
for (i = 0; i < l; i++) {
pair = vars[i].split('=');
key = decodeURIComponent(pair[0]);
if (key) {
if (typeof result[key] !== 'undefined') {
if (({}).toString.call(result[key]) !== '[object Array]') {
result[key] = [result[key]];
}
result[key].push(decodeURIComponent(pair[1]));
} else {
result[key] = decodeURIComponent(pair[1]);
}
}
}
return result;
}
// Replace standard search input with textarea and add completion toggle
DjangoQL.DOMReady(function () {
// use '-' in the param name to prevent conflicts with any model field name
var QLParamName = 'q-l';
var QLEnabled;
var QLEnabledInURL;
var QLInput;
var QLToggle;
var QLPlaceholder = 'Advanced search with Query Language';
var originalPlaceholder;
var textarea;
var input = document.querySelector('input[name=q]');
var djangoQL;
if (!input) {
return;
}
originalPlaceholder = input.placeholder;
QLEnabledInURL = parseQueryString()[QLParamName];
if (QLEnabledInURL === 'on') {
QLEnabled = true;
} else if (QLEnabledInURL === 'off') {
QLEnabled = false;
} else {
QLEnabled = Boolean(DjangoQL._toggleOnByDefault);
}
function onCompletionToggle(e) {
if (e.target.checked) {
djangoQL.enableCompletion();
QLInput.value = 'on';
textarea.placeholder = QLPlaceholder;
textarea.focus();
djangoQL.popupCompletion();
} else {
djangoQL.disableCompletion();
QLInput.value = 'off';
textarea.placeholder = originalPlaceholder;
textarea.focus();
}
}
if (DjangoQL._enableToggle) {
QLInput = document.querySelector('input[name=' + QLParamName + ']');
if (!QLInput) {
QLInput = document.createElement('input');
QLInput.type = 'hidden';
input.parentNode.insertBefore(QLInput, input);
}
QLInput.name = QLParamName;
QLInput.value = QLEnabled ? 'on' : 'off';
QLToggle = document.createElement('input');
QLToggle.type = 'checkbox';
QLToggle.checked = QLEnabled;
QLToggle.className = 'djangoql-toggle';
QLToggle.title = QLPlaceholder;
QLToggle.onchange = onCompletionToggle;
input.parentNode.insertBefore(QLToggle, input);
} else {
QLEnabled = true;
}
textarea = document.createElement('textarea');
textarea.value = input.value;
textarea.id = input.id;
textarea.name = input.name;
textarea.rows = 1;
textarea.placeholder = QLEnabled ? QLPlaceholder : originalPlaceholder;
textarea.setAttribute('maxlength', 2000);
input.parentNode.insertBefore(textarea, input);
input.parentNode.removeChild(input);
textarea.focus();
djangoQL = new DjangoQL({
completionEnabled: QLEnabled,
introspections: 'introspect/',
syntaxHelp: 'djangoql-syntax/',
selector: 'textarea[name=q]',
autoResize: true
});
});
}(window.DjangoQL));
@@ -0,0 +1,6 @@
(function (DjangoQL) {
'use strict';
DjangoQL._enableToggle = true;
DjangoQL._toggleOnByDefault = true;
}(window.DjangoQL));
@@ -0,0 +1,5 @@
(function (DjangoQL) {
'use strict';
DjangoQL._toggleOnByDefault = false;
}(window.DjangoQL));
+1 -3
View File
@@ -1,8 +1,6 @@
django django
psycopg2 psycopg2
requests #xrequests
proxmoxer
docker
kubernetes kubernetes
ruamel.yaml ruamel.yaml
pyyaml pyyaml