Compare commits
168
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ff4f98841 | ||
|
|
0a8c337b1e | ||
|
|
2dac0d1f53 | ||
|
|
73b627214d | ||
|
|
c79168453b | ||
|
|
299f72abca | ||
|
|
058125f0b1 | ||
|
|
130b0af8d8 | ||
|
|
6f7542ef27 | ||
|
|
919d1a3a28 | ||
|
|
3c4c32e72d | ||
|
|
3294e70b3f | ||
|
|
5908d8d282 | ||
|
|
32f8251a90 | ||
|
|
a3fec86eae | ||
|
|
672edccd70 | ||
|
|
f188e25453 | ||
|
|
d4a72ebf5d | ||
|
|
4492db4185 | ||
|
|
015edcd63d | ||
|
|
aaad6b2b7e | ||
|
|
3b6eccba80 | ||
|
|
44b730dbfc | ||
|
|
ea4ebb0de0 | ||
|
|
3b3e82f16a | ||
|
|
1430afe600 | ||
|
|
e3f01da175 | ||
|
|
7a5c7b6de9 | ||
|
|
c880172aa5 | ||
|
|
6b631fb3e3 | ||
|
|
712f3d50b5 | ||
|
|
f6875b498b | ||
|
|
2e728d4698 | ||
|
|
98a969fa04 | ||
|
|
154717aca7 | ||
|
|
cc0eb74090 | ||
|
|
e2f49a5b1f | ||
|
|
c8ceaab950 | ||
|
|
3fbf333d3d | ||
|
|
3cb09b34da | ||
|
|
1d9d723ce9 | ||
|
|
cf06bfd1bd | ||
|
|
df7340e578 | ||
|
|
7a02fb89f4 | ||
|
|
bfdf8b3b2a | ||
|
|
1ae2917263 | ||
|
|
1fea1c9e23 | ||
|
|
fa804dbed1 | ||
|
|
3b28145d0a | ||
|
|
e9bf6ba7b5 | ||
|
|
cc3394d5eb | ||
|
|
90156a4733 | ||
|
|
314a6f1bed | ||
|
|
eab0ddd697 | ||
|
|
3c1960f015 | ||
|
|
3ff4dd1fae | ||
|
|
dbeaf4c58c | ||
|
|
0f49484a43 | ||
|
|
b540c7b7e8 | ||
|
|
1012ea31ad | ||
|
|
a00baa490f | ||
|
|
bc9e331c68 | ||
|
|
57f58b0c9a | ||
|
|
496a6bd940 | ||
|
|
2bbdad3e47 | ||
|
|
91e0c992ec | ||
|
|
860de928ba | ||
|
|
9d82d61993 | ||
|
|
294af1945d | ||
|
|
430172911e | ||
|
|
38e00d6ac6 | ||
|
|
75004d16f9 | ||
|
|
47e6d6630d | ||
|
|
d9366b665b | ||
|
|
951bf0a807 | ||
|
|
4145db089f | ||
|
|
a2f6d43398 | ||
|
|
5e41927b8d | ||
|
|
ea9459f013 | ||
|
|
c2e34305eb | ||
|
|
a79a9623b6 | ||
|
|
cac74471aa | ||
|
|
afe668cca6 | ||
|
|
2785eecbf3 | ||
|
|
0833a20347 | ||
|
|
95945cd4cf | ||
|
|
fdb32538bf | ||
|
|
d2740d4b62 | ||
|
|
e26ba6d99d | ||
|
|
f419751206 | ||
|
|
70660fbd5a | ||
|
|
a94390916a | ||
|
|
5d6e5339ad | ||
|
|
b9cd8e3226 | ||
|
|
ce42b3dc33 | ||
|
|
3f25d83f64 | ||
|
|
45a67a11cf | ||
|
|
f0b700a688 | ||
|
|
8d6234927c | ||
|
|
189f81d95b | ||
|
|
c5d0fd8589 | ||
|
|
1a9ea98202 | ||
|
|
4938370eea | ||
|
|
b834ff10bf | ||
|
|
13c360b1b0 | ||
|
|
7804dd5993 | ||
|
|
87257fb0b5 | ||
|
|
56ccc83903 | ||
|
|
f658a018ac | ||
|
|
2608756622 | ||
|
|
6350dacd4e | ||
|
|
1629715732 | ||
|
|
01c1ce7534 | ||
|
|
ad0b611cb5 | ||
|
|
401ca9f935 | ||
|
|
d3a835e3fb | ||
|
|
e98c05ce08 | ||
|
|
9759416787 | ||
|
|
03b007a5a0 | ||
|
|
93f3646abc | ||
|
|
145e55df92 | ||
|
|
08796241a6 | ||
|
|
8e43ea9dbd | ||
|
|
a42eee7797 | ||
|
|
25caebeb0a | ||
|
|
e157a8c077 | ||
|
|
1d86eb582e | ||
|
|
04a216f643 | ||
|
|
533567b31d | ||
|
|
e568afc5e0 | ||
|
|
8865052752 | ||
|
|
f5f73fcacc | ||
|
|
b438956e96 | ||
|
|
e85c372ad8 | ||
|
|
e66c7034f0 | ||
|
|
8af967b4d3 | ||
|
|
b6e60764bd | ||
|
|
de1977fd2a | ||
|
|
60aafb55b8 | ||
|
|
2b410b5ff8 | ||
|
|
7a1021edfa | ||
|
|
a991b69547 | ||
|
|
9595ea326f | ||
|
|
78a95435ae | ||
|
|
a2973bcd82 | ||
|
|
90cb797d2e | ||
|
|
b496c8ee02 | ||
|
|
cbaf675f09 | ||
|
|
3b2f77df35 | ||
|
|
b4ab48be08 | ||
|
|
943781d54d | ||
|
|
54fd66196e | ||
|
|
12078b1439 | ||
|
|
1a8b54b718 | ||
|
|
749c971e1f | ||
|
|
822c42bd62 | ||
|
|
21e77ab0b3 | ||
|
|
d38cea53f8 | ||
|
|
2e5e3b0a26 | ||
|
|
4dbfeff967 | ||
|
|
441716bbbc | ||
|
|
09b52bc16c | ||
|
|
4f4de780ca | ||
|
|
7681aef96e | ||
|
|
a1d7d8005d | ||
|
|
31179d99de | ||
|
|
d8866b038a | ||
|
|
016ffbb1a9 |
@@ -0,0 +1,10 @@
|
||||
.git
|
||||
.github
|
||||
**/__pycache__
|
||||
*.pyc
|
||||
.pytest_cache
|
||||
media
|
||||
staticfiles
|
||||
*.sqlite3
|
||||
node_modules
|
||||
.env
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Gitea Actions Demo
|
||||
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
||||
name: Dockerfile runner
|
||||
run-name: Building and deploying to Prod 🚀
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -15,9 +15,9 @@ jobs:
|
||||
env:
|
||||
RUNNER_TOOL_CACHE: /toolcache
|
||||
DEBUG: True
|
||||
ALLOWED_HOSTS: "django.tryton.geeraert.eu"
|
||||
ALLOWED_HOSTS: "django.geeraert.eu"
|
||||
container:
|
||||
image: gitea.tryton.geeraert.eu/pi-ux-ce/custom-runner-debian-slim:1.0.6
|
||||
image: gitea.geeraert.eu/pi-ux-ce/custom-runner-debian-slim:1.0.6
|
||||
volumes:
|
||||
- act-toolcache:/opt/hostedtoolcache # this is where Runner store their cache default
|
||||
runs-on: host-runner
|
||||
@@ -56,49 +56,27 @@ jobs:
|
||||
echo "------------------------------------------------"
|
||||
echo "Next version: $next_version"
|
||||
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /opt/hostedtoolcache/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
|
||||
|
||||
- name: inject cache into docker
|
||||
uses: reproducible-containers/buildkit-cache-dance@v3.1.0
|
||||
with:
|
||||
cache-source: /opt/hostedtoolcache/pip
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to gitea
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: gitea.tryton.geeraert.eu
|
||||
registry: gitea.geeraert.eu
|
||||
username: ${{ secrets.USERNAME_GITEA }}
|
||||
password: ${{ secrets.PASSWORD_GITEA }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: infra/production/dockerfile
|
||||
push: true
|
||||
build-args: |
|
||||
ALLOWED_HOSTS='django.tryton.geeraert.eu'
|
||||
DEBUG='True'
|
||||
tags: |
|
||||
gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest
|
||||
gitea.tryton.geeraert.eu/pi-ux-ce/django-python:${{ env.next_version }}
|
||||
cache-from: type=local,src=/opt/hostedtoolcache/.buildx-cache
|
||||
cache-to: type=local,dest=/opt/hostedtoolcache/.buildx-cache-new,mode=max
|
||||
|
||||
- name: Move cache
|
||||
- name: Build image
|
||||
run: |
|
||||
rm -rf /opt/hostedtoolcache/.buildx-cache
|
||||
mv /opt/hostedtoolcache/.buildx-cache-new /opt/hostedtoolcache/.buildx-cache
|
||||
docker build \
|
||||
-f infra/production/dockerfile \
|
||||
--build-arg ALLOWED_HOSTS='django.geeraert.eu' \
|
||||
--build-arg DEBUG='True' \
|
||||
-t gitea.geeraert.eu/pi-ux-ce/django-python:latest \
|
||||
-t gitea.geeraert.eu/pi-ux-ce/django-python:${{ env.next_version }} \
|
||||
.
|
||||
|
||||
- name: Push image
|
||||
run: |
|
||||
docker push gitea.geeraert.eu/pi-ux-ce/django-python:latest
|
||||
docker push gitea.geeraert.eu/pi-ux-ce/django-python:${{ env.next_version }}
|
||||
|
||||
- name: Rollout Django to force pulling the new image
|
||||
uses: actions-hub/kubectl@master
|
||||
@@ -107,19 +85,13 @@ jobs:
|
||||
with:
|
||||
args: rollout restart deployment django -n django
|
||||
|
||||
- name: Rollout Celery worker to force pulling the new image
|
||||
uses: actions-hub/kubectl@master
|
||||
env:
|
||||
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
|
||||
with:
|
||||
args: rollout restart deployment celery-worker -n django
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||
|
||||
- name: update version in the variable
|
||||
run: |
|
||||
curl -X PUT -H "Content-Type: application/json" \
|
||||
--user ${{ secrets.USERNAME_GITEA }}:${{ secrets.PASSWORD_GITEA }} \
|
||||
https://gitea.tryton.geeraert.eu/api/v1/repos/pi-ux-ce/${{ github.event.repository.name }}/actions/variables/VERSION \
|
||||
https://gitea.geeraert.eu/api/v1/repos/pi-ux-ce/${{ github.event.repository.name }}/actions/variables/VERSION \
|
||||
-d "{\"Value\":\"$next_version\"}"
|
||||
|
||||
- name: backup git for future use
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Gitea Actions Demo
|
||||
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
||||
name: Dockerfile testing runner
|
||||
run-name: Building and deploying to testing 🔎
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
@@ -22,9 +22,6 @@ jobs:
|
||||
- name: List files in the repository
|
||||
run: |
|
||||
ls ${{ gitea.workspace }}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Compute next version
|
||||
id: versioning
|
||||
run: |
|
||||
@@ -39,30 +36,31 @@ jobs:
|
||||
- name: Login to gitea
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: gitea.tryton.geeraert.eu
|
||||
registry: gitea.geeraert.eu
|
||||
username: ${{ secrets.USERNAME_GITEA }}
|
||||
password: ${{ secrets.PASSWORD_GITEA }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: infra/testing/dockerfile
|
||||
push: true
|
||||
build-args: |
|
||||
ALLOWED_HOSTS='django-testing.tryton.geeraert.eu'
|
||||
DEBUG='True'
|
||||
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: Build image
|
||||
run: |
|
||||
docker build \
|
||||
-f infra/testing/dockerfile \
|
||||
--build-arg ALLOWED_HOSTS='django-testing.geeraert.eu' \
|
||||
--build-arg DEBUG='True' \
|
||||
--build-arg CACHE_BUST=${{ env.next_version }} \
|
||||
-t gitea.geeraert.eu/pi-ux-ce/django-testing:latest \
|
||||
-t gitea.geeraert.eu/pi-ux-ce/django-testing:${{ env.next_version }} \
|
||||
.
|
||||
|
||||
- name: Push image
|
||||
run: |
|
||||
docker push gitea.geeraert.eu/pi-ux-ce/django-testing:latest
|
||||
docker push gitea.geeraert.eu/pi-ux-ce/django-testing:${{ env.next_version }}
|
||||
|
||||
- name: update version in the variable
|
||||
run: |
|
||||
curl -X PUT -H "Content-Type: application/json" \
|
||||
--user ${{ secrets.USERNAME_GITEA }}:${{ secrets.PASSWORD_GITEA }} \
|
||||
https://gitea.tryton.geeraert.eu/api/v1/repos/pi-ux-ce/${{ github.event.repository.name }}/actions/variables/VERSION_TESTING \
|
||||
https://gitea.geeraert.eu/api/v1/repos/pi-ux-ce/${{ github.event.repository.name }}/actions/variables/VERSION_TESTING \
|
||||
-d "{\"Value\":\"$next_version\"}"
|
||||
|
||||
- name: Rollout Django to force pulling the new image
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Gitea Actions Demo
|
||||
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
||||
run-name: Deploying to Prod 🪂🛫
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Gitea Actions Demo
|
||||
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
||||
run-name: Deploying to testing 🏗️🧪
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
||||
@@ -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;
|
||||
```
|
||||
|
||||
|
||||
@@ -68,14 +72,14 @@ export bitwarden_organization_id=""
|
||||
|
||||
```
|
||||
cd existing_repo
|
||||
git remote add origin https://gitlab.tryton.geeraert.eu/pierre/django_kube.git
|
||||
git remote add origin https://gitea.geeraert.eu/pi-ux-ce/Django_kube.git
|
||||
git branch -M main
|
||||
git push -uf origin main
|
||||
```
|
||||
|
||||
## Integrate with your tools
|
||||
|
||||
- [ ] [Set up project integrations](https://gitlab.tryton.geeraert.eu/pierre/django_kube/-/settings/integrations)
|
||||
- [ ] [Set up project integrations](https://gitlab.geeraert.eu/pierre/django_kube/-/settings/integrations)
|
||||
|
||||
## Collaborate with your team
|
||||
|
||||
|
||||
@@ -60,21 +60,40 @@ class betaserieUtils():
|
||||
|
||||
return show_id
|
||||
|
||||
def poster_serie(self,serie_name,verbose=False):
|
||||
#
|
||||
# Usage
|
||||
# poster_url = beta.poster_serie("The simpsons")
|
||||
# poster_url = beta.poster_serie("The simpsons",verbose=True)
|
||||
#
|
||||
url = "https://api.betaseries.com/shows/search?title="+serie_name
|
||||
|
||||
response = requests.request("GET", url, headers=self.headers, data=self.payload)
|
||||
if verbose:
|
||||
print("Url request: "+str(url))
|
||||
print(response.text)
|
||||
|
||||
poster_url = response.json()['shows'][0]['images']['show']
|
||||
|
||||
return poster_url
|
||||
|
||||
|
||||
def identify_episode(self,show_id,episode_number,verbose=False):
|
||||
#
|
||||
# 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)
|
||||
|
||||
response = requests.request("GET", url, headers=self.headers, data=self.payload)
|
||||
|
||||
episode_id = response.json()['episode']['id']
|
||||
episode_seen = response.json()['episode']['user']['seen']
|
||||
if verbose:
|
||||
print("Url request: "+str(url))
|
||||
print(response.text)
|
||||
|
||||
return episode_id
|
||||
return episode_id,episode_seen
|
||||
|
||||
def mark_episodes_watched(self,episode_id,verbose=False):
|
||||
#
|
||||
@@ -112,10 +131,20 @@ class betaserieUtils():
|
||||
url = "https://api.betaseries.com/shows/display?id="+str(show_id)
|
||||
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))
|
||||
|
||||
seasons_details = response.json()['show']['seasons_details']
|
||||
|
||||
if verbose:
|
||||
print("Url request: "+str(url))
|
||||
|
||||
@@ -12,9 +12,9 @@ class bitwardenUtils():
|
||||
client = BitwardenClient(
|
||||
client_settings_from_dict(
|
||||
{
|
||||
"apiUrl": os.getenv("API_URL", "https://bitwarden.tryton.geeraert.eu/api"),
|
||||
"apiUrl": os.getenv("API_URL", "https://bitwarden.geeraert.eu/api"),
|
||||
"deviceType": DeviceType.SDK,
|
||||
"identityUrl": os.getenv("IDENTITY_URL", "https://bitwarden.tryton.geeraert.eu/identity"),
|
||||
"identityUrl": os.getenv("IDENTITY_URL", "https://bitwarden.geeraert.eu/identity"),
|
||||
"userAgent": "Python",
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from django.contrib import admin,messages
|
||||
from django.utils.translation import ngettext
|
||||
from .models import Deployment_Data,Schedule_Day_Data,Schedule_Week_Data,Namespace_Data,namespace_cmm_data_object
|
||||
from .utils import import_namespace
|
||||
from .models import Deployment_Data,Schedule_Day_Data,Schedule_Week_Data,Namespace_Data,Ingress_Data
|
||||
from .utils import import_namespace,import_deployment,generate_default_day_schedule,generate_default_week_schedule,Check_server_supposed_XXX,retrieve_and_apply
|
||||
from apps.kubernetes_connection.utils import scale_up,scale_down
|
||||
from admin_extra_buttons.api import button
|
||||
from core.admin import UniversalModelAdmin
|
||||
|
||||
DB = 'cloudmanager_db'
|
||||
|
||||
|
||||
@admin.action(description="scale up")
|
||||
@@ -38,21 +39,17 @@ def scale_down_deploy(modeladmin, request, queryset):
|
||||
messages.SUCCESS,
|
||||
)
|
||||
|
||||
@admin.action(description="create_entry")
|
||||
def create_entry(modeladmin, request, queryset):
|
||||
print("simpsons_data_object.create(season=2, episode=3, url='google.com'', seen=True)")
|
||||
#call function to trigger refresh of all deploy
|
||||
@admin.action(description="Expected False")
|
||||
def Check_server_supposed_False(modeladmin, request, queryset):
|
||||
servers_supposed_false = Check_server_supposed_XXX(False)
|
||||
for server in servers_supposed_false:
|
||||
messages.add_message(request, messages.INFO, server)
|
||||
|
||||
@admin.action(description="import namespace")
|
||||
def import_namespace_admin(modeladmin, request, queryset):
|
||||
#
|
||||
#
|
||||
#
|
||||
# don't forgot to clear thge quyeryset before running this
|
||||
#
|
||||
import_namespace(namespace_cmm_data_object)
|
||||
print("simpsons_data_object.create(season=2, episode=3, url='google.com'', seen=True)")
|
||||
#call function to trigger refresh of all deploy
|
||||
@admin.action(description="Expected True")
|
||||
def Check_server_supposed_true(modeladmin, request, queryset):
|
||||
servers_supposed_false = Check_server_supposed_XXX(True)
|
||||
for server in servers_supposed_false:
|
||||
messages.add_message(request, messages.INFO, server)
|
||||
|
||||
|
||||
class ActiveAtHourFilter(admin.SimpleListFilter):
|
||||
@@ -69,44 +66,58 @@ class ActiveAtHourFilter(admin.SimpleListFilter):
|
||||
return queryset
|
||||
|
||||
|
||||
class MultiDBModelAdmin(admin.ModelAdmin):
|
||||
"""Base class that pins all admin operations to DB."""
|
||||
db = DB
|
||||
|
||||
def get_queryset(self, request):
|
||||
return super().get_queryset(request).using(self.db)
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.save(using=self.db)
|
||||
|
||||
def delete_model(self, request, obj):
|
||||
obj.delete(using=self.db)
|
||||
|
||||
def delete_queryset(self, request, queryset):
|
||||
queryset.using(self.db).delete()
|
||||
|
||||
|
||||
@admin.register(Deployment_Data)
|
||||
class DeploymentDataAdmin(MultiDBModelAdmin):
|
||||
class DeploymentDataAdmin(UniversalModelAdmin):
|
||||
list_display = ('name', 'namespace', 'schedule_week', 'schedule_day', 'replicas')
|
||||
list_filter = (ActiveAtHourFilter,)
|
||||
actions = [scale_up_deploy,scale_down_deploy]
|
||||
actions = [Check_server_supposed_False,Check_server_supposed_true,scale_up_deploy,scale_down_deploy]
|
||||
ordering = ('name',)
|
||||
@button()
|
||||
def retrieve_and_apply(self, request):
|
||||
# your business logic here
|
||||
retrieve_and_apply()
|
||||
self.message_user(request, 'Operation started')
|
||||
|
||||
@button()
|
||||
def import_deployment(self, request):
|
||||
# your business logic here
|
||||
import_deployment()
|
||||
self.message_user(request, 'Deployments imported')
|
||||
|
||||
@admin.register(Schedule_Day_Data)
|
||||
class ScheduleDayAdmin(MultiDBModelAdmin):
|
||||
class ScheduleDayAdmin(UniversalModelAdmin):
|
||||
list_display = ['name_schedule'] + [f'state_at_{h}' for h in range(24)]
|
||||
|
||||
@button()
|
||||
def generate_default_day_schedule_admin(self, request):
|
||||
generate_default_day_schedule()
|
||||
generate_default_week_schedule()
|
||||
self.message_user(request, 'Created default schedules')
|
||||
|
||||
@admin.register(Schedule_Week_Data)
|
||||
class ScheduleWeekAdmin(MultiDBModelAdmin):
|
||||
class ScheduleWeekAdmin(UniversalModelAdmin):
|
||||
list_display = (
|
||||
'name_schedule',
|
||||
'state_Monday', 'state_Tuesday', 'state_Wednesday',
|
||||
'state_Thursday', 'state_Friday', 'state_Saturday', 'state_Sunday',
|
||||
)
|
||||
@button()
|
||||
def generate_default_day_schedule_admin(self, request):
|
||||
generate_default_day_schedule()
|
||||
generate_default_week_schedule()
|
||||
self.message_user(request, 'Created default schedules')
|
||||
|
||||
|
||||
@admin.register(Namespace_Data)
|
||||
class NamespaceAdmin(MultiDBModelAdmin):
|
||||
class NamespaceAdmin(UniversalModelAdmin):
|
||||
list_display = ('namespace',)
|
||||
actions = [import_namespace_admin]
|
||||
|
||||
|
||||
@button()
|
||||
def import_namespace(self, request):
|
||||
# your business logic here
|
||||
import_namespace()
|
||||
self.message_user(request, 'Namespaces imported')
|
||||
|
||||
@admin.register(Ingress_Data)
|
||||
class IngressAdmin(UniversalModelAdmin):
|
||||
list_display = ('url','namespace')
|
||||
@@ -1,37 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render
|
||||
import os
|
||||
import psycopg2
|
||||
from apps.cloudmanager.db_interaction import DB_generation,Check_server_supposed_XXX,Give_current_weekday,Give_current_hour
|
||||
|
||||
|
||||
class CloudmanagerConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'apps.cloudmanager'
|
||||
label = 'cloudmanager'
|
||||
|
||||
def coucou(request):
|
||||
return HttpResponse('<h1>Hello cmm!</h1>')
|
||||
|
||||
def hello(request):
|
||||
list_schedule = ['schedule1','schedule2']
|
||||
list_servers_up = [['wiki', 'wikijs', 2], ['book', 'bookstack-db', 1]]
|
||||
return render(request, 'cloudmanager/index.html', {'list_schedule':list_schedule,'list_servers_up':list_servers_up})
|
||||
|
||||
def redirect(request):
|
||||
db_host = os.environ.get('DB_HOST')
|
||||
db_port = os.environ.get('DB_PORT')
|
||||
db_user = os.environ.get('DB_USERNAME')
|
||||
db_password = os.environ.get('DB_PASSWORD')
|
||||
db_name = os.environ.get('CUSTOM_DB_DATABASE',os.environ.get('DB_DATABASE'))
|
||||
|
||||
generated_db = DB_generation(db_host, db_port, db_user, db_password,db_name)
|
||||
##operation:
|
||||
## Server(s) supposed to be UP
|
||||
|
||||
list_servers_up = Check_server_supposed_XXX(generated_db, "up", Give_current_hour(),Give_current_weekday())
|
||||
print(list_servers_up)
|
||||
return render(request, 'cloudmanager/cmm_blank_page.html', {'list_servers_up':list_servers_up})
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import psycopg2
|
||||
#import psycopg2
|
||||
from django.http import HttpResponse
|
||||
from django.views.decorators.http import require_POST
|
||||
from apps.kubernetes_connection import apps as kubernetes_connection
|
||||
@@ -154,10 +154,6 @@ def main(request):
|
||||
#print(Is_the_server_already_wanted_state(112, "stopped"))
|
||||
return HttpResponse('<h1>CMM executed!</h1>')
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
"""
|
||||
TO DO:
|
||||
EXTRACT TYPE OF MACHINE
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-09 12:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='deployment_data',
|
||||
name='actual_replica',
|
||||
field=models.IntegerField(default=1),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.29 on 2026-09-13 15:38
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0002_deployment_data_actual_replica'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-14 13:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0003_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-14 14:14
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0004_alter_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateTimeField(default=datetime.datetime(2026, 9, 14, 14, 14, 29, 566084, tzinfo=datetime.timezone.utc), verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-14 14:14
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0005_alter_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateTimeField(default=datetime.datetime(2026, 9, 14, 14, 14, 33, 642627, tzinfo=datetime.timezone.utc), verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-14 14:35
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0006_alter_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateTimeField(default=datetime.datetime(2026, 9, 14, 14, 35, 47, 473312, tzinfo=datetime.timezone.utc), verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-14 14:35
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0007_alter_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateTimeField(default=datetime.datetime(2026, 9, 14, 14, 35, 51, 657797, tzinfo=datetime.timezone.utc), verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-14 14:43
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0008_alter_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateTimeField(default=datetime.datetime(2026, 9, 14, 14, 43, 26, 985719, tzinfo=datetime.timezone.utc), verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-14 14:43
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0009_alter_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateTimeField(default=datetime.datetime(2026, 9, 14, 14, 43, 31, 55115, tzinfo=datetime.timezone.utc), verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-14 14:46
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0010_alter_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-14 15:13
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0011_alter_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deployment_data',
|
||||
name='do_not_touch_until',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='do_not_touch_until'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-21 16:14
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0012_alter_deployment_data_do_not_touch_until'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Ingress_Data',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('url', models.CharField(max_length=100)),
|
||||
('namespace', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cloudmanager.namespace_data')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-21 21:06
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cloudmanager', '0013_ingress_data'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='ingress_data',
|
||||
name='namespace',
|
||||
field=models.CharField(blank=True, max_length=100, null=True),
|
||||
),
|
||||
]
|
||||
@@ -1,6 +1,5 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
class Schedule_Week_Data(models.Model):
|
||||
name_schedule = models.CharField(max_length=100,unique=True)
|
||||
@@ -53,6 +52,8 @@ class Deployment_Data(models.Model):
|
||||
schedule_week = models.ForeignKey(Schedule_Week_Data,null=True, blank=True, on_delete=models.SET_NULL)
|
||||
schedule_day = models.ForeignKey(Schedule_Day_Data,null=True, blank=True, on_delete=models.SET_NULL)
|
||||
replicas = models.IntegerField()
|
||||
actual_replica = models.IntegerField()
|
||||
do_not_touch_until = models.DateTimeField('do_not_touch_until', default=timezone.now)
|
||||
class Meta:
|
||||
db_table = 'machine'
|
||||
|
||||
@@ -61,5 +62,9 @@ class Namespace_Data(models.Model):
|
||||
#deployments = models.ForeignKey(Schedule_Week_Data,null=True, blank=True, on_delete=models.SET_NULL)
|
||||
class Meta:
|
||||
db_table = 'namespace'
|
||||
def __str__(self):
|
||||
return self.namespace
|
||||
|
||||
namespace_cmm_data_object = Namespace_Data.objects.using('cloudmanager_db')
|
||||
class Ingress_Data(models.Model):
|
||||
url = models.CharField(max_length=100)
|
||||
namespace = models.CharField(max_length=100,null=True, blank=True)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
URL configuration for django_code project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/
|
||||
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.urls import path
|
||||
|
||||
from .views import hello,import_namespace_view,retrieve_and_apply_view,scale_up_gui,scale_down_gui,add_ingress,delete_ingress
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
################### cloudmanager ###################
|
||||
path('', hello, name='hello'),
|
||||
path('import_namespace', import_namespace_view, name='import_namespace'),
|
||||
path('retrieve_and_apply_view', retrieve_and_apply_view, name='retrieve_and_apply_view'),
|
||||
path('scale_up/<str:namespace_name>/<str:deploy_name>', scale_up_gui),
|
||||
path('scale_down/<str:namespace_name>/<str:deploy_name>', scale_down_gui),
|
||||
path('add_ingress', add_ingress),
|
||||
path('delete_ingress', delete_ingress),
|
||||
|
||||
|
||||
]
|
||||
@@ -1,13 +1,144 @@
|
||||
from apps.kubernetes_connection.utils import get_namespace
|
||||
from django.utils import timezone
|
||||
import datetime
|
||||
from apps.kubernetes_connection.utils import get_namespace,get_deployments,scale_up,scale_down
|
||||
from apps.cloudmanager.models import Schedule_Day_Data,Schedule_Week_Data,Namespace_Data,Deployment_Data
|
||||
|
||||
|
||||
def import_namespace(queryset):
|
||||
|
||||
def import_namespace():
|
||||
namespaces_list = get_namespace()
|
||||
for namespace in namespaces_list:
|
||||
queryset.create(namespace=namespace)
|
||||
if namespace[0]!="kube-system":
|
||||
Namespace_Data.objects.get_or_create(namespace=namespace)
|
||||
|
||||
def import_deployment(queryset):
|
||||
namespaces_list = get_namespace()
|
||||
#for namespace in namespaces_list:
|
||||
# queryset.create(namespace=namespace)
|
||||
def import_deployment():
|
||||
deployment_list = get_deployments()
|
||||
Schedule_Day_Always_off,Schedule_Day_Always_on = generate_default_day_schedule()
|
||||
Schedule_Week_Always_off,Schedule_Week_Always_on = generate_default_week_schedule()
|
||||
|
||||
for deployment in deployment_list:
|
||||
#if the replicas is originally 0 , it means it is disabled so put the schedule as always off
|
||||
if deployment[2] == 0:
|
||||
schedule_object = Schedule_Day_Always_off
|
||||
else:
|
||||
schedule_object = Schedule_Day_Always_on
|
||||
if deployment[0]!="kube-system":
|
||||
Deployment_Data.objects.get_or_create(namespace=deployment[0],name=deployment[1],defaults={"replicas":deployment[2],"actual_replica":deployment[2],"schedule_day":schedule_object,"schedule_week":Schedule_Week_Always_on})
|
||||
|
||||
|
||||
def generate_default_day_schedule():
|
||||
Always_off,status = Schedule_Day_Data.objects.update_or_create(name_schedule="Always_off",defaults={"state_at_0" : False ,"state_at_1" : False ,"state_at_2" : False ,"state_at_3" : False ,"state_at_4" : False ,"state_at_5" : False ,"state_at_6" : False ,"state_at_7" : False ,"state_at_8" : False ,"state_at_9" : False ,"state_at_10" : False ,"state_at_11" : False ,"state_at_12" : False ,"state_at_13" : False ,"state_at_14" : False ,"state_at_15" : False ,"state_at_16" : False ,"state_at_17" : False ,"state_at_18" : False ,"state_at_19" : False ,"state_at_20" : False ,"state_at_21" : False ,"state_at_22" : False ,"state_at_23" : False})
|
||||
Always_on,status = Schedule_Day_Data.objects.update_or_create(name_schedule="Always_on",defaults={"state_at_0" : True ,"state_at_1" : True ,"state_at_2" : True ,"state_at_3" : True ,"state_at_4" : True ,"state_at_5" : True ,"state_at_6" : True ,"state_at_7" : True ,"state_at_8" : True ,"state_at_9" : True ,"state_at_10" : True ,"state_at_11" : True ,"state_at_12" : True ,"state_at_13" : True ,"state_at_14" : True ,"state_at_15" : True ,"state_at_16" : True ,"state_at_17" : True ,"state_at_18" : True ,"state_at_19" : True ,"state_at_20" : True ,"state_at_21" : True ,"state_at_22" : True ,"state_at_23" : True})
|
||||
return Always_off,Always_on
|
||||
|
||||
def generate_default_week_schedule():
|
||||
Always_off,status = Schedule_Week_Data.objects.update_or_create(name_schedule="Always_off",defaults={"state_Monday" : False , "state_Tuesday" : False , "state_Wednesday" : False , "state_Thursday" : False , "state_Friday" : False , "state_Saturday" : False , "state_Sunday" : False})
|
||||
Always_on,status = Schedule_Week_Data.objects.update_or_create(name_schedule="Always_on",defaults={"state_Monday" : True , "state_Tuesday" : True , "state_Wednesday" : True , "state_Thursday" : True , "state_Friday" : True , "state_Saturday" : True , "state_Sunday" : True})
|
||||
return Always_off,Always_on
|
||||
|
||||
def Give_current_weekday():
|
||||
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday','Saturday', 'Sunday']
|
||||
weekday = days[datetime.datetime.today().weekday()]
|
||||
return weekday
|
||||
|
||||
def Give_current_hour():
|
||||
now = datetime.datetime.now()
|
||||
return now.hour
|
||||
|
||||
def get_current_replicas():
|
||||
deployments_list = get_deployments()
|
||||
for deployment in deployments_list:
|
||||
if deployment[0]!="kube-system":
|
||||
object,created = Deployment_Data.objects.update_or_create(namespace=deployment[0],name=deployment[1],defaults={"actual_replica":deployment[2]})
|
||||
if created:
|
||||
print("THIS DEPLOY: name: "+str(server[1])+" namespace: "+str(server[0])+" replicas: "+str(server[2])+" IS NEW !!!!!")
|
||||
return 0
|
||||
|
||||
def Check_server_supposed_XXX(expected_status,verbose=False):
|
||||
#just for testing
|
||||
#expected_status = True
|
||||
|
||||
# Get week schedule
|
||||
|
||||
argument_week="state_"+str(Give_current_weekday())
|
||||
query_week = {argument_week : expected_status}
|
||||
|
||||
schedules_week = Schedule_Week_Data.objects.filter(**query_week)
|
||||
|
||||
# Get day schedule
|
||||
|
||||
argument_day="state_at_"+str(Give_current_hour())
|
||||
query_day = {argument_day : expected_status}
|
||||
|
||||
schedules_day = Schedule_Day_Data.objects.filter(**query_day)
|
||||
|
||||
if expected_status:
|
||||
deployments = Deployment_Data.objects.filter(schedule_week__in=schedules_week, schedule_day__in=schedules_day)
|
||||
else:
|
||||
deployments = Deployment_Data.objects.filter(schedule_week__in=schedules_week) | Deployment_Data.objects.filter(schedule_day__in=schedules_day)
|
||||
|
||||
deployments_list = []
|
||||
for deployment in deployments:
|
||||
display_list = []
|
||||
name = deployment.name
|
||||
display_list.append(name)
|
||||
if verbose : print("name: "+str(name))
|
||||
namespace = deployment.namespace
|
||||
display_list.append(namespace)
|
||||
if verbose : print("namespace: "+str(namespace))
|
||||
replicas = deployment.replicas
|
||||
display_list.append(replicas)
|
||||
if verbose : print("replicas: "+str(replicas))
|
||||
#Adding the whole object as well for future use
|
||||
display_list.append(deployment)
|
||||
deployments_list.append(display_list)
|
||||
|
||||
return deployments_list
|
||||
|
||||
|
||||
def retrieve_and_apply(verbose=False):
|
||||
output = ""
|
||||
output += str(Give_current_hour())
|
||||
output += str("\n")
|
||||
|
||||
|
||||
#Get current replica to compare with the replicas created at the start
|
||||
get_current_replicas()
|
||||
|
||||
print("------------------------------------------")
|
||||
print("-----------------UP-----------------------")
|
||||
print("------------------------------------------")
|
||||
servers_supposed_true = Check_server_supposed_XXX(True)
|
||||
for server in servers_supposed_true:
|
||||
#check if the expected replica (server[2]) match the current replica of the deployment (server[3].actual_replica)
|
||||
if server[3].actual_replica == server[2]:
|
||||
if verbose : print("name: "+str(server[1])+" namespace: "+str(server[0])+" already UP")
|
||||
elif server[3].do_not_touch_until > timezone.now():
|
||||
if verbose : print("name: "+str(server[1])+" namespace: "+str(server[0])+" is in freeze period")
|
||||
else:
|
||||
echo = "Starting -> name: "+str(server[1])+" namespace: "+str(server[0])+" replicas: "+str(server[2])
|
||||
output += str(echo)
|
||||
output += "\n"
|
||||
print(echo)
|
||||
|
||||
scale_up(namespace_name=server[1],deploy_name=server[0],replicas=server[2])
|
||||
|
||||
print("------------------------------------------")
|
||||
print("----------------DOWN----------------------")
|
||||
print("------------------------------------------")
|
||||
servers_supposed_false = Check_server_supposed_XXX(False)
|
||||
for server in servers_supposed_false:
|
||||
#check if the current replica of the deployment (server[3].actual_replica) is already 0 meaning the server is already down
|
||||
if server[3].actual_replica == 0:
|
||||
if verbose : print("name: "+str(server[1])+" namespace: "+str(server[0])+" already DOWN")
|
||||
elif server[3].do_not_touch_until > timezone.now():
|
||||
if verbose : print("name: "+str(server[1])+" namespace: "+str(server[0])+" is in freeze period")
|
||||
else:
|
||||
|
||||
echo = "Shutting down -> name: "+str(server[1])+" namespace: "+str(server[0])+" replicas: "+str(server[2])
|
||||
output += str(echo)
|
||||
output += str("\n")
|
||||
print(echo)
|
||||
scale_down(namespace_name=server[1],deploy_name=server[0])
|
||||
print("------------------------------------------")
|
||||
return output
|
||||
@@ -1,25 +1,77 @@
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
from datetime import timedelta
|
||||
from django.utils import timezone
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.http import JsonResponse
|
||||
|
||||
# IMPORT AT THE TOP HERE: This is completely safe!
|
||||
from apps.cloudmanager.models import Deployment_Data,Schedule_Week_Data
|
||||
from apps.import_aggregator.import_rest_framework import api_view, authentication_classes, permission_classes,TokenAuthentication,IsAuthenticated,Response,status
|
||||
|
||||
def coucou(request):
|
||||
# 1. Prepare the data inside the function
|
||||
data = CmmData(
|
||||
name="test",
|
||||
namespace="testspace",
|
||||
schedule_hour="1",
|
||||
schedule_day="deux",
|
||||
replicas=3
|
||||
)
|
||||
from .utils import import_namespace,retrieve_and_apply
|
||||
from apps.kubernetes_connection.utils import scale_up,scale_down
|
||||
from .models import Deployment_Data,Ingress_Data
|
||||
|
||||
# 2. This line actually pushes the data into your cloudmanager_db!
|
||||
data.save()
|
||||
def hello(request):
|
||||
list_schedule = ['schedule1','schedule2']
|
||||
list_servers_up = [['wiki', 'wikijs', 2], ['book', 'bookstack-db', 1]]
|
||||
return render(request, 'cloudmanager/index.html', {'list_schedule':list_schedule,'list_servers_up':list_servers_up})
|
||||
|
||||
return HttpResponse('<h1>Hello cmm! Data saved successfully!</h1>')
|
||||
def import_namespace_view(request):
|
||||
import_namespace()
|
||||
return HttpResponse('<h1>Namespace imported!</h1>')
|
||||
|
||||
def display(request):
|
||||
data = CmmData.objects.all()
|
||||
print(data[0].namespace)
|
||||
return HttpResponse(data)
|
||||
|
||||
def retrieve_and_apply_view(request):
|
||||
output = retrieve_and_apply()
|
||||
return HttpResponse('<h1>'+output+'</h1>')
|
||||
|
||||
def scale_up_gui(request,namespace_name,deploy_name,replicas=1):
|
||||
Deployment_Data.objects.filter(namespace=namespace_name,name=deploy_name).update(do_not_touch_until=timezone.now() + timedelta(hours=1))
|
||||
scale_up(namespace_name=namespace_name,deploy_name=deploy_name,replicas=replicas)
|
||||
return render(request, 'dashboard/start.html', {'namespace':namespace_name,'deployment': deploy_name, 'url': 'https://namespace.com'})
|
||||
|
||||
|
||||
def scale_down_gui(request,namespace_name,deploy_name):
|
||||
Deployment_Data.objects.filter(namespace=namespace_name,name=deploy_name).update(do_not_touch_until=timezone.now() + timedelta(hours=1))
|
||||
scale_down(namespace_name=namespace_name,deploy_name=deploy_name)
|
||||
return render(request, 'dashboard/shutdown.html',
|
||||
{'namespace': namespace_name, 'deployment': deploy_name, 'url': 'https://namespace.com'})
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
@authentication_classes([TokenAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def add_ingress(request):
|
||||
url = request.POST.get('url')
|
||||
namespace = request.POST.get('namespace')
|
||||
print("URL: "+str(url))
|
||||
print("NS: "+str(namespace))
|
||||
|
||||
try:
|
||||
Ingress_Data.objects.update_or_create(url=url,namespace=namespace)
|
||||
except Exception as exception:
|
||||
return JsonResponse({"status": "error","reason":str(exception)})
|
||||
|
||||
return JsonResponse({"status": "added","url":str(url),"namespace":str(namespace)})
|
||||
|
||||
@api_view(['POST'])
|
||||
@authentication_classes([TokenAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def delete_ingress(request):
|
||||
url = request.POST.get('url')
|
||||
namespace = request.POST.get('namespace')
|
||||
print("URL: "+str(url))
|
||||
print("NS: "+str(namespace))
|
||||
|
||||
try:
|
||||
ingress_object = Ingress_Data.objects.filter(url=url,namespace=namespace)
|
||||
except Exception as exception:
|
||||
return JsonResponse({"status": "error","reason":str(exception)})
|
||||
|
||||
try:
|
||||
ingress_object.delete()
|
||||
except Exception as exception:
|
||||
return JsonResponse({"status": "error","reason":str(exception)})
|
||||
|
||||
return JsonResponse({"status": "deleted","url":str(url),"namespace":str(namespace)})
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
@@ -1,46 +0,0 @@
|
||||
from django.apps import AppConfig
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
import requests
|
||||
from proxmoxer import ProxmoxAPI
|
||||
import docker
|
||||
|
||||
class BackofficeConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'backoffice'
|
||||
|
||||
def hello(request):
|
||||
return HttpResponse('<h1>Start bookstack!</h1>')
|
||||
|
||||
def http_call_test(request):
|
||||
url = 'http://portainer.zeus.geeraert.eu/api/auth/'
|
||||
myobj = {'Username': 'admin','Password':'Xtm78*CX3mJ54g'}
|
||||
|
||||
x = requests.post(url, json = myobj)
|
||||
|
||||
print(x.text)
|
||||
return HttpResponse(x.text)
|
||||
|
||||
def proxmox(request):
|
||||
proxmox = ProxmoxAPI("proxmox.zeus.geeraert.eu", user="root@pam", password="dinner_sl@v3", verify_ssl=False)
|
||||
return HttpResponse(proxmox)
|
||||
|
||||
def docker_call(request,action,id_docker):
|
||||
print(action)
|
||||
print(id_docker)
|
||||
client = docker.from_env()
|
||||
if action == "start":
|
||||
print("nous allons start")
|
||||
client.containers.get(id_docker).start()
|
||||
if action == "stop":
|
||||
print("nous allons stop")
|
||||
client.containers.get(id_docker).stop()
|
||||
|
||||
return HttpResponse(client.containers.get(id_docker).status)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
@@ -1,8 +0,0 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
|
||||
def hello(request):
|
||||
return HttpResponse('<h1>Hello Django!</h1>')
|
||||
@@ -0,0 +1,6 @@
|
||||
from rest_framework.decorators import api_view, authentication_classes, permission_classes
|
||||
from rest_framework.authentication import TokenAuthentication
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from django.contrib import admin
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
from import_export import resources
|
||||
from import_export.fields import Field
|
||||
from .models import JobData
|
||||
from django.utils.text import Truncator
|
||||
from core.admin import UniversalModelAdmin
|
||||
|
||||
# Register your models here.
|
||||
|
||||
@@ -31,7 +31,7 @@ class JobResource(resources.ModelResource):
|
||||
|
||||
|
||||
@admin.register(JobData)
|
||||
class JobAdmin(ImportExportModelAdmin):
|
||||
class JobAdmin(UniversalModelAdmin):
|
||||
list_display = ('job_position','company','URL','status','date_saved','date_applied','type','resume','location','short_description','salary','contact','source')
|
||||
#fields = ['job_position','company','URL','status','date_saved','date_applied','type','resume','cover_letter','location','job_description','salary ','contact','source']
|
||||
resource_classes = [JobResource]
|
||||
|
||||
@@ -14,9 +14,8 @@ 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.contrib import admin
|
||||
|
||||
urlpatterns = [
|
||||
path('', admin.site.urls),
|
||||
|
||||
@@ -62,7 +62,7 @@ def nodes(request):
|
||||
'spec': {
|
||||
|
||||
'containers': [{
|
||||
'image': 'gitea.tryton.geeraert.eu/pi-ux-ce/bitwarden_cli:1.0.1',
|
||||
'image': 'gitea.geeraert.eu/pi-ux-ce/bitwarden_cli:1.0.1',
|
||||
# 'pod-running-timeout': '5m0s',
|
||||
'name': 'testpython',
|
||||
'env': [
|
||||
@@ -96,7 +96,7 @@ def backup_job(request):
|
||||
'spec': {
|
||||
|
||||
'containers': [{
|
||||
'image': 'gitea.tryton.geeraert.eu/pi-ux-ce/bitwarden_cli:1.0.1',
|
||||
'image': 'gitea.geeraert.eu/pi-ux-ce/bitwarden_cli:1.0.1',
|
||||
'name': 'testpython',
|
||||
'command': ['/bin/sh -c /config/export_bitwarden.sh'],
|
||||
'env': [
|
||||
@@ -124,8 +124,8 @@ def backup_job_yaml(request,sync_target):
|
||||
v1 = client.BatchV1Api()
|
||||
|
||||
yaml_location = {
|
||||
"synology" : "https://gitea.tryton.geeraert.eu/pi-ux-ce/Backup_kube/raw/branch/main/Infrequent_access/synology_pod.yaml",
|
||||
"openmediavault":"https://gitea.tryton.geeraert.eu/pi-ux-ce/Backup_kube/raw/branch/main/Infrequent_access/openmediavault_pod.yaml"
|
||||
"synology" : "https://gitea.geeraert.eu/pi-ux-ce/Backup_kube/raw/branch/main/Infrequent_access/synology_pod.yaml",
|
||||
"openmediavault":"https://gitea.geeraert.eu/pi-ux-ce/Backup_kube/raw/branch/main/Infrequent_access/openmediavault_pod.yaml"
|
||||
}
|
||||
print(yaml_location[sync_target])
|
||||
url_to_select=yaml_location[sync_target]
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
URL configuration for django_code project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/
|
||||
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.urls import path
|
||||
from apps.kubernetes_connection import apps as kubernetes_connection
|
||||
|
||||
urlpatterns = [
|
||||
################## kubernetes_connection#####
|
||||
path('hello/', kubernetes_connection.hello),
|
||||
path('nodes/', kubernetes_connection.nodes),
|
||||
path('backup_job/', kubernetes_connection.backup_job),
|
||||
path('backup_job_yaml/', kubernetes_connection.backup_job_yaml),
|
||||
path('scale_up/<str:namespace_name>/<str:deploy_name>', kubernetes_connection.scale_up),
|
||||
path('scale_down/<str:namespace_name>/<str:deploy_name>', kubernetes_connection.scale_down),
|
||||
|
||||
]
|
||||
@@ -32,26 +32,27 @@ def import_Deployments():
|
||||
test.items[2].spec.template.spec.containers[0].name # name the third deploy within the namespace
|
||||
return 0
|
||||
|
||||
def get_namespace():
|
||||
def get_namespace(verbose=False):
|
||||
config.load_kube_config(config_file='/kubeconfig/config')
|
||||
core = client.CoreV1Api()
|
||||
namespace = core.list_namespace()
|
||||
namespace_list = []
|
||||
for i in range(0,len(namespace.items)):
|
||||
print(namespace.items[i].metadata.name)
|
||||
if verbose : print(namespace.items[i].metadata.name)
|
||||
namespace_list.append(namespace.items[i].metadata.name)
|
||||
return namespace_list
|
||||
|
||||
def get_deployments():
|
||||
def get_deployments(verbose=False):
|
||||
config.load_kube_config(config_file='/kubeconfig/config')
|
||||
api = client.AppsV1Api()
|
||||
namespaces_list = get_namespace()
|
||||
deployments_list = []
|
||||
for namespace in namespaces_list:
|
||||
print(namespace)
|
||||
if verbose : print(namespace)
|
||||
deployments = api.list_namespaced_deployment(namespace)
|
||||
for deployment_index in range(0,len(deployments.items)):
|
||||
deployment = deployments.items[deployment_index].metadata.name
|
||||
print(" "+str(deployment))
|
||||
deployments_list.append([namespace,deployment])
|
||||
replicas = deployments.items[deployment_index].spec.replicas
|
||||
if verbose : print(" "+str(deployment)+" -- Replicas: "+str(replicas))
|
||||
deployments_list.append([namespace,deployment,replicas])
|
||||
return deployments_list
|
||||
@@ -1,9 +1,12 @@
|
||||
from django.contrib import admin
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
from import_export import resources
|
||||
from django.utils.html import format_html
|
||||
from .models import podcastData
|
||||
from core.admin import UniversalModelAdmin
|
||||
|
||||
# Register your models here.
|
||||
@admin.register(podcastData)
|
||||
class JobAdmin(ImportExportModelAdmin):
|
||||
list_display = ('podcast_name','podcast_url','enabled')
|
||||
class PodcastAdmin(UniversalModelAdmin):
|
||||
list_display = ('podcast_name','clickable_links','enabled')
|
||||
|
||||
link_field = 'podcast_url'
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
"""
|
||||
URL configuration for django_code project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/
|
||||
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.urls import path
|
||||
from apps.podcast_aggregator import views as podcast_views
|
||||
|
||||
urlpatterns = [
|
||||
################### cloudmanager ###################
|
||||
path('', podcast_views.execute_podcast),
|
||||
|
||||
]
|
||||
@@ -1,12 +1,11 @@
|
||||
from django.contrib import admin,messages
|
||||
from django.utils.translation import ngettext
|
||||
from prompt_toolkit.shortcuts import print_container
|
||||
from .models import SimpsonsData,simpsons_data_object,urlData
|
||||
from .utils import mark_episode_watched,unwatch_all_episodes,generate_new_urls_for_episode
|
||||
from import_export import resources
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
from django.utils import timezone
|
||||
from djangoql.admin import DjangoQLSearchMixin
|
||||
from prompt_toolkit.shortcuts import print_container
|
||||
from import_export import resources
|
||||
from .models import SimpsonsData,urlData
|
||||
from .utils import mark_episode_watched,unwatch_all_episodes,generate_new_urls_for_episode
|
||||
from core.admin import UniversalModelAdmin
|
||||
|
||||
# Register your models here.
|
||||
|
||||
@@ -64,16 +63,14 @@ def generate_new_urls(modeladmin, request, queryset):
|
||||
|
||||
|
||||
@admin.register(SimpsonsData)
|
||||
class EpisodeAdmin(DjangoQLSearchMixin,ImportExportModelAdmin):
|
||||
class EpisodeAdmin(UniversalModelAdmin):
|
||||
list_display = [field.name for field in SimpsonsData._meta.fields if field.name != 'id']
|
||||
list_display += ['clickable_links']
|
||||
list_filter = ['seen','modified_at']
|
||||
#list_filter = ['seen']
|
||||
fields = ['season', 'episode', 'url', 'seen']
|
||||
actions = [make_seen,make_unseen,unseen_betaserie,generate_new_urls]
|
||||
search_fields = ['season', 'episode', 'url', 'seen']
|
||||
djangoql_completion_enabled_by_default = False
|
||||
|
||||
|
||||
|
||||
def get_queryset(self, request):
|
||||
return super().get_queryset(request).using(DB)
|
||||
@@ -88,7 +85,7 @@ class EpisodeAdmin(DjangoQLSearchMixin,ImportExportModelAdmin):
|
||||
queryset.using(DB).delete()
|
||||
|
||||
@admin.register(urlData)
|
||||
class urldataAdmin(ImportExportModelAdmin):
|
||||
class urldataAdmin(UniversalModelAdmin):
|
||||
list_display = ('url_example', 'prefix', 'infix', 'suffix','addedDate')
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-17 21:26
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('simpsons', '0008_alter_simpsonsdata_modified_at_alter_urldata_infix_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='simpsonsdata',
|
||||
name='modified_at',
|
||||
field=models.DateTimeField(default=datetime.datetime(1969, 12, 31, 23, 0, tzinfo=datetime.timezone.utc)),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
"""
|
||||
URL configuration for django_code project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/
|
||||
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.urls import path
|
||||
from apps.random_simpsons import views as random_simpsons
|
||||
|
||||
urlpatterns = [
|
||||
################### Simpsons ###################
|
||||
path('hello', random_simpsons.hello),
|
||||
path('', random_simpsons.episode_generator),
|
||||
path('download_file/', random_simpsons.download_file),
|
||||
]
|
||||
@@ -22,7 +22,7 @@ def mark_episode_watched(season,episode,action,verbose=False):
|
||||
#mark episode as seen in betaserie
|
||||
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":
|
||||
betaserie.mark_episodes_watched(episode_id)
|
||||
@@ -50,19 +50,15 @@ def generate_new_urls_for_episode(verbose=False):
|
||||
# example
|
||||
# https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=33&episode=18
|
||||
|
||||
simpsons_series_information = betaserie.series_information(simpsons_id)
|
||||
seasons_information = simpsons_series_information[0]
|
||||
seasons_information,maximum_number_season = betaserie.series_information(simpsons_id)
|
||||
|
||||
|
||||
#for the simpsons, there is a season 0 which increase the count of seasons by 1
|
||||
# we need to remove this entry ,
|
||||
# so we cannot trust the maximum_number_season coming from simpsons_series_information
|
||||
|
||||
season_0_to_remove = seasons_information[0]
|
||||
|
||||
if verbose : print(season_0_to_remove)
|
||||
|
||||
seasons_information.remove(season_0_to_remove)
|
||||
maximum_number_season = len(seasons_information)
|
||||
# edit 26/08/2026
|
||||
# I updated the function betaserie.series_information to remove this season 0
|
||||
|
||||
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
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
URL configuration for django_code project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/
|
||||
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.urls import path
|
||||
from apps.stash_management import apps as stashapp
|
||||
from apps.stash_management import views as stashview
|
||||
|
||||
urlpatterns = [
|
||||
################## stash #####
|
||||
path('', stashview.home),
|
||||
path('hello/', stashapp.hello),
|
||||
path('form/', stashapp.form),
|
||||
path('incremental/', stashapp.incremental),
|
||||
path('album/', stashapp.album),
|
||||
path('album-form/', stashapp.album_form, name='submit_form'),
|
||||
path('simple/', stashapp.simple),
|
||||
path('simple-form/', stashapp.simple_form, name='submit_form'),
|
||||
path('submit-form/', stashapp.handle_survey_form, name='submit_form'),
|
||||
path('incremental-form/', stashapp.incremental_form, name='submit_form'),
|
||||
]
|
||||
@@ -0,0 +1,100 @@
|
||||
from django.contrib import admin
|
||||
from django.utils.html import format_html
|
||||
from .models import StreamingSiteTestingData,StreamingRedirectData
|
||||
from .utils import full_testing
|
||||
from apps.website_redirection.utils import redirect_method
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
from core.admin import UniversalModelAdmin
|
||||
|
||||
|
||||
@admin.action(description="Add this show to streaming")
|
||||
def re_redirect(modeladmin, request, queryset):
|
||||
output_generated = ""
|
||||
for query in queryset.values():
|
||||
print(query)
|
||||
key = "streaming"
|
||||
value = query.get('url_display')
|
||||
output_generated = output_generated + redirect_method(key,value)+";"
|
||||
|
||||
modeladmin.message_user(
|
||||
request,
|
||||
output_generated
|
||||
)
|
||||
|
||||
@admin.action(description="check the URLs")
|
||||
def check(modeladmin, request, queryset):
|
||||
for query in queryset:
|
||||
website_url = query.url
|
||||
status=full_testing(website_url)[0]
|
||||
result= full_testing(website_url)[1]
|
||||
print(str(query.url)+": "+str(status)+" -> "+str(result))
|
||||
query.status = status
|
||||
query.result = result
|
||||
query.save(update_fields=["status","result"])
|
||||
|
||||
|
||||
|
||||
@admin.action(description="cleaning the url")
|
||||
def urlcleaning(modeladmin, request, queryset):
|
||||
for query in queryset:
|
||||
# Split the URL into components
|
||||
parsed = urlsplit(query.url)
|
||||
|
||||
# Rebuild using only scheme and netloc, adding a trailing slash at the end
|
||||
base_url = urlunsplit((parsed.scheme, parsed.netloc, "/", "", ""))
|
||||
query.url = base_url
|
||||
query.save(update_fields=["url"])
|
||||
print("Cleaning :"+str(base_url))
|
||||
|
||||
return 0
|
||||
@admin.register(StreamingSiteTestingData)
|
||||
class streamingAdmin(UniversalModelAdmin):
|
||||
list_display = ['clickable_links','result_colored','newstatus']
|
||||
fields = ['url']
|
||||
actions = [check,urlcleaning]
|
||||
|
||||
def result_colored(self, obj):
|
||||
colors = {
|
||||
'REACHABLE': 'green',
|
||||
'VPN REQUIRED': 'yellow',
|
||||
'UNREACHABLE': 'red',
|
||||
}
|
||||
|
||||
return format_html(
|
||||
'<b style="background:{};">{}</b>',
|
||||
colors[obj.result],
|
||||
obj.result,
|
||||
)
|
||||
def newstatus(self, obj):
|
||||
if obj.status != '200':
|
||||
return format_html('<div style="width:100%%; height:100%%; background-color:orange;">{}</div>', obj.status)
|
||||
#return obj.status
|
||||
|
||||
|
||||
|
||||
@admin.register(StreamingRedirectData)
|
||||
class StreamingRedirectAdmin(UniversalModelAdmin):
|
||||
list_display = ['name','image_tag','season','episode','randomViewing','clickable_links','addedDate','alias']
|
||||
actions = [re_redirect]
|
||||
|
||||
#fields = ['name','season','episode','url_example','prefix','infix','suffix','alias','randomViewing','seasonInformation']
|
||||
fieldsets = (
|
||||
(
|
||||
'Serie', {
|
||||
'fields': ('name', 'season', 'episode','randomViewing')
|
||||
}),
|
||||
(
|
||||
'url', {
|
||||
|
||||
'fields': (('prefix','infix','suffix'))
|
||||
}),
|
||||
(
|
||||
'Information', {
|
||||
"classes": ["collapse"],
|
||||
'fields': ('seasonInformation','alias','betaserieShowId','maximumNumberSeason','poster_url')
|
||||
}),
|
||||
)
|
||||
link_field = 'url_display'
|
||||
|
||||
def image_tag(self,obj):
|
||||
return format_html('<img src="{0}" style="width: 355px; height:200px;" />'.format(obj.poster_url))
|
||||
@@ -0,0 +1,7 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class StreamingConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'apps.streaming'
|
||||
label = 'streaming'
|
||||
@@ -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',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -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),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-07 13:13
|
||||
|
||||
import apps.streaming.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0002_streamingdata_result'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='StreamingRedirectData',
|
||||
fields=[
|
||||
('name', models.CharField(help_text='Name of the show', max_length=1000, primary_key=True, serialize=False)),
|
||||
('url_example', models.CharField(help_text='https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=18&episode=5', max_length=1000)),
|
||||
('prefix', models.CharField(blank=True, help_text='https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=', max_length=1000, null=True)),
|
||||
('infix', models.CharField(blank=True, help_text='&episode=', max_length=1000, null=True)),
|
||||
('suffix', models.CharField(blank=True, max_length=1000, null=True)),
|
||||
('addedDate', models.DateField(auto_now_add=True, null=True, verbose_name='Published')),
|
||||
('alias', models.CharField(default=apps.streaming.models.StreamingRedirectData.sanitize, max_length=1000)),
|
||||
],
|
||||
options={
|
||||
'db_table': 'StreamingRedirect',
|
||||
},
|
||||
),
|
||||
]
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-07 14:02
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0003_streamingredirectdata'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='streamingredirectdata',
|
||||
name='episode_to_watch',
|
||||
field=models.IntegerField(default=1),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='streamingredirectdata',
|
||||
name='season_to_watch',
|
||||
field=models.IntegerField(default=1),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='streamingredirectdata',
|
||||
name='alias',
|
||||
field=models.CharField(blank=True, max_length=1000, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-07 14:49
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0004_streamingredirectdata_episode_to_watch_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='streamingredirectdata',
|
||||
name='hello',
|
||||
field=models.CharField(blank=True, max_length=1000, null=True),
|
||||
),
|
||||
]
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-07 14:55
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0005_streamingredirectdata_hello'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='streamingredirectdata',
|
||||
name='hello',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='streamingredirectdata',
|
||||
name='seasonInformation',
|
||||
field=models.JSONField(blank=True, max_length=1000, null=True),
|
||||
),
|
||||
]
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-07 15:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0006_remove_streamingredirectdata_hello_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='streamingData',
|
||||
new_name='StreamingSiteTestingData',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='streamingredirectdata',
|
||||
name='seasonInformation',
|
||||
field=models.JSONField(blank=True, default='', max_length=1000),
|
||||
),
|
||||
]
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-07 15:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0007_rename_streamingdata_streamingsitetestingdata_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='streamingredirectdata',
|
||||
name='randomViewing',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='streamingredirectdata',
|
||||
name='seasonInformation',
|
||||
field=models.JSONField(blank=True, default=dict),
|
||||
),
|
||||
]
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-25 14:06
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0008_streamingredirectdata_randomviewing_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='streamingredirectdata',
|
||||
old_name='episode_to_watch',
|
||||
new_name='episode',
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='streamingredirectdata',
|
||||
old_name='season_to_watch',
|
||||
new_name='season',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-25 14:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0009_rename_episode_to_watch_streamingredirectdata_episode_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='streamingredirectdata',
|
||||
name='episode',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-25 15:13
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0010_alter_streamingredirectdata_episode'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='streamingredirectdata',
|
||||
name='betaserieShowId',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
]
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.30 on 2026-08-25 15:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0011_streamingredirectdata_betaserieshowid'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='streamingredirectdata',
|
||||
name='betaserieShowId',
|
||||
field=models.IntegerField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
+18
@@ -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),
|
||||
),
|
||||
]
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-04 14:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0013_streamingredirectdata_maximumnumberseason'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='streamingredirectdata',
|
||||
name='url_example',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='streamingredirectdata',
|
||||
name='url_display',
|
||||
field=models.CharField(blank=True, help_text='https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=18&episode=5', max_length=1000, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.30 on 2026-09-17 21:26
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('streaming', '0014_remove_streamingredirectdata_url_example_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='streamingredirectdata',
|
||||
name='poster_url',
|
||||
field=models.CharField(blank=True, help_text='poster URL', max_length=1000, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,80 @@
|
||||
from django.db import models
|
||||
from apps.betaserie.utils import betaserieUtils
|
||||
|
||||
from django_code.core.settings import ENVIRONMENT
|
||||
|
||||
|
||||
# Create your models here.
|
||||
class StreamingSiteTestingData(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'
|
||||
|
||||
|
||||
|
||||
|
||||
class StreamingRedirectData(models.Model):
|
||||
name = models.CharField(primary_key=True,max_length=1000, help_text="Name of the show")
|
||||
season = models.IntegerField(null=False,default=1)
|
||||
episode = models.IntegerField(null=False,default=0)
|
||||
url_display = models.CharField(max_length=1000, help_text="https://streaming.geeraert.eu/office",blank=True, null=True)
|
||||
prefix = models.CharField(max_length=1000, help_text="https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=",blank=True, null=True)
|
||||
infix = models.CharField(max_length=1000, help_text="&episode=",blank=True, null=True)
|
||||
suffix = models.CharField(max_length=1000, help_text="" ,blank=True, null=True)
|
||||
addedDate = models.DateField('Published', blank=True, null=True, auto_now_add=True)
|
||||
alias = models.CharField(max_length=1000, null=True,blank=True)
|
||||
seasonInformation = models.JSONField(default=dict, blank=True)
|
||||
betaserieShowId = models.IntegerField(null=True,blank=True)
|
||||
maximumNumberSeason = models.IntegerField(null=True,blank=True)
|
||||
randomViewing = models.BooleanField(default=False)
|
||||
poster_url = models.CharField(max_length=1000, help_text="poster URL",blank=True, null=True)
|
||||
|
||||
def sanitize(self, name):
|
||||
return name.replace(" ", "").lower()
|
||||
|
||||
def season_information(self, serie_name):
|
||||
betaserie = betaserieUtils()
|
||||
return betaserie.series_information(betaserie.identify_serie(serie_name))[0]
|
||||
|
||||
def maximum_Number_Season(self, serie_name):
|
||||
betaserie = betaserieUtils()
|
||||
return betaserie.series_information(betaserie.identify_serie(serie_name))[1]
|
||||
|
||||
def betaserie_show_id(self,serie_name):
|
||||
betaserie = betaserieUtils()
|
||||
return betaserie.identify_serie(serie_name)
|
||||
|
||||
def betaserie_poster_url(self,serie_name):
|
||||
betaserie = betaserieUtils()
|
||||
return betaserie.poster_serie(serie_name)
|
||||
|
||||
def url_display_set(self,alias):
|
||||
if ENVIRONMENT == "PRODUCTION":
|
||||
url = "https://streaming.geeraert.eu/"
|
||||
else:
|
||||
url = "https://streaming-testing.geeraert.eu/"
|
||||
|
||||
return url+alias
|
||||
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.seasonInformation :
|
||||
self.seasonInformation = self.season_information(self.name)
|
||||
if not self.alias:
|
||||
self.alias = self.sanitize(self.name)
|
||||
if not self.betaserieShowId:
|
||||
self.betaserieShowId = self.betaserie_show_id(self.name)
|
||||
if not self.maximumNumberSeason:
|
||||
self.maximumNumberSeason = self.maximum_Number_Season(self.name)
|
||||
if not self.url_display:
|
||||
self.url_display = self.url_display_set(self.alias)
|
||||
if not self.poster_url:
|
||||
self.poster_url = self.betaserie_poster_url(self.name)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
db_table = 'StreamingRedirect'
|
||||
@@ -0,0 +1,24 @@
|
||||
"""
|
||||
URL configuration for django_code project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/
|
||||
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.urls import path
|
||||
from apps.streaming import views as streaming_views
|
||||
|
||||
urlpatterns = [
|
||||
################### streaming ###################
|
||||
path('<str:alias>', streaming_views.streamingRedirect),
|
||||
]
|
||||
@@ -0,0 +1,67 @@
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from apps.betaserie.utils import betaserieUtils
|
||||
import random
|
||||
|
||||
def full_testing(url_website):
|
||||
status = "unknown"
|
||||
|
||||
#step 1 : test without VPN
|
||||
status = test_website(url_website)
|
||||
|
||||
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,result
|
||||
|
||||
|
||||
def test_website(url_website,bool_proxy=False):
|
||||
try:
|
||||
if bool_proxy:
|
||||
status = requests.get(url_website,proxies=settings.PROXIES).status_code
|
||||
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
|
||||
|
||||
|
||||
def randomEpisode(seasonInformation,maximum_number_of_seasons):
|
||||
random_season = random.randint(1, maximum_number_of_seasons)
|
||||
print("random season: " + str(random_season))
|
||||
|
||||
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
|
||||
#check if the episode is the last one of the season
|
||||
if (episode < seasonInformation[season-1]['episodes']):
|
||||
#the current episode is not the last one of the season
|
||||
episode += 1
|
||||
|
||||
#check if the season is the last one
|
||||
elif((season) < maximum_number_seasons):
|
||||
season += 1
|
||||
episode = 1
|
||||
else:
|
||||
print("You watched the last episode of the serie")
|
||||
lastEpisode = True
|
||||
return season,episode,lastEpisode
|
||||
@@ -0,0 +1,87 @@
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import redirect
|
||||
from six import print_
|
||||
from .models import StreamingRedirectData
|
||||
from .utils import randomEpisode,followingEpisode
|
||||
from apps.betaserie.utils import betaserieUtils
|
||||
|
||||
|
||||
betaserie = betaserieUtils()
|
||||
|
||||
|
||||
# Create your views here.
|
||||
def hello(request):
|
||||
return HttpResponse('<h1>Hello streaming view!</h1>')
|
||||
|
||||
|
||||
def streamingRedirect(request,alias):
|
||||
#sanitize
|
||||
alias = alias.lower()
|
||||
|
||||
streaming_object = StreamingRedirectData.objects.filter(alias=alias)
|
||||
|
||||
episode = streaming_object.values('episode')[0]['episode']
|
||||
season = streaming_object.values('season')[0]['season']
|
||||
seasonInformation = streaming_object.values('seasonInformation')[0]['seasonInformation']
|
||||
maximumNumberSeason = streaming_object.values('maximumNumberSeason')[0]['maximumNumberSeason']
|
||||
|
||||
|
||||
url_prefix = streaming_object.values('prefix')[0]['prefix']
|
||||
url_infix = streaming_object.values('infix')[0]['infix']
|
||||
url_suffix = streaming_object.values('suffix')[0]['suffix'] or ''
|
||||
|
||||
betaserieShowId = streaming_object.values('betaserieShowId')[0]['betaserieShowId']
|
||||
|
||||
print("Last episode seen:")
|
||||
print("Season: "+str(season))
|
||||
print("Episode: "+str(episode))
|
||||
|
||||
|
||||
print(seasonInformation)
|
||||
|
||||
|
||||
randomViewing = streaming_object.values('randomViewing')[0]['randomViewing']
|
||||
print("randomViewing: "+str(randomViewing))
|
||||
|
||||
if (randomViewing == True):
|
||||
print('show set to random')
|
||||
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:
|
||||
print('show set to following episode')
|
||||
season,episode,lastEpisode = followingEpisode(season,episode,seasonInformation,maximumNumberSeason)
|
||||
if (lastEpisode):
|
||||
return HttpResponse('<h1>You already watched the last episode of the serie!</h1>')
|
||||
|
||||
print(season)
|
||||
print(episode)
|
||||
|
||||
|
||||
url_generated = str(url_prefix)+str(season)+str(url_infix)+str(episode)+str(url_suffix)
|
||||
print(url_generated)
|
||||
|
||||
|
||||
#append the data into the model
|
||||
StreamingRedirectData.objects.filter(alias=alias).update(season=season,episode=episode)
|
||||
|
||||
#### mark as view in betaserie
|
||||
|
||||
#mark episode as seen in betaserie
|
||||
episode_number = "S"+str(season)+"E"+str(episode)
|
||||
|
||||
episode_id,episode_seen = betaserie.identify_episode(betaserieShowId,episode_number)
|
||||
|
||||
betaserie.mark_episodes_watched(episode_id)
|
||||
|
||||
return redirect(str(url_generated))
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.contrib import admin
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
from .models import TelegramData
|
||||
from .utils import telegramUtils
|
||||
from core.admin import UniversalModelAdmin
|
||||
|
||||
@admin.action(description="Clear all expired messages")
|
||||
def messages_cleaning(modeladmin, request, queryset):
|
||||
@@ -10,7 +10,7 @@ def messages_cleaning(modeladmin, request, queryset):
|
||||
|
||||
# Register your models here.
|
||||
@admin.register(TelegramData)
|
||||
class JobAdmin(ImportExportModelAdmin):
|
||||
class JobAdmin(UniversalModelAdmin):
|
||||
list_display = ('message_id','chat_id','description','creation_date','expiration_date')
|
||||
actions = [messages_cleaning]
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.contrib import admin
|
||||
from .models import redirectData
|
||||
from .models import historicalData,redirectData
|
||||
from .utils import redirect_method
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
from core.admin import UniversalModelAdmin
|
||||
|
||||
# Register your models here.
|
||||
|
||||
@@ -18,8 +18,14 @@ def re_redirect(modeladmin, request, queryset):
|
||||
request,
|
||||
output_generated
|
||||
)
|
||||
@admin.register(historicalData)
|
||||
class historicalAdmin(UniversalModelAdmin):
|
||||
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]
|
||||
|
||||
@admin.register(redirectData)
|
||||
class redirectAdmin(ImportExportModelAdmin):
|
||||
class redirectAdmin(UniversalModelAdmin):
|
||||
list_display = [field.name for field in redirectData._meta.fields if field.name != 'id']
|
||||
actions = [re_redirect]
|
||||
list_display += ['clickable_links']
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import redis
|
||||
#import redis
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 4.2.30 on 2026-07-28 09:11
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('redirect', '0003_redirectdata_key'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='redirectData',
|
||||
new_name='historicalData',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.30 on 2026-07-28 09:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('redirect', '0004_rename_redirectdata_historicaldata'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='historicaldata',
|
||||
name='seenDate',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='Seen'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 4.2.30 on 2026-07-28 09:15
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('redirect', '0005_alter_historicaldata_seendate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelTable(
|
||||
name='historicaldata',
|
||||
table='historical',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 4.2.30 on 2026-07-28 09:17
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('redirect', '0006_alter_historicaldata_table'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='redirectData',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('key', models.CharField(default='streaming', max_length=1000)),
|
||||
('url', models.CharField(max_length=1000)),
|
||||
],
|
||||
options={
|
||||
'db_table': 'redirect',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,10 +1,17 @@
|
||||
from django.db import models
|
||||
from django.contrib import admin
|
||||
|
||||
class redirectData(models.Model):
|
||||
class historicalData(models.Model):
|
||||
url = models.CharField(max_length=1000)
|
||||
key = models.CharField(max_length=1000,default="streaming")
|
||||
addedDate = models.DateField('Published', blank=True, null=True, auto_now_add=True)
|
||||
seenDate = models.DateField('Published', blank=True, null=True)
|
||||
seenDate = models.DateField('Seen', blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'historical'
|
||||
|
||||
class redirectData(models.Model):
|
||||
key = models.CharField(max_length=1000,default="streaming")
|
||||
url = models.CharField(max_length=1000)
|
||||
class Meta:
|
||||
db_table = 'redirect'
|
||||
|
||||
@@ -14,12 +14,10 @@ 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 apps.website_redirection import views as website_redirectionapp
|
||||
|
||||
urlpatterns = [
|
||||
# path('admin/', admin.site.urls),
|
||||
|
||||
################### Redirect ###################
|
||||
path('', website_redirectionapp.redirect),
|
||||
@@ -30,6 +28,4 @@ urlpatterns = [
|
||||
path('redirect-form/', website_redirectionapp.redirect_process, name='submit_form'),
|
||||
path('clearkey/', website_redirectionapp.clearkey_process, name='submit_form'),
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import redis
|
||||
from .models import redirectData
|
||||
from .models import historicalData,redirectData
|
||||
|
||||
r = redis.Redis(
|
||||
host='django-redis-svc',
|
||||
port=6379,
|
||||
db=0 # The default Redis database index
|
||||
)
|
||||
|
||||
def redirect_method(key,value):
|
||||
key = key.lower()
|
||||
|
||||
r.set(key, value)
|
||||
redirectData.objects.create(url=value,key=key)
|
||||
|
||||
#Add to the redirect database to be used as a redirection point
|
||||
# using update_or_create so there is no duplicate of one index/key
|
||||
redirectData.objects.update_or_create(key=key,defaults={'url': value})
|
||||
|
||||
#Add to the historical database
|
||||
historicalData.objects.create(url=value, key=key)
|
||||
|
||||
text_generated = "successfully set "+value+" to "+key
|
||||
return text_generated
|
||||
@@ -2,22 +2,15 @@ from django.shortcuts import render
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.apps import AppConfig
|
||||
from .models import redirectData
|
||||
from .models import historicalData,redirectData
|
||||
from .utils import redirect_method
|
||||
import redis
|
||||
|
||||
|
||||
|
||||
def hello(request):
|
||||
return HttpResponse('<h1>Hello Django!</h1>')
|
||||
|
||||
|
||||
|
||||
r = redis.Redis(
|
||||
host='django-redis-svc',
|
||||
port=6379,
|
||||
db=0 # The default Redis database index
|
||||
)
|
||||
|
||||
def hello(request):
|
||||
return HttpResponse('<h1>Hello redirect!</h1>')
|
||||
|
||||
@@ -27,8 +20,11 @@ def redirect(request):
|
||||
|
||||
def clearkey_process(request):
|
||||
key = request.GET.get('key')
|
||||
r.delete(key)
|
||||
return 0
|
||||
key = key.lower()
|
||||
redirectData.objects.update_or_create(key=key,defaults={'url': "None"})
|
||||
|
||||
text_generated = key+" is set to None"
|
||||
return HttpResponse(text_generated, content_type="text/plain")
|
||||
|
||||
def redirect_process(request):
|
||||
key = request.GET.get('key')
|
||||
@@ -39,22 +35,24 @@ def redirect_process(request):
|
||||
return HttpResponse(text_generated, content_type="text/plain")
|
||||
|
||||
def display_key(request,key):
|
||||
value = r.get(key)
|
||||
value = redirectData.objects.filter(key=key).values('url')[0]['url']
|
||||
value_extracted = str(value.decode())
|
||||
text_generated = key+" is set to "+value_extracted
|
||||
return HttpResponse(text_generated, content_type="text/plain")
|
||||
|
||||
|
||||
def redirect_to_key(request,key):
|
||||
value = r.get(key)
|
||||
if value == None:
|
||||
icon_url = r.get('icon')
|
||||
if icon_url == None:
|
||||
icon_url = "https://cdn-icons-png.flaticon.com/512/6402/6402576.png"
|
||||
redirect_object = redirectData.objects.filter(key=key)
|
||||
value = str(redirect_object.values('url')[0]['url'])
|
||||
|
||||
if value == "None":
|
||||
#get the icon url, if it doesn't exist , create it with a default icon
|
||||
icon_url = redirectData.objects.get_or_create(key="icon",defaults={'url':"https://cdn-icons-png.flaticon.com/512/6402/6402576.png"})[0].url
|
||||
|
||||
print(key+" is not setup, displaying default page")
|
||||
return render(request, 'website_redirection/blank_page.html', {'title': key,'icon_url':icon_url})
|
||||
else:
|
||||
value_extracted = str(value.decode('utf-8'))
|
||||
value_extracted = str(value)
|
||||
print(key+" is setup to : "+value_extracted)
|
||||
print(value_extracted)
|
||||
return HttpResponseRedirect(value_extracted)
|
||||
@@ -0,0 +1,20 @@
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
from admin_extra_buttons.api import ExtraButtonsMixin
|
||||
from django.contrib import admin
|
||||
from djangoql.admin import DjangoQLSearchMixin
|
||||
from django.utils.html import format_html
|
||||
|
||||
class UniversalModelAdmin(DjangoQLSearchMixin,ImportExportModelAdmin,ExtraButtonsMixin,admin.ModelAdmin):
|
||||
djangoql_completion_enabled_by_default = True
|
||||
|
||||
#Add search fields if you want to have the toggle on/off
|
||||
# example:
|
||||
# search_fields = ['season', 'episode', 'url', 'seen']
|
||||
|
||||
link_field = 'url'
|
||||
|
||||
|
||||
def clickable_links(self, obj):
|
||||
url = getattr(obj, self.link_field, None)
|
||||
return format_html('<a href="{}">{}</a>', url,url)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
from django.conf import settings
|
||||
from django_hosts import patterns, host
|
||||
|
||||
#ADMIN
|
||||
# redirect
|
||||
# streaming
|
||||
# cloudmanager
|
||||
# stash
|
||||
# podcast
|
||||
# simpsons
|
||||
|
||||
host_patterns = patterns('',
|
||||
host(r"admin-testing", settings.ROOT_URLCONF, name="admin"),
|
||||
host(r"redirect-testing", 'apps.website_redirection.urls', name="redirect"),
|
||||
host(r"streaming-testing", 'apps.streaming.urls', name="streaming"),
|
||||
host(r"stash-testing", 'apps.stash_management.urls', name="stash"),
|
||||
host(r"podcast-testing", 'apps.podcast_aggregator.urls', name="podcast"),
|
||||
host(r"simpsons-testing", 'apps.random_simpsons.urls', name="simpsons"),
|
||||
host(r"kubernetes-testing", 'apps.kubernetes_connection.urls', name="kubernetes"),
|
||||
host(r"cloudmanager-testing", 'apps.cloudmanager.urls', name="cloudmanager"),
|
||||
)
|
||||
@@ -1,10 +1,21 @@
|
||||
from django.conf import settings
|
||||
from django_hosts import patterns, host
|
||||
|
||||
#ADMIN
|
||||
# redirect
|
||||
# streaming
|
||||
# cloudmanager
|
||||
# stash
|
||||
# podcast
|
||||
# simpsons
|
||||
|
||||
host_patterns = patterns('',
|
||||
host(r"django-testing", settings.ROOT_URLCONF, name="django-testing"),
|
||||
host(r"admin", settings.ROOT_URLCONF, name="admin"),
|
||||
host(r"redirect", 'apps.website_redirection.urls', name="redirect"),
|
||||
host(r"redirect-testing", 'apps.website_redirection.urls', name="redirect-testing"),
|
||||
host(r"job", 'apps.job_dashboard.urls', name="job_dashboard"),
|
||||
host(r"job-testing", 'apps.job_dashboard.urls', name="job_dashboard-testing"),
|
||||
host(r"streaming", 'apps.streaming.urls', name="streaming"),
|
||||
host(r"stash", 'apps.stash_management.urls', name="stash"),
|
||||
host(r"podcast", 'apps.podcast_aggregator.urls', name="podcast"),
|
||||
host(r"simpsons", 'apps.random_simpsons.urls', name="simpsons"),
|
||||
host(r"kubernetes", 'apps.kubernetes_connection.urls', name="kubernetes"),
|
||||
host(r"cloudmanager", 'apps.cloudmanager.urls', name="cloudmanager"),
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -49,8 +50,13 @@ INSTALLED_APPS = [
|
||||
'apps.job_dashboard.apps.JobDashboardConfig',
|
||||
'apps.telegram_communication.apps.TelegramCommunicationConfig',
|
||||
'apps.podcast_aggregator.apps.PodcastAggregatorConfig',
|
||||
'apps.streaming.apps.StreamingConfig',
|
||||
'import_export',
|
||||
'djangoql',
|
||||
'admin_extra_buttons',
|
||||
'rest_framework',
|
||||
'rest_framework.authtoken',
|
||||
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
@@ -67,8 +73,14 @@ MIDDLEWARE = [
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'core.urls'
|
||||
|
||||
ENVIRONMENT = os.getenv("ENVIRONMENT","TESTING")
|
||||
if ENVIRONMENT == "PRODUCTION":
|
||||
ROOT_HOSTCONF = 'core.hosts'
|
||||
DEFAULT_HOST = 'django-testing'
|
||||
else:
|
||||
ROOT_HOSTCONF = 'core.hosts-testing'
|
||||
|
||||
DEFAULT_HOST = 'admin'
|
||||
|
||||
|
||||
TEMPLATES = [
|
||||
@@ -153,6 +165,15 @@ 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 = []
|
||||
@@ -181,7 +202,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
TIME_ZONE = 'Europe/London'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
@@ -214,3 +235,24 @@ 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
|
||||
}
|
||||
|
||||
|
||||
@@ -16,82 +16,7 @@ Including another URLconf
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
#from apps.cloudmanager import (credentials,db_interaction)
|
||||
from apps.cloudmanager import apps as cloudmanager_apps
|
||||
from apps.cloudmanager import views as cloudmanager_views
|
||||
from apps.random_simpsons import views as random_simpsons
|
||||
from apps.dashboard import apps as dashboardapp
|
||||
from apps.dashboard import views as dashboardview
|
||||
from apps.kubernetes_connection import apps as kubernetes_connection
|
||||
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
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
|
||||
################### Simpsons ###################
|
||||
path('hello/', random_simpsons.hello),
|
||||
path('simpsons/', random_simpsons.episode_generator),
|
||||
path('download_file/', random_simpsons.download_file),
|
||||
|
||||
################### Redirect ###################
|
||||
path('redirect/hello/', website_redirectionapp.hello),
|
||||
path('redirect/set/', website_redirectionapp.redirect),
|
||||
path('redirect/get/<str:key>', website_redirectionapp.display_key),
|
||||
path('redirect/go/<str:key>', website_redirectionapp.redirect_to_key),
|
||||
path('redirect/redirect-form/', website_redirectionapp.redirect_process, name='submit_form'),
|
||||
path('redirect/clearkey/', website_redirectionapp.clearkey_process, name='submit_form'),
|
||||
|
||||
################### onenote ###################
|
||||
path('dashboard/hello/', dashboardapp.hello),
|
||||
path('dashboard/view/about', dashboardview.about),
|
||||
path('dashboard/view/home', dashboardview.home),
|
||||
path('dashboard/view/success', dashboardview.success),
|
||||
path('dashboard/scale_up/<str:namespace_name>/<str:deploy_name>', dashboardview.scale_up),
|
||||
path('dashboard/scale_down/<str:namespace_name>/<str:deploy_name>', dashboardview.scale_down),
|
||||
|
||||
|
||||
|
||||
################## kubernetes_connection#####
|
||||
path('kubernetes_connection/hello/', kubernetes_connection.hello),
|
||||
path('kubernetes_connection/nodes/', kubernetes_connection.nodes),
|
||||
path('kubernetes_connection/backup_job/', kubernetes_connection.backup_job),
|
||||
path('kubernetes_connection/backup_job_yaml/', kubernetes_connection.backup_job_yaml),
|
||||
path('kubernetes_connection/scale_up/<str:namespace_name>/<str:deploy_name>', kubernetes_connection.scale_up),
|
||||
path('kubernetes_connection/scale_down/<str:namespace_name>/<str:deploy_name>', kubernetes_connection.scale_down),
|
||||
|
||||
################## stash#####
|
||||
path('stash/', stashview.home),
|
||||
path('stash/hello/', stashapp.hello),
|
||||
path('stash/form/', stashapp.form),
|
||||
path('stash/incremental/', stashapp.incremental),
|
||||
path('stash/album/', stashapp.album),
|
||||
path('stash/album-form/', stashapp.album_form, name='submit_form'),
|
||||
path('stash/simple/', stashapp.simple),
|
||||
path('stash/simple-form/', stashapp.simple_form, name='submit_form'),
|
||||
path('stash/submit-form/', stashapp.handle_survey_form, name='submit_form'),
|
||||
path('stash/incremental-form/', stashapp.incremental_form, name='submit_form'),
|
||||
|
||||
# path('bookstack/', docker_connection.apps.hello),
|
||||
# path('test/', docker_connection.apps.http_call_test),
|
||||
# path('proxmox/', docker_connection.apps.proxmox),
|
||||
# path('simpsons/', random_simpsons.hello),
|
||||
# path('docker/<str:action>/<str:id_docker>', docker_connection.apps.docker_call),
|
||||
|
||||
################### cloudmanager ###################
|
||||
path('cmm/', cloudmanager_apps.redirect),
|
||||
path('cmm/hello', cloudmanager_apps.hello, name='hello'),
|
||||
path('cmm/coucou', cloudmanager_views.coucou, name='coucou'),
|
||||
path('cmm/display', cloudmanager_views.display, name='display'),
|
||||
#path('cmm/run-action/', cloudmanager_views.trigger_my_action, name='run_my_action_url'),
|
||||
#path('change-schedule/', cloudmanager_views.change_schedule, name='change_schedule'),
|
||||
#path('cmm/main/', db_interaction.main),
|
||||
|
||||
################### cloudmanager ###################
|
||||
path('podcast/', podcast_views.execute_podcast),
|
||||
|
||||
|
||||
path('', admin.site.urls)
|
||||
]
|
||||
|
||||
@@ -111,7 +111,7 @@ body {
|
||||
<div class="modal-dialog modal-confirm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<div class="icon-box" onclick="window.location='/kubernetes_connection/scale_up/{{namespace}}/{{deployment}}';">
|
||||
<div class="icon-box" onclick="window.location='/scale_up/{{namespace}}/{{deployment}}';">
|
||||
<!--<i class="material-icons"></i>-->
|
||||
<i class="material-icons">×</i>
|
||||
</div>
|
||||
|
||||
@@ -109,7 +109,7 @@ body {
|
||||
<div class="modal-dialog modal-confirm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<div class="icon-box" onclick="window.location='/kubernetes_connection/scale_down/{{namespace}}/{{deployment}}';">
|
||||
<div class="icon-box" onclick="window.location='/scale_down/{{namespace}}/{{deployment}}';">
|
||||
<!--<i class="material-icons"></i>-->
|
||||
<i class="material-icons"></i>
|
||||
</div>
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
<h1 id="title">Stash Form</h1>
|
||||
<p id="description" class="description" class="text-center">Download form</p>
|
||||
</div>
|
||||
<form method="GET" action="/stash/album-form/" id="survey-form" name="survey-form">
|
||||
<form method="GET" action="/album-form/" id="survey-form" name="survey-form">
|
||||
|
||||
<fieldset>
|
||||
<label for="name" id="name-label">
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
<h1 id="title">Incremental Form</h1>
|
||||
<p id="description" class="description" class="text-center">Download form</p>
|
||||
</div>
|
||||
<form method="GET" action="/stash/incremental-form/" id="survey-form" name="survey-form">
|
||||
<form method="GET" action="/incremental-form/" id="survey-form" name="survey-form">
|
||||
|
||||
<fieldset>
|
||||
<label for="name" id="name-label">
|
||||
|
||||
@@ -10852,7 +10852,7 @@
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">Technologies</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<li><a class="dropdown-item" href="/stash/incremental/">Incremental</a></li>
|
||||
<li><a class="dropdown-item" href="/incremental/">Incremental</a></li>
|
||||
<li><hr class="dropdown-divider" /></li>
|
||||
<li><a class="dropdown-item" href="#!">Album</a></li>
|
||||
</ul>
|
||||
@@ -10887,7 +10887,7 @@
|
||||
</div>
|
||||
<!-- Product actions-->
|
||||
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent">
|
||||
<div class="text-center"><a class="btn btn-outline-dark mt-auto" href="/stash/incremental/">Visit</a></div>
|
||||
<div class="text-center"><a class="btn btn-outline-dark mt-auto" href="/incremental/">Visit</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -10908,7 +10908,7 @@
|
||||
</div>
|
||||
<!-- Product actions-->
|
||||
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent">
|
||||
<div class="text-center"><a class="btn btn-outline-dark mt-auto" href="/stash/incremental/">Visit</a></div>
|
||||
<div class="text-center"><a class="btn btn-outline-dark mt-auto" href="/incremental/">Visit</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -10928,7 +10928,7 @@
|
||||
</div>
|
||||
<!-- Product actions-->
|
||||
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent">
|
||||
<div class="text-center"><a class="btn btn-outline-dark mt-auto" href="/stash/album/">Visit</a></div>
|
||||
<div class="text-center"><a class="btn btn-outline-dark mt-auto" href="/album/">Visit</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -10975,7 +10975,7 @@
|
||||
</div>
|
||||
<!-- Product actions-->
|
||||
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent">
|
||||
<div class="text-center"><a class="btn btn-outline-dark mt-auto" href="/stash/simple">Visit</a></div>
|
||||
<div class="text-center"><a class="btn btn-outline-dark mt-auto" href="/simple">Visit</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
<h1 id="title">Stash Form</h1>
|
||||
<p id="description" class="description" class="text-center">Download form</p>
|
||||
</div>
|
||||
<form method="GET" action="/stash/simple-form/" id="survey-form" name="survey-form">
|
||||
<form method="GET" action="/simple-form/" id="survey-form" name="survey-form">
|
||||
|
||||
<fieldset>
|
||||
<label for="name" id="name-label">
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
<h1 id="title">Stash Form</h1>
|
||||
<p id="description" class="description" class="text-center">Download form</p>
|
||||
</div>
|
||||
<form method="GET" action="/stash/submit-form/" id="survey-form" name="survey-form">
|
||||
<form method="GET" action="/submit-form/" id="survey-form" name="survey-form">
|
||||
|
||||
<fieldset>
|
||||
<label for="name" id="name-label">
|
||||
|
||||
@@ -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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user