Python 2 and AppleScript. Dialogue prompts and default answers - python-2.7

Here is just a small snippet of the Python code I use to read the XML data of Mac System Profiler files for the purpose of adding the data to a database without having to copy/paste the details manually.
Specifically this snippet of code prompts the user to enter an "Article Number" to save the given ".spx" (System Profiler Report) under.
import subprocess
exampleString = "12345"
theText = subprocess.check_output(['osascript', '-e',
r'''set theText to text returned of (display dialog "Enter new Article Number here:
\n\nElse just press OK" default answer "" with title "Hardware Paster v1.0" with icon 2)'''
])
"theText" will go to on dictate the name of the spx file.
I would like to set the value of the "default answer" inside of the AppleScript prompt with the value of another variable inside the main python script ("exampleString" in this case). The "12345" is just placeholder text here.
The ultimate aim is to minimise data-entry by the end user.
Thanks for your help.

Just string format and you're good!
>>> exampleString = "world"
>>> 'hello there "{}"!'.format(exampleString)
'hello there "world"!'
And applied to your program:
exampleString = "12345"
template = r'''set theText to text returned of (display dialog "Enter new Article Number here:
\n\nElse just press OK" default answer "{}" with title "Hardware Paster v1.0" with icon 2)'''
theText = subprocess.check_output(
['osascript', '-e', template.format(exampleString)])

Related

Google Apps Script Form textValidationBuilder does not recognize regex pattern

I am trying to create a Form with apps script and for some reason it will not allow the simplest phone number validation in a TextItem input field. I only need the user to enter their 10 digit number with no spaces, dashes, dots, with area code included. I know this isn't the technical "best" way to validate phone numbers but for our purposes it works. This is section of code I have to generate the field. (edited to make a more reproducible example)
function CreateForm() {
var form = FormApp.create('Test');
var tenantNum = form.addTextItem()
.setTitle("Tenant Phone #");
var phoneValid = FormApp.createTextValidation()
.setHelpText("Please enter valid phone number, 10-digits, no symbols or spaces.")
.requireTextMatchesPattern(/\d{10}/g)
.build();
tenantNum.setValidation(phoneValid);
console.log(form.getPublishedUrl())
}
I have also tried other things like:
(No capture group or global tag, both individually)
.requireTextMatchesPattern(/\d{10}/)
Entering the regex as a string literal.
.requireTextMatchesPattern("\d{10}")
Even dumdum stuff like.
.requireTextMatchesPattern(/[0-9]{10}/)
or
.requireTextMatchesPattern(/\d\d\d\d\d\d\d\d\d\d/)
Just to see if it works. I have also tried .requireTextContainsPattern() as well.
Whenever you enter in the form however i get this response:
Please enter valid phone number, 10-digits, no symbols or spaces.
My only thought is that there might be some confusion with whether or not the user is entering a string vs. number and this method only works on strings. But this validation
and regex work fine when you enter it into the form creation manually so I'm completely lost. Any help is appreciated!
Just a guess... Try this:
.requireTextMatchesPattern("\\d{10}")
Update
It works fine for me:
function CreateForm() {
var form = FormApp.create('Test');
var tenantNum = form.addTextItem()
.setTitle("Tenant Phone #");
var phoneValid = FormApp.createTextValidation()
.setHelpText("Please enter valid phone number, 10-digits, no symbols or spaces.")
.requireTextMatchesPattern("\\d{10}")
.build();
tenantNum.setValidation(phoneValid);
console.log(form.getPublishedUrl())
}
And the "not existed" method setHelpText() works fine as well, as you can tell from the screenshots.

Pepper robot: How to use tablet to send text input for further processing in Choregraphe?

