Skip to content

Commit

Permalink
refactor: move span to custom widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
dfguerrerom committed Apr 21, 2023
1 parent e30f1a2 commit ec719ac
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 143 deletions.
171 changes: 62 additions & 109 deletions component/tiles/download_tile.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import logging
import os
import time

import ee
import ipyvuetify as v
import sepal_ui.scripts.utils as su
import sepal_ui.sepalwidgets as sw

import component.parameter as param
import component.widget as cw
from component.message import cm
from component.scripts.utils import GDrive

FAILED = "FAILED"
CANCEL_REQUESTED = "CANCEL_REQUESTED"
CANCELLED = "CANCELLED"
COMPLETED = "COMPLETED"
UNKNOWN = "UNKNOWN"

import component.scripts.google_handler as goog
from component.scripts.taks_controller import TaskController
from component.widget.count_span import CountSpan
from component.widget.count_span import DownloadAlert


logging.getLogger("googleapiclient.discovery_cache").setLevel(logging.ERROR)
Expand Down Expand Up @@ -55,8 +47,20 @@ def __init__(self, *args, **kwargs):

super().__init__(*args, **kwargs)

self.alert = cw.Alert()
self.result_alert = cw.Alert()
# Define HTML spans. These will be added to the alert view after
# some initial messages are displayed

self.status_span = sw.Html(children=[])
self.success_span = CountSpan("success", color="success")
self.error_span = CountSpan("error", color="error", with_total=False)
self.running_span = CountSpan("running", color="warning", with_total=False)

self.alert = DownloadAlert(
self.status_span,
self.success_span,
self.error_span,
self.running_span,
)

self.w_overwrite = v.Switch(
v_model=True, label="Overwrite SEPAL images", small=True, class_="mr-4"
Expand All @@ -68,7 +72,10 @@ def __init__(self, *args, **kwargs):

self.w_selection = sw.FileInput(folder=str(param.RAW_DIR), extentions=[".txt"])

self.btn = sw.Btn(text="Download", icon="mdi-download")
self.btn = sw.Btn(text="Download", icon="mdi-download", small=True)
self.stop_btn = sw.Btn(
text="Cancel", icon="mdi-cancel", small=True, class_="ml-2"
)

self.children = [
self.w_selection,
Expand All @@ -79,9 +86,24 @@ def __init__(self, *args, **kwargs):
self.w_remove,
],
),
self.btn,
sw.Flex(
class_="d-flex",
children=[
self.btn,
self.stop_btn,
],
),
self.alert,
self.result_alert,
sw.Layout(
class_="d-block",
# create a space between elements
justify_content="space-between",
children=[
self.success_span,
self.error_span,
self.running_span,
],
),
]

self.btn.on_event("click", self.download_to_sepal)
Expand All @@ -91,99 +113,30 @@ def download_to_sepal(self, *args):
"""
Download images from Google Drive to SEPAL.
It will loop over the task file and download the images
It will loop over the task file and download the images
if they have a status of COMPLETED.
"""
task_file = self.w_selection.v_model
alerts = [self.alert, self.result_alert]
overwrite = self.w_overwrite.v_model
rmdrive = self.w_remove.v_model
self.counter = 0

state_alert = alerts[0]
result_alert = alerts[1]

state_alert.reset()
result_alert.reset()

out_path = os.path.split(task_file)[0]

ee.Initialize()

to_remove_states = {CANCEL_REQUESTED, CANCELLED, FAILED, COMPLETED, UNKNOWN}

tasks = []
with open(task_file, "r") as tf:
for line in tf:
tasks.append([x.strip() for x in line.split(",")])

drive_handler = GDrive()

def remove_from_list(task_to_remove):
with open(task_file, "r") as f:
lines = f.readlines()

# Overwrite the file without the task to remove
with open(task_file, "w") as f:
for line in lines:
if task_to_remove not in line:
f.write(line)

def check_for_not_completed(task):
state = ee.data.getTaskStatus(task[0])[0]["state"]
file_name = task[1]

if state in to_remove_states:
if state == COMPLETED:
output_file = os.path.join(out_path, f"{file_name}.tif")

self.counter += 1
# result_alert.update_progress(self.counter, total=len(tasks))

if not overwrite:
if not os.path.exists(output_file):
result_alert.append_msg(f"Downloading: {file_name}")
drive_handler.download_file(
f"{file_name}.tif", output_file, items_to_search
)
else:
result_alert.append_msg(f"Skipping: {file_name}")
else:
result_alert.append_msg(f"Overwriting: {file_name}")
drive_handler.download_file(
f"{file_name}.tif", output_file, items_to_search
)
if rmdrive:
result_alert.append_msg(f"Removing from drive: {file_name}")
remove_from_list(task[0])
drive_handler.delete_file(items_to_search, f"{file_name}.tif")
elif state in [UNKNOWN, FAILED]:
result_alert.add_msg(
"There was an error task, state", type_="error"
)
return False

return True

def download(tasks):
while tasks:
state_alert.add_msg("Retrieving tasks status...", type_="info")
global items_to_search
items_to_search = drive_handler.get_items()
tasks = list(filter(check_for_not_completed, tasks))
if tasks:
state_alert.add_msg("Waiting...", type_="info")
time.sleep(45)

if tasks:
download(tasks)
state_alert.reset()
result_alert.append_msg(
"All the images were downloaded succesfully", type_="success"
)
else:
state_alert.reset()
result_alert.append_msg(
"All the images were already downloaded.", type_="warning"
)
remove_from_drive = self.w_remove.v_model

if not task_file:
raise ValueError("Please select a task file")

downloader = goog.ImageDownloader(
task_file,
overwrite,
remove_from_drive,
self.alert,
self.status_span,
self.success_span,
self.error_span,
self.running_span,
)

task_controller = TaskController(
self.btn, self.stop_btn, downloader.download_to_sepal
)

task_controller.start_task()
35 changes: 1 addition & 34 deletions component/tiles/process_tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from component.message import cm
from component.scripts import run_pysmm
from component.scripts.resize import rt
from component.widget.count_span import CountSpan

__all__ = ["ProcessTile"]

Expand Down Expand Up @@ -183,40 +184,6 @@ def run_process(self, widget, event, data):
)


class CountSpan(sw.Html):
"""HTML span component to control the number of images or chips that have been processed"""

value = Int(0).tag(sync=True)
total = Int(0).tag(sync=True)

def __init__(self, name, *args, **kwargs):
super().__init__(*args, **kwargs)

self.tag = "span"
self.name = name + ": "
self.children = self.get_value()

def get_value(self):
"""Get the value of the span"""
return [self.name, f"{self.value}/{self.total}"]

def update(self):
"""Update the value of the span"""
self.value += 1
self.children = self.get_value()

def set_total(self, total):
"""Set the total value of the span"""
self.total = total
self.children = self.get_value()

def reset(self):
"""Reset the value of the span"""
self.value = -1
self.total = 0
self.update()


class StepperContent(v.StepperContent):
def __init__(self, key, title, content, *args, **kwargs):
self.key = key
Expand Down

0 comments on commit ec719ac

Please sign in to comment.