296 Commits
Author SHA1 Message Date
pi-ux-ce aa6ce119b8 Merge pull request 'testing' (#24) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1m12s
Reviewed-on: #24
2026-07-17 14:41:04 +00:00
pi-ux-ce 94e47be079 restructuring
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-17 15:16:16 +01:00
pi-ux-ce 8abcd775ce Merge branch 'testing' of https://gitea.tryton.geeraert.eu/pi-ux-ce/Django_kube into testing
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 9m35s
2026-07-17 15:14:42 +01:00
pi-ux-ce a9a3cf69c6 restructuring 2026-07-17 15:14:16 +01:00
pi-ux-ce 87d8c52c48 Merge pull request 'testing' (#23) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 9m32s
Reviewed-on: #23
2026-07-14 22:00:44 +00:00
pierre geeraert f3672fed63 upgrade the testing entrypoint
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-14 22:58:34 +01:00
pierre geeraert 9f7fdbc198 letting re apply the redirect of a previous element
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-07-14 22:57:50 +01:00
pi-ux-ce 2661593e69 Merge pull request 'testing' (#22) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m10s
Reviewed-on: #22
2026-07-10 11:17:38 +00:00
pi-ux-ce 6f1c8cd8ff we can delete the message from telegram from the webui now
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-10 12:09:31 +01:00
pi-ux-ce a3fb4d843a remove unnecessary imports
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-09 09:14:23 +01:00
pi-ux-ce e7b72b1754 use temporary folder to avoid downloading into disk
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-09 09:13:36 +01:00
pi-ux-ce 7cb3d1917e Merge pull request 'testing' (#21) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m54s
Reviewed-on: #21
2026-07-07 09:48:19 +00:00
pi-ux-ce 0aebb19650 generate new urls based on the urlData form
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-07 10:47:24 +01:00
pi-ux-ce 3c2e6fe2f1 migrations from the new model 2026-07-07 10:20:43 +01:00
pi-ux-ce 78e9da8bd3 admin field for the url 2026-07-07 10:20:31 +01:00
pi-ux-ce b31480b68c adding redircet url and also avoid timezone conflict 2026-07-07 10:20:12 +01:00
pierre geeraert d556284977 enable whitenoise for production , as debug=false doesn't support static file
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5m55s
2026-07-05 18:53:52 +01:00
pi-ux-ce d90696a1a5 Merge pull request 'testing' (#20) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m36s
Reviewed-on: #20
2026-07-05 13:51:01 +00:00
pierre geeraert b4eaf9eb5d work on timestamp
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-05 14:47:17 +01:00
pierre geeraert 333d065043 utilise less queryset ressources
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-05 14:24:40 +01:00
pierre geeraert 8aed35a67a bad idea actually
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m49s
2026-07-05 14:06:45 +01:00
pi-ux-ce 4fd57edecd Merge pull request 'testing' (#19) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 2m52s
Reviewed-on: #19
2026-07-05 13:01:18 +00:00
pierre geeraert 15e28502c1 collectstatic all the time
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-05 13:54:52 +01:00
pierre geeraert 035b878b3c re-organise the static 2026-07-05 13:51:34 +01:00
pi-ux-ce 0cbc34293e Merge pull request 'testing' (#18) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5m4s
Reviewed-on: #18
2026-07-05 11:59:45 +00:00
pierre geeraert 95c11fe68d remove unnecessary import
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-07-05 12:57:47 +01:00
pierre geeraert cece5eae71 using thread now
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-05 12:56:52 +01:00
pi-ux-ce f659209cd6 Merge pull request 'testing' (#17) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m53s
Reviewed-on: #17
2026-07-04 20:14:02 +00:00
pierre geeraert decbfc1bb5 stop this async crap for now
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-07-04 20:56:57 +01:00
pierre geeraert e9c7068b52 new readme
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-07-04 20:50:25 +01:00
pierre geeraert 8be9e7dd13 remove the journal
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-04 19:47:56 +01:00
pi-ux-ce f0e6339b3d Merge pull request 'testing' (#16) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5m44s
Reviewed-on: #16
2026-07-04 17:39:51 +00:00
pierre geeraert e320f881d1 celery is an env var now
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-04 16:56:02 +01:00
pierre geeraert 22557fb166 removing migration step
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6s
2026-07-04 14:54:06 +01:00
pierre geeraert 919065093d slowness due to the betaseries step, moving to shared task
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-07-04 13:53:44 +01:00
pierre geeraert c9e66762df add the admin action for it
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-07-04 13:21:34 +01:00
pierre geeraert f1ffa5c949 rewriting url and adding new one if they were not created
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-04 13:11:06 +01:00
pierre geeraert 4d5f3809d9 we can get info from show now 2026-07-04 13:09:01 +01:00
pierre geeraert b2ef330fc9 rename the command
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-03 23:48:07 +01:00
pierre geeraert 2ba56cb00f new_url command will automatically gather and replace the router file
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-07-03 23:43:37 +01:00
pierre geeraert d7ef0fcd3e create an equivalent of router, need to find a data type for it
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-02 22:25:35 +01:00
pierre geeraert c7eb2c5aba templating works some WIP though
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-02 22:11:43 +01:00
pierre geeraert 19e997f7ae improve message
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-07-02 21:46:07 +01:00
pierre geeraert 5433b97b00 add commands
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-02 21:38:37 +01:00
pierre geeraert 2a609b2143 only fetch enabled data
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-07-02 21:07:38 +01:00
pi-ux-ce dfd77e458a add admin for telegram
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-07-02 16:31:33 +01:00
pi-ux-ce 11d8176622 add proxy
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-02 16:20:46 +01:00
pi-ux-ce f9f831738d parse the podcasts and run them
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-02 10:43:59 +01:00
pi-ux-ce a435eac3e8 improve parsing
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-02 09:58:13 +01:00
pi-ux-ce 97a74fb2cf target messages older than today not older than tomorrow
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-07-02 09:42:29 +01:00
pierre geeraert 444039b64a just in case
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-30 23:57:32 +01:00
pierre geeraert 7492061f58 add some options for podcast aggregator , multiple urls
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-30 23:55:35 +01:00
pierre geeraert a44ca7e825 setup new model 2026-06-30 23:55:10 +01:00
pierre geeraert f68b0ad00f add model 2026-06-30 22:55:13 +01:00
pierre geeraert 9863662e34 'QuerySet' object has no attribute 'len'
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-30 20:17:51 +01:00
pierre geeraert 7edecd7d1c exit if the list is empty
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-30 19:54:16 +01:00
pierre geeraert 5e9e5a1e7b fix the result issue
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-06-30 19:48:58 +01:00
pi-ux-ce 6af4c36fae miss requirement
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-30 16:07:56 +01:00
pi-ux-ce fa61ab2733 run the podcast through an url
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-06-30 15:57:36 +01:00
pi-ux-ce 8764522525 create usefull functions
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-30 15:40:35 +01:00
pi-ux-ceandClaude Sonnet 4.6 b4545d6c99 Add telegram_communication app with dedicated DB routing
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
- Register TelegramCommunicationConfig in INSTALLED_APPS and add telegram_db to DATABASES
- Define TelegramData model mapped to the messages table
- Fix allow_migrate in ProjectDatabaseRouter: redirect and telegram entries were returning the DB name string (always truthy) instead of a boolean comparison, causing their migrations to bleed into every database
- Add telegram routing to db_for_read, db_for_write, allow_relation, and allow_migrate

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 13:20:40 +01:00
pi-ux-ce ec2696ee43 just add a testing loop to clean messages, will be deleted after testing
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-30 10:56:50 +01:00
pi-ux-ce 52ba892d6f some news for podcats mostly calling telegram directly 2026-06-30 10:56:25 +01:00
pi-ux-ce 5478a1032c we can send messages through telegram now 2026-06-30 10:12:44 +01:00
pi-ux-ce b11c840688 add some debug 2026-06-30 09:50:51 +01:00
pi-ux-ce 15994f11b1 able to downlaod podcast mp3 2026-06-30 09:49:46 +01:00
pi-ux-ce b5c3aa1bdb Merge pull request 'revoke keys and replace them by env variable' (#15) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m36s
Reviewed-on: #15
2026-06-25 22:27:28 +00:00
pierre geeraert 623bc9b74e revoke keys and replace them by env variable
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-25 23:09:37 +01:00
pi-ux-ce 6a6b0a0167 Merge pull request 'testing' (#14) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 14m51s
Reviewed-on: #14
2026-06-25 21:24:06 +00:00
pi-ux-ce ad9c6c7a2a adding the unseen all option
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-25 16:01:08 +01:00
pi-ux-ce 25b602a3b8 update requirements
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-25 14:03:35 +01:00
pi-ux-ce ed70f03a83 add options for the admin page
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-06-25 13:56:25 +01:00
pi-ux-ce e76fb6684c adding &bulk=false to avoid as If specified, all previous episodes will also be marked as watched (default true) 2026-06-25 13:56:01 +01:00
pierre geeraert 2454d77ce8 last bit added
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-24 23:57:22 +01:00
pierre geeraert 5432647293 some code were usefull
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-24 23:51:12 +01:00
pierre geeraert 14d2e869bb remove unnecessary code
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-24 23:29:14 +01:00
pierre geeraert ce9072124d add quite some betaserie work 2026-06-24 23:25:38 +01:00
pierre geeraert f78ffcc595 add quite some bitwarden work 2026-06-24 23:25:24 +01:00
pierre geeraert 57d2559ad3 more work on bitwarden
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-24 11:42:53 +01:00
pierre geeraert 024736c887 work in progress , stil need to turn everything into a class
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-23 23:46:00 +01:00
pierre geeraert 73f57871b4 settings
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-22 21:52:47 +01:00
pierre geeraert cf0c355416 add some settings
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-22 21:33:28 +01:00
pierre geeraert 54c53d4510 add some settings 2026-06-22 21:32:17 +01:00
pi-ux-ce 5e247e831c enable multiple urls
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-22 11:53:56 +01:00
pi-ux-ce ecaa988b5f remove migrations files
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-22 11:45:15 +01:00
pi-ux-ce 73c89d8d93 work on new app
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-22 11:43:38 +01:00
pierre geeraert 1a41a01dfa need to make some try
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-22 10:54:03 +01:00
pi-ux-ce 5d26a4dd05 add new app
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-22 10:28:56 +01:00
pi-ux-ce 956e7fc1d0 Duplicate host name: redirect
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-22 09:42:33 +01:00
pi-ux-ce 73101d8cb9 add alias for testing
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-22 09:37:09 +01:00
pierre geeraert 78cc6cbad3 make python version match testing
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 11m10s
2026-06-21 23:00:25 +01:00
pierre geeraert ec5eadac06 use the right function
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m25s
2026-06-21 22:42:56 +01:00
pierre geeraert f22a33ad1a also remove function then
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m9s
2026-06-21 22:33:50 +01:00
pierre geeraert f28a9096f7 fix function for date and import
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-06-21 22:32:02 +01:00
pierre geeraert 0216a9f1e1 fix function for date and import
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m6s
2026-06-21 22:21:55 +01:00
pierre geeraert bb642c781a type object 'redirectData' has no attribute 'create'
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m48s
2026-06-21 22:06:13 +01:00
pi-ux-ce 0af676ec39 Merge pull request 'no need for migration if the DB doesn't exist' (#13) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6m7s
Reviewed-on: #13
2026-06-21 20:39:15 +00:00
pierre geeraert e93f00321e no need for migration if the DB doesn't exist
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-21 21:38:19 +01:00
pi-ux-ce 565a381977 Merge pull request 'testing' (#12) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 4m24s
Reviewed-on: #12
2026-06-21 20:30:30 +00:00
pierre geeraert 914e1c691f write down every time redirect adds something
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-21 21:23:20 +01:00
pierre geeraert e153be4b58 write down every time redirect adds something 2026-06-21 21:21:54 +01:00
pierre geeraert 6cacd1a2cf add import_export into requirement
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-21 20:12:38 +01:00
pierre geeraert eecdb55ba0 add import_export into requirement
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-21 20:11:37 +01:00
pierre geeraert 4de2cbf1bc renaming to core
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-21 19:57:39 +01:00
pierre geeraert aff4debd79 add import/export
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-21 19:52:22 +01:00
pi-ux-ce 022ad01ace don't forgot to clear thge quyeryset before running this
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-19 16:43:28 +01:00
pi-ux-ce cda89ea243 add deploy import
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-06-19 16:41:13 +01:00
pi-ux-ce aa0939be6d add namespace import
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-19 15:58:38 +01:00
pi-ux-ce e74b659b45 Add action to crate new entry
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-19 11:04:35 +01:00
pi-ux-ce f522b69a68 add scale down
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-18 17:41:51 +01:00
pi-ux-ce ef7b47b0c5 Try to start a deploy using admin interface
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-18 17:26:50 +01:00
pi-ux-ce 3d8fc1d848 remove import export as it failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-18 17:06:11 +01:00
pi-ux-ce 5820be065c remove import export as it failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-18 17:04:45 +01:00
pi-ux-ce 5ee60c8324 Add import_export pip package
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-18 17:00:24 +01:00
pi-ux-ce 4918d968b7 work on the import/export and static
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-18 11:07:09 +01:00
pi-ux-ce 75e172c7c0 work on the import/export 2026-06-18 11:05:02 +01:00
pi-ux-ce 9ad042b371 removing cloudmanager_old
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-18 10:38:05 +01:00
pi-ux-ce ed240d3cd0 having to change the admin direction due to no router
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-18 10:26:09 +01:00
pi-ux-ce 2da9e9390d 🗑️ cleaning
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-17 18:59:14 +01:00
pi-ux-ce 47bf1d40f9 cleaning 2026-06-17 18:51:05 +01:00
pi-ux-ce 256cc8cd71 simpsons redirection working 2026-06-17 18:48:22 +01:00
pi-ux-ce 51769fb08a avoid untracked files
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-17 14:54:01 +01:00
pi-ux-ce 555b222d6b try another method
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-06-17 13:46:24 +00:00
pi-ux-ce cf26fa90d3 remove pycache
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-17 14:41:39 +01:00
pi-ux-ce 0cce30b7d2 point to DB instead fo sqllite
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-17 14:39:36 +01:00
pi-ux-ce 200fea731c remove all codes
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-17 14:34:33 +01:00
pi-ux-ce 0eca15a19b dispaly data for cloudmanager in admin 2026-06-17 14:18:43 +01:00
pierre geeraert fbe38faf59 downgrade python to 3.12 instead of 3 latest
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-16 21:08:38 +01:00
pierre geeraert 0015e105f9 django-bootstrap-v5 1.0.11 depends on django<5.0 and >=2.2 2026-06-16 21:06:26 +01:00
pierre geeraert 3dc8cce37a upgrade django version as well
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-16 21:04:19 +01:00
pierre geeraert 090eeccf8c add https for the CORS setting 2026-06-16 20:58:09 +01:00
pi-ux-ce 17a7e173fe work on django admin
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 33s
2026-06-16 10:26:17 +01:00
pierre geeraert 8d52c43e68 data work inside the view
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-15 23:01:21 +01:00
pi-ux-ce 3eb7fd44e5 Merge pull request 'testing' (#10) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 9m30s
Reviewed-on: #10
2026-06-15 19:22:44 +00:00
pierre geeraert 8c09ab3c6e trying to fix the redirect url
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-15 20:20:27 +01:00
pierre geeraert 19665ea0b7 update readme
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m22s
2026-06-15 09:59:43 +01:00
pi-ux-ce 7d4a1897f7 remove pycache files
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-12 11:50:14 +01:00
pi-ux-ce 72ab577431 try to trigger new build
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-12 11:16:48 +01:00
pi-ux-ce 535617594f try to trigger new build
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-12 11:05:49 +01:00
pi-ux-ce 1230cac914 add tags in the build process
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-12 11:04:18 +01:00
pi-ux-ce a3d5c16484 try to trigger new build
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-06-12 10:57:06 +01:00
pi-ux-ce 29ea329ed5 remove python cache
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-12 10:03:02 +01:00
pi-ux-ce d719af498c reset testing branch 2026-06-12 10:02:37 +01:00
pi-ux-ce b118391dc6 reset testing branch 2026-06-12 09:59:20 +01:00
pi-ux-ce 17d2f3544c wrong cache image
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m37s
2026-06-12 09:54:05 +01:00
pi-ux-ce 25ba693bbd use sqllite as default db for building purpose
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m53s
2026-06-12 09:49:18 +01:00
pi-ux-ce e5406b6549 Merge pull request 'testing' (#9) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 6m52s
Reviewed-on: #9
2026-06-12 08:29:43 +00:00
pi-ux-ce 5fa8ad286f application not renamed
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-12 08:29:30 +01:00
pierre geeraert d3061eddaf work on databse model
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-11 22:12:00 +01:00
pierre geeraert 883e028cae refactoring
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-06-11 20:18:59 +01:00
pierre geeraert 2f4b93d11c removing print function 2026-06-11 20:17:51 +01:00
pierre geeraert 57d7e8feee removing print function
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-11 20:16:07 +01:00
pierre geeraert dd3b0b7731 removing cloudmanager_old
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-11 19:52:20 +01:00
pierre geeraert c86301c9b2 refactoring
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-11 19:51:19 +01:00
pierre geeraert 3079df9072 refactoring
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-11 19:19:15 +01:00
pi-ux-ce 1c04605dc7 prototype fo namespace import
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-06-11 11:51:12 +01:00
pierre geeraert 2b8a4ed46f try again something new
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-09 22:55:46 +01:00
pierre geeraert 622f2c8758 try again something new
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-09 22:52:24 +01:00
pierre geeraert 4e6637aba9 Revert "try new method"
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
This reverts commit c6784759cd.
2026-06-09 22:47:54 +01:00
pierre geeraert c6784759cd try new method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-09 22:45:07 +01:00
pierre geeraert 55f27433f9 try new method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-06-09 22:41:51 +01:00
pierre geeraert 2dd02f0632 try new method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-06-09 22:40:03 +01:00
pierre geeraert 5d4bc9e93b try new method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-06-09 22:37:54 +01:00
pierre geeraert ccb69a43d2 try new method
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-06-09 22:36:20 +01:00
pierre geeraert 36755ccfb0 add the missing return
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-06-09 21:46:58 +01:00
pierre geeraert 27dff192f2 now the template adapt depending of the data and tries ajax button without success
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-31 00:25:56 +01:00
pierre geeraert e9dad6bfe5 adding alot of template files
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-03-30 23:40:49 +01:00
pierre geeraert 69d161c19b finding how to target the good one
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-27 00:18:58 +00:00
pierre geeraert 103dcc919e fix scale down and add the down query
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-27 00:08:49 +00:00
pierre geeraert 3eea2ea4a2 need to add the request
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-27 00:05:43 +00:00
pierre geeraert d0a948e93f I was meant to fix it from the start
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-03-27 00:02:02 +00:00
pierre geeraert 2a3c71f939 adding weekday input
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-03-26 23:58:29 +00:00
pierre geeraert 8caa778ee0 add servers down as well
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-26 23:56:39 +00:00
pierre geeraert 5521b70e46 adding custom DB name for the terraform secret that point to the django db not the cmm one
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-26 23:44:59 +00:00
pierre geeraert c8d784ae2b using env variable for DB creds
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-03-26 23:21:52 +00:00
pierre geeraert 910170b594 found the bit of code that deals with days
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-25 23:14:20 +00:00
pierre geeraert 4dee3442b0 actually easy fix
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-25 22:54:55 +00:00
pierre geeraert b38f2a8b2f adding all the files , still work in progress but getting there , needs to move scale_up function to somrthing not managed by REQUEST 2026-03-25 22:53:36 +00:00
pierre geeraert 1e8afcbc44 adding the sql code for the template
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-03-25 22:00:44 +00:00
pierre geeraert 9e2b51de60 adding some mysql function to convert to postgresal
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-03-17 23:26:08 +00:00
pierre geeraert eb0f467aad Merge branch 'testing' of https://gitea.tryton.geeraert.eu/pi-ux-ce/Django_kube into testing 2026-03-17 22:57:20 +00:00
pi-ux-ce da4b86f4d3 no need this anymore
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6s
2026-03-17 10:31:21 +00:00
pi-ux-ce b5ef38bc0d try gemini ai idea
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m48s
2026-03-17 10:26:34 +00:00
pi-ux-ce c5b7e9dcde moving the env variables
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5m55s
2026-03-17 10:13:24 +00:00
pi-ux-ce b611d41e8a moving the env variables
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 3m41s
2026-03-17 09:51:14 +00:00
pi-ux-ce c3ba43b0fa moving the env variables 2026-03-17 09:47:51 +00:00
pierre geeraert dc0e006e0f change link
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m32s
2026-03-16 23:26:42 +00:00
pierre geeraert 0b66858969 also try for the icon url
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m44s
2026-03-16 23:11:48 +00:00
pierre geeraert 16c8fba623 trying to variablise the title of the blank page
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-03-16 23:08:44 +00:00
pierre geeraert 852fccd95c remove extra slash
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m36s
2026-03-16 23:04:11 +00:00
pierre geeraert 316d07db61 default page is set and button to got to favorite ones
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m52s
2026-03-16 22:55:19 +00:00
pierre geeraert bf99f618f6 fetch only latest commit from main branch
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m43s
2026-03-16 22:09:19 +00:00
pierre geeraert 534f0cb7cb move the vars
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6m37s
2026-03-16 21:59:35 +00:00
pierre geeraert 974f6820d4 move the vars 2026-03-16 21:53:47 +00:00
pierre geeraert 6ccf910e29 add env variable
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 3m5s
2026-03-16 21:47:03 +00:00
pierre geeraert aaf1ced21c emulate some variables 2026-03-16 21:45:47 +00:00
pi-ux-ce d05a3e2dc6 Merge pull request 'testing' (#8) from testing into main
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 4m7s
Reviewed-on: #8
2026-03-16 21:06:42 +00:00
pierre geeraert 8be8b44584 also variablize DEBUG
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 21:03:28 +00:00
pierre geeraert 4a028c04c9 fix the extra s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 20:59:41 +00:00
pierre geeraert 1f1d7ab75d convert it to list
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 20:59:11 +00:00
pierre geeraert e0e5d9e290 trying to variablise allowed_hosts
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 20:33:46 +00:00
pierre geeraert 181eb67501 remove useless imports
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 20:21:28 +00:00
pierre geeraert 8af976c528 change path as well
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 20:16:01 +00:00
pierre geeraert beba1f16b4 changing path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-03-16 20:14:47 +00:00
pierre geeraert 76d0cbdb8d default url
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 20:03:53 +00:00
pierre geeraert 6ff0bb31d3 fix name of the module
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 20:03:20 +00:00
pierre geeraert e78825b99f importnt first argument
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 19:57:06 +00:00
pi-ux-ce 33a9d6fec7 d
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-03-16 18:36:55 +00:00
pi-ux-ce b01145e6bd adding nano
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6m40s
2026-03-16 18:33:22 +00:00
pi-ux-ce 06024c82c1 trying like that
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 18:30:37 +00:00
pi-ux-ce ce4a4838f1 adding required value
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-03-16 18:26:03 +00:00
pi-ux-ce f80cfbeba7 adding required value
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 18:24:15 +00:00
pi-ux-ce 61e5966083 missed requirements
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-03-16 18:18:46 +00:00
pi-ux-ce f49a606693 trying this url conf
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 18:13:52 +00:00
pi-ux-ce 2b866b32bb enable redirect..tryton.geeraert.eu
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2s
2026-03-16 17:50:55 +00:00
pi-ux-ce 97896b5170 changing the authorised URL
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-03-16 14:50:49 +00:00
pi-ux-ce 3647ff15e1 trying to trigger a new image
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6s
2026-03-16 14:42:55 +00:00
pi-ux-ce 267f753452 using the testing branch
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-03-16 14:36:44 +00:00
pi-ux-ce c33e463e09 addign a restart after restarT
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-03-16 14:32:41 +00:00
pi-ux-ce 40cfc3c9f5 prevent main runner to run if there was a testing change 2026-03-16 14:21:39 +00:00
pi-ux-ce 632ba5257e fixing image name
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m39s
2026-03-16 10:42:57 +00:00
pi-ux-ce 7127effdaf trying to setup the django testing image 2026-03-16 10:39:26 +00:00
pi-ux-ce ca3f7e964e change title page
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m2s
2026-03-03 23:12:26 +00:00
pi-ux-ce 904e779b59 changing the extra >
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5m23s
2026-03-03 22:55:55 +00:00
pi-ux-ce 63054b4a3a adding some print
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m56s
2026-02-05 20:11:01 +00:00
pi-ux-ce 871f3c5ba8 put lower var
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 7m54s
2026-02-03 14:51:21 +00:00
pi-ux-ce 9c706bb9b1 Update .gitea/workflows/dockerfile_runner.yaml
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m14s
2026-01-20 00:02:19 +00:00
pi-ux-ce 06c57ca837 try v6
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 2s
2026-01-19 23:55:53 +00:00
pi-ux-ce 39a3ec055b try again
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-01-19 23:54:36 +00:00
pi-ux-ce 401cf8e1a7 Update .gitea/workflows/dockerfile_runner.yaml
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 10s
2026-01-19 23:46:19 +00:00
pi-ux-ce f50d624d22 set git location
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 10s
2026-01-19 23:45:27 +00:00
pi-ux-ce 4aeee1acb5 manually git pull
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 7s
2026-01-19 23:43:31 +00:00
pi-ux-ce b6a9cfed19 do not clean before checkout
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-01-19 23:36:15 +00:00
pi-ux-ce a67dcf763b trigger new build
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-01-19 23:31:52 +00:00
pi-ux-ce 0f58c2dcae only if present
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m12s
2026-01-19 20:53:13 +00:00
pi-ux-ce 9cb1418b0d avoid crashing if no source file
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 10s
2026-01-19 20:48:49 +00:00
pi-ux-ce f62e6ca651 trying to cache git folder
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 8s
2026-01-19 20:47:06 +00:00
pi-ux-ce 0c6ddd4904 trying host_runner
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4m38s
2026-01-19 19:46:48 +00:00
Pierre Geeraert 14d4dbfe97 update runner to add curl
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-01-19 17:53:28 +00:00
Pierre Geeraert 50d0c2cd4d debug
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 5m57s
2026-01-19 17:43:25 +00:00
Pierre Geeraert 4fe45169c3 try with the exact version of the runner
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1m36s
2026-01-19 17:40:43 +00:00
Pierre Geeraert 78d93a16eb remove kubeconfig
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 23s
2026-01-19 17:25:50 +00:00
Pierre Geeraert b94bf528be display kubeconfig
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-01-19 17:23:49 +00:00
Pierre Geeraert 11ad57bce4 no need to download docker.io as the base image is doing it now 2026-01-19 17:16:07 +00:00
Pierre Geeraert 495a55f8c1 try to install docker
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 7m17s
2026-01-19 16:54:55 +00:00
Pierre Geeraert c611360c04 try debug
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 29s
2026-01-19 16:52:17 +00:00
Pierre Geeraert ada418374b trying gitea.tryton.geeraert.eu/pi-ux-ce/custom-runner-debian-slim:latest
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 35s
2026-01-19 15:57:09 +00:00
Pierre Geeraert 3bf7f2a195 trying to use debian
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 5m41s
2026-01-19 13:46:25 +00:00
pi-ux-ce 2d22cab6e7 changing to debian image
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-01-19 11:54:38 +00:00
pi-ux-ce 96dcbe1798 Update django_code/django_code/urls.py
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m14s
2026-01-08 23:58:04 +00:00
pi-ux-ce ac6dc5b426 revert e2d3868a9e
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 1m58s
revert add prowlarr script in tash until I create a prowlarr project with celery
2026-01-08 23:53:12 +00:00
pi-ux-ce b4f22ffeea update due to some errors
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 2m14s
2026-01-08 23:42:30 +00:00
pi-ux-ce ca3ed630ed adding the URL
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m42s
2026-01-08 23:34:27 +00:00
pi-ux-ce e2d3868a9e add prowlarr script in tash until I create a prowlarr project with celery
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2026-01-08 23:31:22 +00:00
Pierre Geeraert 47314620be can only concatenate str (not bytes) to str
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m35s
2026-01-07 17:57:22 +00:00
Pierre Geeraert f26f3f2665 try a new function with clearing the key
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m45s
2026-01-07 13:42:47 +00:00
Pierre Geeraert 938b37e920 add some comments
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m52s
2026-01-07 13:31:57 +00:00
Pierre Geeraert 2c5a989306 fix syntax error
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m1s
2026-01-07 13:19:24 +00:00
Pierre Geeraert 88a6dd9316 adding the default page in case there is no redis entry
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 2m12s
2026-01-07 12:08:03 +00:00
Pierre Geeraert 77742c1d6f ubuntu-slim wasn't working
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m33s
2025-12-09 10:20:21 +00:00
Pierre Geeraert ba16c6475a Merge branch 'main' of https://gitea.tryton.geeraert.eu/pi-ux-ce/Django_kube
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
2025-12-09 09:50:42 +00:00
Pierre Geeraert 1735098b3a trying ubuntu-slim 2025-12-09 09:49:49 +00:00
pierre geeraert 2fdaaa47ab f you are just trying to redirect to an absolute URL stored in Redis, your code should work provided the string is clean.
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m58s
A robust way to ensure it's treated as a simple URL might involve using Django's HttpResponseRedirect directly instead of the redirect shortcut:
2025-12-08 23:44:06 +00:00
pierre geeraert bd4e4aed27 try to debug it
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m1s
2025-12-08 23:34:41 +00:00
pierre geeraert 94a8240ad4 In Django, the <str:key> part of your URL pattern is designed to capture a value from the URL (e.g., if someone visits /redirect/go/xyz123) and pass it to the view function as a keyword argument named key.
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m51s
2025-12-08 23:22:27 +00:00
pierre geeraert be03af61ea prepare new function
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m44s
2025-12-08 23:14:34 +00:00
pierre geeraert 4da34c98f3 forgot dependencies
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m15s
2025-12-08 23:05:49 +00:00
pierre geeraert 12253f0621 try to work on the redirection
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m8s
2025-12-08 23:00:46 +00:00
Pierre Geeraert 369954f5d2 changing form submit path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m3s
2025-12-08 09:16:20 +00:00
pierre geeraert 4eee702dce add the comment for later review
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5m0s
2025-12-07 23:46:59 +00:00
pierre geeraert e90daa2e61 forgot the url
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5m19s
2025-12-07 23:39:45 +00:00
pierre geeraert cc8570d02f adding reddit downloader
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5m48s
2025-12-07 23:22:46 +00:00
Pierre Geeraert 98e5ea965c forgot one variable
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m59s
2025-12-05 11:16:44 +00:00
Pierre Geeraert 7a98ab1c6d cache seems good , doing a test
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 2m49s
2025-12-05 11:12:30 +00:00
Pierre Geeraert 70973a63fb frogot the step to move the cache
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 2m36s
2025-12-05 10:30:33 +00:00
Pierre Geeraert ad82f73c1d promising solution using volume mount
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-05 10:24:44 +00:00
Pierre Geeraert e08016c103 promising solution using volume mount
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-05 10:08:57 +00:00
Pierre Geeraert a65e99b199 another test
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-05 10:04:07 +00:00
Pierre Geeraert 4853150f07 another test
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
2025-12-05 10:02:22 +00:00
Pierre Geeraert a341e66c13 another test
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-05 09:53:55 +00:00
pierre geeraert 874779d230 now reverting
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6m15s
2025-12-04 23:52:19 +00:00
pierre geeraert 779e8a8b0f to revert, just a try
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-04 23:46:47 +00:00
pierre geeraert 8f35e88ce4 to revert, just a try
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-04 23:42:58 +00:00
pierre geeraert 71e874cfb4 to revert, just a try
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-04 23:40:27 +00:00
pierre geeraert 622b8942b5 to revert, just a try
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-04 23:40:16 +00:00
pierre geeraert 7aeb7d094c to revert, just a try
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 27s
2025-12-04 23:39:10 +00:00
pierre geeraert 4ee80f8b7e to revert, just a try
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-04 23:37:57 +00:00
pierre geeraert 4859fa6877 No matching distribution found for json
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6m2s
2025-12-04 23:17:56 +00:00
pierre geeraert a1d831cdf2 another cache try
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-04 23:17:08 +00:00
pierre geeraert a3ee639d77 put the steps for a reddit downloader
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 5m1s
2025-12-04 22:59:15 +00:00
pierre geeraert cd274aea81 change path
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5m49s
2025-12-04 19:59:53 +00:00
Pierre Geeraert aaa548eb21 1.651 IndentationError: unindent does not match any outer indentation level
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6m22s
2025-12-04 18:08:51 +00:00
Pierre Geeraert 99f05a055d add the retry function
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 5m46s
2025-12-04 17:00:48 +00:00
Pierre Geeraert e614d50f9c also clean .gitea/python_build
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6m55s
2025-12-04 16:54:01 +00:00
Pierre Geeraert 20526c829c revert everything
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
2025-12-04 16:53:18 +00:00
pi-ux-ce c9ed33f108 Merge pull request 'addign this for the syntax but this solution is too slow' (#6) from revert-caching into main
Gitea Actions Demo / changes (push) Successful in 24s
Gitea Actions Demo / Build-dockerfile (push) Has been cancelled
Gitea Actions Demo / Explore-Gitea-Actions (push) Has started running
Reviewed-on: #6
2025-12-04 16:50:07 +00:00
387 changed files with 74048 additions and 586 deletions
-16
View File
@@ -1,16 +0,0 @@
FROM gitea.tryton.geeraert.eu/pi-ux-ce/python:3
ENV PYTHONUNBUFFERED 1
WORKDIR /code/
# Copy only the requirements file first (Changes infrequently)
COPY requirements.txt ./
RUN --mount=type=cache,target=/root/.cache/pip pip install --upgrade pip
RUN --mount=type=cache,target=/root/.cache/pip pip list --outdated
RUN --mount=type=cache,target=/root/.cache/pip pip install --upgrade wheel
RUN --mount=type=cache,target=/root/.cache/pip pip install --upgrade setuptools
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt
-15
View File
@@ -1,15 +0,0 @@
django
psycopg2
requests
proxmoxer
docker
kubernetes
ruamel.yaml
pyyaml
django-bootstrap-v5
jinja2
watchdog
celery
redis
lxml
requests
+52 -89
View File
@@ -2,96 +2,46 @@ name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
on:
push:
#paths-ignore:
# - 'requirements.txt'
branches:
- main
paths-ignore:
- 'infra/production/dockerfile'
issue_comment:
types: [created]
workflow_dispatch: # Enables the manual run UI button
jobs:
# Job to check for file changes and set an output
changes:
runs-on: ubuntu-latest
outputs:
requirements_changed: ${{ steps.filter.outputs.requirements }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
requirements:
- 'requirements.txt'
Build-dockerfile:
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.requirements_changed == 'true' }}
steps:
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
- name: Check out repository code
uses: actions/checkout@v4
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}
- name: Compute next version
id: versioning
run: |
latest="${{ vars.PYTHON_VERSION }}"
next_version=$(echo "$latest" | awk -F. -v OFS=. '{$NF += 1 ; print}')
echo "next_version=$next_version" >> $GITHUB_ENV
echo "Variables used :"
echo "------------------------------------------------"
echo "Next version: $next_version"
- uses: actions/cache@v3
with:
path: /root/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: inject cache into docker
uses: reproducible-containers/buildkit-cache-dance@v3.1.0
with:
cache-source: /root/.cache/pip
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to gitea
uses: docker/login-action@v3
with:
registry: gitea.tryton.geeraert.eu
username: ${{ secrets.USERNAME_GITEA }}
password: ${{ secrets.PASSWORD_GITEA }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: "{{defaultContext}}:.gitea/python_build"
push: true
tags: |
gitea.tryton.geeraert.eu/pi-ux-ce/modified-python:latest
gitea.tryton.geeraert.eu/pi-ux-ce/modified-python:${{ env.next_version }}
cache-from: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/modified-python:buildcache
cache-to: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/modified-python:buildcache,mode=max
- name: update version in the variable
run: |
curl -X PUT -H "Content-Type: application/json" \
--user ${{ secrets.USERNAME_GITEA }}:${{ secrets.PASSWORD_GITEA }} \
https://gitea.tryton.geeraert.eu/api/v1/repos/pi-ux-ce/${{ github.event.repository.name }}/actions/variables/PYTHON_VERSION \
-d "{\"Value\":\"$next_version\"}"
Explore-Gitea-Actions:
runs-on: ubuntu-latest
env:
RUNNER_TOOL_CACHE: /toolcache
DEBUG: True
ALLOWED_HOSTS: "django.tryton.geeraert.eu"
container:
image: gitea.tryton.geeraert.eu/pi-ux-ce/custom-runner-debian-slim:1.0.6
volumes:
- act-toolcache:/opt/hostedtoolcache # this is where Runner store their cache default
runs-on: host-runner
steps:
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
- name: restore git folder if exist
run: if [ -d "/opt/hostedtoolcache/${{ github.event.repository.name }}/" ]; then cp -r /opt/hostedtoolcache/${{ github.event.repository.name }}/ ${{ gitea.workspace }}; fi
- name: Check Docker Version
run: whereis docker
- name: Check out repository code
uses: actions/checkout@v4
clean: false
fetch-depth: 1
ref: 'main'
# - name: Manually check out repository code
# run: cd ${{ gitea.workspace }} ; git pull origin main
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}
@@ -106,18 +56,19 @@ jobs:
echo "------------------------------------------------"
echo "Next version: $next_version"
- uses: actions/cache@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /root/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
path: /opt/hostedtoolcache/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-buildx-
- name: inject cache into docker
uses: reproducible-containers/buildkit-cache-dance@v3.1.0
with:
cache-source: /root/.cache/pip
cache-source: /opt/hostedtoolcache/pip
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
@@ -132,12 +83,21 @@ jobs:
- name: Build and push
uses: docker/build-push-action@v6
with:
context: infra/production/
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=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-python:buildcache
cache-to: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-python:buildcache,mode=max
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: |
rm -rf /opt/hostedtoolcache/.buildx-cache
mv /opt/hostedtoolcache/.buildx-cache-new /opt/hostedtoolcache/.buildx-cache
- name: Rollout Django to force pulling the new image
uses: actions-hub/kubectl@master
@@ -160,3 +120,6 @@ jobs:
--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 \
-d "{\"Value\":\"$next_version\"}"
- name: backup git for future use
run: cp -r ${{ gitea.workspace }} /opt/hostedtoolcache/${{ github.event.repository.name }}/
@@ -0,0 +1,74 @@
name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
on:
push:
branches:
- "testing"
paths:
- 'infra/testing/dockerfile'
tags-ignore:
- '*'
workflow_dispatch: # Enables the manual run UI button
jobs:
Explore-Gitea-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
- name: Check out repository code
uses: actions/checkout@v4
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
- name: List files in the repository
run: |
ls ${{ gitea.workspace }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Compute next version
id: versioning
run: |
latest="${{ vars.VERSION_TESTING }}"
next_version=$(echo "$latest" | awk -F. -v OFS=. '{$NF += 1 ; print}')
echo "next_version=$next_version" >> $GITHUB_ENV
echo "Variables used :"
echo "------------------------------------------------"
echo "Next version: $next_version"
- name: Login to gitea
uses: docker/login-action@v3
with:
registry: gitea.tryton.geeraert.eu
username: ${{ secrets.USERNAME_GITEA }}
password: ${{ secrets.PASSWORD_GITEA }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: infra/testing/
push: true
build-args: |
ALLOWED_HOSTS='django-testing.tryton.geeraert.eu'
DEBUG='True'
tags: |
gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:latest
gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:${{ env.next_version }}
cache-from: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:buildcache
cache-to: type=registry,ref=gitea.tryton.geeraert.eu/pi-ux-ce/django-testing:buildcache,mode=max
- name: update version in the variable
run: |
curl -X PUT -H "Content-Type: application/json" \
--user ${{ secrets.USERNAME_GITEA }}:${{ secrets.PASSWORD_GITEA }} \
https://gitea.tryton.geeraert.eu/api/v1/repos/pi-ux-ce/${{ github.event.repository.name }}/actions/variables/VERSION_TESTING \
-d "{\"Value\":\"$next_version\"}"
- name: Rollout Django to force pulling the new image
uses: actions-hub/kubectl@master
env:
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
with:
args: rollout restart deployment django-testing -n django-testing
- run: echo "🍏 This job's status is ${{ job.status }}."
@@ -0,0 +1,23 @@
name: Gitea Actions Demo
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
on:
push:
branches:
- "testing"
tags-ignore:
- '*'
jobs:
Explore-Gitea-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
- name: Rollout Django to force pulling the new image
uses: actions-hub/kubectl@master
env:
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
with:
args: rollout restart deployment django-testing -n django-testing
- run: echo "🍏 This job's status is ${{ job.status }}."
+226 -3
View File
@@ -1,6 +1,229 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py.cover
*.lcov
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
# Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
# poetry.lock
# poetry.toml
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
# pdm.lock
# pdm.toml
.pdm-python
.pdm-build/
# pixi
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
# pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi/*
!.pixi/config.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule*
celerybeat.pid
# Redis
*.rdb
*.aof
*.pid
# RabbitMQ
mnesia/
rabbitmq/
rabbitmq-data/
# ActiveMQ
activemq-data/
# SageMath parsed files
*.sage.py
# Environments
.env
.envrc
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
# .idea/
# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/
# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
# Temporary file for partial code execution
tempCodeRunnerFile.py
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/
# Streamlit
.streamlit/secrets.toml
*/__pycache__/*
*/.idea
venv/*
*__pycache__*
*/.idea/*
*/venv/*
*/.env/*
Webcal-python/*
.idea/*
django_code/db.sqlite3
-67
View File
@@ -1,67 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: django-python
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: django-webserver
namespace: django-python
spec:
replicas: 1
selector:
matchLabels:
app: django-python
template:
metadata:
labels:
app: django-python
spec:
containers:
- name: django-python
image: gitea.tryton.geeraert.eu/pi-ux-ce/django-python:latest
imagePullPolicy: Always
ports:
- containerPort: 8000
name: webserver-port
volumeMounts:
## - name: django-python-code
# mountPath: /code
- name: servarr-data
mountPath: /data
readOnly: true
- name: secret-kubeconfig
mountPath: /kubeconfig
resources:
limits:
cpu: 100m
memory: 200Mi
volumes:
- name: django-python-code
persistentVolumeClaim:
claimName: django-python-code
- name: servarr-data
hostPath:
path: /data
- name: secret-kubeconfig
secret:
defaultMode: 420
secretName: kubeconfig
---
apiVersion: v1
kind: Service
metadata:
name: webserver
namespace: django-python
spec:
ports:
- name: http
port: 8000
protocol: TCP
selector:
app: django-python
+57 -5
View File
@@ -1,13 +1,65 @@
=======
# Django_kube
test
## Getting started
### Database migration
```
python django_code/manage.py makemigrations
python django_code/manage.py makemigrations redirect
python django_code/manage.py makemigrations cloudmanager
python django_code/manage.py makemigrations simpsons
python django_code/manage.py makemigrations job
python django_code/manage.py makemigrations telegram
python django_code/manage.py makemigrations podcast
python django_code/manage.py migrate
python django_code/manage.py migrate --database=cloudmanager_db
python django_code/manage.py migrate --database=simpsons_db
python django_code/manage.py migrate --database=redirect_db
python django_code/manage.py migrate --database=job_db
python django_code/manage.py migrate --database=telegram_db
python django_code/manage.py migrate --database=podcast_db
```
### Database debug
```
create database django;
create database redirect;
create database cloudmanager;
create database simpsons;
create database job;
create database telegram;
create database podcast;
drop database redirect;
drop database cloudmanager;
drop database simpsons;
drop database job;
drop database telegram;
drop database podcast;
```
### Setup virtualenv variables
edit venv/bin/activate or .env/bin/activate
and add the following code
```
export DB_HOST=localhost
export DB_PORT=5432
export DB_USERNAME=postgres
export DB_PASSWORD=example
export DB_DATABASE=cloudmanager
export CUSTOM_DB_DATABASE=cloudmanager
export ALLOWED_HOSTS="0.0.0.0,localhost,127.0.0.1"
export DEBUG=true
export bitwarden_access_token="PROVIDED IN BITWARDEN ADMIN INTERFACE"
export bitwarden_organization_id=""
```
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
+125
View File
@@ -0,0 +1,125 @@
import requests
import hashlib
from apps.bitwarden.utils import bitwardenUtils
import os
class betaserieUtils():
url = "https://api.betaseries.com/members/auth"
username_UID="7bc7ebd2-9c95-487f-9ba2-b47301591ef0"
password_UID="262c3246-203b-44e0-854b-b47301599730"
token_UID="2cf4be0f-f26f-473f-b8f1-b473016139e4"
#Adding __ to make the variable private and can't be access outside the class,
# only by the class itself ot the subclass
__bitwarden_access_token = os.environ.get('bitwarden_access_token')
__bitwarden_organization_id = os.environ.get('bitwarden_organization_id')
bw = bitwardenUtils(__bitwarden_access_token,__bitwarden_organization_id)
__betaserie_username = bw.read_value_secret(username_UID)
__betaserie_md5_password = bw.read_value_secret(password_UID)
__betaserie_apikey = bw.read_value_secret(token_UID)
payload = {
'login': __betaserie_username, # username or email
'password': __betaserie_md5_password # MD5 hashed password
}
headers = {
'X-BetaSeries-Key': __betaserie_apikey,
}
response = requests.post(url, headers=headers, data=payload)
#now set with the correct value
__betaserie_token = response.json()['token']
#set the __betaserie_token to the doct headers now
headers.update({'X-BetaSeries-Token': __betaserie_token})
def status_code(self):
print("Status code:", self.response.status_code)
print("Response:", self.response.json())
def identify_serie(self,serie_name,verbose=False):
#
# Usage
# show_id = beta.identify_serie("The simpsons")
# show_id = beta.identify_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)
show_id = response.json()['shows'][0]['id']
return show_id
def identify_episode(self,show_id,episode_number,verbose=False):
#
# Usage
# episode_id = beta.identify_episode(show_id,"S01E01",True)
#
url = "https://api.betaseries.com/episodes/search?show_id="+str(show_id)+"&number="+str(episode_number)
response = requests.request("GET", url, headers=self.headers, data=self.payload)
episode_id = response.json()['episode']['id']
if verbose:
print("Url request: "+str(url))
print(response.text)
return episode_id
def mark_episodes_watched(self,episode_id,verbose=False):
#
# Usage
# response = beta.mark_episodes_watched(episode_id,True)
#
url = "https://api.betaseries.com/episodes/watched?id="+str(episode_id)+"&bulk=false"
response = requests.request("POST", url, headers=self.headers, data=self.payload)
if verbose:
print("Url request: "+str(url))
print(response.text)
return response.status_code
def unmark_episodes_watched(self,episode_id,verbose=False):
#
# Usage
# response = beta.unmark_episodes_watched(episode_id,True)
#
url = "https://api.betaseries.com/episodes/watched?id="+str(episode_id)
response = requests.request("DELETE", url, headers=self.headers, data=self.payload)
if verbose:
print("Url request: "+str(url))
print(response.text)
return response.status_code
def series_information(self,show_id,verbose=False):
#
# Usage
#
url = "https://api.betaseries.com/shows/display?id="+str(show_id)
response = requests.request("GET", url, headers=self.headers, data=self.payload)
maximum_number_seasons = response.json()['show']['seasons']
if verbose : print("maximum_number_seasons: "+str(maximum_number_seasons))
seasons_details = response.json()['show']['seasons_details']
if verbose:
print("Url request: "+str(url))
print(response.text)
return seasons_details,maximum_number_seasons
+87
View File
@@ -0,0 +1,87 @@
import logging
import os
from datetime import datetime, timezone
from bitwarden_sdk import BitwardenClient, DeviceType, client_settings_from_dict
class bitwardenUtils():
#documentation
#https://github.com/external-secrets/bitwarden-sdk-server
state_path = "/tmp/state_file.txt"
client = BitwardenClient(
client_settings_from_dict(
{
"apiUrl": os.getenv("API_URL", "https://bitwarden.tryton.geeraert.eu/api"),
"deviceType": DeviceType.SDK,
"identityUrl": os.getenv("IDENTITY_URL", "https://bitwarden.tryton.geeraert.eu/identity"),
"userAgent": "Python",
}
)
)
def verbose(self):
logging.basicConfig(level=logging.DEBUG)
def __init__(self, __access_token, __organization_id):
self.__access_token = __access_token
self.__organization_id = __organization_id
self.client.auth().login_access_token(self.__access_token, self.state_path)
def create_project(self,project_name):
project = self.client.projects().create(self.__organization_id, project_name)
return project.data.id
def generate_strong_password(self):
# Note: using the generator does not require authentication with a server
return self.client.generators().generate() # using default params
def create_secret(self,project_id,secret_name,secret_value,description="description"):
secret = self.client.secrets().create(
self.__organization_id,
secret_name,
secret_value,
description,
[project_id],
)
return secret.data.id
def read_value_secret(self,secret_id):
return self.client.secrets().get_by_ids([secret_id]).data.data[0].value
def read_value_secrets(self,list_secret_id):
if not(isinstance(list_secret_id, list)):
print("this is not a list")
return 1
list_secret_value = []
for secret_value in self.client.secrets().get_by_ids(list_secret_id).data.data:
list_secret_value.append(secret_value.value)
return list_secret_value
def delete_secrets(self,list_secret_id):
if not(isinstance(list_secret_id, list)):
print("this is not a list")
return 1
try:
self.client.secrets().delete(list_secret_id)
status=0
except:
print("Cannot delete the secrets")
status=1
return status
def delete_projects(self,list_project_id):
if not(isinstance(list_project_id, list)):
print("this is not a list")
return 1
try:
self.client.projects().delete(list_project_id)
status=0
except:
print("Cannot delete the project")
status=1
return status
+112
View File
@@ -0,0 +1,112 @@
from django.contrib import admin,messages
from django.utils.translation import ngettext
from .models import Deployment_Data,Schedule_Day_Data,Schedule_Week_Data,Namespace_Data,namespace_cmm_data_object
from .utils import import_namespace
from apps.kubernetes_connection.utils import scale_up,scale_down
DB = 'cloudmanager_db'
@admin.action(description="scale up")
def scale_up_deploy(modeladmin, request, queryset):
for query in queryset.values():
scale_up(namespace_name=query['namespace'],deploy_name=query['name'],replicas=query['replicas'])
modeladmin.message_user(
request,
ngettext(
"%d server was successfully scaled up.",
"%d servers were successfully scaled up.",
queryset.values().count(),
)
% queryset.values().count(),
messages.SUCCESS,
)
@admin.action(description="scale down")
def scale_down_deploy(modeladmin, request, queryset):
for query in queryset.values():
scale_down(namespace_name=query['namespace'],deploy_name=query['name'])
modeladmin.message_user(
request,
ngettext(
"%d server was successfully scaled down.",
"%d servers were successfully scaled down.",
queryset.values().count(),
)
% queryset.values().count(),
messages.SUCCESS,
)
@admin.action(description="create_entry")
def create_entry(modeladmin, request, queryset):
print("simpsons_data_object.create(season=2, episode=3, url='google.com'', seen=True)")
#call function to trigger refresh of all deploy
@admin.action(description="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
class ActiveAtHourFilter(admin.SimpleListFilter):
title = 'Active at hour'
parameter_name = 'active_at_hour'
def lookups(self, request, model_admin):
return [(str(h), f'{h:02d}:00') for h in range(24)]
def queryset(self, request, queryset):
if self.value() is not None:
hour = self.value()
return queryset.filter(**{f'schedule_day__state_at_{hour}': True})
return queryset
class MultiDBModelAdmin(admin.ModelAdmin):
"""Base class that pins all admin operations to DB."""
db = DB
def get_queryset(self, request):
return super().get_queryset(request).using(self.db)
def save_model(self, request, obj, form, change):
obj.save(using=self.db)
def delete_model(self, request, obj):
obj.delete(using=self.db)
def delete_queryset(self, request, queryset):
queryset.using(self.db).delete()
@admin.register(Deployment_Data)
class DeploymentDataAdmin(MultiDBModelAdmin):
list_display = ('name', 'namespace', 'schedule_week', 'schedule_day', 'replicas')
list_filter = (ActiveAtHourFilter,)
actions = [scale_up_deploy,scale_down_deploy]
@admin.register(Schedule_Day_Data)
class ScheduleDayAdmin(MultiDBModelAdmin):
list_display = ['name_schedule'] + [f'state_at_{h}' for h in range(24)]
@admin.register(Schedule_Week_Data)
class ScheduleWeekAdmin(MultiDBModelAdmin):
list_display = (
'name_schedule',
'state_Monday', 'state_Tuesday', 'state_Wednesday',
'state_Thursday', 'state_Friday', 'state_Saturday', 'state_Sunday',
)
@admin.register(Namespace_Data)
class NamespaceAdmin(MultiDBModelAdmin):
list_display = ('namespace',)
actions = [import_namespace_admin]
+37
View File
@@ -0,0 +1,37 @@
from django.apps import AppConfig
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.shortcuts import render
import os
import psycopg2
from apps.cloudmanager.db_interaction import DB_generation,Check_server_supposed_XXX,Give_current_weekday,Give_current_hour
class CloudmanagerConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.cloudmanager'
label = 'cloudmanager'
def coucou(request):
return HttpResponse('<h1>Hello cmm!</h1>')
def hello(request):
list_schedule = ['schedule1','schedule2']
list_servers_up = [['wiki', 'wikijs', 2], ['book', 'bookstack-db', 1]]
return render(request, 'cloudmanager/index.html', {'list_schedule':list_schedule,'list_servers_up':list_servers_up})
def redirect(request):
db_host = os.environ.get('DB_HOST')
db_port = os.environ.get('DB_PORT')
db_user = os.environ.get('DB_USERNAME')
db_password = os.environ.get('DB_PASSWORD')
db_name = os.environ.get('CUSTOM_DB_DATABASE',os.environ.get('DB_DATABASE'))
generated_db = DB_generation(db_host, db_port, db_user, db_password,db_name)
##operation:
## Server(s) supposed to be UP
list_servers_up = Check_server_supposed_XXX(generated_db, "up", Give_current_hour(),Give_current_weekday())
print(list_servers_up)
return render(request, 'cloudmanager/cmm_blank_page.html', {'list_servers_up':list_servers_up})
@@ -0,0 +1,7 @@
class sql:
url = 'localhost'
port = 5432
user = 'postgres'
password = 'example'
database = 'cloudmanager'
@@ -0,0 +1,167 @@
import psycopg2
from django.http import HttpResponse
from django.views.decorators.http import require_POST
from apps.kubernetes_connection import apps as kubernetes_connection
import datetime
from apps.cloudmanager import credentials
import os
def hello(request):
kubernetes_connection.echoHello();
return HttpResponse('<h1>Hello cmm !</h1>')
def DB_generation(host_in,port_in,user_in,password_in,db_in):
db = psycopg2.connect(host=host_in, port=port_in, user=user_in, password=password_in,database=db_in)
return db
@require_POST
def change_schedule(request):
# HTMX sends these via standard POST data
schedule_id = request.POST.get('schedule_id')
server_name = request.POST.get('server_name')
if not schedule_id or not server_name:
return HttpResponse("<span style='color: red;'>Missing parameters.</span>", status=400)
try:
# --- Your Core Logic Here ---
# e.g., Server.objects.filter(name=server_name).update(schedule_id=schedule_id)
print(f"Updating {server_name} to schedule profile {schedule_id}")
# Return a success message that will instantly inject into the server's status div
return HttpResponse("<span style='color: green;'>✓ Updated successfully!</span>")
except Exception as e:
return HttpResponse(f"<span style='color: red;'>Error: {str(e)}</span>", status=500)
def Launch_sql_query(sql,db):
# prepare a cursor object using cursor() method
cursor = db.cursor()
try:
# Execute the SQL command
cursor.execute(sql)
# Fetch all the rows in a list of lists.
results = cursor.fetchall()
result_machine = []
#result_machine_type = []
for row in results:
result_machine_type = []
namespace = row[0]
name = row[1]
replicas = row[2]
result_machine_type.append(namespace)
result_machine_type.append(name)
result_machine_type.append(replicas)
result_machine.append(result_machine_type)
return result_machine
except:
print ("Error: unable to fetch data")
#Return the day of the week as an integer, where Monday is 0 and Sunday is 6.
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 Check_server_supposed_XXX(generated_db_in,wanted_status,Wanted_hour,Wanted_day):
sql_in=""
if wanted_status == "up":
sql_in = "select machine.namespace, machine.name, machine.replicas from scenario_hour,machine ,scenario_day_of_week where state_at_" + str(Wanted_hour) + "='1' and state_" + str(Wanted_day) + "='1' and machine.hour_behaviour_id=scenario_hour.id_scenario and machine.day_behaviour_id=scenario_day_of_week.id_scenario;"
elif wanted_status == "down":
sql_in = "select machine.namespace, machine.name, machine.replicas from scenario_hour,machine ,scenario_day_of_week where not(state_at_" + str(Wanted_hour) + "='1' and state_" + str(Wanted_day) + "='1') and machine.hour_behaviour_id=scenario_hour.id_scenario and machine.day_behaviour_id=scenario_day_of_week.id_scenario;"
else:
print("error value")
print(sql_in)
return_value = Launch_sql_query(sql_in, generated_db_in)
return return_value
def Is_the_server_already_wanted_state(id_machine, wanted_state,instance_type):
#stopped/running
bool_result = ""
proxmox = function.proxmox_connection(credentials.proxmox.zeus.url_proxmox,credentials.proxmox.zeus.user,credentials.proxmox.zeus.password)
if str(function.check_state_mix(id_machine,wanted_state,proxmox,instance_type)) == str(wanted_state):
bool_result = True
else:
bool_result = False
return bool_result
def all_operations(request,wanted_state,list_machine):
for machine_target in list_machine:
print(machine_target[1])
info_to_display = ""
if wanted_state == "up":
kubernetes_connection.scale_up(request,namespace_name=machine_target[0],deploy_name=machine_target[1],replicas=machine_target[2]);
elif wanted_state == "down":
kubernetes_connection.scale_down(request,namespace_name=machine_target[0],deploy_name=machine_target[1]);
else:
print("Incorrect wanted state")
# if not(Is_the_server_already_wanted_state(machine_target[0], wanted_state,machine_target[1])):
# function.action(False,machine_target[0],operation_to_perform,machine_target[1])
# print(str(machine_target[0])+" is now "+str(wanted_state))
# elif Is_the_server_already_wanted_state(machine_target[0], wanted_state,machine_target[1]):
# info_to_display = "operation already performed for "+machine_target[2]
# print(info_to_display)
#return info_to_display
return ""
def main(request):
#get credentials from the env
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("------------------------------------------")
print("-----------------UP-----------------------")
print("------------------------------------------")
print(list_servers_up)
print(all_operations(request,"up", list_servers_up))
## Server(s) supposed to be DOWN
list_servers_down = Check_server_supposed_XXX(generated_db, "down", Give_current_hour(),Give_current_weekday())
print("------------------------------------------")
print("----------------DOWN----------------------")
print("------------------------------------------")
print(list_servers_down)
print(all_operations(request,"down",list_servers_down))
# disconnect from server
generated_db.close()
#print(Is_the_server_already_wanted_state(112, "stopped"))
return HttpResponse('<h1>CMM executed!</h1>')
if __name__ == "__main__":
main()
"""
TO DO:
EXTRACT TYPE OF MACHINE
CREATE FUNCTION TO CHECK IF A MACHINE IS ALREADY DOWN OR NOT
ADD FIELD IN SQL WITH PROJECT AND PUT DESCRIPTION -> ATTACH MACHINE TO PROJECT
"""
@@ -0,0 +1,90 @@
# Generated by Django 4.2.29 on 2026-06-22 20:21
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Namespace_Data',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('namespace', models.CharField(max_length=100)),
],
options={
'db_table': 'namespace',
},
),
migrations.CreateModel(
name='Schedule_Day_Data',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name_schedule', models.CharField(max_length=100, unique=True)),
('state_at_0', models.BooleanField()),
('state_at_1', models.BooleanField()),
('state_at_2', models.BooleanField()),
('state_at_3', models.BooleanField()),
('state_at_4', models.BooleanField()),
('state_at_5', models.BooleanField()),
('state_at_6', models.BooleanField()),
('state_at_7', models.BooleanField()),
('state_at_8', models.BooleanField()),
('state_at_9', models.BooleanField()),
('state_at_10', models.BooleanField()),
('state_at_11', models.BooleanField()),
('state_at_12', models.BooleanField()),
('state_at_13', models.BooleanField()),
('state_at_14', models.BooleanField()),
('state_at_15', models.BooleanField()),
('state_at_16', models.BooleanField()),
('state_at_17', models.BooleanField()),
('state_at_18', models.BooleanField()),
('state_at_19', models.BooleanField()),
('state_at_20', models.BooleanField()),
('state_at_21', models.BooleanField()),
('state_at_22', models.BooleanField()),
('state_at_23', models.BooleanField()),
],
options={
'db_table': 'schedule_day',
},
),
migrations.CreateModel(
name='Schedule_Week_Data',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name_schedule', models.CharField(max_length=100, unique=True)),
('state_Monday', models.BooleanField()),
('state_Tuesday', models.BooleanField()),
('state_Wednesday', models.BooleanField()),
('state_Thursday', models.BooleanField()),
('state_Friday', models.BooleanField()),
('state_Saturday', models.BooleanField()),
('state_Sunday', models.BooleanField()),
],
options={
'db_table': 'schedule_week',
},
),
migrations.CreateModel(
name='Deployment_Data',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('namespace', models.CharField(max_length=100)),
('replicas', models.IntegerField()),
('schedule_day', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cloudmanager.schedule_day_data')),
('schedule_week', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cloudmanager.schedule_week_data')),
],
options={
'db_table': 'machine',
},
),
]
+65
View File
@@ -0,0 +1,65 @@
from django.db import models
class Schedule_Week_Data(models.Model):
name_schedule = models.CharField(max_length=100,unique=True)
state_Monday = models.BooleanField()
state_Tuesday = models.BooleanField()
state_Wednesday = models.BooleanField()
state_Thursday = models.BooleanField()
state_Friday = models.BooleanField()
state_Saturday = models.BooleanField()
state_Sunday = models.BooleanField()
class Meta:
db_table = 'schedule_week'
def __str__(self):
return self.name_schedule
class Schedule_Day_Data(models.Model):
name_schedule = models.CharField(max_length=100,unique=True)
state_at_0 = models.BooleanField()
state_at_1 = models.BooleanField()
state_at_2 = models.BooleanField()
state_at_3 = models.BooleanField()
state_at_4 = models.BooleanField()
state_at_5 = models.BooleanField()
state_at_6 = models.BooleanField()
state_at_7 = models.BooleanField()
state_at_8 = models.BooleanField()
state_at_9 = models.BooleanField()
state_at_10 = models.BooleanField()
state_at_11 = models.BooleanField()
state_at_12 = models.BooleanField()
state_at_13 = models.BooleanField()
state_at_14 = models.BooleanField()
state_at_15 = models.BooleanField()
state_at_16 = models.BooleanField()
state_at_17 = models.BooleanField()
state_at_18 = models.BooleanField()
state_at_19 = models.BooleanField()
state_at_20 = models.BooleanField()
state_at_21 = models.BooleanField()
state_at_22 = models.BooleanField()
state_at_23 = models.BooleanField()
class Meta:
db_table = 'schedule_day'
def __str__(self):
return self.name_schedule
class Deployment_Data(models.Model):
name = models.CharField(max_length=100)
namespace = models.CharField(max_length=100)
schedule_week = models.ForeignKey(Schedule_Week_Data,null=True, blank=True, on_delete=models.SET_NULL)
schedule_day = models.ForeignKey(Schedule_Day_Data,null=True, blank=True, on_delete=models.SET_NULL)
replicas = models.IntegerField()
class Meta:
db_table = 'machine'
class Namespace_Data(models.Model):
namespace = models.CharField(max_length=100)
#deployments = models.ForeignKey(Schedule_Week_Data,null=True, blank=True, on_delete=models.SET_NULL)
class Meta:
db_table = 'namespace'
namespace_cmm_data_object = Namespace_Data.objects.using('cloudmanager_db')
+13
View File
@@ -0,0 +1,13 @@
from apps.kubernetes_connection.utils import get_namespace
def import_namespace(queryset):
namespaces_list = get_namespace()
for namespace in namespaces_list:
queryset.create(namespace=namespace)
def import_deployment(queryset):
namespaces_list = get_namespace()
#for namespace in namespaces_list:
# queryset.create(namespace=namespace)
+25
View File
@@ -0,0 +1,25 @@
from django.http import HttpResponse
# IMPORT AT THE TOP HERE: This is completely safe!
from apps.cloudmanager.models import Deployment_Data,Schedule_Week_Data
def coucou(request):
# 1. Prepare the data inside the function
data = CmmData(
name="test",
namespace="testspace",
schedule_hour="1",
schedule_day="deux",
replicas=3
)
# 2. This line actually pushes the data into your cloudmanager_db!
data.save()
return HttpResponse('<h1>Hello cmm! Data saved successfully!</h1>')
def display(request):
data = CmmData.objects.all()
print(data[0].namespace)
return HttpResponse(data)
+21
View File
@@ -0,0 +1,21 @@
from django.shortcuts import render
def home(request):
thislist = ["apple", "banana", "cherry"]
return render(request, 'dashboard/home.html',{'thislist': thislist})
def about(request):
thislist = ["apple", "banana", "cherry"]
return render(request, 'dashboard/about.html',{'thislist': thislist})
def success(request):
return render(request, 'dashboard/start.html',{'deployment': 'django','url':'https://google.com'})
def scale_up(request,namespace_name,deploy_name):
baseurl = "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path)
return render(request, 'dashboard/start.html', {'namespace':namespace_name,'deployment': deploy_name, 'url': 'https://namespace.com','baseurl': baseurl})
def scale_down(request,namespace_name,deploy_name):
baseurl = "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path)
return render(request, 'dashboard/shutdown.html', {'namespace':namespace_name,'deployment': deploy_name, 'url': 'https://namespace.com','baseurl': baseurl})
+40
View File
@@ -0,0 +1,40 @@
from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from import_export import resources
from import_export.fields import Field
from .models import JobData
from django.utils.text import Truncator
# Register your models here.
class JobResource(resources.ModelResource):
# Map 'csv_column_name' from the file to 'model_variable_name' in your DB
job_position = Field(attribute='job_position',column_name='Job Position')
company = Field(attribute='company',column_name='Company')
URL = Field(attribute='URL',column_name='URL')
status = Field(attribute='status',column_name='Status')
date_saved = Field(attribute='date_saved',column_name='Date Saved')
date_applied = Field(attribute='date_applied',column_name='Date Applied')
type = Field(attribute='type',column_name='Type')
resume = Field(attribute='resume',column_name='Resume')
#cover_letter = Field(attribute='cover_letter',column_name='Cover Letter')
location = Field(attribute='location',column_name='Location')
job_description = Field(attribute='job_description',column_name='Job Description')
salary = Field(attribute='salary',column_name='Salary')
contact = Field(attribute='contact',column_name='Contact')
source = Field(attribute='source',column_name='Source')
class Meta:
model = JobData
@admin.register(JobData)
class JobAdmin(ImportExportModelAdmin):
list_display = ('job_position','company','URL','status','date_saved','date_applied','type','resume','location','short_description','salary','contact','source')
#fields = ['job_position','company','URL','status','date_saved','date_applied','type','resume','cover_letter','location','job_description','salary ','contact','source']
resource_classes = [JobResource]
def short_description(self, obj):
return Truncator(obj.job_description).words(10, truncate=' ...')
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class JobDashboardConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.job_dashboard'
label = 'job'
@@ -0,0 +1,36 @@
# Generated by Django 4.2.29 on 2026-06-22 20:21
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='JobData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('job_position', models.CharField(max_length=100, null=True)),
('company', models.CharField(max_length=100, null=True)),
('URL', models.URLField(max_length=1000, null=True)),
('status', models.CharField(choices=[('Rejected', 'Rejected'), ('Applied', 'Applied'), ('Negotiating', 'Negotiating'), ('Bookmarked', 'Bookmarked'), ('Accepted', 'Accepted')], max_length=100, null=True)),
('date_saved', models.CharField(max_length=100, null=True)),
('date_applied', models.CharField(max_length=100, null=True)),
('type', models.CharField(max_length=100, null=True)),
('resume', models.URLField(null=True)),
('location', models.CharField(max_length=100, null=True)),
('job_description', models.CharField(null=True)),
('salary', models.CharField(null=True)),
('contact', models.CharField(max_length=100, null=True)),
('source', models.CharField(max_length=100, null=True)),
],
options={
'db_table': 'job',
},
),
]
+29
View File
@@ -0,0 +1,29 @@
from django.db import models
status_CHOICES = (
('Rejected','Rejected'),
('Applied','Applied'),
('Negotiating','Negotiating'),
('Bookmarked','Bookmarked'),
('Accepted','Accepted')
)
class JobData(models.Model):
job_position = models.CharField(max_length=100, null=True)
company = models.CharField(max_length=100, null=True)
URL = models.URLField(max_length=1000,null=True)
status = models.CharField(max_length=100,choices=status_CHOICES, null=True)
date_saved = models.CharField(max_length=100, null=True)
date_applied = models.CharField(max_length=100, null=True)
type = models.CharField(max_length=100, null=True)
resume = models.URLField(max_length=200, null=True)
#cover_letter = models.URLField(max_length=200, null=True)
location = models.CharField(max_length=100, null=True)
job_description = models.CharField(null=True)
salary = models.CharField(null=True)
contact = models.CharField(max_length=100, null=True)
source = models.CharField(max_length=100, null=True)
class Meta:
db_table = 'job'
+23
View File
@@ -0,0 +1,23 @@
"""
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.contrib import admin
from django.urls import path
urlpatterns = [
path('', admin.site.urls),
]
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
@@ -14,18 +14,23 @@ import ruamel.yaml
import yaml
import urllib.request
def hello(request):
return HttpResponse('<h1>Hello k8s!</h1>')
def scale_up(request,namespace_name,deploy_name):
def echoHello():
print("hello from k8s")
return "returned from k8s"
def scale_up(request,namespace_name,deploy_name,replicas=1):
config.load_kube_config(config_file='/kubeconfig/config')
api = client.AppsV1Api()
deployment = api.read_namespaced_deployment(name=deploy_name, namespace=namespace_name)
deployment.spec.replicas = 1
deployment.spec.replicas = replicas
resp = api.patch_namespaced_deployment(
name=deploy_name, namespace=namespace_name, body=deployment);
#return HttpResponse('<h1>Scaled up !</h1>')
return render(request, 'start.html', {'namespace':namespace_name,'deployment': deploy_name, 'url': 'https://namespace.com'})
return render(request, 'dashboard/start.html', {'namespace':namespace_name,'deployment': deploy_name, 'url': 'https://namespace.com'})
def scale_down(request,namespace_name,deploy_name):
@@ -36,7 +41,7 @@ def scale_down(request,namespace_name,deploy_name):
resp = api.patch_namespaced_deployment(
name=deploy_name, namespace=namespace_name, body=deployment);
#return HttpResponse('<h1>Scaled down !</h1>')
return render(request, 'shutdown.html',
return render(request, 'dashboard/shutdown.html',
{'namespace': namespace_name, 'deployment': deploy_name, 'url': 'https://namespace.com'})
def nodes(request):
@@ -0,0 +1,57 @@
from kubernetes import client, config
def scale_up(namespace_name,deploy_name,replicas=1):
config.load_kube_config(config_file='/kubeconfig/config')
api = client.AppsV1Api()
deployment = api.read_namespaced_deployment(name=deploy_name, namespace=namespace_name)
deployment.spec.replicas = replicas
resp = api.patch_namespaced_deployment(
name=deploy_name, namespace=namespace_name, body=deployment);
return 0
def scale_down(namespace_name,deploy_name):
config.load_kube_config(config_file='/kubeconfig/config')
api = client.AppsV1Api()
deployment = api.read_namespaced_deployment(name=deploy_name, namespace=namespace_name)
deployment.spec.replicas = 0
resp = api.patch_namespaced_deployment(
name=deploy_name, namespace=namespace_name, body=deployment);
return 0
def import_Deployments():
config.load_kube_config(config_file='/kubeconfig/config')
api = client.AppsV1Api()
deployment = api.list_deployment_for_all_namespaces()
for i in range(1,len(deployment.items)):
print(deployment.items[i].spec.template.spec.containers[0].name)
len(deployment.items) #list all deployment inside the namespace
test.items[0].spec.template.spec.containers[0].name # name the first deploy within the namespace
test.items[2].spec.template.spec.containers[0].name # name the third deploy within the namespace
return 0
def get_namespace():
config.load_kube_config(config_file='/kubeconfig/config')
core = client.CoreV1Api()
namespace = core.list_namespace()
namespace_list = []
for i in range(0,len(namespace.items)):
print(namespace.items[i].metadata.name)
namespace_list.append(namespace.items[i].metadata.name)
return namespace_list
def get_deployments():
config.load_kube_config(config_file='/kubeconfig/config')
api = client.AppsV1Api()
namespaces_list = get_namespace()
deployments_list = []
for namespace in namespaces_list:
print(namespace)
deployments = api.list_namespaced_deployment(namespace)
for deployment_index in range(0,len(deployments.items)):
deployment = deployments.items[deployment_index].metadata.name
print(" "+str(deployment))
deployments_list.append([namespace,deployment])
return deployments_list
@@ -0,0 +1,9 @@
from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from import_export import resources
from .models import podcastData
# Register your models here.
@admin.register(podcastData)
class JobAdmin(ImportExportModelAdmin):
list_display = ('podcast_name','podcast_url','enabled')
@@ -0,0 +1,7 @@
from django.apps import AppConfig
class PodcastAggregatorConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.podcast_aggregator'
label = 'podcast'
@@ -0,0 +1,25 @@
# Generated by Django 4.2.29 on 2026-06-30 22:05
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='podcastData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('podcast_name', models.CharField(max_length=100, null=True)),
('podcast_url', models.CharField(max_length=100, null=True)),
],
options={
'db_table': 'podcasts',
},
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.29 on 2026-06-30 22:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('podcast', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='podcastdata',
name='enabled',
field=models.BooleanField(default=True),
),
]
@@ -0,0 +1,8 @@
from django.db import models
class podcastData(models.Model):
podcast_name = models.CharField(max_length=100, null=True)
podcast_url = models.CharField(max_length=100, null=True)
enabled = models.BooleanField(default=True)
class Meta:
db_table = 'podcasts'
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
@@ -0,0 +1,89 @@
import requests
import xmltodict
from urllib import request as urlrequest
import tempfile
#Django import
from apps.telegram_communication.utils import telegramUtils
from .models import podcastData
proxy_url = 'http://gluetun-svc.gluetun.svc:8888'
proxy = urlrequest.ProxyHandler({
'http': proxy_url,
'https': proxy_url # Add the handler for HTTPS
})
proxies = {
"http" : proxy_url,
"https" : proxy_url
}
def rss_to_dict(url):
response = requests.get(url)
data = xmltodict.parse(response.content)
print(data['rss'])
title = data['rss']['channel']['title']
#Get the keys if needed of debug
#print(data['rss'].keys())
#use first object as it's ordered in a chronological order
today_object = data['rss']['channel']['item']
if isinstance(today_object, list):
today_object = data['rss']['channel']['item'][0]
today_title = today_object['title']
today_podcast_url = today_object['enclosure']['@url']
return title,today_title,today_podcast_url
def download_news_mp3(url_mp3, filename):
opener = urlrequest.build_opener(proxy)
urlrequest.install_opener(opener)
print("Downloading : " + filename +" -- " + url_mp3)
try:
urlrequest.urlretrieve(url_mp3, filename)
except:
print("Can't download " + filename +" -- " + url_mp3 + " == Cancelling")
return 0
def pretty_filename(filename,extension=''):
filename = filename.replace(' ', '_')
pretty_filename = filename.replace('/', '_')
if extension != '':
extension = str('.'+extension)
return pretty_filename+extension
def podcasts():
telegram = telegramUtils()
#clear all expired messages before
telegram.clear_expired_messages()
podcasts = podcastData.objects.filter(enabled=True)
for podcast in podcasts:
url = podcast.podcast_url
today_podcast = rss_to_dict(url)
print(today_podcast)
pretty_file_name = pretty_filename(today_podcast[1],'mp3')
temp = tempfile.TemporaryDirectory()
temp_path = temp.name.replace("\\", "/")
file_path = temp_path+"/"+pretty_file_name
download_news_mp3(today_podcast[2],file_path)
print(file_path)
telegram.send_document(file_path,str(today_podcast[0])+" "+str(today_podcast[1]))
#main()
@@ -0,0 +1,7 @@
from django.http import HttpResponse
from .utils import podcasts
# Create your views here.
def execute_podcast(request):
podcasts()
return HttpResponse('<h1>Generating the podcast!</h1>')
+97
View File
@@ -0,0 +1,97 @@
from django.contrib import admin,messages
from django.utils.translation import ngettext
from prompt_toolkit.shortcuts import print_container
from .models import SimpsonsData,simpsons_data_object,urlData
from .utils import mark_episode_watched,unwatch_all_episodes,generate_new_urls_for_episode
from import_export import resources
from import_export.admin import ImportExportModelAdmin
from django.utils import timezone
# Register your models here.
DB = 'simpsons_db'
@admin.action(description="Mark episode as seen")
def make_seen(modeladmin, request, queryset):
updated = queryset.update(seen="True",modified_at=timezone.now())
for query in queryset.values():
print(query)
season_number = query.get('season')
episode_number = query.get('episode')
mark_episode_watched(season_number,episode_number,"watched")
modeladmin.message_user(
request,
ngettext(
"%d episode was successfully marked as seen.",
"%d episodes were successfully marked as seen.",
updated,
)
% updated,
messages.SUCCESS,
)
@admin.action(description="Mark episode as not seen")
def make_unseen(modeladmin, request, queryset):
updated = queryset.update(seen="False")
for query in queryset.values():
print(query)
season_number = query.get('season')
episode_number = query.get('episode')
mark_episode_watched(season_number,episode_number,"unwatched")
modeladmin.message_user(
request,
ngettext(
"%d episode was successfully marked as not seen.",
"%d episodes were successfully marked as not seen.",
updated,
)
% updated,
messages.SUCCESS,
)
@admin.action(description="mark all of them as unseen on betaserie")
def unseen_betaserie(modeladmin, request, queryset):
unwatch_all_episodes()
@admin.action(description="generate new urls for episode")
def generate_new_urls(modeladmin, request, queryset):
generate_new_urls_for_episode()
@admin.register(SimpsonsData)
class EpisodeAdmin(ImportExportModelAdmin):
list_display = [field.name for field in SimpsonsData._meta.fields if field.name != 'id']
list_filter = ['seen','modified_at']
#list_filter = ['seen']
fields = ['season', 'episode', 'url', 'seen']
actions = [make_seen,make_unseen,unseen_betaserie,generate_new_urls]
search_fields = ['season', 'episode', 'url', 'seen']
def get_queryset(self, request):
return super().get_queryset(request).using(DB)
def save_model(self, request, obj, form, change):
obj.save(using=DB)
def delete_model(self, request, obj):
obj.delete(using=DB)
def delete_queryset(self, request, queryset):
queryset.using(DB).delete()
@admin.register(urlData)
class urldataAdmin(ImportExportModelAdmin):
list_display = ('url_example', 'prefix', 'infix', 'suffix','addedDate')
fieldsets = [
(
None,
{
'fields': (('prefix', 'infix', 'suffix'), 'url_example')
},
)
]
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class RandomSimpsonsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.random_simpsons'
label = 'simpsons'
@@ -0,0 +1,27 @@
# Generated by Django 4.2.29 on 2026-06-22 20:21
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='SimpsonsData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('season', models.IntegerField()),
('episode', models.IntegerField()),
('url', models.CharField(max_length=1000)),
('seen', models.BooleanField()),
],
options={
'db_table': 'episodes',
},
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.29 on 2026-07-05 13:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('simpsons', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='simpsonsdata',
name='modified_at',
field=models.DateTimeField(auto_now=True),
),
]
@@ -0,0 +1,19 @@
# Generated by Django 4.2.29 on 2026-07-05 13:40
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('simpsons', '0002_simpsonsdata_modified_at'),
]
operations = [
migrations.AlterField(
model_name='simpsonsdata',
name='modified_at',
field=models.DateTimeField(default=datetime.datetime(1970, 1, 1, 0, 0)),
),
]
@@ -0,0 +1,17 @@
# Generated by Django 4.2.29 on 2026-07-05 13:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('simpsons', '0003_alter_simpsonsdata_modified_at'),
]
operations = [
migrations.RemoveField(
model_name='simpsonsdata',
name='modified_at',
),
]
@@ -0,0 +1,19 @@
# Generated by Django 4.2.30 on 2026-07-07 08:35
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('simpsons', '0004_remove_simpsonsdata_modified_at'),
]
operations = [
migrations.AddField(
model_name='simpsonsdata',
name='modified_at',
field=models.DateTimeField(default=datetime.datetime(1970, 1, 1, 0, 0)),
),
]
@@ -0,0 +1,27 @@
# Generated by Django 4.2.30 on 2026-07-07 08:40
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('simpsons', '0005_simpsonsdata_modified_at'),
]
operations = [
migrations.CreateModel(
name='urlData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url_example', models.CharField(max_length=1000)),
('prefix', models.CharField(max_length=1000)),
('infix', models.CharField(max_length=1000)),
('suffix', models.CharField(max_length=1000)),
('addedDate', models.DateField(auto_now_add=True, null=True, verbose_name='Published')),
],
options={
'db_table': 'redirectUrl',
},
),
]
@@ -0,0 +1,28 @@
# Generated by Django 4.2.30 on 2026-07-07 08:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('simpsons', '0006_urldata'),
]
operations = [
migrations.AlterField(
model_name='urldata',
name='infix',
field=models.CharField(help_text='8&episode=', max_length=1000),
),
migrations.AlterField(
model_name='urldata',
name='prefix',
field=models.CharField(help_text='https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=', max_length=1000),
),
migrations.AlterField(
model_name='urldata',
name='url_example',
field=models.CharField(help_text='https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=18&episode=5', max_length=1000),
),
]
@@ -0,0 +1,34 @@
# Generated by Django 4.2.30 on 2026-07-07 09:28
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('simpsons', '0007_alter_urldata_infix_alter_urldata_prefix_and_more'),
]
operations = [
migrations.AlterField(
model_name='simpsonsdata',
name='modified_at',
field=models.DateTimeField(default=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)),
),
migrations.AlterField(
model_name='urldata',
name='infix',
field=models.CharField(blank=True, help_text='&episode=', max_length=1000, null=True),
),
migrations.AlterField(
model_name='urldata',
name='prefix',
field=models.CharField(blank=True, help_text='https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=', max_length=1000, null=True),
),
migrations.AlterField(
model_name='urldata',
name='suffix',
field=models.CharField(blank=True, max_length=1000, null=True),
),
]
@@ -0,0 +1,27 @@
from django.db import models
from datetime import datetime
from django.utils.timezone import make_aware
EPOCH = make_aware(datetime(1970, 1, 1))
class SimpsonsData(models.Model):
season = models.IntegerField()
episode = models.IntegerField()
url = models.CharField(max_length=1000)
seen = models.BooleanField()
modified_at = models.DateTimeField(default=EPOCH)
class Meta:
db_table = 'episodes'
class urlData(models.Model):
url_example = models.CharField(max_length=1000, help_text="https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=18&episode=5")
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)
class Meta:
db_table = 'redirectUrl'
simpsons_data_object = SimpsonsData.objects.using('simpsons_db')
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+92
View File
@@ -0,0 +1,92 @@
from django.db.models import Count
from django.core.exceptions import MultipleObjectsReturned
from celery.worker.state import active_requests
from requests.compat import str
from django.utils import timezone
from apps.betaserie.utils import betaserieUtils
from .models import simpsons_data_object,urlData
betaserie = betaserieUtils()
simpsons_id = 12
def mark_episode_watched(season,episode,action,verbose=False):
#mark episode as seen in DB
simpsons_data_object.filter(season=season, episode=episode).values('seen').update(seen=True,modified_at=timezone.now())
if verbose : print("season_number: "+str(season))
if verbose : print("episode_number: "+str(episode))
#mark episode as seen in betaserie
episode_number = "S"+str(season)+"E"+str(episode)
episode_id = betaserie.identify_episode(simpsons_id,episode_number)
if action == "watched":
betaserie.mark_episodes_watched(episode_id)
elif action == "unwatched":
betaserie.unmark_episodes_watched(episode_id)
else:
print("Parameter action not in range")
def unwatch_all_episodes():
maximum_number_of_seasons = simpsons_data_object.aggregate(unique_season=Count('season', distinct=True))['unique_season']
print("maximum_number_of_seasons: "+str(maximum_number_of_seasons))
for season in range(1,maximum_number_of_seasons+1):
maximum_number_of_episodes = simpsons_data_object.filter(season=season).count()
print("maximum_number_of_episodes for "+str(season)+": "+str(maximum_number_of_episodes))
for episode in range(1,maximum_number_of_episodes+1):
print("S"+str(season)+"E"+str(episode))
mark_episode_watched(season,episode,"unwatched")
def generate_new_urls_for_episode(verbose=False):
# kisscartoons didn't work anymore so moving to another website with the format:
# URL.com/simpsons/season=XX&episode=XX
# example
# https://www.1shows.org/tv/456-the-simpsons?streaming=true&season=33&episode=18
simpsons_series_information = betaserie.series_information(simpsons_id)
seasons_information = simpsons_series_information[0]
#for the simpsons, there is a season 0 which increase the count of seasons by 1
# we need to remove this entry ,
# so we cannot trust the maximum_number_season coming from simpsons_series_information
season_0_to_remove = seasons_information[0]
if verbose : print(season_0_to_remove)
seasons_information.remove(season_0_to_remove)
maximum_number_season = len(seasons_information)
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
# we need to add -1
number_episodes_in_season = int(seasons_information[season-1]['episodes'])
for episode in range(1,number_episodes_in_season+1):
if verbose : print("Season: "+str(season))
if verbose : print("episode: "+str(episode))
new_url_object = urlData.objects.all().order_by('-addedDate').first()
new_url = str(new_url_object.prefix)+str(season)+str(new_url_object.infix)+str(episode)+str(new_url_object.suffix)
if verbose : print(new_url)
try:
obj,created = simpsons_data_object.get_or_create(
season=season,
episode=episode,
defaults={"url":new_url,"seen":"False"}
)
obj.url=new_url
obj.save()
except MultipleObjectsReturned:
print("duplicated object for season: "+str(episode)+" episode: "+str(episode)+", ignoring")
return 0
+75
View File
@@ -0,0 +1,75 @@
from django.http import HttpResponse
from django.db.models import Count
from django.shortcuts import redirect
from .models import SimpsonsData,simpsons_data_object
from .utils import mark_episode_watched
import random
import threading
def hello(request):
return HttpResponse('<h1>Hello Simpsons view!</h1>')
def episode_generator(request):
boolean_restart = True;
simpsons_object = {}
while (boolean_restart):
maximum_number_of_seasons = simpsons_data_object.aggregate(unique_season=Count('season', distinct=True))['unique_season']
random_season = random.randint(1, maximum_number_of_seasons)
print("random season: " + str(random_season))
simpsons_object = simpsons_data_object.filter(season=random_season)
maximum_number_of_episodes = simpsons_object.count()
random_episode = random.randint(1, maximum_number_of_episodes)
print("random episode: " + str(random_episode))
simpsons_object = simpsons_object.filter(episode=random_episode)
episode_seen = simpsons_object.values('seen')[0]['seen']
if not(episode_seen):
boolean_restart = False
else:
print("episode "+str(random_episode)+" from season "+str(random_season)+" already seen")
#Set episode as seen
# It will still update an already seem episode but it works and I'm lazy
#Mark episode as seen on betaseries
thread = threading.Thread(
target=mark_episode_watched,
args=(random_season, random_episode, "watched"),
daemon=True,
)
thread.start()
random_url = simpsons_object.values('url')[0]['url']
return redirect(str(random_url))
def download_file(request):
# fill these variables with real values
fl_path = '/data/download/sonarr'
filename = 'The.Boys.2019.S04E05.2160p.HDR10Plus.WEBRip.6CH.x265.HEVC-PSA.mkv'
# fl = open(fl_path, 'r')
# mime_type, _ = mimetypes.guess_type(fl_path)
# response = HttpResponse(fl, content_type=mime_type)
# response['Content-Disposition'] = "attachment; filename=%s" % filename
some_file = open('/data/kubernetes/Backup/nextcloud/notes/2024-07-28/Course.md', "r")
django_file = File(some_file)
return HttpResponse("<h1>Hello download!</h1><h1><a href='{{ MEDIA_URL }}{{ django_file.relative_path }}'>{{ django_file.name }}</a></h1><h1>bye download!</h1>")
# return response
def download_mo(request,file):
path_to_file = os.path.realpath(file)
response = FileResponse(open(path_to_file, 'rb'))
file_name = file[5:]
response['Content-Disposition'] = 'inline; filename=' + file_name
return response
@@ -2,7 +2,6 @@ from django.apps import AppConfig
from django.http import HttpResponse
from django.shortcuts import render
from django.shortcuts import redirect
#from jinja2 import Environment, FileSystemLoader
from django.core.files import File
from kubernetes import client, config
from celery import shared_task
@@ -10,6 +9,7 @@ from celery import shared_task
from lxml import html
import requests
import os
import json
import time
import random
import mimetypes
@@ -33,15 +33,16 @@ proxies = {
"https" : proxy_url
}
destination_folder = "/tmp/stash/"
destination_folder = "/stash/"
def hello(request):
return HttpResponse('<h1>Hello stash!</h1>')
def form(request):
return render(request, 'stash_form.html',{})
return render(request, 'stash/stash_form.html',{})
def album(request):
return render(request, 'album_form.html',{})
return render(request, 'stash/album_form.html',{})
def simple(request):
return render(request, 'stash/simple_form.html',{})
def check_and_create_destination_folder(name):
#check if the output directory exist and create if not
if not os.path.isdir(destination_folder):
@@ -116,12 +117,69 @@ def images_downloader(name,images_url_list,destination_named_folder):
opener = urlrequest.build_opener(proxy)
urlrequest.install_opener(opener)
urlrequest.urlretrieve(image_url, filename )
try:
urlrequest.urlretrieve(image_url, filename )
except:
print("Can't download "+filename+" -- "+image_url)
individual_image_downloader.delay(image_url=image_url, filename=filename)
return 0
@shared_task()
def individual_image_downloader(image_url, filename ):
print("Downloading again: "+filename+" -- "+image_url)
opener = urlrequest.build_opener(proxy)
urlrequest.install_opener(opener)
try:
urlrequest.urlretrieve(image_url, filename )
except:
print("Still Can't download "+filename+" -- "+image_url+" == Cancelling")
return 0
def simple_form(request):
name = request.GET.get('name')
reddit_downloader(username=name)
text_generated = "successfully sent to the reddit downloader"
return HttpResponse(text_generated, content_type="text/plain")
def reddit_downloader(username):
#create the prerequisites folder
destination_named_folder = check_and_create_destination_folder(name=username)
url = "https://www.reddit.com/user/"+username+"/submitted/.json?limit=1000"
opener = urlrequest.build_opener(proxy)
urlrequest.install_opener(opener)
req = urlrequest.Request(url)
urlcurl = urlrequest.urlopen(req).read()
data = json.loads(urlcurl)
picture_list=[]
for children in data['data']['children']:
print("adding to the list : "+children['data']['url'])
picture_list.append(children['data']['url'])
images_downloader.delay(name=username,images_url_list=picture_list,destination_named_folder=destination_named_folder)
return 0
def redgif_donloader(username):
#on te front page of the user , https://www.redgifs.com/users/princesspizookie
# F12 and search network , find something that start as api.redgifs.com
# and the file is search?order=new&count=40&type=g
# copy as curl and you got the bearer
#curl curl 'https://api.redgifs.com/v2/users/princesspizookie/search?order=new&count=40&type=g'
#and you get the URLS , needs to be parsedw
return 0
def incremental(request):
return render(request, 'incremental_form.html',{})
return render(request, 'stash/incremental_form.html',{})
def incremental_form(request):
name = request.GET.get('name')
@@ -165,9 +223,10 @@ def increment_and_download(minimum_increment,maximum_increment,url,url_suffix,na
increment_generated ='000' + str(increment)
url_generated = url+increment_generated+url_suffix
print(url_generated)
destination_filename = increment_generated+url_suffix
destination_file = os.path.join(destination_named_folder,destination_filename)
print(destination_file)
opener = urlrequest.build_opener(proxy)
urlrequest.install_opener(opener)
urlrequest.urlretrieve(url_generated, destination_file )
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
@@ -9,4 +9,4 @@ def hello(request):
def home(request):
return render(request, 'listing.html')
return render(request, 'stash/listing.html')
@@ -0,0 +1,26 @@
from django.contrib import admin
from import_export.admin import ImportExportModelAdmin
from .models import TelegramData
from .utils import telegramUtils
@admin.action(description="Clear all expired messages")
def messages_cleaning(modeladmin, request, queryset):
telegram = telegramUtils()
telegram.clear_expired_messages()
# Register your models here.
@admin.register(TelegramData)
class JobAdmin(ImportExportModelAdmin):
list_display = ('message_id','chat_id','description','creation_date','expiration_date')
actions = [messages_cleaning]
def delete_queryset(self, request, queryset):
"""Given a queryset, delete it from the database."""
print("here")
telegram = telegramUtils()
list_of_message_id = list(queryset.all().values_list('message_id',flat=True))
telegram.delete_message(list_of_message_id)
#no queryset.delete() because it is specified in delete_message function already
@@ -0,0 +1,7 @@
from django.apps import AppConfig
class TelegramCommunicationConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.telegram_communication'
label = 'telegram'
@@ -0,0 +1,47 @@
from django.core.management.base import BaseCommand
from django.conf import settings
import os
#import jinja2
from jinja2 import Environment, FileSystemLoader
router_path = os.path.join(settings.BASE_DIR,'core','routers.py')
class Command(BaseCommand):
args = '<team_id>'
help = 'Affiche la liste des backlogs'
def extract_settings_database(self):
settings_databases = []
for database in settings.DATABASES:
if database == 'default':
continue
print(database)
database_label = database.split('_db')[0]
settings_databases.append([database,database_label])
return settings_databases
def coucou(self):
self.stdout.write('Coucou !')
def templating(self,databases_list):
template_dir = os.path.join(settings.BASE_DIR, 'templates','routers')
env = Environment(loader=FileSystemLoader(template_dir))
template = env.get_template('routers.jinja.py')
output = template.render(databases_list = databases_list)
with open(router_path, 'w') as f:
print(output, file = f)
print(output)
def main(self):
databases_list = self.extract_settings_database()
print(databases_list)
self.templating(databases_list)
self.coucou()
def handle(self, *args, **options):
self.main()
@@ -0,0 +1,19 @@
from apps.telegram_communication.utils import telegramUtils
from django.core.management.base import BaseCommand
import datetime
class Command(BaseCommand):
telegram = telegramUtils()
date_now = datetime.datetime.now()
message = "Test message sent at "+str(date_now)
telegram.send_message(message)
args = '<team_id>'
help = 'Affiche la liste des backlogs'
def handle(self, *args, **options):
self.stdout.write('Message sent !')
@@ -0,0 +1,28 @@
# Generated by Django 4.2.30 on 2026-06-30 12:13
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='TelegramData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('message_id', models.IntegerField(max_length=100, null=True)),
('chat_id', models.IntegerField(max_length=100, null=True)),
('description', models.CharField(max_length=100, null=True)),
('creation_date', models.DateField(blank=True, null=True, verbose_name='Published')),
('expiration_date', models.DateField(blank=True, null=True, verbose_name='Published')),
],
options={
'db_table': 'messages',
},
),
]
@@ -0,0 +1,33 @@
# Generated by Django 4.2.30 on 2026-06-30 12:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('telegram', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='telegramdata',
name='chat_id',
field=models.IntegerField(),
),
migrations.AlterField(
model_name='telegramdata',
name='creation_date',
field=models.DateField(blank=True, verbose_name='Published'),
),
migrations.AlterField(
model_name='telegramdata',
name='expiration_date',
field=models.DateField(blank=True, verbose_name='Published'),
),
migrations.AlterField(
model_name='telegramdata',
name='message_id',
field=models.IntegerField(),
),
]
@@ -0,0 +1,12 @@
from django.db import models
class TelegramData(models.Model):
message_id = models.IntegerField(null=False)
chat_id = models.IntegerField(null=False)
description = models.CharField(max_length=100, null=True)
creation_date = models.DateField(blank=True, null=False, verbose_name='Published')
expiration_date = models.DateField(blank=True, null=False, verbose_name='Published')
class Meta:
db_table = 'messages'
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
@@ -0,0 +1,86 @@
import os
import requests
from apps.bitwarden.utils import bitwardenUtils
from .models import TelegramData
from datetime import datetime, timedelta
class telegramUtils():
token_uid = "a88dbe52-b862-422a-a116-b479009733ab"
chat_id_uid = "13e948ab-494a-4b09-bb3a-b47900974cef"
__bitwarden_access_token = os.environ.get('bitwarden_access_token')
__bitwarden_organization_id = os.environ.get('bitwarden_organization_id')
bw = bitwardenUtils(__bitwarden_access_token,__bitwarden_organization_id)
__TOKEN = bw.read_value_secret(token_uid)
__CHAT_ID = bw.read_value_secret(chat_id_uid)
def get_chat_id(self):
# Source - https://stackoverflow.com/a/75118239
# Posted by Yasantha Biyuranga, modified by community. See post 'Timeline' for change history
# Retrieved 2026-06-30, License - CC BY-SA 4.0
url = f"https://api.telegram.org/bot{self.__TOKEN}/getUpdates"
print(requests.get(url).json())
return 0
def send_message(self,message):
# Source - https://stackoverflow.com/a/75118239
# Posted by Yasantha Biyuranga, modified by community. See post 'Timeline' for change history
# Retrieved 2026-06-30, License - CC BY-SA 4.0
url = f"https://api.telegram.org/bot{self.__TOKEN}/sendMessage?chat_id={self.__CHAT_ID}&text={message}"
result = requests.get(url).json() # this sends the message
send_result = result['ok']
TelegramData.objects.create(message_id=result['result']['message_id'],chat_id=self.__CHAT_ID,description=message[0:99],creation_date=datetime.now(),expiration_date=datetime.now()+timedelta(days=1))
return send_result
def send_document(self,file,message=''):
url = 'https://api.telegram.org/bot{}/sendDocument'.format(self.__TOKEN)
data = {'chat_id': self.__CHAT_ID ,'caption': message}
document = open(file, 'rb')
files = {'document': document}
response = requests.post(url, data=data, files=files)
result = response.json()
#Create data , for the dercsription use a message of set , or use the filename , cut it to grab the end if the filename is more then 99 characters
TelegramData.objects.create(message_id=result['result']['message_id'],chat_id=self.__CHAT_ID,description=message[0:99] or str(file)[-99:],creation_date=datetime.now(),expiration_date=datetime.now()+timedelta(days=1))
return result['ok'],result['result']['message_id'],result
#example send_document('apps/Le_journal_10h00_du_30_06_2026.mp3')
def delete_message(self,message_id_list):
send_result = []
for message_id in message_id_list:
url = f"https://api.telegram.org/bot{self.__TOKEN}/deleteMessage?chat_id={self.__CHAT_ID}&message_id={message_id}"
result = requests.get(url).json()
send_result.append(["Message id: "+str(message_id),result['ok']])
if result['ok']:
message = TelegramData.objects.filter(message_id=message_id)
message.delete()
return send_result
def clear_expired_messages(self):
today = datetime.now()
#filter all the messages that expired yesterday or before
expired_messages_list = []
expired_messages = TelegramData.objects.filter(expiration_date__lte=today)
#leave if the list is empty
if len(expired_messages) == 0:
return 1
#create a list with only the message_id
for expired_message in expired_messages:
expired_messages_list.append(expired_message.message_id)
#run the delete query with the list created before
result = self.delete_message(expired_messages_list)
return result[0]
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
@@ -0,0 +1,25 @@
from django.contrib import admin
from .models import redirectData
from .utils import redirect_method
from import_export.admin import ImportExportModelAdmin
# Register your models here.
@admin.action(description="Add this episode back to its key")
def re_redirect(modeladmin, request, queryset):
output_generated = ""
for query in queryset.values():
print(query)
key = query.get('key')
value = query.get('url')
output_generated = output_generated + redirect_method(key,value)+";"
modeladmin.message_user(
request,
output_generated
)
@admin.register(redirectData)
class redirectAdmin(ImportExportModelAdmin):
list_display = [field.name for field in redirectData._meta.fields if field.name != 'id']
actions = [re_redirect]
@@ -0,0 +1,11 @@
import redis
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.apps import AppConfig
class redirectConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.website_redirection'
label = 'redirect'
@@ -0,0 +1,26 @@
# Generated by Django 4.2.29 on 2026-06-22 20:21
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='redirectData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('url', models.CharField(max_length=1000)),
('addedDate', models.DateField(blank=True, null=True, verbose_name='Published')),
('seenDate', models.DateField(blank=True, null=True, verbose_name='Published')),
],
options={
'db_table': 'redirect',
},
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.29 on 2026-07-05 13:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('redirect', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='redirectdata',
name='addedDate',
field=models.DateField(auto_now_add=True, null=True, verbose_name='Published'),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.29 on 2026-07-14 21:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('redirect', '0002_alter_redirectdata_addeddate'),
]
operations = [
migrations.AddField(
model_name='redirectdata',
name='key',
field=models.CharField(default='streaming', max_length=1000),
),
]
@@ -0,0 +1,10 @@
from django.db import models
class redirectData(models.Model):
url = models.CharField(max_length=1000)
key = models.CharField(max_length=1000,default="streaming")
addedDate = models.DateField('Published', blank=True, null=True, auto_now_add=True)
seenDate = models.DateField('Published', blank=True, null=True)
class Meta:
db_table = 'redirect'

Some files were not shown because too many files have changed in this diff Show More