From b632face71658d93598d621b03636e68eb958daa Mon Sep 17 00:00:00 2001 From: jacobecontreras Date: Mon, 5 May 2025 12:53:33 -0700 Subject: [PATCH 1/2] Homepage/Calendar/Refactoring --- appservice_logs.zip | Bin 0 -> 24948 bytes .../2025_05_05_10-30-0-104_default_docker.log | 80 ++ ...5_05_05_10-30-0-104_default_scm_docker.log | 140 ++++ .../2025_05_05_10-30-0-104_docker.log | 84 ++ .../startup_4.log | 4 + .../LogFiles/CodeProfiler/870d61_debug.log | 8 + ...0d61_001_Startup_POST_api-zipdeploy_0s.xml | 3 + ...0_870d61_002_POST_api-zipdeploy_202_0s.xml | 20 + ..._Background_POST_api-zipdeploy_pending.xml | 32 + ..._004_GET_api-deployments-latest_202_0s.xml | 9 + ...262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml | 4 + ...262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml | 5 + ...262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml | 5 + ...8-12_870d61_008_GET_logstream_200_180s.xml | 6 + ...treamManager:-Dispose()-called_pending.xml | 2 + ...41_870d61_001_Startup_GET_logstream_0s.xml | 3 + ...24-41_870d61_002_GET_logstream_pending.xml | 2 + ...5T19-26-27_870d61_003_GET_dump_pending.xml | 2 + ...a-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt | 1 + ...0-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt | 4 + ...0-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt | 1 + .../LogFiles/webssh/.log | 0 .../log.log | 103 +++ .../status.xml | 19 + appservice_logs/deployments/active | 1 + .../deployments/pending | 0 backend/controller_task.py | 45 +- backend/handler_task.py | 16 + backend/main.py | 13 +- msdocs-python-flask-webapp-quickstart | 1 + .../lib/common/widget/appbar/appbar.dart | 2 + .../widget/search/task_search_delegate.dart | 42 + .../common/widget/task/task_list_widget.dart | 196 +++++ roomiebuddy/lib/main.dart | 2 +- .../lib/{NavScreen.dart => nav_screen.dart} | 12 +- .../{add_taskpage.dart => add_task_page.dart} | 270 +++---- roomiebuddy/lib/pages/calendar_page.dart | 306 +++++++- roomiebuddy/lib/pages/group_page.dart | 4 + roomiebuddy/lib/pages/home_page.dart | 717 +++++++++--------- roomiebuddy/lib/pages/settings_page.dart | 10 +- .../{ => subpages/auth}/login_screen.dart | 4 +- .../{ => subpages/auth}/signup_screen.dart | 2 +- .../subpages/home/group_detail_page.dart | 141 ++++ .../pages/subpages/home/task_detail_page.dart | 132 ++++ roomiebuddy/lib/pages/view_taskpage.dart | 15 - roomiebuddy/lib/providers/theme_provider.dart | 12 +- roomiebuddy/lib/services/api_service.dart | 45 +- roomiebuddy/lib/services/auth_storage.dart | 20 +- roomiebuddy/lib/splash_screen.dart | 4 +- roomiebuddy/lib/utils/data_transformer.dart | 35 +- 50 files changed, 1950 insertions(+), 634 deletions(-) create mode 100644 appservice_logs.zip create mode 100644 appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_docker.log create mode 100644 appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_scm_docker.log create mode 100644 appservice_logs/LogFiles/2025_05_05_10-30-0-104_docker.log create mode 100644 appservice_logs/LogFiles/AppServiceAppLogs_Feature_Installer/startup_4.log create mode 100644 appservice_logs/LogFiles/CodeProfiler/870d61_debug.log create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_001_Startup_POST_api-zipdeploy_0s.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_002_POST_api-zipdeploy_202_0s.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_003_Background_POST_api-zipdeploy_pending.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-05_870d61_004_GET_api-deployments-latest_202_0s.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-06_870d61_005_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-22_870d61_006_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-38_870d61_007_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-18-12_870d61_008_GET_logstream_200_180s.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-21-12_870d61_009_LogStreamManager:-Dispose()-called_pending.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_001_Startup_GET_logstream_0s.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_002_GET_logstream_pending.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-26-27_870d61_003_GET_dump_pending.xml create mode 100644 appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-a9ca9bea-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt create mode 100644 appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt create mode 100644 appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt rename data/make_a_new_file_called_(data.db) => appservice_logs/LogFiles/webssh/.log (100%) create mode 100644 appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/log.log create mode 100644 appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/status.xml create mode 100644 appservice_logs/deployments/active rename log/make_a_new_file_called_(log.txt) => appservice_logs/deployments/pending (100%) create mode 160000 msdocs-python-flask-webapp-quickstart create mode 100644 roomiebuddy/lib/common/widget/search/task_search_delegate.dart create mode 100644 roomiebuddy/lib/common/widget/task/task_list_widget.dart rename roomiebuddy/lib/{NavScreen.dart => nav_screen.dart} (91%) rename roomiebuddy/lib/pages/{add_taskpage.dart => add_task_page.dart} (93%) rename roomiebuddy/lib/pages/{ => subpages/auth}/login_screen.dart (98%) rename roomiebuddy/lib/pages/{ => subpages/auth}/signup_screen.dart (99%) create mode 100644 roomiebuddy/lib/pages/subpages/home/group_detail_page.dart create mode 100644 roomiebuddy/lib/pages/subpages/home/task_detail_page.dart delete mode 100644 roomiebuddy/lib/pages/view_taskpage.dart diff --git a/appservice_logs.zip b/appservice_logs.zip new file mode 100644 index 0000000000000000000000000000000000000000..65339b414c706886048d9076d5f6bcca1e8b88db GIT binary patch literal 24948 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 literal 0 HcmV?d00001 diff --git a/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_docker.log b/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_docker.log new file mode 100644 index 0000000..20daeda --- /dev/null +++ b/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_docker.log @@ -0,0 +1,80 @@ +2025-05-05T19:17:51.8360525Z _____ +2025-05-05T19:17:51.8387064Z / _ \ __________ _________ ____ +2025-05-05T19:17:51.8387358Z / /_\ \\___ / | \_ __ \_/ __ \ +2025-05-05T19:17:51.8387461Z / | \/ /| | /| | \/\ ___/ +2025-05-05T19:17:51.8388642Z \____|__ /_____ \____/ |__| \___ > +2025-05-05T19:17:51.8388720Z \/ \/ \/ +2025-05-05T19:17:51.8388775Z A P P S E R V I C E O N L I N U X +2025-05-05T19:17:51.8388816Z +2025-05-05T19:17:51.8388869Z Documentation: http://aka.ms/webapp-linux +2025-05-05T19:17:51.8388922Z Python 3.10.16 +2025-05-05T19:17:51.8388960Z Note: Any data outside '/home' is not persisted +2025-05-05T19:17:53.0262476Z Starting OpenBSD Secure Shell server: sshd. +2025-05-05T19:17:53.0262921Z WEBSITES_INCLUDE_CLOUD_CERTS is not set to true. +2025-05-05T19:17:53.0262963Z Updating certificates in /etc/ssl/certs... +2025-05-05T19:17:53.7725931Z 2 added, 0 removed; done. +2025-05-05T19:17:53.7726600Z Running hooks in /etc/ca-certificates/update.d... +2025-05-05T19:17:53.7747355Z done. +2025-05-05T19:17:53.7764774Z CA certificates copied and updated successfully. +2025-05-05T19:17:53.7973879Z App Command Line not configured, will attempt auto-detect +2025-05-05T19:17:54.0174525Z Starting periodic command scheduler: cron. +2025-05-05T19:17:54.0178380Z Launching oryx with: create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite +2025-05-05T19:17:54.0971751Z Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it... +2025-05-05T19:17:54.0998037Z Build Operation ID: 0bf5a6b10c464f0d +2025-05-05T19:17:54.1004103Z Output is compressed. Extracting it... +2025-05-05T19:17:54.1004103Z Oryx Version: 0.2.20250121.2, Commit: d363b83aad8365d7e91cc246d6dfb3ddad209ddb, ReleaseTagName: 20250121.2 +2025-05-05T19:17:54.1017783Z Extracting '/home/site/wwwroot/output.tar.gz' to directory '/tmp/8dd8c096c8b2d70'... +2025-05-05T19:17:54.7542578Z App path is set to '/tmp/8dd8c096c8b2d70' +2025-05-05T19:17:54.7542901Z No framework detected; using default app from /opt/defaultsite +2025-05-05T19:17:54.7543237Z Generating `gunicorn` command for 'application:app' +2025-05-05T19:17:54.9603867Z Writing output script to '/opt/startup/startup.sh' +2025-05-05T19:17:56.8833780Z Using packages from virtual environment antenv located at /tmp/8dd8c096c8b2d70/antenv. +2025-05-05T19:17:56.8834102Z Updated PYTHONPATH to '/agents/python:/opt/startup/app_logs:/tmp/8dd8c096c8b2d70/antenv/lib/python3.10/site-packages' +2025-05-05T19:17:58.1019375Z [2025-05-05 19:17:58 +0000] [1045] [INFO] Starting gunicorn 23.0.0 +2025-05-05T19:17:58.1149444Z [2025-05-05 19:17:58 +0000] [1045] [INFO] Listening at: http://0.0.0.0:8000 (1045) +2025-05-05T19:17:58.1149856Z [2025-05-05 19:17:58 +0000] [1045] [INFO] Using worker: sync +2025-05-05T19:17:58.1237539Z [2025-05-05 19:17:58 +0000] [1058] [INFO] Booting worker with pid: 1058 +2025-05-05T19:17:59.0421230Z 169.254.129.1 - - [05/May/2025:19:17:59 +0000] "GET /robots933456.txt HTTP/1.1" 404 207 "-" "HealthCheck/1.0" +2025-05-05T19:17:59.0743324Z 169.254.129.1 - - [05/May/2025:19:17:59 +0000] "GET /robots933456.txt HTTP/1.1" 404 207 "-" "HealthCheck/1.0" +2025-05-05T19:18:00.0053057Z 169.254.129.1 - - [05/May/2025:19:17:59 +0000] "GET / HTTP/1.1" 200 0 "-" "ReadyForRequest/1.0 (LocalCache)" +2025-05-05T19:18:00.0528981Z 169.254.129.1 - - [05/May/2025:19:18:00 +0000] "GET / HTTP/1.1" 200 0 "-" "ReadyForRequest/1.0 (AppInit)" +2025-05-05T19:18:10.1394732Z 169.254.129.1 - - [05/May/2025:19:18:10 +0000] "GET / HTTP/1.1" 200 0 "-" "python-urllib3/1.26.19" +2025-05-05T19:18:10.3987699Z 169.254.129.1 - - [05/May/2025:19:18:10 +0000] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0" +2025-05-05T19:19:27.5164144Z 169.254.129.1 - - [05/May/2025:19:19:27 +0000] "GET /favicon.ico HTTP/1.1" 404 207 "https://msdocs-python-webapp-quickstart-rmb.azurewebsites.net/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0" +2025-05-05T19:19:29.0063973Z 169.254.129.1 - - [05/May/2025:19:19:28 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0" +2025-05-05T19:20:47.4336461Z _____ +2025-05-05T19:20:47.4337876Z / _ \ __________ _________ ____ +2025-05-05T19:20:47.4337928Z / /_\ \\___ / | \_ __ \_/ __ \ +2025-05-05T19:20:47.4337947Z / | \/ /| | /| | \/\ ___/ +2025-05-05T19:20:47.4337964Z \____|__ /_____ \____/ |__| \___ > +2025-05-05T19:20:47.4337990Z \/ \/ \/ +2025-05-05T19:20:47.4338007Z A P P S E R V I C E O N L I N U X +2025-05-05T19:20:47.4338051Z +2025-05-05T19:20:47.4338074Z Documentation: http://aka.ms/webapp-linux +2025-05-05T19:20:47.4338094Z Python 3.10.16 +2025-05-05T19:20:47.4338114Z Note: Any data outside '/home' is not persisted +2025-05-05T19:20:47.9853268Z Starting OpenBSD Secure Shell server: sshd. +2025-05-05T19:20:47.9969621Z WEBSITES_INCLUDE_CLOUD_CERTS is not set to true. +2025-05-05T19:20:48.0225846Z Updating certificates in /etc/ssl/certs... +2025-05-05T19:20:50.1148729Z 2 added, 0 removed; done. +2025-05-05T19:20:50.1149550Z Running hooks in /etc/ca-certificates/update.d... +2025-05-05T19:20:50.1169011Z done. +2025-05-05T19:20:50.1224381Z CA certificates copied and updated successfully. +2025-05-05T19:20:50.1887369Z Site's appCommandLine: gunicorn --bind=0.0.0.0 --timeout 600 main:app +2025-05-05T19:20:50.3910131Z Starting periodic command scheduler: cron. +2025-05-05T19:20:50.3912304Z Launching oryx with: create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite -userStartupCommand 'gunicorn --bind=0.0.0.0 --timeout 600 main:app' +2025-05-05T19:20:50.4811707Z Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it... +2025-05-05T19:20:50.4836111Z Build Operation ID: 0bf5a6b10c464f0d +2025-05-05T19:20:50.4838925Z Output is compressed. Extracting it... +2025-05-05T19:20:50.4839189Z Oryx Version: 0.2.20250121.2, Commit: d363b83aad8365d7e91cc246d6dfb3ddad209ddb, ReleaseTagName: 20250121.2 +2025-05-05T19:20:50.4854600Z Extracting '/home/site/wwwroot/output.tar.gz' to directory '/tmp/8dd8c096c8b2d70'... +2025-05-05T19:20:51.1289065Z App path is set to '/tmp/8dd8c096c8b2d70' +2025-05-05T19:20:51.3927172Z Writing output script to '/opt/startup/startup.sh' +2025-05-05T19:20:53.5147632Z Using packages from virtual environment antenv located at /tmp/8dd8c096c8b2d70/antenv. +2025-05-05T19:20:53.5148287Z Updated PYTHONPATH to '/agents/python:/opt/startup/app_logs:/tmp/8dd8c096c8b2d70/antenv/lib/python3.10/site-packages' +2025-05-05T19:20:54.7037155Z [2025-05-05 19:20:54 +0000] [1044] [INFO] Starting gunicorn 23.0.0 +2025-05-05T19:20:54.7046045Z [2025-05-05 19:20:54 +0000] [1044] [INFO] Listening at: http://0.0.0.0:8000 (1044) +2025-05-05T19:20:54.7049491Z [2025-05-05 19:20:54 +0000] [1044] [INFO] Using worker: sync +2025-05-05T19:20:54.7111569Z [2025-05-05 19:20:54 +0000] [1055] [INFO] Booting worker with pid: 1055 +2025-05-05T19:21:15.1610720Z [2025-05-05 19:21:15 +0000] [1058] [INFO] Worker exiting (pid: 1058) +2025-05-05T19:21:15.8809815Z [2025-05-05 19:21:15 +0000] [1045] [INFO] Handling signal: term diff --git a/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_scm_docker.log b/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_scm_docker.log new file mode 100644 index 0000000..6b66193 --- /dev/null +++ b/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_scm_docker.log @@ -0,0 +1,140 @@ +2025-05-05T19:16:55.1352331Z chown: changing ownership of '/temp': Operation not permitted +2025-05-05T19:16:55.1371299Z chmod: changing permissions of '/temp': Operation not permitted +2025-05-05T19:16:57.0095386Z __ __ __ __ _ __ +2025-05-05T19:16:57.0095736Z / //_/_ _ ____/ /_ __/ / (_) /____ +2025-05-05T19:16:57.0095772Z / ,< / / / / __ / / / / / / / __/ _ +2025-05-05T19:16:57.0095799Z / /| / /_/ / /_/ / /_/ / /___/ / /_/ __/ +2025-05-05T19:16:57.0095847Z /_/ |_\__,_/\__,_/\__,_/_____/_/\__/\___/ +2025-05-05T19:16:57.0095921Z +2025-05-05T19:16:57.0096024Z +2025-05-05T19:16:57.0096053Z DEBUG CONSOLE | AZURE APP SERVICE ON LINUX +2025-05-05T19:16:57.0096080Z +2025-05-05T19:16:57.0096106Z Documentation: http://aka.ms/webapp-linux +2025-05-05T19:16:57.0096172Z Kudu Version : 20250415.4 +2025-05-05T19:16:57.0096205Z Commit : 4daf9e0c104d05cf6c82d02a0722563488f851b4 +2025-05-05T19:16:57.0096226Z +2025-05-05T19:16:57.0096278Z Restarting OpenBSD Secure Shell server: sshd. +2025-05-05T19:16:57.0096310Z node not running, starting node /opt/webssh/index.js +2025-05-05T19:16:57.0096354Z Mon May 5 19:16:56 UTC 2025 running .net core +2025-05-05T19:16:57.4639938Z Startup : 07.16.57.456144 +2025-05-05T19:16:57.4841044Z Configure Services : 07.16.57.483913 +2025-05-05T19:16:57.6653459Z Configure : 07.16.57.665175 +2025-05-05T19:16:57.8232206Z Setting Up Routes : 07.16.57.822970 +2025-05-05T19:16:57.9178137Z Exiting Configure : 07.16.57.917650 +2025-05-05T19:16:58.0009015Z warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35] +2025-05-05T19:16:58.0009565Z No XML encryptor configured. Key {eee0e4ac-1fe7-42ee-b2cf-3a79b5d4dd6b} may be persisted to storage in unencrypted form. +2025-05-05T19:16:58.0620611Z Hosting environment: Production +2025-05-05T19:16:58.0621163Z Content root path: /opt/Kudu +2025-05-05T19:16:58.0623329Z Now listening on: http://0.0.0.0:8181 +2025-05-05T19:16:58.0624302Z Application started. Press Ctrl+C to shut down. +2025-05-05T19:17:04.3551826Z Deploy Async +2025-05-05T19:17:07.0743440Z Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx +2025-05-05T19:17:07.0817044Z You can report issues at https://github.com/Microsoft/Oryx/issues +2025-05-05T19:17:07.0929060Z +2025-05-05T19:17:07.1006624Z Oryx Version: 0.2.20250107.1+ef3fb2f9c490a4fbb1f76b5746cd4ba2ff0409f4, Commit: ef3fb2f9c490a4fbb1f76b5746cd4ba2ff0409f4, ReleaseTagName: 20250107.1 +2025-05-05T19:17:07.1076865Z +2025-05-05T19:17:07.1168538Z Build Operation ID: 0bf5a6b10c464f0d +2025-05-05T19:17:07.1245523Z Repository Commit : 00c9c262-5fed-4fb0-88d7-36d91b7e3d39 +2025-05-05T19:17:07.1299474Z OS Type : bullseye +2025-05-05T19:17:07.1368880Z Image Type : githubactions +2025-05-05T19:17:07.1436429Z +2025-05-05T19:17:07.1519133Z Detecting platforms... +2025-05-05T19:17:07.6661481Z Detected following platforms: +2025-05-05T19:17:07.6763950Z python: 3.10.17 +2025-05-05T19:17:07.6814182Z Version '3.10.17' of platform 'python' is not installed. Generating script to install it... +2025-05-05T19:17:08.3325335Z +2025-05-05T19:17:08.3325563Z Using intermediate directory '/tmp/8dd8c096c8b2d70'. +2025-05-05T19:17:08.3325581Z +2025-05-05T19:17:08.3325607Z Copying files to the intermediate directory... +2025-05-05T19:17:08.3325624Z Done in 0 sec(s). +2025-05-05T19:17:08.3325640Z +2025-05-05T19:17:08.3325657Z Source directory : /tmp/8dd8c096c8b2d70 +2025-05-05T19:17:08.3325674Z Destination directory: /home/site/wwwroot +2025-05-05T19:17:08.3325714Z +2025-05-05T19:17:08.3325728Z +2025-05-05T19:17:08.3325748Z Downloading and extracting 'python' version '3.10.17' to '/tmp/oryx/platforms/python/3.10.17'... +2025-05-05T19:17:08.3325765Z Detected image debian flavor: bullseye. +2025-05-05T19:17:10.2712585Z Downloaded in 3 sec(s). +2025-05-05T19:17:10.3090738Z Verifying checksum... +2025-05-05T19:17:10.3428480Z Extracting contents... +2025-05-05T19:17:14.6256499Z performing sha512 checksum for: python... +2025-05-05T19:17:14.9567640Z Done in 7 sec(s). +2025-05-05T19:17:14.9651830Z +2025-05-05T19:17:14.9829172Z image detector file exists, platform is python.. +2025-05-05T19:17:14.9927826Z OS detector file exists, OS is bullseye.. +2025-05-05T19:17:15.0825719Z Python Version: /tmp/oryx/platforms/python/3.10.17/bin/python3.10 +2025-05-05T19:17:15.0896694Z Creating directory for command manifest file if it does not exist +2025-05-05T19:17:15.1106194Z Removing existing manifest file +2025-05-05T19:17:15.1185665Z Python Virtual Environment: antenv +2025-05-05T19:17:15.1247963Z Creating virtual environment... +2025-05-05T19:17:18.3393596Z Activating virtual environment... +2025-05-05T19:17:18.3746803Z Running pip install... +2025-05-05T19:17:22.3654412Z [19:17:19+0000] Collecting blinker==1.9.0 +2025-05-05T19:17:22.3864735Z [19:17:19+0000] Downloading blinker-1.9.0-py3-none-any.whl (8.5 kB) +2025-05-05T19:17:22.4096020Z [19:17:19+0000] Collecting click==8.1.8 +2025-05-05T19:17:22.4384848Z [19:17:19+0000] Downloading click-8.1.8-py3-none-any.whl (98 kB) +2025-05-05T19:17:22.4507324Z [19:17:19+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.2/98.2 kB 4.1 MB/s eta 0:00:00 +2025-05-05T19:17:22.4593691Z [19:17:19+0000] Collecting colorama==0.4.6 +2025-05-05T19:17:22.4657878Z [19:17:19+0000] Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB) +2025-05-05T19:17:22.4739751Z [19:17:19+0000] Collecting Flask==3.1.0 +2025-05-05T19:17:22.4820947Z [19:17:19+0000] Downloading flask-3.1.0-py3-none-any.whl (102 kB) +2025-05-05T19:17:22.5026036Z [19:17:19+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 103.0/103.0 kB 12.5 MB/s eta 0:00:00 +2025-05-05T19:17:22.5128405Z [19:17:19+0000] Collecting itsdangerous==2.2.0 +2025-05-05T19:17:22.5203445Z [19:17:19+0000] Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB) +2025-05-05T19:17:22.5291272Z [19:17:20+0000] Collecting Jinja2==3.1.6 +2025-05-05T19:17:22.5382939Z [19:17:20+0000] Downloading jinja2-3.1.6-py3-none-any.whl (134 kB) +2025-05-05T19:17:22.5597341Z [19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.9/134.9 kB 18.5 MB/s eta 0:00:00 +2025-05-05T19:17:22.5680952Z [19:17:20+0000] Collecting MarkupSafe==3.0.2 +2025-05-05T19:17:22.5772842Z [19:17:20+0000] Downloading MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (20 kB) +2025-05-05T19:17:22.5837091Z [19:17:20+0000] Collecting pytz==2025.2 +2025-05-05T19:17:22.5945568Z [19:17:20+0000] Downloading pytz-2025.2-py2.py3-none-any.whl (509 kB) +2025-05-05T19:17:22.6057195Z [19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 509.2/509.2 kB 19.2 MB/s eta 0:00:00 +2025-05-05T19:17:22.6281323Z [19:17:20+0000] Collecting Werkzeug==3.1.3 +2025-05-05T19:17:22.6452733Z [19:17:20+0000] Downloading werkzeug-3.1.3-py3-none-any.whl (224 kB) +2025-05-05T19:17:22.6685003Z [19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 224.5/224.5 kB 39.9 MB/s eta 0:00:00 +2025-05-05T19:17:22.6805280Z [19:17:21+0000] Installing collected packages: pytz, MarkupSafe, itsdangerous, colorama, click, blinker, Werkzeug, Jinja2, Flask +2025-05-05T19:17:22.6884388Z [19:17:22+0000] Successfully installed Flask-3.1.0 Jinja2-3.1.6 MarkupSafe-3.0.2 Werkzeug-3.1.3 blinker-1.9.0 click-8.1.8 colorama-0.4.6 itsdangerous-2.2.0 pytz-2025.2 +2025-05-05T19:17:22.6942308Z +2025-05-05T19:17:22.7084989Z [notice] A new release of pip is available: 23.0.1 -> 25.1.1 +2025-05-05T19:17:22.7182881Z [notice] To update, run: pip install --upgrade pip +2025-05-05T19:17:22.7332243Z Not a vso image, so not writing build commands +2025-05-05T19:17:22.7433673Z Preparing output... +2025-05-05T19:17:22.7590532Z +2025-05-05T19:17:22.7768156Z Copying files to destination directory '/tmp/_preCompressedDestinationDir'... +2025-05-05T19:17:23.1865886Z Done in 1 sec(s). +2025-05-05T19:17:23.1944206Z Compressing content of directory '/tmp/_preCompressedDestinationDir'... +2025-05-05T19:17:24.6561040Z Copied the compressed output to '/home/site/wwwroot' +2025-05-05T19:17:24.7046232Z +2025-05-05T19:17:24.7149284Z Removing existing manifest file +2025-05-05T19:17:24.7239576Z Creating a manifest file... +2025-05-05T19:17:24.7328884Z Manifest file created. +2025-05-05T19:17:24.7381346Z Copying .ostype to manifest output directory. +2025-05-05T19:17:24.7451296Z +2025-05-05T19:17:24.7519679Z Done in 17 sec(s). +2025-05-05T19:20:45.6815589Z __ __ __ __ _ __ +2025-05-05T19:20:45.6913278Z / //_/_ _ ____/ /_ __/ / (_) /____ +2025-05-05T19:20:45.6913364Z / ,< / / / / __ / / / / / / / __/ _ +2025-05-05T19:20:45.6913418Z / /| / /_/ / /_/ / /_/ / /___/ / /_/ __/ +2025-05-05T19:20:45.6913436Z /_/ |_\__,_/\__,_/\__,_/_____/_/\__/\___/ +2025-05-05T19:20:45.6913469Z +2025-05-05T19:20:45.6913491Z +2025-05-05T19:20:45.6913531Z DEBUG CONSOLE | AZURE APP SERVICE ON LINUX +2025-05-05T19:20:45.6913546Z +2025-05-05T19:20:45.6913565Z Documentation: http://aka.ms/webapp-linux +2025-05-05T19:20:45.6913582Z Kudu Version : 20250415.4 +2025-05-05T19:20:45.6913600Z Commit : 4daf9e0c104d05cf6c82d02a0722563488f851b4 +2025-05-05T19:20:45.6913616Z +2025-05-05T19:20:45.8788525Z chown: changing ownership of '/temp': Operation not permitted +2025-05-05T19:20:45.8834645Z chmod: changing permissions of '/temp': Operation not permitted +2025-05-05T19:20:46.3638312Z Restarting OpenBSD Secure Shell server: sshd. +2025-05-05T19:20:46.3847302Z node not running, starting node /opt/webssh/index.js +2025-05-05T19:20:48.3783830Z Mon May 5 19:20:48 UTC 2025 running .net core +2025-05-05T19:20:48.9937896Z Startup : 07.20.48.981381 +2025-05-05T19:20:49.0286284Z Configure Services : 07.20.49.028467 +2025-05-05T19:20:49.3892564Z Configure : 07.20.49.388587 +2025-05-05T19:20:49.9836682Z Setting Up Routes : 07.20.49.687685 +2025-05-05T19:20:50.0455445Z Exiting Configure : 07.20.50.045009 +2025-05-05T19:20:50.3799302Z Hosting environment: Production +2025-05-05T19:20:50.3799598Z Content root path: /opt/Kudu +2025-05-05T19:20:50.3825425Z Now listening on: http://0.0.0.0:8181 +2025-05-05T19:20:50.3825692Z Application started. Press Ctrl+C to shut down. diff --git a/appservice_logs/LogFiles/2025_05_05_10-30-0-104_docker.log b/appservice_logs/LogFiles/2025_05_05_10-30-0-104_docker.log new file mode 100644 index 0000000..3f33852 --- /dev/null +++ b/appservice_logs/LogFiles/2025_05_05_10-30-0-104_docker.log @@ -0,0 +1,84 @@ +2025-05-05T19:17:41.4717465Z Container start method called. +2025-05-05T19:17:41.4728377Z Establishing network. +2025-05-05T19:17:41.4731359Z Pulling image: appsvc/python:3.10_20250213.3.tuxprod. +2025-05-05T19:17:50.9795124Z Image appsvc/python:3.10_20250213.3.tuxprod is pulled from registry 10.1.0.7:13209 +2025-05-05T19:17:50.9904134Z Container is starting. +2025-05-05T19:17:50.9905561Z Establishing user namespace if not established already. +2025-05-05T19:17:50.9906483Z Establishing network if not established already. +2025-05-05T19:17:50.9907256Z Mounting volumes. +2025-05-05T19:17:50.9914579Z Nested mountpoint +2025-05-05T19:17:50.9990681Z Nested mountpoint volatile/logs +2025-05-05T19:17:51.0024642Z Nested mountpoint +2025-05-05T19:17:51.0201407Z Nested mountpoint +2025-05-05T19:17:51.0207045Z Nested mountpoint +2025-05-05T19:17:51.0211206Z Nested mountpoint +2025-05-05T19:17:51.0335267Z Nested mountpoint +2025-05-05T19:17:51.0357867Z Nested mountpoint +2025-05-05T19:17:51.0375589Z Nested mountpoint +2025-05-05T19:17:51.0388349Z Nested mountpoint +2025-05-05T19:17:51.4756521Z Creating container. +2025-05-05T19:17:51.4757692Z Creating pipes for streaming container io. +2025-05-05T19:17:51.4760508Z Creating stdout named pipe at /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504. +2025-05-05T19:17:51.4766905Z Successfully created stdout named pipe at: /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504. +2025-05-05T19:17:51.4767976Z Opening named pipe /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504 for reading in non-blocking mode. +2025-05-05T19:17:51.4773325Z Successfully opened named pipe: /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504. +2025-05-05T19:17:51.4774766Z Successfully removed non-blocking flag from /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504. +2025-05-05T19:17:51.4779954Z Creating stderr named pipe at /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00. +2025-05-05T19:17:51.4782401Z Successfully created stderr named pipe at: /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00. +2025-05-05T19:17:51.4783850Z Opening named pipe /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00 for reading in non-blocking mode. +2025-05-05T19:17:51.4785186Z Successfully opened named pipe: /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00. +2025-05-05T19:17:51.4786792Z Successfully removed non-blocking flag from /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00. +2025-05-05T19:17:51.4808543Z Creating container with image: appsvc/python:3.10_20250213.3.tuxprod from registry: 10.1.0.7:13209 and fully qualified image name: 10.1.0.7:13209/appsvc/python:3.10_20250213.3.tuxprod +2025-05-05T19:17:51.7562535Z Starting container: ad8972c0_msdocs-python-webapp-quickstart-rmb. +2025-05-05T19:17:51.7732099Z Starting watchers and probes. +2025-05-05T19:17:51.8032256Z Starting metrics collection. +2025-05-05T19:17:51.8065077Z Container is running. +2025-05-05T19:17:51.8621134Z Container start method finished after 10390 ms. +2025-05-05T19:17:59.1339718Z Site startup probe succeeded after 7.2431449 seconds. +2025-05-05T19:17:59.7768666Z Site started. +2025-05-05T19:17:59.7997645Z Site is running with deployment version: 00c9c262-5fed-4fb0-88d7-36d91b7e3d39 +2025-05-05T19:20:44.7876889Z Container start method called. +2025-05-05T19:20:44.7878026Z Establishing network. +2025-05-05T19:20:44.7878787Z Pulling image: appsvc/python:3.10_20250213.3.tuxprod. +2025-05-05T19:20:45.1631223Z Image appsvc/python:3.10_20250213.3.tuxprod is pulled from registry 10.1.0.4:13209 +2025-05-05T19:20:45.1636430Z Container is starting. +2025-05-05T19:20:45.1639308Z Establishing user namespace if not established already. +2025-05-05T19:20:45.1643991Z Establishing network if not established already. +2025-05-05T19:20:45.1647483Z Mounting volumes. +2025-05-05T19:20:45.1655405Z Nested mountpoint +2025-05-05T19:20:45.1680458Z Nested mountpoint volatile/logs +2025-05-05T19:20:45.1710420Z Nested mountpoint +2025-05-05T19:20:45.1731084Z Nested mountpoint +2025-05-05T19:20:45.1749503Z Nested mountpoint +2025-05-05T19:20:45.1766564Z Nested mountpoint +2025-05-05T19:20:45.1837639Z Nested mountpoint +2025-05-05T19:20:45.1843657Z Nested mountpoint +2025-05-05T19:20:45.1872261Z Nested mountpoint +2025-05-05T19:20:45.1905725Z Nested mountpoint +2025-05-05T19:20:45.6332278Z Creating container. +2025-05-05T19:20:45.6336238Z Creating pipes for streaming container io. +2025-05-05T19:20:45.6339722Z Creating stdout named pipe at /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d. +2025-05-05T19:20:45.6344359Z Successfully created stdout named pipe at: /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d. +2025-05-05T19:20:45.6347943Z Opening named pipe /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d for reading in non-blocking mode. +2025-05-05T19:20:45.6362484Z Successfully opened named pipe: /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d. +2025-05-05T19:20:45.6366054Z Successfully removed non-blocking flag from /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d. +2025-05-05T19:20:45.6370608Z Creating stderr named pipe at /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74. +2025-05-05T19:20:45.6374579Z Successfully created stderr named pipe at: /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74. +2025-05-05T19:20:45.6378138Z Opening named pipe /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74 for reading in non-blocking mode. +2025-05-05T19:20:45.6389388Z Successfully opened named pipe: /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74. +2025-05-05T19:20:45.6404969Z Successfully removed non-blocking flag from /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74. +2025-05-05T19:20:45.6416156Z Creating container with image: appsvc/python:3.10_20250213.3.tuxprod from registry: 10.1.0.4:13209 and fully qualified image name: 10.1.0.4:13209/appsvc/python:3.10_20250213.3.tuxprod +2025-05-05T19:20:47.2958213Z Starting container: 34de0832_msdocs-python-webapp-quickstart-rmb. +2025-05-05T19:20:47.3254636Z Starting watchers and probes. +2025-05-05T19:20:47.3302946Z Starting metrics collection. +2025-05-05T19:20:47.3312657Z Container is running. +2025-05-05T19:20:47.3649944Z Container start method finished after 2576 ms. +2025-05-05T19:20:54.9916983Z Site startup probe succeeded after 7.6221948 seconds. +2025-05-05T19:20:55.0979300Z Site started. +2025-05-05T19:20:55.1042513Z Site is running with deployment version: 00c9c262-5fed-4fb0-88d7-36d91b7e3d39 +2025-05-05T19:21:15.1351042Z Container is terminating. Grace period: 5 seconds. +2025-05-05T19:21:15.1469269Z Stop and delete container. Retry count = 0 +2025-05-05T19:21:15.1470867Z Stopping container: ad8972c0_msdocs-python-webapp-quickstart-rmb. +2025-05-05T19:21:20.1629238Z Deleting container: ad8972c0_msdocs-python-webapp-quickstart-rmb. Retry count = 0 +2025-05-05T19:21:20.3330163Z Container spec TerminationMessagePolicy path +2025-05-05T19:21:20.3336293Z Container is terminated. Total time elapsed: 5198 ms. diff --git a/appservice_logs/LogFiles/AppServiceAppLogs_Feature_Installer/startup_4.log b/appservice_logs/LogFiles/AppServiceAppLogs_Feature_Installer/startup_4.log new file mode 100644 index 0000000..15a8855 --- /dev/null +++ b/appservice_logs/LogFiles/AppServiceAppLogs_Feature_Installer/startup_4.log @@ -0,0 +1,4 @@ +2025-05-05 19:17:58,113 [MainThread] [DEBUG] : Initializating AppServiceAppLogging +2025-05-05 19:17:58,113 [Thread-1 (] [DEBUG] : Did not find any previously bound socket +2025-05-05 19:17:58,114 [MainThread] [DEBUG] : Initialized AppServiceAppLogging +2025-05-05 19:17:58,131 [Thread-3 (] [DEBUG] : Waiting for the logs flag to be set diff --git a/appservice_logs/LogFiles/CodeProfiler/870d61_debug.log b/appservice_logs/LogFiles/CodeProfiler/870d61_debug.log new file mode 100644 index 0000000..eb6b22d --- /dev/null +++ b/appservice_logs/LogFiles/CodeProfiler/870d61_debug.log @@ -0,0 +1,8 @@ +[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Code Profiler Installer is starting up +[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Cleaning up any existing status file which indicated signal handlers initialized status +[2025_05_05_19_17_58] [appsvc_profiler.installer] [DEBUG] APPSETTING_WEBSITE_ENABLE_DEFAULT_CODE_PROFILER : None +[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Attempting to install the default code profiler. +[2025_05_05_19_17_58] [appsvc_profiler.installer] [DEBUG] viztracer would save traces to /tmp/870d61_profiler_trace.json +[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Successfully installed code profiler. +[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Signal Handlers SIGUSR for needed code-profiler have been initialized for gunicorn process on instance 870d616759e74713524da24210e88870fbcc76bc99b00f44c089fc8ca08f9724 +[2025_05_05_19_17_58] [appsvc_profiler.installer] [DEBUG] Code Profiler Installer is exiting as installation is completed diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_001_Startup_POST_api-zipdeploy_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_001_Startup_POST_api-zipdeploy_0s.xml new file mode 100644 index 0000000..014db5a --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_001_Startup_POST_api-zipdeploy_0s.xml @@ -0,0 +1,3 @@ + + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_002_POST_api-zipdeploy_202_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_002_POST_api-zipdeploy_202_0s.xml new file mode 100644 index 0000000..e00d33d --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_002_POST_api-zipdeploy_202_0s.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_003_Background_POST_api-zipdeploy_pending.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_003_Background_POST_api-zipdeploy_pending.xml new file mode 100644 index 0000000..772e4a9 --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_003_Background_POST_api-zipdeploy_pending.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-05_870d61_004_GET_api-deployments-latest_202_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-05_870d61_004_GET_api-deployments-latest_202_0s.xml new file mode 100644 index 0000000..1aaabcf --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-05_870d61_004_GET_api-deployments-latest_202_0s.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-06_870d61_005_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-06_870d61_005_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml new file mode 100644 index 0000000..8c66ddc --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-06_870d61_005_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml @@ -0,0 +1,4 @@ + + + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-22_870d61_006_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-22_870d61_006_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml new file mode 100644 index 0000000..e104d44 --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-22_870d61_006_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-38_870d61_007_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-38_870d61_007_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml new file mode 100644 index 0000000..b01f59e --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-38_870d61_007_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-18-12_870d61_008_GET_logstream_200_180s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-18-12_870d61_008_GET_logstream_200_180s.xml new file mode 100644 index 0000000..d887328 --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-18-12_870d61_008_GET_logstream_200_180s.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-21-12_870d61_009_LogStreamManager:-Dispose()-called_pending.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-21-12_870d61_009_LogStreamManager:-Dispose()-called_pending.xml new file mode 100644 index 0000000..fb1d2f4 --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-21-12_870d61_009_LogStreamManager:-Dispose()-called_pending.xml @@ -0,0 +1,2 @@ + + + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_002_GET_logstream_pending.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_002_GET_logstream_pending.xml new file mode 100644 index 0000000..ec55ec4 --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_002_GET_logstream_pending.xml @@ -0,0 +1,2 @@ + + diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-26-27_870d61_003_GET_dump_pending.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-26-27_870d61_003_GET_dump_pending.xml new file mode 100644 index 0000000..7e5db30 --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-26-27_870d61_003_GET_dump_pending.xml @@ -0,0 +1,2 @@ + + diff --git a/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-a9ca9bea-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt b/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-a9ca9bea-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt new file mode 100644 index 0000000..39b3c40 --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-a9ca9bea-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt @@ -0,0 +1 @@ +2025-05-05T19:24:41 Startup Request, url: /logstream, method: GET, type: request, pid: 768,1,7, ScmType: None, SCM_DO_BUILD_DURING_DEPLOYMENT: true diff --git a/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt b/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt new file mode 100644 index 0000000..20a0fe9 --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt @@ -0,0 +1,4 @@ +2025-05-05T19:17:00 Startup Request, url: /api/zipdeploy?isAsync=true, method: POST, type: request, pid: 768,1,7, SCM_DO_BUILD_DURING_DEPLOYMENT: true, ScmType: None +2025-05-05T19:17:00 Error occurred, type: error, text: Error removing symlink: Path doesn't exist!, stackTrace: at Mono.Unix.UnixFileSystemInfo.AssertValid() + at Mono.Unix.UnixFileSystemInfo.get_FileType() + at Kudu.Services.Deployment.PushDeploymentController.PushDeployAsync(ArtifactDeploymentInfo deploymentInfo, Boolean isAsync, HttpContext context, JObject requestJson) in /tmp/KuduLite/Kudu.Services/Deployment/PushDeploymentController.cs:line 740 diff --git a/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt b/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt new file mode 100644 index 0000000..3250767 --- /dev/null +++ b/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt @@ -0,0 +1 @@ +2025-05-05T19:21:12 Error occurred, type: error, text: LogStreamManager: ProcessRequest end diff --git a/data/make_a_new_file_called_(data.db) b/appservice_logs/LogFiles/webssh/.log similarity index 100% rename from data/make_a_new_file_called_(data.db) rename to appservice_logs/LogFiles/webssh/.log diff --git a/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/log.log b/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/log.log new file mode 100644 index 0000000..2380f6c --- /dev/null +++ b/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/log.log @@ -0,0 +1,103 @@ +2025-05-05T19:17:04.5367109Z,Updating submodules.,de3dbd92-b845-41b7-8442-26c1c0b2764a,0 +2025-05-05T19:17:05.9156942Z,Preparing deployment for commit id '00c9c262-5'.,5fceedae-25ac-40fc-a431-44bbb3f50de9,0 +2025-05-05T19:17:06.1083519Z,PreDeployment: context.CleanOutputPath False,ee624d2c-5268-4166-b4c6-85d7b564d969,0 +2025-05-05T19:17:06.1721967Z,PreDeployment: context.OutputPath /home/site/wwwroot,8a1ef3be-3167-474d-95b7-46c69f22eddc,0 +2025-05-05T19:17:06.3195445Z,Repository path is /tmp/zipdeploy/extracted,f91b6150-19b9-44fe-b24d-3acef5365d2f,0 +2025-05-05T19:17:06.3875451Z,Running oryx build...,78f69326-50ce-48c8-ba5b-6be6c578933d,0 + 2025-05-05T19:17:06.3928139Z,Command: oryx build /tmp/zipdeploy/extracted -o /home/site/wwwroot --platform python --platform-version 3.10 -p virtualenv_name=antenv --log-file /tmp/build-debug.log -i /tmp/8dd8c096c8b2d70 --compress-destination-dir | tee /tmp/oryx-build.log,,0 + 2025-05-05T19:17:07.0742322Z,Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx,,0 + 2025-05-05T19:17:07.0816026Z,You can report issues at https://github.com/Microsoft/Oryx/issues,,0 + 2025-05-05T19:17:07.0928213Z,,,0 + 2025-05-05T19:17:07.1006696Z,Oryx Version: 0.2.20250107.1+ef3fb2f9c490a4fbb1f76b5746cd4ba2ff0409f4, Commit: ef3fb2f9c490a4fbb1f76b5746cd4ba2ff0409f4, ReleaseTagName: 20250107.1,,0 + 2025-05-05T19:17:07.1076851Z,,,0 + 2025-05-05T19:17:07.1165886Z,Build Operation ID: 0bf5a6b10c464f0d,,0 + 2025-05-05T19:17:07.1243416Z,Repository Commit : 00c9c262-5fed-4fb0-88d7-36d91b7e3d39,,0 + 2025-05-05T19:17:07.1297690Z,OS Type : bullseye,,0 + 2025-05-05T19:17:07.1367418Z,Image Type : githubactions,,0 + 2025-05-05T19:17:07.1435562Z,,,0 + 2025-05-05T19:17:07.1519233Z,Detecting platforms...,,0 + 2025-05-05T19:17:07.6661693Z,Detected following platforms:,,0 + 2025-05-05T19:17:07.6763926Z, python: 3.10.17,,0 + 2025-05-05T19:17:07.6814200Z,Version '3.10.17' of platform 'python' is not installed. Generating script to install it...,,0 + 2025-05-05T19:17:07.7707859Z,,,0 + 2025-05-05T19:17:07.7922682Z,Using intermediate directory '/tmp/8dd8c096c8b2d70'.,,0 + 2025-05-05T19:17:07.8000236Z,,,0 + 2025-05-05T19:17:07.8106748Z,Copying files to the intermediate directory...,,0 + 2025-05-05T19:17:07.8817109Z,Done in 0 sec(s).,,0 + 2025-05-05T19:17:07.8904193Z,,,0 + 2025-05-05T19:17:07.8980479Z,Source directory : /tmp/8dd8c096c8b2d70,,0 + 2025-05-05T19:17:07.9189602Z,Destination directory: /home/site/wwwroot,,0 + 2025-05-05T19:17:07.9307659Z,,,0 + 2025-05-05T19:17:07.9488312Z,,,0 + 2025-05-05T19:17:07.9542319Z,Downloading and extracting 'python' version '3.10.17' to '/tmp/oryx/platforms/python/3.10.17'...,,0 + 2025-05-05T19:17:07.9601580Z,Detected image debian flavor: bullseye.,,0 + 2025-05-05T19:17:10.2709940Z,Downloaded in 3 sec(s).,,0 + 2025-05-05T19:17:10.3088531Z,Verifying checksum...,,0 + 2025-05-05T19:17:10.3426547Z,Extracting contents...,,0 + 2025-05-05T19:17:14.6262426Z,performing sha512 checksum for: python...,,0 + 2025-05-05T19:17:14.9572297Z,Done in 7 sec(s).,,0 + 2025-05-05T19:17:14.9650256Z,,,0 + 2025-05-05T19:17:14.9845790Z,image detector file exists, platform is python..,,0 + 2025-05-05T19:17:14.9927820Z,OS detector file exists, OS is bullseye..,,0 + 2025-05-05T19:17:15.0824438Z,Python Version: /tmp/oryx/platforms/python/3.10.17/bin/python3.10,,0 + 2025-05-05T19:17:15.0895718Z,Creating directory for command manifest file if it does not exist,,0 + 2025-05-05T19:17:15.1105138Z,Removing existing manifest file,,0 + 2025-05-05T19:17:15.1190665Z,Python Virtual Environment: antenv,,0 + 2025-05-05T19:17:15.1256738Z,Creating virtual environment...,,0 + 2025-05-05T19:17:18.3418133Z,Activating virtual environment...,,0 + 2025-05-05T19:17:18.3783851Z,Running pip install...,,0 + 2025-05-05T19:17:22.3653505Z,[19:17:19+0000] Collecting blinker==1.9.0,,0 + 2025-05-05T19:17:22.3857878Z,[19:17:19+0000] Downloading blinker-1.9.0-py3-none-any.whl (8.5 kB),,0 + 2025-05-05T19:17:22.4097567Z,[19:17:19+0000] Collecting click==8.1.8,,0 + 2025-05-05T19:17:22.4384090Z,[19:17:19+0000] Downloading click-8.1.8-py3-none-any.whl (98 kB),,0 + 2025-05-05T19:17:22.4506519Z,[19:17:19+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.2/98.2 kB 4.1 MB/s eta 0:00:00,,0 + 2025-05-05T19:17:22.4592714Z,[19:17:19+0000] Collecting colorama==0.4.6,,0 + 2025-05-05T19:17:22.4657052Z,[19:17:19+0000] Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB),,0 + 2025-05-05T19:17:22.4739377Z,[19:17:19+0000] Collecting Flask==3.1.0,,0 + 2025-05-05T19:17:22.4819570Z,[19:17:19+0000] Downloading flask-3.1.0-py3-none-any.whl (102 kB),,0 + 2025-05-05T19:17:22.5025173Z,[19:17:19+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 103.0/103.0 kB 12.5 MB/s eta 0:00:00,,0 + 2025-05-05T19:17:22.5120936Z,[19:17:19+0000] Collecting itsdangerous==2.2.0,,0 + 2025-05-05T19:17:22.5202653Z,[19:17:19+0000] Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB),,0 + 2025-05-05T19:17:22.5290525Z,[19:17:20+0000] Collecting Jinja2==3.1.6,,0 + 2025-05-05T19:17:22.5379789Z,[19:17:20+0000] Downloading jinja2-3.1.6-py3-none-any.whl (134 kB),,0 + 2025-05-05T19:17:22.5596313Z,[19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.9/134.9 kB 18.5 MB/s eta 0:00:00,,0 + 2025-05-05T19:17:22.5680555Z,[19:17:20+0000] Collecting MarkupSafe==3.0.2,,0 + 2025-05-05T19:17:22.5781414Z,[19:17:20+0000] Downloading MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (20 kB),,0 + 2025-05-05T19:17:22.5836391Z,[19:17:20+0000] Collecting pytz==2025.2,,0 + 2025-05-05T19:17:22.5944709Z,[19:17:20+0000] Downloading pytz-2025.2-py2.py3-none-any.whl (509 kB),,0 + 2025-05-05T19:17:22.6056521Z,[19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 509.2/509.2 kB 19.2 MB/s eta 0:00:00,,0 + 2025-05-05T19:17:22.6280268Z,[19:17:20+0000] Collecting Werkzeug==3.1.3,,0 + 2025-05-05T19:17:22.6451274Z,[19:17:20+0000] Downloading werkzeug-3.1.3-py3-none-any.whl (224 kB),,0 + 2025-05-05T19:17:22.6684151Z,[19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 224.5/224.5 kB 39.9 MB/s eta 0:00:00,,0 + 2025-05-05T19:17:22.6803987Z,[19:17:21+0000] Installing collected packages: pytz, MarkupSafe, itsdangerous, colorama, click, blinker, Werkzeug, Jinja2, Flask,,0 + 2025-05-05T19:17:22.6870664Z,[19:17:22+0000] Successfully installed Flask-3.1.0 Jinja2-3.1.6 MarkupSafe-3.0.2 Werkzeug-3.1.3 blinker-1.9.0 click-8.1.8 colorama-0.4.6 itsdangerous-2.2.0 pytz-2025.2,,0 + 2025-05-05T19:17:22.6941647Z,,,0 + 2025-05-05T19:17:22.7080932Z,[notice] A new release of pip is available: 23.0.1 -> 25.1.1,,0 + 2025-05-05T19:17:22.7181540Z,[notice] To update, run: pip install --upgrade pip,,0 + 2025-05-05T19:17:22.7331385Z,Not a vso image, so not writing build commands,,0 + 2025-05-05T19:17:22.7432342Z,Preparing output...,,0 + 2025-05-05T19:17:22.7605242Z,,,0 + 2025-05-05T19:17:22.7773301Z,Copying files to destination directory '/tmp/_preCompressedDestinationDir'...,,0 + 2025-05-05T19:17:23.1845753Z,Done in 1 sec(s).,,0 + 2025-05-05T19:17:23.1993554Z,Compressing content of directory '/tmp/_preCompressedDestinationDir'...,,0 + 2025-05-05T19:17:24.6560208Z,Copied the compressed output to '/home/site/wwwroot',,0 + 2025-05-05T19:17:24.7052856Z,,,0 + 2025-05-05T19:17:24.7150280Z,Removing existing manifest file,,0 + 2025-05-05T19:17:24.7238893Z,Creating a manifest file...,,0 + 2025-05-05T19:17:24.7328270Z,Manifest file created.,,0 + 2025-05-05T19:17:24.7380821Z,Copying .ostype to manifest output directory.,,0 + 2025-05-05T19:17:24.7450571Z,,,0 + 2025-05-05T19:17:24.7519152Z,Done in 17 sec(s).,,0 +2025-05-05T19:17:25.1157876Z,Running post deployment command(s)...,823f060d-59d6-4e26-862d-7272dee2eb75,0 +2025-05-05T19:17:25.1823277Z,,9ca189b3-1914-4655-ad14-a831e45b959c,0 +2025-05-05T19:17:25.2463247Z,Generating summary of Oryx build,e009db63-3535-4548-b51e-0f74b4969183,0 +2025-05-05T19:17:25.3527029Z,Parsing the build logs,88216918-715c-4210-9aa5-9d0ddddb11b5,0 +2025-05-05T19:17:25.4500464Z,Found 0 issue(s),0f6b7e10-7dc7-4e34-8e82-8199738cdf16,0 +2025-05-05T19:17:25.5618546Z,,b33daa74-bfb5-47d6-8d7f-842989209312,0 +2025-05-05T19:17:25.6326232Z,Build Summary :,b2fe12da-5fdc-4fd2-851a-369310fcde91,0 +2025-05-05T19:17:25.7001984Z,===============,a3de1b18-eb02-452e-8407-c029a6e2f757,0 +2025-05-05T19:17:25.7651899Z,Errors (0),a9173eb6-9dd7-4444-91cf-c3d4a82ffb58,0 +2025-05-05T19:17:25.8256469Z,Warnings (0),3bc3ca2d-23ad-45ec-b06c-14a97189b5a7,0 +2025-05-05T19:17:25.8855955Z,,1615e5ef-6e98-4ba4-a1cc-4d4cb1b83bbe,0 +2025-05-05T19:17:25.9796508Z,Triggering recycle (preview mode disabled).,3869912d-0786-4fe6-88c4-884e17b4cd15,0 +2025-05-05T19:17:26.0944225Z,Deployment successful. deployer = Push-Deployer deploymentPath = ZipDeploy. Extract zip. Remote build.,bd7b213d-7741-4baa-bd4e-bc3444d5936f,0 diff --git a/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/status.xml b/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/status.xml new file mode 100644 index 0000000..36e8d99 --- /dev/null +++ b/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/status.xml @@ -0,0 +1,19 @@ + + + 00c9c262-5fed-4fb0-88d7-36d91b7e3d39 + N/A + Push-Deployer + N/A + Created via a push deployment + + Success + + 2025-05-05T19:17:26.3209072Z + 2025-05-05T19:17:04.4115236Z + 2025-05-05T19:17:05.958156Z + 2025-05-05T19:17:26.3209072Z + True + False + True + + \ No newline at end of file diff --git a/appservice_logs/deployments/active b/appservice_logs/deployments/active new file mode 100644 index 0000000..4ee4579 --- /dev/null +++ b/appservice_logs/deployments/active @@ -0,0 +1 @@ +00c9c262-5fed-4fb0-88d7-36d91b7e3d39 \ No newline at end of file diff --git a/log/make_a_new_file_called_(log.txt) b/appservice_logs/deployments/pending similarity index 100% rename from log/make_a_new_file_called_(log.txt) rename to appservice_logs/deployments/pending diff --git a/backend/controller_task.py b/backend/controller_task.py index 9aab959..0a53496 100644 --- a/backend/controller_task.py +++ b/backend/controller_task.py @@ -97,7 +97,7 @@ def edit_task_control( with db_operation() as data_cursor: data_cursor.execute( "UPDATE task SET name = ?, description = ?, due = ?, est_day = ?, " - "est_hour = ?, est_min = ?, assigner_uuid = ?, assign_uuid = ?, group_id = ?, " + "est_hour = ?, est_min = ?, assigner_uuid = ?, assign_uuid = ?, group_uuid = ?, " "recursive = ?, priority = ?, image_path = ?, completed = ? " "WHERE uuid = ?;", ( @@ -151,6 +151,14 @@ def get_user_task_control(self, user_id: str, password: str) -> dict[str, dict]: username_result = username_cursor.fetchone() if username_result: assigner_username = username_result[0] + + # Get assignee username + assignee_username = "Unknown" + with db_operation() as username_cursor: + username_cursor.execute("SELECT username FROM user WHERE uuid = ?;", (task[8],)) + username_result = username_cursor.fetchone() + if username_result: + assignee_username = username_result[0] new_task_list[task[0]] = { "name": task[1], @@ -162,17 +170,12 @@ def get_user_task_control(self, user_id: str, password: str) -> dict[str, dict]: "assigner_id": task[7], "assigner_username": assigner_username, "assign_id": task[8], + "assignee_username": assignee_username, "group_id": task[9], "completed": bool(task[10]), -<<<<<<< Updated upstream "priority": int(task[11]) if len(task) > 11 else 0, "recursive": int(task[12]) if len(task) > 12 else 0, "image_path": task[13] if len(task) > 13 else "", -======= - "priority": int(task[11]), - "recursive": int(task[12]), - "image_path": task[13], ->>>>>>> Stashed changes } return new_task_list @@ -192,10 +195,7 @@ def get_group_task_control( if not Validator().check_user_in_group(user_id=user_id, group_id=group_id): raise BackendError("Backend Error: User is not in the group", "310") with db_operation() as data_cursor: - data_cursor.execute( - "SELECT * FROM task WHERE group_id = ?;", - (group_id), - ) + data_cursor.execute("SELECT * FROM task WHERE group_uuid = ?;", (group_id,)) task_list: list[tuple] = data_cursor.fetchall() new_task_list: dict[str, dict] = {} for task in task_list: @@ -207,6 +207,14 @@ def get_group_task_control( if username_result: assigner_username = username_result[0] + # Get assignee username + assignee_username = "Unknown" + with db_operation() as username_cursor: + username_cursor.execute("SELECT username FROM user WHERE uuid = ?;", (task[8],)) + username_result = username_cursor.fetchone() + if username_result: + assignee_username = username_result[0] + new_task_list[task[0]] = { "name": task[1], "description": task[2], @@ -217,17 +225,12 @@ def get_group_task_control( "assigner_id": task[7], "assigner_username": assigner_username, "assign_id": task[8], + "assignee_username": assignee_username, "group_id": task[9], "completed": bool(task[10]), -<<<<<<< Updated upstream "priority": int(task[11]) if len(task) > 11 else 0, "recursive": int(task[12]) if len(task) > 12 else 0, "image_path": task[13] if len(task) > 13 else "", -======= - "priority": int(task[11]), - "recursive": int(task[12]), - "image_path": task[13], ->>>>>>> Stashed changes } return new_task_list @@ -249,7 +252,7 @@ def get_completed_task_control( with db_operation() as data_cursor: data_cursor.execute( "SELECT * FROM task WHERE assign_id = ? " - "OR group_id IN (SELECT group_id FROM group_user WHERE user_id = ?) " + "OR group_uuid IN (SELECT group_uuid FROM group_user WHERE user_id = ?) " "AND completed = 1;", ( group_id, @@ -279,15 +282,9 @@ def get_completed_task_control( "assign_id": task[8], "group_id": task[9], "completed": bool(task[10]), -<<<<<<< Updated upstream "priority": int(task[11]) if len(task) > 11 else 0, "recursive": int(task[12]) if len(task) > 12 else 0, "image_path": task[13] if len(task) > 13 else "", -======= - "priority": int(task[11]), - "recursive": int(task[12]), - "image_path": task[13], ->>>>>>> Stashed changes } return new_task_list diff --git a/backend/handler_task.py b/backend/handler_task.py index 6be8027..8b15349 100644 --- a/backend/handler_task.py +++ b/backend/handler_task.py @@ -86,6 +86,22 @@ def get_user_task_request(self) -> dict[str, dict[str, Any]]: user_id=user_id, password=password ) + @handle_backend_exceptions + def get_group_task_request(self) -> dict[str, dict[str, Any]]: + """Gets tasks for a specific group.""" + request_data: dict[str, Any] = extract_request_data( + request=self.user_request, + required_fields=["user_id", "group_id", "password"], + ) + user_id: str = request_data["user_id"] + group_id: str = request_data["group_id"] + password: str = request_data["password"] + return TaskController().get_group_task_control( + user_id=user_id, + group_id=group_id, + password=password + ) + @handle_backend_exceptions def get_image_request(self) -> str: """Gets the image.""" diff --git a/backend/main.py b/backend/main.py index b5b21a7..604d0de 100644 --- a/backend/main.py +++ b/backend/main.py @@ -57,7 +57,6 @@ def handle_signup() -> Response: @error_handling_decorator("login") def handle_login() -> Response: """Login a user.""" -<<<<<<< Updated upstream user_info: dict[str, str] = UserHandle(request).login_user_request() # Extract user_id and username user_id: str = user_info["user_id"] @@ -67,10 +66,6 @@ def handle_login() -> Response: # (Front end expects this and needs it to store user info) [{"error_no": "0", "message": "success", "user_id": user_id, "username": username}] ) -======= - user_id: str = UserHandle(request).login_user_request() - return jsonify([{"error_no": "0", "message": "success", "user_id": user_id}]) ->>>>>>> Stashed changes @app.route("/edit_user", methods=["POST"]) @@ -124,6 +119,14 @@ def handle_get_user_task() -> Response: return jsonify([{"error_no": "0", "message": "success", "tasks": tasks}]) +@app.route("/get_group_task", methods=["POST"]) +@error_handling_decorator("get_group_task") +def handle_get_group_task() -> Response: + """Get all tasks for a specific group.""" + tasks: dict[str, dict[str, Any]] = TaskHandle(request).get_group_task_request() + return jsonify([{"error_no": "0", "message": "success", "tasks": tasks}]) + + @app.route("/get_image", methods=["POST"]) @error_handling_decorator("get_image") def handle_get_image() -> Response: diff --git a/msdocs-python-flask-webapp-quickstart b/msdocs-python-flask-webapp-quickstart new file mode 160000 index 0000000..5bfb67b --- /dev/null +++ b/msdocs-python-flask-webapp-quickstart @@ -0,0 +1 @@ +Subproject commit 5bfb67bffda1a5083e33fec45861de6b55f74e57 diff --git a/roomiebuddy/lib/common/widget/appbar/appbar.dart b/roomiebuddy/lib/common/widget/appbar/appbar.dart index 43cd174..612c98a 100644 --- a/roomiebuddy/lib/common/widget/appbar/appbar.dart +++ b/roomiebuddy/lib/common/widget/appbar/appbar.dart @@ -26,6 +26,8 @@ class TAppBar extends StatelessWidget implements PreferredSizeWidget { Widget build(BuildContext context) { return AppBar( automaticallyImplyLeading: false, + elevation: 0, + backgroundColor: Theme.of(context).appBarTheme.backgroundColor, leading: showBackArrow ? IconButton(onPressed: () => Get.back(), icon: const Icon(Icons.arrow_back)) : leadingIcon != null diff --git a/roomiebuddy/lib/common/widget/search/task_search_delegate.dart b/roomiebuddy/lib/common/widget/search/task_search_delegate.dart new file mode 100644 index 0000000..f0bf36c --- /dev/null +++ b/roomiebuddy/lib/common/widget/search/task_search_delegate.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:roomiebuddy/pages/subpages/home/task_detail_page.dart'; + +class TaskSearchDelegate extends SearchDelegate { + final List> tasks; + TaskSearchDelegate({required this.tasks}); + + @override + List buildActions(BuildContext context) => + [IconButton(icon: const Icon(Icons.clear), onPressed: () => query = '')]; + + @override + Widget buildLeading(BuildContext context) => + IconButton(icon: const Icon(Icons.arrow_back), onPressed: () => close(context, null)); + + @override + Widget buildResults(BuildContext context) { + final results = tasks + .where((task) => + task['taskName'].toLowerCase().contains(query.toLowerCase())) + .toList(); + + return ListView.builder( + itemCount: results.length, + itemBuilder: (context, index) => ListTile( + title: Text(results[index]['taskName']), + subtitle: Text('Assigned by: ${results[index]['assignedBy']}'), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => TaskDetailScreen(task: results[index]), + ), + ); + }, + ), + ); + } + + @override + Widget buildSuggestions(BuildContext context) => buildResults(context); +} \ No newline at end of file diff --git a/roomiebuddy/lib/common/widget/task/task_list_widget.dart b/roomiebuddy/lib/common/widget/task/task_list_widget.dart new file mode 100644 index 0000000..c7600a0 --- /dev/null +++ b/roomiebuddy/lib/common/widget/task/task_list_widget.dart @@ -0,0 +1,196 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:roomiebuddy/providers/theme_provider.dart'; +import 'package:roomiebuddy/pages/subpages/home/task_detail_page.dart'; + +class TaskListWidget extends StatelessWidget { + // --- State Variables --- // + final List> allTasks; + final String? focusedGroupId; + final Set userGroupIds; + final List> roommateGroups; + final VoidCallback onTaskActionCompleted; + final bool showOnlyMyTasks; + final String? currentUserId; + + // --- Constructor --- // + + const TaskListWidget({ + super.key, + required this.allTasks, + required this.focusedGroupId, + required this.userGroupIds, + required this.roommateGroups, + required this.onTaskActionCompleted, + required this.showOnlyMyTasks, + required this.currentUserId, + }); + + @override + Widget build(BuildContext context) { + final themeProvider = Provider.of(context); + + // Create the content to display inside the container + Widget content; + + // If there are no tasks, show a message + if (allTasks.isEmpty) { + content = Center( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Text( + 'No tasks!', + style: TextStyle(color: themeProvider.currentSecondaryTextColor, fontSize: 16), + textAlign: TextAlign.center, + ), + ), + ); + } else { + // Filter tasks based on the focused group ID + List> filteredTasks = allTasks.where((task) { + final String? groupId = task["group_id"] as String?; + + // Show tasks for the focused group if one is selected + if (focusedGroupId != null) { + return groupId == focusedGroupId; + } + + // If no group is focused, show tasks that either have no group ID + // or belong to any of the user's groups. + return groupId == null || groupId == "0" || userGroupIds.contains(groupId); + }).toList(); + + // Further filter by assigned user if the flag is set + if (showOnlyMyTasks && currentUserId != null) { + filteredTasks = filteredTasks.where((task) { + // Keep tasks where assignee_id matches the current user ID + return task['assignee_id'] == currentUserId; + }).toList(); + } + + // If no tasks are found with the current filter display a message + if (filteredTasks.isEmpty) { + content = Center( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Text( + showOnlyMyTasks + ? 'No tasks assigned specifically to you${focusedGroupId != null ? ' in this group' : ''}.' + : 'No tasks found${focusedGroupId != null ? ' for this group' : ''}.', + style: TextStyle(color: themeProvider.currentSecondaryTextColor, fontSize: 16), + textAlign: TextAlign.center, + ), + ), + ); + } else { + // If there are tasks, display them + content = ListView.builder( + shrinkWrap: true, + itemCount: filteredTasks.length, + itemBuilder: (context, index) { + final task = filteredTasks[index]; + String groupName = 'Unknown Group'; // Default group name + + // Find the group name if focusedGroupId is null (showing all groups) + if (focusedGroupId == null && task['group_id'] != null) { + final group = roommateGroups.firstWhere( + (g) => g['group_id'] == task['group_id'], + orElse: () => {'group_name': 'Unknown Group'} + ); + groupName = group['group_name'] ?? 'Unknown Group'; + } + + // Return a card for each task + return Card( + margin: EdgeInsets.only(bottom: index < filteredTasks.length - 1 ? 12 : 0), + color: themeProvider.currentBackground, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + child: ListTile( + contentPadding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), + title: Text(task['taskName'], + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w500, + color: themeProvider.currentTextColor + ), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 4.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Show group name when displaying tasks from multiple groups (like in calendar) + if (focusedGroupId == null && task['group_id'] != null) ...[ + Text('Group: $groupName', style: TextStyle(color: themeProvider.currentSecondaryTextColor)), + const SizedBox(height: 2), + ], + // Always show assigned by + Text('Assigned by: ${task['assignedBy']}', style: TextStyle(color: themeProvider.currentSecondaryTextColor)), + + if (!showOnlyMyTasks) ...[ + const SizedBox(height: 2), + Text('For: ${task['assignedTo']}', style: TextStyle(color: themeProvider.currentSecondaryTextColor)), + ], + ], + ), + ), + ], + ), + trailing: Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: task['priority'] == 'High' + ? themeProvider.errorColor.withAlpha(40) + : task['priority'] == 'Medium' + ? themeProvider.warningColor.withAlpha(40) + : themeProvider.successColor.withAlpha(40), + borderRadius: BorderRadius.circular(4), + ), + child: Text( + task['priority'], + style: TextStyle( + color: task['priority'] == 'High' + ? themeProvider.errorColor + : task['priority'] == 'Medium' + ? themeProvider.warningColor + : themeProvider.successColor, + fontWeight: FontWeight.bold, + fontSize: 13, + ), + ), + ), + onTap: () async { + final result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TaskDetailScreen(task: task), + ), + ); + if (result == true && context.mounted) { + onTaskActionCompleted(); + } + }, + ), + ); + }, + ); + } + } + + // Return the styled container with the content + return Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: themeProvider.currentInputFill, + borderRadius: BorderRadius.circular(8), + ), + child: content, + ); + } +} \ No newline at end of file diff --git a/roomiebuddy/lib/main.dart b/roomiebuddy/lib/main.dart index a72173b..d1c414b 100644 --- a/roomiebuddy/lib/main.dart +++ b/roomiebuddy/lib/main.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:roomiebuddy/pages/login_screen.dart'; +import 'package:roomiebuddy/pages/subpages/auth/login_screen.dart'; import 'package:roomiebuddy/providers/theme_provider.dart'; void main() { diff --git a/roomiebuddy/lib/NavScreen.dart b/roomiebuddy/lib/nav_screen.dart similarity index 91% rename from roomiebuddy/lib/NavScreen.dart rename to roomiebuddy/lib/nav_screen.dart index 33da0ee..9d9907a 100644 --- a/roomiebuddy/lib/NavScreen.dart +++ b/roomiebuddy/lib/nav_screen.dart @@ -5,7 +5,7 @@ import 'package:roomiebuddy/providers/theme_provider.dart'; import 'pages/home_page.dart'; import 'pages/calendar_page.dart'; -import 'pages/add_taskpage.dart'; +import 'pages/add_task_page.dart'; import 'pages/group_page.dart'; import 'pages/settings_page.dart'; @@ -18,11 +18,11 @@ class Navscreen extends StatefulWidget { class _NavscreenState extends State { final pages = [ - HomePage(), - CalendarPage(), - AddTaskpage(), - GroupPage(), - SettingsPage(), + const HomePage(), + const CalendarPage(), + const AddTaskpage(), + const GroupPage(), + const SettingsPage(), ]; int selectedIndex = 0; @override diff --git a/roomiebuddy/lib/pages/add_taskpage.dart b/roomiebuddy/lib/pages/add_task_page.dart similarity index 93% rename from roomiebuddy/lib/pages/add_taskpage.dart rename to roomiebuddy/lib/pages/add_task_page.dart index f6d464e..038e328 100644 --- a/roomiebuddy/lib/pages/add_taskpage.dart +++ b/roomiebuddy/lib/pages/add_task_page.dart @@ -15,7 +15,6 @@ class AddTaskpage extends StatefulWidget { } class _AddTaskpageState extends State { - // TextEditingControllers final TextEditingController _titleController = TextEditingController(); final TextEditingController _descriptionController = TextEditingController(); @@ -70,7 +69,8 @@ class _AddTaskpageState extends State { super.dispose(); } - // Get the users id and password from the auth storage + // ------- Backend Communication Methods ------- // + Future _loadInitialData() async { setState(() => _isLoadingGroups = true); final userId = await _authStorage.getUserId(); @@ -163,112 +163,6 @@ class _AddTaskpageState extends State { } } - // For Date Picker - Future _selectDate(BuildContext context) async { - final themeProvider = Provider.of(context, listen: false); - - final DateTime? picked = await showDatePicker( - context: context, - initialDate: _selectedDate ?? DateTime.now(), - firstDate: DateTime.now().subtract(const Duration(days: 1)), - lastDate: DateTime(2101), - builder: (context, child) { - return Theme( - data: Theme.of(context).copyWith( - colorScheme: themeProvider.isDarkMode - ? ColorScheme.dark( - primary: themeProvider.themeColor, - onPrimary: themeProvider.currentTextColor, - surface: themeProvider.currentInputFill, - onSurface: themeProvider.currentTextColor, - ) - : ColorScheme.light( - primary: themeProvider.themeColor, - onPrimary: themeProvider.currentTextColor, - surface: themeProvider.currentInputFill, - onSurface: themeProvider.currentTextColor, - ), - dialogTheme: DialogTheme( - backgroundColor: themeProvider.currentInputFill, - ), - textButtonTheme: TextButtonThemeData( - style: TextButton.styleFrom( - foregroundColor: themeProvider.themeColor, - ), - ), - ), - child: child!, - ); - }, - ); - if (picked != null && picked != _selectedDate) { - setState(() { - _selectedDate = picked; - }); - } - } - - // For Time Picker - Future _selectTime(BuildContext context) async { - final themeProvider = Provider.of(context, listen: false); - - final TimeOfDay? picked = await showTimePicker( - context: context, - initialTime: _selectedTime ?? TimeOfDay.now(), - builder: (context, child) { - return Theme( - data: Theme.of(context).copyWith( - colorScheme: themeProvider.isDarkMode - ? ColorScheme.dark( - primary: themeProvider.themeColor, - onPrimary: themeProvider.currentTextColor, - surface: themeProvider.currentInputFill, - onSurface: themeProvider.currentTextColor, - ) - : ColorScheme.light( - primary: themeProvider.themeColor, - onPrimary: themeProvider.currentTextColor, - surface: themeProvider.currentInputFill, - onSurface: themeProvider.currentTextColor, - ), - timePickerTheme: TimePickerThemeData( - backgroundColor: themeProvider.currentInputFill, - dialHandColor: themeProvider.themeColor, - dayPeriodColor: themeProvider.themeColor, - dayPeriodTextColor: themeProvider.currentTextColor, - ), - dialogTheme: DialogTheme( - backgroundColor: themeProvider.currentInputFill, - ), - textButtonTheme: TextButtonThemeData( - style: TextButton.styleFrom( - foregroundColor: themeProvider.themeColor, - ), - ), - ), - child: child!, - ); - }, - ); - if (picked != null && picked != _selectedTime) { - setState(() { - _selectedTime = picked; - }); - } - } - - // For Image Picker - Future _pickImage() async { - final ImagePicker picker = ImagePicker(); - final XFile? image = await picker.pickImage(source: ImageSource.gallery); - - if (image != null) { - setState(() { - _selectedImage = File(image.path); - }); - } - } - Future _saveTask() async { if (!mounted) return; final scaffoldMessenger = ScaffoldMessenger.of(context); @@ -336,11 +230,10 @@ class _AddTaskpageState extends State { }; final int recurrenceInt = recurrenceMap[_selectedRecurrence ?? 'Once'] ?? 0; - final double? dueTimestamp = dateTimeToTimestamp(_selectedDate, _selectedTime); final int priorityInt = priorityToInt(_selectedPriority); - // If the date/time is invalid, show a snackbar - if (dueTimestamp == null) { + // If the date/time is invalid (shouldn't happen with current checks, but good practice) + if (_selectedDate == null || _selectedTime == null) { scaffoldMessenger.showSnackBar(const SnackBar(content: Text('Invalid date/time selected.'))); return; } @@ -348,21 +241,24 @@ class _AddTaskpageState extends State { setState(() => _isSaving = true); // Set saving state to true, shows a loading indicator try { - final response = await _apiService.post('/add_task', { - 'task_name': _titleController.text, - 'task_description': _descriptionController.text, - 'task_due': dueTimestamp, - 'assigner_id': _userId, - 'assign_id': _selectedMemberId!, - 'group_id': _selectedGroupId!, - 'password': _password, - 'priority': priorityInt, - 'task_est_day': estDays, - 'task_est_hour': estHours, - 'task_est_min': estMins, - 'recursive': recurrenceInt, - 'image_path': '' // TODO: Implement image upload not via path, but via file - }); + final response = await _apiService.addTask( + _titleController.text, // taskName + _descriptionController.text, // taskDescription + _selectedDate!.year, // dueYear + _selectedDate!.month, // dueMonth + _selectedDate!.day, // dueDate + _selectedTime!.hour, // dueHour + _selectedTime!.minute, // dueMin + estDays, // estDay + estHours, // estHour + estMins, // estMin + _userId, // assignerId + _selectedMemberId!, // assignId + _selectedGroupId!, // groupId + recurrenceInt, // recursive + priorityInt, // priority + _password, // password + ); if (!mounted) return; @@ -401,6 +297,114 @@ class _AddTaskpageState extends State { } } + + // ------- Date/Time/Image Picker Methods ------- // + + Future _selectDate(BuildContext context) async { + final themeProvider = Provider.of(context, listen: false); + + final DateTime? picked = await showDatePicker( + context: context, + initialDate: _selectedDate ?? DateTime.now(), + firstDate: DateTime.now().subtract(const Duration(days: 1)), + lastDate: DateTime(2101), + builder: (context, child) { + return Theme( + data: Theme.of(context).copyWith( + colorScheme: themeProvider.isDarkMode + ? ColorScheme.dark( + primary: themeProvider.themeColor, + onPrimary: themeProvider.currentTextColor, + surface: themeProvider.currentInputFill, + onSurface: themeProvider.currentTextColor, + ) + : ColorScheme.light( + primary: themeProvider.themeColor, + onPrimary: themeProvider.currentTextColor, + surface: themeProvider.currentInputFill, + onSurface: themeProvider.currentTextColor, + ), + dialogTheme: DialogTheme( + backgroundColor: themeProvider.currentInputFill, + ), + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: themeProvider.themeColor, + ), + ), + ), + child: child!, + ); + }, + ); + if (picked != null && picked != _selectedDate) { + setState(() { + _selectedDate = picked; + }); + } + } + + Future _selectTime(BuildContext context) async { + final themeProvider = Provider.of(context, listen: false); + + final TimeOfDay? picked = await showTimePicker( + context: context, + initialTime: _selectedTime ?? TimeOfDay.now(), + builder: (context, child) { + return Theme( + data: Theme.of(context).copyWith( + colorScheme: themeProvider.isDarkMode + ? ColorScheme.dark( + primary: themeProvider.themeColor, + onPrimary: themeProvider.currentTextColor, + surface: themeProvider.currentInputFill, + onSurface: themeProvider.currentTextColor, + ) + : ColorScheme.light( + primary: themeProvider.themeColor, + onPrimary: themeProvider.currentTextColor, + surface: themeProvider.currentInputFill, + onSurface: themeProvider.currentTextColor, + ), + timePickerTheme: TimePickerThemeData( + backgroundColor: themeProvider.currentInputFill, + dialHandColor: themeProvider.themeColor, + dayPeriodColor: themeProvider.themeColor, + dayPeriodTextColor: themeProvider.currentTextColor, + ), + dialogTheme: DialogTheme( + backgroundColor: themeProvider.currentInputFill, + ), + textButtonTheme: TextButtonThemeData( + style: TextButton.styleFrom( + foregroundColor: themeProvider.themeColor, + ), + ), + ), + child: child!, + ); + }, + ); + if (picked != null && picked != _selectedTime) { + setState(() { + _selectedTime = picked; + }); + } + } + + Future _pickImage() async { + final ImagePicker picker = ImagePicker(); + final XFile? image = await picker.pickImage(source: ImageSource.gallery); + + if (image != null) { + setState(() { + _selectedImage = File(image.path); + }); + } + } + + // ------- Main Build Method ------- // + @override Widget build(BuildContext context) { // Theme and general input styling setup @@ -433,7 +437,7 @@ class _AddTaskpageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Task Details Section - Title and Description + // ------------ Task Details Section ------------ // Text( 'Task Details', style: TextStyle( @@ -455,7 +459,7 @@ class _AddTaskpageState extends State { ), const SizedBox(height: 12), - // Assignment Section - Group and Member Selection + // ------------ Assignment Section ------------ // Text( 'Assign To', style: TextStyle( @@ -527,7 +531,7 @@ class _AddTaskpageState extends State { ), const SizedBox(height: 12), - // Priority Section - Task Priority Selection + // ------------ Priority Section ------------ // Text( 'Priority', style: TextStyle( @@ -558,7 +562,7 @@ class _AddTaskpageState extends State { ), const SizedBox(height: 12), - // Due Date & Time Section - Calendar and Time Pickers + // ------------ Due Date & Time Section ------------ // Text( 'Due Date & Time', style: TextStyle( @@ -603,7 +607,7 @@ class _AddTaskpageState extends State { ), const SizedBox(height: 12), - // Estimated Duration Section - Days, Hours, Minutes inputs + // ------------ Estimated Duration Section ------------ // Text( 'Estimated Duration', style: TextStyle( @@ -642,7 +646,7 @@ class _AddTaskpageState extends State { ), const SizedBox(height: 12), - // Recurrence Section - Task repetition pattern + // ------------ Recurrence Section ------------ // Text( 'Recurrence', style: TextStyle( @@ -674,7 +678,7 @@ class _AddTaskpageState extends State { ), const SizedBox(height: 16), - // Action Buttons - Add Photo and Save Task + // ------------ Action Buttons ------------ // Row( children: [ ElevatedButton.icon( diff --git a/roomiebuddy/lib/pages/calendar_page.dart b/roomiebuddy/lib/pages/calendar_page.dart index a88182f..a90287c 100644 --- a/roomiebuddy/lib/pages/calendar_page.dart +++ b/roomiebuddy/lib/pages/calendar_page.dart @@ -2,6 +2,11 @@ import 'package:flutter/material.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:provider/provider.dart'; import 'package:roomiebuddy/providers/theme_provider.dart'; +import 'package:roomiebuddy/services/auth_storage.dart'; +import 'package:roomiebuddy/services/api_service.dart'; +import 'package:roomiebuddy/common/widget/task/task_list_widget.dart'; +import 'package:roomiebuddy/utils/data_transformer.dart'; +import 'dart:async'; class CalendarPage extends StatefulWidget { const CalendarPage({super.key}); @@ -11,20 +16,36 @@ class CalendarPage extends StatefulWidget { } class _CalendarPageState extends State { - // CALENDAR PROPERTIES CalendarFormat _calendarFormat = CalendarFormat.month; DateTime _selectedDay = DateTime.now(); // Tracks day user has selected DateTime _focusedDay = DateTime.now(); // Tracks month period in view final DateTime _firstDay = DateTime.utc(2020, 1, 1); final DateTime _lastDay = DateTime.utc(2030, 12, 31); - // STYLE CONSTANTS + Map>> _events = {}; + bool _showOnlyMyTasks = true; + static const double _cellMargin = 2.0; static const double _cellPadding = 4.0; static const double _borderRadius = 8.0; static const double _fontSize = 14.0; - // MAIN BUILD METHOD + bool _isTaskLoading = true; + List> _roommateGroups = []; + String? _userId; + String? _password; + + final AuthStorage _authStorage = AuthStorage(); + final ApiService _apiService = ApiService(); + + @override + void initState() { + super.initState(); + _loadUserDataAndGroups(); + } + + // ------------ Main Build Method ------------ // + @override Widget build(BuildContext context) { final themeProvider = Provider.of(context); @@ -46,25 +67,233 @@ class _CalendarPageState extends State { children: [ _buildCalendar(), const SizedBox(height: 20), - Text( - 'Selected Day: ${_formatSelectedDate()}', - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Selected Day: ${_formatSelectedDate()}', + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: themeProvider.currentTextColor), + ), + Tooltip( + message: _showOnlyMyTasks ? 'Show all tasks' : 'Show only my tasks', + child: IconButton( + icon: Icon( + _showOnlyMyTasks ? Icons.person : Icons.group, + color: themeProvider.currentTextColor, + ), + onPressed: () { + setState(() { + _showOnlyMyTasks = !_showOnlyMyTasks; + }); + }, + ), + ), + ], ), const SizedBox(height: 10), _buildEventsList(themeProvider), + const SizedBox(height: 10), ], ), ), ); } - // CALENDAR BUILDER METHODS + // ------------ Backend Communication Methods ------------ // + Future _loadUserDataAndGroups() async { + _userId = await _authStorage.getUserId(); + _password = await _authStorage.getPassword(); + + if (_userId != null && _password != null) { + try { + final response = await _apiService.getGroupList(_userId!, _password!); + if (mounted) { + if (response['success']) { + final groupsMap = response['data']?['groups'] as Map? ?? {}; + setState(() { + _roommateGroups = groupsMap.values.map((rawGroup) { + final group = Map.from(rawGroup as Map); + final List membersData = group['members'] ?? []; + final List> processedMembers = membersData.map((member) { + if (member is Map) { + return member; + } else if (member is Map) { + return Map.from(member); + } else { + return {'user_id': 'unknown', 'username': 'Invalid Member Data'}; + } + }).toList(); + return { + ...group, + 'members': processedMembers, + 'group_name': group['name'] ?? 'Unnamed Group' + }; + }).toList(); + }); + // After loading groups, load all tasks + await _loadAllTasks(); + } else { + setState(() => _isTaskLoading = false); // Stop loading if group fetch fails + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Failed to load groups: ${response['message']}')), + ); + } + } + } catch (e) { + if (mounted) { + setState(() => _isTaskLoading = false); // Stop loading on error + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Error loading groups: $e')), + ); + } + } + } else { + if (mounted) { + setState(() => _isTaskLoading = false); // Stop loading if not logged in + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Please log in to view tasks.')), + ); + } + } + } + + Future _loadAllTasks() async { + if (!mounted || _userId == null || _password == null || _roommateGroups.isEmpty) { + setState(() => _isTaskLoading = false); // Stop loading if prerequisites aren't met + return; + } + + setState(() { + _isTaskLoading = true; // Start loading tasks + _events = {}; // Clear previous events + }); + + try { + List>> taskFutures = []; + for (var group in _roommateGroups) { + final groupId = group['group_id']; + if (groupId != null) { + taskFutures.add(_apiService.getGroupTasks(_userId!, groupId, _password!)); + } + } + + final List> responses = await Future.wait(taskFutures); + final List> allTasks = []; + final Set addedTaskIds = {}; // To handle potential duplicates if API returns same task for multiple group calls + + for (var response in responses) { + if (response['success']) { + final Map? tasksData = response['data'] as Map?; + if (tasksData != null && tasksData.containsKey('tasks')) { + final tasksMap = tasksData['tasks'] as Map; + tasksMap.forEach((taskId, taskDataRaw) { + if (!addedTaskIds.contains(taskId)) { + final taskData = taskDataRaw as Map; + // Process task data + final double? dueTimestamp = taskData['due_timestamp'] as double?; + DateTime? dueDateObject; + String? dueDateStr; + String? dueTimeStr; + if (dueTimestamp != null) { + final dateTime = DateTime.fromMillisecondsSinceEpoch((dueTimestamp * 1000).toInt()); + dueDateObject = dateTime; + const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; + dueDateStr = "${monthNames[dateTime.month - 1]} ${dateTime.day}, ${dateTime.year}"; + int hour = dateTime.hour; + final int minute = dateTime.minute; + final String period = hour < 12 ? 'AM' : 'PM'; + if (hour == 0) { hour = 12; } else if (hour > 12) { hour -= 12; } + dueTimeStr = "$hour:${minute.toString().padLeft(2, '0')} $period"; + final defaultDateCheck = "${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')}"; + final defaultTimeCheck = "${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}"; + if (defaultDateCheck == '2000-01-01' && defaultTimeCheck == '00:00') { + dueDateStr = null; dueTimeStr = null; + } + } + final int priorityInt = taskData['priority'] as int? ?? 0; + final String priorityStr = priorityToString(priorityInt); + final int estDay = taskData['est_day'] as int? ?? 0; + final int estHour = taskData['est_hour'] as int? ?? 0; + final int estMin = taskData['est_min'] as int? ?? 0; + List durationParts = []; + if (estDay > 0) durationParts.add('$estDay day${estDay > 1 ? 's' : ''}'); + if (estHour > 0) durationParts.add('$estHour hour${estHour > 1 ? 's' : ''}'); + if (estMin > 0) durationParts.add('$estMin min${estMin > 1 ? 's' : ''}'); + String estimatedDuration = durationParts.join(' '); + if (estimatedDuration.isEmpty) estimatedDuration = 'Not specified'; + final int recurrenceInt = taskData['recursive'] as int? ?? 0; + String recurrence = 'Does not repeat'; + switch (recurrenceInt) { + case 1: recurrence = 'Repeats Daily'; break; + case 7: recurrence = 'Repeats Weekly'; break; + case 30: recurrence = 'Repeats Monthly'; break; + } + + allTasks.add({ + "id": taskId, + "taskName": taskData["name"] ?? "No Task Name", + "assignedBy": taskData["assigner_username"] ?? taskData["assigner_id"] ?? "Unknown", + "assignedTo": taskData["assignee_username"] ?? taskData["assign_id"] ?? "Unknown", + "priority": priorityStr, + "description": taskData["description"] ?? "", + "dueDate": dueDateStr, + "dueTime": dueTimeStr, + "dueDateObject": dueDateObject, + "estimatedDuration": estimatedDuration, + "recurrence": recurrence, + "photo": taskData["image_path"], + "assignee_id": taskData["assign_id"], + "group_id": taskData["group_id"], + "completed": taskData["completed"] as bool? ?? false, + }); + addedTaskIds.add(taskId); + } + }); + } + } else { + // Handle individual task fetch failure (optional: show a message) + debugPrint('Failed to load tasks for a group: ${response['message']}'); + } + } + if (mounted) { + setState(() { + // Populate the events map + _events = {}; + for (var task in allTasks) { + if (task['dueDateObject'] != null) { + final date = task['dueDateObject'] as DateTime; + final dayOnly = DateTime.utc(date.year, date.month, date.day); + if (_events[dayOnly] == null) { + _events[dayOnly] = []; + } + _events[dayOnly]!.add(task); + } + } + }); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Error fetching tasks: $e')), + ); + } + } finally { + if (mounted) { + setState(() { + _isTaskLoading = false; // Loading finished + }); + } + } + } + + // ------------ Calendar Builder Methods ------------ // Widget _buildCalendar() { return TableCalendar( firstDay: _firstDay, lastDay: _lastDay, focusedDay: _focusedDay, calendarFormat: _calendarFormat, + eventLoader: _getEventsForDay, selectedDayPredicate: (day) => isSameDay(_selectedDay, day), onDaySelected: _onDaySelected, onFormatChanged: _onFormatChanged, @@ -75,7 +304,7 @@ class _CalendarPageState extends State { ); } - // CALENDAR EVENT HANDLERS + // ------------ Calendar Event Handlers ------------ // void _onDaySelected(DateTime selectedDay, DateTime focusedDay) { setState(() { _selectedDay = selectedDay; @@ -89,7 +318,7 @@ class _CalendarPageState extends State { }); } - // CALENDAR STYLE CONFIG + // ------------ Calendar Style Config ------------ // HeaderStyle _buildHeaderStyle() { return const HeaderStyle( formatButtonVisible: true, @@ -120,6 +349,12 @@ class _CalendarPageState extends State { ), cellMargin: const EdgeInsets.all(_cellMargin), cellAlignment: Alignment.topLeft, + markersAlignment: Alignment.bottomRight, + markerDecoration: BoxDecoration( + color: themeProvider.isDarkMode ? Colors.white : Colors.black87, + shape: BoxShape.circle, + ), + markersMaxCount: 1, ); } @@ -132,7 +367,7 @@ class _CalendarPageState extends State { ); } - // DAY CELL BUILDERS + // ------------ Day Cell Builders ------------ // Widget _defaultDayBuilder(BuildContext context, DateTime day, DateTime focusedDay) { final themeProvider = Provider.of(context); return _buildBaseDayContainer( @@ -183,7 +418,7 @@ class _CalendarPageState extends State { day, decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(_borderRadius)), - border: Border.all(color: themeProvider.currentBorderColor.withOpacity(0.3), width: 0.5), + border: Border.all(color: themeProvider.currentBorderColor.withAlpha(77), width: 0.5), ), textStyle: TextStyle( fontSize: _fontSize, @@ -208,29 +443,46 @@ class _CalendarPageState extends State { ); } - // HELPER METHODS + // ------------ Helper Methods ------------ // String _formatSelectedDate() { return '${_selectedDay.month}-${_selectedDay.day}-${_selectedDay.year}'; // "MM-DD-YYYY" formatting } - // EVENT LIST WIDGETS + // Helper to get events for a specific day (normalized) + List> _getEventsForDay(DateTime day) { + final normalizedDay = DateTime.utc(day.year, day.month, day.day); + final dayEvents = _events[normalizedDay] ?? []; + + // Filter events based on _showOnlyMyTasks + if (_showOnlyMyTasks && _userId != null) { + return dayEvents.where((task) => task['assignee_id'] == _userId).toList(); + } else { + return dayEvents; + } + } + + // ------------ Event List Widgets ------------ // Widget _buildEventsList(ThemeProvider themeProvider) { + final Set userGroupIds = _roommateGroups + .map((group) => group['group_id']) + .where((id) => id != null) + .cast() + .toSet(); + + final tasksForSelectedDay = _getEventsForDay(_selectedDay); + return Expanded( - child: Container( - decoration: BoxDecoration( - color: themeProvider.currentInputFill, - borderRadius: BorderRadius.circular(12), - ), - padding: const EdgeInsets.all(12), - child: Center( - child: Text( - 'No events for this day', - style: TextStyle( - color: themeProvider.currentSecondaryTextColor, + child: _isTaskLoading + ? const Center(child: CircularProgressIndicator()) + : TaskListWidget( + allTasks: tasksForSelectedDay, + focusedGroupId: null, + userGroupIds: userGroupIds, + roommateGroups: _roommateGroups, + onTaskActionCompleted: _loadAllTasks, + showOnlyMyTasks: _showOnlyMyTasks, + currentUserId: _userId, ), - ), - ), - ), ); } } diff --git a/roomiebuddy/lib/pages/group_page.dart b/roomiebuddy/lib/pages/group_page.dart index 98980a3..7bdfd67 100644 --- a/roomiebuddy/lib/pages/group_page.dart +++ b/roomiebuddy/lib/pages/group_page.dart @@ -44,6 +44,8 @@ class _GroupPageState extends State { super.dispose(); } + // ------- Backend Communication Methods ------- // + Future _loadUserData() async { setState(() { _isLoading = true; @@ -274,6 +276,8 @@ class _GroupPageState extends State { } } + // ------- Main Build Method ------- // + @override Widget build(BuildContext context) { final themeProvider = Provider.of(context); diff --git a/roomiebuddy/lib/pages/home_page.dart b/roomiebuddy/lib/pages/home_page.dart index 6ccf2b0..13830e4 100644 --- a/roomiebuddy/lib/pages/home_page.dart +++ b/roomiebuddy/lib/pages/home_page.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:http/http.dart' as http; -import 'dart:convert'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:provider/provider.dart'; import '../common/widget/appbar/appbar.dart'; import '../providers/theme_provider.dart'; import 'package:roomiebuddy/services/auth_storage.dart'; import 'package:roomiebuddy/services/api_service.dart'; +import 'subpages/home/group_detail_page.dart'; +import '../common/widget/search/task_search_delegate.dart'; +import '../common/widget/task/task_list_widget.dart'; +import '../utils/data_transformer.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @@ -16,42 +18,67 @@ class HomePage extends StatefulWidget { } class HomePageState extends State { - bool _isLoading = false; + bool _isTaskLoading = false; List> _tasks = []; List> _roommateGroups = []; + int _currentGroupIndex = 0; + bool _showOnlyMyTasks = true; final AuthStorage _authStorage = AuthStorage(); final ApiService _apiService = ApiService(); + String? _userId; String? _password; - String _userName = "User"; + String _userName = "Unknown"; @override void initState() { super.initState(); - _loadUserDataAndTasks(); + _loadUserDataAndGroups(); } - Future _loadUserDataAndTasks() async { - if (!mounted) return; - setState(() => _isLoading = true); + // --- Backend Communication Functions --- // + + Future _loadUserDataAndGroups() async { _userId = await _authStorage.getUserId(); _password = await _authStorage.getPassword(); _userName = await _authStorage.getUsername() ?? "User"; if (_userId != null && _password != null) { - await Future.wait([ - _loadTasks(_userId!, _password!), - _loadGroups(_userId!, _password!), - ]); + try { + // Load groups first + await _loadGroups(_userId!, _password!); + // After loading groups, load tasks for the initial group (if any) + if (_roommateGroups.isNotEmpty) { + final initialGroupId = _roommateGroups[_currentGroupIndex]['group_id'] ?? _roommateGroups[_currentGroupIndex]['uuid'] ?? _roommateGroups[_currentGroupIndex]['id']; + if (initialGroupId != null) { + await _loadTasksForGroup(initialGroupId); // Load tasks for the first group + } else { + // Handle case where the initial group has no ID? Set tasks empty? + if (mounted) setState(() => _tasks = []); + } + } else { + // No groups, so no group tasks to load + if (mounted) setState(() => _tasks = []); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Error loading initial data: $e')), + ); + setState(() => _tasks = []); // Clear tasks on error + } + } } else { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please log in to view tasks.')), ); + setState(() { + _tasks = []; // Clear tasks if not logged in + }); } - if (mounted) setState(() => _isLoading = false); } } @@ -81,6 +108,10 @@ class HomePageState extends State { 'group_name': group['name'] ?? 'Unnamed Group' }; }).toList(); + // Reset index if it's out of bounds after refresh + if (_currentGroupIndex >= _roommateGroups.length) { + _currentGroupIndex = _roommateGroups.isEmpty ? 0 : _roommateGroups.length - 1; + } }); } } else { @@ -88,6 +119,7 @@ class HomePageState extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Failed to load groups: ${response['message']}')), ); + setState(() => _roommateGroups = []); // Clear groups on failure } } } catch (e) { @@ -95,291 +127,354 @@ class HomePageState extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error loading groups: $e')), ); + setState(() => _roommateGroups = []); // Clear groups on error } } } - String _getGreeting() { - final hour = DateTime.now().hour; - if (hour < 12) return "Good Morning"; - if (hour < 18) return "Good Afternoon"; - return "Good Evening"; - } + Future _loadTasksForGroup(String groupId) async { + if (!mounted || _userId == null || _password == null) return; - Future _loadTasks(String userId, String password) async { - if (!mounted) return; setState(() { - _isLoading = true; + _isTaskLoading = true; // Use the task-specific loading flag }); try { - final response = await http.post( - Uri.parse('http://10.0.2.2:5000/get_user_task'), - headers: {'Content-Type': 'application/json'}, - body: jsonEncode({ - 'user_id': userId, - 'password': password - }), - ); - - if (response.statusCode == 200) { - final decoded = jsonDecode(response.body); - if (decoded is List && decoded.isNotEmpty) { - final firstItem = decoded[0]; - if (firstItem['error_no'] == '0' && firstItem['message'] is Map) { - final tasksMap = firstItem['message'] as Map; - if (mounted) { - setState(() { - _tasks = tasksMap.entries.map((entry) { - final taskId = entry.key; - final taskData = entry.value as Map; - - final double? dueTimestamp = taskData['due_timestamp'] as double?; - String? dueDateStr; - String? dueTimeStr; - if (dueTimestamp != null) { - final dateTime = DateTime.fromMillisecondsSinceEpoch((dueTimestamp * 1000).toInt()); - dueDateStr = "${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')}"; - dueTimeStr = "${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}"; + // Use ApiService to get tasks for the specified group + final response = await _apiService.getGroupTasks(_userId!, groupId, _password!); + + if (response['success']) { + final Map? tasksData = response['data'] as Map?; + + if (tasksData != null && tasksData.containsKey('tasks')) { + final tasksMap = tasksData['tasks'] as Map; + + if (mounted) { + setState(() { + _tasks = tasksMap.entries.map((entry) { + final taskId = entry.key; + final taskData = entry.value as Map; + + final double? dueTimestamp = taskData['due_timestamp'] as double?; + String? dueDateStr; + String? dueTimeStr; + if (dueTimestamp != null) { + final dateTime = DateTime.fromMillisecondsSinceEpoch((dueTimestamp * 1000).toInt()); + + // Format Date: Month DD, YYYY + const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; + dueDateStr = "${monthNames[dateTime.month - 1]} ${dateTime.day}, ${dateTime.year}"; + + // Format Time: H:MM AM/PM + int hour = dateTime.hour; + final int minute = dateTime.minute; + final String period = hour < 12 ? 'AM' : 'PM'; + if (hour == 0) { + hour = 12; // Midnight + } else if (hour > 12) { + hour -= 12; // Convert to 12-hour format } + dueTimeStr = "$hour:${minute.toString().padLeft(2, '0')} $period"; + + // Check for default date/time from backend (using original YYYY-MM-DD format for check) + final defaultDateCheck = "${dateTime.year}-${dateTime.month.toString().padLeft(2, '0')}-${dateTime.day.toString().padLeft(2, '0')}"; + final defaultTimeCheck = "${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}"; + if (defaultDateCheck == '2000-01-01' && defaultTimeCheck == '00:00') { + dueDateStr = null; // Treat as unspecified + dueTimeStr = null; + } + } - final int priorityInt = taskData['priority'] as int? ?? 0; - final String priorityStr = priorityToString(priorityInt); - - return { - "id": taskId, - "taskName": taskData["name"] ?? "No Task Name", - "assignedBy": taskData["assigner_username"] ?? taskData["assigner_id"] ?? "Unknown", - "priority": priorityStr, - "description": taskData["description"] ?? "", - "dueDate": dueDateStr, - "dueTime": dueTimeStr, - "photo": taskData["image_path"], - "assignee_id": taskData["assign_id"], - "group_id": taskData["group_id"], - "completed": taskData["completed"] as bool? ?? false, - }; - }).toList(); - }); - } - } else { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to load tasks: ${firstItem['message']}')), - ); - } + final int priorityInt = taskData['priority'] as int? ?? 0; + final String priorityStr = priorityToString(priorityInt); + + // Process estimated duration + final int estDay = taskData['est_day'] as int? ?? 0; + final int estHour = taskData['est_hour'] as int? ?? 0; + final int estMin = taskData['est_min'] as int? ?? 0; + List durationParts = []; + if (estDay > 0) durationParts.add('$estDay day${estDay > 1 ? 's' : ''}'); + if (estHour > 0) durationParts.add('$estHour hour${estHour > 1 ? 's' : ''}'); + if (estMin > 0) durationParts.add('$estMin min${estMin > 1 ? 's' : ''}'); + String estimatedDuration = durationParts.join(' '); + if (estimatedDuration.isEmpty) { + estimatedDuration = 'Not specified'; + } + + // Process recurrence + final int recurrenceInt = taskData['recursive'] as int? ?? 0; + String recurrence = 'Does not repeat'; + switch (recurrenceInt) { + case 1: recurrence = 'Repeats Daily'; break; + case 7: recurrence = 'Repeats Weekly'; break; + case 30: recurrence = 'Repeats Monthly'; break; + // Add other cases if needed + } + + return { + "id": taskId, + "taskName": taskData["name"] ?? "No Task Name", + "assignedBy": taskData["assigner_username"] ?? taskData["assigner_id"] ?? "Unknown", + "assignedTo": taskData["assignee_username"] ?? taskData["assign_id"] ?? "Unknown", + "priority": priorityStr, + "description": taskData["description"] ?? "", + "dueDate": dueDateStr, + "dueTime": dueTimeStr, + "estimatedDuration": estimatedDuration, + "recurrence": recurrence, + "photo": taskData["image_path"], + "assignee_id": taskData["assign_id"], + "group_id": taskData["group_id"], + "completed": taskData["completed"] as bool? ?? false, + }; + }).toList(); + }); } } else { if (mounted) { + setState(() => _tasks = []); // Clear tasks if format is invalid ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Failed to load tasks: Invalid server response.')), + const SnackBar(content: Text('Failed to load tasks for group: Invalid data format.')), ); } } } else { if (mounted) { + setState(() => _tasks = []); // Clear tasks on failure ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Failed to load tasks: Server error ${response.statusCode}')), + SnackBar(content: Text('Failed to load tasks for group: ${response['message']}')), ); } } } catch (e) { if (mounted) { + setState(() => _tasks = []); // Clear tasks on error ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Error fetching tasks: $e')), + SnackBar(content: Text('Error fetching tasks for group: $e')), ); } } finally { if (mounted) { setState(() { - _isLoading = false; + _isTaskLoading = false; // Loading finished for this group's tasks }); } } } - String priorityToString(int priority) { - switch (priority) { - case 0: return 'Low'; - case 1: return 'Medium'; - case 2: return 'High'; - default: return 'Unknown'; - } + // --- Helper Functions --- // + + String _getGreeting() { + final hour = DateTime.now().hour; + if (hour < 12) return "Good Morning"; + if (hour < 18) return "Good Afternoon"; + return "Good Evening"; } + // --- Build Widgets --- // + @override Widget build(BuildContext context) { String userName = _userName; - String? profileImagePath; + // String? profileImagePath; final themeProvider = Provider.of(context); - return SafeArea( - child: Scaffold( - appBar: TAppBar( - title: Row( - children: [ - if (profileImagePath != null) - Container( - width: 40, - height: 40, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all(color: Colors.grey, width: 2), - ), - child: ClipOval( - child: Image.asset( - profileImagePath, - fit: BoxFit.cover, - errorBuilder: (context, error, stackTrace) => - Icon(Icons.person, size: 30, color: Colors.grey), - ), - ), - ) - else - Container( - width: 40, - height: 40, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all(color: Colors.grey, width: 2), - ), - child: Icon(Icons.person, size: 30, color: Colors.grey), + return Scaffold( + // -------------------- AppBar -------------------- // + appBar: TAppBar( + title: Row( + // Profile Image + children: [ + // COMMENTED OUT UNTIL WE GET PROFILE PIC WORKING (The warning was bothering me) + // if (profileImagePath != null) + // Container( + // width: 40, + // height: 40, + // decoration: BoxDecoration( + // shape: BoxShape.circle, + // border: Border.all(color: Colors.grey, width: 2), + // ), + // child: ClipOval( + // child: Image.asset( + // profileImagePath, + // fit: BoxFit.cover, + // errorBuilder: (context, error, stackTrace) => const Icon(Icons.person, size: 30, color: Colors.grey), + // ), + // ), + // ) + // else + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: Colors.grey, width: 2), ), - const SizedBox(width: 10), - Text( - "${_getGreeting()}, $userName", - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + child: const Icon(Icons.person, size: 30, color: Colors.grey), ), - ], - ), - actions: [ - IconButton( - icon: const Icon(Icons.search), - onPressed: () { - showSearch( - context: context, - delegate: TaskSearchDelegate(tasks: _tasks), - ); - }, + const SizedBox(width: 10), + // Greeting + Text( + "${_getGreeting()}, $userName", + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), ], ), - body: SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - color: Theme.of(context).scaffoldBackgroundColor, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16.0, vertical: 12.0), + actions: [ + // Search Button + IconButton( + icon: const Icon(Icons.search), + onPressed: () { + showSearch( + context: context, + delegate: TaskSearchDelegate(tasks: _tasks), + ); + }, + ), + ], + ), + // -------------------- Body -------------------- // + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Roommate Groups title + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 12.0), + child: Text( + 'Groups', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: themeProvider.currentTextColor, + ), + ), + ), + // Roommate Groups carousel + Container( + color: themeProvider.themeColor, + height: 180, + child: _roommateGroups.isEmpty + ? Center( child: Text( - 'Roommate Groups', - style: TextStyle( - fontSize: 22, - fontWeight: FontWeight.bold, - color: themeProvider.currentTextColor, - ), + 'No groups found.', + style: TextStyle(color: themeProvider.currentSecondaryTextColor), ), - ), - Container( - color: themeProvider.themeColor, - height: 180, - child: _isLoading - ? const Center(child: CircularProgressIndicator()) - : _roommateGroups.isEmpty - ? Center( - child: Text( - 'No groups found.', - style: TextStyle(color: themeProvider.currentSecondaryTextColor), - ), - ) - : _buildGroupCarousel(), - ), - ], + ) + : _buildGroupCarousel(), + ), + + // -------------------- Leaderboard Section -------------------- // + Padding( + padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0), + child: Text( + 'Leaderboard', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: themeProvider.currentTextColor, ), ), - Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - 'My Tasks', - style: TextStyle( - fontSize: 25, - fontWeight: FontWeight.bold, - color: themeProvider.currentTextColor, + ), + const SizedBox(height: 50), + + // -------------------- Task Section -------------------- // + Padding( + padding: const EdgeInsets.fromLTRB(16.0, 16.0, 8.0, 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // Dynamic title + Text( + _showOnlyMyTasks ? 'My Tasks' : 'All Tasks', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: themeProvider.currentTextColor, + ), ), - ), + // Dynamic icon + Tooltip( + message: _showOnlyMyTasks ? 'Show all tasks' : 'Show only my tasks', + child: IconButton( + icon: Icon( + _showOnlyMyTasks ? Icons.person : Icons.group, + color: themeProvider.currentTextColor, + ), + onPressed: () { + setState(() { + _showOnlyMyTasks = !_showOnlyMyTasks; + }); + }, + ), + ), + ], ), - _isLoading - ? const Center(child: CircularProgressIndicator()) - : displayTasks(), - ], - ), + ), + + // Tasks List (in task_list_widget.dart) + _isTaskLoading + ? const Center(child: CircularProgressIndicator()) + : Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: _buildTaskList(), + ), + const SizedBox(height: 50), + ], ), ), ); } - Widget displayTasks() { - final themeProvider = Provider.of(context); - - if (_tasks.isEmpty) { - return Center( - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Text( - 'No tasks assigned to you yet!', - style: TextStyle(color: themeProvider.currentSecondaryTextColor, fontSize: 16), - textAlign: TextAlign.center, - ), - ), - ); + Widget _buildTaskList() { + // Get the ID of the group currently in focus + String? currentFocusedGroupId; + if (_roommateGroups.isNotEmpty && _currentGroupIndex < _roommateGroups.length) { + currentFocusedGroupId = _roommateGroups[_currentGroupIndex]['group_id']; } - return ListView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: _tasks.length, - itemBuilder: (context, index) { - final task = _tasks[index]; - Color priorityColor = themeProvider.currentSecondaryTextColor; - if (task['priority'] == 'Medium') { - priorityColor = themeProvider.warningColor; - } else if (task['priority'] == 'High') { - priorityColor = themeProvider.errorColor; - } - - return Card( - margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), - color: themeProvider.currentCardBackground, - child: ListTile( - title: Text(task['taskName'], style: TextStyle(color: themeProvider.currentTextColor)), - subtitle: Text('Assigned by: ${task['assignedBy']}', style: TextStyle(color: themeProvider.currentSecondaryTextColor)), - trailing: Text(task['priority'], - style: TextStyle(color: priorityColor, fontWeight: FontWeight.bold)), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => TaskDetailScreen(task: task), - ), - ); - }, - ), - ); - }, + // Get all group IDs the user is in + final Set userGroupIds = _roommateGroups + .map((group) => group['group_id']) // iterate through all groups + .where((id) => id != null) // filter out null IDs + .cast() // cast to String + .toSet(); // convert to a set + + // --- Task List Widget --- // + return ConstrainedBox( + constraints: const BoxConstraints( + minHeight: 300, // min height (CHANGE THIS TO MAKE DYNAMIC) + maxHeight: 300, // max height + ), + child: TaskListWidget( + allTasks: _tasks, + focusedGroupId: currentFocusedGroupId, + userGroupIds: userGroupIds, + roommateGroups: _roommateGroups, + onTaskActionCompleted: () { + if (currentFocusedGroupId != null) { + _loadTasksForGroup(currentFocusedGroupId); + } else { + // Reload groups and then tasks if group ID is missing + _loadUserDataAndGroups(); + } + }, + showOnlyMyTasks: _showOnlyMyTasks, + currentUserId: _userId, + ), ); } Widget _buildGroupCarousel() { final themeProvider = Provider.of(context); + + // No groups to display if (_roommateGroups.isEmpty) { return const Center(child: Text('No groups to display.')); } + // --- Group Carousel --- // return SizedBox( height: 140, child: CarouselSlider( @@ -387,24 +482,47 @@ class HomePageState extends State { height: 140.0, enlargeCenterPage: true, autoPlay: false, - viewportFraction: 0.6, + viewportFraction: 0.85, + initialPage: _currentGroupIndex, + onPageChanged: (index, reason) { + setState(() { + _currentGroupIndex = index; + }); + // Load tasks for the newly focused group + if (_roommateGroups.isNotEmpty && index < _roommateGroups.length) { + final newGroupId = _roommateGroups[index]['group_id']; + if (newGroupId != null) { + _loadTasksForGroup(newGroupId); + } + } + }, ), items: _roommateGroups.map((group) { - final List membersData = group['members'] ?? []; - final List memberNames = membersData - .map((member) => member['username'] as String? ?? 'Unknown') - .toList(); - return Builder( builder: (BuildContext context) { return GestureDetector( - onTap: () { - Navigator.push( + onTap: () async { + // Determine if this is the last group before navigating + final result = await Navigator.push( context, MaterialPageRoute( - builder: (_) => GroupDetailScreen(group: group), + builder: (_) => GroupDetailScreen( + group: group, + ), ), ); + + // If left group (result is true), refresh the groups list and initial tasks + if (result == true && mounted) { + _loadUserDataAndGroups(); // Reload groups and tasks for index 0 + } + // If a task within the group was updated, refresh tasks for the *current* group + else if (result == 'task_updated' && mounted) { + final currentGroupId = _roommateGroups[_currentGroupIndex]['group_id']; + if (currentGroupId != null) { + _loadTasksForGroup(currentGroupId); + } + } }, child: Container( width: MediaQuery.of(context).size.width * 0.6, @@ -424,7 +542,8 @@ class HomePageState extends State { ], ), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( group['group_name'] ?? 'Unnamed Group', @@ -433,16 +552,7 @@ class HomePageState extends State { fontWeight: FontWeight.bold, color: themeProvider.currentTextColor, ), - ), - const SizedBox(height: 8), - Text( - "Members: ${memberNames.join(', ')}", - style: TextStyle( - fontSize: 16, - color: themeProvider.currentSecondaryTextColor, - ), - overflow: TextOverflow.ellipsis, - maxLines: 2, + textAlign: TextAlign.center, ), ], ), @@ -455,116 +565,3 @@ class HomePageState extends State { ); } } - -// ========================== -// EXTRA SCREENS (Appended) -// ========================== - -class TaskDetailScreen extends StatelessWidget { - final Map task; - - const TaskDetailScreen({super.key, required this.task}); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar(title: Text(task['taskName'])), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: ListView( - children: [ - Text("Title: ${task['taskName']}", - style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), - const SizedBox(height: 12), - Text("Description: ${task['description'] ?? "No description"}"), - const SizedBox(height: 12), - Text("Priority: ${task['priority']}"), - const SizedBox(height: 12), - if (task['photo'] != null) - Image.network(task['photo'], - errorBuilder: (_, __, ___) => const Text("Image failed to load")), - const SizedBox(height: 12), - Text("Due Date: ${task['dueDate'] ?? 'Not specified'}"), - Text("Time Due: ${task['dueTime'] ?? 'Not specified'}"), - ], - ), - ), - ); - } -} - -class GroupDetailScreen extends StatelessWidget { - final Map group; - - const GroupDetailScreen({super.key, required this.group}); - - @override - Widget build(BuildContext context) { - final List membersData = group['members'] ?? []; - final List memberNames = membersData - .map((member) => member['username'] as String? ?? 'Unknown') - .toList(); - - return Scaffold( - appBar: AppBar(title: Text(group['group_name'] ?? 'Group Details')), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Group Name: ${group['group_name'] ?? 'Unnamed Group'}", - style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold) - ), - const SizedBox(height: 20), - const Text("Members:", style: TextStyle(fontSize: 20)), - ...memberNames.map((name) => Padding( - padding: const EdgeInsets.only(left: 8.0, top: 4.0), - child: Text("- $name"), - )), - ], - ), - ), - ); - } -} - -class TaskSearchDelegate extends SearchDelegate { - final List> tasks; - TaskSearchDelegate({required this.tasks}); - - @override - List buildActions(BuildContext context) => - [IconButton(icon: const Icon(Icons.clear), onPressed: () => query = '')]; - - @override - Widget buildLeading(BuildContext context) => - IconButton(icon: const Icon(Icons.arrow_back), onPressed: () => close(context, null)); - - @override - Widget buildResults(BuildContext context) { - final results = tasks - .where((task) => - task['taskName'].toLowerCase().contains(query.toLowerCase())) - .toList(); - - return ListView.builder( - itemCount: results.length, - itemBuilder: (context, index) => ListTile( - title: Text(results[index]['taskName']), - subtitle: Text('Assigned by: ${results[index]['assignedBy']}'), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (_) => TaskDetailScreen(task: results[index]), - ), - ); - }, - ), - ); - } - - @override - Widget buildSuggestions(BuildContext context) => buildResults(context); -} diff --git a/roomiebuddy/lib/pages/settings_page.dart b/roomiebuddy/lib/pages/settings_page.dart index 82ba93c..09afaa2 100644 --- a/roomiebuddy/lib/pages/settings_page.dart +++ b/roomiebuddy/lib/pages/settings_page.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:roomiebuddy/providers/theme_provider.dart'; import 'package:flutter_colorpicker/flutter_colorpicker.dart'; -import 'package:roomiebuddy/pages/login_screen.dart'; +import 'package:roomiebuddy/pages/subpages/auth/login_screen.dart'; import 'package:roomiebuddy/services/auth_storage.dart'; import 'package:flutter/services.dart'; @@ -26,6 +26,8 @@ class _SettingsPageState extends State { _loadUserData(); } + // ------- Backend Communication Methods ------- // + Future _loadUserData() async { setState(() { _isLoading = true; @@ -62,6 +64,8 @@ class _SettingsPageState extends State { } } + // ------- Color Picker Method ------- // + void _openColorPicker(BuildContext context, ThemeProvider themeProvider) { Color pickerColor = themeProvider.themeColor; @@ -113,6 +117,8 @@ class _SettingsPageState extends State { ); } + // ------- Main Build Method ------- // + @override Widget build(BuildContext context) { final themeProvider = Provider.of(context); @@ -166,7 +172,7 @@ class _SettingsPageState extends State { ), margin: const EdgeInsets.only(bottom: 16.0), child: Padding( - padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 16.0), + padding: const EdgeInsets.fromLTRB(16.0, 4.0, 0.0, 4.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ diff --git a/roomiebuddy/lib/pages/login_screen.dart b/roomiebuddy/lib/pages/subpages/auth/login_screen.dart similarity index 98% rename from roomiebuddy/lib/pages/login_screen.dart rename to roomiebuddy/lib/pages/subpages/auth/login_screen.dart index 7ddfcbc..399879f 100644 --- a/roomiebuddy/lib/pages/login_screen.dart +++ b/roomiebuddy/lib/pages/subpages/auth/login_screen.dart @@ -3,9 +3,9 @@ import 'package:flutter/material.dart'; import 'package:email_validator/email_validator.dart'; import 'package:provider/provider.dart'; -import 'package:roomiebuddy/NavScreen.dart'; +import 'package:roomiebuddy/nav_screen.dart'; import 'package:roomiebuddy/providers/theme_provider.dart'; -import 'package:roomiebuddy/pages/signup_screen.dart'; +import 'package:roomiebuddy/pages/subpages/auth/signup_screen.dart'; import 'package:roomiebuddy/services/api_service.dart'; import 'package:roomiebuddy/services/auth_storage.dart'; diff --git a/roomiebuddy/lib/pages/signup_screen.dart b/roomiebuddy/lib/pages/subpages/auth/signup_screen.dart similarity index 99% rename from roomiebuddy/lib/pages/signup_screen.dart rename to roomiebuddy/lib/pages/subpages/auth/signup_screen.dart index 9846491..b1e8395 100644 --- a/roomiebuddy/lib/pages/signup_screen.dart +++ b/roomiebuddy/lib/pages/subpages/auth/signup_screen.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:email_validator/email_validator.dart'; import 'package:provider/provider.dart'; import 'package:roomiebuddy/providers/theme_provider.dart'; -import 'package:roomiebuddy/pages/login_screen.dart'; +import 'package:roomiebuddy/pages/subpages/auth/login_screen.dart'; import 'package:roomiebuddy/services/api_service.dart'; class SignupScreen extends StatefulWidget { diff --git a/roomiebuddy/lib/pages/subpages/home/group_detail_page.dart b/roomiebuddy/lib/pages/subpages/home/group_detail_page.dart new file mode 100644 index 0000000..3088e5c --- /dev/null +++ b/roomiebuddy/lib/pages/subpages/home/group_detail_page.dart @@ -0,0 +1,141 @@ +import 'package:flutter/material.dart'; +import 'package:roomiebuddy/services/api_service.dart'; +import 'package:roomiebuddy/services/auth_storage.dart'; + +class GroupDetailScreen extends StatelessWidget { + final Map group; + + const GroupDetailScreen({ + super.key, + required this.group, + }); + + @override + // ----- Group Detail Page ----- // + Widget build(BuildContext context) { + final List membersData = group['members'] ?? []; + final List memberNames = membersData + .map((member) => member['username'] as String? ?? 'Unknown') + .toList(); + + return Scaffold( + appBar: AppBar(title: Text(group['group_name'] ?? 'Group Details')), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Group Name: ${group['group_name'] ?? 'Unnamed Group'}", + style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold) + ), + const SizedBox(height: 20), + const Text("Members:", style: TextStyle(fontSize: 20)), + ...memberNames.map((name) => Padding( + padding: const EdgeInsets.only(left: 8.0, top: 4.0), + child: Text("- $name"), + )), + const SizedBox(height: 30), + Center( + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + ), + onPressed: () => _showLeaveGroupConfirmation(context), + child: const Text('Leave Group'), + ), + ), + ], + ), + ), + ); + } + + // ----- Leave Group Confirmation ----- // + void _showLeaveGroupConfirmation(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext dialogContext) { + return AlertDialog( + title: const Text('Leave Group'), + content: Text('Are you sure you want to leave "${group['group_name'] ?? 'this group'}"?'), + actions: [ + TextButton( + onPressed: () => Navigator.of(dialogContext).pop(), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () { + Navigator.of(dialogContext).pop(); + _leaveGroup(context); + }, + child: const Text('Leave'), + ), + ], + ); + }, + ); + } + + // ----- Leave Group (Backend Communication) ----- // + Future _leaveGroup(BuildContext context) async { + final AuthStorage authStorage = AuthStorage(); + final ApiService apiService = ApiService(); + + try { + final userId = await authStorage.getUserId(); + final password = await authStorage.getPassword(); + + if (!context.mounted) return; + + if (userId == null || password == null) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Please log in to leave the group.')), + ); + return; + } + + // Try to find group ID from various possible fields + final String? groupId = group['group_id'] ?? group['uuid'] ?? group['id']; + if (groupId == null) { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Group ID not found.')), + ); + return; + } + + final response = await apiService.leaveGroup(userId, password, groupId); + + if (!context.mounted) return; + + // Check for success directly from the Map response + final bool isSuccess = response['success'] == true; + + if (isSuccess) { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Successfully left the group.')), + ); + + // Pop to home page and signal success (true) + Navigator.pop(context, true); + } else { + // Get error message directly from the Map response + final String errorMsg = response['message'] as String? ?? 'Unknown error leaving group'; + + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Failed to leave group: $errorMsg')), + ); + } + } catch (e) { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Error leaving group: $e')), + ); + } + } +} \ No newline at end of file diff --git a/roomiebuddy/lib/pages/subpages/home/task_detail_page.dart b/roomiebuddy/lib/pages/subpages/home/task_detail_page.dart new file mode 100644 index 0000000..09f7933 --- /dev/null +++ b/roomiebuddy/lib/pages/subpages/home/task_detail_page.dart @@ -0,0 +1,132 @@ +import 'package:flutter/material.dart'; +import 'package:roomiebuddy/services/api_service.dart'; +import 'package:roomiebuddy/services/auth_storage.dart'; + +class TaskDetailScreen extends StatelessWidget { + final Map task; + + const TaskDetailScreen({super.key, required this.task}); + + @override + // ----- Task Detail Page ----- // + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text(task['taskName'])), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListView( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + children: [ + Text("Title: ${task['taskName']}", + style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)), + const SizedBox(height: 12), + Text("Description: ${task['description']?.isNotEmpty == true ? task['description'] : 'Not specified'}"), + const SizedBox(height: 12), + Text("Priority: ${task['priority']}"), + const SizedBox(height: 12), + Text("Assigned by: ${task['assignedBy']}"), + Text("Assigned to: ${task['assignedTo']}"), + const SizedBox(height: 12), + Text("Due Date: ${task['dueDate'] ?? 'Not specified'}"), + Text("Time Due: ${task['dueTime'] ?? 'Not specified'}"), + const SizedBox(height: 12), + Text("Estimated Duration: ${task['estimatedDuration'] ?? 'Not specified'}"), + const SizedBox(height: 12), + Text("Recurrence: ${task['recurrence'] ?? 'Not specified'}"), + ], + ), + const SizedBox(height: 30), + Center( + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), + ), + onPressed: () => _showDeleteConfirmation(context), + child: const Text('Delete Task'), + ), + ), + ], + ), + ), + ); + } + + // ----- Delete Task Confirmation ----- // + void _showDeleteConfirmation(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext dialogContext) { + return AlertDialog( + title: const Text('Delete Task'), + content: Text('Are you sure you want to delete "${task['taskName']}"? This action cannot be undone.'), + actions: [ + TextButton( + onPressed: () => Navigator.of(dialogContext).pop(), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () { + Navigator.of(dialogContext).pop(); + _deleteTask(context); + }, + child: const Text('Delete', style: TextStyle(color: Colors.red)), + ), + ], + ); + }, + ); + } + + // ----- Delete Task (Backend Communication) ----- // + Future _deleteTask(BuildContext context) async { + final AuthStorage authStorage = AuthStorage(); + final ApiService apiService = ApiService(); + + try { + final userId = await authStorage.getUserId(); + final password = await authStorage.getPassword(); + final taskId = task['id'] as String?; + + if ((userId == null || password == null)) { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Please log in to delete the task.')), + ); + return; + } + if (taskId == null) { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Task ID not found.')), + ); + return; + } + + final response = await apiService.deleteTask(userId, password, taskId); + + if (!context.mounted) return; + + if (response['success']) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Task deleted successfully.')), + ); + Navigator.pop(context, true); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Failed to delete task: ${response['message']}')), + ); + } + } catch (e) { + if (!context.mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Error deleting task: $e')), + ); + } + } +} \ No newline at end of file diff --git a/roomiebuddy/lib/pages/view_taskpage.dart b/roomiebuddy/lib/pages/view_taskpage.dart deleted file mode 100644 index 876e163..0000000 --- a/roomiebuddy/lib/pages/view_taskpage.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:flutter/material.dart'; - -class ViewTaskpage extends StatefulWidget { - const ViewTaskpage({super.key}); - - @override - State createState() => _ViewTaskpageState(); -} - -class _ViewTaskpageState extends State { - @override - Widget build(BuildContext context) { - return const Scaffold(); - } -} \ No newline at end of file diff --git a/roomiebuddy/lib/providers/theme_provider.dart b/roomiebuddy/lib/providers/theme_provider.dart index b144ebc..5b9380e 100644 --- a/roomiebuddy/lib/providers/theme_provider.dart +++ b/roomiebuddy/lib/providers/theme_provider.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; class ThemeProvider extends ChangeNotifier { - bool _isDarkMode = true; // GLOBAL DARK MODE FLAG - Color _themeColor = Colors.blueGrey; // GLOBAL THEME COLOR + bool _isDarkMode = true; // Dark mode set to default + Color _themeColor = Colors.blueGrey; // Global theme color // Utility colors (Theme independent) Color get errorColor => Colors.red; @@ -32,12 +32,12 @@ class ThemeProvider extends ChangeNotifier { Color get switchInactiveTrack => Colors.grey[300]!; // Circle colors (Main background) - Color get primaryHeaderColor => _themeColor.withOpacity(0.8); - Color get primaryHeaderOverlayColor => Colors.white.withOpacity(0.1); + Color get primaryHeaderColor => _themeColor.withAlpha(204); + Color get primaryHeaderOverlayColor => Colors.white.withAlpha(26); // Calendar colors Color get calendarSelectedDayColor => _themeColor; - Color get calendarTodayColor => _themeColor.withOpacity(0.5); + Color get calendarTodayColor => _themeColor.withAlpha(128); Color get calendarWeekendTextColor => _isDarkMode ? darkTextColor : lightTextColor; Color get calendarDefaultTextColor => _isDarkMode ? darkTextColor : lightTextColor; Color get calendarSelectedDayTextColor => _isDarkMode ? darkBackground : Colors.white; @@ -63,7 +63,7 @@ class ThemeProvider extends ChangeNotifier { final secondaryTextColor = isDark ? darkTextSecondary : lightTextSecondary; final borderColor = isDark ? darkBorder : lightBorder; final inputFillColor = isDark ? darkWidgetBackground : lightInputFill; - final appBarBgColor = isDark ? _themeColor.withOpacity(0.8) : _themeColor; + final appBarBgColor = isDark ? _themeColor.withAlpha(204) : _themeColor; return ThemeData( brightness: isDark ? Brightness.dark : Brightness.light, diff --git a/roomiebuddy/lib/services/api_service.dart b/roomiebuddy/lib/services/api_service.dart index c82cd67..620a913 100644 --- a/roomiebuddy/lib/services/api_service.dart +++ b/roomiebuddy/lib/services/api_service.dart @@ -3,12 +3,12 @@ import 'package:http/http.dart' as http; class ApiService { // BASE URL - static const String baseUrl = 'http://10.0.2.2:5000'; + static const String baseUrl = 'https://msdocs-python-webapp-quickstart-rmb.azurewebsites.net'; // HTTP client final http.Client _client = http.Client(); - // Singleton pattern implC + // Singleton pattern impl static final ApiService _instance = ApiService._internal(); factory ApiService() { @@ -65,7 +65,7 @@ class ApiService { }); } - // TASK METHODS + // ------------ TASK METHODS ------------ // // Get user tasks Future> getUserTasks(String userId, String password) async { @@ -75,6 +75,15 @@ class ApiService { }); } + // Get group tasks + Future> getGroupTasks(String userId, String groupId, String password) async { + return await post('/get_group_task', { + 'user_id': userId, + 'group_id': groupId, + 'password': password, + }); + } + // Add a new task Future> addTask( String taskName, @@ -114,7 +123,20 @@ class ApiService { }); } - // GROUP METHODS + // Delete a task + Future> deleteTask( + String userId, + String password, + String taskId, + ) async { + return await post('/delete_task', { + 'user_id': userId, + 'password': password, + 'task_id': taskId, + }); + } + + // ------------ GROUP METHODS ------------ // // Get all groups for a user Future> getGroupList(String userId, String password) async { @@ -170,17 +192,6 @@ class ApiService { return _handleError(e); } } - // **** END NEW METHOD **** - - // Helper to convert priority int to string - String priorityToString(int priority) { - switch (priority) { - case 0: return 'Low'; - case 1: return 'Medium'; - case 2: return 'High'; - default: return 'Unknown'; - } - } // Create a new group Future> createGroup( @@ -223,6 +234,8 @@ class ApiService { }); } + // ------------ INVITE METHODS ------------ // + // Invite a user to a group Future> inviteToGroup( String inviterId, @@ -261,6 +274,8 @@ class ApiService { }); } + // ------------ HANDLE RESPONSE METHODS ------------ // + // Handle HTTP response Map _handleResponse(http.Response response) { if (response.statusCode >= 200 && response.statusCode < 300) { diff --git a/roomiebuddy/lib/services/auth_storage.dart b/roomiebuddy/lib/services/auth_storage.dart index 56273e5..a3d31d2 100644 --- a/roomiebuddy/lib/services/auth_storage.dart +++ b/roomiebuddy/lib/services/auth_storage.dart @@ -1,5 +1,5 @@ import 'package:shared_preferences/shared_preferences.dart'; - +import 'package:flutter/foundation.dart' show debugPrint; class AuthStorage { // Keys for SharedPreferences static const String _userIdKey = 'user_id'; @@ -26,7 +26,7 @@ class AuthStorage { await prefs.setString(_usernameKey, username); return true; } catch (e) { - print('Error storing user credentials: $e'); + debugPrint('Error storing user credentials: $e'); return false; } } @@ -37,7 +37,7 @@ class AuthStorage { final prefs = await SharedPreferences.getInstance(); return prefs.getString(_userIdKey); } catch (e) { - print('Error getting user ID: $e'); + debugPrint('Error getting user ID: $e'); return null; } } @@ -48,7 +48,7 @@ class AuthStorage { final prefs = await SharedPreferences.getInstance(); return prefs.getString(_emailKey); } catch (e) { - print('Error getting email: $e'); + debugPrint('Error getting email: $e'); return null; } } @@ -59,7 +59,7 @@ class AuthStorage { final prefs = await SharedPreferences.getInstance(); return prefs.getString(_passwordKey); } catch (e) { - print('Error getting password: $e'); + debugPrint('Error getting password: $e'); return null; } } @@ -70,7 +70,7 @@ class AuthStorage { final prefs = await SharedPreferences.getInstance(); return prefs.getString(_usernameKey); } catch (e) { - print('Error getting username: $e'); + debugPrint('Error getting username: $e'); return null; } } @@ -86,8 +86,8 @@ class AuthStorage { final password = prefs.getString(_passwordKey); final username = prefs.getString(_usernameKey); - // For development/debugging - remove or set to false in production - print("Auth check: UserId=$userId, Email=$email, Username=$username"); + // For development/debugging - REMEMBER: remove or set to false in production (proabably wont happen) + debugPrint("Auth check: UserId=$userId, Email=$email, Username=$username"); // Ensure all values exist and aren't empty return userId != null && userId.isNotEmpty && @@ -95,7 +95,7 @@ class AuthStorage { password != null && password.isNotEmpty && username != null && username.isNotEmpty; } catch (e) { - print('Error checking login status: $e'); + debugPrint('Error checking login status: $e'); return false; } } @@ -110,7 +110,7 @@ class AuthStorage { await prefs.remove(_usernameKey); return true; } catch (e) { - print('Error clearing user credentials: $e'); + debugPrint('Error clearing user credentials: $e'); return false; } } diff --git a/roomiebuddy/lib/splash_screen.dart b/roomiebuddy/lib/splash_screen.dart index 344083a..facd7ba 100644 --- a/roomiebuddy/lib/splash_screen.dart +++ b/roomiebuddy/lib/splash_screen.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -//import 'package:roomiebuddy/NavScreen.dart'; -import 'package:roomiebuddy/pages/login_screen.dart'; -// import 'package:myapp/main.dart'; +import 'package:roomiebuddy/pages/subpages/auth/login_screen.dart'; import 'package:animated_text_kit/animated_text_kit.dart'; import 'package:provider/provider.dart'; import 'package:roomiebuddy/providers/theme_provider.dart'; diff --git a/roomiebuddy/lib/utils/data_transformer.dart b/roomiebuddy/lib/utils/data_transformer.dart index dab6506..3dbfc7b 100644 --- a/roomiebuddy/lib/utils/data_transformer.dart +++ b/roomiebuddy/lib/utils/data_transformer.dart @@ -1,25 +1,3 @@ -import 'package:flutter/material.dart'; - -/// Converts a DateTime and TimeOfDay into a Unix timestamp (seconds since epoch). -/// Returns null if either date or time is null. -double? dateTimeToTimestamp(DateTime? date, TimeOfDay? time) { - if (date == null || time == null) { - return null; - } - final combinedDateTime = DateTime( - date.year, - date.month, - date.day, - time.hour, - time.minute, - ); - // Convert to seconds since epoch (Unix timestamp) - return combinedDateTime.millisecondsSinceEpoch / 1000.0; -} - -/// Converts a priority string ('Low', 'Medium', 'High') to an integer. -/// Returns 0 for 'Low', 1 for 'Medium', 2 for 'High'. -/// Returns 0 (Low) if the input is null or doesn't match. int priorityToInt(String? priority) { switch (priority) { case 'Low': @@ -29,6 +7,15 @@ int priorityToInt(String? priority) { case 'High': return 2; default: - return 0; // Default to Low if null or unknown + return 0; + } +} + +String priorityToString(int priority) { + switch (priority) { + case 0: return 'Low'; + case 1: return 'Medium'; + case 2: return 'High'; + default: return 'Unknown'; } -} \ No newline at end of file +} \ No newline at end of file From 898dad5e8664e5c80173bf11ef7efcff56bbbd0c Mon Sep 17 00:00:00 2001 From: jacobecontreras Date: Mon, 5 May 2025 13:01:42 -0700 Subject: [PATCH 2/2] Remove Azure log files --- appservice_logs.zip | Bin 24948 -> 0 bytes .../2025_05_05_10-30-0-104_default_docker.log | 80 ---------- ...5_05_05_10-30-0-104_default_scm_docker.log | 140 ------------------ .../2025_05_05_10-30-0-104_docker.log | 84 ----------- .../startup_4.log | 4 - .../LogFiles/CodeProfiler/870d61_debug.log | 8 - ...0d61_001_Startup_POST_api-zipdeploy_0s.xml | 3 - ...0_870d61_002_POST_api-zipdeploy_202_0s.xml | 20 --- ..._Background_POST_api-zipdeploy_pending.xml | 32 ---- ..._004_GET_api-deployments-latest_202_0s.xml | 9 -- ...262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml | 4 - ...262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml | 5 - ...262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml | 5 - ...8-12_870d61_008_GET_logstream_200_180s.xml | 6 - ...treamManager:-Dispose()-called_pending.xml | 2 - ...41_870d61_001_Startup_GET_logstream_0s.xml | 3 - ...24-41_870d61_002_GET_logstream_pending.xml | 2 - ...5T19-26-27_870d61_003_GET_dump_pending.xml | 2 - ...a-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt | 1 - ...0-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt | 4 - ...0-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt | 1 - appservice_logs/LogFiles/webssh/.log | 0 .../log.log | 103 ------------- .../status.xml | 19 --- appservice_logs/deployments/active | 1 - appservice_logs/deployments/pending | 0 26 files changed, 538 deletions(-) delete mode 100644 appservice_logs.zip delete mode 100644 appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_docker.log delete mode 100644 appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_scm_docker.log delete mode 100644 appservice_logs/LogFiles/2025_05_05_10-30-0-104_docker.log delete mode 100644 appservice_logs/LogFiles/AppServiceAppLogs_Feature_Installer/startup_4.log delete mode 100644 appservice_logs/LogFiles/CodeProfiler/870d61_debug.log delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_001_Startup_POST_api-zipdeploy_0s.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_002_POST_api-zipdeploy_202_0s.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_003_Background_POST_api-zipdeploy_pending.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-05_870d61_004_GET_api-deployments-latest_202_0s.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-06_870d61_005_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-22_870d61_006_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-38_870d61_007_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-18-12_870d61_008_GET_logstream_200_180s.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-21-12_870d61_009_LogStreamManager:-Dispose()-called_pending.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_001_Startup_GET_logstream_0s.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_002_GET_logstream_pending.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/2025-05-05T19-26-27_870d61_003_GET_dump_pending.xml delete mode 100644 appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-a9ca9bea-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt delete mode 100644 appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt delete mode 100644 appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt delete mode 100644 appservice_logs/LogFiles/webssh/.log delete mode 100644 appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/log.log delete mode 100644 appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/status.xml delete mode 100644 appservice_logs/deployments/active delete mode 100644 appservice_logs/deployments/pending diff --git a/appservice_logs.zip b/appservice_logs.zip deleted file mode 100644 index 65339b414c706886048d9076d5f6bcca1e8b88db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24948 zcmb@t19W6vyDl0h9j9a4s@S$|+qToOZQHh;j&0jUhn?j1_wT*W_n+^cJI20yoT{}( z&9TNT)9N-mV6T(3M{T$~*kiNtlxL)%OkLS*C3cXY zN1^s0ipu-M(>kjRsfUOM!-K0-QJKppC>7sxrzV@4JkHQrGEQeL;*|Cm&?8h<*DaRB z-n?H9bB0X0b^3N*=mmd-ULyju|i)Zu4>t*wqYv9$p+pBBf za?6_A%&iVQ8^Oc`#Gl8|yl-6HpLlYedxZzK=ARn1mvPU)twcHIdYv{#FprFt!-`b-gXu(A z+VYq+&*NNNv1S@e)4b#yc6#cVYP8hVFzP}Ju}~AK)Yvm4aF&wAmdq}DP)dn^4k{I; zNqg?K1cf#|`x=6Jke8@C%yoPKKw^ZIGgULc|C3JRN zxf$THx!JMpvFbwj8#{$^El;sjpS$3w;loQzq}|jo{T76(9>Lev=m_voYST_aBcdee zwlP}SJBObJ3$3-(FLq4dJke)ewDs!3OS@oAcB_TuW%W}i-%r8na+7}T!$yKpU@$Qo+1 z#bPfLf{bm)~ z%02Qq;3`KPwN+!y!5c|b2n7{shCPajir;I_eMNjPe0IcUMbLMGF6@9~Q8{e)CV{IQ z#$=9bcSX5EiGAa}LvgC#e@Wpm*E$0@%z_y!43D}{@=3zZ z=M^m^5&gkSrTj!2T7NR7?Xq}0)I}e@X!h@{5KM-$`>_p#?_XQq{jzC`i3O_~g_4v< z>MF=Y&o5er=*#T|L7^wHe`I_@n(q@$TyYDJI@TV?80=SE@VPCl(5TIP7Xwj!Xw?F( z2$&wr(NYCXG~S%v*>C#}JH9EDu1#{?kBeSZ4xdSePOPRwa=*=d+b**b`inCK^VMn- z_Bt2DX>NHV=W*(htNh(*q&Y>Sw7;@(qfwV&Uto#PSpt&fg?>&7_f5P{bCz~ALL2t( z5VS!kD@Uo(DC*lco+-V4Ons1~F7p-yizDF{9Zn5DWV05B>!Rs9hH#HH>-mqMcsjIP z=iHpNBC`l`nn}BPt`eHX=Z>}J;c~$Qv8o(6;Kl)NH@wG;JU1v5L`n6B51?fl*vAMkwpj_MNIsc`{;x#{{36I9@z{j^HU`SA#Mn6#tR;qyFa<;;2;Q zpEK#O>$~gyOrrQ9^vj?|1e429yi1&$ELZXNrm)}izNdK9Cggo6Bv1^!JV5nDCvcRK zmSOd1sDZ*pW~z5xxVAQ8%e7J(GztEEK1x$1Re?J@D#<0suVD;)L~GTheNy1wTG;}d z0#8qo(YUjmp?%PjPhU}milvpdZ|${L-!x?2KdF*4^uxpKk?G=FBUGSncqBxKxVfmg zDRJk-<)_=1;JE$uAb7_#Bm-=!nm3(>EGZE;QpwQIW&90PCR^l? zv6js%jx37zrka};7`2q*sUX@&!P$7Q+)-jXz`D6+ceXI$96CsP96~xp+DGE>`)=%RU?{)#r4Qs{Z<^ZYEC|6ww0)quI_>;}j zAuu-?#pC$XU09rQF7-#JpuJ87m0pz~7st`Gk^w_4yS+Xkpe!BDFxaJtMc9+C6ZHwl zFU)=T_wX)$=^Zoh*N*M3$g3mL8E;mjYm)JN!Fu_@&;qD*andyt`e^up(xB)o0 z%+SkEQyE@|bh4YCmq!m9Bh14hv^U?5$+4J77oD!oE@#Y{%`Sp70vI|M-`+qP&M;5Y z*6r+_DpS+4qTHGvr_a4#pC^UCk!~34rR`R^6)?$nyz4K;FF_5cQ$CNAO9X_qc~sWR zpE6w*LN@F@#ux!lT{MNX3s7}($xhH|hV(J;^ZKCiJR;FA;Iryy#XJZZwafXS=KL0B z{53e75Krg=fqfg@g@I*e{DT^bzqyB$;`Y$IZq}M?LmEI-t*B8K9g76v+K+cZUAC8?WBcz>Gi|X&e#&}QpKlXTnr>e_`Kop z%m+x8=vfZ|=OAtQr1?w6eCMjARtPl_JZ@yV0WJVpjeOFjAXBM@13CzmAQnw)Z0!@5 zV;D4G@A^aQE@h+jCfmbG+4V&gP*Xx5s!q1*;lvTHiP8QLddztTYaGHiNZbc?GJTvZ z2=b*oYvfF-;f%r}RG2}^HN})@ux@@g83SA!i!=kp8YR!#g#a{Is)qm|#wj~YtH&X5 zDEPuRdcQtt>%_y=o*tOUtERqW0N@$(u=aoGZtm{iW1^$)cST|!pvYC%BQQMF)A+-g zd2)1-!-ylOeJ#nII`z2q_~pcHM$cM0)TVOMnKmU5n-)-SM? zF7o+6QVJm(B(_iRAtU5!(S=4X)zk@>XHVk{;9Rw--H`wJc-3Vbj&X*l)+6GBIjR$?s(+p# zZFt9_lJjiC!z>a?2%5wxtzwE*QzliF0HPCZ5Yn8x$TApqsr_mqP7l4!j&+0vb~gZgH5u2*zuX&G_*AcK^a=oPEVgvdwB z&S_JT{vPzhXpYad)AwXsUc&tGQ@x@w(*|xuLPs{u#7~^jlB=1IKIaLT-gGvvK{=r9 zH3xom%5XVU{EjOVR>D6HzOgeALco19C#@CAHU;CkDB>Vf%qD^8m-6g-4qvMC>0K5O zxm5?R3{f6|F^$oPNo`|b_;i?(IkI|KrXFH2o!rqTFlQ{5CFPAfGppR^jM4;9aeuzm z51t(OwrAZ`&)HKG4nk^Eb%|zrI2EKoMKfWE>bim`g`rK$N3UF+Z_g3RKy=9qE#$#q@OV6Pol+6wI7WO`$_(k#3BVl3l0PDUH(tJ{=Cu~5H0G$KfTkjB}mt) zl`Vn=YL4R@#w)Z95T~=V*2)*_TKMUnsr08KUQ+dW9T6e2w+8yl&U~TO4QuG*vfdDx zf00t(jdRSLBmp5aN)Oeb>9KGis(286s-R;w?Q=- zo|^P+-jl6dM4n>EhVQ4!P~(8NF(96tpyIwD=z1uJIy4l8dbHHfv&ee(tX*6J0UaL| z!7Qth%xa;kC!Ychv5yNe!@5NT&5gIfJTM>8rKQ8~MH5JgKbh5^O!s#X9zshm24BRJ zMoC_Bl_l%om>y);Yq42yJw$#wBXVCnXJD%XDhY(9Klf0W6HK9Ek5X{DG9BV@hEM*{ zhA)(f2Z;eb-W4YTR1*w~!F{eio0T5mh|2v|&bwk@>vuYAl`B~SK7tIbFcOh*ddDn^ z=WnmeA6!i3n8THR;$W(_UBb)e{v@NNS4bvDFobfE-$(IrMh4Ql*f`oOr{OH%iPnEU#RXF!Rd$^pb2m6oxeqq@#m}%A5w9K)6^xNLeIV zI)P%tKkR2FOZdIEbfGg*ggZ~LauN72FUI}mnoi{!jBj2WALQ#MbVfI4V`Pr3n}5km z#m;K+e#57RJ(?i@4+d|TO9jwYf>~Y1A%zp_IUAb@`g(uojxEbrhKSmcJnV^TChMb$ z@lKTIhbgK(eIDm!IiXuiTk9DbYz0Yh8bS%Q_}gR$hRD)JV@642#W;(5(K}p%NAoiN z>%CYAM!e_)cB%PryBE}}=Y^-wB@%2@4Lq|S51G&PK>fWf-9;b@%@vjXAk@vE5w%9Q zMINnroKKTh2i+5^TAw#zE#`hv zjzyNC1?*3VKtgrTzaNwR`3{ml=YNFEp8*iTKW0JxbM4>jVtW%?V+&iezi*Jq{ND@d zfBr0IJ3DJ9`oCkc^dA#2{+U49&P>$8+Qf;T5x~fz2l&^)0H9?8&;n=~0L*&ECZ+~1 z*3Npyc1Bhvj(?ThQyNxs8>?s^yuF5z^cF7I?=L===epq_xN#H&cnj@GNC&IrLj(0Z zPYkh^zQ3!CxCrG#L!5`A1j3OwtZo{2%!Z9in2gWA7H>fZVQ_>FQYLT~ILL8Q&*jNy zaQM=@2{w&ts`;J!5Otc=Y4so01zPQ-1ZYA*!7$#Az~$-ey&_-9dG}E8>FItQN2dg= z);QDv!fsJ=tYlrX4tjk$XX!JR&ZPv}tTIpHf)C`118b&}>~T2vD$z83#J;pjzCBAX zW2lzTo!#ATd#`o#j~o%;bu~(ey%2Ne<8qehna8%+i#m%#x^In~fN~bXp0ygHpbZ0L8s2Qn5qE;7Vy=%!W=7{>OE9nR zy>!x!2~vsjrY>{#xf1C!uI| zX~S$Z;tcIMeb?D|kOysH#iwT(j}#t4F=c2rG^{wM_^!fIv+(FU*5EUNMTN$ zE4y^?E-`oe>_^O-D31hO;-`wOyWtE+PRdG}mF#eDgBAHg8AYT-2 z)+JRuZEbBeiJ8SCI*imz$U#@ERR&razSOBCWA2i;RY|)xW`o>Q?h8{iW(y*X8RSeJ zXP+wEG7H}7wcTOjhE#ZDs5KZ>$Sz{&FBwx;PWUMSZN7H2MGWWCT(x&8D|5WyoHy6P z&q->K;jKa~XY9AyC*3oXew4isDoXIZ(YgZW$_8>s)QH?!3?kBc1+TH^vPD5S%?403 zXJAE<1jb%Lfy6_!Y4((5_%P zP{SHMijqGC*$Ky6bk<|XimBp+){p&W$LlUMijS!KUb>g;D9evv-YpA2^uZg^L~F8@ z+ColblUhQATVGoFLB-^tNK~)~-6k#zlRd%^n|34WZTu4to2Ie%WVPfVzqo>*QW|8~={{?o=DQ=-{NYU=$K4YC($)v1C8N-=D9LjAoSxzldT3@RKIzCrqSr{_T zx3{8^WPIZC*+VtvApwG4R^>zadhj(*O=HId%?hQ1{hh&?_%Kfzz zlL4o%GAeF;doCxMV}j=uMU#GLvVhQLR(3Q4?=J@W*kOE@jN%5+?lm#TQY}K!;MN_C z;-w*m_8A36wOL`F+f_dLS>r~Erv~At@_Y#UiILq9!G;8^pOThMB4+BTloes%UTHO^ zFFdCH-V-M|7sTkFqOZC4wHU90TM98RD54T%50>{iPXO%VAo|nWAYYMl^N@#}@yx!u zwx8Pt{lY684Il?V5tu&0a=0gMo=(58uRi)7nMdqxgqDg>o751vUH93$1du0~yJ%jV za`Y;6^TjU~sHO`oS2db9%sv#z=UkW&;3v++VR{Xhhe=s>R5ZzoVh+7&x$;&4D+Am; z6}ZP&d9OcxXQ=YIRAYrk1%v_o!CMqFD@BymPM^z*CH2!5*Q;a(fC9WkGj5siY z-hJE?_S~D1;m2Z_F=&$~F(w^QnXe_khGE4Z4?BC_*#J1uaHLDjxVFTk%cku92YHg% ztYM6gVJet0uSPuw1aH1cdujdctNR2&Zx}JxXbVlWOACH+d#AJP&oslG*?DCMRLwT$ z?(iZ`V9fX#p@Rwu!(UerT3GNVjHs)Nh%dO8dx@s>k2br54JomrrEP^CyIo0F<|^Ru zrZU10y|Gt$25?jb8hSj9_;9+Wou$}0u5+wxuyUv+D+SV~hO{g44s8%7jAFYzhL3-) z9AotKBV~ntp_ni(4Ax^~J)lw`lOkymOkPc@M7?JuNx&Grl3}pHZu3nFQgFi*Qn1^y zjP^pqFr<#j#K69=)gelfYCZIkVMT=cHniH-O#ieS7F>Pk{?+v~6)8v$!!Rh;wnjgo z7ad%e+koig(Q`$-p{6(ErV$2@DKeyRb;LC~4XXEm1GC3%0}$0`fAJa7pR&`I3ofgK zxmM5PC1K74w=g>jhmA4R!jsDK~|&i#kizy$%V)sq1-yT`5XVmSkl?M4z9)q87Yvv zz1`ic8yp-#`+SHj-<{XHQ3Nqb58pgt#Ftc>ZpxcTq)*ae7hP>8Z$=fL#2F0^1IWRj zlgE(6PoB0FMPm~Is3wEA1}SXOW1j?Bv+?x%X?bQQE#NktODyu|W&vV&C-uU^>!;yHv|zlrIt z5XR~}! zBcmdN#01L#ahh^X_am|X(9-38qvCoEttGYz6@2 zh6#FFF8oLymgkUAoM9h*9QGI${8a825C&G}O>gmzu8Ty70n&E^%&r>SGiw`;bKE!@ zFi2vX-w@y9pFm%p&qg*u*h%|z@*RQA5h-HZ5uARX2Oc)o^1i&l1g!ZeqPim=BqFwr zy0aRZd1xlPa9DJq|N6bjJfaSDLt>G@rm~inwEyF|TO)^5#L;H7zAM*s;TQT+DF4T0 znlN=BG@;NtC;gh786QBYXvuLq2^FnND|OPy-{_0^r#*3^^RApUbKF2$zj{%kK%DTM zx(VaNz+LYu>`!J^lr|^K zZXPOV%-u+XLyf`NZC-}?w;zb!Au1NLKU7GACyLrJ87>Hfaea6K`TGi{C%jlm@5aW| z!)G_=P@XSm#NXF%0^@)o`MT3)NR{)5<>2PR zr0C_xSA+rNro6PNmm=LX^IHZEUE znVG|@QWI&~7B#5wCl`@NQtcRG;&8qy!S*3oJ#Q!3$l^$H0id(J7GN6 zc>STA?Sty{j3U;Xgo_7b(~dNwP#0N9+I%udr`ET8(eEx}x^(vzEzP#IvVihCVbZ0jfC!iy8Z0m6#mwt|v%VaJ2Qho#+Yc*Njl4 z9JyLFN5t^*35GOh{j?_wMT9W5JTphU@#rC8yjV2zPxVnu*(uM53m4PGC-w$GWhDUg zpT`r&As7U=-q)}3@2*!;?&nA2G;0EG&%j5kmG!FvkuE@?^$OhdeXt9Z41;bEn0%`s z1xpsmGuQ>8HQ7heUJ>h{I^_iR8|oVoG{*_uwcpqwalaEDN*Jl9s6pWwGp*`P9t&lg za2_#y&#NCL^4(Rm2o8V%wouBP!5_T`j)ZNcd z?nfy)**);W4i!J#NA>q=@-XZL#xe0ZiTFRAV{#Hb6P;Y7& z*&s#INJwM}pWcR3)ZGkcHr;6)!Nqin<`PlP9SU&sSd!42MSD{8!rSx~2&=<#ie^5E z6ngs9TkvAx6J-bB&$IK9s1!k$4kkTw#EFAfqpB{u%zC3JRzHltKQ_#>C=e(zJJQo| zeNTR~A7ms*b!E_L5;w08vsMKTnW4$N7R(1GxL|RnEx2z(qq@&8V@n}WTU_B-C|qX2 zIT10lH@15>jq$-*alrU#AAd03)Yaz7G|xA`uohK?m+B2-W}O@_$DcA<*2k$#T;Jg^ z@V*-P2KKc)InJeN>_y-0;lH||L48Tjsx(u7CsA_g%q1l=I(@zQ5gcWhnO}1pa=A=o zebjC{L6i^;ib_oB4XoE|rSd?z6%TD8t0B}GZ0w|*-obx>qX`+my)Yi% zFA^8_3zIwcbV+d)2^aTO_mU$eN#B`*7+SRxU@Zey^aXFB{{!N|1VDiZ0wGcV zcx_j5X>~>E`hK73Gi3;M=vo%u7wa0jn!qfg>+9uQ#Iv(t8wXS+0NV+3FE1O(R0n{k zG}@vs0*O~3>x_*xf86={{T}(dLEXzx935)9=%leRbuc5H%)oo-Y^9n871AIoO5crf z1BKtAlIOwg4Q>_eZ)e9~h)q3~`j9cu(z3KDk6J2oTG2 z2IF#Yv4r1V4MZ5rt)MUm0L0wHf-TdkHYg5M(dXnl5t^V^?%S7H-7!vYV0`Zc4+2|D ziQv|)bnA4n?L|!Jof0baUvo$;PCS-s0Y-@zeV*n-8}^`)$Me3cwccP_0&^|M8n-?z z?^e3M6T+57H=m-qv%^4xMs$)w2R;pdRK*9;F@Ubomqrxw+e&-Tk{>nc`HQCE6SQNj zSF(I3IxofiMx7_cM)vW+1*>(`cZy6jO;pKC`%CwC2F(?6+M> z$Hx*)jTYoKHN6;d(f531qJoG)x@n>29XI*qV9-z)n7Nw)LQDRvg!&JLo~UKQs?v}r zNlgSpdf$R&7PWvD&C2u_T#Ft{E1aa&Vw;w*scmivI|bs3E4uR)A?_dQ9M6RJ&oa#H zMZByoeO!_o@M>#&gj&^mgjQoOacgZ?Mc^nU#(AyU;?DCrG>Y8zW#na6v}ziF!$xtN z!|PeCknQhHq%qAXSNF9=R!%Fbhpa-{az!%Qc#{oqicJ<;9Ccpb>rsG5NV2MtRv4F2 z?CS3Nm6CGTU{uq*lFV)9=9lv+7R1t@=*CLN+$B+^4f%56K8N~vds@}zTVfFN8;Z-1 z8%2H98iu)rP|xCWkPML6w4hiqXpUD@0#1})mT4&?R0Ri4XX=HdR&}BU(U%Z!0hLXi zE$Gl>yZun3OFFmC-(oMma1K)?gESX3=Ng4@k% zedF4{a%vJBS!!W(sP{Ej$Tliqvk#Ykc*zA9Ar>3R%*?8RgY@?D`xnTph!YY1}P%~g1R2IY}p(xi)XvFl_53)bSzz%!$W~v1Qw`R<%I_v5V6S!i-1s4 z#tCmiz+_I1Sbb!ZQUEDQL|*dI=|!;EJ_u#o#TwZ&5Wh=Y&fTCUVk<|Vy1zxF9O5g#uLF|aLA)2+TJT0-6@3o*0;XN6)*@rGBOVcJR4XB<$B zU>0vO0q4+~-$+_>AF@=q>X!4s*AsoWom9c_3a-&k{m*T`W{?u#p-(!jd0PvA7%7t&Q9aucuM(5kh#5yoc5?mX1M=e3 znmFYU1o3~O%R*Vp<<1Cz(ku*w$aNJiz|H2Y#JGI>CPvbcQ}!n1SbTyLzseuPK=QRn z{QV2`uZHz^;go4aI3OS)%73r9D*jP(QT=ynu7B$zOWAFR!}i?Nrt#@}Y$Jg3xS&V! zIJd4oB}wItP#{rBRgjQp`t{Sn@Vow^YN34C!RBm;mMm`oOJze zDH?!6K8E+>dRk?@c`TDL}nnJG}85Xsik<}pa*-3VhoV? z4gGX1S=JDg2!_7x6Q!Vg;Gwz_Qd~NMAzCHIds>VEL`-=sUULU>7}#%98tGR{V1Y3s zyH*khkt9mvQjNME-`J?UV}+qNF;+eM`b` zSl5|S%E9YvEgt-a4o!D&cZ<%w#Z^rt*MLQ9Jf&Yw2zqjFAEQTJzE$!n#8L>09zdCz zHBC7)p(M>7GQiDeEum`wFH@(PgBU@mW_5&#tgO3>fGnv;QX4dDMGtyE)@174&8;Q~ z4W0UoG+tjGU6+aGw6s?eAwS<2{0mw{aTR*F9h+X?_y)R)Eg->rEM^Gg;zxEx%)QW- zvrJHy!r_X!)}ccC)s)TFSF3MPbOB+{j+z3VYNl(8b&d_tpy|U$T+mKN$yU<4{zgW( z86#8^sRIExN*olda|b?zrUJFmkJp0Kd3}mp`cOcV3hJP-hd}-Ws`JmRkxson6B88W zTfX3_O`SFdXX(?ahP9+XZ2RdSB!OqCHUZ2Cz3n^i+znD^s!?+m9ZpbSMC`+NFo)_6 zq=X}d4HQ?revUElfze7|`5)i6XkH`RSw!1nwN}pLds?jdlx{Zd^`CfIA>O85>Yoe< zz^UQ@8Fj`17RaI)^d9AuBY;@ZbX?}m^pP87SUbmbiyyTs_Ey?nE`t^Vk4`K{vuGJ2TX{pMD@uLQK ztV(i6W7^2u)jbB*{j|66$xHqwUq z-~o_bQ_Nz>*k~NT23kF3Z-M(rdnt3vidZ%pKRAEgi1X4%Zm1|syWIwe(c6y|bp zU$lV*_V%>*SUQ3Qwk1(5sUvtq^Xms+|C>Q`7Z?QpQXIxWmesS`g2pB%7<58I{y=e5 zQ!8kdwQ2TQf!`)MV^JYAg0(nv{MW6Mb}}MMq_l` zED%Ai!zsAGw^C}d1HU;fad(InI_M$YR)XWoR-tn(_~;6harrlrOQjOu9teV+d9&an zXK*lguf9igHU3o3GyN`nN1WkRvlL2Muw7|OcN*tiCo4gh7Lao){^pBW1#nob>&XK* z%Qm+5s_@LP70Wi3n(mIhrXM2x(O9-J1Tb(T3~ciZ$$O@^XmHPHx#1+&gu4+@k71@O zjPr#rl^Eq0a=SvJ=I&Afk!c1+sZrtWUaELi#O=nmLi6c*{o-0P7=r-)kP1GtqHMB! zI5O=1PjFFB<@ikuczplF@h~kJ49Z~IPgp{5t$;x;jQF2CeAPrn35teox*AH{<)PxRwHV-^gP@T(@pCLQ*ae=a_G9>i`RTJbs5{yC?0nHnF%lF%$UA(1P$e_}!eRHwB~jv8!?Z z`>rNnZ?9zH=xSkP@@MpiJ9W|%HTlEQJDTW8*#2Sbt*uQQ>HmB>I=k5GG5^Ju2FKPz z4*)QN+;aCtAz@^!6gnwUk(?DB5JQ_J7VxDM*PHU>?1UkM(e^?PLSk<~_`mVLW0CMS0O{BIh+G-|oPu`{XeE`;K~u$qpm>#D(0qu* zyJ@{Miyr=7_aqW45BwP}WPX3jvS=9-^U{KWyWdb;UZjC@0e zbZXG_sCR?j_368(=&5OEPN`HwFq?WZbSUg4N)ATgO2v`2q*SpB&?GqFNC3+`kQ*L1 zHx^@gsVlNxi7AfN3k9}Cvmsm1QzQh}`;vC$3j6(i{Z|;6&0gwGhq4fa8%kq{(_)8t z(eEy%Ce;tV+8!VD(A;Ns<1@otn|ul@`7jT@v)7uuspw)KL1jPik>p%#Qg;pN(v}Sj zNi`!}1)O{(Q=I7UQ3Io24A28v;0C*17$ayjvRPsW$Z`pZC#VLa-RzX^lj-Q_5-34J zj~CJJBdF_v7L9|Om`!U2qHWF1OV64TO^^?daDRDUgqZ2H;*aOQK>y48e;f_;Pq6{! zzkA=x#n^@ZZ>_?=X%7A=YEb@v-RA6QU}W+y`2j6}<jx|ah znSH-NM%wk>q`(MS7&J1&ZaAjaMKD5H1v4oP{GgWXm!1{^XJb7RT!aTlkvL`Te317T z=q152lG^cnKPe5uTAxm?H-#u#LaD|oOCNY;Dh|EZ&1O^@xJq6p3{sPkwu3~rlJ!!m zQh(yl01fOEx6qo+Cv`Z}7JXEH_9n;bkL+ce2r$7%3Dbk#a>Avc&IrDre@JaDv3-L5 z3z1)TtY7}IrPTkHqW`qE{Qtz-jC%hEEB}#){HLXxRkfVf*-?CV^zz>fO0R@}vi3CO zb1~;YQ}=tsIVnX(fJCG=ZzH>EYl4AfP>liTHYAs>Q z;ZFE*!KLO+c!SM`pjpr~1}}1P3J8D#yu=ioRsUPSzJn6gVW!jiY75wsv{5lB@$m7c zf3gw}D2Dco3=Q*0@Bs74&tYhCYkBB|xHk(7LwW;X*RAlt1=ixUp!^B%`IrQ->%w{n z{g)v5XhM9T3c5az1W{jpA##~O3R%#7@*M2%HLvD6<4+m!Q-5$Npn1Y5q*N(h6t~PJBn0fVBb;jFy*>-}?b@#dB>cqUi zbn)SA{&rcyfwrSJBUtTLS_=@>pvC@llkb#=I^emh5gCg!PWJyqb^O7f3hk>LThOOx_DS^I z_!I4}Di9}>Y!QYBM;gf6FM*RirV*-jkj7ylthtfZc{830M82511SLJdQm56^ilvQg z_#xO=fW3_0$+*+`L$}Gd@@>E7E)XWQv`>AQ4&}W!l6GAXANp1In{yGW!et zd1V(M-w>jmHKD*j>CV(H!gWt~0@{>vZn&pqlDmMu2b{}<)h1*(hy6~5X(9~DoSU|o z)K&Z66rr2s!ya?37hn;bD_sH1%cFV9#*tstxCoryrD|PQuA3Wmx=lXDrADn31~tkv z{7gUYlqk>d-6L_6n(>0oVwpdh34yVo-rP~H5NCNcw zeZxkSd(OEnc=>j026|nxtYlCZC#_PTe0#}Rw12zlWPnnOpL21L$KRo921w3)wk4LR z1K5Juydts~wka)VV7()Us4Y?L{RgqkThd*<1O^0T0rOw`-e1J>Ked0_|C1$^Nl(zg z$jZ#o&c)XF|FpXPr?l@crDw6)hV6zZqR)+*ba+7>zWAN5LKRT`0RgzBdYH*$y}ER!t#SGpUvR$PhZ`Z~2kbFS$A&^81y9=NzV&B_i)y9E2yvv~5+#{# z)9Or%mkTYg3RU4*yUV7>)gg8HOV;`PwEDIhi53T@sHk5H?X|hsU2z0oeyWy9V+K$X zaXH(uPHYp{?PxiROUw8qgPR(1GfWg!=yLVhsNWiz*XwDZK7@;zyJOaw zSo+Rcye8wUX8#sl+#I)-)311&BoQuQ44sb8*eoP1;;8J{&mWJjTELkf=XASCDLx|w zk#U;q6~=9pAv|#JY1koB7&3r!kRt9+$FJnlYGk3Cs4_g3*?d8FS7A zs5y?yeFilnI;Ej%W%Yv7%n^DZw(Ca^hwFZ`<_hTRB+3F)nZxOtg1(NKr}fV}5NZj; zn@(mg2Rk`ng2Y>jm|DBum=PG-4ZQuGWgSq)GM>`vZoJfDee}6W!lUAWy~gV%74GGV zilv0zHgCfAEPHq3(^lr!LJC^{wHS13G6#OM&_MzFnv(N9_Ut#;!?`4s4OY~_E5_^k z9zPKn3*`_}g972fGFeqd)D?udOitCdlj&OOs=WbzgdI%&p_b)L2|8G&V7;%3_P0I- z2y&fhPQtX)gl?j}hziGo$1DMtp<#^{UWRA$>$b_hMjY%(=%;jfmNAX?uSODZEktYA z_7S^7Z!6u&E~GYzwT^Ag7jz&duDJ-xXeF+1O3sd02I5Rd;MZ`Jcg;hRERDAF(tUhw z2HUQIveVXvtaH4~ys*7Aep=gn)x6a?x!Vx{=6r`Z_H3jjoAai3jdLU&)>pm7-&{L% z;c>``=MZheAvoPuFraDF@iupLvwZ=@BPeWpDvg3`z_alfv(gDJ)2GcW6=*|phFwvf zBO?gAeD)bOjM`>0JNCg9$bZo0y-L zVLIPS3)_DZx;)Q}px_BPb}i)}iOum>X6Lzp=19Kt#T!n*hrD5|e#rK4Rrl6sAy+sF zeo%CQVOy}AeD{QnfOh(W4~0|eQBP?$Dr*y`@U1_RAJAVv_%)U^#)sY-1rmx7c+~sxNl=N$^O^dD+=qctv=f9TXnN z+(~R9H-Y%yb@!8598SlM15ooOWJ1<%UD=88|6kTVq&$0m!b#fz$gBCEVdJ@Qqkh0?I-PToqS zwLSMjlTIOj{BTT_EHbyh+-BgqR@@(EKwmEwt0tDDlM0^ECN-(z=Oz#ZcJs#l2HdKG z^(F9KF>rDvB*KZx&;98MZqy zTvi(pjWeBnt1j5fsyIT%8&PgV6KBr~4XEyom|%%87}kQ?dKnT`|fV zqV!v^l7_`%DZ3`LigKMWj#R&ev|greu;BE!v0_VMGf}0jd97&!h1(7lsLnKS$YWdZ z!P4tXq$;xdW?89l&<51oM;Jo#+E$~qyRtGcjU&u&<8TdpO}IRgnx*7=z~YKyrn(SC zsnj61@GrkTlv*S)(6wjUDjEi{PxWK4F5zan?FAZt(3b=rdR^h(hRz<8g|TY)0C;G` zW;Tf-nX1hM01B08@72bWo}}x(u{Ezz_j9A*s8BZaJwcR|5TwC4 z6)X!44$wT+@whTmG{#DMp)4cVaQN^mCw0V#PCQbWl4^fXBypj`8c$w2hjRd2RD|rX zyXG9N>?753F#b47S!)glrm$g;$jUK&pVQL73d5!9{+7UMLO@_W0?%q5idTNgJME$c ze)$KAKHd{mo9&*z0lJXQ4Pqf61Y=2fnZo1M{6xbC#b0ymc7NRaBH;PEeQr; zr7Mpk^oe2u%bo1K%4V;e`k_`46}j)cd*DHHOqWyCIPH%%znIXGzBiGj%6m*$0vo|^ zysdx&_11M4OWSQcCk$^ zvY;}GrpXK@^&!3{6IEF#ez5uLSaORD)Vu2OA=P6gMfHo> zz{{At48vPTb+3&60^*p;jw|wn#n-nHcrq1AgAT@yTqpQy%0%@pEWdZ){JR@_Ilp^% zU6FKTB;-H!)}i(a$x`6Pofwd^^Cj3M6lRKw6PP^<>G=@oRW2fNS20}b&z_GE8nLGy ze_x5z%ZM1cA_E?ID$!bW%2ztK$m=g6Q9db5gg2kBB+H6(j?aG)d!6+Q{OEr|_ws-B zdj7(^)c@1aWn}z2bXotegs#$tZRUS2?i_&{ecCk0;heID;Cew4SG&3s?bbev~kx zlh_(5{ULOuCd4Yshn&ODlLID6&IQnC1P4cX{JPC@EUc37(o6`B6V3WE4H=Z>4{EJ*d$IbCPZXhn|DbU4pd1PoVSj6Ke(#bZ+^YrP=uz?A*!V(~N z_t2*38EhFnsR*?C!P$WatGr-d)Szak`OOoU5R-+*-)Bl9QA{g!DFPXG>>p=v)>1AW zQCAwBq0tvqx_-0rk(`g?r)4F`G%dGHoU+R9dA7@<&w0NQo@y1f0`vx{V&*4I7(>^H zvdJPT;4P>)FUh;DhmFXfy9<)dRj}v1ircu$241m-V;M&hXYu7V$7(4K1>{Xvd2Eqw zmhCt4SXK3&Sm(Ar7jU)Gl#5*#!e@PQjm(#zZ6eY4X84d8KR31#p&LsMjJ4EAY;Txr z-8Q$pJnVTtVfiCuakLqUT9l+f>=j@4TbE*qFxASwC+YmU{RmX|pyX!b zmkmN{hh47r#0osJ1o_KTsP^oQN|~J86SZ4KMp73~@prk3*7k2BjCXN&?$c!Mxj^ud zmp_e1NT|F-h%vyQm=^m3Oa6u=O#joEW@7(4rrG}Q#I%jv1_1H1M{nuFKk` z`~aS239~5k!g06Un-IZP>U#g^lW2@xeBW@Hb<%XkK+y|ceoeH(|I^BqfJ4=`f1yZZ ziNb^|*@u}in2A!8WG#l2Yz;=HnvlH=DJ5A#)+lR;>}!~cvV^y&EK!KEyq2bf5dF`o zf6d{0zxSKI@4cDpI$U#}`*-f=cb?_G@8?#?<(Wg7%*t*O={Rp0p z=pJVEO+GtNi7s@zhJCpnk&|$L1pWB%3w}xJmdv}Fe7v{Ud*}N*CeN(b>9QK*>ALy} z7tjr}V!5XHEbx3#xuT!&QT)ZbZUzEnF+0nm5(?#2P0b&*9y2+KDE4i3f0D@K-x5u< z5F~HY=erVj7*WmsG3D4ElWy$0`;U$d_^>jgTxun4M7`ZLT3N2POWiWsBG+nu(>RvA z*!l2lQdyi(@LBC7yHo3ejE#ZZLs(P zg24W<_o#$Nry>tr-^U+>iGh#D+nkw?*E?Ze8f7)j(|;2Fa*u#`r{S{v22Z}TYj4La zJk8j_e!}uVP<6-@Kx%~j-TVo%UDZ;Sh8p6I{!r$o)aqTzsRD5go1fJs`|ol3T2L(` z&~n2(#mG7}{zI#k*uCB_MP9p>InFyNa4QL=rkJx2WYFquvmQ7(SR-#DI?TmvBHjqi zXEe6?R6i;1(CB-U>7Y;3Nw`Ek*gsp-wP8nQVq#m~jre`;I;zxUG5l<=Q+bWg#g@qC z%C0f*v<8##?_sJ#{qM{a0X}Q5;B)3GJ{vK%yuiSbkTDwbozFm+%FX=@kwE^wWfx=of?ULHM7aJphd%a>PYzrK59ML zE;7X+i=3sDm4Ux^5O(jiQ~EX~S-FR=n_p%fCTIuyD77D+Y;WP@B3HQ89o(8274Whl z>(T*Yn#Fvm>xG?lJCqDOZHZ4rhVhs0*pbIF3J2r#*WB=M+-=DmF^RiqSG$h2j#X=O zNuido+Sc4Z;EBFMh7E7$6|MYkOX>2-a&0Jj&EGOZinTLzywz?-I2uEJEPcH$Yow@L zF(gXH+$r{*P*sr##r(R~%Vms)zTTw%F+GnVA2A)R{d^;4cnw*>S^H%=sqo63Zu(V$NYf zFCj%8UYOx`_eO9I~Q98^%TlPB9&Y>7zt`H=@ia;u3cB8>t;NpSieP|wbNL$NyA%t z(@3QiTY`5kMe}fWw3)WF-fjMj#sCo;=e!{a+W2OiNT3)k@Y7dEjqrUnYdW@f*Rz)P zSu-;;yK)P9gij}!IZBRer0tHwkE)+|W0G^+$6s)Es`Agw=af^v6benPX8B6FgG|@{ z>{3s&vtd=#Z|cEbr=}*Y{k|XZ@Vb;+>;*9X^WQR_z!2k6$Q6vo+5#a?k-jig?Xxs%!9S*|j94Wi`W6DyW>}Q3PMXHsA>Dl8onODv#`X}Zc`T|T{Z0vfzWa3%i zF*AS zYh%t0*#=>>X`eoaBS#$-vc(LU6?U$%pO=_9P4$=a|I&~Q+BWx&q+vf`IqZrE+G^Vx z{x`Notr}J#dpO+LKljDK;jYt_m~wvco1OP^9H=tE-aFXs<>XKyBl$zKwWPz%7gKv- zvzYPfBt8pRVh1*s(>IGodzaD@;i+GyZXR+sErV|sm;k9Eruq{_wMUosQX|>F^bJJW zE<_tf7m4Q?rk-K>gO{XQbH%z7O>>W!m$bPJA3f1%Xj3#Xld`r>=P2O_yzo^SuW%YQ z+eCVy=D^_itI{D6a`sBwnu3l`swMai zacVQCeP~pHu~3siFwtd7w5RXl{jRy2R_9^t+?a2JyUP`5Lq1lYi}S@;N1tp?lL~k> zxG_`R`Teo+j}(p7A(>X{Bc@(B+@Pp z@_|gZPO?v;Q^^Gnc+X+nD-YD-&LftU%gfvRKW4vAZomCpFsS7C&<32&18Kj^*<4d& z84K%Z+%sYT?0`gfsh|0^K_C+%Fx zrWI7gO%lU3n?BvyICATpPLE4)D1uFNfE3epJ9}34El~JvUAlzItd`pm?xb0Rv13g& z;?u!hllD^bNlL$*=2esQjcca(jpUH>_k40fn6$LzbcSUo;}^sgFRk@0@HZ+r zCunqn%xv{%+Edl0^xKDM%@qmJwAWX@hEVni8NZJmt&w_VnO=FR3}JQss%5gm9|D2r zY%CIJ)AGTmhe$!Z$$V_oryic?s$`3v+S*;!da-p{_Jd=-mS8tVjYoR@ z<7u||KI`V9&h$q9%n&BiINr|NfeY4k*&6PYpki|mtdV48$mWkh=pBFo`AI@65wbRbrnYk6p)L7LZRSjG*K09=K$1SL?N&Q0`QAK zqSch#z1>x>ws2h7&A)q&QonQ_Hg?RSq*O?o#=Ar5C>K7C15K_e8U0YQ4U_l?E5Xz2 zL8}jBlamm-#Kh$lzQn3Z)%+uLz*?E`;#x(5hzCpEZeOtiK0KM{%g#vFx#X-yzQH%5 zdqa6|v>fxJZcQ#7Eh@|@)=PZfoKya^`K3IiIoB=KKr-NFRtFn6mM_DCDM7$<#sDAs zJh?g>f>BF2A`o^MECwimfpTYkhrR1n=~~z#N2PEQKKODHo`u=t-Xyh zyQnF1a|joOv0Inl_zAKyAzk+#T3_+y0nUI^{(8{BG=9OkxV5m=gQ7I~uv0%N@=nB_ zfYRp{>>)l$h?J_wJgwz5(MB2mzI9c1pKZIJl-aIHJrXW$A`ExlUowssR+64x9CL{c zEL;=1FS1ltC9m+sVz@L~4Xp!f!E$)H-3~Ra4nL9SZIZ5Ub zq|y`Dn7W=n7h4xw>8;1Ph3i`brq)bh5*}k!(Hql>%!d<@_-j3|BO#Zkyp>9pEPp;c7~Z*^=%P!<@IJY#MGHS&=<)V#MaeKAjQl4dnpyz@-53`KGm#Q6f9L zb>F8XwG80Kx8A$JJt_EAQeNbgiY!m!^;+*`TIhxHg|Iwxwrv7m%%blP?T8GVe1E<4 z!O4klx<|VU6Etz(WJhbh53bW^n-BT`Z-Fg~~Q_dN!IL=vz_dpJP_i-e;w z4hT2_rDhMevr|E0FhnAPfKUhfUf>Fn<2-_g^_;CMw=rVPhJp%Ho*5Q#C39h_)oy=h zl%a~fWv?pPRb{8;qXxVq&w5<#qSOVd^wMcW>g%oEF(l5$9A>WrQ)k!$NwEXGLlhE8mM(Hgj5id(hw;|Kl+ENXw0aq%MBxw$zhgQw|Zm%OYP7_kbC9*zY6dCuqXJ%)pPes0D7w$_*saD-XCBo9_T@KuoMqn ze1Q9Z^(e!Id44|N&*SjWLmS|6c)A=CWW4>AhvT6-z~dj#6k7232VI_QXF$iV!ywRh z!8}uF1}d0~`1pgtg5UL$~zoC(3 zFzJRa`2d@Ly&m7q$bk0WNWp<30VCPa_#QYM(`5)4;TS{m`*Ce33NV%k4b_0LM7oUZ zVid(c9a)581cOFU*ZWG0X?qyN_>YH>pcug*0Mwnj5~HU!gBbtukN^}TxN?Cyz(B_? zU37q5A_I(L+|9dMHPq!qpz8&$F#3$B{vZ8qP&nXD2I{3bxB|`|1BT%Ij@N6oa_GJt zbOh1mCh+Hf?grFK<$vQAf@%im5a`wp^b6319k2oeni=sDK$U{FhVG)k^)g*-P5xTx z|GbBULI9^6=wf~)1QMPx2*15~gF*n`J?Nr)B?KZc4gZztS6ks11V;A|KOuky|EtwK fy(4x5h<-s>vDRM;9Asi*f&o7hK>q5P@5uiTa$0|G diff --git a/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_docker.log b/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_docker.log deleted file mode 100644 index 20daeda..0000000 --- a/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_docker.log +++ /dev/null @@ -1,80 +0,0 @@ -2025-05-05T19:17:51.8360525Z _____ -2025-05-05T19:17:51.8387064Z / _ \ __________ _________ ____ -2025-05-05T19:17:51.8387358Z / /_\ \\___ / | \_ __ \_/ __ \ -2025-05-05T19:17:51.8387461Z / | \/ /| | /| | \/\ ___/ -2025-05-05T19:17:51.8388642Z \____|__ /_____ \____/ |__| \___ > -2025-05-05T19:17:51.8388720Z \/ \/ \/ -2025-05-05T19:17:51.8388775Z A P P S E R V I C E O N L I N U X -2025-05-05T19:17:51.8388816Z -2025-05-05T19:17:51.8388869Z Documentation: http://aka.ms/webapp-linux -2025-05-05T19:17:51.8388922Z Python 3.10.16 -2025-05-05T19:17:51.8388960Z Note: Any data outside '/home' is not persisted -2025-05-05T19:17:53.0262476Z Starting OpenBSD Secure Shell server: sshd. -2025-05-05T19:17:53.0262921Z WEBSITES_INCLUDE_CLOUD_CERTS is not set to true. -2025-05-05T19:17:53.0262963Z Updating certificates in /etc/ssl/certs... -2025-05-05T19:17:53.7725931Z 2 added, 0 removed; done. -2025-05-05T19:17:53.7726600Z Running hooks in /etc/ca-certificates/update.d... -2025-05-05T19:17:53.7747355Z done. -2025-05-05T19:17:53.7764774Z CA certificates copied and updated successfully. -2025-05-05T19:17:53.7973879Z App Command Line not configured, will attempt auto-detect -2025-05-05T19:17:54.0174525Z Starting periodic command scheduler: cron. -2025-05-05T19:17:54.0178380Z Launching oryx with: create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite -2025-05-05T19:17:54.0971751Z Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it... -2025-05-05T19:17:54.0998037Z Build Operation ID: 0bf5a6b10c464f0d -2025-05-05T19:17:54.1004103Z Output is compressed. Extracting it... -2025-05-05T19:17:54.1004103Z Oryx Version: 0.2.20250121.2, Commit: d363b83aad8365d7e91cc246d6dfb3ddad209ddb, ReleaseTagName: 20250121.2 -2025-05-05T19:17:54.1017783Z Extracting '/home/site/wwwroot/output.tar.gz' to directory '/tmp/8dd8c096c8b2d70'... -2025-05-05T19:17:54.7542578Z App path is set to '/tmp/8dd8c096c8b2d70' -2025-05-05T19:17:54.7542901Z No framework detected; using default app from /opt/defaultsite -2025-05-05T19:17:54.7543237Z Generating `gunicorn` command for 'application:app' -2025-05-05T19:17:54.9603867Z Writing output script to '/opt/startup/startup.sh' -2025-05-05T19:17:56.8833780Z Using packages from virtual environment antenv located at /tmp/8dd8c096c8b2d70/antenv. -2025-05-05T19:17:56.8834102Z Updated PYTHONPATH to '/agents/python:/opt/startup/app_logs:/tmp/8dd8c096c8b2d70/antenv/lib/python3.10/site-packages' -2025-05-05T19:17:58.1019375Z [2025-05-05 19:17:58 +0000] [1045] [INFO] Starting gunicorn 23.0.0 -2025-05-05T19:17:58.1149444Z [2025-05-05 19:17:58 +0000] [1045] [INFO] Listening at: http://0.0.0.0:8000 (1045) -2025-05-05T19:17:58.1149856Z [2025-05-05 19:17:58 +0000] [1045] [INFO] Using worker: sync -2025-05-05T19:17:58.1237539Z [2025-05-05 19:17:58 +0000] [1058] [INFO] Booting worker with pid: 1058 -2025-05-05T19:17:59.0421230Z 169.254.129.1 - - [05/May/2025:19:17:59 +0000] "GET /robots933456.txt HTTP/1.1" 404 207 "-" "HealthCheck/1.0" -2025-05-05T19:17:59.0743324Z 169.254.129.1 - - [05/May/2025:19:17:59 +0000] "GET /robots933456.txt HTTP/1.1" 404 207 "-" "HealthCheck/1.0" -2025-05-05T19:18:00.0053057Z 169.254.129.1 - - [05/May/2025:19:17:59 +0000] "GET / HTTP/1.1" 200 0 "-" "ReadyForRequest/1.0 (LocalCache)" -2025-05-05T19:18:00.0528981Z 169.254.129.1 - - [05/May/2025:19:18:00 +0000] "GET / HTTP/1.1" 200 0 "-" "ReadyForRequest/1.0 (AppInit)" -2025-05-05T19:18:10.1394732Z 169.254.129.1 - - [05/May/2025:19:18:10 +0000] "GET / HTTP/1.1" 200 0 "-" "python-urllib3/1.26.19" -2025-05-05T19:18:10.3987699Z 169.254.129.1 - - [05/May/2025:19:18:10 +0000] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0" -2025-05-05T19:19:27.5164144Z 169.254.129.1 - - [05/May/2025:19:19:27 +0000] "GET /favicon.ico HTTP/1.1" 404 207 "https://msdocs-python-webapp-quickstart-rmb.azurewebsites.net/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0" -2025-05-05T19:19:29.0063973Z 169.254.129.1 - - [05/May/2025:19:19:28 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:138.0) Gecko/20100101 Firefox/138.0" -2025-05-05T19:20:47.4336461Z _____ -2025-05-05T19:20:47.4337876Z / _ \ __________ _________ ____ -2025-05-05T19:20:47.4337928Z / /_\ \\___ / | \_ __ \_/ __ \ -2025-05-05T19:20:47.4337947Z / | \/ /| | /| | \/\ ___/ -2025-05-05T19:20:47.4337964Z \____|__ /_____ \____/ |__| \___ > -2025-05-05T19:20:47.4337990Z \/ \/ \/ -2025-05-05T19:20:47.4338007Z A P P S E R V I C E O N L I N U X -2025-05-05T19:20:47.4338051Z -2025-05-05T19:20:47.4338074Z Documentation: http://aka.ms/webapp-linux -2025-05-05T19:20:47.4338094Z Python 3.10.16 -2025-05-05T19:20:47.4338114Z Note: Any data outside '/home' is not persisted -2025-05-05T19:20:47.9853268Z Starting OpenBSD Secure Shell server: sshd. -2025-05-05T19:20:47.9969621Z WEBSITES_INCLUDE_CLOUD_CERTS is not set to true. -2025-05-05T19:20:48.0225846Z Updating certificates in /etc/ssl/certs... -2025-05-05T19:20:50.1148729Z 2 added, 0 removed; done. -2025-05-05T19:20:50.1149550Z Running hooks in /etc/ca-certificates/update.d... -2025-05-05T19:20:50.1169011Z done. -2025-05-05T19:20:50.1224381Z CA certificates copied and updated successfully. -2025-05-05T19:20:50.1887369Z Site's appCommandLine: gunicorn --bind=0.0.0.0 --timeout 600 main:app -2025-05-05T19:20:50.3910131Z Starting periodic command scheduler: cron. -2025-05-05T19:20:50.3912304Z Launching oryx with: create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite -userStartupCommand 'gunicorn --bind=0.0.0.0 --timeout 600 main:app' -2025-05-05T19:20:50.4811707Z Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it... -2025-05-05T19:20:50.4836111Z Build Operation ID: 0bf5a6b10c464f0d -2025-05-05T19:20:50.4838925Z Output is compressed. Extracting it... -2025-05-05T19:20:50.4839189Z Oryx Version: 0.2.20250121.2, Commit: d363b83aad8365d7e91cc246d6dfb3ddad209ddb, ReleaseTagName: 20250121.2 -2025-05-05T19:20:50.4854600Z Extracting '/home/site/wwwroot/output.tar.gz' to directory '/tmp/8dd8c096c8b2d70'... -2025-05-05T19:20:51.1289065Z App path is set to '/tmp/8dd8c096c8b2d70' -2025-05-05T19:20:51.3927172Z Writing output script to '/opt/startup/startup.sh' -2025-05-05T19:20:53.5147632Z Using packages from virtual environment antenv located at /tmp/8dd8c096c8b2d70/antenv. -2025-05-05T19:20:53.5148287Z Updated PYTHONPATH to '/agents/python:/opt/startup/app_logs:/tmp/8dd8c096c8b2d70/antenv/lib/python3.10/site-packages' -2025-05-05T19:20:54.7037155Z [2025-05-05 19:20:54 +0000] [1044] [INFO] Starting gunicorn 23.0.0 -2025-05-05T19:20:54.7046045Z [2025-05-05 19:20:54 +0000] [1044] [INFO] Listening at: http://0.0.0.0:8000 (1044) -2025-05-05T19:20:54.7049491Z [2025-05-05 19:20:54 +0000] [1044] [INFO] Using worker: sync -2025-05-05T19:20:54.7111569Z [2025-05-05 19:20:54 +0000] [1055] [INFO] Booting worker with pid: 1055 -2025-05-05T19:21:15.1610720Z [2025-05-05 19:21:15 +0000] [1058] [INFO] Worker exiting (pid: 1058) -2025-05-05T19:21:15.8809815Z [2025-05-05 19:21:15 +0000] [1045] [INFO] Handling signal: term diff --git a/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_scm_docker.log b/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_scm_docker.log deleted file mode 100644 index 6b66193..0000000 --- a/appservice_logs/LogFiles/2025_05_05_10-30-0-104_default_scm_docker.log +++ /dev/null @@ -1,140 +0,0 @@ -2025-05-05T19:16:55.1352331Z chown: changing ownership of '/temp': Operation not permitted -2025-05-05T19:16:55.1371299Z chmod: changing permissions of '/temp': Operation not permitted -2025-05-05T19:16:57.0095386Z __ __ __ __ _ __ -2025-05-05T19:16:57.0095736Z / //_/_ _ ____/ /_ __/ / (_) /____ -2025-05-05T19:16:57.0095772Z / ,< / / / / __ / / / / / / / __/ _ -2025-05-05T19:16:57.0095799Z / /| / /_/ / /_/ / /_/ / /___/ / /_/ __/ -2025-05-05T19:16:57.0095847Z /_/ |_\__,_/\__,_/\__,_/_____/_/\__/\___/ -2025-05-05T19:16:57.0095921Z -2025-05-05T19:16:57.0096024Z -2025-05-05T19:16:57.0096053Z DEBUG CONSOLE | AZURE APP SERVICE ON LINUX -2025-05-05T19:16:57.0096080Z -2025-05-05T19:16:57.0096106Z Documentation: http://aka.ms/webapp-linux -2025-05-05T19:16:57.0096172Z Kudu Version : 20250415.4 -2025-05-05T19:16:57.0096205Z Commit : 4daf9e0c104d05cf6c82d02a0722563488f851b4 -2025-05-05T19:16:57.0096226Z -2025-05-05T19:16:57.0096278Z Restarting OpenBSD Secure Shell server: sshd. -2025-05-05T19:16:57.0096310Z node not running, starting node /opt/webssh/index.js -2025-05-05T19:16:57.0096354Z Mon May 5 19:16:56 UTC 2025 running .net core -2025-05-05T19:16:57.4639938Z Startup : 07.16.57.456144 -2025-05-05T19:16:57.4841044Z Configure Services : 07.16.57.483913 -2025-05-05T19:16:57.6653459Z Configure : 07.16.57.665175 -2025-05-05T19:16:57.8232206Z Setting Up Routes : 07.16.57.822970 -2025-05-05T19:16:57.9178137Z Exiting Configure : 07.16.57.917650 -2025-05-05T19:16:58.0009015Z warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35] -2025-05-05T19:16:58.0009565Z No XML encryptor configured. Key {eee0e4ac-1fe7-42ee-b2cf-3a79b5d4dd6b} may be persisted to storage in unencrypted form. -2025-05-05T19:16:58.0620611Z Hosting environment: Production -2025-05-05T19:16:58.0621163Z Content root path: /opt/Kudu -2025-05-05T19:16:58.0623329Z Now listening on: http://0.0.0.0:8181 -2025-05-05T19:16:58.0624302Z Application started. Press Ctrl+C to shut down. -2025-05-05T19:17:04.3551826Z Deploy Async -2025-05-05T19:17:07.0743440Z Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx -2025-05-05T19:17:07.0817044Z You can report issues at https://github.com/Microsoft/Oryx/issues -2025-05-05T19:17:07.0929060Z -2025-05-05T19:17:07.1006624Z Oryx Version: 0.2.20250107.1+ef3fb2f9c490a4fbb1f76b5746cd4ba2ff0409f4, Commit: ef3fb2f9c490a4fbb1f76b5746cd4ba2ff0409f4, ReleaseTagName: 20250107.1 -2025-05-05T19:17:07.1076865Z -2025-05-05T19:17:07.1168538Z Build Operation ID: 0bf5a6b10c464f0d -2025-05-05T19:17:07.1245523Z Repository Commit : 00c9c262-5fed-4fb0-88d7-36d91b7e3d39 -2025-05-05T19:17:07.1299474Z OS Type : bullseye -2025-05-05T19:17:07.1368880Z Image Type : githubactions -2025-05-05T19:17:07.1436429Z -2025-05-05T19:17:07.1519133Z Detecting platforms... -2025-05-05T19:17:07.6661481Z Detected following platforms: -2025-05-05T19:17:07.6763950Z python: 3.10.17 -2025-05-05T19:17:07.6814182Z Version '3.10.17' of platform 'python' is not installed. Generating script to install it... -2025-05-05T19:17:08.3325335Z -2025-05-05T19:17:08.3325563Z Using intermediate directory '/tmp/8dd8c096c8b2d70'. -2025-05-05T19:17:08.3325581Z -2025-05-05T19:17:08.3325607Z Copying files to the intermediate directory... -2025-05-05T19:17:08.3325624Z Done in 0 sec(s). -2025-05-05T19:17:08.3325640Z -2025-05-05T19:17:08.3325657Z Source directory : /tmp/8dd8c096c8b2d70 -2025-05-05T19:17:08.3325674Z Destination directory: /home/site/wwwroot -2025-05-05T19:17:08.3325714Z -2025-05-05T19:17:08.3325728Z -2025-05-05T19:17:08.3325748Z Downloading and extracting 'python' version '3.10.17' to '/tmp/oryx/platforms/python/3.10.17'... -2025-05-05T19:17:08.3325765Z Detected image debian flavor: bullseye. -2025-05-05T19:17:10.2712585Z Downloaded in 3 sec(s). -2025-05-05T19:17:10.3090738Z Verifying checksum... -2025-05-05T19:17:10.3428480Z Extracting contents... -2025-05-05T19:17:14.6256499Z performing sha512 checksum for: python... -2025-05-05T19:17:14.9567640Z Done in 7 sec(s). -2025-05-05T19:17:14.9651830Z -2025-05-05T19:17:14.9829172Z image detector file exists, platform is python.. -2025-05-05T19:17:14.9927826Z OS detector file exists, OS is bullseye.. -2025-05-05T19:17:15.0825719Z Python Version: /tmp/oryx/platforms/python/3.10.17/bin/python3.10 -2025-05-05T19:17:15.0896694Z Creating directory for command manifest file if it does not exist -2025-05-05T19:17:15.1106194Z Removing existing manifest file -2025-05-05T19:17:15.1185665Z Python Virtual Environment: antenv -2025-05-05T19:17:15.1247963Z Creating virtual environment... -2025-05-05T19:17:18.3393596Z Activating virtual environment... -2025-05-05T19:17:18.3746803Z Running pip install... -2025-05-05T19:17:22.3654412Z [19:17:19+0000] Collecting blinker==1.9.0 -2025-05-05T19:17:22.3864735Z [19:17:19+0000] Downloading blinker-1.9.0-py3-none-any.whl (8.5 kB) -2025-05-05T19:17:22.4096020Z [19:17:19+0000] Collecting click==8.1.8 -2025-05-05T19:17:22.4384848Z [19:17:19+0000] Downloading click-8.1.8-py3-none-any.whl (98 kB) -2025-05-05T19:17:22.4507324Z [19:17:19+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.2/98.2 kB 4.1 MB/s eta 0:00:00 -2025-05-05T19:17:22.4593691Z [19:17:19+0000] Collecting colorama==0.4.6 -2025-05-05T19:17:22.4657878Z [19:17:19+0000] Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB) -2025-05-05T19:17:22.4739751Z [19:17:19+0000] Collecting Flask==3.1.0 -2025-05-05T19:17:22.4820947Z [19:17:19+0000] Downloading flask-3.1.0-py3-none-any.whl (102 kB) -2025-05-05T19:17:22.5026036Z [19:17:19+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 103.0/103.0 kB 12.5 MB/s eta 0:00:00 -2025-05-05T19:17:22.5128405Z [19:17:19+0000] Collecting itsdangerous==2.2.0 -2025-05-05T19:17:22.5203445Z [19:17:19+0000] Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB) -2025-05-05T19:17:22.5291272Z [19:17:20+0000] Collecting Jinja2==3.1.6 -2025-05-05T19:17:22.5382939Z [19:17:20+0000] Downloading jinja2-3.1.6-py3-none-any.whl (134 kB) -2025-05-05T19:17:22.5597341Z [19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.9/134.9 kB 18.5 MB/s eta 0:00:00 -2025-05-05T19:17:22.5680952Z [19:17:20+0000] Collecting MarkupSafe==3.0.2 -2025-05-05T19:17:22.5772842Z [19:17:20+0000] Downloading MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (20 kB) -2025-05-05T19:17:22.5837091Z [19:17:20+0000] Collecting pytz==2025.2 -2025-05-05T19:17:22.5945568Z [19:17:20+0000] Downloading pytz-2025.2-py2.py3-none-any.whl (509 kB) -2025-05-05T19:17:22.6057195Z [19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 509.2/509.2 kB 19.2 MB/s eta 0:00:00 -2025-05-05T19:17:22.6281323Z [19:17:20+0000] Collecting Werkzeug==3.1.3 -2025-05-05T19:17:22.6452733Z [19:17:20+0000] Downloading werkzeug-3.1.3-py3-none-any.whl (224 kB) -2025-05-05T19:17:22.6685003Z [19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 224.5/224.5 kB 39.9 MB/s eta 0:00:00 -2025-05-05T19:17:22.6805280Z [19:17:21+0000] Installing collected packages: pytz, MarkupSafe, itsdangerous, colorama, click, blinker, Werkzeug, Jinja2, Flask -2025-05-05T19:17:22.6884388Z [19:17:22+0000] Successfully installed Flask-3.1.0 Jinja2-3.1.6 MarkupSafe-3.0.2 Werkzeug-3.1.3 blinker-1.9.0 click-8.1.8 colorama-0.4.6 itsdangerous-2.2.0 pytz-2025.2 -2025-05-05T19:17:22.6942308Z -2025-05-05T19:17:22.7084989Z [notice] A new release of pip is available: 23.0.1 -> 25.1.1 -2025-05-05T19:17:22.7182881Z [notice] To update, run: pip install --upgrade pip -2025-05-05T19:17:22.7332243Z Not a vso image, so not writing build commands -2025-05-05T19:17:22.7433673Z Preparing output... -2025-05-05T19:17:22.7590532Z -2025-05-05T19:17:22.7768156Z Copying files to destination directory '/tmp/_preCompressedDestinationDir'... -2025-05-05T19:17:23.1865886Z Done in 1 sec(s). -2025-05-05T19:17:23.1944206Z Compressing content of directory '/tmp/_preCompressedDestinationDir'... -2025-05-05T19:17:24.6561040Z Copied the compressed output to '/home/site/wwwroot' -2025-05-05T19:17:24.7046232Z -2025-05-05T19:17:24.7149284Z Removing existing manifest file -2025-05-05T19:17:24.7239576Z Creating a manifest file... -2025-05-05T19:17:24.7328884Z Manifest file created. -2025-05-05T19:17:24.7381346Z Copying .ostype to manifest output directory. -2025-05-05T19:17:24.7451296Z -2025-05-05T19:17:24.7519679Z Done in 17 sec(s). -2025-05-05T19:20:45.6815589Z __ __ __ __ _ __ -2025-05-05T19:20:45.6913278Z / //_/_ _ ____/ /_ __/ / (_) /____ -2025-05-05T19:20:45.6913364Z / ,< / / / / __ / / / / / / / __/ _ -2025-05-05T19:20:45.6913418Z / /| / /_/ / /_/ / /_/ / /___/ / /_/ __/ -2025-05-05T19:20:45.6913436Z /_/ |_\__,_/\__,_/\__,_/_____/_/\__/\___/ -2025-05-05T19:20:45.6913469Z -2025-05-05T19:20:45.6913491Z -2025-05-05T19:20:45.6913531Z DEBUG CONSOLE | AZURE APP SERVICE ON LINUX -2025-05-05T19:20:45.6913546Z -2025-05-05T19:20:45.6913565Z Documentation: http://aka.ms/webapp-linux -2025-05-05T19:20:45.6913582Z Kudu Version : 20250415.4 -2025-05-05T19:20:45.6913600Z Commit : 4daf9e0c104d05cf6c82d02a0722563488f851b4 -2025-05-05T19:20:45.6913616Z -2025-05-05T19:20:45.8788525Z chown: changing ownership of '/temp': Operation not permitted -2025-05-05T19:20:45.8834645Z chmod: changing permissions of '/temp': Operation not permitted -2025-05-05T19:20:46.3638312Z Restarting OpenBSD Secure Shell server: sshd. -2025-05-05T19:20:46.3847302Z node not running, starting node /opt/webssh/index.js -2025-05-05T19:20:48.3783830Z Mon May 5 19:20:48 UTC 2025 running .net core -2025-05-05T19:20:48.9937896Z Startup : 07.20.48.981381 -2025-05-05T19:20:49.0286284Z Configure Services : 07.20.49.028467 -2025-05-05T19:20:49.3892564Z Configure : 07.20.49.388587 -2025-05-05T19:20:49.9836682Z Setting Up Routes : 07.20.49.687685 -2025-05-05T19:20:50.0455445Z Exiting Configure : 07.20.50.045009 -2025-05-05T19:20:50.3799302Z Hosting environment: Production -2025-05-05T19:20:50.3799598Z Content root path: /opt/Kudu -2025-05-05T19:20:50.3825425Z Now listening on: http://0.0.0.0:8181 -2025-05-05T19:20:50.3825692Z Application started. Press Ctrl+C to shut down. diff --git a/appservice_logs/LogFiles/2025_05_05_10-30-0-104_docker.log b/appservice_logs/LogFiles/2025_05_05_10-30-0-104_docker.log deleted file mode 100644 index 3f33852..0000000 --- a/appservice_logs/LogFiles/2025_05_05_10-30-0-104_docker.log +++ /dev/null @@ -1,84 +0,0 @@ -2025-05-05T19:17:41.4717465Z Container start method called. -2025-05-05T19:17:41.4728377Z Establishing network. -2025-05-05T19:17:41.4731359Z Pulling image: appsvc/python:3.10_20250213.3.tuxprod. -2025-05-05T19:17:50.9795124Z Image appsvc/python:3.10_20250213.3.tuxprod is pulled from registry 10.1.0.7:13209 -2025-05-05T19:17:50.9904134Z Container is starting. -2025-05-05T19:17:50.9905561Z Establishing user namespace if not established already. -2025-05-05T19:17:50.9906483Z Establishing network if not established already. -2025-05-05T19:17:50.9907256Z Mounting volumes. -2025-05-05T19:17:50.9914579Z Nested mountpoint -2025-05-05T19:17:50.9990681Z Nested mountpoint volatile/logs -2025-05-05T19:17:51.0024642Z Nested mountpoint -2025-05-05T19:17:51.0201407Z Nested mountpoint -2025-05-05T19:17:51.0207045Z Nested mountpoint -2025-05-05T19:17:51.0211206Z Nested mountpoint -2025-05-05T19:17:51.0335267Z Nested mountpoint -2025-05-05T19:17:51.0357867Z Nested mountpoint -2025-05-05T19:17:51.0375589Z Nested mountpoint -2025-05-05T19:17:51.0388349Z Nested mountpoint -2025-05-05T19:17:51.4756521Z Creating container. -2025-05-05T19:17:51.4757692Z Creating pipes for streaming container io. -2025-05-05T19:17:51.4760508Z Creating stdout named pipe at /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504. -2025-05-05T19:17:51.4766905Z Successfully created stdout named pipe at: /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504. -2025-05-05T19:17:51.4767976Z Opening named pipe /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504 for reading in non-blocking mode. -2025-05-05T19:17:51.4773325Z Successfully opened named pipe: /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504. -2025-05-05T19:17:51.4774766Z Successfully removed non-blocking flag from /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stdout_36bb8e1fb651405b9413acb872e6f504. -2025-05-05T19:17:51.4779954Z Creating stderr named pipe at /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00. -2025-05-05T19:17:51.4782401Z Successfully created stderr named pipe at: /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00. -2025-05-05T19:17:51.4783850Z Opening named pipe /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00 for reading in non-blocking mode. -2025-05-05T19:17:51.4785186Z Successfully opened named pipe: /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00. -2025-05-05T19:17:51.4786792Z Successfully removed non-blocking flag from /podr/container/pipe/ad8972c0_msdocs-python-webapp-quickstart-rmb/stderr_f998e19af8a349b7b63880635389cd00. -2025-05-05T19:17:51.4808543Z Creating container with image: appsvc/python:3.10_20250213.3.tuxprod from registry: 10.1.0.7:13209 and fully qualified image name: 10.1.0.7:13209/appsvc/python:3.10_20250213.3.tuxprod -2025-05-05T19:17:51.7562535Z Starting container: ad8972c0_msdocs-python-webapp-quickstart-rmb. -2025-05-05T19:17:51.7732099Z Starting watchers and probes. -2025-05-05T19:17:51.8032256Z Starting metrics collection. -2025-05-05T19:17:51.8065077Z Container is running. -2025-05-05T19:17:51.8621134Z Container start method finished after 10390 ms. -2025-05-05T19:17:59.1339718Z Site startup probe succeeded after 7.2431449 seconds. -2025-05-05T19:17:59.7768666Z Site started. -2025-05-05T19:17:59.7997645Z Site is running with deployment version: 00c9c262-5fed-4fb0-88d7-36d91b7e3d39 -2025-05-05T19:20:44.7876889Z Container start method called. -2025-05-05T19:20:44.7878026Z Establishing network. -2025-05-05T19:20:44.7878787Z Pulling image: appsvc/python:3.10_20250213.3.tuxprod. -2025-05-05T19:20:45.1631223Z Image appsvc/python:3.10_20250213.3.tuxprod is pulled from registry 10.1.0.4:13209 -2025-05-05T19:20:45.1636430Z Container is starting. -2025-05-05T19:20:45.1639308Z Establishing user namespace if not established already. -2025-05-05T19:20:45.1643991Z Establishing network if not established already. -2025-05-05T19:20:45.1647483Z Mounting volumes. -2025-05-05T19:20:45.1655405Z Nested mountpoint -2025-05-05T19:20:45.1680458Z Nested mountpoint volatile/logs -2025-05-05T19:20:45.1710420Z Nested mountpoint -2025-05-05T19:20:45.1731084Z Nested mountpoint -2025-05-05T19:20:45.1749503Z Nested mountpoint -2025-05-05T19:20:45.1766564Z Nested mountpoint -2025-05-05T19:20:45.1837639Z Nested mountpoint -2025-05-05T19:20:45.1843657Z Nested mountpoint -2025-05-05T19:20:45.1872261Z Nested mountpoint -2025-05-05T19:20:45.1905725Z Nested mountpoint -2025-05-05T19:20:45.6332278Z Creating container. -2025-05-05T19:20:45.6336238Z Creating pipes for streaming container io. -2025-05-05T19:20:45.6339722Z Creating stdout named pipe at /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d. -2025-05-05T19:20:45.6344359Z Successfully created stdout named pipe at: /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d. -2025-05-05T19:20:45.6347943Z Opening named pipe /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d for reading in non-blocking mode. -2025-05-05T19:20:45.6362484Z Successfully opened named pipe: /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d. -2025-05-05T19:20:45.6366054Z Successfully removed non-blocking flag from /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stdout_89beaf9fcb2d4d3082b82c1c6fd6e59d. -2025-05-05T19:20:45.6370608Z Creating stderr named pipe at /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74. -2025-05-05T19:20:45.6374579Z Successfully created stderr named pipe at: /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74. -2025-05-05T19:20:45.6378138Z Opening named pipe /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74 for reading in non-blocking mode. -2025-05-05T19:20:45.6389388Z Successfully opened named pipe: /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74. -2025-05-05T19:20:45.6404969Z Successfully removed non-blocking flag from /podr/container/pipe/34de0832_msdocs-python-webapp-quickstart-rmb/stderr_ac40df0a3e37415099294f58ba4e9c74. -2025-05-05T19:20:45.6416156Z Creating container with image: appsvc/python:3.10_20250213.3.tuxprod from registry: 10.1.0.4:13209 and fully qualified image name: 10.1.0.4:13209/appsvc/python:3.10_20250213.3.tuxprod -2025-05-05T19:20:47.2958213Z Starting container: 34de0832_msdocs-python-webapp-quickstart-rmb. -2025-05-05T19:20:47.3254636Z Starting watchers and probes. -2025-05-05T19:20:47.3302946Z Starting metrics collection. -2025-05-05T19:20:47.3312657Z Container is running. -2025-05-05T19:20:47.3649944Z Container start method finished after 2576 ms. -2025-05-05T19:20:54.9916983Z Site startup probe succeeded after 7.6221948 seconds. -2025-05-05T19:20:55.0979300Z Site started. -2025-05-05T19:20:55.1042513Z Site is running with deployment version: 00c9c262-5fed-4fb0-88d7-36d91b7e3d39 -2025-05-05T19:21:15.1351042Z Container is terminating. Grace period: 5 seconds. -2025-05-05T19:21:15.1469269Z Stop and delete container. Retry count = 0 -2025-05-05T19:21:15.1470867Z Stopping container: ad8972c0_msdocs-python-webapp-quickstart-rmb. -2025-05-05T19:21:20.1629238Z Deleting container: ad8972c0_msdocs-python-webapp-quickstart-rmb. Retry count = 0 -2025-05-05T19:21:20.3330163Z Container spec TerminationMessagePolicy path -2025-05-05T19:21:20.3336293Z Container is terminated. Total time elapsed: 5198 ms. diff --git a/appservice_logs/LogFiles/AppServiceAppLogs_Feature_Installer/startup_4.log b/appservice_logs/LogFiles/AppServiceAppLogs_Feature_Installer/startup_4.log deleted file mode 100644 index 15a8855..0000000 --- a/appservice_logs/LogFiles/AppServiceAppLogs_Feature_Installer/startup_4.log +++ /dev/null @@ -1,4 +0,0 @@ -2025-05-05 19:17:58,113 [MainThread] [DEBUG] : Initializating AppServiceAppLogging -2025-05-05 19:17:58,113 [Thread-1 (] [DEBUG] : Did not find any previously bound socket -2025-05-05 19:17:58,114 [MainThread] [DEBUG] : Initialized AppServiceAppLogging -2025-05-05 19:17:58,131 [Thread-3 (] [DEBUG] : Waiting for the logs flag to be set diff --git a/appservice_logs/LogFiles/CodeProfiler/870d61_debug.log b/appservice_logs/LogFiles/CodeProfiler/870d61_debug.log deleted file mode 100644 index eb6b22d..0000000 --- a/appservice_logs/LogFiles/CodeProfiler/870d61_debug.log +++ /dev/null @@ -1,8 +0,0 @@ -[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Code Profiler Installer is starting up -[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Cleaning up any existing status file which indicated signal handlers initialized status -[2025_05_05_19_17_58] [appsvc_profiler.installer] [DEBUG] APPSETTING_WEBSITE_ENABLE_DEFAULT_CODE_PROFILER : None -[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Attempting to install the default code profiler. -[2025_05_05_19_17_58] [appsvc_profiler.installer] [DEBUG] viztracer would save traces to /tmp/870d61_profiler_trace.json -[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Successfully installed code profiler. -[2025_05_05_19_17_58] [appsvc_profiler.installer] [INFO] Signal Handlers SIGUSR for needed code-profiler have been initialized for gunicorn process on instance 870d616759e74713524da24210e88870fbcc76bc99b00f44c089fc8ca08f9724 -[2025_05_05_19_17_58] [appsvc_profiler.installer] [DEBUG] Code Profiler Installer is exiting as installation is completed diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_001_Startup_POST_api-zipdeploy_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_001_Startup_POST_api-zipdeploy_0s.xml deleted file mode 100644 index 014db5a..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_001_Startup_POST_api-zipdeploy_0s.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_002_POST_api-zipdeploy_202_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_002_POST_api-zipdeploy_202_0s.xml deleted file mode 100644 index e00d33d..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_002_POST_api-zipdeploy_202_0s.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_003_Background_POST_api-zipdeploy_pending.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_003_Background_POST_api-zipdeploy_pending.xml deleted file mode 100644 index 772e4a9..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-00_870d61_003_Background_POST_api-zipdeploy_pending.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-05_870d61_004_GET_api-deployments-latest_202_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-05_870d61_004_GET_api-deployments-latest_202_0s.xml deleted file mode 100644 index 1aaabcf..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-05_870d61_004_GET_api-deployments-latest_202_0s.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-06_870d61_005_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-06_870d61_005_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml deleted file mode 100644 index 8c66ddc..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-06_870d61_005_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-22_870d61_006_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-22_870d61_006_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml deleted file mode 100644 index e104d44..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-22_870d61_006_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-38_870d61_007_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-38_870d61_007_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml deleted file mode 100644 index b01f59e..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-17-38_870d61_007_GET_api-deployments-00c9c262-5fed-4fb0-88d7-36d91b7e3d39_200_0s.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-18-12_870d61_008_GET_logstream_200_180s.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-18-12_870d61_008_GET_logstream_200_180s.xml deleted file mode 100644 index d887328..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-18-12_870d61_008_GET_logstream_200_180s.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-21-12_870d61_009_LogStreamManager:-Dispose()-called_pending.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-21-12_870d61_009_LogStreamManager:-Dispose()-called_pending.xml deleted file mode 100644 index fb1d2f4..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-21-12_870d61_009_LogStreamManager:-Dispose()-called_pending.xml +++ /dev/null @@ -1,2 +0,0 @@ - - - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_002_GET_logstream_pending.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_002_GET_logstream_pending.xml deleted file mode 100644 index ec55ec4..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-24-41_870d61_002_GET_logstream_pending.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-26-27_870d61_003_GET_dump_pending.xml b/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-26-27_870d61_003_GET_dump_pending.xml deleted file mode 100644 index 7e5db30..0000000 --- a/appservice_logs/LogFiles/kudu/trace/2025-05-05T19-26-27_870d61_003_GET_dump_pending.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-a9ca9bea-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt b/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-a9ca9bea-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt deleted file mode 100644 index 39b3c40..0000000 --- a/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-a9ca9bea-4373fd25-0222-44e5-bdd7-209aa9aa0146.txt +++ /dev/null @@ -1 +0,0 @@ -2025-05-05T19:24:41 Startup Request, url: /logstream, method: GET, type: request, pid: 768,1,7, ScmType: None, SCM_DO_BUILD_DURING_DEPLOYMENT: true diff --git a/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt b/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt deleted file mode 100644 index 20a0fe9..0000000 --- a/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-12fd7e67-de96-4103-a0f0-41f43fd9353d.txt +++ /dev/null @@ -1,4 +0,0 @@ -2025-05-05T19:17:00 Startup Request, url: /api/zipdeploy?isAsync=true, method: POST, type: request, pid: 768,1,7, SCM_DO_BUILD_DURING_DEPLOYMENT: true, ScmType: None -2025-05-05T19:17:00 Error occurred, type: error, text: Error removing symlink: Path doesn't exist!, stackTrace: at Mono.Unix.UnixFileSystemInfo.AssertValid() - at Mono.Unix.UnixFileSystemInfo.get_FileType() - at Kudu.Services.Deployment.PushDeploymentController.PushDeployAsync(ArtifactDeploymentInfo deploymentInfo, Boolean isAsync, HttpContext context, JObject requestJson) in /tmp/KuduLite/Kudu.Services/Deployment/PushDeploymentController.cs:line 740 diff --git a/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt b/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt deleted file mode 100644 index 3250767..0000000 --- a/appservice_logs/LogFiles/kudu/trace/msdocs-pyt-kudu-f00b8980-8011a91c-a391-48d0-a26c-bb3188ee0a07.txt +++ /dev/null @@ -1 +0,0 @@ -2025-05-05T19:21:12 Error occurred, type: error, text: LogStreamManager: ProcessRequest end diff --git a/appservice_logs/LogFiles/webssh/.log b/appservice_logs/LogFiles/webssh/.log deleted file mode 100644 index e69de29..0000000 diff --git a/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/log.log b/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/log.log deleted file mode 100644 index 2380f6c..0000000 --- a/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/log.log +++ /dev/null @@ -1,103 +0,0 @@ -2025-05-05T19:17:04.5367109Z,Updating submodules.,de3dbd92-b845-41b7-8442-26c1c0b2764a,0 -2025-05-05T19:17:05.9156942Z,Preparing deployment for commit id '00c9c262-5'.,5fceedae-25ac-40fc-a431-44bbb3f50de9,0 -2025-05-05T19:17:06.1083519Z,PreDeployment: context.CleanOutputPath False,ee624d2c-5268-4166-b4c6-85d7b564d969,0 -2025-05-05T19:17:06.1721967Z,PreDeployment: context.OutputPath /home/site/wwwroot,8a1ef3be-3167-474d-95b7-46c69f22eddc,0 -2025-05-05T19:17:06.3195445Z,Repository path is /tmp/zipdeploy/extracted,f91b6150-19b9-44fe-b24d-3acef5365d2f,0 -2025-05-05T19:17:06.3875451Z,Running oryx build...,78f69326-50ce-48c8-ba5b-6be6c578933d,0 - 2025-05-05T19:17:06.3928139Z,Command: oryx build /tmp/zipdeploy/extracted -o /home/site/wwwroot --platform python --platform-version 3.10 -p virtualenv_name=antenv --log-file /tmp/build-debug.log -i /tmp/8dd8c096c8b2d70 --compress-destination-dir | tee /tmp/oryx-build.log,,0 - 2025-05-05T19:17:07.0742322Z,Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx,,0 - 2025-05-05T19:17:07.0816026Z,You can report issues at https://github.com/Microsoft/Oryx/issues,,0 - 2025-05-05T19:17:07.0928213Z,,,0 - 2025-05-05T19:17:07.1006696Z,Oryx Version: 0.2.20250107.1+ef3fb2f9c490a4fbb1f76b5746cd4ba2ff0409f4, Commit: ef3fb2f9c490a4fbb1f76b5746cd4ba2ff0409f4, ReleaseTagName: 20250107.1,,0 - 2025-05-05T19:17:07.1076851Z,,,0 - 2025-05-05T19:17:07.1165886Z,Build Operation ID: 0bf5a6b10c464f0d,,0 - 2025-05-05T19:17:07.1243416Z,Repository Commit : 00c9c262-5fed-4fb0-88d7-36d91b7e3d39,,0 - 2025-05-05T19:17:07.1297690Z,OS Type : bullseye,,0 - 2025-05-05T19:17:07.1367418Z,Image Type : githubactions,,0 - 2025-05-05T19:17:07.1435562Z,,,0 - 2025-05-05T19:17:07.1519233Z,Detecting platforms...,,0 - 2025-05-05T19:17:07.6661693Z,Detected following platforms:,,0 - 2025-05-05T19:17:07.6763926Z, python: 3.10.17,,0 - 2025-05-05T19:17:07.6814200Z,Version '3.10.17' of platform 'python' is not installed. Generating script to install it...,,0 - 2025-05-05T19:17:07.7707859Z,,,0 - 2025-05-05T19:17:07.7922682Z,Using intermediate directory '/tmp/8dd8c096c8b2d70'.,,0 - 2025-05-05T19:17:07.8000236Z,,,0 - 2025-05-05T19:17:07.8106748Z,Copying files to the intermediate directory...,,0 - 2025-05-05T19:17:07.8817109Z,Done in 0 sec(s).,,0 - 2025-05-05T19:17:07.8904193Z,,,0 - 2025-05-05T19:17:07.8980479Z,Source directory : /tmp/8dd8c096c8b2d70,,0 - 2025-05-05T19:17:07.9189602Z,Destination directory: /home/site/wwwroot,,0 - 2025-05-05T19:17:07.9307659Z,,,0 - 2025-05-05T19:17:07.9488312Z,,,0 - 2025-05-05T19:17:07.9542319Z,Downloading and extracting 'python' version '3.10.17' to '/tmp/oryx/platforms/python/3.10.17'...,,0 - 2025-05-05T19:17:07.9601580Z,Detected image debian flavor: bullseye.,,0 - 2025-05-05T19:17:10.2709940Z,Downloaded in 3 sec(s).,,0 - 2025-05-05T19:17:10.3088531Z,Verifying checksum...,,0 - 2025-05-05T19:17:10.3426547Z,Extracting contents...,,0 - 2025-05-05T19:17:14.6262426Z,performing sha512 checksum for: python...,,0 - 2025-05-05T19:17:14.9572297Z,Done in 7 sec(s).,,0 - 2025-05-05T19:17:14.9650256Z,,,0 - 2025-05-05T19:17:14.9845790Z,image detector file exists, platform is python..,,0 - 2025-05-05T19:17:14.9927820Z,OS detector file exists, OS is bullseye..,,0 - 2025-05-05T19:17:15.0824438Z,Python Version: /tmp/oryx/platforms/python/3.10.17/bin/python3.10,,0 - 2025-05-05T19:17:15.0895718Z,Creating directory for command manifest file if it does not exist,,0 - 2025-05-05T19:17:15.1105138Z,Removing existing manifest file,,0 - 2025-05-05T19:17:15.1190665Z,Python Virtual Environment: antenv,,0 - 2025-05-05T19:17:15.1256738Z,Creating virtual environment...,,0 - 2025-05-05T19:17:18.3418133Z,Activating virtual environment...,,0 - 2025-05-05T19:17:18.3783851Z,Running pip install...,,0 - 2025-05-05T19:17:22.3653505Z,[19:17:19+0000] Collecting blinker==1.9.0,,0 - 2025-05-05T19:17:22.3857878Z,[19:17:19+0000] Downloading blinker-1.9.0-py3-none-any.whl (8.5 kB),,0 - 2025-05-05T19:17:22.4097567Z,[19:17:19+0000] Collecting click==8.1.8,,0 - 2025-05-05T19:17:22.4384090Z,[19:17:19+0000] Downloading click-8.1.8-py3-none-any.whl (98 kB),,0 - 2025-05-05T19:17:22.4506519Z,[19:17:19+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.2/98.2 kB 4.1 MB/s eta 0:00:00,,0 - 2025-05-05T19:17:22.4592714Z,[19:17:19+0000] Collecting colorama==0.4.6,,0 - 2025-05-05T19:17:22.4657052Z,[19:17:19+0000] Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB),,0 - 2025-05-05T19:17:22.4739377Z,[19:17:19+0000] Collecting Flask==3.1.0,,0 - 2025-05-05T19:17:22.4819570Z,[19:17:19+0000] Downloading flask-3.1.0-py3-none-any.whl (102 kB),,0 - 2025-05-05T19:17:22.5025173Z,[19:17:19+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 103.0/103.0 kB 12.5 MB/s eta 0:00:00,,0 - 2025-05-05T19:17:22.5120936Z,[19:17:19+0000] Collecting itsdangerous==2.2.0,,0 - 2025-05-05T19:17:22.5202653Z,[19:17:19+0000] Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB),,0 - 2025-05-05T19:17:22.5290525Z,[19:17:20+0000] Collecting Jinja2==3.1.6,,0 - 2025-05-05T19:17:22.5379789Z,[19:17:20+0000] Downloading jinja2-3.1.6-py3-none-any.whl (134 kB),,0 - 2025-05-05T19:17:22.5596313Z,[19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.9/134.9 kB 18.5 MB/s eta 0:00:00,,0 - 2025-05-05T19:17:22.5680555Z,[19:17:20+0000] Collecting MarkupSafe==3.0.2,,0 - 2025-05-05T19:17:22.5781414Z,[19:17:20+0000] Downloading MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (20 kB),,0 - 2025-05-05T19:17:22.5836391Z,[19:17:20+0000] Collecting pytz==2025.2,,0 - 2025-05-05T19:17:22.5944709Z,[19:17:20+0000] Downloading pytz-2025.2-py2.py3-none-any.whl (509 kB),,0 - 2025-05-05T19:17:22.6056521Z,[19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 509.2/509.2 kB 19.2 MB/s eta 0:00:00,,0 - 2025-05-05T19:17:22.6280268Z,[19:17:20+0000] Collecting Werkzeug==3.1.3,,0 - 2025-05-05T19:17:22.6451274Z,[19:17:20+0000] Downloading werkzeug-3.1.3-py3-none-any.whl (224 kB),,0 - 2025-05-05T19:17:22.6684151Z,[19:17:20+0000] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 224.5/224.5 kB 39.9 MB/s eta 0:00:00,,0 - 2025-05-05T19:17:22.6803987Z,[19:17:21+0000] Installing collected packages: pytz, MarkupSafe, itsdangerous, colorama, click, blinker, Werkzeug, Jinja2, Flask,,0 - 2025-05-05T19:17:22.6870664Z,[19:17:22+0000] Successfully installed Flask-3.1.0 Jinja2-3.1.6 MarkupSafe-3.0.2 Werkzeug-3.1.3 blinker-1.9.0 click-8.1.8 colorama-0.4.6 itsdangerous-2.2.0 pytz-2025.2,,0 - 2025-05-05T19:17:22.6941647Z,,,0 - 2025-05-05T19:17:22.7080932Z,[notice] A new release of pip is available: 23.0.1 -> 25.1.1,,0 - 2025-05-05T19:17:22.7181540Z,[notice] To update, run: pip install --upgrade pip,,0 - 2025-05-05T19:17:22.7331385Z,Not a vso image, so not writing build commands,,0 - 2025-05-05T19:17:22.7432342Z,Preparing output...,,0 - 2025-05-05T19:17:22.7605242Z,,,0 - 2025-05-05T19:17:22.7773301Z,Copying files to destination directory '/tmp/_preCompressedDestinationDir'...,,0 - 2025-05-05T19:17:23.1845753Z,Done in 1 sec(s).,,0 - 2025-05-05T19:17:23.1993554Z,Compressing content of directory '/tmp/_preCompressedDestinationDir'...,,0 - 2025-05-05T19:17:24.6560208Z,Copied the compressed output to '/home/site/wwwroot',,0 - 2025-05-05T19:17:24.7052856Z,,,0 - 2025-05-05T19:17:24.7150280Z,Removing existing manifest file,,0 - 2025-05-05T19:17:24.7238893Z,Creating a manifest file...,,0 - 2025-05-05T19:17:24.7328270Z,Manifest file created.,,0 - 2025-05-05T19:17:24.7380821Z,Copying .ostype to manifest output directory.,,0 - 2025-05-05T19:17:24.7450571Z,,,0 - 2025-05-05T19:17:24.7519152Z,Done in 17 sec(s).,,0 -2025-05-05T19:17:25.1157876Z,Running post deployment command(s)...,823f060d-59d6-4e26-862d-7272dee2eb75,0 -2025-05-05T19:17:25.1823277Z,,9ca189b3-1914-4655-ad14-a831e45b959c,0 -2025-05-05T19:17:25.2463247Z,Generating summary of Oryx build,e009db63-3535-4548-b51e-0f74b4969183,0 -2025-05-05T19:17:25.3527029Z,Parsing the build logs,88216918-715c-4210-9aa5-9d0ddddb11b5,0 -2025-05-05T19:17:25.4500464Z,Found 0 issue(s),0f6b7e10-7dc7-4e34-8e82-8199738cdf16,0 -2025-05-05T19:17:25.5618546Z,,b33daa74-bfb5-47d6-8d7f-842989209312,0 -2025-05-05T19:17:25.6326232Z,Build Summary :,b2fe12da-5fdc-4fd2-851a-369310fcde91,0 -2025-05-05T19:17:25.7001984Z,===============,a3de1b18-eb02-452e-8407-c029a6e2f757,0 -2025-05-05T19:17:25.7651899Z,Errors (0),a9173eb6-9dd7-4444-91cf-c3d4a82ffb58,0 -2025-05-05T19:17:25.8256469Z,Warnings (0),3bc3ca2d-23ad-45ec-b06c-14a97189b5a7,0 -2025-05-05T19:17:25.8855955Z,,1615e5ef-6e98-4ba4-a1cc-4d4cb1b83bbe,0 -2025-05-05T19:17:25.9796508Z,Triggering recycle (preview mode disabled).,3869912d-0786-4fe6-88c4-884e17b4cd15,0 -2025-05-05T19:17:26.0944225Z,Deployment successful. deployer = Push-Deployer deploymentPath = ZipDeploy. Extract zip. Remote build.,bd7b213d-7741-4baa-bd4e-bc3444d5936f,0 diff --git a/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/status.xml b/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/status.xml deleted file mode 100644 index 36e8d99..0000000 --- a/appservice_logs/deployments/00c9c262-5fed-4fb0-88d7-36d91b7e3d39/status.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - 00c9c262-5fed-4fb0-88d7-36d91b7e3d39 - N/A - Push-Deployer - N/A - Created via a push deployment - - Success - - 2025-05-05T19:17:26.3209072Z - 2025-05-05T19:17:04.4115236Z - 2025-05-05T19:17:05.958156Z - 2025-05-05T19:17:26.3209072Z - True - False - True - - \ No newline at end of file diff --git a/appservice_logs/deployments/active b/appservice_logs/deployments/active deleted file mode 100644 index 4ee4579..0000000 --- a/appservice_logs/deployments/active +++ /dev/null @@ -1 +0,0 @@ -00c9c262-5fed-4fb0-88d7-36d91b7e3d39 \ No newline at end of file diff --git a/appservice_logs/deployments/pending b/appservice_logs/deployments/pending deleted file mode 100644 index e69de29..0000000