SmartCane/python_app/Chemba_download.ipynb
Martin Folkerts 5886f59bd8 wip
2024-04-18 13:43:14 +02:00

470 lines
21 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "0c18e312-8421-47d7-84f9-ed7d5e47e7ee",
"metadata": {
"tags": []
},
"source": [
"#### Load packages and connect to SentinelHub"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "b7ca7102-5fd9-481f-90cd-3ba60e288649",
"metadata": {},
"outputs": [],
"source": [
"# $ pip install sentinelhub\n",
"# pip install gdal\n",
"\n",
"import os\n",
"import json\n",
"import datetime\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from pathlib import Path\n",
"from osgeo import gdal\n",
"\n",
"from sentinelhub import MimeType, CRS, BBox, SentinelHubRequest, SentinelHubDownloadClient, \\\n",
" DataCollection, bbox_to_dimensions, DownloadRequest, SHConfig, BBoxSplitter, read_data\n",
"\n",
"config = SHConfig()\n",
"\n",
"import time\n",
"import shutil"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "330c967c-2742-4a7a-9a61-28bfdaf8eeca",
"metadata": {},
"outputs": [],
"source": [
"#pip install pipreqs"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "49f8496a-a267-4b74-9500-a168e031ed68",
"metadata": {},
"outputs": [],
"source": [
"#import pipreqs\n",
"#pipreqs Resilience BV/4002 CMD App - General/4002 CMD Team/4002 TechnicalData/04 WP2 technical/python/Chemba_download.ipynb"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "5491a840-779c-4f0c-8164-c3de738b3298",
"metadata": {},
"outputs": [],
"source": [
"config.sh_client_id = '1a72d811-4f0e-4447-8282-df09608cff44'\n",
"config.sh_client_secret = 'FcBlRL29i9ZmTzhmKTv1etSMFs5PxSos'"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "eb1fb662-0e25-4ca9-8317-c6953290842b",
"metadata": {},
"outputs": [],
"source": [
"collection_id = 'c691479f-358c-46b1-b0f0-e12b70a9856c'\n",
"byoc = DataCollection.define_byoc(\n",
" collection_id,\n",
" name='planet_data2',\n",
" is_timeless=True)"
]
},
{
"cell_type": "markdown",
"id": "6adb603d-8182-48c6-a051-869e16ee7bba",
"metadata": {
"tags": []
},
"source": [
"#### Set some variables\n",
"The only place anything might need to be changed."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "060396e0-e5ee-4b54-b211-5d8bfcba167f",
"metadata": {},
"outputs": [],
"source": [
"#project = 'chemba' #or xinavane or chemba_test_8b\n",
"#project = 'xinavane' #or xinavane or chemba_test_8b\n",
"project = 'chemba_test_8b' #or xinavane or chemba_test_8b\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "c9f79e81-dff8-4109-8d26-6c423142dcf2",
"metadata": {},
"outputs": [],
"source": [
"# Adjust the number of days needed\n",
"days = 1095 #change back to 28 which is the default. 3 years is 1095 days."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "e18bdf8f-be4b-44ab-baaa-de5de60d92cb",
"metadata": {},
"outputs": [],
"source": [
"#delete all the satellite outputs -> then True\n",
"empty_folder_question = False"
]
},
{
"cell_type": "markdown",
"id": "81bbb513-0bd2-4277-83e8-6f94051ce70b",
"metadata": {
"tags": []
},
"source": [
"#### Define functions\n",
"After this block, no manual changes to parameters are required. \n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "3f7c8e04-4569-457b-b39d-283582c4ba36",
"metadata": {},
"outputs": [],
"source": [
"BASE_PATH = Path('../laravel_app/storage/app') / os.getenv('PROJECT_DIR',project) \n",
"BASE_PATH_SINGLE_IMAGES = Path(BASE_PATH / 'single_images')\n",
"folder_for_merged_tifs = str(BASE_PATH / 'merged_tif')\n",
"folder_for_virtual_raster = str(BASE_PATH / 'merged_virtual')\n",
" \n",
"# Check if the folders exist, and if not, create them\n",
"if not os.path.exists(BASE_PATH_SINGLE_IMAGES):\n",
" os.makedirs(BASE_PATH_SINGLE_IMAGES)\n",
" \n",
"if not os.path.exists(folder_for_merged_tifs):\n",
" os.makedirs(folder_for_merged_tifs)\n",
"\n",
"if not os.path.exists(folder_for_virtual_raster):\n",
" os.makedirs(folder_for_virtual_raster)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "244b5752-4f02-4347-9278-f6a0a46b88f4",
"metadata": {},
"outputs": [],
"source": [
"evalscript_true_color = \"\"\"\n",
" //VERSION=3\n",
"\n",
" function setup() {\n",
" return {\n",
" input: [{\n",
" bands: [\"Red\", \"Green\", \"Blue\", \"NIR\", \"UDM2_Clear\"]\n",
" }],\n",
" output: {\n",
" bands: 4 \n",
" //sampleType: \"FLOAT32\"\n",
" }\n",
" };\n",
" }\n",
"\n",
" function evaluatePixel(sample) {\n",
" // Scale the bands\n",
" var scaledBlue = [2.5 * sample.Blue / 10000];\n",
" var scaledGreen = [2.5 * sample.Green / 10000];\n",
" var scaledRed = [2.5 * sample.Red / 10000];\n",
" var scaledNIR = [2.5 * sample.NIR / 10000];\n",
" \n",
" // Calculate the CI (Chlorophyll Index) using the scaled values\n",
" // var CI = [scaledNIR / scaledGreen - 1] ;\n",
"\n",
"// Output the scaled bands and CI\n",
" if (sample.UDM2_Clear != 0) { \n",
" return [\n",
" scaledRed,\n",
" scaledGreen,\n",
" scaledBlue,\n",
" scaledNIR\n",
" // sample.UDM,\n",
" // CI,\n",
" ]\n",
" } else {\n",
" return [NaN, NaN, NaN, NaN]}\n",
" }\n",
"\"\"\"\n",
"\n",
"def get_true_color_request_day(time_interval, bbox, size):\n",
" return SentinelHubRequest(\n",
" evalscript=evalscript_true_color,\n",
" input_data=[\n",
" SentinelHubRequest.input_data(\n",
" data_collection=DataCollection.planet_data2,\n",
" time_interval=(time_interval, time_interval)\n",
" )\n",
" ],\n",
" responses=[\n",
" SentinelHubRequest.output_response('default', MimeType.TIFF)\n",
" ],\n",
" bbox=bbox,\n",
" size=size,\n",
" config=config,\n",
" data_folder=str(BASE_PATH_SINGLE_IMAGES / time_interval),\n",
"\n",
" )\n",
"\n",
"def download_function(slot, bbox, size):\n",
" # create a list of requests\n",
" list_of_requests = [get_true_color_request_day(slot, bbox, size)]\n",
" list_of_requests = [request.download_list[0] for request in list_of_requests]\n",
"\n",
" # download data chemba west with multiple threads\n",
" data = SentinelHubDownloadClient(config=config).download(list_of_requests, max_threads=15)\n",
" print(f' Image downloaded for ' +slot)\n",
" \n",
" time.sleep(.5)\n",
"\n",
"def merge_files(slot):\n",
" \n",
" # List the downloaded Tiffs in the different subfolders with pathlib (native library)\n",
" file_list = [f\"{x}/response.tiff\" for x in Path(BASE_PATH_SINGLE_IMAGES / slot).iterdir()]\n",
" \n",
" #print(file_list)\n",
"\n",
" folder_for_merged_tifs = str(BASE_PATH / 'merged_tif' / f\"{slot}.tif\")\n",
" folder_for_virtual_raster = str(BASE_PATH / 'merged_virtual' / f\"merged{slot}.vrt\")\n",
"\n",
" # Create a virtual raster\n",
" vrt_all = gdal.BuildVRT(folder_for_virtual_raster, file_list)\n",
" vrt_all = gdal.BuildVRT(folder_for_virtual_raster, file_list)\n",
"\n",
" # Convert to JPEG\n",
" gdal.Translate(folder_for_merged_tifs,folder_for_virtual_raster)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "848dc773-70d6-4ae6-b05c-d6ebfb41624d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Monthly time windows:\n",
"\n",
"2024-02-28\n",
"2024-02-29\n",
"2024-03-01\n",
"2024-03-02\n",
"2024-03-03\n",
"2024-03-04\n",
"2024-03-05\n"
]
}
],
"source": [
"days_needed = int(os.environ.get(\"DAYS\", days))\n",
"date_str = os.environ.get(\"DATE\")\n",
"if date_str:\n",
" # Parse de datumstring naar een datetime.date object\n",
" end = datetime.datetime.strptime(date_str, \"%Y-%m-%d\").date()\n",
"else:\n",
" # Gebruik de huidige datum als fallback\n",
" end = datetime.date.today() \n",
"\n",
"start = end - datetime.timedelta(days=days_needed - 1)\n",
"\n",
"slots = [(start + datetime.timedelta(days=i)).strftime('%Y-%m-%d') for i in range(days_needed)]\n",
"\n",
"print('Monthly time windows:\\n')\n",
"if len(slots) > 10:\n",
" for slot in slots[:3]:\n",
" print(slot)\n",
" print(\"...\")\n",
" for slot in slots[-3:]:\n",
" print(slot)\n",
"else:\n",
" for slot in slots:\n",
" print(slot)\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "f8ea846f-783b-4460-a951-7b522273555f",
"metadata": {},
"source": [
"#### Download images\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b9efd953-7dd9-4e10-aefe-b8215a166796",
"metadata": {},
"outputs": [],
"source": [
"if project == 'chemba':\n",
" chosen_area = [[34.946, -17.3516, 34.938, -17.2917], [34.883, -17.3516, 34.938, -17.2917]]\n",
"\n",
"if project == 'chemba_test_8b':\n",
" chosen_area = [[34.946, -17.3516, 34.938, -17.2917], [34.883, -17.3516, 34.938, -17.2917]]\n",
"\n",
"if project == 'xinavane':\n",
" chosen_area = [[32.6790, -25.0333, 32.7453, -25.0235], [32.6213, -25.0647, 32.6284, -25.0570]]"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "6c02d7de-cddf-4fc3-8d23-8431415d07b8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Image downloaded for 2024-02-28\n",
" Image downloaded for 2024-02-28\n",
" Image downloaded for 2024-02-29\n",
" Image downloaded for 2024-02-29\n",
" Image downloaded for 2024-03-01\n",
" Image downloaded for 2024-03-01\n",
" Image downloaded for 2024-03-02\n",
" Image downloaded for 2024-03-02\n"
]
},
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn [12], line 10\u001b[0m\n\u001b[0;32m 8\u001b[0m bbox \u001b[38;5;241m=\u001b[39m BBox(bbox\u001b[38;5;241m=\u001b[39marea, crs\u001b[38;5;241m=\u001b[39mCRS\u001b[38;5;241m.\u001b[39mWGS84)\n\u001b[0;32m 9\u001b[0m size \u001b[38;5;241m=\u001b[39m bbox_to_dimensions(bbox, resolution\u001b[38;5;241m=\u001b[39mresolution)\n\u001b[1;32m---> 10\u001b[0m \u001b[43mdownload_function\u001b[49m\u001b[43m(\u001b[49m\u001b[43mslot\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbbox\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msize\u001b[49m\u001b[43m)\u001b[49m\n",
"Cell \u001b[1;32mIn [10], line 67\u001b[0m, in \u001b[0;36mdownload_function\u001b[1;34m(slot, bbox, size)\u001b[0m\n\u001b[0;32m 64\u001b[0m list_of_requests \u001b[38;5;241m=\u001b[39m [request\u001b[38;5;241m.\u001b[39mdownload_list[\u001b[38;5;241m0\u001b[39m] \u001b[38;5;28;01mfor\u001b[39;00m request \u001b[38;5;129;01min\u001b[39;00m list_of_requests]\n\u001b[0;32m 66\u001b[0m \u001b[38;5;66;03m# download data chemba west with multiple threads\u001b[39;00m\n\u001b[1;32m---> 67\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[43mSentinelHubDownloadClient\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdownload\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlist_of_requests\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_threads\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m15\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 68\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m Image downloaded for \u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m+\u001b[39mslot)\n\u001b[0;32m 70\u001b[0m time\u001b[38;5;241m.\u001b[39msleep(\u001b[38;5;241m.5\u001b[39m)\n",
"File \u001b[1;32m~\\anaconda3\\lib\\site-packages\\sentinelhub\\download\\sentinelhub_client.py:51\u001b[0m, in \u001b[0;36mSentinelHubDownloadClient.download\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 49\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlock \u001b[38;5;241m=\u001b[39m Lock()\n\u001b[0;32m 50\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m---> 51\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mdownload(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 52\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[0;32m 53\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlock \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n",
"File \u001b[1;32m~\\anaconda3\\lib\\site-packages\\sentinelhub\\download\\client.py:76\u001b[0m, in \u001b[0;36mDownloadClient.download\u001b[1;34m(self, download_requests, max_threads, decode_data, show_progress)\u001b[0m\n\u001b[0;32m 72\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m ThreadPoolExecutor(max_workers\u001b[38;5;241m=\u001b[39mmax_threads) \u001b[38;5;28;01mas\u001b[39;00m executor:\n\u001b[0;32m 73\u001b[0m download_list \u001b[38;5;241m=\u001b[39m [\n\u001b[0;32m 74\u001b[0m executor\u001b[38;5;241m.\u001b[39msubmit(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_single_download, request, decode_data) \u001b[38;5;28;01mfor\u001b[39;00m request \u001b[38;5;129;01min\u001b[39;00m download_requests\n\u001b[0;32m 75\u001b[0m ]\n\u001b[1;32m---> 76\u001b[0m future_order \u001b[38;5;241m=\u001b[39m {future: i \u001b[38;5;28;01mfor\u001b[39;00m i, future \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(download_list)}\n\u001b[0;32m 78\u001b[0m data_list \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28;01mNone\u001b[39;00m] \u001b[38;5;241m*\u001b[39m \u001b[38;5;28mlen\u001b[39m(download_list)\n\u001b[0;32m 79\u001b[0m \u001b[38;5;66;03m# Consider using tqdm.contrib.concurrent.thread_map in the future\u001b[39;00m\n",
"File \u001b[1;32m~\\anaconda3\\lib\\concurrent\\futures\\_base.py:637\u001b[0m, in \u001b[0;36mExecutor.__exit__\u001b[1;34m(self, exc_type, exc_val, exc_tb)\u001b[0m\n\u001b[0;32m 636\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__exit__\u001b[39m(\u001b[38;5;28mself\u001b[39m, exc_type, exc_val, exc_tb):\n\u001b[1;32m--> 637\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mshutdown\u001b[49m\u001b[43m(\u001b[49m\u001b[43mwait\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m 638\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n",
"File \u001b[1;32m~\\anaconda3\\lib\\concurrent\\futures\\thread.py:235\u001b[0m, in \u001b[0;36mThreadPoolExecutor.shutdown\u001b[1;34m(self, wait, cancel_futures)\u001b[0m\n\u001b[0;32m 233\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m wait:\n\u001b[0;32m 234\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m t \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_threads:\n\u001b[1;32m--> 235\u001b[0m \u001b[43mt\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n",
"File \u001b[1;32m~\\anaconda3\\lib\\threading.py:1060\u001b[0m, in \u001b[0;36mThread.join\u001b[1;34m(self, timeout)\u001b[0m\n\u001b[0;32m 1057\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcannot join current thread\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 1059\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m-> 1060\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_wait_for_tstate_lock\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1061\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 1062\u001b[0m \u001b[38;5;66;03m# the behavior of a negative timeout isn't documented, but\u001b[39;00m\n\u001b[0;32m 1063\u001b[0m \u001b[38;5;66;03m# historically .join(timeout=x) for x<0 has acted as if timeout=0\u001b[39;00m\n\u001b[0;32m 1064\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_wait_for_tstate_lock(timeout\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mmax\u001b[39m(timeout, \u001b[38;5;241m0\u001b[39m))\n",
"File \u001b[1;32m~\\anaconda3\\lib\\threading.py:1080\u001b[0m, in \u001b[0;36mThread._wait_for_tstate_lock\u001b[1;34m(self, block, timeout)\u001b[0m\n\u001b[0;32m 1077\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[0;32m 1079\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m-> 1080\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43mlock\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43macquire\u001b[49m\u001b[43m(\u001b[49m\u001b[43mblock\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m:\n\u001b[0;32m 1081\u001b[0m lock\u001b[38;5;241m.\u001b[39mrelease()\n\u001b[0;32m 1082\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_stop()\n",
"\u001b[1;31mKeyboardInterrupt\u001b[0m: "
]
}
],
"source": [
"# Load areas outside the loop if they remain constant\n",
"bbox_area = json.dumps(chosen_area)\n",
"areas = json.loads(os.getenv('BBOX', bbox_area))\n",
"resolution = 3\n",
"\n",
"for slot in slots:\n",
" for area in areas:\n",
" bbox = BBox(bbox=area, crs=CRS.WGS84)\n",
" size = bbox_to_dimensions(bbox, resolution=resolution)\n",
" download_function(slot, bbox, size)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "68db3c15-6f94-432e-b315-c329e4251b21",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"for slot in slots:\n",
" merge_files(slot)"
]
},
{
"cell_type": "markdown",
"id": "4274d8e7-1ea3-46db-9528-069ede0b2132",
"metadata": {
"tags": []
},
"source": [
"#### Delete intermediate files\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb3fa856-a550-4899-844a-e69209bba3ad",
"metadata": {},
"outputs": [],
"source": [
"# List of folder names\n",
"\n",
"folders_to_empty = [BASE_PATH / 'merged_virtual', BASE_PATH_SINGLE_IMAGES]\n",
" \n",
"# Function to empty folders\n",
"\n",
"# Function to empty folders\n",
"def empty_folders(folders, run=True):\n",
" if not run:\n",
" print(\"Skipping empty_folders function.\")\n",
" return\n",
" \n",
" for folder in folders:\n",
" try:\n",
" for filename in os.listdir(folder):\n",
" file_path = os.path.join(folder, filename)\n",
" try:\n",
" if os.path.isfile(file_path):\n",
" os.unlink(file_path)\n",
" elif os.path.isdir(file_path):\n",
" shutil.rmtree(file_path)\n",
" except Exception as e:\n",
" print(f\"Error: {e}\")\n",
" print(f\"Emptied folder: {folder}\")\n",
" except OSError as e:\n",
" print(f\"Error: {e}\")\n",
"\n",
"# Call the function to empty folders only if the 'run' parameter is set to True\n",
"empty_folders(folders_to_empty, run=empty_folder_question)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}