0

How would I call a global variable from my python script inside of the tell application? Here's a sample of where that might go. Say I wanted to change all "front window" from outside of the applescript from a global python variable. How might that happen?

import subprocess

def get_window_title():
    cmd = """
        tell application "System Events"
            set frontApp to name of first application process whose frontmost is true
        end tell
        tell application frontApp
            if the (count of windows) is not 0 then
                set window_name to name of front window
            end if
        end tell
        return window_name
    """
    result = subprocess.run(['osascript', '-e', cmd], capture_output=True)
    return result.stdout

print(get_window_title())

3 Answers3

0

Here's a way better example:

The phone number is defined on line 7 with input on line 74. It's called on line 91 from inside the applescript. I'd like to do the same for the message from inside the applescript on line 98, like the phone number was able to, and not from line 113 (msg). I'd like to define msg from outside of the applescript and call it just like the phone number.

import subprocess, sys
 from os import system, name
 from time import sleep


 msg = ""
 Phone_num = ""
 repeat = ""


 def Ascii():
     clear()
     print("+++++++++++++++++++++++++++++++++++++++.")
     print("++++++++++++++77       77I++++++++++++++")
     print("++++++++++77               77+++++++++++")
     print("========77                   77=========")
     print("=======7                       7========")
     print("======7                         7=======")
     print("=====7                           7======")
     print("=====                             ======")
     print("=====                             ======")
     print("=====                             ======")
     print(
         "=====7                           7======    _ __  __                                "
     )
     print(
         "~~~~~~7                         7~~~~~~~   (_)  \/  |                               "
     )
     print(
         "~~~~~~~7                       7~~~~~~~~    _| \  / | ___  ___ ___  __ _  __ _  ___ "
     )
     print(
         "~~~~~~~~77                   77~~~~~~~~~   | | |\/| |/ _ \/ __/ __|/ _` |/ _` |/ _ \ "
     )
     print(
         "~~~~~~~~~~77               77~~~~~~~~~~~   | | |  | |  __/\__ \__ \ (_| | (_| |  __/"
     )
     print(
         "~~~~~~~~~~~~   77     777I~~~~~~~~~~~~~~   |_|_|  |_|\___||___/___/\__,_|\__, |\___|"
     )
     print(
         "~~~~~~~~~~~ 7I~~~~~~~~~~~~~~~~~~~~~~~~~~                                  __/ |     "
     )
     print(
         "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.                                 |___/     "
     )
     print("\nWith Python!")
     sleep(3)


 def intro():
     clear()
     print("Welcome to iMessage for Python.\n")
     print(
         "This Adapts From The AppleScript and Uses Elements From Python to Send Automated Messages to Others.\n"
     )
     print('This Uses US Based Numbers "(+1)" Only.\n')

     print(
         "[WARNING] By Agreeing to Use this Software, Any Liability Due to Misuse Will NOT be Placed On the Author. "
     )
     sleep(5)


 def clear():
     _ = system("clear")


 def questions():
     clear()
     global msg, Phone_num, repeat
     print('NO Dashes "-", Spaces "_", or parentheses"()"  or the script WILL Fail.')
     print("Input Ex:XXXXXXXXX\n")
     Phone_num = str(input("Enter Here:"))
     clear()
     print("What is Your Message?\n")
     msg = input("Enter Here:")
     clear()
     print("How Many Times do You Want to Send this Message?\n")
     repeat = input("Enter Here:")
     clear()


 def apple():

     applescript = (
         """
     tell application "Messages"
         
         set targetBuddy to "+1 """
         + Phone_num
         + """"
         set targetService to id of 1st service whose service type = iMessage
         set i to 1
         set p to "Sent" 
         repeat {0}
             
             set textMessage to "{1}"
             
             set theBuddy to buddy targetBuddy of service id targetService
             send textMessage to theBuddy
             delay 1
             
             log ("Repeated " & i &" Time(s).") 
             
             set i to i + 1
             
             
         end repeat
         
     end tell
     """.format(
             repeat, msg
         )
     )
     args = [
         item
         for x in [("-e", l.strip()) for l in applescript.split("\n") if l.strip() != ""]
         for item in x
     ]
     proc = subprocess.Popen(["osascript"] + args, stdout=subprocess.PIPE)
     progname = proc.stdout.read().strip()

  • You are already programmatically building the script string using `format`, why not just do the same thing for all the items you are wanting to insert? – red_menace Oct 29 '21 at 21:44
0

You are using two different ways to programmatically build the script string. One way uses concatenation, the other uses a string function. Using one or the other would probably be less confusing.

The format function uses passed arguments to replace placeholders in the string. With index formatting, the arguments can be used in any order and multiple times (or not at all), so this method gives you a little more flexibility when building this kind of script. For example:

msg = "This is a test."
Phone_num = "8761234"
repeat = "5"

applescript = (
"""
tell application "Messages"
   
   set targetBuddy to "+1 {0}"
   set targetService to id of 1st service whose service type = iMessage
   set i to 1
   set p to "Sent" 
   repeat {1}
      
      set textMessage to "{2}"
      
      set theBuddy to buddy targetBuddy of service id targetService
      send textMessage to theBuddy
      delay 1
      
      log ("Repeated " & i &" Time(s).") 
      
      set i to i + 1
   end repeat
end tell
""".format(Phone_num, repeat, msg)) # replace placeholders with variable values

print(applescript)
red_menace
  • 3,162
  • 2
  • 10
  • 18
  • Thank you so much. You were right. The two different formats were what did me in. I see it now. – punkroast Oct 30 '21 at 04:10
  • Assembling executable code by string munging is a [bad accident](https://xkcd.com/327/) [waiting to happen](https://www.google.com/search?q=string+injection+attack). Don’t do that. e.g. Try `msg = 'Bobby says "Hello!"'` for a non-destructive demonstration of how your code will break. It is also unnecessary here, as osascript can forward additional arguments to AppleScript’s `run` handler. See my answer and bookmark it for future reference. – foo Oct 30 '21 at 07:45
0

If you want to pass arguments into AppleScript, here is the correct way to do it:

#!/usr/bin/env python3

import subprocess

scpt = """
on run {arg1, arg2}
    return arg1 + arg2
end run
"""

arg1 = 37
arg2 = 5

proc = subprocess.Popen(['osascript', '-', str(arg1), str(arg2)], 
    stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding='utf8')

out, err = proc.communicate(scpt)
print(out) # 42

Since you’re on Python, you also have the options of py-applescript, which is supported, or appscript, which is not. If you need to pass complex arguments to AppleScript, the py-applescript library automatically converts between common AS and Python types. Appscript avoids AppleScript entirely, but you’re on your own with that.

foo
  • 664
  • 1
  • 4
  • 4
  • I'm going to check out and try everything you suggested. Bookmarked. Thank you! – punkroast Oct 30 '21 at 17:24
  • I should mention I wrote appscript and py-applescript too, but no longer give support for either. Both are mature, finished code and other developers continue to provide maintenance releases. But if/when Apple start removing long-deprecated Carbon APIs, I expect appscript will cease working; and if they ever deprecate AppleScript itself in favor of a bright new Shortcuts future then it all becomes moot anyway.) If your needs are modest—simple string arguments and no great need for speed—then calling AppleScript via `osascript` should be sufficient, and avoids external dependencies. – foo Oct 30 '21 at 19:59