Merge branch 'master' of https://gitlab.com/UnicodeLabs/OpenRPA.git
@ -0,0 +1,3 @@
|
||||
for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do (
|
||||
%windir%\System32\tscon.exe %%s /dest:console
|
||||
)
|
@ -0,0 +1,14 @@
|
||||
import time #lib to create delay
|
||||
from . import Screen # module to detect screen exists
|
||||
#Check screen every 1 second
|
||||
def CheckScreen(inIntervalSeconds=1):
|
||||
while True:
|
||||
#Check if screen exist
|
||||
if not Screen.Exists():
|
||||
#Send os command to create console version (base screen)
|
||||
Screen.ConsoleScreenBase()
|
||||
#Delay to create console screen
|
||||
time.sleep(2)
|
||||
#Delay
|
||||
time.sleep(inIntervalSeconds)
|
||||
return None
|
@ -0,0 +1,20 @@
|
||||
from PIL import ImageGrab
|
||||
import os # to execute cmd commands
|
||||
#Check if screen is exists
|
||||
def Exists():
|
||||
#Try to get 1 px from screen
|
||||
try:
|
||||
#Take 1 px
|
||||
ImageGrab.grab(bbox=(0,0,1,1))
|
||||
#Screen is exists - return True
|
||||
return True
|
||||
#Catch exception
|
||||
except Exception:
|
||||
#Screen does not exists - return false
|
||||
return False
|
||||
#Make console session
|
||||
def ConsoleScreenBase():
|
||||
#Get script folder path
|
||||
lFolderPath = "/".join(__file__.split("\\")[:-1])
|
||||
#Send command to cmd
|
||||
os.system(os.path.join(lFolderPath,"ConsoleStart.bat"))
|
@ -0,0 +1,16 @@
|
||||
#Run example
|
||||
#cd %~dp0..\..\Sources
|
||||
#..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe -m pyOpenRPA.Tools.RobotScreenActive
|
||||
#pause >nul
|
||||
#Import parent folder to import current / other packages
|
||||
#########################################################
|
||||
import sys
|
||||
import subprocess #start process async
|
||||
import os #path, run, remove
|
||||
import time #timer
|
||||
import importlib
|
||||
#lFolderPath = "\\".join(__file__.split("\\")[:-4])
|
||||
lFolderPath = "/".join(__file__.split("/")[:-4])
|
||||
sys.path.insert(0, lFolderPath)
|
||||
from pyOpenRPA.Tools.RobotScreenActive import Monitor
|
||||
Monitor.CheckScreen()
|
@ -0,0 +1,646 @@
|
||||
var mGlobal={}
|
||||
$(document).ready(function() {
|
||||
// fix main menu to page on passing
|
||||
$('.main.menu').visibility({
|
||||
type: 'fixed'
|
||||
});
|
||||
$('.overlay').visibility({
|
||||
type: 'fixed',
|
||||
offset: 80
|
||||
});
|
||||
|
||||
// lazy load images
|
||||
$('.image').visibility({
|
||||
type: 'image',
|
||||
transition: 'vertical flip in',
|
||||
duration: 500
|
||||
});
|
||||
|
||||
// show dropdown on hover
|
||||
$('.main.menu .ui.dropdown').dropdown({
|
||||
on: 'hover'
|
||||
});
|
||||
function clone(obj) {
|
||||
var copy;
|
||||
|
||||
// Handle the 3 simple types, and null or undefined
|
||||
if (null == obj || "object" != typeof obj) return obj;
|
||||
|
||||
// Handle Date
|
||||
if (obj instanceof Date) {
|
||||
copy = new Date();
|
||||
copy.setTime(obj.getTime());
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Array
|
||||
if (obj instanceof Array) {
|
||||
copy = [];
|
||||
for (var i = 0, len = obj.length; i < len; i++) {
|
||||
copy[i] = clone(obj[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Object
|
||||
if (obj instanceof Object) {
|
||||
copy = {};
|
||||
for (var attr in obj) {
|
||||
if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
throw new Error("Unable to copy obj! Its type isn't supported.");
|
||||
}
|
||||
//For data storage key
|
||||
mGlobal["DataStorage"] = {}
|
||||
|
||||
String.prototype.replaceAll = function(search, replace){
|
||||
return this.split(search).join(replace);
|
||||
}
|
||||
mGlobal.GeneralGenerateHTMLCodeHandlebars=function(inInnerTemplateSelector,inData) {
|
||||
lHTMLTemplate=$(inInnerTemplateSelector)[0].innerHTML
|
||||
//console.log(lHTMLTemplate)
|
||||
//Компиляция
|
||||
var template = Handlebars.compile(lHTMLTemplate);
|
||||
//Вставка данных
|
||||
var lHTMLResult = template(inData);
|
||||
return lHTMLResult
|
||||
}
|
||||
mGlobal.GeneralGenerateHTMLCode=function(inTemplateHTMLSelector,inItemDictionary,inKeywordPrefix="::",inKeywordPostfix="::") {
|
||||
///Получить заготовку
|
||||
lTemplateHTMLCode=$(inTemplateHTMLSelector)[0].outerHTML
|
||||
///Определить ключь экранирования специальных ключевых слов
|
||||
///Выполнить циклические замены, если там есть пожходящие ключи
|
||||
lResultHTMLCode=lTemplateHTMLCode
|
||||
for(var lKey in inItemDictionary) {
|
||||
lHTMLKey=inKeywordPrefix+lKey+inKeywordPostfix;
|
||||
lResultHTMLCode=lResultHTMLCode.replaceAll(lHTMLKey,inItemDictionary[lKey])
|
||||
}
|
||||
///Вернуть результат
|
||||
return lResultHTMLCode
|
||||
}
|
||||
//////////////////////////
|
||||
/////Info JS module
|
||||
//////////////////////////
|
||||
mGlobal.Info={};
|
||||
|
||||
mGlobal.Info.TableActivityLogScheduleListRefresh=function() {
|
||||
|
||||
}
|
||||
//////////////////////////
|
||||
/////Controller JS module
|
||||
//////////////////////////
|
||||
mGlobal.Controller={};
|
||||
mGlobal.Controller.CMDRunText=function(inCMDText) {
|
||||
///Подготовить конфигурацию
|
||||
lData = [
|
||||
{"Type":"CMDStart", "Command": inCMDText}
|
||||
]
|
||||
///Обнулить таблицу
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3){},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Controller.CMDRun=function() {
|
||||
///Обнулить таблицу
|
||||
lCMDCode=$(".openrpa-controller-cmd-run-input")[0].value
|
||||
///Подготовить конфигурацию
|
||||
lData = [
|
||||
{"Type":"CMDStart", "Command": lCMDCode }
|
||||
]
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///Отправить запрос на формирование таблицы
|
||||
//lHTMLCode=console.log("CMDRun result: "+lResponseJSON[0].result)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Controller.CMDRunGUILogout=function() {
|
||||
///Обнулить таблицу
|
||||
lCMDCode="for /f \"skip=1 tokens=2\" %s in ('query user %USERNAME%') do (tscon \\dest:console)"
|
||||
//lCMDCode = lCMDCode.replace(/\\n/g, "\\n")
|
||||
// .replace(/\\'/g, "\\'")
|
||||
// .replace(/\\"/g, '\\"')
|
||||
// .replace(/\\&/g, "\\&")
|
||||
// .replace(/\\r/g, "\\r")
|
||||
// .replace(/\\t/g, "\\t")
|
||||
// .replace(/\\b/g, "\\b")
|
||||
// .replace(/\\f/g, "\\f")
|
||||
// .replace('"', "\\\"");
|
||||
///Подготовить конфигурацию
|
||||
lData = [
|
||||
{"Type":"CMDStart", "Command": lCMDCode }
|
||||
]
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///Отправить запрос на формирование таблицы
|
||||
//lHTMLCode=console.log("CMDRun result: "+lResponseJSON[0].result)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
///Перезагрузить Orchestrator
|
||||
mGlobal.Controller.OrchestratorRestart=function() {
|
||||
///Подготовить конфигурацию
|
||||
lData = [
|
||||
{"Type":"OrchestratorRestart"}
|
||||
]
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
//////////////////////////
|
||||
/////Monitor JS module
|
||||
//////////////////////////
|
||||
mGlobal.Monitor={};
|
||||
mGlobal.Monitor.ScreenshotModal={};
|
||||
mGlobal.Monitor.GenerateUniqueID=function(inPrefix="tempUID=") {
|
||||
return inPrefix+Math.round(Math.random()*1000)+"-"+Math.round(Math.random()*10000)+"-"+Math.round(Math.random()*1000)
|
||||
}
|
||||
//inHostURI: http://localhost:8081
|
||||
mGlobal.Monitor.ScreenshotModal.Show=function(inHostURI=" ") {
|
||||
$('.ui.modal.daemon-screenshot').modal('show');
|
||||
|
||||
//Функция обновления картинки
|
||||
lScreenshotUpdate=function() {
|
||||
lScreenshotSrc=inHostURI+"/GetScreenshot?"+mGlobal.Monitor.GenerateUniqueID()
|
||||
$(".daemon-screenshot img").attr('src', lScreenshotSrc);
|
||||
}
|
||||
|
||||
mGlobal.Monitor.ScreenshotModal.timerId=setInterval(lScreenshotUpdate,1500)
|
||||
}
|
||||
mGlobal.Monitor.ScreenshotModal.Close=function() {
|
||||
clearInterval(mGlobal.Monitor.ScreenshotModal.timerId);
|
||||
}
|
||||
///Monitor
|
||||
mGlobal.Monitor.DaemonList={}
|
||||
mGlobal.Monitor.DaemonList.fRefreshTable=function() {
|
||||
///Загрузка данных
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'Monitor/JSONDaemonListGet',
|
||||
data: '',
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///Сформировать HTML код новой таблицы
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-monitor-table-general",lResponseJSON)
|
||||
///Очистить дерево
|
||||
//mGlobal.ElementTree.fClear();
|
||||
///Прогрузить новую таблицу
|
||||
$(".openrpa-monitor").html(lHTMLCode)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
////////////////////////////////
|
||||
///////Control panel
|
||||
///////////////////////////////
|
||||
///Refresh control panel
|
||||
mGlobal.Monitor.fControlPanelRefresh=function() {
|
||||
///Загрузка данных
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'Monitor/ControlPanelDictGet',
|
||||
data: '',
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///Escape onclick
|
||||
/// RenderRobotList
|
||||
lResponseJSON["RenderRobotList"].forEach(
|
||||
function(lItem){
|
||||
if ('FooterButtonX2List' in lItem) {
|
||||
/// FooterButtonX2List
|
||||
lItem["FooterButtonX2List"].forEach(
|
||||
function(lItem2){
|
||||
if ('OnClick' in lItem) {
|
||||
lOnClickEscaped = lItem["OnClick"];
|
||||
lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
||||
lItem["OnClick"] = lOnClickEscaped;
|
||||
}
|
||||
}
|
||||
);
|
||||
/// FooterButtonX1List
|
||||
lItem["FooterButtonX1List"].forEach(
|
||||
function(lItem2){
|
||||
if ('OnClick' in lItem) {
|
||||
lOnClickEscaped = lItem["OnClick"];
|
||||
lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
||||
lItem["OnClick"] = lOnClickEscaped;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
///Сформировать HTML код новой таблицы
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-control-panel",lResponseJSON)
|
||||
//Присвоить ответ в mGlobal.Monitor.mResponseList
|
||||
mGlobal.Monitor.mResponseList = lResponseJSON
|
||||
///Set result in mGlobal.DataStorage
|
||||
lResponseJSON["RenderRobotList"].forEach(
|
||||
function(lItem){
|
||||
if ('DataStorageKey' in lItem) {
|
||||
mGlobal["DataStorage"][lItem['DataStorageKey']]=lItem
|
||||
}
|
||||
}
|
||||
)
|
||||
///Очистить дерево
|
||||
//mGlobal.ElementTree.fClear();
|
||||
///Прогрузить новую таблицу
|
||||
$(".openrpa-control-panel").html(lHTMLCode)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
///
|
||||
mGlobal.Monitor.mControlPanelAutoUpdateSeconds=3;
|
||||
mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent=3;
|
||||
mGlobal.Monitor.fControlPanelAutoUpdateRun=function(inRefreshSeconds) {
|
||||
mGlobal.Monitor.mControlPanelAutoUpdateSeconds=inRefreshSeconds;
|
||||
//Функция обновления текста кнопки обновления
|
||||
lControlPanelUpdate=function() {
|
||||
mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent=mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent-1
|
||||
if (mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent==-1) {
|
||||
mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent=mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent=mGlobal.Monitor.mControlPanelAutoUpdateSeconds;
|
||||
mGlobal.Monitor.fControlPanelRefresh()
|
||||
}
|
||||
$(".openrpa-control-panel-general .openrpa-refresh-button").html("Refresh "+mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent);
|
||||
}
|
||||
mGlobal.Monitor.mControlPanelAutoUpdateTimerId=setInterval(lControlPanelUpdate,1000)
|
||||
}
|
||||
mGlobal.Monitor.fControlPanelRefresh()
|
||||
mGlobal.Monitor.fControlPanelAutoUpdateRun(3);
|
||||
////////////////////////////////
|
||||
/////// /Orchestrator/RobotRDPActive/ControlPanelDictGet
|
||||
///////////////////////////////
|
||||
mGlobal.RobotRDPActive = {}
|
||||
///Refresh control panel
|
||||
mGlobal.RobotRDPActive.fControlPanelRefresh=function() {
|
||||
///Загрузка данных
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'Orchestrator/RobotRDPActive/ControlPanelDictGet',
|
||||
data: '',
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///Сформировать HTML код новой таблицы
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-robotrdpactive-control-panel",lResponseJSON)
|
||||
//Присвоить ответ в mGlobal.RobotRDPActive.mResponseList
|
||||
mGlobal.RobotRDPActive.mResponseList = lResponseJSON
|
||||
///Прогрузить новую таблицу
|
||||
$(".openrpa-robotrdpactive-control-panel").html(lHTMLCode)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
///
|
||||
mGlobal.RobotRDPActive.mControlPanelAutoUpdateSeconds=3;
|
||||
mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent=3;
|
||||
mGlobal.RobotRDPActive.fControlPanelAutoUpdateRun=function(inRefreshSeconds) {
|
||||
mGlobal.RobotRDPActive.mControlPanelAutoUpdateSeconds=inRefreshSeconds;
|
||||
//Функция обновления текста кнопки обновления
|
||||
lControlPanelUpdate=function() {
|
||||
mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent=mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent-1
|
||||
if (mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent==-1) {
|
||||
mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent=mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent=mGlobal.RobotRDPActive.mControlPanelAutoUpdateSeconds;
|
||||
mGlobal.RobotRDPActive.fControlPanelRefresh()
|
||||
}
|
||||
$(".openrpa-robotrdpactive-control-panel-general .openrpa-refresh-button").html("Refresh "+mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent);
|
||||
}
|
||||
mGlobal.RobotRDPActive.mControlPanelAutoUpdateTimerId=setInterval(lControlPanelUpdate,1000)
|
||||
}
|
||||
mGlobal.RobotRDPActive.fControlPanelRefresh()
|
||||
mGlobal.RobotRDPActive.fControlPanelAutoUpdateRun(3);
|
||||
mGlobal.Test=function() {
|
||||
///Обнулить таблицу
|
||||
lData = [
|
||||
{
|
||||
"Type":"GlobalDictKeyListValueSet",
|
||||
"key_list":["Storage","Robot_R01"],
|
||||
"value":{
|
||||
"RunDateTimeString":"Test1",
|
||||
"StepCurrentName":"Test2",
|
||||
"StepCurrentDuration":"Test3"
|
||||
}
|
||||
}
|
||||
]
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
//console.log(lData)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
///////////////////////////////
|
||||
///Processor functions
|
||||
///////////////////////////////
|
||||
mGlobal.Processor = {}
|
||||
mGlobal.Processor.ServerValueAppend = function(inKeyList,inValue) {
|
||||
lData = [
|
||||
{
|
||||
"Type":"GlobalDictKeyListValueAppend",
|
||||
"KeyList": inKeyList,
|
||||
"Value": inValue
|
||||
}
|
||||
]
|
||||
///Обнулить таблицу
|
||||
$('.ui.modal.basic .content').html("");
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///TODO Show error if exist error
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Processor.ServerValueSet = function(inKeyList,inValue) {
|
||||
lData = [
|
||||
{
|
||||
"Type":"GlobalDictKeyListValueSet",
|
||||
"KeyList": inKeyList,
|
||||
"Value": inValue
|
||||
}
|
||||
]
|
||||
///Обнулить таблицу
|
||||
$('.ui.modal.basic .content').html("");
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///TODO Show error if exist error
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Processor.ServerValueOperatorPlus = function(inKeyList,inValue) {
|
||||
lData = [
|
||||
{
|
||||
"Type":"GlobalDictKeyListValueOperator+",
|
||||
"KeyList": inKeyList,
|
||||
"Value": inValue
|
||||
}
|
||||
]
|
||||
///Обнулить таблицу
|
||||
$('.ui.modal.basic .content').html("");
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///TODO Show error if exist error
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Processor.Send = function(inData) {
|
||||
lData = inData
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///TODO Show error if exist error
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Server= {}
|
||||
mGlobal.Server.JSONGet=function(inMethod, inURL, inDataJSON, inCallback)
|
||||
{
|
||||
$.ajax({
|
||||
type: inMethod,
|
||||
url: inURL,
|
||||
data: JSON.stringify(inDataJSON),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
inCallback(lResponseJSON)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
|
||||
/////////////////
|
||||
///Modal
|
||||
///////////////////
|
||||
mGlobal.Modal={}
|
||||
/////////////////////////////////////////////////////
|
||||
mGlobal.Modal.TableFilter={}
|
||||
mGlobal.Modal.TableFilter.Show=function(inJSON) {
|
||||
//{
|
||||
// "Title":"",
|
||||
// "Headers":["Header1","Header2"],
|
||||
// "Rows": [["Cell1","Cell2"],["Cell2-1","Cell2-2"]],
|
||||
// "FilterOnKeyUp": "<JS Code>" //Fill here in function
|
||||
//}
|
||||
//Set js handler to Search field
|
||||
inJSON["FilterOnKeyUp"]="mGlobal.Modal.TableFilter.FilterUpdate(this.value);"
|
||||
///Set value
|
||||
mGlobal.Modal.TableFilter.mDataJSON = inJSON
|
||||
//Render HTML
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-handlebar-template-table-filter",inJSON);
|
||||
///Установить HTML код
|
||||
$('.ui.modal.basic .content').html(lHTMLCode);
|
||||
$('.ui.modal.basic').modal('show');
|
||||
//DO widest modal for table with scroll x
|
||||
$("div.ui.basic.modal.transition.visible.active.scrolling")[0].style["width"]="1300px"
|
||||
$("div.ui.basic.modal.transition.visible.active.scrolling")[0].style["overflow"]="scroll"
|
||||
}
|
||||
//Service function
|
||||
mGlobal.Modal.TableFilter.FilterUpdate=function(inFilterValue) {
|
||||
//Get JSON, apply filter, clone data
|
||||
lDataJSON = clone(mGlobal.Modal.TableFilter.mDataJSON)
|
||||
delete lDataJSON["Rows"]
|
||||
lDataJSON["Rows"]=[]
|
||||
//Filter code [any occurence in the row is ok for push! ]
|
||||
mGlobal.Modal.TableFilter.mDataJSON["Rows"].forEach(
|
||||
function(inElement) {
|
||||
lFlagElementAppend = false
|
||||
inElement.forEach(
|
||||
function(inElement2) {
|
||||
if (String(inElement2).includes(inFilterValue)) {
|
||||
lFlagElementAppend = true
|
||||
}
|
||||
}
|
||||
)
|
||||
if (lFlagElementAppend) {
|
||||
lDataJSON["Rows"].push(inElement)
|
||||
}
|
||||
}
|
||||
)
|
||||
//Clear Filter Title property (fixed in html)
|
||||
delete lDataJSON["FilterOnKeyUp"]
|
||||
delete lDataJSON["Title"]
|
||||
//Search the table element [replace only table html]
|
||||
lElement = $('.ui.modals.active .content table.table')[0]
|
||||
lElementParentElement = lElement.parentNode
|
||||
lElement.parentNode.removeChild(lElement);
|
||||
//Render HTML
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-handlebar-template-table-filter",lDataJSON);
|
||||
///Установить HTML код
|
||||
lElementParentElement.insertAdjacentHTML("beforeend",lHTMLCode);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////
|
||||
mGlobal.Modal.ListFilter={}
|
||||
mGlobal.Modal.ListFilter.Show=function(inJSON) {
|
||||
//{
|
||||
// "Title":"",
|
||||
// "List":[{"Header":"","Description":""}],
|
||||
// "FilterOnKeyUp": "<JS Code>" //Fill here in function
|
||||
//}
|
||||
//Set js handler to Search field
|
||||
inJSON["FilterOnKeyUp"]="mGlobal.Modal.ListFilter.FilterUpdate(this.value);"
|
||||
///Set value
|
||||
mGlobal.Modal.ListFilter.mDataJSON = inJSON
|
||||
//Render HTML
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-handlebar-template-list-filter",inJSON);
|
||||
///Установить HTML код
|
||||
$('.ui.modal.basic .content').html(lHTMLCode);
|
||||
$('.ui.modal.basic').modal('show');
|
||||
}
|
||||
//Service function
|
||||
mGlobal.Modal.ListFilter.FilterUpdate=function(inFilterValue) {
|
||||
//Get JSON, apply filter, clone data
|
||||
lDataJSON = clone(mGlobal.Modal.ListFilter.mDataJSON)
|
||||
delete lDataJSON["List"]
|
||||
lDataJSON["List"]=[]
|
||||
//Filter code [any occurence in the row is ok for push! ]
|
||||
mGlobal.Modal.ListFilter.mDataJSON["List"].forEach(
|
||||
function(inElement) {
|
||||
lFlagElementAppend = false
|
||||
if (String(inElement["Header"]).includes(inFilterValue)) {
|
||||
lFlagElementAppend = true
|
||||
}
|
||||
if (String(inElement["Description"]).includes(inFilterValue)) {
|
||||
lFlagElementAppend = true
|
||||
}
|
||||
if (lFlagElementAppend) {
|
||||
lDataJSON["List"].push(inElement)
|
||||
}
|
||||
}
|
||||
)
|
||||
//Clear Filter Title property (fixed in html)
|
||||
delete lDataJSON["FilterOnKeyUp"]
|
||||
delete lDataJSON["Title"]
|
||||
//Search the table element [replace only table html]
|
||||
lElement = $('.ui.modals.active .content div.ui.inverted.segment')[0]
|
||||
lElementParentElement = lElement.parentNode
|
||||
lElement.parentNode.removeChild(lElement);
|
||||
//Render HTML
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-handlebar-template-list-filter",lDataJSON);
|
||||
///Установить HTML код
|
||||
lElementParentElement.insertAdjacentHTML("beforeend",lHTMLCode);
|
||||
}
|
||||
mGlobal.UserRoleHierarchyDict = null // Put here the user role hierarchy
|
||||
// UAC Ask
|
||||
mGlobal.UserRoleAsk=function(inList) {
|
||||
var lResult = true; // Init flag
|
||||
var lRoleHierarchyDict = mGlobal.UserRoleHierarchyDict; // get the Hierarchy
|
||||
// Try to get value from key list
|
||||
var lKeyValue = lRoleHierarchyDict; // Init the base
|
||||
var lListLength = inList.length;
|
||||
for (var i = 0; i<lListLength; i++) {
|
||||
var lItem = inList[i]; // get the item
|
||||
if (typeof lKeyValue == "object") {
|
||||
if (lItem in lKeyValue) { // Has key
|
||||
lKeyValue = lKeyValue[lItem]; // Get the value and go to the next loop iteration
|
||||
} else { // Else branch - true or false
|
||||
if (Object.keys(lKeyValue).length > 0) { // false - if Dict has some elements
|
||||
lResult = false; // Set the False Flag
|
||||
} else {
|
||||
lResult = true; // Set the true flag
|
||||
}
|
||||
break; // Stop the loop
|
||||
}
|
||||
} else { // Has element with no detalization - return true
|
||||
lResult = true; // Set the flag
|
||||
break; // Close the loop
|
||||
}
|
||||
}
|
||||
return lResult; // Return the result
|
||||
}
|
||||
// Check user roles and update the Orchestrator UI
|
||||
mGlobal.UserRoleUpdate=function() {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Orchestrator/UserRoleHierarchyGet',
|
||||
data: "",
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lUACAsk = mGlobal.UserRoleAsk // Alias
|
||||
var lResponseDict=JSON.parse(lData)
|
||||
mGlobal.UserRoleHierarchyDict = lResponseDict // set the user role hierarchy
|
||||
//Turn on the Lookmachine screenshot button
|
||||
if (lUACAsk(["Orchestrator","Controls","LookMachineScreenshots"])) {
|
||||
$(".openrpa-control-lookmachinescreenshot").show() //Show button
|
||||
}
|
||||
//Turn on the restart orchestrator button
|
||||
if (lUACAsk(["Orchestrator","Controls","RestartOrchestrator"])) {
|
||||
$(".openrpa-control-restartorchestrator").show() //Show button
|
||||
}
|
||||
//Turn on the rdp session list
|
||||
if (lUACAsk(["Orchestrator","RDPActive","ListRead"])) {
|
||||
$(".openrpa-rdpactive-title").show() //Show section
|
||||
$(".openrpa-robotrdpactive-control-panel-general").show() //Show section
|
||||
}
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.UserRoleUpdate() // Cal the update User Roles function
|
||||
});
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 110 KiB |
After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 110 KiB |
@ -0,0 +1,18 @@
|
||||
Dear RPA-tors. Let me congratulate you with great change in the RPA world. **The first enterprise level open source RPA platform is here!**
|
||||
> The OpenRPA - free, fast and reliable
|
||||
|
||||
The **OpenRPA** is based on Python and using well known opensource solutions such as Selenium, OpenCV, Win32, UI automation and others. Thanks to it we were able to create consolidated platform with all possible features.
|
||||
|
||||
The **OpenRPA** is distributed under the MIT license which allows you to use it in any way you want and any time you need without any restrictions.
|
||||
|
||||
At the time of this writing the OpenRPA is successefully using in several big Russian companies. Companies in which it was decided to develop own RPA division with no dependencies on expensive licenses.
|
||||
|
||||
The **OpenRPA** consist of:
|
||||
- WinPython 3.7.1 32-bit & 64-bit, license MIT (https://github.com/winpython/winpython)
|
||||
- Selenium v..., license Apache 2.0
|
||||
- pywinauto 0.6.5, license BSD 3-Clause (https://github.com/pywinauto/pywinauto)
|
||||
- Semantic UI ..., license MIT (https://github.com/Semantic-Org/Semantic-UI)
|
||||
- PyAutoGUI ..., license BSD 3-Clause (https://github.com/asweigart/pyautogui)
|
||||
- keyboard ..., license MIT (https://github.com/boppreh/keyboard)
|
||||
- OpenCV ...
|
||||
- pywin32
|
@ -0,0 +1,41 @@
|
||||
Here you can find information about the OpenRPA modules.
|
||||
|
||||
## The OpenRPA has 3 main tools:
|
||||
- Studio
|
||||
- Robot
|
||||
- Orchestrator
|
||||
## Description
|
||||
`Studio`
|
||||
___
|
||||
Studio tool has been developed to help RPA-tors to create the robot algorythms.<br>
|
||||
___
|
||||
**Features**
|
||||
- Run actions
|
||||
- Create visual algorythms of the robot
|
||||
- Desktop app: Analyze desktop app ui tree
|
||||
- Desktop app: Search desktop app ui by mouse
|
||||
- Desktop app: Generate & edit the UIO Selector
|
||||
___
|
||||
`Robot`
|
||||
___
|
||||
The Robot tool is the core of any action execution in OpenRPA. All action from algorythms are perfoming by the Robot tool. It looks like a console process without graphic user interface.
|
||||
___
|
||||
**Features**
|
||||
- Based on Python (killer feature)
|
||||
- Support Win32 GUI framework (desktop app)
|
||||
- Support UI automation framework (desktop app)
|
||||
- Support Selenium (web app)
|
||||
- Support PyAutoGUI (screen capture & mouse)
|
||||
- Support OpenCV (computer vision)
|
||||
___
|
||||
`Orchestrator`
|
||||
___
|
||||
The Orchestrator tool has been developed to maintain robot infrastructure (2+ robots algorythm).
|
||||
___
|
||||
**Features**
|
||||
- Start/Stop robot algorythm
|
||||
- Robot scheduler
|
||||
- Remote machine screenshot viewer
|
||||
- Remote machine cmd shell
|
||||
- Remote machine logs storage
|
||||
___
|
@ -0,0 +1,21 @@
|
||||
Are you ready to install the OpenRPA solution on your machine?<br>
|
||||
|
||||
Ok, we start. <br>
|
||||
**Do the following operations:**
|
||||
- Download the OpenRPA package from master branch on GitLab [Download ZIP](https://gitlab.com/UnicodeLabs/OpenRPA/-/archive/master/OpenRPA-master.zip)
|
||||
- Unzip the package
|
||||
|
||||
**Installation has been completed :)**
|
||||
|
||||
## How to check installation
|
||||
- Run portable python (built in the OpenRPA)
|
||||
- x32 python (OpenRPA\Resources\WPy32-3720\python-3.7.2\python.exe)
|
||||
- x64 python (OpenRPA\Resources\WPy64-3720\python-3.7.2.amd64\python.exe)
|
||||
|
||||
**The OpenRPA has been successfully installed if the portable python 3.7.2 was started without any exceptions (see screenshot).**
|
||||
![image](uploads/cb5dec8cecafa7d64f6cd14b2672acce/image.png)
|
||||
|
||||
## System requirements
|
||||
- OS Windows 7+
|
||||
- Need Windows package KB2999226 if use windows Vista/7/8/8.1/Server 2008/Server 2012 [Download package](https://support.microsoft.com/ru-ru/help/2999226)
|
||||
- For OpenCV: OS Windows 7/8/8/10 only (no Windows Server)
|
@ -0,0 +1,60 @@
|
||||
# Content
|
||||
- [How to run](#how-to-run)
|
||||
- [UI Description](#ui-description)
|
||||
- [How to extract UI tree](#how-to-extract-ui-tree)
|
||||
- [How to search UI object by mouse hover](#how-to-search-ui-object-by-mouse-hover)
|
||||
- [How to extract UI object properties](#how-to-extract-ui-object-properties)
|
||||
|
||||
# How to run
|
||||
- For OS x32
|
||||
- Run (double click): OpenRPA\Studio\StudioRun_32.cmd (for OS x32)
|
||||
- For OS x64
|
||||
- Run (double click): OpenRPA\Studio\StudioRun_64.cmd (for OS x64)
|
||||
- Wait text "running server" in console. Default browser will be open automatically
|
||||
- **Attention!** The studio tool does not support the Internet explorer (any version) for GUI rendering (lol)
|
||||
![image](uploads/504b98f76747f63900a2943532a946bb/image.png)
|
||||
|
||||
# UI Description
|
||||
|
||||
**The studio tool GUI contains of:**
|
||||
- 1. UI tree viewer
|
||||
- 2. Selected UI object hierarchy list
|
||||
- 3. Selected UI object property list
|
||||
- 4. UIO selector editor
|
||||
- 5. UIO action panel
|
||||
- 6. Another Python activity panel
|
||||
- 7. Action/activity list
|
||||
|
||||
*Look it on the GUI screenshots are listed below*
|
||||
|
||||
## GUI Screenshot 1
|
||||
![image](uploads/d3d6ad14a7e50843bd89d2b14a092fee/image.png)
|
||||
|
||||
## GUI Screenshot 2
|
||||
![image](uploads/65b7d51c0a5b21e6b27dc23d4062d3ca/image.png)
|
||||
|
||||
# How to extract UI tree
|
||||
In order to extract the UI tree do the following: in `UI tree viewer` choose the object you are interested and click the button "Expand".
|
||||
## Action: Click the button "Expand"
|
||||
![image](uploads/6effc376ff6ea928840674bd744caced/image.png)
|
||||
## Result
|
||||
![image](uploads/18b9ab36126c8c32168bf5bbb9330701/image.png)
|
||||
# How to search UI object by mouse hover
|
||||
In order to search UI object do the following: in `UI tree viewer` choose the parent object, where you are want to search UI object, and click the button "Mouse search". The mouse search mode will start. Turn mouse on the UI object you are interested and wait when the studio will highlight the UI object. After the hightlight hold the "Ctrl" key and wait 3 seconds. The interested UI object will be shown in `UI tree viewer`.
|
||||
|
||||
## Action: Click the button "Mouse search"
|
||||
![image](uploads/84d7e4de0c840631f87cf7b325b53ad8/image.png)
|
||||
|
||||
## Action: Turn mouse on the UI object you are interested and hold the "Ctrl" key for 3 seconds
|
||||
![image](uploads/b7c38d622bf5b7afa5b26d1686d7302a/image.png)
|
||||
|
||||
## Result: The interested UI object will be shown in `UI tree viewer`
|
||||
![image](uploads/629bbf4db2c01b9c640194230949fcd2/image.png)
|
||||
|
||||
# How to extract UI object properties
|
||||
In order to extract UI object properties do the following: in `Selected UI object hierarchy list` choose the UI object you are interested and click it. The UI object property list will be shown in `Selected UI object property list`
|
||||
## Action: Choose the UI object you are interested and click it
|
||||
![image](uploads/2c27be5bdde20b5d062cbb40e74eaec5/image.png)
|
||||
|
||||
## Result: The UI object property list will be shown in `Selected UI object property list`
|
||||
![image](uploads/f235ae29099a713e0246cd574ac3a17c/image.png)
|
@ -0,0 +1,67 @@
|
||||
# Content
|
||||
- [About](#about)
|
||||
- [How to use](#how-to-use)
|
||||
- [Create python script](#create-python-script)
|
||||
- [Execute python script](#execute-python-script)
|
||||
|
||||
# About
|
||||
The Robot tool is the main module for production process automation. It has no graphic/console interface. All low-level actions to OS are perfoming by the Robot tool in OpenRPA.
|
||||
|
||||
# How to use
|
||||
You can use the robot by the several ways:
|
||||
- In Python script
|
||||
- In Studio script (n/a)
|
||||
|
||||
|
||||
## Create python script
|
||||
In order to use robot just add Robot tool folder in work directory and add line "import GUI" in your script.
|
||||
### Example
|
||||
> import sys <br>
|
||||
> sys.path.append('../../')<br>
|
||||
> import selenium [#Web app access](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.1.-Theory-&-practice:-Web-app-access-(Chrome,-Firefox,-Opera))<br>
|
||||
> import GUI [#Win32 & UI Automation access](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.2.-Theory-&-practice:-Desktop-app-UI-access-(win32-and-UI-automation-dlls)) <br>
|
||||
> import pyautogui [#Screen capture/recognition](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.4.-Theory-&-practice:-Screen-capture-&-image-recognition) [#Mouse manipulation](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.3.-Theory-&-practice:-Keyboard-&-mouse-manipulation)<br>
|
||||
> import cv2 [#Computer vision](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.4.-Theory-&-practice:-Screen-capture-&-image-recognition)<br>
|
||||
> import keyboard [#Keyboard manipulation](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.3.-Theory-&-practice:-Keyboard-&-mouse-manipulation)<br>
|
||||
|
||||
## Execute python script
|
||||
The OpenRPA is fully portable solution. It contains own python enviroment both 32 and 64 bit versions. So, you can execute your python script in several ways:
|
||||
- Execute in python x32 (\OpenRPA\Resources\WPy32-3720\python-3.7.2)
|
||||
- Execute in python x64 (\OpenRPA\Resources\WPy64-3720\python-3.7.2.amd64)
|
||||
- Execute from .cmd file
|
||||
|
||||
### Execute in the Python x32
|
||||
To execute your python script in x32 bit version just write in command line from x32 python directory: <br>
|
||||
> cd "\OpenRPA\Resources\WPy32-3720\python-3.7.2"<br>
|
||||
> python.exe "path to your python script.py"<br>
|
||||
|
||||
### Execute in the Python x64
|
||||
To execute your python script in x32 bit version just write in command line from x32 python directory: <br>
|
||||
> cd "\OpenRPA\Resources\WPy64-3720\python-3.7.2.amd64"<br>
|
||||
> python.exe "path to your python script.py"<br>
|
||||
|
||||
### Execute from .cmd file
|
||||
In order to simplify the execution process you can write several code lines in file with the .cmd extansion: <br>
|
||||
> cd %~dp0
|
||||
> copy /Y ..\Resources\WPy32-3720\python-3.7.2\python.exe ..\Resources\WPy32-3720\python-3.7.2\OpenRPAOrchestrator.exe
|
||||
> .\..\Resources\WPy32-3720\python-3.7.2\OpenRPAOrchestrator.exe orchestratorMain.py
|
||||
> pause >nul
|
||||
|
||||
## Use in studio script (n/a)
|
||||
|
||||
> import sys <br>
|
||||
> sys.path.append('../../')<br>
|
||||
> import GUI<br>
|
||||
> import keyboard<br>
|
||||
> import subprocess<br>
|
||||
> import time<br>
|
||||
>
|
||||
> #Highlight the UI Object in Folder explorer<br>
|
||||
> GUI.UIOSelector_FocusHighlight([{"class_name":"CabinetWClass","backend":"uia"},{"ctrl_index":2},{"ctrl_index":0},{"ctrl_index":2},{"ctrl_index":0}])<br>
|
||||
>
|
||||
>#Wait 2 seconds<br>
|
||||
>time.sleep(3)<br>
|
||||
>
|
||||
>#Loop: get child element of UI List<br>
|
||||
>for lItem in GUI.UIOSelector_Get_UIO([{"class_name":"CabinetWClass","backend":"uia"},{"ctrl_index":2},{"ctrl_index":0},{"ctrl_index":2},{"ctrl_index":0}]).children():<br>
|
||||
> print(str(lItem))<br>
|
@ -0,0 +1,22 @@
|
||||
# Content
|
||||
- About
|
||||
- How to use
|
||||
|
||||
# About
|
||||
The OpenRPA support web app manipulation (by the Selenium lib).
|
||||
More docs about selenium you can find [here](https://selenium-python.readthedocs.io/)
|
||||
|
||||
# How to use
|
||||
To start use selenium just import selenium modules in [the robot tool](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/04.2.-Tool-Robot:-How-to-use). Here is the example of the usage.
|
||||
> from selenium import webdriver <br>
|
||||
> from selenium.webdriver.common.keys import Keys <br>
|
||||
> <br>
|
||||
> driver = webdriver.Chrome() <br>
|
||||
> driver.get("http://www.python.org") <br>
|
||||
> assert "Python" in driver.title <br>
|
||||
> elem = driver.find_element_by_name("q") <br>
|
||||
> elem.clear() <br>
|
||||
> elem.send_keys("pycon") <br>
|
||||
> elem.send_keys(Keys.RETURN) <br>
|
||||
> assert "No results found." not in driver.page_source <br>
|
||||
> driver.close() <br>
|
@ -0,0 +1,270 @@
|
||||
Here you can find the docs and examples of the OpenRPA desktop (GUI) app access.
|
||||
|
||||
# Definitions
|
||||
|
||||
**UIO** - UI Object (class of pywinauto UI object) [pywinauto.base_wrapper]<br>
|
||||
**UIOSelector** - List of dict (key attributes)<br>
|
||||
**PWA** - PyWinAuto<br>
|
||||
**PWASpecification** - List of dict (key attributes in pywinauto.find_window notation)<br>
|
||||
**UIOTree** - Recursive Dict of Dict ... (UI Parent -> Child hierarchy)<br>
|
||||
**UIOInfo** - Dict of UIO attributes<br>
|
||||
**UIOActivity** - Activity of the UIO (UI object) from the Pywinauto module<br>
|
||||
**UIOEI** - UI Object info object
|
||||
|
||||
# What is UIO?
|
||||
UIO is a User Interface Object (pyOpenRPA terminology). For maximum compatibility, this instance is inherited from the object model developed in the [pywinauto library (click to get a list of available class functions)](https://pywinauto.readthedocs.io/en/latest/code/pywinauto.base_wrapper.html).
|
||||
|
||||
This approach allows us to implement useful functionality that has already been successfully developed in other libraries, and Supplement it with the missing functionality. In our case, the missing functionality is the ability to dynamically access UIO objects using UIO selectors.
|
||||
|
||||
# UIOSelector structure & example
|
||||
<a name="UIOSelector_Structure_Examples"></a>
|
||||
UIOSelector is the list of condition items for the UIO in GUI. Each item has condition attributes for detect applicable UIO. Here is the description of the available condition attributes in item.
|
||||
|
||||
**Desciption**<br>
|
||||
```
|
||||
[
|
||||
{
|
||||
"depth_start" :: [int, start from 1] :: the depth index, where to start check the condition list (default 1),
|
||||
"depth_end" :: [int, start from 1] :: the depth index, where to stop check the condition list (default 1),
|
||||
"ctrl_index" || "index" :: [int, starts from 0] :: the index of the UIO in parent UIO child list,
|
||||
"title" :: [str] :: the condition for the UIO attribute *title*,
|
||||
"title_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *title*,
|
||||
"rich_text" :: [str] :: the condition for the UIO attribute *rich_text*,
|
||||
"rich_text_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *rich_text*,
|
||||
"class_name" :: [str] :: the condition for the UIO attribute *class_name*,
|
||||
"class_name_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *class_name*,
|
||||
"friendly_class_name" :: [str] :: the condition for the UIO attribute *friendly_class_name*,
|
||||
"friendly_class_name_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *friendly_class_name*,
|
||||
"control_type" :: [str] :: the condition for the UIO attribute *control_type*,
|
||||
"control_type_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *control_type*,
|
||||
"is_enabled" :: [bool] :: the condition for the UIO attribute *is_enabled*. If UI object is enabled on GUI,
|
||||
"is_visible" :: [bool] :: the condition for the UIO attribute *is_visible*. If UI object is visible on GUI,
|
||||
"backend" :: [str, "win32" || "uia"] :: the method of UIO extraction (default "win32"). ATTENTION! Current option can be only for the first item of the UIO selector. For the next items this option will be implemented from the first item.
|
||||
},
|
||||
{ ... specification next level UIO }
|
||||
]
|
||||
```
|
||||
**The UIO selector example**
|
||||
```
|
||||
[
|
||||
{"class_name":"CalcFrame", "backend":"win32"}, # 1-st level UIO specification
|
||||
{"title":"Hex", "depth_start":3, "depth_end": 3} # 3-rd level specification (because of attribute depth_start|depth_stop)
|
||||
]
|
||||
```
|
||||
# The UIDesktop module (OpenRPA/Robot/UIDesktop.py)
|
||||
The UIDesktop is extension of the pywinauto module which provide access to the desktop apps by the **win32** and **ui automation** dll frameworks (big thx to the Microsoft :) ).
|
||||
|
||||
## Functions
|
||||
*Naming convention: \<InArgument\>\_\<ActivityName\>\_\<OutArgument - if exist>*<br>
|
||||
### List
|
||||
- [UIOSelector_Get_UIOList](#UIOSelector_Get_UIOList)
|
||||
- [UIOSelector_Get_UIO](#UIOSelector_Get_UIO)
|
||||
- [UIOSelector_Exist_Bool](#UIOSelector_Exist_Bool)
|
||||
- [UIOSelectorsSecs_WaitAppear_List](#UIOSelectorsSecs_WaitAppear_List)
|
||||
- [UIOSelectorsSecs_WaitDisappear_List](#UIOSelectorsSecs_WaitDisappear_List)
|
||||
- [UIOSelectorSecs_WaitAppear_Bool](#UIOSelectorSecs_WaitAppear_Bool)
|
||||
- [UIOSelectorSecs_WaitDisappear_Bool](#UIOSelectorSecs_WaitDisappear_Bool)
|
||||
- [UIOSelector_Get_BitnessInt](#UIOSelector_Get_BitnessInt)
|
||||
- [UIOSelector_SearchChildByMouse_UIO](#UIOSelector_SearchChildByMouse_UIO)
|
||||
- [UIOSelector_SearchChildByMouse_UIOTree](#UIOSelector_SearchChildByMouse_UIOTree)
|
||||
- [UIOSelector_Get_UIOInfoList](#UIOSelector_Get_UIOInfoList)
|
||||
- [UIOSelector_IsExist_Bool](#UIOSelector_IsExist_Bool)
|
||||
- [UIOSelector_WaitAppear_Dict](#UIOSelector_WaitAppear_Dict)
|
||||
- [UIOSelector_TryRestore_Dict](#UIOSelector_TryRestore_Dict)
|
||||
- [UIOSelector_Get_UIOActivityList](#UIOSelector_Get_UIOActivityList)
|
||||
- [UIOSelectorUIOActivity_Run_Dict](#UIOSelectorUIOActivity_Run_Dict)
|
||||
- [UIOSelector_Get_UIOInfo](#UIOSelector_Get_UIOInfo)
|
||||
- [UIOSelector_GetChildList_UIOList](#UIOSelector_GetChildList_UIOList)
|
||||
- [UIOSelector_SearchUIONormalize_UIOSelector](#UIOSelector_SearchUIONormalize_UIOSelector)
|
||||
- [UIOSelector_SearchProcessNormalize_UIOSelector](#UIOSelector_SearchProcessNormalize_UIOSelector)
|
||||
- [UIOSelector_FocusHighlight](#UIOSelector_FocusHighlight)
|
||||
- [UIOSelector_Highlight](#UIOSelector_Highlight)
|
||||
### Description
|
||||
**`UIOSelector_Get_UIOList (inUIOSelector,inParentUIO=None,inFlagRaiseException=True)`**<br>
|
||||
<a name="UIOSelector_Get_UIOList"></a>
|
||||
___
|
||||
Get the list of the UIO items<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
**inParentUIO** - Technical argument. Applicable only if you has UIO object, which is parent for the futher search the child UIO.<br>
|
||||
**inFlagRaiseException** - if True - raise exception if UIO hasn't been detected. False - don't raise the exception - return None.<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_Get_UIO (inUIOSelector,inParentUIO=None,inFlagRaiseException=True)`**<br>
|
||||
<a name="UIOSelector_Get_UIO"></a>
|
||||
___
|
||||
Get first (if more than one UIO are applied) UIO (UI Object) <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
**inParentUIO** - Technical argument. Applicable only if you has UIO object, which is parent for the futher search the child UIO.<br>
|
||||
**inFlagRaiseException** - if True - raise exception if UIO hasn't been detected. False - don't raise the exception - return None.<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_Exist_Bool (inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_Exist_Bool"></a>
|
||||
___
|
||||
Check if UIO exist (Identified by the UIOSelector) <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelectorsSecs_WaitAppear_List (inUIOSelectorList,inWaitSecs,inFlagWaitAllInMoment=False)`**<br>
|
||||
<a name="UIOSelectorsSecs_WaitAppear_List"></a>
|
||||
___
|
||||
Wait for UIO is appear (at least one of them or all at the same time). return: \[0,1,2\] - index of UIOSpecification, which is appear <br>
|
||||
___
|
||||
**inUIOSelectorList** - !ATTENTION! Current argument is not the UIOSelector. This is the !list! of the many UIO selectors. ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
**inWaitSecs** - Time in seconds to wait the UIO will appear.<br>
|
||||
**inFlagWaitAllInMoment** - True - wait when UIO of the all UIOSelectors will appear. False - at least one UIO of the UIOSelector list.<br>
|
||||
___
|
||||
|
||||
**`UIOSelectorsSecs_WaitDisappear_List (inUIOSelectorList,inWaitSecs,inFlagWaitAllInMoment=False)`**<br>
|
||||
<a name="UIOSelectorsSecs_WaitDisappear_List"></a>
|
||||
___
|
||||
Wait for UIO is Disappear (at least one of them or all at the same time). return: \[0,1,2\] - index of UIOSpecification, which is Disappear <br>
|
||||
___
|
||||
**inUIOSelectorList** - !ATTENTION! Current argument is not the UIOSelector. This is the !list! of the many UIO selectors. ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
**inWaitSecs** - Time in seconds to wait the UIO will appear.<br>
|
||||
**inFlagWaitAllInMoment** - True - wait when UIO of the all UIOSelectors will appear. False - at least one UIO of the UIOSelector list.<br>
|
||||
___
|
||||
|
||||
**`UIOSelectorSecs_WaitAppear_Bool (inUIOSelector,inWaitSecs)`**<br>
|
||||
<a name="UIOSelectorSecs_WaitAppear_Bool"></a>
|
||||
___
|
||||
Wait for UIO is appear (at least one of them or all at the same time). return: Bool - True - UIO is appear. <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
**inWaitSecs** - Time in seconds to wait the UIO will appear.<br>
|
||||
___
|
||||
|
||||
|
||||
**`UIOSelectorSecs_WaitDisappear_Bool (inUIOSelector,inWaitSecs)`**<br>
|
||||
<a name="UIOSelectorSecs_WaitDisappear_Bool"></a>
|
||||
___
|
||||
Wait for UIO is disappear (at least one of them or all at the same time) . return: Bool - True - UIO is Disappear. <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
**inWaitSecs** - Time in seconds to wait the UIO will appear.<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_Get_BitnessInt (inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_Get_BitnessInt"></a>
|
||||
___
|
||||
Get process bitness (32 or 64). return None (if Process not found), int 32, or int 64<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
|
||||
**`UIOSelector_SearchChildByMouse_UIO(inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_SearchChildByMouse_UIO"></a>
|
||||
___
|
||||
Run the search UIO by mouse hover event. result = UIO element wrapper instance or None <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_SearchChildByMouse_UIOTree(inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_SearchChildByMouse_UIOTree"></a>
|
||||
___
|
||||
Run the search UIO by mouse hover event. result = UIO element wrapper instance or None <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_Get_UIOInfoList (inUIOSelector,inElement=None)`**<br>
|
||||
<a name="UIOSelector_Get_UIOInfoList"></a>
|
||||
___
|
||||
Get the UIOEI object.<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_IsExist_Bool (inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_IsExist_Bool"></a>
|
||||
___
|
||||
Check is the UIO/UIO's by the UIOSelector exist <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_WaitAppear_Dict(inUIOSelector,inTimeout=60)`**<br>
|
||||
<a name="UIOSelector_WaitAppear_Dict"></a>
|
||||
___
|
||||
Wait for the UIO by the UIOSelector appear <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_TryRestore_Dict(inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_TryRestore_Dict"></a>
|
||||
___
|
||||
Try to restore (maximize) window, if it's minimized. (!IMPORTANT! When use UIA framework minimized windows doesn't appear by the UIOSelector. You need to try restore windows and after that try to get UIO)<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_Get_UIOActivityList (inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_Get_UIOActivityList"></a>
|
||||
___
|
||||
Get the list of the UI object activities<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelectorUIOActivity_Run_Dict(inUIOSelector,inActionName,inArgumentList=\[\],inkwArgumentObject={})`**<br>
|
||||
<a name="UIOSelectorUIOActivity_Run_Dict"></a>
|
||||
___
|
||||
Run the activity in UIO (UI Object) <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
**inActionName** - UIOActivity (name) from Pywinauto<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_Get_UIOInfo(inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_Get_UIOInfo"></a>
|
||||
___
|
||||
Get the UIO dict of the attributes <br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_GetChildList_UIOList(inUIOSelector=\[\],inBackend=mDefaultPywinautoBackend)`**<br>
|
||||
<a name="UIOSelector_GetChildList_UIOList"></a>
|
||||
___
|
||||
Get list of child UIO's by Parent UIOSelector<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_SearchUIONormalize_UIOSelector (inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_SearchUIONormalize_UIOSelector"></a>
|
||||
___
|
||||
Technical def. Do UIOSelector normalization for the search processes.<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_SearchProcessNormalize_UIOSelector (inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_SearchProcessNormalize_UIOSelector"></a>
|
||||
___
|
||||
Technical def. Do UIOSelector normalization for the search processes.<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_FocusHighlight(inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_FocusHighlight"></a>
|
||||
___
|
||||
Set focus and highlight (draw outline) the element (in app) by the UIO selector.<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
||||
|
||||
**`UIOSelector_Highlight(inUIOSelector)`**<br>
|
||||
<a name="UIOSelector_Highlight"></a>
|
||||
___
|
||||
Highlight (draw outline) the element (in app) by the UIO selector.<br>
|
||||
___
|
||||
**inUIOSelector** - UIOSelector - List of items, which contains condition attributes ([see UIOSelector Structure&Examples](#UIOSelector_Structure_Examples))<br>
|
||||
___
|
@ -0,0 +1 @@
|
||||
**How to automate Keyboard and Mouse device in PC**
|
@ -0,0 +1,7 @@
|
||||
**How to automate image recognition on PC**
|
||||
|
||||
Here you can find any ways you need to use in your business case:
|
||||
* Find the exact match on the screen with the other image
|
||||
* Use text recognition module (OCR)
|
||||
* Use computer vision (CV) to identify the objects on screen/image/video
|
||||
* Use artificial intelligence (AI) to make custom identification/classification/text recognition
|
After Width: | Height: | Size: 770 B |
After Width: | Height: | Size: 225 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,3 @@
|
||||
cd %~dp0..\OpenRPA\Sources
|
||||
..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe "..\..\OpenRPA Habr\2. MonitoringModeProgrammer_Run_64.py"
|
||||
pause >nul
|
@ -0,0 +1,17 @@
|
||||
from pyOpenRPA.Robot import UIDesktop # Импорт модуля, который умеет управлять UI элеметами GUI приложений
|
||||
import time # Библиотека сна алгоритма
|
||||
import os # Билбиотека системных функций, позволит открять калькулятор, если это потребуется
|
||||
lUIOSelectorCalculator = [{"title":"Калькулятор","class_name":"CalcFrame","backend":"win32"}] # Сформировали UIO селектор из студии pyOpenRPA
|
||||
while True: # Вечный цикл
|
||||
lExistBool = UIDesktop.UIOSelector_Exist_Bool(inUIOSelector=lUIOSelectorCalculator) # Проверить наличие окна по UIO селектору
|
||||
if not lExistBool: # Проверить наличие окна калькулятора
|
||||
os.system("calc") # Открыть калькулятор
|
||||
else: # Проверить, что окно калькулятора не свернуто
|
||||
lUIOCalculator = UIDesktop.UIOSelector_Get_UIO(inSpecificationList=lUIOSelectorCalculator) # Получить UIO экземпляр
|
||||
if lUIOCalculator.is_minimized(): # Проверить, что калькулятор находится в свернутом виде
|
||||
lUIOCalculator.restore() # Восстановить окно калькулятора из свернутого вида
|
||||
else:
|
||||
lCalcHex_IsExistBool = UIDesktop.UIOSelector_Exist_Bool(inUIOSelector=[{"class_name":"CalcFrame","backend":"win32"},{ "title":"Hex", "depth_start":3, "depth_end": 3}]) # Проверить наличие UI элемента по UIO селектору
|
||||
if not lCalcHex_IsExistBool: # Проверить, что UI элемент отсутствует
|
||||
lUIOCalculator.menu_select("&Вид -> &Программист") # Выполнить смену режима калькулятора
|
||||
time.sleep(1) # Выполнить сон на 1 сек., после чего перейти на следующую итерацию
|
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,17 @@
|
||||
# The OpenRPA Wiki
|
||||
Dear friend! <br>
|
||||
Welcome to the OpenRPA wiki portal. Here you can find theory & practical docs to work with first Open Source RPA platform.
|
||||
|
||||
## Content
|
||||
In wiki you can find:
|
||||
- [About OpenRPA, library dependencies and licensing](01.-About-OpenRPA,-library-dependencies-and-licensing.md)
|
||||
- [Architecture (Studio, Robot, Orchestrator)](02.-Architecture-(Studio,-Robot,-Orchestrator).md)
|
||||
- [How to install (system requirements)](03.-How-to-install-(system-requirements).md)
|
||||
- [Tool Studio: How to use](04.1.-Tool-Studio.-How-to-use.md)
|
||||
- [Tool Robot: How to use](04.2.-Tool-Robot.-How-to-use.md)
|
||||
- Tool Orchestrator: How to use
|
||||
- [Theory & practice: Web app access (Chrome, Firefox, Opera)](05.1.-Theory-&-practice.-Web-app-access-(Chrome,-Firefox,-Opera).md)
|
||||
- [Theory & practice: Desktop app UI access (win32 and UI automation dlls)](05.2.-Theory-&-practice.-Desktop-app-UI-access-(win32-and-UI-automation-dlls).md)
|
||||
- Theory & practice: Keyboard & mouse manipulation
|
||||
- Theory & practice: Screen capture & image recognition
|
||||
|
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 116 KiB |
After Width: | Height: | Size: 105 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 218 KiB |
After Width: | Height: | Size: 238 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 186 KiB |
After Width: | Height: | Size: 15 KiB |