From b89eb99cb87bbcb1a3f661345aff1f0f95652164 Mon Sep 17 00:00:00 2001 From: fido Date: Mon, 1 Feb 2021 01:08:18 +0100 Subject: [PATCH 1/9] add configurable installation directory to init and setup function --- tagui.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tagui.py b/tagui.py index c13c985..b0e0d9f 100644 --- a/tagui.py +++ b/tagui.py @@ -247,14 +247,11 @@ def unzip(file_to_unzip = None, unzip_location = None): zip_file.close() return True -def setup(): +def setup(installation_dir): """function to setup TagUI to user home folder on Linux / macOS / Windows""" - # get user home folder location to setup tagui - if platform.system() == 'Windows': - home_directory = os.environ['APPDATA'] - else: - home_directory = os.path.expanduser('~') + # set directory to setup tagui + home_directory = installation_dir print('[RPA][INFO] - setting up TagUI for use in your Python environment') @@ -437,7 +434,7 @@ def setup(): return True -def init(visual_automation = False, chrome_browser = True): +def init(visual_automation = False, chrome_browser = True, installation_dir = None): """start and connect to tagui process by checking tagui live mode readiness""" global _process, _tagui_started, _tagui_id, _tagui_visual, _tagui_chrome, _tagui_init_directory @@ -458,12 +455,16 @@ def init(visual_automation = False, chrome_browser = True): else: tagui_directory = os.path.expanduser('~') + '/' + '.tagui' + # override home folder when manual path is set + if installation_dir: + tagui_directory = installation_dir + tagui_executable = tagui_directory + '/' + 'src' + '/' + 'tagui' end_processes_executable = tagui_directory + '/' + 'src' + '/' + 'end_processes' # if tagui executable is not found, initiate setup() to install tagui if not os.path.isfile(tagui_executable): - if not setup(): + if not setup(installation_dir): # error message is shown by setup(), no need for message here return False From 3e86e45b47372e64bcaa19862772bcf21991da16 Mon Sep 17 00:00:00 2001 From: fido Date: Fri, 5 Feb 2021 20:21:46 +0100 Subject: [PATCH 2/9] add .tagui for custome path --- tagui.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tagui.py b/tagui.py index b0e0d9f..8e38617 100644 --- a/tagui.py +++ b/tagui.py @@ -247,11 +247,18 @@ def unzip(file_to_unzip = None, unzip_location = None): zip_file.close() return True -def setup(installation_dir): +def setup(installation_dir = None): """function to setup TagUI to user home folder on Linux / macOS / Windows""" - # set directory to setup tagui - home_directory = installation_dir + # get user home folder location to setup tagui + if platform.system() == 'Windows': + home_directory = os.environ['APPDATA'] + else: + home_directory = os.path.expanduser('~') + + # override home folder when manual path is set + if installation_dir: + home_directory = installation_dir print('[RPA][INFO] - setting up TagUI for use in your Python environment') @@ -305,6 +312,10 @@ def setup(installation_dir): else: tagui_directory = home_directory + '/' + '.tagui' + # override with custome dir + if installation_dir: + tagui_directory = installation_dir + '/' + '.tagui' + # overwrite tagui to .tagui folder for Linux / macOS # first rename existing .tagui folder to .tagui_previous @@ -457,7 +468,7 @@ def init(visual_automation = False, chrome_browser = True, installation_dir = No # override home folder when manual path is set if installation_dir: - tagui_directory = installation_dir + tagui_directory = installation_dir + '/' + '.tagui' tagui_executable = tagui_directory + '/' + 'src' + '/' + 'tagui' end_processes_executable = tagui_directory + '/' + 'src' + '/' + 'end_processes' From d766300af82cadbfcb6dbc29dbf9df3b3b72c6fe Mon Sep 17 00:00:00 2001 From: fido Date: Fri, 5 Feb 2021 22:41:11 +0100 Subject: [PATCH 3/9] add custom folder ability to pack and update function --- tagui.py | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/tagui.py b/tagui.py index 8e38617..cd72583 100644 --- a/tagui.py +++ b/tagui.py @@ -312,7 +312,7 @@ def setup(installation_dir = None): else: tagui_directory = home_directory + '/' + '.tagui' - # override with custome dir + # override with custom dir if installation_dir: tagui_directory = installation_dir + '/' + '.tagui' @@ -466,9 +466,14 @@ def init(visual_automation = False, chrome_browser = True, installation_dir = No else: tagui_directory = os.path.expanduser('~') + '/' + '.tagui' - # override home folder when manual path is set + # check if custom installation path is set if installation_dir: - tagui_directory = installation_dir + '/' + '.tagui' + if "tagui" in installation_dir: + print('[RPA][INFO] - It was detected to use a custom directory.') + tagui_directory = installation_dir + else: + print('[RPA][ERROR] - Please use path with target directory name tagui.') + sys.exit(1) tagui_executable = tagui_directory + '/' + 'src' + '/' + 'tagui' end_processes_executable = tagui_directory + '/' + 'src' + '/' + 'end_processes' @@ -598,19 +603,26 @@ def init(visual_automation = False, chrome_browser = True, installation_dir = No _tagui_started = False return False -def pack(): +def pack(installation_dir = None): """function to pack TagUI files for installation on an air-gapped computer without internet""" print('[RPA][INFO] - pack() is to deploy RPA for Python to a computer without internet') print('[RPA][INFO] - update() is to update an existing installation deployed from pack()') print('[RPA][INFO] - detecting and zipping your TagUI installation to rpa_python.zip ...') + # check custom installation path + if installation_dir: + print('[RPA][INFO] - It was detected to use a custom directory as source for packing.') + if not os.path.isdir(installation_dir + "/src"): + print('[RPA][ERROR] - Your target destination is not a valid path.') + sys.exit(1) + # first make sure TagUI files have been downloaded and synced to latest stable delta files global _tagui_started if _tagui_started: if not close(): return False - if not init(False, False): + if not init(False, False, installation_dir): return False if not close(): return False @@ -689,11 +701,24 @@ def update(): update_zip_file.write(base64.b64decode(rpa_update_zip)) update_zip_file.close() -# unzip update.zip to tagui folder in user home directory +# check tagui path if platform.system() == 'Windows': base_directory = os.environ['APPDATA'] + '/tagui' else: base_directory = os.path.expanduser('~') + '/.tagui' + +if len(sys.argv) == 2: + print('[RPA][INFO] - It was detected to use a custom directory for updating.') + if os.path.isdir(sys.argv[1]): + if "tagui" in sys.argv[1]: + base_directory = sys.argv[1] + else: + print('[RPA][ERROR] - Please use path with target directory name tagui.') + sys.exit(1) + else: + print('[RPA][ERROR] - Your target destination is not a valid path.') + +# unzip update.zip to tagui folder in target directory r.unzip('update.zip', base_directory + '/src') if os.path.isfile('update.zip'): os.remove('update.zip') From 13f8ef253e96c3bba6cfaf06348e56c0be6ffe11 Mon Sep 17 00:00:00 2001 From: fido Date: Fri, 5 Feb 2021 23:11:18 +0100 Subject: [PATCH 4/9] add custom installation dir explanation --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9425dbe..2faf7a8 100644 --- a/README.md +++ b/README.md @@ -97,12 +97,13 @@ An element identifier helps to tell RPA for Python exactly which element on the #### CORE FUNCTIONS Function|Parameters|Purpose :-------|:---------|:------ -init()|visual_automation = False, chrome_browser = True|start TagUI, auto-setup on first run +init()|visual_automation = False, chrome_browser = True, installation_dir = "path"|start TagUI, auto-setup on first run close()||close TagUI, Chrome browser, SikuliX pack()||for deploying package without internet update()||for updating package without internet >_to print and log debug info to rpa_python.log use debug(True), to switch off use debug(False)_ +>_to set custome installation path use r.init(installation_dir="/home/user/opt/.tagui")_ #### BASIC FUNCTIONS Function|Parameters|Purpose From 97fcd06deac4bb5dff35a8f88ed503c0b91c721b Mon Sep 17 00:00:00 2001 From: fido Date: Fri, 5 Feb 2021 23:21:38 +0100 Subject: [PATCH 5/9] add custom installation dir explanation --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2faf7a8..c20dd2d 100644 --- a/README.md +++ b/README.md @@ -100,10 +100,10 @@ Function|Parameters|Purpose init()|visual_automation = False, chrome_browser = True, installation_dir = "path"|start TagUI, auto-setup on first run close()||close TagUI, Chrome browser, SikuliX pack()||for deploying package without internet -update()||for updating package without internet +update()|installation_dir = "path"|for updating package without internet ->_to print and log debug info to rpa_python.log use debug(True), to switch off use debug(False)_ ->_to set custome installation path use r.init(installation_dir="/home/user/opt/.tagui")_ +>_to print and log debug info to rpa_python.log use debug(True), to switch off use debug(False)._ +>_to set custome installation path use r.init(installation_dir="/home/user/opt/.tagui")._ #### BASIC FUNCTIONS Function|Parameters|Purpose From ab7c6dfa35724e00b914c5b376550610442b0346 Mon Sep 17 00:00:00 2001 From: fido Date: Fri, 5 Feb 2021 23:23:22 +0100 Subject: [PATCH 6/9] modify installation dir explanation --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c20dd2d..9456ff0 100644 --- a/README.md +++ b/README.md @@ -99,8 +99,8 @@ Function|Parameters|Purpose :-------|:---------|:------ init()|visual_automation = False, chrome_browser = True, installation_dir = "path"|start TagUI, auto-setup on first run close()||close TagUI, Chrome browser, SikuliX -pack()||for deploying package without internet -update()|installation_dir = "path"|for updating package without internet +pack()|installation_dir = "path"|for deploying package without internet +update()||for updating package without internet >_to print and log debug info to rpa_python.log use debug(True), to switch off use debug(False)._ >_to set custome installation path use r.init(installation_dir="/home/user/opt/.tagui")._ From 23db347255958f0708fa26ace6e91a0a0f0dc948 Mon Sep 17 00:00:00 2001 From: fido Date: Fri, 12 Feb 2021 23:52:36 +0100 Subject: [PATCH 7/9] fix path composition --- tagui.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tagui.py b/tagui.py index cd72583..1b7f161 100644 --- a/tagui.py +++ b/tagui.py @@ -259,6 +259,9 @@ def setup(installation_dir = None): # override home folder when manual path is set if installation_dir: home_directory = installation_dir + # Check if directory exists, if not create one + if not os.path.isdir(home_directory): + os.mkdir(home_directory) print('[RPA][INFO] - setting up TagUI for use in your Python environment') @@ -309,13 +312,17 @@ def setup(installation_dir = None): # set correct tagui folder for different operating systems if platform.system() == 'Windows': tagui_directory = home_directory + '/' + 'tagui' + + elif installation_dir: + # copy content to parent folder + from distutils.dir_util import copy_tree, remove_tree + tagui_directory = home_directory + copy_tree(home_directory + '/' + 'tagui', home_directory) + remove_tree(home_directory + '/' + 'tagui') + else: tagui_directory = home_directory + '/' + '.tagui' - # override with custom dir - if installation_dir: - tagui_directory = installation_dir + '/' + '.tagui' - # overwrite tagui to .tagui folder for Linux / macOS # first rename existing .tagui folder to .tagui_previous @@ -473,7 +480,7 @@ def init(visual_automation = False, chrome_browser = True, installation_dir = No tagui_directory = installation_dir else: print('[RPA][ERROR] - Please use path with target directory name tagui.') - sys.exit(1) + return False tagui_executable = tagui_directory + '/' + 'src' + '/' + 'tagui' end_processes_executable = tagui_directory + '/' + 'src' + '/' + 'end_processes' @@ -615,7 +622,7 @@ def pack(installation_dir = None): print('[RPA][INFO] - It was detected to use a custom directory as source for packing.') if not os.path.isdir(installation_dir + "/src"): print('[RPA][ERROR] - Your target destination is not a valid path.') - sys.exit(1) + return False # first make sure TagUI files have been downloaded and synced to latest stable delta files global _tagui_started @@ -717,7 +724,8 @@ def update(): sys.exit(1) else: print('[RPA][ERROR] - Your target destination is not a valid path.') - + sys.exit(1) + # unzip update.zip to tagui folder in target directory r.unzip('update.zip', base_directory + '/src') if os.path.isfile('update.zip'): os.remove('update.zip') From 5b455320c406f146c30a1be40627678c402f67d9 Mon Sep 17 00:00:00 2001 From: Ken Soh Date: Mon, 24 May 2021 01:40:43 +0800 Subject: [PATCH 8/9] implementation using a tagui_location() --- tagui.py | 163 +++++++++++++++++++------------------------------------ 1 file changed, 56 insertions(+), 107 deletions(-) diff --git a/tagui.py b/tagui.py index 1b7f161..0c2688d 100644 --- a/tagui.py +++ b/tagui.py @@ -1,8 +1,8 @@ """INTEGRATION ENGINE OF RPA FOR PYTHON PACKAGE ~ TEBEL.ORG""" -# Apache License 2.0, Copyright 2020 Tebel.Automation Private Limited +# Apache License 2.0, Copyright 2019 Tebel.Automation Private Limited # https://github.com/tebelorg/RPA-Python/blob/master/LICENSE.txt __author__ = 'Ken Soh ' -__version__ = '1.27.1' +__version__ = '1.36.0' import subprocess import os @@ -37,6 +37,12 @@ # to track the original directory when init() was called _tagui_init_directory = '' +# to track location of TagUI (default user home folder) +if platform.system() == 'Windows': + _tagui_location = os.environ['APPDATA'] +else: + _tagui_location = os.path.expanduser('~') + # delete tagui temp output text file to avoid reading old data if os.path.isfile('rpa_python.txt'): os.remove('rpa_python.txt') @@ -216,6 +222,22 @@ def _tagui_delta(base_directory = None): delta_done_file.close() return True +def _patch_macos_pjs(): + """patch PhantomJS to latest v2.1.1 that plays well with new macOS versions""" + if platform.system() == 'Darwin' and not os.path.isdir(tagui_location() + '/.tagui/src/phantomjs_old'): + original_directory = os.getcwd(); os.chdir(tagui_location() + '/.tagui/src') + print('[RPA][INFO] - downloading latest PhantomJS to fix OpenSSL issue') + download('https://github.com/tebelorg/Tump/releases/download/v1.0.0/phantomjs-2.1.1-macosx.zip', 'phantomjs.zip') + if not os.path.isfile('phantomjs.zip'): + print('[RPA][ERROR] - unable to download latest PhantomJS v2.1.1') + os.chdir(original_directory); return False + unzip('phantomjs.zip'); os.rename('phantomjs', 'phantomjs_old'); os.rename('phantomjs-2.1.1-macosx', 'phantomjs') + if os.path.isfile('phantomjs.zip'): os.remove('phantomjs.zip') + os.system('chmod -R 755 phantomjs > /dev/null 2>&1') + os.chdir(original_directory); return True + else: + return True + def coord(x_coordinate = 0, y_coordinate = 0): """function to form a coordinate string from x and y integers""" return '(' + str(x_coordinate) + ',' + str(y_coordinate) + ')' @@ -226,6 +248,12 @@ def debug(on_off = None): if on_off is not None: _tagui_debug = on_off return _tagui_debug +def tagui_location(location = None): + """function to set location of TagUI installation""" + global _tagui_location + if location is not None: _tagui_location = location + return _tagui_location + def unzip(file_to_unzip = None, unzip_location = None): """function to unzip zip file to specified location""" import zipfile @@ -247,28 +275,20 @@ def unzip(file_to_unzip = None, unzip_location = None): zip_file.close() return True -def setup(installation_dir = None): +def setup(): """function to setup TagUI to user home folder on Linux / macOS / Windows""" # get user home folder location to setup tagui - if platform.system() == 'Windows': - home_directory = os.environ['APPDATA'] - else: - home_directory = os.path.expanduser('~') - - # override home folder when manual path is set - if installation_dir: - home_directory = installation_dir - # Check if directory exists, if not create one - if not os.path.isdir(home_directory): - os.mkdir(home_directory) + home_directory = tagui_location() print('[RPA][INFO] - setting up TagUI for use in your Python environment') # special check for macOS - download() will fail due to no SSL certs for Python 3 if platform.system() == 'Darwin' and _python3_env(): - if os.system('/Applications/Python\ 3.7/Install\ Certificates.command > /dev/null 2>&1') != 0: - os.system('/Applications/Python\ 3.6/Install\ Certificates.command > /dev/null 2>&1') + if os.system('/Applications/Python\ 3.9/Install\ Certificates.command > /dev/null 2>&1') != 0: + if os.system('/Applications/Python\ 3.8/Install\ Certificates.command > /dev/null 2>&1') != 0: + if os.system('/Applications/Python\ 3.7/Install\ Certificates.command > /dev/null 2>&1') != 0: + os.system('/Applications/Python\ 3.6/Install\ Certificates.command > /dev/null 2>&1') # set tagui zip filename for respective operating systems if platform.system() == 'Linux': tagui_zip_file = 'TagUI_Linux.zip' @@ -312,14 +332,6 @@ def setup(installation_dir = None): # set correct tagui folder for different operating systems if platform.system() == 'Windows': tagui_directory = home_directory + '/' + 'tagui' - - elif installation_dir: - # copy content to parent folder - from distutils.dir_util import copy_tree, remove_tree - tagui_directory = home_directory - copy_tree(home_directory + '/' + 'tagui', home_directory) - remove_tree(home_directory + '/' + 'tagui') - else: tagui_directory = home_directory + '/' + '.tagui' @@ -379,47 +391,9 @@ def setup(installation_dir = None): print('[RPA][ERROR] - unable to set permissions for .tagui folder') return False - # check for openssl, a dependency of phantomjs removed in newer macOS - if not os.path.isfile('/usr/local/opt/openssl/lib/libssl.1.0.0.dylib'): - - # if openssl is missing, first attempt to install using homebrew - os.system('brew uninstall openssl > /dev/null 2>&1') - os.system('brew uninstall openssl > /dev/null 2>&1') - os.system('brew install https://github.com/tebelorg/Tump/releases/download/v1.0.0/openssl.rb > /dev/null 2>&1') - - # if it is still missing, attempt again by first installing homebrew - if not os.path.isfile('/usr/local/opt/openssl/lib/libssl.1.0.0.dylib'): - print('') - print('[RPA][INFO] - now installing OpenSSL dependency using Homebrew') - print('[RPA][INFO] - you may be prompted for login password to continue') - print('') - os.system('echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"') - os.system('brew uninstall openssl > /dev/null 2>&1') - os.system('brew uninstall openssl > /dev/null 2>&1') - os.system('brew install https://github.com/tebelorg/Tump/releases/download/v1.0.0/openssl.rb') - - # if it is still missing, prompt user to install homebrew and openssl - if not os.path.isfile('/usr/local/opt/openssl/lib/libssl.1.0.0.dylib'): - print('[RPA][INFO] - OpenSSL was not able to be installed automatically') - print('[RPA][INFO] - run below commands in your terminal to install manually') - print('[RPA][INFO] - after that, TagUI ready for use in your Python environment') - print('') - print('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"') - print('brew uninstall openssl; brew uninstall openssl; brew install https://github.com/tebelorg/Tump/releases/download/v1.0.0/openssl.rb') - print('') - print('[RPA][INFO] - if there is an issue running brew command, check the solution below') - print('[RPA][INFO] - https://github.com/kelaberetiv/TagUI/issues/86#issuecomment-532466727') - print('') - return False - - else: - print('[RPA][INFO] - TagUI now ready for use in your Python environment') - - else: - print('[RPA][INFO] - TagUI now ready for use in your Python environment') - - else: - print('[RPA][INFO] - TagUI now ready for use in your Python environment') + # patch PhantomJS to solve OpenSSL issue + if not _patch_macos_pjs(): return False + print('[RPA][INFO] - TagUI now ready for use in your Python environment') # perform Windows specific setup actions if platform.system() == 'Windows': @@ -452,7 +426,7 @@ def setup(installation_dir = None): return True -def init(visual_automation = False, chrome_browser = True, installation_dir = None): +def init(visual_automation = False, chrome_browser = True, headless_mode = False): """start and connect to tagui process by checking tagui live mode readiness""" global _process, _tagui_started, _tagui_id, _tagui_visual, _tagui_chrome, _tagui_init_directory @@ -469,35 +443,24 @@ def init(visual_automation = False, chrome_browser = True, installation_dir = No # get user home folder location to locate tagui executable if platform.system() == 'Windows': - tagui_directory = os.environ['APPDATA'] + '/' + 'tagui' + tagui_directory = tagui_location() + '/' + 'tagui' else: - tagui_directory = os.path.expanduser('~') + '/' + '.tagui' - - # check if custom installation path is set - if installation_dir: - if "tagui" in installation_dir: - print('[RPA][INFO] - It was detected to use a custom directory.') - tagui_directory = installation_dir - else: - print('[RPA][ERROR] - Please use path with target directory name tagui.') - return False + tagui_directory = tagui_location() + '/' + '.tagui' tagui_executable = tagui_directory + '/' + 'src' + '/' + 'tagui' end_processes_executable = tagui_directory + '/' + 'src' + '/' + 'end_processes' # if tagui executable is not found, initiate setup() to install tagui if not os.path.isfile(tagui_executable): - if not setup(installation_dir): + if not setup(): # error message is shown by setup(), no need for message here return False # sync tagui delta files for current release if needed if not _tagui_delta(tagui_directory): return False - # on Windows, check if there is space in folder path name - if platform.system() == 'Windows' and ' ' in os.getcwd(): - print('[RPA][INFO] - to use RPA for Python on Windows, avoid space in folder path name') - return False + # on macOS, patch PhantomJS to latest v2.1.1 to solve OpenSSL issue + if platform.system() == 'Darwin' and not _patch_macos_pjs(): return False # create entry flow to launch SikuliX accordingly if visual_automation: @@ -539,13 +502,15 @@ def init(visual_automation = False, chrome_browser = True, installation_dir = No browser_option = '' if chrome_browser: browser_option = 'chrome' + if headless_mode: + browser_option = 'headless' # entry shell command to invoke tagui process tagui_cmd = tagui_executable + ' rpa_python ' + browser_option # run tagui end processes script to flush dead processes # for eg execution ended with ctrl+c or forget to close() - os.system(end_processes_executable) + os.system('"' + end_processes_executable + '"') try: # launch tagui using subprocess @@ -610,39 +575,32 @@ def init(visual_automation = False, chrome_browser = True, installation_dir = No _tagui_started = False return False -def pack(installation_dir = None): +def pack(): """function to pack TagUI files for installation on an air-gapped computer without internet""" print('[RPA][INFO] - pack() is to deploy RPA for Python to a computer without internet') print('[RPA][INFO] - update() is to update an existing installation deployed from pack()') print('[RPA][INFO] - detecting and zipping your TagUI installation to rpa_python.zip ...') - # check custom installation path - if installation_dir: - print('[RPA][INFO] - It was detected to use a custom directory as source for packing.') - if not os.path.isdir(installation_dir + "/src"): - print('[RPA][ERROR] - Your target destination is not a valid path.') - return False - # first make sure TagUI files have been downloaded and synced to latest stable delta files global _tagui_started if _tagui_started: if not close(): return False - if not init(False, False, installation_dir): + if not init(False, False): return False if not close(): return False # next download jython to tagui/src/sikulix folder (after init() it can be moved away) if platform.system() == 'Windows': - tagui_directory = os.environ['APPDATA'] + '/' + 'tagui' + tagui_directory = tagui_location() + '/' + 'tagui' # pack in Visual C++ MSVCR110.dll dependency from PHP for offline installation vcredist_x86_url = 'https://raw.githubusercontent.com/tebelorg/Tump/master/vcredist_x86.exe' if not download(vcredist_x86_url, tagui_directory + '/vcredist_x86.exe'): return False else: - tagui_directory = os.path.expanduser('~') + '/' + '.tagui' + tagui_directory = tagui_location() + '/' + '.tagui' sikulix_directory = tagui_directory + '/' + 'src' + '/' + 'sikulix' sikulix_jython_url = 'https://github.com/tebelorg/Tump/releases/download/v1.0.0/jython-standalone-2.7.1.jar' if not download(sikulix_jython_url, sikulix_directory + '/' + 'jython-standalone-2.7.1.jar'): @@ -708,25 +666,15 @@ def update(): update_zip_file.write(base64.b64decode(rpa_update_zip)) update_zip_file.close() -# check tagui path +# unzip update.zip to tagui folder in user home directory if platform.system() == 'Windows': base_directory = os.environ['APPDATA'] + '/tagui' else: base_directory = os.path.expanduser('~') + '/.tagui' -if len(sys.argv) == 2: - print('[RPA][INFO] - It was detected to use a custom directory for updating.') - if os.path.isdir(sys.argv[1]): - if "tagui" in sys.argv[1]: - base_directory = sys.argv[1] - else: - print('[RPA][ERROR] - Please use path with target directory name tagui.') - sys.exit(1) - else: - print('[RPA][ERROR] - Your target destination is not a valid path.') - sys.exit(1) +# uncomment below to define and use custom TagUI folder +#base_directory = 'your_full_path' -# unzip update.zip to tagui folder in target directory r.unzip('update.zip', base_directory + '/src') if os.path.isfile('update.zip'): os.remove('update.zip') @@ -761,6 +709,7 @@ def update(): if os.path.isfile('rpa_update.zip'): os.remove('rpa_update.zip') print('[RPA][INFO] - done. copy or email update.py to your target computer and run') print('[RPA][INFO] - python update.py to update RPA for Python to version ' + rpa_python_py) + print('[RPA][INFO] - to use custom TagUI folder, set base_directory in update.py') return True except Exception as e: From 77ae10eced1c33a5ec488f556b37f3e8aa037d1a Mon Sep 17 00:00:00 2001 From: Ken Soh Date: Mon, 24 May 2021 01:41:48 +0800 Subject: [PATCH 9/9] bump to v1.36 --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 9456ff0..f6bde7c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # RPA for Python :snake: -[**Use Cases**](#use-cases) | [**API Reference**](#api-reference) | [**About & Credits**](#about--credits) | [**PyCon Video**](https://www.youtube.com/watch?v=F2aQKWx_EAE) | [**v1.27**](https://github.com/tebelorg/RPA-Python/releases) +[**v1.36**](https://github.com/tebelorg/RPA-Python/releases) | [**Use Cases**](#use-cases) | [**API Reference**](#api-reference) | [**About & Credits**](#about--credits) | [**PyCon Video**](https://www.youtube.com/watch?v=F2aQKWx_EAE) | [**Run in Colab**](https://colab.research.google.com/drive/13bQO6G_hzE1teX35a3NZ4T5K-ICFFdB5?usp=sharing) | [**Telegram Chat**](https://t.me/rpa_chat) ->_This tool was previously known as TagUI for Python. [More details](https://github.com/tebelorg/RPA-Python/issues/100) on the name change, which is backward compatible so existing scripts written with `import tagui as t` and `t.function()` will continue to work._ +>_This tool was previously known as TagUI for Python. [More details](https://github.com/tebelorg/RPA-Python/issues/100) on the name change, which is backward compatible so existing scripts written with `import tagui as t` and `t.function()` will still work._ ![RPA for Python demo in Jupyter notebook](https://raw.githubusercontent.com/tebelorg/Tump/master/tagui_python.gif) @@ -23,7 +23,7 @@ Notes on different operating systems and optional visual automation mode - # Use Cases -RPA for Python's simple and powerful API makes robotic process automation fun! You can use it to quickly automate repetitive time-consuming tasks, whether the tasks involve websites, desktop applications, or the command line. +RPA for Python's simple and powerful API makes robotic process automation fun! You can use it to quickly automate away repetitive time-consuming tasks on websites, desktop applications, or the command line. #### WEB AUTOMATION :spider_web: ```python @@ -62,7 +62,7 @@ r.init(visual_automation = True, chrome_browser = False) r.keyboard('[cmd][space]') r.keyboard('safari[enter]') r.keyboard('[cmd]t') -r.keyboard('joker[enter]') +r.keyboard('mortal kombat[enter]') r.wait(2.5) r.snap('page.png', 'results.png') r.close() @@ -73,8 +73,8 @@ r.close() r.init(visual_automation = True) r.type(600, 300, 'open source') r.click(900, 300) -r.snap('page.bmp', 'results.bmp') -r.hover('button_to_drag.bmp') +r.snap('page.png', 'results.png') +r.hover('button_to_drag.png') r.mouse('down') r.hover(r.mouse_x() + 300, r.mouse_y()) r.mouse('up') @@ -83,7 +83,7 @@ r.close() # API Reference -Check out [sample Python script](https://github.com/tebelorg/RPA-Python/blob/master/sample.py), [RPA Challenge solution](https://github.com/tebelorg/RPA-Python/issues/120#issuecomment-610518196), and [RedMart groceries example](https://github.com/tebelorg/RPA-Python/issues/24). To automate Chrome browser invisibly, see this [simple hack](https://github.com/tebelorg/RPA-Python/issues/133#issuecomment-634113838). To run 20-30X faster, without normal UI interaction delays, [see this advanced hack](https://github.com/tebelorg/RPA-Python/issues/120#issuecomment-610532082). +See [sample Python script](https://github.com/tebelorg/RPA-Python/blob/master/sample.py), the [RPA Challenge solution](https://github.com/tebelorg/RPA-Python/issues/120#issuecomment-610518196), and [RedMart groceries example](https://github.com/tebelorg/RPA-Python/issues/24). To automate Chrome browser invisibly, use [headless_mode](https://github.com/tebelorg/RPA-Python#core-functions). To run 20-30X faster, without normal UI interaction delays, [see this hack](https://github.com/tebelorg/RPA-Python/issues/120#issuecomment-610532082). You can even run on your phone browser [using this Colab notebook](https://colab.research.google.com/drive/13bQO6G_hzE1teX35a3NZ4T5K-ICFFdB5?usp=sharing) (eg datascraping in headless mode). #### ELEMENT IDENTIFIERS An element identifier helps to tell RPA for Python exactly which element on the user interface you want to interact with. For example, //\*[@id="email"] is an XPath pointing to the webpage element having the id attribute "email". @@ -97,13 +97,13 @@ An element identifier helps to tell RPA for Python exactly which element on the #### CORE FUNCTIONS Function|Parameters|Purpose :-------|:---------|:------ -init()|visual_automation = False, chrome_browser = True, installation_dir = "path"|start TagUI, auto-setup on first run +init()|visual_automation = False, chrome_browser = True|start TagUI, auto-setup on first run close()||close TagUI, Chrome browser, SikuliX -pack()|installation_dir = "path"|for deploying package without internet +pack()||for deploying package without internet update()||for updating package without internet +debug()|True or False|print & log debug info to rpa_python.log ->_to print and log debug info to rpa_python.log use debug(True), to switch off use debug(False)._ ->_to set custome installation path use r.init(installation_dir="/home/user/opt/.tagui")._ +>_by default Chrome runs with visible mode, to run Chrome invisibly use init(headless_mode = True)_ #### BASIC FUNCTIONS Function|Parameters|Purpose @@ -142,7 +142,7 @@ vision()|command_to_run (Python code for SikuliX)|run custom SikuliX commands timeout()|timeout_in_seconds (blank returns current timeout)|change wait timeout (default 10s) keyboard() modifiers and special keys - ->_[shift] [ctrl] [alt] [cmd] [win] [meta] [clear] [space] [enter] [backspace] [tab] [esc] [up] [down] [left] [right] [pageup] [pagedown] [delete] [home] [end] [insert] [f1] .. [f15] [printscreen] [scrolllock] [pause] [capslock] [numlock]_ +>_[shift] [ctrl] [alt] [win] [cmd] [clear] [space] [enter] [backspace] [tab] [esc] [up] [down] [left] [right] [pageup] [pagedown] [delete] [home] [end] [insert] [f1] .. [f15] [printscreen] [scrolllock] [pause] [capslock] [numlock]_ #### HELPER FUNCTIONS Function|Parameters|Purpose @@ -158,19 +158,19 @@ title()||return page title of current web page as string text()||return text content of current web page as string timer()||return time elapsed in sec between calls as float ->_to type large amount of text quickly, use clipboard() and keyboard() to paste instead of type()_ +>_to type a large amount of text quickly, use clipboard() and keyboard() to paste instead of type()_ # About & Credits -TagUI is the leading open-source RPA software :robot: with thousands of active users. It was created in 2016-2017 when I left DBS Bank as a test automation engineer, to embark on a one-year sabbatical to Eastern Europe. Most of its code base was written in Novi Sad Serbia. My wife and I also spent a couple of months in Budapest Hungary, as well as Chiang Mai Thailand for visa runs. In 2018, I joined AI Singapore to continue development of TagUI. +TagUI is a leading open-source RPA software :robot: with tens of thousands of users. It was created in 2016-2017 when I left DBS Bank as a test automation engineer, to embark on a one-year sabbatical to Eastern Europe. Most of its code base was written in Novi Sad Serbia. My wife and I also spent a couple of months in Budapest Hungary, as well as Chiang Mai Thailand for visa runs. In 2018, I joined AI Singapore to continue development of TagUI. -Over the past few months I take on a daddy role full-time, taking care of my newborn baby girl and wife :cowboy_hat_face:🤱. In between the nannying, I use my time pockets to create this Python package that's built on TagUI. I hope that RPA for Python and ML frameworks would be good friends, and `pip install rpa` would make life easier for Python users. +Over the past few months I take on a daddy role full-time, taking care of my newborn baby girl and wife :cowboy_hat_face:🤱. In between nannying, I use my time pockets to create this Python package built on TagUI. I hope that RPA for Python and ML frameworks would be good friends, and `pip install rpa` would make life easier for Python users. -Lastly, at only ~1k lines of code, it would make my day to see developers of other languages port this project over to their favourite programming language. See ample comments in this [single-file package](https://github.com/tebelorg/RPA-Python/blob/master/tagui.py), and its intuitive architecture - +At only ~1k lines of code, it would make my day to see developers of other languages port this project over to their favourite programming language. See ample comments in this [single-file package](https://github.com/tebelorg/RPA-Python/blob/master/tagui.py), and its intuitive architecture. ![RPA for Python architecture](https://raw.githubusercontent.com/tebelorg/Tump/master/TagUI-Python/architecture.png) -I would like to credit and express my appreciation below :bowing_man:, and you are invited to [connect on LinkedIn](https://www.linkedin.com/in/kensoh) - +I would like to credit and express my appreciation below :heart:, and you are invited to [connect on LinkedIn](https://www.linkedin.com/in/kensoh) - - [TagUI](https://github.com/kelaberetiv/TagUI/tree/pre_v6) - AI Singapore from Singapore / [@aisingapore](https://www.aisingapore.org) - [SikuliX](https://github.com/RaiMan/SikuliX1) - Raimund Hocke from Germany / [@RaiMan](https://github.com/RaiMan)