172 Commits
Author SHA1 Message Date
pierre geeraert 3ff4f98841 fixed
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 3s
2026-10-13 23:50:43 +01:00
pi-ux-ce 0a8c337b1e Merge pull request 'Testing' (#51) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Failing after 3m38s
Reviewed-on: #51
2026-10-13 22:49:30 +00:00
pierre geeraert 2dac0d1f53 remove tryton reference 2026-10-13 23:48:38 +01:00
pierre geeraert 73b627214d remove tryton reference
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 3s
2026-10-13 23:46:42 +01:00
pierre geeraert c79168453b remove tryton reference
Dockerfile testing runner / Explore-Gitea-Actions (push) Failing after 3m17s
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 4s
2026-10-13 23:46:13 +01:00
pi-ux-ce 299f72abca remove gitea.tryton reference
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 4s
2026-10-13 20:35:52 +00:00
pi-ux-ce 058125f0b1 Merge pull request 'Testing' (#50) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 6m23s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/50
2026-10-03 22:28:35 +00:00
pierre geeraert 130b0af8d8 redirect to streaming
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-10-03 23:17:27 +01:00
pierre geeraert 6f7542ef27 change image format
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-10-03 22:01:02 +01:00
pierre geeraert 919d1a3a28 lowercase the alias as well
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 9s
2026-10-03 21:43:09 +01:00
pierre geeraert 3c4c32e72d lowercase the sanitized name 2026-10-03 21:25:11 +01:00
pierre.geeraert 3294e70b3f add rest framework authentication
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-22 10:01:09 +01:00
pierre.geeraert 5908d8d282 views to add or delete ingress for terraform
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-21 22:27:22 +01:00
pierre.geeraert 32f8251a90 enable ingress module
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-21 17:34:07 +01:00
pierre geeraert a3fec86eae increase size poster
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-17 22:49:47 +01:00
pi-ux-ce 672edccd70 Merge pull request 'poster integration' (#48) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 2m0s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/48
2026-09-17 21:44:13 +00:00
pierre geeraert f188e25453 add poster function
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-09-17 22:33:11 +01:00
pierre.geeraert d4a72ebf5d we can have logos
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-16 14:38:11 +01:00
pierre.geeraert 4492db4185 cleanup
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-16 13:23:41 +01:00
pierre.geeraert 015edcd63d universal method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-16 11:25:36 +01:00
pierre.geeraert aaad6b2b7e add exmaple
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-15 18:23:16 +01:00
pierre.geeraert 3b6eccba80 create universal admin class
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-15 18:22:03 +01:00
pi-ux-ce 44b730dbfc Merge pull request 'more pretty' (#47) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 48s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/47
2026-09-15 10:40:20 +00:00
pierre.geeraert ea4ebb0de0 more pretty
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-15 11:39:05 +01:00
pi-ux-ce 3b3e82f16a Merge pull request 'change timezone to London' (#46) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 44s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/46
2026-09-15 10:25:57 +00:00
pierre.geeraert 1430afe600 change timezone to London
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-15 11:03:48 +01:00
pi-ux-ce e3f01da175 Merge pull request 'freeze period in place' (#45) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 42s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/45
2026-09-14 15:50:44 +00:00
pierre.geeraert 7a5c7b6de9 use ELIF as otherwise the else is ignored
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-14 16:32:37 +01:00
pierre.geeraert c880172aa5 use function for default
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-14 16:15:03 +01:00
pierre.geeraert 6b631fb3e3 this was supposed to be deleted
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-14 16:12:33 +01:00
pierre.geeraert 712f3d50b5 add back timezone as it was required
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-09-14 15:46:51 +01:00
pierre.geeraert f6875b498b add back timezone as it was required
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-14 15:42:15 +01:00
pierre.geeraert 2e728d4698 add migration file
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-14 15:36:29 +01:00
pierre.geeraert 98a969fa04 remove old imports
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-14 15:34:28 +01:00
pierre.geeraert 154717aca7 should be good
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-14 15:22:13 +01:00
pierre.geeraert cc0eb74090 add the time test
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-14 15:09:16 +01:00
pierre.geeraert e2f49a5b1f untested addition of the condition and scale up and down function
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-14 10:44:41 +01:00
pierre geeraert c8ceaab950 untested bit of code
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-13 16:46:33 +01:00
pierre geeraert 3fbf333d3d ordering by name 2026-09-13 16:31:42 +01:00
pi-ux-ce 3cb09b34da Merge pull request 'add import export' (#44) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 44s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/44
2026-09-11 10:27:24 +00:00
pierre.geeraert 1d9d723ce9 add favicon
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-11 11:02:52 +01:00
pierre.geeraert cf06bfd1bd add import export
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-11 10:53:19 +01:00
pi-ux-ce df7340e578 Merge pull request 'Testing' (#43) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 2m39s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/43
2026-09-11 09:23:12 +00:00
pierre.geeraert 7a02fb89f4 remove django_q
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-11 09:41:24 +01:00
pierre geeraert bfdf8b3b2a stringify
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 22:28:42 +01:00
pierre geeraert 1ae2917263 stringify
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 22:26:25 +01:00
pierre geeraert 1fea1c9e23 add the view
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 7s
2026-09-10 22:24:25 +01:00
pierre geeraert fa804dbed1 add the view
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 22:24:12 +01:00
pierre geeraert 3b28145d0a add the view
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 22:22:10 +01:00
pierre geeraert e9bf6ba7b5 The view apps.cloudmanager.views.import_namespace_view didn't return an HttpResponse object. It returned None instead.
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 21:38:00 +01:00
pierre geeraert cc3394d5eb change the way it work to fix import_namespace() takes 0 positional arguments but 1 was given
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 21:36:02 +01:00
pierre geeraert 90156a4733 enable import namespace from web
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 21:31:10 +01:00
pierre.geeraert 314a6f1bed trying to avoid sidecontainer
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 13:21:33 +01:00
pierre.geeraert eab0ddd697 fix shit
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 11:05:40 +01:00
pierre.geeraert 3c1960f015 clean cloudmanager
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 10:45:45 +01:00
pierre.geeraert 3ff4dd1fae clean cloudmanager
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-10 10:41:29 +01:00
pierre.geeraert dbeaf4c58c remove the dashboard part of cloudmanager
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-10 10:34:39 +01:00
pierre geeraert 0f49484a43 add extra button admin
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 20:59:44 +01:00
pierre geeraert b540c7b7e8 add extra button admin 2026-09-09 20:59:18 +01:00
pierre.geeraert 1012ea31ad testing django_q2
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 17:09:15 +01:00
pierre.geeraert a00baa490f try django-q
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 15:18:00 +01:00
pierre.geeraert bc9e331c68 set always off if the replica was already 0
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 14:46:02 +01:00
pi-ux-ce 57f58b0c9a Merge pull request 'Testing' (#42) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 57s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/42
2026-09-09 13:40:43 +00:00
pierre.geeraert 496a6bd940 verbose everywhere
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-09-09 14:34:14 +01:00
pierre.geeraert 2bbdad3e47 verbose everywhere
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 14:26:50 +01:00
pierre.geeraert 91e0c992ec verbose everywhere 2026-09-09 14:26:01 +01:00
pierre.geeraert 860de928ba verbose everywhere
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-09-09 14:25:05 +01:00
pierre.geeraert 9d82d61993 add the check to avoid making the operations for everyone
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-09 14:17:37 +01:00
pierre.geeraert 294af1945d add the actua_replicas to gather the data whenever required
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 13:49:53 +01:00
pierre.geeraert 430172911e not touching kube-system 2026-09-09 13:29:31 +01:00
pierre.geeraert 38e00d6ac6 not touching kube-system
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 13:07:51 +01:00
pierre.geeraert 75004d16f9 fix call and remove one echo
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 13:02:18 +01:00
pierre.geeraert 47e6d6630d add function
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 12:59:52 +01:00
pierre.geeraert d9366b665b Add check for state true
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-09-09 10:29:55 +01:00
pierre.geeraert 951bf0a807 creating the function to display the expected state list 2026-09-09 10:29:10 +01:00
pierre.geeraert 4145db089f sounds promising
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-09 09:40:23 +01:00
pierre.geeraert a2f6d43398 seems good, more testing to do
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 21:07:46 +01:00
pierre.geeraert 5e41927b8d wrong identiation
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 20:57:22 +01:00
pierre.geeraert ea9459f013 good progress on the filter part
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 19:52:27 +01:00
pierre.geeraert c2e34305eb trying this way
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 19:09:54 +01:00
pierre.geeraert a79a9623b6 trying this way 2026-09-08 18:56:38 +01:00
pierre.geeraert cac74471aa fix the wrong import
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 18:50:37 +01:00
pierre.geeraert afe668cca6 change the logic
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 18:48:45 +01:00
pierre.geeraert 2785eecbf3 cleanup 2026-09-08 18:30:05 +01:00
pierre.geeraert 0833a20347 move the import of data so other app can invoke the methods
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 18:24:03 +01:00
pierre.geeraert 95945cd4cf fix same name and add schedule week
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 18:17:25 +01:00
pierre.geeraert fdb32538bf wrong find & replace
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 18:10:52 +01:00
pierre.geeraert d2740d4b62 default schedule
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 18:01:29 +01:00
pierre.geeraert e26ba6d99d default schedule
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 17:57:24 +01:00
pierre.geeraert f419751206 create default day schedule, WIP and function not tested
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-09-08 17:24:12 +01:00
pierre.geeraert 70660fbd5a revert name and namespace , and switch to update and create
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 17:08:30 +01:00
pierre.geeraert a94390916a add replicas
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 17:03:03 +01:00
pierre.geeraert 5d6e5339ad change model
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 16:47:29 +01:00
pierre.geeraert b9cd8e3226 change model
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 13:05:22 +01:00
pierre.geeraert ce42b3dc33 add action
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-08 10:41:19 +01:00
pierre.geeraert 3f25d83f64 add action
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-09-08 10:15:18 +01:00
pierre.geeraert 45a67a11cf big untested try of cmm
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-08 10:10:18 +01:00
pierre.geeraert f0b700a688 big untested try of cmm
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-08 10:08:35 +01:00
pierre.geeraert 8d6234927c lower the key otherwise it will craerte duplicate with the existing key with uppercase
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-07 11:27:19 +01:00
pi-ux-ce 189f81d95b Merge pull request 'change workflow name' (#41) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 46s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/41
2026-09-07 09:58:56 +00:00
pierre.geeraert c5d0fd8589 change workflow name
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-07 10:57:57 +01:00
pi-ux-ce 1a9ea98202 Merge pull request 'setup the clearkey' (#40) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 47s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/40
2026-09-07 09:51:31 +00:00
pierre.geeraert 4938370eea setup the clearkey
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-07 10:44:14 +01:00
pi-ux-ce b834ff10bf Merge pull request 'Update django_code/apps/streaming/utils.py' (#39) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 47s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/39
2026-09-05 22:10:42 +00:00
pi-ux-ce 13c360b1b0 Update django_code/apps/streaming/utils.py
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-05 22:08:58 +00:00
pi-ux-ce 7804dd5993 Merge pull request 'clickable links' (#35) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 53s
Reviewed-on: http://gitea.tryton.geeraert.eu/pi-ux-ce/Django_kube/pulls/35
2026-09-04 14:59:38 +00:00
pierre.geeraert 87257fb0b5 clickable links
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-04 15:52:38 +01:00
pi-ux-ce 56ccc83903 Merge pull request 'Testing' (#34) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 1m58s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/34
2026-09-03 09:08:40 +00:00
pierre.geeraert f658a018ac fix hardcoded path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-03 09:52:19 +01:00
pierre.geeraert 2608756622 ?
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-03 09:05:47 +01:00
pierre.geeraert 6350dacd4e switch to never start to save laptop ressources
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6s
2026-09-03 09:05:08 +01:00
pi-ux-ce 1629715732 Merge pull request 'Testing' (#32) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 1m1s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/32
2026-09-02 12:02:28 +00:00
pierre.geeraert 01c1ce7534 change urls path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-02 12:59:58 +01:00
pierre.geeraert ad0b611cb5 change urls path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-02 12:56:38 +01:00
pierre.geeraert 401ca9f935 change urls path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-09-02 12:55:01 +01:00
pi-ux-ce d3a835e3fb Merge pull request 'Testing' (#31) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 50s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/31
2026-09-02 11:47:22 +00:00
pierre.geeraert e98c05ce08 change urls path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-02 12:42:10 +01:00
pierre.geeraert 9759416787 change urls path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-02 12:40:20 +01:00
pierre.geeraert 03b007a5a0 change urls path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-02 12:36:06 +01:00
pierre.geeraert 93f3646abc work on the URLs
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-02 11:47:02 +01:00
pi-ux-ce 145e55df92 Merge pull request 'Testing' (#30) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 2m19s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/30
2026-08-27 13:27:32 +00:00
pierre.geeraert 08796241a6 remove the display and put the redirect instead
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-26 20:36:43 +01:00
pierre.geeraert 8e43ea9dbd maybe finished
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-26 20:33:58 +01:00
pierre.geeraert a42eee7797 no need for psql,proxmox or docker anymore
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-26 19:50:39 +01:00
pierre.geeraert 25caebeb0a just test the creds
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-26 19:43:57 +01:00
pi-ux-ce e157a8c077 work on the random part
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-26 19:29:15 +01:00
pi-ux-ce 1d86eb582e new method worked
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-26 12:35:43 +01:00
pi-ux-ce 04a216f643 adding the episode_seen option and fix potential mistake
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-26 12:04:58 +01:00
pi-ux-ce 533567b31d Merge pull request 'Testing' (#29) from testing into main
Dockerfile runner / Explore-Gitea-Actions (push) Successful in 2m9s
Reviewed-on: http://gitea.tryton.geeraert.eu/pi-ux-ce/Django_kube/pulls/29
2026-08-26 10:15:44 +00:00
pi-ux-ce e568afc5e0 use this method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 10s
2026-08-26 11:13:40 +01:00
pi-ux-ce 8865052752 use this method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-26 11:05:45 +01:00
pi-ux-ce f5f73fcacc use this method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-26 11:04:37 +01:00
pi-ux-ce b438956e96 Merge pull request 'Testing' (#28) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 3m29s
Reviewed-on: http://gitea.geeraert.eu/pi-ux-ce/Django_kube/pulls/28
2026-08-26 08:39:23 +00:00
pi-ux-ce e85c372ad8 following episode function good, need to work on the random episode and more admin stuff
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 7s
2026-08-25 16:24:43 +01:00
pi-ux-ce e66c7034f0 finishing the design of the admin page
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-07 17:17:26 +01:00
pi-ux-ce 8af967b4d3 change default
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-07 16:34:07 +01:00
pi-ux-ce b6e60764bd change default
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-07 16:29:29 +01:00
pi-ux-ce de1977fd2a work on the redirection
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-07 16:26:50 +01:00
pi-ux-ce 60aafb55b8 adding also new migrations
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-07 12:02:01 +01:00
pi-ux-ce 2b410b5ff8 reverting and merging into streaming app instead
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-07 12:00:32 +01:00
pi-ux-ce 7a1021edfa adding streaming_redirect
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-07 11:56:22 +01:00
pi-ux-ce a991b69547 add colored background
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-06 15:33:19 +01:00
pierre geeraert 9595ea326f clean the URLs from import
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-05 19:55:27 +01:00
pi-ux-ce 78a95435ae clickable links almost everywhere
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-05 16:59:10 +01:00
pi-ux-ce a2973bcd82 no need for python-json-logger anymore as we cancelled netdata idea
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 9s
2026-08-05 15:32:03 +01:00
pi-ux-ce 90cb797d2e Merge pull request 'testing' (#27) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 7m5s
Reviewed-on: #27
2026-08-05 14:30:37 +00:00
pi-ux-ce b496c8ee02 add the migrate step for the prod entrypoint
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-05 15:28:51 +01:00
pi-ux-ce cbaf675f09 only edit the URL
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-05 15:28:07 +01:00
pi-ux-ce 3b2f77df35 add a result for the method of use
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-05 14:45:52 +01:00
pi-ux-ce b4ab48be08 display status code
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-05 14:38:06 +01:00
pi-ux-ce 943781d54d enable vpn
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-05 14:34:20 +01:00
pi-ux-ce 54fd66196e test working 2026-08-05 14:34:06 +01:00
pi-ux-ce 12078b1439 global settings and work on test website
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-05 14:05:59 +01:00
pi-ux-ce 1a8b54b718 add new entrypoint
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-05 13:10:11 +01:00
pi-ux-ce 749c971e1f data structure
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-08-05 13:08:06 +01:00
pi-ux-ce 822c42bd62 add new streaming app
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-05 13:01:06 +01:00
pi-ux-ce 21e77ab0b3 try again
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-03 14:43:56 +01:00
pi-ux-ce d38cea53f8 try another build method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-08-03 14:33:25 +01:00
pi-ux-ce 2e5e3b0a26 trying the netdata logging
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-03 14:22:48 +01:00
pi-ux-ce 4dbfeff967 add clickable links
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-31 15:14:11 +01:00
pi-ux-ce 441716bbbc stop rollout restart celery as there is no celery anymore
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m48s
2026-07-28 15:07:19 +01:00
pi-ux-ce 09b52bc16c Merge pull request 'testing' (#26) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 3m35s
Reviewed-on: #26
2026-07-28 14:02:07 +00:00
pi-ux-ce 4f4de780ca add docker ignore
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-28 14:50:22 +01:00
pi-ux-ce 7681aef96e avoiding git clone within the dockerfile
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 4m7s
2026-07-28 13:40:52 +01:00
pi-ux-ce a1d7d8005d avoiding git clone within the dockerfile
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 7s
2026-07-28 13:38:41 +01:00
pi-ux-ce 31179d99de add cat of requirements as they don't get build
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 9s
2026-07-28 11:58:28 +01:00
pi-ux-ce d8866b038a add cat of requirements as they don't get build
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-28 11:56:30 +01:00
pi-ux-ce 016ffbb1a9 remove redis for website redircet
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-07-28 10:49:01 +01:00
pi-ux-ce 8d90b3ef9d Merge pull request 'testing' (#25) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 9m44s
Reviewed-on: #25
2026-07-23 12:16:05 +00:00
pi-ux-ce 7e9b474f10 fix random spacing
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-23 13:15:23 +01:00
pi-ux-ce e06a02db13 adding djangoql
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-23 13:07:49 +01:00
pi-ux-ce 540b5fea80 adding djangoql 2026-07-23 13:07:39 +01:00
111 changed files with 2050 additions and 436 deletions
+10
View File
@@ -0,0 +1,10 @@
.git
.github
**/__pycache__
*.pyc
.pytest_cache
media
staticfiles
*.sqlite3
node_modules
.env
+19 -47
View File
@@ -1,5 +1,5 @@
name: Gitea Actions Demo name: Dockerfile runner
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 run-name: Building and deploying to Prod 🚀
on: on:
push: push:
branches: branches:
@@ -15,9 +15,9 @@ jobs:
env: env:
RUNNER_TOOL_CACHE: /toolcache RUNNER_TOOL_CACHE: /toolcache
DEBUG: True DEBUG: True
ALLOWED_HOSTS: "django.tryton.geeraert.eu" ALLOWED_HOSTS: "django.geeraert.eu"
container: 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: volumes:
- act-toolcache:/opt/hostedtoolcache # this is where Runner store their cache default - act-toolcache:/opt/hostedtoolcache # this is where Runner store their cache default
runs-on: host-runner runs-on: host-runner
@@ -56,49 +56,27 @@ jobs:
echo "------------------------------------------------" echo "------------------------------------------------"
echo "Next version: $next_version" 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 - name: Login to gitea
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: gitea.tryton.geeraert.eu registry: gitea.geeraert.eu
username: ${{ secrets.USERNAME_GITEA }} username: ${{ secrets.USERNAME_GITEA }}
password: ${{ secrets.PASSWORD_GITEA }} password: ${{ secrets.PASSWORD_GITEA }}
- name: Build and push - name: Build image
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
run: | run: |
rm -rf /opt/hostedtoolcache/.buildx-cache docker build \
mv /opt/hostedtoolcache/.buildx-cache-new /opt/hostedtoolcache/.buildx-cache -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 - name: Rollout Django to force pulling the new image
uses: actions-hub/kubectl@master uses: actions-hub/kubectl@master
@@ -107,19 +85,13 @@ jobs:
with: with:
args: rollout restart deployment django -n django 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 }}." - run: echo "🍏 This job's status is ${{ job.status }}."
- name: update version in the variable - name: update version in the variable
run: | run: |
curl -X PUT -H "Content-Type: application/json" \ curl -X PUT -H "Content-Type: application/json" \
--user ${{ secrets.USERNAME_GITEA }}:${{ secrets.PASSWORD_GITEA }} \ --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\"}" -d "{\"Value\":\"$next_version\"}"
- name: backup git for future use - name: backup git for future use
+19 -21
View File
@@ -1,5 +1,5 @@
name: Gitea Actions Demo name: Dockerfile testing runner
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 run-name: Building and deploying to testing 🔎
on: on:
push: push:
branches: branches:
@@ -22,9 +22,6 @@ jobs:
- name: List files in the repository - name: List files in the repository
run: | run: |
ls ${{ gitea.workspace }} ls ${{ gitea.workspace }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Compute next version - name: Compute next version
id: versioning id: versioning
run: | run: |
@@ -39,30 +36,31 @@ jobs:
- name: Login to gitea - name: Login to gitea
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: gitea.tryton.geeraert.eu registry: gitea.geeraert.eu
username: ${{ secrets.USERNAME_GITEA }} username: ${{ secrets.USERNAME_GITEA }}
password: ${{ secrets.PASSWORD_GITEA }} password: ${{ secrets.PASSWORD_GITEA }}
- name: Build and push - name: Build image
uses: docker/build-push-action@v6 run: |
with: docker build \
context: . -f infra/testing/dockerfile \
file: infra/testing/dockerfile --build-arg ALLOWED_HOSTS='django-testing.geeraert.eu' \
push: true --build-arg DEBUG='True' \
build-args: | --build-arg CACHE_BUST=${{ env.next_version }} \
ALLOWED_HOSTS='django-testing.tryton.geeraert.eu' -t gitea.geeraert.eu/pi-ux-ce/django-testing:latest \
DEBUG='True' -t gitea.geeraert.eu/pi-ux-ce/django-testing:${{ env.next_version }} \
tags: | .
gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:latest
gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:${{ env.next_version }} - name: Push image
cache-from: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:buildcache run: |
cache-to: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:buildcache,mode=max 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 - name: update version in the variable
run: | run: |
curl -X PUT -H "Content-Type: application/json" \ curl -X PUT -H "Content-Type: application/json" \
--user ${{ secrets.USERNAME_GITEA }}:${{ secrets.PASSWORD_GITEA }} \ --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\"}" -d "{\"Value\":\"$next_version\"}"
- name: Rollout Django to force pulling the new image - name: Rollout Django to force pulling the new image
+1 -1
View File
@@ -1,5 +1,5 @@
name: Gitea Actions Demo name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 run-name: Deploying to Prod 🪂🛫
on: on:
push: push:
branches: branches:
+1 -1
View File
@@ -1,5 +1,5 @@
name: Gitea Actions Demo name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 run-name: Deploying to testing 🏗️🧪
on: on:
push: push:
branches: branches:
+6 -2
View File
@@ -11,6 +11,7 @@ python django_code/manage.py makemigrations simpsons
python django_code/manage.py makemigrations job python django_code/manage.py makemigrations job
python django_code/manage.py makemigrations telegram python django_code/manage.py makemigrations telegram
python django_code/manage.py makemigrations podcast 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
python django_code/manage.py migrate --database=cloudmanager_db 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=job_db
python django_code/manage.py migrate --database=telegram_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=podcast_db
python django_code/manage.py migrate --database=streaming_db
``` ```
### Database debug ### Database debug
@@ -30,6 +32,7 @@ create database simpsons;
create database job; create database job;
create database telegram; create database telegram;
create database podcast; create database podcast;
create database streaming;
@@ -39,6 +42,7 @@ drop database simpsons;
drop database job; drop database job;
drop database telegram; drop database telegram;
drop database podcast; drop database podcast;
drop database streaming;
``` ```
@@ -68,14 +72,14 @@ export bitwarden_organization_id=""
``` ```
cd existing_repo 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 branch -M main
git push -uf origin main git push -uf origin main
``` ```
## Integrate with your tools ## 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 ## Collaborate with your team
+35 -6
View File
@@ -59,22 +59,41 @@ class betaserieUtils():
show_id = response.json()['shows'][0]['id'] show_id = response.json()['shows'][0]['id']
return show_id 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): def identify_episode(self,show_id,episode_number,verbose=False):
# #
# Usage # Usage
# episode_id = beta.identify_episode(show_id,"S01E01",True) # episode_id,episode_seen = beta.identify_episode(show_id,"S01E01",True)
# #
url = "https://api.betaseries.com/episodes/search?show_id="+str(show_id)+"&number="+str(episode_number) url = "https://api.betaseries.com/episodes/search?show_id="+str(show_id)+"&number="+str(episode_number)
response = requests.request("GET", url, headers=self.headers, data=self.payload) response = requests.request("GET", url, headers=self.headers, data=self.payload)
episode_id = response.json()['episode']['id'] episode_id = response.json()['episode']['id']
episode_seen = response.json()['episode']['user']['seen']
if verbose: if verbose:
print("Url request: "+str(url)) print("Url request: "+str(url))
print(response.text) print(response.text)
return episode_id return episode_id,episode_seen
def mark_episodes_watched(self,episode_id,verbose=False): def mark_episodes_watched(self,episode_id,verbose=False):
# #
@@ -112,11 +131,21 @@ class betaserieUtils():
url = "https://api.betaseries.com/shows/display?id="+str(show_id) url = "https://api.betaseries.com/shows/display?id="+str(show_id)
response = requests.request("GET", url, headers=self.headers, data=self.payload) response = requests.request("GET", url, headers=self.headers, data=self.payload)
maximum_number_seasons = response.json()['show']['seasons']
if verbose : print("maximum_number_seasons: "+str(maximum_number_seasons))
seasons_details = response.json()['show']['seasons_details'] seasons_details = response.json()['show']['seasons_details']
#checking if the first season is season 0, and if so remove this season
if (seasons_details[0]['number']==0):
season_0_to_remove = seasons_details[0]
if verbose : print(season_0_to_remove)
seasons_details.remove(season_0_to_remove)
maximum_number_seasons = len(seasons_details)
if verbose : print("maximum_number_seasons: "+str(maximum_number_seasons))
if verbose: if verbose:
print("Url request: "+str(url)) print("Url request: "+str(url))
print(response.text) print(response.text)
+2 -2
View File
@@ -12,9 +12,9 @@ class bitwardenUtils():
client = BitwardenClient( client = BitwardenClient(
client_settings_from_dict( 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, "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", "userAgent": "Python",
} }
) )
+54 -43
View File
@@ -1,10 +1,11 @@
from django.contrib import admin,messages from django.contrib import admin,messages
from django.utils.translation import ngettext from django.utils.translation import ngettext
from .models import Deployment_Data,Schedule_Day_Data,Schedule_Week_Data,Namespace_Data,namespace_cmm_data_object from .models import Deployment_Data,Schedule_Day_Data,Schedule_Week_Data,Namespace_Data,Ingress_Data
from .utils import import_namespace 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 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") @admin.action(description="scale up")
@@ -38,22 +39,18 @@ def scale_down_deploy(modeladmin, request, queryset):
messages.SUCCESS, messages.SUCCESS,
) )
@admin.action(description="create_entry") @admin.action(description="Expected False")
def create_entry(modeladmin, request, queryset): def Check_server_supposed_False(modeladmin, request, queryset):
print("simpsons_data_object.create(season=2, episode=3, url='google.com'', seen=True)") servers_supposed_false = Check_server_supposed_XXX(False)
#call function to trigger refresh of all deploy 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): class ActiveAtHourFilter(admin.SimpleListFilter):
title = 'Active at hour' title = 'Active at hour'
@@ -69,44 +66,58 @@ class ActiveAtHourFilter(admin.SimpleListFilter):
return queryset 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) @admin.register(Deployment_Data)
class DeploymentDataAdmin(MultiDBModelAdmin): class DeploymentDataAdmin(UniversalModelAdmin):
list_display = ('name', 'namespace', 'schedule_week', 'schedule_day', 'replicas') list_display = ('name', 'namespace', 'schedule_week', 'schedule_day', 'replicas')
list_filter = (ActiveAtHourFilter,) 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) @admin.register(Schedule_Day_Data)
class ScheduleDayAdmin(MultiDBModelAdmin): class ScheduleDayAdmin(UniversalModelAdmin):
list_display = ['name_schedule'] + [f'state_at_{h}' for h in range(24)] 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) @admin.register(Schedule_Week_Data)
class ScheduleWeekAdmin(MultiDBModelAdmin): class ScheduleWeekAdmin(UniversalModelAdmin):
list_display = ( list_display = (
'name_schedule', 'name_schedule',
'state_Monday', 'state_Tuesday', 'state_Wednesday', 'state_Monday', 'state_Tuesday', 'state_Wednesday',
'state_Thursday', 'state_Friday', 'state_Saturday', 'state_Sunday', '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) @admin.register(Namespace_Data)
class NamespaceAdmin(MultiDBModelAdmin): class NamespaceAdmin(UniversalModelAdmin):
list_display = ('namespace',) 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')
-31
View File
@@ -1,37 +1,6 @@
from django.apps import AppConfig 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): class CloudmanagerConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.cloudmanager' name = 'apps.cloudmanager'
label = '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.http import HttpResponse
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from apps.kubernetes_connection import apps as kubernetes_connection from apps.kubernetes_connection import apps as kubernetes_connection
@@ -153,10 +153,6 @@ def main(request):
#print(Is_the_server_already_wanted_state(112, "stopped")) #print(Is_the_server_already_wanted_state(112, "stopped"))
return HttpResponse('<h1>CMM executed!</h1>') return HttpResponse('<h1>CMM executed!</h1>')
if __name__ == "__main__":
main()
""" """
TO DO: TO DO:
@@ -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'),
),
]
@@ -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'),
),
]
@@ -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'),
),
]
@@ -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'),
),
]
@@ -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'),
),
]
@@ -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'),
),
]
@@ -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'),
),
]
@@ -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'),
),
]
@@ -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'),
),
]
@@ -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),
),
]
+8 -3
View File
@@ -1,6 +1,5 @@
from django.db import models from django.db import models
from django.utils import timezone
class Schedule_Week_Data(models.Model): class Schedule_Week_Data(models.Model):
name_schedule = models.CharField(max_length=100,unique=True) 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_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) schedule_day = models.ForeignKey(Schedule_Day_Data,null=True, blank=True, on_delete=models.SET_NULL)
replicas = models.IntegerField() replicas = models.IntegerField()
actual_replica = models.IntegerField()
do_not_touch_until = models.DateTimeField('do_not_touch_until', default=timezone.now)
class Meta: class Meta:
db_table = 'machine' 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) #deployments = models.ForeignKey(Schedule_Week_Data,null=True, blank=True, on_delete=models.SET_NULL)
class Meta: class Meta:
db_table = 'namespace' 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)
+33
View File
@@ -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),
]
+139 -8
View File
@@ -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() namespaces_list = get_namespace()
for namespace in namespaces_list: 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): def import_deployment():
namespaces_list = get_namespace() deployment_list = get_deployments()
#for namespace in namespaces_list: Schedule_Day_Always_off,Schedule_Day_Always_on = generate_default_day_schedule()
# queryset.create(namespace=namespace) 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
+70 -18
View File
@@ -1,25 +1,77 @@
from django.http import HttpResponse 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.import_aggregator.import_rest_framework import api_view, authentication_classes, permission_classes,TokenAuthentication,IsAuthenticated,Response,status
from apps.cloudmanager.models import Deployment_Data,Schedule_Week_Data
def coucou(request): from .utils import import_namespace,retrieve_and_apply
# 1. Prepare the data inside the function from apps.kubernetes_connection.utils import scale_up,scale_down
data = CmmData( from .models import Deployment_Data,Ingress_Data
name="test",
namespace="testspace",
schedule_hour="1",
schedule_day="deux",
replicas=3
)
# 2. This line actually pushes the data into your cloudmanager_db! def hello(request):
data.save() 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
+2 -2
View File
@@ -1,9 +1,9 @@
from django.contrib import admin from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from import_export import resources from import_export import resources
from import_export.fields import Field from import_export.fields import Field
from .models import JobData from .models import JobData
from django.utils.text import Truncator from django.utils.text import Truncator
from core.admin import UniversalModelAdmin
# Register your models here. # Register your models here.
@@ -31,7 +31,7 @@ class JobResource(resources.ModelResource):
@admin.register(JobData) @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') 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'] #fields = ['job_position','company','URL','status','date_saved','date_applied','type','resume','cover_letter','location','job_description','salary ','contact','source']
resource_classes = [JobResource] resource_classes = [JobResource]
+1 -2
View File
@@ -14,9 +14,8 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path 1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.contrib import admin
from django.urls import path from django.urls import path
from django.contrib import admin
urlpatterns = [ urlpatterns = [
path('', admin.site.urls), path('', admin.site.urls),
@@ -62,7 +62,7 @@ def nodes(request):
'spec': { 'spec': {
'containers': [{ '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', # 'pod-running-timeout': '5m0s',
'name': 'testpython', 'name': 'testpython',
'env': [ 'env': [
@@ -96,7 +96,7 @@ def backup_job(request):
'spec': { 'spec': {
'containers': [{ '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', 'name': 'testpython',
'command': ['/bin/sh -c /config/export_bitwarden.sh'], 'command': ['/bin/sh -c /config/export_bitwarden.sh'],
'env': [ 'env': [
@@ -124,8 +124,8 @@ def backup_job_yaml(request,sync_target):
v1 = client.BatchV1Api() v1 = client.BatchV1Api()
yaml_location = { yaml_location = {
"synology" : "https://gitea.tryton.geeraert.eu/pi-ux-ce/Backup_kube/raw/branch/main/Infrequent_access/synology_pod.yaml", "synology" : "https://gitea.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" "openmediavault":"https://gitea.geeraert.eu/pi-ux-ce/Backup_kube/raw/branch/main/Infrequent_access/openmediavault_pod.yaml"
} }
print(yaml_location[sync_target]) print(yaml_location[sync_target])
url_to_select=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 test.items[2].spec.template.spec.containers[0].name # name the third deploy within the namespace
return 0 return 0
def get_namespace(): def get_namespace(verbose=False):
config.load_kube_config(config_file='/kubeconfig/config') config.load_kube_config(config_file='/kubeconfig/config')
core = client.CoreV1Api() core = client.CoreV1Api()
namespace = core.list_namespace() namespace = core.list_namespace()
namespace_list = [] namespace_list = []
for i in range(0,len(namespace.items)): 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) namespace_list.append(namespace.items[i].metadata.name)
return namespace_list return namespace_list
def get_deployments(): def get_deployments(verbose=False):
config.load_kube_config(config_file='/kubeconfig/config') config.load_kube_config(config_file='/kubeconfig/config')
api = client.AppsV1Api() api = client.AppsV1Api()
namespaces_list = get_namespace() namespaces_list = get_namespace()
deployments_list = [] deployments_list = []
for namespace in namespaces_list: for namespace in namespaces_list:
print(namespace) if verbose : print(namespace)
deployments = api.list_namespaced_deployment(namespace) deployments = api.list_namespaced_deployment(namespace)
for deployment_index in range(0,len(deployments.items)): for deployment_index in range(0,len(deployments.items)):
deployment = deployments.items[deployment_index].metadata.name deployment = deployments.items[deployment_index].metadata.name
print(" "+str(deployment)) replicas = deployments.items[deployment_index].spec.replicas
deployments_list.append([namespace,deployment]) if verbose : print(" "+str(deployment)+" -- Replicas: "+str(replicas))
deployments_list.append([namespace,deployment,replicas])
return deployments_list return deployments_list
+6 -3
View File
@@ -1,9 +1,12 @@
from django.contrib import admin from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from import_export import resources from import_export import resources
from django.utils.html import format_html
from .models import podcastData from .models import podcastData
from core.admin import UniversalModelAdmin
# Register your models here. # Register your models here.
@admin.register(podcastData) @admin.register(podcastData)
class JobAdmin(ImportExportModelAdmin): class PodcastAdmin(UniversalModelAdmin):
list_display = ('podcast_name','podcast_url','enabled') 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),
]
+9 -7
View File
@@ -1,11 +1,12 @@
from django.contrib import admin,messages from django.contrib import admin,messages
from django.utils.translation import ngettext 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 django.utils import timezone
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. # Register your models here.
DB = 'simpsons_db' DB = 'simpsons_db'
@@ -62,8 +63,9 @@ def generate_new_urls(modeladmin, request, queryset):
@admin.register(SimpsonsData) @admin.register(SimpsonsData)
class EpisodeAdmin(ImportExportModelAdmin): class EpisodeAdmin(UniversalModelAdmin):
list_display = [field.name for field in SimpsonsData._meta.fields if field.name != 'id'] 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','modified_at']
#list_filter = ['seen'] #list_filter = ['seen']
fields = ['season', 'episode', 'url', 'seen'] fields = ['season', 'episode', 'url', 'seen']
@@ -83,7 +85,7 @@ class EpisodeAdmin(ImportExportModelAdmin):
queryset.using(DB).delete() queryset.using(DB).delete()
@admin.register(urlData) @admin.register(urlData)
class urldataAdmin(ImportExportModelAdmin): class urldataAdmin(UniversalModelAdmin):
list_display = ('url_example', 'prefix', 'infix', 'suffix','addedDate') 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)),
),
]
+25
View File
@@ -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),
]
+5 -9
View File
@@ -22,7 +22,7 @@ def mark_episode_watched(season,episode,action,verbose=False):
#mark episode as seen in betaserie #mark episode as seen in betaserie
episode_number = "S"+str(season)+"E"+str(episode) episode_number = "S"+str(season)+"E"+str(episode)
episode_id = betaserie.identify_episode(simpsons_id,episode_number) episode_id,episode_seen = betaserie.identify_episode(simpsons_id,episode_number)
if action == "watched": if action == "watched":
betaserie.mark_episodes_watched(episode_id) betaserie.mark_episodes_watched(episode_id)
@@ -49,20 +49,16 @@ def generate_new_urls_for_episode(verbose=False):
# URL.com/simpsons/season=XX&episode=XX # URL.com/simpsons/season=XX&episode=XX
# example # example
# https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=33&episode=18 # https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=33&episode=18
seasons_information,maximum_number_season = betaserie.series_information(simpsons_id)
simpsons_series_information = betaserie.series_information(simpsons_id)
seasons_information = simpsons_series_information[0]
#for the simpsons, there is a season 0 which increase the count of seasons by 1 #for the simpsons, there is a season 0 which increase the count of seasons by 1
# we need to remove this entry , # we need to remove this entry ,
# so we cannot trust the maximum_number_season coming from simpsons_series_information # so we cannot trust the maximum_number_season coming from simpsons_series_information
season_0_to_remove = seasons_information[0] # edit 26/08/2026
# I updated the function betaserie.series_information to remove this season 0
if verbose : print(season_0_to_remove)
seasons_information.remove(season_0_to_remove)
maximum_number_season = len(seasons_information)
for season in range(1,maximum_number_season+1): for season in range(1,maximum_number_season+1):
# the list doesn't start with season 0 anymore so we cannot use the season number as index # the list doesn't start with season 0 anymore so we cannot use the season number as index
+33
View File
@@ -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'),
]
+100
View File
@@ -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))
+7
View File
@@ -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',
},
),
]
@@ -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),
),
]
@@ -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),
),
]
@@ -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),
),
]
@@ -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),
),
]
@@ -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),
),
]
@@ -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),
),
]
@@ -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),
),
]
@@ -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),
),
]
+80
View File
@@ -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'
+24
View File
@@ -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),
]
+67
View File
@@ -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
+87
View File
@@ -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 django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from .models import TelegramData from .models import TelegramData
from .utils import telegramUtils from .utils import telegramUtils
from core.admin import UniversalModelAdmin
@admin.action(description="Clear all expired messages") @admin.action(description="Clear all expired messages")
def messages_cleaning(modeladmin, request, queryset): def messages_cleaning(modeladmin, request, queryset):
@@ -10,7 +10,7 @@ def messages_cleaning(modeladmin, request, queryset):
# Register your models here. # Register your models here.
@admin.register(TelegramData) @admin.register(TelegramData)
class JobAdmin(ImportExportModelAdmin): class JobAdmin(UniversalModelAdmin):
list_display = ('message_id','chat_id','description','creation_date','expiration_date') list_display = ('message_id','chat_id','description','creation_date','expiration_date')
actions = [messages_cleaning] actions = [messages_cleaning]
+10 -4
View File
@@ -1,7 +1,7 @@
from django.contrib import admin from django.contrib import admin
from .models import redirectData from .models import historicalData,redirectData
from .utils import redirect_method from .utils import redirect_method
from import_export.admin import ImportExportModelAdmin from core.admin import UniversalModelAdmin
# Register your models here. # Register your models here.
@@ -18,8 +18,14 @@ def re_redirect(modeladmin, request, queryset):
request, request,
output_generated 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) @admin.register(redirectData)
class redirectAdmin(ImportExportModelAdmin): class redirectAdmin(UniversalModelAdmin):
list_display = [field.name for field in redirectData._meta.fields if field.name != 'id'] list_display = [field.name for field in redirectData._meta.fields if field.name != 'id']
actions = [re_redirect] list_display += ['clickable_links']
+1 -1
View File
@@ -1,4 +1,4 @@
import redis #import redis
from django.http import HttpResponse from django.http import HttpResponse
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render from django.shortcuts import render
@@ -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.db import models
from django.contrib import admin
class redirectData(models.Model): class historicalData(models.Model):
url = models.CharField(max_length=1000) url = models.CharField(max_length=1000)
key = models.CharField(max_length=1000,default="streaming") key = models.CharField(max_length=1000,default="streaming")
addedDate = models.DateField('Published', blank=True, null=True, auto_now_add=True) 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: class Meta:
db_table = 'redirect' db_table = 'redirect'
@@ -14,12 +14,10 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path 1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.contrib import admin
from django.urls import path from django.urls import path
from apps.website_redirection import views as website_redirectionapp from apps.website_redirection import views as website_redirectionapp
urlpatterns = [ urlpatterns = [
# path('admin/', admin.site.urls),
################### Redirect ################### ################### Redirect ###################
path('', website_redirectionapp.redirect), path('', website_redirectionapp.redirect),
@@ -30,6 +28,4 @@ urlpatterns = [
path('redirect-form/', website_redirectionapp.redirect_process, name='submit_form'), path('redirect-form/', website_redirectionapp.redirect_process, name='submit_form'),
path('clearkey/', website_redirectionapp.clearkey_process, name='submit_form'), path('clearkey/', website_redirectionapp.clearkey_process, name='submit_form'),
] ]
@@ -1,16 +1,16 @@
import redis from .models import historicalData,redirectData
from .models import redirectData
r = redis.Redis(
host='django-redis-svc',
port=6379,
db=0 # The default Redis database index
)
def redirect_method(key,value): def redirect_method(key,value):
key = key.lower() 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 text_generated = "successfully set "+value+" to "+key
return text_generated return text_generated
+16 -18
View File
@@ -2,22 +2,15 @@ from django.shortcuts import render
from django.http import HttpResponse from django.http import HttpResponse
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.apps import AppConfig from django.apps import AppConfig
from .models import redirectData from .models import historicalData,redirectData
from .utils import redirect_method from .utils import redirect_method
import redis
def hello(request): def hello(request):
return HttpResponse('<h1>Hello Django!</h1>') 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): def hello(request):
return HttpResponse('<h1>Hello redirect!</h1>') return HttpResponse('<h1>Hello redirect!</h1>')
@@ -27,8 +20,11 @@ def redirect(request):
def clearkey_process(request): def clearkey_process(request):
key = request.GET.get('key') key = request.GET.get('key')
r.delete(key) key = key.lower()
return 0 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): def redirect_process(request):
key = request.GET.get('key') key = request.GET.get('key')
@@ -39,22 +35,24 @@ def redirect_process(request):
return HttpResponse(text_generated, content_type="text/plain") return HttpResponse(text_generated, content_type="text/plain")
def display_key(request,key): def display_key(request,key):
value = r.get(key) value = redirectData.objects.filter(key=key).values('url')[0]['url']
value_extracted = str(value.decode()) value_extracted = str(value.decode())
text_generated = key+" is set to "+value_extracted text_generated = key+" is set to "+value_extracted
return HttpResponse(text_generated, content_type="text/plain") return HttpResponse(text_generated, content_type="text/plain")
def redirect_to_key(request,key): def redirect_to_key(request,key):
value = r.get(key) redirect_object = redirectData.objects.filter(key=key)
if value == None: value = str(redirect_object.values('url')[0]['url'])
icon_url = r.get('icon')
if icon_url == None: if value == "None":
icon_url = "https://cdn-icons-png.flaticon.com/512/6402/6402576.png" #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") print(key+" is not setup, displaying default page")
return render(request, 'website_redirection/blank_page.html', {'title': key,'icon_url':icon_url}) return render(request, 'website_redirection/blank_page.html', {'title': key,'icon_url':icon_url})
else: else:
value_extracted = str(value.decode('utf-8')) value_extracted = str(value)
print(key+" is setup to : "+value_extracted) print(key+" is setup to : "+value_extracted)
print(value_extracted) print(value_extracted)
return HttpResponseRedirect(value_extracted) return HttpResponseRedirect(value_extracted)
+20
View File
@@ -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)
+21
View File
@@ -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"),
)
+15 -4
View File
@@ -1,10 +1,21 @@
from django.conf import settings from django.conf import settings
from django_hosts import patterns, host from django_hosts import patterns, host
#ADMIN
# redirect
# streaming
# cloudmanager
# stash
# podcast
# simpsons
host_patterns = patterns('', 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", 'apps.website_redirection.urls', name="redirect"),
host(r"redirect-testing", 'apps.website_redirection.urls', name="redirect-testing"), host(r"streaming", 'apps.streaming.urls', name="streaming"),
host(r"job", 'apps.job_dashboard.urls', name="job_dashboard"), host(r"stash", 'apps.stash_management.urls', name="stash"),
host(r"job-testing", 'apps.job_dashboard.urls', name="job_dashboard-testing"), 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"),
) )
+12 -3
View File
@@ -27,6 +27,9 @@ class ProjectDatabaseRouter:
if model._meta.app_label == 'podcast': if model._meta.app_label == 'podcast':
return 'podcast_db' return 'podcast_db'
if model._meta.app_label == 'streaming':
return 'streaming_db'
return 'default' return 'default'
def db_for_write(self, model, **hints): def db_for_write(self, model, **hints):
@@ -50,14 +53,17 @@ class ProjectDatabaseRouter:
if model._meta.app_label == 'podcast': if model._meta.app_label == 'podcast':
return 'podcast_db' return 'podcast_db'
if model._meta.app_label == 'streaming':
return 'streaming_db'
return 'default' return 'default'
def allow_relation(self, obj1, obj2, **hints): def allow_relation(self, obj1, obj2, **hints):
"""Allow relations if both models are in the same database.""" """Allow relations if both models are in the same database."""
# Prevents accidental foreign key relationships across different physical DBs # Prevents accidental foreign key relationships across different physical DBs
if ( if (
obj1._meta.app_label in ['cloudmanager', 'simpsons', 'redirect', 'job', 'telegram', 'podcast'] or obj1._meta.app_label in ['cloudmanager', 'simpsons', 'redirect', 'job', 'telegram', 'podcast', 'streaming'] or
obj2._meta.app_label in ['cloudmanager', 'simpsons', 'redirect', 'job', 'telegram', 'podcast'] obj2._meta.app_label in ['cloudmanager', 'simpsons', 'redirect', 'job', 'telegram', 'podcast', 'streaming']
): ):
return obj1._meta.app_label == obj2._meta.app_label return obj1._meta.app_label == obj2._meta.app_label
return None return None
@@ -83,8 +89,11 @@ class ProjectDatabaseRouter:
if app_label == 'podcast': if app_label == 'podcast':
return db == 'podcast_db' 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 # 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 False
return None return None
+46 -3
View File
@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.2/ref/settings/
""" """
import os import os
from pathlib import Path from pathlib import Path
from urllib import request as urllib_request
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
@@ -49,7 +50,13 @@ INSTALLED_APPS = [
'apps.job_dashboard.apps.JobDashboardConfig', 'apps.job_dashboard.apps.JobDashboardConfig',
'apps.telegram_communication.apps.TelegramCommunicationConfig', 'apps.telegram_communication.apps.TelegramCommunicationConfig',
'apps.podcast_aggregator.apps.PodcastAggregatorConfig', 'apps.podcast_aggregator.apps.PodcastAggregatorConfig',
'apps.streaming.apps.StreamingConfig',
'import_export', 'import_export',
'djangoql',
'admin_extra_buttons',
'rest_framework',
'rest_framework.authtoken',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@@ -66,8 +73,14 @@ MIDDLEWARE = [
] ]
ROOT_URLCONF = 'core.urls' ROOT_URLCONF = 'core.urls'
ROOT_HOSTCONF = 'core.hosts'
DEFAULT_HOST = 'django-testing' ENVIRONMENT = os.getenv("ENVIRONMENT","TESTING")
if ENVIRONMENT == "PRODUCTION":
ROOT_HOSTCONF = 'core.hosts'
else:
ROOT_HOSTCONF = 'core.hosts-testing'
DEFAULT_HOST = 'admin'
TEMPLATES = [ TEMPLATES = [
@@ -152,6 +165,15 @@ DATABASES = {
'HOST': os.environ.get('DB_HOST'), 'HOST': os.environ.get('DB_HOST'),
'PORT': os.environ.get('DB_PORT'), '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 = ['core.routers.ProjectDatabaseRouter']
#DATABASE_ROUTERS = [] #DATABASE_ROUTERS = []
@@ -180,7 +202,7 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC' TIME_ZONE = 'Europe/London'
USE_I18N = True USE_I18N = True
@@ -213,3 +235,24 @@ CELERY_IMPORTS = [
'apps.random_simpsons.utils' 'apps.random_simpsons.utils'
# Add other app tasks here if needed # 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
}
+1 -76
View File
@@ -16,82 +16,7 @@ Including another URLconf
""" """
from django.contrib import admin from django.contrib import admin
from django.urls import path 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 = [ urlpatterns = [
path('admin/', admin.site.urls), path('', 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),
] ]
@@ -111,7 +111,7 @@ body {
<div class="modal-dialog modal-confirm"> <div class="modal-dialog modal-confirm">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <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">&#xE876;</i>--> <!--<i class="material-icons">&#xE876;</i>-->
<i class="material-icons">&#xd7;</i> <i class="material-icons">&#xd7;</i>
</div> </div>
+1 -1
View File
@@ -109,7 +109,7 @@ body {
<div class="modal-dialog modal-confirm"> <div class="modal-dialog modal-confirm">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <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">&#xE876;</i>--> <!--<i class="material-icons">&#xE876;</i>-->
<i class="material-icons">&#xE876;</i> <i class="material-icons">&#xE876;</i>
</div> </div>
+1 -1
View File
@@ -259,7 +259,7 @@
<h1 id="title">Stash Form</h1> <h1 id="title">Stash Form</h1>
<p id="description" class="description" class="text-center">Download form</p> <p id="description" class="description" class="text-center">Download form</p>
</div> </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> <fieldset>
<label for="name" id="name-label"> <label for="name" id="name-label">
@@ -259,7 +259,7 @@
<h1 id="title">Incremental Form</h1> <h1 id="title">Incremental Form</h1>
<p id="description" class="description" class="text-center">Download form</p> <p id="description" class="description" class="text-center">Download form</p>
</div> </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> <fieldset>
<label for="name" id="name-label"> <label for="name" id="name-label">
+5 -5
View File
@@ -10852,7 +10852,7 @@
<li class="nav-item dropdown"> <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> <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"> <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><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item" href="#!">Album</a></li> <li><a class="dropdown-item" href="#!">Album</a></li>
</ul> </ul>
@@ -10887,7 +10887,7 @@
</div> </div>
<!-- Product actions--> <!-- Product actions-->
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent"> <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> </div>
</div> </div>
@@ -10908,7 +10908,7 @@
</div> </div>
<!-- Product actions--> <!-- Product actions-->
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent"> <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> </div>
</div> </div>
@@ -10928,7 +10928,7 @@
</div> </div>
<!-- Product actions--> <!-- Product actions-->
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent"> <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> </div>
</div> </div>
@@ -10975,7 +10975,7 @@
</div> </div>
<!-- Product actions--> <!-- Product actions-->
<div class="card-footer p-4 pt-0 border-top-0 bg-transparent"> <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> </div>
</div> </div>
+1 -1
View File
@@ -259,7 +259,7 @@
<h1 id="title">Stash Form</h1> <h1 id="title">Stash Form</h1>
<p id="description" class="description" class="text-center">Download form</p> <p id="description" class="description" class="text-center">Download form</p>
</div> </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> <fieldset>
<label for="name" id="name-label"> <label for="name" id="name-label">
+1 -1
View File
@@ -259,7 +259,7 @@
<h1 id="title">Stash Form</h1> <h1 id="title">Stash Form</h1>
<p id="description" class="description" class="text-center">Download form</p> <p id="description" class="description" class="text-center">Download form</p>
</div> </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> <fieldset>
<label for="name" id="name-label"> <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