From 3f57d6ad75e0b3e41efb80b1aaf4e118ead28c4a Mon Sep 17 00:00:00 2001 From: samapriya Date: Wed, 8 Jul 2020 08:39:07 -0400 Subject: [PATCH] updated v0.4.1 - Fixed selenium parser issue [Issue 19](https://github.com/samapriya/geeup/issues/19) - Implemented Cloud API fix for table uploads - Improved Cloud API fix for Imagery upload with improved manifest handling - Improvement and code cleanup --- README.md | 8 +- dist/geeup-0.4.0-py3-none-any.whl | Bin 29819 -> 0 bytes dist/geeup-0.4.0.tar.gz | Bin 21446 -> 0 bytes dist/geeup-0.4.1-py3-none-any.whl | Bin 0 -> 29650 bytes dist/geeup-0.4.1.tar.gz | Bin 0 -> 21454 bytes geeup/__init__.py | 2 +- geeup/batch_uploader.py | 326 +++++++++++++++++------------- geeup/sel_setup.py | 17 +- geeup/sel_tuploader.py | 197 ++++++++++-------- setup.py | 2 +- 10 files changed, 319 insertions(+), 233 deletions(-) delete mode 100644 dist/geeup-0.4.0-py3-none-any.whl delete mode 100644 dist/geeup-0.4.0.tar.gz create mode 100644 dist/geeup-0.4.1-py3-none-any.whl create mode 100644 dist/geeup-0.4.1.tar.gz diff --git a/README.md b/README.md index 330acd0..cb1961f 100644 --- a/README.md +++ b/README.md @@ -240,10 +240,16 @@ optional arguments: ``` # Changelog +### v0.4.1 +- Fixed selenium parser issue [Issue 19](https://github.com/samapriya/geeup/issues/19) +- Implemented Cloud API fix for table uploads +- Improved Cloud API fix for Imagery upload with improved manifest handling +- Improvement and code cleanup + ### v0.4.0 - Updated earthengine API library requirements to 0.1.222 - Added version check tool for auto version check with PyPI - + ### v0.3.7 - Revisions to account for changes to API and client library 0.1.215 - Now checks vertex count for each shapefile and logs warning with those exceeding million vertices while zipping. diff --git a/dist/geeup-0.4.0-py3-none-any.whl b/dist/geeup-0.4.0-py3-none-any.whl deleted file mode 100644 index 1e2fbab812df24251f4bdf421bb4c405b306be60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29819 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 diff --git a/dist/geeup-0.4.1-py3-none-any.whl b/dist/geeup-0.4.1-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..3baac582bdb27dc925d0f96c9e60cc3b4d0f1bb8 GIT binary patch literal 29650 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 literal 0 HcmV?d00001 diff --git a/geeup/__init__.py b/geeup/__init__.py index ed38971..1a54590 100644 --- a/geeup/__init__.py +++ b/geeup/__init__.py @@ -2,4 +2,4 @@ __author__ = 'Samapriya Roy' __email__ = 'samapriya.roy@gmail.com' -__version__ = '0.4.0' +__version__ = '0.4.1' diff --git a/geeup/batch_uploader.py b/geeup/batch_uploader.py index 49694e1..9a0a155 100644 --- a/geeup/batch_uploader.py +++ b/geeup/batch_uploader.py @@ -1,4 +1,5 @@ from __future__ import print_function + __copyright__ = """ Copyright 2016 Lukasz Tracewski @@ -37,12 +38,12 @@ """ __license__ = "Apache 2.0" -''' +""" Modifications to file: - Uses selenium based upload instead of simple login - Removed multipart upload - Uses polling -''' +""" import ast import csv @@ -56,37 +57,38 @@ import requests import ast import ee -import requests import pandas as pd import subprocess import retrying -from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver import Firefox from selenium.webdriver.firefox.options import Options -from selenium.webdriver.common.keys import Keys -from selenium.common.exceptions import TimeoutException -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC -from selenium.webdriver.common.by import By from requests_toolbelt import MultipartEncoder from .metadata_loader import load_metadata_from_csv, validate_metadata_from_csv + os.chdir(os.path.dirname(os.path.realpath(__file__))) -lp=os.path.dirname(os.path.realpath(__file__)) +lp = os.path.dirname(os.path.realpath(__file__)) sys.path.append(lp) ee.Initialize() -slist=[] +slist = [] + -def upload(user, source_path, destination_path, metadata_path=None, nodata_value=None, bucket_name=None): - submitted_tasks_id = {} +def upload( + user, + source_path, + destination_path, + metadata_path=None, + nodata_value=None, + bucket_name=None, +): __verify_path_for_upload(destination_path) - path = os.path.join(os.path.expanduser(source_path), '*.tif') + path = os.path.join(os.path.expanduser(source_path), "*.tif") all_images_paths = glob.glob(path) if len(all_images_paths) == 0: - print('%s does not contain any tif images.', path) + print("%s does not contain any tif images.", path) sys.exit(1) metadata = load_metadata_from_csv(metadata_path) if metadata_path else None @@ -99,79 +101,122 @@ def upload(user, source_path, destination_path, metadata_path=None, nodata_value __create_image_collection(destination_path) - images_for_upload_path = __find_remaining_assets_for_upload(all_images_paths, destination_path) + images_for_upload_path = __find_remaining_assets_for_upload( + all_images_paths, destination_path + ) no_images = len(images_for_upload_path) if no_images == 0: - print('No images found that match %s. Exiting...', path) + print("No images found that match %s. Exiting...", path) sys.exit(1) - failed_asset_writer = FailedAssetsWriter() - for current_image_no, image_path in enumerate(images_for_upload_path): - print('Processing image '+str(current_image_no+1)+' out of '+str(no_images)+': '+str(image_path)) + print( + "Processing image " + + str(current_image_no + 1) + + " out of " + + str(no_images) + + ": " + + str(image_path) + ) filename = __get_filename_from_path(path=image_path) - asset_full_path = destination_path + '/' + filename + destination_path = ee.data.getAsset(destination_path + "/")["name"] + asset_full_path = destination_path + "/" + filename if metadata and not filename in metadata: - print("No metadata exists for image "+str(filename)+" : it will not be ingested") - failed_asset_writer.writerow([filename, 0, 'Missing metadata']) + print( + "No metadata exists for image " + + str(filename) + + " : it will not be ingested" + ) continue properties = metadata[filename] if metadata else None try: if user is not None: - gsid = __upload_file_gee(session=google_session, - file_path=image_path) + gsid = __upload_file_gee(session=google_session, file_path=image_path) else: gsid = __upload_file_gcs(storage_client, bucket_name, image_path) - df=pd.read_csv(metadata_path) - dd=(df.applymap(type) == str).all(0) + df = pd.read_csv(metadata_path) + dd = (df.applymap(type) == str).all(0) for ind, val in dd.iteritems(): - if val==True: + if val == True: slist.append(ind) - intcol= list(df.select_dtypes(include=['int64']).columns) - floatcol = list(df.select_dtypes(include=['float64']).columns) - with open(metadata_path, 'r') as f: - reader = csv.DictReader(f,delimiter=",") + intcol = list(df.select_dtypes(include=["int64"]).columns) + floatcol = list(df.select_dtypes(include=["float64"]).columns) + with open(metadata_path, "r") as f: + reader = csv.DictReader(f, delimiter=",") for i, line in enumerate(reader): - if line["id_no"]==os.path.basename(image_path).split('.')[0]: - j={} + if line["id_no"] == os.path.basename(image_path).split(".")[0]: + j = {} for integer in intcol: - value=integer - j[value]=int(line[integer]) + value = integer + j[value] = int(line[integer]) for s in slist: - value=s - j[value]=str(line[s]) + value = s + j[value] = str(line[s]) for f in floatcol: - value=f - j[value]=float(line[f]) + value = f + j[value] = float(line[f]) # j['id']=destination_path+'/'+line["id_no"] # j['tilesets'][0]['sources'][0]['primaryPath']=gsid + if "system:time_start" in j: + start = j["system:time_start"] + start = int(str(start)[:10]) + j.pop("system:time_start") + elif "system:time_start" not in j: + start = None + if "system:time_end" in j: + end = j["system:time_end"] + end = int(str(end)[:10]) + j.pop("system:time_end") + elif "system:time_end" not in j: + end = None json_data = json.dumps(j) - if nodata_value is not None: - main_payload={"id": asset_full_path,"tilesets": [{"sources": [{"primaryPath": gsid,"additionalPaths": []}]}],"properties": j,"missingData":{"value":nodata_value}} + main_payload = { + "name": asset_full_path, + "tilesets": [{"sources": [{"uris": gsid}]}], + "start_time": {"seconds": ""}, + "end_time": {"seconds": ""}, + "properties": j, + "missing_data": {"values": [nodata_value]}, + } + if start is not None: + main_payload["start_time"]["seconds"] = start + else: + main_payload.pop("start_time") + if end is not None: + main_payload["end_time"]["seconds"] = end else: - main_payload={"id": asset_full_path,"tilesets": [{"sources": [{"primaryPath": gsid,"additionalPaths": []}]}],"properties": j} - with open(os.path.join(lp,'data.json'), 'w') as outfile: + main_payload.pop("end_time") + if nodata_value is None: + main_payload.pop("missing_data") + # print(json.dumps(main_payload)) + with open(os.path.join(lp, "data.json"), "w") as outfile: json.dump(main_payload, outfile) - subprocess.call("earthengine --no-use_cloud_api upload image --manifest "+'"'+os.path.join(lp,'data.json')+'"',shell=True) + subprocess.call( + "earthengine upload image --manifest " + + '"' + + os.path.join(lp, "data.json") + + '"', + shell=True, + stdout=subprocess.PIPE, + ) except Exception as e: print(e) - print('Upload of '+str(filename)+' has failed.') - failed_asset_writer.writerow([filename, 0, str(e)]) - - __check_for_failed_tasks_and_report(tasks=submitted_tasks_id, writer=failed_asset_writer) - failed_asset_writer.close() + print("Upload of " + str(filename) + " has failed.") def __verify_path_for_upload(path): - folder = path[:path.rfind('/')] + folder = path[: path.rfind("/")] response = ee.data.getInfo(folder) if not response: - print(str(path)+' is not a valid destination. Make sure full path is provided e.g. users/user/nameofcollection ' - 'or projects/myproject/myfolder/newcollection and that you have write access there.') + print( + str(path) + + " is not a valid destination. Make sure full path is provided e.g. users/user/nameofcollection " + "or projects/myproject/myfolder/newcollection and that you have write access there." + ) sys.exit(1) @@ -182,12 +227,22 @@ def __find_remaining_assets_for_upload(path_to_local_assets, path_remote): if len(remote_assets) > 0: assets_left_for_upload = set(local_assets) - set(remote_assets) if len(assets_left_for_upload) == 0: - print('Collection already exists and contains all assets provided for upload. Exiting ...') + print( + "Collection already exists and contains all assets provided for upload. Exiting ..." + ) sys.exit(1) - print('Collection already exists. '+str(len(assets_left_for_upload))+' assets left for upload to '+str(path_remote)) - assets_left_for_upload_full_path = [path for path in path_to_local_assets - if __get_filename_from_path(path) in assets_left_for_upload] + print( + "Collection already exists. " + + str(len(assets_left_for_upload)) + + " assets left for upload to " + + str(path_remote) + ) + assets_left_for_upload_full_path = [ + path + for path in path_to_local_assets + if __get_filename_from_path(path) in assets_left_for_upload + ] return assets_left_for_upload_full_path return path_to_local_assets @@ -197,7 +252,12 @@ def retry_if_ee_error(exception): return isinstance(exception, ee.EEException) -@retrying.retry(retry_on_exception=retry_if_ee_error, wait_exponential_multiplier=1000, wait_exponential_max=4000, stop_max_attempt_number=3) +@retrying.retry( + retry_on_exception=retry_if_ee_error, + wait_exponential_multiplier=1000, + wait_exponential_max=4000, + stop_max_attempt_number=3, +) def __start_ingestion_task(asset_request): task_id = ee.data.newTaskId(1)[0] _ = ee.data.startIngestion(task_id, asset_request) @@ -207,21 +267,26 @@ def __start_ingestion_task(asset_request): def __validate_metadata(path_for_upload, metadata_path): validation_result = validate_metadata_from_csv(metadata_path) keys_in_metadata = {result.keys for result in validation_result} - images_paths = glob.glob(os.path.join(path_for_upload, '*.tif*')) + images_paths = glob.glob(os.path.join(path_for_upload, "*.tif*")) keys_in_data = {__get_filename_from_path(path) for path in images_paths} missing_keys = keys_in_data - keys_in_metadata if missing_keys: - print(str(len(missing_keys)+' images does not have a corresponding key in metadata')) - print('\n'.join(e for e in missing_keys)) + print( + str( + len(missing_keys) + + " images does not have a corresponding key in metadata" + ) + ) + print("\n".join(e for e in missing_keys)) else: - print('All images have metadata available') + print("All images have metadata available") if not validation_result.success: print('Validation finished with errors. Type "y" to continue, default NO: ') choice = input().lower() - if choice not in ['y', 'yes']: - print('Application will terminate') + if choice not in ["y", "yes"]: + print("Application will terminate") exit(1) @@ -229,68 +294,89 @@ def __extract_metadata_for_image(filename, metadata): if filename in metadata: return metadata[filename] else: - print('Metadata for '+str(filename)+' not found') + print("Metadata for " + str(filename) + " not found") return None def __get_google_auth_session(username, password): ee.Initialize() options = Options() - options.add_argument('-headless') - uname=str(username) - passw=str(password) - if os.name=="nt": - driver = Firefox(executable_path=os.path.join(lp,"geckodriver.exe"),firefox_options=options) + options.add_argument("-headless") + uname = str(username) + passw = str(password) + if os.name == "nt": + driver = Firefox( + executable_path=os.path.join(lp, "geckodriver.exe"), firefox_options=options + ) else: - driver = Firefox(executable_path=os.path.join(lp,"geckodriver"),firefox_options=options) + driver = Firefox( + executable_path=os.path.join(lp, "geckodriver"), firefox_options=options + ) try: # Using stackoverflow for third-party login & redirect - driver.get('https://stackoverflow.com/users/signup?ssrc=head&returnurl=%2fusers%2fstory%2fcurrent%27') + driver.get( + "https://stackoverflow.com/users/signup?ssrc=head&returnurl=%2fusers%2fstory%2fcurrent%27" + ) time.sleep(5) driver.find_element_by_xpath('//*[@id="openid-buttons"]/button[1]').click() time.sleep(5) driver.find_element_by_xpath('//input[@type="email"]').send_keys(uname) - driver.find_element_by_xpath("//div[@id='identifierNext']/span/span").click() + driver.find_element_by_xpath("//div[@id='identifierNext']").click() time.sleep(5) driver.find_element_by_xpath('//input[@type="password"]').send_keys(passw) driver.find_element_by_xpath('//*[@id="passwordNext"]').click() time.sleep(5) - driver.get('https://code.earthengine.google.com') + driver.get("https://code.earthengine.google.com") time.sleep(8) except Exception as e: print(e) driver.close() - sys.exit('Failed to setup & use selenium') + sys.exit("Failed to setup & use selenium") cookies = driver.get_cookies() session = requests.Session() for cookie in cookies: - session.cookies.set(cookie['name'], cookie['value']) + session.cookies.set(cookie["name"], cookie["value"]) driver.close() return session + def __get_upload_url(session): - r=session.get("https://code.earthengine.google.com/assets/upload/geturl") + r = session.get("https://code.earthengine.google.com/assets/upload/geturl") try: d = ast.literal_eval(r.text) - return d['url'] + return d["url"] except Exception as e: print(e) -@retrying.retry(retry_on_exception=retry_if_ee_error, wait_exponential_multiplier=1000, wait_exponential_max=4000, stop_max_attempt_number=3) + +@retrying.retry( + retry_on_exception=retry_if_ee_error, + wait_exponential_multiplier=1000, + wait_exponential_max=4000, + stop_max_attempt_number=3, +) def __upload_file_gee(session, file_path): - with open(file_path, 'rb') as f: - file_name=os.path.basename(file_path) + with open(file_path, "rb") as f: + file_name = os.path.basename(file_path) upload_url = __get_upload_url(session) - files = {'file': f} - m=MultipartEncoder( fields={'image_file':(file_name, f)}) + files = {"file": f} + m = MultipartEncoder(fields={"image_file": (file_name, f)}) try: - resp = session.post(upload_url, data=m, headers={'Content-Type': m.content_type}) + resp = session.post( + upload_url, data=m, headers={"Content-Type": m.content_type} + ) gsid = resp.json()[0] return gsid except Exception as e: print(e) -@retrying.retry(retry_on_exception=retry_if_ee_error, wait_exponential_multiplier=1000, wait_exponential_max=4000, stop_max_attempt_number=3) + +@retrying.retry( + retry_on_exception=retry_if_ee_error, + wait_exponential_multiplier=1000, + wait_exponential_max=4000, + stop_max_attempt_number=3, +) def __upload_file_gcs(storage_client, bucket_name, image_path): bucket = storage_client.get_bucket(bucket_name) blob_name = __get_filename_from_path(path=image_path) @@ -298,48 +384,28 @@ def __upload_file_gcs(storage_client, bucket_name, image_path): blob.upload_from_filename(image_path) - url = 'gs://' + bucket_name + '/' + blob_name + url = "gs://" + bucket_name + "/" + blob_name return url -def __periodic_check(current_image, period, tasks, writer): - if (current_image + 1) % period == 0: - print('Periodic check') - __check_for_failed_tasks_and_report(tasks=tasks, writer=writer) - # Time to check how many tasks are running! - __wait_for_tasks_to_complete(waiting_time=10, no_allowed_tasks_running=20) - - -def __check_for_failed_tasks_and_report(tasks, writer): - if len(tasks) == 0: - return - - statuses = ee.data.getTaskStatus(tasks.keys()) - - for status in statuses: - if status['state'] == 'FAILED': - task_id = status['id'] - filename = tasks[task_id] - error_message = status['error_message'] - writer.writerow([filename, task_id, error_message]) - print('Ingestion of image '+str(filename)+' has failed with message '+str(error_message)) - - tasks.clear() - def __get_filename_from_path(path): return os.path.splitext(os.path.basename(os.path.normpath(path)))[0] def __get_number_of_running_tasks(): - return len([task for task in ee.data.getTaskList() if task['state'] == 'RUNNING']) + return len([task for task in ee.data.getTaskList() if task["state"] == "RUNNING"]) def __wait_for_tasks_to_complete(waiting_time, no_allowed_tasks_running): tasks_running = __get_number_of_running_tasks() while tasks_running > no_allowed_tasks_running: - logging.info('Number of running tasks is %d. Sleeping for %d s until it goes down to %d', - tasks_running, waiting_time, no_allowed_tasks_running) + logging.info( + "Number of running tasks is %d. Sleeping for %d s until it goes down to %d", + tasks_running, + waiting_time, + no_allowed_tasks_running, + ) time.sleep(waiting_time) tasks_running = __get_number_of_running_tasks() @@ -350,35 +416,15 @@ def __collection_exist(path): def __create_image_collection(full_path_to_collection): if __collection_exist(full_path_to_collection): - print("Collection "+str(full_path_to_collection)+" already exists") + print("Collection " + str(full_path_to_collection) + " already exists") else: - ee.data.createAsset({'type': ee.data.ASSET_TYPE_IMAGE_COLL}, full_path_to_collection) - print('New collection '+str(full_path_to_collection)+' created') + ee.data.createAsset( + {"type": ee.data.ASSET_TYPE_IMAGE_COLL}, full_path_to_collection + ) + print("New collection " + str(full_path_to_collection) + " created") def __get_asset_names_from_collection(collection_path): - assets_list = ee.data.getList(params={'id': collection_path}) - assets_names = [os.path.basename(asset['id']) for asset in assets_list] + assets_list = ee.data.getList(params={"id": collection_path}) + assets_names = [os.path.basename(asset["id"]) for asset in assets_list] return assets_names - - -class FailedAssetsWriter(object): - - def __init__(self): - self.initialized = False - - def writerow(self, row): - if not self.initialized: - if sys.version_info > (3, 0): - self.failed_upload_file = open('failed_upload.csv', 'w') - else: - self.failed_upload_file = open('failed_upload.csv', 'wb') - self.failed_upload_writer = csv.writer(self.failed_upload_file) - self.failed_upload_writer.writerow(['filename', 'task_id', 'error_msg']) - self.initialized = True - self.failed_upload_writer.writerow(row) - - def close(self): - if self.initialized: - self.failed_upload_file.close() - self.initialized = False diff --git a/geeup/sel_setup.py b/geeup/sel_setup.py index 8648ce0..d9e82ee 100644 --- a/geeup/sel_setup.py +++ b/geeup/sel_setup.py @@ -33,7 +33,7 @@ def authenticate(): driver.find_element_by_xpath('//*[@id="openid-buttons"]/button[1]').click() time.sleep(5) driver.find_element_by_xpath('//input[@type="email"]').send_keys(uname) - driver.find_element_by_xpath("//div[@id='identifierNext']/span/span").click() + driver.find_element_by_xpath("//div[@id='identifierNext']").click() time.sleep(5) driver.find_element_by_xpath('//input[@type="password"]').send_keys(passw) driver.find_element_by_xpath('//*[@id="passwordNext"]').click() @@ -49,11 +49,14 @@ def authenticate(): for cookie in cookies: s.cookies.set(cookie['name'], cookie['value']) r=s.get("https://code.earthengine.google.com/assets/upload/geturl") - try: - d = ast.literal_eval(r.text) - if d['url']: - print('\n'+'Selenium Setup complete with Google Profile') - except Exception as e: - print(e) + if r.status_code ==200: + try: + d = ast.literal_eval(r.text) + if d['url']: + print('\n'+'Selenium Setup complete with Google Profile') + except Exception as e: + print(e) + else: + print('Authentication failed for GEE account') driver.close() authenticate() diff --git a/geeup/sel_tuploader.py b/geeup/sel_tuploader.py index ee0228c..7e76c6b 100644 --- a/geeup/sel_tuploader.py +++ b/geeup/sel_tuploader.py @@ -22,125 +22,156 @@ import ee import sys import json -from selenium import webdriver from selenium.webdriver import Firefox from selenium.webdriver.firefox.options import Options -from selenium.webdriver.common.keys import Keys -from selenium.common.exceptions import TimeoutException -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC -from selenium.webdriver.common.by import By from requests_toolbelt import MultipartEncoder -import time,os,getpass,subprocess -lp=os.path.dirname(os.path.realpath(__file__)) +import time +import os +import getpass +import subprocess + +lp = os.path.dirname(os.path.realpath(__file__)) sys.path.append(lp) ee.Initialize() -def table_exist(path): - return True if ee.data.getInfo(path) else False - -def folder_exist(path): - if ee.data.getInfo(path) and ee.data.getInfo(path)['type']=='FOLDER': - return True - else: - return False - +table_exists = [] +gee_table_exists = [] -def create_image_collection(full_path_to_collection): - if folder_exist(full_path_to_collection): - print("Folder "+str(full_path_to_collection)+" already exists") - else: - ee.data.createAsset({'type': ee.data.ASSET_TYPE_FOLDER}, full_path_to_collection) - print('New folder '+str(full_path_to_collection)+' created') -table_exists=[] -gee_table_exists=[] -def seltabup(dirc,uname,destination): +def seltabup(dirc, uname, destination): ee.Initialize() for (root, directories, files) in os.walk(dirc): for filename in files: - if filename.endswith('.zip'): - table_exists.append(filename.split('.zip')[0]) - if ee.data.getInfo(destination) and ee.data.getInfo(destination)['type']=='FOLDER': - children = ee.data.getList({'id': destination}) - for child in children: - gee_table_exists.append(child['id'].split('/')[-1]) - diff_set=set(table_exists)-set(gee_table_exists) - if len(diff_set)!=0: + if filename.endswith(".zip"): + table_exists.append(filename.split(".zip")[0]) + try: + destination_info = ee.data.getAsset(destination + "/") + full_path_to_collection = destination_info["name"] + if destination_info["name"] and destination_info["type"].lower() == "folder": + print("Folder exists: {}".format(destination_info["id"])) + children = ee.data.listAssets({"parent": full_path_to_collection}) + for child in children["assets"]: + gee_table_exists.append(child["id"].split("/")[-1]) + except Exception as e: + full_path_to_collection = ( + destination.rsplit("/", 1)[0] + "/" + destination.split("/")[-1] + ) + print("Creating a folder {}".format(full_path_to_collection)) + try: + ee.data.createAsset( + {"type": ee.data.ASSET_TYPE_FOLDER_CLOUD}, full_path_to_collection + ) + except: + ee.data.createAsset( + {"type": ee.data.ASSET_TYPE_FOLDER}, full_path_to_collection + ) + diff_set = set(table_exists) - set(gee_table_exists) + if len(diff_set) != 0: options = Options() - options.add_argument('-headless') - passw=getpass.getpass() - create_image_collection(destination) - if os.name=="nt": - driver = Firefox(executable_path=os.path.join(lp,"geckodriver.exe"),firefox_options=options) + options.add_argument("-headless") + passw = getpass.getpass() + if os.name == "nt": + driver = Firefox( + executable_path=os.path.join(lp, "geckodriver.exe"), + firefox_options=options, + ) else: - driver = Firefox(executable_path=os.path.join(lp,"geckodriver"),firefox_options=options) + driver = Firefox( + executable_path=os.path.join(lp, "geckodriver"), firefox_options=options + ) try: # Using stackoverflow for third-party login & redirect - driver.get('https://stackoverflow.com/users/signup?ssrc=head&returnurl=%2fusers%2fstory%2fcurrent%27') + driver.get( + "https://stackoverflow.com/users/signup?ssrc=head&returnurl=%2fusers%2fstory%2fcurrent%27" + ) time.sleep(5) driver.find_element_by_xpath('//*[@id="openid-buttons"]/button[1]').click() time.sleep(5) driver.find_element_by_xpath('//input[@type="email"]').send_keys(uname) - driver.find_element_by_xpath("//div[@id='identifierNext']/span/span").click() + driver.find_element_by_xpath("//div[@id='identifierNext']").click() time.sleep(5) driver.find_element_by_xpath('//input[@type="password"]').send_keys(passw) driver.find_element_by_xpath('//*[@id="passwordNext"]').click() time.sleep(5) - driver.get('https://code.earthengine.google.com') + driver.get("https://code.earthengine.google.com") time.sleep(8) except Exception as e: print(e) driver.close() - sys.exit('Failed to setup & use selenium') + sys.exit("Failed to setup & use selenium") cookies = driver.get_cookies() s = requests.Session() for cookie in cookies: - s.cookies.set(cookie['name'], cookie['value']) + s.cookies.set(cookie["name"], cookie["value"]) driver.close() - try: - i=1 - file_count = len(diff_set) - for item in list(diff_set): - full_path_to_table=os.path.join(root,item+'.zip') - file_name=item+'.zip' - if table_exist(full_path_to_table)==True: - print('Table already exists Skipping: '+str(fpath)) - i=i+1 - else: - r=s.get("https://code.earthengine.google.com/assets/upload/geturl") + auth_check = s.get("https://code.earthengine.google.com") + if auth_check.status_code == 200: + try: + i = 1 + file_count = len(diff_set) + for item in list(diff_set): + full_path_to_table = os.path.join(root, item + ".zip") + file_name = item + ".zip" + asset_full_path = full_path_to_collection + "/" + item.split(".")[0] + r = s.get( + "https://code.earthengine.google.com/assets/upload/geturl" + ) d = ast.literal_eval(r.text) - upload_url = d['url'] - with open(full_path_to_table, 'rb') as f: - upload_url = d['url'] + upload_url = d["url"] + with open(full_path_to_table, "rb") as f: + upload_url = d["url"] try: - m=MultipartEncoder( fields={'zip_file':(file_name, f)}) - resp = s.post(upload_url, data=m, headers={'Content-Type': m.content_type}) + m = MultipartEncoder(fields={"zip_file": (file_name, f)}) + resp = s.post( + upload_url, + data=m, + headers={"Content-Type": m.content_type}, + ) gsid = resp.json()[0] - asset_full_path=destination+'/'+item.split('.')[0] - if asset_full_path.startswith('projects'): - asset_full_path='projects/earthengine-legacy/assets/'+asset_full_path - elif asset_full_path.startswith('users'): - asset_full_path='projects/earthengine-legacy/assets/'+asset_full_path - main_payload= {"name": asset_full_path, + asset_full_path = ( + full_path_to_collection + "/" + item.split(".")[0] + ) + main_payload = { + "name": asset_full_path, "sources": [ - { - "charset": "UTF-8", - "maxErrorMeters": 1, - "maxVertices": 1000000, - "uris": [gsid] - } - ] + { + "charset": "UTF-8", + "maxErrorMeters": 1, + "maxVertices": 1000000, + "uris": [gsid], + } + ], } - with open(os.path.join(lp,'data.json'), 'w') as outfile: + with open(os.path.join(lp, "data.json"), "w") as outfile: json.dump(main_payload, outfile) - output=subprocess.check_output("earthengine upload table --manifest "+'"'+os.path.join(lp,'data.json')+'"',shell=True) - print('Ingesting '+str(i)+' of '+str(file_count)+' '+str(os.path.basename(asset_full_path))+' Task Id: '+output.decode('ascii').strip().split(' ')[-1]) + output = subprocess.check_output( + "earthengine upload table --manifest " + + '"' + + os.path.join(lp, "data.json") + + '"', + shell=True, + ) + print( + "Ingesting " + + str(i) + + " of " + + str(file_count) + + " " + + str(os.path.basename(asset_full_path)) + + " Task Id: " + + output.decode("ascii").strip().split(" ")[-1] + ) except Exception as e: print(e) - i=i+1 - except Exception as e: - print(e) - elif len(diff_set)==0: - print('All assets already copied') -#authenticate(dirc=r'C:\planet_demo\grid') + i = i + 1 + except Exception as e: + print(e) + except (KeyboardInterrupt, SystemExit) as e: + sys.exit("Program escaped by User") + else: + print("Authentication Failed for GEE account") + elif len(diff_set) == 0: + print("All assets already copied") + + +# authenticate(dirc=r'C:\planet_demo\grid') diff --git a/setup.py b/setup.py index 190ac89..77fe100 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def readme(): setuptools.setup( name="geeup", - version="0.4.0", + version="0.4.1", packages=find_packages(), url="https://github.com/samapriya/geeup", install_requires=[