Как заставить AppleScript игнорировать escape-символы в строке при создании заметки AppleScript - PullRequest
1 голос
/ 30 июня 2019

У меня есть скрипт Python 2.7.10, который принимает вводимые пользователем данные и вставляет их в параметр name и body в make new note AppleScript.

Проблема в том, что любые escape-символы или специальные символы интерпретируются AppleScript.Я хочу, чтобы все строки обрабатывались как необработанные и игнорировали все экранирующие символы и такие вещи, как :\//tft// или c:\test\test.txt, не давая мне ошибки Expected “"” but found unknown token. или игнорируя символ t после \

Строка python выглядит следующим образом:

cmd = "osascript -e 'tell application \"Notes\" \n tell account \"iCloud\" \n make new note at folder \"Notes\" with properties {name:\"%s\", body:\"%s\"} \n end tell \n end tell'" % (header, body)

... где header и body - строки, предоставленные пользователем.

Но для ручного тестирования я использую Script Editorчтобы быстро воспроизвести ошибку.

tell application "Notes"
  tell account "iCloud"
    make new note at folder "Notes" with properties {name:"myname", body:"c:\test\test.txt"}
  end tell
end tell

Эта конкретная заметка в итоге выглядит так:

enter image description here

Я знаю, что могуиспользуйте \\ вместо \, но я не хочу, чтобы пользователям приходилось очищать все свои входные данные, поскольку они могут копировать вставки из большого объема текста.Подумайте о файле журнала или теле текста в виде вставки.

Есть ли способ программной очистки пользовательского ввода?

ПРИМЕЧАНИЕ:

Это НЕ дубликат этого вопроса, потому что я пытался заменить строковую переменную header и body на eval(header) и eval(body), но это не сработало.Я также пытался .decode('string_escape') безрезультатно.Наконец, я попробовал это тоже безуспешно:

d = header.escape('\w[0-9]')
header = d.decode('string_escape')

Я думаю, что это связано со способностью AppleScript принимать эту строку, а не только со способностью Python санировать ее с помощью вышеуказанных функций.

ОБНОВЛЕНИЕ

Я фиксирую пользовательский ввод, используя диалоговое окно с кодом, подобным этому:

cmd = "osascript -e \'set theString to text returned of (display dialog \"Please Enter The Note To Add To Your iCloud Notes \" with icon file \"%s\" default answer \"\n\n\n\" buttons {\"OK\",\"Cancel\"} default button 1) \'"  % (appicon_abs_path_apple)
note = run_script(cmd)

Ответы [ 3 ]

1 голос
/ 02 июля 2019