I need to send a user text input to the robot through the integrated tablet, and catch it somehow, for further processing in Choregraphe.
After reading the Aldebaran documentation about ALTabletService API, I found few methods which might be a solution to all this. The methods are ALTabletService::showInputTextDialog and ALTabletService::onInputText, but somehow I can't get them to work: they return absolutely nothing when I input some text through the tablet.
I need access to the string created when the user inputs a piece of text. Any advice how to do it?
i realized this without ALTabletService methods showInputTextDialog or onInputText
My Approach:
I made an html page with an input field and a button to send the input.
On button press I use the forceInput method from ALDialog doc via QiMessaging Javascript library. doc
I can't test it right now but this should help as a inspiration
function forceInput(input) {
QiSession(function(session) {
session.service('ALDialog').then(function(ALDialog) {
ALDialog.forceInput(input);
});
}
}
Now you can send the input to the topic.
This could be sth like "imput_from_tablet blablabla".
And in the Dialog you catch
u:(imput_from_tablet _*) $1
Where $1 should be blablabla.
Hope that helps
best regards
You can create a webpage for the tablet and package it in your application - see the documentation here; then on that webpage you can create a text input field (be careful that the bottom half of the screen will be hidden by the keyboard when the field is selected), and then use the javascript SDK to (for example) raise an ALMemory event with the inputted text value, that you can then get from Choregraphe.
I had exactly the same problem and I found this ALTabletService::onInputText method in the signal list. You can find examples how to use signals on the same page. Based on these examples I created the following script that can get a value from the input field:
import qi
import sys
def main(app):
try:
session = app.session
tabletService = session.service("ALTabletService")
tabletService.showInputTextDialog("Example dialog", "OK", "Cancel")
signal_id = 0
def callback(button_id, input_text):
if button_id == 1:
print "'OK' button is pressed."
print "Input text: " + input_text
if button_id == 0:
print "'Cancel' button is pressed"
tabletService.onInputText.disconnect(signal_id)
app.stop()
# attach the callback function to onJSEvent signal
signal_id = tabletService.onInputText.connect(callback)
print "Signal ID: {}".format(signal_id)
app.run()
except Exception, e:
print "Error was: ", e
if __name__ == "__main__":
ip = "10.0.10.254" # the IP of the robot
port = 9559
try:
connection_url = "tcp://{}:{}".format(ip, port)
app = qi.Application(url=connection_url)
app.start()
except RuntimeError:
print("Can't connect to Naoqi.")
sys.exit(1)
main(app)

Does webstorm have some shortcut for console.log or console.info?

Just tired of typing console.log again and again, and do not find a way like Sysout + Control + Space in Eclipse will create System.out.println().
There's a predefined Postfix template that allows you to type .log after a JavaScript expression or string and hit Tab to transform it to console.log().
You can also create a Live template (see Preferences | Editor | Live templates) that would expand into a code snippet once you type the selected abbreviation and hit Tab.
Update: there's now also a plugin that allows you to add console.log with a shortcut: https://plugins.jetbrains.com/plugin/10986-console-log
Yes it does,
<anything>.log and press Tab key. This will result in console.log(<anything>);
ie,
<anything>.log + Tab => console.log(<anything>);
eg1: variable
let my_var = 'Hello, World!';
my_var.log + Tab => console.log(my_var);
eg2: string
'hello'.log + Tab => console.log('hello');
eg3: string and variable
'hello', my_var.log + Tab => console.log('hello', my_var);
[UPDATE 2020]
Typing log + Enter autocompletes to console.log()
I made my own template that seems to work.
It may be useful for somebody.
Abbreviation: ll
Template text:
console.log('$NAME$ ', $VALUE$);
$END$
Variables: (just select the given field values by clicking drop down box)
NAME - jsDefineParameter()
VALUE - jsSuggestVariableName
I'm including what I find to be the most efficient, which I added via live templates -> javascript -> applicable to "Everything". Hopefully someone finds it useful.
console.log('L$LINE$ $MYSTRING$ ===', $MYVAR$);$END$
What it does:
When I type cl and press tab, it creates the log and the first thing you type fills both MYSTRING and MYVAR variables. If you tab again, it selects MYVAR where you can rewrite/delete as desired. The third time you hit tab will take you to the end of the line at $END.
This snippet also prints the line number like L123 but you can easily remove that if it isn't helpful because obviously most browsers show line number anyway.
You also have to set the variables' behaviour as seen in the image below:
Edit variables setup
use Macros!
https://www.jetbrains.com/help/webstorm/using-macros-in-the-editor.html
I recorded a macro that takes the name my cursor is on and create
console.log("#### name = ", name);
on the next line.
and assigned a keyboard shortcut to it :)
super easy, and couldn't get Live Template to get the same result with 1 action.
to create a new macro: Edit -> Macros -> Start Macro Recording. then record your next moves and create the desired result.
this is mine:
This is my solution, it somewhat mimics a turbo-console approach and gives you certain freedoms to build on it.
Step 1: Go to Editor > General > Postfix Completion;
Step 2: Click on JavaScript, click the + button, select JavaScript and TypeScript;
Step 3: In the Key input, type a alias for your command, I choose 'cl' for mine;
Step 4: In the 'Minimum language level' select your desired preference, I choose ECMAScript 6+;
Step 5: In the bellow text area, add your logic, for me it is console.log('$EXPR$', $EXPR$, '$END$');
Step 6: Customize however you like.
So what does all of this do?
Lets consider the following:
const willNeedToBeLogged = 'some value you want to check';
All you need to do for a console long is type
willNeedToBeLogged.cl + press (Tab, Enter or Spance)
And you will get this
console.log('willNeedToBeLogged', willNeedToBeLogged, '');
With your cursor being on the $END$ variable, where you could write, a line, or anything you like.
Have fun!
I made a custom template. This can help you.
Abbreviation: clog
Template code:
console.log("\n\n--------------------------------");
console.log($END$);
console.log("--------------------------------\n\n");
Simplest live template text:
console.log($END$);
Maybe it is a recent addition but you can write log and hit tab and console.log() will appear with the caret in between the braces.
The answer from Ekaterina Prigara (https://stackoverflow.com/a/32975087/5653914) was very useful to me but if you want to log a string like "Test" this method is quicker.
Try a logit plugin. It provides the next logging pattern by default:
const data = 'data';
console.log('-> data', data);
You can configure it.
Try Dot Log (vscode extension), It can automatically transfer aaa.log to console.log('aaa', aaa )

Playing a imacro loop from VBS script

i am trying to execute an iMacro script using a VBS script. I am using play() method. but it seems play() doesn't support the loop functionality. I searched through the iMacros wiki and Google and unable to find an answer.
Here is the code
Set iim1 = CreateObject ("IMacros")
i = iim1.iimInit()
i = iim1.iimPlay("amazon_search")
i = iim1.iimExit()
Can anyone help? Thanks in advance.
//Scripts by Talon
var nameoffile = "my100.csv"
var numberOfUrls = 101
for(var i=1;i<numberOfUrls;i++){
//sets basic requirements
//do what you want here
var macro = "CODE: "
macro+= "SET !ERRORIGNORE YES"+"\n"
macro+= "SET !REPLAYSPEED fast"+"\n"
macro+= "SET !TIMEOUT_STEP 1"+"\n"
macro+= "SET !DATASOURCE "+nameoffile+"\n"
macro+= "SET !LOOP "+i+"\n"
macro+= "SET !DATASOURCE_LINE {{!LOOP}}"+"\n"
macro+= "URL GOTO={{!COL1}}"+"\n"
//Add what you want to do at each site here if using macro format
iimPlay(macro)
Or add your new iimPlay code here , or add more jscript
}
The above code uses jscript to call imacros script, in this example I'm first calling a file named my100.csv. my 100 has 100 urls, or website that I go to to pull different information, or to set different information.
the numberOfUrls variable tells my code how many times to run my code.
I then dimension the variable "macro" and build the imacros script, one line at a time, setting the predefined builtin variables how I want them.
Once everything is set I call my first url, and manipulate the data how I want.
NOTE: you do not have to use Urls in you .csv file, you could place your data in the .csv file and go to a site them run your information whatever way you want.

Get full directory contents with AppleScript

I need to get the entire (visible) contents of a folder and its subfolders as a list. Is this possible?
see how easy this can be
tell application "Finder"
set file_list to entire contents of (choose folder with prompt "Please select directory.")
end tell
if you want a list of file names then you could do this
tell application "Finder"
set file_list to name of every file of entire contents of (choose folder with prompt "Please select directory.")
end tell
Yes, entire contents does exactly what you say -- but it easily chokes on
large folders, and takes forever. It's OK for
small things, like extracting all the files of one kind out of a folder you
know will only contain a small number of files.
The recursive method also works well -- but it's using "list folder", and
the dictionary listing for it says it's deprecated and we shouldn't use it
any more.
I'm sure there is a shell command that can do this faster, but here is one way in pure Applescript that gives you total control over formatting what info you would like displayed.
property kFileList : {}
tell application "Finder"
set source_folder to choose folder with prompt "Please select directory."
my createList(source_folder)
end tell
on createList(item_list)
set the the_items to list folder item_list without invisibles
set item_list to item_list as string
repeat with i from 1 to number of items in the the_items
set the_item to item i of the the_items
set the_item to (item_list & the_item) as alias
set this_info to info for the_item
set file_name to name of this_info
set end of kFileList to file_name
if folder of this_info is true then
my createList(the_item)
end if
end repeat
end createList
On a side note, there are also a number file listing applications that can do this faster than Applescript.
UPDATE: As a result of this discussion, here is the function again, but this time using the updated API. This could probably could use some cleaning up, but it works cataloging my Desktop handily enough (and that's a deep, deep folder for me):
property kFileList : {}
tell application "Finder"
set source_folder to choose folder with prompt "Please select directory."
my createList(source_folder)
end tell
return kFileList
on createList(mSource_folder)
set item_list to ""
tell application "System Events"
set item_list to get the name of every disk item of mSource_folder
end tell
set item_count to (get count of items in item_list)
repeat with i from 1 to item_count
set the_properties to ""
set the_item to item i of the item_list
set the_item to ((mSource_folder & the_item) as string) as alias
tell application "System Events"
set file_info to get info for the_item
end tell
if visible of file_info is true then
set file_name to displayed name of file_info
set end of kFileList to file_name
if folder of file_info is true then
my createList(the_item)
end if
end if
end repeat
end createList
Wow this is quite late but I checked and it works.
tell application "Finder" to set folder_root to (choose folder with prompt "Please select directory.")
set fl to {}
dump_folder(folder_root)
on dump_folder(f)
global fl
tell application "System Events" to set end of fl to (get the POSIX path of f)
tell application "Finder" to set nfl to (the items of the contents of f)
repeat with nf in nfl
dump_folder(nf as alias)
end repeat
end dump_folder
fl