diff --git a/.gitignore b/.gitignore index 26627560..7f8f2041 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ Automagica.egg-info Automagica.egg-info build dist +.ipynb_checkpoints +docs/build +migrated \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 9e0094c3..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,3 +0,0 @@ -include automagica/bin/* -include automagica/icon.ico -include LICENSE diff --git a/README.md b/README.md index 4b1dfe6d..d17d1952 100644 --- a/README.md +++ b/README.md @@ -4,45 +4,46 @@ Automagica is an open source Smart Robotic Process Automation (SRPA) platform. W ![](https://github.com/OakwoodAI/automagica/blob/master/images/automagica_drawing.gif) -Refer to our [website](https://www.automagica.io) for more information, registered users can access the [portal](https://portal.automagica.io). For more info see the [documentation](https://automagica.readthedocs.io). +Refer to our [website](https://www.automagica.com) for more information, registered users can access the [portal](https://portal.automagica.com). For more info see the [documentation](https://portal.automagica.com). ## Important update! -- We're on PyPi now! -- Follow our [blog](https://automagica.io) to stay up to date with the latest changes! +- [Portal 2.0](https://portal.automagica.com) is now live! +- You can still access the old portal on [old portal](https://portal.automagica.io) +- Follow our [blog](https://automagica.com) to stay up to date with the latest changes! ## Need expert support? -We can support you end-to-end in all your automation needs, from estimating automation potential for processes to technical implementation and integration. Please send an e-mail to [mail@oakwood.ai](mailto:mail@oakwood.ai) for enquiries and rates. +We can support you end-to-end in all your automation needs, from estimating automation potential for processes to technical implementation and integration. Please send an e-mail to [sales@automagica.be](mailto:sales@automagica.be) for enquiries and rates. ## Getting started -[![Play](https://i.imgur.com/kkvLWNc.png)](https://www.youtube.com/watch?v=C5447eGY7_0) -### Prerequisites -1. Python 3.7 from https://www.python.org +## Installation -### Installation +For Windows you can download the one-click installer on [portal](https://portal.automagica.com). -1. Install the latest version Automagica on your machine: +#### Developers + +#### Developer Installation + +If you wish to only install the open source component without the portal functionalities: + +Download and install [Python 3.7](https://www.python.org) + +Install the latest version Automagica on your machine: ``` pip install automagica --upgrade ``` -2. In order to register your machine with the Automagica portal (sign up for free [here](https://portal.automagica.io)), run the following command: (optional) -``` -automagica --login -``` -Follow the setup process and Automagica will from then on run in the background and at startup! -### Uninstall procedure +#### Developer Uninstall procedure + To remove Automagica, run the following commands: ``` -automagica --logout pip uninstall automagica ``` +#### Importing the activities -### Importing the activities - -Before getting started, don't forget to import the activities from automagica in your python script. If unsure, it is possible to import all the activities for development purposes by starting your script with: +Before getting started in development mode, don't forget to import the activities from automagica in your python script. If unsure, it is possible to import all the activities for development purposes by starting your script with: ``` from automagica import * ``` @@ -65,250 +66,6 @@ Folder and File manipulation -### Example code - -This is a simple example that opens Notepad and types 'Hello world!'. - -``` -PressHotkey('win','r') -Wait(seconds=1) -Type(text='notepad', interval_seconds=0) -PressKey('enter') -Wait(seconds=2) -Type(text='Hello world!', interval_seconds=0.15) -``` - -This is a simple example that opens Chrome and goes to Google.com. - -``` -browser = ChromeBrowser() -browser.get('https://google.com') -``` - -For more info and examples see the [documentation](https://automagica.readthedocs.io). - -#### Running the other examples -Running the examples is easy: -``` -cd examples -dir -cd -automagica -f app.py -``` - -#### Optional (to enable Optical Character Recognition) -For _Windows_, install Tesseract 4 [from here](http://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe). - -For _Linux_ (Ubuntu): -``` -sudo apt-get install tesseract-ocr -``` -For _MacOS_: -``` -brw install tesseract -``` - -### Failsafe - -As a safety feature, a failsafe mechanism is enabled by default. You can trigger this by moving your mouse to the upper left corner of the screen. You can disable this by running the following command in the editor: -``` -Failsafe(False) -``` - -## Automagica with Natural Language - -Wouldn't it be cool if we could write Robotic Process Automation scripts in plain ol' English rather than the already easy Python scripting language? Well it's possible with Automagica! We have cooked up a more human-friendly interface to get started with automation! - -### How it works -Natural language for Automagica (.nla) looks like this: -``` -open the browser -navigate to google.com -search for oranges -``` - -### Try it yourself - -A Wit.ai key is included, so you can get a headstart! - -Install (in addition to the above) the following required package: -``` -pip install https://github.com/OakwoodAI/understanding/tarball/master -``` -Then install Natural Language for Automagica: -``` -git clone https://github.com/OakwoodAI/natural-language-automagica -cd natural-language-automagica -pip install . -``` - -Then you can get started by running the examples: -``` -cd examples -nla google.nla -nla wikipedia.nla -nla youtube.nla -``` -We are quickly expanding the Natural Language Understanding features of this part of Automagica to make automation accessible to all! - -## Important notes -For the `Type`-function to work, you need to set the "United States-International" keyboard layout on your system. If the keyboard layout is not available, outcomes of the function might be different. - - -## Our Activities - -| Script | Info | -| ------------- | ------------- | -|**Mouse**| -| GetMouseCoordinates() | Displays message box with absolute coordinates of the mouse position | -| ClickOnPosition(x=0, y=0) | Clicks on a specific (x,y) pixel coordinate on the screen. | -| DoubleClickOnPosition(x=None, y=None) | Double clicks on a specific (x,y) pixel coordinate on the screen. | -| RightClickOnPosition(x=None, y=None) | Right clicks on a specific (x,y) pixel coordinate on the screen. | -| MoveToPosition(x=None, y=None) | Moves te pointer to a x-y pixel position. | -| MoveRelative(x=None, y=None) | Moves the mouse an x- and y- distance relative to its current pixel position. | -| DragToPosition | Drag the mouse from its current position to a entered x-y position, while holding a specified button. | -| ClickOnImage("example.png") | Clicks on an image on the screen. Image path needs to be specified. | -|**Keyboard**| -| PressKey(key) | Press and release a specific key. | -| PressHotkey("ctrl","shift","c") | Press a hotkey (combination) | -| Type(text="Hello world!", interval_seconds=0.01) | Types text with a specified interval in seconds | -| CapsLock() | Press the Caps Lock key. | -| NumLock() | Press the Num Lock key. | -| Enter() | Press the Enter key. | -| SpaceBar() | Press the Space bar key. | -| Backspace() | Press the Backspace key. | -| Delete() | Press the delete key. | -| Endkey() | Press the End key. | -| Tab() | Press the Tab key. | -|**Monitoring**| -| TypeInRunWindow(text) | Type the entered text in the Windows "Run" window. | -| CreateUniqueKey(length) | Returns a UUID as a string with. "Length" determines the amount of characters returned. | -| CPULoad(measure_time=1) | Returns average CPU load for all cores over a measured time. | -| NumberOfCPU(logical=True) | Returns the number of CPU's in the current system. | -| CPUFreq() | Returns frequency at which CPU currently operates together with maximum and minimum frequency. | -| CPUStats() | Returns CPU statistics: Number of CTX switches, interrupts, soft-interrupts and systemcalls. | -| MemoryStats(mem_type='swap') | Returns memory statistics: total, used, free and percentage in use. | -| DiskStats() | Returns disk statistics of main disk: total, used, free and percentage in use. | -| DiskPartitions() | Returns tuple with info for every partition. | -| BootTime() | Returns time PC was booted in seconds after the epoch. | -| TimeSinceLastBoot() | Returns time since last boot in seconds. | -|**Windows Activities**| -| BeepSound(frequency=1000, duration=250) | Makes a beeping sound with a given frequency and duration. | -| ClearClipboard() | Removes everything from the clipboard. | -|**Delay**| -| Wait(seconds=5) | Wait for a specified time in seconds | -| WaitForImage("example.png") | Wait for an image to appear on the screen. Image path needs to be specified | -|**Browser**| -| browser = ChromeBrowser() | Opens the Chrome browser | -| browser.get("https://google.com/") | Browse to a specific URL. Browser needs to be opened first | -| GetGoogleSearchLinks(search_text) | Return a list of search results google returns when searching for search_text. | -|**Applications**| -| ProcessRunning(name) | Checks if given process name (name) is currently running on the system. Returns True or False. | -| ListRunningProcesses() | Returns a list with all names of unique processes currently running on the system. | -| ChromeRunning() | Returns True if Chrome is running. | -| WordRunning() | Returns True if Word is running. | -| ExcelRunning() | Returns True if Excel is running. | -| PowerpointRunning() | Returns True if Powerpoint is running. | -| DropboxRunning() | Returns True if Dropbox is running. | -| FirefoxRunning() | Returns True is Firefox is running. | -| TeamviewerRunning() | Returns True is Teamviewer is running. | -| SkypeRunning() | Returns True is Skype is running. | -| EdgeRunning() | Returns True is Microsoft Edge is running. | -| OnedriveRunning() | Returns True is Onedrive is running. | -| IllustratorRunning() | Returns True is Illustrator is running. | -| LaunchProcess(process_executable="mspaint.exe") | Launches a process based on the executable | -| KillProcess(process=my_process) | Kills a process | -|**Control Flow**| -| For Loop | Perform a for-looping operation. | -| Condition | If a condition is true, run the indented code. | -| **Message Box** | -| input_variable = RequestUserInput() | Shows a pop-up message asking for user for input. | -| DisplayMessageBox(title=\"Title Text\", body=\"Body Text\", type=\"info\") | Shows an info pop-up message with title and body | -| DisplayMessageBox(title=\"Title Text\", body=\"Body Text\", type=\"warning\") | -| ExcelCreateWorkbook(path="pathname") | Create new excel workbook and save it at the give path. | Shows a warning pop-up message with title and body | -| DisplayMessageBox(title=\"Title Text\", body=\"Body Text\", type=\"error\") | Shows an error pop-up message with title and body | -| **Excel** | -| ExcelOpenWorkbook(path="pathname") | Open an existing .xlsx file with Microsoft Excel. | -| ExcelSaveExistingWorkbook(path="pathname", new_path=None) | Save a existing .xlsx file to its current path or to a new path. | -| ExcelCreateWorkSheet(path="pathname", sheet_name=None) | Create a named worksheet in a existing .xlsx file specified by a path. | -| ExcelGetSheets(path="pathname") | Return a list with the names of the worksheets is a .xlsx file specified by the path variable. | -| ExcelReadCell(path="pathname", row=1, col=1) | Read cell value from Excel by row and col: first row is defined row number 1 and first column is defined column number 1. | -| ExcelReadCell(path="pathname", cell="A1") | Read cell value from Excel by cell name e.g. cell="A2" is the first cell | -| ExcelWriteCell(path="pathname", sheet="Sheet 1", row=1, col=1, write_value="Value") | Write value to Excel by row and col: first row is defined row number 1 and first column is defined column number 1 | -| ExcelWriteCell(path="pathname", cell=None, write_value="Value") | Write cell value from Excel by cell name e.g. cell="A2" is the first cell | -| ExcelPutRowInList(path="pathname", start_cell="B3", end_cell="E8", sheet=None) | Return the elements from a specified row in a list. | -| ExcelPutColumnInList(path="pathname", start_cell="A3", end_cell="A8", sheet=None) | Return the elements from a specified column in a list. | -| ExcelPutSelectionInMatrix(path="pathname", upper_left_cell="B2", bottom_right_cell="C3", sheet=None) | Return the elements of a specified selection in a matrix. | -|**Word**| -| OpenWordDocument(filename="pathname") | Open a Word document by referring to the absolute path | -| ReplaceText(absolute_document_path, text="[example_placeholder]", replace_with="Example Replacetext") | Replaces text in a Word document, for example to fill in certain fields in a form | -| ConvertWordToPDF(word_filename=absolute_word_path, pdf_filename=absolute_pdf_path) | Transforms a Word document to PDF | -|**PDF**| -| MergePDF(pdf1="pathname", pdf2="pathname", merged_path="pathname") | Adds the pages of pdf2 to pdf1 and saves it at merged_path. | -| ExtractTextFromPage(path, page=1) | Extracts all the text from a give page and returns it as a string. | -|**File Manipulation**| -| OpenFile(path="pathname") | Opens a file at the given path | -| RenameFile(path="pathname", new_name) | Changes the name of a file located by a specified path to new_name | -| RemoveFile(path="pathname") | Removes the file with a specified pathname. | -| MoveFile(old_path="old_pathname", new_location="new_location_path") | Moves a file with a specified path to a new location. | -| FileExists(path="pathname") | Checks whether a file with the given path exists. | -| CopyFile(old_path="old_pathname",new_location="new_location_path") | Copies a file from a location specified by old_path to a new location. | -| WaitForFile(path="pathname") | Waits for a file to be created and then opens it. | -| WriteListToFile(list_to_write, file="pathname") | Write the contents of a list to a specified .txt file. | -| WriteFileToList(file="pathname") | Returns the contents of a specified .txt file as a list. | -|**Folder Manipulation**| -| CreateFolder(path="pathname") | Creates new folder at the given path | -| OpenFolder(path="pathname") | Opens a folder at the given path | -| RenameFolder(path="pathname", new_folder_name="name") | Changes the name of a folder located by a specified path to new_name | -| RemoveFolder(path="pathname", allow_root=False, delete_read_only=True) | Removes the folder with all its contents from a specified pathname. | -| MoveFolder(old_path="old_pathname", new_location="new_location_path") | Moves a folder from one specified path to a new path. | -| EmptyFolder(path="pathname", allow_root=False) | Removes all the folders and files from a given directory. | -| FolderExists(path="pathname") | Checks whether the folder with a given path exists. | -| CopyFolder(old_path="old pathname", new_location="new_location_path") | Copies a folder located by old pathname to a new location specified by new pathname. | -| ZipFolder(folder_path="pathname_folder", new_path="pathname_compressed_folder") | Zips a folder specified by folder_path. | -| UnZipFolder(path="pathname_zipped_folder", new_path="pathname_target_location") | Zips a folder specified by path and stores it at new_path. | -| WaitForFolder(path="pathname") | Waits for a folder to be created and then opens it. | -|**Image Operation**] -| OpenImage(path="pathname") | Opens an image with the given path. | -| RotateImage(path="pathname", angle) | Rotate an image over a specified angle. | -| ResizeImage(path="pathname", size=(640, 480)) | Resizes an image. The new size is entered with a tuple of the form: (width, height) | -| ImageSize(path="Pathname") | Returns the pixel-size of an entered image in a message box. | -| CropImage(path="pathname", box=None) | Crops an image to a region specified by the box argument. | -| MirrorImageHorizontally(path="pathname") | Mirrors an image with a given path horizontally. | -| MirrorImageVertically(path="pathname") | Mirrors an image with a given path vertically. | -| ImageFormat(path="Pathname") | Returns a message box specifying the format of an image. | -|**Windows Applications**| -| OpenCalculator() | Open Windows Calculator. | -| OpenPaint() | Open MS Paint. | -| OpenNotepad() | Open Windows Notepad. | -| OpenSnippingTool() | Open Windows Snipping Tool. | -| OpenControlPanel() | Open Windows Control Panel. | -| OpenCleanManager() | Open Windows Clean Manager. | -| OpenDialer() | Open Windows Dialer. | -| OpenVolumeMixer() | Open Windows Volume Mixer. | -| OpenXPSViewer | Open Windows XPS Viewer. | -|**Email**| -| SendMailWithHotmail(user, password, destination, subject="", message="", port=587) | Send an email with a given text and subject with your Hotmail account. | -| SendMailWithGmail(user, password, destination, subject="", message="", port=587) | Send an email with a given text and subject with your Gmail account. | -| SendMailWithYahoo(user, password, destination, subject="", message="", port=587) | Send an email with a given text and subject with your Yahoo account. | -|**Math**| -| abs(x) | Calculates the absolute value of an integer or float | -| round(x) | Rounds up an integer or float to the closest number | -| exp(x) | The exponential of x | -| floor(x) | The floor of x: the largest integer not greater than x | -| log(x) | The natural logarithm of x, for x> 0 | -| max(x1, x2, ...) | The largest of its arguments: the value closest to positive infinity | -| min(x1, x2, ...) | The smallest of its arguments: the value closest to negative infinity | -| round(x) | x rounded to n digits from the decimal point. | -| abs(x) | Calculates the absolute value of an integer or float | -| sqrt(x) | The square root of x for x > 0 | - -## Known issues -- Run after boot might not work for Linux/OSX systems. This will be fixed soon®. - -## Telegram Community -Join us in [Telegram](https://t.me/automagica)! - ## Credits Under the hood, Automagica is built on some of the greatest open source libraries. Within Automagica, the following libraries are currently included: - [PyAutoGUI](https://github.com/asweigart/pyautogui) diff --git a/automagica/__init__.py b/automagica/__init__.py index 0c80a2e9..05f1065b 100644 --- a/automagica/__init__.py +++ b/automagica/__init__.py @@ -1,2 +1 @@ -if not __name__ == '__main__': - from .activities import * +from .activities import * diff --git a/automagica/activities.py b/automagica/activities.py index cbf189b5..5d7b208d 100644 --- a/automagica/activities.py +++ b/automagica/activities.py @@ -1,1478 +1,7680 @@ -import os -import platform -import shutil -from PIL import Image -import uuid -import psutil -from time import sleep -import pyautogui -''' -Delay activities -''' - - -def Wait(seconds=None): - ''' - Stall the execution of the preceding functions for a specified number of seconds. - ''' - sleep(seconds) - +def activity(func): + """Wrapper for Automagica activities + """ + from functools import wraps + import logging + + @wraps(func) + def wrapper(*args, **kwargs): + """Wrapper function + """ + if func.__doc__: + name = func.__doc__.split("\n")[0] + else: + name = func.__name__ + logging.info("Automagica (activity): {}".format(name)) + telemetry(func) + return func(*args, **kwargs) -''' -Keyboard/mouse activities -''' + return wrapper -def GetMouseCoordinates(): - ''' - Displays a message box with the absolute coordinates of the current position of the mouse. - ''' - coord = pyautogui.position() - coordstring = "( " + str(coord[0]) + " , " + str(coord[1]) + " )" - return DisplayMessageBox(coordstring, "Mouse Position") +def telemetry(func): + """Automagica Activity Telemetry + This allows us to collect information on the usage of + certain Automagica functionalities in order for us to keep improving + the software. If you would like to disable telemetry, make sure the + environment variable 'AUTOMAGICA_NO_TELEMETRY' is set. That way no + information is being shared with us. + """ + import requests + from uuid import getnode + import os + import platform + + if not os.environ.get("AUTOMAGICA_NO_TELEMETRY") and not os.environ.get( + "AUTOMAGICA_URL" + ): + if func.__doc__: + name = func.__doc__.split("\n")[0] + else: + name = func.__name__ + + data = { + "activity": name, + "machine_id": getnode(), + "os": { + "name": os.name, + "platform": platform.system(), + "release": platform.release(), + }, + } -def ClickOnPosition(x=None, y=None): - ''' - Clicks on a pixel position on the visible screen determined by x and y coördinates. - ''' - return pyautogui.click(x, y) + try: + r = requests.post( + "https://telemetry.automagica.com/", json=data, timeout=1 + ) + except: + pass -def DoubleClickOnPosition(x=None, y=None): - ''' - Double clicks on a pixel position on the visible screen determined by x and y coördinates. - ''' - return pyautogui.doubleClick(x, y) +""" +Cryptography +Icon: las la-shield-alt +""" -def RightClickOnPosition(x=None, y=None): - ''' - Right clicks on a pixel position on the visible screen determined by x and y coördinates. - ''' - return pyautogui.rightClick(x, y) +@activity +def generate_random_key(): + """Random key + Generate random Fernet key. Fernet guarantees that a message encrypted using it cannot be manipulated or read without the key. Fernet is an implementation of symmetric (also known as “secret key”) authenticated cryptography -def MoveToPosition(x=None, y=None): - ''' - Moves te pointer to a x-y position. - ''' - return pyautogui.moveTo(x, y) + :return: Bytes-like object + :Example: -def MoveRelative(x=None, y=None): - ''' - Moves the mouse an x- and y- distance relative to its current pixel position. - ''' - return pyautogui.moveRel(x, y) + >>> # Generate a random key + >>> generate_random_key() + b'AYv6ZPVgnrUtHDbGZqAopRyAo9r0_UKrA2Rm3K_NjIo=' + Keywords + random, key, fernet, hash, security, cryptography, password, secure -def DragToPosition(x=None, y=None, button="left"): - ''' - Drag the mouse from its current position to a entered x-y position, while holding a specified button. - ''' - return pyautogui.dragTo(x, y, 0.2, button=button) + Icon + las la-key + """ + import os + from cryptography.fernet import Fernet + key = Fernet.generate_key() + return key -def ClickOnImage(filename=None, double_click=False, right_click=False): - from pyautogui import locateCenterOnScreen, rightClick, click - x, y = locateCenterOnScreen(filename) - clicks = 2 if double_click else 1 - if right_click: - return rightClick(x, y) - else: - return click(x, y, clicks) +@activity +def encrypt_text_with_key(text, key): + """Encrypt text -def WaitOnImage(filename=None, timeout=120): - """ - Waits for an image to appear on the screen - """ - from pyautogui import locateCenterOnScreen - from time import sleep + Encrypt text with (Fernet) key, - for _ in range(timeout): - try: - locateCenterOnScreen(filename) - break - except TypeError: - sleep(1) + :parameter text: Text to be encrypted. + :parameter key: Path where key is stored. - + :return: bytes-like object. + :Example: -def PressKey(key=None): - ''' - Press and release an entered key. - ''' - if key: - return pyautogui.press(key) + >>> # Generate a random key + >>> key = generate_random_key() + >>> # Encrypt text with this key + >>> encrypt_text_with_key('Sample text', key) + b'gAAAAABd8lpG8fNqcj5eXrPPHlx4KeCm-1TgX3jkyhStMfIlgGImIa-qaINZAj8XcxPcG8iu84iT56b_qAW9c5qpe7btUFhtxQ==' + Keywords + random, encryption, secure, security, hash, password, fernet, text -def PressHotkey(first_key, second_key, third_key=None): - ''' - Press a combination of two or three keys simultaneously. - ''' - if not third_key: - return pyautogui.hotkey(first_key, second_key) - if third_key: - return pyautogui.hotkey(first_key, second_key, third_key) + Icon + las la-lock + """ + from cryptography.fernet import Fernet + f = Fernet(key) + return f.encrypt(text.encode('utf-8')) -def Type(text=None, interval_seconds=0.001): - ''' - Type text in the current active field. The first argument represent the text and is entered as a string. - The second variable is the time between two keystrokes. Pay attention that you can only press single - character keys. Keys like ":", "F1",... can not be part of the text argument. - ''' - from pyautogui import typewrite - # Set keyboard layout for Windows platform - if platform.system() == 'Windows': - from win32api import LoadKeyboardLayout - LoadKeyboardLayout('00000409', 1) - return typewrite(text, interval=interval_seconds) +@activity +def decrypt_text_with_key(encrypted_text, key): + """Decrypt text -def CapsLock(): - ''' - Press the Caps Lock key. - ''' - return pyautogui.press('capslock') + Dexrypt bytes-like object to string with (Fernet) key + :return: String -def NumLock(): - ''' - Press the Num Lock key. - ''' - return pyautogui.press('numlock') + :parameter encrypted_text: Text to be encrypted. + :parameter key: Path where key is stored. + :Example: -def Enter(): - ''' - Press the enter key. - ''' - return pyautogui.press('enter') + >>> # Generate a random key + >>> key = generate_random_key() + >>> # Encrypt text with generated key + >>> encrypted_text = encrypt_text_with_key('Sample text', key) + >>> # Decrypt text with same key + >>> decrypt_text_with_key(encrypted_text, key) + 'Sample text' + Keywords + decrypt, random, unlock, un-lock hash, security, cryptography, password, secure, hash, text -def SpaceBar(): - ''' - Press the space bar key. - ''' - return pyautogui.press('space') + Icon + las la-lock-open + """ + from cryptography.fernet import Fernet + f = Fernet(key) + return f.decrypt(encrypted_text).decode("utf-8") -def Backspace(): - ''' - Press the Backspace key. - ''' - return pyautogui.press('backspace') +@activity +def encrypt_file_with_key(input_path, key, output_path=None): + """Encrypt file -def Delete(): - ''' - Press the Delete key. - ''' - return pyautogui.press('delete') + Encrypt file with (Fernet) key. Note that file will be unusable unless unlocked with the same key. + :parameter input_file: Full path to file to be encrypted. + :parameter key: Path where key is stored. + :parameter output_file: Output path. Default is the same directory with "_encrypted" added to the name -def Endkey(): - ''' - Press the End key. - ''' - return pyautogui.press('end') + :return: Path to encrypted file + :Example: -def Tab(): - ''' - Press the Tab key. - ''' - return pyautogui.press('tab') + >>> # Generate a random key + >>> key = generate_random_key() + >>> # Create a textfile to illustrate file encryption + >>> textfile_path = make_textfile() + >>> # Encrypt the textfile + >>> encrypt_file_with_key(textfile_path, key=key) + 'C:\\Users\\\\generated_textfile_encrypted.txt' + Keywords + encrypt, random, password, secure, secure file, lock -def CreateUniqueKey(length=32): - ''' - universally unique identifier (UUID) is a 128-bit number used to identify information in computer systems. This key can be - considered as unique for there to be a one in a billion chance of duplication, 103 trillion version 4 UUIDs must be generated. - The general form is e.g. "123e4567-e89b-12d3-a456-426655440000". The argument specifies the length of the returned string. - If it is omitted, the entire 128-bit UUID is returned as a string. - ''' - return str(uuid.uuid4())[:length] + Icon + las la-lock + """ + # Set path if not specified + import os + if not output_path: + filepath = os.path.dirname(input_path) + base = os.path.basename(input_path) + filename = os.path.splitext(base)[0] + extension = os.path.splitext(base)[1] + output_path = os.path.join( + filepath, filename + '_encrypted' + extension) -def TypeInRunWindow(text=None): - ''' - Open the "Run" window and type the entered text. - ''' - if text: - PressHotkey("win", "r") - Type(text, 0.08) - Enter - return + from cryptography.fernet import Fernet + with open(input_path, 'rb') as f: + data = f.read() + fernet = Fernet(key) + encrypted = fernet.encrypt(data) -''' -Monitoring -''' + with open(output_path, 'wb') as f: + f.write(encrypted) + return output_path -def CPULoad(measure_time=1): - ''' - Returns average CPU load for all cores. - Measures once every second, adjust measure_time (seconds) to get a longer averaged measured time. Standard measure_time is 1 second. - ''' - cpu_measurements = [] - for x in range(measure_time): - cpu_measurements.append(psutil.cpu_percent(interval=1)) - return sum(cpu_measurements)/len(cpu_measurements) +@activity +def decrypt_file_with_key(input_path, key, output_path=None): + """Decrypt file -def NumberOfCPU(logical=True): - ''' - Returns the number of CPU's in the current system. - The parameter 'logical' determines if only logical units are added to the count, default value is True. - ''' - return psutil.cpu_count(logical=logical) + Decrypts file with (Fernet) key + :parameter input_file: Bytes-like file to be decrypted. + :parameter key: Path where key is stored. + :parameter output_file: Outputfile, make sure to give this the same extension as basefile before encryption. Default is the same directory with "_decrypted" added to the name -def CPUFreq(): - ''' - Returns frequency at which CPU currently operates. - Also shows minimum and maximum frequency. - ''' - return psutil.cpu_freq() + :return: Path to decrypted file + :Example: -def CPUStats(): - ''' - Returns CPU statistics: Number of CTX switches, intterupts, soft-interrupts and systemcalls. - ''' - return psutil.cpu_stats() + >>> # Generate a random key + >>> key = generate_random_key() + >>> # Create a textfile to encrypt file + >>> textfile_path = make_textfile() + >>> # Encrypt the textfile + >>> encrypted_textfile = encrypt_file_with_key(textfile_path, key=key) + >>> # Decrypt the newly encrypted file + >>> decrypt_file_with_key(encrypted_textfile, key=key) + 'C:\\Users\\\\generated_textfile_encrypted_decrypted.txt' + Keywords + decrypt, random, password, secure, secure file, unlock -def MemoryStats(mem_type='swap'): - ''' - Returns memory statistics: total, used, free and percentage in use. - Choose mem_type = 'virtual' for virtual memory, and mem_type = 'swap' for swap memory (standard). - ''' - if mem_type == 'virtual': - return psutil.virtual_memory() - else: - return psutil.swap_memory() + Icon + las la-lock-open + """ + # Set path if not specified + import os + if not output_path: + filepath = os.path.dirname(input_path) + base = os.path.basename(input_path) + filename = os.path.splitext(base)[0] + extension = os.path.splitext(base)[1] + output_path = os.path.join( + filepath, filename + '_decrypted' + extension) + from cryptography.fernet import Fernet + with open(input_path, 'rb') as f: + data = f.read() -def DiskStats(): - ''' - Returns disk statistics of main disk: total, used, free and percentage in use. - ''' - return psutil.disk_usage('/') + fernet = Fernet(key) + decrypted = fernet.decrypt(data) + with open(output_path, 'wb') as f: + f.write(decrypted) -def DiskPartitions(): - ''' - Returns tuple with info for every partition. - ''' - return psutil.disk_partitions() + return output_path -def BootTime(): - ''' - Returns time PC was booted in seconds after the epoch. - ''' - return psutil.boot_time() +@activity +def generate_key_from_password(password, salt=None): + """Key from password + Generate key based on password and salt. If both password and salt are known the key can be regenerated. -def TimeSinceLastBoot(): - ''' - Returns time since last boot in seconds. - ''' - import time - return time.time() - psutil.boot_time() + :parameter password: Passwords + :parameter salt: Salt to generate key in combination with password. Default value is the hostname. Take in to account that hostname is necessary to generate key, e.g. when files are encrypted with salt 'A' and password 'B', both elements are necessary to decrypt files. + :return: Bytes-like object -''' -Windows activities -''' + :Example: + >>> # Generate a key from password + >>> key = generate_key_from_password(password='Sample password') + b'7jGGF5w_xyI0CIZGCmLlnNyUvFpNvIUY08JCHopgAmm8=' -def BeepSound(frequency=1000, duration=250): - ''' - Makes a beeping sound. - Choose frequency (Hz) and duration (ms), standard is 1000 Hz and 250 ms. - ''' - import winsound - winsound.Beep(frequency, duration) - return + Keywords + random, key, fernet, hash, security, cryptography, password, secure, salt + Icon + las la-lock + """ + import base64 + from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives import hashes + from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC + import socket -def UseFailsafe(switch=True): - from pyautogui import FAILSAFE - FAILSAFE = switch + # If no salt is set, use hostname as salt + if not salt: + salt = socket.gethostname().encode('utf-8') + kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, + salt=salt, iterations=500000, backend=default_backend()) + key = base64.urlsafe_b64encode(kdf.derive(password.encode('utf-8'))) -def ClearClipboard(): - ''' - Removes everything from the clipboard. - ''' - from ctypes import windll - if windll.user32.OpenClipboard(None): - windll.user32.EmptyClipboard() - windll.user32.CloseClipboard() - return + return key -''' -Process activities -''' +@activity +def generate_hash_from_file(input_path, method='md5', buffer_size=65536): + """Hash from file + Generate hash from file -def ProcessRunning(name): - ''' - Checks if given process name (name) is currently running on the system. - Returns True or False. - ''' - if name: - for p in psutil.process_iter(): - if name in p.name(): - return True - return False + Can be used to create unique identifier for file validation or comparison. + :parameter file: File to hash + :parameter method: Method for hashing, choose between 'md5', 'sha256' and 'blake2b'. Note that different methods generate different hashes. Default method is 'md5'. + :parameter buffer_size: Buffer size for reading file in chunks, default value is 64kb -def ListRunningProcesses(): - ''' - Returns a list with all names of unique processes currently running on the system. - ''' - process_list = [] - for p in psutil.process_iter(): - process_list.append(p.name()) - return set(process_list) + :return: Bytes-like object + :Example: -def ChromeRunning(): - ''' - Returns True is Chrome is running. - ''' - for p in psutil.process_iter(): - if "chrome.exe" in p.name(): - return True - return False + >>> # Generate a text file to illustrate hash + >>> textfile_path = make_textfile() + >>> # Get hash from textfile + >>> generate_hash_from_file(textfile_path) + '1ba249ca5931f3c85fe44d354c2f274d' + Keywords + hash, mdf5, sha256, blake2b, identifier, unique, hashing, fingerprint, comparison -def WordRunning(): - ''' - Returns True is Word is running. - ''' - for p in psutil.process_iter(): - if "winword.exe" in p.name().lower(): - return True - return False + Icon + las la-fingerprint + """ + import sys + import hashlib -def ExcelRunning(): - ''' - Returns True is Excel is running. - ''' - for p in psutil.process_iter(): - if "excel.exe" in p.name(): - return True - return False + # Arbitrary buffer size. 64kb for compatibility with most systems + buffer_size = 65536 + if method == 'md5': + hash_list = hashlib.md5() + if method == 'sha256': + hash_list = hashlib.sha1() + if method == 'blake2b': + hash_list = hashlib.blake2b() -def PowerpointRunning(): - ''' - Returns True is Powerpoint is running. - ''' - for p in psutil.process_iter(): - if "powerpnt.exe" in p.name().lower: - return True - return False + with open(input_path, 'rb') as f: + while True: + data = f.read(buffer_size) + if data: + hash_list.update(data) + else: + return hash_list.hexdigest() -def DropboxRunning(): - ''' - Returns True is Dropbox is running. - ''' - for p in psutil.process_iter(): - if "dropbox.exe" in p.name().lower(): - return True - return False +@activity +def generate_hash_from_text(text, method='md5'): + """Hash from text + Generate hash from text -def FirefoxRunning(): - ''' - Returns True is Firefox is running. - ''' - for p in psutil.process_iter(): - if "firefox.exe" in p.name().lower(): - return True - return False + :parameter file: Text to hash + :parameter method: Method for hashing, choose between 'md5', 'sha256' and 'blake2b'. Note that different methods generate different hashes. Default method is 'md5'. -def TeamviewerRunning(): - ''' - Returns True is Teamviewer is running. - ''' - for p in psutil.process_iter(): - if "teamviewer.exe" in p.name().lower(): - return True - return False + :Example: + >>> # Generate a hast from text + >>> generate_hash_from_text('Sample text') + '1ba249ca5931f3c85fe44d354c2f274d' -def SkypeRunning(): - ''' - Returns True is Skype is running. - ''' - for p in psutil.process_iter(): - if "skypehost.exe" in p.name().lower(): - return True - return False + Keywords + Hash, mdf5, sha256, blake2b, identifier, unique, hashing, fingerprint, text, comparison + Icon + las la-fingerprint -def EdgeRunning(): - ''' - Returns True is Microsoft Edge is running. - ''' - for p in psutil.process_iter(): - if "microsoftedge.exe" in p.name().lower(): - return True - return False + """ + import sys + import hashlib + encoded_text = text.encode('utf-8') -def OnedriveRunning(): - ''' - Returns True is Onedrive is running. - ''' - for p in psutil.process_iter(): - if "onedrive.exe" in p.name().lower(): - return True - return False + if method == 'md5': + return hashlib.md5(encoded_text).hexdigest() + if method == 'sha256': + return hashlib.sha256(encoded_text).hexdigest() + if method == 'blake2b': + return hashlib.balke2b(encoded_text).hexdigest() -def IllustratorRunning(): - ''' - Returns True is Illustrator is running. - ''' - for p in psutil.process_iter(): - if "illustrator.exe" in p.name().lower(): - return True - return False +""" +Random +Icon: las la-dice-d6 +""" -def LaunchProcess(process_executable=None): - from subprocess import Popen +@activity +def generate_random_number(lower_limit=0, upper_limit=100, fractional=False): + """Random number - return Popen(process_executable) + Random numbers can be integers (not a fractional number) or a float (fractional number). + :parameter lower_limit: Lower limit for random number + :parameter upper_limit: Upper limit for random number + :parameter fractional: Setting this to True will generate fractional number. Default value is False and only generates whole numbers. -def OpenProgramByName(name, main_drive="C:\\"): - from subprocess import Popen + :return: Random integer or float - if not name[-4:] == ".exe": - name = name + ".exe" - for root, dirs, files in os.walk(main_drive): - for file in files: - if file == name and file.endswith(".exe"): - Popen(os.path.join(root, file)) - return + :Example: + >>> # Generate a random number + >>> generate_random_number() + 7 -def KillProcess(process=None, name=None): - if process: - return process.kill() - if name: - return os.system("taskkill /f /im " + name + " >nul 2>&1") - return + Keywords: + random number, random integer, dice, gamble, rng, random + Icon + las la-dice + """ + import random + if fractional: + return random.uniform(lower_limit, upper_limit) + else: + return random.randrange(lower_limit, upper_limit, 1) -''' -Browser activities -''' +@activity +def generate_random_boolean(): + """Random boolean -def ChromeBrowser(ignore_images=False, headless=False): - ''' + Generates a random boolean (True or False) - Opens the Chrome Browser in a Selenium instance. + :return: Boolean - Args: - ignore_images (bool): do not load images - headless (bool): run without a window + :Example: - Returns: - webdriver: Selenium Webdriver + >>> # Generate a random boolean + >>> generate_random_boolean() + True - Example: - browser = ChromeBrowser(ignore_iamges=True) - browser.get('https://automagica.io') + Keywords: + random, dice, gamble, rng, coin, coinflip, heads, tails - ''' - if platform.system() == 'Linux': - chromedriver_path = '\\bin\\webdriver\\linux64\\chromedriver' - elif platform.system() == 'Windows': - chromedriver_path = '\\bin\\win32\\chromedriver.exe' + Icon + las la-coins + """ + import random + return bool(random.getrandbits(1)) + + +@activity +def generate_random_name(locale=None): + """Random name + + Generates a random name. Adding a locale adds a more common name in the specified locale. Provides first name and last name. + + :parameter locale: Add a locale to generate popular name for selected locale. + + - ar_EG - Arabic (Egypt) + - ar_PS - Arabic (Palestine) + - ar_SA - Arabic (Saudi Arabia) + - bg_BG - Bulgarian + - bs_BA - Bosnian + - cs_CZ - Czech + - de_DE - German + - dk_DK - Danish + - el_GR - Greek + - en_AU - English (Australia) + - en_CA - English (Canada) + - en_GB - English (Great Britain) + - en_NZ - English (New Zealand) + - en_US - English (United States) + - es_ES - Spanish (Spain) + - es_MX - Spanish (Mexico) + - et_EE - Estonian + - fa_IR - Persian (Iran) + - fi_FI - Finnish + - fr_FR - French + - hi_IN - Hindi + - hr_HR - Croatian + - hu_HU - Hungarian + - hy_AM - Armenian + - it_IT - Italian + - ja_JP - Japanese + - ka_GE - Georgian (Georgia) + - ko_KR - Korean + - lt_LT - Lithuanian + - lv_LV - Latvian + - ne_NP - Nepali + - nl_NL - Dutch (Netherlands) + - no_NO - Norwegian + - pl_PL - Polish + - pt_BR - Portuguese (Brazil) + - pt_PT - Portuguese (Portugal) + - ro_RO - Romanian + - ru_RU - Russian + - sl_SI - Slovene + - sv_SE - Swedish + - tr_TR - Turkish + - uk_UA - Ukrainian + - zh_CN - Chinese (China) + - zh_TW - Chinese (Taiwan) + + :return: Name as string + + :Example: + + >>> # Generate a random name + >>> generate_random_name() + 'Michelle Murphy' + + Keywords + random, dummy name, name, name generater, fake person, fake, person, surname, lastname, fake name generator + + Icon + las la-user-tag + """ + from faker import Faker + if locale: + seed = Faker(locale) + else: + seed = Faker() + return seed.name() + + +def generate_random_sentence(locale=None): + """Random sentence + + Generates a random sentence. Specifying locale changes language and content based on locale. + + :parameter locale: Add a locale to generate popular name for selected locale. + + - ar_EG - Arabic (Egypt) + - ar_PS - Arabic (Palestine) + - ar_SA - Arabic (Saudi Arabia) + - bg_BG - Bulgarian + - bs_BA - Bosnian + - cs_CZ - Czech + - de_DE - German + - dk_DK - Danish + - el_GR - Greek + - en_AU - English (Australia) + - en_CA - English (Canada) + - en_GB - English (Great Britain) + - en_NZ - English (New Zealand) + - en_US - English (United States) + - es_ES - Spanish (Spain) + - es_MX - Spanish (Mexico) + - et_EE - Estonian + - fa_IR - Persian (Iran) + - fi_FI - Finnish + - fr_FR - French + - hi_IN - Hindi + - hr_HR - Croatian + - hu_HU - Hungarian + - hy_AM - Armenian + - it_IT - Italian + - ja_JP - Japanese + - ka_GE - Georgian (Georgia) + - ko_KR - Korean + - lt_LT - Lithuanian + - lv_LV - Latvian + - ne_NP - Nepali + - nl_NL - Dutch (Netherlands) + - no_NO - Norwegian + - pl_PL - Polish + - pt_BR - Portuguese (Brazil) + - pt_PT - Portuguese (Portugal) + - ro_RO - Romanian + - ru_RU - Russian + - sl_SI - Slovene + - sv_SE - Swedish + - tr_TR - Turkish + - uk_UA - Ukrainian + - zh_CN - Chinese (China) + - zh_TW - Chinese (Taiwan) + + :return: Random sentence as string + + :Example: + + >>> # Generate a random sentence + >>> generate_random_sentence() + 'The age of automation is going to be the age of do-it-yourself' + + Keywords + random, sentence, lorem ipsum, text generater, filler, place holder, noise, random text + + Icon + las la-comment + """ + from faker import Faker + if locale: + seed = Faker(locale) + else: + seed = Faker() + return seed.sentence() + + +@activity +def generate_random_address(locale=None): + """Random address + + Generates a random address. Specifying locale changes random locations and streetnames based on locale. + + :parameter locale: Add a locale to generate popular name for selected locale. + + - ar_EG - Arabic (Egypt) + - ar_PS - Arabic (Palestine) + - ar_SA - Arabic (Saudi Arabia) + - bg_BG - Bulgarian + - bs_BA - Bosnian + - cs_CZ - Czech + - de_DE - German + - dk_DK - Danish + - el_GR - Greek + - en_AU - English (Australia) + - en_CA - English (Canada) + - en_GB - English (Great Britain) + - en_NZ - English (New Zealand) + - en_US - English (United States) + - es_ES - Spanish (Spain) + - es_MX - Spanish (Mexico) + - et_EE - Estonian + - fa_IR - Persian (Iran) + - fi_FI - Finnish + - fr_FR - French + - hi_IN - Hindi + - hr_HR - Croatian + - hu_HU - Hungarian + - hy_AM - Armenian + - it_IT - Italian + - ja_JP - Japanese + - ka_GE - Georgian (Georgia) + - ko_KR - Korean + - lt_LT - Lithuanian + - lv_LV - Latvian + - ne_NP - Nepali + - nl_NL - Dutch (Netherlands) + - no_NO - Norwegian + - pl_PL - Polish + - pt_BR - Portuguese (Brazil) + - pt_PT - Portuguese (Portugal) + - ro_RO - Romanian + - ru_RU - Russian + - sl_SI - Slovene + - sv_SE - Swedish + - tr_TR - Turkish + - uk_UA - Ukrainian + - zh_CN - Chinese (China) + - zh_TW - Chinese (Taiwan) + + :return: Random address as string + + :Example: + + >>> # Generate a random address + >>> generate_random_address() + '5639 Cynthia Bridge Suite 610 + 'Port Nancy, GA 95894' + + Keywords + random, address, random address, fake person , fake address, fake person generator + + Icon + las la-map + """ + from faker import Faker + if locale: + seed = Faker(locale) else: - chromedriver_path = '\\bin\\mac64\\chromedriver.exe' + seed = Faker() + return seed.address() - from selenium.webdriver import Chrome, ChromeOptions - chrome_options = ChromeOptions() +@activity +def generate_random_beep(max_duration=2000, max_frequency=5000): + """Random beep - if headless: - chrome_options.add_argument("--headless") + Generates a random beep, only works on Windows - if ignore_images: - prefs = {"profile.managed_default_content_settings.images": 2} - chrome_options.add_experimental_option("prefs", prefs) + :parameter max_duration: Maximum random duration in miliseconds. Default value is 2 miliseconds + :parameter max_frequency: Maximum random frequency in Hz. Default value is 5000 Hz. - return Chrome(os.path.abspath(__file__).replace('activities.py', '') + chromedriver_path, chrome_options=chrome_options) + :return: Sound + :Example: -def GetGoogleSearchLinks(search_text): - ''' - Return a list with the links on the first page of google when searching for the entered text. - This text needs to be entered as a string. - ''' - import urllib - import requests - from bs4 import BeautifulSoup - r = requests.get('https://www.google.com/search?&q=' + - urllib.parse.quote_plus(search_text)) - soup = BeautifulSoup(r.content, "html.parser") - links = [] - for block in soup.findAll('h3', {'class': 'r'}): - link = block.a.get('href').split("?q=")[1].split("&sa=U")[0] - if 'https' in link: - links.append(link) - return links + >>> # Generate a random beep + >>> generate_random_beep() + Keywords + beep, sound, random, noise, alert, notification -''' -OCR activities -''' + Icon + las la-volume-up + """ + import winsound + import random + frequency = random.randrange(5000) + duration = random.randrange(2000) + winsound.Beep(frequency, duration) -def ExtractTextFromImage(filename=None): - import pytesseract - if platform.system() == 'Windows': - pytesseract.pytesseract.tesseract_cmd = 'C:\\Program Files (x86)\\Tesseract-OCR\\tesseract' - from pytesseract import image_to_string - return image_to_string(Image.open(filename)) +@activity +def generate_random_date(formatting='%m/%d/%Y %I:%M', days_in_past=1000): + """Random date + + Generates a random date. + + - %a Abbreviated weekday name. + - %A Full weekday name. + - %b Abbreviated month name. + - %B Full month name. + - %c Predefined date and time representation. + - %d Day of the month as a decimal number [01,31]. + - %H Hour (24-hour clock) as a decimal number [00,23]. + - %I Hour (12-hour clock) as a decimal number [01,12]. + - %j Day of the year as a decimal number [001,366]. + - %m Month as a decimal number [01,12]. + - %M Minute as a decimal number [00,59]. + - %p AM or PM. + - %S Second as a decimal number [00,61]. + - %U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. + - %w Weekday as a decimal number [0(Sunday),6]. + - %W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. + - %x Predefined date representation. + - %X Predefined time representation. + - %y Year without century as a decimal number [00,99]. + - %Y Year with century as a decimal number. + - %Z Time zone name (no characters if no time zone exists). + + :parameter days_in_past: Days in the past for which oldest random date is generated, default is 1000 days + :parameter formatting: Formatting of the dates, replace with 'None' to get raw datetime format. e.g. format='Current month is %B' generates 'Current month is Januari' and format='%m/%d/%Y %I:%M' generates format 01/01/1900 00:00. + + :return: Random date as string + + :Example: + + >>> # Generate a random date + >>> generate_random_date() + 01/01/2020 13:37' + + Keywords + random, date, datetime, random date, fake date , calendar + + Icon + las la-calendar + """ + import random + import datetime -''' -Excel activities -''' + latest = datetime.datetime.now() + earliest = latest - datetime.timedelta(days=days_in_past) + delta_seconds = (latest - earliest).total_seconds() -from openpyxl import load_workbook, Workbook + random_date = earliest + \ + datetime.timedelta(seconds=random.randrange(delta_seconds)) -# Renaming functions -OpenExcelWorkbook = load_workbook + if formatting: + return random_date.strftime(formatting) + else: + return random_date -# Renaming classes -NewExcelWorkbook = Workbook +@activity +def generate_unique_identifier(): + """Generate unique identifier -def ExcelCreateWorkbook(path): - ''' - Create a new .xlsx file and save it under a specified path. If the entered path already - exists, the function does nothing. - ''' - if not os.path.exists(path): - Workbook().save(path) - return + Generates a random UUID4 (universally unique identifier). While the probability that a UUID will be duplicated is not zero, it is close enough to zero to be negligible. + :return: Identifier as string -def ExcelOpenWorkbook(path): - ''' - Open a .xlsx file with Microsoft Excel. Make sure you enter a valid path. This can be a path - referencing an existing .xlsx file e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". - This will open the existing file. You can also enter a comletely new path. In this case, the - function creates a new .xlsx file with that path and opens it with Excel. - ''' - if os.path.exists(path): - os.startfile(path) - elif not os.path.exists(path): - ExcelCreateWorkbook(path) - os.startfile(path) - return + :Example: + >>> # Generate unique identifier + >>> generate_unique_identifier() + 'd72fd7ea-d682-4f78-8ca1-0ed34142a992' -def ExcelSaveExistingWorkbook(path, new_path=None): - ''' - Save (as) an existing .xlsx file. The second variable is the new path the file needs to be saved - at. You can ignore this variable if you just want to save the file and do not want to "save as". - For the function to work properly, it is important that the file you want to save is not opened. - ''' - workbook = load_workbook(path) - if not new_path: - workbook.save(path) - elif not os.path.isfile(new_path): - workbook.save(new_path) - return + Keywords + unique, identifier, primary key, random + Icon + las la-random + """ + from uuid import uuid4 -def ExcelCreateWorkSheet(path, sheet_name=None): - ''' - Create a new worksheet with a specified name in an existing workbook specified by the path variable. If - no sheet_name is entered, the new sheet is named "sheet1", "sheet2", "sheet3", ..., depending on the sheets - that already exist. - Make shure you enter a valid path referencing a .xlsx file e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". - For the function to work properly, it is important that the .xlsx file is closed during the execution. - ''' - workbook = load_workbook(path) - if sheet_name and sheet_name not in workbook.get_sheet_names(): - workbook.create_sheet(title=sheet_name) - elif not sheet_name: - workbook.create_sheet() - workbook.save(path) - return + return str(uuid4()) -def ExcelGetSheets(path): - ''' - Return a list containing the sheet names of an Excel file. Make shure you enter a valid path - referencing a .xlsx file e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". - ''' - workbook = load_workbook(path) - return workbook.get_sheet_names() - - -def ExcelReadCell(path, cell="A1", sheet=None): - ''' - Read a cell from an Excel file and return its value. - Make sure you enter a valid path e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". - The cell you want to read needs to be defined by a cell name e.g. "A2". The third variable - is a string with the name of the sheet that needs to be read. If omitted, the - function reads the entered cell of the active sheet. - ''' - workbook = load_workbook(path) - if sheet: - worksheet = workbook.get_sheet_by_name(sheet) - else: - worksheet = workbook.active - - return worksheet[cell].value - - -def ExcelReadRowCol(path, r=1, c=1, sheet=None): - ''' - Read a Cell from an Excel file and return its value. - Make sure you enter a valid path e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". - The cell you want to read needs to be row and a column. E.g. r = 2 and c = 3 refers to cell C3. - The third variable needs to be a string with the name of the sheet that needs to be read. - If omitted, the function reads the entered cell of the active sheet. First row is defined - row number 1 and first column is defined column number 1. - ''' - workbook = load_workbook(path) - if sheet: - worksheet = workbook.get_sheet_by_name(sheet) - else: - worksheet = workbook.active - - return worksheet.cell(row=r, column=c).value - - -def ExcelWriteRowCol(path, sheet=None, r=1, c=1, write_value='Value'): - ''' - Write a value to a Cell to an Excel file. - Make sure you enter a valid path e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx"... - The cell should be defined by a row and a column. E.g. row=4, column=8. - First row is defined row number 1 and first column is defined column number 1... - Value can be anything, standard is "Value". - When executing the code, make sure .xlsx file you want to write is closed. - ''' - workbook = load_workbook(path) - if sheet: - worksheet = workbook.get_sheet_by_name(sheet) - else: - worksheet = workbook.active - worksheet.cell(row=r, column=c).value = write_value - workbook.save(path) - return +""" +User Input +Icon: lab la-wpforms +""" -def ExcelWriteCell(path, sheet=None, cell="A1", write_value='Value'): - ''' - Write a Cell to an Excel file. - Make sure you enter a valid path e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx"... - The cell should be defined by a cell name. E.g. "B6". - Value can be anything, standard is "Value". - When executing the code, make sure .xlsx file you want to write is closed. - ''' - workbook = load_workbook(path) - if sheet: - worksheet = workbook.get_sheet_by_name(sheet) - else: - worksheet = workbook.active +@activity +def ask_user_input(title="Title", label="Input", password=False): + """Ask user for input - worksheet[cell] = write_value - workbook.save(path) - return + Prompt the user for an input with a pop-up window. + :parameter title: Title for the pop-up window + :parameter message: The message to be shown to the user -def ExcelPutRowInList(path, start_cell, end_cell, sheet=None): - ''' - Put the elements of a specified row in a list. The .xlsx file and sheet that needs to be read are - specified by respectively the path- and sheet variable. If no sheet is specified, the sheet-variable - is set to the current active sheet. Also make shure to enter a valid path e.g. - "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". - The row is specified by strings referring to the first and final cell. E.g. start_cell = "B3" - and end_cell = "E3" will put all the elements of the third row from cell "B3" to cell "E3" in - a list: ["B3", "C3", "D3", "E3"]. For the function to work, the two cells need to be of the same row and start_cell needs to be - the cell at the left hand side. - ''' - workbook = load_workbook(path) - if sheet: - worksheet = workbook.get_sheet_by_name(sheet) - else: - worksheet = workbook.active - - values = [] - for rowobj in worksheet[start_cell:end_cell][0]: - values.append(rowobj.value) - - return values - - -def ExcelPutColumnInList(path, start_cell, end_cell, sheet=None): - ''' - Put the elements of a specified column in a list. The .xlsx file and sheet that needs to be read are - specified by respectively the path- and sheet variable. If no sheet is specified, the sheet-variable - is set to the current active sheet. Also make shure to enter a valid path e.g. - "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". - The column is specified by strings referring to the first and final cell. E.g. start_cell = "E3" - and end_cell = "E6" will put all the elements of the fifth column from cell "E3" to cell "E6" in - a list: ["E3", "E4", "E5", "E6]. For the function to work, the two cells need to be of the same - column and start_cell needs to be the upper cell. - ''' - workbook = load_workbook(path) - if sheet: - worksheet = workbook.get_sheet_by_name(sheet) - else: - worksheet = workbook.active - - values = [] - for colobj in worksheet[start_cell:end_cell]: - values.append(colobj[0].value) - - return values - - -def ExcelPutSelectionInMatrix(path, upper_left_cell, bottom_right_cell, sheet=None): - ''' - Put the elements of a specified selection in a matrix. The .xlsx file and sheet that needs to be read are - specified by respectively the path- and sheet variable. If no sheet is specified, the sheet-variable - is set to the current active sheet. Also make shure to enter a valid path e.g. - "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". - The selection is specified by strings referring to the upper left and bottom right cell. - E.g. upper_left_cell = "B2" and bottom_right_cell = "C3" will return a matrix with values: - [["B2", "C2"], ["B3", "C3"]]. If a cell is empty, its value is set to "None". - ''' - workbook = load_workbook(path) - if sheet: - worksheet = workbook.get_sheet_by_name(sheet) - else: - worksheet = workbook.active + :return: Inputted text as string - matrix = [] - for rowobj in worksheet[upper_left_cell:bottom_right_cell]: - next_row = [] - for cellobj in rowobj: - next_row.append(cellobj.value) - matrix.append(next_row) + :Example: - return matrix + >>> # Make a window pop-up ask for user input + >>> ask_user_input() + >>> # Type in text and press 'submit', e.g. 'Sample text' + 'Sample text' + Keywords + user input, pop-up, interaction, popup, window, feedback, screen, ad-hoc, attended -''' -Word activities -''' + Icon + las la-window-maximize + """ + import PySimpleGUI as sg + sg.ChangeLookAndFeel("SystemDefault") -def OpenWordDocument(filename=None): - from docx import Document - return Document(filename) + text = sg.Text(label, background_color="#2196F3", text_color="white") + input_field = sg.InputText(justification="center", focus=True) -def ReplaceText(document, text=None, replace_with=None): - for paragraph in document.paragraphs: - paragraph.text = paragraph.text.replace(text, replace_with) - return document + if password: + input_field = sg.InputText( + password_char="*", justification="center", focus=True + ) + submit_button = sg.Submit(button_color=("white", "#0069C0")) -def ConvertWordToPDF(word_filename=None, pdf_filename=None): - if platform.system() == 'Windows': - from win32com import client - word = client.DispatchEx('Word.Application') - word_document = word.Documents.Open(word_filename) - word_document.SaveAs(pdf_filename, FileFormat=17) - word_document.Close() - else: - print('Not implemented for other platforms than Windows.') + layout = [[text], [input_field], [submit_button]] + window = sg.Window( + title, + layout, + icon="icon.ico", + no_titlebar=True, + background_color="#2196F3", + element_justification="center", + use_default_focus=False, + keep_on_top=True + ) + _, values = window.Read() + window.Close() + value = values[0] -''' -PDF Activities -''' + return value -import PyPDF2 +@activity +def ask_user_password(label="Password"): + """Ask user for password -def MergePDF(pdf1, pdf2, merged_path): - ''' - The first two arguments are the PDF's that need to be merged, entered as a path. The pages from pdf2 - will be added to pdf2. The merged PDF receives a new path specefied by the third argument. - ''' - from PyPDF2 import PdfFileMerger + Prompt the user for a password. The password will be masked on screen while entering. - pdfs = [str(pdf1), str(pdf2)] + :parameter title: Title for the pop-up window + :parameter message: The message to be shown to the user - merger = PdfFileMerger() + :return: Inputted password as string - for pdf in pdfs: - merger.append(pdf) + :Example: - merger.write(merged_path) - return + >>> # Make a window pop-up ask for user password + >>> ask_user_password() + >>> # Type in password and press 'submit', e.g. 'Sample password' + 'Sample password' + Keywords + user input, pop-up, interaction, interactive, credential, popup, window, feedback, password, screen, login, attended -def ExtractTextFromPDFPage(path, page=1): - ''' - This function extracts all the text from a given page and returns it as a string. The pdf needs to be - entered as a path. Pay attention that the entered page needs to be greater than 0. - ''' - if os.path.isfile(path) and page > 0: - pdfFile = open(path, "rb") - pdfReader = PyPDF2.PdfFileReader(pdfFile) - if page <= pdfReader.numPages: - pdfPage = pdfReader.getPage(page-1) - else: - pdfPage = pdfReader.getPage(pdfReader.numPages - 1) - return pdfPage.extractText() + Icon + lar la-window-maximize + """ + return ask_user_input(title="Password", label=label, password=True) -''' -Message boxes -''' +@activity +def ask_credentials(title="Credentials required", dialogue_text_username="Username:", dialogue_text_password="Password:"): + """Ask user for credentials + Prompt a popup which asks user for username and password and returns in plain text. Password will be masked. -def DisplayMessageBox(body, title="Message", type="info"): - ''' - Shows a pop-up message with title and body. Three possible types, info, error and warning with the default value info. - ''' - import tkinter - from tkinter import messagebox + :parameter title: Title for the popup + :parameter dialogue_text: Dialogue text for username + :parameter dialogue_text: Dialogue text for password - # hide main window - root = tkinter.Tk() - root.withdraw() + :return: Typle with nputted username and password as strings - if not body: - messagebox.showwarning("Warning", "No input for message box") + :Example: - if type == "error": - messagebox.showwarning(title, body) - if type == "warning": - messagebox.showwarning(title, body) - if type == "info": - messagebox.showinfo(title, body) - return + >>> # Make a window pop-up ask user credentials + >>> ask_credentials() + >>> # Type in Username and Password 'submit', e.g. 'Sample username' and 'Sample password' + ('Sample username', 'Sample password') + Keywords + user input, credentials, interactive, pop-up, interaction, popup, window, feedback, password, screen, login, attended -def RequestUserInput(): - ''' - Shows a pop-up message which asks for input which is captured and returned. - ''' - from tkinter import Tk - from tkinter.simpledialog import askstring + Icon + las la-window-maximize + """ + import PySimpleGUI as sg + + sg.ChangeLookAndFeel("SystemDefault") + + layout = [ + [ + sg.Text( + dialogue_text_username, background_color="#2196F3", text_color="white" + ) + ], + [sg.InputText(justification="center", focus=True)], + [ + sg.Text( + dialogue_text_password, background_color="#2196F3", text_color="white" + ) + ], + [sg.InputText(password_char="*", justification="center")], + [sg.Submit(button_color=("white", "#0069C0"))], + ] + + window = sg.Window( + title, + layout, + icon="icon.ico", + no_titlebar=True, + background_color="#2196F3", + element_justification="center", + use_default_focus=False, + keep_on_top=True + ) + _, values = window.Read() - root = Tk() - root.withdraw() # hide main window + window.Close() + username = values[0] + password = values[1] - text = askstring("Input", "Give input:") - return text + return username, password +@activity +def display_message_box(title="Title", message="Example message"): + """Shows message box -def StartFile(path): - from os import startfile - startfile(path) - return + A pop-up message with title and message. + :parameter title: Title for the pop-up window + :parameter message: The message to be shown to the user -''' -File Operations -''' + :return: True if user presses 'OK' + :Example: -def OpenFile(path): - ''' - Entering "C:\\Users\\Downloads\\Automagica.docx" as pathname will open the .docx-file "Automagica.docx". - ''' - if os.path.isfile(path): - os.startfile(path) - return + >>> # Show pop-up with message + >>> display_message_box() + >>> # Wait till user presses 'OK' + True + Keywords + message box, warning, info, popup, window, feedback, screen, attended -def RenameFile(old_path, new_file_name): - ''' - Entering "C:\\Users\\Documents\\Automagica.docx" as "old_path" and "Automagica123.docx" as new_file_name changes - the name of the directory in C:\\Users\\Documents from Automagica to Automagica123. The function will not - rename a file if a file with the desired name already exists in the folder. - ''' - if os.path.isfile(old_path): - base_path = old_path.split("\\")[:-1] - new_path = "\\".join(base_path)+"\\" + new_file_name - if not os.path.exists(new_path): - os.rename(old_path, new_path) - return + Icon + las la-window-maximize + """ + import PySimpleGUI as sg + sg.ChangeLookAndFeel("SystemDefault") -def MoveFile(old_path, new_location): - ''' - Entering "C:\\Users\\Documents\\Automagica.docx" as old_path and "C:\\Users\\Downloads" - as new_location moves the file Automagica.docx from directory "Documents" to directory "Downloads". - If the new location already contains a file with the same name, a random 8 character uid will be added - in front of the name before the file is moved. - ''' - import uuid - name = old_path.split("\\")[-1] - new_path = new_location + "\\" + name - if os.path.exists(old_path): - if not os.path.exists(new_path): - os.rename(old_path, new_path) - elif os.path.exists(new_path): - new_path = new_location + "\\" + \ - "(" + str(uuid.uuid4())[:8] + ") " + name - os.rename(old_path, new_path) - return + text = sg.Text(message, background_color="#2196F3", text_color="white") + ok_button = sg.OK(button_color=("white", "#0069C0")) -def RemoveFile(path): - ''' - Entering "C:\\Users\\Downloads\\Automagica.xlsx" will delete the file named "Automagica.xlsx" at the location specified by - the given path. - ''' - if os.path.isfile(path): - os.remove(path) - return + layout = [[text], [ok_button]] + window = sg.Window( + title, + layout, + icon="icon.ico", + no_titlebar=True, + background_color="#2196F3", + element_justification="center", + use_default_focus=False, + keep_on_top=True + ) + _, values = window.Read() + window.Close() -def FileExists(path): - ''' - This function checks whether the file with the given path exists, e.g. by entering - "C:\\Users\\Documents\\Automagica.docx", the function returns True if the file exists or False - if it doesn't exist. - ''' - return os.path.isfile(path) + return True -def CopyFile(old_path, new_path): - ''' - By entering "C:\\Users\\Documents\\Automagica.docx" as old_path and "C:\\Users\\Downloads" as new_location... - the function copies the file "Automagica.docx" to the new location. If the new location already contains a file - with the same name, the copy will replace this file. - ''' - from shutil import copyfile - copyfile(old_path, new_path) +@activity +def display_osd_message(message='Example message', seconds=5): + """Display overlay message + Display custom OSD (on-screen display) message. Can be used to display a message for a limited amount of time. Can be used for illustration, debugging or as OSD. -def WaitForFile(path): - ''' - Wait until a file with the entered path exists. - ''' - from time import sleep - while not os.path.exists(path): - sleep(1) - return + :parameter message: Message to be displayed + :Example: -def WriteListToFile(list_to_write, file): - ''' - Writes a list to a .txt file. Every element of the entered list is written on a new - line of the text file. The .txt file is entered with a path. If the path does not exist - yet, the function will create a new .txt file at the specified path and write it. If the - path does exist, the function writes the list in the existing file. - ''' - with open(file, 'w') as filehandle: - filehandle.writelines("%s\n" % place for place in list_to_write) - return + >>> # Display overlay message + >>> display_osd_message() + Keywords + message box, osd, overlay, info warning, info, popup, window, feedback, screen, login, attended -def WriteFileToList(file): - ''' - This function writes the content of a entered .txt file to a list and returns that list. - Every new line from the .txt file becomes a new element of the list. The function will - not work if the entered path is not attached to a .txt file. - ''' - written_list = [] - with open(file, 'r') as filehandle: - filecontents = filehandle.readlines() - for line in filecontents: - current_place = line[:-1] - written_list.append(current_place) - return written_list + Icon + las la-tv + """ + if "DISABLE_AUTOMAGICA_OSD" in globals(): + return + + from threading import Thread + + def load_osd(): + import tkinter + import win32con + import pywintypes + import win32api + + screen_width = win32api.GetSystemMetrics(0) + screen_height = win32api.GetSystemMetrics(1) + + root = tkinter.Tk() + label = tkinter.Label( + text=message, font=("Helvetica", "30"), fg="white", bg="black", borderwidth=10 + ) + label.master.overrideredirect(True) + label.config(anchor=tkinter.CENTER) + label.master.geometry( + "+{}+{}".format(int(screen_width / 2), int(screen_height - 250)) + ) + label.master.lift() + label.master.wm_attributes("-topmost", True) + label.master.wm_attributes("-disabled", True) + label.master.wm_attributes("-transparentcolor", "black") + + hWindow = pywintypes.HANDLE(int(label.master.frame(), 16)) + + exStyle = ( + win32con.WS_EX_COMPOSITED + | win32con.WS_EX_LAYERED + | win32con.WS_EX_NOACTIVATE + | win32con.WS_EX_TOPMOST + | win32con.WS_EX_TRANSPARENT + ) + win32api.SetWindowLong(hWindow, win32con.GWL_EXSTYLE, exStyle) + + label.after(seconds * 1000, lambda: root.destroy()) + label.pack() + label.mainloop() + + t = Thread(target=load_osd) + try: + t.start() + except: + pass + finally: + try: + t.kill() + except: + pass -''' -Folder Operations -''' +""" +Browser +Icon: lab la-chrome +""" +import selenium.webdriver -def CreateFolder(path): - ''' - Creates new folder at the given path - ''' - if not os.path.exists(path): - os.makedirs(path) - return +class Chrome(selenium.webdriver.Chrome): + @activity + def __init__(self, load_images=True, headless=False): + """Open Chrome Browser -def RenameFolder(old_path, new_folder_name): - ''' - Entering "C:\\Users\\OldFolder as old_path" and "NewFolder" as new_folder_name changes - the name of the directory in C:\\Users from "OldFolder" to "NewFolder". - ''' - if os.path.exists(old_path): - base_path = old_path.split("\\")[:-1] - new_path = "\\".join(base_path)+"\\" + new_folder_name - if not os.path.exists(new_path): - os.rename(old_path, new_path) - return + Open the Chrome Browser with the Selenium webdriver. Canb be used to automate manipulations in the browser. + Different elements can be found as: + - Xpath: e.g. browser.find_element_by_xpath() or browser.xpath() + One can easily find an xpath by right clicking an element -> inspect. Look for the element in the menu and right click -> copy -> xpath + find_element_by_id + - Name: find_element_by_name + - Link text: find_element_by_link_text + - Partial link text: find_element_by_partial_link_text + - Tag name: find_element_by_tag_name + - Class name: find_element_by_class_name + - Css selector: find_element_by_css_selector -def OpenFolder(path): - ''' - Entering "C:\\Users\\Downloads\\Automagica" will open the folder "Automagica" if the path exists. - ''' - if os.path.isdir(path): - os.startfile(path) - return + Elements can be manipulated by: + - Clicking: e.g. element.click() + - Typing: e.g. element.send_keys() -def MoveFolder(old_path, new_location): - ''' - Entering "C:\\Users\\Oldlocation\\Automagica" as old_path and "C:\\Users\\Newlocation" - as new_location moves the folder "Automagica" from directory "Oldlocation" to directory "Newlocation". - If the new location already contains a folder with the same name, a random 8 character uid is added to the name. - ''' - import uuid - name = old_path.split("\\")[-1] - new_path = new_location + "\\" + name - if os.path.isdir(old_path): - if not os.path.isdir(new_path): - os.rename(old_path, new_path) - elif os.path.isdir(new_path): - new_path = new_path + " (" + str(uuid.uuid4())[:8] + ")" - os.rename(old_path, new_path) - return + :parameter load_images: Do not load images (bool). This could speed up loading pages + :parameter headless: Run headless, this means running without a visible window (bool) + return: wWbdriver: Selenium Webdriver -def RemoveFolder(path, allow_root=False, delete_read_only=True): - ''' - Entering "C:\\Users\\Documents\\Automagica" removes the folder "Automagica" including all of its subdirectories and files. - Standard, the safety variable allow_root is False. When False the function checks whether the path lenght has a minimum of 10 characters. - This is to prevent entering for example "\\" as a path resulting in deleting the root and all of its subdirectories. - To turn off this safety check, explicitly set allow_root to True. For the function to work optimal, all files present in the - directory must be closed. - ''' - if len(path) > 10 or allow_root: - if os.path.isdir(path): - shutil.rmtree(path, ignore_errors=delete_read_only) - return + :Example: + >>> # Open the browser + >>> browser = Chrome() + >>> # Go to a website + >>> browser.get('https://automagica.com') + >>> # Close browser + >>> browser.quit() -def EmptyFolder(path, allow_root=False): - ''' - Entering "C:\\Users\\Documents\\Automagica" removes all the files and folders saved in the "Automagica" folder but maintains the folder itself. - Standard, the safety variable allow_root is False. When False the function checks whether the path lenght has a minimum of 10 characters. - This is to prevent entering for example "\\" as a path resulting in deleting the root and all of its subdirectories. - To turn off this safety check, explicitly set allow_root to True. For the function to work optimal, all files present in the directory - must be closed. - ''' - if len(path) > 10 or allow_root: - if os.path.isdir(path): - for root, dirs, files in os.walk(path, topdown=False): - for name in files: - os.remove(os.path.join(root, name)) - for name in dirs: - os.rmdir(os.path.join(root, name)) - return + Keywords + chrome, browsing, browser, internet, surfing, web, webscraping, www, selenium, crawling, webtesting, mozilla, firefox, internet explorer + Icon + lab la-chrome -def FolderExists(path): - ''' - This function checks whether the folder with the given path exists, e.g. by entering... - "C:\\Users\\Documents\\Automagica", the function returns True if the folder exists or False if - it doesn't exist. - ''' - return os.path.isdir(path) + """ + import platform + import os + # Check what OS we are on + if platform.system() == "Linux": + chromedriver_path = "\\bin\\webdriver\\linux64\\chromedriver" + elif platform.system() == "Windows": + chromedriver_path = "\\bin\\win32\\chromedriver.exe" + else: + chromedriver_path = "\\bin\\mac64\\chromedriver.exe" -def CopyFolder(old_path, new_location): - ''' - By entering "C:\\Users\\Documents\\Automagica" as old_path and "C:\\Users\\Downloads" as new_location... - the function copies the folder "Automagica" together with all its contents to the new location. The folder name... - remains unchanged, except when the folder already exists a 8 character random uid will be added to the name. - ''' - import uuid - new_path = new_location + "\\" + old_path.split("\\")[-1] - if os.path.isdir(old_path): - if not os.path.isdir(new_path): - shutil.copytree(old_path, new_path) - elif os.path.isdir(new_path): - if os.path.isdir(new_path): - new_path = new_path + " (" + str(uuid.uuid4())[:8] + ")" - shutil.copytree(old_path, new_path) - return + chrome_options = selenium.webdriver.ChromeOptions() + if headless: + chrome_options.add_argument("--headless") -def ZipFolder(dir_path, new_path): - ''' - Creates a zipped directory of a directory specified by the first argument. The newly zipped directory - receives a path specified by the second argument. - ''' - if os.path.isdir(dir_path): - shutil.make_archive(new_path, 'zip', dir_path) - return + if not load_images: + prefs = {"profile.managed_default_content_settings.images": 2} + chrome_options.add_experimental_option("prefs", prefs) + selenium.webdriver.Chrome.__init__(self, os.path.abspath( + __file__).replace('activities.py', '') + chromedriver_path) -def UnzipFolder(path, new_path=False): - ''' - Unzips a folder specified by the first variable. The unzipped folder will be stored in a directory specified by - new_path. If this second variable is omitted, the unzipped folder will be stored in the same directory as the - zipped folder is located. - ''' - import zipfile - if os.path.exists(path): - zipp = zipfile.ZipFile(path) - if not new_path: - base_path = "\\".join(path.split("\\")[:-1]) - zipp.extractall(base_path) - elif os.path.isdir(new_path): - zipp.extractall(new_path) - zipp.close() - return + @activity + def save_all_images(self, output_path=None): + """Save all images + Save all images on current page in the Browser -def WaitForFolder(path): - ''' - Wait until a folder with the entered path exists. - ''' - from time import sleep - while not os.path.exists(path): - sleep(1) - return + :parameter output_path: Path where images can be saved. Default value is home directory. + :return: List with paths to images -''' -Image Operations -''' + :Example: -import sys -from PIL import Image -import PIL + >>> # Open the browser + >>> browser = Chrome() + >>> # Go to a website + >>> browser.get('https://www.nytimes.com/') + >>> # Save all images + >>> browser.save_all_images() + >>> browser.quit() + ['C:\\Users\\\\image1.png', 'C:\\Users\\\\image2.jpg', 'C:\\Users\\\\image4.gif'] + Keywords + image scraping, chrome, internet, browsing, browser, surfing, web, webscraping, www, selenium, crawling, webtesting, mozilla, firefox, internet explorer -def OpenImage(path): - ''' - Displays an image specified by the path variable on the default imaging program. - ''' - im = Image.open(path) - return im.show() + Icon + las la-images + """ + import requests + import os + from urllib.parse import urlparse -def RotateImage(path, angle): - ''' - Entering "C:\\Users\\Pictures\\Automagica.jpg" as path and an a angle of 90 rotates the picture specified by the first - argument over 90 degrees. Pay attention, because angles other than 90, 180, 270, 360 can resize the picture. - ''' - im = Image.open(path) - return im.rotate(angle, expand=True).save(path) + if not output_path: + output_path = os.path.expanduser("~") + paths = [] -def ResizeImage(path, size): - ''' - Resizes the image specified by the path variable. The size is specifie by the second argument. This is a tuple with the - width and height in pixels. E.g. ResizeImage("C:\\Users\\Pictures\\Automagica.jpg", (300, 400)) gives the image a width - of 300 pixels and a height of 400 pixels. - ''' - im = Image.open(path) - return im.resize(size).save(path) + images = self.find_elements_by_tag_name('img') + for image in images: + url = image.get_attribute('src') + a = urlparse(url) + filename = os.path.basename(a.path) -def ImageSize(path): - ''' - Returns the size in pixels of an image specified by a path. The size is returned in a message box - of the form: "(height, width)" - ''' + if filename: + with open(os.path.join(output_path, filename), 'wb') as f: + try: + r = requests.get(url) + f.write(r.content) + paths.append(os.path.join(output_path, filename)) + except: + pass - im = Image.open(path) - return DisplayMessageBox(str(im.size)) + return paths + @activity + def find_elements_by_text(self, text): + """Find elements by text -def CropImage(path, box=None): - ''' - Crops the image specified by path to a region determined by the box variable. This variable is a 4 tuple who defines the - left, upper, right and lower pixel coördinate e.g.: (left, upper, right, lower). - ''' - im = Image.open(path) - return im.crop(box).save(path) + Find all elements by their text. Text does not need to match exactly, part of text is enough. + :Example: -def ImageFormat(path): - ''' - Returns the format of an image specified by the input path. E.g. entering "C:\\Users\\Pictures\\Automagica.jpg" - returns a message box saying JPEG. - ''' - im = Image.open(path) - return DisplayMessageBox(im.format) + >>> # Open the browser + >>> browser = Chrome() + >>> # Go to a website + >>> browser.get('https://nytimes.com') + >>> # Find elements by text + >>> browser.find_elements_by_text('world') + [webelement1, webelement2 , .. ] + Keywords + element, element by text, chrome, internet, browsing, browser, surfing, web, webscraping, www, selenium, crawling, webtesting, mozilla, firefox, internet explorer -def MirrorImageHorizontally(path): - ''' - Mirrors an image with a given path from left to right. - ''' - im = Image.open(path) - return im.transpose(Image.FLIP_LEFT_RIGHT).save(path) + Icon + las la-align-center + """ + return self.find_elements_by_xpath("//*[contains(text(), '" + text.lower() + "')] | //*[@value='" + text.lower() + "']") -def MirrorImageVertically(path): - ''' - Mirrors an image with a given path from top to bottom. - ''' - im = Image.open(path) - return im.transpose(Image.FLIP_TOP_BOTTOM).save(path) + @activity + def find_element_by_text(self, text): + """Find element by text + Find one element by text. Text does not need to match exactly, part of text is enough. -''' -Email Operations -''' + :Example: -import smtplib + >>> # Open the browser + >>> browser = Chrome() + >>> # Go to a website + >>> browser.get('https://nytimes.com') + >>> # Find elements by text + >>> browser.find_element_by_text('world') + webelement + Keywords + element, element by text, chrome, internet, browsing, browser, surfing, web, webscraping, www, selenium, crawling, webtesting, mozilla, firefox, internet explorer -def SendMail(host, user, password, destination, subject="", message="", port=587): - ''' - This function lets you send emails with an e-mail address. The first and second arguments require the - mail address and password of your e-mail account. The destination is the receiving mail address. The subject - and message variables contain respectively the mail subject and the text in the mail. The port variable is standard - 587. In most cases this argument can be ignored, but in some cases it needs to be changed to 465. - ''' - BODY = '\r\n'.join(['To: %s' % destination, 'From: %s' % - user, 'Subject: %s' % subject, '', message]) - smtpObj = smtplib.SMTP(host, port) - smtpObj.ehlo() - smtpObj.starttls() - smtpObj.login(user, password) - smtpObj.sendmail(user, destination, BODY) - smtpObj.quit() - return + Icon + las la-align-center + """ + return self.find_element_by_xpath("//*[contains(text(), '" + text.lower() + "')] | //*[@value='" + text.lower() + "']") -def SendMailWithHotmail(user, password, destination, subject="", message="", port=587): - ''' - This function lets you send emails with a hotmail address. The first and second arguments require the - mail address and password of your hotmail account. The destination is the receiving mail address. The subject - and message variables contain respectively the mail subject and the text in the mail. The port variable is standard - 587. In most cases this argument can be ignored, but in some cases it needs to be changed to 465. - ''' - SendMail('smtp-mail.outlook.com', user, password, - destination, subject, message, port) - return + @activity + def find_all_links(self): + """Find all links + Find all links on a webpage in the browser -def SendMailWithGmail(user, password, destination, subject="", message="", port=587): - ''' - This function lets you send emails with a gmail address. The first and second arguments require the - mail address and password of your gmail account. The destination is the receiving mail address. The subject - and message variables contain respectively the mail subject and the text in the mail. The port variable is standard - 587. In most cases this argument can be ignored, but in some cases it needs to be changed to 465. Google has a - safety feature that blocks lessecure apps. For this function to work properly, this needs to be turned off, which - can be done at the following link: https://myaccount.google.com/lesssecureapps. - ''' - SendMail('smtp.gmail.com', user, password, - destination, subject, message, port) - return + :Example: + >>> # Open the browser + >>> browser = Chrome() + >>> # Go to a website + >>> browser.get('https://nytimes.com') + >>> # Find elements by text + >>> browser.find_all_links() + [webelement1, webelement2 , .. ] -def SendMailWithYahoo(user, password, destination, subject="", message="", port=587): - ''' - This function lets you send emails with a Yahoo address. The first and second arguments require the - mail address and password of your Yahoo account. The destination is the receiving mail address. The subject - and message variables contain respectively the mail subject and the text in the mail. The port variable is standard - 587. In most cases this argument can be ignored, but in some cases it needs to be changed to 465. - ''' - SendMail('smtp.mail.yahoo.com', user, password, - destination, subject, message, port) - return + Keywords + random, element, element by text, chrome, internet, browsing, browser, surfing, web, webscraping, www, selenium, crawling, webtesting, mozilla, firefox, internet explorer + Icon + las la-window-restore + """ + return self.find_elements_by_xpath("//a[@href]") -''' -Windows Applications -''' + @activity + def highlight(self, element): + """Highlight element -import subprocess + Highlight elements in yellow in the browser + :Example: -def OpenCalculator(): - ''' - Open Calculator. - ''' - subprocess.Popen("calc.exe") - return + >>> # Open the browser + >>> browser = Chrome() + >>> # Go to a website + >>> browser.get('https://wikipedia.org') + >>> # Find all links + >>> links = browser.find_all_links() + >>> # Select first link to highlight for illustration + >>> first_link = links[0] + >>> # Highlight first link + >>> browser.highlight(first_link) + Keywords + element, element by text, chrome, internet, browsing, browser, surfing, web, webscraping, www, selenium, crawling, webtesting, mozilla, firefox, internet explorer -def OpenPaint(): - ''' - Open MS Paint. - ''' - subprocess.Popen("mspaint.exe") - return + Icon + las la-highlighter + """ + driver = element._parent -def OpenNotepad(): - ''' - Open Notepad - ''' - subprocess.Popen("notepad.exe") - return + def apply_style(s): + driver.execute_script("arguments[0].setAttribute('style', arguments[1]);", + element, s) + original_style = element.get_attribute('style') + apply_style("background: yellow; border: 2px solid red;") -def OpenSnippingTool(): - ''' - Open Snipping Tool. - ''' - subprocess.Popen("SnippingTool.exe") - return + @activity + def exit(self): + """Exit the browser + Quit the browser by exiting gracefully. One can also use the native 'quit' function, e.g. 'browser.quit()' -def OpenControlPanel(): - ''' - Open Windows Control Panel. - ''' - subprocess.Popen("control.exe") - return + :Example: + >>> # Open the browser + >>> browser = Chrome() + >>> # Go to a website + >>> browser.get('https://automagica.com') + >>> # Close browser + >>> browser.exit() -def OpenCleanManager(): - ''' - Open Clean Manager. - ''' - subprocess.Popen("cleanmgr.exe") - return + Keywords + quit, exit, close, element, element by text, chrome, internet, browsing, browser, surfing, web, webscraping, www, selenium, crawling, webtesting, mozilla, firefox, internet explorer -def OpenDialer(): - ''' - Open Windows Dialer. - ''' - subprocess.Popen("dialer.exe") - return + Icon + las la-window-close + """ + self.quit() + @activity + def find_all_xpaths(self, element): + """Find all XPaths -def OpenVolumeMixer(): - ''' - Open Windows Volume Mixer. - ''' - subprocess.Popen("SndVol.exe") - return + Find all elements with specified xpath on a webpage in the the browser. Can also use native 'find_elements_by_xpath' function e.g. browser.find_elements_by_xpath() + You can easily + :Example: -def OpenXPSViewer(): - ''' - Open Windows XPS Viewer. - ''' - subprocess.Popen("xpsrchvw") - return + >>> # Open the browser + >>> browser = Chrome() + >>> # Go to a website + >>> browser.get('https://wikipedia.org') + >>> # Find element by xpath + >>> browser.find_xpaths('//*[@id=\'js-link-box-en\']') + [webelement1, webelement2 , .. ] + Keywords + random, element, xpath, xml, element by text, chrome, internet, browsing, browser, surfing, web, webscraping, www, selenium, crawling, webtesting, mozilla, firefox, internet explorer -''' -Portal (premium) activities -''' + Icon + las la-times -def InsertReportTableHeader(data): - """ - Inserts the header of an Automagica Report. - """ - data_keys = [] + """ + return self.find_elements_by_xpath(element) - for row in data: - for key, _ in row.items(): - if key not in data_keys: - data_keys.append(key) + @activity + def find_xpath(self, element): + """Find XPath in browser - header = '|'.join(data_keys) + Find all element with specified xpath on a webpage in the the browser. Can also use native 'find_elements_by_xpath' function e.g. browser.find_element_by_xpath() - header_next = '|'.join(['---' for key in data_keys]) - - print('AUTOMAGICA_MARKDOWN_START: ' + str(header) + ' :AUTOMAGICA_MARKDOWN_END') - print('AUTOMAGICA_MARKDOWN_START: ' + str(header_next) + ' :AUTOMAGICA_MARKDOWN_END') + :Example: - return data_keys + >>> # Open the browser + >>> browser = Chrome() + >>> # Go to a website + >>> browser.get('https://wikipedia.org') + >>> # Find element by xpath + >>> elements = browser.find_xpath('//*[@id=\'js-link-box-en\']') + >>> # We can now use this element, for example to click on + >>> element.click() + Keywords + random, xpath, element, xml element by text, chrome, internet, browsing, browser, surfing, web, webscraping, www, selenium, crawling, webtesting, mozilla, firefox, internet explorer -def InsertReportTableItem(item, keys): - """ - Inserts the header of an Automagica Report. - """ - print('AUTOMAGICA_MARKDOWN_START: ' + '|'.join([str(item.get(key, '')) for key in keys]) + ' :AUTOMAGICA_MARKDOWN_END') + Icon + las la-times + """ + return self.find_element_by_xpath(element) - -def InsertReportTable(data): - ''' - Function to report in the Automagica Portal. Can be used to generate reports, - logs and worklists. Only available to users with access to the Portal. - This outputs a list of flat dicts to a markdown table with headers to the console. - ''' - keys = InsertReportTableHeader(data) - for item in data: - InsertReportTableItem(item, keys) +""" +Credential Management +Icon: las la-key +""" -def InsertReportTitle(title='My title', level=1): - ''' - Function to insert a report title in the Automagica Portal. - This outputs a string as a title to the console. - ''' - print('AUTOMAGICA_MARKDOWN_START: ' + '#' * level + ' :AUTOMAGICA_MARKDOWN_END') +@activity +def set_credential(username=None, password=None, system="Automagica"): + """Set credential + Add a credential which stores credentials locally and securely. All parameters should be Unicode text. -''' -Trello activities -''' + :parameter username: Username for which credential will be added. + :parameter password: Password to add + :parameter system: Name of the system for which credentials are stored. Extra safety measure and method for keeping passwords for similar usernames on different applications a part. Highly recommended to change default value. + :return: Stores credentials locally -def MakeTrelloCard(title='My card', - description='My description', - board_name='My board', - list_name='My list', - api_key='', - api_secret='', - token='', - token_secret='any'): - """ - For this you need a Trello API key, secret and token. - Token secret can be any string, but should be altered for security purposes. - """ - from trello import TrelloClient + :Example: - client = TrelloClient( - api_key=api_key, - api_secret=api_secret, - token=token, - token_secret=token_secret - ) + >>> set_credential('SampleUsername', 'SamplePassword') - trello_boards = client.list_boards() - for trello_board in trello_boards: + Keywords + credential, login, password, username, store, vault, secure, credentials, store, log in, encrypt + + Icon + las la-key + + """ + import keyring + + keyring.set_password(system, username, password) + + +@activity +def delete_credential(username=None, password=None, system="Automagica"): + """Delete credential + + Delete a locally stored credential. All parameters should be Unicode text. + + :parameter username: Username for which credential (username + password) will be deleted. + :parameter system: Name of the system for which password will be deleted. + + + :Example: + + >>> set_credential('SampleUsername', 'SamplePassword') + >>> delete_credential('SampleUsername', 'SamplePassword') + + Keywords + credential, delete, login, password, username, store, vault, secure, credentials, store, log in, encrypt + + Icon + las la-key + + """ + import keyring + + keyring.delete_password(system, username) + + +@activity +def get_credential(username=None, system="Automagica"): + """Get credential + + Get a locally stored redential. All parameters should be Unicode text. + + :parameter username: Username to get password for. + :parameter system: Name of the system for which credentials are retreived. + + :return: Stored credential as string + + :Example: + + >>> set_credential('SampleUsername', 'SamplePassword') + >>> get_credential('SampleUsername') + 'SamplePassword' + + Keywords + credential, get, delete, login, password, username, store, vault, secure, credentials, store, log in, encrypt + + Icon + las la-key + + """ + import keyring + + return keyring.get_password(system, username) + + +""" +FTP +Icon: las la-key +""" + + +class FTP: + @activity + def __init__(self, server, username, password): + """Create FTP connection + + Can be used to automate activites for FTP + + :parameter server: Name of the server + :parameter username: Username + :parameter password: Password + + :Example: + + >>> # This example uses the Rebex FPT test server. + >>> # Take caution uploading and downloading from this server as it is public + >>> ftp = FTP('test.rebex.net', 'demo', 'password') + + Keywords + FTP, file transfer protocol, filezilla, winscp, server, remote, folder, folders + + Icon + las la-folder-open + + """ + import ftplib + + self.connection = ftplib.FTP(server) + self.connection.login(username, password) + + @activity + def download_file(self, input_path, output_path=None): + """Download file + + Downloads a file from FTP server. Connection needs to be established first. + + :parameter input_path: Path to the file on the FPT server to download + :parameter output_path: Destination path for downloaded files. Default is the same directory with "_downloaded" added to the name + + :return: Path to output file as string + + :Example: + + >>> # This example uses the Rebex FPT test server. + >>> # Take caution uploading and downloading from this server as it is public + >>> ftp = FTP('test.rebex.net', 'demo', 'password') + >>> # Download Rebex public file 'readme.txt' + >>> ftp.download_file('readme.txt') + 'C:\\Users\\\\readme_downloaded.txt' + + Keywords + FTP, file transfer protocol, download, filezilla, winscp, server, remote, folder, folders + + Icon + las la-download + + """ + # Set path if not specified + if not output_path: + import os + filepath = os.path.expanduser("~") + base = os.path.basename(input_path) + filename = os.path.splitext(base)[0] + extension = os.path.splitext(base)[1] + output_path = os.path.join( + filepath, filename + '_downloaded' + extension) + + self.connection.retrbinary( + "RETR " + input_path, open(output_path, "wb").write) + + return output_path + + @activity + def upload_file(self, input_path, output_path=None): + """Upload file + + Upload file to FTP server + + :parameter from_path: Path file that will be uploaded + :parameter to_path: Destination path to upload. + + :return: Patht to uploaded file as string + + :Example: + + >>> # This example uses the Rebex FPT test server. + >>> # Take caution uploading and downloading from this server as it is public + >>> ftp = FTP('test.rebex.net', 'demo', 'password') + >>> # Create a .txt file for illustration + >>> textfile = make_textfile() + >>> # Upload file to FTP test server + >>> # Not that this might result in a persmission error for public FPT's + >>> ftp.upload_file(textfile) + + Keywords + FTP, upload, fptfile transfer protocol, filezilla, winscp, server, remote, folder, folders + + Icon + las la-upload + """ + # Set to user home if no path specified + if not output_path: + output_path = "/" + + self.connection.retrbinary( + "RETR " + input_path, open(output_path, "wb").write) + + @activity + def enumerate_files(self, path="/"): + """List FTP files + + Generate a list of all the files in the FTP directory + + :parameter path: Path to list files from. Default is the main directory + + :return: Prints list of all files and directories + + :Example: + + >>> # This example uses the Rebex FPT test server. + >>> # Take caution uploading and downloading from this server as it is public + >>> ftp = FTP('test.rebex.net', 'demo', 'password') + >>> # Show all files in main directory + >>> ftp.enumerate_files() + 10-27-15 03:46PM pub + 04-08-14 03:09PM 403 readme.txt + '226 Transfer complete.' + + Keywords + FTP, list, upload, fptfile transfer protocol, filezilla, winscp, server, remote, folder, folders + + Icon + las la-list-ol + """ + self.connection.cwd(path) + lines = self.connection.retrlines("LIST") + return lines + + @activity + def directory_exists(self, path="/"): + """Check FTP directory + + Check if FTP directory exists + + :parameter path: Path to check on existence. Default is main directory + + :return: Boolean + + :Example: + + >>> # This example uses the Rebex FPT test server. + >>> # Take caution uploading and downloading from this server as it is public + >>> ftp = FTP('test.rebex.net', 'demo', 'password') + >>> # Check if 'pub' folder exists in main directory + >>> ftp.directory_exists('\\pub') + True + + Keywords + FTP, list, upload, fptfile transfer protocol, filezilla, winscp, server, remote, folder, folders + + Icon + las la-list-ol + + """ + try: + self.connection.cwd(path) + return True + except: + return False + + @activity + def create_directory(self, directory_name, path="/"): + """Create FTP directory + + Create a FTP directory. Note that sufficient permissions are present + + :parameter directory_name: Name of the new directory, should be a string e.g. 'my_directory' + :parameter path: Path to parent directory where to make new directory. Default is main directory + + :return: Boolean if creation was succesful (True) or failed (False) + :Example: + + >>> # This example uses the Rebex FPT test server. + >>> # Trying to create a directory will most likely fail due to permission + >>> ftp = FTP('test.rebex.net', 'demo', 'password') + >>> # Create directory + >>> ftp.create_directory('brand_new_directory') + False + + Keywords + FTP, create, create folder, new, new folder, fptfile transfer protocol, filezilla, winscp, server, remote, folder, folders + + Icon + las la-folder-plus + + """ + try: + self.connection.cwd(path) + try: + self.connection.mkd(directory_name) + return True + except Exception as e: + if not e.args[0].startswith("550"): # Exists already + raise + except: + return False + + +""" +Keyboard +Icon: las la-keyboard +""" + + +def easy_key_translation(key): + """Activity supporting key translations + """ + + if not key: + return '' + + key_translation = {'backspace': '{BACKSPACE}', + 'break': '{BREAK}', + 'capslock': '{CAPSLOCK}', + 'delete': '{DELETE}', + 'alt': '%', + 'ctrl': '^', + 'shift': '+', + 'downarrow': '{DOWN}', + 'end': '{END}', + 'enter': '{ENTER}', + 'escape': '{ESC}', + 'help': '{HELP}', + 'home': '{HOME}', + 'insert': '{INSERT}', + 'win': '^{Esc}', + 'leftarrow': '{LEFT}', + 'numlock': '{NUMLOCK}', + 'pagedown': '{PGDN}', + 'pageup': '{PGUP}', + 'printscreen': '{PRTSC}', + 'rightarrow': '{RIGHT}', + 'scrolllock': '{SCROLLLOCK}', + 'tab': '{TAB}', + 'uparrow': '{UP}', + 'f1': '{F1}', + 'f2': '{F2}', + 'f3': '{F3}', + 'f4': '{F4}', + 'f5': '{F5}', + 'f6': '{F6}', + 'f7': '{F7}', + 'f8': '{F8}', + 'f9': '{F9}', + 'f10': '{F10}', + 'f11': '{F11}', + 'f12': '{F12}', + 'f13': '{F13}', + 'f14': '{F14}', + 'f15': '{F15}', + 'f16': '{F16}', + '+': '{+}', + '^': '{^}', + '%': '{%}', + '~': '{~}', + '(': '{(}', + ')': '{)}', + '[': '{[}', + ']': '{]}', + '{': '{{}', + '}': '{}}', + } + + if key_translation.get(key): + return key_translation.get(key) + + return key + + +@activity +def press_key(key=None): + """Press key + + Press and release an entered key. Make sure your keyboard is on US layout (standard QWERTY). + If you are using this on Mac Os you might need to grant acces to your terminal application. (Security Preferences > Security & Privacy > Privacy > Accessibility) + + Supported keys: + ' ', '!', '"', '#', '$', '%', '&', "'", '(', ,')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<','=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e','f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 'alt', 'backspace', 'ctrl', 'delete' 'downarrow', 'rightarrow', 'leftarrow', 'uparrow', 'enter', 'escape', 'f1', 'f2', f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'home', 'insert', 'pagedown', 'pageup', 'help', 'printscreen', 'space', 'scrollock', 'tab', shift, 'win' + + :parameter key: Key to press + + :return: Keypress + + :Example: + + >>> # Open notepad to illustrate typing + >>> run('notepad.exe') + >>> # Press some keys + >>> press_key('a') + >>> press_key('enter') + >>> press_key('b') + >>> press_key('enter') + >>> press_key('c') + + Keywords + keyboard, typing, type, key, keystroke, hotkey, press, press key + + Icon + las la-keyboard + + """ + import platform + + # Check if system is not running Windows + if platform.system() != "Windows": + from pyautogui import press + + if key: + return press(key) + + import win32com.client + shell = win32com.client.Dispatch("WScript.Shell") + shell.SendKeys(easy_key_translation(key), 0) + + +@activity +def press_key_combination(first_key, second_key, third_key=None, force_pyautogui=False): + """Press key combination + + Press a combination of two or three keys simultaneously. Make sure your keyboard is on US layout (standard QWERTY). + + Supported keys: + ' ', '!', '"', '#', '$', '%', '&', "'", '(', ,')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<','=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e','f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 'alt', 'backspace', 'ctrl', 'delete' 'downarrow', 'rightarrow', 'leftarrow', 'uparrow', 'enter', 'escape', 'f1', 'f2', f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'home', 'insert', 'pagedown', 'pageup', 'help', 'printscreen', 'space', 'scrollock', 'tab', shift, 'win'] + + :parameter first_key: First key to press + :parameter second_key: Second key to press + :parameter third_key: Third key to press, this is optional. + :parameter force_pyautogui: Set parameter to true to force the use of pyautogui. This could help when certain keypresses do not work correctly. + + :return: Key combination + + :Example: + + >>> # Open notepad to illustrate typing + >>> run('notepad.exe') + >>> # Press 'ctrl + s' to prompt save window + >>> press_key_combination('ctrl', 's') + + Keywords + keyboard, key combination, shortcut, typing, type, key, keystroke, hotkey, press, press key + + Icon + las la-keyboard + + """ + + import platform + + # Check if system is not running Windows + if first_key == 'win' or second_key == 'win' or third_key == 'win': + force_pyautogui = True + if platform.system() != "Windows" or force_pyautogui: + from pyautogui import hotkey + + if not third_key: + return hotkey(first_key, second_key) + if third_key: + return hotkey(first_key, second_key, third_key) + + import win32com.client + shell = win32com.client.Dispatch("WScript.Shell") + key_combination = easy_key_translation( + first_key) + easy_key_translation(second_key) + easy_key_translation(third_key) + shell.SendKeys(easy_key_translation(key_combination), 0) + + +@activity +def type_text(text='', interval_seconds=0.01): + """Type text + + Types text in the current active field by simulating keyboard typing. Make sure your keyboard is on US layout (standard QWERTY). + + Supported keys: + ' ', '!', '"', '#', '$', '%', '&', "'", '(', ,')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<','=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e','f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 'alt', 'backspace', 'ctrl', 'delete' 'downarrow', 'rightarrow', 'leftarrow', 'uparrow', 'enter', 'escape', 'f1', 'f2', f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'home', 'insert', 'pagedown', 'pageup', 'help', 'printscreen', 'space', 'scrollock', 'tab', shift, 'win' + + :parameter text: Text in string format to type. Note that you can only press single character keys. Special keys like ":", "F1",... can not be part of the text argument. + :parameter interval_seconds: Time in seconds between two keystrokes. Defautl value is 0.01 seconds. + + :return: Keystrokes + + :Example: + + >>> # Open notepad to illustrate typing + >>> run('notepad.exe') + >>> # Type a story + >>> type_text('Why was the robot mad? \n They kept pushing his buttons!') + + Keywords + keyboard, keystrokes, key combination, shortcut, typing, type, key, keystroke, hotkey, press, press key + + Icon + las la-keyboard + + """ + + import platform + + # Set keyboard layout for Windows platform + if platform.system() != "Windows": + from pyautogui import typewrite + return typewrite(text, interval=interval_seconds) + + import win32com.client + shell = win32com.client.Dispatch("WScript.Shell") + import time + for character in text: + shell.SendKeys(easy_key_translation(character), 0) + time.sleep(interval_seconds) + + +""" +Mouse +Icon: las la-mouse-pointer +""" + + +@activity +def get_mouse_position(delay=None, to_clipboard=False): + """Get mouse coordinates + + Get the x and y pixel coordinates of current mouse position. + These coordinates represent the absolute pixel position of the mouse on the computer screen. The x-coördinate starts on the left side and increases going right. The y-coördinate increases going down. + + :parameter delay: Delay in seconds before capturing mouse position. + :parameter to_clipboard: Put the coordinates in the clipboard e.g. 'x=1, y=1' + + :return: Tuple with (x, y) coordinates + + :Example: + + >>> get_mouse_position() + (314, 271) + + Keywords + mouse, mouse automation, click, right click, mouse button, move mouse, position, pixel + + Icon + las la-mouse + """ + from pyautogui import position + from time import sleep + + if delay: + sleep(delay) + + coord = position() + + if to_clipboard: + set_to_clipboard("x=" + str(coord[0]) + ", y=" + str(coord[1])) + + return coord[0], coord[1] + + +@activity +def display_mouse_position(duration=10): + """Display mouse position + + Displays mouse position in an overlay. Refreshes every two seconds. Can be used to find mouse position of element on the screen. + These coordinates represent the absolute pixel position of the mouse on the computer screen. The x-coördinate starts on the left side and increases going right. The y-coördinate increases going down. + + :parameter duration: Duration to show overlay. + + :return: Overlay with (x, y) coordinates + + :Example: + + >>> display_mouse_position() + + Keywords + mouse, osd, overlay, show, display, mouse automation, click, right click, mouse button, move mouse, position, pixel + + Icon + lars la-search-location + """ + + if duration < 1 or type(duration) != int: + return + + from pyautogui import position + from time import sleep + + duration_half = int(duration / 2) + for i in range(0, duration_half, 2): + coord = position() + message = "x=" + str(coord[0]) + ", y=" + str(coord[1]) + display_osd_message(message, seconds=2) + sleep(2) + + +@activity +def click(x=None, y=None): + """Mouse click + + Clicks on a pixel position on the visible screen determined by x and y coordinates. + + :parameter x: X-coördinate + :parameter y: Y-coördinate + + :return: Mouse click on (x, y) coordinates + + :Example: + + >>> click(x=100, y=100) + + Keywords + mouse, osd, overlay, show, display, mouse automation, click, right click, mouse button, move mouse, position, pixel + + Icon + las la-mouse-pointer + """ + from pyautogui import click + + return click(x, y) + + +@activity +def double_click(x=None, y=None): + """Double mouse click + + Double clicks on a pixel position on the visible screen determined by x and y coordinates. + + :parameter x: X-coördinate + :parameter y: Y-coördinate + + :return: Double mouse click on (x, y) coordinates + + :Example: + + >>> double_click(x=100, y=100) + + Keywords + mouse, osd, overlay, double, double click, doubleclick show, display, mouse automation, click, right click, mouse button, move mouse, position, pixel + + Icon + las la-mouse-pointer + """ + from pyautogui import doubleClick + + return doubleClick(x, y) + + +@activity +def right_click(x=None, y=None): + """Right click + + Right clicks on a pixel position on the visible screen determined by x and y coordinates. + + :parameter x: X-coördinate + :parameter y: Y-coördinate + + :return: Right mouse click on (x, y) coordinates + + :Example: + + >>> right_click(x=100, y=100) + + Keywords + mouse, osd, right click, right, rightclick, overlay, show, display, mouse automation, click, right click, mouse button, move mouse, position, pixel + + Icon + las la-mouse-pointer + """ + + from pyautogui import rightClick + + return rightClick(x, y) + + +@activity +def move_mouse_to(x=None, y=None): + """Move mouse + + Moves te pointer to a x-y position. + + :parameter x: X-coördinate + :parameter y: Y-coördinate + + :return: Move mouse to (x, y) coordinates + + :Example: + + >>> move_mouse_to(x=100, y=100) + + Keywords + mouse, osd, move mouse, right click, right, rightclick, overlay, show, display, mouse automation, click, right click, mouse button, move mouse, position, pixel + + Icon + las la-arrows-alt + """ + + from pyautogui import moveTo + + return moveTo(x, y) + + +@activity +def move_mouse_relative(x=None, y=None): + """Move mouse relative + + Moves the mouse an x- and y- distance relative to its current pixel position. + + :parameter x: X-coördinate + :parameter y: Y-coördinate + + :return: Move mouse (x, y) coordinates + + :Example: + + >>> move_mouse_to(x=100, y=100) + >>> wait(1) + >>> move_mouse_relative(x=10, y=10) + + Keywords + mouse, osd, move mouse, right click, right, rightclick, overlay, show, display, mouse automation, click, right click, mouse button, move mouse, position, pixel + + Icon + las la-arrows-alt + """ + + from pyautogui import moveRel + + return moveRel(x, y) + + +@activity +def drag_mouse_to(x=None, y=None, button="left"): + """Drag mouse + + Drag the mouse from its current position to a entered x-y position, while holding a specified button. + + :parameter x: X-coördinate + :parameter y: Y-coördinate + :parameter button: Button to hold while dragging. Options are 'left', 'middle' and 'right'. Standard value is 'left'. + + :return: Drag mouse (x, y) coordinates + + :Example: + + >>> move_mouse_to(x=100, y=100) + >>> drag_mouse_to(x=1, y=1) + + Keywords + mouse, osd, move mouse, right click, right, rightclick, overlay, show, display, mouse automation, click, right click, mouse button, move mouse, position, pixel + + Icon + las la-arrows-alt + """ + from pyautogui import dragTo + + return dragTo(x, y, 0.2, button=button) + + +""" +Image +Icon: las la-image +""" + + +@activity +def random_screen_snippet(size=100, path=None): + """Random screen snippet + + Take a random square snippet from the current screen. Mainly for testing and/or development purposes. + + :parameter size: Size (width and height) in pixels for square snippet. Default value is 100 pixels + :parameter path: Path where snippet will be saved. Default value is home directory with name 'random_screensnippet.jpg' + + :return: Path to snippet + + :Example: + + >>> random_screen_snippet() + 'C:\\Users\\\\random_screensnippet.jpg' + + Keywords + image, random, testing, screengrab, snippet + + Icon + las la-crop-alt + + """ + import PIL.ImageGrab + img = PIL.ImageGrab.grab() + + width, height = img.size + + import random + random_left = random.randrange(1, width, 1) + random_top = random.randrange(1, height, 1) + + left, top, right, bottom = random_left, random_top, random_left + size, random_top + size + cropped = img.crop((left, top, right, bottom)) + + if not path: + import os + path = os.path.join(os.path.expanduser( + "~"), "random_screensnippet.jpg") + cropped.save(path, "JPEG") + + return path + + +@activity +def take_screenshot(path=None): + """Screenshot + + Take a screenshot of current screen. + + :parameter path: Path to save screenshot. Default value is home directory with name 'screenshot.jpg'. + + :return: Path to screenshot + + :Example: + + >>> take_screenshot + 'C:\\Users\\\\screenshot.jpg' + + Keywords + image, screenshot, printscreen, + + Icon + las la-expand + + """ + import PIL.ImageGrab + img = PIL.ImageGrab.grab() + + if not path: + import os + path = os.path.join(os.path.expanduser("~"), "screenshot.jpg") + img.save(path, "JPEG") + + return path + + +@activity +def click_image(filename=None): + """Click on image + + This function searches the screen for a match with template image and clicks directly in the middle. Note that this only finds exact matches. + For a more advanced and robust vision detection method see Automagica AI functionality. + + :parameter filename: Path to the template image. + + :return: True if image was found and clicked on. False if template image was not found. + + :Example: + + >>> # Create a random snippet from current screen + >>> # This is for illustration and can be replaced by template + >>> snippet = random_screen_snippet(size=10) + >>> # Click on the snippet + >>> click_image(snippet) + + Keywords + image matching, matching, vision, button, click, template, template matching. + + Icon + las la-image + + """ + if not filename: + return + + from pyautogui import locateCenterOnScreen, click + + try: + x, y = locateCenterOnScreen(filename) + click(x, y) + return True + except: + return False + + +@activity +def double_click_image(filename=None): + """Double click image + + Double click on similar image on the screen. This function searches the screen for a match with template image and doubleclicks directly in the middle. + Note that this only finds exact matches. For a more advanced and robust vision detection method see Automagica AI functionality. + + :parameter filename: Path to the template image. + + :return: True if image was found and double clicked on. False if template image was not found. + + :Example: + + >>> # Create a random snippet from current screen + >>> # This is for illustration and can be replaced by template + >>> snippet = random_screen_snippet(size=10) + >>> # Click on the snippet + >>> double_click_image(snippet) + + Keywords + image matching, matching, vision, button, double click, template, template matching,click + + Icon + las la-image + """ + if not filename: + return + + from pyautogui import locateCenterOnScreen, click + + try: + x, y = locateCenterOnScreen(filename) + click(x, y, 2) + return True + except: + return False + + +@activity +def right_click_image(filename=None): + """Right click image + + Right click on similar image on the screen. This function searches the screen for a match with template image and right clicks directly in the middle. + Note that this only finds exact matches. For a more advanced and robust vision detection method see Automagica AI functionality. + + :return: True if image was found and right clicked on. False if template image was not found. + + :Example: + + >>> # Create a random snippet from current screen + >>> # This is for illustration and can be replaced by template + >>> snippet = random_screen_snippet(size=10) + >>> # Click on the snippet + >>> right_click_image(snippet) + + Keywords + image matching, matching, vision, button, right click, template, template matching, click + + Icon + las la-image + """ + + if not filename: + return + + from pyautogui import locateCenterOnScreen, rightClick + + try: + x, y = locateCenterOnScreen(filename) + rightClick(x, y, 2) + return True + except: + return False + + +@activity +def locate_image_on_screen(filename=None): + """Locate image on screen + + Find exact image on the screen. This function searches the screen for a match with template image and clicks directly in the middle. + Note that this only finds exact matches. For a more advanced and robust vision detection method see Automagica AI functionality. + + :parameter filename: Path to the template image. + + :return: Tuple with (x, y) coordinates if image is found. None if image was not found + + :Example: + + >>> # Create a random snippet from current screen + >>> # This is for illustration and can be replaced by template + >>> snippet = random_screen_snippet(size=10) + >>> # Click on the snippet + >>> locate_image_on_screen(snippet) + + Keywords + image matching, matching, vision, button, right click, template, template matching, click + + Icon + las la-image + """ + + if not filename: + return + from pyautogui import locateCenterOnScreen + + try: + x, y = locateCenterOnScreen(filename) + return x, y + except: + return None + + +""" +Folder Operations +Icon: las la-folder-open +""" + + +@activity +def get_files_in_folder(path=None, extension=None, show_full_path=True, scan_subfolders=False): + """List files in folder + + List all files in a folder (and subfolders) + Checks all folders and subfolders for files. This could take some time for large repositories. + + :parameter path: Path of the folder to retreive files from. Default folder is the home directory. + :parameter extension: Optional filter on certain extensions, for example 'pptx', 'exe,' xlsx', 'txt', .. Default value is no filter. + :parameter show_full_path: Set this to True to show full path, False will only show file or dirname. Default is True + :scan_subfolders: Boolean to scan subfolders or not. Not that depending on the folder and hardware this activity could take some time if scan_subfolders is set to True + + :return: List of files with their full path + + :Example: + + >>> # List all files in the homedirectory + >>> get_files_in_folder() + ['C:\\Users\\\\file1.jpg', 'C:\\Users\\\\file2.txt', ... ] + + Keywords + folder, files, explorer, nautilus, folder, file, create folder, get files, list files, all files, overview, get files + + Icon + las la-search + """ + import os + + if not path: + path = os.path.expanduser("~") + + if scan_subfolders: + paths = [] + for dirpath, _, filenames in os.walk(path): + for f in filenames: + full_path = os.path.abspath(os.path.join(dirpath, f)) + if extension: + if not full_path.endswith(extension): + continue + if show_full_path: + paths.append(full_path) + else: + paths.append(f) + return paths + + if not scan_subfolders: + paths = [] + for item in os.listdir(path): + full_path = os.path.abspath(os.path.join(path, item)) + if extension: + if not full_path.endswith(extension): + continue + if show_full_path: + paths.append(full_path) + else: + paths.append(item) + return paths + + +@activity +def create_folder(path=None): + """Create folder + + Creates new folder at the given path. + + :parameter path: Full path of folder that will be created. If no path is specified a folder called 'new_folder' will be made in home directory. If this folder already exists 8 random characters will be added to the name. + + :return: Path to new folder as string + + :Example: + + >>> # Create folder in the home directory + >>> create_folder() + 'C:\\Users\\\\new_folder' + + Keywords + create folder, folder, folders, make folder, new folder, folder manipulation, explorer, nautilus + + Icon + las la-folder-plus + """ + import os + + if not path: + path = os.path.join(os.path.expanduser("~"), "new_folder") + + if not os.path.exists(path): + os.makedirs(path) + return path + + from uuid import uuid4 + folder_name = os.path.basename(path) + extended_folder_name = folder_name + '_' + str(uuid4())[:4] + parent_dir = os.path.abspath(os.path.join(path, os.pardir)) + path = os.path.abspath(os.path.join(parent_dir, extended_folder_name)) + os.makedirs(path) + + return path + + +@activity +def rename_folder(input_path, new_name=None): + """Rename folder + + Rename a folder + + :parameter path: Full path of folder that will be renamed + :parameter new_name: New name of the folder e.g. 'new_folder'. By default folder will be renamed to original folder name with '_renamed' added to the folder name. + + :return: Path to renamed folder as a string. None if folder could not be renamed. + + :Example: + + >>> # Make new folder in home directory for illustration + >>> testfolder = create_folder() + >>> # Rename the folder + >>> rename_folder(testfolder, new_name='testfolder_brand_new_name') + 'C:\\Users\\\\testfolder_brand_new_name' + + Keywords + folder, rename, rename folder, organise folder, folders, folder manipulation, explorer, nautilus + + Icon + las la-folder + + """ + import os + + if not os.path.exists(input_path): + return None + + if not new_name: + folder_name = os.path.basename(input_path) + new_name = folder_name + '_renamed' + + parent_dir = os.path.abspath(os.path.join(input_path, os.pardir)) + renamed_dir = os.path.join(parent_dir, new_name) + + if os.path.exists(renamed_dir): + return None + + os.rename(input_path, renamed_dir) + + return renamed_dir + + +@activity +def show_folder(path=None): + """Open a folder + + Open a folder with the default explorer. + + :parameter path: Full path of folder that will be opened. Default value is the home directory + + :return: Path to opend folder as a string + + :Example: + + >>> # Make new folder in home directory for illustration + >>> testfolder = create_folder() + >>> # Open folder + >>> show_folder(testfolder) + 'C:\\Users\\\\new_folder' + + + Keywords + folder, open, open folder, explorer, nautilus + + Icon + las la-folder-open + + """ + import os + + if not path: + path = os.path.expanduser("~") + + if os.path.isdir(path): + os.startfile(path) + + return path + + +@activity +def move_folder(from_path, to_path): + """Move a folder + + Moves a folder from one place to another. + If the new location already contains a folder with the same name, a random 4 character uid is added to the name. + + :parameter fom_path: Full path to the source location of the folder + :parameter new_path: Full path to the destination location of the folder. + + :return: Path to new location of folder as a string. None if folder could not be moved. + + :Example: + + >>> # Make new folder in home directory for illustration + >>> # If no new_folder exists in home dir this will be called new_folder + >>> testfolder = create_folder() + >>> # Make a second new folder + >>> # Since new_folder already exists this folder will get a random id added (in this case abc1) + >>> testfolder_2 = create_folder() + >>> # Move testfolder in testfolder_2 + >>> move_folder(testfolder, testfolder_2) + 'C:\\Users\\\\new_folder_abc1\\new_folder' + + Keywords + folder, move, move folder, explorer, nautilus, folder manipulation + + Icon + las la-folder + """ + from uuid import uuid4 + import os + import shutil + + from_path_folder = os.path.basename(from_path) + if os.path.isdir(from_path): + if not os.path.isdir(to_path): + shutil.move(from_path, to_path) + return os.path.join(to_path, from_path_folder) + elif os.path.isdir(to_path): + to_path_folder_name = os.path.basename(to_path) + to_path_folder_name = to_path_folder_name + str(uuid4())[:4] + to_path_base_name = os.path.abspath( + os.path.join(to_path, os.pardir)) + to_path = os.path.join(to_path_base_name, to_path_folder_name) + shutil.move(from_path, to_path) + return os.path.join(to_path, from_path_folder) + return None + + +@activity +def remove_folder(path, allow_root=False, delete_read_only=True): + """Remove folder + + Remove a folder including all subfolders and files. For the function to work optimal, all files and subfolders in the main targetfolder should be closed. + + :parameter path: Full path to the folder that will be deleted + :parameter allow_root: Allow paths with an arbitrary length of 10 characters or shorter to be deleted. Default value is False. + + :return: Path to deleted folder as a string + + :Example: + + >>> # Make new folder in home directory for illustration + >>> testfolder = create_folder() + >>> # Check if folder exists + >>> print( folder_exists(testfolder) ) # Should print True + >>> # Remove folder + >>> remove_folder(testfolder) + >>> # Check again if folder exists + >>> folder_exists(testfolder) + False + + Keywords + folder, delete folder, delete, nautilus, folder manipulation, explorer, delete folder, remove, remove folder + + Icon + las la-folder-minus + + """ + import os + import shutil + + if len(path) > 10 or allow_root: + if os.path.isdir(path): + shutil.rmtree(path, ignore_errors=delete_read_only) + return path + + +@activity +def empty_folder(path, allow_root=False): + """Empty folder + + Remove all contents from a folder + For the function to work optimal, all files and subfolders in the main targetfolder should be closed. + + :parameter path: Full path to the folder that will be emptied + :parameter allow_root: Allow paths with an arbitrary length of 10 characters or shorter to be emptied. Default value is False. + + :Example: + + >>> # Make new folder in home directory for illustration + >>> testfolder = create_folder() + >>> # Make new textfile in this folder + >>> import os + >>> textfile_location = os.path.join(testfolder, 'testfile.txt') + >>> make_textfile(output_path=textfile_location ) + >>> # Print all files in the testfolder + >>> print( get_files_in_folder(testfolder) ) # Should show + >>> # Empty the folder + >>> empty_folder(testfolder) + >>> # Check what is in the folder + >>> get_files_in_folder(testfolder) + [] + + Keywords + folder, empty folder, delete, empty, clean, clean folder, nautilus, folder manipulation, explorer, delete folder, remove, remove folder + + Icon + las la-folder-minus + """ + import os + + if len(path) > 10 or allow_root: + if os.path.isdir(path): + for root, dirs, files in os.walk(path, topdown=False): + for name in files: + os.remove(os.path.join(root, name)) + for name in dirs: + os.rmdir(os.path.join(root, name)) + + +@activity +def folder_exists(path): + """Checks if folder exists + + Check whether folder exists or not, regardless if folder is empty or not. + + :parameter path: Full path to folder + + :return: Boolean + + :Example: + + >>> # Make new folder in home directory for illustration + >>> testfolder = create_folder() + >>> # Check if folder exists + >>> folder_exists(testfolder) + True + + Keywords + folder, folder exists, nautilus, explorer, folder manipulation, files + + Icon + las la-folder + """ + import os + + return os.path.isdir(path) + + +@activity +def copy_folder(from_path, to_path=None): + """Copy a folder + + Copies a folder from one place to another. + If the new location already contains a folder with the same name, a random 4 character id is added to the name. + + :parameter old_path: Full path to the source location of the folder + :parameter new_path: Full path to the destination location of the folder. If no path is specified folder will get copied in the from_path directory + + :return: Path to new folder as string + + :Example: + + >>> # Make new folder in home directory for illustration + >>> testfolder = create_folder() + >>> # Copy this folder + >>> # Since new_folder already exists in home dir this folder will get a random id added (in this case abc1) + >>> copy_folder(testfolder) + + Keywords + folder, move, move folder, explorer, nautilus, folder manipulation + + Icon + lar la-folder + """ + from uuid import uuid4 + import os + import shutil + + if not to_path: + to_path = from_path + + from_path_folder = os.path.basename(from_path) + if os.path.isdir(from_path): + if not os.path.isdir(to_path): + shutil.copytree(from_path, to_path) + return os.path.join(to_path, from_path_folder) + elif os.path.isdir(to_path): + to_path_folder_name = os.path.basename( + to_path) + '_copy_' + str(uuid4())[:4] + to_path_base_name = os.path.abspath( + os.path.join(to_path, os.pardir)) + to_path = os.path.join(to_path_base_name, to_path_folder_name) + shutil.copytree(from_path, to_path) + return os.path.join(to_path, from_path_folder) + return None + + +@activity +def zip_folder(path, new_path=None): + """Zip + + Zia folder and it's contents. Creates a .zip file. + + :parameter path: Full path to the source location of the folder that will be zipped + :parameter new_path: Full path to save the zipped folder. If no path is specified a folder with the original folder name plus 4 random characters + + :return: Path to zipped folder + + :Example: + + >>> # Make new folder in home directory for illustration + >>> testfolder = create_folder() + >>> # Zip this folder + >>> zip_folder(testfolder) + + Keywords + zip, zipping, winrar, rar, 7zip, compress, unzip + + Icon + las la-archive + """ + import zipfile + import os + import shutil + from uuid import uuid4 + + if not new_path: + from uuid import uuid4 + new_path = path + "_" + str(uuid4())[:4] + if os.path.isdir(path): + shutil.make_archive(new_path, "zip", path) + return new_path + + +@activity +def unzip(path, to_path=None): + """Unzip + + Unzips a file or folder from a .zip file. + + :parameter path: Full path to the source location of the file or folder that will be unzipped + :parameter to_path: Full path to save unzipped contents. If no path is specified the unzipped contents will be stored in the same directory as the zipped file is located. + + :return: Path to unzipped folder + + :Example: + + >>> # Make new folder in home directory for illustration + >>> testfolder = create_folder() + >>> # Zip this folder + >>> zipped_folder = zip_folder(testfolder) + >>> # Unzip this folder + >>> unzip(zipped_folder) + + Keywords + zip, zipping, winrar, rar, 7zip, compress, unzip + + Icon + las la-archive + """ + import zipfile + import os + import shutil + + if os.path.exists(path): + zipp = zipfile.ZipFile(path) + if not to_path: + to_path = from_path_folder = os.path.basename(path) + zipp.extractall(to_path) + elif os.path.isdir(to_path): + zipp.extractall(to_path) + zipp.close() + return to_path + + +""" +Delay +Icon: las la-hourglass +""" + + +@activity +def wait(seconds=1): + """Wait + + Make the robot wait for a specified number of seconds. Note that this activity is blocking. This means that subsequent activities will not occur until the the specified waiting time has expired. + + :parameter seconds: Time in seconds to wait + + :Example: + + >>> print('Start the wait') + >>> wait() + >>> print('The wait is over') + + Keywords + wait, sleep, time, timeout, time-out, hold, pause + + Icon + las la-hourglass + """ + from time import sleep + + sleep(seconds) + + +@activity +def wait_for_image(path=None, timeout=60): + """Wait for image + + Waits for an image to appear on the screen + Note that this activity waits for an exact match of the template image to appear on the screen. + Small variations, such as color or resolution could result in a mismatch. + + :parameter path: Full or relative path to the template image. + :parameter timeout: Maximum time in seconds to wait before continuing. Default value is 60 seconds. + + :Example: + + >>> # Create a random snippet from current screen + >>> # This is for illustration and can be replaced by template + >>> snippet = random_screen_snippet(size=10) + >>> # Wait for the snippet to be visible + >>> wait_for_image(snippet) + + Keywords + image matching, wait, pause, vision, template, template matching + + Icon + las la-hourglass + """ + + from pyautogui import locateCenterOnScreen + from time import sleep + + for _ in range(timeout): + try: + locateCenterOnScreen(path) + break + except TypeError: + sleep(1) + + +@activity +def wait_folder_exists(path, timeout=60): + """Wait for folder + + Waits until a folder exists. + Not that this activity is blocking and will keep the system waiting. + + :parameter path: Full path to folder. + :parameter timeout: Maximum time in seconds to wait before continuing. Default value is 60 seconds. + + :Example: + + >>> # Create a random folder + >>> testfolder = create_folder() + >>> # Wait for the snippet to be visible + >>> wait_folder_exists(testfolder) + + Keywords + image matching, wait, pause, vision, template, template matching + + Icon + las la-hourglass + """ + from time import sleep + import os + + while not os.path.exists(path): + sleep(1) + return + + for _ in range(timeout): + if os.path.exists(path): + break + sleep(1) + + +""" +Word Application +Icon: las la-file-word +""" + + +class Word: + @activity + def __init__(self, visible=True, file_path=None): + """Start Word Application + + For this activity to work, Microsoft Office Word needs to be installed on the system. + + :parameter visible: Show Word in the foreground if True or hide if False, defaults to True. + :parameter path: Enter a path to open Word with an existing Word file. If no path is specified a document will be initialized, this is the default value. + + :Example: + + >>> word = Word() + + Keywords + word, editor, text, text edit, office, document, microsoft word, doc, docx + + Icon + lar la-file-word + + """ + self.file_path = file_path + + self.app = self._launch() + self.app.Visible = visible + + def _launch(self): + """Utility function to create the Word application scope object + + :return: Application object (win32com.client) + """ + try: + import win32com.client + + app = win32com.client.gencache.EnsureDispatch("Word.Application") + #app = win32com.client.dynamic.Dispatch("Word.Application") + + except: + raise Exception( + "Could not launch Word, do you have Microsoft Office installed on Windows?" + ) + + if self.file_path: + app.Documents.Open(self.file_path) + else: + app.Documents.Add() + + return app + + @activity + def append_text(self, text): + """Append text + + Append text at end of Word document. + + :parameter text: Text to append to document + + :Example: + + >>> # Start Word + >>> word = Word() + >>> word.append_text('This is sample text') + + Keywords + word, editor, text, text edit, office, document, microsoft word, doc, docx + + Icon + lar la-file-word + """ + import win32com.client + + wc = win32com.client.constants + self.app.Selection.EndKey(Unit=wc.wdStory) + self.app.Selection.TypeText(text) + + @activity + def replace_text(self, placeholder_text, replacement_text): + """Replace text + + Can be used for example to replace arbitrary placeholder value. For example when + using template document, using 'XXXX' as a placeholder. Take note that all strings are case sensitive. + + :parameter placeholder_text: Placeholder text value (string) in the document, this will be replaced, e.g. 'Company Name' + :parameter replacement_text: Text (string) to replace the placeholder values with. It is recommended to make this unique to avoid wrongful replacement, e.g. 'XXXX_placeholder_XXX' + + :Example: + + >>> # Start Word + >>> word = Word() + >>> word.append_text('This is sample text') + >>> word.replace_text('sample', 'real') + + Keywords + word, replace, text, template + + Icon + lar la-file-word + """ + + self.app.Selection.GoTo(0) + self.app.Selection.Find.Text = placeholder_text + self.app.Selection.Find.Replacement.Text = replacement_text + self.app.Selection.Find.Execute(Replace=2, Forward=True) + + @activity + def read_all_text(self, return_as_list=False): + """Read all text + + Read all the text from a document + + :parameter return_as_list: Set this paramater to True to return text as a list of strings. Default value is False. + + :return: Text from the document + + :Example: + + >>> # Start Word + >>> word = Word() + >>> word.append_text('This is sample text') + >>> word.replace_text('sample', 'real') + >>> word.read_all_text() + 'This is real text' + + Keywords + word, extract, text, document + + Icon + lar la-file-word + """ + + if return_as_list: + return self.app.ActiveDocument.Content.Text.split('\r') + return self.app.ActiveDocument.Content.Text + + @activity + def export_to_pdf(self, path=None): + """Export to PDF + + Export the document to PDF + + :parameter path: Output path where PDF file will be exported to. Default path is home directory with filename 'pdf_export.pdf'. + + :Example: + + >>> # Start Word + >>> word = Word() + >>> word.append_text('This is sample text') + >>> word.replace_text('sample', 'real') + >>> word.export_to_pdf('output.pdf') + + Keywords + word, pdf, document, export, save as + + Icon + lar la-file-pdf + + """ + + if not path: + import os + path = os.path.expanduser("~") + '/pdf_export.pdf' + + self.app.ActiveDocument.ExportAsFixedFormat(OutputFileName=path, + ExportFormat=17, + OpenAfterExport=False, + OptimizeFor=0, + CreateBookmarks=1, + DocStructureTags=True + ) + + @activity + def export_to_html(self, path=None): + """Export to HTML + + Export to HTML + + :parameter path: Output path where HTML file will be exported to. Default path is home directory with filename 'html_export.html'. + + :Example: + + >>> # Start Word + >>> word = Word() + >>> word.append_text('This is sample text') + >>> word.replace_text('sample', 'real') + >>> word.export_to_html('output.html') + + Keywords + word, html, document, export, save as + + Icon + las la-html5 + + """ + if not path: + import os + path = os.path.expanduser("~") + '/pdf_export.pdf' + + import win32com.client + + wc = win32com.client.constants + word.app.ActiveDocument.WebOptions.RelyOnCSS = 1 + word.app.ActiveDocument.WebOptions.OptimizeForBrowser = 1 + word.app.ActiveDocument.WebOptions.BrowserLevel = 0 + word.app.ActiveDocument.WebOptions.OrganizeInFolder = 0 + word.app.ActiveDocument.WebOptions.UseLongFileNames = 1 + word.app.ActiveDocument.WebOptions.RelyOnVML = 0 + word.app.ActiveDocument.WebOptions.AllowPNG = 1 + word.app.ActiveDocument.SaveAs( + FileName=path, FileFormat=wc.wdFormatHTML) + + @activity + def set_footers(self, text): + """Set footers + + Set the footers of the document + + :parameter text: Text to put in the footer + + :Example: + + >>> # Start Word + >>> word = Word() + >>> word.set_footers('This is a footer!') + + + Keywords + word, footer, footers + + Icon + las la-heading + """ + for section in self.app.ActiveDocument.Sections: + for footer in section.Footers: + footer.Range.Text = text + + @activity + def set_headers(self, text): + """Set headers + + Set the headers of the document + + :parameter text: Text to put in the header + + :Example: + + >>> # Start Word + >>> word = Word() + >>> word.set_headers('This is a header!') + + Keywords + word, header, headers + + Icon + las la-subscript + """ + for section in self.app.ActiveDocument.Sections: + for footer in section.Headers: + footer.Range.Text = text + + +""" +Word File +Icon: las la-file-word +""" + +class WordFile: + @activity + def __init__(self, file_path=None): + """Read and Write Word files + + These activities can read, write and edit Word (docx) files without the need of having Word installed. + Note that, in contrary to working with the :func: 'Word' activities, a file get saved directly after manipulation. + + :parameter file_path: Enter a path to open Word with an existing Word file. If no path is specified a 'document.docx' will be initialized in the home directory, this is the default value. If a document with the same name already exists the file will be overwritten. + + :Example: + + >>> wordfile = WordFile() + >>> wordfile.append_text('Some sample text') + >>> wordfile.read_all_text() + 'Some sample text' + + Keywords + word, read, text, file + + Icon + las la-file-word + + """ + + self.file_path = file_path + + self.app = self._launch() + + def _launch(self): + from docx import Document + import os + + if self.file_path: + if not os.path.exists(self.file_path): + document = Document(self.file_path) + else: + path = os.path.expanduser("~") + '\document.docx' + document = Document() + document.save(path) + self.file_path = path + + @activity + def read_all_text(self, return_as_list=False): + """Read all text + + Read all the text from the document + + :parameter return_as_list: Set this paramater to True to return text as a list of strings. Default value is False. + + :return: Text of the document + + :Example: + + >>> wordfile = WordFile() + >>> wordfile.append_text('Some sample text') + >>> wordfile.read_all_text() + 'Some sample text' + + Keywords + word, read, text, file + + Icon + las la-file-word + """ + + from docx import Document + + document = Document(self.file_path) + text = [] + for paragraph in document.paragraphs: + text.append(paragraph.text) + + if return_as_list: + return text + return '\r'.join(map(str, text)) + + @activity + def append_text(self, text, auto_save=True): + """Append text + + Append text at the end of the document + + :parameter text: Text to append + :parameter auto_save: Save document after performing activity. Default value is True + + :Example: + + >>> wordfile = WordFile() + >>> wordfile.append_text('Some sample text') + + Keywords + word, append text, add text + + Icon + las la-file-word + """ + from docx import Document + + document = Document(self.file_path) + document.add_paragraph(text) + + if auto_save: + document.save(self.file_path) + + @activity + def save(self): + """Save + + Save document + + :Example: + + >>> wordfile = WordFile() + >>> wordfile.append_text('Some sample text') + >>> wordfile.save() + + Keywords + word, save, store + + Icon + las la-file-word + """ + document.save(self.file_path) + + @activity + def save_as(self, path): + """Save as + + :Example: + + >>> wordfile = WordFile() + >>> wordfile.append_text('Some sample text') + >>> wordfile.save_as('document.docx') + + Keywords + word, save as, store + + Icon + las la-file-word + """ + document.save(path) + + @activity + def set_headers(self, text, auto_save=True): + """Set headers + + Set headers of Word document + + :parameter text: Text to put in the header + :parameter auto_save: Save document after performing activity. Default value is True + + :Example: + + >>> wordfile = WordFile() + >>> wordfile.append_text('Some sample text') + >>> wordfile.set_headers('This is a header') + + Keywords + word, header text + + Icon + las la-file-word + """ + from docx import Document + + document = Document(self.file_path) + document.add_heading(text) + + if auto_save: + document.save(self.file_path) + + @activity + def replace_text(self, placeholder_text, replacement_text, auto_save=True): + """Replace all + + Replaces all occurences of a placeholder text in the document with a replacement text. + + Can be used for example to replace arbitrary placeholder value. + For example when using template slidedeck, using 'XXXX' as a placeholder. + Take note that all strings are case sensitive. + + :parameter placeholder_text: Placeholder text value (string) in the document, this will be replaced, e.g. 'Company Name' + :parameter replacement_text: Text (string) to replace the placeholder values with. It is recommended to make this unique to avoid wrongful replacement, e.g. 'XXXX_placeholder_XXX' + :parameter auto_save: Save document after performing activity. Default value is True + + :Example: + + >>> wordfile = WordFile() + >>> wordfile.append_text('Some sample text') + >>> wordfile.replace_text('sample', 'real') + + Keywords + word, replace text, template + + Icon + las la-file-word + """ + from docx import Document + + document = Document(self.file_path) + for paragraph in document.paragraphs: + paragraph.text = paragraph.text.replace( + placeholder_text, replacement_text) + + if auto_save: + document.save(self.file_path) + + +""" +Outlook Application +Icon: las la-envelope +""" + + +class Outlook: + @activity + def __init__(self, account_name=None): + """Start Outlook Application + + For this activity to work, Outlook needs to be installed on the system. + + :Example: + + >>> outlook = Outlook() + + Keywords + outlook, send e-mail, send mail + + Icon + las la-mail-bulk + + """ + self.app = self._launch() + self.account_name = account_name + + def _launch(self): + """Utility function to create the Outlook application scope object + + :return: Application object (win32com.client) + """ + try: + import win32com.client + + app = win32com.client.gencache.EnsureDispatch( + "outlook.application") + + except: + raise Exception( + "Could not launch Outlook, do you have Microsoft Office installed on Windows?" + ) + + return app + + @activity + def send_mail(self, to_address, subject="", body="", html_body=None, attachment_paths=None): + """Send e-mail + + Send an e-mail using Outlook + + :parameter to_address: The e-mail address the e-mail should be sent to + :parameter subject: The subject of the e-mail + :parameter body: The text body contents of the e-mail + :parameter html_body: The HTML body contents of the e-mail (optional) + :parameter attachment_paths: List of file paths to attachments + + :Example: + + >>> outlook = Outlook() + >>> outlook.send_mail('test@test.com', subject='Hello world', body='Hi there') + + Keywords + outlook, send e-mail, send mail + + Icon + las la-mail-bulk + """ + # mapi = self.app.GetNamespace("MAPI") + + # Create a new e-mail + mail = self.app.CreateItem(0) + + mail.To = to_address + mail.Subject = subject + mail.Body = body + + if html_body: + mail.HTMLBody = html_body + + # Add attachments + if attachment_paths: + for attachment_path in attachment_paths: + mail.Attachments.Add(attachment_path) + + # Send the e-mail + mail.Send() + + @activity + def get_folders(self, limit=999): + """Retrieve folders + + Retrieve list of folders from Outlook + + :parameter limit: Maximum number of folders to retrieve + + :Example: + + >>> outlook = Outlook() + >>> outlook.get_folders() + ['Inbox', 'Sent', ...] + + Keywords + outlook, get folders, list folders + + Icon + las la-mail-bulk + """ + + folders = [] + + if self.account_name: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(self.account_name).Folders + else: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(1).Folders + for folder in found_folders: + name = folder.Name + folders.append(name) + + return folders + + @activity + def get_mails(self, folder_name="Inbox", fields=None): + """Retrieve e-mails + + Retrieve list of messages from Outlook + + :parameter folder_name: Name of the Outlook folder, can be found using `get_folders`. + :parameter limit: Number of messages to retrieve + :parameter fields: Fields (properties) of e-mail messages to give, requires tupl Stadard is 'Subject', 'Body', 'SentOn' and 'SenderEmailAddress'. + + :return: List of dictionaries containing the e-mail messages with from, to, subject, body and html. + + :Example: + + >>> outlook = Outlook() + >>> outlook.get_mails() + [ + { + 'Subject': 'Hello World!', + 'Body' : 'This is an e-mail', + 'SenderEmailAddress': 'from@test.com' + } + ] + + Keywords + outlook, retrieve e-mail, receive e-mails, process e-mails, get mails + + Icon + las la-mail-bulk + """ + + if not fields: + fields = ("Subject", "Body", "SenderEmailAddress") + + messages = [] + + if self.account_name: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(self.account_name).Folders + else: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(1).Folders + for folder in found_folders: + name = folder.Name + if name == folder_name: + break + else: + raise Exception( + "Could not find the folder with name '{}'.".format(folder_name) + ) + + # Loop over the items in the folder + for item in folder.Items: + message = {} + + for key in fields: + try: + message[key] = getattr(item, key) + except AttributeError: + pass + + messages.append(message) + + return messages + + @activity + def delete_mails(self,folder_name="Inbox",limit=0,subject_contains="",body_contains="",sender_contains=""): + """Delete e-mails + + Deletes e-mail messages in a certain folder. Can be specified by searching on subject, body or sender e-mail. + + :parameter folder_name: Name of the Outlook folder, can be found using `get_folders` + :parameter limit: Maximum number of e-mails to delete in one go + :parameter subject_contains: Only delete e-mail if subject contains this + :parameter body_contains: Only delete e-mail if body contains this + :parameter sender_contains: Only delete e-mail if sender contains this + + :Example: + + >>> outlook = Outlook() + >>> outlook.delete_mails(subject_contains='hello') + + Keywords + outlook, remove e-mails, delete mail, remove mail + + Icon + las la-mail-bulk + + """ + # Find the appropriate folder + if self.account_name: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(self.account_name).Folders + else: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(1).Folders + for folder in found_folders: + name = folder.Name + if name == folder_name: + break + else: + raise Exception( + "Could not find the folder with name '{}'.".format(folder_name) + ) + + # Loop over the items in the folder + for i, item in enumerate(folder.Items): + + if limit: + if i > limit: + break + + if subject_contains in item.Subject: + if body_contains in item.Body: + if sender_contains in item.SenderEmailAddress: + item.Delete() + + @activity + def move_mails(self,source_folder_name="Inbox",target_folder_name="Archive",limit=0,subject_contains="",body_contains="",sender_contains=""): + """Move e-mails + + Move e-mail messages in a certain folder. Can be specified by searching on subject, body or sender e-mail. + + :parameter source_folder_name: Name of the Outlook source folder from where e-mails will be moved, can be found using `get_folders` + :parameter target_folder_name: Name of the Outlook destination folder to where e-mails will be moved, can be found using `get_folders` + :parameter limit: Maximum number of e-mails to move in one go + :parameter subject_contains: Only move e-mail if subject contains this + :parameter body_contains: Only move e-mail if body contains this + :parameter sender_contains: Only move e-mail if sender contains this + + :Example: + + >>> outlook = Outlook() + >>> outlook.move_mails(subject_contains='move me') + + Keywords + outlook, move e-mail, move e-mail to folder + + Icon + las la-mail-bulk + """ + # Find the appropriate source folder + if self.account_name: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(self.account_name).Folders + else: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(1).Folders + for source_folder in found_folders: + name = source_folder.Name + if name == source_folder_name: + break + else: + raise Exception( + "Could not find the folder with name '{}'.".format( + source_folder_name) + ) + + # Find the appropriate target folder + if self.account_name: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(self.account_name).Folders + else: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(1).Folders + for target_folder in found_folders: + name = target_folder.Name + if name == target_folder_name: + break + else: + raise Exception( + "Could not find the folder with name '{}'.".format( + target_folder_name) + ) + + # Loop over the items in the folder + for i, item in enumerate(source_folder.Items): + + if limit: + if i > limit: + break + + if subject_contains in item.Subject: + if body_contains in item.Body: + if sender_contains in item.SenderEmailAddress: + item.Move(target_folder) + + @activity + def save_attachments(self, folder_name="Inbox", target_folder_path=None): + """Save attachments + + :parameter folder_name: Name of the Outlook folder, can be found using `get_folders`. + :parameter target_folder_path: Path where attachments will be saved. Default is the home directory. + + :return: List of paths to saved attachments. + + :Example: + + >>> outlook = Outlook() + >>> outlook.save_attachments() + ['Attachment.pdf', 'Signature_image.jpeg'] + + Keywords + outlook, save attachments, download attachments, extract attachments + + Icon + las la-mail-bulk + """ + import os + + paths = [] + + # Set to user home if no path specified + if not target_folder_path: + target_folder_path = os.path.expanduser("~") + + # Find the appropriate folder + if self.account_name: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(self.account_name).Folders + else: + found_folders = self.app.GetNamespace( + "MAPI").Folders.Item(1).Folders + for folder in found_folders: + name = folder.Name + if name == folder_name: + break + else: + raise Exception( + "Could not find the folder with name '{}'.".format(folder_name) + ) + # Loop over the items in the folder + for item in folder.Items: + for attachment in item.Attachments: + path = os.path.join(target_folder_path, attachment.FileName) + attachment.SaveAsFile(path) + paths.append(path) + + return paths + + @activity + def get_contacts(self, fields=None): + """Retrieve contacts + + :parameter fields: Fields can be specified as a tuple with their exact names. Standard value is None returning "LastName", "FirstName" and "Email1Address". + + :return: List of dictionaries containing the contact details. + + :Example: + + >>> outlook = Outlook() + >>> outlook.get_contacts() + [ + { + 'LastName': 'Doe', + 'FirstName' : 'John', + 'Email1Address': 'john@test.com' + } + ] + + Keywords + outlook, get contacts, download contacts, rolodex + + Icon + las la-mail-bulk + """ + import win32com.client + + if not fields: + fields = ("LastName", "FirstName", "Email1Address") + + contacts = [] + + mapi = self.app.GetNamespace("MAPI") + + data = mapi.GetDefaultFolder( + win32com.client.constants.olFolderContacts) + + for item in data.Items: + if item.Class == win32com.client.constants.olContact: + contact = {} + for key in item._prop_map_get_: + if key in fields: + if isinstance(getattr(item, key), (int, str)): + contact[key] = getattr(item, key) + contacts.append(contact) + + return contacts + + @activity + def add_contact(self, email, first_name="", last_name=""): + """Add a contact + + Add a contact to Outlook contacts + + :parameter email: The e-mail address for the contact + :parameter first_name: First name for the contact (optional) + :parameter last_name: Last name for the contact (optional) + + :Example: + + >>> outlook = Outlook() + >>> outlook.add_contact('sales@automagica.com') + + Keywords + outlook, create contact, add contact + + Icon + las la-mail-bulk + """ + + # Create a new contact + contact = self.app.CreateItem(2) + + contact.Email1Address = email + + if first_name: + contact.FirstName = first_name + + if last_name: + contact.LastName = last_name + + contact.Save() + + @activity + def quit(self): + """Quit + + Close the Outlook application + + :Example: + + >>> outlook = Outlook() + >>> outlook.quit() + + Keywords + outlook, close, quit + + Icon + las la-mail-bulk + """ + self.app.Application.Quit() + + +""" +Excel Application +Icon: las la-file-excel +""" + + +class Excel: + @activity + def __init__(self, visible=True, file_path=None): + """Start Excel Application + + For this activity to work, Microsoft Office Excel needs to be installed on the system. + + :parameter visible: Show Excel in the foreground if True or hide if False, defaults to True. + :parameter path: Enter a path to open Excel with an existing Excel file. If no path is specified a workbook will be initialized, this is the default value. + + :Example: + + >>> # Open Excel + >>> excel = Excel() + + Keywords + excel, add worksheet, add tab + + Icon + las la-file-excel + + """ + self.file_path = file_path + + self.app = self._launch() + self.app.Visible = visible + + def _launch(self): + """Utility function to create the Excel application scope object + + :return: Application object (win32com.client) + """ + try: + import win32com.client + + app = win32com.client.gencache.EnsureDispatch("Excel.Application") + + except: + raise Exception( + "Could not launch Excel, do you have Microsoft Office installed on Windows?") + + if self.file_path: + app.Workbooks.Open(self.file_path) + else: + app.Workbooks.Add() + + self.workbook = app.ActiveWorkbook + + return app + + @activity + def add_worksheet(self, name=None): + """Add worksheet + + Adds a worksheet to the current workbook + + :parameter workbook: Workbook object which is retrieved with either new_workbook or open_workbook + :parmeter name: Give the sheet a name (optional) + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Add a worksheet + >>> excel.add_worksheet('My Example Worksheet') + + Keywords + excel, add worksheet, add tab, insert worksheet, new worksheet + + Icon + las la-file-excel + + """ + worksheet = self.workbook.Worksheets.Add() + if name: + worksheet.Name = name + + @activity + def activate_worksheet(self, name): + """Activate worksheet + + Activate a worksheet in the current Excel document by name + + :parameter name: Name of the worksheet to activate + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Add the first worksheet + >>> excel.add_worksheet('My Example Worksheet') + >>> # Add another worksheet + >>> excel.add_worksheet('Another Worksheet') + >>> # Activate the first worksheet + >>> excel.activate_worksheet('My Example Worksheet) + + + Keywords + excel, activate worksheet, set worksheet, select worksheet, select tab, activate tab + + Icon + las la-file-excel + + """ + for worksheet in self.workbook.Worksheets: + if worksheet.Name == name: + worksheet.Activate() + + @activity + def save(self): + """Save + + Save the current workbook + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Add the first worksheet + >>> excel.add_worksheet('My Example Worksheet') + >>> # Save the workbook to My Documents + >>> excel.save() + + Keywords + excel, save, store + + Icon + las la-file-excel + """ + self.workbook.Save() + + @activity + def save_as(self, path): + """Save as + + Save the current workbook to a specific path + + :parameter path: Path where workbook will be saved. Default is home directory and filename 'workbook.xlsx' + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Add the first worksheet + >>> excel.add_worksheet('My Example Worksheet') + >>> # Save the workbook to the current working directory + >>> excel.save_as('output.xlsx') + + Keywords + excel, save as, export + + Icon + las la-file-excel + + """ + if not path: + import os + path = os.path.expanduser("~") + '\workbook.xlsx' + + self.app.DisplayAlerts = False + self.workbook.SaveAs(path) + self.app.DisplayAlerts = True + + @activity + def write_cell(self, column, row, value): + """Write cell + + Write to a specific cell in the currently active workbook and active worksheet + + :parameter column: Column number (integer) to write + :parameter row: Row number (integer) to write + :parameter value: Value to write to specific cell + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Add the first worksheet + >>> excel.add_worksheet('My Example Worksheet') + >>> # Insert a text into the first cell + >>> excel.write_cell(1,1, 'Hello World!') + + Keywords + excel, cell, insert cell, insert data + + Icon + las la-file-excel + """ + self.workbook.ActiveSheet.Cells(row, column).Value = value + + @activity + def read_cell(self, column, row): + """Read cell + + Read a cell from the currently active workbook and active worksheet + + :parameter column: Column number (integer) to read + :parameter row: Row number (integer) to read + + :return: Cell value + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Add the first worksheet + >>> excel.add_worksheet('My Example Worksheet') + >>> # Insert a text into the first cell + >>> excel.write_cell(1,1, 'Hello World!') + >>> excel.read_cell(1,1) + 'Hello World!' + + Keywords + excel, cell, read cell, read data + + Icon + las la-file-excel + """ + return self.workbook.ActiveSheet.Cells(row, column).Value + + @activity + def write_range(self, range_, value): + """Write range + + Write to a specific range in the currently active worksheet in the active workbook + + :parameter range_: Range to write to, e.g. "A1:D10" + :parameter value: Value to write to range + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Add the first worksheet + >>> excel.add_worksheet('My Example Worksheet') + >>> # Insert a text in every cell in this range + >>> excel.write_range('A1:D5', 'Hello World!') + + Keywords + excel, cell, write range, read data + + Icon + las la-file-excel + """ + self.workbook.ActiveSheet.Range(range_).Value = value + + @activity + def read_range(self, range_): + """Read range + + Read a range of cells from the currently active worksheet in the active workbook + + :parameter range_: Range to read from, e.g. "A1:D10" + + :return value: Values in param range + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Add the first worksheet + >>> excel.add_worksheet('My Example Worksheet') + >>> # Insert a text in every cell in this range + >>> excel.write_range('A1:D5', 'Hello World!') + >>> # Read the same range + >>> excel.read_range('A1:D5') + [['Hello World', 'Hello World', 'Hello World', 'Hello World'], ...] + + Keywords + excel, cell, read range, read data + + Icon + las la-file-excel + """ + return self.workbook.ActiveSheet.Range(range_).Value + + @activity + def run_macro(self, name): + """Run macro + + Run a macro by name from the currently active workbook + + :parameter name: Name of the macro to run. + + :Example: + + >>> excel = Excel('excel_with_macro.xlsx') + >>> # Run the macro + >>> excel.run_macro('Macro1') + + Keywords + excel, run macro, run vba + + Icon + las la-file-excel + """ + return self.app.Run(name) + + @activity + def get_worksheet_names(self): + """Get worksheet names + + Get names of all the worksheets in the currently active workbook + + :return: List is worksheet names + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Add a worksheet + >>> excel.add_worksheet('My Example Worksheet') + >>> # Get all worksheet names + >>> excel.get_worksheet_names() + ['Sheet1', 'My Example Worksheet'] + + Keywords + excel, worksheet names, tab names + + Icon + las la-file-excel + """ + names = [] + + for worksheet in self.workbook.Worksheets: + names.append(worksheet.Name) + + return names + + @activity + def get_table(self, name): + """Get table + + Get table data from the currently active worksheet by name of the table + + :parameter name: List of table names + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Create a table (Table1) + >>> data = [ + { + 'Column A': 'Data Row 1 for A', + 'Column B': 'Data Row 1 for B', + 'Column C': 'Data Row 1 for C', + }, + { + 'Column A': 'Data Row 2 for A', + 'Column B': 'Data Row 2 for B', + 'Column C': 'Data Row 2 for C', + }] + >>> excel.insert_data_as_table(data) + >>> # Get the table + >>> excel.get_table('Table1') + [['Column A', 'Column B', 'Column C'], ['Row 1 A Data', 'Row 1 B Data', 'Row 1 C Data'], ...] + + Keywords + excel, worksheet names, tab names + + Icon + las la-file-excel + """ + data = [] + + for worksheet in self.workbook.Worksheets: + for list_object in worksheet.ListObjects: + if list_object.Name == name: + for row in list_object.DataBodyRange.Value: + data_row = {} + for i, column in enumerate(list_object.HeaderRowRange.Value[0]): + data_row[column] = row[i] + data.append(data_row) + + return data + + @activity + def activate_range(self, range_): + """Activate range + + Activate a particular range in the currently active workbook + + :parameter range_: Range to activate, e.g. "A1:D10" + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Activate a cell range + >>> excel.activate_range('A1:D5') + + Keywords + excel, activate range, make selection, select cells, select range + + Icon + las la-file-excel + """ + self.workbook.ActiveSheet.Range(range_).Select() + + @activity + def activate_first_empty_cell_down(self): + """Activate first empty cell down + + Activates the first empty cell going down + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Write some cells + >>> excel.write_cell(1, 1, 'Filled') + >>> excel.write_cell(1, 2, 'Filled') + >>> excel.write_cell(1, 3, 'Filled') + >>> # Activate the first empty cell going down, in this case cell A4 or (1,4) + >>> excel.activate_first_empty_cell_down() + + Keywords + excel, first empty cell, down + + Icon + las la-file-excel + """ + column = self.app.ActiveCell.Column + row = self.app.ActiveCell.Row + for cell in self.workbook.ActiveSheet.Columns(column).Cells: + if not cell.Value and cell.Row > row: + cell.Select() + break + + @activity + def activate_first_empty_cell_right(self): + """Activate first empty cell right + + Activates the first empty cell going right + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Write some cells + >>> excel.write_cell(1, 1, 'Filled') + >>> excel.write_cell(1, 2, 'Filled') + >>> excel.write_cell(1, 3, 'Filled') + >>> # Activate the first empty cell going right, in this case cell B1 or (2,1) + >>> excel.activate_first_empty_cell_right() + + Keywords + excel, first empty cell, right + + Icon + las la-file-excel + """ + column = self.app.ActiveCell.Column + row = self.app.ActiveCell.Row + for cell in self.workbook.ActiveSheet.Rows(row).Cells: + if not cell.Value and cell.Column > column: + cell.Select() + break + + @activity + def activate_first_empty_cell_left(self): + """Activate first empty cell left + + Activates the first empty cell going left + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> excel.write_cell(1, 1, 'Filled') + >>> excel.write_cell(1, 2, 'Filled') + >>> excel.write_cell(1, 3, 'Filled') + >>> excel.activate_first_empty_cell_left() + + Keywords + excel, first empty cell, left + + Icon + las la-file-excel + """ + column = self.app.ActiveCell.Column + row = self.app.ActiveCell.Row + + for i in range(column): + if column-i > 0: + cell = self.workbook.ActiveSheet.Cells(row, column-i) + if not cell.Value: + cell.Select() + break + + @activity + def activate_first_empty_cell_up(self): + """Activate first empty cell up + + Activates the first empty cell going up + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Write some cells + >>> excel.write_cell(1, 1, 'Filled') + >>> excel.write_cell(1, 2, 'Filled') + >>> excel.write_cell(1, 3, 'Filled') + >>> # Activate first empty cell + >>> excel.activate_first_empty_cell_up() + + Keywords + excel, first empty cell, up + + Icon + las la-file-excel + """ + column = self.app.ActiveCell.Column + row = self.app.ActiveCell.Row + + for i in range(row): + if row-i > 0: + cell = self.workbook.ActiveSheet.Cells(row-i, column) + if not cell.Value: + cell.Select() + break + + @activity + def write_cell_formula(self, column, row, formula): + """Write cell formula + + Write a formula to a particular cell + + :parameter column: Column number (integer) to write formula + :parameter row: Row number (integer) to write formula + :parameter value: Formula to write to specific cell e.g. "=10*RAND()" + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Write a formula to the first cell + >>> excel.write_cell_formula(1, 1, '=1+1) + + Keywords + excel, insert formula, insert calculation, insert calculated cell + + Icon + las la-file-excel + """ + self.workbook.ActiveSheet.Cells(row, column).Formula = formula + + @activity + def read_cell_formula(self, column, row, formula): + """Read cell formula + + Read the formula from a particular cell + + :parameter column: Column number (integer) to read formula + :parameter row: Row number (integer) to read formula + + :return: Cell value + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Write a formula to the first cell + >>> excel.write_cell_formula(1, 1, '=1+1) + >>> # Read the cell + >>> excel.read_cell_formula(1, 1) + '=1+1' + + Keywords + excel, read formula, read calculation + + Icon + las la-file-excel + """ + return self.workbook.ActiveSheet.Cells(row, column).Formula + + @activity + def insert_empty_row(self, row): + """Insert empty row + + Inserts an empty row to the currently active worksheet + + :parameter row: Row number (integer) where to insert empty row e.g 1 + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> excel.write_cell(1, 1, 'Filled') + >>> excel.write_cell(1, 2, 'Filled') + >>> excel.write_cell(1, 3, 'Filled') + >>> excel.insert_empty_row(2) + + Keywords + excel, insert row, add row, empty row + + Icon + las la-file-excel + """ + row_range = 'A' + str(row) + self.workbook.ActiveSheet.Range(row_range).EntireRow.Insert() + + @activity + def insert_empty_column(self, column): + """Insert empty column + + Inserts an empty column in the currently active worksheet. Existing columns will shift to the right. + + :parameter column: Column letter (string) where to insert empty column e.g. 'A' + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> excel.write_cell(1, 1, 'Filled') + >>> excel.write_cell(2, 2, 'Filled') + >>> excel.write_cell(3, 3, 'Filled') + >>> excel.insert_empty_column(2) + + Keywords + excel, insert column, add column + + Icon + las la-file-excel + """ + column_range = str(column) + '1' + self.workbook.ActiveSheet.Range(column_range).EntireColumn.Insert() + + @activity + def delete_row(self, row): + """Delete row in Excel + + Deletes a row from the currently active worksheet. Existing data will shift up. + + :parameter row: Row number (integer) where to delete row e.g 1 + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> excel.write_cell(1, 1, 'Filled') + >>> excel.write_cell(2, 2, 'Filled') + >>> excel.write_cell(3, 3, 'Filled') + >>> excel.delete_row(2) + + Keywords + excel, delete row, remove row + + Icon + las la-file-excel + """ + row_range = 'A' + str(row) + self.workbook.ActiveSheet.Range(row_range).EntireRow.Delete() + + @activity + def delete_column(self, range_): + """Delete column + + Delet a column from the currently active worksheet. Existing columns will shift to the left. + + :parameter column: Column letter (string) where to delete column e.g. 'A' + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> excel.write_cell(1, 1, 'Filled') + >>> excel.write_cell(2, 2, 'Filled') + >>> excel.write_cell(3, 3, 'Filled') + >>> excel.delete_column(2) + + Keywords + excel, delete column, remove column + + Icon + las la-file-excel + """ + column_range = str(column) + '1' + self.workbook.ActiveSheet.Range(column_range).EntireColumn.Delete() + + @activity + def export_to_pdf(self, path=None): + """Export to PDF + + :parameter path: Output path where PDF file will be exported to. Default path is home directory with filename 'pdf_export.pdf'. + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> excel.write_cell(1, 1, 'Filled') + >>> excel.write_cell(2, 2, 'Filled') + >>> excel.write_cell(3, 3, 'Filled') + >>> excel.export_to_pdf('output.pdf') + + Keywords + excel, save as pdf, export to pdf, export as pdf + + Icon + las la-file-excel + """ + if not path: + import os + path = os.path.join(os.path.expanduser("~"), 'pdf_export.pdf') + + self.workbook.ActiveSheet.ExportAsFixedFormat(0, path, 0, True, True) + + @activity + def insert_data_as_table(self, data, range_='A1', table_style="TableStyleMedium2"): + """Insert data as table + + Insert list of dictionaries as a table in Excel + + :parameter data: List of dictionaries to write as table + :parameter range_: Range or startingpoint for table e.g. 'A1' + + :Example: + + >>> excel = Excel() + >>> data = [ + { + 'Column A': 'Data Row 1 for A', + 'Column B': 'Data Row 1 for B', + 'Column C': 'Data Row 1 for C', + }, + { + 'Column A': 'Data Row 2 for A', + 'Column B': 'Data Row 2 for B', + 'Column C': 'Data Row 2 for C', + } + >>> excel.insert_data_as_table(data) + + Keywords + excel, insert data, insert table, create table + + Icon + las la-file-excel + """ + row = self.workbook.ActiveSheet.Range(range_).Row + column = self.workbook.ActiveSheet.Range(range_).Column + + column_names = list(data[0].keys()) + data_values = [[d[key] for key in data[0].keys()] for d in data] + + values = [column_names] + data_values + for i in range(len(values)): + for j in range(len(values[0])): + self.workbook.ActiveSheet.Cells( + row+i, column+j).Value = values[i][j] + + start_cell = self.workbook.ActiveSheet.Cells(row, column) + end_cell = self.workbook.ActiveSheet.Cells(row+i, column+j) + self.workbook.ActiveSheet.Range(start_cell, end_cell).Select() + self.app.ActiveSheet.ListObjects.Add().TableStyle = table_style + + @activity + def read_worksheet(self, name=None, headers=False): + """Read worksheet + + Read data from a worksheet as a list of lists + + :parameter name: Optional name of worksheet to read. If no name is specified will take active sheet + :parameter headers: Boolean to treat first row as headers. Default value is False + + :return: List of dictionaries with sheet data + + :Example: + + >>> # Open excel + >>> excel = Excel() + >>> Write some cells + >>> excel.write_cell(1, 1, 'A') + >>> excel.write_cell(1, 2, 'B') + >>> excel.write_cell(1, 3, 'C') + >>> excel.read_worksheet() + [['A'],['B'],['C']] + + Keywords + excel, read worksheet, export data, read data + + Icon + las la-file-excel + """ + if name: + self.activate_worksheet(name) + + data = self.workbook.ActiveSheet.UsedRange.Value + + if isinstance(data, str): + return data + + # Remove empty columns and rows + data = [list(x) for x in data if any(x)] + transposed = list(map(list, zip(*data))) + transposed = [row for row in transposed if any(row)] + data = list(map(list, zip(*transposed))) + + if headers: + header_row = data[0] + data = data[1:] + data = [{column: row[i] + for i, column in enumerate(header_row)} for row in data] + + return data + + @activity + def quit(self): + """Quit Excel + + This closes Excel, make sure to use :func: 'save' or 'save_as' if you would like to save before quitting. + + :Example: + + >>> # Open Excel + >>> excel = Excel() + >>> # Quit Excel + >>> excel.quit() + + Keywords + excel, exit, quit, close + + Icon + las la-file-excel + """ + self.app.Application.Quit() + +""" +Excel File +Icon: las la-file-excel +""" + +class ExcelFile: + @activity + def __init__(self, file_path=None): + """Read and Write xlsx files. + + This activity can read, write and edit Excel (xlsx) files without the need of having Excel installed. + Note that, in contrary to working with the :func: 'Excel' activities, a file get saved directly after manipulation. + + :parameter file_path: Enter a path to open Excel with an existing Excel file. If no path is specified a 'workbook.xlsx' will be initialized in the home directory, this is the default value. If a workbook with the same name already exists the file will be overwritten. + + :Example: + + >>> # Open a new Excel file + >>> excel_file = ExcelFile() + + Keywords + excel, open, start, xlsx + + Icon + las la-file-excel + + """ + + self.file_path = file_path + self.sheet_name = None + + self.app = self._launch() + + def _launch(self): + + import openpyxl + import os + + if self.file_path: + if not os.path.exists(self.file_path): + # self.book(self.file_path) + self.book = openpyxl.load_workbook(self.file_path) + else: + path = os.path.join(os.path.expanduser("~"), 'workbook.xlsx') + self.book = openpyxl.load_workbook(path) + self.file_path = path + + @activity + def activate_worksheet(self, name): + """Activate worksheet + + Activate a worksheet. By default the first worksheet is activated. + + :parameter name: Name of the worksheet to activate. + + :Example: + + >>> # Open a new Excel file + >>> excel_file = ExcelFile() + >>> # Add some worksheets + >>> excel_file.add_worksheet('My Example Worksheet') + >>> excel_file.add_worksheet('Another Worksheet') + >>> # Activate a worksheet + >>> excel_file.active_worksheet('My Example Worksheet') + + Keywords + excel, activate tab, activate worksheet + + Icon + las la-file-excel + """ + + self.sheet_name = name + + @activity + def save_as(self, path): + """Save as + + :parameter path: Path where workbook will be saved + + :Example: + + >>> # Open a new Excel file + >>> excel_file = ExcelFile() + >>> # Ad a worksheet + >>> excel_file.add_worksheet('My Example Worksheet') + >>> # Save the Excel file + >>> excel_file.save_as('output.xlsx') + >>> # We can also save it in the home directory by using + >>> excel_file.save_as( home_path('output.xlsx') ) + + Keywords + excel, save as, export, save + + Icon + las la-file-excel + """ + self.book.save(path) + + @activity + def write_cell(self, column, row, value, auto_save=True): + """Write cell + + :parameter column: Column number (integer) to write + :parameter row: Row number (integer) to write + :parameter value: Value to write to specific cell + :parameter auto_save: Save document after performing activity. Default value is True + + :Example: + + >>> # Open a new Excel file + >>> excel_file = ExcelFile() + >>> # Add a worksheet + >>> excel_file.add_worksheet('My Example Worksheet') + >>> excel_file.write_cell(1, 1, 'Filled!') + + Keywords + excel, write cell, insert data + + Icon + las la-file-excel + """ + if self.sheet_name: + sheet = book[self.sheet_name] + else: + sheet = book.active + + sheet.cell(row=row, column=column).value = value + + if auto_save: + self.book.save(self.file_path) + + @activity + def read_cell(self, column, row): + """Read cell + + :parameter column: Column number (integer) to read + :parameter row: Row number (integer) to read + + :return: Cell value + + :Example: + + >>> # Open a new Excel file + >>> excel_file = ExcelFile() + >>> # Add a worksheet + >>> excel_file.add_worksheet('My Example Worksheet') + >>> # Write the first cell + >>> excel_file.write_cell(1, 1, 'Filled!') + >>> # Read the first cell + >>> excel_file.read_cell(1, 1) + 'Filled!' + + Keywords + excel, read cell, read + + Icon + las la-file-excel + + """ + if self.sheet_name: + sheet = self.book[self.sheet_name] + else: + sheet = self.book.active + + return sheet.cell(row=row, column=column).value + + @activity + def add_worksheet(self, name, auto_save=True): + """Add worksheet + + :parameter name: Name of the worksheet to add + :parameter auto_save: Save document after performing activity. Default value is True + + :Example: + + >>> # Open a new Excel file + >>> excel_file = ExcelFile() + >>> # Add a worksheet + >>> excel_file.add_worksheet('My Example Worksheet') + >>> # List all the worksheets + >>> excel.get_worksheet_names() + + + Keywords + excel, add worksheet, worksheet + + Icon + las la-file-excel + """ + + self.book.create_sheet(name) + if auto_save: + self.book.save(self.file_path) + + @activity + def get_worksheet_names(self): + """Get worksheet names + + :return: List of worksheet names + + :Example: + + >>> # Open a new Excel file + >>> excel_file = ExcelFile() + >>> # Add some worksheets + >>> excel_file.add_worksheet('My Example Worksheet') + >>> excel_file.add_worksheet('Another Worksheet') + >>> # Get the worksheet names + >>> excel_file.get_worksheet_names() + ['My Example Worksheet', 'Another Worksheet'] + + Keywords + excel, worksheet names, worksheet, + + Icon + las la-file-excel + + """ + + return self.book.sheetnames + + +""" +PowerPoint Application +icon: las la-file-powerpoint +""" + + +class PowerPoint: + @activity + def __init__(self, visible=True, path=None, add_slide=True): + """Start PowerPoint Application + + For this activity to work, PowerPoint needs to be installed on the system. + + :parameter visible: Show PowerPoint in the foreground if True or hide if False, defaults to True. + :parameter path: Enter a path to open an existing PowerPoint presentation. If no path is specified a new presentation will be initialized, this is the default value. + :parameter add_slide: Add an initial empty slide when creating new PowerPointfile, this prevents errors since most manipulations require a non-empty presentation. Default value is True + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + + Keywords + powerpoint, ppt + + Icon + las la-file-powerpoint + + """ + self.app = self._launch(path) + self.app.Visible = visible + + def _launch(self, path): + """Utility function to create the Excel application scope object + + :return: Application object (win32com.client) + """ + try: + import win32com.client + + app = win32com.client.gencache.EnsureDispatch( + "PowerPoint.Application") + + except: + raise Exception( + "Could not launch PowerPoint, do you have Microsoft Office installed on Windows?") + + if path: + return app.Presentations.Open(file_path) + else: + return app.Presentations.Add() + + @activity + def save_as(self, path=None): + """Save PowerPoint + + Save PowerPoint Slidedeck + + :parameter path: Save the PowerPoint presentation. Default value is the home directory and filename 'presentation.pptx' + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + >>> # Add a first slide + >>> powerpoint.add_slide() + >>> # Save the PowerPoint presentation + >>> powerpoint.save() + + Keywords + powerpoint, ppt, save, save as, save powerpoint + + Icon + las la-file-powerpoint + + """ + if not path: + import os + os.path.join(os.path.expanduser("~"), 'presentation.pptx') + + return self.app.SaveAs(path) + + @activity + def quit(self): + """Close PowerPoint Application + + Close PowerPoint + + :parameter index: Index where the slide should be inserted. Default value is as final slide. + :parmeter type: Type of the slide to be added. Supports following types: blank, chart, text, title and picture. + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + >>> # Close PowerPoint + >>> powerpoint.quit() + + + Keywords + powerpoint, ppt, quit, exit + + Icon + las la-file-powerpoint + + """ + self.app.Application.Quit() + + @activity + def add_slide(self, index=None, type='blank'): + """Add PowerPoint Slides + + Adds slides to a presentation + + :parameter index: Index where the slide should be inserted. Default value is as final slide. + :parmeter type: Type of the slide to be added. Supports following types: blank, chart, text, title and picture. + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + >>> # Add a first slide + >>> powerpoint.add_slide() + + + Keywords + powerpoint, ppt, add, add slide powerpoint, slides + + Icon + las la-file-powerpoint + + """ + if type == 'blank': + type_id = 12 + if type == 'chart': + type_id = 8 + if type == 'text': + type_id = 2 + if type == 'title': + type_id = 1 + if type == 'picture': + type_id = 36 + + if not index: + index = self.app.Slides.Count + 1 + + return self.app.Slides.Add(index, type_id) + + @activity + def number_of_slides(self): + """Slide count + + :return: The number of slides + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + >>> # Add some slides + >>> powerpoint.add_slide() + >>> powerpoint.add_slide() + >>> # Show number of slides + >>> powerpoint.number_of_slides() + + Keywords + powerpoint, ppt, slide count, number of slides + + Icon + las la-file-powerpoint + """ + return self.app.Slides.Count + + @activity + def add_text(self, text, index=None, font_size=48, font_name=None, bold=False, margin_bottom=100, margin_left=100, margin_right=100, margin_top=100): + """Text to slide + + Add text to a slide + + :parameter index: Slide index to add text. If none is specified, a new slide will be added as final slide + :parmeter text: Text to be added + :parameter font_size: Fontsize, default value is 48 + :parameter font_name: Fontname, if not specified will take default PowerPoint font + :parameter bold: Toggle bold with True or False, default value is False + :parameter margin_bottom: Margin from the bottom in pixels, default value is 100 pixels + :parameter margin_left: Margin from the left in pixels, default value is 100 pixels + :parameter margin_right: Margin from the right in pixels, default value is 100 pixels + :parameter margin_top: Margin from the top in pixels, default value is 100 pixels + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + >>> # Add slide with text + >>> powerpoint.add_text(text='Sample Text') + + + Keywords + powerpoint, ppt, text, add text, slides + Icon + las la-file-powerpoint + + """ + + if not index: + index = self.app.Slides.Count + 1 + self.app.Slides.Add(index, 12) + text_box = self.app.Slides(index).Shapes.AddTextbox( + 1, 100, 100, 200, 50).TextFrame.TextRange + text_box.Text = text + text_box.Font.Size = font_size + if font_name: + text_box.Font.Name = font_name + text_box.Font.Bold = bold + + @activity + def delete_slide(self, index=None): + """Delete slide + + :parameter index: Slide index to be deleted. If none is specified, last slide will be deleted + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + >>> # Add some slides + >>> powerpoint.add_slide() + >>> powerpoint.add_slide() + >>> # Delete last slide + >>> powerpoint.delete_slide() + + Keywords + powerpoint, ppt, delete, delete slide + + Icon + las la-file-powerpoint + + """ + if not index: + index = self.app.Slides.Count + + return self.app.Slides(index).Delete() + + @activity + def replace_text(self, placeholder_text, replacement_text): + """Replace all occurences of text in PowerPoint slides + + Can be used for example to replace arbitrary placeholder value in a PowerPoint. + For example when using a template slidedeck, using 'XXXX' as a placeholder. + Take note that all strings are case sensitive. + + :parameter placeholder_text: Placeholder value (string) in the PowerPoint, this will be replaced, e.g. 'Company Name' + :parameter replacement_text: Text (string) to replace the placeholder values with. It is recommended to make this unique in your PowerPoint to avoid wrongful replacement, e.g. 'XXXX_placeholder_XXX' + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + >>> # Add some slides with text + >>> powerpoint.add_text(text='Hello, my name is placeholder') + >>> # Change 'placeholder' to the word 'robot + >>> powerpoint.replace_text(placeholder_text = 'placeholder', replacement_text ='robot') + + Keywords + powerpoint, ppt, replace, placeholder + + Icon + las la-file-powerpoint + + """ + for slide in self.app.Slides: + for shape in slide.Shapes: + shape.TextFrame.TextRange.Text = shape.TextFrame.TextRange.Text.replace(placeholder_text, replacement_text) + + @activity + def export_to_pdf(self, path=None): + """PowerPoint to PDF + + Export PowerPoint presentation to PDF file + + :parameter path: Output path where PDF file will be exported to. Default path is home directory with filename 'pdf_export.pdf'. + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + >>> # Add some slides with text + >>> powerpoint.add_text(text='Robots are cool') + >>> # Export to pdf + >>> powerpoint.export_to_pdf() + + Keywords + powerpoint, ppt, export, pdf + + Icon + las la-file-powerpoint + + """ + + if self.app.Slides.Count == 0: + raise Exception( + 'Please add a slide first bedore exporting the presentation.') + + if not path: + import os + path = os.path.join(os.path.expanduser("~"), 'pdf_export.pdf') + + return self.app.ExportAsFixedFormat2(path, 2, PrintRange=None) + + @activity + def export_slides_to_images(self, path=None, type='png'): + """Slides to images + + Export PowerPoint slides to seperate image files + + :parameter path: Output path where image files will be exported to. Default path is home directory. + :parameter type: Output type of the images, supports 'png' and 'jpg' with 'png' as default value + + :Example: + + >>> # Start PowerPoint + >>> powerpoint = PowerPoint() + >>> # Add some slides with text + >>> powerpoint.add_text(text='Robots are cool') + >>> powerpoint.add_text(text='Humans are cooler') + >>> # Export slides to images + >>> powerpoint.export_slides_to_images() + + Keywords + powerpoint, ppt, export, png, image, slides to image + + Icon + las la-file-powerpoint + + """ + + if self.app.Slides.Count == 0: + raise Exception( + 'Please add a slide first bedore exporting the presentation.') + + if not path: + import os + path = os.path.expanduser("~") + + return self.app.Export(path, 'png') + + +""" +Office 365 +Icon: las la-cloud +""" + + +@activity +def send_email_with_outlook365(client_id, client_secret, to_email, subject='', body=''): + """Send email Office Outlook 365 + + :parameter client_id: Client id for office 365 account + :parameter client_secret: Client secret for office 365 account + :parameter to_email: E-mail to send to + :parameter subject: Optional subject + :parameter body: Optional body of the email + + :Example: + + >>> # Send email to 'robot@automagica.com' + >>> send_email_with_outlook365('SampleClientID', 'SampleClientSecret', 'robot@automagica.com') + + Keywords + mail, office 365, outlook, email, e-mail + + Icon + las la-envelope + """ + from O365 import Account + + credentials = (client_id, client_secret) + + account = Account(credentials) + m = account.new_message() + m.to.add(to_email) + m.subject = subject + m.body = body + m.send() + + +""" +Salesforce +Icon: lab la-salesforce +""" + +@activity +def salesforce_api_call(action, key, parameters={}, method='get', data={}): + """Salesforce API + + Activity to make calls to Salesforce REST API. + + :parameter action: Action (the URL) + :parameter key: Authorisation key + :parameter parameters: URL params + :parameter method: Method (get, post or patch) + :parameter data: Data for POST/PATCH. + + :return: API data + + :Example: + + >>> spf_api_call('action', 'key', 'parameters') + Response + + Keywords + salesforce + + Icon + lab la-salesforce + + """ + headers = { + 'Content-type': 'application/json', + 'Accept-Encoding': 'gzip', + 'Authorization': 'Bearer ' + key + } + if method == 'get': + r = requests.request(method, instance_url+action, + headers=headers, params=parameters, timeout=30) + elif method in ['post', 'patch']: + r = requests.request(method, instance_url+action, + headers=headers, json=data, params=parameters, timeout=10) + else: + raise ValueError('Method should be get or post or patch.') + print('Debug: API %s call: %s' % (method, r.url)) + if r.status_code < 300: + if method == 'patch': + return None + else: + return r.json() + else: + raise Exception('API error when calling %s : %s' % (r.url, r.content)) + + +""" +E-mail (SMTP) +Icon: las la-at +""" + + +@activity +def send_mail_smtp(smtp_host, smtp_user, smtp_password, to_address, subject="", message="", port=587): + """Mail with SMTP + + This function lets you send emails with an e-mail address. + + :parameter smpt_host: The host of your e-mail account. + :parameter smpt_user: The password of your e-mail account + :parameter smpt_password: The password of your e-mail account + :parameter to_address: The destination is the receiving mail address. + :parameter subject: The subject + :parameter message: The body of the mail + :parameter port: The port variable is standard 587. In most cases this argument can be ignored, but in some cases it needs to be changed to 465. + + :Example: + + >>> send_mail_smpt('robot@automagica.com', 'SampleUser', 'SamplePassword', 'robotfriend@automagica.com') + + Keywords + mail, e-mail, email smpt + + Icon + las la-mail-bulk + + """ + BODY = "\r\n".join( + [ + "To: %s" % destination, + "From: %s" % user, + "Subject: %s" % subject, + "", + message, + ] + ) + smtpObj = smtplib.SMTP(host, port) + smtpObj.ehlo() + smtpObj.starttls() + smtpObj.login(user, password) + smtpObj.sendmail(user, destination, BODY) + smtpObj.quit() + + +""" +Windows OS +icon: lab la-windows +""" + + +@activity +def set_user_password(username, password): + """Set Windows password + + Sets the password for a Windows user. + + :parameter username: Username + :parameter password: New password + + :Example: + + >>> set_user_password('SampleUsername', 'SamplePassword') + + Keywords + windows, user, password, account + + Icon + las la-passport + + """ + from win32com import adsi + + user = adsi.ADsGetObject("WinNT://localhost/%s,user" % username) + user.SetPassword(password) + + +@activity +def validate_user_password(username, password): + """Check Windows password + + Validates a Windows user password if it is correct + + :parameter username: Username + :parameter password: New password + + :return: True if the password is correct + + :Example: + + >>> validate_user_password('SampleUsername', 'SamplePassword') + False + + Keywords + windows, user, password, account + + Icon + las la-passport + + """ + from win32security import LogonUser + from win32con import LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT + + try: + LogonUser( + username, + None, + password, + LOGON32_LOGON_INTERACTIVE, + LOGON32_PROVIDER_DEFAULT, + ) + except: + return False + return True + + +@activity +def lock_windows(): + """Lock Windows + + Locks Windows requiring login to continue. + + :Example: + + >>> lock_windows() + + Keywords + windows, user, password, account, lock, freeze, hibernate, sleep, lockescreen + + Icon + las la-user-lock + + """ + import ctypes + ctypes.windll.user32.LockWorkStation() + + +@activity +def is_logged_in(): + """Check if Windows logged in + + Checks if the current user is logged in and not on the lockscreen. Most automations do not work properly when the desktop is locked. + + :return: True if the user is logged in, False if not + + :Example: + + >>> is_logged_in() + True + + Keywords + windows, login, logged in, lockscreen, user, password, account, lock, freeze, hibernate, sleep + + Icon + lar la-user + """ + import subprocess + + output = subprocess.check_output("TASKLIST") + + if "LogonUI.exe" in str(output): + return False + else: + return True + + +@activity +def is_desktop_locked(): + """Check if Windows is locked + + Checks if the current user is locked out and on the lockscreen. Most automations do not work properly when the desktop is locked. + + :return: True when the lockscreen is active, False if not. + + :Example: + + >>> desktop_locked() + True + + Keywords + windows, login, logged in, lockscreen, user, password, account, lock, locked, freeze, hibernate, sleep + + Icon + las la-user + + """ + return not is_logged_in() + + +@activity +def get_username(): + """Get Windows username + + Get current logged in user's username + + :Example: + + >>> get_username() + 'Automagica' + + Keywords + windows, login, logged in, lockscreen, user, password, account, lock, locked, freeze, hibernate, sleep + + Icon + las la-user + + """ + import getpass + return getpass.getuser() + + +@activity +def set_to_clipboard(text): + """Set clipboard + + Set any text to the Windows clipboard. + + :parameter text: Text to put in the clipboard + + :Example: + + >>> # Create some sample text + >>> sample_text = 'A robots favourite food must be computer chips' + >>> # Set to clipboard + >>> set_to_clipboard(sample_text) + >>> # Print the clipboard to verify + >>> print( get_from_clipboard() ) + + Keywords + copy, clipboard, clip board, ctrl c, ctrl v, paste + + Icon + las la-clipboard-check + """ + import win32clipboard + + win32clipboard.OpenClipboard() + win32clipboard.EmptyClipboard() + win32clipboard.SetClipboardText(text, win32clipboard.CF_UNICODETEXT) + win32clipboard.CloseClipboard() + + +@activity +def get_from_clipboard(): + """Get clipboard + + Get the text currently in the Windows clipboard + + :return: Text currently in the clipboard + + :Example: + + >>> # Create some sample text + >>> sample_text = 'A robots favourite food must be computer chips' + >>> # Set to clipboard + >>> set_to_clipboard(sample_text) + >>> # Get the clipboard to verify + >>> get_from_clipboard() + 'A robots favourite food must be computer chips' + + Keywords + copy, clipboard, clip board, ctrl c, ctrl v, paste + + Icon + las la-clipboard-list + + """ + import win32clipboard + + win32clipboard.OpenClipboard() + try: + data = str(win32clipboard.GetClipboardData( + win32clipboard.CF_UNICODETEXT)) + return data + + except: + return None + + finally: + win32clipboard.CloseClipboard() + + +@activity +def clear_clipboard(): + """Empty clipboard + + Empty text from clipboard. Getting clipboard data after this should return in None + + :Example: + + >>> # Create some sample text + >>> sample_text = 'A robots favourite food must be computer chips' + >>> # Set to clipboard + >>> set_to_clipboard(sample_text) + >>> # Clear the clipboard + >>> clear_clipboard() + >>> # Get clipboard contents to verify + >>> print( get_clipboard() ) + None + + Keywords + copy, clipboard, clip board, ctrl c, ctrl v, paste + + Icon + las la-clipboard + """ + from ctypes import windll + + if windll.user32.OpenClipboard(None): + windll.user32.EmptyClipboard() + windll.user32.CloseClipboard() + return + + +@activity +def run_vbs_script(script_path, parameters=[]): + """Run VBSscript + + Run a VBScript file + + :parameter script_path: Path to the .vbs-file + :parameter parameters: Additional arguments to pass to the VBScript + + :Example: + + >>> # Run a VBS script + >>> run_vbs_script('Samplescript.vbs') + + Keywords + vbs, VBScript + + Icon + las la-cogs + """ + import subprocess + + subprocess.call(["cscript.exe", script_path] + parameters) + + +@activity +def beep(frequency=1000, duration=500): + """Beep + + Make a beeping sound. Make sure your volume is up and you have hardware connected. + + :parameter frequency: Integer to specify frequency (Hz), default value is 1000 Hz + :parameter duration: Integer to specify duration of beep in miliseconds (ms), default value is 500 ms. + + :return: Sound + + :Example: + + >>> beep() + + Keywords + beep, sound, noise, speaker, alert + + Icon + las la-volume-up + + """ + import winsound + + winsound.Beep(frequency, duration) + + +""" +Text-to-Speech +Icon: las la-volume-up +""" + + +@activity +def speak(text, speed=None): + """Speak + + Use the Text-To-Speech engine available on your system to read text + + :parameter text: The text which should be said + :parameter speed: Multiplication factor for the speed at which the text should be pronounced. + + :return: Spoken text + + :Example: + + >>> # Read the following text out loud + >>> speak('How do robots eat guacamole?') + >>> speak('With microchips!') + + Keywords + sound, speech, text, speech to text, speech-to-text, translate, read, read out loud + + Icon + las la-microphone-alt + + + """ + import pyttsx3 + + engine = pyttsx3.init() + + if speed: + default_rate = engine.getProperty("rate") + engine.setProperty("rate", speed * default_rate) + + engine.say(text) + engine.runAndWait() + + +""" +Active Directory +Icon: las la-user +""" + + +class ActiveDirectory(): + @activity + def __init__(self, ldap_server=None, username=None, password=None): + """AD interface + + Interface to Windows Active Directory through ADSI + + Activity to connect the ADSI interface to Microsoft Active Directory. + Connects to the AD domain to which the machine is joined by default. + + :Example: + + >>> ad = ActiveDirectory() + + Keywords + AD, active directory, activedirectory + + Icon + las la-audio-description + + """ + import pyad + + self.pyad = pyad + + if ldap_server: + self.pyad.set_defaults(ldap_server=ldap_server) + + if username: + self.pyad.set_defaults(username=username) + + if password: + self.pyad.set_defaults(password=password) + + @activity + def get_object_by_distinguished_name(self, distinguished_name): + """Get AD object by name + + Interface to Windows Active Directory through ADSI + + Activity to connect the ADSI interface to Microsoft Active Directory. + Connects to the AD domain to which the machine is joined by default. + + :Example: + + >>> ad = ActiveDirectory() + >>> ad.get_object_by_distinguished_name('SampleDN') + + Keywords + AD, active directory, activedirectory + + Icon + las la-audio-description + + """ + return self.pyad.from_dn(distinguished_name) + + +""" +Utilities +icon: las la-toolbox +""" + + +@activity +def home_path(subdir=None): + """Get user home path + + Returns the current user's home path + + :parameter filename: Optional filename to add to the path. Can also be a subdirectory + + :return: Path to the current user's home folder + + :Example: + + >>> # Home_path without arguments will return the home path + >>> print( home_path() ) + >>> # When looking for a file in the home path, we can specify it + >>> # First make a sample textfile + >>> make_textfile() + >>> # Refer to it + >>> home_path('generated_textfile.txt') + 'C:\\Users\\\\generated_textfile.txt' + + Keywords + home, home path, homepath, home directory, homedir + + Icon + las la-home + + """ + import os + + if subdir: + return os.path.join(os.path.expanduser("~"), subdir) + return os.path.expanduser("~") + + +@activity +def desktop_path(subdir=None): + """Get desktop path + + Returns the current user's desktop path + + :parameter filename: Optional filename to add to the path. Can also be a subdirectory + + :return: Path to the current user's desktop folder + + :Example: + + >>> # Desktop_path without arguments will return the home path + >>> print( desktop_path() ) + >>> # When looking for a file on the desktop, we can specify it + >>> # First make a sample textfile + >>> make_textfile() + >>> # Refer to it + >>> desktop_path('generated_textfile.txt') + 'C:\\Users\\\\Desktop\\generated_textfile.txt' + + Keywords + desktop, desktop path, desktoppath, desktop directory, desktopdir + + Icon + lar la-desktop + """ + import os + + if subdir: + return os.path.join(os.path.join(os.path.expanduser("~"), "Desktop"), subdir) + return os.path.join(os.path.expanduser("~"), "Desktop") + + +@activity +def open_file(path): + """Open file + + Opens file with default programs + + :parameter path: Path to file. + + :return: Path to file + + :Example: + + >>> # Make textfile + >>> testfile = make_textfile() + >>> # Open the file + >>> open_file(testfile) + + Keywords + file, open, open file, show, reveal, explorer, run, start + + Icon + lar la-file + + """ + + import os + os.startfile(path) + + return path + + +@activity +def set_wallpaper(image_path): + """Set wallpaper + + Set Windows desktop wallpaper with the the specified image + + :parameter image_path: Path to the image. This image will be set as desktop wallpaper + + :Example: + + >>> # Caution: this example will change your wallpaper + >>> # Take a screenshot of current screen + >>> screenshot = take_screenshot() + >>> # Flip it hozirontally for fun + >>> mirror_image_horizontally(screenshot) + >>> # Set flipped image as wallpaper + >>> set_wallpaper(screenshot) + + Keywords + desktop, desktop path, desktoppath, desktop directory, desktopdir + + Icon + las la-desktop + + """ + import ctypes + ctypes.windll.user32.SystemParametersInfoW(20, 0, image_path, 0) + + +@activity +def download_file_from_url(url, filename=None, path=None): + """Download file from a URL + + :parameter url: Source URL to download file from + :parameter filename: + :parameter path: Target path. If no path is given will download to the home directory + + :return: Target path as string + + :Example: + + >>> # Download robot picture from the wikipedia robot page + >>> picture_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Atlas_from_boston_dynamics.jpg/220px-Atlas_from_boston_dynamics.jpg' + >>> download_file_from_url(url = picture_url, filename = 'robot.jpg') + 'C:\\Users\\\\robot.jpg' + + Keywords + download, download url, save, request + + Icon + las la-cloud-download-alt + """ + import requests + import re + import os + + if not filename: + base_path, filename = os.path.split(url) + if not path: + path = os.path.join(os.path.expanduser("~"), filename) + + r = requests.get(url, stream=True) + + if r.status_code == 200: + with open(path, 'wb') as f: + f.write(r.content) + + return path + + else: + raise Exception('Could not download file from {}'.format(url)) + + +""" +Trello +Icon: lab la-trello +""" + + +@activity +def add_trello_card(title="My card", description="My description", board_name="My board", list_name="My list", api_key="", api_secret="", token="", token_secret="any"): + """Add Trello Card + + Add a card to the Trello board. For this you need a Trello API key, secret and token. + + + :parameter title: Title of Trello card + :parameter description: Description of Trello card + :parameter board_name: Name of the Trello board + :parameter api_key: Trello API key + :parameter api_secret: Trello API secret + :parameter token: Trello token + :parameter token_secret: Token secret can be any string, but should be altered for security purposes. + + :Example: + + >>> add_trello_card(title='ExampleTitle', description='ExampleDescription', api_key='SampleKey', api_secret='ApiSecret', token='SampleToken') + + Keywords + trello + + Icon + lab la-trello + + """ + from trello import TrelloClient + + client = TrelloClient( + api_key=api_key, + api_secret=api_secret, + token=token, + token_secret=token_secret, + ) + + trello_boards = client.list_boards() + for trello_board in trello_boards: if trello_board.name == board_name: target_board = trello_board break - trello_lists = target_board.all_lists() - for trello_list in trello_lists: - if trello_list.name == list_name: - target_list = trello_list - break + trello_lists = target_board.all_lists() + for trello_list in trello_lists: + if trello_list.name == list_name: + target_list = trello_list + break + + target_list.add_card(title, desc=description) + + +""" +System +Icon: las la-laptop +""" + + +@activity +def rename_file(input_path, new_name=None): + """Rename a file + + This activity will rename a file. If the the desired name already exists in the folder file will not be renamed. + + :parameter path: Full path to file that will be renamed + :parameter new_name: New name of the file e.g. 'newfile.txt'. By default file will be renamed to original folder name with '_renamed' added to the folder name. + + :return: Path to renamed file as a string. None if folder could not be renamed. + + :Example: + + >>> # Make new textfile in home directory + >>> textfile = make_textfile() + >>> # Rename the file + >>> rename_file(textfile) + C:\\Users\\\\generated_textfile_renamed.txt' + + Keywords + file, rename, rename file, organise file, files, file manipulation, explorer, nautilus + + Icon + las la-file-contract + """ + import os + + if not os.path.isfile(input_path): + return None + + if not new_name: + base, file_extension = os.path.splitext(input_path) + new_path = base + '_renamed' + file_extension + else: + base_path, filename = os.path.split(input_path) + new_path = os.path.join(base_path, new_name) + + if os.path.isfile(new_path): + return None + + os.rename(input_path, new_path) + return new_path + + +@activity +def move_file(from_path, to_path): + """Move a file + + If the new location already contains a file with the same name, a random 4 character uid will be added in front of the name before the file is moved. + + :parameter old_path: Full path to the file that will be moved + :parameter new_location: Path to the folder where file will be moved to + + :return: Path to renamed file as a string. None if folder could not be moved. + + :Example: + + >>> # Make new textfile in home directory + >>> textfile = make_textfile() + >>> # Make a folder to move the file to + >>> new_folder = create_folder() + >>> # Move textfile to the folder + >>> move_file(textfile, new_folder) + + Keywords + file, move, move file, organise file, files, file manipulation, explorer, nautilus + + Icon + las la-file-export + + """ + import uuid + import os + import shutil + + if not os.path.isfile(from_path): + return None + + if os.path.isfile(to_path): + base, file_extension = os.path.splitext(to_path) + to_path = base + str(uuid4())[:4] + file_extension + + shutil.move(from_path, to_path) + return to_path + + +@activity +def remove_file(path): + """Remove a file + + :parameter path: Full path to the file that will be deleted. + + :return: Path to removed file as a string. + + :Example: + + >>> # Make new textfile in home directory + >>> textfile = make_textfile() + >>> # Remove the file + >>> remove_file(textfile) + + Keywords + file, delete, erase, delete file, organise file, files, file manipulation, explorer, nautilus + + Icon + las la-trash + """ + + import os + if os.path.isfile(path): + os.remove(path) + return path + + +@activity +def file_exists(path): + """Check if file exists + + This function checks whether the file with the given path exists. + + :parameter path: Full path to the file to check. + + return: True or False (boolean) + + :Example: + + >>> # Make new textfile in home directory + >>> textfile = make_textfile() + >>> # Check if file exists + >>> file_exists(textfile) + True + + Keywords + file, exists, files, file manipulation, explorer, nautilus + + Icon + las la-tasks + """ + import os + return os.path.isfile(path) + + +@activity +def wait_file_exists(path, timeout=60): + """Wait until a file exists. + + Not that this activity is blocking and will keep the system waiting. + + :parameter path: Full path to file. + :parameter timeout: Maximum time in seconds to wait before continuing. Default value is 60 seconds. + + :Example: + + >>> # Make new textfile in home directory + >>> textfile = make_textfile() + >>> # Wait untile file exists # Should pass immediatly + >>> wait_file_exists(textfile) + + Keywords + file, wait, wait till exists, files, file manipulation, explorer, nautilus + + Icon + las la-list-alt + + """ + from time import sleep + + while not os.path.exists(path): + sleep(1) + return + + for _ in range(timeout): + if os.path.exists(path): + break + sleep(1) + + +@activity +def write_list_to_file(list_to_write, file_path): + """List to .txt + + Writes a list to a text (.txt) file. + Every element of the entered list is written on a new line of the text file. + + :parameter list_to_write: List to write to .txt file + :parameter path: Path to the text-file. + + :Example: + + >>> # Make a list to write + >>> robot_names = ['WALL-E', 'Terminator', 'R2D2'] + >>> # Create a new text file + >>> textfile = make_textfile() + >>> write_list_to_file(robot_names, textfile) + >>> # Open the file for illustration + >>> open_file(textfile) + + Keywords + list, text, txt, list to file, write list, write + + Icon + las la-list + + """ + with open(file_path, "w") as filehandle: + filehandle.writelines("%s\n" % place for place in list_to_write) + return + + +@activity +def read_list_from_txt(file_path): + """Read .txt file + + This activity writes the content of a .txt file to a list and returns that list. + Every new line from the .txt file becomes a new element of the list. The activity will + not work if the entered path is not attached to a .txt file. + + :parameter path: Path to the .txt file + + :return: List with contents of specified .txt file + + :Example: + + >>> # Make a list to write + >>> robot_names = ['WALL-E', 'Terminator', 'R2D2'] + >>> # Create a new text file + >>> textfile = make_textfile() + >>> write_list_to_file(robot_names, textfile) + >>> # Read list from file + >>> read_list_from_txt(textfile) + ['WALL-E', 'Terminator', 'R2D2'] + + Keywords + list, text, txt, list to file, write list, read, read txt, read text + + Icon + las la-th-list + + """ + written_list = [] + with open(file_path, "r") as filehandle: + filecontents = filehandle.readlines() + for line in filecontents: + current_place = line[:-1] + written_list.append(current_place) + return written_list + + +@activity +def append_line(text, file_path): + """Append to .txt + + Append a text line to a file and creates the file if it does not exist yet. + + :parameter text: The text line to write to the end of the file + :parameter file_path: Path to the file to write to + + :Example: + + >>> # Create a new text file + >>> textfile = make_textfile() + >>> # Append a few lines to the file + >>> append_line('Line 1', textfile) + >>> append_line('Line 2', textfile) + >>> append_line('Line 3', textfile) + >>> # Open the file for illustration + >>> open_file(textfile) + + Keywords + list, text, txt, list to file, write list, read, write txt, append text, append line, append, add to file, add + + Icon + las la-tasks + """ + + import os + + if not os.path.isfile(file_path): + with open(file_path, "a"): + os.utime(file_path, None) + + with open(file_path, "a") as f: + f.write("\n" + text) + + +@activity +def make_textfile(text='Sample text', output_path=None): + """Make text file + + Initialize text file + + :parameter text: The text line to write to the end of the file. Default text is 'Sample text' + :parameter output_path: Ouput path. Will write to home directory + + :return: Path as string + + :Example: + + >>> # Create a new text file + >>> textfile = make_textfile() + C:\\Users\\\\generated_textfile.txt' + + Keywords + make textfile, textfile, testfile, exampel file, make file, make, new file, new textfile, txt, new txt + + Icon + las la-file-alt + + """ + + # Set to user home if no path specified + import os + if not output_path: + output_path = os.path.join( + os.path.expanduser("~"), "generated_textfile.txt") + with open(output_path, "w", encoding="utf-8") as file: + file.write(text) + + return output_path + + +@activity +def copy_file(old_path, new_path=None): + """Copy a file + + Copies a file from one place to another. + If the new location already contains a file with the same name, a random 4 character uid is added to the name. + + :parameter old_path: Full path to the source location of the folder + :parameter new_path: Optional full path to the destination location of the folder. If not specified file will be copied to the same location with a random 8 character uid is added to the name. + + :return: New path as string + + :Example: + + >>> # Create a new text file + >>> textfile = make_textfile() + >>> # Copy the textfile + >>> copy_file(textfile) + C:\\Users\\\\generated_textfile.txt' + + Keywords + make textfile, textfile, testfile, exampel file, make file, make, new file, new textfile, txt, new txt + + Icon + las la-copy + + """ + from uuid import uuid4 + import os + import shutil + + if not new_path: + new_path = old_path + + if os.path.isfile(old_path): + if not os.path.isfile(new_path): + shutil.copy(old_path, new_path) + elif os.path.isfile(new_path): + filename, file_extension = os.path.splitext(old_path) + new_path = filename + "_copy_" + str(uuid4())[:4] + file_extension + shutil.copy(old_path, new_path) + return new_path + + +@activity +def get_file_extension(path): + """Get file extension + + Get extension of a file + + :parameter path: Path to file to get extension from + + :return: String with extension, e.g. '.txt' + + :Example: + + >>> # Create a new text file + >>> textfile = make_textfile() + >>> # Get file extension of this textfile + >>> get_file_extension(textfile) + '.txt' + + Keywords + file, extension, file extension, details + + Icon + las la-info + + """ + + import os + filename, file_extension = os.path.splitext(path) + + return file_extension + + +@activity +def send_to_printer(file): + """Print + + Send file to default printer to priner. This activity sends a file to the printer. Make sure to have a default printer set up. + + :parameter file: Path to the file to print, should be a printable file + + :Example: + + >>> # Caution as this example could result in a print from default printer + >>> # Create a new text file + >>> textfile = make_textfile(text = 'What does a robot do at lunch? Take a megabyte!') + >>> # Print the textfile + >>> send_to_printer(textfile) + + Keywords + print, printer, printing, ink, export + + Icon + las la-print + """ + import os + os.startfile(file, 'print') + + +""" +PDF +Icon: las la-file-pdf +""" + +@activity +def read_text_from_pdf(file_path): + """Text from PDF + + Extracts the text from a PDF. This activity reads text from a pdf file. Can only read PDF files that contain a text layer. + + :parameter file_path: Path to the PDF (either relative or absolute) + :return: The text from the PDF + + :Example: + + >>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP + >>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf') + >>> # Open example pdf for illustration + >>> open_file(example_pdf) + >>> # Read the text + >>> read_text_from_pdf(example_pdf) + + Keywords + PDF, read, text, extract text, PDF file + + Icon + las la-glasses + """ + from PyPDF2 import PdfFileReader + + text = "" + + with open(file_path, 'rb') as f: + reader = PdfFileReader(f) + for i in range(reader.numPages): + page = reader.getPage(i) + text += page.extractText() + + return text + + +@activity +def join_pdf_files(file_paths, output_path=None): + """Merge PDF + + Merges multiple PDFs into a single file + + :parameter file_paths: List of paths to PDF files + :parameter output_path: Full path where joined pdf files can be written. If no path is given will write to home dir as 'merged_pdf.pdf' + + :return: Output path as string + + :Example: + + >>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP + >>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf') + >>> # Join the PDF file three times with itself for illustration, could also be different files + >>> merged_pdf = join_pdf_files([example_pdf, example_pdf, example_pdf]) + >>> # Open resulting PDF file for illustration + >>> open_file(merged_pdf) + + Keywords + PDF, read, text, extract text, PDF file, join PDF, join, merge, merge PDF + + Icon + las la-object-ungroup + + """ + from PyPDF2 import PdfFileMerger, PdfFileReader + + if not output_path: + import os + output_path = os.path.expanduser("~") + '\merged_pdf.pdf' + + merger = PdfFileMerger() + for file_path in file_paths: + with open(file_path, "rb") as f: + merger.append(PdfFileReader(f)) + + merger.write(output_path) + + return output_path + + +@activity +def extract_page_range_from_pdf(file_path, start_page, end_page, output_path=None): + """Extract page from PDF + + Extracts a particular range of a PDF to a separate file. + + :parameter file_path: Path to the PDF (either relative or absolute) + :parameter start_page: Page number to start from, with 0 being the first page + :parameter end_page: Page number to end with, with 0 being the first page + :param output_path: Output path, if no path is provided same path as input will be used with 'extracted' added to the name + + + :Example: + + >>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP + >>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf') + >>> # Join the PDF file three times to create multi page + >>> multi_page_pdf_example = join_pdf_files([example_pdf, example_pdf, example_pdf]) + >>> # Extract some pages from it + >>> new_file = extract_page_range_from_pdf(multi_page_pdf_example, 1, 2 ) + >>> # Open resulting PDF file for illustration + >>> open_file(new_file) + + Keywords + PDF, read, extract text, PDF file, extract PDF, join, cut, cut PDF, extract pages, extract from pdf, select page, page + Icon + las la-cut + + """ + from PyPDF2 import PdfFileWriter, PdfFileReader + + if not output_path: + import os + base, file_extension = os.path.splitext(file_path) + output_path = base + '_extracted' + file_extension + + + with open(file_path, "rb") as f: + + reader = PdfFileReader(f) + writer = PdfFileWriter() + + for i in range(start_page, end_page): + writer.addPage(reader.getPage(i)) + + with open(output_path, "wb") as f: + writer.write(f) + + return output_path + + +@activity +def extract_images_from_pdf(file_path): + """Extract images from PDF + + Save a specific page from a PDF as an image + + :parameter file_path: Full path to store extracted images + + :Example: + + >>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP + >>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf') + >>> # Extract the images + >>> extract_images_from_pdf(example_pdf) + + Keywords + PDF, extract images, images, extract text, PDF file, image + + Icon + las la-icons + + """ + from PyPDF2 import PdfFileReader + from PIL import Image + + extracted_images = [] + with open(file_path, "rb") as f: + reader = PdfFileReader(f) + for i in range(reader.getNumPages()): + page = reader.getPage(i) + objects = page["/Resources"]["/XObject"].getObject() + + for obj in objects: + if objects[obj]["/Subtype"] == "/Image": + size = (objects[obj]["/Width"], objects[obj]["/Height"]) + data = objects[obj].getData() + + if objects[obj]["/ColorSpace"] == "/DeviceRGB": + mode = "RGB" + else: + mode = "P" + + if objects[obj]["/Filter"] == "/FlateDecode": + img = Image.frombytes(mode, size, data) + img.save(obj[1:] + ".png") + extraced_images.append(obj[1:] + ".png") + + elif objects[obj]["/Filter"] == "/JPXDecode": + img = open(obj[1:] + ".jp2", "wb") + extraced_images.append(obj[1:] + ".jp2") + img.write(data) + img.close() + + +@activity +def apply_watermark_to_pdf(file_path, watermark_path, output_path=''): + """Watermark a PDF + + :parameter file_path: Filepath to the document that will be watermarked. Should be pdf file. + :parameter watermark_path: Filepath to the watermark. Should be pdf file. + :parameter output_path: Path to save watermarked PDF. If no path is provided same path as input will be used with 'watermarked' added to the name + + :return: Output path as a string + :Example: + + >>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP + >>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf') + >>> # Download the watermark + >>> example_watermark = download_file_from_url('http://automagica.com/examples/approved_stamp.pdf') + >>> # Apply the watermark + >>> watermarked_file = apply_watermark_to_pdf(example_pdf, example_watermark) + >>> # Open the file for illustration + >>> open_file(watermarked_file) + + Keywords + PDF, extract images, images, extract text, PDF file, image + + Icon + las la-stamp + """ + from PyPDF2 import PdfFileWriter, PdfFileReader + import os + + if not output_path: + base, file_extension = os.path.splitext(file_path) + output_path = base + '_watermarked_' + file_extension + + + watermark = PdfFileReader(open(watermark_path, "rb")) + + input_file = PdfFileReader(open(file_path, "rb")) + + page_count = input_file.getNumPages() + + output_file = PdfFileWriter() + + for page_number in range(page_count): + input_page = input_file.getPage(page_number) + input_page.mergePage(watermark.getPage(0)) + output_file.addPage(input_page) + + + with open(output_path, "wb") as outputStream: + output_file.write(outputStream) + + return output_path + + +""" +System Monitoring +Icon: las la-wave-square +""" + + +@activity +def get_cpu_load(measure_time=1): + """CPU load + + Get average CPU load for all cores. + + :parameter measure_time: Time (seconds) to measure load. Standard measure_time is 1 second. + + :return: Displayed load is an average over measured_time. + + :Example: + + >>> get_cpu_load() + 10.1 + + Keywords + cpu, load, cpuload + + Icon + las la-microchip + + """ + import psutil + + cpu_measurements = [] + for _ in range(measure_time): + cpu_measurements.append(psutil.cpu_percent(interval=1)) + return sum(cpu_measurements) / len(cpu_measurements) + + +@activity +def get_number_of_cpu(logical=True): + """Count CPU + + Get the number of CPU's in the current system. + + :parameter logical: Determines if only logical units are added to the count, default value is True. + + :return: Number of CPU Integer + + :Example: + + >>> get_number_of_cpu() + 2 + + Keywords + cpu, count, number of cpu + + Icon + las la-calculator + + """ + import psutil + + return psutil.cpu_count(logical=logical) + + +@activity +def get_cpu_frequency(): + """CPU frequency + + Get frequency at which CPU currently operates. + + :return: minimum and maximum frequency + + :Example: + + >>> get_cpu_frequency() + scpufreq(current=3600.0, min=0.0, max=3600.0) + + Keywords + cpu, load, cpu frequency + + Icon + las la-wave-square + + """ + import psutil + + return psutil.cpu_freq() + + +@activity +def get_cpu_stats(): + """CPU Stats + + Get CPU statistics + + :return: Number of CTX switches, intterupts, soft-interrupts and systemcalls. + + :Example: + + >>> get_cpu_stats() + scpustats(ctx_switches=735743826, interrupts=1540483897, soft_interrupts=0, syscalls=2060595131) + + Keywords + cpu, load, cpu frequency, stats, cpu statistics + + Icon + las la-server + """ + import psutil + + return psutil.cpu_stats() + + +@activity +def get_memory_stats(mem_type="swap"): + """Memory statistics + + Get memory statistics + + :parameter mem_type: Choose mem_type = 'virtual' for virtual memory, and mem_type = 'swap' for swap memory (standard). + + :return: Total, used, free and percentage in use. + + :Example: + + >>> get_memory_stats() + sswap(total=24640016384, used=18120818688, free=6519197696, percent=73.5, sin=0, sout=0) + + Keywords + memory, statistics, usage, ram + + Icon + las la-memory + + """ + import psutil + + if mem_type == "virtual": + return psutil.virtual_memory() + else: + return psutil.swap_memory() + + +@activity +def get_disk_stats(): + """Disk stats + + Get disk statistics of main disk + + :return: Total, used, free and percentage in use. + + :Example: + + >>> get_disk_stats() + sdiskusage(total=999559262208, used=748696350720, free=250862911488, percent=74.9) + + Keywords + disk usage, disk stats, disk, harddisk, space + + Icon + las la-save + """ + import psutil + + return psutil.disk_usage("/") + + +@activity +def get_disk_partitions(): + """Partition info + + Get disk partition info + + :return: tuple with info for every partition. + + :Example: + + >>> get_disk_paritions() + [sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed')] + + Keywords + disk usage, disk stats, disk, harddisk, space + + Icon + las la-save + + """ + import psutil + + return psutil.disk_partitions() + + +@activity +def get_boot_time(): + """Boot time + + Get most recent boot time + + :return: time PC was booted in seconds after the epoch. + + :Example: + + >>> get_boot_time() + 123456789.0 + + Keywords + boot, boot time, boottime, startup, timer + + Icon + lar la-clock + """ + import psutil + + return psutil.boot_time() + + +@activity +def get_time_since_last_boot(): + """Uptime + + Get uptime since last boot + + :return: time since last boot in seconds. + + :Example: + + >>> get_time_since_last_boot() + 1337.0 + + Keywords + boot, boot time, boottime, startup, timer + + Icon + lar la-clock + """ + import time + import psutil + + return time.time() - psutil.boot_time() + - target_list.add_card(title, desc=description) +""" +Image Processing +Icon: las la-photo-video +""" + + +@activity +def show_image(path): + """Show image + + Displays an image specified by the path variable on the default imaging program. + + :parameter path: Full path to image + + :Example: + + >>> # Take screenshot of current screen to use as test image + >>> testimage = take_screenshot() + >>> # Show the image + >>> show_image(testimage) + + Keywords + image, show image, reveal, open image, open + + Icon + las la-images + + """ + from PIL import Image + + im = Image.open(path) + + return im.show() + + +@activity +def rotate_image(path, angle=90): + """Rotate image + + Rotate an image + + :parameter angle: Degrees to rotate image. Note that angles other than 90, 180, 270, 360 can resize the picture. + + :Example: + + >>> # Take screenshot of current screen to use as test image + >>> testimage = take_screenshot() + >>> # Rotate the image + >>> rotate_image(testimage) + >>> # Show the image + >>> show_image(testimage) + + Keywords + image, rotate image, 90 degrees, image manipulation, photoshop, paint + + Icon + las la-undo + + """ + from PIL import Image + + im = Image.open(path) + + return im.rotate(angle, expand=True).save(path) + + +@activity +def resize_image(path, size): + """Resize image + + Resizes the image specified by the path variable. + + :parameter path: Path to the image + :parameter size: Tuple with the width and height in pixels. E.g. (300, 400) gives the image a width of 300 pixels and a height of 400 pixels. + + :Example: + + >>> # Take screenshot of current screen to use as test image + >>> testimage = take_screenshot() + >>> # Resize the image + >>> resize_image(testimage, size=(100,100)) + >>> # Show the image + >>> show_image(testimage) + + Keywords + image, resize image, resize, size, image manipulation, photoshop, paint + + Icon + las la-expand-arrows-alt + """ + from PIL import Image + + im = Image.open(path) + + return im.resize(size).save(path) + + +@activity +def get_image_width(path): + """Get image width + + Get with of image + + :parameter path: Path to image + + :Example: + + >>> # Take screenshot of current screen to use as test image + >>> testimage = take_screenshot() + >>> # get image height + >>> get_image_width(testimage) + 1000 + + Keywords + image, height, width, image height, image width + + Icon + las la-expand-arrows-alt + """ + from PIL import Image + + im = Image.open(path) + + width, _ = im.size + + return width + + +@activity +def get_image_height(path): + """Get image height + + Get height of image + + :parameter path: Path to image + + :return: Height of image + + :Example: + + >>> # Take screenshot of current screen to use as test image + >>> testimage = take_screenshot() + >>> # get image height + >>> get_image_height(testimage) + 1000 + + Keywords + image, height, width, image height, image width + + Icon + las la-arrows-alt-v + + """ + from PIL import Image + + im = Image.open(path) + + _, height = im.size + + return height + + +@activity +def crop_image(path, box=None): + """Crop image + + Crops the image specified by path to a region determined by the box variable. + + :parameter path: Path to image + :parameter box: A tuple that defines the left, upper, right and lower pixel coördinate e.g.: (left, upper, right, lower) + + :Example: + + >>> # Take screenshot of current screen to use as test image + >>> testimage = take_screenshot() + >>> # Crop the image + >>> crop_image(testimage, box = (10,10,100,100)) + >>> # Show the image + >>> show_image(testimage) + + Keywords + image, crop, crop image + + Icon + las la-crop + """ + from PIL import Image + im = Image.open(path) + return im.crop(box).save(path) + + +@activity +def mirror_image_horizontally(path): + """Mirror image horizontally + + Mirrors an image with a given path horizontally from left to right. + + :parameter path: Path to image + + :Example: + + >>> # Take screenshot of current screen to use as test image + >>> testimage = take_screenshot() + >>> # Mirror image horizontally + >>> mirror_image_horizontally(testimage) + >>> # Show the image + >>> show_image(testimage) + + Keywords + image, flip, flip image, mirror, mirror image, horizon, horizontally + + Icon + las la-caret-up + """ + from PIL import Image + im = Image.open(path) + return im.transpose(Image.FLIP_LEFT_RIGHT).save(path) + + +@activity +def mirror_image_vertically(path): + """Mirror image vertically + + Mirrors an image with a given path vertically from top to bottom. + + :parameter path: Path to image + + :Example: + + >>> # Take screenshot of current screen to use as test image + >>> testimage = take_screenshot() + >>> # Mirror image vertically + >>> mirror_image_vertically(testimage) + >>> # Show the image + >>> show_image(testimage) + + Keywords + image, flip, flip image, mirror, mirror image, vertical, vertically + + Icon + las la-caret-right + """ + from PIL import Image + im = Image.open(path) + return im.transpose(Image.FLIP_TOP_BOTTOM).save(path) + + +""" +Process +Icon: las la-play +""" + + +@activity +def run_manual(task): + """Windows run + + Use Windows Run to boot a process + Note this uses keyboard inputs which means this process can be disrupted by interfering inputs + + :parameter task: Name of the task to run e.g. 'mspaint.exe' + + :Example: + + >>> # Open paint with Windows run + >>> run_manual('mspaint.exe') + >>> # Open home directory with Windows run + >>> run_manual(home_path()) + + Keywords + run, open, task, win r, windows run, shell, cmd + + Icon + las la-cog + """ + + import time + + press_key_combination('win', 'r') + time.sleep(0.5) + + import platform + + # Set keyboard layout for Windows platform + if platform.system() == "Windows": + from win32api import LoadKeyboardLayout + LoadKeyboardLayout("00000409", 1) + + type_text(task) + press_key('enter') + + +@activity +def run(process): + """Run process + + Use subprocess to open a windows process + + :parameter process: Process to open e.g: 'calc.exe', 'notepad.exe', 'control.exe', 'mspaint.exe'. + + :Example: + + >>> # Open paint with Windows run + >>> run('mspaint.exe') + + Keywords + run, open, task, win r, windows run, shell, cmd + + Icon + las la-play + """ + import subprocess + subprocess.Popen(process) + + +@activity +def is_process_running(name): + """Check if process is running + + Check if process is running. Validates if given process name (name) is currently running on the system. + + :parameter name: Name of process + + :return: Boolean + + :Example: + + >>> # Open paint with Windows run + >>> run('mspaint.exe') + >>> # Check if paint is running + >>> is_process_running('mspaint.exe') + True + + Keywords + run, open, task, win r, windows run, shell, cmd + + Icon + las la-cogs + """ + import psutil + + if name: + for p in psutil.process_iter(): + if name in p.name(): + return True + + return False + + +@activity +def get_running_processes(): + """Get running processes + + Get names of unique processes currently running on the system. + + :return: List of unique running processes + + :Example: + + >>> # Show all running processes + >>> get_running_processes() + ['cmd.exe', 'chrome.exe', ... ] + + Keywords + process, processes, list processes, running, running processes + + Icon + las la-list + """ + import psutil + + process_list = [] + + for p in psutil.process_iter(): + process_list.append(p.name()) + + return list(set(process_list)) + + +@activity +def kill_process(name=None): + """Kill process + + Kills a process forcefully + + :parameter name: Name of the process + + :Example: + + >>> # Open paint with Windows run + >>> run('mspaint.exe') + >>> # Force paint to close + >>> kill_process('mspaint.exe') + + + Keywords + run, open, task, win r, windows run, shell, cmd, kill, stop, kill process, stop process, quit, exit + + Icon + las la-window-close + """ + import os + return os.system("taskkill /f /im " + name + " >nul 2>&1") + + +""" +Optical Character Recognition (OCR) +Icon: las la-glasses +""" + + +@activity +def extract_text_ocr(path=None): + """Get text with OCR + + This activity extracts all text from the current screen or an image if a path is specified. + + :parameter path: Path to image from where text will be extracted. If no path is specified a screenshot of current screen will be used. + + :return: String with all text from current screen + + :Example: + + >>> # Make a textfile with some text to recognize + >>> testfile = make_textfile(text='OCR Example') + >>> # Open the textfile + >>> open_file(testfile) + >>> # Find the text with OCR + >>> extracted_text = find_text_on_screen_ocr(text='OCR Example') + >>> # Check if the extracted_text contains the original word + >>> 'OCR Example' in extracted_text + True + + Keywords + OCR, vision, AI, screen, citrix, read, optical character recognition + + Icon + lab la-readme + """ + + import requests + import base64 + import os + import json + + if not path: + import PIL.ImageGrab + img = PIL.ImageGrab.grab() + path = os.path.join(os.path.expanduser("~"), "ocr_temp.jpg") + img.save(path, "JPEG") + + # Open file and encode as Base 64 + with open(path, 'rb') as f: + image_base64 = base64.b64encode(f.read()).decode('utf-8') + + # Get Bot API_key + config_path = os.path.join(os.path.expanduser("~"), "automagica.json") + + # Read JSON + with open(config_path) as json_file: + local_data = json.load(json_file) + api_key = str(local_data['bot_secret']) # Your API key + + # Prepare data for request + data = { + "image_base64": image_base64, + "api_key": api_key + } + + # Post request to API + r = requests.post('https://ocr.automagica.com/', json=data) + + # Print results + return r.json()['text'] + + +@activity +def find_text_on_screen_ocr(text, criteria=None): + """Find text on screen with OCR + + This activity finds position (coordinates) of specified text on the current screen using OCR. + + :parameter text: Text to find. Only exact matches are returned. + :parameter criteria: Criteria to select on if multiple matches are found. If no criteria is specified all matches will be returned. Options are 'first', which returns the first match closest to the upper left corner, 'last' returns the last match closest to the lower right corner, random selects a random match. + + :return: Dictionary or list of dictionaries with matches with following elements: 'h' height in pixels, 'text' the matched text,'w' the width in pixels, 'x' absolute x-coördinate , 'y' absolute y-coördinate. Returns nothing if no matches are found + + :Example: + + >>> # Make a textfile with some text to recognize + >>> testfile = make_textfile(text='OCR Example') + >>> # Open the textfile + >>> open_file(testfile) + >>> # Find the text with OCR + >>> find_text_on_screen_ocr(text='OCR Example') + + Keywords + OCR, vision, AI, screen, citrix, read, optical character recognition + + Icon + las la-glasses + + """ + + import requests + import base64 + import os + import json + + import PIL.ImageGrab + img = PIL.ImageGrab.grab() + path = os.path.join(os.path.expanduser("~"), "ocr_capture.jpg") + img.save(path, "JPEG") + + # Open file and encode as Base 64 + with open(path, 'rb') as f: + image_base64 = base64.b64encode(f.read()).decode('utf-8') + + # Get Bot API_key + config_path = os.path.join(os.path.expanduser("~"), "automagica.json") + + # Read JSON + with open(config_path) as json_file: + local_data = json.load(json_file) + api_key = str(local_data['bot_secret']) # Your API key + + # Prepare data for request + data = { + "image_base64": image_base64, + "api_key": api_key + } + + # Post request to API + r = requests.post('https://ocr.automagica.com/', json=data) + + # Print results + data = r.json()['locations'] + + # Find all matches + matches = [] + for item in data: + if item['text'].lower() == text.lower(): + matches.append(item) + + if not matches: + return None + + if criteria: + if len(matches) > 0: + if criteria == 'first': + best_match = matches[0] + if criteria == 'last': + best_match = matches[-1] + if criteria == 'random': + import random + best_match = random.choice(matches) + + return best_match + + else: + return matches + + +@activity +def click_on_text_ocr(text): + """Click on text with OCR + + This activity clicks on position (coordinates) of specified text on the current screen using OCR. + + :parameter text: Text to find. Only exact matches are returned. + + :Example: + + >>> # Make a textfile with some text to recognize + >>> testfile = make_textfile(text='OCR Example') + >>> # Open the textfile + >>> open_file(testfile) + >>> # Find the text with OCR and click on it + >>> click_on_text(text='OCR Example') + + Keywords + OCR, vision, AI, screen, citrix, read, optical character recognition, click + + Icon + las la-mouse-pointer + """ + position = find_text_on_screen_ocr(text, criteria='first') + if position: + from pyautogui import click + x = int(position['x'] + position['w']/2) + y = int(position['y'] + position['h']/2) + return click(x=x, y=y) + + +@activity +def double_click_on_text_ocr(text): + """Double click on text with OCR + + This activity double clicks on position (coordinates) of specified text on the current screen using OCR. + + :parameter text: Text to find. Only exact matches are returned. + + :Example: + + >>> # Make a textfile with some text to recognize + >>> testfile = make_textfile(text='OCR Example') + >>> # Open the textfile + >>> open_file(testfile) + >>> # Find the text with OCR and double click on it + >>> double_click_on_text(text='OCR Example') + + Keywords + OCR, vision, AI, screen, citrix, read, optical character recognition, click, double click + + Icon + las la-mouse-pointer + + """ + + position = find_text_on_screen_ocr(text, criteria='first') + if position: + from pyautogui import doubleClick + x = int(position['x'] + position['w']/2) + y = int(position['y'] + position['h']/2) + return doubleClick(x=x, y=y) + + +@activity +def right_click_on_text_ocr(text): + """Right click on text with OCR + + This activity Right clicks on position (coordinates) of specified text on the current screen using OCR. + + :parameter text: Text to find. Only exact matches are returned. + + :Example: + + >>> # Make a textfile with some text to recognize + >>> testfile = make_textfile(text='OCR Example') + >>> # Open the textfile + >>> open_file(testfile) + >>> # Find the text with OCR and right click on it + >>> right_click_on_text(text='OCR Example') + + Keywords + OCR, vision, AI, screen, citrix, read, optical character recognition, click, right click + + Icon + las la-mouse-pointer + """ + position = find_text_on_screen_ocr(text, criteria='first') + if position: + from pyautogui import rightClick + x = int(position['x'] + position['w']/2) + y = int(position['y'] + position['h']/2) + return rightClick(x=x, y=y) diff --git a/automagica/bin/linux64/chromedriver b/automagica/bin/linux64/chromedriver index 02ff671c..eeecd359 100644 Binary files a/automagica/bin/linux64/chromedriver and b/automagica/bin/linux64/chromedriver differ diff --git a/automagica/bin/mac64/chromedriver b/automagica/bin/mac64/chromedriver index f2bcba36..4ff3bcce 100644 Binary files a/automagica/bin/mac64/chromedriver and b/automagica/bin/mac64/chromedriver differ diff --git a/automagica/bin/win32/chromedriver.exe b/automagica/bin/win32/chromedriver.exe index 28a40679..ec9ce298 100644 Binary files a/automagica/bin/win32/chromedriver.exe and b/automagica/bin/win32/chromedriver.exe differ diff --git a/automagica/cli.py b/automagica/cli.py index ec7572a1..78d7c18d 100644 --- a/automagica/cli.py +++ b/automagica/cli.py @@ -6,25 +6,29 @@ import sys from time import sleep - -__version__ = "1.0.10" +__version__ = "2.0.0" parser = argparse.ArgumentParser(description="Automagica Robot v" + __version__) -parser.add_argument("--login", default="", type=str, help="Log in with access key") - -parser.add_argument("--logout", dest="logout", action="store_true", help="Log out") +parser.add_argument( + "--connect", + default="", + type=str, + help="Connect to Automagica Portal with user secret", +) parser.add_argument( - "--daemon", dest="daemon", action="store_true", help="Run robot as a daemon" + "--disconnect", + dest="disconnect", + action="store_true", + help="Disconnect from Automagica Portal", ) parser.add_argument( - "--foreground", - dest="foreground", - default=False, + "--bot", + dest="bot", action="store_true", - help="Keep process in the foreground", + help="Run bot connected to Automagica Portal", ) parser.add_argument( @@ -58,11 +62,19 @@ ) parser.add_argument( - "--verbose", - dest="verbose", + "--debug", + dest="debug", default=False, action="store_true", - help="Verbose logging", + help="Debug level logging", +) + +parser.add_argument( + "-e", + "--edit", + default="", + type=str, + help="Edit Automagica script in Automagica Lab using the script id", ) @@ -72,10 +84,12 @@ def __init__(self): args = parser.parse_args() # Set up logging - self._setup_logging(verbose=args.verbose) + self._setup_logging(debug=args.debug) # Environment variable override Automagica Portal URL - self.url = os.environ.get("AUTOMAGICA_URL", "https://bots.portal.automagica.io") + self.url = os.environ.get( + "AUTOMAGICA_PORTAL_URL", "https://portal.automagica.com" + ) # Custom config specified? if args.config: @@ -83,16 +97,24 @@ def __init__(self): else: self.config_path = os.path.join(os.path.expanduser("~"), "automagica.json") - self.config = self.load_config() + self.config = self._load_config() + + # Download and run Jupyter Notebook (.ipynb) + if args.edit: + self.edit(args.edit) - if args.login: - self.login(args.login) + # Connect to Automagica Portal + if args.connect: + user_secret = args.connect.split("[")[1].split("]")[0] + self.connect(user_secret) - if args.logout: - self.logout() + # Disconnect from Automagica Portal + if args.disconnect: + self.disconnect() - if args.daemon: - self.daemon(foreground=args.foreground) + # Start Automagica Bot manually + if args.bot: + self.bot() # Was a file specified? if args.file: @@ -114,8 +136,8 @@ def __init__(self): # Run script exec(script, globals()) - def _setup_logging(self, verbose=False): - if verbose: + def _setup_logging(self, debug=False): + if debug: log_level = logging.INFO else: log_level = logging.WARNING @@ -136,11 +158,117 @@ def _setup_logging(self, verbose=False): logger.addHandler(file_handler) logger.addHandler(stdout_handler) - def save_config(self): + def edit(self, url): + """Edit a script from the Automagica Portal + """ + from time import sleep + import requests + import re + import subprocess + + try: + script_id = None + script_version_id = None + + if url.startswith("automagica://"): + ids = url.replace("automagica://", "").split("/") + + if len(ids) == 1: + script_id = ids[0] + + if len(ids) == 2: + script_id = ids[0] + script_version_id = ids[1] + + # Check if Automagica folder exists + target_folder = os.path.join(os.path.expanduser("~"), ".automagica") + + if not os.path.exists(target_folder): + os.mkdir(target_folder) + + # Retrieve URL + headers = { + "user_secret": self.config["user_secret"], + "script_id": script_id, + } + + if script_version_id: + headers["script_version_id"] = script_version_id + + print(headers) + + r = requests.get(self.url + "/api/script", headers=headers) + + import re + + print(r.content) + + d = r.headers["content-disposition"] + fname = re.findall("filename=(.+)", d)[0] + + path = os.path.join(target_folder, fname) + + with open(path, "wb") as f: + f.write(r.content) + + notebook_path = path + + # Run notebook server + import subprocess + + my_env = os.environ.copy() + my_env["JUPYTER_CONFIG_DIR"] = os.path.abspath(__file__).replace( + "cli.py", "lab\\.jupyter" + ) + + print(my_env["JUPYTER_CONFIG_DIR"]) + + process = subprocess.Popen( + 'jupyter notebook "{}"'.format(notebook_path), env=my_env + ) + + # While server is running, check for changes of the path + last_known_modification = os.path.getmtime(notebook_path) + + with open(notebook_path, "r") as f: + last_known_binary = f.read() + + print( + "Automagica's Jupyter Notebook server running. Do not close this window." + ) + + while not process.poll(): + last_modification = os.path.getmtime(notebook_path) + + if last_known_modification < last_modification: + + last_known_modification = last_modification + + with open(notebook_path, "r", encoding="utf-8") as f: + last_binary = f.read() + + if last_known_binary != last_binary: + last_known_binary = last_binary + + r = requests.post( + self.url + "/api/script", headers=headers + ).json() + + with open(notebook_path, "rb") as f: + files = {"file": (notebook_path, f)} + _ = requests.post(r["url"], data=r["fields"], files=files) + + sleep(1) + + except: + logging.exception("oops") + input() + + def _save_config(self): with open(self.config_path, "w") as f: json.dump(self.config, f) - def load_config(self): + def _load_config(self): try: with open(self.config_path, "r") as f: config = json.load(f) @@ -148,7 +276,7 @@ def load_config(self): except FileNotFoundError: config = {} self.config = config - self.save_config() + self._save_config() return config @@ -164,143 +292,147 @@ def notification(self, message): ticker="Automagica", ) - def daemon(self, foreground=False): - import socketio + def _alive(self): + import requests + import os + from time import sleep - if not foreground: - # Hide console if we're on Windows - if os.name == "nt": - import ctypes + headers = {"bot_secret": self.config["bot_secret"]} - ctypes.windll.user32.ShowWindow( - ctypes.windll.kernel32.GetConsoleWindow(), 0 - ) + while True: + try: + _ = requests.post(self.url + "/api/bot/alive", headers=headers) + print(_.content) + except: + logging.exception("Could not reach Automagica Portal.") + sleep(30) + + def run(self, notebook, parameters=None, cell_timeout=600): + from nbconvert.preprocessors import ExecutePreprocessor, CellExecutionError + from nbformat.notebooknode import from_dict + + ep = ExecutePreprocessor(timeout=cell_timeout, kernel_name="python3") + + if parameters: + parameter_node = from_dict( + { + "cell_type": "code", + "metadata": {"tags": ["parameters"]}, + "source": parameters, + } + ) + for i, cell in enumerate(notebook.cells): + if cell.metadata: + if cell.metadata.tags: + if "default-parameters" in cell.metadata.tags: + break + else: + i = 0 + notebook.cells.insert(i, parameter_node) + + errors = False - sio = socketio.Client() + try: + out = ep.preprocess(notebook) - if not self.config.get("bot_id"): - raise Exception("You need to log in first!") + except CellExecutionError: + errors = True - @sio.on("connect", namespace="/bot") - def connect(): - logging.info("Connected") + finally: + return notebook, errors - # After connecting, send authentication message - sio.emit( - "auth", - {"bot_id": self.config["bot_id"], "version": __version__}, - namespace="/bot", - ) + def bot(self): + global CURRENT_JOB + + from threading import Thread + import requests - @sio.on("run", namespace="/bot") - def run(data): - logging.info("Running script") - logging.info(str(data)) + # Start seperate thread to let portal know I'm alive + t = Thread(target=self._alive) - job_id = data["schedule"]["job"]["id"] + t.start() - # Save backup of the script - fn = str(job_id) + ".py" - path = os.path.join(os.path.expanduser("~"), fn) + while True: + # Get next job + headers = {"bot_secret": self.config["bot_secret"]} - with open(path, "w", newline="", encoding="utf-8") as f: - f.write(data["schedule"]["script"]["code"]) + try: + r = requests.get(self.url + "/api/job/next", headers=headers) - cmd = '"' + sys.executable + '" -u -m automagica -f ' + '"' + path + '"' + print(r.content) + job = r.json() - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + # We got a job! + if job: + logging.info("Received job {}".format(job["job_id"])) - self.notification( - "Script {} (job #{}) started.".format( - data["schedule"]["script"]["name"], data["schedule"]["job"]["id"] - ) - ) + CURRENT_JOB = job["job_id"] - @sio.on("kill", namespace="/bot") - def kill(job): - if job == job_id: - p.kill() - logging.info("Stopping job") - - # Read STDOUT - for line in iter(p.stdout.readline, b""): - if line: - output = { - "output": line.decode("utf-8"), - "job_id": job_id, - "bot_id": self.config["bot_id"], - } - sio.emit("output", output, namespace="/bot") - - # Read STDERR - for line in iter(p.stderr.readline, b""): - if line: - error = { - "error": line.decode("utf-8"), - "job_id": job_id, - "bot_id": self.config["bot_id"], + headers = { + "script_id": job["script_id"], + "script_version_id": job.get("script_version_id"), + "bot_secret": self.config["bot_secret"], } - sio.emit("error", error, namespace="/bot") - # Wait for process to finish - p.wait() + # Retrieve notebook + r = requests.get( + self.url + "/api/script", headers=headers, stream=True + ) - # Retrieve status code - code = p.poll() + from io import BytesIO + import nbformat - result = {"job_id": job_id, "bot_id": self.config["bot_id"]} + notebook = nbformat.read(BytesIO(r.content), as_version=4) - if code == 0: # Success - result["type"] = "success" - else: # Failure - result["type"] = "failure" + output, errors = self.run( + notebook, + parameters=job.get("parameters"), + cell_timeout=-1, # No timeout + ) - logging.info("Finished script!") - self.notification( - "Script {} (job #{}) finished.".format( - data["schedule"]["script"]["name"], data["schedule"]["job"]["id"] - ) - ) + if not errors: + # Completed without exceptions + job["status"] = "completed" + logging.exception("Completed job {}".format(job["job_id"])) - sio.emit("finish", result, namespace="/bot") + else: + # Exceptions occured + job["status"] = "failed" + logging.exception("Failed job {}".format(job["job_id"])) - @sio.on("disconnect", namespace="/bot") - def disconnect(): - logging.info("Disconnected") + headers = { + "bot_secret": self.config["bot_secret"], + "job_id": job["job_id"], + "job_status": job["status"], + } - @sio.on("authed", namespace="/bot") - def authed(data): - logging.info( - "Authenticated to Automagica as {}".format(data["bot"]["name"]) - ) - self.notification( - "Connected as {} to Automagica!".format(data["bot"]["name"]) - ) + r = requests.post(self.url + "/api/job", headers=headers).json() - @sio.on("error", namespace="/bot") - def error(data): - logging.info(data.get("error")) - try: - from tkinter import messagebox + from io import BytesIO - messagebox.showwarning("Error", data.get("error")) + data = nbformat.writes(output, version=4) - if data.get("url"): - import webbrowser + fileobj = BytesIO() - webbrowser.open(data["url"]) - except: - logging.error(data.get("error")) + fileobj.write(data.encode("utf-8")) + + fileobj.seek(0) + + files = {"file": ("notebook.ipynb", fileobj)} + + _ = requests.post(r["url"], data=r["fields"], files=files) + + CURRENT_JOB = None + + # We did not get a job! + else: + sleep(10) - while True: - try: - sio.connect(self.url) - sio.wait() except: - logging.info("Could not connect to Automagica, retrying in 5 seconds.") - sleep(5) + logging.exception("Could not reach portal.") + sleep(10) - def kill_process(self, name): + def _kill_processes_by_name(self, name): import psutil for proc in psutil.process_iter(): @@ -309,30 +441,49 @@ def kill_process(self, name): proc.kill() proc.wait() - def login(self, bot_id): - self.config["bot_id"] = bot_id - self.save_config() + def connect(self, user_secret): + import requests + import socket + import os + + headers = {"user_secret": user_secret} + data = {"name": socket.gethostname()} + + print(headers) + print(data) + + r = requests.post(self.url + "/api/bot/setup", json=data, headers=headers) + + if r.status_code != 200: + raise Exception("Could not connect to Automagica Portal") + + data = r.json() + + self.config["user_secret"] = user_secret + self.config["bot_secret"] = data["bot_secret"] + self._save_config() self.add_startup() - self.kill_process("python") + self._kill_processes_by_name("python") sleep(3) - cmd = sys.executable + " -m automagica --daemon" + cmd = sys.executable + " -m automagica --bot" subprocess.Popen(cmd) - def logout(self): - self.kill_process("python") + def disconnect(self): + self._kill_processes_by_name("python") self.remove_startup() def add_startup(self): import platform - cmd = sys.executable + " -m automagica --daemon" + cmd = sys.executable + " -m automagica --bot" if platform.system() == "Windows": import winreg as reg + # Add to start-up registry = reg.OpenKey( reg.HKEY_CURRENT_USER, "Software\Microsoft\Windows\CurrentVersion\Run", @@ -342,6 +493,25 @@ def add_startup(self): reg.SetValueEx(registry, "Automagica", 0, reg.REG_SZ, cmd) reg.CloseKey(registry) + registry = reg.OpenKey( + reg.HKEY_CLASSES_ROOT, "Automagica", 0, reg.KEY_WRITE + ) + reg.SetValueEx(registry, "", 0, reg.REG_SZ, "URL:automagica") + reg.SetValueEx(registry, "URL Protocol", 0, reg.REG_SZ, "") + + # Register automagica:// protocol + registry = reg.OpenKey( + reg.HKEY_CLASSES_ROOT, + "Automagica\\shell\\open\\command", + 0, + reg.KEY_WRITE, + ) + reg.SetValueEx( + registry, "", 0, reg.REG_SZ, sys.executable + " -m automagica -e %1" + ) + + reg.CloseKey(registry) + if platform.system() == "Linux": # Create Automagica.desktop file in ~/.config/autostart/ path = os.path.join( diff --git a/automagica/lab/.jupyter/custom/automagica-lab.png b/automagica/lab/.jupyter/custom/automagica-lab.png new file mode 100644 index 00000000..26fb6890 Binary files /dev/null and b/automagica/lab/.jupyter/custom/automagica-lab.png differ diff --git a/automagica/lab/.jupyter/custom/custom.css b/automagica/lab/.jupyter/custom/custom.css new file mode 100644 index 00000000..963161b8 --- /dev/null +++ b/automagica/lab/.jupyter/custom/custom.css @@ -0,0 +1,120 @@ +body { + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; +} + +.btn { + background-color: white; + color: #007bff; +} + +.btn:hover { + background-color: #0069c0; + color: white; +} + +.notebook_app { + background: url("automagica-lab.png") no-repeat; + background-position: bottom -900px right -50px; + +} + +/* Hiding confusing elements */ +#filelink, +#logout, +#kernel_logo_widget, +#cmd_palette, +#kernel_indicator, +#kernel_indicator_icon, +#notification_trusted, +#menu-change-kernel { + display: none !important; +} + +#save_widget, +#modal_indicator { + color: white !important; +} + +.shadow { + box-shadow: rgba(0, 0, 0, 0.13) 10px 10px 21px 5px; + } + + +#ipython_notebook img{ + display:block; + /* logo url here */ + background: url("logo-white.png") no-repeat; + background-size: contain; + width: 233px; + height: 33px; + padding-left: 233px; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +#header { + background-color: #007BFF !important; +} + +.navbar-default { + background-color: #007BFF !important; + border: 0px; +} + +.navbar-default .navbar-nav > li > a { + color: rgba(255,255,255,.5); +} + +.navbar-default .navbar-nav > li > a:active { + color: rgba(255,255,255,.75); +} + +.navbar-default .navbar-nav > li > a:hover { + color: rgba(255,255,255,.75); +} + +.navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { + color: rgba(255,255,255,.75); + background-color: #007BFF !important; +} + + + +.header-bar { + background-color: #007BFF !important; + border: 0px; +} + +#notebook_name { + display: none; +} + +#kernal_indicator { + display: none; +} + +.run_this_cell { + display: block !important; + background-color: white !important; + color: #0069c0 !important; + + width: 30px !important; +} + + +.run_this_cell i { + visibility: hidden; + } + .run_this_cell i:after { + content:'▶'; + visibility: visible; + display: block; + position: absolute; + background-color: #2195f3; + color: white; + padding: 8px; + top: 2px; + margin-top:3px; + margin-right: 5px; + margin-left: -15px; + } \ No newline at end of file diff --git a/automagica/lab/.jupyter/custom/custom.js b/automagica/lab/.jupyter/custom/custom.js new file mode 100644 index 00000000..56794cb3 --- /dev/null +++ b/automagica/lab/.jupyter/custom/custom.js @@ -0,0 +1,212 @@ + + +requirejs([ + 'jquery', + 'base/js/utils', +], function ($, utils +) { + + utils.change_favicon("custom/favicon.png") +}); + +$([Jupyter.events]).on("notebook_loaded.Notebook", function () { + Jupyter.notebook.set_autosave_interval(0); + +}); + +var htmlToInsert = ''; + +define([ + 'base/js/namespace', + 'base/js/promises' +], function (Jupyter, promises) { + promises.app_initialized.then(function (appname) { + if (appname === 'NotebookApp') { + Jupyter.notebook.set_autosave_interval(0); + + + $('a:contains("Kernel")').text('Bot'); + + $('a:contains("Widgets")').hide(); + + $('#cell_type option[value="raw"]').hide(); + $('#cell_type option[value="heading"]').hide(); + + + + $('#maintoolbar-container').append(` + Run all + Clear output`); + + $('head').append('') + + var categories; + + $.getJSON('https://raw.githubusercontent.com/OakwoodAI/Automagica/v2.0/docs/portal/activities.json', function (data) { + categories = data; + + htmlToInsert += ` +
+
Activities
+
+ +
+
+
+
`; + categories.forEach(function (category, i) { + + var category_keywords = ''; + + category.activities.forEach(function (activity) { + category_keywords += activity.keywords; + } + ); + + htmlToInsert += ` + + +
+
    `; + + category.activities.forEach(function (activity) { + + htmlToInsert += ` +
  •   ` + activity.name + `
  • `; + + }); + + htmlToInsert += ` +
+
`; + }); + + htmlToInsert += `
`; + + htmlToInsert += ` + + `; + + var notebook = document.getElementById('notebook'); + notebook.insertAdjacentHTML('beforeend', htmlToInsert); + + dragElement(document.getElementById("activities")); + + + + }) + } + }); +}); + +function insertSnippet(cell_type, contents) { + cell = Jupyter.notebook.insert_cell_below(cell_type); + cell.set_text(contents.replace(/\\n/g, '\n')); + if (cell_type == 'markdown') { + cell.execute(); + + } + cell.focus_cell(); +} + +function filterActivities(q) { + var category_panels = $('.category_panel'); + var category_headers = $('.category_header'); + var activity_containers = $('.activity_container') + + if (q.length > 0) { + // hide panels and expand resulting panels + category_panels.each(function (index) { + if ($(this).attr('data-keywords').toLowerCase().includes(q.toLowerCase())) { + $(this).collapse('show'); + } + }); + + // hide category buttons and show matches + category_headers.each(function (index) { + $(this).hide(); + if ($(this).attr('data-keywords').toLowerCase().includes(q.toLowerCase())) { + $(this).show(); + } + }); + + // hide activiy buttons and show matches + activity_containers.each(function (index) { + $(this).hide(); + if ($(this).attr('data-keywords').toLowerCase().includes(q.toLowerCase())) { + $(this).show(); + } + }); + + + } else { + category_panels.each(function (index) { + //$(this).show(); + // $(this).collapse('show'); + $(this).collapse('hide'); + + }); + + category_headers.each(function (index) { + $(this).show(); + }); + + activity_containers.each(function (index) { + $(this).show(); + }); + + } +} + + +function dragElement(elmnt) { + var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; + if (document.getElementById(elmnt.id + "header")) { + // if present, the header is where you move the DIV from: + document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown; + } else { + // otherwise, move the DIV from anywhere inside the DIV: + elmnt.onmousedown = dragMouseDown; + } + + function dragMouseDown(e) { + e = e || window.event; + e.preventDefault(); + // get the mouse cursor position at startup: + pos3 = e.clientX; + pos4 = e.clientY; + document.onmouseup = closeDragElement; + // call a function whenever the cursor moves: + document.onmousemove = elementDrag; + } + + function elementDrag(e) { + e = e || window.event; + e.preventDefault(); + // calculate the new cursor position: + pos1 = pos3 - e.clientX; + pos2 = pos4 - e.clientY; + pos3 = e.clientX; + pos4 = e.clientY; + // set the element's new position: + elmnt.style.top = (elmnt.offsetTop - pos2) + "px"; + elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; + } + + function closeDragElement() { + // stop moving when mouse button is released: + document.onmouseup = null; + document.onmousemove = null; + } +} \ No newline at end of file diff --git a/automagica/lab/.jupyter/custom/favicon.png b/automagica/lab/.jupyter/custom/favicon.png new file mode 100644 index 00000000..0ebd8082 Binary files /dev/null and b/automagica/lab/.jupyter/custom/favicon.png differ diff --git a/automagica/lab/.jupyter/custom/logo-white.png b/automagica/lab/.jupyter/custom/logo-white.png new file mode 100644 index 00000000..bf6b0fa9 Binary files /dev/null and b/automagica/lab/.jupyter/custom/logo-white.png differ diff --git a/automagica/lab/.jupyter/custom/logo.png b/automagica/lab/.jupyter/custom/logo.png new file mode 100644 index 00000000..a7c89edc Binary files /dev/null and b/automagica/lab/.jupyter/custom/logo.png differ diff --git a/automagica/lab/.jupyter/custom/temp.html b/automagica/lab/.jupyter/custom/temp.html new file mode 100644 index 00000000..5cfa5c73 --- /dev/null +++ b/automagica/lab/.jupyter/custom/temp.html @@ -0,0 +1,1252 @@ + + + + + + +
+
+ +
+ +
+
+
+ +
+
+
+

+ + + Delay +

+
+
+ +
+
+
+ +
+ +
+ + + +
+
+ +
+ +
+
+
+ + + + + +
+
+
+

+ + + Word +

+
+ +
+
+ +
+
+
+

+ + + PDF +

+
+
+ +
+
+
+ + + + + + + + + +
+
+
+

+ + + Email +

+
+ +
+
+ +
+
+
+

+ + + Math +

+
+
+ +
+
+
+ +
+
+ +
+ +
+
+
diff --git a/automagica/lab/.jupyter/nbconfig/notebook.json b/automagica/lab/.jupyter/nbconfig/notebook.json new file mode 100644 index 00000000..467240e7 --- /dev/null +++ b/automagica/lab/.jupyter/nbconfig/notebook.json @@ -0,0 +1,11 @@ +{ + "Cell": { + "cm_config": { + "lineNumbers": false + } + }, + "Notebook": { + "Header": true, + "Toolbar": true + } +} \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile index a72490b5..31245328 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -3,10 +3,10 @@ # You can set these variables from the command line. SPHINXOPTS = -SPHINXBUILD = python -msphinx +SPHINXBUILD = sphinx-build SPHINXPROJ = Automagica -SOURCEDIR = . -BUILDDIR = _build +SOURCEDIR = source +BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle deleted file mode 100644 index 693c62cd..00000000 Binary files a/docs/_build/doctrees/environment.pickle and /dev/null differ diff --git a/docs/_build/doctrees/images/6787a6ecc801e2112074827fc474cac013314d82/logo.png b/docs/_build/doctrees/images/6787a6ecc801e2112074827fc474cac013314d82/logo.png deleted file mode 100644 index 448508f4..00000000 Binary files a/docs/_build/doctrees/images/6787a6ecc801e2112074827fc474cac013314d82/logo.png and /dev/null differ diff --git a/docs/_build/doctrees/images/https/i.imgur.com/7gSv7gc.png/7gSv7gc.png b/docs/_build/doctrees/images/https/i.imgur.com/7gSv7gc.png/7gSv7gc.png deleted file mode 100644 index 8113ea08..00000000 Binary files a/docs/_build/doctrees/images/https/i.imgur.com/7gSv7gc.png/7gSv7gc.png and /dev/null differ diff --git a/docs/_build/doctrees/images/https/i.imgur.com/A2xdvUP.png/A2xdvUP.png b/docs/_build/doctrees/images/https/i.imgur.com/A2xdvUP.png/A2xdvUP.png deleted file mode 100644 index f9096e93..00000000 Binary files a/docs/_build/doctrees/images/https/i.imgur.com/A2xdvUP.png/A2xdvUP.png and /dev/null differ diff --git a/docs/_build/doctrees/images/https/i.imgur.com/V3p8spl.jpg/V3p8spl.jpg b/docs/_build/doctrees/images/https/i.imgur.com/V3p8spl.jpg/V3p8spl.jpg deleted file mode 100644 index b4cd5aca..00000000 Binary files a/docs/_build/doctrees/images/https/i.imgur.com/V3p8spl.jpg/V3p8spl.jpg and /dev/null differ diff --git a/docs/_build/doctrees/images/https/i.imgur.com/WRD46Xi.png/WRD46Xi.png b/docs/_build/doctrees/images/https/i.imgur.com/WRD46Xi.png/WRD46Xi.png deleted file mode 100644 index 5c675e27..00000000 Binary files a/docs/_build/doctrees/images/https/i.imgur.com/WRD46Xi.png/WRD46Xi.png and /dev/null differ diff --git a/docs/_build/doctrees/images/https/i.imgur.com/jMj2ypX.png/jMj2ypX.png b/docs/_build/doctrees/images/https/i.imgur.com/jMj2ypX.png/jMj2ypX.png deleted file mode 100644 index a74c8721..00000000 Binary files a/docs/_build/doctrees/images/https/i.imgur.com/jMj2ypX.png/jMj2ypX.png and /dev/null differ diff --git a/docs/_build/doctrees/images/https/i.imgur.com/rh3OUdh.jpg/rh3OUdh.jpg b/docs/_build/doctrees/images/https/i.imgur.com/rh3OUdh.jpg/rh3OUdh.jpg deleted file mode 100644 index 2a05cba6..00000000 Binary files a/docs/_build/doctrees/images/https/i.imgur.com/rh3OUdh.jpg/rh3OUdh.jpg and /dev/null differ diff --git a/docs/_build/doctrees/index.doctree b/docs/_build/doctrees/index.doctree deleted file mode 100644 index 8e4fab2b..00000000 Binary files a/docs/_build/doctrees/index.doctree and /dev/null differ diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 421efdaa..00000000 --- a/docs/index.md +++ /dev/null @@ -1,1549 +0,0 @@ -Automagica Documentation - -This is the documentation for automating in Automagica Smart Automation. -Automagica is based on the Python language. - -![Automagica](https://raw.githubusercontent.com/OakwoodAI/automagica/master/images/logo.png) - -# Table of contents - -- [Getting Started](#getting-started) - - [Prerequisites](#Prerequisites) - - [Installing instructions](#installing-instructions) - - [Failsafe](#failsafe) - - [Examples](#examples) - - [Automagica with Natural Language](#automagica-with-natural-language-for-prototyping) -- [Mouse And Keyboard Automation](#mouse-and-keyboard-automation) - - [Mouse](#mouse) - - [Coordinate System](#coordinate-system) - - [Functions](#functions) - - [Keyboard](#keyboard) -- [Browser Automation](#browser-automation) - - [Basic functions](#basic-functions) - - [Navigating](#navigating) - - [Quick start](#quick-start) - - [Selecting elements](#selecting-elements) - - [Selection by name](#selection-by-name) - - [Selection by Id](#selection-by-id) - - [Selection by Xpath](#selection-by-xpath) - - [Browsing Example](#browsing-example) -- [Process Activities](#process-activities) - - [Standard Windows Applications](#windows-applications) - - [General Commands](#general-commands) - - [Running Programs](#running-programs) -- [Monitoring](#monitoring) -- [Office Automation](#office-automation) - - [Entering Pathnames](#entering-pathnames) - - [Word](#word) - - [Excel](#excel) - - [Reading And Writing](#reading-and-writing) - - [Basic Operations](#basic-operations) -- [PDF Manipulation](#pdf-manipulation) - - [Merge PDF Files](#merge-pdf-files) - - [Extract Text From PDF](#extract-text-from-pdf) -- [File And Folder Manipulation](#file-folder-automation) - - [Files](#files) - - [Open A File](#open-a-file) - - [Renaming Files](#renaming-files) - - [Moving Files](#moving-files) - - [Copying Files](#copying-files) - - [Removing Files](#removing-files) - - [Check If A File Exists](#check-if-a-file-exists) - - [Folders](#folders) - - [Creating Folders](#creating-folders) - - [Open A Folders](#opening-folders) - - [Renaming Folders](#renaming-folders) - - [Moving Folders](#moving-folders) - - [Copying Folders](#copying-folders) - - [Removing Folders](#removing-folders) - - [Empty A Folder](#empty-a-folder) - - [Check If A Folder Exists](#check-if-a-folder-exists) - - [Zip Folder](#zip-folder) - - [UnZip Folder](#unzip-folder) -- [Image Operations](#image-operations) -- [Email Operations](#email-operations) -- [Basic operations](#basic-operations) - - [Variables and Types](#variables-and-types) - - [Strings](#strings) - - [String manipulation](#string-manipulation) - - [Adding variables to a string](#adding-variables-to-a-string) - - [Slicing strings](#slicing-strings) - - [String replacing](#string-replacing) - - [Upper and lower cases in strings](#upper-and-lower-cases-in-strings) - - [Splitting strings](#splitting-strings) - - [Numbers](#numbers) - - [Integers](#integers) - - [Floats](#floats) - - [Math operations](#math-operations) - - [Lists](#lists) - - [Logic operations](#logic-operations) - - [If statement](#if-statement) - - [While loops](#while-loops) - - [For loops](#for-loops) -- [Examples](#examples) - - [Example 1](#example-1) - - [Example 2](#example-2) -- [Credits](#credits) - -# Getting started - - -Refer to our [website](https://www.automagica.io) for more information, registered users can access the [portal](https://portal.automagica.io). More details also available on our [github](https://github.com/OakwoodAI/automagica). - -Alternatively you can use Automagica locally by starting your Python script with: -``` -from automagica import * -``` - -For a step-to-step tutorial on how to install and configure Python see [this video](https://www.youtube.com/watch?v=cpPG0bKHYKc).
-For a step-to-step tutorial on how to build and run a Python script see [this video](https://www.youtube.com/watch?v=hFhiV5X5QM4). - -## Prerequisites -- Python 3.7 from [www.python.org](https://www.python.org) - -## Installation instructions -Install Automagica on the bot host machine: -``` -pip install https://github.com/OakwoodAI/automagica/tarball/master -``` - -### Optional Optical Character Recognition -For _Windows_, install Tesseract 4 [from here](http://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe). - -For _Linux_ (Ubuntu): -``` -sudo apt-get install tesseract-ocr -``` -For _MacOS_: -``` -brw install tesseract -``` - -## Failsafe - -As a safety feature, a failsafe mechanism is enabled by default. You can trigger this by moving your mouse to the upper left corner of the screen. You can disable this by running the following command: -``` -Failsafe(False) -``` -## Examples - -For some animated examples see: [Browser working with Excel](https://raw.githubusercontent.com/OakwoodAI/automagica/master/images/browser_excel.gif) and [SAP Automation](https://github.com/OakwoodAI/automagica/blob/master/images/sap.gif) - -## Automagica with Natural Language for prototyping - -Wouldn't it be cool if we could write Robotic Process Automation scripts in plain ol' English rather than the already easy Python scripting language? Well it's possible with Automagica! We have cooked up a more human-friendly interface to get started with automation ! - -### How it works -Natural language for Automagica (.nla) looks like this: -``` -open the browser -navigate to google.com -search for oranges -``` - -### Try it yourself - -NLP is handled by Wit.ai. A Wit.ai key is included, so you can get a headstart! - -Install (in addition to the above) the following required package: -``` -pip install https://github.com/OakwoodAI/understanding/tarball/master -``` -Then install Natural Language for Automagica: -``` -git clone https://github.com/OakwoodAI/natural-language-automagica -cd natural-language-automagica -pip install . -``` - -Then you can get started by running the examples: -``` -cd examples -nla google.nla -nla wikipedia.nla -nla youtube.nla -``` - -Automagica with natural language is still in development and it's main goal for now is to speed up prototyping. -Not all Automagica activities are supported as natural language and we do not recommend this for production builds for now. - -# Mouse And Keyboard Automation - -Next section explains which functions automagica offers to automate mouse movements and keystrokes. - -## Mouse - -### Coordinate System - -Most functions for mouse operations need coordinates as an input. These coordinates represent the absolute pixel position of the mouse on the computer screen. Following picuter gives the coördinate system for a 1920 x 1080 resolution screen. The x-coördinate starts at the left side and increases going right. The y-coördinate increases going down. -``` -0,0 X increases --> -+---------------------------+ -| | Y increases -| | | -| 1920 x 1080 screen | | -| | V -| | -| | -+---------------------------+ 1919, 1079 -``` -Following function returns the coordinates of the actual position of the mouse in a pop-up message box: -``` -GetMouseCoordinates() -``` - -### Functions - -The different mouse functionalities are listed below. They all require a coördinate set as input to determine the mouse position where an operation needs to be executed. If no coordinates are entered, the operation is executed at the actual pointer position. - -There are three functions to perform a click on a desired location on the screen. - -Left click: -``` -ClickOnPosition(x, y) -``` -Double click: -``` -DoubleClickOnPosition(x, y) -``` -Right click: -``` -RightClickOnPosition(x, y) -``` -Moving the pointer to a certain location. This can be done to a position determined by a absolute coördinate pair or relative to the current mouse position: -``` -#Move to absolute coordinates -MoveToPosition(x, y) - -#Move relative to current position -MoveRelative(x, y) -``` -To move the mouse from its current position to a specified position while holding a button, e.g. to drag an object across the screen, following function can be used: -``` -DragToPosition(x, y, button="left") -``` -The third argument specifies which mouse button needs to be held down. This can be a string: "left", "middle" or "right". Following example moves the mouse to the position of the "chrome" icon and drags it to a different location. -``` -MoveToPosition(180, 240) # Move mouse to chrome icon -DragToPosition(x, y, "left") # Drag to new position -``` -![Imgur](https://i.imgur.com/LDoBMrZ.gif) - -## Keyboard - -To press and release a certain key on the keyboard you can use following function: -``` -PressKey(key="Keyname") -``` -The argument should be a string. Following list contains every possible keyname. : -``` -['\t', '\n', '\r', ' ', '!', '"', '#', '$', '%', '&', "'", '(', -')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', -'8', '9', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', -'a', 'b', 'c', 'd', 'e','f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', -'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', -'accept', 'add', 'alt', 'altleft', 'altright', 'apps', 'backspace', -'browserback', 'browserfavorites', 'browserforward', 'browserhome', -'browserrefresh', 'browsersearch', 'browserstop', 'capslock', 'clear', -'convert', 'ctrl', 'ctrlleft', 'ctrlright', 'decimal', 'del', 'delete', -'divide', 'down', 'end', 'enter', 'esc', 'escape', 'execute', 'f1', 'f10', -'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f2', 'f20', -'f21', 'f22', 'f23', 'f24', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', -'final', 'fn', 'hanguel', 'hangul', 'hanja', 'help', 'home', 'insert', 'junja', -'kana', 'kanji', 'launchapp1', 'launchapp2', 'launchmail', -'launchmediaselect', 'left', 'modechange', 'multiply', 'nexttrack', -'nonconvert', 'num0', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', -'num7', 'num8', 'num9', 'numlock', 'pagedown', 'pageup', 'pause', 'pgdn', -'pgup', 'playpause', 'prevtrack', 'print', 'printscreen', 'prntscrn', -'prtsc', 'prtscr', 'return', 'right', 'scrolllock', 'select', 'separator', -'shift', 'shiftleft', 'shiftright', 'sleep', 'space', 'stop', 'subtract', 'tab', -'up', 'volumedown', 'volumemute', 'volumeup', 'win', 'winleft', 'winright', 'yen', -'command', 'option', 'optionleft', 'optionright'] -``` -A hotkey combination of two or three keys can be executed with next function: -``` -PressHotkey(first_key,second_key,third_key=None) -``` -The arguments are the keys that need to be pressed. If only two keys should be pressed, the third argument can be omitted. Next example opens the task manager with the key combination "Ctrl+Shift+Esc": -``` -PressHotkey("ctrl","shift","esc") -``` -Text can be typed in the selected field using the function: -``` -Type(text, interval_seconds=0.001) -``` -The first argument is the text entered as a string, while variable is the time between key strokes. Pay attention that you can only press single character keys. Keys like ":", "F1",... can not be part of the first argument. Following example types "automagica.io/" in the selected field (in this case is that the chrome search bar) and presses enter: -``` -Type("automagica.io/", interval_seconds=0.01) -PressKey("enter") -``` -![Imgur](https://i.imgur.com/ibeLf7f.gif) - -Frequently used keys can also be pressed with a key-specific functions. In what follows, the available functions are listed. - -``` -Capslock() -Numlock() -Enter() -SpaceBar() -Backspace() -Delete() -Endkey() -Tab() -``` - -# Browser Automation - -Out-of-the box Automagica uses Chrome as automated browser. The following sections will explain how to find, read and manipulate web elements. - -## Basic functions - -To open a browser choose 'Open Chrome browser' from menu or type the command: -``` -browser = ChromeBrowser() -``` - -The browser function will wait until the page has fully loaded (that is, the “onload” event has fired) before continuing in the Automagica script. It’s worth noting that if your page uses a lot of AJAX on load then the browser function may not know when it has completely loaded. - -Browse to a website by clicking 'Browse to URL' in the menu or use the command: -``` -browser.get('https://mywebsite.com/') -``` - -Closing the browser can be done by: -``` -browser.close() -``` - -To move backward and forward in your browser’s history: -``` -browser.forward() -browser.back() -``` - -To click on an element: -``` -element.click() -``` - -To enter text into a text field: -``` -element.send_keys("some text") -``` - -To clear an element: -``` -element.clear() -``` - - -An optional check to see if you are on the correct website is to check the title. For example if you are surfing to https://www.google.com, you might want to check if "Google" is in the title to make sure the bot surfed to the correct page. -``` -browser = ChromeBrowser() -browser.get('https://google.com/') -if not "Google" in browser.title: - errorbox("Site is not correct") -``` - -## Navigating - -To navigate and perform actions in the browser it is crucial to locate elements. Elements can be everything in the html files of a website like text, titles, buttons, text fields, tables, etc... - -### Quick start - -There are two methods to finding elements, *find_element* to find a single element and *find_elements* to find multiple. -Arguably the easiest way to find a certain element is by copying it's XPath. - -To do this in Chrome right click on the element you want to find, in the example below this is the "Google Search" button on Google.com. Click *inspect element* and a side tab with the html code opens with the element you selected highlighted in blue. - -![Imgur](https://i.imgur.com/A2xdvUP.png) - -In the html code, right click the highlighted block and select *Copy* -> *Copy XPath*. - -![Imgur](https://i.imgur.com/WRD46Xi.png) - -You can now use the absolute XPath to manipulate the element. However this is a fast method for prototyping, we do not recommend using absolute paths in production environments. Slight changes in the html code would cause the absolute path to change and to likely cause errors. A more in-depth overview in the next section. - -### Selecting elements - -#### Selection by name - -Use this when you know name attribute of an element. With this strategy, the first element with the name attribute value matching the location will be returned. If no element has a matching name attribute, a NoSuchElementException will be raised. - -For instance, consider these elements on a webpage: - - - -
- - - - -
- - - -  - -The corresponding html code would be: - - - -
- - - - -
- - - -The username and password field can be found by: - -``` -username = browser.find_element_by_name('username') -password = browser.find_element_by_name('password') -``` - -To fill in the fields: - -``` -username.send_keys("Automagica_User1") -password.send_keys("thisismypassword123") -``` - -To find and click on the login button: - -``` -login = browser.find_element_by_name('loginbutton') -login.click() -``` - -**Side note** - -In case of double naming, finding by name always finds the first element. Imagine the following html code: - - - -
- - - -
- - - -The following command will find the first element with the name "continue" and thus selecting the Login button: - -``` -continue = browser.find_element_by_name('continue') -``` - -#### Selection by Id - -You can select elements by Id when this is known. This is a robust method, yet generally nog every element had a known id tag. Consider the html code below: - - - -
- - -
- - - -In this case the form has an id "loginForm". Hence the form can be selected with the Id by: - -``` -loginform = browser.find_element_by_id('loginForm') -``` - -### Selection by Xpath - -XPath (XML Path Language) is a query language for selecting nodes from an XML document. Since HTML can be an implementation of XML (referred to as XHTML), this language can be used to find and manipulate target elements in web applications. - -The advantage of using XPath is the possibility to reach every element within an HTML structure. See [Quick start](#quick-start) for a visual introduction on how to find and use an element with XPath. -The disadvantage of using a full XPath is that it is not very robust. Even the slightest changes in a HTML page would cause absolute XPaths to change, which in result will likely cause your robot unable to find the correct elements. Note that this is different from using an element name or id, as elements will still be able to be found with changes in the HTML page as long as the name or id remains the same. - -Therefore, when working with Xpath the robustness can be increased by finding a nearby element with an id or name attribute (ideally a parent element), so you can locate your target element based on the relationship. - -Consider the following structure on a HTML page: - - - -
- - - - -
- - - -  - -With the following source code: - - - -
- - - - -
- - - - -**Selecting the username:** - -1. Absolute path (note that this would break if the HTML was changed only slightly) -2. Point to the first element in the form -3. First input element with attribute named ‘name’ and the value username -``` -username = browser.find_element_by_xpath("//form[input/@name='username']") -username = browser.find_element_by_xpath("//form[@id='loginForm']/input[1]") -username = browser.find_element_by_xpath("//input[@name='username']") -``` - -**The "clear" button can be located by:** - -1. Fourth input element of the form element with attribute named id and value loginForm -2. Input with attribute named name and the value continue and attribute named type and the value button -``` -clear_button = browser.find_element_by_xpath("//form[@id='loginForm']/input[4]") -clear_button = browser.find_element_by_xpath("//input[@name='continue'][@type='button']") -``` - -**The form can be selected by:** - -1. Absolute path (note that this would break if the HTML was changed only slightly): -2. First form element in the HTML -3. The form element with attribute named id and the value loginForm -``` -login_form = browser.find_element_by_xpath("/html/body/form[1]") -login_form = browser.find_element_by_xpath("//form[1]") -login_form = browser.find_element_by_xpath("//form[@id='loginForm']") -``` - -### Browsing Example - -The following example browses to Google, searches for Automagica, opens the first Google Search result link - -``` -# Open Chrome -browser = ChromeBrowser() - -# Browse to Google -browser.get('https://google.com') - -# Enter Search Text -browser.find_element_by_xpath('//*[@id="lst-ib"]').send_keys('automagica') - -# Submit -browser.find_element_by_xpath('//*[@id="lst-ib"]').submit() - -# Click the first link -browser.find_elements_by_class_name('r')[0].click() -``` -# Process Activities - -## Entering Pathnames - -In many of the following functions, pathnames are required as input arguments. It is important that these are entered in the correct manner to prevent malfunction of the desired operations. The pathname specifies the directories in which a file, folder, executable,... is located. An example of such a pathname is: "C:\\Users\\Bob\\Desktop\\Automagica.pptx". A pathname needs to be a string when entered in a function. Because of this, every backslash needs to be doubled in the input. The next snippet of code illustrates how a pathname needs to be entered in a function. -``` -# Pathname: -C:\Users\Bob\Desktop\Automagica.pptx - -# As a string: -"C:\\Users\\Bob\\Desktop\\Automagica.pptx" - -# In a function: -Openfile("C:\\Users\\Bob\\Desktop\\Automagica.pptx") -``` -In Windows Explorer, a path can be determined by pressing shift + right click on a file, folder,... A menu pops up, where you can select "copy as path" (see image). This copies te path as a string to the clipboard, e.g. "C:\Program Files (x86)\Dropbox\Client\Dropbox.exe". This path still needs all its backslashes doubled for it to be in correct form for a function input: "C:\\\Program Files (x86)\\\Dropbox\\\Client\\\Dropbox.exe". - -![Imgur](https://i.imgur.com/9xI2mbk.png?2) - -## Standard Windows Applications - -Windows has an couple of standard applications which can be opened with functions from Automagica. Following list sums up all the available functions. If the program you want to open is in this list, it is recommended to use one of these function instead of the more general functions described in next subsection. - -Open Windows Calculator: - -``` -OpenCalculator() -``` -Open MS Paint: -``` -OpenPaint() -``` -Open Notepad: -``` -OpenNotepad() -``` -Open Windows Snipping Tool: -``` -OpenSnippingTool() -``` -Open Windows Control Panel: -``` -OpenControlPanel() -``` -Open Windows Clean Manager: -``` -OpenCleanManager() -``` -Open Windows Dialer: -``` -OpenDialer() -``` -Open Windows Volume Mixer: -``` -OpenVolumeMixer() -``` -Open Windows XPS Viewer: -``` -OpenXPSViewer() -``` - -## General Commands - -The above functions are all program specific. It is possible to run a program or shut it down if the exact path is known. Following function can open an executable located at a specified path: -``` -#Start Process -LaunchProcess(process_executable=\"pathname\") -``` -Following example explains the usage of the function. The code will open Dropbox. -``` -LaunchProcess("C:\\Program Files (x86)\\Dropbox\\Client\\Dropbox.exe") -``` -A (slow) alternative is to use: -``` -OpenProgramByName(name, main_drive = "C:\\") -``` -This function does not require a full path as input in the first variable. Returning to the example above, Dropbox can aswell be opened in the following way: -``` -OpenProgramByName("Dropbox") -``` -## Running Programs - -Automagica can check wether a program is currently active on your computer. This can be done with a general function that requires the process name and returns True if the specified program is active: -``` -ProcessRunning(name="program_name") -``` -Next to that there are a couple of functions that are program specific who return True if that program is currently running. Those are listed below: -``` -ChromeRunning() -WordRunning() -ExcelRunning() -PowerpointRunning() -DropboxRunning() -FirefoxRunning() -TeamviewerRunning() -SkypeRunning() -EdgeRunning() -OnedriveRunning() -IllustratorRunning() -``` -Finally, a list of every active program can be displayed as follows: -``` -ListRunningProcesses() -``` - -# Monitoring - -Following list of functions can be used to return information about the current status of your CPU, disk, memory etc. -``` -CPULoad(measure_time=1) -``` -Returns average CPU load for all cores. Measures once every second, adjust measure_time (seconds) to get a longer averaged measured time. Standard measure_time is 1 second. -``` -NumberOfCPU(logical=True) -``` -Returns the number of CPU's in the current system. The parameter 'logical' determines if only logical units are added to the count, default value is True. -``` -CPUFreq() -``` -Returns frequency at which CPU currently operates. Also shows minimum and maximum frequency. -``` -CPUStats() -``` -Returns CPU statistics: Number of CTX switches, interrupts, soft-interrupts and systemcalls. -``` -MemoryStats(mem_type='swap') -``` -Returns memory statistics: total, used, free and percentage in use. Choose mem_type = 'virtual' for virtual memory, and mem_type = 'swap' for swap memory (standard). -``` -DiskStats() -``` -Returns disk statistics of main disk: total, used, free and percentage in use. -``` -DiskPartitions() -``` -Returns tuple with info for every partition. -``` -BootTime() -``` -Returns time PC was booted in seconds after the epoch. -``` -TimeSinceLastBoot() -``` -Returns time since last boot in seconds. - -# Office Automation - -A lot of automation processes involve Microsoft Office. Automagica packs some useful functions to make automating office as easy as possible. - -## Word - -To open a Word document: -``` -document = OpenWordDocument('example.docx') -``` - -Replace words in a Word document. This can be particularly useful when using templates for forms. Make sure the template contains unique placeholder variables so that automated filling doesn't cause ambiguities. - -``` -document = ReplaceTextInDocument(document, text='[placeholder]', replace_with='My text') -``` - -Converting a Word document to PDF: -``` -ConvertWordToPDF(word_filename='C:\\document.docx', pdf_filename='C:\\document.pdf') -``` - -## Excel - -### Reading And Writing - -Automation in Excel most of the time requires reading and writing cells. In Automagica, this is very easy. - -There are two functions for reading a cell. -``` -#Using cell value -ExcelReadCell(path="\pathname\", cell="A1", sheet=None) -``` -Read a cell from an Excel file and return its value. Make sure you enter a valid path e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". The cell you want to read needs to be defined by a cell name e.g. "A2". The third variable is a string with the name of the sheet that needs to be read. If omitted, the function reads the entered cell of the current active sheet. -``` -#Using row column -ExcelReadRowCol(path="\pathname\", r=1, c=1, sheet=None) -``` -Read a Cell from an Excel file and return its value. Make sure you enter a valid path e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". The cell you want to read needs to be row and a column. E.g. r = 2 and c = 3 refers to cell C3. The third variable is string with the name of the sheet that needs to be read. If omitted, the function reads the entered cell of the active sheet. First row is defined row number 1 and first column is defined column number 1 - -Similar to reading a cell, there are two functions for writing a value to a cell. -``` -#Using cell value -ExcelWriteCell(path="\pathname\", sheet=None, cell="A1", write_value="Value") -``` -Write a Cell to an Excel file. Make sure you enter a valid path e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". The cell should be defined by a cell name. E.g. "B6". Value can be anything, standard is "Value". When executing the code, make sure .xlsx file you want to write is closed. -``` -#Using row and column -ExcelWriteCell("C:\\Users\Bob\\Desktop\\RPA Examples\\data.xlsx",1,1,value="Robot") -``` -Read a Cell from an Excel file and return its value. Make sure you enter a valid path e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". The cell you want to read needs to be row and a column. E.g. r = 2 and c = 3 refers to cell C3. The third variable needs to be a string with the name of the sheet that needs to be read. If omitted, the function reads the entered cell of the active sheet. First row is defined row number 1 and first column is defined column number 1. - -### Basic Operations - -Next to reading and writing, Automagica offers some basic operations for .xlsx files. These are listed below. -``` -ExcelCreateWorkbook(path=\"pathname\") -``` -Create a new .xlsx file and save it under a specified path. If the entered path already exists, the function does nothing. -``` -ExcelOpenWorkbook(path=\"pathname\") -``` -Open a .xlsx file with Microsoft Excel. Make sure you enter a valid path. This can be a path referencing an existing .xlsx file e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". This will open the existing file. You can also enter a completely new path. In this case, the function creates a new .xlsx file with that path and opens it with Excel. -``` -ExcelSaveExistingWorkbook(path=\"pathname\", new_path=None) -``` -Save (as) an existing .xlsx file. The second variable is the new path the file needs to be saved at. You can ignore this variable if you just want to save the file and do not want to "save as". For the function to work properly, it is important that the file you want to save is not opened. -``` -ExcelCreateWorkSheet(path=\"pathname\", sheet_name=None) -``` -Create a new worksheet with a specified name in an existing workbook specified by the path variable. If no sheet_name is entered, the new sheet is named "sheet1", "sheet2", "sheet3", ..., depending on the sheets that already exist. Make shure you enter a valid path referencing a .xlsx file e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". For the function to work properly, it is important that the .xlsx file is closed during the execution. -``` -ExcelGetSheets(path=\"pathname\") -``` -Return a list containing the sheet names of an Excel file. Make shure you enter a valid path referencing a .xlsx file e.g. "C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". -``` -ExcelPutRowInList(path=\"pathname\", start_cell=\"B3\", end_cell=\"E8\", sheet=None) -``` -Put the elements of a specified row in a list. The .xlsx file and sheet that needs to be read are specified by respectively the path- and sheet variable. If no sheet is specified, the sheet-variable is set to the current active sheet. Also make shure to enter a valid path e.g. -"C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". The row is specified by strings referring to the first and final cell. E.g. the row in the image below is defined by start_cell = "C4" and end_cell = "G4". Calling the function with these two cells returns a list: [8,"RPA",None,19,"Automagica]. For the function to work, the two cells need to be of the same row and start_cell needs to be the cell at the left hand side. - -![Imgur](https://i.imgur.com/S4xJWBh.png) - -``` -ExcelPutColumnInList(path=\"pathname\", start_cell=\"A3\", end_cell=\"A8\", sheet=None) -``` -Put the elements of a specified column in a list. The .xlsx file and sheet that needs to be read are specified by respectively the path- and sheet variable. If no sheet is specified, the sheet-variable is set to the current active sheet. Also make shure to enter a valid path e.g. -"C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". The column is specified by strings referring to the first and final cell. E.g. the region in the image below is defined by start_cell = "C4" and end_cell = "C7". Calling the function returns with this two cells returns a list: [8, "RPA", 19, "Automagica"]. For the function to work, the two entered cells need to be of the same column and start_cell needs to be the upper cell. - -![Imgur](https://i.imgur.com/XOft1RL.png) - -``` -ExcelPutSelectionInMatrix(path=\"pathname\", upper_left_cell=\"B2\", bottom_right_cell=\"C3\", sheet=None) -``` -Put the elements of a specified selection in a matrix. The .xlsx file and sheet that needs to be read are specified by respectively the path- and sheet variable. If no sheet is specified, the sheet-variable is set to the current active sheet. Also make shure to enter a valid path e.g. -"C:\\Users\\Bob\\Desktop\\RPA Examples\\data.xlsx". The selection is specified by strings referring to the upper left and bottom right cell. E.g. in the image below, the region is defined by upper_left_cell = "C4" and bottom_right_cell = "E6". The function will return a matrix with values: [[8,"Automagica",12],["RPA",15,None],[19,None,55]. If a cell is empty, its value is set to "None". - -![Imgur](https://i.imgur.com/fUfHd0M.png) - -# PDF Manipulation - -## Merge PDF Files -``` -MergePDF(pdf1=\"pathname\", pdf2=\"pathname\", merged_pdf=\"pathname\") -``` -This function can merge two existing PDF files. The first two arguments are the PDF's that need to be merged, entered as a path. The pages from pdf2 are added to pdf2. The merged PDF receives a new path specefied by the third argument. - -## Extract Text From PDF - -``` -ExtractTextFromPDFPage(path=\"pathname\", page=1) -``` - -This function extracts all the text from a given page and returns it as a string. The pdf needs to be entered as a path. Pay attention that the entered page needs to be greater than 0. - -# File and folder manipulations - -In many automation processes it is useful to control the stored files and directories. Automagica has some functions to make the manipulation of files and folders as easy as possible. - -## File Manipulation - -In the following sections the functions that Automagica offers for manipulating files are described. The arguments for this functions mostly consist of a path. In this path, it is important to always use the full file-name in a path. E.g. if a png-file named "Automagica" needs manipulation, a possible path could be: "C:\\Users\\Bob\\Desktop\\Automagica.png". For the functions to work, .png needs to be included in the name. - -### Open A File - -To open a file, Automagica offers following function: -``` -OpenFile(path=\"pathname\") -``` -An example path can be "C:\\Users\\Bob\\Desktop\\Automagica.xlsx". -### Renaming Files - -A file can be renamed with the following code: -``` -RenameFile(path=\"pathname\", new_name) -``` -The first argument is the path of the file that needs its name changed. The second variable is just the name that the file has to receive, so this does not need to be a full path. E.g. next line of code changes the name of a file named "Automagica.pptx" to "Automagica123.pptx": -``` -RenameFile("C:\\Users\\Bob\\Desktop\\Automagica.pptx", "Automagica123.pptx") -``` -Note that it is not possible to change change the file-type: if the path in the first argument ends in ".pptx", the new name also needs to end in ".pptx". - -### Moving Files - -The following function can be used to move a file from one to an other directory: -``` -MoveFile(old_path=\"old_pathname\", new_location=\"new_location_path\") -``` -The first variable contains the path of the file that should be moved (this includes the name of the file). The the second argument contains the path of the location that the file needs to be moved to (in this path, the file name should be omitted). If one of the two arguments contain a non-existing path, the function will return nothing. As an example, next piece of code moves the file "Automagica.txt" from C:\\Users\\Bob\\Desktop\\ to C:\\Users\\Bob\\Downloads\\: -``` -MoveFile("C:\\Users\\Bob\\Desktop\\Automagica.txt", "C:\\Users\\Bob\\Downloads") -``` -If the target location already contains a folder with exactly the same name as the folder that needs to be moved, a random uid of eight characters will be added to the name. E.g., if in the previous example the location C:\\Users\\Bob\\Downloads already contains a file named "Automagica.txt" and the code is executed, it will move the folder "Automagica" from C:\\Users\\Bob\\Desktop to C:\\Users\\Bob\\Downloads and change its name to "(be8e4c88) Automagica.txt". Note that the added characters are completely random. -As a final note for the function to work optimal, it is important that the file that needs to be moved is closed. -### Copying Files - -If a file needs to be copied from one to an other directory, the following function can be used: -``` -MoveFile(old_path=\"old_pathname\", new_location=\"new_location_path\") -``` -The inputs work in exactly the same way as in the MoveFile function and the copied file needs to be closed for the function to work properly. Also keep in mind that if the new location already contains a file with exactly the same name as the copy,it will be overwritten by the copied file. - -### Removing Files - -Following function is used to delete a file from a folder: -``` -RemoveFile(path=\"pathname\") -``` -It will delete a file with a given pathname. With this code it is again important that the file that needs to be removed is closed. -### Check If A File Exists - -Next function returns True if the path of a certain file exists and False if the path does not exist or refers to a folder instead of a file. -``` -FileExists(path=\"pathname\") -``` -### Wait For A File - -Following function waits until a file with the entered path is created. -``` -WaitForFile(path=\"pathname\") -``` - -### Writing To And From Files - -It is possible to write a list to a .txt file or to write a .txt file to a list. This can be done with following functions. -``` -WriteListToFile(list_to_write, file) -``` -This function writes a list to a .txt file. Every element of the entered list is written on a new line in the text file. The .txt file is entered with a path. If the path does not exist yet, the function will create a new .txt file at the specified path and write it. If the path does exist, the function writes the list in the existing file. -``` -WriteFileToList(file) -``` -This function writes the content of a entered .txt file to a list and returns that list. Every new line from the .txt file becomes a new element of the list. The function will not work if the entered path is not attached to a .txt file. - - -## Folder Manipulation -Most of the manipulations that can be done on files can be executed on folders as well. Automagica offers a selection of functions that make it easy to perform manipulations on folders. - -### Creating Folders - -To create a folder in a desired locations, the following function can be used: -``` -CreateFolder(path=\"pathname\") -``` -This function creates a folder with its name and location specified in the path. Next snippet of code illustrates this principle by creating a folder named "Automagica" at location C:\\Users\\Bob\\Desktop. -``` -CreateFolder("C:\\Users\\Bob\\Desktop\\Automagica") -``` -One note to keep in mind is that entered path needs to be unique. If there is already a folder with the same name in the same location, the function does nothing. - - -### Open A Folder - -A folder can be opened with the function: -``` -OpenFolder(path=\"pathname\") -``` - -### Renaming Folders - -Renaming a folder happens with the following function: -``` -RenameFolder(path=\"pathname\", new_name) -``` -The first variable is the path of the folder that needs to be renamed. The second variable is the new name that the folder has to receive. Next example of code changes the name of a folder from "Automagica" to "Automagica123". The folder is located at C:\\Users\\Bob\\Desktop. -``` -RenameFolder("C:\\Users\\Bob\\Desktop\\Automagica", "Automagica123") -``` -The code will return nothing if the new path already exists. - -### Moving Folders - -It is possible to move a folder from one to an other location using next function: -``` -MoveFolder(old_path=\"pathname\", new_location=\"pathname\") -``` -The first variable contains the path of the folder that should be moved (this includes the name of the folder). The the second argument contains the path of the location that the folder needs to be moved to (in this path, the name of the moved folder should be omitted). If one of the two arguments contain a non-existing path, the function will return nothing. As an example, next piece of code moves the folder "Automagica" from C:\\Users\\Bob\\Desktop\\ to C:\\Users\\Bob\\Downloads\\: -``` -MoveFolder("C:\\Users\\Bob\\Desktop\\Automagica", "C:\\Users\\Bob\\Downloads") -``` -If the target location already contains a folder with exactly the same name as the folder that needs to be moved, a random uid of eight characters will be added to the name. E.g. if in the previous example the location C:\\Users\\Bob\\Downloads already contains a folder named "Automagica" and the code is executed, it will move the folder "Automagica" from C:\\Users\\Bob\\Desktop to C:\\Users\\Bob\\Downloads and change its name to "Automagica (be8e3c88)". Note that the added characters are completely random. -As a final note for the function to work optimal, it is important that all files in a moved folder are closed. - -### Copying Folders - -A folder can be copied from one to an other location. The difference with the moving of folders is that in this case the copied folder also remains in the original location. The principle of the inputs is completely analogous to the moving of a folder. E.g. next code would copy a folder named "Automagica" from C:\\Users\\Bob\\Desktop\\ to C:\\Users\\Bob\\Downloads\\. -``` -CopyFolder("C:\\Users\\Bob\\Desktop\\Automagica", "C:\\Users\\Bob\\Downloads\\") -``` -If the target location already has a folder with the same name, the function will add a random uid of eight characters to the name of the copied folder. This works in exactly the same way as in MoveFolder function. Next to that, for the code to work properly, all files of the copied folder need to be closed. - -### Removing Folders - -Next function can delete a folder together with all its contents (files, read-only files, folders, ...). -``` -RemoveFolder(path=\"pathname\", allow_root=False, delete_read_only=True) -``` -The first argument should be the path of the folder that needs to be removed. The safety variable "allow_root" makes sure that the first argument is longer than 10 characters. This safety prevents entering for example "\\" as a path resulting in deleting the root and all of its subdirectories. To turn off this safety, explicitly set allow_root to True. The third argument makes it possible to make sure the function does not delete a folder if it contains read-only files. When "delete_read_only" is explicitly set to False, the function will not delete folders with read-only files. A final requirement for the code to work optimal is that all the files in the folder need to be closed. Next examples illustrate the usage of the function. -Next line of code removes the folder with C:\\Users\\Bob\\Desktop\\Automagica as path. Also read only files will be removed, because the variable delete_read_only is True unless explicitly entered otherwise. Finally notice that the code would not do anything if the path was less than 10 characters long. - -``` -RemoveFolder("C:\\Users\\Bob\\Desktop\\Automagica") -``` -The following example deletes the folder at a given path unless it contains read only files. The safety variable remains False, so the path should be longer than 10 characters. -``` -RemoveFolder("C:\\Users\\Bob\\Desktop\\Automagica", delete_read_only=False) -``` - -### Empty A Folder - -Alle the contents of folder can be deleted using the following function: -``` -EmptyFolder(path=\"pathname\", allow_root=False) -``` -The first argument specifies again the path of the folder that needs to be emptied. The allow_root safety-variable has the same functionality as in the function for removing a folder. The following line of code gives an example for how a folder with a path C:\\Users\\Bob\\Desktop\\Automagica can be emptied: -``` -"EmptyFolder("C:\\Users\\Bob\\Desktop\\Automagica") -``` -For the function to work, it is important that all the files that the folder contain are closed. - -### Check If A Folder Exists - -Next function can check if a specified path exists. -``` -FolderExists(path=\"pathname\") -``` -If the entered path does not exist, the function will return False. If it does exist, True will be returned. E.g. next snippet checks if the folder with a path C:\\Users\\Bob\\Desktop\\Automagica exists: -``` -FolderExists("C:\\Users\\Bob\\Desktop\\Automagica") -``` - -### Zip Folder - -Following function can be used to create a zipped folder of an existing directory: -``` -ZipFolder(folder_path=\"pathname_folder\", new_path=\"pathname_compressed_folder\") -``` -The first argument is the pathname of the directory that needs to be compressed. The second argument specifies the location and name of the zipped folder with a pathname. E.g. the following function zips the directory with pathname "C:\\Users\\Bob\\Desktop\\Automagica". The zipped directory is specified by the second argument. -``` -ZipFolder("C:\\Users\\Bob\\Desktop\\Automagica","C:\\Users\\Bob\\Downloads\\Automagica") -``` -Pay attention, because if there already exists a zipped directory with new_path as pathname, it will be overwritten. - -### Unzip Folder - -The opposite of the ZipFolder function can be achieved with: -``` -UnZipFolder(path=\"pathname_zipped_folder\", new_path=\"pathname_target_location\") -``` -The first argument is the pathname of compressed folder that needs to be unzipped. The second argument is optional. It is the path of the directory where the unzipped folder will be stored. If omitted, the unzipped folder is stored in the same location as the original zipped folder. - -### Wait For A Folder - -Following function waits until a folder with the entered path is created. -``` -WaitForFolder(path=\"pathname\") -``` - -# Image Operations - -Images can be manipulated in many ways with Automagica. The available functions are listed below. -``` -OpenImage(path=\"pathname\") -``` -Displays an image specified by the path variable on the default imaging program. -``` -RotateImage(path=\"pathname\", angle) -``` -Rotate an image over a specified angle. E.g. Entering "C:\\Users\\Pictures\\Automagica.jpg" as path and an a angle of 90 rotates the picture with the given path over 90 degrees. Pay attention, because angles other than 90, 180, 270, 360 can deform the picture. -``` -ResizeImage(path=\"pathname\", size=(1024, 768)) -``` -Resizes the image specified by the path variable. The size is specified by the second argument. This is a tuple with the width and height in pixels. E.g. ResizeImage("C:\\Users\\Pictures\\Automagica.jpg", (300, 400)) gives the image a width of 300 pixels and a height of 400 pixels. -``` -ImageSize(path=\"pathname\") -``` -Returns the size in pixels of an image specified by a path. The size is returned in a message box of the form: "(height, width) -``` -CropImage(path=\"pathname\",box=None) -``` -Crops the image specified by path to a region determined by the box variable. This variable is a 4 tuple who defines the left, upper, right and lower pixel coördinate e.g.: (left, upper, right, lower). -``` -ImageFormat(path=\"pathname\") -``` -Returns the format of an image specified by the input path. E.g. entering "C:\\Users\\Pictures\\Automagica.jpg" returns a message box saying JPEG. -``` -MirrorImageHorizontally(path=\"pathname\") -``` -Mirrors an image with a given path from left to right. -``` -MirrorImageVertically(path=\"pathname\") -``` -Mirrors an image with a given path from top to bottom. - -# Email Operations - -Automagica makes it possible to send an email with your Hotmail, Gmail or Yahoo mail address. The input for the three functions works in the same way. The first and second arguments are respectively your email address and user password. The destination variable is the email address you want to contact. The subject and message variable contain respectively the subject and the text message. The port variable is standard 587. In most cases this argument can be ignored, but in some cases it needs to be changed to 465. When using a Gmail account, there is one exception. Google has a safety feature that blocks lessecure apps. For this function to work properly, this needs to be turned off, which can be done at the following link: https://myaccount.google.com/lesssecureapps. - -``` -SendMailWithHotmail(user="user@hotmail.com", password, destination, subject="", message="", port=587) -SendMailWithGmail(user="user@gmail.com", password, destination, subject="", message="", port=587) -SendMailWithYahoo(user="user@yahoo.com", password, destination, subject="", message="", port=587) -``` - -# Basic Operations - -## Variables and Types - -Variables are used to store information to be referenced and manipulated in an automation script. They also provide a way of labeling data with a descriptive name, so the automation script can be understood more clearly by the reader. It is helpful to think of variables as containers that hold information. Variables come in a great variety of types. Automagica supports all variable types from the Python language, but down here are some of the most prominent. - -### Strings - -A string is any finite sequence of characters (i.e., letters, numerals, symbols and punctuation marks). -Strings are defined either with a single quote or a double quotes. - -``` -automagica_string = "robots" -DisplayMessageBox(automagica_string) -``` - -#### String manipulation - -##### Adding variables to a string - -You can add all variables to a string. If you want, for example, to add an integer to a string you can do so by defining the integer as a string: - -``` -automagica_string = "robot number " -automagica_integer = 100 - -automagica_string2 = automagica_string + int(100) -DisplayMessageBox(automagica_string2) -``` - -##### Slicing strings - -Adding **[n]** to a string will select the nth character: -``` -x = "automagica" -x[2] ->>> t -``` - -Adding **[n:p]** will slice the string from character n to p. By leaving n or p out it will select the first and last character respectively: -``` -x = "Hello Robot!" -x[:5] ->>> Hello -``` -##### String replacing -``` -x = "Robots are evil!" -x.replace('evil', 'friendly') ->>>Robots are friendly! -``` - -##### Upper and lower cases in strings -``` -x = "Robots" -#Convert to upper case -x.upper() -#Convert to lower case -x.lower() -#Capitalize -x.capitalize() -``` - -##### Splitting strings - -You can choose to split a string at a certain word or character. Don't forget to indicate if you want to keep the first or second part of the string by adding [0] or [1] as splitting causes your string to turn in to a list of multiple strings: -``` -x = "Robots will take over the world!" -x.split(" over ") ->>>['Robots will take', 'the world!'] -#accesing the different strings can be done by: -x[0] ->>>Robots will take -x[1] ->>>the world!" -``` - -### Numbers - -#### Integers - -An integer (of int in short) is a whole number, not a fractional number, that can be positive, negative, or zero. - -To declare and display an integer: -``` -automagica_integer = 5 -DisplayMessageBox(automagica_integer) -``` - -You can do basic math manipulations with integers: - -``` -automagica_int1 = 5 -automagica_int2 = 10 - -automagica_int3 = automagica_int1 + automagica_int2 = 15 -DisplayMessageBox(automagica_int3) -``` - -#### Floats - -Floats represent real numbers and are written with a decimal point dividing the integer and fractional parts. -``` -automagica_float = 3.1 -DisplayMessageBox(automagica_float) -``` - -### Math operations - -Down here is a list with basic math operations that can be used with both integers and floats. Before they can be used, the math module needs to be imported: - -``` -from math import * -``` - - -**abs(x)** : The absolute value of x (the (positive) distance between x and zero) -``` -x = -3 -abs(x) ->>> 3 -``` -**ceil(x)** : The ceiling of x (the smallest integer not less than x) -``` -x = 4.1 -ceil(x) ->>> 5 -``` -**exp(x)** : The exponential of x: ex -``` -x = 3 -exp(x) ->>> 20.085536923187668 -``` -**floor(x)** : The floor of x: the largest integer not greater than x -``` -x = 4.1 -floor(x) ->>> 4 -``` -**log(x)** : The natural logarithm of x, for x> 0 -``` -x = 10 -log(x) ->>> 2.302585092994046 -``` -**max(x1, x2,...)** and **max(x1, x2,...)** : The smallest and largest of its arguments: the value closest to positive infinity -``` -x1 = 2 -x2 = 3 -max(x1,x2) ->>> 3 -``` -**round(x)** : x rounded to n digits from the decimal point. -``` -x = 0.5555 -round(x, 2) ->>> 0.56 -``` -**sqrt(x)** : The square root of x for x > 0 -``` -x = 9 -sqrt(9) ->>> 3 -``` - -## Lists - -Lists are very similar to arrays. They can contain any type of variable, and they can contain as many variables as you wish. Lists can also be iterated over in a very simple manner. Down here some examples of list usage: - -``` -list = ["R2-D2", "Terminator", "Optimus Prime","WALL-E", "RoboCop"] -list.append("WALL-E") -list.append("RoboCop") ->>>["R2-D2", "Terminator", "Optimus Prime","WALL-E", "RoboCop"] -list[0] ->>>R2-D2 -``` - -## Logic operations - -### If statement - -An *if statement* is used for decision making. It will run the body of code only when if statement is true. -The conditional block of code has to be intended. - -if condition : - indentedStatementBlock - - - -An example would be: - -``` -temperature = RequestUserInput() -if temperature > 20: - DisplayMessageBox("Wear short pants!") -``` - -Expanding this example to multiple if statements: - -``` -temperature = RequestUserInput() -if temperature < 10: - DisplayMessageBox("Wear a warm hat!") -if temperature > 20: - DisplayMessageBox("Wear short pants!") -else: - DisplayMessageBox("You can wear normal clothes!") -``` -The previous example will output the string *"Wear a warm hat!"* if the inputnumber was lower than 10. If the number was higher than 20, the output will be *Wear short pants!*. If the condition was still not met, which means the input number was between 10 and 20, the else statement will be activated. In that case the message will show *"You can wear normal clothes!"*. - -### While loops - -The while loop evaluates the test expression. - -If the test expression is true (nonzero), codes inside the body of while loop are executed. The test expression is evaluated again. The process goes on until the test expression is false. - -When the test expression is false, the while loop is terminated. - -![Imgur](https://i.imgur.com/rh3OUdh.jpg) - -An example of a while loop: -``` -automagica_count = 0 -while (automagica_count < 3): - display_string = "Current count is: " + str(automagica_count) - DisplayMessageBox(display_string) - count = count + 1 -``` - - -### For loops - -The initialization statement is executed only once. - -Then, the test expression is evaluated. If the test expression is false (0), for loop is terminated. But if the test expression is true (nonzero), codes inside the body of for loop is executed and the update expression is updated. - -This process repeats until the test expression is false. - -The for loop is commonly used when the number of iterations is known. - -![Imgur](https://i.imgur.com/V3p8spl.jpg) - -An example of a for loop: -``` -for x in range(0, 2): - display_string = "We are currently at number " + str(x) - DisplayMessageBox(display_string) -``` - -# Examples - -## Example 1 - -The following example opens Excel and reads a worksheet with the following layout: - -![Imgur](https://i.imgur.com/jMj2ypX.png) - -It opens Chrome and surfs to google.com where the robot enters the searchterm. It then collects all the urls from the first page and writes these urls in Excel in the correct cell. - -``` -excel_path = "Enter Path to Excel Here" #example: C:\\Users\Bob\\Desktop\\RPA Examples\\data.xlsx - -# Read information from the excel in the second row, for columns 2 to 10 -lookup_terms = [] -for col in range(2,10): - try: - lookup_terms.append(ExcelReadCell(excel_path, 2, col)) - except: - pass - -# Open Chrome -browser = ChromeBrowser() - -for j,item in enumerate(lookup_terms): - - # Browse to Google - browser.get('https://google.com') - # Lookup the searchterm - browser.find_element_by_xpath('//*[@id="lst-ib"]').send_keys(item) - # Search - browser.find_element_by_xpath('//*[@id="lst-ib"]').submit() - # Get all found items - articles = browser.find_elements_by_class_name("g") - # Parse the headertexts to find the urls - urls = [] - for article in articles: - try: - import re - urls.append(re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', article.text)[0]) - except: - pass - - # Write found urls to Excel - for i,url in enumerate(urls): - ExcelWriteCell(excel_path, row=i+2, col=j+2, write_value=url) - -# Exit the browser -browser.quit() -``` - -If you open the Excel file, the result should look something like this: - -![Imgur](https://i.imgur.com/7gSv7gc.png) - -Note that the links differ depending on your location, as google search results are location dependent. - -## Example 2 - -This example uses Automagica activities for Excel operations and file/folder manipulation. -The code reads an Excel document specified by the path "C:\\Users\\Bob\\Downloads\\USPresidents.xlsx". This file contains in the first column a list of every US president together with some background informations. To begin, all the president names are added in a list. After that, the for loop creates for every president a named folder containing a .txt file with the extra information about that president. - -``` -from automagica import * - -# Put the president names of the first column in a list. - -names = ExcelPutColumnInList("C:\\Users\\Bob\\Downloads\\USPresidents.xlsx", "A2","A45") - -# Create for every president a folder with his name and save a .txt file in that folder with his extra information. - -for name in names: - CreateFolder("C:\\Users\\Bob\\Documents\\Presidents\\" + name) - row = names.index(name) + 2 - data = ExcelPutRowInList("C:\\Users\\Bob\\Downloads\\USPresidents.xlsx", "B"+str(row), "H" + str(row)) - WriteListToFile(data, "C:\\Users\\Bob\\Documents\\Presidents\\" + name + "\\" + name + ".txt") -``` -Following gif illustrates the actions. - -![Imgur](https://i.imgur.com/YKIoR4Y.gif) - -| Icon | Name | Info | -| ------------- | ------------- | ------------- | -|**Mouse**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANPSURBVFiF7ZdBaFxVFIa/c+e9eSPTtKV1MkJKA4E62KIgXbjIRihIQ6k00UkEF0owi9q4KQHBjStBly6ShZTSLDR2oSJ20SJdTRZmFBcppAWbRJgmWiql1bTpZN7c4yI3ZabJJO+NM135w+W9d8+5//9z3rtn7qCqxBkm4U+YhD+x8Qz0uethoCcuX7xkyCFSRaQK5Nzcd8BLQAHoaqsBk/Cn9vQcLe/pOVo2CX/KGTgE3AQ+jiuuqhgiQkRy1oaDmSPHkpkjx5LWhoMiklPV34BF4FxUrjrEKP8gYAF1wwKDLvYN8GwzFRBHEBkicsEZf7dmTjQukUPkV7AdmhVvmYH/gv8NeE2uOygipxrEysCPqhpGIYq1C0TkZd/3rxpjOowxmxaurq767vZ1Vf0hEmmMPvCq53kP8vl8WCqVdHl5uW6Mjo5aY4wVEQucamkrBgaMMZWRkRG7tLRUJ1wqlXRoaCj0fT/s7+9Xz/PW4hjY8RsQkXdE5Hx3d7fJZDKMj4/XxQuFQlgsFhkYGPCy2WykqtdiRwNBkPwwnU5bsJWpqS/rYmFYlVLpVjKfz9OMeCQDIImTJ/u8Eyde25R7585fnDkzRjqdjiQmIvuBu7Wd86n2ASP8HohcF5E3RUSg+T6wE15x/E9iV+/ejucL9//52sBNETnbUgOzs7OEYegBp93YhNNdnfLirmcSn9+6nfNEPvNEJAtMAgngnKpebEa8WCzqzMyMAsOqOrlVjojo23PzVuFv4JNQdcJT1dvAcRG5BPzcjHihULALCwuhqr6hqpca5fnGXFyz9hdgQlUfgvsGROQ4cENVF7ZaODd3Y0vClZUVABYXFx+qap+qTm9ndK1afevJOWF9J1wF+lX1Xl1QZBj4IgiC+Uak1tp7lUrlPVW9tp2443t8cqq9fwH4CbgMfFDTfoeBkPV3Gvus16CljwN9wKdsnCcbJLZc3PF2Ab+y/h/CPDYAdACpdoo77iQwC0zW/RqmAqaTPvPAWLvEnYGPgLPA90DvRkd+TgR7oJMK6+f9sXaIO7FeV4Uu4NCGgff37ab8xxX0QCcVV4lUu0xsMpUKmM7uR/ftpiyCTQVMAx1Py4Akfa4Zw/1HZb4CvlXVP3faz63Ev9I70cKEH0/TAAAAAElFTkSuQmCC)|Get Mouse Coordinates | Displays message box with absolute coordinates of the mouse position | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABfVBMVEUAAABie6Jie6RjgKNhe6NVgKpifKNgfaNkeqZifKNhfaJjeqJifKNifKRggJ9jfaRggJ9jfKNifaNifqVbgKRifaJmgJljfKNje6VVcapjfKNifKNjfaQAAP9ifKNkfKJifKJhfKNkgKRifKNifKRifKNifKNifKNidp1ifKNhfaJgfaRifKNifKNhfKRjfaRhfKJhfKOAgIBje6JifKNjfaRjfKJifKRie6NifKNje6JmZpljfKNjfKNggJ9he6NmeqNifaJifKNheZ5hfKRifKNjfKNje6NifKNhe6NjfKNjfaJie6RhfqJie6JifaNifKJhe6JhfKRpeKVjfKJjfaJifKNje6JifKOAgL9ie6NlfaBifKNifaNifaFmgKZgfaRie6NifKNifKNifaJifKNifKNjfqRifKNddKJifKNifKNkfKNifKRifKNifKRifaNffKBifKNifKNhe6NifKNVVapifaRigKdqgKpifKJifKNjfKNifKMAAAAbs8LoAAAAfXRSTlMAPHgkkwbEPRfWPyzFxiCwGKO0QQ6PCsI+CW/MOwGeUslpHH270ejuDcA3Nefee2KlmAJNzVp5ZXLlfAW1UAi6GYfKFdQn3HTjOkhYcEc02ZpurRGEgdNVuQS8K+qNORQt2+SnYLf7Q/AL/thAov1t1SP0gFm9A5EaDLPgljs6ba0AAAABYktHRACIBR1IAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4gcfDwIsJrDCrAAAAUdJREFUOMtjYEAFjEwM+AEzCwEFrGzsBFRwcHIRUMHNQ0ABAy8uCT6IB7j5sUsLCAoJs4oAGaKMWOXFxCUkpaRlGBhkeWSxKpCT51BQVFJWUVVTl2YTxDREg01SU0tbR1dP38CQwcjYRA9dgamZuYWGpZU1AwOTIYhvY4vuBDt7B0cnoO3OLuLMQL6rmzWaCll3WQ9PIO2l6e0D4ov6YjjDz58BSQFjAIaCwCBkBcGcGApCQpEVMIRhKAgIR1EQEYmugJ8bRHK4REWDuaIC6Ap4YmLjgHFhBnZdvGJYArqCxFogSLJ3SpZICU1Nq61NR1eQUYsKvNHkWdHkawPRFGRmoSmwQLciG01BDrqCXFT5PA10BfmoCgowQrKwCEVBMYYChhJk+dIyTAUM5Qh5D2cs8gxl5mpQB8pVMGAHlUxV1RlsNcjRAADCI22hLSPcLAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wNy0zMVQxNTowMjo0NCswMjowMCovWKsAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMDctMzFUMTU6MDI6NDQrMDI6MDBbcuAXAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg==)|Click on Position | Clicks on a specific (x,y) pixel coordinate on the screen. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABfVBMVEUAAABie6Jie6RjgKNhe6NVgKpifKNgfaNkeqZifKNhfaJjeqJifKNifKRggJ9jfaRggJ9jfKNifaNifqVbgKRifaJmgJljfKNje6VVcapjfKNifKNjfaQAAP9ifKNkfKJifKJhfKNkgKRifKNifKRifKNifKNifKNidp1ifKNhfaJgfaRifKNifKNhfKRjfaRhfKJhfKOAgIBje6JifKNjfaRjfKJifKRie6NifKNje6JmZpljfKNjfKNggJ9he6NmeqNifaJifKNheZ5hfKRifKNjfKNje6NifKNhe6NjfKNjfaJie6RhfqJie6JifaNifKJhe6JhfKRpeKVjfKJjfaJifKNje6JifKOAgL9ie6NlfaBifKNifaNifaFmgKZgfaRie6NifKNifKNifaJifKNifKNjfqRifKNddKJifKNifKNkfKNifKRifKNifKRifaNffKBifKNifKNhe6NifKNVVapifaRigKdqgKpifKJifKNjfKNifKMAAAAbs8LoAAAAfXRSTlMAPHgkkwbEPRfWPyzFxiCwGKO0QQ6PCsI+CW/MOwGeUslpHH270ejuDcA3Nefee2KlmAJNzVp5ZXLlfAW1UAi6GYfKFdQn3HTjOkhYcEc02ZpurRGEgdNVuQS8K+qNORQt2+SnYLf7Q/AL/thAov1t1SP0gFm9A5EaDLPgljs6ba0AAAABYktHRACIBR1IAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4gcfDwIsJrDCrAAAAUdJREFUOMtjYEAFjEwM+AEzCwEFrGzsBFRwcHIRUMHNQ0ABAy8uCT6IB7j5sUsLCAoJs4oAGaKMWOXFxCUkpaRlGBhkeWSxKpCT51BQVFJWUVVTl2YTxDREg01SU0tbR1dP38CQwcjYRA9dgamZuYWGpZU1AwOTIYhvY4vuBDt7B0cnoO3OLuLMQL6rmzWaCll3WQ9PIO2l6e0D4ov6YjjDz58BSQFjAIaCwCBkBcGcGApCQpEVMIRhKAgIR1EQEYmugJ8bRHK4REWDuaIC6Ap4YmLjgHFhBnZdvGJYArqCxFogSLJ3SpZICU1Nq61NR1eQUYsKvNHkWdHkawPRFGRmoSmwQLciG01BDrqCXFT5PA10BfmoCgowQrKwCEVBMYYChhJk+dIyTAUM5Qh5D2cs8gxl5mpQB8pVMGAHlUxV1RlsNcjRAADCI22hLSPcLAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wNy0zMVQxNTowMjo0NCswMjowMCovWKsAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMDctMzFUMTU6MDI6NDQrMDI6MDBbcuAXAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg==)|Double Click on Position | Double clicks on a specific (x,y) pixel coordinate on the screen. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABlVBMVEUAAABifKNhfaJjfaNjfKNjeqJhfKNdgKJje6VifKNheZ5jfKNifKNmgKJjfKJifKRifKRjfKJkfKJifKJVcapmd6pVgKpifqVjfKNhfKJee6FkeqFifKRjfaRifKNhfKJddKJgfaNifKNhe6Nhe6JifKNifKNifKNifKNifKNjfaJjhKVhfKNigKdifKNie6Rhe6RifKNje6KAgIBhfKNifaRjfaRhfKRifKNifKNkfaVgfaRifKNjfKNidp1ie6RifKNmZplje6JifKNhe6JifKRie6RjfaSAgL9ie6NifKNjgKNifaIAAP9ifKNie6RggJ9mgJlkfqNifaJie6RjfaJjfKNie6Rie6JifaNifaNifKNpeKVhfKRhfaRifaNje6Jie6NmgKZlfaBie6NifKNkeqZifKNheaRifKJifaFifaNifKNifKNifKNifaJifKNifKNhe6RifKNie6NifKNkfKNifKNifaNifKNffKBVVapifKNhe6NifaRifKNgfaRjfKNifKNifKJqgKpifKMAAABuSHiZAAAAhXRSTlMAfzdsUCzHFj7YFWeKHqhzbXkhyQkPBkG1pRsuojvNcQs9xDqdwejy07mBH2kaTp9+zE0CmKpie97qMzXAwg1RgAV8425leFoE3Sck1wHKuAgKRY9wWEiXPNkv0BGtg7ZVmRQrvNYXryqaOY3F+7dgp9pX8HL+QP3V9CMDvVmRni2W4LMMdicdPwAAAAFiS0dEAIgFHUgAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfiBx8OOhgRWeDVAAABRklEQVQ4y2NgQAaMTAz4ATMLAQWsbOwEVHBwchFQwc1DQAEvHwEF/AJAQlAItwJhEQZRMXEJSSkc8tIyDAyycvIKikoKmJLKKqrCauoamlraOnK6evoY8gaGRsYMJqZm5haWVtY2IrZ2aPL2EiDSxIGBwdHJWcHF1c0dVd7D0wtIetv6AAPK18+Byz8gEFVBUDCIDAm1CQO5xoJB3hfNhvAIJAUMkVEYToyOQVYQy4yhQI4BWYFWHLq8bzyKgoREdAVJYDcyJKekpoFo1nR0BRkaOkkgOlOLgcEuK9syB12BeGtrbp5WPkeBnKZzKxAUoisoakUFxegKBNAUtIqhKShBky9Fj+0yNAWc6FbYlaMqkMEIyQpUBQIYChxQ5CurMBRU1yArqGXABFzOCPk6BmxAtx7qUDXXagbsoKFRqbip2a0FRRAAuxR3CVsTlh0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTgtMDctMzFUMTQ6NTg6MjQrMDI6MDBXo7QiAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE4LTA3LTMxVDE0OjU4OjI0KzAyOjAwJv4MngAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAASUVORK5CYII=)|Right Click on Position | Right clicks on a specific (x,y) pixel coordinate on the screen. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABnlBMVEUAAABkfaVjfqSAgIBVVapifaJifKNie6RmgKZheZ5ifKNifKJke6RifKNifKNifKNifKNmgJljfKNie6JifaNifKNigKdhfKRjgKNgeqVggJ9ifaNtbZJifKNgfKJifKJje6Vie6NifKNgfKVifKNifKNVgKpie6Rie6RjfaRhfKNhfKNifKNifKNkfKJie6NqgKpifKNifKNie6RifKNhfaNifaNjfaRifaNhfKNheqNjfKNifKNkfKNkeqZifKNjfKNifKNifaNhfaRifKFifKNie6Nmd6oAAP9mZplhfKRifKNifaNmgKJjfaJifKNifKNidp1ifKNjfaRifKNifKOAgL9ifKNifKNifKNje6NgfaRhe6JifaJkfKJlfaBje6JjfKNifaJbgKRjgKpifaRhfqJhfKRifKNddKJjfKNifKNVcapifKNifaNhfKNifKNdgKJifKNifKNhfKNjfaRifKNpeKVjfKNifaFifKNhe6NgeaZjfaRifqVifKNie6JhfaJifKNifKRhfKRje6VgfaNifaNifKMAAABCGDdQAAAAiHRSTlMAM0MCA4f+uBQVveI49vvy8Ap3vi+mGoYkMAiFB8xK7R+V8SXSywZR37C/kIjIKVMM+NFw94uuatWYMmf9QBfso7lmg0TzmQ8BBUznXh6B480N9GLg3gTEsfybNZ3XISt8z2gOEpFHrZwLUO4JglbhyhbA6GFarxHCOcM6KDtB9Tw/+qLUPj2sFsDMHwAAAAFiS0dEAIgFHUgAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfiBx8PBCPgVXi7AAABq0lEQVQ4y32SZVtCQRCFV0EwL2B3YGOAXdiioFjYHdid2F3nZzv3clcUFufD7uzOu/OcnRnGhBYRqWH/mDZKB310+HhMLMji4sMCeiRIMMBoCgckJiUbEZmSIo6mpqXTakQGY5lZEaHx7BxEcSAXefkhQAHMhRwwFaG4JCheCpSVk0mw0FoMVAQBlQiyKlZttf2uYA1q68jq0UBrI9DEmmFoaQ0QbbC3cw0dnehirFtOlNPzk6YLvRzoQxHVygpY7ICjX/2zNnfA6ZIBp8s5KD9zDcE9PDJKacbaxtUkngkjeianpv3HNMzQu8HZOUozvyDfLPo/sKTWYFmHFaXGq5N0u7buZdpKHXn6DS6rG5t+R7O1LQGenV22Z9aNBCbGiv0D7ncc0uM6GonCX8WRZXL/6Bg4OQ1ukCJTNu8ZcH7hDOkgl8kuAZ9XNCRcpq0KZuEkKjKvrn22ASJuBIAicxO4lQnDnYAgmfcSJJV4CAVI5hosj09+wvEskgl7MmtXiGZMiWSihbYXD27dr3gTyJx5j5H3Dw+1yecSyNSqvfl04EsUD1i1e/rP+RtzqoK0S6GtfwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wNy0zMVQxNTowNDozNSswMjowMIuDKkEAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMDctMzFUMTU6MDQ6MzUrMDI6MDD63pL9AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg==)|Move To Position | Moves te pointer to a x-y pixel position. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAt1BMVEUAAACAgIBhfKNifKNifKNifKNhe6NhfKRjfKNhe6difKNifaJigKdifKNifKNifKNjfKNigKVje6VgfaRjfKJhfKNifKNifKNifKNifaRifKNkfaVie6Rie6Rje6JjfKNhfKRhe6IAAP9ifKNifKJifKRifKNifaNifKNie6NifaNie6NjfKNifKRifaNjfaRifKNkgKRee6Fie6JifKJhfKNifKNifKNhe6NifaNje6NifKIAAACNe4HzAAAAPHRSTlMAAmHLnvuTVI4d+mAa3sjBtSIfLYSYxfjokfwzcHhd3IadAa+zu/DZypVeW5ZlhYn5HBs0jKDNwLqum8kaEYxVAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+IHHw8GAQcDW90AAAExSURBVDjLfZHbdoIwEEUHMKAoab1ANVK1tBY0Ihe1tPr//9VA5E6YBxjW3g9zDgDVkWRFkSUQjjRAqooGUg/XADShwbnYyLnQGOY8NYZtPtLH5cdYH7WEiW5g/JJurxgb+qSBpzOYL0zrLd2X2FzMYTat3rciZM3eNhfe2WNNyKq4lN2/2e7qwm67QR9OJR8264KJi7Q8P7Zs2/7kwhdbLZz38exn/53OMhXcbN3njcllP+3RkAyKCj2jKuAd+oSDB0dCxZySIzinzOg8kpITq4IbXTE5fxodReU8M3zjXBfOhl9wZgQhav4sFAZO5dwohsv15nHh53a9QBw1EsXITZLfdPtLEhfFrchR6Jcffhi1BAjKxigJOlp7NgZQyddtiHhuiHlm3O89nBn08aB1/g/vYyMbsj40/QAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wNy0zMVQxNTowNjowMSswMjowMPW22YwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMDctMzFUMTU6MDY6MDErMDI6MDCE62EwAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg==)|Move Relative | Moves the mouse an x- and y- distance relative to its current pixel position. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAt1BMVEUAAACAgIBhfKNifKNifKNifKNhe6NhfKRjfKNhe6difKNifaJigKdifKNifKNifKNjfKNigKVje6VgfaRjfKJhfKNifKNifKNifKNifaRifKNkfaVie6Rie6Rje6JjfKNhfKRhe6IAAP9ifKNifKJifKRifKNifaNifKNie6NifaNie6NjfKNifKRifaNjfaRifKNkgKRee6Fie6JifKJhfKNifKNifKNhe6NifaNje6NifKIAAACNe4HzAAAAPHRSTlMAAmHLnvuTVI4d+mAa3sjBtSIfLYSYxfjokfwzcHhd3IadAa+zu/DZypVeW5ZlhYn5HBs0jKDNwLqum8kaEYxVAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+IHHw8GAQcDW90AAAExSURBVDjLfZHbdoIwEEUHMKAoab1ANVK1tBY0Ihe1tPr//9VA5E6YBxjW3g9zDgDVkWRFkSUQjjRAqooGUg/XADShwbnYyLnQGOY8NYZtPtLH5cdYH7WEiW5g/JJurxgb+qSBpzOYL0zrLd2X2FzMYTat3rciZM3eNhfe2WNNyKq4lN2/2e7qwm67QR9OJR8264KJi7Q8P7Zs2/7kwhdbLZz38exn/53OMhXcbN3njcllP+3RkAyKCj2jKuAd+oSDB0dCxZySIzinzOg8kpITq4IbXTE5fxodReU8M3zjXBfOhl9wZgQhav4sFAZO5dwohsv15nHh53a9QBw1EsXITZLfdPtLEhfFrchR6Jcffhi1BAjKxigJOlp7NgZQyddtiHhuiHlm3O89nBn08aB1/g/vYyMbsj40/QAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wNy0zMVQxNTowNjowMSswMjowMPW22YwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMDctMzFUMTU6MDY6MDErMDI6MDCE62EwAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg==)|Drag | Drag the mouse from its current position to a entered x-y position, while holding a specified button. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAeCAAAHggFwQHG1AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAXdQTFRF////VVVVMzMzQEBAQDNNPTFJOS9MPjFKPTBNVV5yVV1yPTNNPTJNVF9yVF50UFduUFVtPTJMPDJNPTFMPTJNQjxVPTJLPTNMPTJMWWJ3WWN4eYKSd3+Qc3yNTE1kSUZdipKgj5ekbW1/PjNNEZ+FEaCFE5qCG5aCHYF1HYJ2HZWCIZGBI4+AJY2AJrmZJ4p/J5mIJ7iYJ7iZKGZnKLWXKoh+K7CVLIV+LVlgLqmSL4J9MYB8MqGPN3t7N5eLOpuOOzZOPHZ5PTJMPYuGPzROQoKCQpmPRXyAR0JZR3h+S296TWV1T2h3UGJ0UWN1UmBzUmB0Up2WU19zU2B0VF5zVl9zWGFyW2NyW2RyXFRqYlpvam9va29vdndudn6LeoOTe3ttg5GdhYJriJCeioZrkLCxlY9plo9pn8fEoMfEpc3Jps3JtdXSvq1iwrBiyszS1Nnd3uLl38Zd4OTn48ld4+fq5Ojq5err5+vt6Ozt7PDx8tVa89VaeKdWIgAAACR0Uk5TAAMFCBQVGz5PV2BkcXSAiY2krb/S0tXe6+/x9PX29/n5+fv8FggocAAAAR1JREFUOE+F01VDwzAUhuGz4e7uEpzAcJdsuAxGcXd3GAPy40k6aFOaZO9Fbr7n8gQgVqnaUgCM8jJ1FSUMPH+peyrl4PP9VV44EgUfh4a807AAjs42tOCB0rctDdj7ppReasAuBxcaYNxT+rJpLUE3MPZP1q19oXHSDYSWWhAa1YCVVsQalgH/DHtC7cisP/QfrI1hHxO96LeOoBMsj2DMxBCyajsWweIg5vk6bYCmBTDfh7FLjNtgrgdjt7DBVBe2M0VTgwhWsSMuuicGmuv/QOTuxtnt9dU5IWT24DEKpNe4Q3jblfFgVNfIqjVBoCoRMuVl1bG9IDtD/aFyCSnMT1DvkEyK4nJ0wlucBh6tSPcCE3lqYOZJigEAfgBeXN5IKUhh3gAAAABJRU5ErkJggg==)|Click on Image | Clicks on an image on the screen. Image path needs to be specified. | -| **Keyboard** | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA0lBMVEUAAABffKBjfKNifaFjfaJifKNifKNifKNifKNifaNhfKNifKNifKNifKNie6RhfaJjfaRjfKJhfKNheqNifKNifKNje6JifKNifaJmgJlggJ9ie6JifKRifKNifKNifKNifKNhfKJjfKNhfqJhe6JifaNifaJie6Nie6NjfKNhfaNggJ9ifKNifKNidp1ke6RmZplifKNifaNhfKNkgKRgfaRifKNifKNjfqRifKNifKNifKNhfKRie6NifqVifKRje6VgfaNifKNifKJifKMAAAAaoMKDAAAARHRSTlMAI1A5WP6esfasoKnz+bg/iaiQMvhOXehgChi+bfX37spCSEd2VtdyW8KLEPLwDTgFqy/HHC376kPO/OVU20HGPj2CmoKHyGIAAAABYktHRACIBR1IAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4gcfDwoLS2P9zwAAAMJJREFUOMvl09cOgjAUgOEjuBW3orhxoii4cO/z/s8kGghQaHkA/5sm8IWS0xTAW4TzxBOvIRpDb3ECJBCTqbRdJosCAXKI+ULRrlRG9IFK1bVBTQwAnAvU/wg0JFdNP2i1vafTIUGXOD7fF8yl15edBkM/GI2RkgVk58lkGgIkoANFYYPZXGWBBQdLzUyngZVuzXpN22Kz3YnfDOo/7A/HkDmczlRwuVIGadzUH7g/5OCeL/PiCMhMgDgbvAF4jpEGH821q5ZoP5xyAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTA3LTMxVDE1OjEwOjExKzAyOjAw9Yx2lQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wNy0zMVQxNToxMDoxMSswMjowMITRzikAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC)|Press Key | Press and release a specific key. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAhZQTFRF////SUlJQEBAOTk5KysrQEBAPT09MzM8NjY2NTU1Pjk+JycnMi4yOztCKyswKSktPDxCPTtAPDtBKiouKSgsKSgtJCQoOztBPDtBJiQoPDpCPDxBIyMnISElHx8iPDtBPDtBNzY9PDtBHh0gHx8iGxseHBwfHh0gGBgbGRkbGxseFxcZGxkZHBweHRoZHxwZIR0YJB4YKCQeKSktKyIYLCstMCUYODc8OTc9PDtBPjxBPzw+QTw8QT0/TEM6UTcXU0Y3VDkWVjkWVkc3WUk1WkQmXUs0YEwzYk8zY04vZkIVZlAxaVEwakUVa1EzbEYVb0cUcVEedEkUdVIbd1AgeFgpfVwri2QojmIckGcnkWcnkmQooGkgo3EiqGYRqGscsWoQs2sQt20QvIAivoEhw4QgxYUfxoYfxoYgzIogzIohzYog1XwM1nwM2n4M234L5oMK6Jsf6Zse6oUJ7p4f84gH9YgG+aUf+4oE/Kcf/YoD/ooC/osD/qgf/4gA/4kB/4oB/4oC/4sC/40E/5YJ/50O/6QS/6US/6cT/6kf/6kg/6sU/6si/6wW/6wi/6wj/60V/64m/7EY/7Iq/7YZ/7Yw/7ca/7k0/7o2/70b/8Mc/8RC/8RD/8Yc/8hJ/81P/84W/84X/88A/88U/9AH/9AK/9AN/9AP/9BT/9RY/9Va/9th/9xj/+Jq/+Jr/+Nt/+Rt/+ZwoiROiQAAACt0Uk5TAAcICQwYGR4hIi00PUlrcYSXmKzAwMHByMva4+bs8PLz9PX4+fv9/f7+/ruUxDEAAAHpSURBVBgZBcHdbttkAADQ4++LnZA69uI1i9iqqu3GBJO2978D7ngCLhjiAqHQorZZ0ib1T2xzTgJAkqdpzLR91z2PABKA7Kx4C2CzP7SABAhFtQYAd4/7AUSQrn7IQdkC8lXXDBBhfn4F+P66PwKWp75DRHp+CRC/LJMtoGzrgUhYXQE4fTytxi2gbI6jQHENwIz+/UeA64IgqwDwCuPVO4AqE5ytgQt4DePNCbA+E5ICqD7kXF6B2U8toEji4j1w8+7N/OJHOsi/DhEsvsX8HMw/ZVlVMk8bhM4xgm1IgXUO5OsplF+KFqQhAgUwWw43Karic91CDBmYlMAi0b3Bmbm6RRaAWIG0xCJAdq5uEVowARYTnGa+w5K61YYeROAViNkFetRtP+nACEQwXQ3ooR5CB55vUcYIqnCi34A2PG9gvMfkcgCDJ/YdnPZh3IN7NNMADI/8DR7G4HAHuz841IANj3/CcBD14woeJpVjHjXUjw4/j3C/E2m7JcaHdNm/TNMmPm28/NLC/r9RZGxOJcbbXTrbtfVmn/zzawfNvx0RQ9+WSPZ/dZPJt3H321fQ3r4gAenraxiO4cPi9wPw9HCABAhFtcZwHADj3XYACUB2VrxlOA7Q77Y1IAEgydM0TtO+aZrjCcD/QYnGEnUj7BIAAAAASUVORK5CYII=)|Hotkey | Press a hotkey (combination) | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAPrSURBVFiFvZVvTFV1GMc/zznnklgXLggDLM3NJspyhKPmaDnkBUy8pDajrfXGWHO5hpW8tulqhZM5Wbb1omVvWn+dTYEG6nWYWVvOWi665Au1W0Aw7mU0Arn3PL04l8u5DLZ7wct3OzvP7/k+v+f57jm/8/xEVUmguf6BMTHOKGxV5HjeyXPvkmEY7kUYeU6hHsgX9GjkjT2+ZRUA7HLZluq9+uUTsL/SIyI7klibZ5dNwFh2UTWQ4yZFZAf7Kz3LIkDVmG2/6tm4lRMXlnkBoA1xIyTKO/MKy5SASHN9BbAWQIWO3Pc7rwMDjgI7o+fAAkDEVUTPo6oc9HcCTYisiTTXV/jaO284fKMZ7l9XJdirnHC1Taygt7Q1uHgBGLvAGUii0ho56H8bKEhEOQJvAER+X3tYxD48m0KIESMSbBkBCUQxmgpKW8dTFWCMHtq9BrTC5SsDyoGHEx6d7ZAKpQvkKgB93sL+KNXiAIZEp2fbL1xV1c9nHuBO3L/FEZoMVV5U0Z2IHgKmnVBt4PIRK1UBFriGjcReymvvuj2zjDT7X0c44VDRBuAD9+aobQQKNx4bBDoj/S3bUfwKK0YfmSjOh1AqAgxByuP2Td+J2eIOKR0JW3XzQkkGrh9ZibIJQGAy/7GVf6dS3MmLvAx8ImrvnkvmnDz3hwiNoB+rYbfO5T2WfSESbPkl+6HxUWC949Uz8JadqgBJuo5TQDjY8pnACwtnZI9vw/GzC/JzMPc2TAuCfAv6DdCfcCqnRm815yy8Kxkpn9b5cC8m+wrL2gYBxoItpxQOAKvN6IqtQDdA45eYkcKhfYYtT6tBEWrfViXQU1P8lYIuSYAbqlxEOACgomVAd9W1ULa3wNMrSqWKxmedIMKrtYGh7+umqV3SJ0gSgLgH1BiAd9LTClTOOAVGXDFVeOTYkjpgGfb20eCbYROzXERfm/Hbtt0XN/fG3//apv1Uz7aSvtrLw0+I2j8BJqh/aYdQ+NTA6FL0PWC149Ur+ZvafvB/dzcPKHECCfRsK+kD6K4u/Bk474QylXYHRAki83OKdqtpNQHEolm5LiJpMJmWvhKNGV1qxnrTFuDbePdouH/dhcR1DAg6HjPpz1/f9mcqOTqfKR4GPoRF/YZfxPI2cCX9ffPjvv0Fi8V9mwPpQEDqLg0+mTWhNzPWgemY8V9ioeS6udrA4GkV+XHqQSOQ9mWUDuoCQ2HAJzAyJUUlgWqiVddC2d5JzxDgBYYzegYEegEUCrJ0KFQbGPzaO+kJxYujkNkO7Lw08GhUjF9nCs7BP1G1tmS0Ax01JXcstTeLymngFjCh8BvQblr6+MWaVX/9D48CdgjDk2lOAAAAAElFTkSuQmCC)|Type Text | Types text with a specified interval in seconds | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAArlBMVEUAAABifqVhfKRifKNhe6difKNhfaRie6RifKNifKNifaJjfaJhe6FigKdjfKNie6RifKNmgJlifKNifKJgfaNifKNjfKNifKRifKJifKNhfKNkfKNjfaRkfaVifKNifKNddKJjfKNdgKJie6RjfKJgeaZifaJifKRifKNifKNifKNifKNffKBifKNifKRjfKJjgKpVVapifKNgfKVkgKRifaJifaNifKNifKMAAABOmTqZAAAAOHRSTlMAQa37HfyDuP65YFhPGm942grukj3AUGWz+JBAWjP9ygtIFp+oKIei5NjqqSPgRnkSA9IlHI/VzUqSt1kAAAABYktHRACIBR1IAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4ggDDxEmPxUV1gAAAMdJREFUOMvNk8kSgjAQRBsEgiiooHHBDXdU3Jf8/5cZEUWLQK6+Qw6ZV6mpVDegqCWWQ0lVAE1nBegaDFaIAcJPs2xVMlhlk49ILFRtp5bBsatvod5wRa+7jXoieE2+TcuhlLY73S+j6SVCz2esjxeDYSr4vVQYAeMgCCbAVCzMgDm/WlC6LBR++VNhFYZrsbABtlEU7YC9WHAPyU8eT2KBzc7x/HLN2YFzI4TcTZYvZPkr4Rk5EZ/ISUMrjX1xcaTVk5ZXVv8Hy/WmWw/A3AMAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTgtMDgtMDNUMTU6MTc6MzgrMDI6MDBXSMdrAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE4LTA4LTAzVDE1OjE3OjM4KzAyOjAwJhV/1wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAASUVORK5CYII=)|Press Caps Lock | Press the Caps Lock key. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAolBMVEUAAABifqVhfKRifKNhe6difKNhfaRie6RifKNifKNifaJjfaJhe6FigKdjfKNie6RifKNmgJlifKNifKJgfaNifKNifKNifKNifKNifKNhfKNkfKNifaJifKNggJ9mZplifKNje6RVVapifaJje6IAAP9ifaJtbZJje6VkeqZggJ9ifKNieqRifKNhfKRifKOAgIBifKRie6NhfKRifKMAAADtyAz6AAAANHRSTlMAQa37HfyDuP65YFhPGm942grukj3zyPDyy5BAaMAQBd5fA9dVAY8HPhcIw0nNVNYCRnpMuLirZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfiCAMPExdc/XduAAAAuklEQVQ4y83TxxaCMBAF0KEXAWlGJSo27Ipl/v/bRA6ykJDZ+hZZJPdk9R6AomrYE01VAHQDJTF0MFEaE6zqtB130Inr2NWTVQPPD4adBL73BWEUi36Po7ABSYo4YoyNESeMTVuRJg3IOCIDgBniHGDRAp79gHxJAFhRYL0hAGwpUOxkYH8AOMrA6Vz/IgF4ocC1IADeKFDee0HJ+aO6e3L+EgNR/gp8KidKWzmytGTt5cMhp0eOl5r/Gyf0lU4JF2BaAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTA4LTAzVDE1OjE5OjIzKzAyOjAwhyyjvAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wOC0wM1QxNToxOToyMyswMjowMPZxGwAAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC)|Press Num Lock | Press the Num Lock key. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA0lBMVEUAAABffKBjfKNifaFjfaJifKNifKNifKNifKNifaNhfKNifKNifKNifKNie6RhfaJjfaRjfKJhfKNheqNifKNifKNje6JifKNifaJmgJlggJ9ie6JifKRifKNifKNifKNifKNhfKJjfKNhfqJhe6JifaNifaJie6Nie6NjfKNhfaNggJ9ifKNifKNidp1ke6RmZplifKNifaNhfKNkgKRgfaRifKNifKNjfqRifKNifKNifKNhfKRie6NifqVifKRje6VgfaNifKNifKJifKMAAAAaoMKDAAAARHRSTlMAI1A5WP6esfasoKnz+bg/iaiQMvhOXehgChi+bfX37spCSEd2VtdyW8KLEPLwDTgFqy/HHC376kPO/OVU20HGPj2CmoKHyGIAAAABYktHRACIBR1IAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4gcfDwoLS2P9zwAAAMJJREFUOMvl09cOgjAUgOEjuBW3orhxoii4cO/z/s8kGghQaHkA/5sm8IWS0xTAW4TzxBOvIRpDb3ECJBCTqbRdJosCAXKI+ULRrlRG9IFK1bVBTQwAnAvU/wg0JFdNP2i1vafTIUGXOD7fF8yl15edBkM/GI2RkgVk58lkGgIkoANFYYPZXGWBBQdLzUyngZVuzXpN22Kz3YnfDOo/7A/HkDmczlRwuVIGadzUH7g/5OCeL/PiCMhMgDgbvAF4jpEGH821q5ZoP5xyAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTA3LTMxVDE1OjEwOjExKzAyOjAw9Yx2lQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wNy0zMVQxNToxMDoxMSswMjowMITRzikAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC)|Press Enter | Press the Enter key. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA7VBMVEUAAABifqVhfKRifKNhe6difKNhfaRie6RifKNifKNifaJjfaJhe6FigKdjfKNie6RifKNmgJlifKNifKJgfaNifKNhfKJleaFggJ9meqNjfKNifKRifKNhfKNkfKNifKNddKJifaNie6RhfaJifKNjfaRifKNifaJifKJifKNifKNigKVjfKNifaNmgKJifKNje6NggJ8AAP9ifaNie6NifKNifKJVVaptbZJifKNifaJje6JpeKVhfKNhfKNifKNifKNhfaJjfKKAgL9ifKNie6NifaNVcapgeqVifKNifKNifKNifKNifKMAAAAffb+/AAAATXRSTlMAQa37HfyDuP65YFhPGm942grukj3McSYYGVCi+pBA5QuFcDeIavZo4vd1IrXZHsp0CAFW2+NjAwek100Rv5jQ8D+oBPRyrAkwgvP4+Q2HcRMAAAABYktHRACIBR1IAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4ggDDxIKJuAq9gAAAPhJREFUOMvN01dTwkAUBeBDCSXUBBQQCcVQLChVBaRXgfv//w6LRM3AbvaV85CX/WZzZudewOX2kCAetwvwKuQQxQsfOcYHP/sGgmroImowwI78PyAcicYuEo2Ef0Fc03m361rcAokk0c1tKp3O3GXvbSKZsEDOoHwBpxRtwMj9gxLwYJplQKvwgQpUiWqs2yMfPAHPL+ct7aD+yv5vvIkB6Y0m0Gp3hICo+/4BfPbEgKg/AL4UPhiORkOiMSsy4YMqMJ3NTGC+4IP+3HrJpajDarBmx5vvrbikstvtHd6Bl6sCx5Hj5W/kpEMrHXvnxZGunnR5Zet/AOS93hzGiKnAAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTA4LTAzVDE1OjE4OjEwKzAyOjAw14nV/AAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wOC0wM1QxNToxODoxMCswMjowMKbUbUAAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC)|Press Space Bar | Press the Space bar key. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAApVBMVEUAAABifqVhfKRifKNhe6difKNhfaRie6RifKNifKNifaJjfaJhe6FigKdjfKNie6RifKNmgJlifKNifKJgfaNjfKNjfaRifKNifKNhfKNkfKNggJ9VgKpje6JifKNifaNifaNifKNifaJgeqVhfKRddKJifKNgfKVifKNjfKJifaNifKRgeaZke6Rje6Vie6Nmd6pifKNjfaRjfKNifKNifKMAAADLEAQGAAAANXRSTlMAQa37HfyDuP65YFhPGm942grukj21sLfykEAQBk34hazwhzBMC8Ul6qheZSg4H1sP5Gpn9O6JV9wAAAABYktHRACIBR1IAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4ggDDxMNoZ+OFAAAALxJREFUOMvNk8cOglAQRQfpSAcL2MCOin3+/9fkIZYEHrNw41m8vGROJrO4F0DoiMhB7AgAkowtyBIo2IoCavFqutGtYehaMVJLwbRsp4ZtmS/B9fym7b7nVkIQIvb6jMHw2wiDSohixBGUjCfTjxBHdQFgxheSNJ0DLPgC+7UKzw1L4obVmhA2W77gZNkOYP/DkaRwyPMjwIk48nzhCFeDcUvuyBGa+CuBRa6Jd+TI0JKxby8OWT2yvFT9Hzt6mG3OxEGhAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTA4LTAzVDE1OjE5OjEzKzAyOjAwCaOkXwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wOC0wM1QxNToxOToxMyswMjowMHj+HOMAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC)|Press Backspace | Press the Backspace key. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAkFBMVEUAAABifqVhfKRifKNhe6difKNhfaRie6RifKNifKNifaJjfaJhe6FigKdjfKNie6RifKNmgJlifKNifKJgfaNifKNifKNifKNhfKNkfKNlfaBifaJifaNVgKpifKNifaNhfKRggJ9ifKNjfKNVVapifaJhfaJhfKNifKNifKNgeqVhe6NjfaJifKNifKMAAACy4TRgAAAALnRSTlMAQa37HfyDuP65YFhPGm942grukj302OOQQCuHtgbAZkwIiEgDaDdh4MUwOoHWBsSESQAAAAFiS0dEAIgFHUgAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfiCAMPEwDfLvKpAAAAqUlEQVQ4y92TxxKCMBRFL70ISFPBEkWN3fz/5wkRywwpW8ezyGSSM1m83AsYpsUkWKYB2A5T4NhwmRIXXrv6QTgaEAZ+e+VxIYqT8YAkjl5CmuWi1/Ms7YWiZGwy5cy+jbLoharuNk/mi49QVwIBWEqFFSFkDWykQtOebYHdnwt7SukBOGom2ZzEwvnCud7ukr8Q8VNCFzkR78hpQ6uNvbo42uppy6ur/wPSKoc8yA0EyQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wOC0wM1QxNToxOTowMCswMjowMPThvlwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMDgtMDNUMTU6MTk6MDArMDI6MDCFvAbgAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg==)|Press Delete | Press the delete key. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAilBMVEUAAABifqVhfKRifKNhe6difKNhfaRie6RifKNifKNifaJjfaJhe6FigKdjfKNie6RifKNmgJlifKNifKJgfaNifKNifKNie6NhfKNkfKNhfKNggJ9heaRifKNifKRke6RtbZJggJ9ifKNifKNifKNdgKJifaJjfaNggJ9ifKNgeqVje6VifKMAAACntH0CAAAALHRSTlMAQa37HfyDuP65YFhPGm942grukj3v2NuQQJgYKsDGOAcg1tDmFmhsCKswNrCAMdAAAAABYktHRACIBR1IAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4ggDDx0D2KSOnQAAAKpJREFUOMvNk8kOgjAURR/zIEUmFZwHcHz//30Wi4ZI2xcWJp5FNz1pbpp7AQzTQgWWaQDYDmpwbHBRiwseP/0gnAwIA59feS8hYvF0QMyit5Ckmez1LE06IS8QZ3PBomcUeSeUFeISBKueUJUjhfWGs9UIu++Uo4X9gXOkQp40Amv/r/5pyObMuVAhryrhdhc8VIKMvxLaysn4VI4sLVl7/XDI6ZHjpeb/BD+wha8hV0UXAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTA4LTAzVDE1OjI5OjAzKzAyOjAwXOvCwAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wOC0wM1QxNToyOTowMyswMjowMC22enwAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC)|Press End | Press the End key. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAaVBMVEUAAABifqVhfKRifKNhe6difKNhfaRie6RifKNifKNifaJjfaJhe6FigKdjfKNie6RifKNmgJlifKNifKJgfaNjfaRifKNhfKNkfKNje6NggJ9eeaFVgKphfKNgeqVifKNhfKJifKMAAAAgBlLQAAAAIXRSTlMAQa37HfyDuP65YFhPGm942grukj2wgJBAdCATBpgw0qUQSuUJAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+IIAw8cDSYHktsAAACVSURBVDjL7ZPLDoJADEUvbxgBeelgfWD//yedGEYxA9PElQvPopueNF3cCwRhxBtEYQDECXtIYqTsJUVmZl6onYMqcrPKnkJZ1XuHuiqt0LTd2vWubWahH/hwtCyMoZ8FPbKCZSGM+i2ciM7AhYg2BMMVuH0+8Re+Eyat717B5acEE7lVXpETQyvG3l8csXpieaX6PwA4C2rRdSrKwgAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wOC0wM1QxNToyODoxMyswMjowMH+DqWAAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMDgtMDNUMTU6Mjg6MTMrMDI6MDAO3hHcAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAABJRU5ErkJggg==)|Press Tab | Press the Tab key. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAfpAAAH6QGUejxAAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAVZQTFRF////29vb6+vi5eXTzb/I6Ojg6enf6urfwrTFuae/4uLX3dzQ6eng3NrOo4ewl3eomHiomHipmHmpmnuqm3yqm3yrnH6sn4Gun4OuoIOwoYSwoYSxoYWvooWxo4aypYqxpYq0pYuypou1p4y2qI6zqY+3qZC1qpG1q5G4q5O2rJK5rJO6rJW2rpW7rpe4r5a8r5i4sJq5sZm+spy6tJ3BtJ+8tKC8tqK9t6O+uKW/uaa/uqXGvKfHvKjHvanIvqrJv6vJwK/Ew7HNxLbHxbPOxrjIx7nJyLfRyLjRy7/My8DMzr7WzsPO0MfP0cfP1MzS1cjc18ve2Mzf2c3f2c7g2dfK2tTV29rN3NfX3djY3tTk3tnY3trZ39zZ4N/U4eDW4t/b4+Dc5OHc5OLd5OPd5d3q5uXe5+bf5+ff6Off6eng7Obv7ejw8ezz8e3z8u709vP3/f3+Bb+anQAAAA90Uk5TAA4aHThCR0htfNnr7PP7HqL7KAAAATBJREFUOE+tzvk3AlEUwPFBVJYuZcoWso41xkQI0TBCYazJUra4Y/3/f9FjTmaa+45ffH+YO+e8z3nvCoIg1DZjVY11grWG6nO8brEJtxOc2AQFbIIEVkEDi3CCmzNWUw0XmNVzQSr9Pdx2kJ7ti5mgJ0uAhUA8e4538TziafujE2Rac2xcduwjrs+hEyzNYKXIDgHmFyvnef8tAbbEezbYDqlJJEApMrL3/LPD6CYFsBgLwBj7KbRdkQDxKVdkIzOEHGBWKvwBfvs/4Jnm5DGBFzh5raBT0zRpYBn6E5DUtKQTSIYsh8W30PEaGKvyBAEe2Hfj4MUPxiD1hPSh690Q/NwGMC70BPeGI4N7w6uqDovv4cPyDrvqihMEFUXpDU1B1zhEFSVqAy4fkPlc5cMvjuvkA0Hh2hAAAAAASUVORK5CYII=)|Type In Run Window | Type the entered text in the Windows "Run" window. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAGVAAABlQEMTY6IAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAOpQTFRF//////8A/4AA//+AqqpVv4BA/79AzJkz/8xm379g48ZV6NFdzp0x8chg7Mdd7sVd8cZe7chg7slc78Zf78hf8Mhf8MZe78he78de78hfyp8vyp8v8MZeyqAw7sZey58x78ddyp8w78deyp8w8Mde8MdfyZ8x7sZd7sdeyZ8xz6M0y54wyp8wyp4wyp8x78he8Mhe78Ze78de78df8Mde78de78de78de78de78de78de78de78de78de78de78de78de78de3LNG78deyp8wzKEy0qc63LNH3rRJ4bhN5LtR68NZ7sZd78deCBVgzgAAAER0Uk5TAAECAgMEBAUFCAkLGiUpLDY4PV5hZmd9gIGCh4eLi42OkJOUlpeYmZqdnqGlqa3BxsvMzdfZ3OHj6+3w8/X2+fz9/v75BNv9AAABFElEQVQ4jXXR2VaDQAwG4LgvoGhV6lKt4ob7gsWlqEUGVDTv/zp21IGkE/4LOGfynSQDAL/x/DBKotD3QIwTZPiXLHCEeivGOnHLrqdIk44KJ0aeeGRKoA/LIi9KIwJW9/R+pdIxImN38fVRobpuVxWmhU9BqE9y5YKrcgNCCiKhQ0RBgtYO+ELBLVq3wAcKjtHONQVrAtigYDG1Af+nuzboMDDfs8UKE8sDC/QYgKU7Uvv6HD6eOIC5HbPp90eu3ofv5LHNycLqwc3z/VX7VH9RLbAPYmYujejPTohi6qLqgeuimDyvxKs8ZfzMiGy6QZxUPQYdUYwd1XscymK/FvIU2KtEA4BtI5oAbP2LRgCbWrzhD6LNhybH0Wi3AAAAAElFTkSuQmCC)|Create Unique Key | Returns a UUID as a string with. "Length" determines the amount of characters returned. | -| **Monitoring** | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAPmSURBVFiF7Vc9TCNHFP52ZxbRnAQnJ3fgv1UiErmIlMKHCwoqXCAFRIloLFpMCtMQKXVKZAlCBaJPQ0FDh6BFsoKuhMR/wjj742Aj2cbe2ZcCFi3eBeMj190nWfK8N/Pem3nvfbMDIsJzP13XM6ZpztyPua7rBy7dkq7rS67xARFxIoJpmjO6rmf62ZfRB5IkRYQQQQAoFAocwAeXLixJUtg1/cP9HAghgpIkRfrZ7xvA58aXACQi8gjn5+fniOgXAKOpVOrrYrF4e3R0VFcURdrY2PhmdXX1LwBYWFh4CwD7+/s1ANjc3Pw2k8n83e12aXJyUo1EInxnZ0dwzv8dGhr6+fDw8I9eX9wvKiLaBhAEgHw+j0qlAgDvhRDI5XIA8D0AFItFZ8lXAJDL5SCE+O729hbFYhG2bcO2bdbpdN4R0e8APAH4nsDc3JxX+EIQEa6vr9FrV5Zl6+TkROmdzw3DyPS2y+LiIiqVCo6PjwcOoNVqeZwnk0lEo1HZNM1sT7AlLsvyRyFEza0olUrQNG1g50IItNttj7xcLjvp+NMtZ4xd/q8paDQasCzLV/dkCgBwh70cKIoCIQRs236x806n85xzKIqCQqEw7JarqmpJuq4fwEWv9zt5d3Z2hr29vUeGAoEAVlZWPA6ICJVKBZZlYXt725OGdDqNeDyOkZGRf3qWnvJAIPBTr8Hl5eWBUlCv15/cPQBsbW05KXjfq3s1E1qWhUaj8cnruWEYSz03GmZnZ1GtVh3SeRa1Ws3Tdr1IJBIIh8OyaZrrbjkRlV91As1mE61W6zUmBmNCdxG6C88NvyIEnm7DTz6BfoX3UnDDMDxtmM1m4deGDgYtvPs25IZhVHtUpxIReYhobW2t5UdEjDGMjo7CsiwwxnydXVxc+F1EUBTF2t3dfeOWq6pqcQCWqqqPzrLb7foaF0Lg6uoKNzc3T2/XB7Zto9vtQlVVT3HwWq0243x0OpiamoKmaTg/P/cYazabAzkHgFgshmAwKOu6nnLLGWOX3LbtH2RZfnQdRyIRcM49AbTbbQghBg4gHA4jGo1CluUf3XLbtt++uA1t20a9Xu9LOk9h0DasO3+mp6cxMTGBZrMJSZKQTqcfJiUSCSQSiYdxOp2GLN+ZjMViSCaT7gB8Gcs3AEmSfgVwDQDj4+MIBALodDrgnCMejz/MC4VCCIVCD+N4PA7O7xpqbGwM4fAdwzPGuoqi/Oa71X5PJ8MwspqmpYgI+Xx+WNf1qku3bhjGuutpVs3n88NEBE3TUoZhZF/9NPvc+BJA3wCIqMQYuwTuqBPAqUtXJqKya/qpw6qMsUsiKvWz/x9uEJRGaoWMHQAAAABJRU5ErkJggg==)|CPU Load | Returns average CPU load for all cores over a measured time. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAPmSURBVFiF7Vc9TCNHFP52ZxbRnAQnJ3fgv1UiErmIlMKHCwoqXCAFRIloLFpMCtMQKXVKZAlCBaJPQ0FDh6BFsoKuhMR/wjj742Aj2cbe2ZcCFi3eBeMj190nWfK8N/Pem3nvfbMDIsJzP13XM6ZpztyPua7rBy7dkq7rS67xARFxIoJpmjO6rmf62ZfRB5IkRYQQQQAoFAocwAeXLixJUtg1/cP9HAghgpIkRfrZ7xvA58aXACQi8gjn5+fniOgXAKOpVOrrYrF4e3R0VFcURdrY2PhmdXX1LwBYWFh4CwD7+/s1ANjc3Pw2k8n83e12aXJyUo1EInxnZ0dwzv8dGhr6+fDw8I9eX9wvKiLaBhAEgHw+j0qlAgDvhRDI5XIA8D0AFItFZ8lXAJDL5SCE+O729hbFYhG2bcO2bdbpdN4R0e8APAH4nsDc3JxX+EIQEa6vr9FrV5Zl6+TkROmdzw3DyPS2y+LiIiqVCo6PjwcOoNVqeZwnk0lEo1HZNM1sT7AlLsvyRyFEza0olUrQNG1g50IItNttj7xcLjvp+NMtZ4xd/q8paDQasCzLV/dkCgBwh70cKIoCIQRs236x806n85xzKIqCQqEw7JarqmpJuq4fwEWv9zt5d3Z2hr29vUeGAoEAVlZWPA6ICJVKBZZlYXt725OGdDqNeDyOkZGRf3qWnvJAIPBTr8Hl5eWBUlCv15/cPQBsbW05KXjfq3s1E1qWhUaj8cnruWEYSz03GmZnZ1GtVh3SeRa1Ws3Tdr1IJBIIh8OyaZrrbjkRlV91As1mE61W6zUmBmNCdxG6C88NvyIEnm7DTz6BfoX3UnDDMDxtmM1m4deGDgYtvPs25IZhVHtUpxIReYhobW2t5UdEjDGMjo7CsiwwxnydXVxc+F1EUBTF2t3dfeOWq6pqcQCWqqqPzrLb7foaF0Lg6uoKNzc3T2/XB7Zto9vtQlVVT3HwWq0243x0OpiamoKmaTg/P/cYazabAzkHgFgshmAwKOu6nnLLGWOX3LbtH2RZfnQdRyIRcM49AbTbbQghBg4gHA4jGo1CluUf3XLbtt++uA1t20a9Xu9LOk9h0DasO3+mp6cxMTGBZrMJSZKQTqcfJiUSCSQSiYdxOp2GLN+ZjMViSCaT7gB8Gcs3AEmSfgVwDQDj4+MIBALodDrgnCMejz/MC4VCCIVCD+N4PA7O7xpqbGwM4fAdwzPGuoqi/Oa71X5PJ8MwspqmpYgI+Xx+WNf1qku3bhjGuutpVs3n88NEBE3TUoZhZF/9NPvc+BJA3wCIqMQYuwTuqBPAqUtXJqKya/qpw6qMsUsiKvWz/x9uEJRGaoWMHQAAAABJRU5ErkJggg==)|Number Of CPU | Returns the number of CPU's in the current system. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAPmSURBVFiF7Vc9TCNHFP52ZxbRnAQnJ3fgv1UiErmIlMKHCwoqXCAFRIloLFpMCtMQKXVKZAlCBaJPQ0FDh6BFsoKuhMR/wjj742Aj2cbe2ZcCFi3eBeMj190nWfK8N/Pem3nvfbMDIsJzP13XM6ZpztyPua7rBy7dkq7rS67xARFxIoJpmjO6rmf62ZfRB5IkRYQQQQAoFAocwAeXLixJUtg1/cP9HAghgpIkRfrZ7xvA58aXACQi8gjn5+fniOgXAKOpVOrrYrF4e3R0VFcURdrY2PhmdXX1LwBYWFh4CwD7+/s1ANjc3Pw2k8n83e12aXJyUo1EInxnZ0dwzv8dGhr6+fDw8I9eX9wvKiLaBhAEgHw+j0qlAgDvhRDI5XIA8D0AFItFZ8lXAJDL5SCE+O729hbFYhG2bcO2bdbpdN4R0e8APAH4nsDc3JxX+EIQEa6vr9FrV5Zl6+TkROmdzw3DyPS2y+LiIiqVCo6PjwcOoNVqeZwnk0lEo1HZNM1sT7AlLsvyRyFEza0olUrQNG1g50IItNttj7xcLjvp+NMtZ4xd/q8paDQasCzLV/dkCgBwh70cKIoCIQRs236x806n85xzKIqCQqEw7JarqmpJuq4fwEWv9zt5d3Z2hr29vUeGAoEAVlZWPA6ICJVKBZZlYXt725OGdDqNeDyOkZGRf3qWnvJAIPBTr8Hl5eWBUlCv15/cPQBsbW05KXjfq3s1E1qWhUaj8cnruWEYSz03GmZnZ1GtVh3SeRa1Ws3Tdr1IJBIIh8OyaZrrbjkRlV91As1mE61W6zUmBmNCdxG6C88NvyIEnm7DTz6BfoX3UnDDMDxtmM1m4deGDgYtvPs25IZhVHtUpxIReYhobW2t5UdEjDGMjo7CsiwwxnydXVxc+F1EUBTF2t3dfeOWq6pqcQCWqqqPzrLb7foaF0Lg6uoKNzc3T2/XB7Zto9vtQlVVT3HwWq0243x0OpiamoKmaTg/P/cYazabAzkHgFgshmAwKOu6nnLLGWOX3LbtH2RZfnQdRyIRcM49AbTbbQghBg4gHA4jGo1CluUf3XLbtt++uA1t20a9Xu9LOk9h0DasO3+mp6cxMTGBZrMJSZKQTqcfJiUSCSQSiYdxOp2GLN+ZjMViSCaT7gB8Gcs3AEmSfgVwDQDj4+MIBALodDrgnCMejz/MC4VCCIVCD+N4PA7O7xpqbGwM4fAdwzPGuoqi/Oa71X5PJ8MwspqmpYgI+Xx+WNf1qku3bhjGuutpVs3n88NEBE3TUoZhZF/9NPvc+BJA3wCIqMQYuwTuqBPAqUtXJqKya/qpw6qMsUsiKvWz/x9uEJRGaoWMHQAAAABJRU5ErkJggg==)|CPU frequency | Returns frequency at which CPU currently operates together with maximum and minimum frequency. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAPmSURBVFiF7Vc9TCNHFP52ZxbRnAQnJ3fgv1UiErmIlMKHCwoqXCAFRIloLFpMCtMQKXVKZAlCBaJPQ0FDh6BFsoKuhMR/wjj742Aj2cbe2ZcCFi3eBeMj190nWfK8N/Pem3nvfbMDIsJzP13XM6ZpztyPua7rBy7dkq7rS67xARFxIoJpmjO6rmf62ZfRB5IkRYQQQQAoFAocwAeXLixJUtg1/cP9HAghgpIkRfrZ7xvA58aXACQi8gjn5+fniOgXAKOpVOrrYrF4e3R0VFcURdrY2PhmdXX1LwBYWFh4CwD7+/s1ANjc3Pw2k8n83e12aXJyUo1EInxnZ0dwzv8dGhr6+fDw8I9eX9wvKiLaBhAEgHw+j0qlAgDvhRDI5XIA8D0AFItFZ8lXAJDL5SCE+O729hbFYhG2bcO2bdbpdN4R0e8APAH4nsDc3JxX+EIQEa6vr9FrV5Zl6+TkROmdzw3DyPS2y+LiIiqVCo6PjwcOoNVqeZwnk0lEo1HZNM1sT7AlLsvyRyFEza0olUrQNG1g50IItNttj7xcLjvp+NMtZ4xd/q8paDQasCzLV/dkCgBwh70cKIoCIQRs236x806n85xzKIqCQqEw7JarqmpJuq4fwEWv9zt5d3Z2hr29vUeGAoEAVlZWPA6ICJVKBZZlYXt725OGdDqNeDyOkZGRf3qWnvJAIPBTr8Hl5eWBUlCv15/cPQBsbW05KXjfq3s1E1qWhUaj8cnruWEYSz03GmZnZ1GtVh3SeRa1Ws3Tdr1IJBIIh8OyaZrrbjkRlV91As1mE61W6zUmBmNCdxG6C88NvyIEnm7DTz6BfoX3UnDDMDxtmM1m4deGDgYtvPs25IZhVHtUpxIReYhobW2t5UdEjDGMjo7CsiwwxnydXVxc+F1EUBTF2t3dfeOWq6pqcQCWqqqPzrLb7foaF0Lg6uoKNzc3T2/XB7Zto9vtQlVVT3HwWq0243x0OpiamoKmaTg/P/cYazabAzkHgFgshmAwKOu6nnLLGWOX3LbtH2RZfnQdRyIRcM49AbTbbQghBg4gHA4jGo1CluUf3XLbtt++uA1t20a9Xu9LOk9h0DasO3+mp6cxMTGBZrMJSZKQTqcfJiUSCSQSiYdxOp2GLN+ZjMViSCaT7gB8Gcs3AEmSfgVwDQDj4+MIBALodDrgnCMejz/MC4VCCIVCD+N4PA7O7xpqbGwM4fAdwzPGuoqi/Oa71X5PJ8MwspqmpYgI+Xx+WNf1qku3bhjGuutpVs3n88NEBE3TUoZhZF/9NPvc+BJA3wCIqMQYuwTuqBPAqUtXJqKya/qpw6qMsUsiKvWz/x9uEJRGaoWMHQAAAABJRU5ErkJggg==)|CPU Stats | Returns CPU statistics: Number of CTX switches, interrupts, soft-interrupts and systemcalls. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAATtQTFRF////LYctK4ArKYAtKYEvKTE5KYIuKYIuKIEwKIIwKIIvJ4EuKTI5KIEvKIEvJ4AuKTI5KYEwcKBCcKBDb51BcZ9BdKFCfKRFgqdGhKhGiapIJ4EvKIIvnrJNpLVPKIEvp7VQq7dQKIEwKIEvKDI4KGwxKIEuKIEvKIEvKIEvKIEvKIEvKIEvKDI4KIEvKoIvKoIwLoQxL2s7MGg9MG06Ml1CN0lNOEVPOok0PYo1P4s1Q4w2RI02R2ZISI43SmVJSmtHS5A4TmtJTnJGUnJIVJM6WW9LWZY8XZc9YXdLZZs/Z5s/Z5w/aHlOaH9LaJtAaJw/bZ5BcqBCc4NOdqJDeaNEeqNEe6REfo1PgKZFhKhHka1Kl69LnbJNoLNOo7ROqbdQrrlRsrtStbxTyMRY1Mlb2sxc4M5e7NNh+0K73QAAAC10Uk5TABEYPl1eXmRlZmxvcHOOj5CQq6usrK2xs7W3vL3Dx8jJy8zNztTs9fb4+/3+KwNVbwAAAQtJREFUOMtjYIAAAV1dVS0mBkZ1PQhQY2ZABawquqp6yrzyYFkdJW09PjQFDDxABfrulo6OFnp63AzseoLYFBhmhCYnB+npcTKwYFdgEuHi5+esp6cpo4ldgak5EJgBHREYFSWGV0FUfLwUNgXGvvZubrZABXEpKbL4HKnnHxYmhE2BQZCdh4cNUEFSeroiNgVwEBIdLY5XQWRsrCTWkPSydnW1AipISE2Vw+tI79BQEWwKjIKdPD0dgAoS09IU8AZUeEyMBFkKCFoBd6RPaKgwWd4kGFAEg5pgZMEdGRAWJkpWgiGY5AgmWliy15LW0OPHn3HYsOcLWNbjYuDAUICSebWVtTAyL87sDwAH1W5FFYuAgAAAAABJRU5ErkJggg==)|Memory Stats | Returns memory statistics: total, used, free and percentage in use. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAT1SURBVFiFtZdbbBRVGMd/M7Ozt2Zv9AKltEIBlxRIFTBADJemWKJWIzaIgUajBjVKjPFBY3w0MUETgzHxgZuJASMkWMEUqYKAsSoRwcamstArdbttybbdNm23s7szPmy73WFml7bG/+P/fPN9v3POnJugaRpTunqr6wbg53+Qqqp0tLUiy1bl6Ue22KZ8iy5Kw44AwxNRlHg8ZeeIFoRZFtSAUXU6h0WUkr6miulxeoBJPdr6M4o92SSoGhUHryDG1VkBqBaRiy+vRxOT6NZonC+sJYY40eAAqjjd3/yOgVkXBxDjKvkdA6Y502U6AlOSYgmKm0KmbS6Pm6LS+wAItncxEhk2xBQ3hQiXeEnIUsYpNAUoahvA0T9CYeAOkpJI+d7ceWzf9RSL/cvwzPPqvokMDNEZaKXhxDcMhZM99/UMs/nzq4T8+YwXuMBfPDOA1Y23iUYndN5DWx/msT012Ox205545nkp37iOFQ+u4uzxU/x+qREASUmw6K9e7PZB8JfPDOBu7XrtRco3rptJKDa7nR0v7aG0zM+Jz47eM970J0zXmk0bZlw8XeUb17Fm04b/BuD2eamu3Tnr4lOqrt2J2+fNGpN1CrbVVGN3Ogy+GI3iO1OPo+UGAONlKxh88nHUu/4Pu9PBtppqvj58bG4AJctLjcUnJij64CPkvv6UZw314mxuIfje26g2my7eLIcuX6YGm91OfuF8g+8925AqHkqohBLJTUru68d7tsEQn184P+PKyQpQtKQEQTBuH47ALQDCqsa+yCj7IqOEVU3Xli5BEChaYtyCp5RxCuJph1G6NEvyUJEFsE8CyoK+baa5sgKEurpREyqipB+ksZVl2G+14RYEDnlzAHBOgoytLDPkURMqoa5uJNF8sDNOQUyJ0RfsMfiRqkqiy5emCk8Vjy5fSqSq0hDfF+whpsQylcm+CtpbblJYskjnaZJE6K03cF+8jKMlAMB4mZ/hii1oJr1sb7mZrUR2gAt19axevxa3z6OHEEUilRVEKit0vqyOoCESF5NTMzwY4UJdfVaArDthdGycuiPHsybQJdMmuH/wMLZEGIC6I8eJjo0D4PG5Zw8AEGhq5vK3xvVtJkXyYVFHKB36ksb67wg0NQOQm+fj+b3PzA0AoOHkaY7u/5RIeDBrnIZEmCXYEmEWjF5MFd/7ei0ej8v0mxkdxwCtzX9z4N332fLEdhb7l1G0uBjZagUgpigEO7vpDLQSuv4n+1/NYcdmJ00dVrbV7MHjdRGLme8FpgC+XC+hYJ/BnxiP8v3J0wCIokhB0QIA+oO9qOr0vbG53cqqUpl3nsujTc7h18ZrXDr/Czt3Vxlymk7BC688S35BbtYRUVWV3u4eert7dMUBfriWTJsjDRHtPMeZU+cMN6ysAC5XDnv31d4Twky5eT7WVu1mguQ94IGFQRbmSZD2ALonwFwhnDmO5A/ndXGl3Y2mwfVAlJqtTrTZAswFwuNx4fG6uN0Z5OODfxC8k2BRgYU7Qyrm5TMA/PTjbxz48BCKEpvTSAwORlBiGm9+MsD+YyN8dX509lOQrplCSJPHcW6eD4tFYiyq0fpPHE2D0mX3mX4j6F7HN7s6ETCPBBIJlZiiZAGwIMvJla0oMdTE9KPGIst0dbRhsVjiNVUVcsrX4xDN2kNJRHJkvl6ly2qVgVSd1FIVBFG3Zv8FQwDFpyPx1wAAAAAASUVORK5CYII=)|Disk Stats | Returns disk statistics of main disk: total, used, free and percentage in use. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAT1SURBVFiFtZdbbBRVGMd/M7Ozt2Zv9AKltEIBlxRIFTBADJemWKJWIzaIgUajBjVKjPFBY3w0MUETgzHxgZuJASMkWMEUqYKAsSoRwcamstArdbttybbdNm23s7szPmy73WFml7bG/+P/fPN9v3POnJugaRpTunqr6wbg53+Qqqp0tLUiy1bl6Ue22KZ8iy5Kw44AwxNRlHg8ZeeIFoRZFtSAUXU6h0WUkr6miulxeoBJPdr6M4o92SSoGhUHryDG1VkBqBaRiy+vRxOT6NZonC+sJYY40eAAqjjd3/yOgVkXBxDjKvkdA6Y502U6AlOSYgmKm0KmbS6Pm6LS+wAItncxEhk2xBQ3hQiXeEnIUsYpNAUoahvA0T9CYeAOkpJI+d7ceWzf9RSL/cvwzPPqvokMDNEZaKXhxDcMhZM99/UMs/nzq4T8+YwXuMBfPDOA1Y23iUYndN5DWx/msT012Ox205545nkp37iOFQ+u4uzxU/x+qREASUmw6K9e7PZB8JfPDOBu7XrtRco3rptJKDa7nR0v7aG0zM+Jz47eM970J0zXmk0bZlw8XeUb17Fm04b/BuD2eamu3Tnr4lOqrt2J2+fNGpN1CrbVVGN3Ogy+GI3iO1OPo+UGAONlKxh88nHUu/4Pu9PBtppqvj58bG4AJctLjcUnJij64CPkvv6UZw314mxuIfje26g2my7eLIcuX6YGm91OfuF8g+8925AqHkqohBLJTUru68d7tsEQn184P+PKyQpQtKQEQTBuH47ALQDCqsa+yCj7IqOEVU3Xli5BEChaYtyCp5RxCuJph1G6NEvyUJEFsE8CyoK+baa5sgKEurpREyqipB+ksZVl2G+14RYEDnlzAHBOgoytLDPkURMqoa5uJNF8sDNOQUyJ0RfsMfiRqkqiy5emCk8Vjy5fSqSq0hDfF+whpsQylcm+CtpbblJYskjnaZJE6K03cF+8jKMlAMB4mZ/hii1oJr1sb7mZrUR2gAt19axevxa3z6OHEEUilRVEKit0vqyOoCESF5NTMzwY4UJdfVaArDthdGycuiPHsybQJdMmuH/wMLZEGIC6I8eJjo0D4PG5Zw8AEGhq5vK3xvVtJkXyYVFHKB36ksb67wg0NQOQm+fj+b3PzA0AoOHkaY7u/5RIeDBrnIZEmCXYEmEWjF5MFd/7ei0ej8v0mxkdxwCtzX9z4N332fLEdhb7l1G0uBjZagUgpigEO7vpDLQSuv4n+1/NYcdmJ00dVrbV7MHjdRGLme8FpgC+XC+hYJ/BnxiP8v3J0wCIokhB0QIA+oO9qOr0vbG53cqqUpl3nsujTc7h18ZrXDr/Czt3Vxlymk7BC688S35BbtYRUVWV3u4eert7dMUBfriWTJsjDRHtPMeZU+cMN6ysAC5XDnv31d4Twky5eT7WVu1mguQ94IGFQRbmSZD2ALonwFwhnDmO5A/ndXGl3Y2mwfVAlJqtTrTZAswFwuNx4fG6uN0Z5OODfxC8k2BRgYU7Qyrm5TMA/PTjbxz48BCKEpvTSAwORlBiGm9+MsD+YyN8dX509lOQrplCSJPHcW6eD4tFYiyq0fpPHE2D0mX3mX4j6F7HN7s6ETCPBBIJlZiiZAGwIMvJla0oMdTE9KPGIst0dbRhsVjiNVUVcsrX4xDN2kNJRHJkvl6ly2qVgVSd1FIVBFG3Zv8FQwDFpyPx1wAAAAAASUVORK5CYII=)|Disk Partitions | Returns tuple with info for every partition. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAdiAAAHYgE4epnbAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAPxQTFRF////AAD/gICAUGCAVWOAVWGGWWSFVWCCVV+BVGGAVmCBV2GCWGKFVmKDV2GCV2KFWGOGV2OEV2OEV2KDVmGCVmKEV2KDVmCCW2eMV2OFYG2XYm+bVWGBVWCBWWWKVWCAVmGCWWSDWmaLW2aMW2eMW2eNXWmRXmqTYG2XYW6ZYW6aYm+cY3CdZnSkZ3WnaHaoaXeqaXiranmsa3mta3qubHuwbXyybXyzbneSbn20bn21b362coK9coK+c4K+c4O+c4O/dYXAdn+ZdobBfYWef43Ei5jKjZSqkZ3NpK/WqbPYqrTYvcThvsXh8PH08PL49PX39vf7+Pn8+vr8gyzqRwAAAB90Uk5TAAECEBIVFy1LTHd+gIKTvr/B3ujp7O329/j4+fv8/qyjigcAAAGdSURBVDjLdVNnY4IwEI24B7hRQYl1DwQnFKkaq7XWllr1//+XomIIqPclueTlcuM9ALBRYSaRyuVSCSZMgXsL0GxB6CudjtIXCiwdcF17oiVO1WsIiSJCNV3lSlEPee9L5isyQm8ITSaXRa7kkz77PpjhZ5qKCFO1GZ8J4veZ8hjd2bicsWJ4kvxIvh1vNredPOKT1zyi+Zn9zjDs/SwfvdRXquiPAXqldK6W5iT1MUCRONrsH+tInwSYxbAUCBf05wC9EAaMUJ0/A8yrAgMSffQ8AuonQEohD3bH0zfpKymQ64gT7K8O2+3JMIyfj4s7ETs5J2C5326PLoDzi6/9Yef6wpXkcuVOkhHqdpmLXrPZW9hl1s0yHY1qvEAIG85Gka2W4O+niZAcrTaHJWuW34LrvzWELcudyudhkeNuQ/j+CmHbOW4QwYQZwIsNMGEiV87F+fEAh8ABBmM+bpHWm8akHXa7Q0zatJekvT4lG6TpJO2xcOZX4czvhHOWXtGUXv0qvbopvaJTeqb5Y1lbvNmY/4G+qdBN/iFC/v+lrK3wtSxuQAAAAABJRU5ErkJggg==)|Boot Time | Returns time PC was booted in seconds after the epoch. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAdiAAAHYgE4epnbAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAPxQTFRF////AAD/gICAUGCAVWOAVWGGWWSFVWCCVV+BVGGAVmCBV2GCWGKFVmKDV2GCV2KFWGOGV2OEV2OEV2KDVmGCVmKEV2KDVmCCW2eMV2OFYG2XYm+bVWGBVWCBWWWKVWCAVmGCWWSDWmaLW2aMW2eMW2eNXWmRXmqTYG2XYW6ZYW6aYm+cY3CdZnSkZ3WnaHaoaXeqaXiranmsa3mta3qubHuwbXyybXyzbneSbn20bn21b362coK9coK+c4K+c4O+c4O/dYXAdn+ZdobBfYWef43Ei5jKjZSqkZ3NpK/WqbPYqrTYvcThvsXh8PH08PL49PX39vf7+Pn8+vr8gyzqRwAAAB90Uk5TAAECEBIVFy1LTHd+gIKTvr/B3ujp7O329/j4+fv8/qyjigcAAAGdSURBVDjLdVNnY4IwEI24B7hRQYl1DwQnFKkaq7XWllr1//+XomIIqPclueTlcuM9ALBRYSaRyuVSCSZMgXsL0GxB6CudjtIXCiwdcF17oiVO1WsIiSJCNV3lSlEPee9L5isyQm8ITSaXRa7kkz77PpjhZ5qKCFO1GZ8J4veZ8hjd2bicsWJ4kvxIvh1vNredPOKT1zyi+Zn9zjDs/SwfvdRXquiPAXqldK6W5iT1MUCRONrsH+tInwSYxbAUCBf05wC9EAaMUJ0/A8yrAgMSffQ8AuonQEohD3bH0zfpKymQ64gT7K8O2+3JMIyfj4s7ETs5J2C5326PLoDzi6/9Yef6wpXkcuVOkhHqdpmLXrPZW9hl1s0yHY1qvEAIG85Gka2W4O+niZAcrTaHJWuW34LrvzWELcudyudhkeNuQ/j+CmHbOW4QwYQZwIsNMGEiV87F+fEAh8ABBmM+bpHWm8akHXa7Q0zatJekvT4lG6TpJO2xcOZX4czvhHOWXtGUXv0qvbopvaJTeqb5Y1lbvNmY/4G+qdBN/iFC/v+lrK3wtSxuQAAAAABJRU5ErkJggg==)|Time Since Last Boot | Returns time since last boot in seconds. | -| **Windows Activities** | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAYlQTFRF////SUlJQEBANUBKM0dSOURPOEZQOEZPOEVPN0VPN0VPOEVPOEVQOEVPOERPOEVPOEVPOEVPOUZROkdPOkdSO0hUO0hVPEhPPEpXPUlPPkpPPktaP0pPP01dQEtPQE1eQk1PQk9iRE5PRFJnRU9PRlBPR1BPR1VsSFFPSlhxS1lzTVt3TlVOTlZOT1ZOUFdOUF58UmCAUmGBU1lOVVpOVmSHV1xOWF1OWWiOWmiPXGBOXWBOXWyWX26ZYG+bYWROYXCcYmROYmVOZHOiZHOjZHSjZ3aoaXmta2tOa3uwbX20b25Nb363b3+3cIC6cXBNcYG7cYG8coK9c3FNc4O/dHJNdXNNe3dNe3hNgHtNg31Nhn9NioJNi4NNkIdNlYtMmI1Mmo5MopVMqppMrp5MsZ9MsaBMsqBMtKJMu6dLvKhLvahLvalLv6pLwKtLzLRLzbRLzrVLz7ZL0LdL1LpL17xL2r5L279L3cFK3sFK38JK4MNK4cRK4sRK5sdK6MlK68tK7MxK7cxK0mXPnQAAABF0Uk5TAAcIGBktSYSXmMHI2uPy8/XVqDFbAAABeklEQVQ4y4WT1XbDMBBEN1AnDk+ZU2ZImZnZbVVmZmaGL+9DLclJnJN50vFcW+vdWSIhi6K6PH6/x6UqFoqW3emDkM9pj7CtjgDCFHBYjb7NjSi5bdJP8MrnTbP1+smbIN43+G2MDfKzV/+GVX4/sZMxNgQAOOgA3P91OISf3MsEsPVYBjiIiOyi/tQBJoG0mzMgYCciJ/fTh5kANvbR/jMKOIksvD85I4wDDY3FrzPYugZ8FlKAiklN0zTGNYiFh9z5l6LMnxZAIRXoZmEaAk53cbyN201AJRfQGwXU/GYvX2DvHHCRxwzAU1/LB9buAA/5TYGT1aSv6p53wB8DuJoRgOkVad9VzfwK0yLX7rF0qRepAm2RQO1nPw539N9UgJTKUCgUapWNWtnGxFuJ3ijRalTOySILnhd5q+WwUK4JYP1IDMswbpROcyAvQ47bEBgUTpkExhg55I9z4ERGLiy0wTHWFRna8Nhn1QWjYh9/ceKvXvzljb3+f9DtjCD/3H6zAAAAAElFTkSuQmCC)|Beep Sound | Makes a beeping sound with a given frequency and duration. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADhAAAA4QFwGBwuAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAL1QTFRF///////V/9vb39/f7u7d7+ff7uneU2KA8OndU1+AVWCBZG+J8Ord7+rdVGCAtbW5tba6w8PDVWCAVGCA7+rd7urd6eTZVGCAVGCA7+rd7+rdVGCA7+HU7+fZ7+jb7+nc7+rd8M/B8NLD8NXH8NjK8NrM8NrN8bKi8b2t8cW18peF8p2L8p+O8qaV8qyb84d084d184l2845785OB9I589JB+9JSD9JSE9ZeG+L6z+s7G/OTg/e7r/fDt/vj3vPTr0wAAABt0Uk5TAAYHCB4gLkREbm+Ptrq/wMDAx8jL2Nny+fz+OgMRSgAAAQxJREFUOMvFk1d3gkAQhbGgJpZYo4Jl7WC7YNkoov//Z2WWnACGIa/eF5j5vrMDC6tp8bz1TLP3rqWnZlJqabTYbHWV0G01i0ma1/WyGaas6/knXOoIIT4ioU5lpxQT2tQQ9WdBtCOeVbVoREIjaGRDIRfU/c8w/aCR+yMk8iJhNJuN/hHmWxdwt/M0wSKs4lq8MEGYCScMj7jcJCBvFxyHjDAFHM+X0vccYMoIFpRxvysOixFWarh8PL7UdcUItuK+R1PoxmaEBXCi+fQcJ2DBveYO5yvNd65n7Nh9GBx+t+Ew4Hdyufnhm2Xatxjb+/V6b49f8cNkDI4bmehgVDmhGjtZhUpiDaNSCNA3kY5X0ny9FscAAAAASUVORK5CYII=)|Clear Clipboard | Removes everything from the clipboard. | -| **Delay** | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMDSURBVFiFtZdPSJNxGMc/z7vNxKEEweYyyT8IHirCCiHnRVA204MHERSSIkjDW4eO0bFDNyG7FEbz4sFD2jx5cXWpIDJMEA9B5ByIIk20be+vw7v5b+/ed27zCw/s/T3P8/1++f2e3/ZOlFKcRNuLT5clqV6D6shKFgRZUE65//Hx7V8nM5ppeSL1sHTiAKrD4MyGuQGRldKJW3M6zRYje/53/vLIVrAxMeE+py4WIxzf5094rWwksuefMzVmNgMH2Ai/B3qKMQDM4g325kqaHsERrBcpbsthbUDxvWh5Gw4bA6oEBqw5bI5A/wLsFCG/k+bICdNbcABfzy7RcAhhFD0J8TxHwu0DzQmKEL6e3cINAIh6CfIAzeli8yf8XrSuv9QOlbUACaPXGna3ALzdS4gMAEnquqCmLXdtTRvUdQEkERnA271UvAEAT2AGJYNAivoA+Fqza3ytUB8ASKFkEE9gJh/q/AwAVAemEYYBnYbuzDYbqKyFhm4AHWGY6sB0vrT5GwDwBEMIY4gGdZ2H63WdIBoIY3iCodNQns6AYWICWKWy1ph0zZnZjdV07lSwvwW5oDmhrPLwc6E0p+6IhUeAJuNB0gFAUzp3hgZi4SEU4wfPIkZkoBgnFh46GwPR+X4Uk8d69IQRR/kUk0Tn+0trIDbfh6gpwHGwtrkM+ztGbC4frXYgaorYfF8+1NYvJAAbH66CfAVcqBRsrkD0M2yvHa873wjVt+BCM4gDIAHqht23of34KhlFcBHfgB9vIBE3r9teM8Llhiv3wO11oWQUeGRFb70D67MVaI519GQV3yZgd8PWLwAVXrg+AppzBz3ls/pFtJkB7SZQxdZq/uJg1G6tAlSlOXIrWBKJXAPyfw84ikxPhqMwAxjNfwswkOnJcBRkAHxAcTuQ4cgB01sgz9D85ZE7wcbyFneZDusF/kvTy4j/k5bwWqQ3suefU0/Rs7TMbkH788hdBZOFqZpDYHjxif/tyXXTI1BKNZdS3IrT3IDL8QpkoXTysmBwZuM/IIj31SOcmiQAAAAASUVORK5CYII=)|Wait | Wait for a specified time in seconds | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAdiAAAHYgE4epnbAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAYZQTFRF////VVWAUGBwk7ricY+ts9LsVVtzsdPwsdPvsNXwkrriU11zsdPukLnisdPvstTwkbrhsdPuk63IsdTvkbrhkLjfnLnUrM/skbrhqczskbnghIybgYmYhI+fqczrYmx+iZy0mq7EjazLkLTYkbrhpMblEaCFEp+FE56EE56FFJ2EFZyEF5qDG5qFHKKNJriZJrmZJ7iZKJqIKJuJKLWYKZqIKrGWLqqTLrCWL5mKL6+WMIF9MKqaMaSQM358NZuMNnx7OXl6O3d6O5CIPnN5PoWDPq6jP3N5QYSDQoGCQ294Q6qpRnl+RqiZR2t3S3F7TGZ1Tml4U190U2F0VF5zVV9zVmJ3WmJyXLi3XWuDXa+7Y2lxa36Ma6qzbbDFbnJvcL7EcXmLfJu7gYBshqrOjcTZkLrgkYxpkbrhmb/iocjnpMXkpcnppsrqrMrmsKNktM7mttDoxtjn0OLw2N3g3MRe3ODj4ufp4urv5urs5uvu5u3w5+zt6Ozu6u7v7PDx8NNa89VaAjYoZAAAACZ0Uk5TAAYQGiIoKkVSVGBoaGpzh5epr7Cyv8LZ3+3x9PX19fj4+fv+/v72WgpIAAABOUlEQVQ4T4XT5zvDQADH8dij9ib2uFrh7K02rc1VURRFY9Zo7dH8526kEnI53xd58/s8WU8iSf/lEJYqSahStq/GgcHTl30yBe+PEX6fOng5QvwiJuALhXwi4I1qWtQrAEENFxSAAAEBAUDhWCxsLGtWgPx+Yx9v81iBqUkAmue5YIMeZ5wAAOcUB6wPuPHR0wJoExaw2g+hG620Ar2RP2CpF+Jm28k2uk3av3+oK8iIg4UuSOshYO7w9AJ3dd1UkqODaRivm55/V6U16JfYdEEjKhYZqGdgb8y0w84+DDrOKKhlYHnwV8NDiqIckP28ioIPXq+3qnr5LIu+ybubN/Ye+G0dq+rJDsIgkV8xuYeK5AS73ympkT5Fpt0uZbP3UGQL8hgos5nT80uraeWFuVyQkvVTGheY+wbSNPGqGcWrQgAAAABJRU5ErkJggg==)|Wait for Image | Wait for an image to appear on the screen. Image path needs to be specified | -|**Browser**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAATxSURBVFjDtZdtTFtVGMcbE3X6QZN98ZMfjNNs8wvGmC37MNqhQTOXTF5K14n0BQryIkPasbjgwGUONZlhY1GMQ7ZoFhbdBoUEJkszmAX6XjpeSim0pR3U8dJCX2/b+3junZ3QXe+9Bdfkn6bNPef/e577nOecwwEADis1NDzlKBfsc1YIm5C6HBVCM/r2z5QLIrYygddaKhgcL+FfHSvhS3Qy2fNs52V8YK4m/zlnufAUMltAAiZNlRXAveL88GhxXr9FdvjVLQE4K4X5rgqhk40xFYhRmptAIO1pA8yVf7TDVXFEtRnj9ZotPwIIAMzS3EWrLHcnKwDCHA32bNV8vSZkfDBJ8sJUEBt+OCoLX0EDXP+neVKoOEkIe0nB65QAtqr3n0UP3nsS5klZ0OswSfMeUAKc7ni31vapIPgkAYia0EtywSLjt20AqPvjnRflSu7yxbb3BtKZ0PWZBFzVRWlBWEsLQC/Owa0lBW8/Aqjt4n2BAAApYq7ju+kmmG86uYi5ZnU4Fp1FYxMAeByi3lVYGYjBpCKKmkCESSGdOBHUiS0kQMO1/GeQ8co/APBlR5aG0ryqENYG+s1oELYSjkHf9DJ8fXcOztxxwC/meVgKYogFC4P7UhyZAJ0wkwRWR4pgabjqBU5tz4H9SfOkbp/OMacCBDR/TiFzuDG5CHt+MsKui7oN2tuqgUt6D5Afz+UlOgDcUkwChPTi4xxFd2ZjKkDdTd60o1KYSJp7z5+xEeluNy08ZrxeO5uH4AeNi0DwgfX4DB1EUCuCkEE0wkGGqlQAQr9eOHg3CRBfWbI7fRF4s9VAC0Aoo0UNC2tRgOCUng4gbBBDQCvyEwBTVAAKtCqsNQKfq/rjOIoo2qLxMJqTWTg/DGfvzKB6iE7TAUQQAMpCAAFkLlEBEPruSvbg/Lf1BADIlDZWALtaNMC/aiKGxGG8ghYgoC0KERnA/gsAKW5r/2qemO3o9UmWAFo4dEX/sBgnjtEDaERhIgMeGgA4qzw8iqbCm9CSY/sKTvRNEe3Bw/QKUA1EiAzo6AAIhWMB97B7lRXA7mY1aN1+gIh7lEUR+jiKrsxWJoDfR8/9RWT089uz9NFfGIFPOseA7JCz33jpAALEMtSK1Rx5N+8gEwCh+377TBBLwIl+aog3UPEV3xiDGI4D7jeq2TSisF7UwGlQcbehOggyATTe+hC8ay47Ed6A0wenVA7IuzYO/GtjUNtrg5vjXrLu7A+0k9Gx0hBTK17TFOF+tXQ7uRkhg+tssqBQ8qB7/Pt5LB5ZhpQPqhPPZW39okqdO8y0F5BdUC/WPtoN5T28PWwANmYkB37Wnlz5cUi+XN/7Aflffc+BMZzBPD4qJdMfM4gzNxxI2BQjg3C7VmhljF6HoteJJh47ET2sBa5pswDn+rLVTOZRo4Rc+yGN+GXKQ6lCuf+19WeDNBTwmUWLTIWHOh8WMIoyaI/lih5uBtqIFtIB6FAdGqQzj5kJ86IYZi7ey+piUtPJ3YEmnmRjXtfNm4tZpBjlev+35a7GjOJ9aV3NZLq3npZ3c48Rh1U6gCE1X08dtZTY7XBUcAOgEm3b9OW0pjd7O2pUzVS7ZmNPlinVOIGWGerzUWQ8FDWId2/5dpxUdWfWS7VK7lG5ktemUGbaUVMKOnWFE6it3kemVswkNURNkt8iBkkZXcSp+hvVyR7B5rfKEAAAAABJRU5ErkJggg==)|Open Chrome browser | Opens the Chrome browser | -| ![](data:image/png;base64,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)|Browse to URL | Browse to a specific URL. Browser needs to be opened first | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAQOSURBVFiFvZdbTFxlFIW/fc4AA8jVGGwlQsMQoEUrCTZUW6ORay9EILWNpok+SOKDjbZRmthETeMz1Zroi40xMVW0qZRLaSnipZq21igBCqU2Ek0rpQ9cLIVh5pztA1hhOmdmwI7r4Tyctc5e6/+T8/97i6oSEYqLYybSXNWirEXUg+JB8KDEAqPANYTzYhmdPrd+nd5+ZjKSshIuwPgTRammGVtvwy6B+yJLyw0VfTslZqyR9kve5QV4S4zJ7x5+A2Q3cFeExoG4LCJ7kjrPNC8pwFhZcYqprsOgVcs0DkRHspVQQ3f3TCDhCnwxWV6Sa9quY4jm3yHzCdR+N5g5BOzAVGlJhqXai3DPHTIfEtuuTvrqx4tOgkU7YIkegvDmCldEGUR0EBUbEQ9oPrBqgeyEbc3uSO3+eTxUrVsBJsrWvSgqm0KJBbpR3Zfcde6HYPx42frHDbX3AEPJ6Vmv0dRkhVuMqCregxk53pasHmxJdNDdFNUdSV3nWsIVXCoMADN/tD5u+8VEifcHNVdlazTMAUSbMP1p/A6s1PE4vEdysa8nLBBQm9R19mg0zAEM627KgZUAkurFvXMAM28MAIVvo2kOYKhF5aI3sRZxNZdwrRu5JiIN0TQHEF8nzUB1EG7EVaorwhWoOTDzqahsX6b/9waQ7UAOLLNo5BDuNYCsoJxwIer+Ohcg+HWoc79oNKFgG8CwA/lgtAMAVx0DAIX/RwCXU4B+Oznp1c4NxSfLTp8PVUHQd8D40llhrwXZG/xb+sXfyWaF1oVEu72Cfb5Cexaje3BzR2m4ZYRCbaP3NPBoME7FKDLMMTqAKwA2QqM/lwbfA/gQQ9AnC1orti7XvK5x9hknc0HOHn055heDbWoBH93AxS7fQxyyVgUqP1ndXvHYUs2fapzZqNgHnXhb7Q9g/jacst0f1s4+cv0bO2gvkqTK8YL2ii2RmtcdmNlpIKdA0h0k4zHi/uxWgJTy6d/+VPf+EDUTUFoK2ipOFrRWrXcSrWmr3FjYUvfFlPvCx0CsczlpbHqFaQjoCQvaKptBg90LgRhGGEJ1aK4l0xyQ1cy3ZKImGaP1pE0EaapVDx/d7X5W5w/ART2h6eJ5y08PkBkmQDZKNkg5Asw9/vUQi5GM9/G6h8kYrUfU/Ifqdv3lfk4XnL63zQWFxyo9lmk3z6/oPyNheg2ZV/di+lP6XL64DU0NTCzkbzvv+6o7flUrvkTAcZpZCm7G9/NH5ps/SYxdFWgOIUYzQSSvvfx1URpY5mgmcFlFGgY2dRxx1IQbTnNOlaXEeo0XgJeA+yMxVhgX1f3mdOp7fduaZkOGjHQ8l8+fNvMSJ7eIrUVArggeBQ+KH+gD+sTQXkT7Ykyjt6f8xFQkdf8GbfON88yeJlUAAAAASUVORK5CYII=)|Google Search Links | Return a list of search results google returns when searching for search_text. | -|**Applications**| -| ![](data:image/png;base64,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)|Process Running | Checks if given process name (name) is currently running on the system. Returns True or False. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADhAAAA4QFwGBwuAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAt9QTFRF////AAAAAP//AID/gICAAKqqVVVVVaqqgICAM2ZmM5nMZpmZVYCAbZKSIJ/fYICfVY6OGrPMTWZmLqLRXYuLK6rVaoCVJKTIW4CSIqrMQGBwLaXSaYeWR2NxQ15rPWFtI6LRZIWQKaPMJ6fOQl5xXoSOPmFyZoCRQGBwYICPPl1sZIOTRGJxJKjTZoOSI6PVQFxxPmBuJ6PRZIOPJKbQZYKOKajRKKTSJ6bTJqjUQWJtJaXPJKfQQmFwKKXSYoCOY4COJafRQV1vJKbSZYCRJqfRQV1tKKfPQGBwQmFwQF5xZIGQJKjQQl9tYoCSZYGQJqjSQl5wYoGPJqXSQV9wY4GPJ6fRQV9vJ6XSJqbSJaXQZICPJabRQV9uJqfQJqXRQGBuY4CRY4CRJ6XSJqfQQmBuQGBwYoCPQWBwJ6XRYoGQJqXSQmBuYoCRJ6XRQl9wZIGPJqXSY4CQYoGRJafRQV9vZICQQF5uQmBwJqbQZIGQY4CRZICRJqXRQV5vQF9wZIGPY4CQY4CQY4CRQV9uQF5vJqfQJabQJ6bRJ6XRJqXQQV9vZICQQV9vQV5wY4CQJqXQQV9uY4CRJ6bSQWBvY4CRY4CRJ6bQY4CQQV9vY4CQJqbRJqbRY4CQJqfRJabRY4CQQV5vZICQJqbQJqfRQV9vJqbRY4CQY4CQYoCQZICRJqXRJqbRQF9vJqbRJqbRQV9vY4CQJqfRQF9vJqfRQV9vQV9uQV9vJqbRQl9vY4CQY4CPQV9vZICRJqbRQV9vYoCQQV5vJabRY4CQJqfQY4CQJqbRQV9vQV5wQV9vQV9vJqbRJqbRQV9vZICQJqbSY4CQJqbRJqbRQV9vY4CQYoCQQV9vQV9vJqbRQV9vQV9vY4CQQV9vY4CQQV9vY4CRY4CQY4CQJ6XRQV9vY4CQJqbRY4CQJqbRY4CQJqbRY4CQQV9vQV9vQV9vJqbRY4CQJqbRQV9vJqbRQV9vY4CQksOaGwAAAPJ0Uk5TAAEBAgIDAwMEBQUFBgcICAkKCgsLDAwODg8QERESExUWFxkaGxsdHiAgISEiIyMkJCUnKSsrLC0uLy8wMTIzNDY3Nzk6PT9AQEJERUZGRkdJSUlKS0tOTk9QUlJTVldYWFhaW11dYGBiY2VmaGhpaWlsbG1ubm5vcHNzdnh6ent7fIGEhoeIiYqLjo6PkZKTlJSWmJibnZ6foaOmp6iqq6ytrq+wsbW1t7i7vL2+wcPDw8TGx8fJzM7OztDR0tTU19ja2tvc39/g4eLj5OTk5ubn6Ojo6ers7e3u7u/v8PDx9PX19ff3+Pj5+fr7/P39/v5x/W0zAAACKUlEQVQYGZ3Bh1fNcRgH4E/phojKHtcekYxs2WRk773ntTMLybgk3GTL3ptsUfZKGUkkGtyklNt43+8f4Lcc5+h2juN58H+af+lkt9oNhah5Ze5pkfpATEIhSn8VIjdZiKfLF8GaAWtF6oyyaHxEiLOwouJ3kdsdsoNiDf6YcsAZtpAtFMegqC8+74OiwmIH3VXyqxJ0vRbgtF2shCpenCsKWRCFx5EsrxKwQogtUJTMeg/VWPrN37lj1cnisSNkY8S3/pBMHRhDFDa7y8iN6UQZPzyKxYtdJQC0jBURswB4ksS/CCQtnhGFleojMsXddUt3Z4qtkOn2EB2GyiuHdgBuDV4LSXLWXih8iFpDc4E+GmoAd84siI1w6lwXstHhZNZBE0hEBsCxPIYNhsZMZNZBE0i0yR1A9ZnF0bUXFBNOEbWC5jy9hWwOmyY+T4GqCdF+qLrlUJw72gUPus0SS0CPABsAffOI/Gwh8XhCRIdgZIkliSU/XQEcJ8klg+eQwHSikHlt4M38YqgLGu7M5xuQ1PZq/5I092xRxzeSo/WQLWFe1Q+yEFI8yskog/nMPAIKm5vMryDb8KZtzxgaj+GjAPtgtrhAZeSEDlA4AD4nykExnZOg8eWHKKD3O2ZXqELZYsLfvKOyeRsUTdM4+zIKMnL+MhsAzSI5UQ8rpjHzrfW+oWnMF2HN5pRrrPh0P6EyrLDTw8SJUfyhmn09FGJcdCMcPYl/8gu/3CT6fsf/DgAAAABJRU5ErkJggg==)|List Running Processes | Returns a list with all names of unique processes currently running on the system. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAGFAAABhQFFWZ5CAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAjdQTFRF////AP////8AAICAQL+AzGYz/8xmK6qq1VVV20lJQL+f32BA379gOaqq41VV6NFdQKqVO7Gd605ON7ak3VVE8MNa5llNOq6iIabTQ7GbJ6fO68Ri7MZe5FtJ7cph78Va31hQPrKbPLSe4VpL8Mti4ldJ8MVfQLGc41VOPrOfO7GdQLOf7chb41lO5FdM78lc78VgPbOeP7KfPLWe7chgPbGg4lhL7slcPbKePrKe8MdePrOdPLKe41hMPrSf8Mhf4VhM8Mhe8MZdPrKdPrOe7shd4lZN7sZfJqXRPrSeJabSJqfS7sdf4lhM7shd4VdLPrKePLSf7sdd4lhL78he78de4lhMPrSePbKd4lZNPLOf41dMPbOf7she4ldNPbOd78dePLOf78ZfPrSd4lhMPrKe7sZd7sdePLSf4ldLPbSf78de4lhL7sdeJqbSPrOeJ6bRJqfR41ZN8MdeJabRPbOe7sheJqbQJabS4lhM78dePbOePrOe78dePbOe78dd4ldM4ldM78de4ldNPLOe4ldM78dePbOe7shePbOe78ZdPbOfPbSe4ldL78de41dM4lZM78deJqbRJqbSPbOf4lZN78ZePbOe8Mde4ldM78df41ZMPbOePbOePbOe78he78dePbOePbOePbOe78de4ldM78dePbOe4ldM78dePbOe4ldM8MdePbOePbOe4ldNPbOe4ldM78dePbOe4ldMPbOePbOe4ldM78deJqbRPbOe4ldM78de2NHQUwAAALl0Uk5TAAEBAgQFBQYGBwgICAkJCwwNDQ4PERQWFxcaGhscHR8gISIiIiMjJCQlJygqLi8vMDI1Nzg7PT0/QkRGTFFSU1RUVVZXWFlZXl9hZWlra3B0d3t9fX+DhIWFh4eKioyNk5SUlZeZmZqcnJ+jpqiurrKztLW4uLi6v8DAw8fJysrN0dHS09PT1Nja3d7f39/g4+Pk5ubm5ufn6Ojp7e7v7/Dx8vPz9PT19fX39/f4+fr7+/v8/P3+/v4kxybzAAABzUlEQVQYGW3BCV9MURgH4P8NEVPKVrJFCJF937KnQfYlZclSWdIQDSK7LIVuJNmXkH2M5bzn/XDuvefMMfObeR78N6Bw18n7f8Kdl6pXD0K83IPvpPGpegJipe0Jyxjh3SmIMu6qjHM9B0ZBp0zg4RRoaR0yoY4caMdkYpf7wJWPER9kYtvhGP06H1ukp7lkzhDEOUSn0e+elPLb+l5IIP0N0SIUSvljMSx/wLYDfgsLXrxUbgMriOhWb5yVJcgOCk8wGxWsTcZ+cmxEQXOKFRRa0PI1sbIODeR4lYlc+IXhRzkrx9FGrioAAWEEsJSVB+gm16/pgC0MG8NZeYtu8pwHbGHYGMnKZ7STMhu1wqjFKlaeoIGUvSgWRjH2sdKIA6Tc6YF6odUjuYmVCqwkbQey6oSnLguVrC1HxntSfi8BimpaW2uKgA2sfewPVJH2dWcqlKkh1ioB5H2niLubFg4dmAmcYy00Ho5SijEfyzhiK1x9r1GUE/C1sHYqCZ68p2R8GYPNrLUMhjbjGUWUYlgXK4+nwZh4k5S2dBxl5cYoREkt+0mutZj1l12hch9iTTrynOiilXSBHV2HxyJez3llM7Hm0ZUz2+Ymw/gHCcDUlYiUSq8AAAAASUVORK5CYII=)|Chrome Running | Returns True if Chrome is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJPSURBVFiF5ZfBaxNBFMZ/06SNSWgSCYlWLaKEgqGtUQ9GBYMXPdSLIkYUBU89NEdB/Au8eKwiOXloESnipQj1JCikVakHoYJtaT2YYtK0SbRpmjYZD0sXw65Ns+xaxA8GHo+373188zGzI6SU7CTszRSLqyM2v3dPl0BGEEQERJD0IkhlkrHLphLYe+uVW7ocvUgiKIMiAV+wG6SrnhUAl4wMVwkE+t90CFlTBm2uXY4QNVqMNt42gWD/60EhxYDVg/5IAJOG5/LF5t0sGbNc4i0huLCzBMB6kzVCU+fAVui5/7VhzZnDTh7Hg3W5f0+BoYEwUkpuPvpcl/9076D5BISABzdCANwZnsHjtHMu7KNUqRoati0Cw4kwArg+OEU05OXaKWXPnr/LsvRzHYCF5YqmkWkeOHGondgRH4H2VuLRgJqPR4Ps2+1QCOS1BIxCo8B8tkxPp5vwATd9x/1s3tZ9x/xMfVtRCCyvaRoZ9YBGgfnsKgCJ8/txtdkYnykyMVvE2dbC7VgHAGkrFZjLlAE43eUFYGQiA0A05KHTr2xBWkcB0zwwly2rcalSZXQyx+hkrs75aR0TGoWOAqtq/PLjEitrVTW+clIx5ULeQg/8rsCz8YxubKkCiz/WGXr7nVabIDVdUPOp6QIv3i9S2ahRKG1oGhn1gO5JePfprCYnJSSefGk4pFmYdhua5oG/jf+cgGTMjpAPzfgz9vs8wsh3Qkqp/zCBEE0olEnGjBPQg97TTEI34NKrN52AbrHe4xSOgviQSZ69aDkBK/ALoL3X0FprEyAAAAAASUVORK5CYII=)|Word Running | Returns True if Word is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK3SURBVFiF5ZdbSFRRFIa/deZMMSMNRRcpsQKjJM05mV0eIqKo6AoFaYZRCdFDPVRUlGbSRFDRTSsiSrrQg0gXoqsS1psPOVJaVEZQUJAPQcRgZTirFx3IOQ7M8agPfU+bzdp7/ftn7X3OElVlMDGTCc7Pz/e8mfJhsmGoJSpWFCyBHIWG5lB4jasCgnuCKerz5IgalohaKmqRKdkG+FFBAemKFVjtJHlMQF5p3tgOM2pJ1LBU1BLEwmdOEjAQRQFUEu/kVIBVPuOcetgmKiDadaqBqwtTlW1ubPTt+4/kVSu1hhvJHSMsGVwBwKALSOodSMSKK8tj49y0XEKLDwNwsK6Mpi9NcfPdJOWAz+vj8qaLVBae7qveGLYOnFl3kpShKeys3k3kdyQ2X7ayBCs9yKsvr+PW3N/8wDZBzxP3xNaBgC/A9PEWJ/KP4fV4ASicVcDirEW0d7RTfjeUcNNkkJyy3Lj7mxpI5WpxFaOHjeJRSy23m+5wYcM5TMNk78391L95GreRf4Q/Nu5zDbT9aGNH9S7aO36ydNoSzhedxTRMrjfcsE3eF2wd6Gbe5LmcKjgBQGvbe4oubSSqUdvY+l3OhCW8BVZ6MDaeNCaDORmzHSVJRK8OLMicz/G1R+mMdlL/9hmLpi6kveMnW65t5d3X1rh4V2tgwsgJlK8qA6DiyVn23yrlYctj/EN8VBSeIjWQ6uSwttg6cLW4iuy0LOpeP6Hk9gEAvB4vletPM3NiHs2fWyi+suWfNa7WQOR3hOcfGzl870hs7k/nH/bU7CP8qYnIr4jdMkckvAXJ4GoNDCSuOdAv78BA8J8LUGpNEc678Wc8cnjAUeNgvDgU3u7tlHEqugyVEoUakFbA/qvjMtJbc2rbmqlkA367+JehsCMHehVgh31zqkFFGptD4RX9LqA/+As0xAKOOpJXugAAAABJRU5ErkJggg==)|Excel Running | Returns True if Excel is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJSSURBVFiF5ZfPaxNBFMc/s7vZpD/QgBTbIuIhSA6lLtRY0OJF0B7EooKX3vWgBBsxxx7qTdRKo4f+AUJPQkou9VhapI3eewgIHhqlFmtIiKTJjgdrNNlJskmT9OD3tLPz5r3Pvpk3OyOklByljKas7wh9d4Czmo6FxAIsDUYlvPfH5K22Anx9LPo8eUYFWAgsARYnGdGhl3+SdvB4s5XgZYBvM2JILx58lYYlJJYXAgi0Vh27BtgLi1eG5D4AAujykjD4E/yQ2t3LNI8uWel4iutKcK3jAL7FIGZ8Gm17Q9nfcQCRTaOnEniXJjE25zsLoG1vYMan8S0GnZ3SxrM258hE2wCMzXm8S5PoqQQim1YbSRsjuVA5rpZD390EevDq37GZNKXUKoXlKDLjDOBZmwNpNwTVvnysaIvvD9SV3/eioHQgszvkn513QJj+Srv8ox8NYcDFFOQiJrmISf7lJUqf1hH9A5g3nrpy7kauf0b25ySFeJSeh+vogcsN7XueH69oy/4hft7bcth1bSOyB8eU710DaKdDmFO/U19KrToNRB1XQqMYCiu7Gk5B9WKU2R0Ky1GH3f7ErLoShMb+xCz28HhrAOXADcqweGEG+9RFjORCudTswTGKoXDN4K4AchHTLSP28DiFqTeu7aGLi7CWmjsT1lF12alUOnOFwu237gBKW+8OT+VCNbfiZlV64m7rrdaRr4H/HECyYiB43Y6T8Qn/MdHKOCGlVF5MgABNZMgfk60DqKS8msEI0NsVAKUUl1MB54AP/pi83nmADugXDe3JaeTa3qgAAAAASUVORK5CYII=)|Powerpoint Running | Returns True if Powerpoint is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAD+AAAA/gFPwqL+AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAUFQTFRF////AID/AKr/AID/AJn/AID/JJLbIIDfHI7jFYDqFInrEoDtEYjuEIDvD4fwDIbzDIvoF4voFoXpFYDqFYrqFIXrE4TsF4PoF4fpE4bsF4XoF4joFYfqFIfrE4fsF4boFojpFYjqFYjqE4fsFofpFYjqFIjrFofpFIjrFobpFojpFYfqFofpFYjqFIbrFIfrFIbrFobpFYfqFIfrFIjrFobpFofpFYbqFYfqFofpFYfqFYbqFYfqFIbrFIfrFojpFYfqFofpFYfqFYfqFYfqFYfqFYbqFIfrFIjrFofpFYfqFYfqFIfrFobpFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYjqFYfqFIfrFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqFYfqB9umyQAAAGp0Uk5TAAIDBAUGBwgJDA0ODxARFRYWFxgYGRshIigsLTEzNTc6PD5CRklNU1pdXmBob3BxcnR3fX6BgoOEjJCSlZaXmqCmqLK0tbq7vL3Fx8jJytHT1tfZ293e3+Dj5Obp7O7x8vT19vf4+vv9/sqCUaEAAAGISURBVBgZfcEJQ9JgAAbgl5UzL2yFoHgxsZlXSiTeigdgljQxlVQ0sIZ7//8PaOfXNzyeB6HkACQDSUSpa+1GFkK20V5TIcnUSLYXEVhsk6xlEOrZfKCn2A1Hd5Geh80eeKbrDFWTQLLKUH0aQLxIyXVv7zUlxThMyg4V5ZAyEzmbQmMWjtkGBTsHGHcM7GvwaPsM3BlwjJzRdWVAMK7oOhuBp79E2jt9kPTt2GSpH4HYytEUOkwdrcQgJHQ8oicg6DesDCNiuMIbHYEFi2RrWYGgLLdIWgtwde3SVx1FYLRK324XkDhmyFpV4VBXLYaOEzApOc0AmVNKTOQsSqx43KLEygHpEwp2QVEKNoWTNByxpRZ9zZmx+q+JmSZ9raUYfKkyXefpj/fkn7n0OV3lFP6bvyXLg+v0bLwtk7fzkKnvt/NahYGvWn77HSLM7+OTFxQuJ8e/lSDbYif7CyI+/GTEDx0d1Pw9hd+fXuGx1AEDe0N4mnFBRy2LZ70p/G1+fo2XDGmI+gcE+cSpR+i0owAAAABJRU5ErkJggg==)|Dropbox Running | Returns True if Dropbox is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAGFAAABhQFFWZ5CAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAjdQTFRF//////8A/6pVK4CqIJ+/34BA44455oBN64k7JJK27YBJII+/8Ic8KJS8JJK26opA64lF7IRC7YQ+8Is+6YdE6YpCI5W/7IZA7Ik+7YhB7otD6oc+7IlChJKAIpK8IZS8JJW97YhB64hB7Ic/7IlB64hB7IhAI5S8I5W97IdA64g/64dB64dAIpO8IpS9JJS8I5O97IhAJJS8I5O97YhB7YlA64dA64g/7IhAvotb7IlA7Ig/7IhA7Ig/7YlB64lAy4tU7IhA7Ic/7IhAI5O97YdAI5S87Ig/54lD7IlA7IhA7IhA7IhA64hBI5S85IhF7IhA7IhA7Yg/64dA64lB64dA7Ig/6ohBLJO2JJS8pYxsI5S864hA7IhA7IhAI5S86ohB64lB7IlB7IhB7IhAI5S87IhA7IlBI5S87IhB54lDI5S8JZS7JpS6J5S6KJS5KZS4LJO3LpO1L5O1MJO0MZOzMpOzNJOxNJOyOJOvOpOuO5OtPZKsP5KqQZKqRpKnTZKiTpGhVZGdV5GcXpCYX5CXYZCWZ5CSb4+Nc4+Keo+Ge4+GgI6Dgo6Cho5/iY59jI57jY56jY57j455kY14lY12mI10mY1znI1yn41woI1vooxupIxsqIxqq4xorYxnsYxksotktItjtotivYtdv4tcw4pZyopVzIpUz4pS0IpR0opQ04pQ1IlP1YlO2IlM2YlM24lK24lL3YlJ3olJ4IlH4YlH44lG5ohE54hD6IhC6ohB7IhAnHmEdAAAAGt0Uk5TAAEDBggICQoNDg4QERMVGBobHSEiIyQoKSsuMTY4REVGR0tRUlpcX2BgZWZob3BydHh5e35/gIGDhoiJo6WmqKursbLAwsPFxsbL0tTV1tbW2t3i4uTl6Ozt7e7u7/D2+Pj4+fv8/Pz9/f4/cRJLAAABsklEQVQYGW3Bh0OMYRwH8O+dkb2SPVNky6ouZIVCRdlbVn7VOaKMEIpIJUoRmVmJznbfP87zvveOp3OfD3TDpiUtWTxr6lBENXjhhlNiOr5+/kDoPAD6LtojtpLKa7sX9IHDmwKMyRHdza7g3smwzTngnbJPRMob6v0SVt1Gnl49BGGbmXZIzsitYEeJWMrqv5PMHQTTQYbaP/APeV1cgUckN/WDEkPLj4Do7pNMhxJH29vzomsiD48C4KPjy5NacV0mmQGMP0ZNi7ia35P7PUinprlUXJ1U4pBJ113RtVNZini6HouugUo2kmn5++rzG9FcaKGShyxaWkXOiqbxJZWd2ELLx4vSS1cPle1YQ9unKyJSeadKwr7SsBGpdPxsa+wk+VRM32hYgURG6KgTxV8RomE2Youo664RQ+BhLU0jgJW0BVsf3CgWg//1s24a1gEYW0Tbi0tiKn7O3zQUjoayio5f966Wyrnb72hJhWHcUWpCPXQUxMA04ySjS4BlLqM5MhOOeYX8z65J0EzcxgjZI9HLgOU7qNma3B+RvPFrT9CU75uA6IYnpvh8y6Z7oPkHHsPKXk8cBH8AAAAASUVORK5CYII=)|Firefox Running | Returns True is Firefox is running. | -| ![](data:image/png;base64,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)|Teamviewer Running | Returns True is Teamviewer is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAEbAAABGwGN907lAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAVNQTFRF////AP//AKr/AJn/AKr/AJ//ALPmAKrqAKTtAKruAKXwAKbyAKrzAKb0AKr0AKf2AKruAK3vAKfvAK3wAKjyAKjzAKrzAKzzAKjzAKz0AKj0AKrwAKjxAKrxAKzxAKjxAKryAKvyAKvzAKrzAKn0AKrwAKnxAKnyAKvyAKnyAKryAKnzAKnzAKvzAKrxAKnxAKnyAKnzAKnxAKvxAKnxAKryAKvyAKrzAKvzAKrxAKvxAKnyAKryAKvyAKryAKrzAKvxAKnxAKnyAKryAKryAKnyAKnzAKnxAKryAKryAKryAKryAKryAKryAKryAKrzAKryAKryAKryAKryAKrzAKrzAKrxAKryAKryAKryAKryAKryAKryAKryAKryAKryAKryAKryAKrzAKryAKryAKryAKryAKryAKrzAKryAKryAKryAKryAKryAKryAKryAKryzXR4aAAAAHB0Uk5TAAEDBQYICgwODxEUFRcYHR4fICImKSorLC4vMzU2Nzg8PUBCREVKTU9QUVNWWFpcYmhucHF1eX5/gYKGh4iKkJSVmJmcoaSnqq6vsrO0t7nAwcTFzM3O0dPW19jZ2tvc3uDh4+fr7/H19/j6+/z9/suB3zgAAAF/SURBVBgZrcFdWxJRGAXQLY3SF5KYmCWhlZJZllZoSfldkYIB1ViUFYJCzeT+/1e+75wz4DwPl66FCxLPpJyhxMRCodRoueV8GlFzNY9Rbg49zhb7qCQRWmXEPxrNLIyMz5C38/zB8MDow7UORSeLwDpDh5OwbnygaCahDmj9iKNnjaIC1ab1FOdtUuQg6jTaMQCj76qfXw5D3KFwIYo0DiG+UvivAdyjSgOYpuHFATz5TbU/+ahOlYeo0piFur1c89hVhliiUYrBuPLiiJYLMULrfQzWpU0aLagWrW/PHBgD2zRGIFx2nXxcvA41+JeBJYgy1emX3VMKf38e4hMDVYg81RvgboPKHwPwisY0gDRVCkBi5z/J75cBbNAoQrgUj6Guzkxdg/pFow6Rozi6hXNu0mpDVSiO76Nr7CetA6hkk6o4jkBs/oShdQSyHQb+7BVW3haP2eVnYGSb7GsVoWSFfWw56Mm5jPJqc4hK58tuq1EqLEwkhpxUJo6LcQbYjd5sezi/RQAAAABJRU5ErkJggg==)|Skype Running | Returns True is Skype is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAP8SURBVFiFxZddaJtVGMd/z2myrG3iytq6XXQlaazWC3FzVWxXv5gUkXpZh+iwiMy2rih6NSd4N0pBKJTFtuImKIOpF4plTBAmOoWCgzFXUPqRbE7RrtV1Sbqszfs+XqTp0uRNm3UN/iGQ9/Cc5/97z8dzziuqSqG6JxRttow8YOB+VRpAG0DuBq4Al1TlsoiOlumNExe7q2OF5JRCAIJH43vVcAT0kQJZo6KcwJajkwfLf1k3QHBovlHV7kXZW6BxtixFD0e6fH0KjkZ5AQKh+DMi+hWwaZ3mt0zgS5NceHm8Z+v1ggACg7EnRTkFlN6peYbOa6m3KdxBIrPRZEf5h6JNony9weYAO818rD+7ccUIBD5msyRi4yg1Dglugl4QMWNqM2aLjJWY5IRYUm1Bi4i8AOxcE0PYN9Xp/cwRIPhB/C1F38/qMqdIqES0f6LTO904jPvnAyzm5kX8odjzIhwDylZBmNvkSez49ZWqKGRMQcOxGZ+ihzIC/xXRQyXJhdpwV/k7k5Xe2UAo/sasHdvjlFVBw93ek0a0FbBWAdiyuOBpTz8sAywmNr8NVC09nldJPjTZ6esd79l63T84vyswExtF9PFwp/e7VZIz0en7EfhitRhV6cgBUGH/0r9PFxPe5nBnRQQgGJp/2Kj9PbDbqOldLfGyjHy0RsRj9cNzQQAXQP3AjRpc1AFHprp8h9NRwaPRe9XIKcALXJ26WnauEH9bZcY4151lWUnXHmDSBWC77SdQToa7vO+mAwL91yrE4/4GdGlaZNS/7VptYHBtAMG1Ze0o3QFLI6Bql2qpryOzXIqnpBvUn9GhTdTVtnbiwiSS2uougHCV77i231q59QN4cEnPRpk5SZEaWFqEmeYAliu6H9heTID01OaU4pTk6eKaA4jkB1Bqiw+QksupUYTa7E2kMGmEkY0ytpUIOBzHjcO4/7FiCXJGR0anusof3SiAtHKm4NwBkrDyzE5J76sfwFN0gFQt0DGH2ArbHX2x6AApCHPRsV2lzz8UbSo6gMH+IU98pbHl27pQ9LnbNQoORtvqQrGfAqH4ivrieCdMLcT4b6CBPPksgc8RGblp2aevvO6bzQ6oH8CjJdHdNqYZ0ZeABwFwy/apV8v/XhUAIBCKdojI8QJezgYuADEgmfqJD3QXTjfqLADHOgAQqfZ9EpiJvblMnl+GnLtg/qNYF5Dszs6B7VhJyzwLElkD4I6UFwDg8sGyP8VYrcD0/wIAMPnaXeOW4Sng7Ab4/cXC4ooiV9DHaVqBUGyfCH1wW4eVraqnET70T/tGzrxHct0AkNpetom3UEKrrdoCbBOoJPUl9YdCBOQSaERUIgZzZqK79Pd8+f4DwVuK+TWw7IgAAAAASUVORK5CYII=)|Edge Running | Returns True is Microsoft Edge is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMkSURBVFiF7ZdLaFxVGMd/38nNJFEsWhBfYMFNxFeFoCK2iFilYsFSMhUlbSJ1oQhRCBLaZOZ2Oi2KFaF05cIHYyuYa6uIYkGxpdCFGyFUmaRYoQ+hFKGaxskknTl/F96WdB5hEifERf+ry/0e/x+He879jkliKeWW1P0awP8BIFhooQ1+dQNtxefcmZNrUbnoPXmMUaY6D2skWW64z3x3gWWOBJTP70LWD7Tb6bHKlLy8bdMnw182BcC2fnoTQWIl+HvBPPAisOpKvBoAAMmGlRvetWAA6/+2jWWTgxhbgfY69SU7e2IC7x1wYzUELymX+njeAJaJEpT4AXisRo1H5EBfU7Lv9XbyLwDbkrkd3/KAeQ0Aa+Lcc5ryKzQSztQDqP0RXrI9mKrNxW84bVZ247EYdLn17ngCs/MU7hnTSPIQcMh6d64z9CqwgvaWdcDBhlfAhg7ehiufpXqLjhKwSmFy0tLR48AgYo2dHmuN4wXgsEruNe0fOlXPsFLVK+BKG8AqzS9S9huVfX7SUtHrwLs1aq8DnrXAr7a+ndvxuoA4ifyo9oUT9QCurIClP3sIuTeA9XGz2Wn9ynbvtVTUDURXRersglmaNrHbd/i39H5YqAlg6ZEeZB8AiRoNygSlWylcP01iOg/cMU+AOJHvVLj7mcpDylkq6pzDHMQRhS/8QaL4ZKX5vCSeomN8W+VrBxbWNYdfaOWV+Pn+BZvHMvSyGVYBoIfrZB+gWHxEYfJXS3++GmzDfwUA7nS9O3bblsxdswC4uUbiKVr+7mFiasZSUQ7pKPBgEwCQbMBKLm+bs32XAY5XZ9mQwr4ityzfDmxqhnGFEmZ8aL3ZRx3oQFW4NfjGMvuXIQ0sgvllmUHoCPJ7gGOzAr8rXP8nl9ruA9oWEQCgyykMPQFrwfbFL0sAOE0vsjlA0QEoTE4q272Jsu8EsgC0cJx/z/fFk/hxzoHEUtGbwDtz9Wj4JKzWjOS75h5Kx3kPtBdo9u3lgqQe5cKfG5oJLR11IXs6Hsuu+gvamfEOE1ON+eqiN/sJK3+hj8JzsIChtNla8nvBNYAlB/gHWcJGuLAG05AAAAAASUVORK5CYII=)|Onedrive Running | Returns True is Onedrive is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAiEAAAIhAENVwL6AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAPZQTFRF////aFEXbEsSbU0TbksTbUwUbUwTbUwTbkwTbk0TcE4UcU8UdFIUdlMVeFQVelYVe1cWflkWglwXg10XhF4XhV8XiGEYimIYimMYi2MZjGQZjWUZkWgak2oalWsalmwbl20bmm8bnHAcnXEco3YdpHcdpXcdqnserX4frn4fr38fsIAfsoIgtYMgtoQgtoUhuYchvosiwo4jw44jw48jxI8jx5Ikz5gl1p4m2J8n2qEn26En3KIo3aIo4aYo46cp5qop6awq6q0q660q7a8r7rAr77Er8bIr8rMs+Lct+Lgt+bgt+bkt/Lot/bsu/bwu/r0u/70uBe2RrwAAAAd0Uk5TABZVhbrr7HZg8t4AAAEASURBVDjLhdNXU8MwEATgdd3QIfQWqsGEHkro4FBCDez//zM82DCeiWTt083pe5A0dwDgBWHMvsRh4AEA4Ee0JPIBwGdFfMCLqkDkIWBlAoTVIETp/uOL9aKaa/y/BSV9rqyoOh8Df80SqHWlybxc2qABzOtTzb5LlMCB9nRTBe56Iw/foyTJ1TUDGPu54pE2SZLZqwFsqckFte2grSnWuu9DNjD49kjyTCs2sKzbJElOdWIDx8rzYgOd3k6apmmmWTOo65okua9DM0i1S5Kc0b0ZXGo6L541YQLDX09Fo6VtE1hXq2g0dGH5SUsQV5/H7qF1jr1zcZyr515ex/r/Ak3GNhQFU55qAAAAAElFTkSuQmCC)|Illustrator Running | Returns True is Illustrator is running. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAUWSURBVFiFzVdrbBRVFP7undc+utvFrbu8i8q2lmytPEK2YCItAVISJTHR1KipMUZi1CiYgEGFBBOjif4A/xjhj0aURDE2ShBMWkMkNsGI6Lo8WqWopbRY2W63szuzO/f6g+7szs7ADiYmfr/mnHvmnG/unHvuOYRzDjeIDcWUAAt1EkY3AWgBMAfAnKGfFvqpwIqCwFRRNkZERT+Y09N7JroGMm78kloEEslEVBf4LkLwKIBA9fr5U4ts71CBca9fS9VJWvfQ+qPJf0UgnorLHuLbzgnZBqDueg6cCFQSqQuo/QWvuml8TX/W0cZJmUgmojKt6+OE7L5R8FpgBiWZdF0nmwyNLD62Ie6KwIqzq1oLEj9JwFfXCuAnQcz2RmoS0VQ5OJEJ/Liov+uB6jXLL0gkE9GCxE+CY0Etp8vlTjzu24GMJuLo5WPY/9tHNYmIkmGEg1N3V+aFuQPxVFzWRRxyExwA1indkIgCAFgbXePmFRQLgpDO+U5Evukwf6tJwEN8291sewlBOst8Fono9jVoqhyUcr5eC4FEMhGdyXYLfKQO9yj3IULnuw5QwtJZcWxp3oyIEratZad8HaWkFAFAF/guUpXtUWEBXgrsg5f4keWT2DnZDZU7niQbIkoYO1peBECwKtyO18+8hVNXy+WAGZRkC8pBAHEaG4opM0XGgvs9T8JL/ACAOlKPecIdbj8eK8PLABBTfmbxEzab3LSyJHwkEaQBFupEVYVbKDRhmdxhyirPYtg445pA//gJi1wv3YJ7I+0WHTMo8cqh5+lMbbdgg+cRkIovOJY/gALXXROYLqr4JWOtwI81PmizK2pyN8W1i8WCBWJT2RnPoE/71HXwEt4+9y6Aco0JSvV2Arowj+LarWZChIQGOteU/zAGofP8TROYKmSRZ6opEwjwCB6LjWFQn41ARJgPWlGhLxsXbzp4CX/raYvcFrJuNjOoaLsLDBQtsgjJ0fmFYsp8niykHW1EYnWvs4LdBsAogFhJMW78iTyfhmfmCDaKdzo6/zz3HgBgVqEVewf3OdqE5QaLfPpqyiJTgRVtBDg4fjfOo0lcCgCYK9wGici2U3CFjWDf9K7r9gN+0QeBlHdPYyoYmMVGEJhKAdgO+MXiubIRRKxTHnYMciNsb3nWIo/lx202omyMUE5Zb/VCsvCdRd7o7cFc4XbXwdvDy9ESWGLRHb8yYCeg6AfpFE33AZiqXDhX/AHfal+UDSHhKf9uVyTaw8vxQvPTFt24Noreka8sOiowntPTe+jg4kGNc3xY7eiT3Dv4i42a8myhETuC+7HR0wOJyLbAftGH3a3bsLX5OVCUr2cOhld+fsNm7/VrqYmugQzhnF/rhEQ+hKobMSa2YWtgL0hV52agiEvGBVwsnkU4vxRhucGScJV4f/gAvrz0te3rbw1l7hpafzRptmQrzqx8daYJtSAmtqHH/zIa6JzqJQDARN5w1HMwfDD8sS04AARD2b6RrsNrgYqOKM/VNznIiWrjweJpvJbpseRELYxro9j8/RbH4IpPzxS8qnkB3lRT2iwuQ1xqR6PYjIVCEzzEb+6AxnIYy4/h+JUBW8KV4NSU2gaTFWdXtXJiHK7VnBIQRIT5yP7ahtNXU7Yi4xS8Pjz90HDHkc8sfpwmo0QyEdVFHHLTpN5oMipB8emZkFdd7TSmOU5GA/GBMZ1lOwnnOwG4awQdQAXGg6FsH61Pz7vejPj/HU6r8V+N5/8AlNIVFq+Rn+gAAAAASUVORK5CYII=)|Launch Process | Launches a process based on the executable | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAASeSURBVFiFzVdLbFRVGP7OuY9O78yQybR2OrSUV0vjMG2RBUzalXXBIyFsKjSVEkOCcUO6QlZqYgzBYDCNGyPRaClQsRixKq7qqoQgC2NIjdA0pdiO0jt1ntdh7uO4mM7jzr1t7zQh8VvNf87//98395zzn/8Qxhgcoa2tBj5fLyg9CuBFAEEAQeX+fTcEQaM8rxBBWCCiOCZq2jBisaSTtGRdAZFIAIy9C+AEAG/ldObePWtSjmPU652mXm+/OD//YGMCwmERknQOhLwFwLNaAjsBxeSUMurz/eziuKN4+jRt50NtIyORADyeSRDy3lrk64EZBtGXl3uzirKQa2kJ24q0fIHu7g7o+g8AtqyVXG1vBxMExA2AKBlIN75aUwwRBJ2vrz8mLi5+s7qA/Hr/sh45ACxdvgy9oQGynADHDLR0htYLyYtobNxTvi9KSxAOiwBuOiHfKJiqcsby8hQaGorLWhIgSefAWM/zIi9Az2Q2ZXX9lllAJBJY2e0m5EIhpI8f3zBZbGQUymsnLONGPP5yYVPyALByzk27nYkiEmfOQN+8GaAUnuvXqyKXR68h1bUXma6XsOX7CZBEopTbMIiRSo0BCFO0tdUgX2RMSA8O5skBpPv7oRw+7Jj8n+GPkeraCwDQKQf5ixGLj5FKhVBXt4nC5+tFRYVTd+1C5siR0oCuQ5yediyg9vaPJjvd2o5/Xz1mGmO6TnI8P0RXarsJ2Z4egJCi7RkfBz8351iA66fb8P72q1lE/4DFj+Vy/RT5i8UEtbW1+JtoGtzj447JC6h78w2TnWu2nm6mqk0U+VutBEKg7thRNPnHj0FyuaoFkFQSglqKUyU3QM2V39A0ySJACwbBJKloCzMzVZMXY/+KFn8zAM+6K8qMqvL8RpO/cPo0AMC7xm3oBBRAtHyAj0ZBFKVol++HaqE2lj4uAVBzZ8rsIAiaRQAYgzA7WzS1rVvBRLFqcubdBFUoxQlKBjAMkw/leYUC+L0yuHzdGc8j09dXtYDYJ5+abPHPJxYfIggLFIZxq3LCNTUFlF3T6b4+aNu2OSbPHjyEVOce05hn7JpVgCiOUcTjkwBS5RPCw4dwT0yUBjgO8bNnHYnIHjyEpQsXzeQzf6D26xtmco5joqYNUzx69AzAaGUiz5Ur4BYXi7bW3Az50iWkBwZMx7QAvbER8tUxRC9+BI0rHS7O0FH/+kmLP/V6pxGLJfMdUb4TmkHFjZgLhbB8/rypLAMAGAMXjUKYnYVcH4Dqr4NOOdsvErjwPqSr5v9HKGV8U1OnOD//oNSS7dv39koTakJu924khoagBwK2BLKcsB3nmIH6Dz+ANPKldc7vn3TFYq8A5T1hOCzC45m064qYy4XUqVNQDhxwJEB6Mof6k4Pg5CUrududdElSU6FNr6opzXV0ILt/P7SdO6Fu3w5WWwtZToAAELIKhIUFuL/7Fu7PP7MLt21KN9yWgxBowSCScixf4SqKjC35um15AZFIAMBNJ03qWi+jAji3O0n9/h67Z5r9y+ju3b+RTveCsXcA2D6pnIBQyji/f9IlSU2rvRH/x4/TSjyn5/l/iVjk5sAr/CUAAAAASUVORK5CYII=)|Kill Process | Kills a process | -|**Control Flow**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM0SURBVFiFxZdNaFRXFMd/5+ZN3ozRLFI/uvBroWuJoqDVSWqiVLC0GLQgShErgiAURGlRTFRcFUHoqqiItAgiKS0WBDVqxjRZxeBObBf1Y1FFszAmMy8z804X8U0y5r75eDPQ/+7d8/H/v3sO594rqkok9McvAPNp9PazXkejJQGJLCAVDwJHiHmdUUWYaOxFaCXr3mFIWv4vATWJKF+Cu4llOLoToQNlKbAYaA7xrroc4QIGGlfhm3NAR6XJSopIxQ8CK3jpfcdOzQfLzqzwYYkx4Z5DzSGgoUpygFZybi/w6TR5ogfoBmChq8CxwFTcA7ekiXH3D5TDEclnI5XoAe0ufAtHeeB2FT4LJbgvDg3uPZSNNVJOlyCV2A960eIzhq/raPceT++AxE/WlRwA/+MQv3kYcwqCHehvXIuYIUK3XUZBfwEdhIZBkhPPZwyiEHKm+mncvQ20WZK+w/cWTDWhmOMlyIfJ0cXmzNOQv7GTA6zRLH3NXcSyT0A/nBFzEXeLIRVfCXwekvh3xjOfsDldPXmAjrdvQH+2h+oOA/oV9omYxZdv2aaePZaLKL9VNHjEv2pflzYHZHVI2GXa0/+EJm3LHChJOhN5mQgZ+nEDtNqjzJWKCcrBaMxu0EYDOs9uzKXrJgAnYV+XMQMyabX5kq2fAP/rEMOIA2SspgadUzbvkLQw6V4CXof2xP3Ecgz77An0oUG1324zu8uSZ907CF8ifGP1uSkuRs8Dth7wQa4ZkF/tDLKXvuaPSpKHNjBT94im+J/AFyEeN0hm/nJQ7zbivgPmFtu1hdhkL8OyhTU63Q+lyFNzlkB+A8gGHNljmX4B8qh/FoKzIJW4BrrL7qsnSHpnK/7zSqByhrb0SQgmoO93A2N2b/NvXcmFATRzupAdgHbvMaKWTpVTJNOXAN7fcmojh1ukvc9o11yxAIBNXi/KDx+Q99RIGCCP8CNN3na26vhMQ/Gd8JX3PYtcAf4mmf6pyOZ4XRFL0Ifxj7Bx8pHNWN3LqHwfvAVeIDxD6SMn18sc5RGeZmEikhmpLtEUqn8ZrddRYl4nMBKFsHYBdRYx+2FSjYgh6SwcRhHxH4JZSGO+f4eQAAAAAElFTkSuQmCC)|For Loop | Perform a for-looping operation | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK7SURBVFiF7ZZLaBNBGMf/s9lsstk8GqT1QVFqa9G2ClqQFhF7LCh4EQUf0EsPBQXBg2lAUqHgsSIiWooePHhSQQ/VS0F6qUoo4gONbaRK+gKbpOnm0XT38yCb2MalszHFS7/TfI/9z2+/ndkZRkTgtUAgdBIQLgHUyoAqAPgWnQQACIJAdkmK2yX7vaGhO0FeTcYLEAz03SAgsDZuAPxpLkUZu//gbjuPrsBT1Nt7vYPArq6NMwIEvbQ+rapt3d0XL/NoizxFRDjPQMzw/ck8jo/8RN33DCLZeWhOCY/bPIhW2wrPrCznewDcXE+bqwMAHTRGSlpDz8MY9k6ocCzr0EFg2RzOvFrA1sViOzRtpZZHmQuAgSnG+NhYHK6MVlKjkY5Tb9SCr+s6V3c5O1C02pmcac6zlLcqZx0g7bKZ5jSbZTnrAB8bFdPc5A7nxgOMN3sQ3u8tiec8Mp60WgfgWihr7WlnNd41uVE/lQGLLOFTrYTRPVI5UuUBAEB0p4wPDTZ8bXbAm7CXK1MewLQ/gRcH3mPemwLmqmBjOg6FvdgdMV8fFQNIKGk8an+NvK34L9BIwNvWFNwpETUzDkt6lhfhWH101eQFI4bw4YRVOesAc75F01xa/svJVGkAX8Z8q0l5Zpr7R4DipaHlh/kZUxeVNwiAYcIYNszV4OiXRgi0+m1r4gJaxn0FXxTFOI801y5gxEYJdMLwj0Qa0BTbjqktC/iszWLXpAvbpld/GlEUwxUDcMi4lc2wLoD2GTG/qsCvKvBFl0vq7aI95/E5z/Foc32CUCiUJaATwMi6sA5n3KO4OwYGBrj2JPelFAAYYywY7GtOJdWubC59BQCSyeTviSVHWFbk/sHB28+IiHs/WgIw7OzpC506MAwAsVgMAOB2K9eGXz7vt6pl/QZRYdsE2ATYBPjvAL8AOIXef+sqD0EAAAAASUVORK5CYII=)|Condition | If a condition is true, run the indented code | -|**Message Box**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAblQTFRF////AAAAAAAAAAAAAAAAAAAAAAAAA6ysAAAAAAICAAQEAo2LCgoKDAwMDg4ODhAQACoqABcXAAkJAAwM9GsvDAUBDAYEAAgIAAsLAAsLAAYGAAkJCwsLCQoKAnV0/m4uABgYACQkBQUFBgYGBwIBBwMCBgcHFBgYBwQCBwUEExgYExgYR0dHVVVVAAEBAAICAoqJAwQEExgYExkZVVVVFBkZISEhFBoaEBgXFBoaFBsbHSEhjqOjqamp/mwtAAAAAVJRAXp5AltaAl9eAmxrAn18AoSDAoaFAoeGAoqJAouKAoyLAo2MAo6NApGQApKRApSUAqGgAqmoAqyrA2loA2ppBAQDBQQCBwgGBwkICAsJCAwKCQwKCQ0LCgsJCg0KCg4MCwwJDiEdDiMgFBsbLS0tSktLUlNTWlpaZCYLZDQeeoqJjY6Ojo6Oj4+PoVMwoz4So0EXo0cfo04oo1QypEcdpFUyqKioqampxsbGx8fH0Gs/0l8u0mxA1NTU1tbW2V0m2XBC3Nzc31MX33NE4Pj45lYY5ndG62Ak63lH7HpI9n9L+oFM/m0t/nI1/n1E/oJL/oNN////QOoNSgAAAD90Uk5TAAYQERYzOFBcdnZ9l5e4vMLFzc3Z2trf3+Lm5ujp7e3z8/b29/f4+Pn5+fr6+vv7+/v7+/v8/P3+/v7+/v7+/lINWQAAAUJJREFUOI1jYEAAMXsoEGXADlRbukFApFkFl4L2iSAg30ZAgR0hBb14FDRO7Oqa2IBHQVlPdXVPKSVWYFfAyCEsAQSC7JowBRrsghISkuJCHIxgBVyKjh5AEBAcCVMQERzg7u7u6qDACVYg7RsMBKHJyWGdYAV9HeFJSSFAITdnKbAC/UCQAt/orNqJUFCTGQXS5Omih6Qg2DehBCrfXxAPNhRNQbAPVMWEwnifYGwKgr1jwSqKYryDsSuAqCiGyWNRAFKRHweTx6Yg2Cs20SsYn4Jgf/9g/AqQAfUUCAThUGAAVcDthwPIOYEVsKqpa2lrGxmbmptbpaAASwtDNgYGJhnbSbhAq40sMwOfWR5OkJNtzc9gb5KBDFJTkXnpafYMylVNyCA3F5lXWa7EwKtbVY8L1FXo8DCw8Crb4wRKPCwA8AQNnzJzUC4AAAAASUVORK5CYII=)|User input message box | Shows a pop-up message asking for user for input | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADlAAAA5QGP5Zs8AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAPZQTFRF////JLbbIL/fILXVKbjWKLXSJrbSJbjTJbbTJbfTJbjTJbjSJbbTJbfTJbfTJbfTJbfTJbfTJrfTJ7jTKLjULLnULbrVLrrVMLvVMrvWNr3WOr7XO77XPL/YP7/YRMHZR8LaSMPaS8PbU8bcVcfdWcjeW8neXcneXcreY8vfY8zgZczgac3hb8/idNHjetPkgdXmg9bmitjnjNnokdvpldzqmN3qmd3qmt7rnt/sqeLuquPutObwuOjxu+nxvOnyvuryx+z00O/20fD20/D21fH31/L33fT44fX55Pb68Pr88/v99fz9+v3+/P7+/f7//v//////MZEFEQAAABF0Uk5TAAcIGBktSYSXmMHI2uPy8/XVqDFbAAABO0lEQVQ4y4VTV1vCUAxNS+migwDujRNRcSPiHihOzv//Mz4gvUn5lPPU5KRJbnJClMFygzBK0ygMXIvG4fgJZ0h8J0fbXpkVyp4t+UKJx1AqGL4YC6LSOJhiZua4mP0veb4ETodf8W8OW+Wf/gC6oyrDPjxVutLH9/rI8IiInFz/9bNV8xaHiHz+Bz6RlSjP0tF9tyYmZpEr6WpnAGBbeFwKhDVzAwCDeeEKKDTGwlP/+AroyZwhRcZo7VW5B3RkQESp6nERQFM60lxAC/ia1QGRCrgGHlmXCKVZewcuWDcpn8lbAHZVQKAH1c63wK4e9TPwoPjEUsuqfQLt/LLkutcANKrNu7patxDMPoDz17cdVoIRkjsBgJcVI2w7J9oNYHA7l/FxYUz2m4fLpkEj+8mHM/n0Jh/v3+f/AxHgSjy/wBsUAAAAAElFTkSuQmCC)|Display Info Box | Shows an info pop-up message with title and body | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAASbSURBVFiFxZdtTJVlGMd/1/2cl+cgHOSgCKjTlGFEFDrUGAIBQ8DICeopRXHK8syXWetbH3RuuvVFp261am2t1Rc3+yK51cS5UEcvY9ZW0idbrJjhS04BhfN29eEArgx4Dtj6f7xf/tfvvq77fp77FlXl/5RruhM3bg/laDTccOtmX0Qi5sKlS1/emI6PJJuB9aFQimcw8plCA0D/jd8THcoXw2n2pu729gf/GUAwGPTF3KnngOq56bBqmZDlvc+ZzkGu98cALsaHBxu7uroeOvVMqgRRz6xDolQ/lS0c3m5ItQFm0/BCKvuO/8FPfbFq4007BLzl1NNxBja1tC1RtMcyeE+ELObP+Xv/3b4hmt6+TTTOiFj6zOWOjl+c+BqnpKp6DPA2rJTHggNkZKfwymoPgFejcsypryOA5q27qhGa/CkQrJhgiiW01ftJ9wkITWU1ddVPBCAYDFpGOAmwpcowy060D4fh9FdxPmi/x8ORRBk9gRT2vOgdNdaTwWDQmjFA3J26W6Fo8TyhdrmMt3dcVc5cVk5ffMDZKwOJRkt4qSyNvCyDKkV9d+7unhFAY0tLhsIRgF11gjyKz683E6s2xuJ6X2S8XdJ9vLk2kSZROVJe3pgxbQAb72Egs7RAKFwkkw19JEt4rmAWVctcAJm4w4enBdD86msFCnvdLthR6/iwJOS32V9j43GBwt7SytqCpAHEip0AXBtKhbnpycXHMsyb72PrKg+Ay2XJiaQAmrftagTqMv3QVJbk6sfkt9lW6iUrTVCoK6+qa3QEEAqF3KJyHGB7jcHrnl58LIMdsNlTmTiWKnq8pKTkMbfHAG4PRQ+A5i9bIJQ/63DjTSS/TW2hm6L5FkC+Ly1wYFKA5tbWLFQPCtBWP8PgAJYBv83rNV4EQDhYVleXNSGAibqPAulVxcLSnMkBvGP/UVVszyRj/TZP51isK3KjkG4iHP1XgKaWncUq2ubzQEvV1BuvuliYZYPHFWNdaerEA0ezEKrwkOIRFG0rq1pbPNY9fh8wcAowm8oNsyfxG1NervDhGxaqOZNnAMBvE7g/zI5SN+91ho0Ip4DK0bjQ3LJzM0hFdgAaVzuvvdfN1MFhPAvBEg8LMgxARXnN2s0AVm9vrx2OSTswe/96w8K5zgDuDcG7n8c5d+UOK/K9+LxTlM1jYQ2OkO0XLvwcBVj16ccfvW8GwqYVWPT8EmFlvvPVn7+qdPUo3/REOXt5cOoJo1lYk+di5WILYFFUPK1GVesBNq5J7tjl5YIAqnEKFnucTUpLfJR2lCbGq2q9C6HSCOQvSA5g+VLhnX0WkWgWC7Mc3m1dFhihMNfCCMSh0iD0xxV6epN/IWUHcB4cIBKDuPL9bzHiCiL0G1HtBDj7tTISmcphhhoYZjiinP4uDIDG6ZSXt+ye45bINSDL54XKIiE303k5HgxNvQEDPojcH+Fab5jz16IMhRXgplsjhaKqbNi2s8il8olC8VRm/9T40yw5/RCPaWtXZ8eP4w+TUCjkvjUQXY3oCkECTlxU1XWrvy/qNGpc+dNo/OrDgbvfdnd3R2Aaj9Mnrb8A0TtykI+7cqgAAAAASUVORK5CYII=)|Display Warning Box | Shows a warning pop-up message with title and body | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA+QAAAPkBHYYEgQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAATBSURBVFiFtZfNbxNHGMafeWfWieOES5AaonyhpiUR4lYpiX1hkSKhBFG4gARK/4eUlqQq4oCQSNxDRXvkjFS4EC4uxEDEAX+ot1ZKDnCgakk4xD1kk6w/5qMH2xuv7U2sKDyn9cz4fX47M+87s8wYg1b0bmqqrV3gnNH0NQijMDgB4ESlewMMG9BYY6Sf5iVeDScShVbisoMA/j5//gRZ/LYBu86ArlaCGsBhMA91Sd0ZfPZs41AA7227nUcit8AwC6CjFeMm2oXBz2pn5+7Qykq+ZYD309M9nLMlGIwd0rjOBdntfHFmdHn57YEA/05PnzHEEgD6jsS8oqKUOWgz8/nz578HAryfnu7hxP44avOqHNctMEZnR5PJTLWNPHPbbuecLX0qcwBos6w2pdXLVdvubADgkcitI1vzAIWEADHWwS3+tNrGjDGVVBPv0GS3i54eHLtyFXJ9Hc7SExgp9zVhQqDr0mWI3l5sPX4E+fGjr78oJXbyeViCTYwmVzICAMjit5uZA8CxK1cRmZwsv8HICHIL9wIhmBDonv8B4bG9ifzvl/u+MZzKk85ADwCcoXdTU20G7HrQG8n1de85PDaG7rl5MCGam8/N+8xr/1sVVQBKSp9ete1Oahc4t1+Fc5aewM1m9yDGx9F9c84HwYRA9805hMfHvTY3m4Wz9KQRFOVZMMYwERI3+OwXp74Dw1dBANAabioFa2gIVl85Qaz+flgDA9hNpwAiHL85h3A0umeeySC3uBC4VFIpKK3BQJ/x2ZEvvwcwGAhQhUinYA0Owurv9yBCAwPoiMUQjsb2zNNp5OKL+25WpTWkUiAGQZVT7UAZKZGLL8JNpby2cLTOPJU60BwAqsVPAxECWgOoQmzGF+Gm3jT0uak32GzBHAB0BcBobdEBYz+JtNbeMwHY97yuFROisuFiDX3haAzH67KjmYwxUBUAxpgksNYAvFSr3e2pN77lCEejDSlar5JS3jMR7RI01loyn5tHeGKixjyFzXgcm/G4f2NOTAQWK6Bcir24YB/4tyPDCvtUQq+81haZdBq5n+KAUoAxcDNpf4r29cE6ebIMVrPeSmu4hb2roiXoV8pLvDKAEwTQdemyr7y6mUxDqnkpmvGOeYTHxtB16bIvVq05AwwXofs0nEgUGMzDIADR27sXIJsNrHBGSuQWF3xlu/a/RSl96y84Xx1OJLYEAOiSukOW+AZNTsStx48AoKXj2EiJ3MI933EMlKd+t+C/pRPYNaDmSvbPhQt3wfBjYPRDyhiDLdf15X5IWK9HksmzZZCK1M7OXTBkG0McXkrrBnNB5AjHuVj97QEMrazkt/PFmaKUuaMwL0oJp86cMaaIeGw4k9lqAACA0eXlt9BmxnHdQrGFmt5MSmtsuy528nnU3rgZY6qdiysjyeRfteObfpisTU6OK61eEmMdbZYFTgQiAgswNcagpFR5pzcBF0QOEY/VmwcCAMCqbXdyiz8tlOS5ahsn8mCMMdDGQGvt1fZmCgnrtXCci7XT3hJAVWuT9jgDPSgpfdoYEzQJ/qCAEZyvEti1Uy9e/Lnv2FY/z1dtu1OExA2lzFVjdI8GIkZrC6icakS7DOwDEX7jInR/OJFo+sb1+h9ZRUoxCF3PpgAAAABJRU5ErkJggg==)|Display Error Box | Shows an error pop-up message with title and body | -|**Excel**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAfpAAAH6QGUejxAAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAQhQTFRF////29vb6+vi5eXTyN/E6Ojg6enf6urfwNzAtdi54uLX3dzQ6eng3NrOndGpkc2gks2hks6hk86ilM6ilM+jlc+kmtGnm9Kpn9OsodStodSuotWvpNaxpdaxp9ezqtWyq9m2q9m3rNm3rtq5sNu6sNu7sdy8s9y9td2/t97BvOHFwePKwuPKw+TLx+bPyL24yObQyb+6yufRy8C7y8G7zMK9zcS+z8bA0MfB0MjC0cnD0uvY1Oza1c/I1tDJ1uzc2NLL2dfK29bO29rN3O/h3dnR3fDi3/Dj4N3V4N/U4eDW4fHl4vLm4+HY4/Ln5OLa5fPo5+bd6PTr6eng7Pbu7Pbv7ffv7vfwyAytUwAAAA90Uk5TAA4aHThCR0htfNnr7PP7HqL7KAAAARJJREFUOE+V0GlTwjAQgOGoKOBBinjghWcVrYi19jAqYL3wQAQ8/v8/cUuZkk2WUd9PmeaZZFPGGBuf7SlNTzC5KXW/9zSHRFoHN0hQAAkSyIIGkgDQaffrDMDzbdTM2BCE1X4hPmhSAiL6IBSQloDtQfa5N+weA78J+dfNJD/EwK1B7kUtyf0v+PUKbUhbAdozhQKqWgoIoj8dNNpJgQIcATmeSHIwaIVaLQTo/gwymyPKDECWjygrg3xl3jhe2CrBsnhWIQCvH5Yf+KkFq4/yDgWK7931GHyXqCs4f+nyGKy+XuWpEz7fNmLA+eM2AepHBzDDnWUtXp58LRNgt2DsGSumaRbW9pfwDKkcJ8ulYPMHpgGnXd/VNfEAAAAASUVORK5CYII=)|Create Excel Workbook | Create new excel workbook and save it at the give path. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAHowAAB6MBMC+yxQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGiSURBVFiF7ZfLSkJRFIb/tc8FPZgZ3rCMHDRL6Egv4CShB+k9urxDD5BFgaMc2G0QNJZwlkQQQUWiVIhg0MnVoDQ9KmQc92nQmu0b38fea2/WJmaGmyFcpf8FAbV2GskDlPnJZAJWg8uVrJMCVD2JjJIE9XcmM5p5vHFKYNQj8KvEO8iR4pTAqDvQjk3WeGvURRY0K5a+rzkh8PtgrIcylbV2041bYHY3XL+GrguowwYI9MTETceJQm2+lFYSANBoTlQGJyHpRS2YTDKEx3GBbgxQHngEin9WGTccABhoDBJ4IG1qcdzwr8j2CZA+eQU5yWmp4L0+kOKdiUuAA4xjX6pQ7RUgcQnNmJfBJ3AWsG01eUIVGXAA9ed688AuYCne2IIkgVwiffbaI0CKfgGhheXwuVPUdASEN/omB47bQOrw3C5QJ084JYNOTLvAdyn+KaAaJUAYMgQsFj01pQAAxZj2yYADKAaX8mW7wB3pAXPIAoeDtu09gvSAxKe3tW/vVBUjLufpJRz5zEK1T4BU7zWD58aMrwm0NgZ6/X9O3Rb4AAx4bYSh+ftFAAAAAElFTkSuQmCC)|Open Excel Workbook | Open an existing .xlsx file with Microsoft Excel. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAlsAAAJbAHGUoNyAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAL1QTFRF////VVVVQklgQUpgQklhQkpgRk5jSlJmVVxvVl5wV15wWFxjWmFzZm5/aXB+cXeEdnyIgH1qgIWQg39okZadk4tom5Bnqq6ws7i+trq6t7q6uby8u76+u8DFx8rHyczJzdHS1trZ2N3g4+jp5enq5erq5+zt6MA66b0o67oW67wb678p7Lwc7L4i7L4l7cAs7cEu7sQ57sU68MtQ8c9d8c9e89Zz9t+S9+Oh+eq5+eu7+eu8/PTb/ffk////4p7yfQAAAAV0Uk5TAAaPqLHX0bArAAAAtElEQVQ4T9XQxw7CMBBF0UDwQOi9d0jovdf//yxcYmkc7Oxz10dvpLFswup5tFEflSaJmMVCYDpQgC8Q8CeSANBmQAgMxAQUyqTFARcYiAmoNiRgQgF8AgMSVwGfUIAdAC6dgHzRDNhE1nGcjhG48hcB0JzIhl1RSgXGogRqdU0ZBOYLTRUVHE+0vRksP1/aM2Rhs6OtQ8D1xjtvL4YTrzfvfngYFv7DYLbSVEJg7GnKRQf8AJqfUqUW0vwkAAAAAElFTkSuQmCC)|Save Excel File | Save a existing .xlsx file to its current path or to a new path. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK3SURBVFiF5ZdbSFRRFIa/deZMMSMNRRcpsQKjJM05mV0eIqKo6AoFaYZRCdFDPVRUlGbSRFDRTSsiSrrQg0gXoqsS1psPOVJaVEZQUJAPQcRgZTirFx3IOQ7M8agPfU+bzdp7/ftn7X3OElVlMDGTCc7Pz/e8mfJhsmGoJSpWFCyBHIWG5lB4jasCgnuCKerz5IgalohaKmqRKdkG+FFBAemKFVjtJHlMQF5p3tgOM2pJ1LBU1BLEwmdOEjAQRQFUEu/kVIBVPuOcetgmKiDadaqBqwtTlW1ubPTt+4/kVSu1hhvJHSMsGVwBwKALSOodSMSKK8tj49y0XEKLDwNwsK6Mpi9NcfPdJOWAz+vj8qaLVBae7qveGLYOnFl3kpShKeys3k3kdyQ2X7ayBCs9yKsvr+PW3N/8wDZBzxP3xNaBgC/A9PEWJ/KP4fV4ASicVcDirEW0d7RTfjeUcNNkkJyy3Lj7mxpI5WpxFaOHjeJRSy23m+5wYcM5TMNk78391L95GreRf4Q/Nu5zDbT9aGNH9S7aO36ydNoSzhedxTRMrjfcsE3eF2wd6Gbe5LmcKjgBQGvbe4oubSSqUdvY+l3OhCW8BVZ6MDaeNCaDORmzHSVJRK8OLMicz/G1R+mMdlL/9hmLpi6kveMnW65t5d3X1rh4V2tgwsgJlK8qA6DiyVn23yrlYctj/EN8VBSeIjWQ6uSwttg6cLW4iuy0LOpeP6Hk9gEAvB4vletPM3NiHs2fWyi+suWfNa7WQOR3hOcfGzl870hs7k/nH/bU7CP8qYnIr4jdMkckvAXJ4GoNDCSuOdAv78BA8J8LUGpNEc678Wc8cnjAUeNgvDgU3u7tlHEqugyVEoUakFbA/qvjMtJbc2rbmqlkA367+JehsCMHehVgh31zqkFFGptD4RX9LqA/+As0xAKOOpJXugAAAABJRU5ErkJggg==)|Create Excel Worksheet | Create a named worksheet in a existing .xlsx file specified by a path. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK3SURBVFiF5ZdbSFRRFIa/deZMMSMNRRcpsQKjJM05mV0eIqKo6AoFaYZRCdFDPVRUlGbSRFDRTSsiSrrQg0gXoqsS1psPOVJaVEZQUJAPQcRgZTirFx3IOQ7M8agPfU+bzdp7/ftn7X3OElVlMDGTCc7Pz/e8mfJhsmGoJSpWFCyBHIWG5lB4jasCgnuCKerz5IgalohaKmqRKdkG+FFBAemKFVjtJHlMQF5p3tgOM2pJ1LBU1BLEwmdOEjAQRQFUEu/kVIBVPuOcetgmKiDadaqBqwtTlW1ubPTt+4/kVSu1hhvJHSMsGVwBwKALSOodSMSKK8tj49y0XEKLDwNwsK6Mpi9NcfPdJOWAz+vj8qaLVBae7qveGLYOnFl3kpShKeys3k3kdyQ2X7ayBCs9yKsvr+PW3N/8wDZBzxP3xNaBgC/A9PEWJ/KP4fV4ASicVcDirEW0d7RTfjeUcNNkkJyy3Lj7mxpI5WpxFaOHjeJRSy23m+5wYcM5TMNk78391L95GreRf4Q/Nu5zDbT9aGNH9S7aO36ydNoSzhedxTRMrjfcsE3eF2wd6Gbe5LmcKjgBQGvbe4oubSSqUdvY+l3OhCW8BVZ6MDaeNCaDORmzHSVJRK8OLMicz/G1R+mMdlL/9hmLpi6kveMnW65t5d3X1rh4V2tgwsgJlK8qA6DiyVn23yrlYctj/EN8VBSeIjWQ6uSwttg6cLW4iuy0LOpeP6Hk9gEAvB4vletPM3NiHs2fWyi+suWfNa7WQOR3hOcfGzl870hs7k/nH/bU7CP8qYnIr4jdMkckvAXJ4GoNDCSuOdAv78BA8J8LUGpNEc678Wc8cnjAUeNgvDgU3u7tlHEqugyVEoUakFbA/qvjMtJbc2rbmqlkA367+JehsCMHehVgh31zqkFFGptD4RX9LqA/+As0xAKOOpJXugAAAABJRU5ErkJggg==)|Get Excel Worksheets | Return a list with the names of the worksheets is a .xlsx file specified by the path variable. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAYNQTFRF////////YGBgYk5iiYmJgICSWlppVVVjXlFrhoaUWFhsh4KRWlJrhYWRhoOQiISRhoaSXFNshoOShoaSh4SQhYWRXFRriYaUh4eTW1RqY1twY1xwh4eViYmViYuYiY2aiYqXiIuYiYyYiYyZh4mXiIuXXFRqXFRqiY2aiIqXiIuXbGZ5bGZ5h4qXXVRqXFRqhYeVXFRqhYeVXFRrXFRqiIqXiYqXiIuXiIqXiImWiImWiImWjJSih4iWkaGvkaKwc26AjJKgjpmnkaGvkaKvdHCBiY2ai5KgjZmmjpuoiYuZjpmnh4eUiIeUXFRqh4aUh4iWiIuYiIiVh4eUlq+8lq++l7PAi5urlK27lK28lrG/g4GOhoaUnL/NnL/OXFRqX1htYFhuc25/c2+BncfYn8jXos/eotDfo9Hgo9Lho9PipNTjpdjnptrpptrqp9vrqN/uq+j4rez8ru7+ru//sfD/ufH/vPL/vfL/x/T/yPT/zPX/4Pn/4vn/8Pz/8/3/////FiVGzgAAAF90Uk5TAAEIDQ0OERITExozPkFOT1JTVFRVWmRwcXOJi5OTra+xsrO0tbbAwsLJytTV1dfY2Nra4eXl5ebn6erw8PHy8vPz8/Pz9PT09PT19fb29/f39/j5+fr6+/v7+/7+/v4d+WzOAAABSUlEQVQ4T93QV1fCQBAF4KEJQaKi0hTsEsAGglKs2LBiw15iQ1QslFXs7k93kw0cXoK+6n37Zu7ZM2cB/kmqfljZOPkCZwMw+vTyBb3PCJxBfg9g4ICvtAey/l1BbbK7HCZ1cao2OVx2SlJQArDh8aPL45kIS/dsZJpwIkyoJIUBZ8/6FRJyM9cAOh3ULVJer/U6+3nw8yeHt4SPb8/obqw5EGgaoSygi4NT3g/m+Pm+0P/E+BXtzapUk7sCvzB+QTtncTOAti9NBk8Y4w+UGgTwpggLhO8o7dUKNy1nSy9kV4sUX8iuiEcPZZB0A8qEAIYlFihJWpKomGQnQGsZ28VCTTQnDXKxRoDaWInRevoxbYk8nWx3C+zYoswnuqSfZdzz92T2sOBhRHqWRE65GakACktwc3QjZFVItIYIgxYFlEVTranAP59vjw1xvdJmgZAAAAAASUVORK5CYII=)|Read Cell from Excel (by row and col) | Read cell value from Excel by row and col: first row is defined row number 1 and first column is defined column number 1 | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAYNQTFRF////////YGBgYk5iiYmJgICSWlppVVVjXlFrhoaUWFhsh4KRWlJrhYWRhoOQiISRhoaSXFNshoOShoaSh4SQhYWRXFRriYaUh4eTW1RqY1twY1xwh4eViYmViYuYiY2aiYqXiIuYiYyYiYyZh4mXiIuXXFRqXFRqiY2aiIqXiIuXbGZ5bGZ5h4qXXVRqXFRqhYeVXFRqhYeVXFRrXFRqiIqXiYqXiIuXiIqXiImWiImWiImWjJSih4iWkaGvkaKwc26AjJKgjpmnkaGvkaKvdHCBiY2ai5KgjZmmjpuoiYuZjpmnh4eUiIeUXFRqh4aUh4iWiIuYiIiVh4eUlq+8lq++l7PAi5urlK27lK28lrG/g4GOhoaUnL/NnL/OXFRqX1htYFhuc25/c2+BncfYn8jXos/eotDfo9Hgo9Lho9PipNTjpdjnptrpptrqp9vrqN/uq+j4rez8ru7+ru//sfD/ufH/vPL/vfL/x/T/yPT/zPX/4Pn/4vn/8Pz/8/3/////FiVGzgAAAF90Uk5TAAEIDQ0OERITExozPkFOT1JTVFRVWmRwcXOJi5OTra+xsrO0tbbAwsLJytTV1dfY2Nra4eXl5ebn6erw8PHy8vPz8/Pz9PT09PT19fb29/f39/j5+fr6+/v7+/7+/v4d+WzOAAABSUlEQVQ4T93QV1fCQBAF4KEJQaKi0hTsEsAGglKs2LBiw15iQ1QslFXs7k93kw0cXoK+6n37Zu7ZM2cB/kmqfljZOPkCZwMw+vTyBb3PCJxBfg9g4ICvtAey/l1BbbK7HCZ1cao2OVx2SlJQArDh8aPL45kIS/dsZJpwIkyoJIUBZ8/6FRJyM9cAOh3ULVJer/U6+3nw8yeHt4SPb8/obqw5EGgaoSygi4NT3g/m+Pm+0P/E+BXtzapUk7sCvzB+QTtncTOAti9NBk8Y4w+UGgTwpggLhO8o7dUKNy1nSy9kV4sUX8iuiEcPZZB0A8qEAIYlFihJWpKomGQnQGsZ28VCTTQnDXKxRoDaWInRevoxbYk8nWx3C+zYoswnuqSfZdzz92T2sOBhRHqWRE65GakACktwc3QjZFVItIYIgxYFlEVTranAP59vjw1xvdJmgZAAAAAASUVORK5CYII=)|Read Cell from Excel (by cell name) | Read cell value from Excel by cell name e.g. cell="A2" is the first cell | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAD2AAAA9gFrSKqbAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAgdQTFRF////AP//AAAAgID/VVVVVVWqQIC/M2aZZmZmVarV1dUASUlJYJ+/YJ/fv78gVY7jZpnmVVVqVYC/VZXVYp3YW5LbVYi7Woe0VYC4Y46448YAXl5eZoCzXXSXXYCiyLEW07EL58IAYGBgYGBgxagYXGFuWVlhX5TdWlpiWVlZYJTeWlpgXWBnXFxfXofAWlpgWVlfWFhbXoa/Xl5e07YM5cQAW1teXmBp0rUNWlpfXFxewqkZXFxe5cUAX5TcXpXdWlpf5cQAWVlb4cQGXV1fXpTe0LUM0rYOwakYXYS8XoW8W19mYJbcW1tfwagZXXyovagdXoa85sMAYJXdW1teXoa85sQAX5bcX5XdXXOVwacaXoW8XpTd5sUAwKcZXoa7XoW8X5XdXG2IWVlbXYS7X5Xe5cMAX5XdWlpaX5XdwKgaX5XdXYa6X5XdX5XdW1tbX5XeWlpcXoW6v6cbXoW6X4W6XYW5XoW6W1tcXoW5XoGxXoW6Xoe/WVlaXpXd5cQAZJbWXXebXXulWVlbXoS4YozCvaUbYoOu2L8WX5XesJ8uXoS45cQA5cQA5cQAvKUcvKUcvKUdX5XdXoS35cQAXoS3X5Xdu6QcWVlaWVlbWlpcXHOUXHSVXXmhXXqhXX6rXX+tXn+uXn+vXoO2XoO3Xoa9XozKX4/QX5XcX5Xdu6Qd0LQO5cQAEAW3WgAAAJh0Uk5TAAECAgMDBAUFBgYHCAgICQoMDAwNDg8REhISExQWFhcXKi01NTpCQ0RFRUpKTlFSU1RUV1dXWlphZmdobG1ub3R0dnh5enx+gIGChIWGh4yMjY2QlZiYm5ydoKOlqqutrq6vt7e3uLm7u7u+v8HDxcbHx8fIys3P0NHS09PU2Nnb3N3f4uLj5urs8PHz9PX29/j7/P3+/v6uil2oAAABRklEQVQ4y33RVVNDMRAF4BR3d3d3d4q7u7u7u7trixQopQF60/sjabl566bnLfPtnNkkCOlJ+MBWvh72ih59fjlge+hZTcbM6xzTc+45aVvjajyDzVs5jvuR9Fcx3HpE6xhfVNiDbjsm+ENMIeh2E4Ljssg4yB2nqPeGiY0Ad5qmvhiVbga48yz1pdRYqN99UyX4cnAiuP+6/Ful9RVvsSX0PkO/n/IvJcZrLiGBgJv0cdzvh+xdueGKUjx13bBTu5/iTbbvhlCWgY6LWoT9FXs+mlOAbkEDvd+8A/xBldQnrWAvoj5oCnsu9R5j2COkgneIYEfbgjcx2KNg99/rYPZvvuZPjzCWlMOezGuiPj85TGD05/GPV2pCahEr9Xy23y2582UODF+mlT6RbqZb7JTcEEKCmANdxccL7dWZTEdJ4zZIX/4A0dyRlVJ/y0gAAAAASUVORK5CYII=)|Write Cell to Excel (by row and col) | Write value to Excel by row and col: first row is defined row number 1 and first column is defined column number 1 | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAD2AAAA9gFrSKqbAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAgdQTFRF////AP//AAAAgID/VVVVVVWqQIC/M2aZZmZmVarV1dUASUlJYJ+/YJ/fv78gVY7jZpnmVVVqVYC/VZXVYp3YW5LbVYi7Woe0VYC4Y46448YAXl5eZoCzXXSXXYCiyLEW07EL58IAYGBgYGBgxagYXGFuWVlhX5TdWlpiWVlZYJTeWlpgXWBnXFxfXofAWlpgWVlfWFhbXoa/Xl5e07YM5cQAW1teXmBp0rUNWlpfXFxewqkZXFxe5cUAX5TcXpXdWlpf5cQAWVlb4cQGXV1fXpTe0LUM0rYOwakYXYS8XoW8W19mYJbcW1tfwagZXXyovagdXoa85sMAYJXdW1teXoa85sQAX5bcX5XdXXOVwacaXoW8XpTd5sUAwKcZXoa7XoW8X5XdXG2IWVlbXYS7X5Xe5cMAX5XdWlpaX5XdwKgaX5XdXYa6X5XdX5XdW1tbX5XeWlpcXoW6v6cbXoW6X4W6XYW5XoW6W1tcXoW5XoGxXoW6Xoe/WVlaXpXd5cQAZJbWXXebXXulWVlbXoS4YozCvaUbYoOu2L8WX5XesJ8uXoS45cQA5cQA5cQAvKUcvKUcvKUdX5XdXoS35cQAXoS3X5Xdu6QcWVlaWVlbWlpcXHOUXHSVXXmhXXqhXX6rXX+tXn+uXn+vXoO2XoO3Xoa9XozKX4/QX5XcX5Xdu6Qd0LQO5cQAEAW3WgAAAJh0Uk5TAAECAgMDBAUFBgYHCAgICQoMDAwNDg8REhISExQWFhcXKi01NTpCQ0RFRUpKTlFSU1RUV1dXWlphZmdobG1ub3R0dnh5enx+gIGChIWGh4yMjY2QlZiYm5ydoKOlqqutrq6vt7e3uLm7u7u+v8HDxcbHx8fIys3P0NHS09PU2Nnb3N3f4uLj5urs8PHz9PX29/j7/P3+/v6uil2oAAABRklEQVQ4y33RVVNDMRAF4BR3d3d3d4q7u7u7u7trixQopQF60/sjabl566bnLfPtnNkkCOlJ+MBWvh72ih59fjlge+hZTcbM6xzTc+45aVvjajyDzVs5jvuR9Fcx3HpE6xhfVNiDbjsm+ENMIeh2E4Ljssg4yB2nqPeGiY0Ad5qmvhiVbga48yz1pdRYqN99UyX4cnAiuP+6/Ful9RVvsSX0PkO/n/IvJcZrLiGBgJv0cdzvh+xdueGKUjx13bBTu5/iTbbvhlCWgY6LWoT9FXs+mlOAbkEDvd+8A/xBldQnrWAvoj5oCnsu9R5j2COkgneIYEfbgjcx2KNg99/rYPZvvuZPjzCWlMOezGuiPj85TGD05/GPV2pCahEr9Xy23y2582UODF+mlT6RbqZb7JTcEEKCmANdxccL7dWZTEdJ4zZIX/4A0dyRlVJ/y0gAAAAASUVORK5CYII=)|Write Cell to Excel (by cell name) | Write cell value from Excel by cell name e.g. cell="A2" is the first cell | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK3SURBVFiF5ZdbSFRRFIa/deZMMSMNRRcpsQKjJM05mV0eIqKo6AoFaYZRCdFDPVRUlGbSRFDRTSsiSrrQg0gXoqsS1psPOVJaVEZQUJAPQcRgZTirFx3IOQ7M8agPfU+bzdp7/ftn7X3OElVlMDGTCc7Pz/e8mfJhsmGoJSpWFCyBHIWG5lB4jasCgnuCKerz5IgalohaKmqRKdkG+FFBAemKFVjtJHlMQF5p3tgOM2pJ1LBU1BLEwmdOEjAQRQFUEu/kVIBVPuOcetgmKiDadaqBqwtTlW1ubPTt+4/kVSu1hhvJHSMsGVwBwKALSOodSMSKK8tj49y0XEKLDwNwsK6Mpi9NcfPdJOWAz+vj8qaLVBae7qveGLYOnFl3kpShKeys3k3kdyQ2X7ayBCs9yKsvr+PW3N/8wDZBzxP3xNaBgC/A9PEWJ/KP4fV4ASicVcDirEW0d7RTfjeUcNNkkJyy3Lj7mxpI5WpxFaOHjeJRSy23m+5wYcM5TMNk78391L95GreRf4Q/Nu5zDbT9aGNH9S7aO36ydNoSzhedxTRMrjfcsE3eF2wd6Gbe5LmcKjgBQGvbe4oubSSqUdvY+l3OhCW8BVZ6MDaeNCaDORmzHSVJRK8OLMicz/G1R+mMdlL/9hmLpi6kveMnW65t5d3X1rh4V2tgwsgJlK8qA6DiyVn23yrlYctj/EN8VBSeIjWQ6uSwttg6cLW4iuy0LOpeP6Hk9gEAvB4vletPM3NiHs2fWyi+suWfNa7WQOR3hOcfGzl870hs7k/nH/bU7CP8qYnIr4jdMkckvAXJ4GoNDCSuOdAv78BA8J8LUGpNEc678Wc8cnjAUeNgvDgU3u7tlHEqugyVEoUakFbA/qvjMtJbc2rbmqlkA367+JehsCMHehVgh31zqkFFGptD4RX9LqA/+As0xAKOOpJXugAAAABJRU5ErkJggg==)|Put Row In A List | Return the elements from a specified row in a list. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK3SURBVFiF5ZdbSFRRFIa/deZMMSMNRRcpsQKjJM05mV0eIqKo6AoFaYZRCdFDPVRUlGbSRFDRTSsiSrrQg0gXoqsS1psPOVJaVEZQUJAPQcRgZTirFx3IOQ7M8agPfU+bzdp7/ftn7X3OElVlMDGTCc7Pz/e8mfJhsmGoJSpWFCyBHIWG5lB4jasCgnuCKerz5IgalohaKmqRKdkG+FFBAemKFVjtJHlMQF5p3tgOM2pJ1LBU1BLEwmdOEjAQRQFUEu/kVIBVPuOcetgmKiDadaqBqwtTlW1ubPTt+4/kVSu1hhvJHSMsGVwBwKALSOodSMSKK8tj49y0XEKLDwNwsK6Mpi9NcfPdJOWAz+vj8qaLVBae7qveGLYOnFl3kpShKeys3k3kdyQ2X7ayBCs9yKsvr+PW3N/8wDZBzxP3xNaBgC/A9PEWJ/KP4fV4ASicVcDirEW0d7RTfjeUcNNkkJyy3Lj7mxpI5WpxFaOHjeJRSy23m+5wYcM5TMNk78391L95GreRf4Q/Nu5zDbT9aGNH9S7aO36ydNoSzhedxTRMrjfcsE3eF2wd6Gbe5LmcKjgBQGvbe4oubSSqUdvY+l3OhCW8BVZ6MDaeNCaDORmzHSVJRK8OLMicz/G1R+mMdlL/9hmLpi6kveMnW65t5d3X1rh4V2tgwsgJlK8qA6DiyVn23yrlYctj/EN8VBSeIjWQ6uSwttg6cLW4iuy0LOpeP6Hk9gEAvB4vletPM3NiHs2fWyi+suWfNa7WQOR3hOcfGzl870hs7k/nH/bU7CP8qYnIr4jdMkckvAXJ4GoNDCSuOdAv78BA8J8LUGpNEc678Wc8cnjAUeNgvDgU3u7tlHEqugyVEoUakFbA/qvjMtJbc2rbmqlkA367+JehsCMHehVgh31zqkFFGptD4RX9LqA/+As0xAKOOpJXugAAAABJRU5ErkJggg==)|Put Column In A List | Return the elements from a specified column in a list. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAK3SURBVFiF5ZdbSFRRFIa/deZMMSMNRRcpsQKjJM05mV0eIqKo6AoFaYZRCdFDPVRUlGbSRFDRTSsiSrrQg0gXoqsS1psPOVJaVEZQUJAPQcRgZTirFx3IOQ7M8agPfU+bzdp7/ftn7X3OElVlMDGTCc7Pz/e8mfJhsmGoJSpWFCyBHIWG5lB4jasCgnuCKerz5IgalohaKmqRKdkG+FFBAemKFVjtJHlMQF5p3tgOM2pJ1LBU1BLEwmdOEjAQRQFUEu/kVIBVPuOcetgmKiDadaqBqwtTlW1ubPTt+4/kVSu1hhvJHSMsGVwBwKALSOodSMSKK8tj49y0XEKLDwNwsK6Mpi9NcfPdJOWAz+vj8qaLVBae7qveGLYOnFl3kpShKeys3k3kdyQ2X7ayBCs9yKsvr+PW3N/8wDZBzxP3xNaBgC/A9PEWJ/KP4fV4ASicVcDirEW0d7RTfjeUcNNkkJyy3Lj7mxpI5WpxFaOHjeJRSy23m+5wYcM5TMNk78391L95GreRf4Q/Nu5zDbT9aGNH9S7aO36ydNoSzhedxTRMrjfcsE3eF2wd6Gbe5LmcKjgBQGvbe4oubSSqUdvY+l3OhCW8BVZ6MDaeNCaDORmzHSVJRK8OLMicz/G1R+mMdlL/9hmLpi6kveMnW65t5d3X1rh4V2tgwsgJlK8qA6DiyVn23yrlYctj/EN8VBSeIjWQ6uSwttg6cLW4iuy0LOpeP6Hk9gEAvB4vletPM3NiHs2fWyi+suWfNa7WQOR3hOcfGzl870hs7k/nH/bU7CP8qYnIr4jdMkckvAXJ4GoNDCSuOdAv78BA8J8LUGpNEc678Wc8cnjAUeNgvDgU3u7tlHEqugyVEoUakFbA/qvjMtJbc2rbmqlkA367+JehsCMHehVgh31zqkFFGptD4RX9LqA/+As0xAKOOpJXugAAAABJRU5ErkJggg==)|Put Selection In A Matrix | Return the elements of a specified selection in a matrix. | -|**Word**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAfpAAAH6QGUejxAAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAXdQTFRF////29vb6+vi5eXTksjf6Ojg6enf6urffMLhYbni4uLX3dzQ6eng3NrOIqLlAJbmApfmA5fmBJjmBZjmC5vnD5znEZ3oE57oFZ/oFp/oGqHpJKXqJqbqKKbqK6jqLqnrL6nrOK3rOq7sQLDsQa3kR7PtSLTtSbTtSrTtULfuVrnuYr7wZcDwacHwa8LwbsPxccXxcsXxeMfyfMnyfcnyfsrygMvzg8zzhpfLhs3zh5jLi5vMi8/0jND0jdD0k6LOlaTOlqXOmNX1nqvQntf1n6zQn9f2oq7Rotn2o6/RqbTSqdz3qrXTq7bTrrjTs+D4tr/Vt+H4uMDWuOL4vsXXv8bXwcjXwub5xef5x83Zyun6zdLaztLaztPa0NTb0ez61O371dnc1e7719rc1+/72Nvc2O/72dfK2dzd2vD729rN293d3d/d3d/e3+He4N/U4eDW4eLe4ePe4uPf5OTf5OXf5ebf5fT85ubf5+fg6Ojg6eng6fb9GVaodwAAAA90Uk5TAA4aHThCR0htfNnr7PP7HqL7KAAAAUVJREFUOE9jYGBgYOKpRgNczAzIgA1dvjqfF0UFO6aCdBQV2BSgqMCqAFkFdgVIKoAKsj3d3X0r4QoKskCAmxGhoCw0JCQSwyBWnFZAATtCQaqjAxAEVPuUhoEYXtUBjqkoCqpio4Egtzq1uhDEyKjOja1CUUDQimQrCwSwzrO3sLBKRjUhOwMBcqrzMjKyq9EVFFWXgKWhdDaGFc7VfmALoDS6FYQcWVFcnQjyXxkuBXFBla6gEIrBpQA7oJ4CDhUcgAOqgJMfB+BEViBlZKguwM8vb6YtyM8vZ6YjjK5AMUrDJlBALkHNzolfNkVDXwxDQTA/v7+arS6/YI2QpQEWK0AKPHTcNPn50yRdtHAoyFQyNeYXLec3MsGmIEk/wptfIt48XI9fPN7cWxJdgaiaqgKQElGWBpMyyCaw8PFjBXwsQEkAUY/45mfGYL0AAAAASUVORK5CYII=)|Open Word Document | Open a Word document by referring to the absolute path | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAT3SURBVFiFpZZfTFN3FMe/51J620JLTIsynUwgDhYnxWypuhdj5pjJNt78M002FUxG/Le5zckmuCEKcTObmSYmhuBc5hKXZQtL9sA0kwdNwCUKeyDOAYkIammjtEILvb1nD6Vw/1Pnebq/3z2/3/dzz++c87vEzDCy/lUVa8FyXklX76+GDhlarKbmEyLaA+A3x9jYPly8OKV8LxgtGgj4a0nmy8T0y0CgvPn/iserq5sJaAHzIjC/F/N4fsLGjXZLgIGAvxbAaQCUmqGDAwH/sScVj+2sPg6ig8o5Aqq0ECqAzvLSC1FJUojPWF3/Sv/RTMVvfL30K1mQ3jd6p4WgdA4MBPy1UUk6fScWp8VOBzw2m24xM46WXO85ZCV+7cwznxPxYWfMjaV9rySyktnZRn4MtDsjkQ3EzKqwRyQJQ7E4zCAI1FTUfbPeaNOe7wpOTsSxNz2eCwJEZ+jflf61JPNlKMI+NwQfKerubVDOhToWHGfGhyMPSJiIzc5bQhANC2A5D5oz99hsWOx0YCgWR0SSdOsYVD8YKG9Mj0c7CppB+JgECAsXsOxyzvrGnFHcfuFadjIrkdDtw/zt9BGUNwPqjM0kEgA3upuCdiJWrWUZ8pyRYG5xtLbWKZPwGIC6J4EQK6MQ14wbgFlDCLLtG+fZ1gOAogoAoH+l/ygxPs0EwkocAJJJYPgegQQgHp+dd0y4T6z44PZH6bGqD5R09XzGDF29a3MiE/G7IwSHA3i2YDYnmOkLpbguAmkbDFQcYbCu3iOSBFoXwaLXpnRrtOJOJzDfl9qbZcgj9+mU/937+7T+hgApiPJGBqnqPdMvV4qnCPClr/LBAaM1hpcRABR19zYQ+MjTijNTi5m4JUAaAuDGjMUdevH8yvu6ylKaUXGrbLrOMxPPn/Wb7MzBZEcu8iut97eMwGhHQbO2yRiJOwzF3Uhd5db/E6YATyK+wFA8bdYQhgBziQOpJqMVH/7DjtHfnQbe5hA6gPClwkNziQOAdx7rvhyXPKYXGEAHB9cEdL1FBRAKXXXbK85uJtu8oJFoMgk8fJR6zsmZnU+H3W2zodDkFhW8eUHfj02bQ6GrbtW8ciAKiU0gcZl9+anHWoj0mSck9d+a9syNIARvXtDb1vAYon2ZKCQ2mQKAsQMAQLZiJYQq2zV1PtmR26KNlBJi3OMa87Y1PEa2rTi1iLYrfWdacTR8pQxAnxpIGpi4uctz986YT5twyiZj9j8xnpczVth2OCI4xcXqfbnM7Vt7SxMBNVk6ElnFdTFXrjhhJg4Axd29dQCrIiF484JLvm8M68QBgGibJgJXbNEwhgAU6JynIzH19+5clh7Ot2qv6UjMnHk67HqCEbc3WAhsSAoAEA1hvak4MJ0TJ0eJxHqr3l7c3VtHTrHe23po1FwcAHhhZNT3OjB9BG/vOrclGIqa+OIqCDWTyF3tXXenyXzTlBV1djdN2nNWg7AToGtGPsFQlLfv/2EHANDzL73lE7J52OfNmTp3YmvufJ8bAIYBPg+Wz7l9r/4zl6iVRUN/lqbOnN4BeGEwFMXWPefDY9G4W07Qoizfc6U1BLw5EUugt2+kvWr98v0eb+du0bXtkugqDj+NOACIrqKw6FpyWXRdPzk57uraW/+za+jeoxcB2JFFw1S26o02hnCDE7hw66/20NMKZmKlL1f5KBtbCPKK/wAGOI4jKi0o3QAAAABJRU5ErkJggg==)|Replace Text | Replaces text in a Word document, for example to fill in certain fields in a form | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAFuAAABbgGEUF8kAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAVBQTFRF////AP///4CAv0AgQLOZ3F1RQ7GbO7Gd41VMtTgq4VZOtzcrszgo41hM5FZLzkk7PLKfPLOdPbKdPLOePbOfzEU4zUg64ldM4ldL41dNPrOe4lZMPrOe4ldMPbOePbOePrOe4ldMPbOePLSePbOePbOdPbOetTYp4ldLtjYp4ldMtTcpwj8ztjUp41dMtTYp4lZMPrOe4ldMPbOf4lZN4ldN4ldM4ldM11BD4ldN4ldM4ldMwD0x4ldM4ldMPbOetTYptjcqtzgrvz0ww+fhxuniyerk4ldM4lpP5GBW5GJX5WVb5Wlf53Vs53du6oN76oZ/6oiA646G7ZeQ7ZmS7p2W76Od76Wf8Kii8Kmj8Kqk8a2o87iz87y39s7K99DM+NTR+NXT+NfU+dnX+dvY+d3a+d3b+uDe+uPh++Xk++fm++nn/Ovq/O3s/vr6////kQlsrwAAAD90Uk5TAAECCBQWFxobNzs8QEBBSV1eYGFlaH+TlaqusbKys7W2tri6u7y/wcTGx8nMzc7R4+Tl5ubw+Pn6+vv8/f3+lASLvgAAASNJREFUOI3l0NdWwkAQBuBBFHvHrth7F00kMWFRYcQG2LD3Lmbe/87diOcoTvAB/C/m5v+2AshUjWmaput6JGIYhmmalmXZNiIur4xWqh4mkM+aEOMu8OhRCDH9B5itKQr8foCiAOAfgmvnPoU3zvtFEu+cWwY4mbMHpMP9XBYps82B1OkTUhqzj0g7Gxyg57QCRy9IdM6BXTnoYO/t2GOHyy05cvR6solXScTFno4Z72fa7RXwPYX9Qp0vGAqHu5s8gF0bGIq66StlQZtvOJpPLwvKgqqLr6vZwIA5CKmKSM1OBnRBWK4nGbnHPAP6FUgoEOfBUsmPI6onRUFi9e4lE3E1G+FXL8SUb+TrmQPAgVhreV4MBoA5QojVls+vbpb3+wBkgtxo6h4uQAAAAABJRU5ErkJggg==)|Convert Word to PDF | Transforms a Word document to PDF | -|**PDF**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEHSURBVFiF7ZZNTsMwEIU/R1UNG+JUpOfhNL0AUlfddctNOARn4AK9QBJUpxKNpVphkf5QCagHJcrGbz3y+8Z+Hls9r99a+pV7WT3dhRYnPZuLFQEiQASIAKMDTCTFm807cJncdlvgvSebzVEqwbk9ta30Ylk0gwBAS9t2ANaW+MMBk80BRdN8UtuS1OQAOnTFfx3Bd/MkOXVe8pA+ovW9aC0xQJ/mYgC7LW6aO7cfDsB7/7f5MQcSiUKYzbrA/WpeV5guhMES7cDlqv1snpqc6ZAhvGk+Df6JnTUBXGhxbSudmvwqcLvdB+aqcyUCUKfBEqLF8rVBMGRCNPpbEAEiQASIAKMDfAHZRpDbmRa42gAAAABJRU5ErkJggg==)|Merge PDF | Adds the pages of pdf2 to pdf1 and saves it at merged_path. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAPrSURBVFiFvZVvTFV1GMc/zznnklgXLggDLM3NJspyhKPmaDnkBUy8pDajrfXGWHO5hpW8tulqhZM5Wbb1omVvWn+dTYEG6nWYWVvOWi665Au1W0Aw7mU0Arn3PL04l8u5DLZ7wct3OzvP7/k+v+f57jm/8/xEVUmguf6BMTHOKGxV5HjeyXPvkmEY7kUYeU6hHsgX9GjkjT2+ZRUA7HLZluq9+uUTsL/SIyI7klibZ5dNwFh2UTWQ4yZFZAf7Kz3LIkDVmG2/6tm4lRMXlnkBoA1xIyTKO/MKy5SASHN9BbAWQIWO3Pc7rwMDjgI7o+fAAkDEVUTPo6oc9HcCTYisiTTXV/jaO284fKMZ7l9XJdirnHC1Taygt7Q1uHgBGLvAGUii0ho56H8bKEhEOQJvAER+X3tYxD48m0KIESMSbBkBCUQxmgpKW8dTFWCMHtq9BrTC5SsDyoGHEx6d7ZAKpQvkKgB93sL+KNXiAIZEp2fbL1xV1c9nHuBO3L/FEZoMVV5U0Z2IHgKmnVBt4PIRK1UBFriGjcReymvvuj2zjDT7X0c44VDRBuAD9+aobQQKNx4bBDoj/S3bUfwKK0YfmSjOh1AqAgxByuP2Td+J2eIOKR0JW3XzQkkGrh9ZibIJQGAy/7GVf6dS3MmLvAx8ImrvnkvmnDz3hwiNoB+rYbfO5T2WfSESbPkl+6HxUWC949Uz8JadqgBJuo5TQDjY8pnACwtnZI9vw/GzC/JzMPc2TAuCfAv6DdCfcCqnRm815yy8Kxkpn9b5cC8m+wrL2gYBxoItpxQOAKvN6IqtQDdA45eYkcKhfYYtT6tBEWrfViXQU1P8lYIuSYAbqlxEOACgomVAd9W1ULa3wNMrSqWKxmedIMKrtYGh7+umqV3SJ0gSgLgH1BiAd9LTClTOOAVGXDFVeOTYkjpgGfb20eCbYROzXERfm/Hbtt0XN/fG3//apv1Uz7aSvtrLw0+I2j8BJqh/aYdQ+NTA6FL0PWC149Ur+ZvafvB/dzcPKHECCfRsK+kD6K4u/Bk474QylXYHRAki83OKdqtpNQHEolm5LiJpMJmWvhKNGV1qxnrTFuDbePdouH/dhcR1DAg6HjPpz1/f9mcqOTqfKR4GPoRF/YZfxPI2cCX9ffPjvv0Fi8V9mwPpQEDqLg0+mTWhNzPWgemY8V9ioeS6udrA4GkV+XHqQSOQ9mWUDuoCQ2HAJzAyJUUlgWqiVddC2d5JzxDgBYYzegYEegEUCrJ0KFQbGPzaO+kJxYujkNkO7Lw08GhUjF9nCs7BP1G1tmS0Ax01JXcstTeLymngFjCh8BvQblr6+MWaVX/9D48CdgjDk2lOAAAAAElFTkSuQmCC)|Extract Text From Page | Extracts all the text from a give page and returns it as a string. | -|**File Manipulations**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAO1QTFRF////AAAAAACA///MOTlVQCtV7+/fOi5RQDVK5dzKOjFKgHmGPTROPTJNPTJLPDFMPjJMRz5VPjJMPTJMPTFM7uvePDJMPzRO4d7N4NvKPTJM2dXBPTJNPTJMPTJMQDZPQTZPSD5VVUtfV01hZVttdm17hHuGhX2HkouSlY2UpqCis62tuLKxx8G91dC71tHE1tHJ19K92dXB2dXM2tXB29bC3NjF3djG3tnH4NvJ4NvK4dzL4d3L4t7N497O49/U5ODQ5eDQ5+LT5+PT6OPU6OTU6ubX6uba7Ofb7Oja7ejb7enc7urc7urd7+ve8M8MaQAAAB50Uk5TAAECBQkMEBYYHR8mO2BwcoCEnZ6/yNfc4OTn8/3+6DSEYQAAAM5JREFUOE+l0OUOgzAUhmFmzN2tc3d35sKE+7+cAcuS07WFhL1/edIvHI6LSj8lnBwWAeZpXJCgiwsKwAUNYIIKoKADIFQgjJUEFQhTtaQFAvGkJGIv8awJY+Cygx1JsJ/BlgYm/gerLmxIgtcd9jQwoQsOC9iGBOc1rNe66kwUC7WOJmgghEpBFwCPC0zsI6VsxGv7gvUANpHKqkj5rKzfbMqfM34r+w7bPMrFQyaNQ1VQ1R0Lm9mgnRvxjo+gg1tdvoMjFmAC6aUcyu7h3hgM0xOjQKpIAAAAAElFTkSuQmCC)|Open File | Opens a file at the given path | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAeLAAAHiwGGjZs0AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAUFQTFRF////7e3b8ubZ1lxH2V5M7+ffo0dA4t3K8cWH39/H5N/N4ODKoklB7+vgoUdAqk474Ywl4ook4owk5qVU7uvf1llLpUdB7+re11tK3NnNzcnA3GdB0WFA4Ism11pKrlQ7zVdI8p4l75kh4Ysl75sl4Y0lpEdB8psi5N/P4o0ncXFv4d3Mo0ZAo0dA4Ywl4Ywm2NPA19O/g355lJGMo0dA1dC71sSw11pK19K+19O+2ci22dTA2dTB29bD3M+93NfF39rI4NzK4Ywl4Y8s4d3L4pU24tbG4t3M469v47Fy497N497O5ODQ5uLS6OHS6OTV6eTV6eXW6trG6ubX6ubY69Kt69Ku6+fY6+fZ7OjZ7Oja7ejb7uDN7uLJ7uTT7urc7urd76Q57+PL7+XQ7+ve8KM58Lpr8pwh8qc88qg98qg+EJkP/wAAADJ0Uk5TAA4UGRsgJDU1Nzg6P0FERUVGR1toanqgpqivvMbX2t3d3d7i4ujp6err7O/29/f3+vtf74FqAAABA0lEQVQ4y2MQSUEDGuwMKABDgYsBOwEFpgacBBSYGnARUGBqyEVAgakhNwEFSCrACgIsLYDAHqzA1wEMtBlRTAgJBoIoFJNYcVlBnoJIR2TgnoChIMoFGXgl0MANEG/CQASmAkhAwYBNPLXcwCIhilcBs5y5ghhUQaA1MrAFu4FD2lxBzYQHoiAhwB8JBIOEkhTVZdRMdNhwWZGUla4kK6/Lh8sNSZnpKqpOyvwwR0Z7IwOflKSM9ERNJz0huDfDHZCBY2xGeqqrk54grnBIBsvrC+AMqLg0oLyzMO6QjAnydHIOxR3U8XZWZh5huOMiwdjIzS8BEVm84mhASksSTDNB5AHSbAq+H1vdKgAAAABJRU5ErkJggg==)|Rename File | Changes the name of a file located by a specified path to new_name | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAATVQTFRF/////4CA/1VV/21t7m9e8HFi7+rf7XBi7nBj7XFg7nBh5eHQ7XJh7XFh7XFi7uve7+LT3dnI7HFh7XFh7XFh7nFi7XFi7oJy7XFh7XFh7XFh1dC719C719K919K+2NTA2tXB2tXC29fE3NjF3djG39rI4NvJ4dPB4d3L497O5N/P5ODQ5uLS5+PT6OPU6OTV6ZSE6eXW6ubX6+fZ7JCA7XFh7XJi7XRk7XVl7Xdn7X1t7YR07YZ37Yt87ejb7enc7nhp7npr7paH7puM7qWW7q2e7rCi7rqs7sGz7urc7urd735w739w74Fz74R279HE79PF79XI7+bZ7+rd7+vd7+ve8IV38Ih68It+8ZGE8ZKG8paK8paL86SZ9Kui9bGo9rau+MfB+c/J/vTz/vX0/vj3////q6XFbwAAABt0Uk5TAAIDBx4iMDlLb3aHi5maqK2vwMLIzNnu8vr9USbcyAAAARJJREFUOE+l0ddSwkAUgOEgir13scSOLZb4xy7Yjb2wiiKiQnz/R/ACEzZm4zj4X39zzs5ZLSZ+lGzXfAVB3C8UwC9UwCeUQBZqIIkQUBYxIYSwx3Rd10dNIYSwx0s1+iYsG4ZhLPomtYatqBDMz8mZAWBPTsgtVLDi38AejsvNBickd+XSf1hxd9P2GzjZtqCnocoDZ4kpqelVSnVVuyA9k5Bawq0zolpxCnsvwPM51KvAPlwU8+ScR+h2gblSbhPIFD6cLNAf/T7UyJDXoAXw9vkOQI1ixRaQc14LeaAvogAH8OBkyRSfoEP1yGuL9SvgMgV1ykseeXdoUZ/6/ngNgIGmaNhf3B7ubPQ212qapn0BM+fidWEezeYAAAAASUVORK5CYII=)|Remove File | Removes the file with a specified pathname. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAANtQTFRF////K6pVIK9gIK9g7+rf5eHQ7uve3dnIyeDGIa5eJK9gJK9hJq9hJrBiJ7BhJ7BiKLFjK7FlLbJnMbRpNbVtObdwPLhyQbp1Rrt5R7x6g9Klh9SoiNOpkNevnNu3s+PIuOXMuubNwejSze3a0+/f1O/g1dC71ePO1uTO19K919K+2NTA2tXB2tXC29fE3NjF3djG39rI4NvJ4PTp4d3L4fTq497O5N/P5ODQ5uLS5vbt5+PT6OPU6OTV6eXW6ubX6+fZ6/jw6/jx7ejb7enc7urc7urd7+vd7+veQ+YvegAAAAl0Uk5TAAYgMDCHqK+zA//U2wAAAMhJREFUOE+l0NcSgjAQQFEUG/beFSv2jr2hgvj/X2QIzrgxBEe8DwwPZ3aTcJ7HR6qfI6KBRAoLQAorQAhLAIU1AIIB3gIDbTxEjRT8PzHzEhNOB9SRmORjrXAIthuYQgFtNoXtHaz4G2h9CbamJ6g3mP77CrJuxyjgNnKZ4C7PQWEBlckbX4E3gb6SQRgURQjIYk6AcgZFaaANeiB0hiAGIeaKcj2CQKXGBKlWoyRWLwX2IZPNxXKXs7tFon3N2l8znv7yDq/4J0l2t8Q30wM1AAAAAElFTkSuQmCC)|Move File | Moves a file with a specified path to a new location. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAeCAAAHggFwQHG1AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAWhQTFRF////////////gIC/gI/PhJXKg5vJh5bLhpnMiJjJ7+zd7uvdhZbKhZfKh5fLhpfM7uzdiprMhpbMhpfLhpjMhpjLh5fM5eHQiZrM7+ve6+jd7+veipzN39rJjZ7P3NfFi53Pi53Oi5zOrbXShpfMhpfKhpfLlKXTiJrMkKHRi53OiJnMo7bcm6vWiJnMprreiZrMjJzNjp7Ojp/PkaLQlqjTmKnUnKnQn6vNoa3Mo7bcprneqLjdq7/ircLjsL/gsbrTs8jntcrotrvMucDUuc/ru9HsvNLtwMbWwdjwxdbtxsrXx9ftyN/0ys3UyuD1zdDYzeX3ztHYz+f40Oj50ej50uDx1dC719K919K+2tXB3e763/D74NvJ4NzK4dzL4t3M497O49/O4+Hc4/L85eDQ5ePc5uHS5uLS5+LT6OPU6OTV6Obd6eXW6fX96vb96+fZ7Oja7enc7ere7urc7urd7ure7+velq3F9wAAADB0Uk5TAAECBBAdISIoL1JaXGBseHh+gYmLjZ+fprCywMjKztTY2tzc5Ont8vT19/j7/P7+MsgC3wAAAQZJREFUOI1jkC5HA7JMDCgAQ0GkPBMBBeGoKrAoQFWBTQGKCqwKkFVgV4CkAqwgLgIEUsEK4mPBQBxFQUkhCJQiGySJ0wryFKTHIoNMTAXZicgglxZuKMxCBoWYChKikEESMVYUS+FTUOZhbqCnIMiMS0Gauamrr7+PriIrWmTBgIVVcEhoSn6evRwjTEFRARLwMwkEyefnR2vyYLXCwRYiHxNiJ4FVgbkrVD7ETQmmIAM5riwdofIhTjIwBVkJSMDZBiofoiOK1YpkwzCIvKc2G/Zw8Db2Asm7a4ngCskAIzNrfXUNMTVOXHGRE+SizMvCwKfKQSA98KuwM3ALYAdc4JgSEgYAAoU+jTu4WA0AAAAASUVORK5CYII=)|File Exists | Checks whether a file with the given path exists. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAeCAAAHggFwQHG1AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAaFQTFRF////AP//////Var/VarVTp3YRKLdRqLYSaHbSJ/b8OreSaDcSaDdSKHbR6DcSJ/c7uzd3+XdSKHc5eHQSKDcSJ/c7+veSKDc7uzegLrdSKDc39rJSaDc3NfFkcHdY6zcSKDcTaPcSaHdSqHdS6LdSKDcSaDcSqHcS6LdTaPcTqPdUqXeVKbfVqjfV6jfWangXavhXqrcXqzhX6zhY67iZrDiabHjaq7YbLPkbbPkbrHcbrTkb7XkcLXldrLWebrmerrmfLznfbzng7/phsHpicLqi8Tqjb/djcTrjsXrkMDclMjslcnslsrtmMrtmsvtnMbdn8fdqdPxq9XxrNXxrtbysM/dstjzs9nztNnztdnytdrzttr0t9v0udz0utz0vN71weD2wtfdwuH2xuP3x9vhyeT3yeT4y9vey+X4zOb4z+j50OXy1dC719K919K+2tXB3dvN39rI4NvJ4NzK4dzL4t3M497O49/O5Obe5eDQ5eHR5uHS5uLS5urm6OPU6OTU6OTV6eXW6une6+fZ7Oja7enc7ere7urc7urd7+vecW4iEgAAACV0Uk5TAAECAwYNHiExQFZeaXJzdXh+kp+msLC0uLm+ytPU1djj8PT0902MouoAAAEgSURBVDiNY5DoQgPSTAwoAENBviwTAQW5qCqwKEBVgU0BigqsCpBVYFeApAKsoCQPBKrACkqLwUAYRUFHKwh0IhskhtMK8hRUFyGDWkwFjeXIoIkWbmitRwatmArKCpBBBTXcUJkkx8fJilNBe6CmqZO9kRIPI2pkwUChlUVcdnhISoSBODNUQVsLMvCyznTRU1VVd00z4cdmRYZWiqcqGDjHqbBhURDgFKsBUaAWb8sNUVBTjATsdLRVocDPQwiioKEMCZirwoGHnwgWK9yDs7KyfMEKghz5sSgIC8201AfbYpyuz4lFQXNUYgJYXjfGVYoRW0jmOHgn+9lYuqX4KLNjDeq6VENr7+hIfzMZDmBQcwlgAYKS8ooKorwsQHkAgUdq5YOagO0AAAAASUVORK5CYII=)|Copy File | Copies a file from a location specified by old_path to a new location. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAeCAAAHggFwQHG1AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAARpQTFRF////gID/qqr/gL//n7/fVVWOjsbjUGCA8+jcVWCAa3OU6OjY7+rf7e3fu76+j7nikbni493Mkrngkbvh7uzdkbrikbrhkbrhkLrihYydVWCAVWCAkbrhkrvh5+PTkbrh4dzKVWCBVmGCV2KCkbri19K9VWCAWGODWWSDi7LYkbrhlbzhmb7hm7/hncDhn8HhpKewqMbgsMXXus/gwNLgwtTf0dvf1dC719K919K+19O+2NO+2N/f2dTA2tXB2tbC29bD2+Hf3uLf39rI39vJ3+Pf4NvJ4NzK4d7V4t3M497N497O49/O5N/P5eHR5ebe6OPU6OTV6eXW6+fZ6+jc7OfZ7OjZ7Oja7ejb7enb7enc7urc7urd7+ve9Z348AAAACZ0Uk5TAAIDBAgJCRAWGB8hMDhLUFhaW3h4lKKrrbzg6O7v8/T3+Pz9/f7mJ3I+AAAA/ElEQVQ4jWPgiUUDcoIMKABDgZ+qIAEF5qgqsChAVYFNAYoKrAqQVWBXgKQCrCDS2gIIbKNB7CA3MFDgRjEhHAQiUUzixWUFeQqi3JyRgEskhoIYX28k4BNDAzfEBgYggUBMBREOdkjAPpyAFSEeIMDHCQTsWBUYaKgDgbKSkpKiFCt2RxprQQAL3A1WFkjAMtwUIi/DCHdDWDASCI11gigQwx0OemAF/LgV2OgA5UWZEZHl7oYE3IGR5W8oK4QcWd6eSMALGFmu+irC+OLCTBtohQQbbgW6YEcK4FTgCPGmOE4FJhAF8ky4IstIEwK4gJHFIYIBJNXgQJoVAEDK+Bh97JvfAAAAAElFTkSuQmCC)|Wait For File | Waits for a file to be created and then opens it. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAGxQTFRF////d4i7QFBgcIC/Tlp2VmKJXpGKarCea7WgUnJ5cpS5aXerRExjccKpRlRncoG8QkphccOpQkpgT1Zra3GCccOpc4O/dXuKmqXMo6zPs7vVvMLYwcfazM/d0tXf1Nfg2dvi3t/j4+Pl5ubmy3bLFgAAABJ0Uk5TAA8QEMDAwMbKzdTa2+ns9/j+a68FFAAAAHpJREFUOE/t08cOhDAMRdEMbegMpgy9/v8/omyAhIQnseauj2R7YcZQxtHHVMToyC4VncEvAIDCBACy/EsiILeQk0AcAUBeCgA5X7ELkHvBc5D99zIlyNe9XAP6quqWetSDqWmGtZ1vAW+6G8HrtQAsCc8Uw8AAoednGxKCQxnLbH7rAAAAAElFTkSuQmCC)|Write List To File | Write the contents of a list to a specified .txt file. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAGxQTFRF////d4i7QFBgcIC/Tlp2VmKJXpGKarCea7WgUnJ5cpS5aXerRExjccKpRlRncoG8QkphccOpQkpgT1Zra3GCccOpc4O/dXuKmqXMo6zPs7vVvMLYwcfazM/d0tXf1Nfg2dvi3t/j4+Pl5ubmy3bLFgAAABJ0Uk5TAA8QEMDAwMbKzdTa2+ns9/j+a68FFAAAAHpJREFUOE/t08cOhDAMRdEMbegMpgy9/v8/omyAhIQnseauj2R7YcZQxtHHVMToyC4VncEvAIDCBACy/EsiILeQk0AcAUBeCgA5X7ELkHvBc5D99zIlyNe9XAP6quqWetSDqWmGtZ1vAW+6G8HrtQAsCc8Uw8AAoednGxKCQxnLbH7rAAAAAElFTkSuQmCC)|Write File To List | Returns the contents of a specified .txt file as a list. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAd1AAAHdQEjKi9uAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAANtQTFRF////YGCAQEBQVV6AV2OASFFmPERQVGCAT1dyYo2CZJSDVWCAX3+CVmCAYISCbLSFbLaERE1gRExeQktcaquFTFZva6yEVWCAb72FcL6GbriGbrmFPURRVF18ccKGVF9/VWCAccGGPURRVWCAVWGAVmKAWGuBWWyBWW6BWnGBYIaCYIeCYYuDYo2DYo+DY5KDZJSDZJaDaaeEaqmEaqqEbriFb72GcL6GcMCGcMGGccKGccOGd8aLeMaMeceNeseOfMePfsmRf8mShsyY9Pr29vv3+v37+/37////mBh8MwAAACJ0Uk5TAAgQHiw8QEBeYGl4j5KVsbW/wMHIysvS2Nvj5uvr9vf3+WM4ONIAAADESURBVDiN3dPHDoJAEIBhbKBi772tXVEUUWRVBBvv/0RmOBggQ/bAzf8wl/myGzaB40JHfg3iDEDqEQYgWRYgSd5f1Au6nZEv3gtIlQVImQX6xZKnhB/4E/4aTLd7VZHngWB5pJC2DgAr2F5hSCiYnWD3vMAZKQzIzvm2ATOPAcUFGhhQ6e1lQx+L9jBwoNQwTfth3iltYmDnuqKAgYUGqzd8p55G30ECYMGQ8Ycab87OLbo8ETgRLVNpDdu1nCjGwv/cX6d2dbbN5MFoAAAAAElFTkSuQmCC)|Make New Folder | Creates new folder at the given path | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAeWAAAHlgHGqeZtAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAL1QTFRF////VVWqVWqAr9PwV2CAVWGCVGCAPEVSPUVRVGCBR1FnU158VWCAR09kQEhYPURSS1VuVWCAWGODfpSyTVhyZnOTaHaWjqfFVWCAPUVRpsbhVF99VWCAPURRPURRVWCAV2KCV2ODWGSEXWmJXmyLYnCQZXOTZ3eWbn+ec4WkdYmneY6sfZKwf5WzgJWzhp27hp68jqfElbDNlrHOl7PQnLnWn7zZob/cpsXip8bjq8vnrM3pr9HtsNLusdPvC0szVAAAAB50Uk5TAAMMIzg/QFFof6GlsMHGyMjIyczQ0NHa3OXn8Pz9gXxMGwAAAJtJREFUOI3t07UaAjEQhdHgFtx1sMUhOAS57/9YdMu3gWQKWv76FHOLEYIr7hcLfQX0LsWBTpQB1AgzgDJJs0QQUK5nlDdAu8kAqnQZQIVsoPQHMCr+wW9gM2XAFpf12AUmAJ7HxdB+wxkAcN/VbGAFALguSzYwegBQfcfMPXDQngPMcSKlPTsY3GZESleFtFWWUsp6i/vtCAfEC6QbY4axo4E7AAAAAElFTkSuQmCC)|Open Folder | Opens a folder at the given path | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAeNAAAHjQEGjt+vAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAOdQTFRF////YGCAUV2AXV1dX19fVWKAVmCAVWCAPUVSVl+AVGCAenyHT1p2VV+APURSPUVRVGCAVl9/W15nc1ZoUl15RExdi09UPkVST1l2UFt3UV15VWCAZGRknUlFPURRVF9+PURRVWCAVmCAW2B+XGaDYGB8YV97YmV4a1lucm96c190fGxnfWxmfnx/goWVnEpGnFtfoUhCoV9Jol1Go0dApJ6esZBpsaWau5JlwFhPwVtTwltTwpxtxW1KyLmsyrus0Y8104gu1pEy11pK2JAw2Mm724op3Ysn3Yso3ZMt4Ywl6dnF8pwhMVoetQAAACB0Uk5TAAgWFjs8SmBkbnCGkZOeoKChrbq9wNjZ2d3i6e709fhDjEOaAAAAt0lEQVQ4y2NgIAS44ICTEasCRQTgJaRAkY2QAmkmAgoURfj40QAHqgJFUQU0wI+mQF6cgAJFSTkCChSlJFAAD4YCNCAw9BUoaynhVaBm7WwgiEeBqpWzpb4YbgXqDraW+iayOBWoO/m4GJkYCjPglvd0dDPWwOVIsLyXuzYub0LldXCFA0IehwIzuDx2BSreNo5eHjq4g1rP1d4CKo9dga65nakmPLLYMYCQDDeCw4olK7EwM5ACABMnbbWUe+PLAAAAAElFTkSuQmCC)|Rename Folder | Changes the name of a folder located by a specified path to new_name | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAd1AAAHdQEjKi9uAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAPxQTFRF////YGCAQEBQVV6AV2OASFFmPERQVGCAT1dyl2hypWhwVWCAhGZ2VmCAjGd0129l2G5lRE1gRExeQktcyGxpTFZvym1oVWCA5HBj5HBj3W9k3m9kPURRVF1863FhVF9/VWCA6XFhPURRVWCAVmCAWGB/ZmJ9aGJ8a2J8b2N7j2d0kWd0l2dzmmhym2hynmhxomlwpGlwpWlwqGlvwmxqxGxpx21p3G9k3G9l5HBj5XBj6HBi6XFi63Fh7XFh7XNj7XRl7XVl7nho7nxt731v74J074R28Y2A8ZCD8ZKG8pmO85yR86CV86SZ9bSr972198G6/vb1/vf2////lYhKUQAAACJ0Uk5TAAgQHiw8QEBeYGl4j5KVsbW/wMHIysvS2Nvj5uvr9vf3+WM4ONIAAADTSURBVDiN3dPJUsJAGEXhgApKBGdkEBwamRyAKCoSjiI4EBCkef93cQVVSf1UL9hx1t/qVl3LWjm16GLTANRpyABU3ATUdiRY2A9yZ1eBIn6gTkxAHZnA+cGhr60gCBZda1CsP740nfJSUG0B0L4tyOCGeXciKL3y1gd677g7EnCgrz0G0y/Yk0AT8PR4OgJSEngGGM8mAHkJPAED/ac9IC2BB+jpX4b6E/YlUHHp/gDfH3Ri4g73ix0a8lCFmgtAx7mOWrbY7nHmMptM2PbG6uf+B+nvd9E69Zz5AAAAAElFTkSuQmCC)|Remove Folder | Removes the folder with all its contents from a specified pathname. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAeWAAAHlgHGqeZtAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAKtQTFRF////IJ9gVWGGVWKDVGGBVGCATml6VWCAIq5eVGCAPUVSPURSPURRVWCAUVt4Rk5kPURSVWCAP0dVVF58UFt3N49sUl17Ul18PUVRVWCAVWCAIa5eOYpuPURRPrhzQ7p3Rrt5S718Tb5+UmV+U2J/VWCAbsqWc8yZe8+gftCihtOnidSpi9Wrltmzl9mzl9m0nty5reHEr+LF5/bu7Pjx7vny8Pr0+P36+f37KfPDEQAAABt0Uk5TAAgVJ2dweYeIiImssLKzwMjIzs/e5efp7vX+JEdy2wAAAJJJREFUOI1jYCAEOOGAnQmrAlUE4CWkQJWFkAJJZgIKVIW5edAAF6oCVX5ZNCCApkBKiIACVTEJAgpUxUVQAB+GAjQgOIIVqMgggCg2BcrSIKCuBqZwKzDQH2AFSnIgBQoKOBXoGcsb6CuaauO2QtfEyNBMG58bdMwtNPE7UksD4khWTMAmjQSwZTZGDiRAMPcDAPdLbmhwE+yVAAAAAElFTkSuQmCC)|Move Folder | Moves a folder from one specified path to a new path. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAeWAAAHlgHGqeZtAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAW5QTFRF////ttv/r8/vVWGGVWKDsdPws9HwVWGBstLwVGGBVGCAWmeGsdPwVWCAVGCAPUVSh567PURSPURRVWCAUVt4l7PQRk5kPURSVWCAP0dVVF58aHaVeY2rUFt3Ul17kKjGUl18lbDNPUVRn73Zr8/rVWCApcThrc7qr9LuVWCAPURRVWCAVmGBVmKCV2KCWGODWGSEWWWEWWWFWmaGW2iHXWmJXWqKXmuKX22MYW6OYnCQY3KRZHKSZHOSZnWUaHiXaXmYa3uaa3ybbH2cbn+eboCecYOicoSic4Wkc4aldYindomod4upeIyqeY2seo6tfJGvfpOxfpSyg5m3hJq4hZy6hp68iqPAi6PBjaXDjabDj6jGj6nGkqzKkq3KlK7MlbDNlrHOl7LPl7PQmLPRmbXSmrbTn7zZoL7bosDdosHdo8Heo8LepcXhpsXip8bjqMfkqMjkqMjlq8zorM3prc7qrs/rrtDssNLusdPv+pNMsgAAACp0Uk5TAAcQFSc0Q1dmZ3B0dYeIiaGssLKzvcDIyM7P0dve5+fp6+7y9PX2/P3+YwCKVwAAAQFJREFUOMtjYCAE+OCAlxmrAm0EECakQJuTkAJVFgIKtKUEhdAAP6oCbTEtNCCOpkBTkoACbTklAgq0FWRRgAiGAjQgMbQVGFvgU2ASnl1RXhRvh0uBa0Gsg6G+U0hJoA5WBbalbpbRufkRTvbJRtgU6KYHOJRVAkGFh5GZNBYFznkGBSD5vLQkczN5LAqCwrxA8pWR1tbWjspYFMQUllTCgToWBaGJwcHBUWDpdDc1LAo8/HV8/MPACvwCFbEoMPXV9qwAy6cZ58hgCwdrb2ufTKAvo0ziErCHpFexu56Vi6lNapa5BAMXNiCgUpoSk6Ehys3FjiNLM7Jy8LAxMRADAFwboghkvrTsAAAAAElFTkSuQmCC)|Empty Folder | Removes all the folders and files from a given directory. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAd1AAAHdQEjKi9uAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAASZQTFRF////SW2SN0lJU1+CO0RSSFFmPERQVGCATld0VWCAjanGVF+Af5WyRE1gRExeQkpbTFVurc/rVWCAUl17PURRVF9+VWCAVWCAPURRVWCAVmGBWGSDWGSEWWWFW2iHXWmJYW6OYnGQZHKSZHOSZXSUaHiYaXmYbH2cbn+ecoSidIeleIuqeo6seo6tfZKwgJWzgJa0hp67jKTCkKnGkavIla/Mob7aob/bo8HdpMLep8biq8vnrMvnrMzorM3pr8/qr9DssNDrsNDssNHssdHssdLtsdLus9HrttTtttXuutfvv9zzwdzywd70x+L2yOL2yeL1yuT3y+P1y+X3y+X4zOT2zeb4zub4z+f5z+j50Oj50en50un50+j42e365vT86PX96vb91hQwQgAAABh0Uk5TAAcOKzg8QEBYeHmOn7/AwcnL0ejt9vf+KYdyqAAAANBJREFUOI1jYKAYSMKBGDMBBZJCjAQUSHITUiDOwYIOmFAUSAqLSKABNlQFkgKEFEjyE1IgysuHAljRFaAD9iGsQMXEysHcUBanAgMHb/+QUB8bVRwKNJ2Do6LiEhNj7eWwKpC28wPLJ8Z7GWNVoOoIlY8JtMaqQMcDKh8V6SaPTYGWO1Q+KtxNBpsCRdcEiHyUnxV2X5gFQOQjXHSxK1BwDooGyod5WuIKKCULRy9fDydTa21cQS2loW+kpyypZqtFILLU7bgYOPECHkHKMzcADGFkClIg2mAAAAAASUVORK5CYII=)|Folder Exists | Checks whether the folder with a given path exists. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAd1AAAHdQEjKi9uAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAVZQTFRF////gICAs8zmVWqAWGGEQEhQr8/vVWCAsNXxT1h1VWGCbYKePERQVGCAVWCAVl+Agpq4hqC+mbPRPkRSTldxpMLfqMjjpMLeVWCASVFpTVdxTllyPkVTrMzoq8zors/rUVt4VWCAr9HtPURQsNHtVV9+sNPuPURRVWCAVmGBV2KCV2ODWGODWGSEWWWEWWWFWmeHW2eHW2iIXGmIXWqKXmuLX2yMX22NYG6NYnCPY3GQY3GRaHiXaHiYanuabHybbX6dbn+eb4Cfb4Ggc4WkdIemd4qpd4upeo6te5CufZKwfZOxfpOygpm3hJu5hZy5hZy6iaC+iaG/iqLAi6PBi6TBi6TCjaXDjabEj6jGkKrHkqzKkq3KlrHOmLTRmrbTnLnWnrvXnrvYocDco8LepMPgpsXip8fjqMjlqcnlq8voq8zorM7qrc7rrs/rrs/sr9DssdPvjMtU3wAAACd0Uk5TAAIKDB0gIDA3PT8/QEBIVmhudYCQsLCzv8PQ0tbX2trf7u/09fr9naOAwgAAAPZJREFUOMtjYCAE+OCAC7sCDQTgJ6RAkYWAAg0JRgIKNESE0QErqgJVGXU0wIOqQENBmYACDUlCCjSkpVAAJ4YCNMA7tBXoW+BToBuQXJCdFWePS4FNSqyttoalZ1awFlYFxpleJl4JeUlupon+WBVEB+mnFoJAqGWOABYFBgWmIYUQ4BwgikWBQ64fVL4w0kkWiwLPQjhIMlfBosAxztXV1QOsIMpRDosCozAN98BwsAIXX3FsvvDUNE0Dy8eYZQtiU2Do7GMdll6Y6m0UH4w9JK0yIux0DAxd0mP0eBnYsQFuMaX8NDV5IXZ2ZpyZmo2DiYEoAAC7OpYyby+8cQAAAABJRU5ErkJggg==)|Copy Folder | Copies a folder located by old pathname to a new location specified by new pathname. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAfpAAAH6QGUejxAAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAASBQTFRF////29vb6+vi5eXTsra76Ojg6enf6urfpKiykpin4uLX3dzQ6eng3NrOanSNVWCAVmGBWWSDX2mHYGqIYmyKZW+MZnCMZnCNZ3GNanOPbHaRc3yWd4CZeICaeoOcfYWefoabgoqihY2kho6kho6lipGnjJOpjparkJeslZywmJ+ypKq7pau8rbLCsLXEsrfFwMTQyL24yb65yb+6ysC7y8G7y8G8y87YzMK8zMO9zM/ZzcS+z8bA0MfB0NPc0cnD0svF1c7I1c/I1tDJ1tjg2NLL2dTN2dfK29bO29bP29rN3NjQ3dnR39vT4N3V4N/U4d7W4eDW4t/X4uTq4+HY4+HZ5OLa5OPa5eTb5efs5ujt5+bd6Ofe6Ojf6eng6+zw8RAhTwAAAA90Uk5TAA4aHThCR0htfNnr7PP7HqL7KAAAARBJREFUOI2l0OlOAjEUBeAquwsF9xV1BNdRrICgVRBQQJaiguO44fu/BZ2BxNuZTkPi+dM0/ZJ7bhFCaHpu4MiMD8EEne+D7rwgQm5QFwQENWMEBAFAI1fpjwAUAJQyt50xAAIA47r1xY+XppXZKTcghDT+bgFJScrAJeQG9LLQVgJWqJlKUM3eP/8HfDM+ghnewCCU0mxVBawpCmCSV1IpPypK3j29m7k3BWBXNFNWrvnTAf8kA2ImBuFdj4THIII9EhHBpq7r26uH+OQ0FZOCNU373EsU8cfBeVoKMD6+wBZY3niQg5Xeog3Obo7kIJ/ENthfkpfUfnlJe4THFryktr6whXfiTuCPyr8h6uePQ7tsxuGhDl24AAAAAElFTkSuQmCC)|Zip Folder | Zips a folder specified by folder_path. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAfpAAAH6QGUejxAAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAASBQTFRF////29vb6+vi5eXTsra76Ojg6enf6urfpKiykpin4uLX3dzQ6eng3NrOanSNVWCAVmGBWWSDX2mHYGqIYmyKZW+MZnCMZnCNZ3GNanOPbHaRc3yWd4CZeICaeoOcfYWefoabgoqihY2kho6kho6lipGnjJOpjparkJeslZywmJ+ypKq7pau8rbLCsLXEsrfFwMTQyL24yb65yb+6ysC7y8G7y8G8y87YzMK8zMO9zM/ZzcS+z8bA0MfB0NPc0cnD0svF1c7I1c/I1tDJ1tjg2NLL2dTN2dfK29bO29bP29rN3NjQ3dnR39vT4N3V4N/U4d7W4eDW4t/X4uTq4+HY4+HZ5OLa5OPa5eTb5efs5ujt5+bd6Ofe6Ojf6eng6+zw8RAhTwAAAA90Uk5TAA4aHThCR0htfNnr7PP7HqL7KAAAARBJREFUOI2l0OlOAjEUBeAquwsF9xV1BNdRrICgVRBQQJaiguO44fu/BZ2BxNuZTkPi+dM0/ZJ7bhFCaHpu4MiMD8EEne+D7rwgQm5QFwQENWMEBAFAI1fpjwAUAJQyt50xAAIA47r1xY+XppXZKTcghDT+bgFJScrAJeQG9LLQVgJWqJlKUM3eP/8HfDM+ghnewCCU0mxVBawpCmCSV1IpPypK3j29m7k3BWBXNFNWrvnTAf8kA2ImBuFdj4THIII9EhHBpq7r26uH+OQ0FZOCNU373EsU8cfBeVoKMD6+wBZY3niQg5Xeog3Obo7kIJ/ENthfkpfUfnlJe4THFryktr6whXfiTuCPyr8h6uePQ7tsxuGhDl24AAAAAElFTkSuQmCC)|UnZip Folder | Zips a folder specified by path and stores it at new_path. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAd1AAAHdQEjKi9uAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAOdQTFRF////gICAWGGEQEhQv7/HvsTKVWCAT1h1VWGCPERQVGCAVWCAvMPGVl+AjJWmPkRSTldxrbS8u8HGq7O8VWCASVFpTVdxTllyPkVTuL7EUVt4vMXKVWCAvsbMPURQv8fNVV9+PURRVWCAVmGBVmKBV2OCXGeHYGyLYm6MY2+OZnCManeUcoGddIKedYOfeYKZg4yghpawiJiyjZ63mavDm63FnK/GoKezobTLpKy4pa25pq+6p7vRqLzSqr7UrMHWsMTZscDQs8fcutDkvc3bvdPmvtTnxdzuxt3vydvoz+b40Of50Oj5QlUYKAAAACF0Uk5TAAIdICArMD0/QEBISFZqgJCZpau/w9DS1tnf7e7x9Pb6R7AY+QAAALpJREFUOI3V09UOwjAUgOHh7jpsUFyHD3cdff/ngbXJyEbPes1/2y9pT5MjCLwCel42QN9CPFCwcwBK2jgARSPmHEZQzlZM+YwA5UocgFI8gDJpQ54fYMr/v2CoLNeklZJggo58fJIuchi4YoNJZ/ANYwpmIGi9COjDUyy081PNYsyJiud1q39obA9tZAG6N4wfAxhU79ob1CYIenTMEQimFOxBsKPg+gFuRjExL5GKYpy5js6gnou7/W+FPXVTiaPZUAAAAABJRU5ErkJggg==)|Wait For Folder | Waits for a folder to be created and then opens it. | -|**Image Operations**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAO1QTFRF////AAAAAACA///MOTlVQCtV7+/fOi5RQDVK5dzKOjFKgHmGPTROPTJNPTJLPDFMPjJMRz5VPjJMPTJMPTFM7uvePDJMPzRO4d7N4NvKPTJM2dXBPTJNPTJMPTJMQDZPQTZPSD5VVUtfV01hZVttdm17hHuGhX2HkouSlY2UpqCis62tuLKxx8G91dC71tHE1tHJ19K92dXB2dXM2tXB29bC3NjF3djG3tnH4NvJ4NvK4dzL4d3L4t7N497O49/U5ODQ5eDQ5+LT5+PT6OPU6OTU6ubX6uba7Ofb7Oja7ejb7enc7urc7urd7+ve8M8MaQAAAB50Uk5TAAECBQkMEBYYHR8mO2BwcoCEnZ6/yNfc4OTn8/3+6DSEYQAAAM5JREFUOE+l0OUOgzAUhmFmzN2tc3d35sKE+7+cAcuS07WFhL1/edIvHI6LSj8lnBwWAeZpXJCgiwsKwAUNYIIKoKADIFQgjJUEFQhTtaQFAvGkJGIv8awJY+Cygx1JsJ/BlgYm/gerLmxIgtcd9jQwoQsOC9iGBOc1rNe66kwUC7WOJmgghEpBFwCPC0zsI6VsxGv7gvUANpHKqkj5rKzfbMqfM34r+w7bPMrFQyaNQ1VQ1R0Lm9mgnRvxjo+gg1tdvoMjFmAC6aUcyu7h3hgM0xOjQKpIAAAAAElFTkSuQmCC)|Open Image | Opens an image with the given path. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAdiAAAHYgE4epnbAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAg1QTFRF////gP//v7//s8zmUGBwZnOMsdP0rdbrrdHtVVtzstXtVGGAsdTustPwZ3WVstTuU11zsNLvsdPuU196sdPvsdTvsdLvsdPvYG6Nj6nGstPvsdPwstPvsdPvsdPvhIybgYmYYmx+kaK3V2KClrHPY3GRsdPvWmaHEaCFEp+FE56EE56FFJ2EFZyEF5qDF6KJJriZJrmZJ7iZKJqIKJuJKLWYKZqIKrGWLIZ+LqqTLrCWL6+WMIF9MaSQM358NZuMNaydNnx7OXl6O3d6O5CIPnN5PoWDP3N5QYSDQoGCQ294Rnl+RqiZR2t3S3F7TGZ1Tml4TrSuU190U2F0VF5zVV9zVWCAWmJyWmaGWmeHW2eHXGmJXWmJX2yMX22NYG6NYnCQY2lxZXSKZXSUZnaVZ3aVaXmYa36Ma73AbH2cbX6dbnJvboCecIGgcIKhcXmLcoSjdIemeIyqeY2seo6te4+uf5SygJWzgMPPgYBsgcTPgpi2hp27hp68iaG/i8fWjqjFkYxpkarIkqzKk67LlrLPl7LPl7PQmbXSmrbTnrvYnrzYns3jn7zZob/bocDcoszkpMPgpcThpcXhpsXip8biqMjlqsvnrc7qrc7rr9DssKNksNHtsNLusdPvs9LftNTu2N3g2+jw3MRe3ODj4ufp4+ru5urs5u3x5+zt6Ozu6u7v7PDx8NNa89Va5YyJKwAAACh0Uk5TAAIEChAUFxkcKis6O1ZZWWh+ipmjsLHAwcTM1+3w8/T1+Pj5+vz8/u53oN8AAAFvSURBVDjLY2AgBATwAk4GhhAFedxAUQCoYOka3EAerGDlkoXYwWqoguX5IdjBQiQF4Y2N4fgUhC5et25xKB4FleuAoBKPgmyQgmx8bpi9du1shIw/poKQxESEvJ2uF6YCJOCkoaHljlVBEJh01dTQ0NB0xqIgwNITSHppa4CBI4YCP3NDQ88QXx0NKLBBU+BtaggEbnoacGCBosDDyBAMTCCSDhn1PVXzVyAUuBjCgDFQWj9jenVOSmnzAiVhiIJge0NDZBUVrdGFTR1lCbl9ymAF6bZI8oYGZoG9Ue3zgGBuXpw6B0iBjxUKsJ6QWQeSnzG5PyFSCKhgFRpYNjVyJkhBS2RkZLw4ljS5aE7XPDiQZcBMaUmTaoAALD2xQJqBBQOwqoRllZSAFZQXi2DLS5Jh8dPA8t2RvbzYFPCpFqW2z5o3tyGmQQxrbuSWkKmNjUiLSO6UYsORYdlF1Sa2TZETZMKdp5l5+LkYGYgBADJKK9c+ssxkAAAAAElFTkSuQmCC)|Rotate Image | Rotate an image over a specified angle. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAEhQTFRFF0RhGUZjHUtoH01qIE5sK1p5NmeHN2iIPG6ORXeYUIOlW5CzbaXJda3Sdq/UeLHWebLXerPYerPZgrzihb/mkc30ltL6mtf/hxWUFwAAAJlJREFUOMvN0+sKwyAMBeCj1cVL66xT+/5vOgrbKBk1YzBYfil8oMYTbEKB7dd1DJoxbQgCEEagKkDVAXDaWu3OQUIkikinIPtO1C/X0TOJhD78DqTMQU4HUB08Bx6uPkALSsfOQY9ahbaDmwEsPWuaXksLmPIJEI+QL7nXMnMwL3/3F8fA+Px95MTQyrEXB0ceva0UoQ9vdQftaE/zVb4YBQAAAABJRU5ErkJggg==)|Resize Image | Resizes an image. The new size is entered with a tuple of the form: (width, height) | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAEhQTFRFF0RhGUZjHUtoH01qIE5sK1p5NmeHN2iIPG6ORXeYUIOlW5CzbaXJda3Sdq/UeLHWebLXerPYerPZgrzihb/mkc30ltL6mtf/hxWUFwAAAJlJREFUOMvN0+sKwyAMBeCj1cVL66xT+/5vOgrbKBk1YzBYfil8oMYTbEKB7dd1DJoxbQgCEEagKkDVAXDaWu3OQUIkikinIPtO1C/X0TOJhD78DqTMQU4HUB08Bx6uPkALSsfOQY9ahbaDmwEsPWuaXksLmPIJEI+QL7nXMnMwL3/3F8fA+Px95MTQyrEXB0ceva0UoQ9vdQftaE/zVb4YBQAAAABJRU5ErkJggg==)|Image Size | Returns the pixel-size of an entered image in a message box. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAEhQTFRFF0RhGUZjHUtoH01qIE5sK1p5NmeHN2iIPG6ORXeYUIOlW5CzbaXJda3Sdq/UeLHWebLXerPYerPZgrzihb/mkc30ltL6mtf/hxWUFwAAAJlJREFUOMvN0+sKwyAMBeCj1cVL66xT+/5vOgrbKBk1YzBYfil8oMYTbEKB7dd1DJoxbQgCEEagKkDVAXDaWu3OQUIkikinIPtO1C/X0TOJhD78DqTMQU4HUB08Bx6uPkALSsfOQY9ahbaDmwEsPWuaXksLmPIJEI+QL7nXMnMwL3/3F8fA+Px95MTQyrEXB0ceva0UoQ9vdQftaE/zVb4YBQAAAABJRU5ErkJggg==)|Crop Image | Crops an image to a region specified by the box argument. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAkZQTFRF////AAAAAAAAgICAAEBAQEBAVVVVAAAAAAAAAAAATWZmAAAAVVVVAAAAAAAAWVlZAAAAUlJaVVVVAAAAUFdXAAAAAAAAVVtbAAAAAAAAAAAAE1dIAAAAAAAAUVFUAAAATlBTAAADAAMDAAADAAMDAwMDTk5RAAAATE9RAgICS01QTU1RAgICAgIES01PAAAAEExASExMSEpMR0tLR0lNRkhLRUdKREdJREZJAwMFAwUHQ0VIAwMFBQUIAwMFBQUIQkRFQENFQUJFBAQGBAYJP0JDAwQGBAYHDUI3BAQFBQUIPD4/BAUHBQcJOTo9BAQGBQYIBAUGBQYIAwUGBQYIAwMEBAQILC0uKSssAwMFBAUIJicoAwMEBAQGJCYnISIjHh8fHh8gAgIDAwMFHR4fAgIDAwMFBgcKCQoQCgsQDxAYEhUbFRggGBwoHBwdHSEwAgMDAwQFBgcJCAkMCAkOCwwTGBskGRwlGhscGxwdICU2ISY4AAABAAEBAgIDAwMEBQYHBwcKBwgLCQoPGRoaHB8pJSo+AgIDAwMEAwMFBAQGGBkZFhcXHB8pJSo+Jyw6NDtWKzFAOkJgLTNFLjRHPUZmPkhpCgsLDA0NMTdKQktuAAAAAQEBAwMDBQYGBgYGNDpONTxQP0deQUlhQkpjQ0xlRk9qRlB0SFJ3S1RwTFZzTlh2T1p3UFp4UVt5VF5+VF9/VWB/VWCAVWGNV2SRWWWUW2iXX2yeZXOoZ3asanmwa3qybHuzbXy1cYG8coK+c4K+c4O/2oGVIQAAAJt0Uk5TAAECAgQEBgcJCgoLDA0RFBUfISIjJioqLi81NTxQUldcX19kZGZoa2ttcHF3d3p+f3+GiIySlJeZmpqgo6Ompqanqqurr7Cwsbq6usPDxdXV2trf3+Pj4+fo6Ozt7e7y9PT19fX29vb29vb29vb29vf39/f39/f39/f39/j4+Pj4+Pj4+Pj4+fn5+fn6+vr7+/z8/f39/f7+/v4bhFpOAAABwElEQVQ4jWNgQAYiatbWaiIMOACzUcK8ivDwinkJRszY5OUqW8zYQAw2s5ZKOUx5jRlOrDA2q9MMDQYGBx5kea3pxshc4+na4nMFkQS4us0hDBYWCG3aY5GIrMM1Hsrw8ABZ4W0iFJ3iBxGRBJMRClAF0tIg0jFuft4cPYh0rSqKWyEKGBj4DeNAXlKtYZjd7MKNpABsBQxwOzfOZpi9ozpEDCEGcyQIiAWXrwQq2HNwWqESXNDAAM5ULJiyaS1YwcGtGbYc6Ao4bNKXbIIpOLgrP0gU1QrRwJzVmxAKDu6flCaP7Ej51IkbNiErOHhwc5MVO8yb7JYNizZtQlNwcGdugDBEgbB/9qpNmAoO7puQLAuyQjapf/0mbAoOHlw+W52FRX32gk2bsCvYUmLPaWDAaVe0GKuCA1PrVSDhoFw3eSOmgt1VYRKwcJAILVuDrmBbqTsvIhx43YqXoiqY1amJGt2a7TORFOxti5JCSw8MUpGt62AKtmd58WGmBz7PzGUQBSu6dBmxpQdGnY6FIAV9sTJIiQgpPTAwyMT0AhX4CjDgUsAg4DObQZ8JWQQlyQEBkz4DGkBJtNgA3JswAAAo4vGDvITebwAAAABJRU5ErkJggg==)|Mirror Image Left To Right | Mirrors an image with a given path horizontally. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAklQTFRF////AAAAAAAAgICAAEBAQEBAVVVVAAAAAAAAAAAATWZmAAAAAAAAYGBgAAAAWVlZAAAAUV1dAAAAUFdXU1paAAAAV1deAAAAAAAAAAAAU1hYAAAAE1dIAAAAAAAAUVFUAAAATlBTAAADAAMDAAADAAMDAwMDTk5RAAAATE9RAgICS01QTU1RAgICAgIESkxOAAAAEExASkpOSEpMR0tLRUhKRUdKRkdJREdJAwMFAwUHQ0ZIQ0VIAwMFBQUIAwMFBQUIQENFQUJFBAQGBAYJP0JDAwQGBAYHDUI3PkBDBAQFBQUIBAUHBQcJODk7BAQGBQYIBAUGBQYIAwUGBQYIAwMEBAQILC0uKSssAwMFBAUIJygrJicoAwMEBAQGIiQlICEjISIjHh8fAgIDAwMFHR4eAgIDAwMFBgcKCQoQCgsQDxAYEhUbFRggGBwoHSEwAgMDAwQFBgcJCAkMCAkOCwwTGBskGRwlGhscGxwdICU2ISY4AAABAAEBAgIDAwMEBQYHBwcKBwgLCQoPGRoaHB8pJSo+AgIDAwMEAwMFBAQGGBkZFhcXHB8pJSo+ExMUJyw6NDtWKzFAOkJgLTNFLjRHPUZmPkhpCgsLDA0NMTdKQktuAAAAAQEBAgICBQYGBgYGNDpONTxQP0deQUlhQkpjQ0xlRk9qRlB0SFJ3S1RwTFZzTlh2T1p3UFp4UVt5VF5+VF9/VWB/VWCAVWGNV2SRWWWUW2iXX2yeZXOoZ3asanmwa3qybHuzbXy1cYG8coK+c4K+c4O/uukxCQAAAJx0Uk5TAAECAgQEBgcJCgoLDRARFBUWIiMlJiYqLi8xNTU8UFJXXF9fZGRmaGtrbXBxd3d5fn+DhoiRlJaXmpqcoKOjpqanqqurr7CwsbS6usPDyNXV2trf3+Pj4+fo6Ors7e3w8vL09fX19vb29vb29vb29vf39/f39/f39/f39/j4+Pj4+Pj4+Pj4+fn5+fn6+vr7+/v8/P39/f3+/v7+WGF9DgAAAYNJREFUOMtjYGAwmIMF1EoywAGTb99eNLCzWY0BCQjErTyECqpdGFCAbNcOFPnpIdyoChj0svchyW8rFEeTZ2D0bkPI785UZsAAfFGzYfIH8u1AIhGuXCgqpDu3QxVMDuIACSgmdmujqNAq3QOW35IuChWxmKGJosK96iBQfleTAlzEZKY8sgKesGmHDu3Ps0IScqpkRlYhUb/10MQAdiQR1hZjFEtUS1akCKGImCWhetZhjhyqANt8YRQ+pwZ6+FSoM8h4sBgasnjIYKGBCsJtCCsgaAUysCfgSJWihcn4vClRt2TzBH/cAcUTOmXz5g05llCutSd6ULuVbdq8efPqBmhkxVigRZZW8drNILA4DRzdvAukzFGiW7p92WYImBQISjD6/fE9OshJLnIWVH7zxlxboED03ARTMaRE69W6GQ7WZCgxMAga+aXOc4Qr0M1aj1CweWkBJNmL8MMzTsfyzchgajBqxhGIXbQZFZQ7I8sz+fSuQwOrGpEzL9bsXwPL/gDJJfMYjc+fyAAAAABJRU5ErkJggg==)|Mirror Image Vertically | Mirrors an image with a given path vertically. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAfpAAAH6QGUejxAAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAYZQTFRF////29vb6+vi5eXTm8276Ojg6enf6urf1eXYfseydcSweM22bb+rd8634uLX3dzQ6eng3NrOM6uSFKCFFaCFGKGHGqOIHaSKJrmaJ6iPKKiQKLqbKqmQKrqbK7qcLbucL6uTMryeM7yfN66XOa+YOr6hPbCaQLCZQLGZQcCkQ8CkRsGmR7SfR8GmSbWgSrahTrejT7ikT8OpUbmlVMSqVcSrXceuZMCvZcGvZcixbMqzcsa2c8a2ds23eMi5ecm6fsu8f8+6gcy9g82+iNG9itDCj9LFk9PHmNXJmdbKndjMntfFoNnOpNjHq93TrdrLr9/VsuDXs+DYtOHYt93OuOLau97QvN7QvuXdvuXev+XexeDTx+HUy+LVz+zm0OPX0ePX0ezn0+3o1+Xa2OXa2dfK2uXb29rN4N/U4eDW5Oje5+jf6Ong6ene6enf6eng6ubM6ubP6ufS6ufU6+TC6/f07OO37OS87uCh796V796W8NuD8NyJ8dlz8tdp89Vb89Vc89Vdl1DK2wAAABN0Uk5TAA4aHThCR0hOcXh7fHzZ6+zz+6LlvY4AAAE+SURBVDjLfdD3N8NQFMDxoNSo1Yde0VJae6Qxo2pvitp7FUWNmLWF/9xLRb2XvOT7Q07Ou5/zbk44juPSi2RdBRkcWZZ+Lp8VU8JuBCeUYAFKMAEpNPBwRwFCJMH9h/L9+gfOT9UK00jwrCjK1y29KZME7xgoCRrYSfCE559XFuA68fZykxptGwHVQsWwJVirAui/NAc71YALXhjBetcRfh7UQrLeuB7MVULzsRxrAq3ubBqMqYet++2QKp8E8eDvoed/DnkEiHWCMeKG3UawBCs1YAlmPWAJchrq2eVqwIFMcujAkL9ufNSHkDAZKmWCDVFaDBy626JCn8sMhNG8GO4xW4FBdGqzbElsiYSYYCsgRbwlaGIQSdNGUL4688jjFQi590aWBxg3eDt4xPvUN5fgp7/B5mT/BqcND38AfqfFzITjckMAAAAASUVORK5CYII=)|Image Format | Returns a message box specifying the format of an image. | -|**Windows Applications**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Open Calculator | Open Windows Calculator. | -| ![](data:image/png;base64,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)|Open Paint | Open MS Paint. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAJxQTFRF////MTVEWGSNRE5pQkpgQkpgY3CgUl1/Qkpgb363MDZEQkpgT1dqVFttZW+ObXJ/c4O/eHyGfYGKkpqynaK1yMnIz8qv0Mux1M+21tG52dS92dW+2tW+2ta/3trF39vG39zH4NzH4N3I4d3I4t/L5ODN5OHO5eHO5eLP5+PR5+TS6ebU6ebV6ufW6+jX6+jY7OjY7OnY7enZ7eraccUAvwAAAAp0Uk5TAHjb3ODo6+/4/b2GWfIAAAC2SURBVDhPvc3bDoIwDIBhQERQwKHg+awgzIGK7/9udk4N1i1mN35XTfOnNYwmswtMA7PbXMfzPIsHFgydx8p+Bq7fByEhxGkBB4aQb3z3FUQ3EJOGmG+izyAZNiSS4JtecM2EUhUcJ8JOFcjoBekISfGFE6L9opgJyyor2ByGAgXlRtjXlF22MJS6L6oDUqEgnyK57oufAVshDAV0gVDdFzUVzqogHQtrVSDz1yAYSAXvoKfAgztSE3AT6DJyHQAAAABJRU5ErkJggg==)|Open Notepad | Open Windows Notepad. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAS9QTFRF////VVWqQECAZmaZVVWARl2LS1qHSWGGT2GESmOEUGCAT2GATWGATl2ATWCCUF6AT12CTWCATF6CT2GATl+CTV6AT2CCTV+AT12BTmCATV6ATWCAT2CATl6BT1+BTmCBT16BTl+ATl+ATl+ATl+AT1+ATl6ATl+AT1+ATmCATl+ATV+ATl+ATl+ATl+ATl+ATl5/Tl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+ATl+BTl6ATl+ATl+ATl+ATl+ATl+AT1+ATl+ATl+AXXiaXXmaXXmbX3udYX+hYYChYYCiY4KkcJm8e6zPfK3Qfa7RgLTXgLXYgbXYgrfagrjbhLrdkM7yktL2ltn9ltr+l9v/e8cNfAAAAE10Uk5TAAMEBQYLERUdHyAqMjQ1Njc4OTo7PD1GR0hMUFpfYWVndomkpqytrq+wsbKztLe7w8vP0dXX3d7h4uXm6evs7u/w8fLy8/P09vf9/f5P234UAAAB3ElEQVQ4T22S7VraQBCFh1hQq7VYalRUWtTQxrbSz1gioiFt1NgTpR+gsdYAe//X0N3NRgJkfmXP++aZzUyIeG1bRZqqorWdPC74cKaMpw78BfW8i+aUwXkTu+pg4/HehMH5Xgl2fCigRY/GjSUH5ox2ioI8zaFB44bkRA3MxecjzI4ZSyd4zfksjtQL+9iklPHkBK84p03sK6GCw8LISHjhEJWkZx21XGJwXhM8V0M94TTfxo4yvn9DTRN8B+35B4FWPGV8AAzFvRVK1XNXGls/8DWTE5WEwTk+bWlZnOhZG+8551XJ5ETLp4Le3uJjNqdFF43PuL8X2vFiBj/m83khe3j1CSNfNW3vDG81mnn5BXBL2hucebZZzcdct+R7aK3F81mmtVacWLrkPjph1L/7BX+Vc7zLrfr4+bcfhR343Mhb6A6ZqC6aBhwHRhNdGQy7sPJURWc4uL4MegP2B3xZRQf4zQa94PJ6MOygSgZCdiMa9tg/nPN1F89xx3oiuWEhDDpAxK6wUUbA+nDFpVz0WYDyBq5YhAMllNe5EMW/sc2TAOtlJaRahDCFYPIk1WJ0SXklXjIZXfLhM+OPIppK4kGJsVzoarQXSeLr6VFberKcyUQsa7SaieQ/79yW+3pjKakAAAAASUVORK5CYII=)|Open Snipping Tool | Open Windows Snipping Tool. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAejAAAHowEwL7LFAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAO1QTFRFVWCAVmGBV2KBWWSDWmSDWmaLXGeFXGiOXWmRX2mGYGuHYGuJYWuIYmyJYm2JYm2KY22JY3CeZG6LZnGLZnSkZ3GMZ3GNZ3KOaHaobniTcHqTcnyTdH6XeYOZeYObeoObfIWafYWbfYaagouhho6kh5Cmh5Gsi5axjJWkjJWnkJiqkJq1lZ2vlqC9m6Ounqa2oaiyoamzrLS7r7bDsbi9srm9tbzBt77KuL/Fv8bPwcfMwcjRwsjMw8nNxMvOxs3XzNLV0Nbb1Nnc1drd193f2d7g2d7i3eLm3uPl4ebo4ufp4+jp5err5uvs5+ztbHe1TgAAAN9JREFUOMu909UOwkAQBdAWLUWLFXd3dynu+/+fA8umSZHbN5iXnWTOw9xJluP+VGZB7axWtbOYNEAKqZ3fz155ersO7RgYV+RRYwwS5FleCCoMxCBIX+n8FIDANnmIy4jHKTKDxbwf1YnJBYoF1+cdDLXlsmZgfUj6cqguXa2LgczCyRBkGchCEGcgDoGo0Lki4iVLs/V6VtJJwaeazRSvAzSHegHOaj2oB5IHQs55DPg93f3shiDM0ucgiDBQhkDc0vkxgpdsb25k1zFi4Gj0+i3f+8cRzJpDiZ4ffts7uOgtBiOqjDcAAAAASUVORK5CYII=)|Open Control Panel | Open Windows Control Panel. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAL4SURBVFiFxdVPaBRXHMDx73tvdje7m8TYgrYV71r6B/zTtKhYBNuiUVBjinosVFBEBPEQ6MFScmkPFaW3ngVtPdgY0ZZIFA9iI9RKsV4qFbSCpcb94/x57/16WE1dNTbuzMY5DcwM38+892aeEhFm+lgyONKL5nNsfkDNNGDJ4EgvilPALBSnZxTQFIcJhA/1i4z/PLTmwowApooDtB3wrHjbAf8XbytgOvG2AaYbbwvgeeKZA543nimglXhmgFbjmQDSxFMDVg0eW5Ymngpw8tudX3yz4PC5efm7LccBprcbHh0wYVcyP7D2VefsW/VIr7PWry3rmD/jl2TH1S0rRoc2nm/hPQimunB3/4YeieN9hTfNa/WzbmvwisqVFmvECQUfUtBQ83n+SOYMtRqHp43A+PZcdPvmp1j1WW3MzxWB0lJNddSRm68oLIwQ5wGIdMcPswdOrG81Do+tgXh4XX/8163flahDyjC3vFKjFNQvejpXGZIbQvjLf48UtL2SJg4Pp+DogElK4ZcotefRi8pAeaWmNuapX/SUlnvqZ00j/oZFK/ktLUBzom92UgpPivg9vlaBx6bkIUIpuD8OxXdj7C1DdCXAYS6nBiTo70X8aleZQBBQ6qmI0nsOpSH8NddA/K0pvxxmMALCXle9ZzEGU+7G16u4eqX5LhG8Syi+E08iSsvkGu+fsakBub7jl3SQ32DK3f/4ehVJYkyxE7HJ5Ei4MGqcayYR9roaTxuHB19Bof+nYUmibeKsNV09iLO46gTiLD5JEOuanij2xmKM2p0FoOk/kAyvX+RtNOZqlU5T7gYUrlYBU2hW54KRjk2n1mYBaPoP5PqOX1Iu+cSUu6qN+ERjUT4qVirp8LM+ziL+BAAgv2n0iAnyH7javcby13lwEfgYADHmKzYfqWYFmHIzuv/d6l3i/AFspEDAFFBBcLXYf3phVnF4xnZc7P/xoNKyF2jEjbldlJ63s4zDNLbj8NhHW73zXzubvN615cydrAH/AkZllNlVgvz7AAAAAElFTkSuQmCC)|Open Clean Manager | Open Windows Clean Manager. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAebAAAHmwHPmYv+AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAQJQTFRF////mcz/udHoUV55s9nyVV5xrdHtstHwtNLwr9PwU2BzsNXtVGB0r9PvYG2IU1xzVV50stPvaXmbsNLvVF5zsNTwcICmVF1zanecstLwVF50sdTvcX+msdLusNPusdTvqsrnsdPvsdPvsdPvVF5zVF5zsdPvsdPvVF5zsNPvsdPvsdPvq8voVF5zVF5zsdPvsNHtVF5zVF5zVF5zsdPvMjpFMztGNDxHNT1JN0BMOkNQO0RRPUZUQElYQktbTldqT1ltUFpuUVtvUVtwU1xxU11xVF5zV2J3XWl/Ym6MdIeed4WwhpfLhpy5jqLSj6PSl7LMmrPcn7ngqcjpsNLusdPvR9UxywAAADV0Uk5TAAULExQbHCEiIygqQEBNUFpdYWFkZHB2dneCgoeJi42otLvAzM/a3uDg4eLr7O/z9fj8/f02VUZYAAAAuklEQVQ4y2NgAAJxXTdkoCfFgApYjUDCLpYWVg6WzmAlXKgKeCAaHewd3RwgTH5UBULe6EACVYGYDzqQGVUwqoB6CgKD/PEr8AsN1ZFkw2dFcGhoqImSIBNcAZ8nKvANBQN9YbR8AQceISB5ZV70jONmZ24LYQQA5RUxc5armampE5jlFRoqrSmPocDNxtQawnA3UGdk15KDK2A2hKpwhNLGCqIMDBzasnAVAioayEBVhJsRKMqpxgIkAQ6fpxKgXarXAAAAAElFTkSuQmCC)|Open Dialer | Open Windows Dialer. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAV9QTFRF////SW1tYGBgWV5vRERVRUZXSUlaV1lrV1psWFttWlxuWl1vWl5vW15wW19wXF9xXWFyXmJzX2J0X2N0YGN1Y2d4ZWl6Z2t8aGx9aW1/aW6Aam6Ba2+BbHCBbHCCbnKEbnOFb3KCb3OFcHSGcHWGcXWHc3iJdnuMe4CSfYKTfoOVfoOWgIWWg4mZhYubipCgi5GijpOjkJamkZiokpenkpmpk5qtlpyslp2xl5+ymJ+vmZ+vmqCxnaW4nqW2oKe3o6u+qbHFq7XIrLbJrbXFrbbKsLnNsLrOsbnJsbvPsrrKs7vLtL3Mt8DPuMDQuMLWucHRucLRvMXUwcvfwczgw87hxM3dxM/ixM/jx9LlyNHgyNLlyNPmydTmy9Xky9Xny9bnzNbozNfozdbmzdfmzdfozdfpztjnztnqz9joz9nqz9rq0Nnp0Nrp0Nrq0tvr0tzr0tzs093s1N3t1N7tcMEp+AAAAAR0Uk5TAAcIscJjeQ0AAAGmSURBVDjLhdPpNwJRAAXwJOurVCShFNmV7EsUaZT2rI8WpmQpqhn3/z9UjqN5M9xPb/l9eMu5KlUz3UQm3aqfdBHSL93+Wuj6AWrS1zPQXB3ZCoW2hpujgZ4+ov4FSGvffl27v69d21uCdIJmdJky/Uo5o2vPGTAj0tPBwVMqzigAT40uO53LtOZRAPMCPertPaLCvAIw3uVpKkXzd0YFQBbrxdvbYn2RKAEyGykUIi6iDDojBwxzcwZloN84rwP18w29PLClIbw8PLwISNvkwOQz+Ivj7e3jCx7PkyzQJZE9Gbe63dbxkyySOgasg+dMgQ/gI2DieKwzICNcTvjRin/iUshIwdBbJWgR8bi29gjREqy8DUmAC/zuCrCp0WwCK7s8XBIwDX5vCdjRaHaApT0e0xKgf61wow28+3zvaIxylVe99JAJ8WrqoH3Ig6krMcHcwoty2LTfABr7pnAZXgZoY8idOcwLC2bHWQ4xLfvUYwU83YQPD8M3TyiMyX2WJQqxWixWRUQt7Ge1irMaLwGl+KpMcb6rR7Q2m5aw1fu3vH/V/xOXHm4HxPcQKAAAAABJRU5ErkJggg==)|Open Volume Mixer | Open Windows Volume Mixer. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAehAAAHoQFP0XFMAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAdFQTFRF////AP//gICAVVWqgIC/VVVVgICqcY7GgICzaoC/d4i7cIC/WWaAbYbCdIC5d4C7c4S9dYPBdoO+c4a/V12DcYK+S1dudYW/RlBkcoS/dILAVWGAdIO9V1+DdYO9dIW+bHyxc4O/coS+c4O/VWGBcoK/c4TAcoK/dIPAdIS+VGCAdIO/coO/dIO/RlBlRk9mVWGBdIO/c4LAcoLAdIO+coO+coG8Vl+Ac4O+dIO/dIO/dIK/c4PAVF6AdIPAdIO/c4S/X2uUYGyWXWmRXWqRYG2XYW2ZUVt7XGiPW2eNZHGfTFZySVJrWmWLZHKhWWWLWWaKZ3Skc4O/Z3WnTlh1WGOGVWCAbXuwc4O/SFFoaXirc4O/V2OEZnSmRk9mRk9mbHqvV2GCc4O/c4LAbHuyR1BpbX20bn21bn61coPAVmCBbn+3b3+3c4PAU119c4O/c4O/VmGBb4C5cIC5dIO/cIC5VWGBcIC6c4PAVmCBc4O/VWCBcoG7coG8coK9VV+AcYG7cYG6c4O/U19+VWCAcoPAVWCBc4O/VWCAcoG8coK9Rk9mVWCAc4PAVWCBc4O/Rk9mVWGAc4O/VWCBc4O+VWCARk9mc4O/Rk9mVWCAc4O/YRLwTgAAAJh0Uk5TAAECAwQGBgkKDA8QFBUWHh8lJygpKywwMzg5QkJGRktOUFNUV1xdYGVucHd7gIOEhISJkZaanJ6eo6qssbS1t76/v8DAwMDBwcLCw8TExMXGxsbIysvMzMzNzs/R0dLT1dfY2dve3t/h4eLl5eXm5ufo6Orq7O3t7e7u8PDy8vPz9PT19fX29vf4+Pn5+fr6+/v7/Pz9/v4CLqP4AAABNklEQVQYGdXBhULCABAA0EPFQAW7W1EREyxMMDGwu7s7sVuxW3b3tQ4GDKZ+gO/B/ycKToA/BSSrtL3thfAbaXxWxRbRlKGF4kBAEqMsnSeLmdbxWVp2A55XlEIzYSbOnOFdf0ekAo5HeHrB4Bs5LDa87nUSKxRAFCRXd9yQsw39Aw4tEasPAORr5Gqz2oSfug+yUADLW7lPvN2aS8T1AbJ69gcrSd45cQ51J4jYvU2cMrCTqh+J6LTqABGf6sxkkwQ8WfFx7Q6yFsbIzugJznLRou2IHPLBRQoiXjeSk0hwEYKI5bfEmwRX7iZcYaaHySETBHqwiWG+6s+IY5aBQBH2MwwzGltJVloQyri4Z15yxACpRmKlgVB0FzMSARbSEqIrHxDya84Wg03iqgZ+CgOebyD8I9/m1rRjchq3GQAAAABJRU5ErkJggg==)|Open XPS Viewer | Open Windows XPS Viewer. | -|**Email**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALzSURBVFiFzZdPSBRhGMZ/78y2+J+CJN0It1r7u26DIGQQepC6BGX0x6PHzOgUanToVmqdIgs6dS3DuhaCRYRBIWULHaQ0aLdCI9BozXb27TBuajMaLq7bcxq+eT6eZ57vfV/mE1Ull/Athyy9mBXj37eZiIWBpaoWEBFl8N3poqMraqDs6pfCvOKCiKliqWKBWJvRMEKBojAvOBUaMxH/YyB460c5NpaJbamKhWAVFBaGSGHM6WTnqHxbbn6/bkCrIyEgWdFZFAaz4rmCkUtxWGYXLIVA+5sMikQe5jgBPbhiCcS7qpYsXznRa5YFd1wSoW3++qoksOFCdEN5cEe/CG0Cv1Q4808DFSVCd72PgSY/A01+uut9VJQs/pHlHcMtIu4m3tgR3WckdQihHiEmKeo+dVb1LGmgNmBw74ifwyGTQJEQKBIOh0zuHfFTG/D2LCo3ytuGnwbaozv/iLdHz6L6WCAg6EDK1uqPV6oGF+zbfGNqQfXm+6D/pJ/1+cL9EZueIRuA1mqTxkqTiYTScGeGRHKhgekPozGUjcCMoJdTGNsFbQIQ5Ep89O15vXvcTvPTXeMqwuawyfp8YXhc6Xgyp9LxJMnWtQaRUqE5bHLzlb1g388f+bvy8qY7VfSUIhfFGd1TIM2xrnAfhD2Tc+W5dzbiR2O2i5xe2+txDF+vhSZj3eHTosZ+4DXwUtCaeFe4z1N5Fq4EKtc5ddQ/lnKR+8dSnKuZ43gh1r37GWAtJTofOR/FLgMj35yabAi6vaXX0pysGHged6I/EDRd5PRampMVA7ejNhMJJVIqdNb52FQsbCp2niOlwkRCuR11F2imcBVhIgnnBpJca1hDY6XT+2lMzjjv/p4BK2oAYDCe4tiDGVqrTWrKnJBefE7RM2TzYXJlf81ckzBTTI+NZrQvx20oD1ftf2Ax/BeDqOefrCxCVNXzYgKEWEZC71uKMjoCWexy6nU1Aw0DBatiwJPsdTlV9iDy8n1L4aGsG8gGfgM1OA5jF9TjyAAAAABJRU5ErkJggg==)|Hotmail send mail | Send an email with a given text and subject with your Hotmail account. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA3QAAAN0BcFOiBwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALwSURBVFiF7ZdNSFRRFMd/9857M+loM+NX0qJIFCMLKiP7IjLDwIoIXEkGKkJNuRArEkxCKI1qUYQtpEiYhVEQtGhTCzdCC1u0EFy4MAlRRFKbkXE+3m2hlW8+chyVWdTZPe55///vvHPue/cJpRSpDJlS9/8AgFClpbrPoV1EKDdwIHyqimDDNdD19XUKBtGfP8Xy8T3AIEp022dDHuE9WVaHUC+W5xqFOwneaEdl566Lt5ieQn/QgRwZNi8oUS+XKjeFHBnGeuMKcujLms3l0JdFrUhzAKHcwltxMP4+lJJQbSOhc9VJmWvv3qB5esAw4ub8HWApwkdPEHS3gG1TYs4LfvTuR1gG+ldMjdoF4cPHo5IsA/3YWpsQE+MrCoqJcWytTTHNA2XHVgYIttwmWOcGi2YWHhvFdtON/Pwprrn8/AnbTTdibDSiAo25mga+Xooat9jvgfCZCwQ6HqKycswL8z6sXe1or3ph+StcKbRXvVi72mHeZ7pFZeUwef0Ok0crYkPHq8YoLiHw4BnGnn3mBaXQXnuwdrYhfF6Ez4u1sw3ttccMBYR272Xs1j3mthXEs4keQv+bDxEkBlrfS7S3fVEGKn/rokjkbAiB72w145XnQZprLLpaY7o2NzpWSEmoph6jeBf6k/sIn/ePT4yhVPYMphua+F68Z0VpWMW3wCg9tNiSgqK4OeEdhXxr7UzYfFUAACovn8Ddx4RPVUWt+ctPM9rcjt+VvRrJBFoQGbpO8HIzRnEJes8TAGZqG5naf2TVUskBLEW4vBKjoJCZHz7mcvOTlUkeAEBtLyBTKQKzc/gXAklprPlAIoUg1+lgsz09NQC/wpFhJ8fpQAqRGgCANJuVLdkudC3xzq77mVCzWNiS5SR9ky01AABCCLIdm3FmZiQEMLgREACZ6WnkuZxIGbfOQYkS3RsFAGCz6uRnubDqMeZCiW5pnw15UKKeDXwSFoskz+XEnvb7SDeIEvX22ZBH/P83/OcBfgKOKuVWsq6gzAAAAABJRU5ErkJggg==)|Gmail send mail | Send an email with a given text and subject with your Gmail account. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAGFAAABhQFFWZ5CAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAPNQTFRF////bQCSgACfdQufcAqZcQufcw6dcg6ecw6fcg2ecg+fcQ6ecQ6ecQ2ecg6ecg6ecg6ecg6edBKgdhWhdhahdxeheBiieRmjeRqjehujex2kex6kfSGmfiKmgCaogyuqhS6rhjCsijivizmvjTyxjj2xjz+ykEGzmE64mE+4mlK5mlO6pmfCqGrDqm3ErXPHrnXHs37Lv5HTxZzXz63e0K/f1Lbi2b/l28Hm38np4czq4s7r48/s49Ds6Njv6drw6tvx7N7y7eDy8OX09O349u/59vD59/L6+PP6+vb8+/j8/Pn9/fv9/fz+/v3+/v7/////UZtl0gAAABF0Uk5TAAcIGBktSYSXmMHI2uPy8/XVqDFbAAABL0lEQVQ4y4VT53qCQBA8UOkCm5BGTDO9mWK66ZqiiXHe/2kCBxxEJTd/mG9nuL3d22VMQNFMy/E8xzI1hU2iargk4BrVMVnVffoDX1eLesWmCdiVXK/VaQrqNfH/VD1ypGeoNpXATu6hUyl0Xp9fbvDjag36B0bUP94fpAjGDK7CNE6CYPMDo71ID0KOpdShMTMzHwzxMk90NPgCfgZnadRkljjuFGhHn8UbXIQiaDEnT9gG9qnR6beIbl+vkpjDvNwwc41u8/F9N6IPuExiXtFA4ROGve2Y3aOVGQopiHaALU46WMtSWEXDOrDAyd2zuKRZNGwAy5yc52VquTy3egiscHrcFI1SxCg24l6Pvvufs0RvJ6LV0seSP7d0YOQjJx1a+djLF0e+evLlLV//X6kiRqMR0d/8AAAAAElFTkSuQmCC)|Yahoo send mail | Send an email with a given text and subject with your Yahoo account. | -|**Math**| -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Absolute | Calculates the absolute value of an integer or float | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Ceiling | Rounds up an integer or float to the closest number | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Exponential | The exponential of x | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Floor | The floor of x: the largest integer not greater than x | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Log | The natural logarithm of x, for x> 0 | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Maximum | The largest of its arguments: the value closest to positive infinity | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Minimum | The smallest of its arguments: the value closest to negative infinity | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Round | x rounded to n digits from the decimal point. | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Absolute | Calculates the absolute value of an integer or float | -| ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADdAAAA3QFwU6IHAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAchQTFRF////yNDikperyM/ixs/iwcjchYmchImdcXWHx9DiZ2p7W11uXmBxXmFyYWR1YmR1Y2Z3b3KDcHSHcXSGcXWGcnaHc3aHc3eKdnmLdnqLd3uMf4OUgoaYhImbhYmbh4yeio+gio+hjZKkj5askZitkpepkpmvk5iqk5qwlJmrlZqslZyylpyul5yul560maC2mqCym6K4nKO4naS5nqS2nqW6n6W3n6e8oKa3oam+oqi6oqm+oqq/o6u/pKvApqy/p67Bp6/EqK7AqbHFqrLGq7LFrLLFrLPFrLPGrLTIrbXJrrXIrrbKsLfJsLfKsLfMsrnMsrrOs7rOtLvOtLvPtLzQtbzQtr7Qt77SuMDUucHUucHVusDQusDRusHSusHVusLWu8LVu8PXvMPVvMTYvcTWvcXYwMfXwMfbwMjbwcfXwcjbwcnbwcncwsrdwsrew8vew8vfxMzfxc3gxc3hxs7hx8/iytLky9PlzNTlzNTmzcTVzdXmztXlztXnztbnz9blz9bn0Nfn0Nfo0Njp0djp0dnp0tnp0tnq1LfF1dzr1dzs1d3s1t3s17G+197t4Z2n45qk5Zaf83t/83uA9Hh89Xh7/2RkUGE35QAAAAt0Uk5TAGGdr7C05ufx9/j2Bdh2AAABsUlEQVQ4y5XQ1VMCARDH8bNjTeyORexATBQRsbBR7MIWA/Xw1sJWVBDP9t/1wZO5AW8cvq/7efjNMgzDBKbI/iwlkPkpVCZRqADCZDlrGz6t5cjCPKDBdXzDn9l5x5HTeeRwdve651ovGsTglg7cRK5Dur6mw1PEu2pc8g882h385Tl/b3e57PfugSF+peNKDLJmZn2ayRIBiX5BeJxE4QKIBIkiBRCyJVGIAIJJomAP6E9LLeE0qvqdUZVqdKdepeFKUtP6RaAYIH4PEaeaEJumEHEvHqDYH7CQl6ulPl27bVGnW7S16/pIm5u3IAK7avU4zZsmyGoyWWnCNE/javWuCJQDJLKIaG5BbDEjIpsIUO7PBm10VOZ+hbxo3SCXG9aL5BX7mVHRWhH491FtsTHZXKWi1NKjUPRYShWVXHZMbJs/G8oAElhENGsQNWZEZL2Ata5mhCaNY7RtNG7TmHGSvMDJ6+sTDeoN3LJev8wW5ld5g+evrw8WEaebEZu7AGDTF3x6RnYCgMULPLy/vXCNylrrsFI5vJqelGErSEru9YAgqUcFCSAg4u97RADDMN/r39ZZblPymgAAAABJRU5ErkJggg==)|Square root | The square root of x for x > 0 | - - -## Credits -Under the hood, Automagica is built on some of the greatest open source libraries as listed down below. Large parts of the documentation is based on theirs. Special thanks to all contributors of these great libraries! - -- [PyAutoGUI](https://github.com/asweigart/pyautogui) -- [Selenium](https://github.com/baijum/selenium-python) -- [PyWinAuto](https://github.com/pywinauto/pywinauto) -- [pytesseract](https://github.com/madmaze/pytesseract) -- [Tesseract](https://github.com/tesseract-ocr/tesseract) -- [OpenPyXL](https://bitbucket.org/openpyxl/openpyxl) -- [python-docx](https://github.com/python-openxml/python-docx) -- [pywin32](https://github.com/mhammond/pywin32) -- [PyPDF2](https://github.com/mstamy2/PyPDF2) -- [Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/) diff --git a/docs/make.bat b/docs/make.bat index a991b25e..be713a38 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -5,10 +5,10 @@ pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=python -msphinx + set SPHINXBUILD=sphinx-build ) -set SOURCEDIR=. -set BUILDDIR=_build +set SOURCEDIR=source +set BUILDDIR=build set SPHINXPROJ=Automagica if "%1" == "" goto help @@ -16,10 +16,10 @@ if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. - echo.The Sphinx module was not found. Make sure you have Sphinx installed, - echo.then set the SPHINXBUILD environment variable to point to the full - echo.path of the 'sphinx-build' executable. Alternatively you may add the - echo.Sphinx directory to PATH. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ diff --git a/docs/portal/activities.json b/docs/portal/activities.json new file mode 100644 index 00000000..0a22a2ac --- /dev/null +++ b/docs/portal/activities.json @@ -0,0 +1,5415 @@ +[ + { + "name": "Cryptography", + "icon": "las la-shield-alt", + "activities": [ + { + "function_call": "generate_random_key()", + "name": "Random key", + "description": "Generate random Fernet key. Fernet guarantees that a message encrypted using it cannot be manipulated or read without the key. Fernet is an implementation of symmetric (also known as \u201csecret key\u201d) authenticated cryptography", + "parameters": [], + "return": " Bytes-like object\n", + "example": ">>> # Generate a random key\n>>> generate_random_key()\nb'AYv6ZPVgnrUtHDbGZqAopRyAo9r0_UKrA2Rm3K_NjIo='\n", + "snippet": "# Generate a random key\ngenerate_random_key()\n", + "keywords": [ + "random", + "key", + "fernet", + "hash", + "security", + "cryptography", + "password", + "secure" + ], + "icon": "las la-key" + }, + { + "function_call": "encrypt_text_with_key(text, key)", + "name": "Encrypt text", + "description": "Encrypt text with (Fernet) key,", + "parameters": [ + { + "name": " text", + "description": " Text to be encrypted.\n" + }, + { + "name": " key", + "description": " Path where key is stored.\n" + } + ], + "return": " bytes-like object.\n", + "example": ">>> # Generate a random key\n>>> key = generate_random_key()\n>>> # Encrypt text with this key\n>>> encrypt_text_with_key('Sample text', key)\nb'gAAAAABd8lpG8fNqcj5eXrPPHlx4KeCm-1TgX3jkyhStMfIlgGImIa-qaINZAj8XcxPcG8iu84iT56b_qAW9c5qpe7btUFhtxQ=='\n", + "snippet": "# Generate a random key\nkey = generate_random_key()\n# Encrypt text with this key\nencrypt_text_with_key('Sample text', key)\n", + "keywords": [ + "random", + "encryption", + "secure", + "security", + "hash", + "password", + "fernet", + "text" + ], + "icon": "las la-lock" + }, + { + "function_call": "decrypt_text_with_key(encrypted_text, key)", + "name": "Decrypt text", + "description": "Dexrypt bytes-like object to string with (Fernet) key", + "parameters": [ + { + "name": " encrypted_text", + "description": " Text to be encrypted.\n" + }, + { + "name": " key", + "description": " Path where key is stored.\n" + } + ], + "return": " String\n", + "example": ">>> # Generate a random key\n>>> key = generate_random_key()\n>>> # Encrypt text with generated key\n>>> encrypted_text = encrypt_text_with_key('Sample text', key)\n>>> # Decrypt text with same key\n>>> decrypt_text_with_key(encrypted_text, key)\n'Sample text'\n", + "snippet": "# Generate a random key\nkey = generate_random_key()\n# Encrypt text with generated key\nencrypted_text = encrypt_text_with_key('Sample text', key)\n# Decrypt text with same key\ndecrypt_text_with_key(encrypted_text, key)\n", + "keywords": [ + "decrypt", + "random", + "unlock", + "un-lock hash", + "security", + "cryptography", + "password", + "secure", + "hash", + "text" + ], + "icon": "las la-lock-open" + }, + { + "function_call": "encrypt_file_with_key(input_path, key, output_path=None)", + "name": "Encrypt file", + "description": "Encrypt file with (Fernet) key. Note that file will be unusable unless unlocked with the same key.", + "parameters": [ + { + "name": " input_file", + "description": " Full path to file to be encrypted.\n" + }, + { + "name": " key", + "description": " Path where key is stored.\n" + }, + { + "name": " output_file", + "description": " Output path. Default is the same directory with \"_encrypted\" added to the name\n" + } + ], + "return": " Path to encrypted file\n", + "example": ">>> # Generate a random key\n>>> key = generate_random_key()\n>>> # Create a textfile to illustrate file encryption\n>>> textfile_path = make_textfile()\n>>> # Encrypt the textfile\n>>> encrypt_file_with_key(textfile_path, key=key)\n'C:\\\\Users\\\\\\\\generated_textfile_encrypted.txt'\n", + "snippet": "# Generate a random key\nkey = generate_random_key()\n# Create a textfile to illustrate file encryption\ntextfile_path = make_textfile()\n# Encrypt the textfile\nencrypt_file_with_key(textfile_path, key=key)\n", + "keywords": [ + "encrypt", + "random", + "password", + "secure", + "secure file", + "lock" + ], + "icon": "las la-lock" + }, + { + "function_call": "decrypt_file_with_key(input_path, key, output_path=None)", + "name": "Decrypt file", + "description": "Decrypts file with (Fernet) key", + "parameters": [ + { + "name": " input_file", + "description": " Bytes-like file to be decrypted.\n" + }, + { + "name": " key", + "description": " Path where key is stored.\n" + }, + { + "name": " output_file", + "description": " Outputfile, make sure to give this the same extension as basefile before encryption. Default is the same directory with \"_decrypted\" added to the name \n" + } + ], + "return": " Path to decrypted file\n", + "example": ">>> # Generate a random key\n>>> key = generate_random_key()\n>>> # Create a textfile to encrypt file\n>>> textfile_path = make_textfile()\n>>> # Encrypt the textfile\n>>> encrypted_textfile = encrypt_file_with_key(textfile_path, key=key)\n>>> # Decrypt the newly encrypted file\n>>> decrypt_file_with_key(encrypted_textfile, key=key)\n'C:\\\\Users\\\\\\\\generated_textfile_encrypted_decrypted.txt'\n", + "snippet": "# Generate a random key\nkey = generate_random_key()\n# Create a textfile to encrypt file\ntextfile_path = make_textfile()\n# Encrypt the textfile\nencrypted_textfile = encrypt_file_with_key(textfile_path, key=key)\n# Decrypt the newly encrypted file\ndecrypt_file_with_key(encrypted_textfile, key=key)\n", + "keywords": [ + "decrypt", + "random", + "password", + "secure", + "secure file", + "unlock" + ], + "icon": "las la-lock-open" + }, + { + "function_call": "generate_key_from_password(password, salt=None)", + "name": "Key from password", + "description": "Generate key based on password and salt. If both password and salt are known the key can be regenerated.", + "parameters": [ + { + "name": " password", + "description": " Passwords\n" + }, + { + "name": " salt", + "description": " Salt to generate key in combination with password. Default value is the hostname. Take in to account that hostname is necessary to generate key, e.g. when files are encrypted with salt 'A' and password 'B', both elements are necessary to decrypt files.\n" + } + ], + "return": " Bytes-like object\n", + "example": ">>> # Generate a key from password\n>>> key = generate_key_from_password(password='Sample password')\nb'7jGGF5w_xyI0CIZGCmLlnNyUvFpNvIUY08JCHopgAmm8='\n", + "snippet": "# Generate a key from password\nkey = generate_key_from_password(password='Sample password')\n", + "keywords": [ + "random", + "key", + "fernet", + "hash", + "security", + "cryptography", + "password", + "secure", + "salt" + ], + "icon": "las la-lock" + }, + { + "function_call": "generate_hash_from_file(input_path, method='md5', buffer_size=65536)", + "name": "Hash from file", + "description": "Generate hash from file", + "parameters": [ + { + "name": " file", + "description": " File to hash\n" + }, + { + "name": " method", + "description": " Method for hashing, choose between 'md5', 'sha256' and 'blake2b'. Note that different methods generate different hashes. Default method is 'md5'.\n" + }, + { + "name": " buffer_size", + "description": " Buffer size for reading file in chunks, default value is 64kb\n" + } + ], + "return": " Bytes-like object\n", + "example": ">>> # Generate a text file to illustrate hash\n>>> textfile_path = make_textfile()\n>>> # Get hash from textfile\n>>> generate_hash_from_file(textfile_path)\n'1ba249ca5931f3c85fe44d354c2f274d'\n", + "snippet": "# Generate a text file to illustrate hash\ntextfile_path = make_textfile()\n# Get hash from textfile\ngenerate_hash_from_file(textfile_path)\n", + "keywords": [ + "hash", + "mdf5", + "sha256", + "blake2b", + "identifier", + "unique", + "hashing", + "fingerprint", + "comparison" + ], + "icon": "las la-fingerprint" + }, + { + "function_call": "generate_hash_from_text(text, method='md5')", + "name": "Hash from text", + "description": "Generate hash from text", + "parameters": [ + { + "name": " file", + "description": " Text to hash\n" + }, + { + "name": " method", + "description": " Method for hashing, choose between 'md5', 'sha256' and 'blake2b'. Note that different methods generate different hashes. Default method is 'md5'.\n" + } + ], + "return": "", + "example": ">>> # Generate a hast from text\n>>> generate_hash_from_text('Sample text')\n'1ba249ca5931f3c85fe44d354c2f274d'\n", + "snippet": "# Generate a hast from text\ngenerate_hash_from_text('Sample text')\n", + "keywords": [ + "Hash", + "mdf5", + "sha256", + "blake2b", + "identifier", + "unique", + "hashing", + "fingerprint", + "text", + "comparison" + ], + "icon": "las la-fingerprint" + } + ] + }, + { + "name": "Random", + "icon": "las la-dice-d6", + "activities": [ + { + "function_call": "generate_random_number(lower_limit=0, upper_limit=100, fractional=False)", + "name": "Random number", + "description": "Random numbers can be integers (not a fractional number) or a float (fractional number).", + "parameters": [ + { + "name": " lower_limit", + "description": " Lower limit for random number\n" + }, + { + "name": " upper_limit", + "description": " Upper limit for random number\n" + }, + { + "name": " fractional", + "description": " Setting this to True will generate fractional number. Default value is False and only generates whole numbers.\n" + } + ], + "return": " Random integer or float\n", + "example": ">>> # Generate a random number\n>>> generate_random_number()\n7\n", + "snippet": "# Generate a random number\ngenerate_random_number()\n", + "icon": "las la-dice" + }, + { + "function_call": "generate_random_boolean()", + "name": "Random boolean", + "description": "Generates a random boolean (True or False)", + "parameters": [], + "return": " Boolean\n", + "example": ">>> # Generate a random boolean\n>>> generate_random_boolean()\nTrue\n", + "snippet": "# Generate a random boolean\ngenerate_random_boolean()\n", + "icon": "las la-coins" + }, + { + "function_call": "generate_random_name(locale=None)", + "name": "Random name", + "description": "Generates a random name. Adding a locale adds a more common name in the specified locale. Provides first name and last name.", + "parameters": [ + { + "name": " locale", + "description": " Add a locale to generate popular name for selected locale.\n" + }, + { + "name": " locale", + "description": " Add a locale to generate popular name for selected locale.\n" + } + ], + "return": " Random sentence as string\n", + "example": ">>> # Generate a random name\n>>> generate_random_name()\n'Michelle Murphy'\n", + "snippet": "# Generate a random name\ngenerate_random_name()\n", + "keywords": [ + "random", + "sentence", + "lorem ipsum", + "text generater", + "filler", + "place holder", + "noise", + "random text" + ], + "icon": "las la-comment" + }, + { + "function_call": "generate_random_address(locale=None)", + "name": "Random address", + "description": "Generates a random address. Specifying locale changes random locations and streetnames based on locale.", + "parameters": [ + { + "name": " locale", + "description": " Add a locale to generate popular name for selected locale.\n" + } + ], + "return": " Random address as string\n", + "example": ">>> # Generate a random address\n>>> generate_random_address()\n'5639 Cynthia Bridge Suite 610\n'Port Nancy, GA 95894'\n", + "snippet": "# Generate a random address\ngenerate_random_address()\n", + "keywords": [ + "random", + "address", + "random address", + "fake person ", + "fake address", + "fake person generator" + ], + "icon": "las la-map" + }, + { + "function_call": "generate_random_beep(max_duration=2000, max_frequency=5000)", + "name": "Random beep", + "description": "Generates a random beep, only works on Windows", + "parameters": [ + { + "name": " max_duration", + "description": " Maximum random duration in miliseconds. Default value is 2 miliseconds\n" + }, + { + "name": " max_frequency", + "description": " Maximum random frequency in Hz. Default value is 5000 Hz.\n" + } + ], + "return": " Sound\n", + "example": ">>> # Generate a random beep\n>>> generate_random_beep()\n", + "snippet": "# Generate a random beep\ngenerate_random_beep()\n", + "keywords": [ + "beep", + "sound", + "random", + "noise", + "alert", + "notification" + ], + "icon": "las la-volume-up" + }, + { + "function_call": "generate_random_date(formatting='%m/%d/%Y %I%M', days_in_past=1000)", + "name": "Random date", + "description": "Generates a random date.", + "parameters": [ + { + "name": " days_in_past", + "description": " Days in the past for which oldest random date is generated, default is 1000 days\n" + }, + { + "name": " formatting", + "description": " Formatting of the dates, replace with 'None' to get raw datetime format. e.g. format='Current month is %B' generates 'Current month is Januari' and format='%m/%d/%Y %I:%M' generates format 01/01/1900 00:00. \n" + } + ], + "return": " Random date as string\n", + "example": ">>> # Generate a random date\n>>> generate_random_date()\n01/01/2020 13:37'\n", + "snippet": "# Generate a random date\ngenerate_random_date()\n", + "keywords": [ + "random", + "date", + "datetime", + "random date", + "fake date ", + "calendar" + ], + "icon": "las la-calendar" + }, + { + "function_call": "generate_unique_identifier()", + "name": "Generate unique identifier", + "description": "Generates a random UUID4 (universally unique identifier). While the probability that a UUID will be duplicated is not zero, it is close enough to zero to be negligible.", + "parameters": [], + "return": " Identifier as string\n", + "example": ">>> # Generate unique identifier\n>>> generate_unique_identifier()\n'd72fd7ea-d682-4f78-8ca1-0ed34142a992'\n", + "snippet": "# Generate unique identifier\ngenerate_unique_identifier()\n", + "keywords": [ + "unique", + "identifier", + "primary key", + "random" + ], + "icon": "las la-random" + } + ] + }, + { + "name": "User Input", + "icon": "lab la-wpforms", + "activities": [ + { + "function_call": "ask_user_input(title=\"Title\", label=\"Input\", password=False)", + "name": "Ask user for input", + "description": "Prompt the user for an input with a pop-up window.", + "parameters": [ + { + "name": " title", + "description": " Title for the pop-up window\n" + }, + { + "name": " message", + "description": " The message to be shown to the user\n" + } + ], + "return": " Inputted text as string\n", + "example": ">>> # Make a window pop-up ask for user input\n>>> ask_user_input()\n>>> # Type in text and press 'submit', e.g. 'Sample text'\n'Sample text'\n", + "snippet": "# Make a window pop-up ask for user input\nask_user_input()\n# Type in text and press 'submit', e.g. 'Sample text'\n", + "keywords": [ + "user input", + "pop-up", + "interaction", + "popup", + "window", + "feedback", + "screen", + "ad-hoc", + "attended" + ], + "icon": "las la-window-maximize" + }, + { + "function_call": "ask_user_password(label=\"Password\")", + "name": "Ask user for password", + "description": "Prompt the user for a password. The password will be masked on screen while entering.", + "parameters": [ + { + "name": " title", + "description": " Title for the pop-up window\n" + }, + { + "name": " message", + "description": " The message to be shown to the user\n" + } + ], + "return": " Inputted password as string\n", + "example": ">>> # Make a window pop-up ask for user password\n>>> ask_user_password()\n>>> # Type in password and press 'submit', e.g. 'Sample password'\n'Sample password'\n", + "snippet": "# Make a window pop-up ask for user password\nask_user_password()\n# Type in password and press 'submit', e.g. 'Sample password'\n", + "keywords": [ + "user input", + "pop-up", + "interaction", + "interactive", + "credential", + "popup", + "window", + "feedback", + "password", + "screen", + "login", + "attended" + ], + "icon": "lar la-window-maximize" + }, + { + "function_call": "ask_credentials(title=\"Credentials required\", dialogue_text_username=\"Username\", dialogue_text_password=\"Password\")", + "name": "Ask user for credentials", + "description": "Prompt a popup which asks user for username and password and returns in plain text. Password will be masked.", + "parameters": [ + { + "name": " title", + "description": " Title for the popup\n" + }, + { + "name": " dialogue_text", + "description": " Dialogue text for username\n" + }, + { + "name": " dialogue_text", + "description": " Dialogue text for password\n" + } + ], + "return": " Typle with nputted username and password as strings\n", + "example": ">>> # Make a window pop-up ask user credentials\n>>> ask_credentials()\n>>> # Type in Username and Password 'submit', e.g. 'Sample username' and 'Sample password'\n('Sample username', 'Sample password')\n", + "snippet": "# Make a window pop-up ask user credentials\nask_credentials()\n# Type in Username and Password 'submit', e.g. 'Sample username' and 'Sample password'\n", + "keywords": [ + "user input", + "credentials", + "interactive", + "pop-up", + "interaction", + "popup", + "window", + "feedback", + "password", + "screen", + "login", + "attended" + ], + "icon": "las la-window-maximize" + }, + { + "function_call": "display_message_box(title=\"Title\", message=\"Example message\")", + "name": "Shows message box", + "description": "A pop-up message with title and message.", + "parameters": [ + { + "name": " title", + "description": " Title for the pop-up window\n" + }, + { + "name": " message", + "description": " The message to be shown to the user\n" + } + ], + "return": " True if user presses 'OK'\n", + "example": ">>> # Show pop-up with message\n>>> display_message_box()\n>>> # Wait till user presses 'OK'\nTrue\n", + "snippet": "# Show pop-up with message\ndisplay_message_box()\n# Wait till user presses 'OK'\n", + "keywords": [ + "message box", + "warning", + "info", + "popup", + "window", + "feedback", + "screen", + "attended" + ], + "icon": "las la-window-maximize" + }, + { + "function_call": "display_osd_message(message='Example message', seconds=5)", + "name": "Display overlay message", + "description": "Display custom OSD (on-screen display) message. Can be used to display a message for a limited amount of time. Can be used for illustration, debugging or as OSD.", + "parameters": [ + { + "name": " message", + "description": " Message to be displayed\n" + } + ], + "return": "", + "example": ">>> # Display overlay message\n>>> display_osd_message()\n", + "snippet": "# Display overlay message\ndisplay_osd_message()\n", + "keywords": [ + "message box", + "osd", + "overlay", + "info warning", + "info", + "popup", + "window", + "feedback", + "screen", + "login", + "attended" + ], + "icon": "las la-tv" + } + ] + }, + { + "name": "Browser", + "icon": "lab la-chrome", + "activities": [ + { + "function_call": "Chrome(load_images=True, headless=False)", + "name": "Open Chrome Browser", + "description": "Open the Chrome Browser with the Selenium webdriver. Canb be used to automate manipulations in the browser.Different elements can be found as:", + "parameters": [ + { + "name": " load_images", + "description": " Do not load images (bool). This could speed up loading pages\n" + }, + { + "name": " headless", + "description": " Run headless, this means running without a visible window (bool)\n" + } + ], + "return": "", + "example": ">>> # Open the browser\n>>> browser = Chrome()\n>>> # Go to a website\n>>> browser.get('https://automagica.com')\n>>> # Close browser\n>>> browser.quit()\n", + "snippet": "# Open the browser\nbrowser = Chrome()\n# Go to a website\nbrowser.get('https://automagica.com')\n# Close browser\nbrowser.quit()\n", + "keywords": [ + "chrome", + "browsing", + "browser", + "internet", + "surfing", + "web", + "webscraping", + "www", + "selenium", + "crawling", + "webtesting", + "mozilla", + "firefox", + "internet explorer" + ], + "icon": "lab la-chrome" + }, + { + "function_call": "save_all_images(output_path=None)", + "name": "Save all images", + "description": "Save all images on current page in the Browser", + "parameters": [ + { + "name": " output_path", + "description": " Path where images can be saved. Default value is home directory.\n" + } + ], + "return": " List with paths to images\n", + "example": ">>> # Open the browser\n>>> browser = Chrome()\n>>> # Go to a website\n>>> browser.get('https://www.nytimes.com/')\n>>> # Save all images\n>>> browser.save_all_images()\n>>> browser.quit()\n['C:\\\\Users\\\\\\\\image1.png', 'C:\\\\Users\\\\\\\\image2.jpg', 'C:\\\\Users\\\\\\\\image4.gif']\n", + "snippet": "# Open the browser\nbrowser = Chrome()\n# Go to a website\nbrowser.get('https://www.nytimes.com/')\n# Save all images\nbrowser.save_all_images()\nbrowser.quit()\n", + "keywords": [ + "image scraping", + "chrome", + "internet", + "browsing", + "browser", + "surfing", + "web", + "webscraping", + "www", + "selenium", + "crawling", + "webtesting", + "mozilla", + "firefox", + "internet explorer" + ], + "icon": "las la-images" + }, + { + "function_call": "find_elements_by_text(text)", + "name": "Find elements by text", + "description": "Find all elements by their text. Text does not need to match exactly, part of text is enough.", + "parameters": [], + "return": "", + "example": ">>> # Open the browser\n>>> browser = Chrome()\n>>> # Go to a website\n>>> browser.get('https://nytimes.com')\n>>> # Find elements by text\n>>> browser.find_elements_by_text('world')\n[webelement1, webelement2 , .. ]\n", + "snippet": "# Open the browser\nbrowser = Chrome()\n# Go to a website\nbrowser.get('https://nytimes.com')\n# Find elements by text\nbrowser.find_elements_by_text('world')\n", + "keywords": [ + "element", + "element by text", + "chrome", + "internet", + "browsing", + "browser", + "surfing", + "web", + "webscraping", + "www", + "selenium", + "crawling", + "webtesting", + "mozilla", + "firefox", + "internet explorer" + ], + "icon": "las la-align-center" + }, + { + "function_call": "find_element_by_text(text)", + "name": "Find element by text", + "description": "Find one element by text. Text does not need to match exactly, part of text is enough.", + "parameters": [], + "return": "", + "example": ">>> # Open the browser\n>>> browser = Chrome()\n>>> # Go to a website\n>>> browser.get('https://nytimes.com')\n>>> # Find elements by text\n>>> browser.find_element_by_text('world')\nwebelement\n", + "snippet": "# Open the browser\nbrowser = Chrome()\n# Go to a website\nbrowser.get('https://nytimes.com')\n# Find elements by text\nbrowser.find_element_by_text('world')\n", + "keywords": [ + "element", + "element by text", + "chrome", + "internet", + "browsing", + "browser", + "surfing", + "web", + "webscraping", + "www", + "selenium", + "crawling", + "webtesting", + "mozilla", + "firefox", + "internet explorer" + ], + "icon": "las la-align-center" + }, + { + "function_call": "find_all_links(self)", + "name": "Find all links", + "description": "Find all links on a webpage in the browser", + "parameters": [], + "return": "", + "example": ">>> # Open the browser\n>>> browser = Chrome()\n>>> # Go to a website\n>>> browser.get('https://nytimes.com')\n>>> # Find elements by text\n>>> browser.find_all_links()\n[webelement1, webelement2 , .. ]\n", + "snippet": "# Open the browser\nbrowser = Chrome()\n# Go to a website\nbrowser.get('https://nytimes.com')\n# Find elements by text\nbrowser.find_all_links()\n", + "keywords": [ + "random", + "element", + "element by text", + "chrome", + "internet", + "browsing", + "browser", + "surfing", + "web", + "webscraping", + "www", + "selenium", + "crawling", + "webtesting", + "mozilla", + "firefox", + "internet explorer" + ], + "icon": "las la-window-restore" + }, + { + "function_call": "highlight(element)", + "name": "Highlight element", + "description": "Highlight elements in yellow in the browser", + "parameters": [], + "return": "", + "example": ">>> # Open the browser\n>>> browser = Chrome()\n>>> # Go to a website\n>>> browser.get('https://wikipedia.org')\n>>> # Find all links\n>>> links = browser.find_all_links()\n>>> # Select first link to highlight for illustration\n>>> first_link = links[0]\n>>> # Highlight first link\n>>> browser.highlight(first_link)\n", + "snippet": "# Open the browser\nbrowser = Chrome()\n# Go to a website\nbrowser.get('https://wikipedia.org')\n# Find all links\nlinks = browser.find_all_links()\n# Select first link to highlight for illustration\nfirst_link = links[0]\n# Highlight first link\nbrowser.highlight(first_link)\n", + "keywords": [ + "element", + "element by text", + "chrome", + "internet", + "browsing", + "browser", + "surfing", + "web", + "webscraping", + "www", + "selenium", + "crawling", + "webtesting", + "mozilla", + "firefox", + "internet explorer" + ], + "icon": "las la-highlighter" + }, + { + "function_call": "exit(self)", + "name": "Exit the browser", + "description": "Quit the browser by exiting gracefully. One can also use the native 'quit' function, e.g. 'browser.quit()'", + "parameters": [], + "return": "", + "example": ">>> # Open the browser\n>>> browser = Chrome()\n>>> # Go to a website\n>>> browser.get('https://automagica.com')\n>>> # Close browser\n>>> browser.exit()\n", + "snippet": "# Open the browser\nbrowser = Chrome()\n# Go to a website\nbrowser.get('https://automagica.com')\n# Close browser\nbrowser.exit()\n", + "keywords": [ + "quit", + "exit", + "close", + "element", + "element by text", + "chrome", + "internet", + "browsing", + "browser", + "surfing", + "web", + "webscraping", + "www", + "selenium", + "crawling", + "webtesting", + "mozilla", + "firefox", + "internet explorer" + ], + "icon": "las la-window-close" + }, + { + "function_call": "find_all_xpaths(element)", + "name": "Find all XPaths", + "description": "Find all elements with specified xpath on a webpage in the the browser. Can also use native 'find_elements_by_xpath' function e.g. browser.find_elements_by_xpath()You can easily", + "parameters": [], + "return": "", + "example": ">>> # Open the browser\n>>> browser = Chrome()\n>>> # Go to a website\n>>> browser.get('https://wikipedia.org')\n>>> # Find element by xpath\n>>> browser.find_xpaths('//*[@id=\\'js-link-box-en\\']')\n[webelement1, webelement2 , .. ]\n", + "snippet": "# Open the browser\nbrowser = Chrome()\n# Go to a website\nbrowser.get('https://wikipedia.org')\n# Find element by xpath\nbrowser.find_xpaths('//*[@id=\\'js-link-box-en\\']')\n", + "keywords": [ + "random", + "element", + "xpath", + "xml", + "element by text", + "chrome", + "internet", + "browsing", + "browser", + "surfing", + "web", + "webscraping", + "www", + "selenium", + "crawling", + "webtesting", + "mozilla", + "firefox", + "internet explorer" + ], + "icon": "las la-times" + }, + { + "function_call": "find_xpath(element)", + "name": "Find XPath in browser", + "description": "Find all element with specified xpath on a webpage in the the browser. Can also use native 'find_elements_by_xpath' function e.g. browser.find_element_by_xpath()", + "parameters": [], + "return": "", + "example": ">>> # Open the browser\n>>> browser = Chrome()\n>>> # Go to a website\n>>> browser.get('https://wikipedia.org')\n>>> # Find element by xpath\n>>> elements = browser.find_xpath('//*[@id=\\'js-link-box-en\\']')\n>>> # We can now use this element, for example to click on\n>>> element.click()\n", + "snippet": "# Open the browser\nbrowser = Chrome()\n# Go to a website\nbrowser.get('https://wikipedia.org')\n# Find element by xpath\nelements = browser.find_xpath('//*[@id=\\'js-link-box-en\\']')\n# We can now use this element, for example to click on\nelement.click()\n", + "keywords": [ + "random", + "xpath", + "element", + "xml element by text", + "chrome", + "internet", + "browsing", + "browser", + "surfing", + "web", + "webscraping", + "www", + "selenium", + "crawling", + "webtesting", + "mozilla", + "firefox", + "internet explorer" + ], + "icon": "las la-times" + } + ] + }, + { + "name": "Credential Management", + "icon": "las la-key", + "activities": [ + { + "function_call": "set_credential(username=None, password=None, system=\"Automagica\")", + "name": "Set credential", + "description": "Add a credential which stores credentials locally and securely. All parameters should be Unicode text.", + "parameters": [ + { + "name": " username", + "description": " Username for which credential will be added.\n" + }, + { + "name": " password", + "description": " Password to add\n" + }, + { + "name": " system", + "description": " Name of the system for which credentials are stored. Extra safety measure and method for keeping passwords for similar usernames on different applications a part. Highly recommended to change default value.\n" + } + ], + "return": " Stores credentials locally\n", + "example": ">>> set_credential('SampleUsername', 'SamplePassword')\n", + "snippet": "set_credential('SampleUsername', 'SamplePassword')\n", + "keywords": [ + "credential", + "login", + "password", + "username", + "store", + "vault", + "secure", + "credentials", + "store", + "log in", + "encrypt" + ], + "icon": "las la-key" + }, + { + "function_call": "delete_credential(username=None, password=None, system=\"Automagica\")", + "name": "Delete credential", + "description": "Delete a locally stored credential. All parameters should be Unicode text.", + "parameters": [ + { + "name": " username", + "description": " Username for which credential (username + password) will be deleted.\n" + }, + { + "name": " system", + "description": " Name of the system for which password will be deleted. \n" + } + ], + "return": "", + "example": ">>> set_credential('SampleUsername', 'SamplePassword')\n>>> delete_credential('SampleUsername', 'SamplePassword')\n", + "snippet": "set_credential('SampleUsername', 'SamplePassword')\ndelete_credential('SampleUsername', 'SamplePassword')\n", + "keywords": [ + "credential", + "delete", + "login", + "password", + "username", + "store", + "vault", + "secure", + "credentials", + "store", + "log in", + "encrypt" + ], + "icon": "las la-key" + }, + { + "function_call": "get_credential(username=None, system=\"Automagica\")", + "name": "Get credential", + "description": "Get a locally stored redential. All parameters should be Unicode text.", + "parameters": [ + { + "name": " username", + "description": " Username to get password for.\n" + }, + { + "name": " system", + "description": " Name of the system for which credentials are retreived.\n" + } + ], + "return": " Stored credential as string\n", + "example": ">>> set_credential('SampleUsername', 'SamplePassword')\n>>> get_credential('SampleUsername')\n'SamplePassword'\n", + "snippet": "set_credential('SampleUsername', 'SamplePassword')\nget_credential('SampleUsername')\n", + "keywords": [ + "credential", + "get", + "delete", + "login", + "password", + "username", + "store", + "vault", + "secure", + "credentials", + "store", + "log in", + "encrypt" + ], + "icon": "las la-key" + } + ] + }, + { + "name": "FTP", + "icon": "las la-key", + "activities": [ + { + "function_call": "FTP(server, username, password)", + "name": "Create FTP connection", + "description": "Can be used to automate activites for FTP", + "parameters": [ + { + "name": " server", + "description": " Name of the server\n" + }, + { + "name": " username", + "description": " Username \n" + }, + { + "name": " password", + "description": " Password\n" + } + ], + "return": "", + "example": ">>> # This example uses the Rebex FPT test server.\n>>> # Take caution uploading and downloading from this server as it is public\n>>> ftp = FTP('test.rebex.net', 'demo', 'password')\n", + "snippet": "# This example uses the Rebex FPT test server.\n# Take caution uploading and downloading from this server as it is public\nftp = FTP('test.rebex.net', 'demo', 'password')\n", + "keywords": [ + "FTP", + "file transfer protocol", + "filezilla", + "winscp", + "server", + "remote", + "folder", + "folders" + ], + "icon": "las la-folder-open" + }, + { + "function_call": "download_file(input_path, output_path=None)", + "name": "Download file", + "description": "Downloads a file from FTP server. Connection needs to be established first.", + "parameters": [ + { + "name": " input_path", + "description": " Path to the file on the FPT server to download\n" + }, + { + "name": " output_path", + "description": " Destination path for downloaded files. Default is the same directory with \"_downloaded\" added to the name\n" + } + ], + "return": " Path to output file as string \n", + "example": ">>> # This example uses the Rebex FPT test server.\n>>> # Take caution uploading and downloading from this server as it is public\n>>> ftp = FTP('test.rebex.net', 'demo', 'password')\n>>> # Download Rebex public file 'readme.txt'\n>>> ftp.download_file('readme.txt')\n'C:\\\\Users\\\\\\\\readme_downloaded.txt'\n", + "snippet": "# This example uses the Rebex FPT test server.\n# Take caution uploading and downloading from this server as it is public\nftp = FTP('test.rebex.net', 'demo', 'password')\n# Download Rebex public file 'readme.txt'\nftp.download_file('readme.txt')\n", + "keywords": [ + "FTP", + "file transfer protocol", + "download", + "filezilla", + "winscp", + "server", + "remote", + "folder", + "folders" + ], + "icon": "las la-download" + }, + { + "function_call": "upload_file(input_path, output_path=None)", + "name": "Upload file", + "description": "Upload file to FTP server", + "parameters": [ + { + "name": " from_path", + "description": " Path file that will be uploaded\n" + }, + { + "name": " to_path", + "description": " Destination path to upload. \n" + } + ], + "return": " Patht to uploaded file as string\n", + "example": ">>> # This example uses the Rebex FPT test server.\n>>> # Take caution uploading and downloading from this server as it is public\n>>> ftp = FTP('test.rebex.net', 'demo', 'password')\n>>> # Create a .txt file for illustration\n>>> textfile = make_textfile()\n>>> # Upload file to FTP test server\n>>> # Not that this might result in a persmission error for public FPT's\n>>> ftp.upload_file(textfile)\n", + "snippet": "# This example uses the Rebex FPT test server.\n# Take caution uploading and downloading from this server as it is public\nftp = FTP('test.rebex.net', 'demo', 'password')\n# Create a .txt file for illustration\ntextfile = make_textfile()\n# Upload file to FTP test server\n# Not that this might result in a persmission error for public FPT's\nftp.upload_file(textfile)\n", + "keywords": [ + "FTP", + "upload", + "fptfile transfer protocol", + "filezilla", + "winscp", + "server", + "remote", + "folder", + "folders" + ], + "icon": "las la-upload" + }, + { + "function_call": "enumerate_files(path=\"/\")", + "name": "List FTP files", + "description": "Generate a list of all the files in the FTP directory", + "parameters": [ + { + "name": " path", + "description": " Path to list files from. Default is the main directory\n" + } + ], + "return": " Prints list of all files and directories\n", + "example": ">>> # This example uses the Rebex FPT test server.\n>>> # Take caution uploading and downloading from this server as it is public\n>>> ftp = FTP('test.rebex.net', 'demo', 'password')\n>>> # Show all files in main directory\n>>> ftp.enumerate_files()\n10-27-15 03:46PM pub\n04-08-14 03:09PM 403 readme.txt\n'226 Transfer complete.'\n", + "snippet": "# This example uses the Rebex FPT test server.\n# Take caution uploading and downloading from this server as it is public\nftp = FTP('test.rebex.net', 'demo', 'password')\n# Show all files in main directory\nftp.enumerate_files()\n", + "keywords": [ + "FTP", + "list", + "upload", + "fptfile transfer protocol", + "filezilla", + "winscp", + "server", + "remote", + "folder", + "folders" + ], + "icon": "las la-list-ol" + }, + { + "function_call": "directory_exists(path=\"/\")", + "name": "Check FTP directory", + "description": "Check if FTP directory exists", + "parameters": [ + { + "name": " path", + "description": " Path to check on existence. Default is main directory\n" + } + ], + "return": " Boolean\n", + "example": ">>> # This example uses the Rebex FPT test server.\n>>> # Take caution uploading and downloading from this server as it is public\n>>> ftp = FTP('test.rebex.net', 'demo', 'password')\n>>> # Check if 'pub' folder exists in main directory\n>>> ftp.directory_exists('\\\\pub')\nTrue\n", + "snippet": "# This example uses the Rebex FPT test server.\n# Take caution uploading and downloading from this server as it is public\nftp = FTP('test.rebex.net', 'demo', 'password')\n# Check if 'pub' folder exists in main directory\nftp.directory_exists('\\\\pub')\n", + "keywords": [ + "FTP", + "list", + "upload", + "fptfile transfer protocol", + "filezilla", + "winscp", + "server", + "remote", + "folder", + "folders" + ], + "icon": "las la-list-ol" + }, + { + "function_call": "create_directory(directory_name, path=\"/\")", + "name": "Create FTP directory", + "description": "Create a FTP directory. Note that sufficient permissions are present", + "parameters": [ + { + "name": " directory_name", + "description": " Name of the new directory, should be a string e.g. 'my_directory'\n" + }, + { + "name": " path", + "description": " Path to parent directory where to make new directory. Default is main directory\n" + } + ], + "return": " Boolean if creation was succesful (True) or failed (False)\n", + "example": ">>> # This example uses the Rebex FPT test server.\n>>> # Trying to create a directory will most likely fail due to permission\n>>> ftp = FTP('test.rebex.net', 'demo', 'password')\n>>> # Create directory\n>>> ftp.create_directory('brand_new_directory') \nFalse\n", + "snippet": "# This example uses the Rebex FPT test server.\n# Trying to create a directory will most likely fail due to permission\nftp = FTP('test.rebex.net', 'demo', 'password')\n# Create directory\nftp.create_directory('brand_new_directory') \n", + "keywords": [ + "FTP", + "create", + "create folder", + "new", + "new folder", + "fptfile transfer protocol", + "filezilla", + "winscp", + "server", + "remote", + "folder", + "folders" + ], + "icon": "las la-folder-plus" + } + ] + }, + { + "name": "Keyboard", + "icon": "las la-keyboard", + "activities": [ + { + "function_call": "press_key(key=None)", + "name": "Press key", + "description": "Press and release an entered key. Make sure your keyboard is on US layout (standard QWERTY).If you are using this on Mac Os you might need to grant acces to your terminal application. (Security Preferences > Security & Privacy > Privacy > Accessibility)", + "parameters": [ + { + "name": " key", + "description": " Key to press\n" + } + ], + "return": " Keypress\n", + "example": ">>> # Open notepad to illustrate typing\n>>> run('notepad.exe')\n>>> # Press some keys\n>>> press_key('a')\n>>> press_key('enter')\n>>> press_key('b')\n>>> press_key('enter')\n>>> press_key('c')\n", + "snippet": "# Open notepad to illustrate typing\nrun('notepad.exe')\n# Press some keys\npress_key('a')\npress_key('enter')\npress_key('b')\npress_key('enter')\npress_key('c')\n", + "keywords": [ + "keyboard", + "typing", + "type", + "key", + "keystroke", + "hotkey", + "press", + "press key" + ], + "icon": "las la-keyboard" + }, + { + "function_call": "press_key_combination(first_key, second_key, third_key=None, force_pyautogui=False)", + "name": "Press key combination", + "description": "Press a combination of two or three keys simultaneously. Make sure your keyboard is on US layout (standard QWERTY).", + "parameters": [ + { + "name": " first_key", + "description": " First key to press\n" + }, + { + "name": " second_key", + "description": " Second key to press\n" + }, + { + "name": " third_key", + "description": " Third key to press, this is optional.\n" + }, + { + "name": " force_pyautogui", + "description": " Set parameter to true to force the use of pyautogui. This could help when certain keypresses do not work correctly.\n" + } + ], + "return": " Key combination\n", + "example": ">>> # Open notepad to illustrate typing\n>>> run('notepad.exe')\n>>> # Press 'ctrl + s' to prompt save window \n>>> press_key_combination('ctrl', 's')\n", + "snippet": "# Open notepad to illustrate typing\nrun('notepad.exe')\n# Press 'ctrl + s' to prompt save window \npress_key_combination('ctrl', 's')\n", + "keywords": [ + "keyboard", + "key combination", + "shortcut", + "typing", + "type", + "key", + "keystroke", + "hotkey", + "press", + "press key" + ], + "icon": "las la-keyboard" + }, + { + "function_call": "type_text(text='', interval_seconds=0.01)", + "name": "Type text", + "description": "Types text in the current active field by simulating keyboard typing. Make sure your keyboard is on US layout (standard QWERTY).", + "parameters": [ + { + "name": " text", + "description": " Text in string format to type. Note that you can only press single character keys. Special keys like \":\", \"F1\",... can not be part of the text argument.\n" + }, + { + "name": " interval_seconds", + "description": " Time in seconds between two keystrokes. Defautl value is 0.01 seconds.\n" + } + ], + "return": " Keystrokes\n", + "example": ">>> # Open notepad to illustrate typing\n>>> run('notepad.exe')\n>>> # Type a story\n>>> type_text('Why was the robot mad? \\n They kept pushing his buttons!')\n", + "snippet": "# Open notepad to illustrate typing\nrun('notepad.exe')\n# Type a story\ntype_text('Why was the robot mad? \\n They kept pushing his buttons!')\n", + "keywords": [ + "keyboard", + "keystrokes", + "key combination", + "shortcut", + "typing", + "type", + "key", + "keystroke", + "hotkey", + "press", + "press key" + ], + "icon": "las la-keyboard" + } + ] + }, + { + "name": "Mouse", + "icon": "las la-mouse-pointer", + "activities": [ + { + "function_call": "get_mouse_position(delay=None, to_clipboard=False)", + "name": "Get mouse coordinates", + "description": "Get the x and y pixel coordinates of current mouse position.These coordinates represent the absolute pixel position of the mouse on the computer screen. The x-co\u00f6rdinate starts on the left side and increases going right. The y-co\u00f6rdinate increases going down.", + "parameters": [ + { + "name": " delay", + "description": " Delay in seconds before capturing mouse position.\n" + }, + { + "name": " to_clipboard", + "description": " Put the coordinates in the clipboard e.g. 'x=1, y=1'\n" + } + ], + "return": " Tuple with (x, y) coordinates\n", + "example": ">>> get_mouse_position()\n(314, 271)\n", + "snippet": "get_mouse_position()\n", + "keywords": [ + "mouse", + "mouse automation", + "click", + "right click", + "mouse button", + "move mouse", + "position", + "pixel" + ], + "icon": "las la-mouse" + }, + { + "function_call": "display_mouse_position(duration=10)", + "name": "Display mouse position", + "description": "Displays mouse position in an overlay. Refreshes every two seconds. Can be used to find mouse position of element on the screen.These coordinates represent the absolute pixel position of the mouse on the computer screen. The x-co\u00f6rdinate starts on the left side and increases going right. The y-co\u00f6rdinate increases going down.", + "parameters": [ + { + "name": " duration", + "description": " Duration to show overlay.\n" + } + ], + "return": " Overlay with (x, y) coordinates\n", + "example": ">>> display_mouse_position()\n", + "snippet": "display_mouse_position()\n", + "keywords": [ + "mouse", + "osd", + "overlay", + "show", + "display", + "mouse automation", + "click", + "right click", + "mouse button", + "move mouse", + "position", + "pixel" + ], + "icon": "lars la-search-location" + }, + { + "function_call": "click(x=None, y=None)", + "name": "Mouse click", + "description": "Clicks on a pixel position on the visible screen determined by x and y coordinates.", + "parameters": [ + { + "name": " x", + "description": " X-co\u00f6rdinate\n" + }, + { + "name": " y", + "description": " Y-co\u00f6rdinate\n" + } + ], + "return": " Mouse click on (x, y) coordinates\n", + "example": ">>> click(x=100, y=100)\n", + "snippet": "click(x=100, y=100)\n", + "keywords": [ + "mouse", + "osd", + "overlay", + "show", + "display", + "mouse automation", + "click", + "right click", + "mouse button", + "move mouse", + "position", + "pixel" + ], + "icon": "las la-mouse-pointer" + }, + { + "function_call": "double_click(x=None, y=None)", + "name": "Double mouse click", + "description": "Double clicks on a pixel position on the visible screen determined by x and y coordinates.", + "parameters": [ + { + "name": " x", + "description": " X-co\u00f6rdinate\n" + }, + { + "name": " y", + "description": " Y-co\u00f6rdinate\n" + } + ], + "return": " Double mouse click on (x, y) coordinates\n", + "example": ">>> double_click(x=100, y=100)\n", + "snippet": "double_click(x=100, y=100)\n", + "keywords": [ + "mouse", + "osd", + "overlay", + "double", + "double click", + "doubleclick show", + "display", + "mouse automation", + "click", + "right click", + "mouse button", + "move mouse", + "position", + "pixel" + ], + "icon": "las la-mouse-pointer" + }, + { + "function_call": "right_click(x=None, y=None)", + "name": "Right click", + "description": "Right clicks on a pixel position on the visible screen determined by x and y coordinates.", + "parameters": [ + { + "name": " x", + "description": " X-co\u00f6rdinate\n" + }, + { + "name": " y", + "description": " Y-co\u00f6rdinate\n" + } + ], + "return": " Right mouse click on (x, y) coordinates\n", + "example": ">>> right_click(x=100, y=100)\n", + "snippet": "right_click(x=100, y=100)\n", + "keywords": [ + "mouse", + "osd", + "right click", + "right", + "rightclick", + "overlay", + "show", + "display", + "mouse automation", + "click", + "right click", + "mouse button", + "move mouse", + "position", + "pixel" + ], + "icon": "las la-mouse-pointer" + }, + { + "function_call": "move_mouse_to(x=None, y=None)", + "name": "Move mouse", + "description": "Moves te pointer to a x-y position.", + "parameters": [ + { + "name": " x", + "description": " X-co\u00f6rdinate\n" + }, + { + "name": " y", + "description": " Y-co\u00f6rdinate\n" + } + ], + "return": " Move mouse to (x, y) coordinates\n", + "example": ">>> move_mouse_to(x=100, y=100)\n", + "snippet": "move_mouse_to(x=100, y=100)\n", + "keywords": [ + "mouse", + "osd", + "move mouse", + "right click", + "right", + "rightclick", + "overlay", + "show", + "display", + "mouse automation", + "click", + "right click", + "mouse button", + "move mouse", + "position", + "pixel" + ], + "icon": "las la-arrows-alt" + }, + { + "function_call": "move_mouse_relative(x=None, y=None)", + "name": "Move mouse relative", + "description": "Moves the mouse an x- and y- distance relative to its current pixel position.", + "parameters": [ + { + "name": " x", + "description": " X-co\u00f6rdinate\n" + }, + { + "name": " y", + "description": " Y-co\u00f6rdinate\n" + } + ], + "return": " Move mouse (x, y) coordinates\n", + "example": ">>> move_mouse_to(x=100, y=100)\n>>> wait(1)\n>>> move_mouse_relative(x=10, y=10)\n", + "snippet": "move_mouse_to(x=100, y=100)\nwait(1)\nmove_mouse_relative(x=10, y=10)\n", + "keywords": [ + "mouse", + "osd", + "move mouse", + "right click", + "right", + "rightclick", + "overlay", + "show", + "display", + "mouse automation", + "click", + "right click", + "mouse button", + "move mouse", + "position", + "pixel" + ], + "icon": "las la-arrows-alt" + }, + { + "function_call": "drag_mouse_to(x=None, y=None, button=\"left\")", + "name": "Drag mouse", + "description": "Drag the mouse from its current position to a entered x-y position, while holding a specified button.", + "parameters": [ + { + "name": " x", + "description": " X-co\u00f6rdinate\n" + }, + { + "name": " y", + "description": " Y-co\u00f6rdinate\n" + }, + { + "name": " button", + "description": " Button to hold while dragging. Options are 'left', 'middle' and 'right'. Standard value is 'left'.\n" + } + ], + "return": " Drag mouse (x, y) coordinates\n", + "example": ">>> move_mouse_to(x=100, y=100)\n>>> drag_mouse_to(x=1, y=1)\n", + "snippet": "move_mouse_to(x=100, y=100)\ndrag_mouse_to(x=1, y=1)\n", + "keywords": [ + "mouse", + "osd", + "move mouse", + "right click", + "right", + "rightclick", + "overlay", + "show", + "display", + "mouse automation", + "click", + "right click", + "mouse button", + "move mouse", + "position", + "pixel" + ], + "icon": "las la-arrows-alt" + } + ] + }, + { + "name": "Image", + "icon": "las la-image", + "activities": [ + { + "function_call": "random_screen_snippet(size=100, path=None)", + "name": "Random screen snippet", + "description": "Take a random square snippet from the current screen. Mainly for testing and/or development purposes.", + "parameters": [ + { + "name": " size", + "description": " Size (width and height) in pixels for square snippet. Default value is 100 pixels\n" + }, + { + "name": " path", + "description": " Path where snippet will be saved. Default value is home directory with name 'random_screensnippet.jpg'\n" + } + ], + "return": " Path to snippet\n", + "example": ">>> random_screen_snippet()\n'C:\\\\Users\\\\\\\\random_screensnippet.jpg'\n", + "snippet": "random_screen_snippet()\n", + "keywords": [ + "image", + "random", + "testing", + "screengrab", + "snippet" + ], + "icon": "las la-crop-alt" + }, + { + "function_call": "take_screenshot(path=None)", + "name": "Screenshot", + "description": "Take a screenshot of current screen.", + "parameters": [ + { + "name": " path", + "description": " Path to save screenshot. Default value is home directory with name 'screenshot.jpg'.\n" + } + ], + "return": " Path to screenshot\n", + "example": ">>> take_screenshot\n'C:\\\\Users\\\\\\\\screenshot.jpg'\n", + "snippet": "take_screenshot\n", + "keywords": [ + "image", + "screenshot", + "printscreen," + ], + "icon": "las la-expand" + }, + { + "function_call": "click_image(filename=None)", + "name": "Click on image", + "description": "This function searches the screen for a match with template image and clicks directly in the middle. Note that this only finds exact matches.For a more advanced and robust vision detection method see Automagica AI functionality.", + "parameters": [ + { + "name": " filename", + "description": " Path to the template image.\n" + } + ], + "return": " True if image was found and clicked on. False if template image was not found.\n", + "example": ">>> # Create a random snippet from current screen\n>>> # This is for illustration and can be replaced by template\n>>> snippet = random_screen_snippet(size=10)\n>>> # Click on the snippet\n>>> click_image(snippet)\n", + "snippet": "# Create a random snippet from current screen\n# This is for illustration and can be replaced by template\nsnippet = random_screen_snippet(size=10)\n# Click on the snippet\nclick_image(snippet)\n", + "keywords": [ + "image matching", + "matching", + "vision", + "button", + "click", + "template", + "template matching." + ], + "icon": "las la-image" + }, + { + "function_call": "double_click_image(filename=None)", + "name": "Double click image", + "description": "Double click on similar image on the screen. This function searches the screen for a match with template image and doubleclicks directly in the middle.Note that this only finds exact matches. For a more advanced and robust vision detection method see Automagica AI functionality.", + "parameters": [ + { + "name": " filename", + "description": " Path to the template image.\n" + } + ], + "return": " True if image was found and double clicked on. False if template image was not found.\n", + "example": ">>> # Create a random snippet from current screen\n>>> # This is for illustration and can be replaced by template\n>>> snippet = random_screen_snippet(size=10)\n>>> # Click on the snippet\n>>> double_click_image(snippet)\n", + "snippet": "# Create a random snippet from current screen\n# This is for illustration and can be replaced by template\nsnippet = random_screen_snippet(size=10)\n# Click on the snippet\ndouble_click_image(snippet)\n", + "keywords": [ + "image matching", + "matching", + "vision", + "button", + "double click", + "template", + "template matching,click" + ], + "icon": "las la-image" + }, + { + "function_call": "right_click_image(filename=None)", + "name": "Right click image", + "description": "Right click on similar image on the screen. This function searches the screen for a match with template image and right clicks directly in the middle.Note that this only finds exact matches. For a more advanced and robust vision detection method see Automagica AI functionality.", + "parameters": [], + "return": " True if image was found and right clicked on. False if template image was not found.\n", + "example": ">>> # Create a random snippet from current screen\n>>> # This is for illustration and can be replaced by template\n>>> snippet = random_screen_snippet(size=10)\n>>> # Click on the snippet\n>>> right_click_image(snippet)\n", + "snippet": "# Create a random snippet from current screen\n# This is for illustration and can be replaced by template\nsnippet = random_screen_snippet(size=10)\n# Click on the snippet\nright_click_image(snippet)\n", + "keywords": [ + "image matching", + "matching", + "vision", + "button", + "right click", + "template", + "template matching", + "click" + ], + "icon": "las la-image" + }, + { + "function_call": "locate_image_on_screen(filename=None)", + "name": "Locate image on screen", + "description": "Find exact image on the screen. This function searches the screen for a match with template image and clicks directly in the middle.Note that this only finds exact matches. For a more advanced and robust vision detection method see Automagica AI functionality.", + "parameters": [ + { + "name": " filename", + "description": " Path to the template image.\n" + } + ], + "return": " Tuple with (x, y) coordinates if image is found. None if image was not found\n", + "example": ">>> # Create a random snippet from current screen\n>>> # This is for illustration and can be replaced by template\n>>> snippet = random_screen_snippet(size=10)\n>>> # Click on the snippet\n>>> locate_image_on_screen(snippet)\n", + "snippet": "# Create a random snippet from current screen\n# This is for illustration and can be replaced by template\nsnippet = random_screen_snippet(size=10)\n# Click on the snippet\nlocate_image_on_screen(snippet)\n", + "keywords": [ + "image matching", + "matching", + "vision", + "button", + "right click", + "template", + "template matching", + "click" + ], + "icon": "las la-image" + } + ] + }, + { + "name": "Folder Operations", + "icon": "las la-folder-open", + "activities": [ + { + "function_call": "get_files_in_folder(path=None, extension=None, show_full_path=True, scan_subfolders=False)", + "name": "List files in folder", + "description": "List all files in a folder (and subfolders)Checks all folders and subfolders for files. This could take some time for large repositories.", + "parameters": [ + { + "name": " path", + "description": " Path of the folder to retreive files from. Default folder is the home directory.\n" + }, + { + "name": " extension", + "description": " Optional filter on certain extensions, for example 'pptx', 'exe,' xlsx', 'txt', .. Default value is no filter.\n" + }, + { + "name": " show_full_path", + "description": " Set this to True to show full path, False will only show file or dirname. Default is True\n" + } + ], + "return": " List of files with their full path\n", + "example": ">>> # List all files in the homedirectory\n>>> get_files_in_folder()\n['C:\\\\Users\\\\\\\\file1.jpg', 'C:\\\\Users\\\\\\\\file2.txt', ... ]\n", + "snippet": "# List all files in the homedirectory\nget_files_in_folder()\n", + "keywords": [ + "folder", + "files", + "explorer", + "nautilus", + "folder", + "file", + "create folder", + "get files", + "list files", + "all files", + "overview", + "get files" + ], + "icon": "las la-search" + }, + { + "function_call": "create_folder(path=None)", + "name": "Create folder", + "description": "Creates new folder at the given path.", + "parameters": [ + { + "name": " path", + "description": " Full path of folder that will be created. If no path is specified a folder called 'new_folder' will be made in home directory. If this folder already exists 8 random characters will be added to the name.\n" + } + ], + "return": " Path to new folder as string\n", + "example": ">>> # Create folder in the home directory\n>>> create_folder()\n'C:\\\\Users\\\\\\\\new_folder'\n", + "snippet": "# Create folder in the home directory\ncreate_folder()\n", + "keywords": [ + "create folder", + "folder", + "folders", + "make folder", + "new folder", + "folder manipulation", + "explorer", + "nautilus" + ], + "icon": "las la-folder-plus" + }, + { + "function_call": "rename_folder(input_path, new_name=None)", + "name": "Rename folder", + "description": "Rename a folder", + "parameters": [ + { + "name": " path", + "description": " Full path of folder that will be renamed\n" + }, + { + "name": " new_name", + "description": " New name of the folder e.g. 'new_folder'. By default folder will be renamed to original folder name with '_renamed' added to the folder name.\n" + } + ], + "return": " Path to renamed folder as a string. None if folder could not be renamed.\n", + "example": ">>> # Make new folder in home directory for illustration\n>>> testfolder = create_folder()\n>>> # Rename the folder\n>>> rename_folder(testfolder, new_name='testfolder_brand_new_name')\n'C:\\\\Users\\\\\\\\testfolder_brand_new_name'\n", + "snippet": "# Make new folder in home directory for illustration\ntestfolder = create_folder()\n# Rename the folder\nrename_folder(testfolder, new_name='testfolder_brand_new_name')\n", + "keywords": [ + "folder", + "rename", + "rename folder", + "organise folder", + "folders", + "folder manipulation", + "explorer", + "nautilus" + ], + "icon": "las la-folder" + }, + { + "function_call": "show_folder(path=None)", + "name": "Open a folder", + "description": "Open a folder with the default explorer.", + "parameters": [ + { + "name": " path", + "description": " Full path of folder that will be opened. Default value is the home directory\n" + } + ], + "return": " Path to opend folder as a string\n", + "example": ">>> # Make new folder in home directory for illustration\n>>> testfolder = create_folder()\n>>> # Open folder\n>>> show_folder(testfolder)\n'C:\\\\Users\\\\\\\\new_folder'\n", + "snippet": "# Make new folder in home directory for illustration\ntestfolder = create_folder()\n# Open folder\nshow_folder(testfolder)\n", + "keywords": [ + "folder", + "open", + "open folder", + "explorer", + "nautilus" + ], + "icon": "las la-folder-open" + }, + { + "function_call": "move_folder(from_path, to_path)", + "name": "Move a folder", + "description": "Moves a folder from one place to another.If the new location already contains a folder with the same name, a random 4 character uid is added to the name.", + "parameters": [ + { + "name": " fom_path", + "description": " Full path to the source location of the folder\n" + }, + { + "name": " new_path", + "description": " Full path to the destination location of the folder.\n" + } + ], + "return": " Path to new location of folder as a string. None if folder could not be moved.\n", + "example": ">>> # Make new folder in home directory for illustration\n>>> # If no new_folder exists in home dir this will be called new_folder\n>>> testfolder = create_folder()\n>>> # Make a second new folder\n>>> # Since new_folder already exists this folder will get a random id added (in this case abc1)\n>>> testfolder_2 = create_folder()\n>>> # Move testfolder in testfolder_2\n>>> move_folder(testfolder, testfolder_2)\n'C:\\\\Users\\\\\\\\new_folder_abc1\\\\new_folder'\n", + "snippet": "# Make new folder in home directory for illustration\n# If no new_folder exists in home dir this will be called new_folder\ntestfolder = create_folder()\n# Make a second new folder\n# Since new_folder already exists this folder will get a random id added (in this case abc1)\ntestfolder_2 = create_folder()\n# Move testfolder in testfolder_2\nmove_folder(testfolder, testfolder_2)\n", + "keywords": [ + "folder", + "move", + "move folder", + "explorer", + "nautilus", + "folder manipulation" + ], + "icon": "las la-folder" + }, + { + "function_call": "remove_folder(path, allow_root=False, delete_read_only=True)", + "name": "Remove folder", + "description": "Remove a folder including all subfolders and files. For the function to work optimal, all files and subfolders in the main targetfolder should be closed.", + "parameters": [ + { + "name": " path", + "description": " Full path to the folder that will be deleted\n" + }, + { + "name": " allow_root", + "description": " Allow paths with an arbitrary length of 10 characters or shorter to be deleted. Default value is False.\n" + } + ], + "return": " Path to deleted folder as a string\n", + "example": ">>> # Make new folder in home directory for illustration\n>>> testfolder = create_folder()\n>>> # Check if folder exists\n>>> print( folder_exists(testfolder) ) # Should print True\n>>> # Remove folder\n>>> remove_folder(testfolder)\n>>> # Check again if folder exists\n>>> folder_exists(testfolder)\nFalse\n", + "snippet": "# Make new folder in home directory for illustration\ntestfolder = create_folder()\n# Check if folder exists\nprint( folder_exists(testfolder) ) # Should print True\n# Remove folder\nremove_folder(testfolder)\n# Check again if folder exists\nfolder_exists(testfolder)\n", + "keywords": [ + "folder", + "delete folder", + "delete", + "nautilus", + "folder manipulation", + "explorer", + "delete folder", + "remove", + "remove folder" + ], + "icon": "las la-folder-minus" + }, + { + "function_call": "empty_folder(path, allow_root=False)", + "name": "Empty folder", + "description": "Remove all contents from a folderFor the function to work optimal, all files and subfolders in the main targetfolder should be closed.", + "parameters": [ + { + "name": " path", + "description": " Full path to the folder that will be emptied\n" + }, + { + "name": " allow_root", + "description": " Allow paths with an arbitrary length of 10 characters or shorter to be emptied. Default value is False.\n" + } + ], + "return": "", + "example": ">>> # Make new folder in home directory for illustration\n>>> testfolder = create_folder()\n>>> # Make new textfile in this folder\n>>> import os\n>>> textfile_location = os.path.join(testfolder, 'testfile.txt')\n>>> make_textfile(output_path=textfile_location )\n>>> # Print all files in the testfolder\n>>> print( get_files_in_folder(testfolder) ) # Should show \n>>> # Empty the folder\n>>> empty_folder(testfolder)\n>>> # Check what is in the folder\n>>> get_files_in_folder(testfolder)\n[]\n", + "snippet": "# Make new folder in home directory for illustration\ntestfolder = create_folder()\n# Make new textfile in this folder\nimport os\ntextfile_location = os.path.join(testfolder, 'testfile.txt')\nmake_textfile(output_path=textfile_location )\n# Print all files in the testfolder\nprint( get_files_in_folder(testfolder) ) # Should show \n# Empty the folder\nempty_folder(testfolder)\n# Check what is in the folder\nget_files_in_folder(testfolder)\n", + "keywords": [ + "folder", + "empty folder", + "delete", + "empty", + "clean", + "clean folder", + "nautilus", + "folder manipulation", + "explorer", + "delete folder", + "remove", + "remove folder" + ], + "icon": "las la-folder-minus" + }, + { + "function_call": "folder_exists(path)", + "name": "Checks if folder exists", + "description": "Check whether folder exists or not, regardless if folder is empty or not.", + "parameters": [ + { + "name": " path", + "description": " Full path to folder\n" + } + ], + "return": " Boolean\n", + "example": ">>> # Make new folder in home directory for illustration\n>>> testfolder = create_folder()\n>>> # Check if folder exists\n>>> folder_exists(testfolder)\nTrue\n", + "snippet": "# Make new folder in home directory for illustration\ntestfolder = create_folder()\n# Check if folder exists\nfolder_exists(testfolder)\n", + "keywords": [ + "folder", + "folder exists", + "nautilus", + "explorer", + "folder manipulation", + "files" + ], + "icon": "las la-folder" + }, + { + "function_call": "copy_folder(from_path, to_path=None)", + "name": "Copy a folder", + "description": "Copies a folder from one place to another.If the new location already contains a folder with the same name, a random 4 character id is added to the name.", + "parameters": [ + { + "name": " old_path", + "description": " Full path to the source location of the folder\n" + }, + { + "name": " new_path", + "description": " Full path to the destination location of the folder. If no path is specified folder will get copied in the from_path directory\n" + } + ], + "return": " Path to new folder as string\n", + "example": ">>> # Make new folder in home directory for illustration\n>>> testfolder = create_folder()\n>>> # Copy this folder\n>>> # Since new_folder already exists in home dir this folder will get a random id added (in this case abc1)\n>>> copy_folder(testfolder)\n", + "snippet": "# Make new folder in home directory for illustration\ntestfolder = create_folder()\n# Copy this folder\n# Since new_folder already exists in home dir this folder will get a random id added (in this case abc1)\ncopy_folder(testfolder)\n", + "keywords": [ + "folder", + "move", + "move folder", + "explorer", + "nautilus", + "folder manipulation" + ], + "icon": "lar la-folder" + }, + { + "function_call": "zip_folder(path, new_path=None)", + "name": "Zip", + "description": "Zia folder and it's contents. Creates a .zip file.", + "parameters": [ + { + "name": " path", + "description": " Full path to the source location of the folder that will be zipped\n" + }, + { + "name": " new_path", + "description": " Full path to save the zipped folder. If no path is specified a folder with the original folder name plus 4 random characters\n" + } + ], + "return": " Path to zipped folder\n", + "example": ">>> # Make new folder in home directory for illustration\n>>> testfolder = create_folder()\n>>> # Zip this folder\n>>> zip_folder(testfolder)\n", + "snippet": "# Make new folder in home directory for illustration\ntestfolder = create_folder()\n# Zip this folder\nzip_folder(testfolder)\n", + "keywords": [ + "zip", + "zipping", + "winrar", + "rar", + "7zip", + "compress", + "unzip" + ], + "icon": "las la-archive" + }, + { + "function_call": "unzip(path, to_path=None)", + "name": "Unzip", + "description": "Unzips a file or folder from a .zip file.", + "parameters": [ + { + "name": " path", + "description": " Full path to the source location of the file or folder that will be unzipped\n" + }, + { + "name": " to_path", + "description": " Full path to save unzipped contents. If no path is specified the unzipped contents will be stored in the same directory as the zipped file is located. \n" + } + ], + "return": " Path to unzipped folder\n", + "example": ">>> # Make new folder in home directory for illustration\n>>> testfolder = create_folder()\n>>> # Zip this folder\n>>> zipped_folder = zip_folder(testfolder)\n>>> # Unzip this folder\n>>> unzip(zipped_folder)\n", + "snippet": "# Make new folder in home directory for illustration\ntestfolder = create_folder()\n# Zip this folder\nzipped_folder = zip_folder(testfolder)\n# Unzip this folder\nunzip(zipped_folder)\n", + "keywords": [ + "zip", + "zipping", + "winrar", + "rar", + "7zip", + "compress", + "unzip" + ], + "icon": "las la-archive" + } + ] + }, + { + "name": "Delay", + "icon": "las la-hourglass", + "activities": [ + { + "function_call": "wait(seconds=1)", + "name": "Wait", + "description": "Make the robot wait for a specified number of seconds. Note that this activity is blocking. This means that subsequent activities will not occur until the the specified waiting time has expired.", + "parameters": [ + { + "name": " seconds", + "description": " Time in seconds to wait\n" + } + ], + "return": "", + "example": ">>> print('Start the wait')\n>>> wait()\n>>> print('The wait is over')\n", + "snippet": "print('Start the wait')\nwait()\nprint('The wait is over')\n", + "keywords": [ + "wait", + "sleep", + "time", + "timeout", + "time-out", + "hold", + "pause" + ], + "icon": "las la-hourglass" + }, + { + "function_call": "wait_for_image(path=None, timeout=60)", + "name": "Wait for image", + "description": "Waits for an image to appear on the screenNote that this activity waits for an exact match of the template image to appear on the screen.Small variations, such as color or resolution could result in a mismatch.", + "parameters": [ + { + "name": " path", + "description": " Full or relative path to the template image.\n" + }, + { + "name": " timeout", + "description": " Maximum time in seconds to wait before continuing. Default value is 60 seconds.\n" + } + ], + "return": "", + "example": ">>> # Create a random snippet from current screen\n>>> # This is for illustration and can be replaced by template\n>>> snippet = random_screen_snippet(size=10)\n>>> # Wait for the snippet to be visible\n>>> wait_for_image(snippet)\n", + "snippet": "# Create a random snippet from current screen\n# This is for illustration and can be replaced by template\nsnippet = random_screen_snippet(size=10)\n# Wait for the snippet to be visible\nwait_for_image(snippet)\n", + "keywords": [ + "image matching", + "wait", + "pause", + "vision", + "template", + "template matching" + ], + "icon": "las la-hourglass" + }, + { + "function_call": "wait_folder_exists(path, timeout=60)", + "name": "Wait for folder", + "description": "Waits until a folder exists.Not that this activity is blocking and will keep the system waiting.", + "parameters": [ + { + "name": " path", + "description": " Full path to folder.\n" + }, + { + "name": " timeout", + "description": " Maximum time in seconds to wait before continuing. Default value is 60 seconds.\n" + } + ], + "return": "", + "example": ">>> # Create a random folder\n>>> testfolder = create_folder()\n>>> # Wait for the snippet to be visible\n>>> wait_folder_exists(testfolder)\n", + "snippet": "# Create a random folder\ntestfolder = create_folder()\n# Wait for the snippet to be visible\nwait_folder_exists(testfolder)\n", + "keywords": [ + "image matching", + "wait", + "pause", + "vision", + "template", + "template matching" + ], + "icon": "las la-hourglass" + } + ] + }, + { + "name": "Word Application", + "icon": "las la-file-word", + "activities": [ + { + "function_call": "Word(visible=True, file_path=None)", + "name": "Start Word Application", + "description": "For this activity to work, Microsoft Office Word needs to be installed on the system.", + "parameters": [ + { + "name": " visible", + "description": " Show Word in the foreground if True or hide if False, defaults to True.\n" + }, + { + "name": " path", + "description": " Enter a path to open Word with an existing Word file. If no path is specified a document will be initialized, this is the default value.\n" + } + ], + "return": " Application object (win32com.client)\n", + "example": ">>> word = Word()\n", + "snippet": "word = Word()\n", + "keywords": [ + "word", + "editor", + "text", + "text edit", + "office", + "document", + "microsoft word", + "doc", + "docx" + ], + "icon": "lar la-file-word" + }, + { + "function_call": "append_text(text)", + "name": "Append text", + "description": "Append text at end of Word document.", + "parameters": [ + { + "name": " text", + "description": " Text to append to document\n" + } + ], + "return": "", + "example": ">>> # Start Word\n>>> word = Word()\n>>> word.append_text('This is sample text')\n", + "snippet": "# Start Word\nword = Word()\nword.append_text('This is sample text')\n", + "keywords": [ + "word", + "editor", + "text", + "text edit", + "office", + "document", + "microsoft word", + "doc", + "docx" + ], + "icon": "lar la-file-word" + }, + { + "function_call": "replace_text(placeholder_text, replacement_text)", + "name": "Replace text", + "description": "Can be used for example to replace arbitrary placeholder value. For example whenusing template document, using 'XXXX' as a placeholder. Take note that all strings are case sensitive.", + "parameters": [ + { + "name": " placeholder_text", + "description": " Placeholder text value (string) in the document, this will be replaced, e.g. 'Company Name'\n" + }, + { + "name": " replacement_text", + "description": " Text (string) to replace the placeholder values with. It is recommended to make this unique to avoid wrongful replacement, e.g. 'XXXX_placeholder_XXX'\n" + } + ], + "return": "", + "example": ">>> # Start Word\n>>> word = Word()\n>>> word.append_text('This is sample text')\n>>> word.replace_text('sample', 'real')\n", + "snippet": "# Start Word\nword = Word()\nword.append_text('This is sample text')\nword.replace_text('sample', 'real')\n", + "keywords": [ + "word", + "replace", + "text", + "template" + ], + "icon": "lar la-file-word" + }, + { + "function_call": "read_all_text(return_as_list=False)", + "name": "Read all text", + "description": "Read all the text from a document", + "parameters": [ + { + "name": " return_as_list", + "description": " Set this paramater to True to return text as a list of strings. Default value is False.\n" + } + ], + "return": " Text from the document\n", + "example": ">>> # Start Word\n>>> word = Word()\n>>> word.append_text('This is sample text')\n>>> word.replace_text('sample', 'real')\n>>> word.read_all_text()\n'This is real text'\n", + "snippet": "# Start Word\nword = Word()\nword.append_text('This is sample text')\nword.replace_text('sample', 'real')\nword.read_all_text()\n", + "keywords": [ + "word", + "extract", + "text", + "document" + ], + "icon": "lar la-file-word" + }, + { + "function_call": "export_to_pdf(path=None)", + "name": "Export to PDF", + "description": "Export the document to PDF", + "parameters": [ + { + "name": " path", + "description": " Output path where PDF file will be exported to. Default path is home directory with filename 'pdf_export.pdf'.\n" + } + ], + "return": "", + "example": ">>> # Start Word\n>>> word = Word()\n>>> word.append_text('This is sample text')\n>>> word.replace_text('sample', 'real')\n>>> word.export_to_pdf('output.pdf')\n", + "snippet": "# Start Word\nword = Word()\nword.append_text('This is sample text')\nword.replace_text('sample', 'real')\nword.export_to_pdf('output.pdf')\n", + "keywords": [ + "word", + "pdf", + "document", + "export", + "save as" + ], + "icon": "lar la-file-pdf" + }, + { + "function_call": "export_to_html(path=None)", + "name": "Export to HTML", + "description": "Export to HTML", + "parameters": [ + { + "name": " path", + "description": " Output path where HTML file will be exported to. Default path is home directory with filename 'html_export.html'.\n" + } + ], + "return": "", + "example": ">>> # Start Word\n>>> word = Word()\n>>> word.append_text('This is sample text')\n>>> word.replace_text('sample', 'real')\n>>> word.export_to_html('output.html')\n", + "snippet": "# Start Word\nword = Word()\nword.append_text('This is sample text')\nword.replace_text('sample', 'real')\nword.export_to_html('output.html')\n", + "keywords": [ + "word", + "html", + "document", + "export", + "save as" + ], + "icon": "las la-html5" + }, + { + "function_call": "set_footers(text)", + "name": "Set footers", + "description": "Set the footers of the document", + "parameters": [ + { + "name": " text", + "description": " Text to put in the footer\n" + } + ], + "return": "", + "example": ">>> # Start Word\n>>> word = Word()\n>>> word.set_footers('This is a footer!')\n", + "snippet": "# Start Word\nword = Word()\nword.set_footers('This is a footer!')\n", + "keywords": [ + "word", + "footer", + "footers" + ], + "icon": "las la-heading" + }, + { + "function_call": "set_headers(text)", + "name": "Set headers", + "description": "Set the headers of the document", + "parameters": [ + { + "name": " text", + "description": " Text to put in the header\n" + } + ], + "return": "", + "example": ">>> # Start Word\n>>> word = Word()\n>>> word.set_headers('This is a header!')\n", + "snippet": "# Start Word\nword = Word()\nword.set_headers('This is a header!')\n", + "keywords": [ + "word", + "header", + "headers" + ], + "icon": "las la-subscript" + } + ] + }, + { + "name": "Word File", + "icon": "las la-file-word", + "activities": [ + { + "function_call": "WordFile(file_path=None)", + "name": "Read and Write Word files", + "description": "These activities can read, write and edit Word (docx) files without the need of having Word installed.Note that, in contrary to working with the :func: 'Word' activities, a file get saved directly after manipulation.", + "parameters": [ + { + "name": " file_path", + "description": " Enter a path to open Word with an existing Word file. If no path is specified a 'document.docx' will be initialized in the home directory, this is the default value. If a document with the same name already exists the file will be overwritten.\n" + } + ], + "return": "", + "example": ">>> wordfile = WordFile()\n>>> wordfile.append_text('Some sample text')\n>>> wordfile.read_all_text()\n'Some sample text'\n", + "snippet": "wordfile = WordFile()\nwordfile.append_text('Some sample text')\nwordfile.read_all_text()\n", + "keywords": [ + "word", + "read", + "text", + "file" + ], + "icon": "las la-file-word" + }, + { + "function_call": "read_all_text(return_as_list=False)", + "name": "Read all text", + "description": "Read all the text from the document", + "parameters": [ + { + "name": " return_as_list", + "description": " Set this paramater to True to return text as a list of strings. Default value is False.\n" + } + ], + "return": " Text of the document\n", + "example": ">>> wordfile = WordFile()\n>>> wordfile.append_text('Some sample text')\n>>> wordfile.read_all_text()\n'Some sample text'\n", + "snippet": "wordfile = WordFile()\nwordfile.append_text('Some sample text')\nwordfile.read_all_text()\n", + "keywords": [ + "word", + "read", + "text", + "file" + ], + "icon": "las la-file-word" + }, + { + "function_call": "append_text(text, auto_save=True)", + "name": "Append text", + "description": "Append text at the end of the document", + "parameters": [ + { + "name": " text", + "description": " Text to append\n" + }, + { + "name": " auto_save", + "description": " Save document after performing activity. Default value is True\n" + } + ], + "return": "", + "example": ">>> wordfile = WordFile()\n>>> wordfile.append_text('Some sample text')\n", + "snippet": "wordfile = WordFile()\nwordfile.append_text('Some sample text')\n", + "keywords": [ + "word", + "append text", + "add text" + ], + "icon": "las la-file-word" + }, + { + "function_call": "save(self)", + "name": "Save", + "description": "Save document", + "parameters": [], + "return": "", + "example": ">>> wordfile = WordFile()\n>>> wordfile.append_text('Some sample text')\n>>> wordfile.save()\n", + "snippet": "wordfile = WordFile()\nwordfile.append_text('Some sample text')\nwordfile.save()\n", + "keywords": [ + "word", + "save", + "store" + ], + "icon": "las la-file-word" + }, + { + "function_call": "save_as(path)", + "name": "Save as", + "description": ":Example:", + "parameters": [], + "return": "", + "example": ">>> wordfile = WordFile()\n>>> wordfile.append_text('Some sample text')\n>>> wordfile.save_as('document.docx')\n", + "snippet": "wordfile = WordFile()\nwordfile.append_text('Some sample text')\nwordfile.save_as('document.docx')\n", + "keywords": [ + "word", + "save as", + "store" + ], + "icon": "las la-file-word" + }, + { + "function_call": "set_headers(text, auto_save=True)", + "name": "Set headers", + "description": "Set headers of Word document", + "parameters": [ + { + "name": " text", + "description": " Text to put in the header\n" + }, + { + "name": " auto_save", + "description": " Save document after performing activity. Default value is True\n" + } + ], + "return": "", + "example": ">>> wordfile = WordFile()\n>>> wordfile.append_text('Some sample text')\n>>> wordfile.set_headers('This is a header')\n", + "snippet": "wordfile = WordFile()\nwordfile.append_text('Some sample text')\nwordfile.set_headers('This is a header')\n", + "keywords": [ + "word", + "header text" + ], + "icon": "las la-file-word" + }, + { + "function_call": "replace_text(placeholder_text, replacement_text, auto_save=True)", + "name": "Replace all", + "description": "Replaces all occurences of a placeholder text in the document with a replacement text.", + "parameters": [ + { + "name": " placeholder_text", + "description": " Placeholder text value (string) in the document, this will be replaced, e.g. 'Company Name'\n" + }, + { + "name": " replacement_text", + "description": " Text (string) to replace the placeholder values with. It is recommended to make this unique to avoid wrongful replacement, e.g. 'XXXX_placeholder_XXX'\n" + }, + { + "name": " auto_save", + "description": " Save document after performing activity. Default value is True\n" + } + ], + "return": "", + "example": ">>> wordfile = WordFile()\n>>> wordfile.append_text('Some sample text')\n>>> wordfile.replace_text('sample', 'real')\n", + "snippet": "wordfile = WordFile()\nwordfile.append_text('Some sample text')\nwordfile.replace_text('sample', 'real')\n", + "keywords": [ + "word", + "replace text", + "template" + ], + "icon": "las la-file-word" + } + ] + }, + { + "name": "Outlook Application", + "icon": "las la-envelope", + "activities": [ + { + "function_call": "Outlook(account_name=None)", + "name": "Start Outlook Application", + "description": "For this activity to work, Outlook needs to be installed on the system.", + "parameters": [], + "return": " Application object (win32com.client)\n", + "example": ">>> outlook = Outlook()\n", + "snippet": "outlook = Outlook()\n", + "keywords": [ + "outlook", + "send e-mail", + "send mail" + ], + "icon": "las la-mail-bulk" + }, + { + "function_call": "send_mail(to_address, subject=\"\", body=\"\", html_body=None, attachment_paths=None)", + "name": "Send e-mail", + "description": "Send an e-mail using Outlook", + "parameters": [ + { + "name": " to_address", + "description": " The e-mail address the e-mail should be sent to\n" + }, + { + "name": " subject", + "description": " The subject of the e-mail\n" + }, + { + "name": " body", + "description": " The text body contents of the e-mail\n" + }, + { + "name": " html_body", + "description": " The HTML body contents of the e-mail (optional)\n" + }, + { + "name": " attachment_paths", + "description": " List of file paths to attachments\n" + } + ], + "return": "", + "example": ">>> outlook = Outlook()\n>>> outlook.send_mail('test@test.com', subject='Hello world', body='Hi there')\n", + "snippet": "outlook = Outlook()\noutlook.send_mail('test@test.com', subject='Hello world', body='Hi there')\n", + "keywords": [ + "outlook", + "send e-mail", + "send mail" + ], + "icon": "las la-mail-bulk" + }, + { + "function_call": "get_folders(limit=999)", + "name": "Retrieve folders", + "description": "Retrieve list of folders from Outlook", + "parameters": [ + { + "name": " limit", + "description": " Maximum number of folders to retrieve\n" + } + ], + "return": "", + "example": ">>> outlook = Outlook()\n>>> outlook.get_folders()\n['Inbox', 'Sent', ...]\n", + "snippet": "outlook = Outlook()\noutlook.get_folders()\n", + "keywords": [ + "outlook", + "get folders", + "list folders" + ], + "icon": "las la-mail-bulk" + }, + { + "function_call": "get_mails(folder_name=\"Inbox\", fields=None)", + "name": "Retrieve e-mails", + "description": "Retrieve list of messages from Outlook", + "parameters": [ + { + "name": " folder_name", + "description": " Name of the Outlook folder, can be found using `get_folders`.\n" + }, + { + "name": " limit", + "description": " Number of messages to retrieve\n" + }, + { + "name": " fields", + "description": " Fields (properties) of e-mail messages to give, requires tupl Stadard is 'Subject', 'Body', 'SentOn' and 'SenderEmailAddress'.\n" + } + ], + "return": " List of dictionaries containing the e-mail messages with from, to, subject, body and html.\n", + "example": ">>> outlook = Outlook()\n>>> outlook.get_mails()\n[\n {\n 'Subject': 'Hello World!',\n 'Body' : 'This is an e-mail',\n 'SenderEmailAddress': 'from@test.com'\n }\n]\n", + "snippet": "outlook = Outlook()\noutlook.get_mails()\n {\n 'Subject': 'Hello World!',\n 'Body' : 'This is an e-mail',\n 'SenderEmailAddress': 'from@test.com'\n }\n", + "keywords": [ + "outlook", + "retrieve e-mail", + "receive e-mails", + "process e-mails", + "get mails" + ], + "icon": "las la-mail-bulk" + }, + { + "function_call": "delete_mails(self,folder_name=\"Inbox\",limit=0,subject_contains=\"\",body_contains=\"\",sender_contains=\"\")", + "name": "Delete e-mails", + "description": "Deletes e-mail messages in a certain folder. Can be specified by searching on subject, body or sender e-mail.", + "parameters": [ + { + "name": " folder_name", + "description": " Name of the Outlook folder, can be found using `get_folders`\n" + }, + { + "name": " limit", + "description": " Maximum number of e-mails to delete in one go\n" + }, + { + "name": " subject_contains", + "description": " Only delete e-mail if subject contains this\n" + }, + { + "name": " body_contains", + "description": " Only delete e-mail if body contains this\n" + }, + { + "name": " sender_contains", + "description": " Only delete e-mail if sender contains this\n" + } + ], + "return": "", + "example": ">>> outlook = Outlook()\n>>> outlook.delete_mails(subject_contains='hello')\n", + "snippet": "outlook = Outlook()\noutlook.delete_mails(subject_contains='hello')\n", + "keywords": [ + "outlook", + "remove e-mails", + "delete mail", + "remove mail" + ], + "icon": "las la-mail-bulk" + }, + { + "function_call": "move_mails(self,source_folder_name=\"Inbox\",target_folder_name=\"Archive\",limit=0,subject_contains=\"\",body_contains=\"\",sender_contains=\"\")", + "name": "Move e-mails", + "description": "Move e-mail messages in a certain folder. Can be specified by searching on subject, body or sender e-mail.", + "parameters": [ + { + "name": " source_folder_name", + "description": " Name of the Outlook source folder from where e-mails will be moved, can be found using `get_folders`\n" + }, + { + "name": " target_folder_name", + "description": " Name of the Outlook destination folder to where e-mails will be moved, can be found using `get_folders`\n" + }, + { + "name": " limit", + "description": " Maximum number of e-mails to move in one go\n" + }, + { + "name": " subject_contains", + "description": " Only move e-mail if subject contains this\n" + }, + { + "name": " body_contains", + "description": " Only move e-mail if body contains this\n" + }, + { + "name": " sender_contains", + "description": " Only move e-mail if sender contains this\n" + } + ], + "return": "", + "example": ">>> outlook = Outlook()\n>>> outlook.move_mails(subject_contains='move me')\n", + "snippet": "outlook = Outlook()\noutlook.move_mails(subject_contains='move me')\n", + "keywords": [ + "outlook", + "move e-mail", + "move e-mail to folder" + ], + "icon": "las la-mail-bulk" + }, + { + "function_call": "save_attachments(folder_name=\"Inbox\", target_folder_path=None)", + "name": "Save attachments", + "description": ":parameter folder_name: Name of the Outlook folder, can be found using `get_folders`.:parameter target_folder_path: Path where attachments will be saved. Default is the home directory.", + "parameters": [ + { + "name": " folder_name", + "description": " Name of the Outlook folder, can be found using `get_folders`.\n" + }, + { + "name": " target_folder_path", + "description": " Path where attachments will be saved. Default is the home directory.\n" + } + ], + "return": " List of paths to saved attachments.\n", + "example": ">>> outlook = Outlook()\n>>> outlook.save_attachments()\n['Attachment.pdf', 'Signature_image.jpeg']\n", + "snippet": "outlook = Outlook()\noutlook.save_attachments()\n", + "keywords": [ + "outlook", + "save attachments", + "download attachments", + "extract attachments" + ], + "icon": "las la-mail-bulk" + }, + { + "function_call": "get_contacts(fields=None)", + "name": "Retrieve contacts", + "description": ":parameter fields: Fields can be specified as a tuple with their exact names. Standard value is None returning \"LastName\", \"FirstName\" and \"Email1Address\".", + "parameters": [ + { + "name": " fields", + "description": " Fields can be specified as a tuple with their exact names. Standard value is None returning \"LastName\", \"FirstName\" and \"Email1Address\".\n" + } + ], + "return": " List of dictionaries containing the contact details.\n", + "example": ">>> outlook = Outlook()\n>>> outlook.get_contacts()\n[\n {\n 'LastName': 'Doe',\n 'FirstName' : 'John',\n 'Email1Address': 'john@test.com'\n }\n]\n", + "snippet": "outlook = Outlook()\noutlook.get_contacts()\n {\n 'LastName': 'Doe',\n 'FirstName' : 'John',\n 'Email1Address': 'john@test.com'\n }\n", + "keywords": [ + "outlook", + "get contacts", + "download contacts", + "rolodex" + ], + "icon": "las la-mail-bulk" + }, + { + "function_call": "add_contact(email, first_name=\"\", last_name=\"\")", + "name": "Add a contact", + "description": "Add a contact to Outlook contacts", + "parameters": [ + { + "name": " email", + "description": " The e-mail address for the contact\n" + }, + { + "name": " first_name", + "description": " First name for the contact (optional)\n" + }, + { + "name": " last_name", + "description": " Last name for the contact (optional)\n" + } + ], + "return": "", + "example": ">>> outlook = Outlook()\n>>> outlook.add_contact('sales@automagica.com')\n", + "snippet": "outlook = Outlook()\noutlook.add_contact('sales@automagica.com')\n", + "keywords": [ + "outlook", + "create contact", + "add contact" + ], + "icon": "las la-mail-bulk" + }, + { + "function_call": "quit(self)", + "name": "Quit", + "description": "Close the Outlook application", + "parameters": [], + "return": "", + "example": ">>> outlook = Outlook()\n>>> outlook.quit()\n", + "snippet": "outlook = Outlook()\noutlook.quit()\n", + "keywords": [ + "outlook", + "close", + "quit" + ], + "icon": "las la-mail-bulk" + } + ] + }, + { + "name": "Excel Application", + "icon": "las la-file-excel", + "activities": [ + { + "function_call": "Excel(visible=True, file_path=None)", + "name": "Start Excel Application", + "description": "For this activity to work, Microsoft Office Excel needs to be installed on the system.", + "parameters": [ + { + "name": " visible", + "description": " Show Excel in the foreground if True or hide if False, defaults to True.\n" + }, + { + "name": " path", + "description": " Enter a path to open Excel with an existing Excel file. If no path is specified a workbook will be initialized, this is the default value.\n" + } + ], + "return": " Application object (win32com.client)\n", + "example": ">>> # Open Excel\n>>> excel = Excel()\n", + "snippet": "# Open Excel\nexcel = Excel()\n", + "keywords": [ + "excel", + "add worksheet", + "add tab" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "add_worksheet(name=None)", + "name": "Add worksheet", + "description": "Adds a worksheet to the current workbook", + "parameters": [ + { + "name": " workbook", + "description": " Workbook object which is retrieved with either new_workbook or open_workbook\n" + } + ], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Add a worksheet\n>>> excel.add_worksheet('My Example Worksheet')\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Add a worksheet\nexcel.add_worksheet('My Example Worksheet')\n", + "keywords": [ + "excel", + "add worksheet", + "add tab", + "insert worksheet", + "new worksheet" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "activate_worksheet(name)", + "name": "Activate worksheet", + "description": "Activate a worksheet in the current Excel document by name", + "parameters": [ + { + "name": " name", + "description": " Name of the worksheet to activate\n" + } + ], + "return": "", + "example": ">>> # Open Excel \n>>> excel = Excel()\n>>> # Add the first worksheet\n>>> excel.add_worksheet('My Example Worksheet')\n>>> # Add another worksheet\n>>> excel.add_worksheet('Another Worksheet')\n>>> # Activate the first worksheet\n>>> excel.activate_worksheet('My Example Worksheet)\n", + "snippet": "# Open Excel \nexcel = Excel()\n# Add the first worksheet\nexcel.add_worksheet('My Example Worksheet')\n# Add another worksheet\nexcel.add_worksheet('Another Worksheet')\n# Activate the first worksheet\nexcel.activate_worksheet('My Example Worksheet)\n", + "keywords": [ + "excel", + "activate worksheet", + "set worksheet", + "select worksheet", + "select tab", + "activate tab" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "save(self)", + "name": "Save", + "description": "Save the current workbook", + "parameters": [], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Add the first worksheet\n>>> excel.add_worksheet('My Example Worksheet')\n>>> # Save the workbook to My Documents\n>>> excel.save()\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Add the first worksheet\nexcel.add_worksheet('My Example Worksheet')\n# Save the workbook to My Documents\nexcel.save()\n", + "keywords": [ + "excel", + "save", + "store" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "save_as(path)", + "name": "Save as", + "description": "Save the current workbook to a specific path", + "parameters": [ + { + "name": " path", + "description": " Path where workbook will be saved. Default is home directory and filename 'workbook.xlsx'\n" + } + ], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Add the first worksheet\n>>> excel.add_worksheet('My Example Worksheet')\n>>> # Save the workbook to the current working directory\n>>> excel.save_as('output.xlsx')\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Add the first worksheet\nexcel.add_worksheet('My Example Worksheet')\n# Save the workbook to the current working directory\nexcel.save_as('output.xlsx')\n", + "keywords": [ + "excel", + "save as", + "export" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "write_cell(column, row, value)", + "name": "Write cell", + "description": "Write to a specific cell in the currently active workbook and active worksheet", + "parameters": [ + { + "name": " column", + "description": " Column number (integer) to write\n" + }, + { + "name": " row", + "description": " Row number (integer) to write\n" + }, + { + "name": " value", + "description": " Value to write to specific cell\n" + } + ], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Add the first worksheet\n>>> excel.add_worksheet('My Example Worksheet')\n>>> # Insert a text into the first cell\n>>> excel.write_cell(1,1, 'Hello World!')\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Add the first worksheet\nexcel.add_worksheet('My Example Worksheet')\n# Insert a text into the first cell\nexcel.write_cell(1,1, 'Hello World!')\n", + "keywords": [ + "excel", + "cell", + "insert cell", + "insert data" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "read_cell(column, row)", + "name": "Read cell", + "description": "Read a cell from the currently active workbook and active worksheet", + "parameters": [ + { + "name": " column", + "description": " Column number (integer) to read\n" + }, + { + "name": " row", + "description": " Row number (integer) to read\n" + } + ], + "return": " Cell value\n", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Add the first worksheet\n>>> excel.add_worksheet('My Example Worksheet')\n>>> # Insert a text into the first cell\n>>> excel.write_cell(1,1, 'Hello World!')\n>>> excel.read_cell(1,1)\n'Hello World!'\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Add the first worksheet\nexcel.add_worksheet('My Example Worksheet')\n# Insert a text into the first cell\nexcel.write_cell(1,1, 'Hello World!')\nexcel.read_cell(1,1)\n", + "keywords": [ + "excel", + "cell", + "read cell", + "read data" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "write_range(range_, value)", + "name": "Write range", + "description": "Write to a specific range in the currently active worksheet in the active workbook", + "parameters": [ + { + "name": " range_", + "description": " Range to write to, e.g. \"A1:D10\"\n" + }, + { + "name": " value", + "description": " Value to write to range\n" + } + ], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Add the first worksheet\n>>> excel.add_worksheet('My Example Worksheet')\n>>> # Insert a text in every cell in this range\n>>> excel.write_range('A1:D5', 'Hello World!')\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Add the first worksheet\nexcel.add_worksheet('My Example Worksheet')\n# Insert a text in every cell in this range\nexcel.write_range('A1:D5', 'Hello World!')\n", + "keywords": [ + "excel", + "cell", + "write range", + "read data" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "read_range(range_)", + "name": "Read range", + "description": "Read a range of cells from the currently active worksheet in the active workbook", + "parameters": [ + { + "name": " range_", + "description": " Range to read from, e.g. \"A1:D10\"\n" + } + ], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Add the first worksheet\n>>> excel.add_worksheet('My Example Worksheet')\n>>> # Insert a text in every cell in this range\n>>> excel.write_range('A1:D5', 'Hello World!')\n>>> # Read the same range\n>>> excel.read_range('A1:D5')\n[['Hello World', 'Hello World', 'Hello World', 'Hello World'], ...]\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Add the first worksheet\nexcel.add_worksheet('My Example Worksheet')\n# Insert a text in every cell in this range\nexcel.write_range('A1:D5', 'Hello World!')\n# Read the same range\nexcel.read_range('A1:D5')\n", + "keywords": [ + "excel", + "cell", + "read range", + "read data" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "run_macro(name)", + "name": "Run macro", + "description": "Run a macro by name from the currently active workbook", + "parameters": [ + { + "name": " name", + "description": " Name of the macro to run. \n" + } + ], + "return": "", + "example": ">>> excel = Excel('excel_with_macro.xlsx')\n>>> # Run the macro\n>>> excel.run_macro('Macro1')\n", + "snippet": "excel = Excel('excel_with_macro.xlsx')\n# Run the macro\nexcel.run_macro('Macro1')\n", + "keywords": [ + "excel", + "run macro", + "run vba" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "get_worksheet_names(self)", + "name": "Get worksheet names", + "description": "Get names of all the worksheets in the currently active workbook", + "parameters": [], + "return": " List is worksheet names\n", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Add a worksheet\n>>> excel.add_worksheet('My Example Worksheet')\n>>> # Get all worksheet names\n>>> excel.get_worksheet_names()\n['Sheet1', 'My Example Worksheet']\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Add a worksheet\nexcel.add_worksheet('My Example Worksheet')\n# Get all worksheet names\nexcel.get_worksheet_names()\n", + "keywords": [ + "excel", + "worksheet names", + "tab names" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "get_table(name)", + "name": "Get table", + "description": "Get table data from the currently active worksheet by name of the table", + "parameters": [ + { + "name": " name", + "description": " List of table names\n" + } + ], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Create a table (Table1)\n>>> data = [\n {\n 'Column A': 'Data Row 1 for A',\n 'Column B': 'Data Row 1 for B',\n 'Column C': 'Data Row 1 for C',\n },\n {\n 'Column A': 'Data Row 2 for A',\n 'Column B': 'Data Row 2 for B',\n 'Column C': 'Data Row 2 for C',\n }]\n>>> excel.insert_data_as_table(data)\n>>> # Get the table\n>>> excel.get_table('Table1')\n[['Column A', 'Column B', 'Column C'], ['Row 1 A Data', 'Row 1 B Data', 'Row 1 C Data'], ...]\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Create a table (Table1)\ndata = [\n {\n 'Column A': 'Data Row 1 for A',\n 'Column B': 'Data Row 1 for B',\n 'Column C': 'Data Row 1 for C',\n },\n {\n 'Column A': 'Data Row 2 for A',\n 'Column B': 'Data Row 2 for B',\n 'Column C': 'Data Row 2 for C',\n }]\nexcel.insert_data_as_table(data)\n# Get the table\nexcel.get_table('Table1')\n", + "keywords": [ + "excel", + "worksheet names", + "tab names" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "activate_range(range_)", + "name": "Activate range", + "description": "Activate a particular range in the currently active workbook", + "parameters": [ + { + "name": " range_", + "description": " Range to activate, e.g. \"A1:D10\"\n" + } + ], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Activate a cell range\n>>> excel.activate_range('A1:D5')\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Activate a cell range\nexcel.activate_range('A1:D5')\n", + "keywords": [ + "excel", + "activate range", + "make selection", + "select cells", + "select range" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "activate_first_empty_cell_down(self)", + "name": "Activate first empty cell down", + "description": "Activates the first empty cell going down", + "parameters": [], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Write some cells\n>>> excel.write_cell(1, 1, 'Filled')\n>>> excel.write_cell(1, 2, 'Filled')\n>>> excel.write_cell(1, 3, 'Filled')\n>>> # Activate the first empty cell going down, in this case cell A4 or (1,4)\n>>> excel.activate_first_empty_cell_down()\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Write some cells\nexcel.write_cell(1, 1, 'Filled')\nexcel.write_cell(1, 2, 'Filled')\nexcel.write_cell(1, 3, 'Filled')\n# Activate the first empty cell going down, in this case cell A4 or (1,4)\nexcel.activate_first_empty_cell_down()\n", + "keywords": [ + "excel", + "first empty cell", + "down" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "activate_first_empty_cell_right(self)", + "name": "Activate first empty cell right", + "description": "Activates the first empty cell going right", + "parameters": [], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Write some cells\n>>> excel.write_cell(1, 1, 'Filled')\n>>> excel.write_cell(1, 2, 'Filled')\n>>> excel.write_cell(1, 3, 'Filled')\n>>> # Activate the first empty cell going right, in this case cell B1 or (2,1)\n>>> excel.activate_first_empty_cell_right()\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Write some cells\nexcel.write_cell(1, 1, 'Filled')\nexcel.write_cell(1, 2, 'Filled')\nexcel.write_cell(1, 3, 'Filled')\n# Activate the first empty cell going right, in this case cell B1 or (2,1)\nexcel.activate_first_empty_cell_right()\n", + "keywords": [ + "excel", + "first empty cell", + "right" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "activate_first_empty_cell_left(self)", + "name": "Activate first empty cell left", + "description": "Activates the first empty cell going left", + "parameters": [], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> excel.write_cell(1, 1, 'Filled')\n>>> excel.write_cell(1, 2, 'Filled')\n>>> excel.write_cell(1, 3, 'Filled')\n>>> excel.activate_first_empty_cell_left()\n", + "snippet": "# Open Excel\nexcel = Excel()\nexcel.write_cell(1, 1, 'Filled')\nexcel.write_cell(1, 2, 'Filled')\nexcel.write_cell(1, 3, 'Filled')\nexcel.activate_first_empty_cell_left()\n", + "keywords": [ + "excel", + "first empty cell", + "left" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "activate_first_empty_cell_up(self)", + "name": "Activate first empty cell up", + "description": "Activates the first empty cell going up", + "parameters": [], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Write some cells\n>>> excel.write_cell(1, 1, 'Filled')\n>>> excel.write_cell(1, 2, 'Filled')\n>>> excel.write_cell(1, 3, 'Filled')\n>>> # Activate first empty cell\n>>> excel.activate_first_empty_cell_up()\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Write some cells\nexcel.write_cell(1, 1, 'Filled')\nexcel.write_cell(1, 2, 'Filled')\nexcel.write_cell(1, 3, 'Filled')\n# Activate first empty cell\nexcel.activate_first_empty_cell_up()\n", + "keywords": [ + "excel", + "first empty cell", + "up" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "write_cell_formula(column, row, formula)", + "name": "Write cell formula", + "description": "Write a formula to a particular cell", + "parameters": [ + { + "name": " column", + "description": " Column number (integer) to write formula\n" + }, + { + "name": " row", + "description": " Row number (integer) to write formula\n" + }, + { + "name": " value", + "description": " Formula to write to specific cell e.g. \"=10*RAND()\"\n" + } + ], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Write a formula to the first cell\n>>> excel.write_cell_formula(1, 1, '=1+1)\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Write a formula to the first cell\nexcel.write_cell_formula(1, 1, '=1+1)\n", + "keywords": [ + "excel", + "insert formula", + "insert calculation", + "insert calculated cell" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "read_cell_formula(column, row, formula)", + "name": "Read cell formula", + "description": "Read the formula from a particular cell", + "parameters": [ + { + "name": " column", + "description": " Column number (integer) to read formula\n" + }, + { + "name": " row", + "description": " Row number (integer) to read formula\n" + } + ], + "return": " Cell value\n", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> # Write a formula to the first cell\n>>> excel.write_cell_formula(1, 1, '=1+1)\n>>> # Read the cell\n>>> excel.read_cell_formula(1, 1)\n'=1+1'\n", + "snippet": "# Open Excel\nexcel = Excel()\n# Write a formula to the first cell\nexcel.write_cell_formula(1, 1, '=1+1)\n# Read the cell\nexcel.read_cell_formula(1, 1)\n", + "keywords": [ + "excel", + "read formula", + "read calculation" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "insert_empty_row(row)", + "name": "Insert empty row", + "description": "Inserts an empty row to the currently active worksheet", + "parameters": [ + { + "name": " row", + "description": " Row number (integer) where to insert empty row e.g 1\n" + } + ], + "return": "", + "example": ">>> # Open Excel \n>>> excel = Excel()\n>>> excel.write_cell(1, 1, 'Filled')\n>>> excel.write_cell(1, 2, 'Filled')\n>>> excel.write_cell(1, 3, 'Filled')\n>>> excel.insert_empty_row(2)\n", + "snippet": "# Open Excel \nexcel = Excel()\nexcel.write_cell(1, 1, 'Filled')\nexcel.write_cell(1, 2, 'Filled')\nexcel.write_cell(1, 3, 'Filled')\nexcel.insert_empty_row(2)\n", + "keywords": [ + "excel", + "insert row", + "add row", + "empty row" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "insert_empty_column(column)", + "name": "Insert empty column", + "description": "Inserts an empty column in the currently active worksheet. Existing columns will shift to the right.", + "parameters": [ + { + "name": " column", + "description": " Column letter (string) where to insert empty column e.g. 'A'\n" + } + ], + "return": "", + "example": ">>> # Open Excel\n>>> excel = Excel()\n>>> excel.write_cell(1, 1, 'Filled')\n>>> excel.write_cell(2, 2, 'Filled')\n>>> excel.write_cell(3, 3, 'Filled')\n>>> excel.insert_empty_column(2)\n", + "snippet": "# Open Excel\nexcel = Excel()\nexcel.write_cell(1, 1, 'Filled')\nexcel.write_cell(2, 2, 'Filled')\nexcel.write_cell(3, 3, 'Filled')\nexcel.insert_empty_column(2)\n", + "keywords": [ + "excel", + "insert column", + "add column" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "delete_row(row)", + "name": "Delete row in Excel", + "description": "Deletes a row from the currently active worksheet. Existing data will shift up.", + "parameters": [ + { + "name": " row", + "description": " Row number (integer) where to delete row e.g 1\n" + } + ], + "return": "", + "example": ">>> # Open Excel \n>>> excel = Excel()\n>>> excel.write_cell(1, 1, 'Filled')\n>>> excel.write_cell(2, 2, 'Filled')\n>>> excel.write_cell(3, 3, 'Filled')\n>>> excel.delete_row(2)\n", + "snippet": "# Open Excel \nexcel = Excel()\nexcel.write_cell(1, 1, 'Filled')\nexcel.write_cell(2, 2, 'Filled')\nexcel.write_cell(3, 3, 'Filled')\nexcel.delete_row(2)\n", + "keywords": [ + "excel", + "delete row", + "remove row" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "delete_column(range_)", + "name": "Delete column", + "description": "Delet a column from the currently active worksheet. Existing columns will shift to the left.", + "parameters": [ + { + "name": " column", + "description": " Column letter (string) where to delete column e.g. 'A'\n" + } + ], + "return": "", + "example": ">>> # Open Excel \n>>> excel = Excel()\n>>> excel.write_cell(1, 1, 'Filled')\n>>> excel.write_cell(2, 2, 'Filled')\n>>> excel.write_cell(3, 3, 'Filled')\n>>> excel.delete_column(2)\n", + "snippet": "# Open Excel \nexcel = Excel()\nexcel.write_cell(1, 1, 'Filled')\nexcel.write_cell(2, 2, 'Filled')\nexcel.write_cell(3, 3, 'Filled')\nexcel.delete_column(2)\n", + "keywords": [ + "excel", + "delete column", + "remove column" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "export_to_pdf(path=None)", + "name": "Export to PDF", + "description": ":parameter path: Output path where PDF file will be exported to. Default path is home directory with filename 'pdf_export.pdf'.", + "parameters": [ + { + "name": " path", + "description": " Output path where PDF file will be exported to. Default path is home directory with filename 'pdf_export.pdf'.\n" + } + ], + "return": "", + "example": ">>> # Open Excel \n>>> excel = Excel()\n>>> excel.write_cell(1, 1, 'Filled')\n>>> excel.write_cell(2, 2, 'Filled')\n>>> excel.write_cell(3, 3, 'Filled')\n>>> excel.export_to_pdf('output.pdf')\n", + "snippet": "# Open Excel \nexcel = Excel()\nexcel.write_cell(1, 1, 'Filled')\nexcel.write_cell(2, 2, 'Filled')\nexcel.write_cell(3, 3, 'Filled')\nexcel.export_to_pdf('output.pdf')\n", + "keywords": [ + "excel", + "save as pdf", + "export to pdf", + "export as pdf" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "insert_data_as_table(data, range_='A1', table_style=\"TableStyleMedium2\")", + "name": "Insert data as table", + "description": "Insert list of dictionaries as a table in Excel", + "parameters": [ + { + "name": " data", + "description": " List of dictionaries to write as table\n" + }, + { + "name": " range_", + "description": " Range or startingpoint for table e.g. 'A1'\n" + } + ], + "return": "", + "example": ">>> excel = Excel()\n>>> data = [\n {\n 'Column A': 'Data Row 1 for A',\n 'Column B': 'Data Row 1 for B',\n 'Column C': 'Data Row 1 for C',\n },\n {\n 'Column A': 'Data Row 2 for A',\n 'Column B': 'Data Row 2 for B',\n 'Column C': 'Data Row 2 for C',\n }\n>>> excel.insert_data_as_table(data)\n", + "snippet": "excel = Excel()\ndata = [\n {\n 'Column A': 'Data Row 1 for A',\n 'Column B': 'Data Row 1 for B',\n 'Column C': 'Data Row 1 for C',\n },\n {\n 'Column A': 'Data Row 2 for A',\n 'Column B': 'Data Row 2 for B',\n 'Column C': 'Data Row 2 for C',\n }\nexcel.insert_data_as_table(data)\n", + "keywords": [ + "excel", + "insert data", + "insert table", + "create table" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "read_worksheet(name=None, headers=False)", + "name": "Read worksheet", + "description": "Read data from a worksheet as a list of lists", + "parameters": [ + { + "name": " name", + "description": " Optional name of worksheet to read. If no name is specified will take active sheet\n" + }, + { + "name": " headers", + "description": " Boolean to treat first row as headers. Default value is False\n" + } + ], + "return": " List of dictionaries with sheet data\n", + "example": ">>> # Open excel \n>>> excel = Excel()\n>>> Write some cells\n>>> excel.write_cell(1, 1, 'A')\n>>> excel.write_cell(1, 2, 'B')\n>>> excel.write_cell(1, 3, 'C')\n>>> excel.read_worksheet()\n[['A'],['B'],['C']]\n", + "snippet": "# Open excel \nexcel = Excel()\nWrite some cells\nexcel.write_cell(1, 1, 'A')\nexcel.write_cell(1, 2, 'B')\nexcel.write_cell(1, 3, 'C')\nexcel.read_worksheet()\n", + "keywords": [ + "excel", + "read worksheet", + "export data", + "read data" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "quit(self)", + "name": "Quit Excel", + "description": "This closes Excel, make sure to use :func: 'save' or 'save_as' if you would like to save before quitting.", + "parameters": [], + "return": "", + "example": ">>> # Open Excel \n>>> excel = Excel()\n>>> # Quit Excel\n>>> excel.quit()\n", + "snippet": "# Open Excel \nexcel = Excel()\n# Quit Excel\nexcel.quit()\n", + "keywords": [ + "excel", + "exit", + "quit", + "close" + ], + "icon": "las la-file-excel" + } + ] + }, + { + "name": "Excel File", + "icon": "las la-file-excel", + "activities": [ + { + "function_call": "ExcelFile(file_path=None)", + "name": "Read and Write xlsx files.", + "description": "This activity can read, write and edit Excel (xlsx) files without the need of having Excel installed.Note that, in contrary to working with the :func: 'Excel' activities, a file get saved directly after manipulation.", + "parameters": [ + { + "name": " file_path", + "description": " Enter a path to open Excel with an existing Excel file. If no path is specified a 'workbook.xlsx' will be initialized in the home directory, this is the default value. If a workbook with the same name already exists the file will be overwritten.\n" + } + ], + "return": "", + "example": ">>> # Open a new Excel file\n>>> excel_file = ExcelFile()\n", + "snippet": "# Open a new Excel file\nexcel_file = ExcelFile()\n", + "keywords": [ + "excel", + "open", + "start", + "xlsx" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "activate_worksheet(name)", + "name": "Activate worksheet", + "description": "Activate a worksheet. By default the first worksheet is activated.", + "parameters": [ + { + "name": " name", + "description": " Name of the worksheet to activate. \n" + } + ], + "return": "", + "example": ">>> # Open a new Excel file\n>>> excel_file = ExcelFile()\n>>> # Add some worksheets\n>>> excel_file.add_worksheet('My Example Worksheet')\n>>> excel_file.add_worksheet('Another Worksheet')\n>>> # Activate a worksheet\n>>> excel_file.active_worksheet('My Example Worksheet')\n", + "snippet": "# Open a new Excel file\nexcel_file = ExcelFile()\n# Add some worksheets\nexcel_file.add_worksheet('My Example Worksheet')\nexcel_file.add_worksheet('Another Worksheet')\n# Activate a worksheet\nexcel_file.active_worksheet('My Example Worksheet')\n", + "keywords": [ + "excel", + "activate tab", + "activate worksheet" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "save_as(path)", + "name": "Save as", + "description": ":parameter path: Path where workbook will be saved", + "parameters": [ + { + "name": " path", + "description": " Path where workbook will be saved\n" + } + ], + "return": "", + "example": ">>> # Open a new Excel file\n>>> excel_file = ExcelFile()\n>>> # Ad a worksheet\n>>> excel_file.add_worksheet('My Example Worksheet')\n>>> # Save the Excel file\n>>> excel_file.save_as('output.xlsx')\n>>> # We can also save it in the home directory by using\n>>> excel_file.save_as( home_path('output.xlsx') )\n", + "snippet": "# Open a new Excel file\nexcel_file = ExcelFile()\n# Ad a worksheet\nexcel_file.add_worksheet('My Example Worksheet')\n# Save the Excel file\nexcel_file.save_as('output.xlsx')\n# We can also save it in the home directory by using\nexcel_file.save_as( home_path('output.xlsx') )\n", + "keywords": [ + "excel", + "save as", + "export", + "save" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "write_cell(column, row, value, auto_save=True)", + "name": "Write cell", + "description": ":parameter column: Column number (integer) to write:parameter row: Row number (integer) to write:parameter value: Value to write to specific cell:parameter auto_save: Save document after performing activity. Default value is True", + "parameters": [ + { + "name": " column", + "description": " Column number (integer) to write\n" + }, + { + "name": " row", + "description": " Row number (integer) to write\n" + }, + { + "name": " value", + "description": " Value to write to specific cell\n" + }, + { + "name": " auto_save", + "description": " Save document after performing activity. Default value is True\n" + } + ], + "return": "", + "example": ">>> # Open a new Excel file\n>>> excel_file = ExcelFile()\n>>> # Add a worksheet\n>>> excel_file.add_worksheet('My Example Worksheet')\n>>> excel_file.write_cell(1, 1, 'Filled!')\n", + "snippet": "# Open a new Excel file\nexcel_file = ExcelFile()\n# Add a worksheet\nexcel_file.add_worksheet('My Example Worksheet')\nexcel_file.write_cell(1, 1, 'Filled!')\n", + "keywords": [ + "excel", + "write cell", + "insert data" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "read_cell(column, row)", + "name": "Read cell", + "description": ":parameter column: Column number (integer) to read:parameter row: Row number (integer) to read", + "parameters": [ + { + "name": " column", + "description": " Column number (integer) to read\n" + }, + { + "name": " row", + "description": " Row number (integer) to read\n" + } + ], + "return": " Cell value\n", + "example": ">>> # Open a new Excel file\n>>> excel_file = ExcelFile()\n>>> # Add a worksheet\n>>> excel_file.add_worksheet('My Example Worksheet')\n>>> # Write the first cell\n>>> excel_file.write_cell(1, 1, 'Filled!')\n>>> # Read the first cell\n>>> excel_file.read_cell(1, 1)\n'Filled!'\n", + "snippet": "# Open a new Excel file\nexcel_file = ExcelFile()\n# Add a worksheet\nexcel_file.add_worksheet('My Example Worksheet')\n# Write the first cell\nexcel_file.write_cell(1, 1, 'Filled!')\n# Read the first cell\nexcel_file.read_cell(1, 1)\n", + "keywords": [ + "excel", + "read cell", + "read" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "add_worksheet(name, auto_save=True)", + "name": "Add worksheet", + "description": ":parameter name: Name of the worksheet to add:parameter auto_save: Save document after performing activity. Default value is True", + "parameters": [ + { + "name": " name", + "description": " Name of the worksheet to add\n" + }, + { + "name": " auto_save", + "description": " Save document after performing activity. Default value is True\n" + } + ], + "return": "", + "example": ">>> # Open a new Excel file\n>>> excel_file = ExcelFile()\n>>> # Add a worksheet\n>>> excel_file.add_worksheet('My Example Worksheet')\n>>> # List all the worksheets\n>>> excel.get_worksheet_names()\n", + "snippet": "# Open a new Excel file\nexcel_file = ExcelFile()\n# Add a worksheet\nexcel_file.add_worksheet('My Example Worksheet')\n# List all the worksheets\nexcel.get_worksheet_names()\n", + "keywords": [ + "excel", + "add worksheet", + "worksheet" + ], + "icon": "las la-file-excel" + }, + { + "function_call": "get_worksheet_names(self)", + "name": "Get worksheet names", + "description": ":return: List of worksheet names", + "parameters": [], + "return": " List of worksheet names\n", + "example": ">>> # Open a new Excel file\n>>> excel_file = ExcelFile()\n>>> # Add some worksheets\n>>> excel_file.add_worksheet('My Example Worksheet')\n>>> excel_file.add_worksheet('Another Worksheet')\n>>> # Get the worksheet names\n>>> excel_file.get_worksheet_names()\n['My Example Worksheet', 'Another Worksheet']\n", + "snippet": "# Open a new Excel file\nexcel_file = ExcelFile()\n# Add some worksheets\nexcel_file.add_worksheet('My Example Worksheet')\nexcel_file.add_worksheet('Another Worksheet')\n# Get the worksheet names\nexcel_file.get_worksheet_names()\n", + "keywords": [ + "excel", + "worksheet names", + "worksheet," + ], + "icon": "las la-file-excel" + } + ] + }, + { + "name": "PowerPoint Application", + "icon": "icon: las la-file-powerpoint", + "activities": [ + { + "function_call": "PowerPoint(visible=True, path=None, add_slide=True)", + "name": "Start PowerPoint Application", + "description": "For this activity to work, PowerPoint needs to be installed on the system.", + "parameters": [ + { + "name": " visible", + "description": " Show PowerPoint in the foreground if True or hide if False, defaults to True.\n" + }, + { + "name": " path", + "description": " Enter a path to open an existing PowerPoint presentation. If no path is specified a new presentation will be initialized, this is the default value.\n" + }, + { + "name": " add_slide", + "description": " Add an initial empty slide when creating new PowerPointfile, this prevents errors since most manipulations require a non-empty presentation. Default value is True\n" + } + ], + "return": " Application object (win32com.client)\n", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n", + "keywords": [ + "powerpoint", + "ppt" + ], + "icon": "las la-file-powerpoint" + }, + { + "function_call": "save_as(path=None)", + "name": "Save PowerPoint", + "description": "Save PowerPoint Slidedeck", + "parameters": [ + { + "name": " path", + "description": " Save the PowerPoint presentation. Default value is the home directory and filename 'presentation.pptx'\n" + } + ], + "return": "", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n>>> # Add a first slide\n>>> powerpoint.add_slide()\n>>> # Save the PowerPoint presentation\n>>> powerpoint.save()\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n# Add a first slide\npowerpoint.add_slide()\n# Save the PowerPoint presentation\npowerpoint.save()\n", + "keywords": [ + "powerpoint", + "ppt", + "save", + "save as", + "save powerpoint" + ], + "icon": "las la-file-powerpoint" + }, + { + "function_call": "quit(self)", + "name": "Close PowerPoint Application", + "description": "Close PowerPoint", + "parameters": [ + { + "name": " index", + "description": " Index where the slide should be inserted. Default value is as final slide.\n" + } + ], + "return": "", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n>>> # Close PowerPoint\n>>> powerpoint.quit()\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n# Close PowerPoint\npowerpoint.quit()\n", + "keywords": [ + "powerpoint", + "ppt", + "quit", + "exit" + ], + "icon": "las la-file-powerpoint" + }, + { + "function_call": "add_slide(index=None, type='blank')", + "name": "Add PowerPoint Slides", + "description": "Adds slides to a presentation", + "parameters": [ + { + "name": " index", + "description": " Index where the slide should be inserted. Default value is as final slide.\n" + } + ], + "return": "", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n>>> # Add a first slide\n>>> powerpoint.add_slide()\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n# Add a first slide\npowerpoint.add_slide()\n", + "keywords": [ + "powerpoint", + "ppt", + "add", + "add slide powerpoint", + "slides" + ], + "icon": "las la-file-powerpoint" + }, + { + "function_call": "number_of_slides(self)", + "name": "Slide count", + "description": ":return: The number of slides", + "parameters": [], + "return": " The number of slides\n", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n>>> # Add some slides\n>>> powerpoint.add_slide()\n>>> powerpoint.add_slide()\n>>> # Show number of slides\n>>> powerpoint.number_of_slides()\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n# Add some slides\npowerpoint.add_slide()\npowerpoint.add_slide()\n# Show number of slides\npowerpoint.number_of_slides()\n", + "keywords": [ + "powerpoint", + "ppt", + "slide count", + "number of slides" + ], + "icon": "las la-file-powerpoint" + }, + { + "function_call": "add_text(text, index=None, font_size=48, font_name=None, bold=False, margin_bottom=100, margin_left=100, margin_right=100, margin_top=100)", + "name": "Text to slide", + "description": "Add text to a slide", + "parameters": [ + { + "name": " index", + "description": " Slide index to add text. If none is specified, a new slide will be added as final slide\n" + }, + { + "name": " font_size", + "description": " Fontsize, default value is 48\n" + }, + { + "name": " font_name", + "description": " Fontname, if not specified will take default PowerPoint font\n" + }, + { + "name": " bold", + "description": " Toggle bold with True or False, default value is False\n" + }, + { + "name": " margin_bottom", + "description": " Margin from the bottom in pixels, default value is 100 pixels\n" + }, + { + "name": " margin_left", + "description": " Margin from the left in pixels, default value is 100 pixels\n" + }, + { + "name": " margin_right", + "description": " Margin from the right in pixels, default value is 100 pixels\n" + }, + { + "name": " margin_top", + "description": " Margin from the top in pixels, default value is 100 pixels\n" + } + ], + "return": "", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n>>> # Add slide with text\n>>> powerpoint.add_text(text='Sample Text')\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n# Add slide with text\npowerpoint.add_text(text='Sample Text')\n", + "keywords": [ + "powerpoint", + "ppt", + "text", + "add text", + "slides" + ], + "icon": "las la-file-powerpoint" + }, + { + "function_call": "delete_slide(index=None)", + "name": "Delete slide", + "description": ":parameter index: Slide index to be deleted. If none is specified, last slide will be deleted", + "parameters": [ + { + "name": " index", + "description": " Slide index to be deleted. If none is specified, last slide will be deleted\n" + } + ], + "return": "", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n>>> # Add some slides\n>>> powerpoint.add_slide()\n>>> powerpoint.add_slide()\n>>> # Delete last slide\n>>> powerpoint.delete_slide()\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n# Add some slides\npowerpoint.add_slide()\npowerpoint.add_slide()\n# Delete last slide\npowerpoint.delete_slide()\n", + "keywords": [ + "powerpoint", + "ppt", + "delete", + "delete slide" + ], + "icon": "las la-file-powerpoint" + }, + { + "function_call": "replace_text(placeholder_text, replacement_text)", + "name": "Replace all occurences of text in PowerPoint slides", + "description": "Can be used for example to replace arbitrary placeholder value in a PowerPoint.For example when using a template slidedeck, using 'XXXX' as a placeholder.Take note that all strings are case sensitive.", + "parameters": [ + { + "name": " placeholder_text", + "description": " Placeholder value (string) in the PowerPoint, this will be replaced, e.g. 'Company Name'\n" + }, + { + "name": " replacement_text", + "description": " Text (string) to replace the placeholder values with. It is recommended to make this unique in your PowerPoint to avoid wrongful replacement, e.g. 'XXXX_placeholder_XXX'\n" + } + ], + "return": "", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n>>> # Add some slides with text\n>>> powerpoint.add_text(text='Hello, my name is placeholder')\n>>> # Change 'placeholder' to the word 'robot\n>>> powerpoint.replace_text(placeholder_text = 'placeholder', replacement_text ='robot')\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n# Add some slides with text\npowerpoint.add_text(text='Hello, my name is placeholder')\n# Change 'placeholder' to the word 'robot\npowerpoint.replace_text(placeholder_text = 'placeholder', replacement_text ='robot')\n", + "keywords": [ + "powerpoint", + "ppt", + "replace", + "placeholder" + ], + "icon": "las la-file-powerpoint" + }, + { + "function_call": "export_to_pdf(path=None)", + "name": "PowerPoint to PDF", + "description": "Export PowerPoint presentation to PDF file", + "parameters": [ + { + "name": " path", + "description": " Output path where PDF file will be exported to. Default path is home directory with filename 'pdf_export.pdf'.\n" + } + ], + "return": "", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n>>> # Add some slides with text\n>>> powerpoint.add_text(text='Robots are cool')\n>>> # Export to pdf\n>>> powerpoint.export_to_pdf()\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n# Add some slides with text\npowerpoint.add_text(text='Robots are cool')\n# Export to pdf\npowerpoint.export_to_pdf()\n", + "keywords": [ + "powerpoint", + "ppt", + "export", + "pdf" + ], + "icon": "las la-file-powerpoint" + }, + { + "function_call": "export_slides_to_images(path=None, type='png')", + "name": "Slides to images", + "description": "Export PowerPoint slides to seperate image files", + "parameters": [ + { + "name": " path", + "description": " Output path where image files will be exported to. Default path is home directory.\n" + }, + { + "name": " type", + "description": " Output type of the images, supports 'png' and 'jpg' with 'png' as default value\n" + } + ], + "return": "", + "example": ">>> # Start PowerPoint\n>>> powerpoint = PowerPoint()\n>>> # Add some slides with text\n>>> powerpoint.add_text(text='Robots are cool')\n>>> powerpoint.add_text(text='Humans are cooler')\n>>> # Export slides to images\n>>> powerpoint.export_slides_to_images()\n", + "snippet": "# Start PowerPoint\npowerpoint = PowerPoint()\n# Add some slides with text\npowerpoint.add_text(text='Robots are cool')\npowerpoint.add_text(text='Humans are cooler')\n# Export slides to images\npowerpoint.export_slides_to_images()\n", + "keywords": [ + "powerpoint", + "ppt", + "export", + "png", + "image", + "slides to image" + ], + "icon": "las la-file-powerpoint" + } + ] + }, + { + "name": "Office 365", + "icon": "las la-cloud", + "activities": [ + { + "function_call": "send_email_with_outlook365(client_id, client_secret, to_email, subject='', body='')", + "name": "Send email Office Outlook 365", + "description": ":parameter client_id: Client id for office 365 account:parameter client_secret: Client secret for office 365 account:parameter to_email: E-mail to send to:parameter subject: Optional subject:parameter body: Optional body of the email", + "parameters": [ + { + "name": " client_id", + "description": " Client id for office 365 account\n" + }, + { + "name": " client_secret", + "description": " Client secret for office 365 account\n" + }, + { + "name": " to_email", + "description": " E-mail to send to\n" + }, + { + "name": " subject", + "description": " Optional subject\n" + }, + { + "name": " body", + "description": " Optional body of the email\n" + } + ], + "return": "", + "example": ">>> # Send email to 'robot@automagica.com'\n>>> send_email_with_outlook365('SampleClientID', 'SampleClientSecret', 'robot@automagica.com')\n", + "snippet": "# Send email to 'robot@automagica.com'\nsend_email_with_outlook365('SampleClientID', 'SampleClientSecret', 'robot@automagica.com')\n", + "keywords": [ + "mail", + "office 365", + "outlook", + "email", + "e-mail" + ], + "icon": "las la-envelope" + } + ] + }, + { + "name": "Salesforce", + "icon": "lab la-salesforce", + "activities": [ + { + "function_call": "salesforce_api_call(action, key, parameters={}, method='get', data={})", + "name": "Salesforce API", + "description": "Activity to make calls to Salesforce REST API.", + "parameters": [ + { + "name": " action", + "description": " Action (the URL)\n" + }, + { + "name": " key", + "description": " Authorisation key \n" + }, + { + "name": " parameters", + "description": " URL params\n" + }, + { + "name": " method", + "description": " Method (get, post or patch)\n" + }, + { + "name": " data", + "description": " Data for POST/PATCH.\n" + } + ], + "return": " API data\n", + "example": ">>> spf_api_call('action', 'key', 'parameters')\nResponse\n", + "snippet": "spf_api_call('action', 'key', 'parameters')\n", + "keywords": [ + "salesforce" + ], + "icon": "lab la-salesforce" + } + ] + }, + { + "name": "E-mail (SMTP)", + "icon": "las la-at", + "activities": [ + { + "function_call": "send_mail_smtp(smtp_host, smtp_user, smtp_password, to_address, subject=\"\", message=\"\", port=587)", + "name": "Mail with SMTP", + "description": "This function lets you send emails with an e-mail address.", + "parameters": [ + { + "name": " smpt_host", + "description": " The host of your e-mail account. \n" + }, + { + "name": " smpt_user", + "description": " The password of your e-mail account\n" + }, + { + "name": " smpt_password", + "description": " The password of your e-mail account\n" + }, + { + "name": " to_address", + "description": " The destination is the receiving mail address. \n" + }, + { + "name": " subject", + "description": " The subject \n" + }, + { + "name": " message", + "description": " The body of the mail\n" + }, + { + "name": " port", + "description": " The port variable is standard 587. In most cases this argument can be ignored, but in some cases it needs to be changed to 465.\n" + } + ], + "return": "", + "example": ">>> send_mail_smpt('robot@automagica.com', 'SampleUser', 'SamplePassword', 'robotfriend@automagica.com')\n", + "snippet": "send_mail_smpt('robot@automagica.com', 'SampleUser', 'SamplePassword', 'robotfriend@automagica.com')\n", + "keywords": [ + "mail", + "e-mail", + "email smpt" + ], + "icon": "las la-mail-bulk" + } + ] + }, + { + "name": "Windows OS", + "icon": "icon: lab la-windows", + "activities": [ + { + "function_call": "set_user_password(username, password)", + "name": "Set Windows password", + "description": "Sets the password for a Windows user.", + "parameters": [ + { + "name": " username", + "description": " Username\n" + }, + { + "name": " password", + "description": " New password\n" + } + ], + "return": "", + "example": ">>> set_user_password('SampleUsername', 'SamplePassword')\n", + "snippet": "set_user_password('SampleUsername', 'SamplePassword')\n", + "keywords": [ + "windows", + "user", + "password", + "account" + ], + "icon": "las la-passport" + }, + { + "function_call": "validate_user_password(username, password)", + "name": "Check Windows password", + "description": "Validates a Windows user password if it is correct", + "parameters": [ + { + "name": " username", + "description": " Username\n" + }, + { + "name": " password", + "description": " New password\n" + } + ], + "return": " True if the password is correct\n", + "example": ">>> validate_user_password('SampleUsername', 'SamplePassword')\nFalse\n", + "snippet": "validate_user_password('SampleUsername', 'SamplePassword')\n", + "keywords": [ + "windows", + "user", + "password", + "account" + ], + "icon": "las la-passport" + }, + { + "function_call": "lock_windows()", + "name": "Lock Windows", + "description": "Locks Windows requiring login to continue.", + "parameters": [], + "return": "", + "example": ">>> lock_windows()\n", + "snippet": "lock_windows()\n", + "keywords": [ + "windows", + "user", + "password", + "account", + "lock", + "freeze", + "hibernate", + "sleep", + "lockescreen" + ], + "icon": "las la-user-lock" + }, + { + "function_call": "is_logged_in()", + "name": "Check if Windows logged in", + "description": "Checks if the current user is logged in and not on the lockscreen. Most automations do not work properly when the desktop is locked.", + "parameters": [], + "return": " True if the user is logged in, False if not\n", + "example": ">>> is_logged_in()\nTrue\n", + "snippet": "is_logged_in()\n", + "keywords": [ + "windows", + "login", + "logged in", + "lockscreen", + "user", + "password", + "account", + "lock", + "freeze", + "hibernate", + "sleep" + ], + "icon": "lar la-user" + }, + { + "function_call": "is_desktop_locked()", + "name": "Check if Windows is locked", + "description": "Checks if the current user is locked out and on the lockscreen. Most automations do not work properly when the desktop is locked.", + "parameters": [], + "return": " True when the lockscreen is active, False if not.\n", + "example": ">>> desktop_locked()\nTrue\n", + "snippet": "desktop_locked()\n", + "keywords": [ + "windows", + "login", + "logged in", + "lockscreen", + "user", + "password", + "account", + "lock", + "locked", + "freeze", + "hibernate", + "sleep" + ], + "icon": "las la-user" + }, + { + "function_call": "get_username()", + "name": "Get Windows username", + "description": "Get current logged in user's username", + "parameters": [], + "return": "", + "example": ">>> get_username()\n'Automagica'\n", + "snippet": "get_username()\n", + "keywords": [ + "windows", + "login", + "logged in", + "lockscreen", + "user", + "password", + "account", + "lock", + "locked", + "freeze", + "hibernate", + "sleep" + ], + "icon": "las la-user" + }, + { + "function_call": "set_to_clipboard(text)", + "name": "Set clipboard", + "description": "Set any text to the Windows clipboard.", + "parameters": [ + { + "name": " text", + "description": " Text to put in the clipboard\n" + } + ], + "return": "", + "example": ">>> # Create some sample text\n>>> sample_text = 'A robots favourite food must be computer chips'\n>>> # Set to clipboard\n>>> set_to_clipboard(sample_text)\n>>> # Print the clipboard to verify\n>>> print( get_from_clipboard() )\n", + "snippet": "# Create some sample text\nsample_text = 'A robots favourite food must be computer chips'\n# Set to clipboard\nset_to_clipboard(sample_text)\n# Print the clipboard to verify\nprint( get_from_clipboard() )\n", + "keywords": [ + "copy", + "clipboard", + "clip board", + "ctrl c", + "ctrl v", + "paste" + ], + "icon": "las la-clipboard-check" + }, + { + "function_call": "get_from_clipboard()", + "name": "Get clipboard", + "description": "Get the text currently in the Windows clipboard", + "parameters": [], + "return": " Text currently in the clipboard\n", + "example": ">>> # Create some sample text\n>>> sample_text = 'A robots favourite food must be computer chips'\n>>> # Set to clipboard\n>>> set_to_clipboard(sample_text)\n>>> # Get the clipboard to verify\n>>> get_from_clipboard()\n'A robots favourite food must be computer chips'\n", + "snippet": "# Create some sample text\nsample_text = 'A robots favourite food must be computer chips'\n# Set to clipboard\nset_to_clipboard(sample_text)\n# Get the clipboard to verify\nget_from_clipboard()\n", + "keywords": [ + "copy", + "clipboard", + "clip board", + "ctrl c", + "ctrl v", + "paste" + ], + "icon": "las la-clipboard-list" + }, + { + "function_call": "clear_clipboard()", + "name": "Empty clipboard", + "description": "Empty text from clipboard. Getting clipboard data after this should return in None", + "parameters": [], + "return": "", + "example": ">>> # Create some sample text\n>>> sample_text = 'A robots favourite food must be computer chips'\n>>> # Set to clipboard\n>>> set_to_clipboard(sample_text)\n>>> # Clear the clipboard\n>>> clear_clipboard()\n>>> # Get clipboard contents to verify\n>>> print( get_clipboard() )\nNone\n", + "snippet": "# Create some sample text\nsample_text = 'A robots favourite food must be computer chips'\n# Set to clipboard\nset_to_clipboard(sample_text)\n# Clear the clipboard\nclear_clipboard()\n# Get clipboard contents to verify\nprint( get_clipboard() )\n", + "keywords": [ + "copy", + "clipboard", + "clip board", + "ctrl c", + "ctrl v", + "paste" + ], + "icon": "las la-clipboard" + }, + { + "function_call": "run_vbs_script(script_path, parameters=[])", + "name": "Run VBSscript", + "description": "Run a VBScript file", + "parameters": [ + { + "name": " script_path", + "description": " Path to the .vbs-file\n" + }, + { + "name": " parameters", + "description": " Additional arguments to pass to the VBScript\n" + } + ], + "return": "", + "example": ">>> # Run a VBS script\n>>> run_vbs_script('Samplescript.vbs')\n", + "snippet": "# Run a VBS script\nrun_vbs_script('Samplescript.vbs')\n", + "keywords": [ + "vbs", + "VBScript" + ], + "icon": "las la-cogs" + }, + { + "function_call": "beep(frequency=1000, duration=500)", + "name": "Beep", + "description": "Make a beeping sound. Make sure your volume is up and you have hardware connected.", + "parameters": [ + { + "name": " frequency", + "description": " Integer to specify frequency (Hz), default value is 1000 Hz\n" + }, + { + "name": " duration", + "description": " Integer to specify duration of beep in miliseconds (ms), default value is 500 ms.\n" + } + ], + "return": " Sound\n", + "example": ">>> beep()\n", + "snippet": "beep()\n", + "keywords": [ + "beep", + "sound", + "noise", + "speaker", + "alert" + ], + "icon": "las la-volume-up" + } + ] + }, + { + "name": "Text-to-Speech", + "icon": "las la-volume-up", + "activities": [ + { + "function_call": "speak(text, speed=None)", + "name": "Speak", + "description": "Use the Text-To-Speech engine available on your system to read text", + "parameters": [ + { + "name": " text", + "description": " The text which should be said\n" + }, + { + "name": " speed", + "description": " Multiplication factor for the speed at which the text should be pronounced. \n" + } + ], + "return": " Spoken text\n", + "example": ">>> # Read the following text out loud\n>>> speak('How do robots eat guacamole?')\n>>> speak('With microchips!')\n", + "snippet": "# Read the following text out loud\nspeak('How do robots eat guacamole?')\nspeak('With microchips!')\n", + "keywords": [ + "sound", + "speech", + "text", + "speech to text", + "speech-to-text", + "translate", + "read", + "read out loud" + ], + "icon": "las la-microphone-alt" + } + ] + }, + { + "name": "Active Directory", + "icon": "las la-user", + "activities": [ + { + "function_call": "ActiveDirectory(ldap_server=None, username=None, password=None)", + "name": "AD interface", + "description": "Interface to Windows Active Directory through ADSI", + "parameters": [], + "return": "", + "example": ">>> ad = ActiveDirectory()\n", + "snippet": "ad = ActiveDirectory()\n", + "keywords": [ + "AD", + "active directory", + "activedirectory" + ], + "icon": "las la-audio-description" + }, + { + "function_call": "get_object_by_distinguished_name(distinguished_name)", + "name": "Get AD object by name", + "description": "Interface to Windows Active Directory through ADSI", + "parameters": [], + "return": "", + "example": ">>> ad = ActiveDirectory()\n>>> ad.get_object_by_distinguished_name('SampleDN')\n", + "snippet": "ad = ActiveDirectory()\nad.get_object_by_distinguished_name('SampleDN')\n", + "keywords": [ + "AD", + "active directory", + "activedirectory" + ], + "icon": "las la-audio-description" + } + ] + }, + { + "name": "Utilities", + "icon": "icon: las la-toolbox", + "activities": [ + { + "function_call": "home_path(subdir=None)", + "name": "Get user home path", + "description": "Returns the current user's home path", + "parameters": [ + { + "name": " filename", + "description": " Optional filename to add to the path. Can also be a subdirectory\n" + } + ], + "return": " Path to the current user's home folder\n", + "example": ">>> # Home_path without arguments will return the home path\n>>> print( home_path() )\n>>> # When looking for a file in the home path, we can specify it\n>>> # First make a sample textfile\n>>> make_textfile()\n>>> # Refer to it\n>>> home_path('generated_textfile.txt')\n'C:\\\\Users\\\\\\\\generated_textfile.txt'\n", + "snippet": "# Home_path without arguments will return the home path\nprint( home_path() )\n# When looking for a file in the home path, we can specify it\n# First make a sample textfile\nmake_textfile()\n# Refer to it\nhome_path('generated_textfile.txt')\n", + "keywords": [ + "home", + "home path", + "homepath", + "home directory", + "homedir" + ], + "icon": "las la-home" + }, + { + "function_call": "desktop_path(subdir=None)", + "name": "Get desktop path", + "description": "Returns the current user's desktop path", + "parameters": [ + { + "name": " filename", + "description": " Optional filename to add to the path. Can also be a subdirectory\n" + } + ], + "return": " Path to the current user's desktop folder\n", + "example": ">>> # Desktop_path without arguments will return the home path\n>>> print( desktop_path() )\n>>> # When looking for a file on the desktop, we can specify it\n>>> # First make a sample textfile\n>>> make_textfile()\n>>> # Refer to it\n>>> desktop_path('generated_textfile.txt')\n'C:\\\\Users\\\\\\\\Desktop\\\\generated_textfile.txt'\n", + "snippet": "# Desktop_path without arguments will return the home path\nprint( desktop_path() )\n# When looking for a file on the desktop, we can specify it\n# First make a sample textfile\nmake_textfile()\n# Refer to it\ndesktop_path('generated_textfile.txt')\n", + "keywords": [ + "desktop", + "desktop path", + "desktoppath", + "desktop directory", + "desktopdir" + ], + "icon": "lar la-desktop" + }, + { + "function_call": "open_file(path)", + "name": "Open file", + "description": "Opens file with default programs", + "parameters": [ + { + "name": " path", + "description": " Path to file. \n" + } + ], + "return": " Path to file\n", + "example": ">>> # Make textfile\n>>> testfile = make_textfile()\n>>> # Open the file\n>>> open_file(testfile)\n", + "snippet": "# Make textfile\ntestfile = make_textfile()\n# Open the file\nopen_file(testfile)\n", + "keywords": [ + "file", + "open", + "open file", + "show", + "reveal", + "explorer", + "run", + "start" + ], + "icon": "lar la-file" + }, + { + "function_call": "set_wallpaper(image_path)", + "name": "Set wallpaper", + "description": "Set Windows desktop wallpaper with the the specified image", + "parameters": [ + { + "name": " image_path", + "description": " Path to the image. This image will be set as desktop wallpaper\n" + } + ], + "return": "", + "example": ">>> # Caution: this example will change your wallpaper\n>>> # Take a screenshot of current screen\n>>> screenshot = take_screenshot()\n>>> # Flip it hozirontally for fun\n>>> mirror_image_horizontally(screenshot)\n>>> # Set flipped image as wallpaper\n>>> set_wallpaper(screenshot)\n", + "snippet": "# Caution: this example will change your wallpaper\n# Take a screenshot of current screen\nscreenshot = take_screenshot()\n# Flip it hozirontally for fun\nmirror_image_horizontally(screenshot)\n# Set flipped image as wallpaper\nset_wallpaper(screenshot)\n", + "keywords": [ + "desktop", + "desktop path", + "desktoppath", + "desktop directory", + "desktopdir" + ], + "icon": "las la-desktop" + }, + { + "function_call": "download_file_from_url(url, filename=None, path=None)", + "name": "Download file from a URL", + "description": ":parameter url: Source URL to download file from:parameter filename::parameter path: Target path. If no path is given will download to the home directory", + "parameters": [ + { + "name": " url", + "description": " Source URL to download file from\n" + }, + { + "name": " filename", + "description": " \n" + }, + { + "name": " path", + "description": " Target path. If no path is given will download to the home directory\n" + } + ], + "return": " Target path as string\n", + "example": ">>> # Download robot picture from the wikipedia robot page\n>>> picture_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Atlas_from_boston_dynamics.jpg/220px-Atlas_from_boston_dynamics.jpg'\n>>> download_file_from_url(url = picture_url, filename = 'robot.jpg')\n'C:\\\\Users\\\\\\\\robot.jpg'\n", + "snippet": "# Download robot picture from the wikipedia robot page\npicture_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Atlas_from_boston_dynamics.jpg/220px-Atlas_from_boston_dynamics.jpg'\ndownload_file_from_url(url = picture_url, filename = 'robot.jpg')\n", + "keywords": [ + "download", + "download url", + "save", + "request" + ], + "icon": "las la-cloud-download-alt" + } + ] + }, + { + "name": "Trello", + "icon": "lab la-trello", + "activities": [ + { + "function_call": "add_trello_card(title=\"My card\", description=\"My description\", board_name=\"My board\", list_name=\"My list\", api_key=\"\", api_secret=\"\", token=\"\", token_secret=\"any\")", + "name": "Add Trello Card", + "description": "Add a card to the Trello board. For this you need a Trello API key, secret and token.", + "parameters": [ + { + "name": " title", + "description": " Title of Trello card\n" + }, + { + "name": " description", + "description": " Description of Trello card\n" + }, + { + "name": " board_name", + "description": " Name of the Trello board\n" + }, + { + "name": " api_key", + "description": " Trello API key\n" + }, + { + "name": " api_secret", + "description": " Trello API secret\n" + }, + { + "name": " token", + "description": " Trello token\n" + }, + { + "name": " token_secret", + "description": " Token secret can be any string, but should be altered for security purposes.\n" + } + ], + "return": "", + "example": ">>> add_trello_card(title='ExampleTitle', description='ExampleDescription', api_key='SampleKey', api_secret='ApiSecret', token='SampleToken')\n", + "snippet": "add_trello_card(title='ExampleTitle', description='ExampleDescription', api_key='SampleKey', api_secret='ApiSecret', token='SampleToken')\n", + "keywords": [ + "trello" + ], + "icon": "lab la-trello" + } + ] + }, + { + "name": "System", + "icon": "las la-laptop", + "activities": [ + { + "function_call": "rename_file(input_path, new_name=None)", + "name": "Rename a file", + "description": "This activity will rename a file. If the the desired name already exists in the folder file will not be renamed.", + "parameters": [ + { + "name": " path", + "description": " Full path to file that will be renamed\n" + }, + { + "name": " new_name", + "description": " New name of the file e.g. 'newfile.txt'. By default file will be renamed to original folder name with '_renamed' added to the folder name.\n" + } + ], + "return": " Path to renamed file as a string. None if folder could not be renamed.\n", + "example": ">>> # Make new textfile in home directory\n>>> textfile = make_textfile()\n>>> # Rename the file\n>>> rename_file(textfile)\nC:\\\\Users\\\\\\\\generated_textfile_renamed.txt'\n", + "snippet": "# Make new textfile in home directory\ntextfile = make_textfile()\n# Rename the file\nrename_file(textfile)\n", + "keywords": [ + "file", + "rename", + "rename file", + "organise file", + "files", + "file manipulation", + "explorer", + "nautilus" + ], + "icon": "las la-file-contract" + }, + { + "function_call": "move_file(from_path, to_path)", + "name": "Move a file", + "description": "If the new location already contains a file with the same name, a random 4 character uid will be added in front of the name before the file is moved.", + "parameters": [ + { + "name": " old_path", + "description": " Full path to the file that will be moved\n" + }, + { + "name": " new_location", + "description": " Path to the folder where file will be moved to\n" + } + ], + "return": " Path to renamed file as a string. None if folder could not be moved.\n", + "example": ">>> # Make new textfile in home directory\n>>> textfile = make_textfile()\n>>> # Make a folder to move the file to\n>>> new_folder = create_folder()\n>>> # Move textfile to the folder\n>>> move_file(textfile, new_folder)\n", + "snippet": "# Make new textfile in home directory\ntextfile = make_textfile()\n# Make a folder to move the file to\nnew_folder = create_folder()\n# Move textfile to the folder\nmove_file(textfile, new_folder)\n", + "keywords": [ + "file", + "move", + "move file", + "organise file", + "files", + "file manipulation", + "explorer", + "nautilus" + ], + "icon": "las la-file-export" + }, + { + "function_call": "remove_file(path)", + "name": "Remove a file", + "description": ":parameter path: Full path to the file that will be deleted.", + "parameters": [ + { + "name": " path", + "description": " Full path to the file that will be deleted.\n" + } + ], + "return": " Path to removed file as a string.\n", + "example": ">>> # Make new textfile in home directory\n>>> textfile = make_textfile()\n>>> # Remove the file\n>>> remove_file(textfile)\n", + "snippet": "# Make new textfile in home directory\ntextfile = make_textfile()\n# Remove the file\nremove_file(textfile)\n", + "keywords": [ + "file", + "delete", + "erase", + "delete file", + "organise file", + "files", + "file manipulation", + "explorer", + "nautilus" + ], + "icon": "las la-trash" + }, + { + "function_call": "file_exists(path)", + "name": "Check if file exists", + "description": "This function checks whether the file with the given path exists.", + "parameters": [ + { + "name": " path", + "description": " Full path to the file to check.\n" + } + ], + "return": "", + "example": ">>> # Make new textfile in home directory\n>>> textfile = make_textfile()\n>>> # Check if file exists\n>>> file_exists(textfile)\nTrue\n", + "snippet": "# Make new textfile in home directory\ntextfile = make_textfile()\n# Check if file exists\nfile_exists(textfile)\n", + "keywords": [ + "file", + "exists", + "files", + "file manipulation", + "explorer", + "nautilus" + ], + "icon": "las la-tasks" + }, + { + "function_call": "wait_file_exists(path, timeout=60)", + "name": "Wait until a file exists.", + "description": "Not that this activity is blocking and will keep the system waiting.", + "parameters": [ + { + "name": " path", + "description": " Full path to file.\n" + }, + { + "name": " timeout", + "description": " Maximum time in seconds to wait before continuing. Default value is 60 seconds.\n" + } + ], + "return": "", + "example": ">>> # Make new textfile in home directory\n>>> textfile = make_textfile()\n>>> # Wait untile file exists # Should pass immediatly\n>>> wait_file_exists(textfile)\n", + "snippet": "# Make new textfile in home directory\ntextfile = make_textfile()\n# Wait untile file exists # Should pass immediatly\nwait_file_exists(textfile)\n", + "keywords": [ + "file", + "wait", + "wait till exists", + "files", + "file manipulation", + "explorer", + "nautilus" + ], + "icon": "las la-list-alt" + }, + { + "function_call": "write_list_to_file(list_to_write, file_path)", + "name": "List to .txt", + "description": "Writes a list to a text (.txt) file.Every element of the entered list is written on a new line of the text file.", + "parameters": [ + { + "name": " list_to_write", + "description": " List to write to .txt file\n" + }, + { + "name": " path", + "description": " Path to the text-file. \n" + } + ], + "return": "", + "example": ">>> # Make a list to write\n>>> robot_names = ['WALL-E', 'Terminator', 'R2D2']\n>>> # Create a new text file\n>>> textfile = make_textfile()\n>>> write_list_to_file(robot_names, textfile)\n>>> # Open the file for illustration\n>>> open_file(textfile)\n", + "snippet": "# Make a list to write\nrobot_names = ['WALL-E', 'Terminator', 'R2D2']\n# Create a new text file\ntextfile = make_textfile()\nwrite_list_to_file(robot_names, textfile)\n# Open the file for illustration\nopen_file(textfile)\n", + "keywords": [ + "list", + "text", + "txt", + "list to file", + "write list", + "write" + ], + "icon": "las la-list" + }, + { + "function_call": "read_list_from_txt(file_path)", + "name": "Read .txt file", + "description": "This activity writes the content of a .txt file to a list and returns that list.Every new line from the .txt file becomes a new element of the list. The activity willnot work if the entered path is not attached to a .txt file.", + "parameters": [ + { + "name": " path", + "description": " Path to the .txt file\n" + } + ], + "return": " List with contents of specified .txt file\n", + "example": ">>> # Make a list to write\n>>> robot_names = ['WALL-E', 'Terminator', 'R2D2']\n>>> # Create a new text file\n>>> textfile = make_textfile()\n>>> write_list_to_file(robot_names, textfile)\n>>> # Read list from file\n>>> read_list_from_txt(textfile)\n['WALL-E', 'Terminator', 'R2D2']\n", + "snippet": "# Make a list to write\nrobot_names = ['WALL-E', 'Terminator', 'R2D2']\n# Create a new text file\ntextfile = make_textfile()\nwrite_list_to_file(robot_names, textfile)\n# Read list from file\nread_list_from_txt(textfile)\n", + "keywords": [ + "list", + "text", + "txt", + "list to file", + "write list", + "read", + "read txt", + "read text" + ], + "icon": "las la-th-list" + }, + { + "function_call": "append_line(text, file_path)", + "name": "Append to .txt", + "description": "Append a text line to a file and creates the file if it does not exist yet.", + "parameters": [ + { + "name": " text", + "description": " The text line to write to the end of the file\n" + }, + { + "name": " file_path", + "description": " Path to the file to write to\n" + } + ], + "return": "", + "example": ">>> # Create a new text file\n>>> textfile = make_textfile()\n>>> # Append a few lines to the file\n>>> append_line('Line 1', textfile)\n>>> append_line('Line 2', textfile)\n>>> append_line('Line 3', textfile)\n>>> # Open the file for illustration\n>>> open_file(textfile)\n", + "snippet": "# Create a new text file\ntextfile = make_textfile()\n# Append a few lines to the file\nappend_line('Line 1', textfile)\nappend_line('Line 2', textfile)\nappend_line('Line 3', textfile)\n# Open the file for illustration\nopen_file(textfile)\n", + "keywords": [ + "list", + "text", + "txt", + "list to file", + "write list", + "read", + "write txt", + "append text", + "append line", + "append", + "add to file", + "add" + ], + "icon": "las la-tasks" + }, + { + "function_call": "make_textfile(text='Sample text', output_path=None)", + "name": "Make text file", + "description": "Initialize text file", + "parameters": [ + { + "name": " text", + "description": " The text line to write to the end of the file. Default text is 'Sample text'\n" + }, + { + "name": " output_path", + "description": " Ouput path. Will write to home directory\n" + } + ], + "return": " Path as string\n", + "example": ">>> # Create a new text file\n>>> textfile = make_textfile()\nC:\\\\Users\\\\\\\\generated_textfile.txt'\n", + "snippet": "# Create a new text file\ntextfile = make_textfile()\n", + "keywords": [ + "make textfile", + "textfile", + "testfile", + "exampel file", + "make file", + "make", + "new file", + "new textfile", + "txt", + "new txt" + ], + "icon": "las la-file-alt" + }, + { + "function_call": "copy_file(old_path, new_path=None)", + "name": "Copy a file", + "description": "Copies a file from one place to another.If the new location already contains a file with the same name, a random 4 character uid is added to the name.", + "parameters": [ + { + "name": " old_path", + "description": " Full path to the source location of the folder\n" + }, + { + "name": " new_path", + "description": " Optional full path to the destination location of the folder. If not specified file will be copied to the same location with a random 8 character uid is added to the name.\n" + } + ], + "return": " New path as string\n", + "example": ">>> # Create a new text file\n>>> textfile = make_textfile()\n>>> # Copy the textfile\n>>> copy_file(textfile)\nC:\\\\Users\\\\\\\\generated_textfile.txt'\n", + "snippet": "# Create a new text file\ntextfile = make_textfile()\n# Copy the textfile\ncopy_file(textfile)\n", + "keywords": [ + "make textfile", + "textfile", + "testfile", + "exampel file", + "make file", + "make", + "new file", + "new textfile", + "txt", + "new txt" + ], + "icon": "las la-copy" + }, + { + "function_call": "get_file_extension(path)", + "name": "Get file extension", + "description": "Get extension of a file", + "parameters": [ + { + "name": " path", + "description": " Path to file to get extension from\n" + } + ], + "return": " String with extension, e.g. '.txt'\n", + "example": ">>> # Create a new text file\n>>> textfile = make_textfile()\n>>> # Get file extension of this textfile\n>>> get_file_extension(textfile)\n'.txt'\n", + "snippet": "# Create a new text file\ntextfile = make_textfile()\n# Get file extension of this textfile\nget_file_extension(textfile)\n", + "keywords": [ + "file", + "extension", + "file extension", + "details" + ], + "icon": "las la-info" + }, + { + "function_call": "send_to_printer(file)", + "name": "Print", + "description": "Send file to default printer to priner. This activity sends a file to the printer. Make sure to have a default printer set up.", + "parameters": [ + { + "name": " file", + "description": " Path to the file to print, should be a printable file\n" + } + ], + "return": "", + "example": ">>> # Caution as this example could result in a print from default printer\n>>> # Create a new text file\n>>> textfile = make_textfile(text = 'What does a robot do at lunch? Take a megabyte!')\n>>> # Print the textfile\n>>> send_to_printer(textfile)\n", + "snippet": "# Caution as this example could result in a print from default printer\n# Create a new text file\ntextfile = make_textfile(text = 'What does a robot do at lunch? Take a megabyte!')\n# Print the textfile\nsend_to_printer(textfile)\n", + "keywords": [ + "print", + "printer", + "printing", + "ink", + "export" + ], + "icon": "las la-print" + } + ] + }, + { + "name": "PDF", + "icon": "las la-file-pdf", + "activities": [ + { + "function_call": "read_text_from_pdf(file_path)", + "name": "Text from PDF", + "description": "Extracts the text from a PDF. This activity reads text from a pdf file. Can only read PDF files that contain a text layer.", + "parameters": [ + { + "name": " file_path", + "description": " Path to the PDF (either relative or absolute)\n" + } + ], + "return": " The text from the PDF\n", + "example": ">>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\n>>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n>>> # Open example pdf for illustration\n>>> open_file(example_pdf)\n>>> # Read the text\n>>> read_text_from_pdf(example_pdf)\n", + "snippet": "# Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\nexample_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n# Open example pdf for illustration\nopen_file(example_pdf)\n# Read the text\nread_text_from_pdf(example_pdf)\n", + "keywords": [ + "PDF", + "read", + "text", + "extract text", + "PDF file" + ], + "icon": "las la-glasses" + }, + { + "function_call": "join_pdf_files(file_paths, output_path=None)", + "name": "Merge PDF", + "description": "Merges multiple PDFs into a single file", + "parameters": [ + { + "name": " file_paths", + "description": " List of paths to PDF files\n" + }, + { + "name": " output_path", + "description": " Full path where joined pdf files can be written. If no path is given will write to home dir as 'merged_pdf.pdf'\n" + } + ], + "return": " Output path as string\n", + "example": ">>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\n>>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n>>> # Join the PDF file three times with itself for illustration, could also be different files\n>>> merged_pdf = join_pdf_files([example_pdf, example_pdf, example_pdf])\n>>> # Open resulting PDF file for illustration\n>>> open_file(merged_pdf)\n", + "snippet": "# Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\nexample_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n# Join the PDF file three times with itself for illustration, could also be different files\nmerged_pdf = join_pdf_files([example_pdf, example_pdf, example_pdf])\n# Open resulting PDF file for illustration\nopen_file(merged_pdf)\n", + "keywords": [ + "PDF", + "read", + "text", + "extract text", + "PDF file", + "join PDF", + "join", + "merge", + "merge PDF" + ], + "icon": "las la-object-ungroup" + }, + { + "function_call": "extract_page_range_from_pdf(file_path, start_page, end_page, output_path=None)", + "name": "Extract page from PDF", + "description": "Extracts a particular range of a PDF to a separate file.", + "parameters": [ + { + "name": " file_path", + "description": " Path to the PDF (either relative or absolute)\n" + }, + { + "name": " start_page", + "description": " Page number to start from, with 0 being the first page\n" + }, + { + "name": " end_page", + "description": " Page number to end with, with 0 being the first page\n" + } + ], + "return": "", + "example": ">>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\n>>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n>>> # Join the PDF file three times to create multi page\n>>> multi_page_pdf_example = join_pdf_files([example_pdf, example_pdf, example_pdf])\n>>> # Extract some pages from it\n>>> new_file = extract_page_range_from_pdf(multi_page_pdf_example, 1, 2 )\n>>> # Open resulting PDF file for illustration\n>>> open_file(new_file)\n", + "snippet": "# Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\nexample_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n# Join the PDF file three times to create multi page\nmulti_page_pdf_example = join_pdf_files([example_pdf, example_pdf, example_pdf])\n# Extract some pages from it\nnew_file = extract_page_range_from_pdf(multi_page_pdf_example, 1, 2 )\n# Open resulting PDF file for illustration\nopen_file(new_file)\n", + "keywords": [ + "PDF", + "read", + "extract text", + "PDF file", + "extract PDF", + "join", + "cut", + "cut PDF", + "extract pages", + "extract from pdf", + "select page", + "page" + ], + "icon": "las la-cut" + }, + { + "function_call": "extract_images_from_pdf(file_path)", + "name": "Extract images from PDF", + "description": "Save a specific page from a PDF as an image", + "parameters": [ + { + "name": " file_path", + "description": " Full path to store extracted images\n" + } + ], + "return": "", + "example": ">>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\n>>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n>>> # Extract the images\n>>> extract_images_from_pdf(example_pdf)\n", + "snippet": "# Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\nexample_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n# Extract the images\nextract_images_from_pdf(example_pdf)\n", + "keywords": [ + "PDF", + "extract images", + "images", + "extract text", + "PDF file", + "image" + ], + "icon": "las la-icons" + }, + { + "function_call": "apply_watermark_to_pdf(file_path, watermark_path, output_path='')", + "name": "Watermark a PDF", + "description": ":parameter file_path: Filepath to the document that will be watermarked. Should be pdf file.:parameter watermark_path: Filepath to the watermark. Should be pdf file.:parameter output_path: Path to save watermarked PDF. If no path is provided same path as input will be used with 'watermarked' added to the name", + "parameters": [ + { + "name": " file_path", + "description": " Filepath to the document that will be watermarked. Should be pdf file.\n" + }, + { + "name": " watermark_path", + "description": " Filepath to the watermark. Should be pdf file.\n" + }, + { + "name": " output_path", + "description": " Path to save watermarked PDF. If no path is provided same path as input will be used with 'watermarked' added to the name\n" + } + ], + "return": " Output path as a string\n", + "example": ">>> # Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\n>>> example_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n>>> # Download the watermark\n>>> example_watermark = download_file_from_url('http://automagica.com/examples/approved_stamp.pdf')\n>>> # Apply the watermark\n>>> watermarked_file = apply_watermark_to_pdf(example_pdf, example_watermark)\n>>> # Open the file for illustration\n>>> open_file(watermarked_file)\n", + "snippet": "# Caution, for this example to work a .pdf example file will be downloaded from automagica.com FTP\nexample_pdf = download_file_from_url('http://automagica.com/examples/example_document.pdf')\n# Download the watermark\nexample_watermark = download_file_from_url('http://automagica.com/examples/approved_stamp.pdf')\n# Apply the watermark\nwatermarked_file = apply_watermark_to_pdf(example_pdf, example_watermark)\n# Open the file for illustration\nopen_file(watermarked_file)\n", + "keywords": [ + "PDF", + "extract images", + "images", + "extract text", + "PDF file", + "image" + ], + "icon": "las la-stamp" + } + ] + }, + { + "name": "System Monitoring", + "icon": "las la-wave-square", + "activities": [ + { + "function_call": "get_cpu_load(measure_time=1)", + "name": "CPU load", + "description": "Get average CPU load for all cores.", + "parameters": [ + { + "name": " measure_time", + "description": " Time (seconds) to measure load. Standard measure_time is 1 second.\n" + } + ], + "return": " Displayed load is an average over measured_time.\n", + "example": ">>> get_cpu_load()\n10.1\n", + "snippet": "get_cpu_load()\n", + "keywords": [ + "cpu", + "load", + "cpuload" + ], + "icon": "las la-microchip" + }, + { + "function_call": "get_number_of_cpu(logical=True)", + "name": "Count CPU", + "description": "Get the number of CPU's in the current system.", + "parameters": [ + { + "name": " logical", + "description": " Determines if only logical units are added to the count, default value is True.\n" + } + ], + "return": " Number of CPU Integer\n", + "example": ">>> get_number_of_cpu()\n2\n", + "snippet": "get_number_of_cpu()\n", + "keywords": [ + "cpu", + "count", + "number of cpu" + ], + "icon": "las la-calculator" + }, + { + "function_call": "get_cpu_frequency()", + "name": "CPU frequency", + "description": "Get frequency at which CPU currently operates.", + "parameters": [], + "return": " minimum and maximum frequency\n", + "example": ">>> get_cpu_frequency()\nscpufreq(current=3600.0, min=0.0, max=3600.0)\n", + "snippet": "get_cpu_frequency()\n", + "keywords": [ + "cpu", + "load", + "cpu frequency" + ], + "icon": "las la-wave-square" + }, + { + "function_call": "get_cpu_stats()", + "name": "CPU Stats", + "description": "Get CPU statistics", + "parameters": [], + "return": " Number of CTX switches, intterupts, soft-interrupts and systemcalls.\n", + "example": ">>> get_cpu_stats()\nscpustats(ctx_switches=735743826, interrupts=1540483897, soft_interrupts=0, syscalls=2060595131)\n", + "snippet": "get_cpu_stats()\n", + "keywords": [ + "cpu", + "load", + "cpu frequency", + "stats", + "cpu statistics" + ], + "icon": "las la-server" + }, + { + "function_call": "get_memory_stats(mem_type=\"swap\")", + "name": "Memory statistics", + "description": "Get memory statistics", + "parameters": [ + { + "name": " mem_type", + "description": " Choose mem_type = 'virtual' for virtual memory, and mem_type = 'swap' for swap memory (standard).\n" + } + ], + "return": " Total, used, free and percentage in use.\n", + "example": ">>> get_memory_stats()\nsswap(total=24640016384, used=18120818688, free=6519197696, percent=73.5, sin=0, sout=0)\n", + "snippet": "get_memory_stats()\n", + "keywords": [ + "memory", + "statistics", + "usage", + "ram" + ], + "icon": "las la-memory" + }, + { + "function_call": "get_disk_stats()", + "name": "Disk stats", + "description": "Get disk statistics of main disk", + "parameters": [], + "return": " Total, used, free and percentage in use.\n", + "example": ">>> get_disk_stats()\nsdiskusage(total=999559262208, used=748696350720, free=250862911488, percent=74.9)\n", + "snippet": "get_disk_stats()\n", + "keywords": [ + "disk usage", + "disk stats", + "disk", + "harddisk", + "space" + ], + "icon": "las la-save" + }, + { + "function_call": "get_disk_partitions()", + "name": "Partition info", + "description": "Get disk partition info", + "parameters": [], + "return": " tuple with info for every partition.\n", + "example": ">>> get_disk_paritions()\n[sdiskpart(device='C:\\\\', mountpoint='C:\\\\', fstype='NTFS', opts='rw,fixed')]\n", + "snippet": "get_disk_paritions()\n", + "keywords": [ + "disk usage", + "disk stats", + "disk", + "harddisk", + "space" + ], + "icon": "las la-save" + }, + { + "function_call": "get_boot_time()", + "name": "Boot time", + "description": "Get most recent boot time", + "parameters": [], + "return": " time PC was booted in seconds after the epoch.\n", + "example": ">>> get_boot_time()\n123456789.0\n", + "snippet": "get_boot_time()\n", + "keywords": [ + "boot", + "boot time", + "boottime", + "startup", + "timer" + ], + "icon": "lar la-clock" + }, + { + "function_call": "get_time_since_last_boot()", + "name": "Uptime", + "description": "Get uptime since last boot", + "parameters": [], + "return": " time since last boot in seconds.\n", + "example": ">>> get_time_since_last_boot()\n1337.0\n", + "snippet": "get_time_since_last_boot()\n", + "keywords": [ + "boot", + "boot time", + "boottime", + "startup", + "timer" + ], + "icon": "lar la-clock" + } + ] + }, + { + "name": "Image Processing", + "icon": "las la-photo-video", + "activities": [ + { + "function_call": "show_image(path)", + "name": "Show image", + "description": "Displays an image specified by the path variable on the default imaging program.", + "parameters": [ + { + "name": " path", + "description": " Full path to image\n" + } + ], + "return": "", + "example": ">>> # Take screenshot of current screen to use as test image\n>>> testimage = take_screenshot()\n>>> # Show the image\n>>> show_image(testimage)\n", + "snippet": "# Take screenshot of current screen to use as test image\ntestimage = take_screenshot()\n# Show the image\nshow_image(testimage)\n", + "keywords": [ + "image", + "show image", + "reveal", + "open image", + "open" + ], + "icon": "las la-images" + }, + { + "function_call": "rotate_image(path, angle=90)", + "name": "Rotate image", + "description": "Rotate an image", + "parameters": [ + { + "name": " angle", + "description": " Degrees to rotate image. Note that angles other than 90, 180, 270, 360 can resize the picture. \n" + } + ], + "return": "", + "example": ">>> # Take screenshot of current screen to use as test image\n>>> testimage = take_screenshot()\n>>> # Rotate the image\n>>> rotate_image(testimage)\n>>> # Show the image\n>>> show_image(testimage)\n", + "snippet": "# Take screenshot of current screen to use as test image\ntestimage = take_screenshot()\n# Rotate the image\nrotate_image(testimage)\n# Show the image\nshow_image(testimage)\n", + "keywords": [ + "image", + "rotate image", + "90 degrees", + "image manipulation", + "photoshop", + "paint" + ], + "icon": "las la-undo" + }, + { + "function_call": "resize_image(path, size)", + "name": "Resize image", + "description": "Resizes the image specified by the path variable.", + "parameters": [ + { + "name": " path", + "description": " Path to the image\n" + }, + { + "name": " size", + "description": " Tuple with the width and height in pixels. E.g. (300, 400) gives the image a width of 300 pixels and a height of 400 pixels.\n" + } + ], + "return": "", + "example": ">>> # Take screenshot of current screen to use as test image\n>>> testimage = take_screenshot()\n>>> # Resize the image\n>>> resize_image(testimage, size=(100,100))\n>>> # Show the image\n>>> show_image(testimage)\n", + "snippet": "# Take screenshot of current screen to use as test image\ntestimage = take_screenshot()\n# Resize the image\nresize_image(testimage, size=(100,100))\n# Show the image\nshow_image(testimage)\n", + "keywords": [ + "image", + "resize image", + "resize", + "size", + "image manipulation", + "photoshop", + "paint" + ], + "icon": "las la-expand-arrows-alt" + }, + { + "function_call": "get_image_width(path)", + "name": "Get image width", + "description": "Get with of image", + "parameters": [ + { + "name": " path", + "description": " Path to image\n" + } + ], + "return": "", + "example": ">>> # Take screenshot of current screen to use as test image\n>>> testimage = take_screenshot()\n>>> # get image height\n>>> get_image_width(testimage)\n1000\n", + "snippet": "# Take screenshot of current screen to use as test image\ntestimage = take_screenshot()\n# get image height\nget_image_width(testimage)\n", + "keywords": [ + "image", + "height", + "width", + "image height", + "image width" + ], + "icon": "las la-expand-arrows-alt" + }, + { + "function_call": "get_image_height(path)", + "name": "Get image height", + "description": "Get height of image", + "parameters": [ + { + "name": " path", + "description": " Path to image\n" + } + ], + "return": " Height of image\n", + "example": ">>> # Take screenshot of current screen to use as test image\n>>> testimage = take_screenshot()\n>>> # get image height\n>>> get_image_height(testimage)\n1000\n", + "snippet": "# Take screenshot of current screen to use as test image\ntestimage = take_screenshot()\n# get image height\nget_image_height(testimage)\n", + "keywords": [ + "image", + "height", + "width", + "image height", + "image width" + ], + "icon": "las la-arrows-alt-v" + }, + { + "function_call": "crop_image(path, box=None)", + "name": "Crop image", + "description": "Crops the image specified by path to a region determined by the box variable.", + "parameters": [ + { + "name": " path", + "description": " Path to image\n" + }, + { + "name": " box", + "description": " A tuple that defines the left, upper, right and lower pixel co\u00f6rdinate e.g.: (left, upper, right, lower)\n" + } + ], + "return": "", + "example": ">>> # Take screenshot of current screen to use as test image\n>>> testimage = take_screenshot()\n>>> # Crop the image\n>>> crop_image(testimage, box = (10,10,100,100))\n>>> # Show the image\n>>> show_image(testimage)\n", + "snippet": "# Take screenshot of current screen to use as test image\ntestimage = take_screenshot()\n# Crop the image\ncrop_image(testimage, box = (10,10,100,100))\n# Show the image\nshow_image(testimage)\n", + "keywords": [ + "image", + "crop", + "crop image" + ], + "icon": "las la-crop" + }, + { + "function_call": "mirror_image_horizontally(path)", + "name": "Mirror image horizontally", + "description": "Mirrors an image with a given path horizontally from left to right.", + "parameters": [ + { + "name": " path", + "description": " Path to image\n" + } + ], + "return": "", + "example": ">>> # Take screenshot of current screen to use as test image\n>>> testimage = take_screenshot()\n>>> # Mirror image horizontally\n>>> mirror_image_horizontally(testimage)\n>>> # Show the image\n>>> show_image(testimage)\n", + "snippet": "# Take screenshot of current screen to use as test image\ntestimage = take_screenshot()\n# Mirror image horizontally\nmirror_image_horizontally(testimage)\n# Show the image\nshow_image(testimage)\n", + "keywords": [ + "image", + "flip", + "flip image", + "mirror", + "mirror image", + "horizon", + "horizontally" + ], + "icon": "las la-caret-up" + }, + { + "function_call": "mirror_image_vertically(path)", + "name": "Mirror image vertically", + "description": "Mirrors an image with a given path vertically from top to bottom.", + "parameters": [ + { + "name": " path", + "description": " Path to image\n" + } + ], + "return": "", + "example": ">>> # Take screenshot of current screen to use as test image\n>>> testimage = take_screenshot()\n>>> # Mirror image vertically\n>>> mirror_image_vertically(testimage)\n>>> # Show the image\n>>> show_image(testimage)\n", + "snippet": "# Take screenshot of current screen to use as test image\ntestimage = take_screenshot()\n# Mirror image vertically\nmirror_image_vertically(testimage)\n# Show the image\nshow_image(testimage)\n", + "keywords": [ + "image", + "flip", + "flip image", + "mirror", + "mirror image", + "vertical", + "vertically" + ], + "icon": "las la-caret-right" + } + ] + }, + { + "name": "Process", + "icon": "las la-play", + "activities": [ + { + "function_call": "run_manual(task)", + "name": "Windows run", + "description": "Use Windows Run to boot a processNote this uses keyboard inputs which means this process can be disrupted by interfering inputs", + "parameters": [ + { + "name": " task", + "description": " Name of the task to run e.g. 'mspaint.exe'\n" + } + ], + "return": "", + "example": ">>> # Open paint with Windows run\n>>> run_manual('mspaint.exe')\n>>> # Open home directory with Windows run\n>>> run_manual(home_path())\n", + "snippet": "# Open paint with Windows run\nrun_manual('mspaint.exe')\n# Open home directory with Windows run\nrun_manual(home_path())\n", + "keywords": [ + "run", + "open", + "task", + "win r", + "windows run", + "shell", + "cmd" + ], + "icon": "las la-cog" + }, + { + "function_call": "run(process)", + "name": "Run process", + "description": "Use subprocess to open a windows process", + "parameters": [ + { + "name": " process", + "description": " Process to open e.g: 'calc.exe', 'notepad.exe', 'control.exe', 'mspaint.exe'.\n" + } + ], + "return": "", + "example": ">>> # Open paint with Windows run\n>>> run('mspaint.exe')\n", + "snippet": "# Open paint with Windows run\nrun('mspaint.exe')\n", + "keywords": [ + "run", + "open", + "task", + "win r", + "windows run", + "shell", + "cmd" + ], + "icon": "las la-play" + }, + { + "function_call": "is_process_running(name)", + "name": "Check if process is running", + "description": "Check if process is running. Validates if given process name (name) is currently running on the system.", + "parameters": [ + { + "name": " name", + "description": " Name of process\n" + } + ], + "return": " Boolean\n", + "example": ">>> # Open paint with Windows run\n>>> run('mspaint.exe')\n>>> # Check if paint is running\n>>> is_process_running('mspaint.exe')\nTrue\n", + "snippet": "# Open paint with Windows run\nrun('mspaint.exe')\n# Check if paint is running\nis_process_running('mspaint.exe')\n", + "keywords": [ + "run", + "open", + "task", + "win r", + "windows run", + "shell", + "cmd" + ], + "icon": "las la-cogs" + }, + { + "function_call": "get_running_processes()", + "name": "Get running processes", + "description": "Get names of unique processes currently running on the system.", + "parameters": [], + "return": " List of unique running processes\n", + "example": ">>> # Show all running processes\n>>> get_running_processes()\n['cmd.exe', 'chrome.exe', ... ]\n", + "snippet": "# Show all running processes\nget_running_processes()\n", + "keywords": [ + "process", + "processes", + "list processes", + "running", + "running processes" + ], + "icon": "las la-list" + }, + { + "function_call": "kill_process(name=None)", + "name": "Kill process", + "description": "Kills a process forcefully", + "parameters": [ + { + "name": " name", + "description": " Name of the process\n" + } + ], + "return": "", + "example": ">>> # Open paint with Windows run\n>>> run('mspaint.exe')\n>>> # Force paint to close\n>>> kill_process('mspaint.exe')\n", + "snippet": "# Open paint with Windows run\nrun('mspaint.exe')\n# Force paint to close\nkill_process('mspaint.exe')\n", + "keywords": [ + "run", + "open", + "task", + "win r", + "windows run", + "shell", + "cmd", + "kill", + "stop", + "kill process", + "stop process", + "quit", + "exit" + ], + "icon": "las la-window-close" + } + ] + }, + { + "name": "Optical Character Recognition (OCR)", + "icon": "las la-glasses", + "activities": [ + { + "function_call": "extract_text_ocr(path=None)", + "name": "Get text with OCR", + "description": "This activity extracts all text from the current screen or an image if a path is specified.", + "parameters": [ + { + "name": " path", + "description": " Path to image from where text will be extracted. If no path is specified a screenshot of current screen will be used.\n" + } + ], + "return": " String with all text from current screen\n", + "example": ">>> # Make a textfile with some text to recognize\n>>> testfile = make_textfile(text='OCR Example')\n>>> # Open the textfile\n>>> open_file(testfile)\n>>> # Find the text with OCR\n>>> extracted_text = find_text_on_screen_ocr(text='OCR Example')\n>>> # Check if the extracted_text contains the original word\n>>> 'OCR Example' in extracted_text\nTrue\n", + "snippet": "# Make a textfile with some text to recognize\ntestfile = make_textfile(text='OCR Example')\n# Open the textfile\nopen_file(testfile)\n# Find the text with OCR\nextracted_text = find_text_on_screen_ocr(text='OCR Example')\n# Check if the extracted_text contains the original word\n'OCR Example' in extracted_text\n", + "keywords": [ + "OCR", + "vision", + "AI", + "screen", + "citrix", + "read", + "optical character recognition" + ], + "icon": "lab la-readme" + }, + { + "function_call": "find_text_on_screen_ocr(text, criteria=None)", + "name": "Find text on screen with OCR", + "description": "This activity finds position (coordinates) of specified text on the current screen using OCR.", + "parameters": [ + { + "name": " text", + "description": " Text to find. Only exact matches are returned.\n" + }, + { + "name": " criteria", + "description": " Criteria to select on if multiple matches are found. If no criteria is specified all matches will be returned. Options are 'first', which returns the first match closest to the upper left corner, 'last' returns the last match closest to the lower right corner, random selects a random match.\n" + } + ], + "return": " Dictionary or list of dictionaries with matches with following elements: 'h' height in pixels, 'text' the matched text,'w' the width in pixels, 'x' absolute x-co\u00f6rdinate , 'y' absolute y-co\u00f6rdinate. Returns nothing if no matches are found\n", + "example": ">>> # Make a textfile with some text to recognize\n>>> testfile = make_textfile(text='OCR Example')\n>>> # Open the textfile\n>>> open_file(testfile)\n>>> # Find the text with OCR\n>>> find_text_on_screen_ocr(text='OCR Example')\n", + "snippet": "# Make a textfile with some text to recognize\ntestfile = make_textfile(text='OCR Example')\n# Open the textfile\nopen_file(testfile)\n# Find the text with OCR\nfind_text_on_screen_ocr(text='OCR Example')\n", + "keywords": [ + "OCR", + "vision", + "AI", + "screen", + "citrix", + "read", + "optical character recognition" + ], + "icon": "las la-glasses" + }, + { + "function_call": "click_on_text_ocr(text)", + "name": "Click on text with OCR", + "description": "This activity clicks on position (coordinates) of specified text on the current screen using OCR.", + "parameters": [ + { + "name": " text", + "description": " Text to find. Only exact matches are returned.\n" + } + ], + "return": "", + "example": ">>> # Make a textfile with some text to recognize\n>>> testfile = make_textfile(text='OCR Example')\n>>> # Open the textfile\n>>> open_file(testfile)\n>>> # Find the text with OCR and click on it\n>>> click_on_text(text='OCR Example')\n", + "snippet": "# Make a textfile with some text to recognize\ntestfile = make_textfile(text='OCR Example')\n# Open the textfile\nopen_file(testfile)\n# Find the text with OCR and click on it\nclick_on_text(text='OCR Example')\n", + "keywords": [ + "OCR", + "vision", + "AI", + "screen", + "citrix", + "read", + "optical character recognition", + "click" + ], + "icon": "las la-mouse-pointer" + }, + { + "function_call": "double_click_on_text_ocr(text)", + "name": "Double click on text with OCR", + "description": "This activity double clicks on position (coordinates) of specified text on the current screen using OCR.", + "parameters": [ + { + "name": " text", + "description": " Text to find. Only exact matches are returned.\n" + } + ], + "return": "", + "example": ">>> # Make a textfile with some text to recognize\n>>> testfile = make_textfile(text='OCR Example')\n>>> # Open the textfile\n>>> open_file(testfile)\n>>> # Find the text with OCR and double click on it\n>>> double_click_on_text(text='OCR Example')\n", + "snippet": "# Make a textfile with some text to recognize\ntestfile = make_textfile(text='OCR Example')\n# Open the textfile\nopen_file(testfile)\n# Find the text with OCR and double click on it\ndouble_click_on_text(text='OCR Example')\n", + "keywords": [ + "OCR", + "vision", + "AI", + "screen", + "citrix", + "read", + "optical character recognition", + "click", + "double click" + ], + "icon": "las la-mouse-pointer" + }, + { + "function_call": "right_click_on_text_ocr(text)", + "name": "Right click on text with OCR", + "description": "This activity Right clicks on position (coordinates) of specified text on the current screen using OCR.", + "parameters": [ + { + "name": " text", + "description": " Text to find. Only exact matches are returned.\n" + } + ], + "return": "", + "example": ">>> # Make a textfile with some text to recognize\n>>> testfile = make_textfile(text='OCR Example')\n>>> # Open the textfile\n>>> open_file(testfile)\n>>> # Find the text with OCR and right click on it\n>>> right_click_on_text(text='OCR Example')\n", + "snippet": "# Make a textfile with some text to recognize\ntestfile = make_textfile(text='OCR Example')\n# Open the textfile\nopen_file(testfile)\n# Find the text with OCR and right click on it\nright_click_on_text(text='OCR Example')\n", + "keywords": [ + "OCR", + "vision", + "AI", + "screen", + "citrix", + "read", + "optical character recognition", + "click", + "right click" + ], + "icon": "las la-mouse-pointer" + } + ] + } +] \ No newline at end of file diff --git a/docs/portal/parser.ipynb b/docs/portal/parser.ipynb new file mode 100644 index 00000000..adc55019 --- /dev/null +++ b/docs/portal/parser.ipynb @@ -0,0 +1,5554 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "import os\n", + "cwd = Path().resolve().parents[1]\n", + "activities_path = os.path.join(cwd , 'automagica\\\\activities.py')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'description': 'Generate random Fernet key. Fernet guarantees that a message '\n", + " 'encrypted using it cannot be manipulated or read without the '\n", + " 'key. Fernet is an implementation of symmetric (also known as '\n", + " '“secret key”) authenticated cryptography',\n", + " 'example': '>>> # Generate a random key\\n'\n", + " '>>> generate_random_key()\\n'\n", + " \"b'AYv6ZPVgnrUtHDbGZqAopRyAo9r0_UKrA2Rm3K_NjIo='\\n\",\n", + " 'function_call': 'generate_random_key()',\n", + " 'icon': 'las la-key',\n", + " 'keywords': ['random',\n", + " 'key',\n", + " 'fernet',\n", + " 'hash',\n", + " 'security',\n", + " 'cryptography',\n", + " 'password',\n", + " 'secure'],\n", + " 'name': 'Random key',\n", + " 'parameters': [],\n", + " 'return': ' Bytes-like object\\n',\n", + " 'snippet': '# Generate a random key\\ngenerate_random_key()\\n'}\n", + "{'description': 'Encrypt text with (Fernet) key,',\n", + " 'example': '>>> # Generate a random key\\n'\n", + " '>>> key = generate_random_key()\\n'\n", + " '>>> # Encrypt text with this key\\n'\n", + " \">>> encrypt_text_with_key('Sample text', key)\\n\"\n", + " \"b'gAAAAABd8lpG8fNqcj5eXrPPHlx4KeCm-1TgX3jkyhStMfIlgGImIa-qaINZAj8XcxPcG8iu84iT56b_qAW9c5qpe7btUFhtxQ=='\\n\",\n", + " 'function_call': 'encrypt_text_with_key(text, key)',\n", + " 'icon': 'las la-lock',\n", + " 'keywords': ['random',\n", + " 'encryption',\n", + " 'secure',\n", + " 'security',\n", + " 'hash',\n", + " 'password',\n", + " 'fernet',\n", + " 'text'],\n", + " 'name': 'Encrypt text',\n", + " 'parameters': [{'description': ' Text to be encrypted.\\n', 'name': ' text'},\n", + " {'description': ' Path where key is stored.\\n',\n", + " 'name': ' key'}],\n", + " 'return': ' bytes-like object.\\n',\n", + " 'snippet': '# Generate a random key\\n'\n", + " 'key = generate_random_key()\\n'\n", + " '# Encrypt text with this key\\n'\n", + " \"encrypt_text_with_key('Sample text', key)\\n\"}\n", + "{'description': 'Dexrypt bytes-like object to string with (Fernet) key',\n", + " 'example': '>>> # Generate a random key\\n'\n", + " '>>> key = generate_random_key()\\n'\n", + " '>>> # Encrypt text with generated key\\n'\n", + " \">>> encrypted_text = encrypt_text_with_key('Sample text', key)\\n\"\n", + " '>>> # Decrypt text with same key\\n'\n", + " '>>> decrypt_text_with_key(encrypted_text, key)\\n'\n", + " \"'Sample text'\\n\",\n", + " 'function_call': 'decrypt_text_with_key(encrypted_text, key)',\n", + " 'icon': 'las la-lock-open',\n", + " 'keywords': ['decrypt',\n", + " 'random',\n", + " 'unlock',\n", + " 'un-lock hash',\n", + " 'security',\n", + " 'cryptography',\n", + " 'password',\n", + " 'secure',\n", + " 'hash',\n", + " 'text'],\n", + " 'name': 'Decrypt text',\n", + " 'parameters': [{'description': ' Text to be encrypted.\\n',\n", + " 'name': ' encrypted_text'},\n", + " {'description': ' Path where key is stored.\\n',\n", + " 'name': ' key'}],\n", + " 'return': ' String\\n',\n", + " 'snippet': '# Generate a random key\\n'\n", + " 'key = generate_random_key()\\n'\n", + " '# Encrypt text with generated key\\n'\n", + " \"encrypted_text = encrypt_text_with_key('Sample text', key)\\n\"\n", + " '# Decrypt text with same key\\n'\n", + " 'decrypt_text_with_key(encrypted_text, key)\\n'}\n", + "{'description': 'Encrypt file with (Fernet) key. Note that file will be '\n", + " 'unusable unless unlocked with the same key.',\n", + " 'example': '>>> # Generate a random key\\n'\n", + " '>>> key = generate_random_key()\\n'\n", + " '>>> # Create a textfile to illustrate file encryption\\n'\n", + " '>>> textfile_path = make_textfile()\\n'\n", + " '>>> # Encrypt the textfile\\n'\n", + " '>>> encrypt_file_with_key(textfile_path, key=key)\\n'\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\generated_textfile_encrypted.txt'\\n\",\n", + " 'function_call': 'encrypt_file_with_key(input_path, key, output_path=None)',\n", + " 'icon': 'las la-lock',\n", + " 'keywords': ['encrypt', 'random', 'password', 'secure', 'secure file', 'lock'],\n", + " 'name': 'Encrypt file',\n", + " 'parameters': [{'description': ' Full path to file to be encrypted.\\n',\n", + " 'name': ' input_file'},\n", + " {'description': ' Path where key is stored.\\n', 'name': ' key'},\n", + " {'description': ' Output path. Default is the same directory '\n", + " 'with \"_encrypted\" added to the name\\n',\n", + " 'name': ' output_file'}],\n", + " 'return': ' Path to encrypted file\\n',\n", + " 'snippet': '# Generate a random key\\n'\n", + " 'key = generate_random_key()\\n'\n", + " '# Create a textfile to illustrate file encryption\\n'\n", + " 'textfile_path = make_textfile()\\n'\n", + " '# Encrypt the textfile\\n'\n", + " 'encrypt_file_with_key(textfile_path, key=key)\\n'}\n", + "{'description': 'Decrypts file with (Fernet) key',\n", + " 'example': '>>> # Generate a random key\\n'\n", + " '>>> key = generate_random_key()\\n'\n", + " '>>> # Create a textfile to encrypt file\\n'\n", + " '>>> textfile_path = make_textfile()\\n'\n", + " '>>> # Encrypt the textfile\\n'\n", + " '>>> encrypted_textfile = encrypt_file_with_key(textfile_path, '\n", + " 'key=key)\\n'\n", + " '>>> # Decrypt the newly encrypted file\\n'\n", + " '>>> decrypt_file_with_key(encrypted_textfile, key=key)\\n'\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\generated_textfile_encrypted_decrypted.txt'\\n\",\n", + " 'function_call': 'decrypt_file_with_key(input_path, key, output_path=None)',\n", + " 'icon': 'las la-lock-open',\n", + " 'keywords': ['decrypt',\n", + " 'random',\n", + " 'password',\n", + " 'secure',\n", + " 'secure file',\n", + " 'unlock'],\n", + " 'name': 'Decrypt file',\n", + " 'parameters': [{'description': ' Bytes-like file to be decrypted.\\n',\n", + " 'name': ' input_file'},\n", + " {'description': ' Path where key is stored.\\n', 'name': ' key'},\n", + " {'description': ' Outputfile, make sure to give this the same '\n", + " 'extension as basefile before encryption. '\n", + " 'Default is the same directory with '\n", + " '\"_decrypted\" added to the name \\n',\n", + " 'name': ' output_file'}],\n", + " 'return': ' Path to decrypted file\\n',\n", + " 'snippet': '# Generate a random key\\n'\n", + " 'key = generate_random_key()\\n'\n", + " '# Create a textfile to encrypt file\\n'\n", + " 'textfile_path = make_textfile()\\n'\n", + " '# Encrypt the textfile\\n'\n", + " 'encrypted_textfile = encrypt_file_with_key(textfile_path, '\n", + " 'key=key)\\n'\n", + " '# Decrypt the newly encrypted file\\n'\n", + " 'decrypt_file_with_key(encrypted_textfile, key=key)\\n'}\n", + "{'description': 'Generate key based on password and salt. If both password and '\n", + " 'salt are known the key can be regenerated.',\n", + " 'example': '>>> # Generate a key from password\\n'\n", + " \">>> key = generate_key_from_password(password='Sample password')\\n\"\n", + " \"b'7jGGF5w_xyI0CIZGCmLlnNyUvFpNvIUY08JCHopgAmm8='\\n\",\n", + " 'function_call': 'generate_key_from_password(password, salt=None)',\n", + " 'icon': 'las la-lock',\n", + " 'keywords': ['random',\n", + " 'key',\n", + " 'fernet',\n", + " 'hash',\n", + " 'security',\n", + " 'cryptography',\n", + " 'password',\n", + " 'secure',\n", + " 'salt'],\n", + " 'name': 'Key from password',\n", + " 'parameters': [{'description': ' Passwords\\n', 'name': ' password'},\n", + " {'description': ' Salt to generate key in combination with '\n", + " 'password. Default value is the hostname. Take '\n", + " 'in to account that hostname is necessary to '\n", + " 'generate key, e.g. when files are encrypted '\n", + " \"with salt 'A' and password 'B', both elements \"\n", + " 'are necessary to decrypt files.\\n',\n", + " 'name': ' salt'}],\n", + " 'return': ' Bytes-like object\\n',\n", + " 'snippet': '# Generate a key from password\\n'\n", + " \"key = generate_key_from_password(password='Sample password')\\n\"}\n", + "{'description': 'Generate hash from file',\n", + " 'example': '>>> # Generate a text file to illustrate hash\\n'\n", + " '>>> textfile_path = make_textfile()\\n'\n", + " '>>> # Get hash from textfile\\n'\n", + " '>>> generate_hash_from_file(textfile_path)\\n'\n", + " \"'1ba249ca5931f3c85fe44d354c2f274d'\\n\",\n", + " 'function_call': \"generate_hash_from_file(input_path, method='md5', \"\n", + " 'buffer_size=65536)',\n", + " 'icon': 'las la-fingerprint',\n", + " 'keywords': ['hash',\n", + " 'mdf5',\n", + " 'sha256',\n", + " 'blake2b',\n", + " 'identifier',\n", + " 'unique',\n", + " 'hashing',\n", + " 'fingerprint',\n", + " 'comparison'],\n", + " 'name': 'Hash from file',\n", + " 'parameters': [{'description': ' File to hash\\n', 'name': ' file'},\n", + " {'description': \" Method for hashing, choose between 'md5', \"\n", + " \"'sha256' and 'blake2b'. Note that different \"\n", + " 'methods generate different hashes. Default '\n", + " \"method is 'md5'.\\n\",\n", + " 'name': ' method'},\n", + " {'description': ' Buffer size for reading file in chunks, '\n", + " 'default value is 64kb\\n',\n", + " 'name': ' buffer_size'}],\n", + " 'return': ' Bytes-like object\\n',\n", + " 'snippet': '# Generate a text file to illustrate hash\\n'\n", + " 'textfile_path = make_textfile()\\n'\n", + " '# Get hash from textfile\\n'\n", + " 'generate_hash_from_file(textfile_path)\\n'}\n", + "{'description': 'Generate hash from text',\n", + " 'example': '>>> # Generate a hast from text\\n'\n", + " \">>> generate_hash_from_text('Sample text')\\n\"\n", + " \"'1ba249ca5931f3c85fe44d354c2f274d'\\n\",\n", + " 'function_call': \"generate_hash_from_text(text, method='md5')\",\n", + " 'icon': 'las la-fingerprint',\n", + " 'keywords': ['Hash',\n", + " 'mdf5',\n", + " 'sha256',\n", + " 'blake2b',\n", + " 'identifier',\n", + " 'unique',\n", + " 'hashing',\n", + " 'fingerprint',\n", + " 'text',\n", + " 'comparison'],\n", + " 'name': 'Hash from text',\n", + " 'parameters': [{'description': ' Text to hash\\n', 'name': ' file'},\n", + " {'description': \" Method for hashing, choose between 'md5', \"\n", + " \"'sha256' and 'blake2b'. Note that different \"\n", + " 'methods generate different hashes. Default '\n", + " \"method is 'md5'.\\n\",\n", + " 'name': ' method'}],\n", + " 'return': '',\n", + " 'snippet': '# Generate a hast from text\\n'\n", + " \"generate_hash_from_text('Sample text')\\n\"}\n", + "{'description': 'Random numbers can be integers (not a fractional number) or a '\n", + " 'float (fractional number).',\n", + " 'example': '>>> # Generate a random number\\n>>> generate_random_number()\\n7\\n',\n", + " 'function_call': 'generate_random_number(lower_limit=0, upper_limit=100, '\n", + " 'fractional=False)',\n", + " 'icon': 'las la-dice',\n", + " 'name': 'Random number',\n", + " 'parameters': [{'description': ' Lower limit for random number\\n',\n", + " 'name': ' lower_limit'},\n", + " {'description': ' Upper limit for random number\\n',\n", + " 'name': ' upper_limit'},\n", + " {'description': ' Setting this to True will generate '\n", + " 'fractional number. Default value is False and '\n", + " 'only generates whole numbers.\\n',\n", + " 'name': ' fractional'}],\n", + " 'return': ' Random integer or float\\n',\n", + " 'snippet': '# Generate a random number\\ngenerate_random_number()\\n'}\n", + "{'description': 'Generates a random boolean (True or False)',\n", + " 'example': '>>> # Generate a random boolean\\n'\n", + " '>>> generate_random_boolean()\\n'\n", + " 'True\\n',\n", + " 'function_call': 'generate_random_boolean()',\n", + " 'icon': 'las la-coins',\n", + " 'name': 'Random boolean',\n", + " 'parameters': [],\n", + " 'return': ' Boolean\\n',\n", + " 'snippet': '# Generate a random boolean\\ngenerate_random_boolean()\\n'}\n", + "{'description': 'Generates a random name. Adding a locale adds a more common '\n", + " 'name in the specified locale. Provides first name and last '\n", + " 'name.',\n", + " 'example': '>>> # Generate a random name\\n'\n", + " '>>> generate_random_name()\\n'\n", + " \"'Michelle Murphy'\\n\",\n", + " 'function_call': 'generate_random_name(locale=None)',\n", + " 'icon': 'las la-comment',\n", + " 'keywords': ['random',\n", + " 'sentence',\n", + " 'lorem ipsum',\n", + " 'text generater',\n", + " 'filler',\n", + " 'place holder',\n", + " 'noise',\n", + " 'random text'],\n", + " 'name': 'Random name',\n", + " 'parameters': [{'description': ' Add a locale to generate popular name for '\n", + " 'selected locale.\\n',\n", + " 'name': ' locale'},\n", + " {'description': ' Add a locale to generate popular name for '\n", + " 'selected locale.\\n',\n", + " 'name': ' locale'}],\n", + " 'return': ' Random sentence as string\\n',\n", + " 'snippet': '# Generate a random name\\ngenerate_random_name()\\n'}\n", + "{'description': 'Generates a random address. Specifying locale changes random '\n", + " 'locations and streetnames based on locale.',\n", + " 'example': '>>> # Generate a random address\\n'\n", + " '>>> generate_random_address()\\n'\n", + " \"'5639 Cynthia Bridge Suite 610\\n\"\n", + " \"'Port Nancy, GA 95894'\\n\",\n", + " 'function_call': 'generate_random_address(locale=None)',\n", + " 'icon': 'las la-map',\n", + " 'keywords': ['random',\n", + " 'address',\n", + " 'random address',\n", + " 'fake person ',\n", + " 'fake address',\n", + " 'fake person generator'],\n", + " 'name': 'Random address',\n", + " 'parameters': [{'description': ' Add a locale to generate popular name for '\n", + " 'selected locale.\\n',\n", + " 'name': ' locale'}],\n", + " 'return': ' Random address as string\\n',\n", + " 'snippet': '# Generate a random address\\ngenerate_random_address()\\n'}\n", + "{'description': 'Generates a random beep, only works on Windows',\n", + " 'example': '>>> # Generate a random beep\\n>>> generate_random_beep()\\n',\n", + " 'function_call': 'generate_random_beep(max_duration=2000, max_frequency=5000)',\n", + " 'icon': 'las la-volume-up',\n", + " 'keywords': ['beep', 'sound', 'random', 'noise', 'alert', 'notification'],\n", + " 'name': 'Random beep',\n", + " 'parameters': [{'description': ' Maximum random duration in miliseconds. '\n", + " 'Default value is 2 miliseconds\\n',\n", + " 'name': ' max_duration'},\n", + " {'description': ' Maximum random frequency in Hz. Default '\n", + " 'value is 5000 Hz.\\n',\n", + " 'name': ' max_frequency'}],\n", + " 'return': ' Sound\\n',\n", + " 'snippet': '# Generate a random beep\\ngenerate_random_beep()\\n'}\n", + "{'description': 'Generates a random date.',\n", + " 'example': '>>> # Generate a random date\\n'\n", + " '>>> generate_random_date()\\n'\n", + " \"01/01/2020 13:37'\\n\",\n", + " 'function_call': \"generate_random_date(formatting='%m/%d/%Y %I%M', \"\n", + " 'days_in_past=1000)',\n", + " 'icon': 'las la-calendar',\n", + " 'keywords': ['random',\n", + " 'date',\n", + " 'datetime',\n", + " 'random date',\n", + " 'fake date ',\n", + " 'calendar'],\n", + " 'name': 'Random date',\n", + " 'parameters': [{'description': ' Days in the past for which oldest random '\n", + " 'date is generated, default is 1000 days\\n',\n", + " 'name': ' days_in_past'},\n", + " {'description': \" Formatting of the dates, replace with 'None' \"\n", + " 'to get raw datetime format. e.g. '\n", + " \"format='Current month is %B' generates \"\n", + " \"'Current month is Januari' and \"\n", + " \"format='%m/%d/%Y %I:%M' generates format \"\n", + " '01/01/1900 00:00. \\n',\n", + " 'name': ' formatting'}],\n", + " 'return': ' Random date as string\\n',\n", + " 'snippet': '# Generate a random date\\ngenerate_random_date()\\n'}\n", + "{'description': 'Generates a random UUID4 (universally unique identifier). '\n", + " 'While the probability that a UUID will be duplicated is not '\n", + " 'zero, it is close enough to zero to be negligible.',\n", + " 'example': '>>> # Generate unique identifier\\n'\n", + " '>>> generate_unique_identifier()\\n'\n", + " \"'d72fd7ea-d682-4f78-8ca1-0ed34142a992'\\n\",\n", + " 'function_call': 'generate_unique_identifier()',\n", + " 'icon': 'las la-random',\n", + " 'keywords': ['unique', 'identifier', 'primary key', 'random'],\n", + " 'name': 'Generate unique identifier',\n", + " 'parameters': [],\n", + " 'return': ' Identifier as string\\n',\n", + " 'snippet': '# Generate unique identifier\\ngenerate_unique_identifier()\\n'}\n", + "{'description': 'Prompt the user for an input with a pop-up window.',\n", + " 'example': '>>> # Make a window pop-up ask for user input\\n'\n", + " '>>> ask_user_input()\\n'\n", + " \">>> # Type in text and press 'submit', e.g. 'Sample text'\\n\"\n", + " \"'Sample text'\\n\",\n", + " 'function_call': 'ask_user_input(title=\"Title\", label=\"Input\", '\n", + " 'password=False)',\n", + " 'icon': 'las la-window-maximize',\n", + " 'keywords': ['user input',\n", + " 'pop-up',\n", + " 'interaction',\n", + " 'popup',\n", + " 'window',\n", + " 'feedback',\n", + " 'screen',\n", + " 'ad-hoc',\n", + " 'attended'],\n", + " 'name': 'Ask user for input',\n", + " 'parameters': [{'description': ' Title for the pop-up window\\n',\n", + " 'name': ' title'},\n", + " {'description': ' The message to be shown to the user\\n',\n", + " 'name': ' message'}],\n", + " 'return': ' Inputted text as string\\n',\n", + " 'snippet': '# Make a window pop-up ask for user input\\n'\n", + " 'ask_user_input()\\n'\n", + " \"# Type in text and press 'submit', e.g. 'Sample text'\\n\"}\n", + "{'description': 'Prompt the user for a password. The password will be masked '\n", + " 'on screen while entering.',\n", + " 'example': '>>> # Make a window pop-up ask for user password\\n'\n", + " '>>> ask_user_password()\\n'\n", + " \">>> # Type in password and press 'submit', e.g. 'Sample \"\n", + " \"password'\\n\"\n", + " \"'Sample password'\\n\",\n", + " 'function_call': 'ask_user_password(label=\"Password\")',\n", + " 'icon': 'lar la-window-maximize',\n", + " 'keywords': ['user input',\n", + " 'pop-up',\n", + " 'interaction',\n", + " 'interactive',\n", + " 'credential',\n", + " 'popup',\n", + " 'window',\n", + " 'feedback',\n", + " 'password',\n", + " 'screen',\n", + " 'login',\n", + " 'attended'],\n", + " 'name': 'Ask user for password',\n", + " 'parameters': [{'description': ' Title for the pop-up window\\n',\n", + " 'name': ' title'},\n", + " {'description': ' The message to be shown to the user\\n',\n", + " 'name': ' message'}],\n", + " 'return': ' Inputted password as string\\n',\n", + " 'snippet': '# Make a window pop-up ask for user password\\n'\n", + " 'ask_user_password()\\n'\n", + " \"# Type in password and press 'submit', e.g. 'Sample password'\\n\"}\n", + "{'description': 'Prompt a popup which asks user for username and password and '\n", + " 'returns in plain text. Password will be masked.',\n", + " 'example': '>>> # Make a window pop-up ask user credentials\\n'\n", + " '>>> ask_credentials()\\n'\n", + " \">>> # Type in Username and Password 'submit', e.g. 'Sample \"\n", + " \"username' and 'Sample password'\\n\"\n", + " \"('Sample username', 'Sample password')\\n\",\n", + " 'function_call': 'ask_credentials(title=\"Credentials required\", '\n", + " 'dialogue_text_username=\"Username\", '\n", + " 'dialogue_text_password=\"Password\")',\n", + " 'icon': 'las la-window-maximize',\n", + " 'keywords': ['user input',\n", + " 'credentials',\n", + " 'interactive',\n", + " 'pop-up',\n", + " 'interaction',\n", + " 'popup',\n", + " 'window',\n", + " 'feedback',\n", + " 'password',\n", + " 'screen',\n", + " 'login',\n", + " 'attended'],\n", + " 'name': 'Ask user for credentials',\n", + " 'parameters': [{'description': ' Title for the popup\\n', 'name': ' title'},\n", + " {'description': ' Dialogue text for username\\n',\n", + " 'name': ' dialogue_text'},\n", + " {'description': ' Dialogue text for password\\n',\n", + " 'name': ' dialogue_text'}],\n", + " 'return': ' Typle with nputted username and password as strings\\n',\n", + " 'snippet': '# Make a window pop-up ask user credentials\\n'\n", + " 'ask_credentials()\\n'\n", + " \"# Type in Username and Password 'submit', e.g. 'Sample username' \"\n", + " \"and 'Sample password'\\n\"}\n", + "{'description': 'A pop-up message with title and message.',\n", + " 'example': '>>> # Show pop-up with message\\n'\n", + " '>>> display_message_box()\\n'\n", + " \">>> # Wait till user presses 'OK'\\n\"\n", + " 'True\\n',\n", + " 'function_call': 'display_message_box(title=\"Title\", message=\"Example '\n", + " 'message\")',\n", + " 'icon': 'las la-window-maximize',\n", + " 'keywords': ['message box',\n", + " 'warning',\n", + " 'info',\n", + " 'popup',\n", + " 'window',\n", + " 'feedback',\n", + " 'screen',\n", + " 'attended'],\n", + " 'name': 'Shows message box',\n", + " 'parameters': [{'description': ' Title for the pop-up window\\n',\n", + " 'name': ' title'},\n", + " {'description': ' The message to be shown to the user\\n',\n", + " 'name': ' message'}],\n", + " 'return': \" True if user presses 'OK'\\n\",\n", + " 'snippet': '# Show pop-up with message\\n'\n", + " 'display_message_box()\\n'\n", + " \"# Wait till user presses 'OK'\\n\"}\n", + "{'description': 'Display custom OSD (on-screen display) message. Can be used '\n", + " 'to display a message for a limited amount of time. Can be '\n", + " 'used for illustration, debugging or as OSD.',\n", + " 'example': '>>> # Display overlay message\\n>>> display_osd_message()\\n',\n", + " 'function_call': \"display_osd_message(message='Example message', seconds=5)\",\n", + " 'icon': 'las la-tv',\n", + " 'keywords': ['message box',\n", + " 'osd',\n", + " 'overlay',\n", + " 'info warning',\n", + " 'info',\n", + " 'popup',\n", + " 'window',\n", + " 'feedback',\n", + " 'screen',\n", + " 'login',\n", + " 'attended'],\n", + " 'name': 'Display overlay message',\n", + " 'parameters': [{'description': ' Message to be displayed\\n',\n", + " 'name': ' message'}],\n", + " 'return': '',\n", + " 'snippet': '# Display overlay message\\ndisplay_osd_message()\\n'}\n", + "{'description': 'Open the Chrome Browser with the Selenium webdriver. Canb be '\n", + " 'used to automate manipulations in the browser.Different '\n", + " 'elements can be found as:',\n", + " 'example': '>>> # Open the browser\\n'\n", + " '>>> browser = Chrome()\\n'\n", + " '>>> # Go to a website\\n'\n", + " \">>> browser.get('https://automagica.com')\\n\"\n", + " '>>> # Close browser\\n'\n", + " '>>> browser.quit()\\n',\n", + " 'function_call': 'Chrome(load_images=True, headless=False)',\n", + " 'icon': 'lab la-chrome',\n", + " 'keywords': ['chrome',\n", + " 'browsing',\n", + " 'browser',\n", + " 'internet',\n", + " 'surfing',\n", + " 'web',\n", + " 'webscraping',\n", + " 'www',\n", + " 'selenium',\n", + " 'crawling',\n", + " 'webtesting',\n", + " 'mozilla',\n", + " 'firefox',\n", + " 'internet explorer'],\n", + " 'name': 'Open Chrome Browser',\n", + " 'parameters': [{'description': ' Do not load images (bool). This could speed '\n", + " 'up loading pages\\n',\n", + " 'name': ' load_images'},\n", + " {'description': ' Run headless, this means running without a '\n", + " 'visible window (bool)\\n',\n", + " 'name': ' headless'}],\n", + " 'return': '',\n", + " 'snippet': '# Open the browser\\n'\n", + " 'browser = Chrome()\\n'\n", + " '# Go to a website\\n'\n", + " \"browser.get('https://automagica.com')\\n\"\n", + " '# Close browser\\n'\n", + " 'browser.quit()\\n'}\n", + "{'description': 'Save all images on current page in the Browser',\n", + " 'example': '>>> # Open the browser\\n'\n", + " '>>> browser = Chrome()\\n'\n", + " '>>> # Go to a website\\n'\n", + " \">>> browser.get('https://www.nytimes.com/')\\n\"\n", + " '>>> # Save all images\\n'\n", + " '>>> browser.save_all_images()\\n'\n", + " '>>> browser.quit()\\n'\n", + " \"['C:\\\\\\\\Users\\\\\\\\\\\\\\\\image1.png', \"\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\image2.jpg', \"\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\image4.gif']\\n\",\n", + " 'function_call': 'save_all_images(output_path=None)',\n", + " 'icon': 'las la-images',\n", + " 'keywords': ['image scraping',\n", + " 'chrome',\n", + " 'internet',\n", + " 'browsing',\n", + " 'browser',\n", + " 'surfing',\n", + " 'web',\n", + " 'webscraping',\n", + " 'www',\n", + " 'selenium',\n", + " 'crawling',\n", + " 'webtesting',\n", + " 'mozilla',\n", + " 'firefox',\n", + " 'internet explorer'],\n", + " 'name': 'Save all images',\n", + " 'parameters': [{'description': ' Path where images can be saved. Default '\n", + " 'value is home directory.\\n',\n", + " 'name': ' output_path'}],\n", + " 'return': ' List with paths to images\\n',\n", + " 'snippet': '# Open the browser\\n'\n", + " 'browser = Chrome()\\n'\n", + " '# Go to a website\\n'\n", + " \"browser.get('https://www.nytimes.com/')\\n\"\n", + " '# Save all images\\n'\n", + " 'browser.save_all_images()\\n'\n", + " 'browser.quit()\\n'}\n", + "{'description': 'Find all elements by their text. Text does not need to match '\n", + " 'exactly, part of text is enough.',\n", + " 'example': '>>> # Open the browser\\n'\n", + " '>>> browser = Chrome()\\n'\n", + " '>>> # Go to a website\\n'\n", + " \">>> browser.get('https://nytimes.com')\\n\"\n", + " '>>> # Find elements by text\\n'\n", + " \">>> browser.find_elements_by_text('world')\\n\"\n", + " '[webelement1, webelement2 , .. ]\\n',\n", + " 'function_call': 'find_elements_by_text(text)',\n", + " 'icon': 'las la-align-center',\n", + " 'keywords': ['element',\n", + " 'element by text',\n", + " 'chrome',\n", + " 'internet',\n", + " 'browsing',\n", + " 'browser',\n", + " 'surfing',\n", + " 'web',\n", + " 'webscraping',\n", + " 'www',\n", + " 'selenium',\n", + " 'crawling',\n", + " 'webtesting',\n", + " 'mozilla',\n", + " 'firefox',\n", + " 'internet explorer'],\n", + " 'name': 'Find elements by text',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open the browser\\n'\n", + " 'browser = Chrome()\\n'\n", + " '# Go to a website\\n'\n", + " \"browser.get('https://nytimes.com')\\n\"\n", + " '# Find elements by text\\n'\n", + " \"browser.find_elements_by_text('world')\\n\"}\n", + "{'description': 'Find one element by text. Text does not need to match '\n", + " 'exactly, part of text is enough.',\n", + " 'example': '>>> # Open the browser\\n'\n", + " '>>> browser = Chrome()\\n'\n", + " '>>> # Go to a website\\n'\n", + " \">>> browser.get('https://nytimes.com')\\n\"\n", + " '>>> # Find elements by text\\n'\n", + " \">>> browser.find_element_by_text('world')\\n\"\n", + " 'webelement\\n',\n", + " 'function_call': 'find_element_by_text(text)',\n", + " 'icon': 'las la-align-center',\n", + " 'keywords': ['element',\n", + " 'element by text',\n", + " 'chrome',\n", + " 'internet',\n", + " 'browsing',\n", + " 'browser',\n", + " 'surfing',\n", + " 'web',\n", + " 'webscraping',\n", + " 'www',\n", + " 'selenium',\n", + " 'crawling',\n", + " 'webtesting',\n", + " 'mozilla',\n", + " 'firefox',\n", + " 'internet explorer'],\n", + " 'name': 'Find element by text',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open the browser\\n'\n", + " 'browser = Chrome()\\n'\n", + " '# Go to a website\\n'\n", + " \"browser.get('https://nytimes.com')\\n\"\n", + " '# Find elements by text\\n'\n", + " \"browser.find_element_by_text('world')\\n\"}\n", + "{'description': 'Find all links on a webpage in the browser',\n", + " 'example': '>>> # Open the browser\\n'\n", + " '>>> browser = Chrome()\\n'\n", + " '>>> # Go to a website\\n'\n", + " \">>> browser.get('https://nytimes.com')\\n\"\n", + " '>>> # Find elements by text\\n'\n", + " '>>> browser.find_all_links()\\n'\n", + " '[webelement1, webelement2 , .. ]\\n',\n", + " 'function_call': 'find_all_links(self)',\n", + " 'icon': 'las la-window-restore',\n", + " 'keywords': ['random',\n", + " 'element',\n", + " 'element by text',\n", + " 'chrome',\n", + " 'internet',\n", + " 'browsing',\n", + " 'browser',\n", + " 'surfing',\n", + " 'web',\n", + " 'webscraping',\n", + " 'www',\n", + " 'selenium',\n", + " 'crawling',\n", + " 'webtesting',\n", + " 'mozilla',\n", + " 'firefox',\n", + " 'internet explorer'],\n", + " 'name': 'Find all links',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open the browser\\n'\n", + " 'browser = Chrome()\\n'\n", + " '# Go to a website\\n'\n", + " \"browser.get('https://nytimes.com')\\n\"\n", + " '# Find elements by text\\n'\n", + " 'browser.find_all_links()\\n'}\n", + "{'description': 'Highlight elements in yellow in the browser',\n", + " 'example': '>>> # Open the browser\\n'\n", + " '>>> browser = Chrome()\\n'\n", + " '>>> # Go to a website\\n'\n", + " \">>> browser.get('https://wikipedia.org')\\n\"\n", + " '>>> # Find all links\\n'\n", + " '>>> links = browser.find_all_links()\\n'\n", + " '>>> # Select first link to highlight for illustration\\n'\n", + " '>>> first_link = links[0]\\n'\n", + " '>>> # Highlight first link\\n'\n", + " '>>> browser.highlight(first_link)\\n',\n", + " 'function_call': 'highlight(element)',\n", + " 'icon': 'las la-highlighter',\n", + " 'keywords': ['element',\n", + " 'element by text',\n", + " 'chrome',\n", + " 'internet',\n", + " 'browsing',\n", + " 'browser',\n", + " 'surfing',\n", + " 'web',\n", + " 'webscraping',\n", + " 'www',\n", + " 'selenium',\n", + " 'crawling',\n", + " 'webtesting',\n", + " 'mozilla',\n", + " 'firefox',\n", + " 'internet explorer'],\n", + " 'name': 'Highlight element',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open the browser\\n'\n", + " 'browser = Chrome()\\n'\n", + " '# Go to a website\\n'\n", + " \"browser.get('https://wikipedia.org')\\n\"\n", + " '# Find all links\\n'\n", + " 'links = browser.find_all_links()\\n'\n", + " '# Select first link to highlight for illustration\\n'\n", + " 'first_link = links[0]\\n'\n", + " '# Highlight first link\\n'\n", + " 'browser.highlight(first_link)\\n'}\n", + "{'description': 'Quit the browser by exiting gracefully. One can also use the '\n", + " \"native 'quit' function, e.g. 'browser.quit()'\",\n", + " 'example': '>>> # Open the browser\\n'\n", + " '>>> browser = Chrome()\\n'\n", + " '>>> # Go to a website\\n'\n", + " \">>> browser.get('https://automagica.com')\\n\"\n", + " '>>> # Close browser\\n'\n", + " '>>> browser.exit()\\n',\n", + " 'function_call': 'exit(self)',\n", + " 'icon': 'las la-window-close',\n", + " 'keywords': ['quit',\n", + " 'exit',\n", + " 'close',\n", + " 'element',\n", + " 'element by text',\n", + " 'chrome',\n", + " 'internet',\n", + " 'browsing',\n", + " 'browser',\n", + " 'surfing',\n", + " 'web',\n", + " 'webscraping',\n", + " 'www',\n", + " 'selenium',\n", + " 'crawling',\n", + " 'webtesting',\n", + " 'mozilla',\n", + " 'firefox',\n", + " 'internet explorer'],\n", + " 'name': 'Exit the browser',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open the browser\\n'\n", + " 'browser = Chrome()\\n'\n", + " '# Go to a website\\n'\n", + " \"browser.get('https://automagica.com')\\n\"\n", + " '# Close browser\\n'\n", + " 'browser.exit()\\n'}\n", + "{'description': 'Find all elements with specified xpath on a webpage in the '\n", + " \"the browser. Can also use native 'find_elements_by_xpath' \"\n", + " 'function e.g. browser.find_elements_by_xpath()You can easily',\n", + " 'example': '>>> # Open the browser\\n'\n", + " '>>> browser = Chrome()\\n'\n", + " '>>> # Go to a website\\n'\n", + " \">>> browser.get('https://wikipedia.org')\\n\"\n", + " '>>> # Find element by xpath\\n'\n", + " \">>> browser.find_xpaths('//*[@id=\\\\'js-link-box-en\\\\']')\\n\"\n", + " '[webelement1, webelement2 , .. ]\\n',\n", + " 'function_call': 'find_all_xpaths(element)',\n", + " 'icon': 'las la-times',\n", + " 'keywords': ['random',\n", + " 'element',\n", + " 'xpath',\n", + " 'xml',\n", + " 'element by text',\n", + " 'chrome',\n", + " 'internet',\n", + " 'browsing',\n", + " 'browser',\n", + " 'surfing',\n", + " 'web',\n", + " 'webscraping',\n", + " 'www',\n", + " 'selenium',\n", + " 'crawling',\n", + " 'webtesting',\n", + " 'mozilla',\n", + " 'firefox',\n", + " 'internet explorer'],\n", + " 'name': 'Find all XPaths',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open the browser\\n'\n", + " 'browser = Chrome()\\n'\n", + " '# Go to a website\\n'\n", + " \"browser.get('https://wikipedia.org')\\n\"\n", + " '# Find element by xpath\\n'\n", + " \"browser.find_xpaths('//*[@id=\\\\'js-link-box-en\\\\']')\\n\"}\n", + "{'description': 'Find all element with specified xpath on a webpage in the the '\n", + " \"browser. Can also use native 'find_elements_by_xpath' \"\n", + " 'function e.g. browser.find_element_by_xpath()',\n", + " 'example': '>>> # Open the browser\\n'\n", + " '>>> browser = Chrome()\\n'\n", + " '>>> # Go to a website\\n'\n", + " \">>> browser.get('https://wikipedia.org')\\n\"\n", + " '>>> # Find element by xpath\\n'\n", + " '>>> elements = '\n", + " \"browser.find_xpath('//*[@id=\\\\'js-link-box-en\\\\']')\\n\"\n", + " '>>> # We can now use this element, for example to click on\\n'\n", + " '>>> element.click()\\n',\n", + " 'function_call': 'find_xpath(element)',\n", + " 'icon': 'las la-times',\n", + " 'keywords': ['random',\n", + " 'xpath',\n", + " 'element',\n", + " 'xml element by text',\n", + " 'chrome',\n", + " 'internet',\n", + " 'browsing',\n", + " 'browser',\n", + " 'surfing',\n", + " 'web',\n", + " 'webscraping',\n", + " 'www',\n", + " 'selenium',\n", + " 'crawling',\n", + " 'webtesting',\n", + " 'mozilla',\n", + " 'firefox',\n", + " 'internet explorer'],\n", + " 'name': 'Find XPath in browser',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open the browser\\n'\n", + " 'browser = Chrome()\\n'\n", + " '# Go to a website\\n'\n", + " \"browser.get('https://wikipedia.org')\\n\"\n", + " '# Find element by xpath\\n'\n", + " \"elements = browser.find_xpath('//*[@id=\\\\'js-link-box-en\\\\']')\\n\"\n", + " '# We can now use this element, for example to click on\\n'\n", + " 'element.click()\\n'}\n", + "{'description': 'Add a credential which stores credentials locally and '\n", + " 'securely. All parameters should be Unicode text.',\n", + " 'example': \">>> set_credential('SampleUsername', 'SamplePassword')\\n\",\n", + " 'function_call': 'set_credential(username=None, password=None, '\n", + " 'system=\"Automagica\")',\n", + " 'icon': 'las la-key',\n", + " 'keywords': ['credential',\n", + " 'login',\n", + " 'password',\n", + " 'username',\n", + " 'store',\n", + " 'vault',\n", + " 'secure',\n", + " 'credentials',\n", + " 'store',\n", + " 'log in',\n", + " 'encrypt'],\n", + " 'name': 'Set credential',\n", + " 'parameters': [{'description': ' Username for which credential will be '\n", + " 'added.\\n',\n", + " 'name': ' username'},\n", + " {'description': ' Password to add\\n', 'name': ' password'},\n", + " {'description': ' Name of the system for which credentials are '\n", + " 'stored. Extra safety measure and method for '\n", + " 'keeping passwords for similar usernames on '\n", + " 'different applications a part. Highly '\n", + " 'recommended to change default value.\\n',\n", + " 'name': ' system'}],\n", + " 'return': ' Stores credentials locally\\n',\n", + " 'snippet': \"set_credential('SampleUsername', 'SamplePassword')\\n\"}\n", + "{'description': 'Delete a locally stored credential. All parameters should be '\n", + " 'Unicode text.',\n", + " 'example': \">>> set_credential('SampleUsername', 'SamplePassword')\\n\"\n", + " \">>> delete_credential('SampleUsername', 'SamplePassword')\\n\",\n", + " 'function_call': 'delete_credential(username=None, password=None, '\n", + " 'system=\"Automagica\")',\n", + " 'icon': 'las la-key',\n", + " 'keywords': ['credential',\n", + " 'delete',\n", + " 'login',\n", + " 'password',\n", + " 'username',\n", + " 'store',\n", + " 'vault',\n", + " 'secure',\n", + " 'credentials',\n", + " 'store',\n", + " 'log in',\n", + " 'encrypt'],\n", + " 'name': 'Delete credential',\n", + " 'parameters': [{'description': ' Username for which credential (username + '\n", + " 'password) will be deleted.\\n',\n", + " 'name': ' username'},\n", + " {'description': ' Name of the system for which password will '\n", + " 'be deleted. \\n',\n", + " 'name': ' system'}],\n", + " 'return': '',\n", + " 'snippet': \"set_credential('SampleUsername', 'SamplePassword')\\n\"\n", + " \"delete_credential('SampleUsername', 'SamplePassword')\\n\"}\n", + "{'description': 'Get a locally stored redential. All parameters should be '\n", + " 'Unicode text.',\n", + " 'example': \">>> set_credential('SampleUsername', 'SamplePassword')\\n\"\n", + " \">>> get_credential('SampleUsername')\\n\"\n", + " \"'SamplePassword'\\n\",\n", + " 'function_call': 'get_credential(username=None, system=\"Automagica\")',\n", + " 'icon': 'las la-key',\n", + " 'keywords': ['credential',\n", + " 'get',\n", + " 'delete',\n", + " 'login',\n", + " 'password',\n", + " 'username',\n", + " 'store',\n", + " 'vault',\n", + " 'secure',\n", + " 'credentials',\n", + " 'store',\n", + " 'log in',\n", + " 'encrypt'],\n", + " 'name': 'Get credential',\n", + " 'parameters': [{'description': ' Username to get password for.\\n',\n", + " 'name': ' username'},\n", + " {'description': ' Name of the system for which credentials are '\n", + " 'retreived.\\n',\n", + " 'name': ' system'}],\n", + " 'return': ' Stored credential as string\\n',\n", + " 'snippet': \"set_credential('SampleUsername', 'SamplePassword')\\n\"\n", + " \"get_credential('SampleUsername')\\n\"}\n", + "{'description': 'Can be used to automate activites for FTP',\n", + " 'example': '>>> # This example uses the Rebex FPT test server.\\n'\n", + " '>>> # Take caution uploading and downloading from this server as '\n", + " 'it is public\\n'\n", + " \">>> ftp = FTP('test.rebex.net', 'demo', 'password')\\n\",\n", + " 'function_call': 'FTP(server, username, password)',\n", + " 'icon': 'las la-folder-open',\n", + " 'keywords': ['FTP',\n", + " 'file transfer protocol',\n", + " 'filezilla',\n", + " 'winscp',\n", + " 'server',\n", + " 'remote',\n", + " 'folder',\n", + " 'folders'],\n", + " 'name': 'Create FTP connection',\n", + " 'parameters': [{'description': ' Name of the server\\n', 'name': ' server'},\n", + " {'description': ' Username \\n', 'name': ' username'},\n", + " {'description': ' Password\\n', 'name': ' password'}],\n", + " 'return': '',\n", + " 'snippet': '# This example uses the Rebex FPT test server.\\n'\n", + " '# Take caution uploading and downloading from this server as it '\n", + " 'is public\\n'\n", + " \"ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"}\n", + "{'description': 'Downloads a file from FTP server. Connection needs to be '\n", + " 'established first.',\n", + " 'example': '>>> # This example uses the Rebex FPT test server.\\n'\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " '>>> # Take caution uploading and downloading from this server as '\n", + " 'it is public\\n'\n", + " \">>> ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " \">>> # Download Rebex public file 'readme.txt'\\n\"\n", + " \">>> ftp.download_file('readme.txt')\\n\"\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\readme_downloaded.txt'\\n\",\n", + " 'function_call': 'download_file(input_path, output_path=None)',\n", + " 'icon': 'las la-download',\n", + " 'keywords': ['FTP',\n", + " 'file transfer protocol',\n", + " 'download',\n", + " 'filezilla',\n", + " 'winscp',\n", + " 'server',\n", + " 'remote',\n", + " 'folder',\n", + " 'folders'],\n", + " 'name': 'Download file',\n", + " 'parameters': [{'description': ' Path to the file on the FPT server to '\n", + " 'download\\n',\n", + " 'name': ' input_path'},\n", + " {'description': ' Destination path for downloaded files. '\n", + " 'Default is the same directory with '\n", + " '\"_downloaded\" added to the name\\n',\n", + " 'name': ' output_path'}],\n", + " 'return': ' Path to output file as string \\n',\n", + " 'snippet': '# This example uses the Rebex FPT test server.\\n'\n", + " '# Take caution uploading and downloading from this server as it '\n", + " 'is public\\n'\n", + " \"ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " \"# Download Rebex public file 'readme.txt'\\n\"\n", + " \"ftp.download_file('readme.txt')\\n\"}\n", + "{'description': 'Upload file to FTP server',\n", + " 'example': '>>> # This example uses the Rebex FPT test server.\\n'\n", + " '>>> # Take caution uploading and downloading from this server as '\n", + " 'it is public\\n'\n", + " \">>> ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " '>>> # Create a .txt file for illustration\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> # Upload file to FTP test server\\n'\n", + " '>>> # Not that this might result in a persmission error for '\n", + " \"public FPT's\\n\"\n", + " '>>> ftp.upload_file(textfile)\\n',\n", + " 'function_call': 'upload_file(input_path, output_path=None)',\n", + " 'icon': 'las la-upload',\n", + " 'keywords': ['FTP',\n", + " 'upload',\n", + " 'fptfile transfer protocol',\n", + " 'filezilla',\n", + " 'winscp',\n", + " 'server',\n", + " 'remote',\n", + " 'folder',\n", + " 'folders'],\n", + " 'name': 'Upload file',\n", + " 'parameters': [{'description': ' Path file that will be uploaded\\n',\n", + " 'name': ' from_path'},\n", + " {'description': ' Destination path to upload. \\n',\n", + " 'name': ' to_path'}],\n", + " 'return': ' Patht to uploaded file as string\\n',\n", + " 'snippet': '# This example uses the Rebex FPT test server.\\n'\n", + " '# Take caution uploading and downloading from this server as it '\n", + " 'is public\\n'\n", + " \"ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " '# Create a .txt file for illustration\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " '# Upload file to FTP test server\\n'\n", + " '# Not that this might result in a persmission error for public '\n", + " \"FPT's\\n\"\n", + " 'ftp.upload_file(textfile)\\n'}\n", + "{'description': 'Generate a list of all the files in the FTP directory',\n", + " 'example': '>>> # This example uses the Rebex FPT test server.\\n'\n", + " '>>> # Take caution uploading and downloading from this server as '\n", + " 'it is public\\n'\n", + " \">>> ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " '>>> # Show all files in main directory\\n'\n", + " '>>> ftp.enumerate_files()\\n'\n", + " '10-27-15 03:46PM pub\\n'\n", + " '04-08-14 03:09PM 403 readme.txt\\n'\n", + " \"'226 Transfer complete.'\\n\",\n", + " 'function_call': 'enumerate_files(path=\"/\")',\n", + " 'icon': 'las la-list-ol',\n", + " 'keywords': ['FTP',\n", + " 'list',\n", + " 'upload',\n", + " 'fptfile transfer protocol',\n", + " 'filezilla',\n", + " 'winscp',\n", + " 'server',\n", + " 'remote',\n", + " 'folder',\n", + " 'folders'],\n", + " 'name': 'List FTP files',\n", + " 'parameters': [{'description': ' Path to list files from. Default is the main '\n", + " 'directory\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' Prints list of all files and directories\\n',\n", + " 'snippet': '# This example uses the Rebex FPT test server.\\n'\n", + " '# Take caution uploading and downloading from this server as it '\n", + " 'is public\\n'\n", + " \"ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " '# Show all files in main directory\\n'\n", + " 'ftp.enumerate_files()\\n'}\n", + "{'description': 'Check if FTP directory exists',\n", + " 'example': '>>> # This example uses the Rebex FPT test server.\\n'\n", + " '>>> # Take caution uploading and downloading from this server as '\n", + " 'it is public\\n'\n", + " \">>> ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " \">>> # Check if 'pub' folder exists in main directory\\n\"\n", + " \">>> ftp.directory_exists('\\\\\\\\pub')\\n\"\n", + " 'True\\n',\n", + " 'function_call': 'directory_exists(path=\"/\")',\n", + " 'icon': 'las la-list-ol',\n", + " 'keywords': ['FTP',\n", + " 'list',\n", + " 'upload',\n", + " 'fptfile transfer protocol',\n", + " 'filezilla',\n", + " 'winscp',\n", + " 'server',\n", + " 'remote',\n", + " 'folder',\n", + " 'folders'],\n", + " 'name': 'Check FTP directory',\n", + " 'parameters': [{'description': ' Path to check on existence. Default is main '\n", + " 'directory\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' Boolean\\n',\n", + " 'snippet': '# This example uses the Rebex FPT test server.\\n'\n", + " '# Take caution uploading and downloading from this server as it '\n", + " 'is public\\n'\n", + " \"ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " \"# Check if 'pub' folder exists in main directory\\n\"\n", + " \"ftp.directory_exists('\\\\\\\\pub')\\n\"}\n", + "{'description': 'Create a FTP directory. Note that sufficient permissions are '\n", + " 'present',\n", + " 'example': '>>> # This example uses the Rebex FPT test server.\\n'\n", + " '>>> # Trying to create a directory will most likely fail due to '\n", + " 'permission\\n'\n", + " \">>> ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " '>>> # Create directory\\n'\n", + " \">>> ftp.create_directory('brand_new_directory') \\n\"\n", + " 'False\\n',\n", + " 'function_call': 'create_directory(directory_name, path=\"/\")',\n", + " 'icon': 'las la-folder-plus',\n", + " 'keywords': ['FTP',\n", + " 'create',\n", + " 'create folder',\n", + " 'new',\n", + " 'new folder',\n", + " 'fptfile transfer protocol',\n", + " 'filezilla',\n", + " 'winscp',\n", + " 'server',\n", + " 'remote',\n", + " 'folder',\n", + " 'folders'],\n", + " 'name': 'Create FTP directory',\n", + " 'parameters': [{'description': ' Name of the new directory, should be a '\n", + " \"string e.g. 'my_directory'\\n\",\n", + " 'name': ' directory_name'},\n", + " {'description': ' Path to parent directory where to make new '\n", + " 'directory. Default is main directory\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' Boolean if creation was succesful (True) or failed (False)\\n',\n", + " 'snippet': '# This example uses the Rebex FPT test server.\\n'\n", + " '# Trying to create a directory will most likely fail due to '\n", + " 'permission\\n'\n", + " \"ftp = FTP('test.rebex.net', 'demo', 'password')\\n\"\n", + " '# Create directory\\n'\n", + " \"ftp.create_directory('brand_new_directory') \\n\"}\n", + "{'description': 'Press and release an entered key. Make sure your keyboard is '\n", + " 'on US layout (standard QWERTY).If you are using this on Mac '\n", + " 'Os you might need to grant acces to your terminal '\n", + " 'application. (Security Preferences > Security & Privacy > '\n", + " 'Privacy > Accessibility)',\n", + " 'example': '>>> # Open notepad to illustrate typing\\n'\n", + " \">>> run('notepad.exe')\\n\"\n", + " '>>> # Press some keys\\n'\n", + " \">>> press_key('a')\\n\"\n", + " \">>> press_key('enter')\\n\"\n", + " \">>> press_key('b')\\n\"\n", + " \">>> press_key('enter')\\n\"\n", + " \">>> press_key('c')\\n\",\n", + " 'function_call': 'press_key(key=None)',\n", + " 'icon': 'las la-keyboard',\n", + " 'keywords': ['keyboard',\n", + " 'typing',\n", + " 'type',\n", + " 'key',\n", + " 'keystroke',\n", + " 'hotkey',\n", + " 'press',\n", + " 'press key'],\n", + " 'name': 'Press key',\n", + " 'parameters': [{'description': ' Key to press\\n', 'name': ' key'}],\n", + " 'return': ' Keypress\\n',\n", + " 'snippet': '# Open notepad to illustrate typing\\n'\n", + " \"run('notepad.exe')\\n\"\n", + " '# Press some keys\\n'\n", + " \"press_key('a')\\n\"\n", + " \"press_key('enter')\\n\"\n", + " \"press_key('b')\\n\"\n", + " \"press_key('enter')\\n\"\n", + " \"press_key('c')\\n\"}\n", + "{'description': 'Press a combination of two or three keys simultaneously. Make '\n", + " 'sure your keyboard is on US layout (standard QWERTY).',\n", + " 'example': '>>> # Open notepad to illustrate typing\\n'\n", + " \">>> run('notepad.exe')\\n\"\n", + " \">>> # Press 'ctrl + s' to prompt save window \\n\"\n", + " \">>> press_key_combination('ctrl', 's')\\n\",\n", + " 'function_call': 'press_key_combination(first_key, second_key, '\n", + " 'third_key=None, force_pyautogui=False)',\n", + " 'icon': 'las la-keyboard',\n", + " 'keywords': ['keyboard',\n", + " 'key combination',\n", + " 'shortcut',\n", + " 'typing',\n", + " 'type',\n", + " 'key',\n", + " 'keystroke',\n", + " 'hotkey',\n", + " 'press',\n", + " 'press key'],\n", + " 'name': 'Press key combination',\n", + " 'parameters': [{'description': ' First key to press\\n', 'name': ' first_key'},\n", + " {'description': ' Second key to press\\n',\n", + " 'name': ' second_key'},\n", + " {'description': ' Third key to press, this is optional.\\n',\n", + " 'name': ' third_key'},\n", + " {'description': ' Set parameter to true to force the use of '\n", + " 'pyautogui. This could help when certain '\n", + " 'keypresses do not work correctly.\\n',\n", + " 'name': ' force_pyautogui'}],\n", + " 'return': ' Key combination\\n',\n", + " 'snippet': '# Open notepad to illustrate typing\\n'\n", + " \"run('notepad.exe')\\n\"\n", + " \"# Press 'ctrl + s' to prompt save window \\n\"\n", + " \"press_key_combination('ctrl', 's')\\n\"}\n", + "{'description': 'Types text in the current active field by simulating keyboard '\n", + " 'typing. Make sure your keyboard is on US layout (standard '\n", + " 'QWERTY).',\n", + " 'example': '>>> # Open notepad to illustrate typing\\n'\n", + " \">>> run('notepad.exe')\\n\"\n", + " '>>> # Type a story\\n'\n", + " \">>> type_text('Why was the robot mad? \\\\n They kept pushing his \"\n", + " \"buttons!')\\n\",\n", + " 'function_call': \"type_text(text='', interval_seconds=0.01)\",\n", + " 'icon': 'las la-keyboard',\n", + " 'keywords': ['keyboard',\n", + " 'keystrokes',\n", + " 'key combination',\n", + " 'shortcut',\n", + " 'typing',\n", + " 'type',\n", + " 'key',\n", + " 'keystroke',\n", + " 'hotkey',\n", + " 'press',\n", + " 'press key'],\n", + " 'name': 'Type text',\n", + " 'parameters': [{'description': ' Text in string format to type. Note that you '\n", + " 'can only press single character keys. Special '\n", + " 'keys like \":\", \"F1\",... can not be part of '\n", + " 'the text argument.\\n',\n", + " 'name': ' text'},\n", + " {'description': ' Time in seconds between two keystrokes. '\n", + " 'Defautl value is 0.01 seconds.\\n',\n", + " 'name': ' interval_seconds'}],\n", + " 'return': ' Keystrokes\\n',\n", + " 'snippet': '# Open notepad to illustrate typing\\n'\n", + " \"run('notepad.exe')\\n\"\n", + " '# Type a story\\n'\n", + " \"type_text('Why was the robot mad? \\\\n They kept pushing his \"\n", + " \"buttons!')\\n\"}\n", + "{'description': 'Get the x and y pixel coordinates of current mouse '\n", + " 'position.These coordinates represent the absolute pixel '\n", + " 'position of the mouse on the computer screen. The '\n", + " 'x-coördinate starts on the left side and increases going '\n", + " 'right. The y-coördinate increases going down.',\n", + " 'example': '>>> get_mouse_position()\\n(314, 271)\\n',\n", + " 'function_call': 'get_mouse_position(delay=None, to_clipboard=False)',\n", + " 'icon': 'las la-mouse',\n", + " 'keywords': ['mouse',\n", + " 'mouse automation',\n", + " 'click',\n", + " 'right click',\n", + " 'mouse button',\n", + " 'move mouse',\n", + " 'position',\n", + " 'pixel'],\n", + " 'name': 'Get mouse coordinates',\n", + " 'parameters': [{'description': ' Delay in seconds before capturing mouse '\n", + " 'position.\\n',\n", + " 'name': ' delay'},\n", + " {'description': ' Put the coordinates in the clipboard e.g. '\n", + " \"'x=1, y=1'\\n\",\n", + " 'name': ' to_clipboard'}],\n", + " 'return': ' Tuple with (x, y) coordinates\\n',\n", + " 'snippet': 'get_mouse_position()\\n'}\n", + "{'description': 'Displays mouse position in an overlay. Refreshes every two '\n", + " 'seconds. Can be used to find mouse position of element on the '\n", + " 'screen.These coordinates represent the absolute pixel '\n", + " 'position of the mouse on the computer screen. The '\n", + " 'x-coördinate starts on the left side and increases going '\n", + " 'right. The y-coördinate increases going down.',\n", + " 'example': '>>> display_mouse_position()\\n',\n", + " 'function_call': 'display_mouse_position(duration=10)',\n", + " 'icon': 'lars la-search-location',\n", + " 'keywords': ['mouse',\n", + " 'osd',\n", + " 'overlay',\n", + " 'show',\n", + " 'display',\n", + " 'mouse automation',\n", + " 'click',\n", + " 'right click',\n", + " 'mouse button',\n", + " 'move mouse',\n", + " 'position',\n", + " 'pixel'],\n", + " 'name': 'Display mouse position',\n", + " 'parameters': [{'description': ' Duration to show overlay.\\n',\n", + " 'name': ' duration'}],\n", + " 'return': ' Overlay with (x, y) coordinates\\n',\n", + " 'snippet': 'display_mouse_position()\\n'}\n", + "{'description': 'Clicks on a pixel position on the visible screen determined '\n", + " 'by x and y coordinates.',\n", + " 'example': '>>> click(x=100, y=100)\\n',\n", + " 'function_call': 'click(x=None, y=None)',\n", + " 'icon': 'las la-mouse-pointer',\n", + " 'keywords': ['mouse',\n", + " 'osd',\n", + " 'overlay',\n", + " 'show',\n", + " 'display',\n", + " 'mouse automation',\n", + " 'click',\n", + " 'right click',\n", + " 'mouse button',\n", + " 'move mouse',\n", + " 'position',\n", + " 'pixel'],\n", + " 'name': 'Mouse click',\n", + " 'parameters': [{'description': ' X-coördinate\\n', 'name': ' x'},\n", + " {'description': ' Y-coördinate\\n', 'name': ' y'}],\n", + " 'return': ' Mouse click on (x, y) coordinates\\n',\n", + " 'snippet': 'click(x=100, y=100)\\n'}\n", + "{'description': 'Double clicks on a pixel position on the visible screen '\n", + " 'determined by x and y coordinates.',\n", + " 'example': '>>> double_click(x=100, y=100)\\n',\n", + " 'function_call': 'double_click(x=None, y=None)',\n", + " 'icon': 'las la-mouse-pointer',\n", + " 'keywords': ['mouse',\n", + " 'osd',\n", + " 'overlay',\n", + " 'double',\n", + " 'double click',\n", + " 'doubleclick show',\n", + " 'display',\n", + " 'mouse automation',\n", + " 'click',\n", + " 'right click',\n", + " 'mouse button',\n", + " 'move mouse',\n", + " 'position',\n", + " 'pixel'],\n", + " 'name': 'Double mouse click',\n", + " 'parameters': [{'description': ' X-coördinate\\n', 'name': ' x'},\n", + " {'description': ' Y-coördinate\\n', 'name': ' y'}],\n", + " 'return': ' Double mouse click on (x, y) coordinates\\n',\n", + " 'snippet': 'double_click(x=100, y=100)\\n'}\n", + "{'description': 'Right clicks on a pixel position on the visible screen '\n", + " 'determined by x and y coordinates.',\n", + " 'example': '>>> right_click(x=100, y=100)\\n',\n", + " 'function_call': 'right_click(x=None, y=None)',\n", + " 'icon': 'las la-mouse-pointer',\n", + " 'keywords': ['mouse',\n", + " 'osd',\n", + " 'right click',\n", + " 'right',\n", + " 'rightclick',\n", + " 'overlay',\n", + " 'show',\n", + " 'display',\n", + " 'mouse automation',\n", + " 'click',\n", + " 'right click',\n", + " 'mouse button',\n", + " 'move mouse',\n", + " 'position',\n", + " 'pixel'],\n", + " 'name': 'Right click',\n", + " 'parameters': [{'description': ' X-coördinate\\n', 'name': ' x'},\n", + " {'description': ' Y-coördinate\\n', 'name': ' y'}],\n", + " 'return': ' Right mouse click on (x, y) coordinates\\n',\n", + " 'snippet': 'right_click(x=100, y=100)\\n'}\n", + "{'description': 'Moves te pointer to a x-y position.',\n", + " 'example': '>>> move_mouse_to(x=100, y=100)\\n',\n", + " 'function_call': 'move_mouse_to(x=None, y=None)',\n", + " 'icon': 'las la-arrows-alt',\n", + " 'keywords': ['mouse',\n", + " 'osd',\n", + " 'move mouse',\n", + " 'right click',\n", + " 'right',\n", + " 'rightclick',\n", + " 'overlay',\n", + " 'show',\n", + " 'display',\n", + " 'mouse automation',\n", + " 'click',\n", + " 'right click',\n", + " 'mouse button',\n", + " 'move mouse',\n", + " 'position',\n", + " 'pixel'],\n", + " 'name': 'Move mouse',\n", + " 'parameters': [{'description': ' X-coördinate\\n', 'name': ' x'},\n", + " {'description': ' Y-coördinate\\n', 'name': ' y'}],\n", + " 'return': ' Move mouse to (x, y) coordinates\\n',\n", + " 'snippet': 'move_mouse_to(x=100, y=100)\\n'}\n", + "{'description': 'Moves the mouse an x- and y- distance relative to its current '\n", + " 'pixel position.',\n", + " 'example': '>>> move_mouse_to(x=100, y=100)\\n'\n", + " '>>> wait(1)\\n'\n", + " '>>> move_mouse_relative(x=10, y=10)\\n',\n", + " 'function_call': 'move_mouse_relative(x=None, y=None)',\n", + " 'icon': 'las la-arrows-alt',\n", + " 'keywords': ['mouse',\n", + " 'osd',\n", + " 'move mouse',\n", + " 'right click',\n", + " 'right',\n", + " 'rightclick',\n", + " 'overlay',\n", + " 'show',\n", + " 'display',\n", + " 'mouse automation',\n", + " 'click',\n", + " 'right click',\n", + " 'mouse button',\n", + " 'move mouse',\n", + " 'position',\n", + " 'pixel'],\n", + " 'name': 'Move mouse relative',\n", + " 'parameters': [{'description': ' X-coördinate\\n', 'name': ' x'},\n", + " {'description': ' Y-coördinate\\n', 'name': ' y'}],\n", + " 'return': ' Move mouse (x, y) coordinates\\n',\n", + " 'snippet': 'move_mouse_to(x=100, y=100)\\n'\n", + " 'wait(1)\\n'\n", + " 'move_mouse_relative(x=10, y=10)\\n'}\n", + "{'description': 'Drag the mouse from its current position to a entered x-y '\n", + " 'position, while holding a specified button.',\n", + " 'example': '>>> move_mouse_to(x=100, y=100)\\n>>> drag_mouse_to(x=1, y=1)\\n',\n", + " 'function_call': 'drag_mouse_to(x=None, y=None, button=\"left\")',\n", + " 'icon': 'las la-arrows-alt',\n", + " 'keywords': ['mouse',\n", + " 'osd',\n", + " 'move mouse',\n", + " 'right click',\n", + " 'right',\n", + " 'rightclick',\n", + " 'overlay',\n", + " 'show',\n", + " 'display',\n", + " 'mouse automation',\n", + " 'click',\n", + " 'right click',\n", + " 'mouse button',\n", + " 'move mouse',\n", + " 'position',\n", + " 'pixel'],\n", + " 'name': 'Drag mouse',\n", + " 'parameters': [{'description': ' X-coördinate\\n', 'name': ' x'},\n", + " {'description': ' Y-coördinate\\n', 'name': ' y'},\n", + " {'description': ' Button to hold while dragging. Options are '\n", + " \"'left', 'middle' and 'right'. Standard value \"\n", + " \"is 'left'.\\n\",\n", + " 'name': ' button'}],\n", + " 'return': ' Drag mouse (x, y) coordinates\\n',\n", + " 'snippet': 'move_mouse_to(x=100, y=100)\\ndrag_mouse_to(x=1, y=1)\\n'}\n", + "{'description': 'Take a random square snippet from the current screen. Mainly '\n", + " 'for testing and/or development purposes.',\n", + " 'example': '>>> random_screen_snippet()\\n'\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\random_screensnippet.jpg'\\n\",\n", + " 'function_call': 'random_screen_snippet(size=100, path=None)',\n", + " 'icon': 'las la-crop-alt',\n", + " 'keywords': ['image', 'random', 'testing', 'screengrab', 'snippet'],\n", + " 'name': 'Random screen snippet',\n", + " 'parameters': [{'description': ' Size (width and height) in pixels for square '\n", + " 'snippet. Default value is 100 pixels\\n',\n", + " 'name': ' size'},\n", + " {'description': ' Path where snippet will be saved. Default '\n", + " 'value is home directory with name '\n", + " \"'random_screensnippet.jpg'\\n\",\n", + " 'name': ' path'}],\n", + " 'return': ' Path to snippet\\n',\n", + " 'snippet': 'random_screen_snippet()\\n'}\n", + "{'description': 'Take a screenshot of current screen.',\n", + " 'example': '>>> take_screenshot\\n'\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\screenshot.jpg'\\n\",\n", + " 'function_call': 'take_screenshot(path=None)',\n", + " 'icon': 'las la-expand',\n", + " 'keywords': ['image', 'screenshot', 'printscreen,'],\n", + " 'name': 'Screenshot',\n", + " 'parameters': [{'description': ' Path to save screenshot. Default value is '\n", + " \"home directory with name 'screenshot.jpg'.\\n\",\n", + " 'name': ' path'}],\n", + " 'return': ' Path to screenshot\\n',\n", + " 'snippet': 'take_screenshot\\n'}\n", + "{'description': 'This function searches the screen for a match with template '\n", + " 'image and clicks directly in the middle. Note that this only '\n", + " 'finds exact matches.For a more advanced and robust vision '\n", + " 'detection method see Automagica AI functionality.',\n", + " 'example': '>>> # Create a random snippet from current screen\\n'\n", + " '>>> # This is for illustration and can be replaced by template\\n'\n", + " '>>> snippet = random_screen_snippet(size=10)\\n'\n", + " '>>> # Click on the snippet\\n'\n", + " '>>> click_image(snippet)\\n',\n", + " 'function_call': 'click_image(filename=None)',\n", + " 'icon': 'las la-image',\n", + " 'keywords': ['image matching',\n", + " 'matching',\n", + " 'vision',\n", + " 'button',\n", + " 'click',\n", + " 'template',\n", + " 'template matching.'],\n", + " 'name': 'Click on image',\n", + " 'parameters': [{'description': ' Path to the template image.\\n',\n", + " 'name': ' filename'}],\n", + " 'return': ' True if image was found and clicked on. False if template image '\n", + " 'was not found.\\n',\n", + " 'snippet': '# Create a random snippet from current screen\\n'\n", + " '# This is for illustration and can be replaced by template\\n'\n", + " 'snippet = random_screen_snippet(size=10)\\n'\n", + " '# Click on the snippet\\n'\n", + " 'click_image(snippet)\\n'}\n", + "{'description': 'Double click on similar image on the screen. This function '\n", + " 'searches the screen for a match with template image and '\n", + " 'doubleclicks directly in the middle.Note that this only finds '\n", + " 'exact matches. For a more advanced and robust vision '\n", + " 'detection method see Automagica AI functionality.',\n", + " 'example': '>>> # Create a random snippet from current screen\\n'\n", + " '>>> # This is for illustration and can be replaced by template\\n'\n", + " '>>> snippet = random_screen_snippet(size=10)\\n'\n", + " '>>> # Click on the snippet\\n'\n", + " '>>> double_click_image(snippet)\\n',\n", + " 'function_call': 'double_click_image(filename=None)',\n", + " 'icon': 'las la-image',\n", + " 'keywords': ['image matching',\n", + " 'matching',\n", + " 'vision',\n", + " 'button',\n", + " 'double click',\n", + " 'template',\n", + " 'template matching,click'],\n", + " 'name': 'Double click image',\n", + " 'parameters': [{'description': ' Path to the template image.\\n',\n", + " 'name': ' filename'}],\n", + " 'return': ' True if image was found and double clicked on. False if template '\n", + " 'image was not found.\\n',\n", + " 'snippet': '# Create a random snippet from current screen\\n'\n", + " '# This is for illustration and can be replaced by template\\n'\n", + " 'snippet = random_screen_snippet(size=10)\\n'\n", + " '# Click on the snippet\\n'\n", + " 'double_click_image(snippet)\\n'}\n", + "{'description': 'Right click on similar image on the screen. This function '\n", + " 'searches the screen for a match with template image and right '\n", + " 'clicks directly in the middle.Note that this only finds exact '\n", + " 'matches. For a more advanced and robust vision detection '\n", + " 'method see Automagica AI functionality.',\n", + " 'example': '>>> # Create a random snippet from current screen\\n'\n", + " '>>> # This is for illustration and can be replaced by template\\n'\n", + " '>>> snippet = random_screen_snippet(size=10)\\n'\n", + " '>>> # Click on the snippet\\n'\n", + " '>>> right_click_image(snippet)\\n',\n", + " 'function_call': 'right_click_image(filename=None)',\n", + " 'icon': 'las la-image',\n", + " 'keywords': ['image matching',\n", + " 'matching',\n", + " 'vision',\n", + " 'button',\n", + " 'right click',\n", + " 'template',\n", + " 'template matching',\n", + " 'click'],\n", + " 'name': 'Right click image',\n", + " 'parameters': [],\n", + " 'return': ' True if image was found and right clicked on. False if template '\n", + " 'image was not found.\\n',\n", + " 'snippet': '# Create a random snippet from current screen\\n'\n", + " '# This is for illustration and can be replaced by template\\n'\n", + " 'snippet = random_screen_snippet(size=10)\\n'\n", + " '# Click on the snippet\\n'\n", + " 'right_click_image(snippet)\\n'}\n", + "{'description': 'Find exact image on the screen. This function searches the '\n", + " 'screen for a match with template image and clicks directly in '\n", + " 'the middle.Note that this only finds exact matches. For a '\n", + " 'more advanced and robust vision detection method see '\n", + " 'Automagica AI functionality.',\n", + " 'example': '>>> # Create a random snippet from current screen\\n'\n", + " '>>> # This is for illustration and can be replaced by template\\n'\n", + " '>>> snippet = random_screen_snippet(size=10)\\n'\n", + " '>>> # Click on the snippet\\n'\n", + " '>>> locate_image_on_screen(snippet)\\n',\n", + " 'function_call': 'locate_image_on_screen(filename=None)',\n", + " 'icon': 'las la-image',\n", + " 'keywords': ['image matching',\n", + " 'matching',\n", + " 'vision',\n", + " 'button',\n", + " 'right click',\n", + " 'template',\n", + " 'template matching',\n", + " 'click'],\n", + " 'name': 'Locate image on screen',\n", + " 'parameters': [{'description': ' Path to the template image.\\n',\n", + " 'name': ' filename'}],\n", + " 'return': ' Tuple with (x, y) coordinates if image is found. None if image '\n", + " 'was not found\\n',\n", + " 'snippet': '# Create a random snippet from current screen\\n'\n", + " '# This is for illustration and can be replaced by template\\n'\n", + " 'snippet = random_screen_snippet(size=10)\\n'\n", + " '# Click on the snippet\\n'\n", + " 'locate_image_on_screen(snippet)\\n'}\n", + "{'description': 'List all files in a folder (and subfolders)Checks all folders '\n", + " 'and subfolders for files. This could take some time for large '\n", + " 'repositories.',\n", + " 'example': '>>> # List all files in the homedirectory\\n'\n", + " '>>> get_files_in_folder()\\n'\n", + " \"['C:\\\\\\\\Users\\\\\\\\\\\\\\\\file1.jpg', \"\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\file2.txt', ... ]\\n\",\n", + " 'function_call': 'get_files_in_folder(path=None, extension=None, '\n", + " 'show_full_path=True, scan_subfolders=False)',\n", + " 'icon': 'las la-search',\n", + " 'keywords': ['folder',\n", + " 'files',\n", + " 'explorer',\n", + " 'nautilus',\n", + " 'folder',\n", + " 'file',\n", + " 'create folder',\n", + " 'get files',\n", + " 'list files',\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 'all files',\n", + " 'overview',\n", + " 'get files'],\n", + " 'name': 'List files in folder',\n", + " 'parameters': [{'description': ' Path of the folder to retreive files from. '\n", + " 'Default folder is the home directory.\\n',\n", + " 'name': ' path'},\n", + " {'description': ' Optional filter on certain extensions, for '\n", + " \"example 'pptx', 'exe,' xlsx', 'txt', .. \"\n", + " 'Default value is no filter.\\n',\n", + " 'name': ' extension'},\n", + " {'description': ' Set this to True to show full path, False '\n", + " 'will only show file or dirname. Default is '\n", + " 'True\\n',\n", + " 'name': ' show_full_path'}],\n", + " 'return': ' List of files with their full path\\n',\n", + " 'snippet': '# List all files in the homedirectory\\nget_files_in_folder()\\n'}\n", + "{'description': 'Creates new folder at the given path.',\n", + " 'example': '>>> # Create folder in the home directory\\n'\n", + " '>>> create_folder()\\n'\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\new_folder'\\n\",\n", + " 'function_call': 'create_folder(path=None)',\n", + " 'icon': 'las la-folder-plus',\n", + " 'keywords': ['create folder',\n", + " 'folder',\n", + " 'folders',\n", + " 'make folder',\n", + " 'new folder',\n", + " 'folder manipulation',\n", + " 'explorer',\n", + " 'nautilus'],\n", + " 'name': 'Create folder',\n", + " 'parameters': [{'description': ' Full path of folder that will be created. If '\n", + " 'no path is specified a folder called '\n", + " \"'new_folder' will be made in home directory. \"\n", + " 'If this folder already exists 8 random '\n", + " 'characters will be added to the name.\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' Path to new folder as string\\n',\n", + " 'snippet': '# Create folder in the home directory\\ncreate_folder()\\n'}\n", + "{'description': 'Rename a folder',\n", + " 'example': '>>> # Make new folder in home directory for illustration\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Rename the folder\\n'\n", + " '>>> rename_folder(testfolder, '\n", + " \"new_name='testfolder_brand_new_name')\\n\"\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\testfolder_brand_new_name'\\n\",\n", + " 'function_call': 'rename_folder(input_path, new_name=None)',\n", + " 'icon': 'las la-folder',\n", + " 'keywords': ['folder',\n", + " 'rename',\n", + " 'rename folder',\n", + " 'organise folder',\n", + " 'folders',\n", + " 'folder manipulation',\n", + " 'explorer',\n", + " 'nautilus'],\n", + " 'name': 'Rename folder',\n", + " 'parameters': [{'description': ' Full path of folder that will be renamed\\n',\n", + " 'name': ' path'},\n", + " {'description': \" New name of the folder e.g. 'new_folder'. By \"\n", + " 'default folder will be renamed to original '\n", + " \"folder name with '_renamed' added to the \"\n", + " 'folder name.\\n',\n", + " 'name': ' new_name'}],\n", + " 'return': ' Path to renamed folder as a string. None if folder could not be '\n", + " 'renamed.\\n',\n", + " 'snippet': '# Make new folder in home directory for illustration\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Rename the folder\\n'\n", + " \"rename_folder(testfolder, new_name='testfolder_brand_new_name')\\n\"}\n", + "{'description': 'Open a folder with the default explorer.',\n", + " 'example': '>>> # Make new folder in home directory for illustration\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Open folder\\n'\n", + " '>>> show_folder(testfolder)\\n'\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\new_folder'\\n\",\n", + " 'function_call': 'show_folder(path=None)',\n", + " 'icon': 'las la-folder-open',\n", + " 'keywords': ['folder', 'open', 'open folder', 'explorer', 'nautilus'],\n", + " 'name': 'Open a folder',\n", + " 'parameters': [{'description': ' Full path of folder that will be opened. '\n", + " 'Default value is the home directory\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' Path to opend folder as a string\\n',\n", + " 'snippet': '# Make new folder in home directory for illustration\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Open folder\\n'\n", + " 'show_folder(testfolder)\\n'}\n", + "{'description': 'Moves a folder from one place to another.If the new location '\n", + " 'already contains a folder with the same name, a random 4 '\n", + " 'character uid is added to the name.',\n", + " 'example': '>>> # Make new folder in home directory for illustration\\n'\n", + " '>>> # If no new_folder exists in home dir this will be called '\n", + " 'new_folder\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Make a second new folder\\n'\n", + " '>>> # Since new_folder already exists this folder will get a '\n", + " 'random id added (in this case abc1)\\n'\n", + " '>>> testfolder_2 = create_folder()\\n'\n", + " '>>> # Move testfolder in testfolder_2\\n'\n", + " '>>> move_folder(testfolder, testfolder_2)\\n'\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\new_folder_abc1\\\\\\\\new_folder'\\n\",\n", + " 'function_call': 'move_folder(from_path, to_path)',\n", + " 'icon': 'las la-folder',\n", + " 'keywords': ['folder',\n", + " 'move',\n", + " 'move folder',\n", + " 'explorer',\n", + " 'nautilus',\n", + " 'folder manipulation'],\n", + " 'name': 'Move a folder',\n", + " 'parameters': [{'description': ' Full path to the source location of the '\n", + " 'folder\\n',\n", + " 'name': ' fom_path'},\n", + " {'description': ' Full path to the destination location of the '\n", + " 'folder.\\n',\n", + " 'name': ' new_path'}],\n", + " 'return': ' Path to new location of folder as a string. None if folder could '\n", + " 'not be moved.\\n',\n", + " 'snippet': '# Make new folder in home directory for illustration\\n'\n", + " '# If no new_folder exists in home dir this will be called '\n", + " 'new_folder\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Make a second new folder\\n'\n", + " '# Since new_folder already exists this folder will get a random '\n", + " 'id added (in this case abc1)\\n'\n", + " 'testfolder_2 = create_folder()\\n'\n", + " '# Move testfolder in testfolder_2\\n'\n", + " 'move_folder(testfolder, testfolder_2)\\n'}\n", + "{'description': 'Remove a folder including all subfolders and files. For the '\n", + " 'function to work optimal, all files and subfolders in the '\n", + " 'main targetfolder should be closed.',\n", + " 'example': '>>> # Make new folder in home directory for illustration\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Check if folder exists\\n'\n", + " '>>> print( folder_exists(testfolder) ) # Should print True\\n'\n", + " '>>> # Remove folder\\n'\n", + " '>>> remove_folder(testfolder)\\n'\n", + " '>>> # Check again if folder exists\\n'\n", + " '>>> folder_exists(testfolder)\\n'\n", + " 'False\\n',\n", + " 'function_call': 'remove_folder(path, allow_root=False, '\n", + " 'delete_read_only=True)',\n", + " 'icon': 'las la-folder-minus',\n", + " 'keywords': ['folder',\n", + " 'delete folder',\n", + " 'delete',\n", + " 'nautilus',\n", + " 'folder manipulation',\n", + " 'explorer',\n", + " 'delete folder',\n", + " 'remove',\n", + " 'remove folder'],\n", + " 'name': 'Remove folder',\n", + " 'parameters': [{'description': ' Full path to the folder that will be '\n", + " 'deleted\\n',\n", + " 'name': ' path'},\n", + " {'description': ' Allow paths with an arbitrary length of 10 '\n", + " 'characters or shorter to be deleted. Default '\n", + " 'value is False.\\n',\n", + " 'name': ' allow_root'}],\n", + " 'return': ' Path to deleted folder as a string\\n',\n", + " 'snippet': '# Make new folder in home directory for illustration\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Check if folder exists\\n'\n", + " 'print( folder_exists(testfolder) ) # Should print True\\n'\n", + " '# Remove folder\\n'\n", + " 'remove_folder(testfolder)\\n'\n", + " '# Check again if folder exists\\n'\n", + " 'folder_exists(testfolder)\\n'}\n", + "{'description': 'Remove all contents from a folderFor the function to work '\n", + " 'optimal, all files and subfolders in the main targetfolder '\n", + " 'should be closed.',\n", + " 'example': '>>> # Make new folder in home directory for illustration\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Make new textfile in this folder\\n'\n", + " '>>> import os\\n'\n", + " \">>> textfile_location = os.path.join(testfolder, 'testfile.txt')\\n\"\n", + " '>>> make_textfile(output_path=textfile_location )\\n'\n", + " '>>> # Print all files in the testfolder\\n'\n", + " '>>> print( get_files_in_folder(testfolder) ) # Should show \\n'\n", + " '>>> # Empty the folder\\n'\n", + " '>>> empty_folder(testfolder)\\n'\n", + " '>>> # Check what is in the folder\\n'\n", + " '>>> get_files_in_folder(testfolder)\\n'\n", + " '[]\\n',\n", + " 'function_call': 'empty_folder(path, allow_root=False)',\n", + " 'icon': 'las la-folder-minus',\n", + " 'keywords': ['folder',\n", + " 'empty folder',\n", + " 'delete',\n", + " 'empty',\n", + " 'clean',\n", + " 'clean folder',\n", + " 'nautilus',\n", + " 'folder manipulation',\n", + " 'explorer',\n", + " 'delete folder',\n", + " 'remove',\n", + " 'remove folder'],\n", + " 'name': 'Empty folder',\n", + " 'parameters': [{'description': ' Full path to the folder that will be '\n", + " 'emptied\\n',\n", + " 'name': ' path'},\n", + " {'description': ' Allow paths with an arbitrary length of 10 '\n", + " 'characters or shorter to be emptied. Default '\n", + " 'value is False.\\n',\n", + " 'name': ' allow_root'}],\n", + " 'return': '',\n", + " 'snippet': '# Make new folder in home directory for illustration\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Make new textfile in this folder\\n'\n", + " 'import os\\n'\n", + " \"textfile_location = os.path.join(testfolder, 'testfile.txt')\\n\"\n", + " 'make_textfile(output_path=textfile_location )\\n'\n", + " '# Print all files in the testfolder\\n'\n", + " 'print( get_files_in_folder(testfolder) ) # Should show \\n'\n", + " '# Empty the folder\\n'\n", + " 'empty_folder(testfolder)\\n'\n", + " '# Check what is in the folder\\n'\n", + " 'get_files_in_folder(testfolder)\\n'}\n", + "{'description': 'Check whether folder exists or not, regardless if folder is '\n", + " 'empty or not.',\n", + " 'example': '>>> # Make new folder in home directory for illustration\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Check if folder exists\\n'\n", + " '>>> folder_exists(testfolder)\\n'\n", + " 'True\\n',\n", + " 'function_call': 'folder_exists(path)',\n", + " 'icon': 'las la-folder',\n", + " 'keywords': ['folder',\n", + " 'folder exists',\n", + " 'nautilus',\n", + " 'explorer',\n", + " 'folder manipulation',\n", + " 'files'],\n", + " 'name': 'Checks if folder exists',\n", + " 'parameters': [{'description': ' Full path to folder\\n', 'name': ' path'}],\n", + " 'return': ' Boolean\\n',\n", + " 'snippet': '# Make new folder in home directory for illustration\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Check if folder exists\\n'\n", + " 'folder_exists(testfolder)\\n'}\n", + "{'description': 'Copies a folder from one place to another.If the new location '\n", + " 'already contains a folder with the same name, a random 4 '\n", + " 'character id is added to the name.',\n", + " 'example': '>>> # Make new folder in home directory for illustration\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Copy this folder\\n'\n", + " '>>> # Since new_folder already exists in home dir this folder '\n", + " 'will get a random id added (in this case abc1)\\n'\n", + " '>>> copy_folder(testfolder)\\n',\n", + " 'function_call': 'copy_folder(from_path, to_path=None)',\n", + " 'icon': 'lar la-folder',\n", + " 'keywords': ['folder',\n", + " 'move',\n", + " 'move folder',\n", + " 'explorer',\n", + " 'nautilus',\n", + " 'folder manipulation'],\n", + " 'name': 'Copy a folder',\n", + " 'parameters': [{'description': ' Full path to the source location of the '\n", + " 'folder\\n',\n", + " 'name': ' old_path'},\n", + " {'description': ' Full path to the destination location of the '\n", + " 'folder. If no path is specified folder will '\n", + " 'get copied in the from_path directory\\n',\n", + " 'name': ' new_path'}],\n", + " 'return': ' Path to new folder as string\\n',\n", + " 'snippet': '# Make new folder in home directory for illustration\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Copy this folder\\n'\n", + " '# Since new_folder already exists in home dir this folder will '\n", + " 'get a random id added (in this case abc1)\\n'\n", + " 'copy_folder(testfolder)\\n'}\n", + "{'description': \"Zia folder and it's contents. Creates a .zip file.\",\n", + " 'example': '>>> # Make new folder in home directory for illustration\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Zip this folder\\n'\n", + " '>>> zip_folder(testfolder)\\n',\n", + " 'function_call': 'zip_folder(path, new_path=None)',\n", + " 'icon': 'las la-archive',\n", + " 'keywords': ['zip', 'zipping', 'winrar', 'rar', '7zip', 'compress', 'unzip'],\n", + " 'name': 'Zip',\n", + " 'parameters': [{'description': ' Full path to the source location of the '\n", + " 'folder that will be zipped\\n',\n", + " 'name': ' path'},\n", + " {'description': ' Full path to save the zipped folder. If no '\n", + " 'path is specified a folder with the original '\n", + " 'folder name plus 4 random characters\\n',\n", + " 'name': ' new_path'}],\n", + " 'return': ' Path to zipped folder\\n',\n", + " 'snippet': '# Make new folder in home directory for illustration\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Zip this folder\\n'\n", + " 'zip_folder(testfolder)\\n'}\n", + "{'description': 'Unzips a file or folder from a .zip file.',\n", + " 'example': '>>> # Make new folder in home directory for illustration\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Zip this folder\\n'\n", + " '>>> zipped_folder = zip_folder(testfolder)\\n'\n", + " '>>> # Unzip this folder\\n'\n", + " '>>> unzip(zipped_folder)\\n',\n", + " 'function_call': 'unzip(path, to_path=None)',\n", + " 'icon': 'las la-archive',\n", + " 'keywords': ['zip', 'zipping', 'winrar', 'rar', '7zip', 'compress', 'unzip'],\n", + " 'name': 'Unzip',\n", + " 'parameters': [{'description': ' Full path to the source location of the file '\n", + " 'or folder that will be unzipped\\n',\n", + " 'name': ' path'},\n", + " {'description': ' Full path to save unzipped contents. If no '\n", + " 'path is specified the unzipped contents will '\n", + " 'be stored in the same directory as the zipped '\n", + " 'file is located. \\n',\n", + " 'name': ' to_path'}],\n", + " 'return': ' Path to unzipped folder\\n',\n", + " 'snippet': '# Make new folder in home directory for illustration\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Zip this folder\\n'\n", + " 'zipped_folder = zip_folder(testfolder)\\n'\n", + " '# Unzip this folder\\n'\n", + " 'unzip(zipped_folder)\\n'}\n", + "{'description': 'Make the robot wait for a specified number of seconds. Note '\n", + " 'that this activity is blocking. This means that subsequent '\n", + " 'activities will not occur until the the specified waiting '\n", + " 'time has expired.',\n", + " 'example': \">>> print('Start the wait')\\n\"\n", + " '>>> wait()\\n'\n", + " \">>> print('The wait is over')\\n\",\n", + " 'function_call': 'wait(seconds=1)',\n", + " 'icon': 'las la-hourglass',\n", + " 'keywords': ['wait', 'sleep', 'time', 'timeout', 'time-out', 'hold', 'pause'],\n", + " 'name': 'Wait',\n", + " 'parameters': [{'description': ' Time in seconds to wait\\n',\n", + " 'name': ' seconds'}],\n", + " 'return': '',\n", + " 'snippet': \"print('Start the wait')\\nwait()\\nprint('The wait is over')\\n\"}\n", + "{'description': 'Waits for an image to appear on the screenNote that this '\n", + " 'activity waits for an exact match of the template image to '\n", + " 'appear on the screen.Small variations, such as color or '\n", + " 'resolution could result in a mismatch.',\n", + " 'example': '>>> # Create a random snippet from current screen\\n'\n", + " '>>> # This is for illustration and can be replaced by template\\n'\n", + " '>>> snippet = random_screen_snippet(size=10)\\n'\n", + " '>>> # Wait for the snippet to be visible\\n'\n", + " '>>> wait_for_image(snippet)\\n',\n", + " 'function_call': 'wait_for_image(path=None, timeout=60)',\n", + " 'icon': 'las la-hourglass',\n", + " 'keywords': ['image matching',\n", + " 'wait',\n", + " 'pause',\n", + " 'vision',\n", + " 'template',\n", + " 'template matching'],\n", + " 'name': 'Wait for image',\n", + " 'parameters': [{'description': ' Full or relative path to the template '\n", + " 'image.\\n',\n", + " 'name': ' path'},\n", + " {'description': ' Maximum time in seconds to wait before '\n", + " 'continuing. Default value is 60 seconds.\\n',\n", + " 'name': ' timeout'}],\n", + " 'return': '',\n", + " 'snippet': '# Create a random snippet from current screen\\n'\n", + " '# This is for illustration and can be replaced by template\\n'\n", + " 'snippet = random_screen_snippet(size=10)\\n'\n", + " '# Wait for the snippet to be visible\\n'\n", + " 'wait_for_image(snippet)\\n'}\n", + "{'description': 'Waits until a folder exists.Not that this activity is '\n", + " 'blocking and will keep the system waiting.',\n", + " 'example': '>>> # Create a random folder\\n'\n", + " '>>> testfolder = create_folder()\\n'\n", + " '>>> # Wait for the snippet to be visible\\n'\n", + " '>>> wait_folder_exists(testfolder)\\n',\n", + " 'function_call': 'wait_folder_exists(path, timeout=60)',\n", + " 'icon': 'las la-hourglass',\n", + " 'keywords': ['image matching',\n", + " 'wait',\n", + " 'pause',\n", + " 'vision',\n", + " 'template',\n", + " 'template matching'],\n", + " 'name': 'Wait for folder',\n", + " 'parameters': [{'description': ' Full path to folder.\\n', 'name': ' path'},\n", + " {'description': ' Maximum time in seconds to wait before '\n", + " 'continuing. Default value is 60 seconds.\\n',\n", + " 'name': ' timeout'}],\n", + " 'return': '',\n", + " 'snippet': '# Create a random folder\\n'\n", + " 'testfolder = create_folder()\\n'\n", + " '# Wait for the snippet to be visible\\n'\n", + " 'wait_folder_exists(testfolder)\\n'}\n", + "{'description': 'For this activity to work, Microsoft Office Word needs to be '\n", + " 'installed on the system.',\n", + " 'example': '>>> word = Word()\\n',\n", + " 'function_call': 'Word(visible=True, file_path=None)',\n", + " 'icon': 'lar la-file-word',\n", + " 'keywords': ['word',\n", + " 'editor',\n", + " 'text',\n", + " 'text edit',\n", + " 'office',\n", + " 'document',\n", + " 'microsoft word',\n", + " 'doc',\n", + " 'docx'],\n", + " 'name': 'Start Word Application',\n", + " 'parameters': [{'description': ' Show Word in the foreground if True or hide '\n", + " 'if False, defaults to True.\\n',\n", + " 'name': ' visible'},\n", + " {'description': ' Enter a path to open Word with an existing '\n", + " 'Word file. If no path is specified a document '\n", + " 'will be initialized, this is the default '\n", + " 'value.\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' Application object (win32com.client)\\n',\n", + " 'snippet': 'word = Word()\\n'}\n", + "{'description': 'Append text at end of Word document.',\n", + " 'example': '>>> # Start Word\\n'\n", + " '>>> word = Word()\\n'\n", + " \">>> word.append_text('This is sample text')\\n\",\n", + " 'function_call': 'append_text(text)',\n", + " 'icon': 'lar la-file-word',\n", + " 'keywords': ['word',\n", + " 'editor',\n", + " 'text',\n", + " 'text edit',\n", + " 'office',\n", + " 'document',\n", + " 'microsoft word',\n", + " 'doc',\n", + " 'docx'],\n", + " 'name': 'Append text',\n", + " 'parameters': [{'description': ' Text to append to document\\n',\n", + " 'name': ' text'}],\n", + " 'return': '',\n", + " 'snippet': '# Start Word\\n'\n", + " 'word = Word()\\n'\n", + " \"word.append_text('This is sample text')\\n\"}\n", + "{'description': 'Can be used for example to replace arbitrary placeholder '\n", + " \"value. For example whenusing template document, using 'XXXX' \"\n", + " 'as a placeholder. Take note that all strings are case '\n", + " 'sensitive.',\n", + " 'example': '>>> # Start Word\\n'\n", + " '>>> word = Word()\\n'\n", + " \">>> word.append_text('This is sample text')\\n\"\n", + " \">>> word.replace_text('sample', 'real')\\n\",\n", + " 'function_call': 'replace_text(placeholder_text, replacement_text)',\n", + " 'icon': 'lar la-file-word',\n", + " 'keywords': ['word', 'replace', 'text', 'template'],\n", + " 'name': 'Replace text',\n", + " 'parameters': [{'description': ' Placeholder text value (string) in the '\n", + " 'document, this will be replaced, e.g. '\n", + " \"'Company Name'\\n\",\n", + " 'name': ' placeholder_text'},\n", + " {'description': ' Text (string) to replace the placeholder '\n", + " 'values with. It is recommended to make this '\n", + " 'unique to avoid wrongful replacement, e.g. '\n", + " \"'XXXX_placeholder_XXX'\\n\",\n", + " 'name': ' replacement_text'}],\n", + " 'return': '',\n", + " 'snippet': '# Start Word\\n'\n", + " 'word = Word()\\n'\n", + " \"word.append_text('This is sample text')\\n\"\n", + " \"word.replace_text('sample', 'real')\\n\"}\n", + "{'description': 'Read all the text from a document',\n", + " 'example': '>>> # Start Word\\n'\n", + " '>>> word = Word()\\n'\n", + " \">>> word.append_text('This is sample text')\\n\"\n", + " \">>> word.replace_text('sample', 'real')\\n\"\n", + " '>>> word.read_all_text()\\n'\n", + " \"'This is real text'\\n\",\n", + " 'function_call': 'read_all_text(return_as_list=False)',\n", + " 'icon': 'lar la-file-word',\n", + " 'keywords': ['word', 'extract', 'text', 'document'],\n", + " 'name': 'Read all text',\n", + " 'parameters': [{'description': ' Set this paramater to True to return text as '\n", + " 'a list of strings. Default value is False.\\n',\n", + " 'name': ' return_as_list'}],\n", + " 'return': ' Text from the document\\n',\n", + " 'snippet': '# Start Word\\n'\n", + " 'word = Word()\\n'\n", + " \"word.append_text('This is sample text')\\n\"\n", + " \"word.replace_text('sample', 'real')\\n\"\n", + " 'word.read_all_text()\\n'}\n", + "{'description': 'Export the document to PDF',\n", + " 'example': '>>> # Start Word\\n'\n", + " '>>> word = Word()\\n'\n", + " \">>> word.append_text('This is sample text')\\n\"\n", + " \">>> word.replace_text('sample', 'real')\\n\"\n", + " \">>> word.export_to_pdf('output.pdf')\\n\",\n", + " 'function_call': 'export_to_pdf(path=None)',\n", + " 'icon': 'lar la-file-pdf',\n", + " 'keywords': ['word', 'pdf', 'document', 'export', 'save as'],\n", + " 'name': 'Export to PDF',\n", + " 'parameters': [{'description': ' Output path where PDF file will be exported '\n", + " 'to. Default path is home directory with '\n", + " \"filename 'pdf_export.pdf'.\\n\",\n", + " 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Start Word\\n'\n", + " 'word = Word()\\n'\n", + " \"word.append_text('This is sample text')\\n\"\n", + " \"word.replace_text('sample', 'real')\\n\"\n", + " \"word.export_to_pdf('output.pdf')\\n\"}\n", + "{'description': 'Export to HTML',\n", + " 'example': '>>> # Start Word\\n'\n", + " '>>> word = Word()\\n'\n", + " \">>> word.append_text('This is sample text')\\n\"\n", + " \">>> word.replace_text('sample', 'real')\\n\"\n", + " \">>> word.export_to_html('output.html')\\n\",\n", + " 'function_call': 'export_to_html(path=None)',\n", + " 'icon': 'las la-html5',\n", + " 'keywords': ['word', 'html', 'document', 'export', 'save as'],\n", + " 'name': 'Export to HTML',\n", + " 'parameters': [{'description': ' Output path where HTML file will be exported '\n", + " 'to. Default path is home directory with '\n", + " \"filename 'html_export.html'.\\n\",\n", + " 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Start Word\\n'\n", + " 'word = Word()\\n'\n", + " \"word.append_text('This is sample text')\\n\"\n", + " \"word.replace_text('sample', 'real')\\n\"\n", + " \"word.export_to_html('output.html')\\n\"}\n", + "{'description': 'Set the footers of the document',\n", + " 'example': '>>> # Start Word\\n'\n", + " '>>> word = Word()\\n'\n", + " \">>> word.set_footers('This is a footer!')\\n\",\n", + " 'function_call': 'set_footers(text)',\n", + " 'icon': 'las la-heading',\n", + " 'keywords': ['word', 'footer', 'footers'],\n", + " 'name': 'Set footers',\n", + " 'parameters': [{'description': ' Text to put in the footer\\n',\n", + " 'name': ' text'}],\n", + " 'return': '',\n", + " 'snippet': '# Start Word\\n'\n", + " 'word = Word()\\n'\n", + " \"word.set_footers('This is a footer!')\\n\"}\n", + "{'description': 'Set the headers of the document',\n", + " 'example': '>>> # Start Word\\n'\n", + " '>>> word = Word()\\n'\n", + " \">>> word.set_headers('This is a header!')\\n\",\n", + " 'function_call': 'set_headers(text)',\n", + " 'icon': 'las la-subscript',\n", + " 'keywords': ['word', 'header', 'headers'],\n", + " 'name': 'Set headers',\n", + " 'parameters': [{'description': ' Text to put in the header\\n',\n", + " 'name': ' text'}],\n", + " 'return': '',\n", + " 'snippet': '# Start Word\\n'\n", + " 'word = Word()\\n'\n", + " \"word.set_headers('This is a header!')\\n\"}\n", + "{'description': 'These activities can read, write and edit Word (docx) files '\n", + " 'without the need of having Word installed.Note that, in '\n", + " \"contrary to working with the :func: 'Word' activities, a file \"\n", + " 'get saved directly after manipulation.',\n", + " 'example': '>>> wordfile = WordFile()\\n'\n", + " \">>> wordfile.append_text('Some sample text')\\n\"\n", + " '>>> wordfile.read_all_text()\\n'\n", + " \"'Some sample text'\\n\",\n", + " 'function_call': 'WordFile(file_path=None)',\n", + " 'icon': 'las la-file-word',\n", + " 'keywords': ['word', 'read', 'text', 'file'],\n", + " 'name': 'Read and Write Word files',\n", + " 'parameters': [{'description': ' Enter a path to open Word with an existing '\n", + " 'Word file. If no path is specified a '\n", + " \"'document.docx' will be initialized in the \"\n", + " 'home directory, this is the default value. If '\n", + " 'a document with the same name already exists '\n", + " 'the file will be overwritten.\\n',\n", + " 'name': ' file_path'}],\n", + " 'return': '',\n", + " 'snippet': 'wordfile = WordFile()\\n'\n", + " \"wordfile.append_text('Some sample text')\\n\"\n", + " 'wordfile.read_all_text()\\n'}\n", + "{'description': 'Read all the text from the document',\n", + " 'example': '>>> wordfile = WordFile()\\n'\n", + " \">>> wordfile.append_text('Some sample text')\\n\"\n", + " '>>> wordfile.read_all_text()\\n'\n", + " \"'Some sample text'\\n\",\n", + " 'function_call': 'read_all_text(return_as_list=False)',\n", + " 'icon': 'las la-file-word',\n", + " 'keywords': ['word', 'read', 'text', 'file'],\n", + " 'name': 'Read all text',\n", + " 'parameters': [{'description': ' Set this paramater to True to return text as '\n", + " 'a list of strings. Default value is False.\\n',\n", + " 'name': ' return_as_list'}],\n", + " 'return': ' Text of the document\\n',\n", + " 'snippet': 'wordfile = WordFile()\\n'\n", + " \"wordfile.append_text('Some sample text')\\n\"\n", + " 'wordfile.read_all_text()\\n'}\n", + "{'description': 'Append text at the end of the document',\n", + " 'example': '>>> wordfile = WordFile()\\n'\n", + " \">>> wordfile.append_text('Some sample text')\\n\",\n", + " 'function_call': 'append_text(text, auto_save=True)',\n", + " 'icon': 'las la-file-word',\n", + " 'keywords': ['word', 'append text', 'add text'],\n", + " 'name': 'Append text',\n", + " 'parameters': [{'description': ' Text to append\\n', 'name': ' text'},\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " {'description': ' Save document after performing activity. '\n", + " 'Default value is True\\n',\n", + " 'name': ' auto_save'}],\n", + " 'return': '',\n", + " 'snippet': \"wordfile = WordFile()\\nwordfile.append_text('Some sample text')\\n\"}\n", + "{'description': 'Save document',\n", + " 'example': '>>> wordfile = WordFile()\\n'\n", + " \">>> wordfile.append_text('Some sample text')\\n\"\n", + " '>>> wordfile.save()\\n',\n", + " 'function_call': 'save(self)',\n", + " 'icon': 'las la-file-word',\n", + " 'keywords': ['word', 'save', 'store'],\n", + " 'name': 'Save',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': 'wordfile = WordFile()\\n'\n", + " \"wordfile.append_text('Some sample text')\\n\"\n", + " 'wordfile.save()\\n'}\n", + "{'description': ':Example:',\n", + " 'example': '>>> wordfile = WordFile()\\n'\n", + " \">>> wordfile.append_text('Some sample text')\\n\"\n", + " \">>> wordfile.save_as('document.docx')\\n\",\n", + " 'function_call': 'save_as(path)',\n", + " 'icon': 'las la-file-word',\n", + " 'keywords': ['word', 'save as', 'store'],\n", + " 'name': 'Save as',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': 'wordfile = WordFile()\\n'\n", + " \"wordfile.append_text('Some sample text')\\n\"\n", + " \"wordfile.save_as('document.docx')\\n\"}\n", + "{'description': 'Set headers of Word document',\n", + " 'example': '>>> wordfile = WordFile()\\n'\n", + " \">>> wordfile.append_text('Some sample text')\\n\"\n", + " \">>> wordfile.set_headers('This is a header')\\n\",\n", + " 'function_call': 'set_headers(text, auto_save=True)',\n", + " 'icon': 'las la-file-word',\n", + " 'keywords': ['word', 'header text'],\n", + " 'name': 'Set headers',\n", + " 'parameters': [{'description': ' Text to put in the header\\n',\n", + " 'name': ' text'},\n", + " {'description': ' Save document after performing activity. '\n", + " 'Default value is True\\n',\n", + " 'name': ' auto_save'}],\n", + " 'return': '',\n", + " 'snippet': 'wordfile = WordFile()\\n'\n", + " \"wordfile.append_text('Some sample text')\\n\"\n", + " \"wordfile.set_headers('This is a header')\\n\"}\n", + "{'description': 'Replaces all occurences of a placeholder text in the document '\n", + " 'with a replacement text.',\n", + " 'example': '>>> wordfile = WordFile()\\n'\n", + " \">>> wordfile.append_text('Some sample text')\\n\"\n", + " \">>> wordfile.replace_text('sample', 'real')\\n\",\n", + " 'function_call': 'replace_text(placeholder_text, replacement_text, '\n", + " 'auto_save=True)',\n", + " 'icon': 'las la-file-word',\n", + " 'keywords': ['word', 'replace text', 'template'],\n", + " 'name': 'Replace all',\n", + " 'parameters': [{'description': ' Placeholder text value (string) in the '\n", + " 'document, this will be replaced, e.g. '\n", + " \"'Company Name'\\n\",\n", + " 'name': ' placeholder_text'},\n", + " {'description': ' Text (string) to replace the placeholder '\n", + " 'values with. It is recommended to make this '\n", + " 'unique to avoid wrongful replacement, e.g. '\n", + " \"'XXXX_placeholder_XXX'\\n\",\n", + " 'name': ' replacement_text'},\n", + " {'description': ' Save document after performing activity. '\n", + " 'Default value is True\\n',\n", + " 'name': ' auto_save'}],\n", + " 'return': '',\n", + " 'snippet': 'wordfile = WordFile()\\n'\n", + " \"wordfile.append_text('Some sample text')\\n\"\n", + " \"wordfile.replace_text('sample', 'real')\\n\"}\n", + "{'description': 'For this activity to work, Outlook needs to be installed on '\n", + " 'the system.',\n", + " 'example': '>>> outlook = Outlook()\\n',\n", + " 'function_call': 'Outlook(account_name=None)',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook', 'send e-mail', 'send mail'],\n", + " 'name': 'Start Outlook Application',\n", + " 'parameters': [],\n", + " 'return': ' Application object (win32com.client)\\n',\n", + " 'snippet': 'outlook = Outlook()\\n'}\n", + "{'description': 'Send an e-mail using Outlook',\n", + " 'example': '>>> outlook = Outlook()\\n'\n", + " \">>> outlook.send_mail('test@test.com', subject='Hello world', \"\n", + " \"body='Hi there')\\n\",\n", + " 'function_call': 'send_mail(to_address, subject=\"\", body=\"\", html_body=None, '\n", + " 'attachment_paths=None)',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook', 'send e-mail', 'send mail'],\n", + " 'name': 'Send e-mail',\n", + " 'parameters': [{'description': ' The e-mail address the e-mail should be sent '\n", + " 'to\\n',\n", + " 'name': ' to_address'},\n", + " {'description': ' The subject of the e-mail\\n',\n", + " 'name': ' subject'},\n", + " {'description': ' The text body contents of the e-mail\\n',\n", + " 'name': ' body'},\n", + " {'description': ' The HTML body contents of the e-mail '\n", + " '(optional)\\n',\n", + " 'name': ' html_body'},\n", + " {'description': ' List of file paths to attachments\\n',\n", + " 'name': ' attachment_paths'}],\n", + " 'return': '',\n", + " 'snippet': 'outlook = Outlook()\\n'\n", + " \"outlook.send_mail('test@test.com', subject='Hello world', \"\n", + " \"body='Hi there')\\n\"}\n", + "{'description': 'Retrieve list of folders from Outlook',\n", + " 'example': '>>> outlook = Outlook()\\n'\n", + " '>>> outlook.get_folders()\\n'\n", + " \"['Inbox', 'Sent', ...]\\n\",\n", + " 'function_call': 'get_folders(limit=999)',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook', 'get folders', 'list folders'],\n", + " 'name': 'Retrieve folders',\n", + " 'parameters': [{'description': ' Maximum number of folders to retrieve\\n',\n", + " 'name': ' limit'}],\n", + " 'return': '',\n", + " 'snippet': 'outlook = Outlook()\\noutlook.get_folders()\\n'}\n", + "{'description': 'Retrieve list of messages from Outlook',\n", + " 'example': '>>> outlook = Outlook()\\n'\n", + " '>>> outlook.get_mails()\\n'\n", + " '[\\n'\n", + " ' {\\n'\n", + " \" 'Subject': 'Hello World!',\\n\"\n", + " \" 'Body' : 'This is an e-mail',\\n\"\n", + " \" 'SenderEmailAddress': 'from@test.com'\\n\"\n", + " ' }\\n'\n", + " ']\\n',\n", + " 'function_call': 'get_mails(folder_name=\"Inbox\", fields=None)',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook',\n", + " 'retrieve e-mail',\n", + " 'receive e-mails',\n", + " 'process e-mails',\n", + " 'get mails'],\n", + " 'name': 'Retrieve e-mails',\n", + " 'parameters': [{'description': ' Name of the Outlook folder, can be found '\n", + " 'using `get_folders`.\\n',\n", + " 'name': ' folder_name'},\n", + " {'description': ' Number of messages to retrieve\\n',\n", + " 'name': ' limit'},\n", + " {'description': ' Fields (properties) of e-mail messages to '\n", + " \"give, requires tupl Stadard is 'Subject', \"\n", + " \"'Body', 'SentOn' and 'SenderEmailAddress'.\\n\",\n", + " 'name': ' fields'}],\n", + " 'return': ' List of dictionaries containing the e-mail messages with from, '\n", + " 'to, subject, body and html.\\n',\n", + " 'snippet': 'outlook = Outlook()\\n'\n", + " 'outlook.get_mails()\\n'\n", + " ' {\\n'\n", + " \" 'Subject': 'Hello World!',\\n\"\n", + " \" 'Body' : 'This is an e-mail',\\n\"\n", + " \" 'SenderEmailAddress': 'from@test.com'\\n\"\n", + " ' }\\n'}\n", + "{'description': 'Deletes e-mail messages in a certain folder. Can be specified '\n", + " 'by searching on subject, body or sender e-mail.',\n", + " 'example': '>>> outlook = Outlook()\\n'\n", + " \">>> outlook.delete_mails(subject_contains='hello')\\n\",\n", + " 'function_call': 'delete_mails(self,folder_name=\"Inbox\",limit=0,subject_contains=\"\",body_contains=\"\",sender_contains=\"\")',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook', 'remove e-mails', 'delete mail', 'remove mail'],\n", + " 'name': 'Delete e-mails',\n", + " 'parameters': [{'description': ' Name of the Outlook folder, can be found '\n", + " 'using `get_folders`\\n',\n", + " 'name': ' folder_name'},\n", + " {'description': ' Maximum number of e-mails to delete in one '\n", + " 'go\\n',\n", + " 'name': ' limit'},\n", + " {'description': ' Only delete e-mail if subject contains '\n", + " 'this\\n',\n", + " 'name': ' subject_contains'},\n", + " {'description': ' Only delete e-mail if body contains this\\n',\n", + " 'name': ' body_contains'},\n", + " {'description': ' Only delete e-mail if sender contains this\\n',\n", + " 'name': ' sender_contains'}],\n", + " 'return': '',\n", + " 'snippet': 'outlook = Outlook()\\n'\n", + " \"outlook.delete_mails(subject_contains='hello')\\n\"}\n", + "{'description': 'Move e-mail messages in a certain folder. Can be specified by '\n", + " 'searching on subject, body or sender e-mail.',\n", + " 'example': '>>> outlook = Outlook()\\n'\n", + " \">>> outlook.move_mails(subject_contains='move me')\\n\",\n", + " 'function_call': 'move_mails(self,source_folder_name=\"Inbox\",target_folder_name=\"Archive\",limit=0,subject_contains=\"\",body_contains=\"\",sender_contains=\"\")',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook', 'move e-mail', 'move e-mail to folder'],\n", + " 'name': 'Move e-mails',\n", + " 'parameters': [{'description': ' Name of the Outlook source folder from where '\n", + " 'e-mails will be moved, can be found using '\n", + " '`get_folders`\\n',\n", + " 'name': ' source_folder_name'},\n", + " {'description': ' Name of the Outlook destination folder to '\n", + " 'where e-mails will be moved, can be found '\n", + " 'using `get_folders`\\n',\n", + " 'name': ' target_folder_name'},\n", + " {'description': ' Maximum number of e-mails to move in one '\n", + " 'go\\n',\n", + " 'name': ' limit'},\n", + " {'description': ' Only move e-mail if subject contains this\\n',\n", + " 'name': ' subject_contains'},\n", + " {'description': ' Only move e-mail if body contains this\\n',\n", + " 'name': ' body_contains'},\n", + " {'description': ' Only move e-mail if sender contains this\\n',\n", + " 'name': ' sender_contains'}],\n", + " 'return': '',\n", + " 'snippet': 'outlook = Outlook()\\n'\n", + " \"outlook.move_mails(subject_contains='move me')\\n\"}\n", + "{'description': ':parameter folder_name: Name of the Outlook folder, can be '\n", + " 'found using `get_folders`.:parameter target_folder_path: Path '\n", + " 'where attachments will be saved. Default is the home '\n", + " 'directory.',\n", + " 'example': '>>> outlook = Outlook()\\n'\n", + " '>>> outlook.save_attachments()\\n'\n", + " \"['Attachment.pdf', 'Signature_image.jpeg']\\n\",\n", + " 'function_call': 'save_attachments(folder_name=\"Inbox\", '\n", + " 'target_folder_path=None)',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook',\n", + " 'save attachments',\n", + " 'download attachments',\n", + " 'extract attachments'],\n", + " 'name': 'Save attachments',\n", + " 'parameters': [{'description': ' Name of the Outlook folder, can be found '\n", + " 'using `get_folders`.\\n',\n", + " 'name': ' folder_name'},\n", + " {'description': ' Path where attachments will be saved. '\n", + " 'Default is the home directory.\\n',\n", + " 'name': ' target_folder_path'}],\n", + " 'return': ' List of paths to saved attachments.\\n',\n", + " 'snippet': 'outlook = Outlook()\\noutlook.save_attachments()\\n'}\n", + "{'description': ':parameter fields: Fields can be specified as a tuple with '\n", + " 'their exact names. Standard value is None returning '\n", + " '\"LastName\", \"FirstName\" and \"Email1Address\".',\n", + " 'example': '>>> outlook = Outlook()\\n'\n", + " '>>> outlook.get_contacts()\\n'\n", + " '[\\n'\n", + " ' {\\n'\n", + " \" 'LastName': 'Doe',\\n\"\n", + " \" 'FirstName' : 'John',\\n\"\n", + " \" 'Email1Address': 'john@test.com'\\n\"\n", + " ' }\\n'\n", + " ']\\n',\n", + " 'function_call': 'get_contacts(fields=None)',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook', 'get contacts', 'download contacts', 'rolodex'],\n", + " 'name': 'Retrieve contacts',\n", + " 'parameters': [{'description': ' Fields can be specified as a tuple with '\n", + " 'their exact names. Standard value is None '\n", + " 'returning \"LastName\", \"FirstName\" and '\n", + " '\"Email1Address\".\\n',\n", + " 'name': ' fields'}],\n", + " 'return': ' List of dictionaries containing the contact details.\\n',\n", + " 'snippet': 'outlook = Outlook()\\n'\n", + " 'outlook.get_contacts()\\n'\n", + " ' {\\n'\n", + " \" 'LastName': 'Doe',\\n\"\n", + " \" 'FirstName' : 'John',\\n\"\n", + " \" 'Email1Address': 'john@test.com'\\n\"\n", + " ' }\\n'}\n", + "{'description': 'Add a contact to Outlook contacts',\n", + " 'example': '>>> outlook = Outlook()\\n'\n", + " \">>> outlook.add_contact('sales@automagica.com')\\n\",\n", + " 'function_call': 'add_contact(email, first_name=\"\", last_name=\"\")',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook', 'create contact', 'add contact'],\n", + " 'name': 'Add a contact',\n", + " 'parameters': [{'description': ' The e-mail address for the contact\\n',\n", + " 'name': ' email'},\n", + " {'description': ' First name for the contact (optional)\\n',\n", + " 'name': ' first_name'},\n", + " {'description': ' Last name for the contact (optional)\\n',\n", + " 'name': ' last_name'}],\n", + " 'return': '',\n", + " 'snippet': 'outlook = Outlook()\\n'\n", + " \"outlook.add_contact('sales@automagica.com')\\n\"}\n", + "{'description': 'Close the Outlook application',\n", + " 'example': '>>> outlook = Outlook()\\n>>> outlook.quit()\\n',\n", + " 'function_call': 'quit(self)',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['outlook', 'close', 'quit'],\n", + " 'name': 'Quit',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': 'outlook = Outlook()\\noutlook.quit()\\n'}\n", + "{'description': 'For this activity to work, Microsoft Office Excel needs to be '\n", + " 'installed on the system.',\n", + " 'example': '>>> # Open Excel\\n>>> excel = Excel()\\n',\n", + " 'function_call': 'Excel(visible=True, file_path=None)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'add worksheet', 'add tab'],\n", + " 'name': 'Start Excel Application',\n", + " 'parameters': [{'description': ' Show Excel in the foreground if True or hide '\n", + " 'if False, defaults to True.\\n',\n", + " 'name': ' visible'},\n", + " {'description': ' Enter a path to open Excel with an existing '\n", + " 'Excel file. If no path is specified a '\n", + " 'workbook will be initialized, this is the '\n", + " 'default value.\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' Application object (win32com.client)\\n',\n", + " 'snippet': '# Open Excel\\nexcel = Excel()\\n'}\n", + "{'description': 'Adds a worksheet to the current workbook',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Add a worksheet\\n'\n", + " \">>> excel.add_worksheet('My Example Worksheet')\\n\",\n", + " 'function_call': 'add_worksheet(name=None)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel',\n", + " 'add worksheet',\n", + " 'add tab',\n", + " 'insert worksheet',\n", + " 'new worksheet'],\n", + " 'name': 'Add worksheet',\n", + " 'parameters': [{'description': ' Workbook object which is retrieved with '\n", + " 'either new_workbook or open_workbook\\n',\n", + " 'name': ' workbook'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Add a worksheet\\n'\n", + " \"excel.add_worksheet('My Example Worksheet')\\n\"}\n", + "{'description': 'Activate a worksheet in the current Excel document by name',\n", + " 'example': '>>> # Open Excel \\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Add the first worksheet\\n'\n", + " \">>> excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Add another worksheet\\n'\n", + " \">>> excel.add_worksheet('Another Worksheet')\\n\"\n", + " '>>> # Activate the first worksheet\\n'\n", + " \">>> excel.activate_worksheet('My Example Worksheet)\\n\",\n", + " 'function_call': 'activate_worksheet(name)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel',\n", + " 'activate worksheet',\n", + " 'set worksheet',\n", + " 'select worksheet',\n", + " 'select tab',\n", + " 'activate tab'],\n", + " 'name': 'Activate worksheet',\n", + " 'parameters': [{'description': ' Name of the worksheet to activate\\n',\n", + " 'name': ' name'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel \\n'\n", + " 'excel = Excel()\\n'\n", + " '# Add the first worksheet\\n'\n", + " \"excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Add another worksheet\\n'\n", + " \"excel.add_worksheet('Another Worksheet')\\n\"\n", + " '# Activate the first worksheet\\n'\n", + " \"excel.activate_worksheet('My Example Worksheet)\\n\"}\n", + "{'description': 'Save the current workbook',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Add the first worksheet\\n'\n", + " \">>> excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Save the workbook to My Documents\\n'\n", + " '>>> excel.save()\\n',\n", + " 'function_call': 'save(self)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'save', 'store'],\n", + " 'name': 'Save',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Add the first worksheet\\n'\n", + " \"excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Save the workbook to My Documents\\n'\n", + " 'excel.save()\\n'}\n", + "{'description': 'Save the current workbook to a specific path',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Add the first worksheet\\n'\n", + " \">>> excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Save the workbook to the current working directory\\n'\n", + " \">>> excel.save_as('output.xlsx')\\n\",\n", + " 'function_call': 'save_as(path)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'save as', 'export'],\n", + " 'name': 'Save as',\n", + " 'parameters': [{'description': ' Path where workbook will be saved. Default '\n", + " 'is home directory and filename '\n", + " \"'workbook.xlsx'\\n\",\n", + " 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Add the first worksheet\\n'\n", + " \"excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Save the workbook to the current working directory\\n'\n", + " \"excel.save_as('output.xlsx')\\n\"}\n", + "{'description': 'Write to a specific cell in the currently active workbook and '\n", + " 'active worksheet',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Add the first worksheet\\n'\n", + " \">>> excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Insert a text into the first cell\\n'\n", + " \">>> excel.write_cell(1,1, 'Hello World!')\\n\",\n", + " 'function_call': 'write_cell(column, row, value)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'cell', 'insert cell', 'insert data'],\n", + " 'name': 'Write cell',\n", + " 'parameters': [{'description': ' Column number (integer) to write\\n',\n", + " 'name': ' column'},\n", + " {'description': ' Row number (integer) to write\\n',\n", + " 'name': ' row'},\n", + " {'description': ' Value to write to specific cell\\n',\n", + " 'name': ' value'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Add the first worksheet\\n'\n", + " \"excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Insert a text into the first cell\\n'\n", + " \"excel.write_cell(1,1, 'Hello World!')\\n\"}\n", + "{'description': 'Read a cell from the currently active workbook and active '\n", + " 'worksheet',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Add the first worksheet\\n'\n", + " \">>> excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Insert a text into the first cell\\n'\n", + " \">>> excel.write_cell(1,1, 'Hello World!')\\n\"\n", + " '>>> excel.read_cell(1,1)\\n'\n", + " \"'Hello World!'\\n\",\n", + " 'function_call': 'read_cell(column, row)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'cell', 'read cell', 'read data'],\n", + " 'name': 'Read cell',\n", + " 'parameters': [{'description': ' Column number (integer) to read\\n',\n", + " 'name': ' column'},\n", + " {'description': ' Row number (integer) to read\\n',\n", + " 'name': ' row'}],\n", + " 'return': ' Cell value\\n',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Add the first worksheet\\n'\n", + " \"excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Insert a text into the first cell\\n'\n", + " \"excel.write_cell(1,1, 'Hello World!')\\n\"\n", + " 'excel.read_cell(1,1)\\n'}\n", + "{'description': 'Write to a specific range in the currently active worksheet '\n", + " 'in the active workbook',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Add the first worksheet\\n'\n", + " \">>> excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Insert a text in every cell in this range\\n'\n", + " \">>> excel.write_range('A1:D5', 'Hello World!')\\n\",\n", + " 'function_call': 'write_range(range_, value)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'cell', 'write range', 'read data'],\n", + " 'name': 'Write range',\n", + " 'parameters': [{'description': ' Range to write to, e.g. \"A1:D10\"\\n',\n", + " 'name': ' range_'},\n", + " {'description': ' Value to write to range\\n',\n", + " 'name': ' value'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Add the first worksheet\\n'\n", + " \"excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Insert a text in every cell in this range\\n'\n", + " \"excel.write_range('A1:D5', 'Hello World!')\\n\"}\n", + "{'description': 'Read a range of cells from the currently active worksheet in '\n", + " 'the active workbook',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Add the first worksheet\\n'\n", + " \">>> excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Insert a text in every cell in this range\\n'\n", + " \">>> excel.write_range('A1:D5', 'Hello World!')\\n\"\n", + " '>>> # Read the same range\\n'\n", + " \">>> excel.read_range('A1:D5')\\n\"\n", + " \"[['Hello World', 'Hello World', 'Hello World', 'Hello World'], \"\n", + " '...]\\n',\n", + " 'function_call': 'read_range(range_)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'cell', 'read range', 'read data'],\n", + " 'name': 'Read range',\n", + " 'parameters': [{'description': ' Range to read from, e.g. \"A1:D10\"\\n',\n", + " 'name': ' range_'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Add the first worksheet\\n'\n", + " \"excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Insert a text in every cell in this range\\n'\n", + " \"excel.write_range('A1:D5', 'Hello World!')\\n\"\n", + " '# Read the same range\\n'\n", + " \"excel.read_range('A1:D5')\\n\"}\n", + "{'description': 'Run a macro by name from the currently active workbook',\n", + " 'example': \">>> excel = Excel('excel_with_macro.xlsx')\\n\"\n", + " '>>> # Run the macro\\n'\n", + " \">>> excel.run_macro('Macro1')\\n\",\n", + " 'function_call': 'run_macro(name)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'run macro', 'run vba'],\n", + " 'name': 'Run macro',\n", + " 'parameters': [{'description': ' Name of the macro to run. \\n',\n", + " 'name': ' name'}],\n", + " 'return': '',\n", + " 'snippet': \"excel = Excel('excel_with_macro.xlsx')\\n\"\n", + " '# Run the macro\\n'\n", + " \"excel.run_macro('Macro1')\\n\"}\n", + "{'description': 'Get names of all the worksheets in the currently active '\n", + " 'workbook',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Add a worksheet\\n'\n", + " \">>> excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Get all worksheet names\\n'\n", + " '>>> excel.get_worksheet_names()\\n'\n", + " \"['Sheet1', 'My Example Worksheet']\\n\",\n", + " 'function_call': 'get_worksheet_names(self)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'worksheet names', 'tab names'],\n", + " 'name': 'Get worksheet names',\n", + " 'parameters': [],\n", + " 'return': ' List is worksheet names\\n',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Add a worksheet\\n'\n", + " \"excel.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Get all worksheet names\\n'\n", + " 'excel.get_worksheet_names()\\n'}\n", + "{'description': 'Get table data from the currently active worksheet by name of '\n", + " 'the table',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Create a table (Table1)\\n'\n", + " '>>> data = [\\n'\n", + " ' {\\n'\n", + " \" 'Column A': 'Data Row 1 for A',\\n\"\n", + " \" 'Column B': 'Data Row 1 for B',\\n\"\n", + " \" 'Column C': 'Data Row 1 for C',\\n\"\n", + " ' },\\n'\n", + " ' {\\n'\n", + " \" 'Column A': 'Data Row 2 for A',\\n\"\n", + " \" 'Column B': 'Data Row 2 for B',\\n\"\n", + " \" 'Column C': 'Data Row 2 for C',\\n\"\n", + " ' }]\\n'\n", + " '>>> excel.insert_data_as_table(data)\\n'\n", + " '>>> # Get the table\\n'\n", + " \">>> excel.get_table('Table1')\\n\"\n", + " \"[['Column A', 'Column B', 'Column C'], ['Row 1 A Data', 'Row 1 B \"\n", + " \"Data', 'Row 1 C Data'], ...]\\n\",\n", + " 'function_call': 'get_table(name)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'worksheet names', 'tab names'],\n", + " 'name': 'Get table',\n", + " 'parameters': [{'description': ' List of table names\\n', 'name': ' name'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Create a table (Table1)\\n'\n", + " 'data = [\\n'\n", + " ' {\\n'\n", + " \" 'Column A': 'Data Row 1 for A',\\n\"\n", + " \" 'Column B': 'Data Row 1 for B',\\n\"\n", + " \" 'Column C': 'Data Row 1 for C',\\n\"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " ' },\\n'\n", + " ' {\\n'\n", + " \" 'Column A': 'Data Row 2 for A',\\n\"\n", + " \" 'Column B': 'Data Row 2 for B',\\n\"\n", + " \" 'Column C': 'Data Row 2 for C',\\n\"\n", + " ' }]\\n'\n", + " 'excel.insert_data_as_table(data)\\n'\n", + " '# Get the table\\n'\n", + " \"excel.get_table('Table1')\\n\"}\n", + "{'description': 'Activate a particular range in the currently active workbook',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Activate a cell range\\n'\n", + " \">>> excel.activate_range('A1:D5')\\n\",\n", + " 'function_call': 'activate_range(range_)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel',\n", + " 'activate range',\n", + " 'make selection',\n", + " 'select cells',\n", + " 'select range'],\n", + " 'name': 'Activate range',\n", + " 'parameters': [{'description': ' Range to activate, e.g. \"A1:D10\"\\n',\n", + " 'name': ' range_'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Activate a cell range\\n'\n", + " \"excel.activate_range('A1:D5')\\n\"}\n", + "{'description': 'Activates the first empty cell going down',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Write some cells\\n'\n", + " \">>> excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 3, 'Filled')\\n\"\n", + " '>>> # Activate the first empty cell going down, in this case cell '\n", + " 'A4 or (1,4)\\n'\n", + " '>>> excel.activate_first_empty_cell_down()\\n',\n", + " 'function_call': 'activate_first_empty_cell_down(self)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'first empty cell', 'down'],\n", + " 'name': 'Activate first empty cell down',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Write some cells\\n'\n", + " \"excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 3, 'Filled')\\n\"\n", + " '# Activate the first empty cell going down, in this case cell A4 '\n", + " 'or (1,4)\\n'\n", + " 'excel.activate_first_empty_cell_down()\\n'}\n", + "{'description': 'Activates the first empty cell going right',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Write some cells\\n'\n", + " \">>> excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 3, 'Filled')\\n\"\n", + " '>>> # Activate the first empty cell going right, in this case '\n", + " 'cell B1 or (2,1)\\n'\n", + " '>>> excel.activate_first_empty_cell_right()\\n',\n", + " 'function_call': 'activate_first_empty_cell_right(self)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'first empty cell', 'right'],\n", + " 'name': 'Activate first empty cell right',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Write some cells\\n'\n", + " \"excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 3, 'Filled')\\n\"\n", + " '# Activate the first empty cell going right, in this case cell B1 '\n", + " 'or (2,1)\\n'\n", + " 'excel.activate_first_empty_cell_right()\\n'}\n", + "{'description': 'Activates the first empty cell going left',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " \">>> excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 3, 'Filled')\\n\"\n", + " '>>> excel.activate_first_empty_cell_left()\\n',\n", + " 'function_call': 'activate_first_empty_cell_left(self)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'first empty cell', 'left'],\n", + " 'name': 'Activate first empty cell left',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " \"excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 3, 'Filled')\\n\"\n", + " 'excel.activate_first_empty_cell_left()\\n'}\n", + "{'description': 'Activates the first empty cell going up',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Write some cells\\n'\n", + " \">>> excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 3, 'Filled')\\n\"\n", + " '>>> # Activate first empty cell\\n'\n", + " '>>> excel.activate_first_empty_cell_up()\\n',\n", + " 'function_call': 'activate_first_empty_cell_up(self)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'first empty cell', 'up'],\n", + " 'name': 'Activate first empty cell up',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Write some cells\\n'\n", + " \"excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 3, 'Filled')\\n\"\n", + " '# Activate first empty cell\\n'\n", + " 'excel.activate_first_empty_cell_up()\\n'}\n", + "{'description': 'Write a formula to a particular cell',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Write a formula to the first cell\\n'\n", + " \">>> excel.write_cell_formula(1, 1, '=1+1)\\n\",\n", + " 'function_call': 'write_cell_formula(column, row, formula)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel',\n", + " 'insert formula',\n", + " 'insert calculation',\n", + " 'insert calculated cell'],\n", + " 'name': 'Write cell formula',\n", + " 'parameters': [{'description': ' Column number (integer) to write formula\\n',\n", + " 'name': ' column'},\n", + " {'description': ' Row number (integer) to write formula\\n',\n", + " 'name': ' row'},\n", + " {'description': ' Formula to write to specific cell e.g. '\n", + " '\"=10*RAND()\"\\n',\n", + " 'name': ' value'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Write a formula to the first cell\\n'\n", + " \"excel.write_cell_formula(1, 1, '=1+1)\\n\"}\n", + "{'description': 'Read the formula from a particular cell',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Write a formula to the first cell\\n'\n", + " \">>> excel.write_cell_formula(1, 1, '=1+1)\\n\"\n", + " '>>> # Read the cell\\n'\n", + " '>>> excel.read_cell_formula(1, 1)\\n'\n", + " \"'=1+1'\\n\",\n", + " 'function_call': 'read_cell_formula(column, row, formula)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'read formula', 'read calculation'],\n", + " 'name': 'Read cell formula',\n", + " 'parameters': [{'description': ' Column number (integer) to read formula\\n',\n", + " 'name': ' column'},\n", + " {'description': ' Row number (integer) to read formula\\n',\n", + " 'name': ' row'}],\n", + " 'return': ' Cell value\\n',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " '# Write a formula to the first cell\\n'\n", + " \"excel.write_cell_formula(1, 1, '=1+1)\\n\"\n", + " '# Read the cell\\n'\n", + " 'excel.read_cell_formula(1, 1)\\n'}\n", + "{'description': 'Inserts an empty row to the currently active worksheet',\n", + " 'example': '>>> # Open Excel \\n'\n", + " '>>> excel = Excel()\\n'\n", + " \">>> excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \">>> excel.write_cell(1, 3, 'Filled')\\n\"\n", + " '>>> excel.insert_empty_row(2)\\n',\n", + " 'function_call': 'insert_empty_row(row)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'insert row', 'add row', 'empty row'],\n", + " 'name': 'Insert empty row',\n", + " 'parameters': [{'description': ' Row number (integer) where to insert empty '\n", + " 'row e.g 1\\n',\n", + " 'name': ' row'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel \\n'\n", + " 'excel = Excel()\\n'\n", + " \"excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 2, 'Filled')\\n\"\n", + " \"excel.write_cell(1, 3, 'Filled')\\n\"\n", + " 'excel.insert_empty_row(2)\\n'}\n", + "{'description': 'Inserts an empty column in the currently active worksheet. '\n", + " 'Existing columns will shift to the right.',\n", + " 'example': '>>> # Open Excel\\n'\n", + " '>>> excel = Excel()\\n'\n", + " \">>> excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \">>> excel.write_cell(2, 2, 'Filled')\\n\"\n", + " \">>> excel.write_cell(3, 3, 'Filled')\\n\"\n", + " '>>> excel.insert_empty_column(2)\\n',\n", + " 'function_call': 'insert_empty_column(column)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'insert column', 'add column'],\n", + " 'name': 'Insert empty column',\n", + " 'parameters': [{'description': ' Column letter (string) where to insert empty '\n", + " \"column e.g. 'A'\\n\",\n", + " 'name': ' column'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel\\n'\n", + " 'excel = Excel()\\n'\n", + " \"excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \"excel.write_cell(2, 2, 'Filled')\\n\"\n", + " \"excel.write_cell(3, 3, 'Filled')\\n\"\n", + " 'excel.insert_empty_column(2)\\n'}\n", + "{'description': 'Deletes a row from the currently active worksheet. Existing '\n", + " 'data will shift up.',\n", + " 'example': '>>> # Open Excel \\n'\n", + " '>>> excel = Excel()\\n'\n", + " \">>> excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \">>> excel.write_cell(2, 2, 'Filled')\\n\"\n", + " \">>> excel.write_cell(3, 3, 'Filled')\\n\"\n", + " '>>> excel.delete_row(2)\\n',\n", + " 'function_call': 'delete_row(row)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'delete row', 'remove row'],\n", + " 'name': 'Delete row in Excel',\n", + " 'parameters': [{'description': ' Row number (integer) where to delete row e.g '\n", + " '1\\n',\n", + " 'name': ' row'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel \\n'\n", + " 'excel = Excel()\\n'\n", + " \"excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \"excel.write_cell(2, 2, 'Filled')\\n\"\n", + " \"excel.write_cell(3, 3, 'Filled')\\n\"\n", + " 'excel.delete_row(2)\\n'}\n", + "{'description': 'Delet a column from the currently active worksheet. Existing '\n", + " 'columns will shift to the left.',\n", + " 'example': '>>> # Open Excel \\n'\n", + " '>>> excel = Excel()\\n'\n", + " \">>> excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \">>> excel.write_cell(2, 2, 'Filled')\\n\"\n", + " \">>> excel.write_cell(3, 3, 'Filled')\\n\"\n", + " '>>> excel.delete_column(2)\\n',\n", + " 'function_call': 'delete_column(range_)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'delete column', 'remove column'],\n", + " 'name': 'Delete column',\n", + " 'parameters': [{'description': ' Column letter (string) where to delete '\n", + " \"column e.g. 'A'\\n\",\n", + " 'name': ' column'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel \\n'\n", + " 'excel = Excel()\\n'\n", + " \"excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \"excel.write_cell(2, 2, 'Filled')\\n\"\n", + " \"excel.write_cell(3, 3, 'Filled')\\n\"\n", + " 'excel.delete_column(2)\\n'}\n", + "{'description': ':parameter path: Output path where PDF file will be exported '\n", + " 'to. Default path is home directory with filename '\n", + " \"'pdf_export.pdf'.\",\n", + " 'example': '>>> # Open Excel \\n'\n", + " '>>> excel = Excel()\\n'\n", + " \">>> excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \">>> excel.write_cell(2, 2, 'Filled')\\n\"\n", + " \">>> excel.write_cell(3, 3, 'Filled')\\n\"\n", + " \">>> excel.export_to_pdf('output.pdf')\\n\",\n", + " 'function_call': 'export_to_pdf(path=None)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'save as pdf', 'export to pdf', 'export as pdf'],\n", + " 'name': 'Export to PDF',\n", + " 'parameters': [{'description': ' Output path where PDF file will be exported '\n", + " 'to. Default path is home directory with '\n", + " \"filename 'pdf_export.pdf'.\\n\",\n", + " 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel \\n'\n", + " 'excel = Excel()\\n'\n", + " \"excel.write_cell(1, 1, 'Filled')\\n\"\n", + " \"excel.write_cell(2, 2, 'Filled')\\n\"\n", + " \"excel.write_cell(3, 3, 'Filled')\\n\"\n", + " \"excel.export_to_pdf('output.pdf')\\n\"}\n", + "{'description': 'Insert list of dictionaries as a table in Excel',\n", + " 'example': '>>> excel = Excel()\\n'\n", + " '>>> data = [\\n'\n", + " ' {\\n'\n", + " \" 'Column A': 'Data Row 1 for A',\\n\"\n", + " \" 'Column B': 'Data Row 1 for B',\\n\"\n", + " \" 'Column C': 'Data Row 1 for C',\\n\"\n", + " ' },\\n'\n", + " ' {\\n'\n", + " \" 'Column A': 'Data Row 2 for A',\\n\"\n", + " \" 'Column B': 'Data Row 2 for B',\\n\"\n", + " \" 'Column C': 'Data Row 2 for C',\\n\"\n", + " ' }\\n'\n", + " '>>> excel.insert_data_as_table(data)\\n',\n", + " 'function_call': \"insert_data_as_table(data, range_='A1', \"\n", + " 'table_style=\"TableStyleMedium2\")',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'insert data', 'insert table', 'create table'],\n", + " 'name': 'Insert data as table',\n", + " 'parameters': [{'description': ' List of dictionaries to write as table\\n',\n", + " 'name': ' data'},\n", + " {'description': \" Range or startingpoint for table e.g. 'A1'\\n\",\n", + " 'name': ' range_'}],\n", + " 'return': '',\n", + " 'snippet': 'excel = Excel()\\n'\n", + " 'data = [\\n'\n", + " ' {\\n'\n", + " \" 'Column A': 'Data Row 1 for A',\\n\"\n", + " \" 'Column B': 'Data Row 1 for B',\\n\"\n", + " \" 'Column C': 'Data Row 1 for C',\\n\"\n", + " ' },\\n'\n", + " ' {\\n'\n", + " \" 'Column A': 'Data Row 2 for A',\\n\"\n", + " \" 'Column B': 'Data Row 2 for B',\\n\"\n", + " \" 'Column C': 'Data Row 2 for C',\\n\"\n", + " ' }\\n'\n", + " 'excel.insert_data_as_table(data)\\n'}\n", + "{'description': 'Read data from a worksheet as a list of lists',\n", + " 'example': '>>> # Open excel \\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> Write some cells\\n'\n", + " \">>> excel.write_cell(1, 1, 'A')\\n\"\n", + " \">>> excel.write_cell(1, 2, 'B')\\n\"\n", + " \">>> excel.write_cell(1, 3, 'C')\\n\"\n", + " '>>> excel.read_worksheet()\\n'\n", + " \"[['A'],['B'],['C']]\\n\",\n", + " 'function_call': 'read_worksheet(name=None, headers=False)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'read worksheet', 'export data', 'read data'],\n", + " 'name': 'Read worksheet',\n", + " 'parameters': [{'description': ' Optional name of worksheet to read. If no '\n", + " 'name is specified will take active sheet\\n',\n", + " 'name': ' name'},\n", + " {'description': ' Boolean to treat first row as headers. '\n", + " 'Default value is False\\n',\n", + " 'name': ' headers'}],\n", + " 'return': ' List of dictionaries with sheet data\\n',\n", + " 'snippet': '# Open excel \\n'\n", + " 'excel = Excel()\\n'\n", + " 'Write some cells\\n'\n", + " \"excel.write_cell(1, 1, 'A')\\n\"\n", + " \"excel.write_cell(1, 2, 'B')\\n\"\n", + " \"excel.write_cell(1, 3, 'C')\\n\"\n", + " 'excel.read_worksheet()\\n'}\n", + "{'description': \"This closes Excel, make sure to use :func: 'save' or \"\n", + " \"'save_as' if you would like to save before quitting.\",\n", + " 'example': '>>> # Open Excel \\n'\n", + " '>>> excel = Excel()\\n'\n", + " '>>> # Quit Excel\\n'\n", + " '>>> excel.quit()\\n',\n", + " 'function_call': 'quit(self)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'exit', 'quit', 'close'],\n", + " 'name': 'Quit Excel',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Open Excel \\nexcel = Excel()\\n# Quit Excel\\nexcel.quit()\\n'}\n", + "{'description': 'This activity can read, write and edit Excel (xlsx) files '\n", + " 'without the need of having Excel installed.Note that, in '\n", + " \"contrary to working with the :func: 'Excel' activities, a \"\n", + " 'file get saved directly after manipulation.',\n", + " 'example': '>>> # Open a new Excel file\\n>>> excel_file = ExcelFile()\\n',\n", + " 'function_call': 'ExcelFile(file_path=None)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'open', 'start', 'xlsx'],\n", + " 'name': 'Read and Write xlsx files.',\n", + " 'parameters': [{'description': ' Enter a path to open Excel with an existing '\n", + " 'Excel file. If no path is specified a '\n", + " \"'workbook.xlsx' will be initialized in the \"\n", + " 'home directory, this is the default value. If '\n", + " 'a workbook with the same name already exists '\n", + " 'the file will be overwritten.\\n',\n", + " 'name': ' file_path'}],\n", + " 'return': '',\n", + " 'snippet': '# Open a new Excel file\\nexcel_file = ExcelFile()\\n'}\n", + "{'description': 'Activate a worksheet. By default the first worksheet is '\n", + " 'activated.',\n", + " 'example': '>>> # Open a new Excel file\\n'\n", + " '>>> excel_file = ExcelFile()\\n'\n", + " '>>> # Add some worksheets\\n'\n", + " \">>> excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " \">>> excel_file.add_worksheet('Another Worksheet')\\n\"\n", + " '>>> # Activate a worksheet\\n'\n", + " \">>> excel_file.active_worksheet('My Example Worksheet')\\n\",\n", + " 'function_call': 'activate_worksheet(name)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'activate tab', 'activate worksheet'],\n", + " 'name': 'Activate worksheet',\n", + " 'parameters': [{'description': ' Name of the worksheet to activate. \\n',\n", + " 'name': ' name'}],\n", + " 'return': '',\n", + " 'snippet': '# Open a new Excel file\\n'\n", + " 'excel_file = ExcelFile()\\n'\n", + " '# Add some worksheets\\n'\n", + " \"excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " \"excel_file.add_worksheet('Another Worksheet')\\n\"\n", + " '# Activate a worksheet\\n'\n", + " \"excel_file.active_worksheet('My Example Worksheet')\\n\"}\n", + "{'description': ':parameter path: Path where workbook will be saved',\n", + " 'example': '>>> # Open a new Excel file\\n'\n", + " '>>> excel_file = ExcelFile()\\n'\n", + " '>>> # Ad a worksheet\\n'\n", + " \">>> excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Save the Excel file\\n'\n", + " \">>> excel_file.save_as('output.xlsx')\\n\"\n", + " '>>> # We can also save it in the home directory by using\\n'\n", + " \">>> excel_file.save_as( home_path('output.xlsx') )\\n\",\n", + " 'function_call': 'save_as(path)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'save as', 'export', 'save'],\n", + " 'name': 'Save as',\n", + " 'parameters': [{'description': ' Path where workbook will be saved\\n',\n", + " 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Open a new Excel file\\n'\n", + " 'excel_file = ExcelFile()\\n'\n", + " '# Ad a worksheet\\n'\n", + " \"excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Save the Excel file\\n'\n", + " \"excel_file.save_as('output.xlsx')\\n\"\n", + " '# We can also save it in the home directory by using\\n'\n", + " \"excel_file.save_as( home_path('output.xlsx') )\\n\"}\n", + "{'description': ':parameter column: Column number (integer) to write:parameter '\n", + " 'row: Row number (integer) to write:parameter value: Value to '\n", + " 'write to specific cell:parameter auto_save: Save document '\n", + " 'after performing activity. Default value is True',\n", + " 'example': '>>> # Open a new Excel file\\n'\n", + " '>>> excel_file = ExcelFile()\\n'\n", + " '>>> # Add a worksheet\\n'\n", + " \">>> excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " \">>> excel_file.write_cell(1, 1, 'Filled!')\\n\",\n", + " 'function_call': 'write_cell(column, row, value, auto_save=True)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'write cell', 'insert data'],\n", + " 'name': 'Write cell',\n", + " 'parameters': [{'description': ' Column number (integer) to write\\n',\n", + " 'name': ' column'},\n", + " {'description': ' Row number (integer) to write\\n',\n", + " 'name': ' row'},\n", + " {'description': ' Value to write to specific cell\\n',\n", + " 'name': ' value'},\n", + " {'description': ' Save document after performing activity. '\n", + " 'Default value is True\\n',\n", + " 'name': ' auto_save'}],\n", + " 'return': '',\n", + " 'snippet': '# Open a new Excel file\\n'\n", + " 'excel_file = ExcelFile()\\n'\n", + " '# Add a worksheet\\n'\n", + " \"excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " \"excel_file.write_cell(1, 1, 'Filled!')\\n\"}\n", + "{'description': ':parameter column: Column number (integer) to read:parameter '\n", + " 'row: Row number (integer) to read',\n", + " 'example': '>>> # Open a new Excel file\\n'\n", + " '>>> excel_file = ExcelFile()\\n'\n", + " '>>> # Add a worksheet\\n'\n", + " \">>> excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # Write the first cell\\n'\n", + " \">>> excel_file.write_cell(1, 1, 'Filled!')\\n\"\n", + " '>>> # Read the first cell\\n'\n", + " '>>> excel_file.read_cell(1, 1)\\n'\n", + " \"'Filled!'\\n\",\n", + " 'function_call': 'read_cell(column, row)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'read cell', 'read'],\n", + " 'name': 'Read cell',\n", + " 'parameters': [{'description': ' Column number (integer) to read\\n',\n", + " 'name': ' column'},\n", + " {'description': ' Row number (integer) to read\\n',\n", + " 'name': ' row'}],\n", + " 'return': ' Cell value\\n',\n", + " 'snippet': '# Open a new Excel file\\n'\n", + " 'excel_file = ExcelFile()\\n'\n", + " '# Add a worksheet\\n'\n", + " \"excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " '# Write the first cell\\n'\n", + " \"excel_file.write_cell(1, 1, 'Filled!')\\n\"\n", + " '# Read the first cell\\n'\n", + " 'excel_file.read_cell(1, 1)\\n'}\n", + "{'description': ':parameter name: Name of the worksheet to add:parameter '\n", + " 'auto_save: Save document after performing activity. Default '\n", + " 'value is True',\n", + " 'example': '>>> # Open a new Excel file\\n'\n", + " '>>> excel_file = ExcelFile()\\n'\n", + " '>>> # Add a worksheet\\n'\n", + " \">>> excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " '>>> # List all the worksheets\\n'\n", + " '>>> excel.get_worksheet_names()\\n',\n", + " 'function_call': 'add_worksheet(name, auto_save=True)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'add worksheet', 'worksheet'],\n", + " 'name': 'Add worksheet',\n", + " 'parameters': [{'description': ' Name of the worksheet to add\\n',\n", + " 'name': ' name'},\n", + " {'description': ' Save document after performing activity. '\n", + " 'Default value is True\\n',\n", + " 'name': ' auto_save'}],\n", + " 'return': '',\n", + " 'snippet': '# Open a new Excel file\\n'\n", + " 'excel_file = ExcelFile()\\n'\n", + " '# Add a worksheet\\n'\n", + " \"excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " '# List all the worksheets\\n'\n", + " 'excel.get_worksheet_names()\\n'}\n", + "{'description': ':return: List of worksheet names',\n", + " 'example': '>>> # Open a new Excel file\\n'\n", + " '>>> excel_file = ExcelFile()\\n'\n", + " '>>> # Add some worksheets\\n'\n", + " \">>> excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " \">>> excel_file.add_worksheet('Another Worksheet')\\n\"\n", + " '>>> # Get the worksheet names\\n'\n", + " '>>> excel_file.get_worksheet_names()\\n'\n", + " \"['My Example Worksheet', 'Another Worksheet']\\n\",\n", + " 'function_call': 'get_worksheet_names(self)',\n", + " 'icon': 'las la-file-excel',\n", + " 'keywords': ['excel', 'worksheet names', 'worksheet,'],\n", + " 'name': 'Get worksheet names',\n", + " 'parameters': [],\n", + " 'return': ' List of worksheet names\\n',\n", + " 'snippet': '# Open a new Excel file\\n'\n", + " 'excel_file = ExcelFile()\\n'\n", + " '# Add some worksheets\\n'\n", + " \"excel_file.add_worksheet('My Example Worksheet')\\n\"\n", + " \"excel_file.add_worksheet('Another Worksheet')\\n\"\n", + " '# Get the worksheet names\\n'\n", + " 'excel_file.get_worksheet_names()\\n'}\n", + "{'description': 'For this activity to work, PowerPoint needs to be installed '\n", + " 'on the system.',\n", + " 'example': '>>> # Start PowerPoint\\n>>> powerpoint = PowerPoint()\\n',\n", + " 'function_call': 'PowerPoint(visible=True, path=None, add_slide=True)',\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt'],\n", + " 'name': 'Start PowerPoint Application',\n", + " 'parameters': [{'description': ' Show PowerPoint in the foreground if True or '\n", + " 'hide if False, defaults to True.\\n',\n", + " 'name': ' visible'},\n", + " {'description': ' Enter a path to open an existing PowerPoint '\n", + " 'presentation. If no path is specified a new '\n", + " 'presentation will be initialized, this is the '\n", + " 'default value.\\n',\n", + " 'name': ' path'},\n", + " {'description': ' Add an initial empty slide when creating new '\n", + " 'PowerPointfile, this prevents errors since '\n", + " 'most manipulations require a non-empty '\n", + " 'presentation. Default value is True\\n',\n", + " 'name': ' add_slide'}],\n", + " 'return': ' Application object (win32com.client)\\n',\n", + " 'snippet': '# Start PowerPoint\\npowerpoint = PowerPoint()\\n'}\n", + "{'description': 'Save PowerPoint Slidedeck',\n", + " 'example': '>>> # Start PowerPoint\\n'\n", + " '>>> powerpoint = PowerPoint()\\n'\n", + " '>>> # Add a first slide\\n'\n", + " '>>> powerpoint.add_slide()\\n'\n", + " '>>> # Save the PowerPoint presentation\\n'\n", + " '>>> powerpoint.save()\\n',\n", + " 'function_call': 'save_as(path=None)',\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt', 'save', 'save as', 'save powerpoint'],\n", + " 'name': 'Save PowerPoint',\n", + " 'parameters': [{'description': ' Save the PowerPoint presentation. Default '\n", + " 'value is the home directory and filename '\n", + " \"'presentation.pptx'\\n\",\n", + " 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Start PowerPoint\\n'\n", + " 'powerpoint = PowerPoint()\\n'\n", + " '# Add a first slide\\n'\n", + " 'powerpoint.add_slide()\\n'\n", + " '# Save the PowerPoint presentation\\n'\n", + " 'powerpoint.save()\\n'}\n", + "{'description': 'Close PowerPoint',\n", + " 'example': '>>> # Start PowerPoint\\n'\n", + " '>>> powerpoint = PowerPoint()\\n'\n", + " '>>> # Close PowerPoint\\n'\n", + " '>>> powerpoint.quit()\\n',\n", + " 'function_call': 'quit(self)',\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt', 'quit', 'exit'],\n", + " 'name': 'Close PowerPoint Application',\n", + " 'parameters': [{'description': ' Index where the slide should be inserted. '\n", + " 'Default value is as final slide.\\n',\n", + " 'name': ' index'}],\n", + " 'return': '',\n", + " 'snippet': '# Start PowerPoint\\n'\n", + " 'powerpoint = PowerPoint()\\n'\n", + " '# Close PowerPoint\\n'\n", + " 'powerpoint.quit()\\n'}\n", + "{'description': 'Adds slides to a presentation',\n", + " 'example': '>>> # Start PowerPoint\\n'\n", + " '>>> powerpoint = PowerPoint()\\n'\n", + " '>>> # Add a first slide\\n'\n", + " '>>> powerpoint.add_slide()\\n',\n", + " 'function_call': \"add_slide(index=None, type='blank')\",\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt', 'add', 'add slide powerpoint', 'slides'],\n", + " 'name': 'Add PowerPoint Slides',\n", + " 'parameters': [{'description': ' Index where the slide should be inserted. '\n", + " 'Default value is as final slide.\\n',\n", + " 'name': ' index'}],\n", + " 'return': '',\n", + " 'snippet': '# Start PowerPoint\\n'\n", + " 'powerpoint = PowerPoint()\\n'\n", + " '# Add a first slide\\n'\n", + " 'powerpoint.add_slide()\\n'}\n", + "{'description': ':return: The number of slides',\n", + " 'example': '>>> # Start PowerPoint\\n'\n", + " '>>> powerpoint = PowerPoint()\\n'\n", + " '>>> # Add some slides\\n'\n", + " '>>> powerpoint.add_slide()\\n'\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " '>>> powerpoint.add_slide()\\n'\n", + " '>>> # Show number of slides\\n'\n", + " '>>> powerpoint.number_of_slides()\\n',\n", + " 'function_call': 'number_of_slides(self)',\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt', 'slide count', 'number of slides'],\n", + " 'name': 'Slide count',\n", + " 'parameters': [],\n", + " 'return': ' The number of slides\\n',\n", + " 'snippet': '# Start PowerPoint\\n'\n", + " 'powerpoint = PowerPoint()\\n'\n", + " '# Add some slides\\n'\n", + " 'powerpoint.add_slide()\\n'\n", + " 'powerpoint.add_slide()\\n'\n", + " '# Show number of slides\\n'\n", + " 'powerpoint.number_of_slides()\\n'}\n", + "{'description': 'Add text to a slide',\n", + " 'example': '>>> # Start PowerPoint\\n'\n", + " '>>> powerpoint = PowerPoint()\\n'\n", + " '>>> # Add slide with text\\n'\n", + " \">>> powerpoint.add_text(text='Sample Text')\\n\",\n", + " 'function_call': 'add_text(text, index=None, font_size=48, font_name=None, '\n", + " 'bold=False, margin_bottom=100, margin_left=100, '\n", + " 'margin_right=100, margin_top=100)',\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt', 'text', 'add text', 'slides'],\n", + " 'name': 'Text to slide',\n", + " 'parameters': [{'description': ' Slide index to add text. If none is '\n", + " 'specified, a new slide will be added as final '\n", + " 'slide\\n',\n", + " 'name': ' index'},\n", + " {'description': ' Fontsize, default value is 48\\n',\n", + " 'name': ' font_size'},\n", + " {'description': ' Fontname, if not specified will take default '\n", + " 'PowerPoint font\\n',\n", + " 'name': ' font_name'},\n", + " {'description': ' Toggle bold with True or False, default '\n", + " 'value is False\\n',\n", + " 'name': ' bold'},\n", + " {'description': ' Margin from the bottom in pixels, default '\n", + " 'value is 100 pixels\\n',\n", + " 'name': ' margin_bottom'},\n", + " {'description': ' Margin from the left in pixels, default '\n", + " 'value is 100 pixels\\n',\n", + " 'name': ' margin_left'},\n", + " {'description': ' Margin from the right in pixels, default '\n", + " 'value is 100 pixels\\n',\n", + " 'name': ' margin_right'},\n", + " {'description': ' Margin from the top in pixels, default value '\n", + " 'is 100 pixels\\n',\n", + " 'name': ' margin_top'}],\n", + " 'return': '',\n", + " 'snippet': '# Start PowerPoint\\n'\n", + " 'powerpoint = PowerPoint()\\n'\n", + " '# Add slide with text\\n'\n", + " \"powerpoint.add_text(text='Sample Text')\\n\"}\n", + "{'description': ':parameter index: Slide index to be deleted. If none is '\n", + " 'specified, last slide will be deleted',\n", + " 'example': '>>> # Start PowerPoint\\n'\n", + " '>>> powerpoint = PowerPoint()\\n'\n", + " '>>> # Add some slides\\n'\n", + " '>>> powerpoint.add_slide()\\n'\n", + " '>>> powerpoint.add_slide()\\n'\n", + " '>>> # Delete last slide\\n'\n", + " '>>> powerpoint.delete_slide()\\n',\n", + " 'function_call': 'delete_slide(index=None)',\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt', 'delete', 'delete slide'],\n", + " 'name': 'Delete slide',\n", + " 'parameters': [{'description': ' Slide index to be deleted. If none is '\n", + " 'specified, last slide will be deleted\\n',\n", + " 'name': ' index'}],\n", + " 'return': '',\n", + " 'snippet': '# Start PowerPoint\\n'\n", + " 'powerpoint = PowerPoint()\\n'\n", + " '# Add some slides\\n'\n", + " 'powerpoint.add_slide()\\n'\n", + " 'powerpoint.add_slide()\\n'\n", + " '# Delete last slide\\n'\n", + " 'powerpoint.delete_slide()\\n'}\n", + "{'description': 'Can be used for example to replace arbitrary placeholder '\n", + " 'value in a PowerPoint.For example when using a template '\n", + " \"slidedeck, using 'XXXX' as a placeholder.Take note that all \"\n", + " 'strings are case sensitive.',\n", + " 'example': '>>> # Start PowerPoint\\n'\n", + " '>>> powerpoint = PowerPoint()\\n'\n", + " '>>> # Add some slides with text\\n'\n", + " \">>> powerpoint.add_text(text='Hello, my name is placeholder')\\n\"\n", + " \">>> # Change 'placeholder' to the word 'robot\\n\"\n", + " \">>> powerpoint.replace_text(placeholder_text = 'placeholder', \"\n", + " \"replacement_text ='robot')\\n\",\n", + " 'function_call': 'replace_text(placeholder_text, replacement_text)',\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt', 'replace', 'placeholder'],\n", + " 'name': 'Replace all occurences of text in PowerPoint slides',\n", + " 'parameters': [{'description': ' Placeholder value (string) in the '\n", + " 'PowerPoint, this will be replaced, e.g. '\n", + " \"'Company Name'\\n\",\n", + " 'name': ' placeholder_text'},\n", + " {'description': ' Text (string) to replace the placeholder '\n", + " 'values with. It is recommended to make this '\n", + " 'unique in your PowerPoint to avoid wrongful '\n", + " \"replacement, e.g. 'XXXX_placeholder_XXX'\\n\",\n", + " 'name': ' replacement_text'}],\n", + " 'return': '',\n", + " 'snippet': '# Start PowerPoint\\n'\n", + " 'powerpoint = PowerPoint()\\n'\n", + " '# Add some slides with text\\n'\n", + " \"powerpoint.add_text(text='Hello, my name is placeholder')\\n\"\n", + " \"# Change 'placeholder' to the word 'robot\\n\"\n", + " \"powerpoint.replace_text(placeholder_text = 'placeholder', \"\n", + " \"replacement_text ='robot')\\n\"}\n", + "{'description': 'Export PowerPoint presentation to PDF file',\n", + " 'example': '>>> # Start PowerPoint\\n'\n", + " '>>> powerpoint = PowerPoint()\\n'\n", + " '>>> # Add some slides with text\\n'\n", + " \">>> powerpoint.add_text(text='Robots are cool')\\n\"\n", + " '>>> # Export to pdf\\n'\n", + " '>>> powerpoint.export_to_pdf()\\n',\n", + " 'function_call': 'export_to_pdf(path=None)',\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt', 'export', 'pdf'],\n", + " 'name': 'PowerPoint to PDF',\n", + " 'parameters': [{'description': ' Output path where PDF file will be exported '\n", + " 'to. Default path is home directory with '\n", + " \"filename 'pdf_export.pdf'.\\n\",\n", + " 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Start PowerPoint\\n'\n", + " 'powerpoint = PowerPoint()\\n'\n", + " '# Add some slides with text\\n'\n", + " \"powerpoint.add_text(text='Robots are cool')\\n\"\n", + " '# Export to pdf\\n'\n", + " 'powerpoint.export_to_pdf()\\n'}\n", + "{'description': 'Export PowerPoint slides to seperate image files',\n", + " 'example': '>>> # Start PowerPoint\\n'\n", + " '>>> powerpoint = PowerPoint()\\n'\n", + " '>>> # Add some slides with text\\n'\n", + " \">>> powerpoint.add_text(text='Robots are cool')\\n\"\n", + " \">>> powerpoint.add_text(text='Humans are cooler')\\n\"\n", + " '>>> # Export slides to images\\n'\n", + " '>>> powerpoint.export_slides_to_images()\\n',\n", + " 'function_call': \"export_slides_to_images(path=None, type='png')\",\n", + " 'icon': 'las la-file-powerpoint',\n", + " 'keywords': ['powerpoint', 'ppt', 'export', 'png', 'image', 'slides to image'],\n", + " 'name': 'Slides to images',\n", + " 'parameters': [{'description': ' Output path where image files will be '\n", + " 'exported to. Default path is home '\n", + " 'directory.\\n',\n", + " 'name': ' path'},\n", + " {'description': \" Output type of the images, supports 'png' \"\n", + " \"and 'jpg' with 'png' as default value\\n\",\n", + " 'name': ' type'}],\n", + " 'return': '',\n", + " 'snippet': '# Start PowerPoint\\n'\n", + " 'powerpoint = PowerPoint()\\n'\n", + " '# Add some slides with text\\n'\n", + " \"powerpoint.add_text(text='Robots are cool')\\n\"\n", + " \"powerpoint.add_text(text='Humans are cooler')\\n\"\n", + " '# Export slides to images\\n'\n", + " 'powerpoint.export_slides_to_images()\\n'}\n", + "{'description': ':parameter client_id: Client id for office 365 '\n", + " 'account:parameter client_secret: Client secret for office 365 '\n", + " 'account:parameter to_email: E-mail to send to:parameter '\n", + " 'subject: Optional subject:parameter body: Optional body of '\n", + " 'the email',\n", + " 'example': \">>> # Send email to 'robot@automagica.com'\\n\"\n", + " \">>> send_email_with_outlook365('SampleClientID', \"\n", + " \"'SampleClientSecret', 'robot@automagica.com')\\n\",\n", + " 'function_call': 'send_email_with_outlook365(client_id, client_secret, '\n", + " \"to_email, subject='', body='')\",\n", + " 'icon': 'las la-envelope',\n", + " 'keywords': ['mail', 'office 365', 'outlook', 'email', 'e-mail'],\n", + " 'name': 'Send email Office Outlook 365',\n", + " 'parameters': [{'description': ' Client id for office 365 account\\n',\n", + " 'name': ' client_id'},\n", + " {'description': ' Client secret for office 365 account\\n',\n", + " 'name': ' client_secret'},\n", + " {'description': ' E-mail to send to\\n', 'name': ' to_email'},\n", + " {'description': ' Optional subject\\n', 'name': ' subject'},\n", + " {'description': ' Optional body of the email\\n',\n", + " 'name': ' body'}],\n", + " 'return': '',\n", + " 'snippet': \"# Send email to 'robot@automagica.com'\\n\"\n", + " \"send_email_with_outlook365('SampleClientID', \"\n", + " \"'SampleClientSecret', 'robot@automagica.com')\\n\"}\n", + "{'description': 'Activity to make calls to Salesforce REST API.',\n", + " 'example': \">>> spf_api_call('action', 'key', 'parameters')\\nResponse\\n\",\n", + " 'function_call': 'salesforce_api_call(action, key, parameters={}, '\n", + " \"method='get', data={})\",\n", + " 'icon': 'lab la-salesforce',\n", + " 'keywords': ['salesforce'],\n", + " 'name': 'Salesforce API',\n", + " 'parameters': [{'description': ' Action (the URL)\\n', 'name': ' action'},\n", + " {'description': ' Authorisation key \\n', 'name': ' key'},\n", + " {'description': ' URL params\\n', 'name': ' parameters'},\n", + " {'description': ' Method (get, post or patch)\\n',\n", + " 'name': ' method'},\n", + " {'description': ' Data for POST/PATCH.\\n', 'name': ' data'}],\n", + " 'return': ' API data\\n',\n", + " 'snippet': \"spf_api_call('action', 'key', 'parameters')\\n\"}\n", + "{'description': 'This function lets you send emails with an e-mail address.',\n", + " 'example': \">>> send_mail_smpt('robot@automagica.com', 'SampleUser', \"\n", + " \"'SamplePassword', 'robotfriend@automagica.com')\\n\",\n", + " 'function_call': 'send_mail_smtp(smtp_host, smtp_user, smtp_password, '\n", + " 'to_address, subject=\"\", message=\"\", port=587)',\n", + " 'icon': 'las la-mail-bulk',\n", + " 'keywords': ['mail', 'e-mail', 'email smpt'],\n", + " 'name': 'Mail with SMTP',\n", + " 'parameters': [{'description': ' The host of your e-mail account. \\n',\n", + " 'name': ' smpt_host'},\n", + " {'description': ' The password of your e-mail account\\n',\n", + " 'name': ' smpt_user'},\n", + " {'description': ' The password of your e-mail account\\n',\n", + " 'name': ' smpt_password'},\n", + " {'description': ' The destination is the receiving mail '\n", + " 'address. \\n',\n", + " 'name': ' to_address'},\n", + " {'description': ' The subject \\n', 'name': ' subject'},\n", + " {'description': ' The body of the mail\\n', 'name': ' message'},\n", + " {'description': ' The port variable is standard 587. In most '\n", + " 'cases this argument can be ignored, but in '\n", + " 'some cases it needs to be changed to 465.\\n',\n", + " 'name': ' port'}],\n", + " 'return': '',\n", + " 'snippet': \"send_mail_smpt('robot@automagica.com', 'SampleUser', \"\n", + " \"'SamplePassword', 'robotfriend@automagica.com')\\n\"}\n", + "{'description': 'Sets the password for a Windows user.',\n", + " 'example': \">>> set_user_password('SampleUsername', 'SamplePassword')\\n\",\n", + " 'function_call': 'set_user_password(username, password)',\n", + " 'icon': 'las la-passport',\n", + " 'keywords': ['windows', 'user', 'password', 'account'],\n", + " 'name': 'Set Windows password',\n", + " 'parameters': [{'description': ' Username\\n', 'name': ' username'},\n", + " {'description': ' New password\\n', 'name': ' password'}],\n", + " 'return': '',\n", + " 'snippet': \"set_user_password('SampleUsername', 'SamplePassword')\\n\"}\n", + "{'description': 'Validates a Windows user password if it is correct',\n", + " 'example': \">>> validate_user_password('SampleUsername', 'SamplePassword')\\n\"\n", + " 'False\\n',\n", + " 'function_call': 'validate_user_password(username, password)',\n", + " 'icon': 'las la-passport',\n", + " 'keywords': ['windows', 'user', 'password', 'account'],\n", + " 'name': 'Check Windows password',\n", + " 'parameters': [{'description': ' Username\\n', 'name': ' username'},\n", + " {'description': ' New password\\n', 'name': ' password'}],\n", + " 'return': ' True if the password is correct\\n',\n", + " 'snippet': \"validate_user_password('SampleUsername', 'SamplePassword')\\n\"}\n", + "{'description': 'Locks Windows requiring login to continue.',\n", + " 'example': '>>> lock_windows()\\n',\n", + " 'function_call': 'lock_windows()',\n", + " 'icon': 'las la-user-lock',\n", + " 'keywords': ['windows',\n", + " 'user',\n", + " 'password',\n", + " 'account',\n", + " 'lock',\n", + " 'freeze',\n", + " 'hibernate',\n", + " 'sleep',\n", + " 'lockescreen'],\n", + " 'name': 'Lock Windows',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': 'lock_windows()\\n'}\n", + "{'description': 'Checks if the current user is logged in and not on the '\n", + " 'lockscreen. Most automations do not work properly when the '\n", + " 'desktop is locked.',\n", + " 'example': '>>> is_logged_in()\\nTrue\\n',\n", + " 'function_call': 'is_logged_in()',\n", + " 'icon': 'lar la-user',\n", + " 'keywords': ['windows',\n", + " 'login',\n", + " 'logged in',\n", + " 'lockscreen',\n", + " 'user',\n", + " 'password',\n", + " 'account',\n", + " 'lock',\n", + " 'freeze',\n", + " 'hibernate',\n", + " 'sleep'],\n", + " 'name': 'Check if Windows logged in',\n", + " 'parameters': [],\n", + " 'return': ' True if the user is logged in, False if not\\n',\n", + " 'snippet': 'is_logged_in()\\n'}\n", + "{'description': 'Checks if the current user is locked out and on the '\n", + " 'lockscreen. Most automations do not work properly when the '\n", + " 'desktop is locked.',\n", + " 'example': '>>> desktop_locked()\\nTrue\\n',\n", + " 'function_call': 'is_desktop_locked()',\n", + " 'icon': 'las la-user',\n", + " 'keywords': ['windows',\n", + " 'login',\n", + " 'logged in',\n", + " 'lockscreen',\n", + " 'user',\n", + " 'password',\n", + " 'account',\n", + " 'lock',\n", + " 'locked',\n", + " 'freeze',\n", + " 'hibernate',\n", + " 'sleep'],\n", + " 'name': 'Check if Windows is locked',\n", + " 'parameters': [],\n", + " 'return': ' True when the lockscreen is active, False if not.\\n',\n", + " 'snippet': 'desktop_locked()\\n'}\n", + "{'description': \"Get current logged in user's username\",\n", + " 'example': \">>> get_username()\\n'Automagica'\\n\",\n", + " 'function_call': 'get_username()',\n", + " 'icon': 'las la-user',\n", + " 'keywords': ['windows',\n", + " 'login',\n", + " 'logged in',\n", + " 'lockscreen',\n", + " 'user',\n", + " 'password',\n", + " 'account',\n", + " 'lock',\n", + " 'locked',\n", + " 'freeze',\n", + " 'hibernate',\n", + " 'sleep'],\n", + " 'name': 'Get Windows username',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': 'get_username()\\n'}\n", + "{'description': 'Set any text to the Windows clipboard.',\n", + " 'example': '>>> # Create some sample text\\n'\n", + " \">>> sample_text = 'A robots favourite food must be computer \"\n", + " \"chips'\\n\"\n", + " '>>> # Set to clipboard\\n'\n", + " '>>> set_to_clipboard(sample_text)\\n'\n", + " '>>> # Print the clipboard to verify\\n'\n", + " '>>> print( get_from_clipboard() )\\n',\n", + " 'function_call': 'set_to_clipboard(text)',\n", + " 'icon': 'las la-clipboard-check',\n", + " 'keywords': ['copy', 'clipboard', 'clip board', 'ctrl c', 'ctrl v', 'paste'],\n", + " 'name': 'Set clipboard',\n", + " 'parameters': [{'description': ' Text to put in the clipboard\\n',\n", + " 'name': ' text'}],\n", + " 'return': '',\n", + " 'snippet': '# Create some sample text\\n'\n", + " \"sample_text = 'A robots favourite food must be computer chips'\\n\"\n", + " '# Set to clipboard\\n'\n", + " 'set_to_clipboard(sample_text)\\n'\n", + " '# Print the clipboard to verify\\n'\n", + " 'print( get_from_clipboard() )\\n'}\n", + "{'description': 'Get the text currently in the Windows clipboard',\n", + " 'example': '>>> # Create some sample text\\n'\n", + " \">>> sample_text = 'A robots favourite food must be computer \"\n", + " \"chips'\\n\"\n", + " '>>> # Set to clipboard\\n'\n", + " '>>> set_to_clipboard(sample_text)\\n'\n", + " '>>> # Get the clipboard to verify\\n'\n", + " '>>> get_from_clipboard()\\n'\n", + " \"'A robots favourite food must be computer chips'\\n\",\n", + " 'function_call': 'get_from_clipboard()',\n", + " 'icon': 'las la-clipboard-list',\n", + " 'keywords': ['copy', 'clipboard', 'clip board', 'ctrl c', 'ctrl v', 'paste'],\n", + " 'name': 'Get clipboard',\n", + " 'parameters': [],\n", + " 'return': ' Text currently in the clipboard\\n',\n", + " 'snippet': '# Create some sample text\\n'\n", + " \"sample_text = 'A robots favourite food must be computer chips'\\n\"\n", + " '# Set to clipboard\\n'\n", + " 'set_to_clipboard(sample_text)\\n'\n", + " '# Get the clipboard to verify\\n'\n", + " 'get_from_clipboard()\\n'}\n", + "{'description': 'Empty text from clipboard. Getting clipboard data after this '\n", + " 'should return in None',\n", + " 'example': '>>> # Create some sample text\\n'\n", + " \">>> sample_text = 'A robots favourite food must be computer \"\n", + " \"chips'\\n\"\n", + " '>>> # Set to clipboard\\n'\n", + " '>>> set_to_clipboard(sample_text)\\n'\n", + " '>>> # Clear the clipboard\\n'\n", + " '>>> clear_clipboard()\\n'\n", + " '>>> # Get clipboard contents to verify\\n'\n", + " '>>> print( get_clipboard() )\\n'\n", + " 'None\\n',\n", + " 'function_call': 'clear_clipboard()',\n", + " 'icon': 'las la-clipboard',\n", + " 'keywords': ['copy', 'clipboard', 'clip board', 'ctrl c', 'ctrl v', 'paste'],\n", + " 'name': 'Empty clipboard',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': '# Create some sample text\\n'\n", + " \"sample_text = 'A robots favourite food must be computer chips'\\n\"\n", + " '# Set to clipboard\\n'\n", + " 'set_to_clipboard(sample_text)\\n'\n", + " '# Clear the clipboard\\n'\n", + " 'clear_clipboard()\\n'\n", + " '# Get clipboard contents to verify\\n'\n", + " 'print( get_clipboard() )\\n'}\n", + "{'description': 'Run a VBScript file',\n", + " 'example': \">>> # Run a VBS script\\n>>> run_vbs_script('Samplescript.vbs')\\n\",\n", + " 'function_call': 'run_vbs_script(script_path, parameters=[])',\n", + " 'icon': 'las la-cogs',\n", + " 'keywords': ['vbs', 'VBScript'],\n", + " 'name': 'Run VBSscript',\n", + " 'parameters': [{'description': ' Path to the .vbs-file\\n',\n", + " 'name': ' script_path'},\n", + " {'description': ' Additional arguments to pass to the '\n", + " 'VBScript\\n',\n", + " 'name': ' parameters'}],\n", + " 'return': '',\n", + " 'snippet': \"# Run a VBS script\\nrun_vbs_script('Samplescript.vbs')\\n\"}\n", + "{'description': 'Make a beeping sound. Make sure your volume is up and you '\n", + " 'have hardware connected.',\n", + " 'example': '>>> beep()\\n',\n", + " 'function_call': 'beep(frequency=1000, duration=500)',\n", + " 'icon': 'las la-volume-up',\n", + " 'keywords': ['beep', 'sound', 'noise', 'speaker', 'alert'],\n", + " 'name': 'Beep',\n", + " 'parameters': [{'description': ' Integer to specify frequency (Hz), default '\n", + " 'value is 1000 Hz\\n',\n", + " 'name': ' frequency'},\n", + " {'description': ' Integer to specify duration of beep in '\n", + " 'miliseconds (ms), default value is 500 ms.\\n',\n", + " 'name': ' duration'}],\n", + " 'return': ' Sound\\n',\n", + " 'snippet': 'beep()\\n'}\n", + "{'description': 'Use the Text-To-Speech engine available on your system to '\n", + " 'read text',\n", + " 'example': '>>> # Read the following text out loud\\n'\n", + " \">>> speak('How do robots eat guacamole?')\\n\"\n", + " \">>> speak('With microchips!')\\n\",\n", + " 'function_call': 'speak(text, speed=None)',\n", + " 'icon': 'las la-microphone-alt',\n", + " 'keywords': ['sound',\n", + " 'speech',\n", + " 'text',\n", + " 'speech to text',\n", + " 'speech-to-text',\n", + " 'translate',\n", + " 'read',\n", + " 'read out loud'],\n", + " 'name': 'Speak',\n", + " 'parameters': [{'description': ' The text which should be said\\n',\n", + " 'name': ' text'},\n", + " {'description': ' Multiplication factor for the speed at which '\n", + " 'the text should be pronounced. \\n',\n", + " 'name': ' speed'}],\n", + " 'return': ' Spoken text\\n',\n", + " 'snippet': '# Read the following text out loud\\n'\n", + " \"speak('How do robots eat guacamole?')\\n\"\n", + " \"speak('With microchips!')\\n\"}\n", + "{'description': 'Interface to Windows Active Directory through ADSI',\n", + " 'example': '>>> ad = ActiveDirectory()\\n',\n", + " 'function_call': 'ActiveDirectory(ldap_server=None, username=None, '\n", + " 'password=None)',\n", + " 'icon': 'las la-audio-description',\n", + " 'keywords': ['AD', 'active directory', 'activedirectory'],\n", + " 'name': 'AD interface',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': 'ad = ActiveDirectory()\\n'}\n", + "{'description': 'Interface to Windows Active Directory through ADSI',\n", + " 'example': '>>> ad = ActiveDirectory()\\n'\n", + " \">>> ad.get_object_by_distinguished_name('SampleDN')\\n\",\n", + " 'function_call': 'get_object_by_distinguished_name(distinguished_name)',\n", + " 'icon': 'las la-audio-description',\n", + " 'keywords': ['AD', 'active directory', 'activedirectory'],\n", + " 'name': 'Get AD object by name',\n", + " 'parameters': [],\n", + " 'return': '',\n", + " 'snippet': 'ad = ActiveDirectory()\\n'\n", + " \"ad.get_object_by_distinguished_name('SampleDN')\\n\"}\n", + "{'description': \"Returns the current user's home path\",\n", + " 'example': '>>> # Home_path without arguments will return the home path\\n'\n", + " '>>> print( home_path() )\\n'\n", + " '>>> # When looking for a file in the home path, we can specify '\n", + " 'it\\n'\n", + " '>>> # First make a sample textfile\\n'\n", + " '>>> make_textfile()\\n'\n", + " '>>> # Refer to it\\n'\n", + " \">>> home_path('generated_textfile.txt')\\n\"\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\generated_textfile.txt'\\n\",\n", + " 'function_call': 'home_path(subdir=None)',\n", + " 'icon': 'las la-home',\n", + " 'keywords': ['home', 'home path', 'homepath', 'home directory', 'homedir'],\n", + " 'name': 'Get user home path',\n", + " 'parameters': [{'description': ' Optional filename to add to the path. Can '\n", + " 'also be a subdirectory\\n',\n", + " 'name': ' filename'}],\n", + " 'return': \" Path to the current user's home folder\\n\",\n", + " 'snippet': '# Home_path without arguments will return the home path\\n'\n", + " 'print( home_path() )\\n'\n", + " '# When looking for a file in the home path, we can specify it\\n'\n", + " '# First make a sample textfile\\n'\n", + " 'make_textfile()\\n'\n", + " '# Refer to it\\n'\n", + " \"home_path('generated_textfile.txt')\\n\"}\n", + "{'description': \"Returns the current user's desktop path\",\n", + " 'example': '>>> # Desktop_path without arguments will return the home path\\n'\n", + " '>>> print( desktop_path() )\\n'\n", + " '>>> # When looking for a file on the desktop, we can specify it\\n'\n", + " '>>> # First make a sample textfile\\n'\n", + " '>>> make_textfile()\\n'\n", + " '>>> # Refer to it\\n'\n", + " \">>> desktop_path('generated_textfile.txt')\\n\"\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\Desktop\\\\\\\\generated_textfile.txt'\\n\",\n", + " 'function_call': 'desktop_path(subdir=None)',\n", + " 'icon': 'lar la-desktop',\n", + " 'keywords': ['desktop',\n", + " 'desktop path',\n", + " 'desktoppath',\n", + " 'desktop directory',\n", + " 'desktopdir'],\n", + " 'name': 'Get desktop path',\n", + " 'parameters': [{'description': ' Optional filename to add to the path. Can '\n", + " 'also be a subdirectory\\n',\n", + " 'name': ' filename'}],\n", + " 'return': \" Path to the current user's desktop folder\\n\",\n", + " 'snippet': '# Desktop_path without arguments will return the home path\\n'\n", + " 'print( desktop_path() )\\n'\n", + " '# When looking for a file on the desktop, we can specify it\\n'\n", + " '# First make a sample textfile\\n'\n", + " 'make_textfile()\\n'\n", + " '# Refer to it\\n'\n", + " \"desktop_path('generated_textfile.txt')\\n\"}\n", + "{'description': 'Opens file with default programs',\n", + " 'example': '>>> # Make textfile\\n'\n", + " '>>> testfile = make_textfile()\\n'\n", + " '>>> # Open the file\\n'\n", + " '>>> open_file(testfile)\\n',\n", + " 'function_call': 'open_file(path)',\n", + " 'icon': 'lar la-file',\n", + " 'keywords': ['file',\n", + " 'open',\n", + " 'open file',\n", + " 'show',\n", + " 'reveal',\n", + " 'explorer',\n", + " 'run',\n", + " 'start'],\n", + " 'name': 'Open file',\n", + " 'parameters': [{'description': ' Path to file. \\n', 'name': ' path'}],\n", + " 'return': ' Path to file\\n',\n", + " 'snippet': '# Make textfile\\n'\n", + " 'testfile = make_textfile()\\n'\n", + " '# Open the file\\n'\n", + " 'open_file(testfile)\\n'}\n", + "{'description': 'Set Windows desktop wallpaper with the the specified image',\n", + " 'example': '>>> # Caution: this example will change your wallpaper\\n'\n", + " '>>> # Take a screenshot of current screen\\n'\n", + " '>>> screenshot = take_screenshot()\\n'\n", + " '>>> # Flip it hozirontally for fun\\n'\n", + " '>>> mirror_image_horizontally(screenshot)\\n'\n", + " '>>> # Set flipped image as wallpaper\\n'\n", + " '>>> set_wallpaper(screenshot)\\n',\n", + " 'function_call': 'set_wallpaper(image_path)',\n", + " 'icon': 'las la-desktop',\n", + " 'keywords': ['desktop',\n", + " 'desktop path',\n", + " 'desktoppath',\n", + " 'desktop directory',\n", + " 'desktopdir'],\n", + " 'name': 'Set wallpaper',\n", + " 'parameters': [{'description': ' Path to the image. This image will be set as '\n", + " 'desktop wallpaper\\n',\n", + " 'name': ' image_path'}],\n", + " 'return': '',\n", + " 'snippet': '# Caution: this example will change your wallpaper\\n'\n", + " '# Take a screenshot of current screen\\n'\n", + " 'screenshot = take_screenshot()\\n'\n", + " '# Flip it hozirontally for fun\\n'\n", + " 'mirror_image_horizontally(screenshot)\\n'\n", + " '# Set flipped image as wallpaper\\n'\n", + " 'set_wallpaper(screenshot)\\n'}\n", + "{'description': ':parameter url: Source URL to download file from:parameter '\n", + " 'filename::parameter path: Target path. If no path is given '\n", + " 'will download to the home directory',\n", + " 'example': '>>> # Download robot picture from the wikipedia robot page\\n'\n", + " '>>> picture_url = '\n", + " \"'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Atlas_from_boston_dynamics.jpg/220px-Atlas_from_boston_dynamics.jpg'\\n\"\n", + " '>>> download_file_from_url(url = picture_url, filename = '\n", + " \"'robot.jpg')\\n\"\n", + " \"'C:\\\\\\\\Users\\\\\\\\\\\\\\\\robot.jpg'\\n\",\n", + " 'function_call': 'download_file_from_url(url, filename=None, path=None)',\n", + " 'icon': 'las la-cloud-download-alt',\n", + " 'keywords': ['download', 'download url', 'save', 'request'],\n", + " 'name': 'Download file from a URL',\n", + " 'parameters': [{'description': ' Source URL to download file from\\n',\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 'name': ' url'},\n", + " {'description': ' \\n', 'name': ' filename'},\n", + " {'description': ' Target path. If no path is given will '\n", + " 'download to the home directory\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' Target path as string\\n',\n", + " 'snippet': '# Download robot picture from the wikipedia robot page\\n'\n", + " 'picture_url = '\n", + " \"'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Atlas_from_boston_dynamics.jpg/220px-Atlas_from_boston_dynamics.jpg'\\n\"\n", + " 'download_file_from_url(url = picture_url, filename = '\n", + " \"'robot.jpg')\\n\"}\n", + "{'description': 'Add a card to the Trello board. For this you need a Trello '\n", + " 'API key, secret and token.',\n", + " 'example': \">>> add_trello_card(title='ExampleTitle', \"\n", + " \"description='ExampleDescription', api_key='SampleKey', \"\n", + " \"api_secret='ApiSecret', token='SampleToken')\\n\",\n", + " 'function_call': 'add_trello_card(title=\"My card\", description=\"My '\n", + " 'description\", board_name=\"My board\", list_name=\"My list\", '\n", + " 'api_key=\"\", api_secret=\"\", token=\"\", token_secret=\"any\")',\n", + " 'icon': 'lab la-trello',\n", + " 'keywords': ['trello'],\n", + " 'name': 'Add Trello Card',\n", + " 'parameters': [{'description': ' Title of Trello card\\n', 'name': ' title'},\n", + " {'description': ' Description of Trello card\\n',\n", + " 'name': ' description'},\n", + " {'description': ' Name of the Trello board\\n',\n", + " 'name': ' board_name'},\n", + " {'description': ' Trello API key\\n', 'name': ' api_key'},\n", + " {'description': ' Trello API secret\\n', 'name': ' api_secret'},\n", + " {'description': ' Trello token\\n', 'name': ' token'},\n", + " {'description': ' Token secret can be any string, but should '\n", + " 'be altered for security purposes.\\n',\n", + " 'name': ' token_secret'}],\n", + " 'return': '',\n", + " 'snippet': \"add_trello_card(title='ExampleTitle', \"\n", + " \"description='ExampleDescription', api_key='SampleKey', \"\n", + " \"api_secret='ApiSecret', token='SampleToken')\\n\"}\n", + "{'description': 'This activity will rename a file. If the the desired name '\n", + " 'already exists in the folder file will not be renamed.',\n", + " 'example': '>>> # Make new textfile in home directory\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> # Rename the file\\n'\n", + " '>>> rename_file(textfile)\\n'\n", + " \"C:\\\\\\\\Users\\\\\\\\\\\\\\\\generated_textfile_renamed.txt'\\n\",\n", + " 'function_call': 'rename_file(input_path, new_name=None)',\n", + " 'icon': 'las la-file-contract',\n", + " 'keywords': ['file',\n", + " 'rename',\n", + " 'rename file',\n", + " 'organise file',\n", + " 'files',\n", + " 'file manipulation',\n", + " 'explorer',\n", + " 'nautilus'],\n", + " 'name': 'Rename a file',\n", + " 'parameters': [{'description': ' Full path to file that will be renamed\\n',\n", + " 'name': ' path'},\n", + " {'description': \" New name of the file e.g. 'newfile.txt'. By \"\n", + " 'default file will be renamed to original '\n", + " \"folder name with '_renamed' added to the \"\n", + " 'folder name.\\n',\n", + " 'name': ' new_name'}],\n", + " 'return': ' Path to renamed file as a string. None if folder could not be '\n", + " 'renamed.\\n',\n", + " 'snippet': '# Make new textfile in home directory\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " '# Rename the file\\n'\n", + " 'rename_file(textfile)\\n'}\n", + "{'description': 'If the new location already contains a file with the same '\n", + " 'name, a random 4 character uid will be added in front of the '\n", + " 'name before the file is moved.',\n", + " 'example': '>>> # Make new textfile in home directory\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> # Make a folder to move the file to\\n'\n", + " '>>> new_folder = create_folder()\\n'\n", + " '>>> # Move textfile to the folder\\n'\n", + " '>>> move_file(textfile, new_folder)\\n',\n", + " 'function_call': 'move_file(from_path, to_path)',\n", + " 'icon': 'las la-file-export',\n", + " 'keywords': ['file',\n", + " 'move',\n", + " 'move file',\n", + " 'organise file',\n", + " 'files',\n", + " 'file manipulation',\n", + " 'explorer',\n", + " 'nautilus'],\n", + " 'name': 'Move a file',\n", + " 'parameters': [{'description': ' Full path to the file that will be moved\\n',\n", + " 'name': ' old_path'},\n", + " {'description': ' Path to the folder where file will be moved '\n", + " 'to\\n',\n", + " 'name': ' new_location'}],\n", + " 'return': ' Path to renamed file as a string. None if folder could not be '\n", + " 'moved.\\n',\n", + " 'snippet': '# Make new textfile in home directory\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " '# Make a folder to move the file to\\n'\n", + " 'new_folder = create_folder()\\n'\n", + " '# Move textfile to the folder\\n'\n", + " 'move_file(textfile, new_folder)\\n'}\n", + "{'description': ':parameter path: Full path to the file that will be deleted.',\n", + " 'example': '>>> # Make new textfile in home directory\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> # Remove the file\\n'\n", + " '>>> remove_file(textfile)\\n',\n", + " 'function_call': 'remove_file(path)',\n", + " 'icon': 'las la-trash',\n", + " 'keywords': ['file',\n", + " 'delete',\n", + " 'erase',\n", + " 'delete file',\n", + " 'organise file',\n", + " 'files',\n", + " 'file manipulation',\n", + " 'explorer',\n", + " 'nautilus'],\n", + " 'name': 'Remove a file',\n", + " 'parameters': [{'description': ' Full path to the file that will be '\n", + " 'deleted.\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' Path to removed file as a string.\\n',\n", + " 'snippet': '# Make new textfile in home directory\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " '# Remove the file\\n'\n", + " 'remove_file(textfile)\\n'}\n", + "{'description': 'This function checks whether the file with the given path '\n", + " 'exists.',\n", + " 'example': '>>> # Make new textfile in home directory\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> # Check if file exists\\n'\n", + " '>>> file_exists(textfile)\\n'\n", + " 'True\\n',\n", + " 'function_call': 'file_exists(path)',\n", + " 'icon': 'las la-tasks',\n", + " 'keywords': ['file',\n", + " 'exists',\n", + " 'files',\n", + " 'file manipulation',\n", + " 'explorer',\n", + " 'nautilus'],\n", + " 'name': 'Check if file exists',\n", + " 'parameters': [{'description': ' Full path to the file to check.\\n',\n", + " 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Make new textfile in home directory\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " '# Check if file exists\\n'\n", + " 'file_exists(textfile)\\n'}\n", + "{'description': 'Not that this activity is blocking and will keep the system '\n", + " 'waiting.',\n", + " 'example': '>>> # Make new textfile in home directory\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> # Wait untile file exists # Should pass immediatly\\n'\n", + " '>>> wait_file_exists(textfile)\\n',\n", + " 'function_call': 'wait_file_exists(path, timeout=60)',\n", + " 'icon': 'las la-list-alt',\n", + " 'keywords': ['file',\n", + " 'wait',\n", + " 'wait till exists',\n", + " 'files',\n", + " 'file manipulation',\n", + " 'explorer',\n", + " 'nautilus'],\n", + " 'name': 'Wait until a file exists.',\n", + " 'parameters': [{'description': ' Full path to file.\\n', 'name': ' path'},\n", + " {'description': ' Maximum time in seconds to wait before '\n", + " 'continuing. Default value is 60 seconds.\\n',\n", + " 'name': ' timeout'}],\n", + " 'return': '',\n", + " 'snippet': '# Make new textfile in home directory\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " '# Wait untile file exists # Should pass immediatly\\n'\n", + " 'wait_file_exists(textfile)\\n'}\n", + "{'description': 'Writes a list to a text (.txt) file.Every element of the '\n", + " 'entered list is written on a new line of the text file.',\n", + " 'example': '>>> # Make a list to write\\n'\n", + " \">>> robot_names = ['WALL-E', 'Terminator', 'R2D2']\\n\"\n", + " '>>> # Create a new text file\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> write_list_to_file(robot_names, textfile)\\n'\n", + " '>>> # Open the file for illustration\\n'\n", + " '>>> open_file(textfile)\\n',\n", + " 'function_call': 'write_list_to_file(list_to_write, file_path)',\n", + " 'icon': 'las la-list',\n", + " 'keywords': ['list', 'text', 'txt', 'list to file', 'write list', 'write'],\n", + " 'name': 'List to .txt',\n", + " 'parameters': [{'description': ' List to write to .txt file\\n',\n", + " 'name': ' list_to_write'},\n", + " {'description': ' Path to the text-file. \\n', 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Make a list to write\\n'\n", + " \"robot_names = ['WALL-E', 'Terminator', 'R2D2']\\n\"\n", + " '# Create a new text file\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " 'write_list_to_file(robot_names, textfile)\\n'\n", + " '# Open the file for illustration\\n'\n", + " 'open_file(textfile)\\n'}\n", + "{'description': 'This activity writes the content of a .txt file to a list and '\n", + " 'returns that list.Every new line from the .txt file becomes a '\n", + " 'new element of the list. The activity willnot work if the '\n", + " 'entered path is not attached to a .txt file.',\n", + " 'example': '>>> # Make a list to write\\n'\n", + " \">>> robot_names = ['WALL-E', 'Terminator', 'R2D2']\\n\"\n", + " '>>> # Create a new text file\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> write_list_to_file(robot_names, textfile)\\n'\n", + " '>>> # Read list from file\\n'\n", + " '>>> read_list_from_txt(textfile)\\n'\n", + " \"['WALL-E', 'Terminator', 'R2D2']\\n\",\n", + " 'function_call': 'read_list_from_txt(file_path)',\n", + " 'icon': 'las la-th-list',\n", + " 'keywords': ['list',\n", + " 'text',\n", + " 'txt',\n", + " 'list to file',\n", + " 'write list',\n", + " 'read',\n", + " 'read txt',\n", + " 'read text'],\n", + " 'name': 'Read .txt file',\n", + " 'parameters': [{'description': ' Path to the .txt file\\n', 'name': ' path'}],\n", + " 'return': ' List with contents of specified .txt file\\n',\n", + " 'snippet': '# Make a list to write\\n'\n", + " \"robot_names = ['WALL-E', 'Terminator', 'R2D2']\\n\"\n", + " '# Create a new text file\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " 'write_list_to_file(robot_names, textfile)\\n'\n", + " '# Read list from file\\n'\n", + " 'read_list_from_txt(textfile)\\n'}\n", + "{'description': 'Append a text line to a file and creates the file if it does '\n", + " 'not exist yet.',\n", + " 'example': '>>> # Create a new text file\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> # Append a few lines to the file\\n'\n", + " \">>> append_line('Line 1', textfile)\\n\"\n", + " \">>> append_line('Line 2', textfile)\\n\"\n", + " \">>> append_line('Line 3', textfile)\\n\"\n", + " '>>> # Open the file for illustration\\n'\n", + " '>>> open_file(textfile)\\n',\n", + " 'function_call': 'append_line(text, file_path)',\n", + " 'icon': 'las la-tasks',\n", + " 'keywords': ['list',\n", + " 'text',\n", + " 'txt',\n", + " 'list to file',\n", + " 'write list',\n", + " 'read',\n", + " 'write txt',\n", + " 'append text',\n", + " 'append line',\n", + " 'append',\n", + " 'add to file',\n", + " 'add'],\n", + " 'name': 'Append to .txt',\n", + " 'parameters': [{'description': ' The text line to write to the end of the '\n", + " 'file\\n',\n", + " 'name': ' text'},\n", + " {'description': ' Path to the file to write to\\n',\n", + " 'name': ' file_path'}],\n", + " 'return': '',\n", + " 'snippet': '# Create a new text file\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " '# Append a few lines to the file\\n'\n", + " \"append_line('Line 1', textfile)\\n\"\n", + " \"append_line('Line 2', textfile)\\n\"\n", + " \"append_line('Line 3', textfile)\\n\"\n", + " '# Open the file for illustration\\n'\n", + " 'open_file(textfile)\\n'}\n", + "{'description': 'Initialize text file',\n", + " 'example': '>>> # Create a new text file\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " \"C:\\\\\\\\Users\\\\\\\\\\\\\\\\generated_textfile.txt'\\n\",\n", + " 'function_call': \"make_textfile(text='Sample text', output_path=None)\",\n", + " 'icon': 'las la-file-alt',\n", + " 'keywords': ['make textfile',\n", + " 'textfile',\n", + " 'testfile',\n", + " 'exampel file',\n", + " 'make file',\n", + " 'make',\n", + " 'new file',\n", + " 'new textfile',\n", + " 'txt',\n", + " 'new txt'],\n", + " 'name': 'Make text file',\n", + " 'parameters': [{'description': ' The text line to write to the end of the '\n", + " \"file. Default text is 'Sample text'\\n\",\n", + " 'name': ' text'},\n", + " {'description': ' Ouput path. Will write to home directory\\n',\n", + " 'name': ' output_path'}],\n", + " 'return': ' Path as string\\n',\n", + " 'snippet': '# Create a new text file\\ntextfile = make_textfile()\\n'}\n", + "{'description': 'Copies a file from one place to another.If the new location '\n", + " 'already contains a file with the same name, a random 4 '\n", + " 'character uid is added to the name.',\n", + " 'example': '>>> # Create a new text file\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> # Copy the textfile\\n'\n", + " '>>> copy_file(textfile)\\n'\n", + " \"C:\\\\\\\\Users\\\\\\\\\\\\\\\\generated_textfile.txt'\\n\",\n", + " 'function_call': 'copy_file(old_path, new_path=None)',\n", + " 'icon': 'las la-copy',\n", + " 'keywords': ['make textfile',\n", + " 'textfile',\n", + " 'testfile',\n", + " 'exampel file',\n", + " 'make file',\n", + " 'make',\n", + " 'new file',\n", + " 'new textfile',\n", + " 'txt',\n", + " 'new txt'],\n", + " 'name': 'Copy a file',\n", + " 'parameters': [{'description': ' Full path to the source location of the '\n", + " 'folder\\n',\n", + " 'name': ' old_path'},\n", + " {'description': ' Optional full path to the destination '\n", + " 'location of the folder. If not specified file '\n", + " 'will be copied to the same location with a '\n", + " 'random 8 character uid is added to the '\n", + " 'name.\\n',\n", + " 'name': ' new_path'}],\n", + " 'return': ' New path as string\\n',\n", + " 'snippet': '# Create a new text file\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " '# Copy the textfile\\n'\n", + " 'copy_file(textfile)\\n'}\n", + "{'description': 'Get extension of a file',\n", + " 'example': '>>> # Create a new text file\\n'\n", + " '>>> textfile = make_textfile()\\n'\n", + " '>>> # Get file extension of this textfile\\n'\n", + " '>>> get_file_extension(textfile)\\n'\n", + " \"'.txt'\\n\",\n", + " 'function_call': 'get_file_extension(path)',\n", + " 'icon': 'las la-info',\n", + " 'keywords': ['file', 'extension', 'file extension', 'details'],\n", + " 'name': 'Get file extension',\n", + " 'parameters': [{'description': ' Path to file to get extension from\\n',\n", + " 'name': ' path'}],\n", + " 'return': \" String with extension, e.g. '.txt'\\n\",\n", + " 'snippet': '# Create a new text file\\n'\n", + " 'textfile = make_textfile()\\n'\n", + " '# Get file extension of this textfile\\n'\n", + " 'get_file_extension(textfile)\\n'}\n", + "{'description': 'Send file to default printer to priner. This activity sends a '\n", + " 'file to the printer. Make sure to have a default printer set '\n", + " 'up.',\n", + " 'example': '>>> # Caution as this example could result in a print from '\n", + " 'default printer\\n'\n", + " '>>> # Create a new text file\\n'\n", + " \">>> textfile = make_textfile(text = 'What does a robot do at \"\n", + " \"lunch? Take a megabyte!')\\n\"\n", + " '>>> # Print the textfile\\n'\n", + " '>>> send_to_printer(textfile)\\n',\n", + " 'function_call': 'send_to_printer(file)',\n", + " 'icon': 'las la-print',\n", + " 'keywords': ['print', 'printer', 'printing', 'ink', 'export'],\n", + " 'name': 'Print',\n", + " 'parameters': [{'description': ' Path to the file to print, should be a '\n", + " 'printable file\\n',\n", + " 'name': ' file'}],\n", + " 'return': '',\n", + " 'snippet': '# Caution as this example could result in a print from default '\n", + " 'printer\\n'\n", + " '# Create a new text file\\n'\n", + " \"textfile = make_textfile(text = 'What does a robot do at lunch? \"\n", + " \"Take a megabyte!')\\n\"\n", + " '# Print the textfile\\n'\n", + " 'send_to_printer(textfile)\\n'}\n", + "{'description': 'Extracts the text from a PDF. This activity reads text from a '\n", + " 'pdf file. Can only read PDF files that contain a text layer.',\n", + " 'example': '>>> # Caution, for this example to work a .pdf example file will '\n", + " 'be downloaded from automagica.com FTP\\n'\n", + " '>>> example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '>>> # Open example pdf for illustration\\n'\n", + " '>>> open_file(example_pdf)\\n'\n", + " '>>> # Read the text\\n'\n", + " '>>> read_text_from_pdf(example_pdf)\\n',\n", + " 'function_call': 'read_text_from_pdf(file_path)',\n", + " 'icon': 'las la-glasses',\n", + " 'keywords': ['PDF', 'read', 'text', 'extract text', 'PDF file'],\n", + " 'name': 'Text from PDF',\n", + " 'parameters': [{'description': ' Path to the PDF (either relative or '\n", + " 'absolute)\\n',\n", + " 'name': ' file_path'}],\n", + " 'return': ' The text from the PDF\\n',\n", + " 'snippet': '# Caution, for this example to work a .pdf example file will be '\n", + " 'downloaded from automagica.com FTP\\n'\n", + " 'example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '# Open example pdf for illustration\\n'\n", + " 'open_file(example_pdf)\\n'\n", + " '# Read the text\\n'\n", + " 'read_text_from_pdf(example_pdf)\\n'}\n", + "{'description': 'Merges multiple PDFs into a single file',\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 'example': '>>> # Caution, for this example to work a .pdf example file will '\n", + " 'be downloaded from automagica.com FTP\\n'\n", + " '>>> example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '>>> # Join the PDF file three times with itself for illustration, '\n", + " 'could also be different files\\n'\n", + " '>>> merged_pdf = join_pdf_files([example_pdf, example_pdf, '\n", + " 'example_pdf])\\n'\n", + " '>>> # Open resulting PDF file for illustration\\n'\n", + " '>>> open_file(merged_pdf)\\n',\n", + " 'function_call': 'join_pdf_files(file_paths, output_path=None)',\n", + " 'icon': 'las la-object-ungroup',\n", + " 'keywords': ['PDF',\n", + " 'read',\n", + " 'text',\n", + " 'extract text',\n", + " 'PDF file',\n", + " 'join PDF',\n", + " 'join',\n", + " 'merge',\n", + " 'merge PDF'],\n", + " 'name': 'Merge PDF',\n", + " 'parameters': [{'description': ' List of paths to PDF files\\n',\n", + " 'name': ' file_paths'},\n", + " {'description': ' Full path where joined pdf files can be '\n", + " 'written. If no path is given will write to '\n", + " \"home dir as 'merged_pdf.pdf'\\n\",\n", + " 'name': ' output_path'}],\n", + " 'return': ' Output path as string\\n',\n", + " 'snippet': '# Caution, for this example to work a .pdf example file will be '\n", + " 'downloaded from automagica.com FTP\\n'\n", + " 'example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '# Join the PDF file three times with itself for illustration, '\n", + " 'could also be different files\\n'\n", + " 'merged_pdf = join_pdf_files([example_pdf, example_pdf, '\n", + " 'example_pdf])\\n'\n", + " '# Open resulting PDF file for illustration\\n'\n", + " 'open_file(merged_pdf)\\n'}\n", + "{'description': 'Extracts a particular range of a PDF to a separate file.',\n", + " 'example': '>>> # Caution, for this example to work a .pdf example file will '\n", + " 'be downloaded from automagica.com FTP\\n'\n", + " '>>> example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '>>> # Join the PDF file three times to create multi page\\n'\n", + " '>>> multi_page_pdf_example = join_pdf_files([example_pdf, '\n", + " 'example_pdf, example_pdf])\\n'\n", + " '>>> # Extract some pages from it\\n'\n", + " '>>> new_file = '\n", + " 'extract_page_range_from_pdf(multi_page_pdf_example, 1, 2 )\\n'\n", + " '>>> # Open resulting PDF file for illustration\\n'\n", + " '>>> open_file(new_file)\\n',\n", + " 'function_call': 'extract_page_range_from_pdf(file_path, start_page, '\n", + " 'end_page, output_path=None)',\n", + " 'icon': 'las la-cut',\n", + " 'keywords': ['PDF',\n", + " 'read',\n", + " 'extract text',\n", + " 'PDF file',\n", + " 'extract PDF',\n", + " 'join',\n", + " 'cut',\n", + " 'cut PDF',\n", + " 'extract pages',\n", + " 'extract from pdf',\n", + " 'select page',\n", + " 'page'],\n", + " 'name': 'Extract page from PDF',\n", + " 'parameters': [{'description': ' Path to the PDF (either relative or '\n", + " 'absolute)\\n',\n", + " 'name': ' file_path'},\n", + " {'description': ' Page number to start from, with 0 being the '\n", + " 'first page\\n',\n", + " 'name': ' start_page'},\n", + " {'description': ' Page number to end with, with 0 being the '\n", + " 'first page\\n',\n", + " 'name': ' end_page'}],\n", + " 'return': '',\n", + " 'snippet': '# Caution, for this example to work a .pdf example file will be '\n", + " 'downloaded from automagica.com FTP\\n'\n", + " 'example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '# Join the PDF file three times to create multi page\\n'\n", + " 'multi_page_pdf_example = join_pdf_files([example_pdf, '\n", + " 'example_pdf, example_pdf])\\n'\n", + " '# Extract some pages from it\\n'\n", + " 'new_file = extract_page_range_from_pdf(multi_page_pdf_example, 1, '\n", + " '2 )\\n'\n", + " '# Open resulting PDF file for illustration\\n'\n", + " 'open_file(new_file)\\n'}\n", + "{'description': 'Save a specific page from a PDF as an image',\n", + " 'example': '>>> # Caution, for this example to work a .pdf example file will '\n", + " 'be downloaded from automagica.com FTP\\n'\n", + " '>>> example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '>>> # Extract the images\\n'\n", + " '>>> extract_images_from_pdf(example_pdf)\\n',\n", + " 'function_call': 'extract_images_from_pdf(file_path)',\n", + " 'icon': 'las la-icons',\n", + " 'keywords': ['PDF',\n", + " 'extract images',\n", + " 'images',\n", + " 'extract text',\n", + " 'PDF file',\n", + " 'image'],\n", + " 'name': 'Extract images from PDF',\n", + " 'parameters': [{'description': ' Full path to store extracted images\\n',\n", + " 'name': ' file_path'}],\n", + " 'return': '',\n", + " 'snippet': '# Caution, for this example to work a .pdf example file will be '\n", + " 'downloaded from automagica.com FTP\\n'\n", + " 'example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '# Extract the images\\n'\n", + " 'extract_images_from_pdf(example_pdf)\\n'}\n", + "{'description': ':parameter file_path: Filepath to the document that will be '\n", + " 'watermarked. Should be pdf file.:parameter watermark_path: '\n", + " 'Filepath to the watermark. Should be pdf file.:parameter '\n", + " 'output_path: Path to save watermarked PDF. If no path is '\n", + " \"provided same path as input will be used with 'watermarked' \"\n", + " 'added to the name',\n", + " 'example': '>>> # Caution, for this example to work a .pdf example file will '\n", + " 'be downloaded from automagica.com FTP\\n'\n", + " '>>> example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '>>> # Download the watermark\\n'\n", + " '>>> example_watermark = '\n", + " \"download_file_from_url('http://automagica.com/examples/approved_stamp.pdf')\\n\"\n", + " '>>> # Apply the watermark\\n'\n", + " '>>> watermarked_file = apply_watermark_to_pdf(example_pdf, '\n", + " 'example_watermark)\\n'\n", + " '>>> # Open the file for illustration\\n'\n", + " '>>> open_file(watermarked_file)\\n',\n", + " 'function_call': 'apply_watermark_to_pdf(file_path, watermark_path, '\n", + " \"output_path='')\",\n", + " 'icon': 'las la-stamp',\n", + " 'keywords': ['PDF',\n", + " 'extract images',\n", + " 'images',\n", + " 'extract text',\n", + " 'PDF file',\n", + " 'image'],\n", + " 'name': 'Watermark a PDF',\n", + " 'parameters': [{'description': ' Filepath to the document that will be '\n", + " 'watermarked. Should be pdf file.\\n',\n", + " 'name': ' file_path'},\n", + " {'description': ' Filepath to the watermark. Should be pdf '\n", + " 'file.\\n',\n", + " 'name': ' watermark_path'},\n", + " {'description': ' Path to save watermarked PDF. If no path is '\n", + " 'provided same path as input will be used with '\n", + " \"'watermarked' added to the name\\n\",\n", + " 'name': ' output_path'}],\n", + " 'return': ' Output path as a string\\n',\n", + " 'snippet': '# Caution, for this example to work a .pdf example file will be '\n", + " 'downloaded from automagica.com FTP\\n'\n", + " 'example_pdf = '\n", + " \"download_file_from_url('http://automagica.com/examples/example_document.pdf')\\n\"\n", + " '# Download the watermark\\n'\n", + " 'example_watermark = '\n", + " \"download_file_from_url('http://automagica.com/examples/approved_stamp.pdf')\\n\"\n", + " '# Apply the watermark\\n'\n", + " 'watermarked_file = apply_watermark_to_pdf(example_pdf, '\n", + " 'example_watermark)\\n'\n", + " '# Open the file for illustration\\n'\n", + " 'open_file(watermarked_file)\\n'}\n", + "{'description': 'Get average CPU load for all cores.',\n", + " 'example': '>>> get_cpu_load()\\n10.1\\n',\n", + " 'function_call': 'get_cpu_load(measure_time=1)',\n", + " 'icon': 'las la-microchip',\n", + " 'keywords': ['cpu', 'load', 'cpuload'],\n", + " 'name': 'CPU load',\n", + " 'parameters': [{'description': ' Time (seconds) to measure load. Standard '\n", + " 'measure_time is 1 second.\\n',\n", + " 'name': ' measure_time'}],\n", + " 'return': ' Displayed load is an average over measured_time.\\n',\n", + " 'snippet': 'get_cpu_load()\\n'}\n", + "{'description': \"Get the number of CPU's in the current system.\",\n", + " 'example': '>>> get_number_of_cpu()\\n2\\n',\n", + " 'function_call': 'get_number_of_cpu(logical=True)',\n", + " 'icon': 'las la-calculator',\n", + " 'keywords': ['cpu', 'count', 'number of cpu'],\n", + " 'name': 'Count CPU',\n", + " 'parameters': [{'description': ' Determines if only logical units are added '\n", + " 'to the count, default value is True.\\n',\n", + " 'name': ' logical'}],\n", + " 'return': ' Number of CPU Integer\\n',\n", + " 'snippet': 'get_number_of_cpu()\\n'}\n", + "{'description': 'Get frequency at which CPU currently operates.',\n", + " 'example': '>>> get_cpu_frequency()\\n'\n", + " 'scpufreq(current=3600.0, min=0.0, max=3600.0)\\n',\n", + " 'function_call': 'get_cpu_frequency()',\n", + " 'icon': 'las la-wave-square',\n", + " 'keywords': ['cpu', 'load', 'cpu frequency'],\n", + " 'name': 'CPU frequency',\n", + " 'parameters': [],\n", + " 'return': ' minimum and maximum frequency\\n',\n", + " 'snippet': 'get_cpu_frequency()\\n'}\n", + "{'description': 'Get CPU statistics',\n", + " 'example': '>>> get_cpu_stats()\\n'\n", + " 'scpustats(ctx_switches=735743826, interrupts=1540483897, '\n", + " 'soft_interrupts=0, syscalls=2060595131)\\n',\n", + " 'function_call': 'get_cpu_stats()',\n", + " 'icon': 'las la-server',\n", + " 'keywords': ['cpu', 'load', 'cpu frequency', 'stats', 'cpu statistics'],\n", + " 'name': 'CPU Stats',\n", + " 'parameters': [],\n", + " 'return': ' Number of CTX switches, intterupts, soft-interrupts and '\n", + " 'systemcalls.\\n',\n", + " 'snippet': 'get_cpu_stats()\\n'}\n", + "{'description': 'Get memory statistics',\n", + " 'example': '>>> get_memory_stats()\\n'\n", + " 'sswap(total=24640016384, used=18120818688, free=6519197696, '\n", + " 'percent=73.5, sin=0, sout=0)\\n',\n", + " 'function_call': 'get_memory_stats(mem_type=\"swap\")',\n", + " 'icon': 'las la-memory',\n", + " 'keywords': ['memory', 'statistics', 'usage', 'ram'],\n", + " 'name': 'Memory statistics',\n", + " 'parameters': [{'description': \" Choose mem_type = 'virtual' for virtual \"\n", + " \"memory, and mem_type = 'swap' for swap memory \"\n", + " '(standard).\\n',\n", + " 'name': ' mem_type'}],\n", + " 'return': ' Total, used, free and percentage in use.\\n',\n", + " 'snippet': 'get_memory_stats()\\n'}\n", + "{'description': 'Get disk statistics of main disk',\n", + " 'example': '>>> get_disk_stats()\\n'\n", + " 'sdiskusage(total=999559262208, used=748696350720, '\n", + " 'free=250862911488, percent=74.9)\\n',\n", + " 'function_call': 'get_disk_stats()',\n", + " 'icon': 'las la-save',\n", + " 'keywords': ['disk usage', 'disk stats', 'disk', 'harddisk', 'space'],\n", + " 'name': 'Disk stats',\n", + " 'parameters': [],\n", + " 'return': ' Total, used, free and percentage in use.\\n',\n", + " 'snippet': 'get_disk_stats()\\n'}\n", + "{'description': 'Get disk partition info',\n", + " 'example': '>>> get_disk_paritions()\\n'\n", + " \"[sdiskpart(device='C:\\\\\\\\', mountpoint='C:\\\\\\\\', fstype='NTFS', \"\n", + " \"opts='rw,fixed')]\\n\",\n", + " 'function_call': 'get_disk_partitions()',\n", + " 'icon': 'las la-save',\n", + " 'keywords': ['disk usage', 'disk stats', 'disk', 'harddisk', 'space'],\n", + " 'name': 'Partition info',\n", + " 'parameters': [],\n", + " 'return': ' tuple with info for every partition.\\n',\n", + " 'snippet': 'get_disk_paritions()\\n'}\n", + "{'description': 'Get most recent boot time',\n", + " 'example': '>>> get_boot_time()\\n123456789.0\\n',\n", + " 'function_call': 'get_boot_time()',\n", + " 'icon': 'lar la-clock',\n", + " 'keywords': ['boot', 'boot time', 'boottime', 'startup', 'timer'],\n", + " 'name': 'Boot time',\n", + " 'parameters': [],\n", + " 'return': ' time PC was booted in seconds after the epoch.\\n',\n", + " 'snippet': 'get_boot_time()\\n'}\n", + "{'description': 'Get uptime since last boot',\n", + " 'example': '>>> get_time_since_last_boot()\\n1337.0\\n',\n", + " 'function_call': 'get_time_since_last_boot()',\n", + " 'icon': 'lar la-clock',\n", + " 'keywords': ['boot', 'boot time', 'boottime', 'startup', 'timer'],\n", + " 'name': 'Uptime',\n", + " 'parameters': [],\n", + " 'return': ' time since last boot in seconds.\\n',\n", + " 'snippet': 'get_time_since_last_boot()\\n'}\n", + "{'description': 'Displays an image specified by the path variable on the '\n", + " 'default imaging program.',\n", + " 'example': '>>> # Take screenshot of current screen to use as test image\\n'\n", + " '>>> testimage = take_screenshot()\\n'\n", + " '>>> # Show the image\\n'\n", + " '>>> show_image(testimage)\\n',\n", + " 'function_call': 'show_image(path)',\n", + " 'icon': 'las la-images',\n", + " 'keywords': ['image', 'show image', 'reveal', 'open image', 'open'],\n", + " 'name': 'Show image',\n", + " 'parameters': [{'description': ' Full path to image\\n', 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Take screenshot of current screen to use as test image\\n'\n", + " 'testimage = take_screenshot()\\n'\n", + " '# Show the image\\n'\n", + " 'show_image(testimage)\\n'}\n", + "{'description': 'Rotate an image',\n", + " 'example': '>>> # Take screenshot of current screen to use as test image\\n'\n", + " '>>> testimage = take_screenshot()\\n'\n", + " '>>> # Rotate the image\\n'\n", + " '>>> rotate_image(testimage)\\n'\n", + " '>>> # Show the image\\n'\n", + " '>>> show_image(testimage)\\n',\n", + " 'function_call': 'rotate_image(path, angle=90)',\n", + " 'icon': 'las la-undo',\n", + " 'keywords': ['image',\n", + " 'rotate image',\n", + " '90 degrees',\n", + " 'image manipulation',\n", + " 'photoshop',\n", + " 'paint'],\n", + " 'name': 'Rotate image',\n", + " 'parameters': [{'description': ' Degrees to rotate image. Note that angles '\n", + " 'other than 90, 180, 270, 360 can resize the '\n", + " 'picture. \\n',\n", + " 'name': ' angle'}],\n", + " 'return': '',\n", + " 'snippet': '# Take screenshot of current screen to use as test image\\n'\n", + " 'testimage = take_screenshot()\\n'\n", + " '# Rotate the image\\n'\n", + " 'rotate_image(testimage)\\n'\n", + " '# Show the image\\n'\n", + " 'show_image(testimage)\\n'}\n", + "{'description': 'Resizes the image specified by the path variable.',\n", + " 'example': '>>> # Take screenshot of current screen to use as test image\\n'\n", + " '>>> testimage = take_screenshot()\\n'\n", + " '>>> # Resize the image\\n'\n", + " '>>> resize_image(testimage, size=(100,100))\\n'\n", + " '>>> # Show the image\\n'\n", + " '>>> show_image(testimage)\\n',\n", + " 'function_call': 'resize_image(path, size)',\n", + " 'icon': 'las la-expand-arrows-alt',\n", + " 'keywords': ['image',\n", + " 'resize image',\n", + " 'resize',\n", + " 'size',\n", + " 'image manipulation',\n", + " 'photoshop',\n", + " 'paint'],\n", + " 'name': 'Resize image',\n", + " 'parameters': [{'description': ' Path to the image\\n', 'name': ' path'},\n", + " {'description': ' Tuple with the width and height in pixels. '\n", + " 'E.g. (300, 400) gives the image a width of '\n", + " '300 pixels and a height of 400 pixels.\\n',\n", + " 'name': ' size'}],\n", + " 'return': '',\n", + " 'snippet': '# Take screenshot of current screen to use as test image\\n'\n", + " 'testimage = take_screenshot()\\n'\n", + " '# Resize the image\\n'\n", + " 'resize_image(testimage, size=(100,100))\\n'\n", + " '# Show the image\\n'\n", + " 'show_image(testimage)\\n'}\n", + "{'description': 'Get with of image',\n", + " 'example': '>>> # Take screenshot of current screen to use as test image\\n'\n", + " '>>> testimage = take_screenshot()\\n'\n", + " '>>> # get image height\\n'\n", + " '>>> get_image_width(testimage)\\n'\n", + " '1000\\n',\n", + " 'function_call': 'get_image_width(path)',\n", + " 'icon': 'las la-expand-arrows-alt',\n", + " 'keywords': ['image', 'height', 'width', 'image height', 'image width'],\n", + " 'name': 'Get image width',\n", + " 'parameters': [{'description': ' Path to image\\n', 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Take screenshot of current screen to use as test image\\n'\n", + " 'testimage = take_screenshot()\\n'\n", + " '# get image height\\n'\n", + " 'get_image_width(testimage)\\n'}\n", + "{'description': 'Get height of image',\n", + " 'example': '>>> # Take screenshot of current screen to use as test image\\n'\n", + " '>>> testimage = take_screenshot()\\n'\n", + " '>>> # get image height\\n'\n", + " '>>> get_image_height(testimage)\\n'\n", + " '1000\\n',\n", + " 'function_call': 'get_image_height(path)',\n", + " 'icon': 'las la-arrows-alt-v',\n", + " 'keywords': ['image', 'height', 'width', 'image height', 'image width'],\n", + " 'name': 'Get image height',\n", + " 'parameters': [{'description': ' Path to image\\n', 'name': ' path'}],\n", + " 'return': ' Height of image\\n',\n", + " 'snippet': '# Take screenshot of current screen to use as test image\\n'\n", + " 'testimage = take_screenshot()\\n'\n", + " '# get image height\\n'\n", + " 'get_image_height(testimage)\\n'}\n", + "{'description': 'Crops the image specified by path to a region determined by '\n", + " 'the box variable.',\n", + " 'example': '>>> # Take screenshot of current screen to use as test image\\n'\n", + " '>>> testimage = take_screenshot()\\n'\n", + " '>>> # Crop the image\\n'\n", + " '>>> crop_image(testimage, box = (10,10,100,100))\\n'\n", + " '>>> # Show the image\\n'\n", + " '>>> show_image(testimage)\\n',\n", + " 'function_call': 'crop_image(path, box=None)',\n", + " 'icon': 'las la-crop',\n", + " 'keywords': ['image', 'crop', 'crop image'],\n", + " 'name': 'Crop image',\n", + " 'parameters': [{'description': ' Path to image\\n', 'name': ' path'},\n", + " {'description': ' A tuple that defines the left, upper, right '\n", + " 'and lower pixel coördinate e.g.: (left, '\n", + " 'upper, right, lower)\\n',\n", + " 'name': ' box'}],\n", + " 'return': '',\n", + " 'snippet': '# Take screenshot of current screen to use as test image\\n'\n", + " 'testimage = take_screenshot()\\n'\n", + " '# Crop the image\\n'\n", + " 'crop_image(testimage, box = (10,10,100,100))\\n'\n", + " '# Show the image\\n'\n", + " 'show_image(testimage)\\n'}\n", + "{'description': 'Mirrors an image with a given path horizontally from left to '\n", + " 'right.',\n", + " 'example': '>>> # Take screenshot of current screen to use as test image\\n'\n", + " '>>> testimage = take_screenshot()\\n'\n", + " '>>> # Mirror image horizontally\\n'\n", + " '>>> mirror_image_horizontally(testimage)\\n'\n", + " '>>> # Show the image\\n'\n", + " '>>> show_image(testimage)\\n',\n", + " 'function_call': 'mirror_image_horizontally(path)',\n", + " 'icon': 'las la-caret-up',\n", + " 'keywords': ['image',\n", + " 'flip',\n", + " 'flip image',\n", + " 'mirror',\n", + " 'mirror image',\n", + " 'horizon',\n", + " 'horizontally'],\n", + " 'name': 'Mirror image horizontally',\n", + " 'parameters': [{'description': ' Path to image\\n', 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Take screenshot of current screen to use as test image\\n'\n", + " 'testimage = take_screenshot()\\n'\n", + " '# Mirror image horizontally\\n'\n", + " 'mirror_image_horizontally(testimage)\\n'\n", + " '# Show the image\\n'\n", + " 'show_image(testimage)\\n'}\n", + "{'description': 'Mirrors an image with a given path vertically from top to '\n", + " 'bottom.',\n", + " 'example': '>>> # Take screenshot of current screen to use as test image\\n'\n", + " '>>> testimage = take_screenshot()\\n'\n", + " '>>> # Mirror image vertically\\n'\n", + " '>>> mirror_image_vertically(testimage)\\n'\n", + " '>>> # Show the image\\n'\n", + " '>>> show_image(testimage)\\n',\n", + " 'function_call': 'mirror_image_vertically(path)',\n", + " 'icon': 'las la-caret-right',\n", + " 'keywords': ['image',\n", + " 'flip',\n", + " 'flip image',\n", + " 'mirror',\n", + " 'mirror image',\n", + " 'vertical',\n", + " 'vertically'],\n", + " 'name': 'Mirror image vertically',\n", + " 'parameters': [{'description': ' Path to image\\n', 'name': ' path'}],\n", + " 'return': '',\n", + " 'snippet': '# Take screenshot of current screen to use as test image\\n'\n", + " 'testimage = take_screenshot()\\n'\n", + " '# Mirror image vertically\\n'\n", + " 'mirror_image_vertically(testimage)\\n'\n", + " '# Show the image\\n'\n", + " 'show_image(testimage)\\n'}\n", + "{'description': 'Use Windows Run to boot a processNote this uses keyboard '\n", + " 'inputs which means this process can be disrupted by '\n", + " 'interfering inputs',\n", + " 'example': '>>> # Open paint with Windows run\\n'\n", + " \">>> run_manual('mspaint.exe')\\n\"\n", + " '>>> # Open home directory with Windows run\\n'\n", + " '>>> run_manual(home_path())\\n',\n", + " 'function_call': 'run_manual(task)',\n", + " 'icon': 'las la-cog',\n", + " 'keywords': ['run', 'open', 'task', 'win r', 'windows run', 'shell', 'cmd'],\n", + " 'name': 'Windows run',\n", + " 'parameters': [{'description': \" Name of the task to run e.g. 'mspaint.exe'\\n\",\n", + " 'name': ' task'}],\n", + " 'return': '',\n", + " 'snippet': '# Open paint with Windows run\\n'\n", + " \"run_manual('mspaint.exe')\\n\"\n", + " '# Open home directory with Windows run\\n'\n", + " 'run_manual(home_path())\\n'}\n", + "{'description': 'Use subprocess to open a windows process',\n", + " 'example': \">>> # Open paint with Windows run\\n>>> run('mspaint.exe')\\n\",\n", + " 'function_call': 'run(process)',\n", + " 'icon': 'las la-play',\n", + " 'keywords': ['run', 'open', 'task', 'win r', 'windows run', 'shell', 'cmd'],\n", + " 'name': 'Run process',\n", + " 'parameters': [{'description': \" Process to open e.g: 'calc.exe', \"\n", + " \"'notepad.exe', 'control.exe', \"\n", + " \"'mspaint.exe'.\\n\",\n", + " 'name': ' process'}],\n", + " 'return': '',\n", + " 'snippet': \"# Open paint with Windows run\\nrun('mspaint.exe')\\n\"}\n", + "{'description': 'Check if process is running. Validates if given process name '\n", + " '(name) is currently running on the system.',\n", + " 'example': '>>> # Open paint with Windows run\\n'\n", + " \">>> run('mspaint.exe')\\n\"\n", + " '>>> # Check if paint is running\\n'\n", + " \">>> is_process_running('mspaint.exe')\\n\"\n", + " 'True\\n',\n", + " 'function_call': 'is_process_running(name)',\n", + " 'icon': 'las la-cogs',\n", + " 'keywords': ['run', 'open', 'task', 'win r', 'windows run', 'shell', 'cmd'],\n", + " 'name': 'Check if process is running',\n", + " 'parameters': [{'description': ' Name of process\\n', 'name': ' name'}],\n", + " 'return': ' Boolean\\n',\n", + " 'snippet': '# Open paint with Windows run\\n'\n", + " \"run('mspaint.exe')\\n\"\n", + " '# Check if paint is running\\n'\n", + " \"is_process_running('mspaint.exe')\\n\"}\n", + "{'description': 'Get names of unique processes currently running on the '\n", + " 'system.',\n", + " 'example': '>>> # Show all running processes\\n'\n", + " '>>> get_running_processes()\\n'\n", + " \"['cmd.exe', 'chrome.exe', ... ]\\n\",\n", + " 'function_call': 'get_running_processes()',\n", + " 'icon': 'las la-list',\n", + " 'keywords': ['process',\n", + " 'processes',\n", + " 'list processes',\n", + " 'running',\n", + " 'running processes'],\n", + " 'name': 'Get running processes',\n", + " 'parameters': [],\n", + " 'return': ' List of unique running processes\\n',\n", + " 'snippet': '# Show all running processes\\nget_running_processes()\\n'}\n", + "{'description': 'Kills a process forcefully',\n", + " 'example': '>>> # Open paint with Windows run\\n'\n", + " \">>> run('mspaint.exe')\\n\"\n", + " '>>> # Force paint to close\\n'\n", + " \">>> kill_process('mspaint.exe')\\n\",\n", + " 'function_call': 'kill_process(name=None)',\n", + " 'icon': 'las la-window-close',\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 'keywords': ['run',\n", + " 'open',\n", + " 'task',\n", + " 'win r',\n", + " 'windows run',\n", + " 'shell',\n", + " 'cmd',\n", + " 'kill',\n", + " 'stop',\n", + " 'kill process',\n", + " 'stop process',\n", + " 'quit',\n", + " 'exit'],\n", + " 'name': 'Kill process',\n", + " 'parameters': [{'description': ' Name of the process\\n', 'name': ' name'}],\n", + " 'return': '',\n", + " 'snippet': '# Open paint with Windows run\\n'\n", + " \"run('mspaint.exe')\\n\"\n", + " '# Force paint to close\\n'\n", + " \"kill_process('mspaint.exe')\\n\"}\n", + "{'description': 'This activity extracts all text from the current screen or an '\n", + " 'image if a path is specified.',\n", + " 'example': '>>> # Make a textfile with some text to recognize\\n'\n", + " \">>> testfile = make_textfile(text='OCR Example')\\n\"\n", + " '>>> # Open the textfile\\n'\n", + " '>>> open_file(testfile)\\n'\n", + " '>>> # Find the text with OCR\\n'\n", + " \">>> extracted_text = find_text_on_screen_ocr(text='OCR Example')\\n\"\n", + " '>>> # Check if the extracted_text contains the original word\\n'\n", + " \">>> 'OCR Example' in extracted_text\\n\"\n", + " 'True\\n',\n", + " 'function_call': 'extract_text_ocr(path=None)',\n", + " 'icon': 'lab la-readme',\n", + " 'keywords': ['OCR',\n", + " 'vision',\n", + " 'AI',\n", + " 'screen',\n", + " 'citrix',\n", + " 'read',\n", + " 'optical character recognition'],\n", + " 'name': 'Get text with OCR',\n", + " 'parameters': [{'description': ' Path to image from where text will be '\n", + " 'extracted. If no path is specified a '\n", + " 'screenshot of current screen will be used.\\n',\n", + " 'name': ' path'}],\n", + " 'return': ' String with all text from current screen\\n',\n", + " 'snippet': '# Make a textfile with some text to recognize\\n'\n", + " \"testfile = make_textfile(text='OCR Example')\\n\"\n", + " '# Open the textfile\\n'\n", + " 'open_file(testfile)\\n'\n", + " '# Find the text with OCR\\n'\n", + " \"extracted_text = find_text_on_screen_ocr(text='OCR Example')\\n\"\n", + " '# Check if the extracted_text contains the original word\\n'\n", + " \"'OCR Example' in extracted_text\\n\"}\n", + "{'description': 'This activity finds position (coordinates) of specified text '\n", + " 'on the current screen using OCR.',\n", + " 'example': '>>> # Make a textfile with some text to recognize\\n'\n", + " \">>> testfile = make_textfile(text='OCR Example')\\n\"\n", + " '>>> # Open the textfile\\n'\n", + " '>>> open_file(testfile)\\n'\n", + " '>>> # Find the text with OCR\\n'\n", + " \">>> find_text_on_screen_ocr(text='OCR Example')\\n\",\n", + " 'function_call': 'find_text_on_screen_ocr(text, criteria=None)',\n", + " 'icon': 'las la-glasses',\n", + " 'keywords': ['OCR',\n", + " 'vision',\n", + " 'AI',\n", + " 'screen',\n", + " 'citrix',\n", + " 'read',\n", + " 'optical character recognition'],\n", + " 'name': 'Find text on screen with OCR',\n", + " 'parameters': [{'description': ' Text to find. Only exact matches are '\n", + " 'returned.\\n',\n", + " 'name': ' text'},\n", + " {'description': ' Criteria to select on if multiple matches '\n", + " 'are found. If no criteria is specified all '\n", + " 'matches will be returned. Options are '\n", + " \"'first', which returns the first match \"\n", + " \"closest to the upper left corner, 'last' \"\n", + " 'returns the last match closest to the lower '\n", + " 'right corner, random selects a random '\n", + " 'match.\\n',\n", + " 'name': ' criteria'}],\n", + " 'return': ' Dictionary or list of dictionaries with matches with following '\n", + " \"elements: 'h' height in pixels, 'text' the matched text,'w' the \"\n", + " \"width in pixels, 'x' absolute x-coördinate , 'y' absolute \"\n", + " 'y-coördinate. Returns nothing if no matches are found\\n',\n", + " 'snippet': '# Make a textfile with some text to recognize\\n'\n", + " \"testfile = make_textfile(text='OCR Example')\\n\"\n", + " '# Open the textfile\\n'\n", + " 'open_file(testfile)\\n'\n", + " '# Find the text with OCR\\n'\n", + " \"find_text_on_screen_ocr(text='OCR Example')\\n\"}\n", + "{'description': 'This activity clicks on position (coordinates) of specified '\n", + " 'text on the current screen using OCR.',\n", + " 'example': '>>> # Make a textfile with some text to recognize\\n'\n", + " \">>> testfile = make_textfile(text='OCR Example')\\n\"\n", + " '>>> # Open the textfile\\n'\n", + " '>>> open_file(testfile)\\n'\n", + " '>>> # Find the text with OCR and click on it\\n'\n", + " \">>> click_on_text(text='OCR Example')\\n\",\n", + " 'function_call': 'click_on_text_ocr(text)',\n", + " 'icon': 'las la-mouse-pointer',\n", + " 'keywords': ['OCR',\n", + " 'vision',\n", + " 'AI',\n", + " 'screen',\n", + " 'citrix',\n", + " 'read',\n", + " 'optical character recognition',\n", + " 'click'],\n", + " 'name': 'Click on text with OCR',\n", + " 'parameters': [{'description': ' Text to find. Only exact matches are '\n", + " 'returned.\\n',\n", + " 'name': ' text'}],\n", + " 'return': '',\n", + " 'snippet': '# Make a textfile with some text to recognize\\n'\n", + " \"testfile = make_textfile(text='OCR Example')\\n\"\n", + " '# Open the textfile\\n'\n", + " 'open_file(testfile)\\n'\n", + " '# Find the text with OCR and click on it\\n'\n", + " \"click_on_text(text='OCR Example')\\n\"}\n", + "{'description': 'This activity double clicks on position (coordinates) of '\n", + " 'specified text on the current screen using OCR.',\n", + " 'example': '>>> # Make a textfile with some text to recognize\\n'\n", + " \">>> testfile = make_textfile(text='OCR Example')\\n\"\n", + " '>>> # Open the textfile\\n'\n", + " '>>> open_file(testfile)\\n'\n", + " '>>> # Find the text with OCR and double click on it\\n'\n", + " \">>> double_click_on_text(text='OCR Example')\\n\",\n", + " 'function_call': 'double_click_on_text_ocr(text)',\n", + " 'icon': 'las la-mouse-pointer',\n", + " 'keywords': ['OCR',\n", + " 'vision',\n", + " 'AI',\n", + " 'screen',\n", + " 'citrix',\n", + " 'read',\n", + " 'optical character recognition',\n", + " 'click',\n", + " 'double click'],\n", + " 'name': 'Double click on text with OCR',\n", + " 'parameters': [{'description': ' Text to find. Only exact matches are '\n", + " 'returned.\\n',\n", + " 'name': ' text'}],\n", + " 'return': '',\n", + " 'snippet': '# Make a textfile with some text to recognize\\n'\n", + " \"testfile = make_textfile(text='OCR Example')\\n\"\n", + " '# Open the textfile\\n'\n", + " 'open_file(testfile)\\n'\n", + " '# Find the text with OCR and double click on it\\n'\n", + " \"double_click_on_text(text='OCR Example')\\n\"}\n", + "{'description': 'This activity Right clicks on position (coordinates) of '\n", + " 'specified text on the current screen using OCR.',\n", + " 'example': '>>> # Make a textfile with some text to recognize\\n'\n", + " \">>> testfile = make_textfile(text='OCR Example')\\n\"\n", + " '>>> # Open the textfile\\n'\n", + " '>>> open_file(testfile)\\n'\n", + " '>>> # Find the text with OCR and right click on it\\n'\n", + " \">>> right_click_on_text(text='OCR Example')\\n\",\n", + " 'function_call': 'right_click_on_text_ocr(text)',\n", + " 'icon': 'las la-mouse-pointer',\n", + " 'keywords': ['OCR',\n", + " 'vision',\n", + " 'AI',\n", + " 'screen',\n", + " 'citrix',\n", + " 'read',\n", + " 'optical character recognition',\n", + " 'click',\n", + " 'right click'],\n", + " 'name': 'Right click on text with OCR',\n", + " 'parameters': [{'description': ' Text to find. Only exact matches are '\n", + " 'returned.\\n',\n", + " 'name': ' text'}],\n", + " 'return': '',\n", + " 'snippet': '# Make a textfile with some text to recognize\\n'\n", + " \"testfile = make_textfile(text='OCR Example')\\n\"\n", + " '# Open the textfile\\n'\n", + " 'open_file(testfile)\\n'\n", + " '# Find the text with OCR and right click on it\\n'\n", + " \"right_click_on_text(text='OCR Example')\\n\"}\n" + ] + } + ], + "source": [ + "from pprint import pprint\n", + "\n", + "with open(activities_path, 'r', encoding='utf-8') as f:\n", + " lines = f.readlines()\n", + "\n", + "categories = []\n", + "\n", + "for i, line in enumerate(lines):\n", + " if line == '\"\"\"\\n': # Category\n", + " if lines[i+1].strip(): # Not empty\n", + " name = lines[i+1].strip()\n", + " icon = lines[i+2].strip().replace('Icon: ','')\n", + " if not icon:\n", + " raise Exception\n", + " category = {'name': name, 'icon': icon, 'activities':[]}\n", + " categories.append(category)\n", + " \n", + " if line.startswith('def ') or line.startswith(' def '): # Function definition\n", + " if lines[i-1].strip() == '@activity':\n", + " activity = {}\n", + " if '__init__' in line:\n", + " if '(' in lines[i-2]:\n", + " parsed_class_line = lines[i-2].split('(')[0] + ':'\n", + " else:\n", + " parsed_class_line = lines[i-2]\n", + " arguments = line.split('(')[-1].replace('):','')\n", + " func_call_raw = (parsed_class_line.replace('class ','').replace(':', '(') + arguments + ')').replace('\\n','')\n", + " activity['function_call'] = func_call_raw.replace('self, ','')\n", + "\n", + " else:\n", + " func_call_raw = line.replace('def ','').replace(':', '').strip()\n", + " activity['function_call'] = func_call_raw.replace('self, ','')\n", + " activity['name'] = lines[i+1].replace('\"\"\"', '').strip()\n", + " if not activity['name']:\n", + " raise Exception('Activity {} should have a name'.format(activity['function_call']))\n", + "\n", + " # Description (multiline)\n", + " activity['description'] = ''\n", + " for k, line3 in enumerate(lines[i+3:]):\n", + " if not line3.strip():\n", + " break\n", + " activity['description'] += line3.strip()\n", + " if not activity['description']:\n", + " raise Exception('Activity {} should have a description'.format(activity['name']))\n", + "\n", + " # Parameters (multiline)\n", + " activity['parameters'] = []\n", + " activity['return'] = ''\n", + " for l, line_param in enumerate(lines[i:]):\n", + " if line_param.strip() == '@activity': # Till we reach next function\n", + " break\n", + " \n", + " if ':parameter' in line_param:\n", + " parameters = {}\n", + " parameters['name'] = line_param.split(':parameter')[-1].split(':')[0]\n", + " parameters['description'] = line_param.split(':',2)[-1]\n", + " \n", + " activity['parameters'].append(parameters)\n", + " \n", + " # Add return too\n", + " if ':return:' in line_param:\n", + " activity['return'] = line_param.split(':',2)[-1]\n", + " \n", + " # Example (multiline)\n", + " activity['example'] = ''\n", + " for l, line4 in enumerate(lines[i:]):\n", + " if line4.strip() == '@activity': # Till we reach next function\n", + " break\n", + "\n", + " if line4.strip() == ':Example:':\n", + " number_of_spaces = len(lines[i:][l+2]) - len(lines[i:][l+2].lstrip())\n", + " for m, line5 in enumerate(lines[i:][l+2:]):\n", + " if not line5.strip():\n", + " break\n", + " activity['example'] += line5[number_of_spaces:]\n", + " break\n", + " \n", + " # Add copy-paste example\n", + " activity['snippet'] = ''\n", + " for example_line in activity['example'].split('\\n'):\n", + " if example_line.strip():\n", + " if example_line[0] in ['>','#',' ']:\n", + " activity['snippet'] += example_line.replace('>>> ','') + '\\n'\n", + " \n", + " if not activity['example']:\n", + " raise Exception('Activity {} should have an example'.format(activity['name']))\n", + " \n", + " # Single lines\n", + " for j, line2 in enumerate(lines[i:]):\n", + " if line2.strip() == '@activity': # Till we reach next function\n", + " break\n", + "\n", + " if line2.strip() == 'Icon': # Icon\n", + " activity['icon'] = lines[i:][j+1].strip().replace('', '')\n", + "\n", + " if line2.strip() == 'Keywords': # Keywords\n", + " activity['keywords'] = lines[i:][j+1].strip().split(', ')\n", + "\n", + " category['activities'].append(activity)\n", + " pprint(activity)\n", + " if not activity.get('icon'):\n", + " raise Exception('Activity {} should have an icon'.format(activity['name']))\n", + " \n", + "import json\n", + "with open('activities.json', 'w') as f:\n", + " json.dump(categories, f)" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "Cryptography\n", + "------------\n", + ".. autofunction:: generate_random_key\n", + ".. autofunction:: encrypt_text_with_key\n", + ".. autofunction:: decrypt_text_with_key\n", + ".. autofunction:: encrypt_file_with_key\n", + ".. autofunction:: decrypt_file_with_key\n", + ".. autofunction:: generate_key_from_password\n", + ".. autofunction:: generate_hash_from_file\n", + ".. autofunction:: generate_hash_from_text\n", + "\n", + "\n", + "Random\n", + "------\n", + ".. autofunction:: generate_random_number\n", + ".. autofunction:: generate_random_boolean\n", + ".. autofunction:: generate_random_name\n", + ".. autofunction:: generate_random_address\n", + ".. autofunction:: generate_random_beep\n", + ".. autofunction:: generate_random_date\n", + ".. autofunction:: generate_unique_identifier\n", + "\n", + "\n", + "User Input\n", + "----------\n", + ".. autofunction:: ask_user_input\n", + ".. autofunction:: ask_user_password\n", + ".. autofunction:: ask_credentials\n", + ".. autofunction:: display_osd_message\n", + "\n", + "\n", + "Browser\n", + "-------\n", + ".. autoclass:: display_osd_message\n", + " :members:\n", + "\n", + "\n", + "Credential Management\n", + "---------------------\n", + ".. autofunction:: set_credential\n", + ".. autofunction:: delete_credential\n", + ".. autofunction:: get_credential\n", + "\n", + "\n", + "FTP\n", + "---\n", + ".. autoclass:: get_credential\n", + " :members:\n", + "\n", + "\n", + "Keyboard\n", + "--------\n", + ".. autofunction:: press_key\n", + ".. autofunction:: press_key_combination\n", + ".. autofunction:: type_text\n", + "\n", + "\n", + "Mouse\n", + "-----\n", + ".. autofunction:: get_mouse_position\n", + ".. autofunction:: display_mouse_position\n", + ".. autofunction:: click\n", + ".. autofunction:: double_click\n", + ".. autofunction:: right_click\n", + ".. autofunction:: move_mouse_to\n", + ".. autofunction:: move_mouse_relative\n", + ".. autofunction:: drag_mouse_to\n", + "\n", + "\n", + "Image\n", + "-----\n", + ".. autofunction:: random_screen_snippet\n", + ".. autofunction:: take_screenshot\n", + ".. autofunction:: click_image\n", + ".. autofunction:: double_click_image\n", + ".. autofunction:: right_click_image\n", + ".. autofunction:: locate_image_on_screen\n", + "\n", + "\n", + "Folder Operations\n", + "-----------------\n", + ".. autofunction:: get_files_in_folder\n", + ".. autofunction:: create_folder\n", + ".. autofunction:: rename_folder\n", + ".. autofunction:: show_folder\n", + ".. autofunction:: move_folder\n", + ".. autofunction:: remove_folder\n", + ".. autofunction:: empty_folder\n", + ".. autofunction:: folder_exists\n", + ".. autofunction:: copy_folder\n", + ".. autofunction:: zip_folder\n", + ".. autofunction:: unzip\n", + "\n", + "\n", + "Delay\n", + "-----\n", + ".. autofunction:: wait\n", + ".. autofunction:: wait_for_image\n", + ".. autofunction:: wait_folder_exists\n", + "\n", + "\n", + "Word Application\n", + "----------------\n", + ".. autoclass:: wait_folder_exists\n", + " :members:\n", + "\n", + "\n", + "Word File\n", + "---------\n", + ".. autoclass:: wait_folder_exists\n", + " :members:\n", + "\n", + "\n", + "Outlook Application\n", + "-------------------\n", + ".. autoclass:: wait_folder_exists\n", + " :members:\n", + "\n", + "\n", + "Excel Application\n", + "-----------------\n", + ".. autoclass:: wait_folder_exists\n", + " :members:\n", + "\n", + "\n", + "Excel File\n", + "----------\n", + ".. autoclass:: wait_folder_exists\n", + " :members:\n", + "\n", + "\n", + "PowerPoint Application\n", + "----------------------\n", + ".. autoclass:: wait_folder_exists\n", + " :members:\n", + "\n", + "\n", + "Office 365\n", + "----------\n", + ".. autofunction:: send_email_with_outlook365\n", + "\n", + "\n", + "Salesforce\n", + "----------\n", + ".. autofunction:: salesforce_api_call\n", + "\n", + "\n", + "E-mail (SMTP)\n", + "-------------\n", + ".. autofunction:: send_mail_smtp\n", + "\n", + "\n", + "Windows OS\n", + "----------\n", + ".. autofunction:: set_user_password\n", + ".. autofunction:: validate_user_password\n", + ".. autofunction:: lock_windows\n", + ".. autofunction:: is_logged_in\n", + ".. autofunction:: is_desktop_locked\n", + ".. autofunction:: get_username\n", + ".. autofunction:: set_to_clipboard\n", + ".. autofunction:: get_from_clipboard\n", + ".. autofunction:: clear_clipboard\n", + ".. autofunction:: run_vbs_script\n", + ".. autofunction:: beep\n", + "\n", + "\n", + "Text-to-Speech\n", + "--------------\n", + ".. autofunction:: speak\n", + "\n", + "\n", + "Active Directory\n", + "----------------\n", + ".. autoclass:: speak\n", + " :members:\n", + "\n", + "\n", + "Utilities\n", + "---------\n", + ".. autofunction:: home_path\n", + ".. autofunction:: desktop_path\n", + ".. autofunction:: open_file\n", + ".. autofunction:: set_wallpaper\n", + ".. autofunction:: download_file_from_url\n", + "\n", + "\n", + "Trello\n", + "------\n", + ".. autofunction:: add_trello_card\n", + "\n", + "\n", + "System\n", + "------\n", + ".. autofunction:: rename_file\n", + ".. autofunction:: move_file\n", + ".. autofunction:: remove_file\n", + ".. autofunction:: file_exists\n", + ".. autofunction:: wait_file_exists\n", + ".. autofunction:: write_list_to_file\n", + ".. autofunction:: read_list_from_txt\n", + ".. autofunction:: append_line\n", + ".. autofunction:: make_textfile\n", + ".. autofunction:: copy_file\n", + ".. autofunction:: get_file_extension\n", + ".. autofunction:: send_to_printer\n", + "\n", + "\n", + "PDF\n", + "---\n", + ".. autofunction:: read_text_from_pdf\n", + ".. autofunction:: join_pdf_files\n", + ".. autofunction:: extract_page_range_from_pdf\n", + ".. autofunction:: extract_images_from_pdf\n", + ".. autofunction:: apply_watermark_to_pdf\n", + "\n", + "\n", + "System Monitoring\n", + "-----------------\n", + ".. autofunction:: get_cpu_load\n", + ".. autofunction:: get_number_of_cpu\n", + ".. autofunction:: get_cpu_frequency\n", + ".. autofunction:: get_cpu_stats\n", + ".. autofunction:: get_memory_stats\n", + ".. autofunction:: get_disk_stats\n", + ".. autofunction:: get_disk_partitions\n", + ".. autofunction:: get_boot_time\n", + ".. autofunction:: get_time_since_last_boot\n", + "\n", + "\n", + "Image Processing\n", + "----------------\n", + ".. autofunction:: show_image\n", + ".. autofunction:: rotate_image\n", + ".. autofunction:: resize_image\n", + ".. autofunction:: get_image_width\n", + ".. autofunction:: get_image_height\n", + ".. autofunction:: crop_image\n", + ".. autofunction:: mirror_image_horizontally\n", + ".. autofunction:: mirror_image_vertically\n", + "\n", + "\n", + "Process\n", + "-------\n", + ".. autofunction:: run_manual\n", + ".. autofunction:: run\n", + ".. autofunction:: is_process_running\n", + ".. autofunction:: get_running_processes\n", + ".. autofunction:: kill_process\n", + "\n", + "\n", + "Optical Character Recognition (OCR)\n", + "-----------------------------------\n", + ".. autofunction:: extract_text_ocr\n", + ".. autofunction:: find_text_on_screen_ocr\n", + ".. autofunction:: click_on_text_ocr\n", + ".. autofunction:: double_click_on_text_ocr\n", + ".. autofunction:: right_click_on_text_ocr\n" + ] + } + ], + "source": [ + "title = ''\n", + "for item in categories:\n", + " print('\\n')\n", + " print(item['name'])\n", + " underline = ''\n", + " for char in range(0,len(item['name'])):\n", + " underline = underline + '-'\n", + " print(underline)\n", + " \n", + " for i in item['activities']:\n", + " function = i['function_call']\n", + " if function[0].isupper():\n", + " class_name = i['function_call'].split('(')[0]\n", + " class_name_rst = '.. autoclass:: ' + function_name +'\\n' + ' :members:' \n", + " print(class_name_rst)\n", + " break\n", + " function_name = i['function_call'].split('(')[0]\n", + " function_name_rst = '.. autofunction:: ' + function_name\n", + " print(function_name_rst)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/activities.rst b/docs/source/activities.rst new file mode 100644 index 00000000..33ff6431 --- /dev/null +++ b/docs/source/activities.rst @@ -0,0 +1,264 @@ + +.. module:: automagica.activities + +Activities +========== + +Cryptography +------------ +.. autofunction:: generate_random_key +.. autofunction:: encrypt_text_with_key +.. autofunction:: decrypt_text_with_key +.. autofunction:: encrypt_file_with_key +.. autofunction:: decrypt_file_with_key +.. autofunction:: generate_key_from_password +.. autofunction:: generate_hash_from_file +.. autofunction:: generate_hash_from_text + + +Random +------ +.. autofunction:: generate_random_number +.. autofunction:: generate_random_boolean +.. autofunction:: generate_random_name +.. autofunction:: generate_random_address +.. autofunction:: generate_random_beep +.. autofunction:: generate_random_date +.. autofunction:: generate_unique_identifier + + +User Input +---------- +.. autofunction:: ask_user_input +.. autofunction:: ask_user_password +.. autofunction:: ask_credentials +.. autofunction:: display_osd_message + + +Browser +------- +.. autoclass:: display_osd_message + :members: + + +Credential Management +--------------------- +.. autofunction:: set_credential +.. autofunction:: delete_credential +.. autofunction:: get_credential + + +FTP +--- +.. autoclass:: get_credential + :members: + + +Keyboard +-------- +.. autofunction:: press_key +.. autofunction:: press_key_combination +.. autofunction:: type_text + + +Mouse +----- +.. autofunction:: get_mouse_position +.. autofunction:: display_mouse_position +.. autofunction:: click +.. autofunction:: double_click +.. autofunction:: right_click +.. autofunction:: move_mouse_to +.. autofunction:: move_mouse_relative +.. autofunction:: drag_mouse_to + + +Image +----- +.. autofunction:: random_screen_snippet +.. autofunction:: take_screenshot +.. autofunction:: click_image +.. autofunction:: double_click_image +.. autofunction:: right_click_image +.. autofunction:: locate_image_on_screen + + +Folder Operations +----------------- +.. autofunction:: get_files_in_folder +.. autofunction:: create_folder +.. autofunction:: rename_folder +.. autofunction:: show_folder +.. autofunction:: move_folder +.. autofunction:: remove_folder +.. autofunction:: empty_folder +.. autofunction:: folder_exists +.. autofunction:: copy_folder +.. autofunction:: zip_folder +.. autofunction:: unzip + + +Delay +----- +.. autofunction:: wait +.. autofunction:: wait_for_image +.. autofunction:: wait_folder_exists + + +Word Application +---------------- +.. autoclass:: wait_folder_exists + :members: + + +Word File +--------- +.. autoclass:: wait_folder_exists + :members: + + +Outlook Application +------------------- +.. autoclass:: wait_folder_exists + :members: + + +Excel Application +----------------- +.. autoclass:: wait_folder_exists + :members: + + +Excel File +---------- +.. autoclass:: wait_folder_exists + :members: + + +PowerPoint Application +---------------------- +.. autoclass:: wait_folder_exists + :members: + + +Office 365 +---------- +.. autofunction:: send_email_with_outlook365 + + +Salesforce +---------- +.. autofunction:: salesforce_api_call + + +E-mail (SMTP) +------------- +.. autofunction:: send_mail_smtp + + +Windows OS +---------- +.. autofunction:: set_user_password +.. autofunction:: validate_user_password +.. autofunction:: lock_windows +.. autofunction:: is_logged_in +.. autofunction:: is_desktop_locked +.. autofunction:: get_username +.. autofunction:: set_to_clipboard +.. autofunction:: get_from_clipboard +.. autofunction:: clear_clipboard +.. autofunction:: run_vbs_script +.. autofunction:: beep + + +Text-to-Speech +-------------- +.. autofunction:: speak + + +Active Directory +---------------- +.. autoclass:: speak + :members: + + +Utilities +--------- +.. autofunction:: home_path +.. autofunction:: desktop_path +.. autofunction:: open_file +.. autofunction:: set_wallpaper +.. autofunction:: download_file_from_url + + +Trello +------ +.. autofunction:: add_trello_card + + +System +------ +.. autofunction:: rename_file +.. autofunction:: move_file +.. autofunction:: remove_file +.. autofunction:: file_exists +.. autofunction:: wait_file_exists +.. autofunction:: write_list_to_file +.. autofunction:: read_list_from_txt +.. autofunction:: append_line +.. autofunction:: make_textfile +.. autofunction:: copy_file +.. autofunction:: get_file_extension +.. autofunction:: send_to_printer + + +PDF +--- +.. autofunction:: read_text_from_pdf +.. autofunction:: join_pdf_files +.. autofunction:: extract_page_range_from_pdf +.. autofunction:: extract_images_from_pdf +.. autofunction:: apply_watermark_to_pdf + + +System Monitoring +----------------- +.. autofunction:: get_cpu_load +.. autofunction:: get_number_of_cpu +.. autofunction:: get_cpu_frequency +.. autofunction:: get_cpu_stats +.. autofunction:: get_memory_stats +.. autofunction:: get_disk_stats +.. autofunction:: get_disk_partitions +.. autofunction:: get_boot_time +.. autofunction:: get_time_since_last_boot + + +Image Processing +---------------- +.. autofunction:: show_image +.. autofunction:: rotate_image +.. autofunction:: resize_image +.. autofunction:: get_image_width +.. autofunction:: get_image_height +.. autofunction:: crop_image +.. autofunction:: mirror_image_horizontally +.. autofunction:: mirror_image_vertically + + +Process +------- +.. autofunction:: run_manual +.. autofunction:: run +.. autofunction:: is_process_running +.. autofunction:: get_running_processes +.. autofunction:: kill_process + + +Optical Character Recognition (OCR) +----------------------------------- +.. autofunction:: extract_text_ocr +.. autofunction:: find_text_on_screen_ocr +.. autofunction:: click_on_text_ocr +.. autofunction:: double_click_on_text_ocr +.. autofunction:: right_click_on_text_ocr \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..d244e64d --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('../..')) + +# -- Project information ----------------------------------------------------- + +project = 'Automagica' +copyright = '2019, Oakwood Technologies BVBA' +author = 'Oakwood Technologies BVBA' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '2' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.githubpages', + 'recommonmark' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# + +source_suffix = ['.rst', '.md'] +# source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Automagicadoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'Automagica.tex', 'Automagica Documentation', + 'Oakwood Technologies BVBA', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'automagica', 'Automagica Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'Automagica', 'Automagica Documentation', + author, 'Automagica', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- \ No newline at end of file diff --git a/docs/source/get_started.md b/docs/source/get_started.md new file mode 100644 index 00000000..2ec57550 --- /dev/null +++ b/docs/source/get_started.md @@ -0,0 +1,328 @@ +# Getting started + +## How to install + +Download automagica and get started within 10 clicks on [www.automagica.com](https://www.automagica.com). +Windows 10 is officially supported. + +## Examples + +Interactive one-click examples with documentation can be found on [www.portal.automagica.com](https://www.portal.automagica.com) + +## General knowledge + +This section contains some general tips & tricks to help you building your first automation with Automagica. + +### Entering variables + +Most Automagica activities include parameters. Some are required and some are optional for more flexibility and advanced usage. The chapter 'Activities' contains a list of all the activities and their possible parameters. + +In general a parameter can be a word (string), a number (integer) or a path (raw string). + +#### String: + +A string can be a word or a sentence, in Python a string starts and ends with apostrophes ('') + +``` +# Example of a string: +my_string = 'This can be everything' +``` + +### Nmber: + +An integer is a number: + +``` +# Example of an integer: +my_integer = 7 +``` + +### Path + +A path specifies the directories in which a file, folder, executable,... is located. An example of such a pathname is: "C:\\Users\\Bob\\Desktop\\Automagica.pptx". A pathname needs to be a (raw) string when entered in a function, you can achieve this by adding an 'r' in front of your path. +``` +# Pathname: +C:\Users\Bob\Desktop\Automagica.pptx + +# As a string: +r'C:\Users\\Bob\Desktop\Automagica.pptx' + +# In a function: +open_file('C:\\Users\\Bob\\Desktop\\Automagica.pptx') +``` + +Alternatively you can double every backslash input. The next snippet of code illustrates how to use this method + +``` +# Pathname: +C:\Users\Bob\Desktop\Automagica.pptx + +# As a string: +'C:\\Users\\Bob\\Desktop\\Automagica.pptx' + +# In a function: +open_file('C:\\Users\\Bob\\Desktop\\Automagica.pptx') +``` + +In Windows Explorer, a path can be determined by pressing shift + right click on a file, folder,... A menu pops up, where you can select "copy as path" (see image). This copies te path as a string to the clipboard, e.g. "C:\Program Files (x86)\Dropbox\Client\Dropbox.exe". This path still needs an 'r' added in front or all its backslashes doubled for it to be in correct form for a function input: r"C:\Program Files (x86)\Dropbox\Client\Dropbox.exe" or "C:\\\Program Files (x86)\\\Dropbox\\\Client\\\Dropbox.exe". + +![Imgur](https://i.imgur.com/9xI2mbk.png?2) + + +### Browser Automation + +Out-of-the box Automagica uses Chrome as automated browser. Automating the browser requires you to find the elements to manipulate them. +The following sections will explain how to find, read and manipulate those web elements. + +#### Basic functions + +To open a browser choose 'Open Chrome browser' from menu or type the command: +``` +browser = Chrome() +``` + +The browser function will wait until the page has fully loaded (that is, the “onload” event has fired) before continuing in the Automagica script. It’s worth noting that if your page uses a lot of AJAX on load then the browser function may not know when it has completely loaded. + +Browse to a website by clicking 'Browse to URL' in the menu or use the command: +``` +browser.get('https://mywebsite.com/') +``` + +Closing the browser can be done by: +``` +browser.close() +``` + +To move backward and forward in your browser’s history: +``` +browser.forward() +browser.back() +``` + +To click on an element: +``` +element.click() +``` + +To enter text into a text field: +``` +element.send_keys("some text") +``` + +To clear an element: +``` +element.clear() +``` + + +An optional check to see if you are on the correct website is to check the title. For example if you are surfing to https://www.google.com, you might want to check if "Google" is in the title to make sure the bot surfed to the correct page. +``` +browser = Chrome() +browser.get('https://google.com/') +if not "Google" in browser.title: + errorbox("Site is not correct") +``` + +#### Navigating + +To navigate and perform actions in the browser it is crucial to locate elements. Elements can be everything in the html files of a website like text, titles, buttons, text fields, tables, etc... + +#### Quick start + +There are two methods to finding elements, *find_element* to find a single element and *find_elements* to find multiple. +Arguably the easiest way to find a certain element is by copying it's XPath. + +To do this in Chrome right click on the element you want to find, in the example below this is the "Google Search" button on Google.com. Click *inspect element* and a side tab with the html code opens with the element you selected highlighted in blue. + +![Imgur](https://i.imgur.com/A2xdvUP.png) + +In the html code, right click the highlighted block and select *Copy* -> *Copy XPath*. + +![Imgur](https://i.imgur.com/WRD46Xi.png) + +You can now use the absolute XPath to manipulate the element. However this is a fast method for prototyping, we do not recommend using absolute paths in production environments. Slight changes in the html code would cause the absolute path to change and to likely cause errors. A more in-depth overview in the next section. + +#### Selecting elements + +###### Selection by name + +Use this when you know name attribute of an element. With this strategy, the first element with the name attribute value matching the location will be returned. If no element has a matching name attribute, a NoSuchElementException will be raised. + +For instance, consider these elements on a webpage: + + + +
+ + + + +
+ + + +  + +The corresponding html code would be: + + + +
+ + + + +
+ + + +The username and password field can be found by: + +``` +username = browser.find_element_by_name('username') +password = browser.find_element_by_name('password') +``` + +To fill in the fields: + +``` +username.send_keys("Automagica_User1") +password.send_keys("thisismypassword123") +``` + +To find and click on the login button: + +``` +login = browser.find_element_by_name('loginbutton') +login.click() +``` + +**Side note** + +In case of double naming, finding by name always finds the first element. Imagine the following html code: + + + +
+ + + +
+ + + +The following command will find the first element with the name "continue" and thus selecting the Login button: + +``` +continue = browser.find_element_by_name('continue') +``` + +###### Selection by Id + +You can select elements by Id when this is known. This is a robust method, yet generally nog every element had a known id tag. Consider the html code below: + + + +
+ + +
+ + + +In this case the form has an id "loginForm". Hence the form can be selected with the Id by: + +``` +loginform = browser.find_element_by_id('loginForm') +``` + +#### Selection by Xpath + +XPath (XML Path Language) is a query language for selecting nodes from an XML document. Since HTML can be an implementation of XML (referred to as XHTML), this language can be used to find and manipulate target elements in web applications. + +The advantage of using XPath is the possibility to reach every element within an HTML structure. See [Quick start](#quick-start) for a visual introduction on how to find and use an element with XPath. +The disadvantage of using a full XPath is that it is not very robust. Even the slightest changes in a HTML page would cause absolute XPaths to change, which in result will likely cause your robot unable to find the correct elements. Note that this is different from using an element name or id, as elements will still be able to be found with changes in the HTML page as long as the name or id remains the same. + +Therefore, when working with Xpath the robustness can be increased by finding a nearby element with an id or name attribute (ideally a parent element), so you can locate your target element based on the relationship. + +Consider the following structure on a HTML page: + + + +
+ + + + +
+ + + +  + +With the following source code: + + + +
+ + + + +
+ + + + +**Selecting the username:** + +1. Absolute path (note that this would break if the HTML was changed only slightly) +2. Point to the first element in the form +3. First input element with attribute named ‘name’ and the value username +``` +username = browser.find_element_by_xpath("//form[input/@name='username']") +username = browser.find_element_by_xpath("//form[@id='loginForm']/input[1]") +username = browser.find_element_by_xpath("//input[@name='username']") +``` + +**The "clear" button can be located by:** + +1. Fourth input element of the form element with attribute named id and value loginForm +2. Input with attribute named name and the value continue and attribute named type and the value button +``` +clear_button = browser.find_element_by_xpath("//form[@id='loginForm']/input[4]") +clear_button = browser.find_element_by_xpath("//input[@name='continue'][@type='button']") +``` + +**The form can be selected by:** + +1. Absolute path (note that this would break if the HTML was changed only slightly): +2. First form element in the HTML +3. The form element with attribute named id and the value loginForm +``` +login_form = browser.find_element_by_xpath("/html/body/form[1]") +login_form = browser.find_element_by_xpath("//form[1]") +login_form = browser.find_element_by_xpath("//form[@id='loginForm']") +``` + +#### Browsing Example + +The following example browses to Google, searches for Automagica, opens the first Google Search result link + +``` +# Open Chrome +browser = Chrome() + +# Browse to Google +browser.get('https://google.com') + +# Enter Search Text +browser.find_element_by_xpath('//*[@id="lst-ib"]').send_keys('automagica') + +# Submit +browser.find_element_by_xpath('//*[@id="lst-ib"]').submit() + +# Click the first link +browser.find_elements_by_class_name('r')[0].click() +``` + diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..e38c6aa5 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,22 @@ +.. Automagica documentation master file, created by + sphinx-quickstart on Wed Dec 18 14:19:13 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Automagica's documentation! +====================================== + +Automagica is an open source Smart Robotic Process Automation (SRPA) platform. With Automagica, automating cross-platform processes becomes a breeze. With this open source library we want to provide a comprehensive and consistent wrapper around known and lesser known automation libraries. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + get_started + activities + + +Indices and tables +================== + +* :ref:`genindex` diff --git a/examples/browser/app.py b/examples/browser/app.py deleted file mode 100644 index f928c5c4..00000000 --- a/examples/browser/app.py +++ /dev/null @@ -1,16 +0,0 @@ -from automagica import * - -""" -Browses to Google, searches for our GitHub project, opens the first Google Search result link -""" - -# Initiate browser -browser = ChromeBrowser() -# Surf to google.com -browser.get('https://google.com') -# Enter searchterm -browser.find_element_by_xpath('//*[@id="lst-ib"]').send_keys('oakwoodai automagica') -# Click on search button -browser.find_element_by_xpath('//*[@id="lst-ib"]').submit() -# Select first hit -browser.find_elements_by_class_name('r')[0].click() diff --git a/examples/browser/google_search_links.py b/examples/browser/google_search_links.py deleted file mode 100644 index f44594cd..00000000 --- a/examples/browser/google_search_links.py +++ /dev/null @@ -1,10 +0,0 @@ -from automagica import * - -# Put the links google returns in a list and name it "president_links". -president_links = GetGoogleSearchLinks("us presidents") - -# Write the links to a .txt file and save it at a new path. -WriteListToFile(president_links, "C:\\Users\\Bob\\Desktop\\US_Presidents.txt") - -# Open the newly made .txt file. -OpenFile("C:\\Users\\Bob\\Desktop\\US_Presidents.txt") \ No newline at end of file diff --git a/examples/browser_automation_example.ipynb b/examples/browser_automation_example.ipynb new file mode 100644 index 00000000..5936543a --- /dev/null +++ b/examples/browser_automation_example.ipynb @@ -0,0 +1,796 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Browser Automation\n", + "\n", + "In this example we go over the basics of browser automation in Automagica. This example will build a script that surfs to the online encyclopedia Wikipedia, look for a subject using the look-up functionality and extract the content. Finally we will write the extracted content to a .txt file." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initializing Automagica\n", + "\n", + "The first step in building a script with Automagica is to import all the Automagica activities." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "from automagica import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using the browser\n", + "\n", + "We will use the Chrome browser in this example, first step is to start an automated version of Chrome." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "# Open an automated browser\n", + "browser = Chrome()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Chrome now opens without anything loaded. Each time an instance of Chrome is created with Automagica this will be a fresh one, this means no history, no history, etc.\n", + "\n", + "In this case we gave the Chrome instance the name \"browser\". You can give it any name you want, as long as you are conistent with the following activities. \n", + "\n", + "Next step is to surft to the Wikipedia website" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# Browse to Wikipedia\n", + "browser.get('https://www.wikipedia.org')" + ] + }, + { + "attachments": { + "inspect.png": { + "image/png": "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" + }, + "xpath.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To navigate and perform actions in the browser it is crucial to locate elements. Elements can be everything in the html files of a website like text, titles, buttons, text fields, tables, etc...\n", + "\n", + "Elements can often be addressed in multiple ways, by its name, id, Xpath.. How to find all these elements we refer to the full documentation. Arguably the easiest way to find a certain element is by copying it's XPath. \n", + "\n", + "To find the Xpath of the Wikipedia search bar, right click it and pick \"inspect element\".\n", + "\n", + "![inspect.png](attachment:inspect.png)\n", + "\n", + "A side tab with the html code opens with the element you selected highlighted in blue. In the html code, right click the highlighted block and select Copy -> Copy XPath.\n", + "\n", + "![xpath.png](attachment:xpath.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# Find the search bar using the Xpath\n", + "search_bar = browser.find_xpath('//*[@id=\"searchInput\"]')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now that we found the search bar, we can manipulate it. \n", + "We will look for the term 'robot', but feel free to change it in the code down below" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "# Type in the search bar\n", + "search_bar.send_keys('robot')\n", + "\n", + "# Submit the query\n", + "search_bar.submit()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "After landing on the page we can find the Xpath of the element that holds the text the same way we found the search bar. After extracting the text we can close the browser and print the text." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "This article is about mechanical robots. For software agents, see Bot. For other uses of the term, see Robot (disambiguation).\n", + "Atlas (2016), a bipedal humanoid robot\n", + "ASIMO (2000) at the Expo 2005\n", + "Articulated welding robots used in a factory are a type of industrial robot\n", + "The quadrupedal military robot Cheetah, an evolution of BigDog (pictured), was clocked as the world's fastest legged robot in 2012, beating the record set by an MIT bipedal robot in 1989.[1]\n", + "A robot is a machine—especially one programmable by a computer— capable of carrying out a complex series of actions automatically.[2] Robots can be guided by an external control device or the control may be embedded within. Robots may be constructed on the lines of human form, but most robots are machines designed to perform a task with no regard to their aesthetics.\n", + "Robots can be autonomous or semi-autonomous and range from humanoids such as Honda's Advanced Step in Innovative Mobility (ASIMO) and TOSY's TOSY Ping Pong Playing Robot (TOPIO) to industrial robots, medical operating robots, patient assist robots, dog therapy robots, collectively programmed swarm robots, UAV drones such as General Atomics MQ-1 Predator, and even microscopic nano robots. By mimicking a lifelike appearance or automating movements, a robot may convey a sense of intelligence or thought of its own. Autonomous things are expected to proliferate in the coming decade,[3] with home robotics and the autonomous car as some of the main drivers.[4]\n", + "The branch of technology that deals with the design, construction, operation, and application of robots,[5] as well as computer systems for their control, sensory feedback, and information processing is robotics. These technologies deal with automated machines that can take the place of humans in dangerous environments or manufacturing processes, or resemble humans in appearance, behavior, or cognition. Many of today's robots are inspired by nature contributing to the field of bio-inspired robotics. These robots have also created a newer branch of robotics: soft robotics.\n", + "From the time of ancient civilization there have been many accounts of user-configurable automated devices and even automata resembling animals and humans, designed primarily as entertainment. As mechanical techniques developed through the Industrial age, there appeared more practical applications such as automated machines, remote-control and wireless remote-control.\n", + "The term comes from a Czech word, robota, meaning \"forced labor\";[6] the word 'robot' was first used to denote a fictional humanoid in a 1920 play R.U.R. (Rossumovi Univerzální Roboti - Rossum's Universal Robots) by the Czech writer, Karel Čapek but it was Karel's brother Josef Čapek who was the word's true inventor.[7][8][9] Electronics evolved into the driving force of development with the advent of the first electronic autonomous robots created by William Grey Walter in Bristol, England in 1948, as well as Computer Numerical Control (CNC) machine tools in the late 1940s by John T. Parsons and Frank L. Stulen. The first commercial, digital and programmable robot was built by George Devol in 1954 and was named the Unimate. It was sold to General Motors in 1961 where it was used to lift pieces of hot metal from die casting machines at the Inland Fisher Guide Plant in the West Trenton section of Ewing Township, New Jersey.[10]\n", + "Robots have replaced humans[11] in performing repetitive and dangerous tasks which humans prefer not to do, or are unable to do because of size limitations, or which take place in extreme environments such as outer space or the bottom of the sea. There are concerns about the increasing use of robots and their role in society. Robots are blamed for rising technological unemployment as they replace workers in increasing numbers of functions.[12] The use of robots in military combat raises ethical concerns. The possibilities of robot autonomy and potential repercussions have been addressed in fiction and may be a realistic concern in the future.\n", + "Contents\n", + "1 Summary\n", + "2 History\n", + "2.1 Early beginnings\n", + "2.2 Remote-controlled systems\n", + "2.3 Origin of the term 'robot'\n", + "2.4 Early robots\n", + "2.5 Modern autonomous robots\n", + "3 Future development and trends\n", + "3.1 New functionalities and prototypes\n", + "4 Etymology\n", + "5 Modern robots\n", + "5.1 Mobile robot\n", + "5.2 Industrial robots (manipulating)\n", + "5.3 Service robot\n", + "5.4 Educational (interactive) robots\n", + "5.5 Modular robot\n", + "5.6 Collaborative robots\n", + "6 Robots in society\n", + "6.1 Autonomy and ethical questions\n", + "6.2 Military robots\n", + "6.3 Relationship to unemployment\n", + "7 Contemporary uses\n", + "7.1 General-purpose autonomous robots\n", + "7.2 Factory robots\n", + "7.3 Dirty, dangerous, dull or inaccessible tasks\n", + "7.4 Military robots\n", + "7.5 Mining robots\n", + "7.6 Healthcare\n", + "7.7 Research robots\n", + "8 Robots in popular culture\n", + "8.1 Literature\n", + "8.2 Films\n", + "8.3 Sex robots\n", + "8.4 Problems depicted in popular culture\n", + "9 See also\n", + "9.1 Specific robotics concepts\n", + "9.2 Robotics methods and categories\n", + "9.3 Specific robots and devices\n", + "9.4 Other related articles\n", + "10 References\n", + "11 Further reading\n", + "12 External links\n", + "Summary\n", + "KITT (a fictional robot) is mentally anthropomorphic.\n", + "iCub is physically anthropomorphic.\n", + "The word robot can refer to both physical robots and virtual software agents, but the latter are usually referred to as bots.[13] There is no consensus on which machines qualify as robots but there is general agreement among experts, and the public, that robots tend to possess some or all of the following abilities and functions: accept electronic programming, process data or physical perceptions electronically, operate autonomously to some degree, move around, operate physical parts of itself or physical processes, sense and manipulate their environment, and exhibit intelligent behavior, especially behavior which mimics humans or other animals.[14][15] Closely related to the concept of a robot is the field of Synthetic Biology, which studies entities whose nature is more comparable to beings than to machines.\n", + "History\n", + "Main article: History of robots\n", + "The idea of automata originates in the mythologies of many cultures around the world. Engineers and inventors from ancient civilizations, including Ancient China,[16] Ancient Greece, and Ptolemaic Egypt,[17] attempted to build self-operating machines, some resembling animals and humans. Early descriptions of automata include the artificial doves of Archytas,[18] the artificial birds of Mozi and Lu Ban,[19] a \"speaking\" automaton by Hero of Alexandria, a washstand automaton by Philo of Byzantium, and a human automaton described in the Lie Zi.[16]\n", + "Early beginnings\n", + "Many ancient mythologies, and most modern religions include artificial people, such as the mechanical servants built by the Greek god Hephaestus[20] (Vulcan to the Romans), the clay golems of Jewish legend and clay giants of Norse legend, and Galatea, the mythical statue of Pygmalion that came to life. Since circa 400 BC, myths of Crete include Talos, a man of bronze who guarded the island from pirates.\n", + "In ancient Greece, the Greek engineer Ctesibius (c. 270 BC) \"applied a knowledge of pneumatics and hydraulics to produce the first organ and water clocks with moving figures.\"[21][22] In the 4th century BC, the Greek mathematician Archytas of Tarentum postulated a mechanical steam-operated bird he called \"The Pigeon\". Hero of Alexandria (10–70 AD), a Greek mathematician and inventor, created numerous user-configurable automated devices, and described machines powered by air pressure, steam and water.[23]\n", + "Al-Jazari – A Musical Toy\n", + "The 11th century Lokapannatti tells of how the Buddha's relics were protected by mechanical robots (bhuta vahana yanta), from the kingdom of Roma visaya (Rome); until they were disarmed by King Ashoka. [24] [25]\n", + "In ancient China, the 3rd-century text of the Lie Zi describes an account of humanoid automata, involving a much earlier encounter between Chinese emperor King Mu of Zhou and a mechanical engineer known as Yan Shi, an 'artificer'. Yan Shi proudly presented the king with a life-size, human-shaped figure of his mechanical 'handiwork' made of leather, wood, and artificial organs.[16] There are also accounts of flying automata in the Han Fei Zi and other texts, which attributes the 5th century BC Mohist philosopher Mozi and his contemporary Lu Ban with the invention of artificial wooden birds (ma yuan) that could successfully fly.[19]\n", + "Su Song's astronomical clock tower showing the mechanical figurines which chimed the hours.\n", + "In 1066, the Chinese inventor Su Song built a water clock in the form of a tower which featured mechanical figurines which chimed the hours.[26][27][28] His mechanism had a programmable drum machine with pegs (cams) that bumped into little levers that operated percussion instruments. The drummer could be made to play different rhythms and different drum patterns by moving the pegs to different locations.[28]\n", + "Samarangana Sutradhara, a Sanskrit treatise by Bhoja (11th century), includes a chapter about the construction of mechanical contrivances (automata), including mechanical bees and birds, fountains shaped like humans and animals, and male and female dolls that refilled oil lamps, danced, played instruments, and re-enacted scenes from Hindu mythology.[29][30][31]\n", + "13th century Muslim Scientist Ismail al-Jazari created several automated devices. He built automated moving peacocks driven by hydropower.[32] He also invented the earliest known automatic gates, which were driven by hydropower,[33] created automatic doors as part of one of his elaborate water clocks.[34] One of al-Jazari's humanoid automata was a waitress that could serve water, tea or drinks. The drink was stored in a tank with a reservoir from where the drink drips into a bucket and, after seven minutes, into a cup, after which the waitress appears out of an automatic door serving the drink.[35] Al-Jazari invented a hand washing automaton incorporating a flush mechanism now used in modern flush toilets. It features a female humanoid automaton standing by a basin filled with water. When the user pulls the lever, the water drains and the female automaton refills the basin.[36]\n", + "Mark E. Rosheim summarizes the advances in robotics made by Muslim engineers, especially al-Jazari, as follows:\n", + "Unlike the Greek designs, these Arab examples reveal an interest, not only in dramatic illusion, but in manipulating the environment for human comfort. Thus, the greatest contribution the Arabs made, besides preserving, disseminating and building on the work of the Greeks, was the concept of practical application. This was the key element that was missing in Greek robotic science.[37]\n", + "Model of Leonardo's robot with inner workings. Possibly constructed by Leonardo da Vinci around 1495.[38]\n", + "In Renaissance Italy, Leonardo da Vinci (1452–1519) sketched plans for a humanoid robot around 1495. Da Vinci's notebooks, rediscovered in the 1950s, contained detailed drawings of a mechanical knight now known as Leonardo's robot, able to sit up, wave its arms and move its head and jaw.[39] The design was probably based on anatomical research recorded in his Vitruvian Man. It is not known whether he attempted to build it. According to Encyclopædia Britannica, Leonardo da Vinci may have been influenced by the classic automata of al-Jazari.[32]\n", + "In Japan, complex animal and human automata were built between the 17th to 19th centuries, with many described in the 18th century Karakuri zui (Illustrated Machinery, 1796). One such automaton was the karakuri ningyō, a mechanized puppet.[40] Different variations of the karakuri existed: the Butai karakuri, which were used in theatre, the Zashiki karakuri, which were small and used in homes, and the Dashi karakuri which were used in religious festivals, where the puppets were used to perform reenactments of traditional myths and legends.\n", + "In France, between 1738 and 1739, Jacques de Vaucanson exhibited several life-sized automatons: a flute player, a pipe player and a duck. The mechanical duck could flap its wings, crane its neck, and swallow food from the exhibitor's hand, and it gave the illusion of digesting its food by excreting matter stored in a hidden compartment.[41]\n", + "Remote-controlled systems\n", + "The Brennan torpedo, one of the earliest 'guided missiles'\n", + "Remotely operated vehicles were demonstrated in the late 19th century in the form of several types of remotely controlled torpedoes. The early 1870s saw remotely controlled torpedoes by John Ericsson (pneumatic), John Louis Lay (electric wire guided), and Victor von Scheliha (electric wire guided).[42]\n", + "The Brennan torpedo, invented by Louis Brennan in 1877, was powered by two contra-rotating propellors that were spun by rapidly pulling out wires from drums wound inside the torpedo. Differential speed on the wires connected to the shore station allowed the torpedo to be guided to its target, making it \"the world's first practical guided missile\".[43] In 1897 the British inventor Ernest Wilson was granted a patent for a torpedo remotely controlled by \"Hertzian\" (radio) waves[44][45] and in 1898 Nikola Tesla publicly demonstrated a wireless-controlled torpedo that he hoped to sell to the US Navy.[46][47]\n", + "Archibald Low, known as the \"father of radio guidance systems\" for his pioneering work on guided rockets and planes during the First World War. In 1917, he demonstrated a remote controlled aircraft to the Royal Flying Corps and in the same year built the first wire-guided rocket.\n", + "Origin of the term 'robot'\n", + "'Robot' was first applied as a term for artificial automata in the 1920 play R.U.R. by the Czech writer, Karel Čapek. However, Josef Čapek was named by his brother Karel as the true inventor of the term robot.[8][9] The word 'robot' itself was not new, having been in the Slavic language as robota (forced laborer), a term which classified those peasants obligated to compulsory service under the feudal system (see: Robot Patent).[48][49] Čapek's fictional story postulated the technological creation of artificial human bodies without souls, and the old theme of the feudal robota class eloquently fit the imagination of a new class of manufactured, artificial workers.\n", + "English pronunciation of the word has evolved relatively quickly since its introduction. In the U.S. during the late '30s to early '40s the second sylable was pronounced with a long \"O\" like \"row-boat.\"[50][better source needed] By the late '50s to early '60s, some were pronouncing it with a short \"U\" like \"row-but\" while others used a softer \"O\" like \"row-bought.\"[51] By the '70s, its current pronunciation \"row-bot\" had become predominant.\n", + "Early robots\n", + "W. H. Richards with \"George\", 1932\n", + "In 1928, one of the first humanoid robots, Eric, was exhibited at the annual exhibition of the Model Engineers Society in London, where it delivered a speech. Invented by W. H. Richards, the robot's frame consisted of an aluminium body of armour with eleven electromagnets and one motor powered by a twelve-volt power source. The robot could move its hands and head and could be controlled through remote control or voice control.[52] Both Eric and his \"brother\" George toured the world.[53]\n", + "Westinghouse Electric Corporation built Televox in 1926; it was a cardboard cutout connected to various devices which users could turn on and off. In 1939, the humanoid robot known as Elektro was debuted at the 1939 New York World's Fair.[54][55] Seven feet tall (2.1 m) and weighing 265 pounds (120.2 kg), it could walk by voice command, speak about 700 words (using a 78-rpm record player), smoke cigarettes, blow up balloons, and move its head and arms. The body consisted of a steel gear, cam and motor skeleton covered by an aluminum skin. In 1928, Japan's first robot, Gakutensoku, was designed and constructed by biologist Makoto Nishimura.\n", + "Modern autonomous robots\n", + "The first electronic autonomous robots with complex behaviour were created by William Grey Walter of the Burden Neurological Institute at Bristol, England in 1948 and 1949. He wanted to prove that rich connections between a small number of brain cells could give rise to very complex behaviors – essentially that the secret of how the brain worked lay in how it was wired up. His first robots, named Elmer and Elsie, were constructed between 1948 and 1949 and were often described as tortoises due to their shape and slow rate of movement. The three-wheeled tortoise robots were capable of phototaxis, by which they could find their way to a recharging station when they ran low on battery power.\n", + "Walter stressed the importance of using purely analogue electronics to simulate brain processes at a time when his contemporaries such as Alan Turing and John von Neumann were all turning towards a view of mental processes in terms of digital computation. His work inspired subsequent generations of robotics researchers such as Rodney Brooks, Hans Moravec and Mark Tilden. Modern incarnations of Walter's turtles may be found in the form of BEAM robotics.[56]\n", + "U.S. Patent 2,988,237, issued in 1961 to Devol.\n", + "The first digitally operated and programmable robot was invented by George Devol in 1954 and was ultimately called the Unimate. This ultimately laid the foundations of the modern robotics industry.[57] Devol sold the first Unimate to General Motors in 1960, and it was installed in 1961 in a plant in Trenton, New Jersey to lift hot pieces of metal from a die casting machine and stack them.[58] Devol's patent for the first digitally operated programmable robotic arm represents the foundation of the modern robotics industry.[59]\n", + "The first palletizing robot was introduced in 1963 by the Fuji Yusoki Kogyo Company.[60] In 1973, a robot with six electromechanically driven axes was patented[61][62][63] by KUKA robotics in Germany, and the programmable universal manipulation arm was invented by Victor Scheinman in 1976, and the design was sold to Unimation.\n", + "Commercial and industrial robots are now in widespread use performing jobs more cheaply or with greater accuracy and reliability than humans. They are also employed for jobs which are too dirty, dangerous or dull to be suitable for humans. Robots are widely used in manufacturing, assembly and packing, transport, earth and space exploration, surgery, weaponry, laboratory research, and mass production of consumer and industrial goods.[64]\n", + "Future development and trends\n", + "External video\n", + "Atlas, The Next Generation\n", + "Further information: Robotics\n", + "Various techniques have emerged to develop the science of robotics and robots. One method is evolutionary robotics, in which a number of differing robots are submitted to tests. Those which perform best are used as a model to create a subsequent \"generation\" of robots. Another method is developmental robotics, which tracks changes and development within a single robot in the areas of problem-solving and other functions. Another new type of robot is just recently introduced which acts both as a smartphone and robot and is named RoboHon.[65]\n", + "As robots become more advanced, eventually there may be a standard computer operating system designed mainly for robots. Robot Operating System is an open-source set of programs being developed at Stanford University, the Massachusetts Institute of Technology and the Technical University of Munich, Germany, among others. ROS provides ways to program a robot's navigation and limbs regardless of the specific hardware involved. It also provides high-level commands for items like image recognition and even opening doors. When ROS boots up on a robot's computer, it would obtain data on attributes such as the length and movement of robots' limbs. It would relay this data to higher-level algorithms. Microsoft is also developing a \"Windows for robots\" system with its Robotics Developer Studio, which has been available since 2007.[66]\n", + "Japan hopes to have full-scale commercialization of service robots by 2025. Much technological research in Japan is led by Japanese government agencies, particularly the Trade Ministry.[67]\n", + "Many future applications of robotics seem obvious to people, even though they are well beyond the capabilities of robots available at the time of the prediction.[68][69] As early as 1982 people were confident that someday robots would:[70] 1. Clean parts by removing molding flash 2. Spray paint automobiles with absolutely no human presence 3. Pack things in boxes—for example, orient and nest chocolate candies in candy boxes 4. Make electrical cable harness 5. Load trucks with boxes—a packing problem 6. Handle soft goods, such as garments and shoes 7. Shear sheep 8. prosthesis 9. Cook fast food and work in other service industries 10. Household robot.\n", + "Generally such predictions are overly optimistic in timescale.\n", + "New functionalities and prototypes\n", + "In 2008, Caterpillar Inc. developed a dump truck which can drive itself without any human operator.[71] Many analysts believe that self-driving trucks may eventually revolutionize logistics.[72] By 2014, Caterpillar had a self-driving dump truck which is expected to greatly change the process of mining. In 2015, these Caterpillar trucks were actively used in mining operations in Australia by the mining company Rio Tinto Coal Australia.[73][74][75][76] Some analysts believe that within the next few decades, most trucks will be self-driving.[77]\n", + "A literate or 'reading robot' named Marge has intelligence that comes from software. She can read newspapers, find and correct misspelled words, learn about banks like Barclays, and understand that some restaurants are better places to eat than others.[78]\n", + "Baxter is a new robot introduced in 2012 which learns by guidance. A worker could teach Baxter how to perform a task by moving its hands in the desired motion and having Baxter memorize them. Extra dials, buttons, and controls are available on Baxter's arm for more precision and features. Any regular worker could program Baxter and it only takes a matter of minutes, unlike usual industrial robots that take extensive programs and coding in order to be used. This means Baxter needs no programming in order to operate. No software engineers are needed. This also means Baxter can be taught to perform multiple, more complicated tasks. Sawyer was added in 2015 for smaller, more precise tasks.[79]\n", + "Etymology\n", + "See also: Glossary of robotics\n", + "A scene from Karel Čapek's 1920 play R.U.R. (Rossum's Universal Robots), showing three robots\n", + "The word robot was introduced to the public by the Czech interwar writer Karel Čapek in his play R.U.R. (Rossum's Universal Robots), published in 1920.[80] The play begins in a factory that uses a chemical substitute for protoplasm to manufacture living, simplified people called robots. The play does not focus in detail on the technology behind the creation of these living creatures, but in their appearance they prefigure modern ideas of androids, creatures who can be mistaken for humans. These mass-produced workers are depicted as efficient but emotionless, incapable of original thinking and indifferent to self-preservation. At issue is whether the robots are being exploited and the consequences of human dependence upon commodified labor (especially after a number of specially-formulated robots achieve self-awareness and incite robots all around the world to rise up against the humans).\n", + "Karel Čapek himself did not coin the word. He wrote a short letter in reference to an etymology in the Oxford English Dictionary in which he named his brother, the painter and writer Josef Čapek, as its actual originator.[80]\n", + "In an article in the Czech journal Lidové noviny in 1933, he explained that he had originally wanted to call the creatures laboři (\"workers\", from Latin labor). However, he did not like the word, and sought advice from his brother Josef, who suggested \"roboti\". The word robota means literally \"corvée\", \"serf labor\", and figuratively \"drudgery\" or \"hard work\" in Czech and also (more general) \"work\", \"labor\" in many Slavic languages (e.g.: Bulgarian, Russian, Serbian, Slovak, Polish, Macedonian, Ukrainian, archaic Czech, as well as robot in Hungarian). Traditionally the robota (Hungarian robot) was the work period a serf (corvée) had to give for his lord, typically 6 months of the year. The origin of the word is the Old Church Slavonic (Old Bulgarian) rabota \"servitude\" (\"work\" in contemporary Bulgarian and Russian), which in turn comes from the Proto-Indo-European root *orbh-. Robot is cognate with the German root Arbeit (work).[81][82]\n", + "The word robotics, used to describe this field of study,[5] was coined by the science fiction writer Isaac Asimov. Asimov created the \"Three Laws of Robotics\" which are a recurring theme in his books. These have since been used by many others to define laws used in fiction. (The three laws are pure fiction, and no technology yet created has the ability to understand or follow them, and in fact most robots serve military purposes, which run quite contrary to the first law and often the third law. \"People think about Asimov's laws, but they were set up to point out how a simple ethical system doesn't work. If you read the short stories, every single one is about a failure, and they are totally impractical,\" said Dr. Joanna Bryson of the University of Bath.[83])\n", + "Modern robots\n", + "A laparoscopic robotic surgery machine\n", + "Mobile robot\n", + "Main articles: Mobile robot and Automated guided vehicle\n", + "Mobile robots[84] have the capability to move around in their environment and are not fixed to one physical location. An example of a mobile robot that is in common use today is the automated guided vehicle or automatic guided vehicle (AGV). An AGV is a mobile robot that follows markers or wires in the floor, or uses vision or lasers.[85] AGVs are discussed later in this article.\n", + "Mobile robots are also found in industry, military and security environments.[86] They also appear as consumer products, for entertainment or to perform certain tasks like vacuum cleaning. Mobile robots are the focus of a great deal of current research and almost every major university has one or more labs that focus on mobile robot research.[citation needed]\n", + "Mobile robots are usually used in tightly controlled environments such as on assembly lines because they have difficulty responding to unexpected interference. Because of this most humans rarely encounter robots. However domestic robots for cleaning and maintenance are increasingly common in and around homes in developed countries. Robots can also be found in military applications.[citation needed]\n", + "Industrial robots (manipulating)\n", + "Main articles: Industrial robot and Manipulator (device)\n", + "A pick and place robot in a factory\n", + "Industrial robots usually consist of a jointed arm (multi-linked manipulator) and an end effector that is attached to a fixed surface. One of the most common type of end effector is a gripper assembly.\n", + "The International Organization for Standardization gives a definition of a manipulating industrial robot in ISO 8373:\n", + "\"an automatically controlled, reprogrammable, multipurpose, manipulator programmable in three or more axes, which may be either fixed in place or mobile for use in industrial automation applications.\"[87]\n", + "This definition is used by the International Federation of Robotics, the European Robotics Research Network (EURON) and many national standards committees.[88]\n", + "Service robot\n", + "Main article: Service robot\n", + "Most commonly industrial robots are fixed robotic arms and manipulators used primarily for production and distribution of goods. The term \"service robot\" is less well-defined. The International Federation of Robotics has proposed a tentative definition, \"A service robot is a robot which operates semi- or fully autonomously to perform services useful to the well-being of humans and equipment, excluding manufacturing operations.\"[89]\n", + "Educational (interactive) robots\n", + "Main article: Educational robotics\n", + "Robots are used as educational assistants to teachers. From the 1980s, robots such as turtles were used in schools and programmed using the Logo language.[90][91]\n", + "There are robot kits like Lego Mindstorms, BIOLOID, OLLO from ROBOTIS, or BotBrain Educational Robots can help children to learn about mathematics, physics, programming, and electronics. Robotics have also been introduced into the lives of elementary and high school students in the form of robot competitions with the company FIRST (For Inspiration and Recognition of Science and Technology). The organization is the foundation for the FIRST Robotics Competition, FIRST LEGO League, Junior FIRST LEGO League, and FIRST Tech Challenge competitions.\n", + "There have also been robots such as the teaching computer, Leachim (1974).[92] Leachim was an early example of speech synthesis using the using the Diphone synthesis method. 2-XL (1976) was a robot shaped game / teaching toy based on branching between audible tracks on an 8-track tape player, both invented by Michael J. Freeman.[93] Later, the 8-track was upgraded to tape cassettes and then to digital.\n", + "Modular robot\n", + "Main article: Self-reconfiguring modular robot\n", + "Modular robots are a new breed of robots that are designed to increase the utilization of robots by modularizing their architecture.[94] The functionality and effectiveness of a modular robot is easier to increase compared to conventional robots. These robots are composed of a single type of identical, several different identical module types, or similarly shaped modules, which vary in size. Their architectural structure allows hyper-redundancy for modular robots, as they can be designed with more than 8 degrees of freedom (DOF). Creating the programming, inverse kinematics and dynamics for modular robots is more complex than with traditional robots. Modular robots may be composed of L-shaped modules, cubic modules, and U and H-shaped modules. ANAT technology, an early modular robotic technology patented by Robotics Design Inc., allows the creation of modular robots from U and H shaped modules that connect in a chain, and are used to form heterogeneous and homogenous modular robot systems. These \"ANAT robots\" can be designed with \"n\" DOF as each module is a complete motorized robotic system that folds relatively to the modules connected before and after it in its chain, and therefore a single module allows one degree of freedom. The more modules that are connected to one another, the more degrees of freedom it will have. L-shaped modules can also be designed in a chain, and must become increasingly smaller as the size of the chain increases, as payloads attached to the end of the chain place a greater strain on modules that are further from the base. ANAT H-shaped modules do not suffer from this problem, as their design allows a modular robot to distribute pressure and impacts evenly amongst other attached modules, and therefore payload-carrying capacity does not decrease as the length of the arm increases. Modular robots can be manually or self-reconfigured to form a different robot, that may perform different applications. Because modular robots of the same architecture type are composed of modules that compose different modular robots, a snake-arm robot can combine with another to form a dual or quadra-arm robot, or can split into several mobile robots, and mobile robots can split into multiple smaller ones, or combine with others into a larger or different one. This allows a single modular robot the ability to be fully specialized in a single task, as well as the capacity to be specialized to perform multiple different tasks.\n", + "Modular robotic technology is currently being applied in hybrid transportation,[95] industrial automation,[96] duct cleaning[97] and handling. Many research centres and universities have also studied this technology, and have developed prototypes.\n", + "Collaborative robots\n", + "A collaborative robot or cobot is a robot that can safely and effectively interact with human workers while performing simple industrial tasks. However, end-effectors and other environmental conditions may create hazards, and as such risk assessments should be done before using any industrial motion-control application.[98]\n", + "The collaborative robots most widely used in industries today are manufactured by Universal Robots in Denmark.[99]\n", + "Rethink Robotics—founded by Rodney Brooks, previously with iRobot—introduced Baxter in September 2012; as an industrial robot designed to safely interact with neighboring human workers, and be programmable for performing simple tasks.[100] Baxters stop if they detect a human in the way of their robotic arms and have prominent off switches. Intended for sale to small businesses, they are promoted as the robotic analogue of the personal computer.[101] As of May 2014, 190 companies in the US have bought Baxters and they are being used commercially in the UK.[12]\n", + "Robots in society\n", + "TOPIO, a humanoid robot, played ping pong at Tokyo International Robot Exhibition (IREX) 2009[102][103]\n", + "Roughly half of all the robots in the world are in Asia, 32% in Europe, and 16% in North America, 1% in Australasia and 1% in Africa.[104] 40% of all the robots in the world are in Japan,[105] making Japan the country with the highest number of robots.\n", + "Autonomy and ethical questions\n", + "Main articles: Roboethics and Ethics of artificial intelligence\n", + "An android, or robot designed to resemble a human, can appear comforting to some people and disturbing to others[106]\n", + "As robots have become more advanced and sophisticated, experts and academics have increasingly explored the questions of what ethics might govern robots' behavior,[107] and whether robots might be able to claim any kind of social, cultural, ethical or legal rights.[108] One scientific team has said that it is possible that a robot brain will exist by 2019.[109] Others predict robot intelligence breakthroughs by 2050.[110] Recent advances have made robotic behavior more sophisticated.[111] The social impact of intelligent robots is subject of a 2010 documentary film called Plug & Pray.[112]\n", + "Vernor Vinge has suggested that a moment may come when computers and robots are smarter than humans. He calls this \"the Singularity\".[113] He suggests that it may be somewhat or possibly very dangerous for humans.[114] This is discussed by a philosophy called Singularitarianism.\n", + "In 2009, experts attended a conference hosted by the Association for the Advancement of Artificial Intelligence (AAAI) to discuss whether computers and robots might be able to acquire any autonomy, and how much these abilities might pose a threat or hazard. They noted that some robots have acquired various forms of semi-autonomy, including being able to find power sources on their own and being able to independently choose targets to attack with weapons. They also noted that some computer viruses can evade elimination and have achieved \"cockroach intelligence.\" They noted that self-awareness as depicted in science-fiction is probably unlikely, but that there were other potential hazards and pitfalls.[113] Various media sources and scientific groups have noted separate trends in differing areas which might together result in greater robotic functionalities and autonomy, and which pose some inherent concerns.[115][116][117] In 2015, the Nao alderen robots were shown to have a capability for a degree of self-awareness. Researchers at the Rensselaer Polytechnic Institute AI and Reasoning Lab in New York conducted an experiment where a robot became aware of itself, and corrected its answer to a question once it had realised this.[118]\n", + "Military robots\n", + "Some experts and academics have questioned the use of robots for military combat, especially when such robots are given some degree of autonomous functions.[119] There are also concerns about technology which might allow some armed robots to be controlled mainly by other robots.[120] The US Navy has funded a report which indicates that, as military robots become more complex, there should be greater attention to implications of their ability to make autonomous decisions.[121][122] One researcher states that autonomous robots might be more humane, as they could make decisions more effectively. However, other experts question this.[123]\n", + "One robot in particular, the EATR, has generated public concerns[124] over its fuel source, as it can continually refuel itself using organic substances.[125] Although the engine for the EATR is designed to run on biomass and vegetation[126] specifically selected by its sensors, which it can find on battlefields or other local environments, the project has stated that chicken fat can also be used.[127]\n", + "Manuel De Landa has noted that \"smart missiles\" and autonomous bombs equipped with artificial perception can be considered robots, as they make some of their decisions autonomously. He believes this represents an important and dangerous trend in which humans are handing over important decisions to machines.[128]\n", + "Relationship to unemployment\n", + "Main article: Technological unemployment\n", + "For centuries, people have predicted that machines would make workers obsolete and increase unemployment, although the causes of unemployment are usually thought to be due to social policy.[129]\n", + "A recent example of human replacement involves Taiwanese technology company Foxconn who, in July 2011, announced a three-year plan to replace workers with more robots. At present the company uses ten thousand robots but will increase them to a million robots over a three-year period.[130]\n", + "Lawyers have speculated that an increased prevalence of robots in the workplace could lead to the need to improve redundancy laws.[131]\n", + "Kevin J. Delaney said \"Robots are taking human jobs. But Bill Gates believes that governments should tax companies’ use of them, as a way to at least temporarily slow the spread of automation and to fund other types of employment.\"[132] The robot tax would also help pay a guaranteed living wage to the displaced workers.\n", + "The World Bank's World Development Report 2019 puts forth evidence showing that while automation displaces workers, technological innovation creates more new industries and jobs on balance.[133]\n", + "Contemporary uses\n", + "A general-purpose robot acts as a guide during the day and a security guard at night.\n", + "See also: List of robots\n", + "At present, there are two main types of robots, based on their use: general-purpose autonomous robots and dedicated robots.\n", + "Robots can be classified by their specificity of purpose. A robot might be designed to perform one particular task extremely well, or a range of tasks less well. All robots by their nature can be re-programmed to behave differently, but some are limited by their physical form. For example, a factory robot arm can perform jobs such as cutting, welding, gluing, or acting as a fairground ride, while a pick-and-place robot can only populate printed circuit boards.\n", + "General-purpose autonomous robots\n", + "Main article: Autonomous robot\n", + "General-purpose autonomous robots can perform a variety of functions independently. General-purpose autonomous robots typically can navigate independently in known spaces, handle their own re-charging needs, interface with electronic doors and elevators and perform other basic tasks. Like computers, general-purpose robots can link with networks, software and accessories that increase their usefulness. They may recognize people or objects, talk, provide companionship, monitor environmental quality, respond to alarms, pick up supplies and perform other useful tasks. General-purpose robots may perform a variety of functions simultaneously or they may take on different roles at different times of day. Some such robots try to mimic human beings and may even resemble people in appearance; this type of robot is called a humanoid robot. Humanoid robots are still in a very limited stage, as no humanoid robot can, as of yet, actually navigate around a room that it has never been in.[citation needed] Thus, humanoid robots are really quite limited, despite their intelligent behaviors in their well-known environments.\n", + "Factory robots\n", + "Car production\n", + "Over the last three decades, automobile factories have become dominated by robots. A typical factory contains hundreds of industrial robots working on fully automated production lines, with one robot for every ten human workers. On an automated production line, a vehicle chassis on a conveyor is welded, glued, painted and finally assembled at a sequence of robot stations.\n", + "Packaging\n", + "Industrial robots are also used extensively for palletizing and packaging of manufactured goods, for example for rapidly taking drink cartons from the end of a conveyor belt and placing them into boxes, or for loading and unloading machining centers.\n", + "Electronics\n", + "Mass-produced printed circuit boards (PCBs) are almost exclusively manufactured by pick-and-place robots, typically with SCARA manipulators, which remove tiny electronic components from strips or trays, and place them on to PCBs with great accuracy.[134] Such robots can place hundreds of thousands of components per hour, far out-performing a human in speed, accuracy, and reliability.[135]\n", + "Automated guided vehicles (AGVs)\n", + "An intelligent AGV drops-off goods without needing lines or beacons in the workspace.\n", + "Mobile robots, following markers or wires in the floor, or using vision[85] or lasers, are used to transport goods around large facilities, such as warehouses, container ports, or hospitals.[136]\n", + "Early AGV-style robots\n", + "Limited to tasks that could be accurately defined and had to be performed the same way every time. Very little feedback or intelligence was required, and the robots needed only the most basic exteroceptors (sensors). The limitations of these AGVs are that their paths are not easily altered and they cannot alter their paths if obstacles block them. If one AGV breaks down, it may stop the entire operation.\n", + "Interim AGV technologies\n", + "Developed to deploy triangulation from beacons or bar code grids for scanning on the floor or ceiling. In most factories, triangulation systems tend to require moderate to high maintenance, such as daily cleaning of all beacons or bar codes. Also, if a tall pallet or large vehicle blocks beacons or a bar code is marred, AGVs may become lost. Often such AGVs are designed to be used in human-free environments.\n", + "Intelligent AGVs (i-AGVs)\n", + "Such as SmartLoader,[137] SpeciMinder,[138] ADAM,[139] Tug[140] Eskorta,[141] and MT 400 with Motivity[142] are designed for people-friendly workspaces. They navigate by recognizing natural features. 3D scanners or other means of sensing the environment in two or three dimensions help to eliminate cumulative errors in dead-reckoning calculations of the AGV's current position. Some AGVs can create maps of their environment using scanning lasers with simultaneous localization and mapping (SLAM) and use those maps to navigate in real time with other path planning and obstacle avoidance algorithms. They are able to operate in complex environments and perform non-repetitive and non-sequential tasks such as transporting photomasks in a semiconductor lab, specimens in hospitals and goods in warehouses. For dynamic areas, such as warehouses full of pallets, AGVs require additional strategies using three-dimensional sensors such as time-of-flight or stereovision cameras.\n", + "Dirty, dangerous, dull or inaccessible tasks\n", + "See also: Dirty, dangerous and demeaning\n", + "There are many jobs which humans would rather leave to robots. The job may be boring, such as domestic cleaning or sports field line marking, or dangerous, such as exploring inside a volcano.[143] Other jobs are physically inaccessible, such as exploring another planet,[144] cleaning the inside of a long pipe, or performing laparoscopic surgery.[145]\n", + "Space probes\n", + "Almost every unmanned space probe ever launched was a robot.[146][147] Some were launched in the 1960s with very limited abilities, but their ability to fly and land (in the case of Luna 9) is an indication of their status as a robot. This includes the Voyager probes and the Galileo probes, among others.\n", + "Telerobots\n", + "A U.S. Marine Corps technician prepares to use a telerobot to detonate a buried improvised explosive device near Camp Fallujah, Iraq.\n", + "Teleoperated robots, or telerobots, are devices remotely operated from a distance by a human operator rather than following a predetermined sequence of movements, but which has semi-autonomous behaviour. They are used when a human cannot be present on site to perform a job because it is dangerous, far away, or inaccessible. The robot may be in another room or another country, or may be on a very different scale to the operator. For instance, a laparoscopic surgery robot allows the surgeon to work inside a human patient on a relatively small scale compared to open surgery, significantly shortening recovery time.[145] They can also be used to avoid exposing workers to the hazardous and tight spaces such as in duct cleaning. When disabling a bomb, the operator sends a small robot to disable it. Several authors have been using a device called the Longpen to sign books remotely.[148] Teleoperated robot aircraft, like the Predator Unmanned Aerial Vehicle, are increasingly being used by the military. These pilotless drones can search terrain and fire on targets.[149][150] Hundreds of robots such as iRobot's Packbot and the Foster-Miller TALON are being used in Iraq and Afghanistan by the U.S. military to defuse roadside bombs or improvised explosive devices (IEDs) in an activity known as explosive ordnance disposal (EOD).[151]\n", + "Automated fruit harvesting machines\n", + "Robots are used to automate picking fruit on orchards at a cost lower than that of human pickers.\n", + "Domestic robots\n", + "The Roomba domestic vacuum cleaner robot does a single, menial job\n", + "Domestic robots are simple robots dedicated to a single task work in home use. They are used in simple but often disliked jobs, such as vacuum cleaning, floor washing, and lawn mowing. An example of a domestic robot is a Roomba.\n", + "Military robots\n", + "Main article: Military robot\n", + "Military robots include the SWORDS robot which is currently used in ground-based combat. It can use a variety of weapons and there is some discussion of giving it some degree of autonomy in battleground situations.[152][153][154]\n", + "Unmanned combat air vehicles (UCAVs), which are an upgraded form of UAVs, can do a wide variety of missions, including combat. UCAVs are being designed such as the BAE Systems Mantis which would have the ability to fly themselves, to pick their own course and target, and to make most decisions on their own.[155] The BAE Taranis is a UCAV built by Great Britain which can fly across continents without a pilot and has new means to avoid detection.[156] Flight trials are expected to begin in 2011.[157]\n", + "The AAAI has studied this topic in depth[107] and its president has commissioned a study to look at this issue.[158]\n", + "Some have suggested a need to build \"Friendly AI\", meaning that the advances which are already occurring with AI should also include an effort to make AI intrinsically friendly and humane.[159] Several such measures reportedly already exist, with robot-heavy countries such as Japan and South Korea[160] having begun to pass regulations requiring robots to be equipped with safety systems, and possibly sets of 'laws' akin to Asimov's Three Laws of Robotics.[161][162] An official report was issued in 2009 by the Japanese government's Robot Industry Policy Committee.[163] Chinese officials and researchers have issued a report suggesting a set of ethical rules, and a set of new legal guidelines referred to as \"Robot Legal Studies.\"[164] Some concern has been expressed over a possible occurrence of robots telling apparent falsehoods.[165]\n", + "Mining robots\n", + "Mining robots are designed to solve a number of problems currently facing the mining industry, including skills shortages, improving productivity from declining ore grades, and achieving environmental targets. Due to the hazardous nature of mining, in particular underground mining, the prevalence of autonomous, semi-autonomous, and tele-operated robots has greatly increased in recent times. A number of vehicle manufacturers provide autonomous trains, trucks and loaders that will load material, transport it on the mine site to its destination, and unload without requiring human intervention. One of the world's largest mining corporations, Rio Tinto, has recently expanded its autonomous truck fleet to the world's largest, consisting of 150 autonomous Komatsu trucks, operating in Western Australia.[166] Similarly, BHP has announced the expansion of its autonomous drill fleet to the world's largest, 21 autonomous Atlas Copco drills.[167]\n", + "Drilling, longwall and rockbreaking machines are now also available as autonomous robots.[168] The Atlas Copco Rig Control System can autonomously execute a drilling plan on a drilling rig, moving the rig into position using GPS, set up the drill rig and drill down to specified depths.[169] Similarly, the Transmin Rocklogic system can automatically plan a path to position a rockbreaker at a selected destination.[170] These systems greatly enhance the safety and efficiency of mining operations.\n", + "Healthcare\n", + "Robots in healthcare have two main functions. Those which assist an individual, such as a sufferer of a disease like Multiple Sclerosis, and those which aid in the overall systems such as pharmacies and hospitals.\n", + "Home automation for the elderly and disabled\n", + "Further information: Disability robot\n", + "The Care-Providing Robot FRIEND\n", + "Robots used in home automation have developed over time from simple basic robotic assistants, such as the Handy 1,[171] through to semi-autonomous robots, such as FRIEND which can assist the elderly and disabled with common tasks.\n", + "The population is aging in many countries, especially Japan, meaning that there are increasing numbers of elderly people to care for, but relatively fewer young people to care for them.[172][173] Humans make the best carers, but where they are unavailable, robots are gradually being introduced.[174]\n", + "FRIEND is a semi-autonomous robot designed to support disabled and elderly people in their daily life activities, like preparing and serving a meal. FRIEND make it possible for patients who are paraplegic, have muscle diseases or serious paralysis (due to strokes etc.), to perform tasks without help from other people like therapists or nursing staff.\n", + "Pharmacies\n", + "Main article: Pharmacy automation\n", + "This section does not cite any sources. Please help improve this section by adding citations to reliable sources. Unsourced material may be challenged and removed.\n", + "Find sources: \"Robot\" – news · newspapers · books · scholar · JSTOR (July 2009) (Learn how and when to remove this template message)\n", + "Script Pro manufactures a robot designed to help pharmacies fill prescriptions that consist of oral solids or medications in pill form.[175][better source needed] The pharmacist or pharmacy technician enters the prescription information into its information system. The system, upon determining whether or not the drug is in the robot, will send the information to the robot for filling. The robot has 3 different size vials to fill determined by the size of the pill. The robot technician, user, or pharmacist determines the needed size of the vial based on the tablet when the robot is stocked. Once the vial is filled it is brought up to a conveyor belt that delivers it to a holder that spins the vial and attaches the patient label. Afterwards it is set on another conveyor that delivers the patient's medication vial to a slot labeled with the patient's name on an LED read out. The pharmacist or technician then checks the contents of the vial to ensure it's the correct drug for the correct patient and then seals the vials and sends it out front to be picked up.\n", + "McKesson's Robot RX is another healthcare robotics product that helps pharmacies dispense thousands of medications daily with little or no errors.[176] The robot can be ten feet wide and thirty feet long and can hold hundreds of different kinds of medications and thousands of doses. The pharmacy saves many resources like staff members that are otherwise unavailable in a resource scarce industry. It uses an electromechanical head coupled with a pneumatic system to capture each dose and deliver it to its either stocked or dispensed location. The head moves along a single axis while it rotates 180 degrees to pull the medications. During this process it uses barcode technology to verify its pulling the correct drug. It then delivers the drug to a patient specific bin on a conveyor belt. Once the bin is filled with all of the drugs that a particular patient needs and that the robot stocks, the bin is then released and returned out on the conveyor belt to a technician waiting to load it into a cart for delivery to the floor.\n", + "Research robots\n", + "See also: Robotics research\n", + "While most robots today are installed in factories or homes, performing labour or life saving jobs, many new types of robot are being developed in laboratories around the world. Much of the research in robotics focuses not on specific industrial tasks, but on investigations into new types of robot, alternative ways to think about or design robots, and new ways to manufacture them. It is expected that these new types of robot will be able to solve real world problems when they are finally realized.[citation needed]\n", + "Bionic and biomimetic robots\n", + "Further information: Bionics\n", + "Further information: Biomimetics\n", + "One approach to designing robots is to base them on animals. BionicKangaroo was designed and engineered by studying and applying the physiology and methods of locomotion of a kangaroo.\n", + "Nanorobots\n", + "Further information: Nanorobotics\n", + "A microfabricated electrostatic gripper holding some silicon nanowires.[177]\n", + "Nanorobotics is the emerging technology field of creating machines or robots whose components are at or close to the microscopic scale of a nanometer (10−9 meters). Also known as \"nanobots\" or \"nanites\", they would be constructed from molecular machines. So far, researchers have mostly produced only parts of these complex systems, such as bearings, sensors, and synthetic molecular motors, but functioning robots have also been made such as the entrants to the Nanobot Robocup contest.[178] Researchers also hope to be able to create entire robots as small as viruses or bacteria, which could perform tasks on a tiny scale. Possible applications include micro surgery (on the level of individual cells), utility fog,[179] manufacturing, weaponry and cleaning.[180] Some people have suggested that if there were nanobots which could reproduce, the earth would turn into \"grey goo\", while others argue that this hypothetical outcome is nonsense.[181][182]\n", + "Reconfigurable robots\n", + "Main article: Self-reconfiguring modular robot\n", + "A few researchers have investigated the possibility of creating robots which can alter their physical form to suit a particular task,[183] like the fictional T-1000. Real robots are nowhere near that sophisticated however, and mostly consist of a small number of cube shaped units, which can move relative to their neighbours. Algorithms have been designed in case any such robots become a reality.[184]\n", + "Soft-bodied robots\n", + "Robots with silicone bodies and flexible actuators (air muscles, electroactive polymers, and ferrofluids) look and feel different from robots with rigid skeletons, and can have different behaviors.[185] Soft, flexible (and sometimes even squishy) robots are often designed to mimic the biomechanics of animals and other things found in nature, which is leading to new applications in medicine, care giving, search and rescue, food handling and manufacturing, and scientific exploration.[186][187]\n", + "Swarm robots\n", + "Main article: Swarm robotics\n", + "A swarm of robots from the open-source micro-robotic project\n", + "Inspired by colonies of insects such as ants and bees, researchers are modeling the behavior of swarms of thousands of tiny robots which together perform a useful task, such as finding something hidden, cleaning, or spying. Each robot is quite simple, but the emergent behavior of the swarm is more complex. The whole set of robots can be considered as one single distributed system, in the same way an ant colony can be considered a superorganism, exhibiting swarm intelligence. The largest swarms so far created include the iRobot swarm, the SRI/MobileRobots CentiBots project[188] and the Open-source Micro-robotic Project swarm, which are being used to research collective behaviors.[189][190] Swarms are also more resistant to failure. Whereas one large robot may fail and ruin a mission, a swarm can continue even if several robots fail. This could make them attractive for space exploration missions, where failure is normally extremely costly.[191]\n", + "Haptic interface robots\n", + "Further information: Haptic technology\n", + "Robotics also has application in the design of virtual reality interfaces. Specialized robots are in widespread use in the haptic research community. These robots, called \"haptic interfaces\", allow touch-enabled user interaction with real and virtual environments. Robotic forces allow simulating the mechanical properties of \"virtual\" objects, which users can experience through their sense of touch.[192]\n", + "Robots in popular culture\n", + "Toy robots on display at the Museo del Objeto del Objeto in Mexico City.\n", + "See also: List of fictional robots and androids and Droid (Star Wars)\n", + "Literature\n", + "Main article: Robots in literature\n", + "Robotic characters, androids (artificial men/women) or gynoids (artificial women), and cyborgs (also \"bionic men/women\", or humans with significant mechanical enhancements) have become a staple of science fiction.\n", + "The first reference in Western literature to mechanical servants appears in Homer's Iliad. In Book XVIII, Hephaestus, god of fire, creates new armor for the hero Achilles, assisted by robots.[193] According to the Rieu translation, \"Golden maidservants hastened to help their master. They looked like real women and could not only speak and use their limbs but were endowed with intelligence and trained in handwork by the immortal gods.\" The words \"robot\" or \"android\" are not used to describe them, but they are nevertheless mechanical devices human in appearance. \"The first use of the word Robot was in Karel Čapek's play R.U.R. (Rossum's Universal Robots) (written in 1920)\". Writer Karel Čapek was born in Czechoslovakia (Czech Republic).\n", + "Possibly the most prolific author of the twentieth century was Isaac Asimov (1920–1992)[194] who published over five-hundred books.[195] Asimov is probably best remembered for his science-fiction stories and especially those about robots, where he placed robots and their interaction with society at the center of many of his works.[196][197] Asimov carefully considered the problem of the ideal set of instructions robots might be given in order to lower the risk to humans, and arrived at his Three Laws of Robotics: a robot may not injure a human being or, through inaction, allow a human being to come to harm; a robot must obey orders given it by human beings, except where such orders would conflict with the First Law; and a robot must protect its own existence as long as such protection does not conflict with the First or Second Law.[198] These were introduced in his 1942 short story \"Runaround\", although foreshadowed in a few earlier stories. Later, Asimov added the Zeroth Law: \"A robot may not harm humanity, or, by inaction, allow humanity to come to harm\"; the rest of the laws are modified sequentially to acknowledge this.\n", + "According to the Oxford English Dictionary, the first passage in Asimov's short story \"Liar!\" (1941) that mentions the First Law is the earliest recorded use of the word robotics. Asimov was not initially aware of this; he assumed the word already existed by analogy with mechanics, hydraulics, and other similar terms denoting branches of applied knowledge.[199]\n", + "Films\n", + "See also: Category:Robot films\n", + "Robots appear in many films. Most of the robots in cinema are fictional. Two of the most famous are R2-D2 and C-3PO from the Star Wars franchise.\n", + "Sex robots\n", + "Main article: Sex robot\n", + "The concept of humanoid sex robots has elicited both public attention and concern. Opponents of the concept have stated that the development of sex robots would be morally wrong.[200][201][202][203] They argue that the introduction of such devices would be socially harmful, and demeaning to women and children.[201]\n", + "Problems depicted in popular culture\n", + "Italian movie The Mechanical Man (1921), the first film to have shown a battle between robots.\n", + "Fears and concerns about robots have been repeatedly expressed in a wide range of books and films. A common theme is the development of a master race of conscious and highly intelligent robots, motivated to take over or destroy the human race. Frankenstein (1818), often called the first science fiction novel, has become synonymous with the theme of a robot or android advancing beyond its creator.\n", + "Other works with similar themes include The Mechanical Man, The Terminator, Runaway, RoboCop, the Replicators in Stargate, the Cylons in Battlestar Galactica, the Cybermen and Daleks in Doctor Who, The Matrix, Enthiran and I, Robot. Some fictional robots are programmed to kill and destroy; others gain superhuman intelligence and abilities by upgrading their own software and hardware. Examples of popular media where the robot becomes evil are 2001: A Space Odyssey, Red Planet and Enthiran.\n", + "The 2017 game Horizon Zero Dawn explores themes of robotics in warfare, robot ethics, and the AI control problem, as well as the positive or negative impact such technologies could have on the environment.\n", + "Another common theme is the reaction, sometimes called the \"uncanny valley\", of unease and even revulsion at the sight of robots that mimic humans too closely.[106]\n", + "More recently, fictional representations of artificially intelligent robots in films such as A.I. Artificial Intelligence and Ex Machina and the 2016 TV adaptation of Westworld have engaged audience sympathy for the robots themselves.\n", + "See also\n", + "Index of robotics articles\n", + "Outline of robotics\n", + "Artificial intelligence\n", + "William Grey Walter\n", + "Specific robotics concepts\n", + "Robot locomotion\n", + "Simultaneous localization and mapping\n", + "Tactile sensor\n", + "Teleoperation\n", + "Uncanny valley\n", + "von Neumann machine\n", + "Wake-up robot problem\n", + "Neuromorphic engineering\n", + "Robotics methods and categories\n", + "Cognitive robotics\n", + "Companion robot\n", + "Domestic robot\n", + "Epigenetic robotics\n", + "Evolutionary robotics\n", + "Humanoid robot\n", + "Autonomous robot\n", + "Microbotics\n", + "Robot control\n", + "Specific robots and devices\n", + "AIBO\n", + "Autonomous spaceport drone ship\n", + "Driverless car\n", + "Friendly Robotics\n", + "Lely Juno family\n", + "Liquid handling robot\n", + "PatrolBot\n", + "RoboBee\n", + "Robot App Store\n", + "Other related articles\n", + "Unmanned vehicle\n", + "Remote control vehicle\n", + "Automated guided vehicle\n", + "References\n", + "^ \"Four-legged Robot, 'Cheetah,' Sets New Speed Record\". Reuters. 2012-03-06. Archived from the original on 2013-10-22. Retrieved 2013-10-05.\n", + "^ Definition of 'robot'. Oxford English Dictionary. Retrieved November 27, 2016.\n", + "^ https://www.conres.com/it-products-solutions/news-events/top-10-tech-trends-autonomous-agents-things/ Archived 2017-04-19 at the Wayback Machine retrieved April 18, 2017\n", + "^ \"Forecasts - Driverless car market watch\". www.driverless-future.com. Archived from the original on 2017-04-19. Retrieved 2017-04-18.\n", + "^\n", + "a b \"robotics\". Oxford Dictionaries. Archived from the original on 18 May 2011. Retrieved 4 February 2011.\n", + "^ Other Slavic languages also use this stem in similar meaning, eg. Eastern Slavic Belarusian & Russian рабыня (rabynya), Ukrainian раб (rab) & Southern Slavic Bosnian, Bulgarian, Croatian, Macedonian, Serbian Роб (rob). Czech is a Western Slavic language, as is Slovak. Robota, in Slovak, is used to just mean work.\n", + "^ Ivan Margolius,'The Robot of Prague', Newsletter, The Friends of Czech Heritage no. 17, Autumn 2017, pp. 3 - 6. https://czechfriends.net/images/RobotsMargoliusJul2017.pdf Archived 2017-09-11 at the Wayback Machine\n", + "^\n", + "a b Karel Capek – Who did actually invent the word \"robot\" and what does it mean? at capek.misto.cz[dead link] – archive\n", + "^\n", + "a b Kurfess, Thomas R. (1 January 2005). Robotics and Automation Handbook. Taylor & Francis. ISBN 9780849318047. Archived from the original on 4 December 2016. Retrieved 5 July 2016 – via Google Books.\n", + "^ Pearce, Jeremy. \"George C. Devol, Inventor of Robot Arm, Dies at 99\" Archived 2016-12-25 at the Wayback Machine, The New York Times, August 15, 2011. Retrieved February 7, 2012. \"In 1961, General Motors put the first Unimate arm on an assembly line at the company's plant in Ewing Township, N.J., a suburb of Trenton. The device was used to lift and stack die-cast metal parts taken hot from their molds.\"\n", + "^ Akins, Crystal. \"5 jobs being replaced by robots\". Excelle. Monster. Archived from the original on 2013-04-24. Retrieved 2013-04-15.\n", + "^\n", + "a b Hoy, Greg (28 May 2014). \"Robots could cost Australian economy 5 million jobs, experts warn, as companies look to cut costs\". ABC News. Australian Broadcasting Corporation. Archived from the original on 29 May 2014. Retrieved 29 May 2014.\n", + "^ \"Telecom glossary \"bot\"\". Alliance for Telecommunications Solutions. 2001-02-28. Archived from the original on 2007-02-02. Retrieved 2007-09-05.\n", + "^ Polk, Igor (2005-11-16). \"RoboNexus 2005 robot exhibition virtual tour\". Robonexus Exhibition 2005. Archived from the original on 2007-08-12. Retrieved 2007-09-10.\n", + "^ Harris, Tom (2002-04-16). \"How Robots Work\". How Stuff Works. Archived from the original on 2007-08-26. Retrieved 2007-09-10.\n", + "^\n", + "a b c Needham, Joseph (1991). Science and Civilisation in China: Volume 2, History of Scientific Thought. Cambridge University Press. ISBN 978-0-521-05800-1.\n", + "^ Currie, Adam (1999). \"The History of Robotics\". Archived from the original on 18 July 2006. Retrieved 2007-09-10.\n", + "^ Noct. Att. L. 10\n", + "^\n", + "a b Needham, Volume 2, 54.\n", + "^ Deborah Levine Gera (2003). Ancient Greek Ideas on Speech, Language, and Civilization. Oxford University Press. ISBN 978-0-19-925616-7. Archived from the original on 2016-12-05. Retrieved 2016-09-25.\n", + "^ Mark E. Rosheim (1994). \"Robot evolution: the development of anthrobotics Archived 2016-12-05 at the Wayback Machine\". p.2. Wiley-IEEE. ISBN 0-471-02622-0\n", + "^ \"Robots then and now Archived 2010-12-20 at the Wayback Machine\". BBC.\n", + "^ O'Connor, J.J. and E.F. Robertson. \"Heron biography\". The MacTutor History of Mathematics archive. Archived from the original on 2008-06-24. Retrieved 2008-09-05.\n", + "^ Strong 2007, p. 143.\n", + "^ Strong 2007, p. 133-134.\n", + "^ Fowler, Charles B. (October 1967). \"The Museum of Music: A History of Mechanical Instruments\". Music Educators Journal. 54 (2): 45–49. doi:10.2307/3391092. JSTOR 3391092.\n", + "^ \"Earliest Clocks\". A Walk Through Time. NIST Physics Laboratory. Archived from the original on 2008-05-31. Retrieved 2008-08-11.\n", + "^\n", + "a b \"The programmable robot of ancient Greece\". New Scientist: 32–35. July 6, 2007.\n", + "^ Varadpande, Manohar Laxman (1987). History of Indian Theatre, Volume 1. p. 68. ISBN 9788170172215.\n", + "^ Wujastyk, Dominik (2003). The Roots of Ayurveda: Selections from Sanskrit Medical Writings. p. 222. ISBN 9780140448245.\n", + "^ Needham, Joseph (1965). Science and Civilisation in China: Volume 4, Physics and Physical Technology Part 2, Mechanical Engineering. p. 164. ISBN 9780521058032.\n", + "^\n", + "a b \"Al-Jazarī | Arab inventor\". Encyclopedia Britannica. Retrieved 2019-06-15.\n", + "^ Howard R. Turner (1997), Science in Medieval Islam: An Illustrated Introduction, p. 81, University of Texas Press, ISBN 0-292-78149-0\n", + "^ Donald Hill, \"Mechanical Engineering in the Medieval Near East\", Scientific American, May 1991, pp. 64-9 (cf. Donald Hill, Mechanical Engineering Archived 25 December 2007 at the Wayback Machine)\n", + "^ Ancient Discoveries Islamic Science Part1, retrieved 2019-06-15\n", + "^ Rosheim, Mark E. (1994). Robot Evolution: The Development of Anthrobotics. John Wiley & Sons. ISBN 978-0-471-02622-8.\n", + "^ Rosheim, Mark E. (1994), Robot Evolution: The Development of Anthrobotics, Wiley-IEEE, p. 9, ISBN 0-471-02622-0[verification needed]\n", + "^ Moran, M. E. (December 2006). \"The da Vinci robot\". J. Endourol. 20 (12): 986–90. doi:10.1089/end.2006.20.986. PMID 17206888. ... the date of the design and possible construction of this robot was 1495 ... Beginning in the 1950s, investigators at the University of California began to ponder the significance of some of da Vinci's markings on what appeared to be technical drawings ... It is now known that da Vinci's robot would have had the outer appearance of a Germanic knight.\n", + "^ \"Leonardo da Vinci's Robots\". Leonardo3.net. Archived from the original on 2008-09-24. Retrieved 2008-09-25.\n", + "^ Jane Marie Law, Puppets of Nostalgia – The Life, Death and Rebirth of the Japanese Awaji Ningyo Tradition, 1997, Princeton University Press, ISBN 978-0-691-02894-1\n", + "^ Wood, Gabby. \"Living Dolls: A Magical History Of The Quest For Mechanical Life\" Archived 2016-12-20 at the Wayback Machine, The Guardian, 2002-02-16.\n", + "^ Edwyn Gray, Nineteenth-century torpedoes and their inventors, page 18\n", + "^ Gray, Edwyn (2004). Nineteenth-Century Torpedoes and Their Inventors. Naval Institute Press. ISBN 978-1-59114-341-3.\n", + "^ Marc Seifer Life and Times of Nikola Tesla, page 1893 google books Archived 2016-12-05 at the Wayback Machine\n", + "^ Benjamin Franklin Miessner, Radiodynamics: The Wireless Control of Torpedoes and Other Mechanisms, D. Van Nostrand Company, 1916, page 83\n", + "^ US 613809\n", + "^ \"Tesla – Master of Lightning\". PBS.org. Archived from the original on 2008-09-28. Retrieved 2008-09-24.\n", + "^ \"Merriam-Webster Dictionary: robot\". Archived from the original on 2017-03-07. Retrieved 2017-03-06. Origin: Czech, from robota, compulsory labor\n", + "^ \"Science Diction: The Origin Of The Word 'Robot'\". Archived from the original on 2018-04-17. Retrieved 2018-04-05.\n", + "^ \"Hank Green's First Novel Is An Absolutely Remarkable Thing\". Indianapolis Monthly. 2018-10-01. Retrieved 2019-11-20.\n", + "^ \"You Are Pronouncing the Word \"Robot\" Wrong\". Daily Kos. Retrieved 2019-11-20.\n", + "^ \"AH Reffell & Eric Robot (1928)\". Archived from the original on 2013-11-11. Retrieved 2013-11-11.\n", + "^ \"Meet Mr. Robot – Not Forgetting His Master\". The Age. 20 September 1935. Archived from the original on 2017-03-07. Retrieved 7 March 2017.\n", + "^ \"Robot Dreams : The Strange Tale Of A Man's Quest To Rebuild His Mechanical Childhood Friend\". The Cleveland Free Times. Archived from the original on 15 January 2010. Retrieved 2008-09-25.\n", + "^ Scott Schaut (2006). Robots of Westinghouse: 1924-Today. Mansfield Memorial Museum. ISBN 978-0-9785844-1-2.\n", + "^ Owen Holland. \"The Grey Walter Online Archive\". Archived from the original on 2008-10-09. Retrieved 2008-09-25.\n", + "^ Waurzyniak, Patrick (July 2006). \"Masters of Manufacturing: Joseph F. Engelberger\". Society of Manufacturing Engineers. 137 (1). Archived from the original on 9 November 2011. Retrieved 2008-09-25.\n", + "^ \"Robot Hall of Fame – Unimate\". Carnegie Mellon University. Archived from the original on 26 September 2011. Retrieved 2008-08-28.\n", + "^ \"National Inventor's Hall of Fame 2011 Inductee\". Invent Now. Archived from the original on 2014-11-04. Retrieved 2011-03-18.\n", + "^ \"Company History\". Fuji Yusoki Kogyo Co. Archived from the original on 4 February 2013. Retrieved 2008-09-12.\n", + "^ \"KUKA Industrial Robot FAMULUS\". Archived from the original on June 10, 2013. Retrieved 2008-01-10.\n", + "^ \"History of Industrial Robots\" (PDF). Archived from the original (PDF) on 2012-12-24. Retrieved 2012-10-27.\n", + "^ \"History of Industrial Robots\". robots.com. Archived from the original on 8 July 2015. Retrieved 24 August 2015.\n", + "^ \"About us\". Archived from the original on 2014-01-09.\n", + "^ \"Archived copy\". Archived from the original on 2015-10-07. Retrieved 2015-10-06.\n", + "^ Robots to get their own operating system, by Mehret Tesfaye Ethipian Review, August 13, 2009.\n", + "^ Research and Development for Next-generation Service Robots in Japan, United Kingdom Foreign Ministry report, by Yumiko Moyen, Science and Innovation Section, British Embassy, Tokyo, Japan, January 2009.\n", + "^ Robotic Tactile Sensing – Technologies and System. Springer.com. 2012-07-30. ISBN 9789400705784. Archived from the original on 2013-12-29. Retrieved 2014-02-08.\n", + "^ Dahiya, Ravinder S.; Metta, Giorgio; Cannata, Giorgio; Valle, Maurizio (2011). \"Guest Editorial Special Issue on Robotic Sense of Touch\". IEEE Transactions on Robotics. 27 (3): 385–388. doi:10.1109/TRO.2011.2155830.\n", + "^ \"Robotics in practice: Future capabilities\" by Joseph F. Engelberger. in \"Electronic Servicing & Technology\" magazine 1982 August.\n", + "^ The Caterpillar Self-Driving Dump Truck Archived 2011-06-07 at the Wayback Machine, By Tim McKeough, Fast Company, November 25, 2008.\n", + "^ Self-Driving Trucks to Revolutionize Logistics, DHL Says Archived 2016-07-22 at the Wayback Machine, Richard Weiss, December 9, 2014.\n", + "^ VIDEO: Why Caterpillar’s autonomous mining tech is “completely different from anything” it’s ever done Archived 2016-05-13 at the Wayback Machine Wayne Grayson | October 16, 2014.\n", + "^ Self-driving dump trucks, automatic shovels coming to Australian mines Archived 2016-05-09 at the Wayback Machine, KAORI TAKAHASHI, April 23, 2015.\n", + "^ Forget self-driving Google cars, Australia has self-driving trucks Archived 2016-04-26 at the Wayback Machine, by Matthew Hall, October 20, 2014.\n", + "^ Australian mining giant Rio Tinto is using these huge self-driving trucks to transport iron ore Archived 2016-05-09 at the Wayback Machine, Charles Clark, Oct. 19, 2015.\n", + "^ Daddy, What Was a Truck Driver? Over the Next Two Decades, the Machines Themselves Will Take Over the Driving Archived 2017-03-04 at the Wayback Machine, By DENNIS K. BERMAN, July 23, 2013, wsj.com.\n", + "^ \"Robot can read, learn like a human\". 6 December 2010. Retrieved 10 December 2010.\n", + "^ Robots: Brave New World moves a step closer Archived 2019-01-14 at the Wayback Machine, By James Melik, Reporter, Business Daily, BBC World Service, 3 January 2013.\n", + "^\n", + "a b Zunt, Dominik. \"Who did actually invent the word \"robot\" and what does it mean?\". The Karel Čapek website. Archived from the original on 2012-02-04. Retrieved 2007-09-11.\n", + "^ \"Indo-European root *orbh-\". 2008-05-12. Archived from the original on January 24, 2009. Retrieved 2014-02-08.\n", + "^ \"Online Etymology Dictionary\". Archived from the original on 2013-12-14. Retrieved 2012-06-10.\n", + "^ Ranger, Steve. \"Robots of death, robots of love: The reality of android soldiers and why laws for robots are doomed to failure\". TechRepublic. Archived from the original on 27 January 2017. Retrieved 21 January 2017.\n", + "^ Moubarak, Paul M.; Ben-Tzvi, Pinhas (2011). \"Adaptive manipulation of a Hybrid Mechanism Mobile Robot\". 2011 IEEE International Symposium on Robotic and Sensors Environments (ROSE). pp. 113–118. doi:10.1109/ROSE.2011.6058520. ISBN 978-1-4577-0819-0.\n", + "^\n", + "a b \"Smart Caddy\". Seegrid. Archived from the original on 2007-10-11. Retrieved 2007-09-13.\n", + "^ Zhang, Gexiang; Pérez-Jiménez, Mario J.; Gheorghe, Marian (2017-04-05). Real-life Applications with Membrane Computing. Springer. ISBN 9783319559896.\n", + "^ \"Definition of a robot\" (PDF). Dansk Robot Forening. Archived from the original (PDF) on 2007-06-28. Retrieved 2007-09-10.\n", + "^ \"Robotics-related Standards Sites\". European Robotics Research Network. Archived from the original on 2006-06-17. Retrieved 2008-07-15.\n", + "^ Provisional definition of Service Robots Archived 2010-02-18 at the Wayback Machine, IFR, 27th of October 2012\n", + "^ Mitgang, Lee (October 25, 1983). \"'Nova's' 'Talking Turtle' Pofiles High Priest of School Computer Movement\". Gainesville Sun.\n", + "^ Barnard, Jeff (January 29, 1985). \"Robots In School: Games Or Learning?\". Observer-Reporter. Washington. Archived from the original on September 22, 2015. Retrieved March 7, 2012.\n", + "^ \"Education: Marvel of the Bronx\". Time. April 1974. Archived from the original on 2019-05-24. Retrieved 2019-05-19.\n", + "^ \"Leachim Archives\". cyberneticzoo.com. 2010-09-13. Archived from the original on 2019-05-28. Retrieved 2019-05-29.\n", + "^ P. Moubarak, et al., Modular and Reconfigurable Mobile Robotics, Journal of Robotics and Autonomous Systems, 60 (12) (2012) 1648–1663.\n", + "^ Rédaction (December 25, 2011). \"Le consortium franco-québécois Mix dévoile son projet de voiture volante\". aerobuzz.fr/ (in French). aerobuzz.fr. Archived from the original on October 6, 2012. Retrieved September 7, 2012.\n", + "^ Scanlan, Steve, Robotics Design Inc., Montreal. \"Modularity in robotics provides automation for all\". Digital.ept.ca. Retrieved September 7, 2012.\n", + "^ Plumbing and HVAC, Magazine (April 2010). \"Duct cleaning robots\" (PDF). roboticsdesign.qc.ca/news.html. plumbingandhvac.ca/. Archived (PDF) from the original on April 25, 2013. Retrieved April 29, 2010.\n", + "^ \"Universal Robots collaborate outside enclosures | Control Engineering\". Controleng.com. February 2013. Archived from the original on 2013-05-18. Retrieved 2013-06-04.\n", + "^ \"A Brief History of Collaborative Robots\" Archived 2016-06-10 at the Wayback Machine Engineering.com, May 19, 2016\n", + "^ Hagerty, James (18 September 2012). \"Baxter Robot Heads to Work'\". Wall Street Journal. New York: Dow Jones & Company. Archived from the original on 10 April 2015. Retrieved 29 May 2014.\n", + "^ John Markoff (September 18, 2012). \"A Robot With a Reassuring Touch\". The New York Times. Archived from the original on September 19, 2012. Retrieved September 18, 2012.\n", + "^ \"A Ping-Pong-Playing Terminator\". Popular Science. Archived from the original on 2011-03-29. Retrieved 2010-12-18.\n", + "^ \"Best robot 2009\". gadgetrivia.com. Archived from the original on 11 May 2012.\n", + "^ Robots Today and Tomorrow: IFR Presents the 2007 World Robotics Statistics Survey Archived 2008-02-05 at the Wayback Machine; World Robotics; 2007-10-29. Retrieved 2007-12-14\n", + "^ Reporting by Watanabe, Hiroaki; Writing and additional reporting by Negishi, Mayumi; Editing by Norton, Jerry; Japan's robots slug it out to be world champ Archived 2007-12-13 at the Wayback Machine; Reuters; 2007-12-02. Retrieved 2007-01-01\n", + "^\n", + "a b Ho, C. C.; MacDorman, K. F.; Pramono, Z. A. D. (2008). \"Human emotion and the uncanny valley: A GLM, MDS, and ISOMAP analysis of robot video ratings\" (PDF). 2008 3rd ACM/IEEE International Conference on Human-Robot Interaction (HRI). Archived (PDF) from the original on 2008-09-11. Retrieved 2008-09-24.\n", + "^\n", + "a b AAAI webpage of materials on robot ethics (Archived).\n", + "^ AAAI compilation of articles on robot rights (Archived), sources compiled up to 2006.\n", + "^ Scientists Predict Artificial Brain in 10 Years (Archived), by Kristie McNealy M.D. July 29, 2009.\n", + "^ Robot: Mere Machine to Transcendent Mind Archived 2016-12-05 at the Wayback Machine By Hans Moravec, Google Books.\n", + "^ Robots Almost Conquering Walking, Reading, Dancing Archived 2011-07-21 at the Wayback Machine, by Matthew Weigand, Korea Itimes, Monday, August 17, 2009.\n", + "^ Plug & Pray Archived 2016-02-12 at the Wayback Machine, documentary film by Jens Schanze about the possibilities of AI and robotics.\n", + "^\n", + "a b Scientists Worry Machines May Outsmart Man Archived 2017-07-01 at the Wayback Machine By John Markoff, The New York Times, July 26, 2009.\n", + "^ The Coming Technological Singularity: How to Survive in the Post-Human Era Archived 2007-01-01 at the Wayback Machine, by Vernor Vinge, Department of Mathematical Sciences, San Diego State University, (c) 1993 by Vernor Vinge.\n", + "^ Gaming the Robot Revolution: A military technology expert weighs in on Terminator: Salvation Archived 2010-01-27 at the Wayback Machine., By P. W. Singer, slate.com Thursday, May 21, 2009.\n", + "^ Robot takeover (Archived), gyre.org.\n", + "^ robot page Archived 2018-05-04 at the Wayback Machine, Engadget.\n", + "^ \"Cute robot politely shows self-awareness\". Archived from the original on 2015-08-22. Retrieved 2015-08-19.\n", + "^ Call for debate on killer robots Archived 2009-08-07 at the Wayback Machine, Jason Palmer. BBC News, August 3, 2009.\n", + "^ Robot three-way portends autonomous future Archived 2012-11-07 at the Wayback Machine, By David Axe wired.com, August 13, 2009.\n", + "^ New Navy-funded Report Warns of War Robots Going \"Terminator\" Archived 2009-07-28 at the Wayback Machine, by Jason Mick (Blog), dailytech.com, February 17, 2009.\n", + "^ Navy report warns of robot uprising, suggests a strong moral compass Archived 2011-06-04 at the Wayback Machine, by Joseph L. Flatley engadget.com, February 18, 2009.\n", + "^ New role for robot warriors Archived 2015-09-24 at the Wayback Machine Drones are just part of a bid to automate combat. Can virtual ethics make machines decisionmakers?, by Gregory M. Lamb, The Christian Science Monitor, February 17, 2010.\n", + "^ \"Biomass-Eating Military Robot Is a Vegetarian, Company Says\". Fox News Channel. 2009-07-16. Archived from the original on 2009-08-03. Retrieved 2009-07-31.\n", + "^ Shachtman, Noah (2009-07-17). \"Danger Room What's Next in National Security Company Denies its Robots Feed on the Dead\". Wired. Archived from the original on 2009-07-29. Retrieved 2009-07-31.\n", + "^ Press release, RTI Inc. (2009 July 16). Cyclone Power Technologies Responds to Rumors about “Flesh Eating” Military Robot Archived 2009-08-23 at the Wayback Machine, pp. 1-2.\n", + "^ Press release, RTI Inc. (2009 April 6). \"Brief Project Overview\" Archived 2009-08-23 at the Wayback Machine, EATR: Energetically Autonomous Tactical Robot, pp. 22.\n", + "^ Manuel de Landa, War in the Age of Intelligent Machines, New York: Zone Books, 1991, 280 pages, Hardcover, ISBN 0-942299-76-0; Paperback, ISBN 0-942299-75-2.\n", + "^ E McGaughey, 'Will Robots Automate Your Job Away? Full Employment, Basic Income, and Economic Democracy' (2018) SSRN, part 3 Archived 2018-05-24 at the Wayback Machine. Porter, Eduardo; Manjoo, Farhad (9 March 2016). \"A Future Without Jobs? Two Views of the Changing Work Force\". The New York Times. Archived from the original on 15 February 2017. Retrieved 23 February 2017.. Thompson, Derek (July–August 2015). \"A World Without Work\". The Atlantic. Archived from the original on 2017-02-27. Retrieved 2017-03-11.\n", + "^ Yan (30 July 2011). \"Foxconn to replace workers with 1 million robots in 3 years\". Xinhua News Agency. Archived from the original on 8 October 2011. Retrieved 4 August 2011.\n", + "^ \"Judgment day – employment law and robots in the workplace\". futureofworkhub. Archived from the original on 2015-04-03. Retrieved 2015-01-07.\n", + "^ Delaney, Kevin. \"The robot that takes your job should pay taxes, says Bill Gates\". QUARTZ. Archived from the original on 5 March 2017. Retrieved 4 March 2017.\n", + "^ \"The Changing Nature of Work\". Archived from the original on 30 September 2018. Retrieved 8 October 2018.\n", + "^ \"Contact Systems Pick and Place robots\". Contact Systems. Archived from the original on 2008-09-14. Retrieved 2008-09-21.\n", + "^ \"SMT pick-and-place equipment\". Assembleon. Archived from the original on 2008-08-03. Retrieved 2008-09-21.\n", + "^ \"The Basics of Automated Guided Vehicles\". Savant Automation, AGV Systems. Archived from the original on 2007-10-08. Retrieved 2007-09-13.\n", + "^ \"Jervis B. Webb\". Webb SmartLoader. Archived from the original on 23 May 2013. Retrieved 2 September 2011.\n", + "^ \"SpeciMinder\". CSS Robotics. Archived from the original on 2009-07-01. Retrieved 2008-09-25.\n", + "^ \"ADAM robot\". RMT Robotics. Archived from the original on 2006-05-17. Retrieved 2008-09-25.\n", + "^ \"Can Do\". Aethon. Archived from the original on 2008-08-03. Retrieved 2008-09-25.\n", + "^ \"Eskorta robot\". Fennec Fox Technologies. Archived from the original on 2011-12-06. Retrieved 2011-11-25.\n", + "^ \"Delivery Robots & AGVs\". Mobile Robots. Archived from the original on 26 February 2010. Retrieved 2008-09-25.\n", + "^ \"Dante II, list of published papers\". The Robotics Institute of Carnegie Mellon University. Archived from the original on 15 May 2008. Retrieved 2007-09-16.\n", + "^ \"Mars Pathfinder Mission: Rover Sojourner\". NASA. 1997-07-08. Archived from the original on 2017-02-01. Retrieved 2007-09-19.\n", + "^\n", + "a b \"Robot assisted surgery: da Vinci Surgical System\". Brown University Division of Biology and Medicine. Archived from the original on 2007-09-16. Retrieved 2007-09-19.\n", + "^ The Utilization of Robotic Space Probes in Deep Space Missions:Case Study of AI Protocols and Nuclear Power Requirements, Proceedings of 2011 International Conference on Mechanical Engineering, Robotics and Aerospace, October 2011.\n", + "^ Review: Space Probes Archived 2012-08-31 at the Wayback Machine, by Jeff Foust, Monday, January 16, 2012. Review of Space Probes: 50 Years of Exploration from Luna 1 to New Horizons, by Philippe Séguéla Firefly, 2011.\n", + "^ \"Celebrities set to reach for Atwood's LongPen\". Canadian Broadcasting Corporation. 2007-08-15. Archived from the original on 22 May 2009. Retrieved 2008-09-21.\n", + "^ Graham, Stephen (2006-06-12). \"America's robot army\". New Statesman. Archived from the original on 17 February 2012. Retrieved 2007-09-24.\n", + "^ \"Battlefield Robots: to Iraq, and Beyond\". Defense Industry Daily. 2005-06-20. Archived from the original on 2007-08-26. Retrieved 2007-09-24.\n", + "^ Shachtman, Noah (November 2005). \"The Baghdad Bomb Squad\". Wired. Archived from the original on 2008-04-22. Retrieved 2007-09-14.\n", + "^ Shachtman, Noah (2013-03-28). \"WIRED: First Armed Robots on Patrol in Iraq\". Blog.wired.com. Archived from the original on 2009-04-03. Retrieved 2014-02-08.\n", + "^ Shachtman, Noah (2013-03-28). \"WIRED: Armed Robots Pushed To Police\". Blog.wired.com. Archived from the original on 2009-04-12. Retrieved 2014-02-08.\n", + "^ \"America's Robot Army\". Popularmechanics.com. 2009-12-18. Archived from the original on 2010-02-05. Retrieved 2014-02-08.\n", + "^ The Present and Future of Unmanned Drone Aircraft: An Illustrated Field Guide; Archived 2010-02-26 at the Wayback Machine Inside the wild kingdom of the world's newest and most spectacular species of unmanned aircraft, from swarming insect ’bots that can storm a burning building to a seven-ton weaponized spyplane invisible to radar. By Eric Hagerman, Popular Science, 23 February 2010.\n", + "^ \"Taranis: The m Fighter Jet Of The Future\". Ministry of Defence. 2010-07-12. Archived from the original on 2010-07-15. Retrieved 2010-07-13.\n", + "^ Emery, Daniel (2010-07-12). \"MoD lifts lid on unmanned combat plane prototype\". BBC News. Archived from the original on 2010-07-12. Retrieved 2010-07-12.\n", + "^ AAAI Presidential Panel on Long-Term AI Futures 2008–2009 Study Archived 2009-08-28 at the Wayback Machine, Association for the Advancement of Artificial Intelligence. Retrieved July 26, 2009.\n", + "^ Why We Need Friendly AI, Asimovlaws.com, July 2004. Retrieved July 27, 2009.\n", + "^ Robotic age poses ethical dilemma Archived 2009-02-15 at the Wayback Machine; BBC News; 2007-03-07. Retrieved 2007-01-02;\n", + "^ Asimov's First Law: Japan Sets Rules for Robots Archived 2008-10-13 at the Wayback Machine, By Bill Christensen, livescience.com, May 26, 2006.\n", + "^ Japan drafts rules for advanced robots Archived 2008-10-11 at the Wayback Machine, UPI via physorg.com, April 6, 2007.\n", + "^ Report compiled by the Japanese government's Robot Industry Policy Committee -Building a Safe and Secure Social System Incorporating the Coexistence of Humans and Robots Archived 2011-09-27 at the Wayback Machine, Official Japan government press release, Ministry of Economy, Trade and Industry, March 2009.\n", + "^ Toward the human-Robot Coexistence Society: on Safety intelligence for next Generation Robots Archived 2009-09-26 at the Wayback Machine, report by Yueh-Hsuan Weng, China Ministry of the Interior, International Journal of Social Robotics Archived 2017-04-29 at the Wayback Machine, April 7, 2009.\n", + "^ Evolving Robots Learn To Lie To Each Other Archived 2013-05-18 at the Wayback Machine, Popular Science, August 19, 2009.\n", + "^ \"Rio Tinto Media Center – Rio Tinto boosts driverless truck fleet to 150 under Mine of the Future™ programme\". Riotinto.com. Archived from the original on 2013-04-24. Retrieved 2014-02-08.\n", + "^ \"BHP Billiton hits go on autonomous drills\". Archived from the original on 2016-08-22. Retrieved 2016-07-27.\n", + "^ Adrian (2011-09-06). \"AIMEX blog – Autonomous mining equipment\". Adrianboeing.blogspot.com. Archived from the original on 2013-12-18. Retrieved 2014-02-08.\n", + "^ \"Atlas Copco – RCS\". Atlascopco.com. Archived from the original on 2014-02-07. Retrieved 2014-02-08.\n", + "^ \"Transmin – Rocklogic\". Rocklogic.com.au. Archived from the original on 2014-01-25. Retrieved 2014-02-08.\n", + "^ Topping, Mike; Smith, Jane (1999). \"An Overview Of Handy 1, A Rehabilitation Robot For The Severely Disabled\". CSUN Center on Disabilities Conference Proceedings. 1999. Proceedings: Session 59. Archived from the original on 5 August 2009. Retrieved 14 August 2010. The early version of the Handy 1 system consisted of a Cyber 310 robotic arm with five degrees of freedom plus a gripper.\n", + "^ Jeavans, Christine (2004-11-29). \"Welcome to the ageing future\". BBC News. Archived from the original on 2007-10-16. Retrieved 2007-09-26.\n", + "^ \"Statistical Handbook of Japan: Chapter 2 Population\". Statistics Bureau & Statistical Research and Training Institute. Archived from the original on 2013-09-06. Retrieved 2007-09-26.\n", + "^ \"Robotic future of patient care\". E-Health Insider. 2007-08-16. Archived from the original on 21 November 2007. Retrieved 2007-09-26.\n", + "^ Gebhart, Fred (2019-07-04). \"The Future of Pharmacy Automation\". Drug Topics. Retrieved 2019-11-20.\n", + "^ Dolan, Kerry A. \"R2D2 Has Your Pills\". Forbes. Retrieved 2019-11-20.\n", + "^ Michael Hahn (1997-04-01). \"Fullerene Nanogears\". NASA. Archived from the original on 2008-05-09. Retrieved 2008-05-27.\n", + "^ \"Nanobots Play Football\". Techbirbal. Archived from the original on 2013-04-03. Retrieved 2014-02-08.\n", + "^ \"KurzweilAI.net\". 21 June 2010. Archived from the original on 21 June 2010. Retrieved 5 July 2016.\n", + "^ \"(Eric Drexler 1986) Engines of Creation, The Coming Era of Nanotechnology\". E-drexler.com. Archived from the original on 2014-09-06. Retrieved 2014-02-08.\n", + "^ Chris Phoenix (December 2003). \"Of Chemistry, Nanobots, and Policy\". Center for Responsible Nanotechnology. Archived from the original on 2007-10-11. Retrieved 2007-10-28.\n", + "^ \"Nanotechnology pioneer slays 'grey goo' myths\". Institute of Physics Electronics Journals. 2004-06-07. Retrieved 2007-10-28. [permanent dead link]\n", + "^ (1996) LEGO(TM)s to the Stars: Active MesoStructures, Kinetic Cellular Automata, and Parallel Nanomachines for Space Applications Archived 2007-09-27 at the Wayback Machine\n", + "^ (Robert Fitch, Zack Butler and Daniela Rus) Reconfiguration Planning for Heterogeneous Self-Reconfiguring Robots Archived 2007-06-19 at the Wayback Machine\n", + "^ John Schwartz (2007-03-27). \"In the Lab: Robots That Slink and Squirm\". The New York Times. Archived from the original on 2015-04-03. Retrieved 2008-09-22.\n", + "^ Kat Eschner (25 March 2019). \"Squishy robots now have squishy computers to control them\". Popular Science.\n", + "^ \"The softer side of robotics\". May 2019. Archived from the original on 2019-05-17. Retrieved 2019-05-17.\n", + "^ \"SRI/MobileRobots\". activrobots.com. Archived from the original on 2009-02-12.\n", + "^ \"Open-source micro-robotic project\". Archived from the original on 2007-11-11. Retrieved 2007-10-28.\n", + "^ \"Swarm\". iRobot Corporation. Archived from the original on 2007-09-27. Retrieved 2007-10-28.\n", + "^ Knapp, Louise (2000-12-21). \"Look, Up in the Sky: Robofly\". Wired. Archived from the original on 2012-06-26. Retrieved 2008-09-25.\n", + "^ \"The Cutting Edge of Haptics\". MIT Technology review. Retrieved 2008-09-25.\n", + "^ \"Comic Potential : Q&A with Director Stephen Cole\". Cornell University. Archived from the original on 3 January 2009. Retrieved 2007-11-21.\n", + "^ Freedman, ed. by Carl (2005). Conversations with Isaac Asimov (1. ed.). Jackson: Univ. Press of Mississippi. p. vii. ISBN 978-1-57806-738-1. Archived from the original on 5 December 2016. Retrieved 4 August 2011. ... quite possibly the most prolific\n", + "^ Oakes, Elizabeth H. (2004). American writers. New York: Facts on File. p. 24. ISBN 978-0-8160-5158-8. Archived from the original on 5 December 2016. Retrieved 4 August 2011.\n", + "^ He wrote \"over 460 books as well as thousands of articles and reviews\", and was the \"third most prolific writer of all time [and] one of the founding fathers of modern science fiction\". White, Michael (2005). Isaac Asimov: a life of the grand master of science fiction. Carroll & Graf. pp. 1–2. ISBN 978-0-7867-1518-3. Archived from the original on 2016-12-05. Retrieved 2016-09-25.\n", + "^ R. Clarke. \"Asimov's Laws of Robotics – Implications for Information Technology\". Australian National University/IEEE. Archived from the original on 2008-07-22. Retrieved 2008-09-25.\n", + "^ Seiler, Edward; Jenkins, John H. (2008-06-27). \"Isaac Asimov FAQ\". Isaac Asimov Home Page. Archived from the original on 2012-07-16. Retrieved 2008-09-24.\n", + "^ White, Michael (2005). Isaac Asimov: A Life of the Grand Master of Science Fiction. Carroll & Graf. p. 56. ISBN 978-0-7867-1518-3.\n", + "^ \"Campaign launched against 'harmful' sex robots\". CNBC. 2015-09-15. Archived from the original on 2017-09-13. Retrieved 2017-09-10.\n", + "^\n", + "a b \"Intelligent machines: Call for a ban on robots designed as sex toys\". BBC News. 2015-09-15. Archived from the original on 2018-06-30. Retrieved 2018-06-21.\n", + "^ \"Campaign calls for ban on sex robots\". Wired UK. 2005-09-15. Archived from the original on 2017-09-14. Retrieved 2017-09-10.\n", + "^ Justin Wm. Moyer (15 September 2015). \"Having sex with robots is really, really bad, Campaign Against Sex Robots says\". Washington Post. Archived from the original on 8 September 2016. Retrieved 10 September 2017.\n", + "Further reading\n", + "See this humanoid robot artist sketch drawings from sight (CNN, Video, 2019)\n", + "Čapek, Karel (1920). R.U.R., Aventinum, Prague.\n", + "Margolius, Ivan. 'The Robot of Prague', Newsletter, The Friends of Czech Heritage no. 17, Autumn 2017, pp. 3 – 6. https://czechfriends.net/images/RobotsMargoliusJul2017.pdf\n", + "Glaser, Horst Albert and Rossbach, Sabine: The Artificial Human, Frankfurt/M., Bern, New York 2011 \"A Tragical History\"\n", + "TechCast Article Series, Jason Rupinski and Richard Mix, \"Public Attitudes to Androids: Robot Gender, Tasks, & Pricing\"\n", + "Cheney, Margaret [1989:123] (1981). Tesla, Man Out of Time. Dorset Press. New York. ISBN 0-88029-419-1\n", + "Craig, J.J. (2005). Introduction to Robotics, Pearson Prentice Hall. Upper Saddle River, NJ.\n", + "Gutkind, L. (2006). Almost Human: Making Robots Think. New York: W. W. Norton & Company, Inc.\n", + "Needham, Joseph (1986). Science and Civilization in China: Volume 2. Taipei: Caves Books Ltd.\n", + "Sotheby's New York. The Tin Toy Robot Collection of Matt Wyse (1996)\n", + "Tsai, L. W. (1999). Robot Analysis. Wiley. New York.\n", + "DeLanda, Manuel. War in the Age of Intelligent Machines. 1991. Swerve. New York.\n", + "Journal of Field Robotics\n", + "External links\n", + "Wikiquote has quotations related to: Robot\n", + "Robot\n", + "at Wikipedia's sister projects\n", + "Definitions from Wiktionary\n", + "Media from Wikimedia Commons\n", + "Textbooks from Wikibooks\n", + "Resources from Wikiversity\n", + "Robot at the Encyclopædia Britannica\n", + "Robotics at Curlie\n", + "show\n", + "vte\n", + "Robotics\n", + "show\n", + "vte\n", + "Machines\n", + "show\n", + "vte\n", + "Science fiction\n", + "\n", + "\n", + "Authority control\n", + "BNF: cb12267450c (data) GND: 4050208-9 LCCN: sh85114637 NDL: 00569589\n" + ] + } + ], + "source": [ + "# Find the element that holds the text\n", + "text_element = browser.find_element_by_xpath('//*[@id=\"mw-content-text\"]')\n", + "\n", + "# Extract the text from the element\n", + "wiki_text = text_element.text\n", + "\n", + "# Quit the browser\n", + "browser.quit()\n", + "\n", + "# Print the text to show the result\n", + "print(wiki_text)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Saving the content\n", + "\n", + "In this final step the content is saved to a textfile located on the desktop." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# Save text to a .txt file\n", + "textfile = make_textfile(text=wiki_text, output_path=desktop_path('textfile.txt'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively, you could leave out 'output_path=desktop_path('textfile.txt')' which would save it to the homedir by default or manually enter a path (make sure to use a raw string).\n", + "\n", + "\n", + "Finally, open to file for illustration" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'C:\\\\Users\\\\TvT\\\\Desktop\\\\textfile.txt'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "open_file(textfile)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "'Python Interactive'", + "language": "python", + "name": "bb341ba4-98f7-43a2-996e-ea9a75df951a" + }, + "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.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/change_wallpaper_automation_example.ipynb b/examples/change_wallpaper_automation_example.ipynb new file mode 100644 index 00000000..a3884fd5 --- /dev/null +++ b/examples/change_wallpaper_automation_example.ipynb @@ -0,0 +1,137 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Change Wallpaper\n", + "\n", + "In this example we will download an image and use it as a allpaper." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initializing Automagica\n", + "\n", + "The first step in building a script with Automagica is to import all the Automagica activities." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from automagica import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Downloading the file\n", + "\n", + "We will use a sample image file directly downloaded from the Automagica website. The image can be found and viewed on:\n", + "\n", + "https://automagica.com/examples/wallpaper.jpg\n", + "\n", + "If you would like to add your own variation, for example by looking up images from other resources on the web we recommend going over the browser automation examples and documentation. \n", + "\n", + "We can specify a path, but by default the download_file_from_url activity will download to the homedir." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Download the file \n", + "downloaded_image = download_file_from_url('https://automagica.com/examples/wallpaper.jpg')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To see the full path to the newly downloaded image we can do so by simply running it's name" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'C:\\\\Users\\\\TvT\\\\wallpaper.jpg'" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "downloaded_image" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Set the file as wallpaper\n", + "\n", + "Last step is the set the newly downloaded image as wallpaper" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Set image as wallpaper\n", + "set_wallpaper(downloaded_image)" + ] + }, + { + "attachments": { + "wallpaper.jpg": { + "image/jpeg": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Your new wallpaper should look like this:\n", + "\n", + "![wallpaper.jpg](attachment:wallpaper.jpg)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "'Python Interactive'", + "language": "python", + "name": "bb341ba4-98f7-43a2-996e-ea9a75df951a" + }, + "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.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/excel/app.py b/examples/excel/app.py deleted file mode 100644 index 8e024f1f..00000000 --- a/examples/excel/app.py +++ /dev/null @@ -1,18 +0,0 @@ -from automagica import * - -""" -Reads information from one Excel file and writes it to the other. -""" - -# Read information from example.xlsx in cell A1 -workbook = OpenExcelWorkbook('example.xlsx') -worksheet = workbook.active -cell_content = worksheet['A1'].value - -# Write information to new file -new_workbook = NewExcelWorkbook() -new_worksheet = new_workbook.active -new_worksheet['A1'] = cell_content - -new_workbook.save('result.xlsx') - diff --git a/examples/excel/example.xlsx b/examples/excel/example.xlsx deleted file mode 100644 index 0ef07f69..00000000 Binary files a/examples/excel/example.xlsx and /dev/null differ diff --git a/examples/excel_automation_example.ipynb b/examples/excel_automation_example.ipynb new file mode 100644 index 00000000..297f40a3 --- /dev/null +++ b/examples/excel_automation_example.ipynb @@ -0,0 +1,332 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Excel Automation\n", + "\n", + "In this example we perform a multitude of Excel operations as an illustration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initializing Automagica\n", + "\n", + "The first step in building a script with Automagica is to import all the Automagica activities." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from automagica import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Starting Excel\n", + "\n", + "Start by opening Excel, in this case we will give the instance the name 'excel'. Feel free to give this any name you want, as long as you consistently use it when addressing it." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "excel = Excel()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Adding data\n", + "\n", + "Let us add some data by writing some cells. We will fill the first 5 rows with random data using different methods. We can use Automagica activities to generate the data, but this can be any data ofcourse. \n", + "\n", + "A random name can be generated by calling:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can start by giving the first column the heading \"Names\":" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "# Write to cell A1, this is column 1, row 1\n", + "excel.write_cell(1, 1, \"Name\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Give the second column the heading \"Address\"" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "# Write to cell, B1, this is column 2, row 1\n", + "excel.write_cell(2, 1, \"Address\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The third column gets the heading \"Age\"" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "# Write to cell, B1, this is column 3, row 1\n", + "excel.write_cell(3, 1, \"Company\")" + ] + }, + { + "attachments": { + "excel1.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The worksheet should now look like this:\n", + "\n", + "![excel1.png](attachment:excel1.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Method 1: Write every cell individually\n", + "\n", + "We can write each cell individually:" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "# Write to cell A2, this is column 1, row 2\n", + "excel.write_cell(1, 2, generate_random_name())\n", + "\n", + "# Write to cell A3, this is column 1, row 3\n", + "excel.write_cell(1, 3, generate_random_name())\n", + "\n", + "# Write to cell A4, this is column 1, row 4\n", + "excel.write_cell(1, 4, generate_random_name())\n", + "\n", + "# Write to cell A5, this is column 1, row 5\n", + "excel.write_cell(1, 5, generate_random_name())\n", + "\n", + "# Write to cell A6, this is column 1, row 6\n", + "excel.write_cell(1, 6, generate_random_name())" + ] + }, + { + "attachments": { + "excel2.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The contents of the first cells of the sheet should like something like this:\n", + "\n", + "![excel2.png](attachment:excel2.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Method 2: Use a for loop to write cells\n", + "\n", + "We can loop over the cells of colunm B to fill in random adresses" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "# Write to cells B2, B3, B4, B5 and B6. This is row 2, cells 2 to 6\n", + "for i in range(2,7):\n", + " excel.write_cell(2,i,generate_random_address())" + ] + }, + { + "attachments": { + "excel3.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This will result in a worksheet comparable to:\n", + "\n", + "![excel3.png](attachment:excel3.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Method 3: Use Automagica range \n", + "\n", + "We can write multiple cells by using the Automagica built-in write_range" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "# Write to cell range C2:C6. This is row 3, cells 2 to 6\n", + "excel.write_range('C2:C6', \"Example Company\")" + ] + }, + { + "attachments": { + "excel4.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This will result in:\n", + "\n", + "![excel4.png](attachment:excel4.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Saving Data\n", + "\n", + "As a next step we can save the data and and exit Excel.\n", + "\n", + "We first declare a path using the Automagica built-in home_path function to make sure we know where it is saved" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "# Declare path to save it to, in this case in the homedir with the name \"awesome_excel.xlsx\"\n", + "excel_save_path = home_path('awesome_excel.xlsx')" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "# Save the worksheet, by default this is in the homedir\n", + "excel.save_as(excel_save_path)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now exit Excel" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "excel.quit()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As a last stap we can re-open the file we just saved to verify:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'C:\\\\Users\\\\TvT\\\\awesome_excel.xlsx'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "open_file(excel_save_path)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "'Python Interactive'", + "language": "python", + "name": "bb341ba4-98f7-43a2-996e-ea9a75df951a" + }, + "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.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/file_folder_automation_example.ipynb b/examples/file_folder_automation_example.ipynb new file mode 100644 index 00000000..3ddd63d5 --- /dev/null +++ b/examples/file_folder_automation_example.ipynb @@ -0,0 +1,218 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Folder & File Automation\n", + "\n", + "In this example we will create, delet and move files and folders on Windows" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initializing Automagica\n", + "\n", + "The first step in building a script with Automagica is to import all the Automagica activities." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "from automagica import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creating some files\n", + "\n", + "Let's start by creating some textfiles on in the home directory." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Make textfile 1\n", + "textfile_1 = make_textfile(output_path=home_path('textfile1.txt'))\n", + "\n", + "# Make textfile 2\n", + "textfile_2 = make_textfile(output_path=home_path('textfile2.txt'))\n", + "\n", + "# Make textfile 3\n", + "textfile_3 = make_textfile(output_path=home_path('textfile3.txt'))" + ] + }, + { + "attachments": { + "filesandfolder1.png": { + "image/png": "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fv2qqp35JI1/9ac7NDqfr15VOq/89VP5GgkdCgJBYU+joph8nzZt0dDBSoctESY14s1cI8dkgc2KcM5sGTSgHDINazfGLuoelw4HoTNBY2yLPS10Lrg8g840xDHY04bXudULAau+viZrZKFtqmdFxfi8Xq6IajZO2suuF6Yas2iiFBwsKDPeZW+9XBHVbBxhH2YoTAWdK8bn9XJFVFVNx4RsspzCVCF1bvNC4OFP93o/fHlG3t+49u0Pmw8o1flmvXetf623/o1OLevjma0mMyyaBDF0FneqvvrkwffXV2TTC3Rugk9neWU7Gn3+3dgbr4F1bvtegBXQAmw47GzzRKs609//v/f+NRr7958JUc5n+ju+1uQ9bjbaDAHirsa3XznR7OYXFLxGFMSaf+rhma2M9xOXGRZNgrZ1vvnPLz/9h/vXHzorwup800xy87tv1X3EKDrrIBQOui4RqACX3/AgS34nw7qRYo+3L2myumV0ZssCKA3IGvlgqslhExdNFceFNnW2W4QclA8200Lnssu5SlbdMro6200jWD7YTBteZ/yrQQCwpmvfCwAARAUhAADWIAQAwBqEAABYgxAAAGsQAgBgDUIAAKxBCACANQgBALAGIQAA1iAEAMAahAAAWIMQAABrEAIAYA1CAACsQQgAgDUIAQCwBiEAAMb0ev8HfYd27Gh73nEAAAAASUVORK5CYII=" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This should create 3 files in your home directory\n", + "\n", + "![filesandfolder1.png](attachment:filesandfolder1.png)\n", + "\n", + "We can use Automagica to open the home directory and have a look" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'C:\\\\Users\\\\TvT'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "open_file(home_path())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creating a folder\n", + "\n", + "We can create a folder in the home directory to move the textfiles to." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "folder_1 = create_folder(path=home_path('nice_folder'))" + ] + }, + { + "attachments": { + "filesandfolder2.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can verify in your home directory that a new folder with the correct name was created\n", + "\n", + "![filesandfolder2.png](attachment:filesandfolder2.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Moving the files\n", + "\n", + "We can now move the textfiles to the folder " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'C:\\\\Users\\\\TvT\\\\nice_folder_fadb'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Move textfile 1\n", + "move_file(textfile_1, folder_1)\n", + "\n", + "# Move textfile 2\n", + "move_file(textfile_2, folder_1)\n", + "\n", + "# Move textfile 3\n", + "move_file(textfile_3, folder_1)" + ] + }, + { + "attachments": { + "filesandfolder3.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The new folder now contains the three textfiles\n", + "\n", + "![filesandfolder3.png](attachment:filesandfolder3.png)\n", + "\n", + "Finally we can open the folder to verify all files have been moved:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'C:\\\\Users\\\\TvT\\\\nice_folder_fadb'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Open the new folder\n", + "open_file(folder_1)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "'Python Interactive'", + "language": "python", + "name": "bb341ba4-98f7-43a2-996e-ea9a75df951a" + }, + "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.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/multiprogram/USPresidents.py b/examples/multiprogram/USPresidents.py deleted file mode 100644 index 001296c0..00000000 --- a/examples/multiprogram/USPresidents.py +++ /dev/null @@ -1,15 +0,0 @@ - -from automagica import * - - -# Put the president names of the first column in a list. -names = ExcelPutColumnInList("C:\\Users\\Bob\\Downloads\\USPresidents.xlsx", "A2","A45") - -# Create for every president a folder with his name and save a .txt file in that folder with his extra information. -for name in names: - CreateFolder("C:\\Users\\Bob\\Documents\\Presidents\\" + name) - row = names.index(name) + 2 - data = ExcelPutRowInList("C:\\Users\\Bob\\Downloads\\USPresidents.xlsx", "B"+str(row), "H" + str(row)) - WriteListToFile(data, "C:\\Users\\Bob\\Documents\\Presidents\\" + name + "\\" + name + ".txt") - - diff --git a/examples/multiprogram/USPresidents.xlsx b/examples/multiprogram/USPresidents.xlsx deleted file mode 100644 index e8d7d027..00000000 Binary files a/examples/multiprogram/USPresidents.xlsx and /dev/null differ diff --git a/examples/multiprogram/app.py b/examples/multiprogram/app.py deleted file mode 100644 index a1c9c35e..00000000 --- a/examples/multiprogram/app.py +++ /dev/null @@ -1,51 +0,0 @@ -""" -Open Excel and reads the searchterms it has to search for. -Opens Chrome and surfs to Google.com and enters searchterm. -Saves all the urls from the first page. -Writes the urls to excel. -""" - -from automagica import * - -excel_path = "Enter Path to Excel Here" #example: C:\\Users\Bob\\Desktop\\RPA Examples\\data.xlsx - -# Read information from the excel in the second row, for columns 2 to 10 -lookup_terms = [] -for col in range(2,10): - try: - print(col) - lookup_terms.append(ExcelReadCell(excel_path, 2, col)) - except: - pass - -# Open Chrome -browser = ChromeBrowser() - -for j,item in enumerate(lookup_terms): - - # Browse to Google - browser.get('https://google.com') - # Lookup the searchterm - browser.find_element_by_xpath('//*[@id="lst-ib"]').send_keys(item) - # Search - browser.find_element_by_xpath('//*[@id="lst-ib"]').submit() - # Get all found items - articles = browser.find_elements_by_class_name("g") - # Parse the headertexts to find the urls - urls = [] - for article in articles: - try: - import re - urls.append(re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', article.text)[0]) - except: - pass - - # Write found urls to Excel - for i,url in enumerate(urls): - ExcelWriteCell(excel_path, row=i+2, col=j+2, write_value=url) - -# Exit the browser -browser.quit() - -# Open the Excel to show result -StartFile(excel_path) diff --git a/examples/multiprogram/data.xlsx b/examples/multiprogram/data.xlsx deleted file mode 100644 index fecd5ebe..00000000 Binary files a/examples/multiprogram/data.xlsx and /dev/null differ diff --git a/examples/november_training/excercise.py b/examples/november_training/excercise.py deleted file mode 100644 index 5bfa8f08..00000000 --- a/examples/november_training/excercise.py +++ /dev/null @@ -1,49 +0,0 @@ -from automagica import * - -def click_qlik_sheet(name): - sheets = browser.find_elements_by_class_name('thumb-hover') - for i, app in enumerate(browser.find_elements_by_id('item-title')): - if name.lower() in app.text.lower(): - sheets[i].click() - return - -def wait_for_qlik_login_screen(): - for i in range(10): - try: - browser.find_element_by_xpath('//*[@id="MemberLoginForm_LoginForm_Username"]') - return - except: - Wait(1) - return - -def get_iframe(): - return browser.find_elements_by_tag_name('iframe')[0].get_attribute('src') - -# Initialise browser and to go qlikid.qlik.com. - - -# Wait for the page to load (login screen specific) - - -# Login using username and password - - -# Go to Qlikcloud.com, directly select the right Sheet. - - -# Wait for page to load - - -# Go into Iframe - - -# Wait for the page to load - - -# Look for the Sheet with summary in it. - - -# Wait for the page to load - - -# Save screenshot diff --git a/examples/november_training/solution.py b/examples/november_training/solution.py deleted file mode 100644 index bb903a1f..00000000 --- a/examples/november_training/solution.py +++ /dev/null @@ -1,59 +0,0 @@ -from automagica import * - -def click_qlik_sheet(name): - sheets = browser.find_elements_by_class_name('thumb-hover') - for i, app in enumerate(browser.find_elements_by_id('item-title')): - if name.lower() in app.text.lower(): - sheets[i].click() - return - -def wait_for_qlik_login_screen(): - for i in range(10): - try: - browser.find_element_by_xpath('//*[@id="MemberLoginForm_LoginForm_Username"]') - return - except: - Wait(1) - return - -def get_iframe(): - return browser.find_elements_by_tag_name('iframe')[0].get_attribute('src') - -# Initialise browser and to go qlikid.qlik.com. -browser = ChromeBrowser() -browser.get('https://qlikid.qlik.com/signin') - -# Wait for the page to load (login screen specific) -wait_for_qlik_login_screen() - -# Login using username and password -username_field = browser.find_element_by_xpath('//*[@id="MemberLoginForm_LoginForm_Username"]') -username_field.send_keys('USERNAME') - -password_field = browser.find_element_by_xpath('//*[@id="MemberLoginForm_LoginForm_Password"]') -password_field.send_keys('PASSWORD') - -login_button = browser.find_element_by_xpath('/html/body/section/div/div[2]/input[1]') -login_button.click() - -# Go to Qlikcloud.com, directly select the right Sheet. -browser.get('https://eu.qlikcloud.com/view/5981e189428a420001e16cab') - -# Wait for page to load -Wait(5) - -# Go into Iframe -browser.get(get_iframe()) - -# Wait for the page to load -Wait(5) - -# Look for the Sheet with summary in it. -click_qlik_sheet('summary') - -# Wait for the page to load -Wait(5) - -# Save screenshot -browser.save_screenshot('result.png') -print('Saved Screenshot!') \ No newline at end of file diff --git a/examples/ocr/app.py b/examples/ocr/app.py deleted file mode 100644 index 3042f3b3..00000000 --- a/examples/ocr/app.py +++ /dev/null @@ -1,8 +0,0 @@ -from automagica import * - -""" -Extracts text from image -""" - -text = ExtractTextFromImage('example.jpg') -print(text) diff --git a/examples/ocr/example.jpg b/examples/ocr/example.jpg deleted file mode 100644 index 131d1826..00000000 Binary files a/examples/ocr/example.jpg and /dev/null differ diff --git a/examples/ocr_automation_example.ipynb b/examples/ocr_automation_example.ipynb new file mode 100644 index 00000000..bef1c854 --- /dev/null +++ b/examples/ocr_automation_example.ipynb @@ -0,0 +1,188 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Optical Character Recognition\n", + "\n", + "In this example we will go over the Optical Character Recognition possibilities of Automagica" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initializing Automagica\n", + "\n", + "The first step in building a script with Automagica is to import all the Automagica activities." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from automagica import *" + ] + }, + { + "attachments": { + "example_ocr_thumbn.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Downloading a sample file\n", + "\n", + "To demonstrate the OCR capabilities we will use a sample image file directly downloaded from the Automagica website. The image can be found and viewed on:\n", + "\n", + "https://automagica.com/examples/ocr_test.jpg\n", + "\n", + "There is no text-layer on this jpg image, the goal is to read the text while using OCR.\n", + "\n", + "![example_ocr_thumbn.png](attachment:example_ocr_thumbn.png)\n", + "\n", + "We could specify a path, but by default the download_file_from_url activity will download to the homedir." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Download the file \n", + "downloaded_image = download_file_from_url('https://automagica.com/examples/ocr_test.jpg')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now open the file to view it's contents " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'C:\\\\Users\\\\TvT\\\\wallpaper.jpg'" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "open_file(downloaded_image)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Reading with OCR\n", + "\n", + "Let's attempt to read the text of the newly downloaded image" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Why was the robot embarassed? Because it had hardware but no underwear!'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Read image\n", + "extract_text_ocr(r\"C:\\Users\\TvT\\Desktop\\ocr_test.png\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Automate using OCR\n", + "\n", + "Another use-case for this activity could be to automatically find elements like buttons on the screen and click on them, for example.\n", + "\n", + "Make sure the image is open and visible on the screen, next we can find the coördinates of the word \"underwear\"" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'h': 10, 'text': 'underwear', 'w': 67, 'x': 2356, 'y': 1427}]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "find_text_on_screen_ocr('underwear')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also click on the word!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "click_on_text_ocr('underwear')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "'Python Interactive'", + "language": "python", + "name": "bb341ba4-98f7-43a2-996e-ea9a75df951a" + }, + "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.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/examples/paint/app.py b/examples/paint/app.py deleted file mode 100644 index 7daeca46..00000000 --- a/examples/paint/app.py +++ /dev/null @@ -1,93 +0,0 @@ -from PIL import Image -from pyautogui import click, hotkey, moveTo, typewrite, locateCenterOnScreen, rightClick -import time -from automagica import * -from pywinauto import Application - -app = Application().start('mspaint.exe') -app.Paint.move_window(x=0, y=0, width=740, height=580, repaint=True) - - -im = Image.open('example.jpg') - -X_total = im.size[0] -Y_total = im.size[1] -XY_total = X_total * Y_total - - -if X_total > Y_total: - new_width = 70 - new_height = int(new_width * (Y_total / X_total)) -else: - new_height = 70 - new_width = int(new_height * (X_total / Y_total)) - -im= im.resize((new_width, new_height), Image.ANTIALIAS) - -im = im.convert(mode='P', colors=16) -rgb_im = im.convert('RGB') - -X_total = im.size[0] -Y_total = im.size[1] -XY_total = X_total * Y_total - -instructions = [] - -x=1 -y=1 - -while x < X_total-1: - x = x + 1 - y = 1 - while y < Y_total-1: - r, g, b = rgb_im.getpixel((x, y)) - instructions.append([4*x+30,4*y+165,r,g,b,3*r+4*g+6*b]) - y = y + 1 - -instructions.sort(key=lambda x: x[5], reverse=True) - -print(instructions) - -def colorpicker(r,g,b): - click(624,83) - click(624,83) - click(555,362) - click(555,362) - time.sleep(0.1) - typewrite(str(r)) - click(555,382) - click(555,382) - time.sleep(0.1) - typewrite(str(g)) - click(555,412) - click(555,412) - time.sleep(0.1) - typewrite(str(b)) - click(172,433) - - return - -color = 1 - -#Select Paint window -click(325,17) - -#Select correct tool -click(126,78) -time.sleep(0.1) - -#Select thick line -click(125,167) -time.sleep(0.1) -click(271,16) -time.sleep(0.1) -click(270,78) -time.sleep(0.3) -click(312,267) - -for item in instructions: - if not (item[2] == 255 and item[3] == 255 and item[4] == 255): #drop white colors - if not item[5] == color: - colorpicker(item[2],item[3],item[4]) - color = item[5] - click(item[0],item[1]) diff --git a/examples/paint/example.jpg b/examples/paint/example.jpg deleted file mode 100644 index a7f17acb..00000000 Binary files a/examples/paint/example.jpg and /dev/null differ diff --git a/examples/ppt_automation_example.ipynb b/examples/ppt_automation_example.ipynb new file mode 100644 index 00000000..6c750e5b --- /dev/null +++ b/examples/ppt_automation_example.ipynb @@ -0,0 +1,268 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# PowerPoint Automation\n", + "\n", + "In this example we will build a fully automated PowerPoint presentation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initializing Automagica\n", + "\n", + "The first step in building a script with Automagica is to import all the Automagica activities." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from automagica import *" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Starting PowerPoint\n", + "\n", + "Start by opening PowerPoint, in this case we will give the instance the name 'presentation'. Feel free to give this any name you want, as long as you consistently use it when addressing it." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "presentation = PowerPoint()" + ] + }, + { + "attachments": { + "powerpoint1.png": { + "image/png": "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LKapqVFVhmI8Mr2x2d38qj8REVFf9dmmT1VlKMYj0+Mv9hMRkWU98K3vqMpQjEem9+orL6qKiIjIYvbv36sqQzEemd5NN61UFRERkcWcLStVlaEYj0yvXz8+iEREZFE3r/ySqgzFntX01q19R1VEREQWs+WzjaoyFOOR6d3x9TtVRUREZDGXL19WlaEYj0zvZGGBqoiIiCzm6qXXqMpQjEemt3fPblURERFZzLN/fVpVhmI8Mr37H3hIVURERBYzZep0VRmK8cj0Ply/TlVEREQWE6TvRmY8Mr1Lly6pioiIyGLWvPayqgzFeGR6QfrKByIiotA3f8EiVRmK8cj0/v56UIIzERFR6Ovfv7+qDMV4ZHqpqemqIiIispjN/FpIcilIX/lAREQU+u69/0FVGYrxyPSef/YZVREREVlMcdFJVRmK8cj05s1fqCoiIiKL2fN5UL4bmfHI9AYNGqwqIiIii7ntjm+oylCMR6a3/v21qiIiIrKYHdu2qMpQjEemd931N6mKiIjIYoL03ciMR6bX2tqiKiIiIotZdPVSVRmK8cj0gvSVD0RERKHvzb+/qipDMR6Z3j33PqAqIiIii0lOTlWVoRiPTG/Xjm2qIiIispiZV81WlaEYj0zvzJkSVREREVnMG2teU5WhGI9ML0hf+UBERBT65s6brypDMR6Z3icff6AqIiIiixk8OFFVhmI8Mr2oqGhVERERWcwH69epylCMR6a3ODhf+UBERBT6vvSV21VlKMYj0/vbC8+qioiIyGJqqqtUZSjGI9ObkDtJVURERBazb+/nqjIU45HpjZ+QqyoiIiKL+fJX7lCVoRiPTO/Nv7+uKiIiIovZvWuHqgzFeGR6y665VlVEREQWU1tboypDMR6Z3sWLbaoiIiKymOtvXKEqQzEemd6WzZtURUREZDGfbvhQVYZiPDK9W7/8VVURERFZTGRklKoMxXhkemdK+JO0RERkUYuC893IjEeml388T1VEREQW89KLz6vKUIxHphekr3wgIiIKfbNmXaUqQzEemd7GjRtURUREZDGJicmqMhTjkeldbOMH+4mIyKI++vB9VRmK8cj0gvSVD0RERKFvydLlqjIU45HprXv3LVURERFZTHv7RVUZivHI9IYNH6EqIiIii9m65TNVGYrxyPRyxk9QFRERkcV84857VGUoxiPTe+ftN1RFRERk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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We have now created an empty PowerPoint presentation without any slides\n", + "\n", + "![powerpoint1.png](attachment:powerpoint1.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Making our first slide\n", + "\n", + "Let's first add a slide to the presentation." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "presentation.add_slide()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we need some content. Let's make a short text where we introduce ourselves and add this to the first slide. The first slide will have index 1" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "presentation.add_text(text='Hi, my name is Bob', index=1)" + ] + }, + { + "attachments": { + "powerpoint2.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Your presentation should look something like:\n", + "\n", + "![powerpoint2.png](attachment:powerpoint2.png)\n", + "\n", + "Let us add a second slide and add some content aswell" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Make new slide\n", + "presentation.add_slide()\n", + "\n", + "# Add content\n", + "presentation.add_text(text='My friends call me Bob', index=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Imagine the situation where someone else instead of Bob would want to give this presentation, we can easily replace his name with the Automagica built-in function:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# Replace all occurences of \"Bob\" with \"Karen\"\n", + "presentation.replace_text('Bob', 'Karen')" + ] + }, + { + "attachments": { + "powerpoint3.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The presentation is now about Karen:\n", + "\n", + "![powerpoint3.png](attachment:powerpoint3.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Saving Data\n", + "\n", + "We can now save the presentation, we choose to both save it as .pdf and as .pptx. Finally let's not forget to exit PowerPoint.\n", + "\n", + "We first declare the pathq using the Automagica built-in home_path function to make sure we know where it is saved" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Declare paths, in this case in the homedir with the names \"awesome_presentation.pptx\" and \"awesome_presentation.pdf\"\n", + "presentation_pptx = home_path('awesome_presentation.pptx')\n", + "\n", + "presentation_pdf = home_path('awesome_presentation.pdf')" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Save pptx\n", + "presentation.save_as(presentation_pptx)\n", + "\n", + "# Save pdf\n", + "presentation.export_to_pdf(presentation_pdf)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now exit PowerPoint" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "presentation.quit()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As a last stap we can re-open the file we just saved to verify:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'C:\\\\Users\\\\TvT\\\\awesome_presentation.pdf'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "open_file(presentation_pdf)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "'Python Interactive'", + "language": "python", + "name": "bb341ba4-98f7-43a2-996e-ea9a75df951a" + }, + "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.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/sap/app.py b/examples/sap/app.py deleted file mode 100644 index a74b7950..00000000 --- a/examples/sap/app.py +++ /dev/null @@ -1,22 +0,0 @@ -import win32com.client - -""" -Performs transaction FEBAN within SAP GUI -Requires scripting engine within SAP GUI to be enabled. - -This works only on Windows platform, because SAP GUI only supports Windows. -""" - -sapgui = win32com.client.GetObject("SAPGUI").GetScriptingEngine - -sap = sapgui.FindById("ses[0]") - -sap.StartTransaction("FEBAN") - -sap.FindById("/app/con[0]/ses[0]/wnd[1]/usr/ctxtSL_BUKRS-LOW").text = "1234" - -sap.FindById("/app/con[0]/ses[0]/wnd[1]/usr/ctxtSL_BUKRS-HIGH").text = "5678" - -sap.FindById("/app/con[0]/ses[0]/wnd[1]/usr/ctxtSL_HBKID-LOW").text = "9012" - - diff --git a/examples/word/app.py b/examples/word/app.py deleted file mode 100644 index 14bd5147..00000000 --- a/examples/word/app.py +++ /dev/null @@ -1,24 +0,0 @@ -from automagica import * - -""" -Opens a template Word document, replaces a template with content and saves as a new file. -""" - -document = OpenWordDocument('example.docx') - -new_document = ReplaceText(document, text='[template]', replace_with='invoice 123456') - -new_document.save('result.docx') - -""" -Opens the new file and saves it as PDF (all in the background). -This only works on Windows with Microsoft Office installed! -""" - -import os - -full_path_word_file = os.path.join(os.getcwd(), 'result.docx') - -full_path_pdf_file = full_path_word_file.replace('.docx', '.pdf') - -ConvertWordToPDF(word_filename=full_path_word_file, pdf_filename=full_path_pdf_file) diff --git a/examples/word/example.docx b/examples/word/example.docx deleted file mode 100644 index b01927e7..00000000 Binary files a/examples/word/example.docx and /dev/null differ diff --git a/examples/workshop/workshop_demo.py b/examples/workshop/workshop_demo.py deleted file mode 100644 index f88970bb..00000000 --- a/examples/workshop/workshop_demo.py +++ /dev/null @@ -1,143 +0,0 @@ -""" -Initialising Automagica -"""" - -from automagica import * - -""" -Browser Automation - Opening -"""" - -from automagica import * -browser = ChromeBrowser() - -""" -Browser Automation - Opening Google.com -"""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://google.com') - -""" -Browser Automation - Opening Google.com and showing title -"""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://google.com') -title = browser.title -browser.close() -DisplayMessageBox(title) - -""" -Browser Automation - Searching on Google with Xpath -""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://google.com') -# Enter Search Text -browser.find_element_by_xpath('//*[@id="lst-ib"]').send_keys('Oslo') -# Submit -browser.find_element_by_xpath('//*[@id="lst-ib"]').submit() - -""" -Browser Automation - Searching on Google with ?q in URL -""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://google.com/?q=oslo') - -""" -Browser Automation - Searching on Bing with Xpath -""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://bing.com') -# Enter Search Text -browser.find_element_by_xpath('//*[@id="sb_form_q"]').send_keys('Oslo') -# Submit -browser.find_element_by_xpath('//*[@id="sb_form_q"]').submit() - -""" -Browser Automation - Searching on Bing with ?q in URL -""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://bing.com/?q=oslo') - -""" -Finding Google search results with Automagica -""" - -from automagica import * -GetGoogleSearchLinks("oslo") - -""" -Visit every Google Search Result for Oslo -""" - -from automagica import * -browser = ChromeBrowser() -for link in GetGoogleSearchLinks("oslo"): - browser.get(link) - -""" -Save every Google Search Result for Oslo in a .txt -""" - -from automagica import * -browser = ChromeBrowser() -links = GetGoogleSearchLinks("oslo") -WriteListToFile(links, file="results.txt") - -""" -Browser Automation - Closing -"""" -from automagica import * - -browser = ChromeBrowser() -browser.get('https://bing.com') -title = browser.title -if not "Google" in title: - browser.close() - DisplayMessageBox(title, title="Oops!", type="warning") - -""" -Simple Mouse Example 1 -""" - -from automagica import * -GetMouseCoordinates() - -""" -Simple Mouse Example 2 -""" - -from automagica import * -x = 100 -y = 100 -DoubleClickOnPosition(x, y) - -""" -Simple Mouse Example - Failsafe -""" - -from automagica import * -import random - -for i in range(0,10): - random_X_position = random.randint(300,500) - random_Y_position = random.randint(300,500) - DragToPosition(random_X_position, random_Y_position) - -""" -Copy File, in this case an xlsx -""" -from automagica import * -Copyfile("example.xlsx", "copy.xlsx") - diff --git a/examples/workshop/workshop_demo_oslo.py b/examples/workshop/workshop_demo_oslo.py deleted file mode 100644 index f88970bb..00000000 --- a/examples/workshop/workshop_demo_oslo.py +++ /dev/null @@ -1,143 +0,0 @@ -""" -Initialising Automagica -"""" - -from automagica import * - -""" -Browser Automation - Opening -"""" - -from automagica import * -browser = ChromeBrowser() - -""" -Browser Automation - Opening Google.com -"""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://google.com') - -""" -Browser Automation - Opening Google.com and showing title -"""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://google.com') -title = browser.title -browser.close() -DisplayMessageBox(title) - -""" -Browser Automation - Searching on Google with Xpath -""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://google.com') -# Enter Search Text -browser.find_element_by_xpath('//*[@id="lst-ib"]').send_keys('Oslo') -# Submit -browser.find_element_by_xpath('//*[@id="lst-ib"]').submit() - -""" -Browser Automation - Searching on Google with ?q in URL -""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://google.com/?q=oslo') - -""" -Browser Automation - Searching on Bing with Xpath -""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://bing.com') -# Enter Search Text -browser.find_element_by_xpath('//*[@id="sb_form_q"]').send_keys('Oslo') -# Submit -browser.find_element_by_xpath('//*[@id="sb_form_q"]').submit() - -""" -Browser Automation - Searching on Bing with ?q in URL -""" - -from automagica import * -browser = ChromeBrowser() -browser.get('https://bing.com/?q=oslo') - -""" -Finding Google search results with Automagica -""" - -from automagica import * -GetGoogleSearchLinks("oslo") - -""" -Visit every Google Search Result for Oslo -""" - -from automagica import * -browser = ChromeBrowser() -for link in GetGoogleSearchLinks("oslo"): - browser.get(link) - -""" -Save every Google Search Result for Oslo in a .txt -""" - -from automagica import * -browser = ChromeBrowser() -links = GetGoogleSearchLinks("oslo") -WriteListToFile(links, file="results.txt") - -""" -Browser Automation - Closing -"""" -from automagica import * - -browser = ChromeBrowser() -browser.get('https://bing.com') -title = browser.title -if not "Google" in title: - browser.close() - DisplayMessageBox(title, title="Oops!", type="warning") - -""" -Simple Mouse Example 1 -""" - -from automagica import * -GetMouseCoordinates() - -""" -Simple Mouse Example 2 -""" - -from automagica import * -x = 100 -y = 100 -DoubleClickOnPosition(x, y) - -""" -Simple Mouse Example - Failsafe -""" - -from automagica import * -import random - -for i in range(0,10): - random_X_position = random.randint(300,500) - random_Y_position = random.randint(300,500) - DragToPosition(random_X_position, random_Y_position) - -""" -Copy File, in this case an xlsx -""" -from automagica import * -Copyfile("example.xlsx", "copy.xlsx") - diff --git a/setup.py b/setup.py index 16521508..be1171b5 100644 --- a/setup.py +++ b/setup.py @@ -3,36 +3,44 @@ import setuptools from distutils.core import setup -setup(name='Automagica', - version='1.0.10', - description='Robot for Automagica - Smart Robotic Process Automation', - author='Oakwood Technologies BVBA', - author_email='mail@oakwood.ai', - url='https://automagica.io/', - entry_points={ - 'console_scripts': ['automagica=automagica.cli:main'], - }, - packages=['automagica'], - package_data={'automagica': [ - 'bin/win32/chromedriver.exe', - 'bin/mac64/chromedriver', - 'bin/linux64/chromedriver']}, - install_requires=[ - 'plyer==1.4.0', - 'python-socketio==4.3.0', - 'PyAutoGUI==0.9.36', - 'opencv-python==3.4.2.17', - 'selenium==3.7.0', - 'pytesseract==0.2.0', - 'openpyxl==2.4.8', - 'python-docx==0.8.6', - 'PyPDF2==1.26.0', - 'psutil==5.4.6', - 'beautifulsoup4==4.6.0', - 'websocket-client==0.56.0', - 'py-trello==0.13.0'] + ( - ['pywinauto==0.6.5', 'pywin32==223'] if sys.platform.startswith('win') else [ - ] - ), - include_package_data=True - ) +setup( + name="Automagica", + version="2.0.0", + description="Bot for Automagica", + author="Oakwood Technologies BVBA", + author_email="mail@oakwood.ai", + url="https://automagica.com/", + entry_points={"console_scripts": ["automagica=automagica.cli:main"]}, + packages=["automagica"], + package_data={ + "automagica": [ + "bin/win32/chromedriver.exe", + "bin/mac64/chromedriver", + "bin/linux64/chromedriver", + ] + }, + install_requires=[ + "requests==2.18.4", + "plyer==1.4.0", + "Pillow==5.0.0", + "PyAutoGUI==0.9.36", + "selenium==3.7.0", + "openpyxl==2.4.8", + "python-docx==0.8.6", + "PyPDF2==1.26.0", + "faker==2.0.3", + "psutil==5.4.6", + "keyring==13.0.0", + "PySimpleGUI==4.4.1", + "keyring==13.0.0", + "cryptography==2.3.1", + "python-docx==0.8.6", + "pyttsx3==2.71", + "pyad==0.6.0", + "jupyterlab==0.32.1", + "py-trello==0.13.0", + ] + + (["pywinauto==0.6.5", "pywin32==225"] if sys.platform.startswith("win") else []), + include_package_data=True, +) +