В приведенном ниже списке demo.py есть пользовательская функция sanitize, которая используется для экранирования любых символов обратной косой черты (\) или двойной кавычки ("), которые пользователь может ввести в диалоговое окно. коробка. Эти символы необходимо экранировать таким образом в файле .py, а затем передать их в osascript.

demo.py

#!/usr/bin/env python

from subprocess import Popen, PIPE


def sanitize(str):
    return str.replace("\\", "\\\\") \
              .replace("\"", "\\\"")


def run_script(script):
    p = Popen(['osascript', '-'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate(script)
    return stdout

appicon_abs_path_apple = "Applications:Stickies.app:Contents:Resources:Stickies.icns"

input_dialog = """
tell application "Finder"
  activate
  set mssg to "Please Enter The Note To Add To Your iCloud Notes"
  set theString to text returned of (display dialog mssg with icon file "%s" \
      default answer "\n\n\n" buttons {"OK", "Cancel"} default button 1)
end tell
""" % (appicon_abs_path_apple)

# Notice in the following line we `sanitize` the text characters returned
# from the input dialog before assigning it to the `note` variable.
note = sanitize(run_script(input_dialog))

# -------------------------------

# Let's test that any special characters have been preserved
show_input = """
tell application "Finder"
  activate
  display dialog "%s"
end tell
""" % (note)

run_script(show_input)

Примечания:

Детали show_input и run_script(show_input) в конце demo.py предназначены только для тестирования. Это должно быть заменено кодом AppleScript, необходимым для создания новой заметки. Например:

# ...
# ...

note = sanitize(run_script(input_dialog))

# header = sanitize(header)

make_note = """
tell application "Notes"
  tell account "iCloud"
    make new note at folder "Notes" with properties {name:"%s", body:"%s"}
  end tell
end tell
""" % (header, note)

run_script(make_note)

Возможно, вы также захотите передать текстовую строку, присвоенную переменной header, через функцию sanitize (согласно строке, закомментированной в приведенном выше фрагменте кода), однако я не уверен в том, что ваш вопрос эти данные поступают из. Если это сгенерированный пользователем, то определенно sanitize это.

Также обратите внимание, как в вышеупомянутой сущности мы заключаем код Applescript в тройные двойные кавычки (""") - это помогает сделать код более читабельным и избавляет от необходимости дополнительного экранирования и \n символов, в отличие от следующее:

make_note = "osascript -e 'tell application \"Notes\" \n tell account \"iCloud\" \n make new note at folder \"Notes\" with properties {name:\"%s\", body:\"%s\"} \n end tell \n end tell'" % (header, body)

Демо-версия:

Чтобы проверить приведенную выше строку demo.py, вам необходимо:

  1. Убедитесь, что файл является исполняемым, выполнив что-то вроде следующей команды chmod и изменив путь к файлу при необходимости.
chmod +x /some/path/to/demo.py
  1. Кроме того, вы, вероятно, захотите изменить путь к HFS (то есть путь, разделенный двоеточиями), который назначен переменной appicon_abs_path_apple - в настоящее время он использует значок для приложения Stickies.

Введите:

В диалог введена следующая произвольная текстовая строка, содержащая специальные символы:

:\//tft//
c:\test\test.txt
c:\\quux\\foo.md
'¡"€#¢∞§¶•ª⁄™‹›fifl‡°·

Screenshot showing input text

Снимок экрана (выше), показывающий, что входной текст содержит много специальных символов.

Выход:

Screenshot showing that the input text is preserved after osascript

Снимок экрана (выше), показывающий, что специальные символы во входном тексте были сохранены в следующем диалоговом окне.

1 голос
/ 01 июля 2019

Мне кажется, это вопрос по питону больше, чем вопрос по AppleScript. Я имею в виду, если вы запрашивали основной текст через AppleScript, используя, скажем:

display dialog "Enter Note" default answer ""

AppleScript будет автоматически экранировать любые проблемные символы (то есть, если они введут c:\test\test.txt, результатом этой команды отображения будет c:\\test\\test.txt). Мне кажется, что вы получаете текст из какого-то другого источника и используете python для отправки его через AppleScript. Это означает, что вы должны избежать всего этого в python перед отправкой в ​​osascript.

Побег довольно прост, аналитически: замените каждый обратный слеш двойным. В Python я думаю, что это будет что-то вроде:

body.replace('\','\\')

В зависимости от того, какой текст вы получаете, вам может понадобиться немного его настроить. Например, если у вас есть лысые двойные кавычки, вам нужно их избежать:

body.replace('"','\"')

и если у вас есть встроенные в текст табуляции, возврат каретки или перевод строки (\ t, \ r, \ n), вам, возможно, придется найти какой-то способ , избегающий экранирования ( вам, возможно, придется покопаться в регулярных выражениях для этого). Но идея состоит в том, чтобы сначала поместить escape-коды AppleScript в python, а затем вызвать команду osacript.

EDIT:

Теперь, когда я знаю, что вы получаете пользовательский текст из display dialog, я собираюсь предложить вам вырезать посредника Python и обработать все это в AppleScript. Сценарий, который вы хотите это:

set txt to text returned of (display dialog "Please Enter The Note To Add To Your iCloud Notes" default answer "\n\n\n")
tell application "Notes"
    tell account "iCloud"
        make new note at folder "Notes" with properties {name:"myname", body:txt}
    end tell
end tell

Вы можете сохранить это как файл сценария и вызвать его из osascript - osascript scriptName.scpt - или вы можете ввести его непосредственно в osascript, используя последовательные опции -e:

osascript -e 'set txt to text returned of (display dialog "Please Enter The Note To Add To Your iCloud Notes" default answer "\n\n\n")' -e 'tell application "Notes"' -e 'tell account "iCloud"' -e 'make new note at folder "Notes" with properties {name:"myname", body:txt}' -e 'end tell' -e 'end tell'

если вам нужно передать аргументы в скрипт (например, переменную для имени пользователя или путь к иконке), вам нужно использовать явный обработчик выполнения. Посмотрите «man osascript» или спросите, и я покажу вам, как.

0 голосов
/ 02 июля 2019

Вот как можно параметризовать запуск AppleScript через osascript:

#!/usr/bin/env python

import subprocess

header ='my name'
body = 'some text'

subprocess.call(['osascript', 
    '-e', 'on run {theHeader, theBody}',
    '-e', ' tell application "Notes"',
    '-e', '  tell account "iCloud"',
    '-e', '   make new note at folder "Notes" with properties {name:theHeader, body:theBody}',
    '-e', '  end tell',
    '-e', ' end tell',
    '-e', 'end run', '--', header, body])

Для передачи более сложных данных рассмотрим py-applecript или PyObjC + AppleScript-ObjC .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...