├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── .markdownlint.json ├── .nojekyll ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── PyXA ├── Additions │ ├── Devices.py │ ├── Learn.py │ ├── Speech.py │ ├── UI.py │ ├── Utils.py │ ├── Web.py │ └── __init__.py ├── XABase.py ├── XABaseScriptable.py ├── XAErrors.py ├── XAEvents.py ├── XAProtocols.py ├── XATypes.py ├── __init__.py └── apps │ ├── AcrobatReader.py │ ├── Alfred.py │ ├── Amphetamine.py │ ├── Arc.py │ ├── Automator.py │ ├── Bike.py │ ├── Calculator.py │ ├── Calendar.py │ ├── Cardhop.py │ ├── Chromium.py │ ├── Console.py │ ├── Contacts.py │ ├── DatabaseEvents.py │ ├── Dictionary.py │ ├── Drafts.py │ ├── Fantastical.py │ ├── Finder.py │ ├── Flow.py │ ├── FontBook.py │ ├── Hammerspoon.py │ ├── IINA.py │ ├── ImageEvents.py │ ├── Keynote.py │ ├── Mail.py │ ├── Maps.py │ ├── Messages.py │ ├── Music.py │ ├── Notes.py │ ├── Numbers.py │ ├── OmniOutliner.py │ ├── OmniWeb.py │ ├── Pages.py │ ├── PathFinder.py │ ├── PhotosApp.py │ ├── Preview.py │ ├── QuickTimePlayer.py │ ├── RStudio.py │ ├── Reminders.py │ ├── Safari.py │ ├── ScriptEditor.py │ ├── Shortcuts.py │ ├── Spotify.py │ ├── Stocks.py │ ├── SystemEvents.py │ ├── SystemPreferences.py │ ├── TV.py │ ├── Terminal.py │ ├── TextEdit.py │ ├── VLC.py │ ├── __init__.py │ ├── iTerm.py │ └── iWorkApplicationBase.py ├── README.md ├── docs ├── .buildinfo ├── .nojekyll ├── _images │ ├── CPUMonitor.png │ ├── HelloMenu.png │ ├── JWSTMenuBar.png │ ├── MenuItemImages.png │ ├── PrintHi.png │ ├── PrintHiImage.png │ └── PyXALogoTransparent.png ├── _modules │ ├── PyXA │ │ ├── Additions │ │ │ ├── Devices.html │ │ │ ├── Learn.html │ │ │ ├── Speech.html │ │ │ ├── UI.html │ │ │ ├── Utils.html │ │ │ └── Web.html │ │ ├── XABase.html │ │ ├── XABaseScriptable.html │ │ ├── XAErrors.html │ │ ├── XAProtocols.html │ │ ├── XATypes.html │ │ └── apps │ │ │ ├── Arc.html │ │ │ ├── Automator.html │ │ │ ├── Bike.html │ │ │ ├── Calculator.html │ │ │ ├── Calendar.html │ │ │ ├── Cardhop.html │ │ │ ├── Chromium.html │ │ │ ├── Console.html │ │ │ ├── Contacts.html │ │ │ ├── Dictionary.html │ │ │ ├── Drafts.html │ │ │ ├── Fantastical.html │ │ │ ├── Finder.html │ │ │ ├── Flow.html │ │ │ ├── FontBook.html │ │ │ ├── Hammerspoon.html │ │ │ ├── IINA.html │ │ │ ├── ImageEvents.html │ │ │ ├── Keynote.html │ │ │ ├── Mail.html │ │ │ ├── Maps.html │ │ │ ├── Messages.html │ │ │ ├── Music.html │ │ │ ├── Notes.html │ │ │ ├── OmniOutliner.html │ │ │ ├── OmniWeb.html │ │ │ ├── Pages.html │ │ │ ├── PathFinder.html │ │ │ ├── PhotosApp.html │ │ │ ├── Preview.html │ │ │ ├── QuickTimePlayer.html │ │ │ ├── RStudio.html │ │ │ ├── Reminders.html │ │ │ ├── Safari.html │ │ │ ├── Shortcuts.html │ │ │ ├── Spotify.html │ │ │ ├── Stocks.html │ │ │ ├── SystemEvents.html │ │ │ ├── SystemPreferences.html │ │ │ ├── TV.html │ │ │ ├── Terminal.html │ │ │ ├── TextEdit.html │ │ │ ├── VLC.html │ │ │ ├── iTerm.html │ │ │ └── iWorkApplicationBase.html │ └── index.html ├── _sources │ ├── about │ │ └── index.rst.txt │ ├── bugs.rst.txt │ ├── index.rst.txt │ ├── reference │ │ ├── additions │ │ │ ├── devices.rst.txt │ │ │ ├── learn.rst.txt │ │ │ ├── speech.rst.txt │ │ │ ├── ui.rst.txt │ │ │ ├── utils.rst.txt │ │ │ └── web.rst.txt │ │ ├── apps │ │ │ ├── arc.rst.txt │ │ │ ├── automator.rst.txt │ │ │ ├── bike.rst.txt │ │ │ ├── calculator.rst.txt │ │ │ ├── calendar.rst.txt │ │ │ ├── cardhop.rst.txt │ │ │ ├── chromium.rst.txt │ │ │ ├── console.rst.txt │ │ │ ├── contacts.rst.txt │ │ │ ├── dictionary.rst.txt │ │ │ ├── drafts.rst.txt │ │ │ ├── fantastical.rst.txt │ │ │ ├── finder.rst.txt │ │ │ ├── flow.rst.txt │ │ │ ├── fontbook.rst.txt │ │ │ ├── hammerspoon.rst.txt │ │ │ ├── iina.rst.txt │ │ │ ├── imageevents.rst.txt │ │ │ ├── iterm.rst.txt │ │ │ ├── iwork.rst.txt │ │ │ ├── keynote.rst.txt │ │ │ ├── mail.rst.txt │ │ │ ├── maps.rst.txt │ │ │ ├── messages.rst.txt │ │ │ ├── music.rst.txt │ │ │ ├── notes.rst.txt │ │ │ ├── numbers.rst.txt │ │ │ ├── omnioutliner.rst.txt │ │ │ ├── omniweb.rst.txt │ │ │ ├── pages.rst.txt │ │ │ ├── pathfinder.rst.txt │ │ │ ├── photos.rst.txt │ │ │ ├── preview.rst.txt │ │ │ ├── quicktimeplayer.rst.txt │ │ │ ├── reminders.rst.txt │ │ │ ├── rstudio.rst.txt │ │ │ ├── safari.rst.txt │ │ │ ├── shortcuts.rst.txt │ │ │ ├── spotify.rst.txt │ │ │ ├── stocks.rst.txt │ │ │ ├── systemevents.rst.txt │ │ │ ├── systempreferences.rst.txt │ │ │ ├── terminal.rst.txt │ │ │ ├── textedit.rst.txt │ │ │ ├── tv.rst.txt │ │ │ └── vlc.rst.txt │ │ ├── index.rst.txt │ │ ├── xabase.rst.txt │ │ ├── xabasescriptable.rst.txt │ │ ├── xaerrors.rst.txt │ │ ├── xaprotocols.rst.txt │ │ └── xatypes.rst.txt │ └── tutorial │ │ ├── applescript.rst.txt │ │ ├── apps │ │ ├── automator │ │ │ ├── index.rst.txt │ │ │ └── tutorial1.rst.txt │ │ ├── bike │ │ │ └── index.rst.txt │ │ ├── calculator │ │ │ └── index.rst.txt │ │ ├── calendar │ │ │ └── index.rst.txt │ │ ├── cardhop │ │ │ └── index.rst.txt │ │ ├── chromium │ │ │ └── index.rst.txt │ │ ├── console │ │ │ └── index.rst.txt │ │ ├── contacts │ │ │ └── index.rst.txt │ │ ├── dictionary │ │ │ └── index.rst.txt │ │ ├── drafts │ │ │ └── index.rst.txt │ │ ├── fantastical │ │ │ └── index.rst.txt │ │ ├── finder │ │ │ └── index.rst.txt │ │ ├── flow │ │ │ └── index.rst.txt │ │ ├── fontbook │ │ │ └── index.rst.txt │ │ ├── hammerspoon │ │ │ └── index.rst.txt │ │ ├── imageevents │ │ │ └── index.rst.txt │ │ ├── index.rst.txt │ │ ├── iterm │ │ │ └── index.rst.txt │ │ ├── keynote │ │ │ └── index.rst.txt │ │ ├── mail │ │ │ └── index.rst.txt │ │ ├── maps │ │ │ └── index.rst.txt │ │ ├── messages │ │ │ └── index.rst.txt │ │ ├── music │ │ │ └── index.rst.txt │ │ ├── notes │ │ │ └── index.rst.txt │ │ ├── numbers │ │ │ └── index.rst.txt │ │ ├── omnioutliner │ │ │ └── index.rst.txt │ │ ├── pages │ │ │ └── index.rst.txt │ │ ├── photos │ │ │ └── index.rst.txt │ │ ├── preview │ │ │ └── index.rst.txt │ │ ├── quicktimeplayer │ │ │ └── index.rst.txt │ │ ├── reminders │ │ │ └── index.rst.txt │ │ ├── rstudio │ │ │ └── index.rst.txt │ │ ├── safari │ │ │ └── index.rst.txt │ │ ├── shortcuts │ │ │ └── index.rst.txt │ │ ├── spotify │ │ │ └── index.rst.txt │ │ ├── stocks │ │ │ └── index.rst.txt │ │ ├── systemevents │ │ │ └── index.rst.txt │ │ ├── systempreferences │ │ │ └── index.rst.txt │ │ ├── terminal │ │ │ └── index.rst.txt │ │ ├── textedit │ │ │ └── index.rst.txt │ │ ├── tv │ │ │ └── index.rst.txt │ │ └── vlc │ │ │ └── index.rst.txt │ │ ├── appscript.rst.txt │ │ ├── clipboard.rst.txt │ │ ├── devices.rst.txt │ │ ├── extensions │ │ └── web │ │ │ └── rssfeed.rst.txt │ │ ├── images.rst.txt │ │ ├── index.rst.txt │ │ ├── lists.rst.txt │ │ ├── menubar.rst.txt │ │ ├── spotlight.rst.txt │ │ ├── tips_tricks.rst.txt │ │ ├── ui_scripting.rst.txt │ │ └── user_input.rst.txt ├── _static │ ├── _sphinx_javascript_frameworks_compat.js │ ├── assets │ │ ├── CPUMonitor.png │ │ ├── Example3_Notes.png │ │ ├── HelloMenu.png │ │ ├── JWSTMenuBar.png │ │ ├── MenuItemImages.png │ │ ├── PrintHi.png │ │ ├── PrintHiImage.png │ │ ├── PyXALogoLight.png │ │ └── PyXALogoTransparent.png │ ├── basic.css │ ├── css │ │ ├── badge_only.css │ │ ├── fonts │ │ │ ├── Roboto-Slab-Bold.woff │ │ │ ├── Roboto-Slab-Bold.woff2 │ │ │ ├── Roboto-Slab-Regular.woff │ │ │ ├── Roboto-Slab-Regular.woff2 │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ ├── fontawesome-webfont.woff2 │ │ │ ├── lato-bold-italic.woff │ │ │ ├── lato-bold-italic.woff2 │ │ │ ├── lato-bold.woff │ │ │ ├── lato-bold.woff2 │ │ │ ├── lato-normal-italic.woff │ │ │ ├── lato-normal-italic.woff2 │ │ │ ├── lato-normal.woff │ │ │ └── lato-normal.woff2 │ │ └── theme.css │ ├── doctools.js │ ├── documentation_options.js │ ├── file.png │ ├── graphviz.css │ ├── jquery-3.5.1.js │ ├── jquery-3.6.0.js │ ├── jquery.js │ ├── js │ │ ├── badge_only.js │ │ ├── html5shiv-printshiv.min.js │ │ ├── html5shiv.min.js │ │ └── theme.js │ ├── language_data.js │ ├── minus.png │ ├── plus.png │ ├── pygments.css │ ├── searchtools.js │ ├── sphinx_highlight.js │ ├── underscore-1.13.1.js │ └── underscore.js ├── about │ └── index.html ├── bugs.html ├── genindex.html ├── index.html ├── objects.inv ├── py-modindex.html ├── reference │ ├── additions │ │ ├── devices.html │ │ ├── learn.html │ │ ├── speech.html │ │ ├── ui.html │ │ ├── utils.html │ │ └── web.html │ ├── apps │ │ ├── arc.html │ │ ├── automator.html │ │ ├── bike.html │ │ ├── calculator.html │ │ ├── calendar.html │ │ ├── cardhop.html │ │ ├── chromium.html │ │ ├── console.html │ │ ├── contacts.html │ │ ├── dictionary.html │ │ ├── drafts.html │ │ ├── fantastical.html │ │ ├── finder.html │ │ ├── flow.html │ │ ├── fontbook.html │ │ ├── hammerspoon.html │ │ ├── iina.html │ │ ├── imageevents.html │ │ ├── iterm.html │ │ ├── iwork.html │ │ ├── keynote.html │ │ ├── mail.html │ │ ├── maps.html │ │ ├── messages.html │ │ ├── music.html │ │ ├── notes.html │ │ ├── numbers.html │ │ ├── omnioutliner.html │ │ ├── omniweb.html │ │ ├── pages.html │ │ ├── pathfinder.html │ │ ├── photos.html │ │ ├── preview.html │ │ ├── quicktimeplayer.html │ │ ├── reminders.html │ │ ├── rstudio.html │ │ ├── safari.html │ │ ├── shortcuts.html │ │ ├── spotify.html │ │ ├── stocks.html │ │ ├── systemevents.html │ │ ├── systempreferences.html │ │ ├── terminal.html │ │ ├── textedit.html │ │ ├── tv.html │ │ └── vlc.html │ ├── index.html │ ├── xabase.html │ ├── xabasescriptable.html │ ├── xaerrors.html │ ├── xaprotocols.html │ └── xatypes.html ├── search.html ├── searchindex.js └── tutorial │ ├── applescript.html │ ├── apps │ ├── automator │ │ ├── index.html │ │ └── tutorial1.html │ ├── bike │ │ └── index.html │ ├── calculator │ │ └── index.html │ ├── calendar │ │ └── index.html │ ├── cardhop │ │ └── index.html │ ├── chromium │ │ └── index.html │ ├── console │ │ └── index.html │ ├── contacts │ │ └── index.html │ ├── dictionary │ │ └── index.html │ ├── drafts │ │ └── index.html │ ├── fantastical │ │ └── index.html │ ├── finder │ │ └── index.html │ ├── flow │ │ └── index.html │ ├── fontbook │ │ └── index.html │ ├── hammerspoon │ │ └── index.html │ ├── imageevents │ │ └── index.html │ ├── index.html │ ├── iterm │ │ └── index.html │ ├── keynote │ │ └── index.html │ ├── mail │ │ └── index.html │ ├── maps │ │ └── index.html │ ├── messages │ │ └── index.html │ ├── music │ │ └── index.html │ ├── notes │ │ └── index.html │ ├── numbers │ │ └── index.html │ ├── omnioutliner │ │ └── index.html │ ├── pages │ │ └── index.html │ ├── photos │ │ └── index.html │ ├── preview │ │ └── index.html │ ├── quicktimeplayer │ │ └── index.html │ ├── reminders │ │ └── index.html │ ├── rstudio │ │ └── index.html │ ├── safari │ │ └── index.html │ ├── shortcuts │ │ └── index.html │ ├── spotify │ │ └── index.html │ ├── stocks │ │ └── index.html │ ├── systemevents │ │ └── index.html │ ├── systempreferences │ │ └── index.html │ ├── terminal │ │ └── index.html │ ├── textedit │ │ └── index.html │ ├── tv │ │ └── index.html │ └── vlc │ │ └── index.html │ ├── appscript.html │ ├── clipboard.html │ ├── devices.html │ ├── extensions │ └── web │ │ └── rssfeed.html │ ├── images.html │ ├── index.html │ ├── lists.html │ ├── menubar.html │ ├── spotlight.html │ ├── tips_tricks.html │ ├── ui_scripting.html │ └── user_input.html ├── pyproject.toml ├── setup.cfg ├── sphinx ├── Makefile ├── make.bat └── source │ ├── _static │ └── assets │ │ ├── CPUMonitor.png │ │ ├── Example3_Notes.png │ │ ├── HelloMenu.png │ │ ├── JWSTMenuBar.png │ │ ├── MenuItemImages.png │ │ ├── PrintHi.png │ │ ├── PrintHiImage.png │ │ ├── PyXALogoLight.png │ │ └── PyXALogoTransparent.png │ ├── about │ └── index.rst │ ├── bugs.rst │ ├── conf.py │ ├── index.rst │ ├── reference │ ├── additions │ │ ├── devices.rst │ │ ├── learn.rst │ │ ├── speech.rst │ │ ├── ui.rst │ │ ├── utils.rst │ │ └── web.rst │ ├── apps │ │ ├── arc.rst │ │ ├── automator.rst │ │ ├── bike.rst │ │ ├── calculator.rst │ │ ├── calendar.rst │ │ ├── cardhop.rst │ │ ├── chromium.rst │ │ ├── console.rst │ │ ├── contacts.rst │ │ ├── dictionary.rst │ │ ├── drafts.rst │ │ ├── fantastical.rst │ │ ├── finder.rst │ │ ├── flow.rst │ │ ├── fontbook.rst │ │ ├── hammerspoon.rst │ │ ├── iina.rst │ │ ├── imageevents.rst │ │ ├── iterm.rst │ │ ├── iwork.rst │ │ ├── keynote.rst │ │ ├── mail.rst │ │ ├── maps.rst │ │ ├── messages.rst │ │ ├── music.rst │ │ ├── notes.rst │ │ ├── numbers.rst │ │ ├── omnioutliner.rst │ │ ├── omniweb.rst │ │ ├── pages.rst │ │ ├── pathfinder.rst │ │ ├── photos.rst │ │ ├── preview.rst │ │ ├── quicktimeplayer.rst │ │ ├── reminders.rst │ │ ├── rstudio.rst │ │ ├── safari.rst │ │ ├── shortcuts.rst │ │ ├── spotify.rst │ │ ├── stocks.rst │ │ ├── systemevents.rst │ │ ├── systempreferences.rst │ │ ├── terminal.rst │ │ ├── textedit.rst │ │ ├── tv.rst │ │ └── vlc.rst │ ├── index.rst │ ├── xabase.rst │ ├── xabasescriptable.rst │ ├── xaerrors.rst │ ├── xaprotocols.rst │ └── xatypes.rst │ └── tutorial │ ├── applescript.rst │ ├── apps │ ├── automator │ │ ├── index.rst │ │ └── tutorial1.rst │ ├── bike │ │ └── index.rst │ ├── calculator │ │ └── index.rst │ ├── calendar │ │ └── index.rst │ ├── cardhop │ │ └── index.rst │ ├── chromium │ │ └── index.rst │ ├── console │ │ └── index.rst │ ├── contacts │ │ └── index.rst │ ├── dictionary │ │ └── index.rst │ ├── drafts │ │ └── index.rst │ ├── fantastical │ │ └── index.rst │ ├── finder │ │ └── index.rst │ ├── flow │ │ └── index.rst │ ├── fontbook │ │ └── index.rst │ ├── hammerspoon │ │ └── index.rst │ ├── imageevents │ │ └── index.rst │ ├── index.rst │ ├── iterm │ │ └── index.rst │ ├── keynote │ │ └── index.rst │ ├── mail │ │ └── index.rst │ ├── maps │ │ └── index.rst │ ├── messages │ │ └── index.rst │ ├── music │ │ └── index.rst │ ├── notes │ │ └── index.rst │ ├── numbers │ │ └── index.rst │ ├── omnioutliner │ │ └── index.rst │ ├── pages │ │ └── index.rst │ ├── photos │ │ └── index.rst │ ├── preview │ │ └── index.rst │ ├── quicktimeplayer │ │ └── index.rst │ ├── reminders │ │ └── index.rst │ ├── rstudio │ │ └── index.rst │ ├── safari │ │ └── index.rst │ ├── shortcuts │ │ └── index.rst │ ├── spotify │ │ └── index.rst │ ├── stocks │ │ └── index.rst │ ├── systemevents │ │ └── index.rst │ ├── systempreferences │ │ └── index.rst │ ├── terminal │ │ └── index.rst │ ├── textedit │ │ └── index.rst │ ├── tv │ │ └── index.rst │ └── vlc │ │ └── index.rst │ ├── appscript.rst │ ├── clipboard.rst │ ├── devices.rst │ ├── extensions │ └── web │ │ └── rssfeed.rst │ ├── images.rst │ ├── index.rst │ ├── lists.rst │ ├── menubar.rst │ ├── spotlight.rst │ ├── tips_tricks.rst │ ├── ui_scripting.rst │ └── user_input.rst └── tests ├── __init__.py ├── test_base_scriptable.py ├── test_calendar.py ├── test_contacts.py ├── test_database_events.py ├── test_finder.py ├── test_iwork.py ├── test_messages.py ├── test_music.py ├── test_notes.py ├── test_omniweb.py ├── test_reminders.py ├── test_safari.py ├── test_shortcuts.py ├── test_terminal.py └── test_textedit.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: SKaplanOfficial 4 | custom: ["https://www.paypal.com/donate/?hosted_button_id=2XFX5UXXR8M6J"] 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Development Files 2 | sdefs/* 3 | dir/* 4 | oldref/* 5 | .vscode/* 6 | 7 | # Byte-compiled / optimized / DLL files 8 | __pycache__/ 9 | *.py[cod] 10 | *$py.class 11 | 12 | # C extensions 13 | *.so 14 | 15 | # Distribution / packaging 16 | .Python 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | .eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | var/ 28 | wheels/ 29 | share/python-wheels/ 30 | *.egg-info/ 31 | .installed.cfg 32 | *.egg 33 | MANIFEST 34 | 35 | # PyInstaller 36 | # Usually these files are written by a python script from a template 37 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 38 | *.manifest 39 | *.spec 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .nox/ 49 | .coverage 50 | .coverage.* 51 | .cache 52 | nosetests.xml 53 | coverage.xml 54 | *.cover 55 | *.py,cover 56 | .hypothesis/ 57 | .pytest_cache/ 58 | cover/ 59 | 60 | # Translations 61 | *.mo 62 | *.pot 63 | 64 | # Django stuff: 65 | *.log 66 | local_settings.py 67 | db.sqlite3 68 | db.sqlite3-journal 69 | 70 | # Flask stuff: 71 | instance/ 72 | .webassets-cache 73 | 74 | # Scrapy stuff: 75 | .scrapy 76 | 77 | # Sphinx documentation 78 | docs/_build/ 79 | 80 | # PyBuilder 81 | .pybuilder/ 82 | target/ 83 | 84 | # Jupyter Notebook 85 | .ipynb_checkpoints 86 | 87 | # IPython 88 | profile_default/ 89 | ipython_config.py 90 | 91 | # pyenv 92 | # For a library or package, you might want to ignore these files since the code is 93 | # intended to run in multiple environments; otherwise, check them in: 94 | # .python-version 95 | 96 | # pipenv 97 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 98 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 99 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 100 | # install all needed dependencies. 101 | #Pipfile.lock 102 | 103 | # poetry 104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 105 | # This is especially recommended for binary packages to ensure reproducibility, and is more 106 | # commonly ignored for libraries. 107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 108 | #poetry.lock 109 | 110 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 111 | __pypackages__/ 112 | 113 | # Celery stuff 114 | celerybeat-schedule 115 | celerybeat.pid 116 | 117 | # SageMath parsed files 118 | *.sage.py 119 | 120 | # Environments 121 | .env 122 | .venv 123 | env/ 124 | venv/ 125 | ENV/ 126 | env.bak/ 127 | venv.bak/ 128 | 129 | # Spyder project settings 130 | .spyderproject 131 | .spyproject 132 | 133 | # Rope project settings 134 | .ropeproject 135 | 136 | # mkdocs documentation 137 | /site 138 | 139 | # mypy 140 | .mypy_cache/ 141 | .dmypy.json 142 | dmypy.json 143 | 144 | # Pyre type checker 145 | .pyre/ 146 | 147 | # pytype static type analyzer 148 | .pytype/ 149 | 150 | # Cython debug symbols 151 | cython_debug/ 152 | 153 | # PyCharm 154 | # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can 155 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 156 | # and can be added to the global gitignore or merged into this file. For a more nuclear 157 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 158 | #.idea/ 159 | .python-version 160 | apps/base.py 161 | test.py 162 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "line-length": false, 3 | "no-inline-html": false, 4 | "no-blanks-blockquote": false, 5 | "first-line-heading": false, 6 | "no-emphasis-as-heading": false 7 | } -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to PyXA 2 | 3 | ## Report Issues 4 | 5 | If you have a problem with PyXA, let us know! We might be able to help you get around the problem while we work toward a more permanent fix. Before you submit an issue, please check to see if it has already been reported -- if so, leave a comment on the existing issue to let us know that you're experiencing it too. 6 | 7 | If you've identified a new problem, go ahead and [create a new issue](https://github.com/SKaplanOfficial/PyXA/issues/new) on the PyXA GitHub repository. Provide as much detail as possible about the problem, your environment (e.g. operating system, Python version), and the steps required to reproduce any errors you encounter. 8 | 9 | ### Getting Started 10 | 11 | 1. Fork the project, create a new branch in your fork, and make changes associated with a reported issue. 12 | 2. Test your changes. We don't have a formal testing procedure yet, but at the very least please play around with your modified version of PyXA and make sure there are no glaring problems. 13 | 3. Create documentation for your changes -- whether this is in the form of code comments or Sphinx documents, please make sure your changes are appropriately documented. Additional documentation may be requested during pull request review. 14 | 4. Create a new pull request into the upcoming PyXA release branch (not the main branch) and fill out the provided template. 15 | 5. Make changes as requested by reviewers of the pull request. 16 | 17 | ## Guidelines for Contributing to PyXA's Documentation 18 | 19 | 20 | 21 | ### Comment on an Issue 22 | 23 | Since we want PyXA's documentation to maintain coherence and consistency, we ask that non-trivial changes to the documentation be discussed in the issue comments before any pull requests are made. Pull requests submitted prior to discussion on a documentation-related issue might not be approved. 24 | 25 | ### Fix an Issue 26 | 27 | After an issue has been discussed, you and others may be tasked with implementing a resolution. You might not be formally assigned to the issue; the assignment might come naturally from the discussion. You can always volunteer to work on an issue, but remember to wait until the discussion reaches a point of maturity before spending time on something we might not move forward with. 28 | 29 | ### Make a Pull Request 30 | 31 | Once you've addressed a documentation issue in full, make a pull request and follow the provided template. 32 | 33 | ## Get More Involved 34 | 35 | If you're interested in getting more involved in PyXA development, join our [Discord server](https://discord.gg/Crypg65dxK) to discuss the future of PyXA! 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2024 Stephen Kaplan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include PyXA/apps * 2 | recursive-include PyXA/Additions * -------------------------------------------------------------------------------- /PyXA/Additions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/PyXA/Additions/__init__.py -------------------------------------------------------------------------------- /PyXA/XAErrors.py: -------------------------------------------------------------------------------- 1 | class ApplicationNotFoundError(Exception): 2 | def __init__(self, name: str): 3 | self.name = name 4 | Exception.__init__(self, name) 5 | 6 | def __str__(self): 7 | return f"Application {self.name} not found." 8 | 9 | 10 | class AuthenticationError(Exception): 11 | def __init__(self, message: str): 12 | self.message = message 13 | Exception.__init__(self, message) 14 | 15 | def __str__(self): 16 | return f"Failed due to insufficient authorization. {self.message}" 17 | 18 | 19 | class InvalidPredicateError(Exception): 20 | def __init__(self, message: str): 21 | self.message = message 22 | Exception.__init__(self, message) 23 | 24 | def __str__(self): 25 | return f"Could not construct valid predicate format. {self.message}" 26 | 27 | 28 | class UnconstructableClassError(Exception): 29 | def __init__(self, message: str): 30 | self.message = message 31 | Exception.__init__(self, message) 32 | 33 | def __str__(self): 34 | return f"Could not create new element. {self.message}" 35 | 36 | 37 | class AppleScriptError(Exception): 38 | """Raised when an AppleScript error occurs.""" 39 | 40 | def __init__(self, err: dict, script: str): 41 | error_number = err["NSAppleScriptErrorNumber"] 42 | error_message = err["NSAppleScriptErrorMessage"] 43 | error_range = err["NSAppleScriptErrorRange"].rangeValue() 44 | error_context = script[ 45 | script.rfind("\n", 0, error_range.location) : script.find( 46 | "\n", error_range.location, len(script) 47 | ) 48 | ].strip() 49 | 50 | print(script.split("\n")) 51 | error_line = next( 52 | (n for (n, l) in enumerate(script.split("\n")) if error_context in l), -1 53 | ) 54 | 55 | self.number = int(error_number) 56 | self.message = error_message 57 | self.line_number = error_line 58 | self.near = error_context 59 | 60 | Exception.__init__( 61 | self, 62 | f"Error {self.number}: {self.message} On line #{self.line_number}: '{self.near}'.", 63 | ) 64 | 65 | def __str__(self): 66 | return f"Error {self.number}: {self.message} On line #{self.line_number}: '{self.near}'." 67 | -------------------------------------------------------------------------------- /PyXA/XATypes.py: -------------------------------------------------------------------------------- 1 | """Types used throughout PyXA for various purposes. 2 | 3 | .. versionadded:: 0.1.1 4 | """ 5 | 6 | from collections import namedtuple 7 | 8 | XAPoint = namedtuple("XAPoint", ["x", "y"]) 9 | """A named tuple representing an (x, y) coordinate. 10 | """ 11 | 12 | XARectangle = namedtuple("XARectangle", ["x", "y", "width", "height"]) 13 | """A named tuple representing a rectangle with an origin point (x, y) and dimensions width x height. 14 | """ 15 | 16 | XADatetimeBlock = namedtuple("XADatetimeBlock", ["date", "duration"]) 17 | """A named tuple representing a date and an associated duration.""" 18 | -------------------------------------------------------------------------------- /PyXA/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import sys 3 | from types import ModuleType 4 | 5 | from PyXA import XABase, XABaseScriptable, XAEvents, Additions 6 | 7 | from .XABase import ( 8 | # Base Types 9 | XAText, 10 | XAURL, 11 | XAPath, 12 | XAColor, 13 | XASound, 14 | XAImage, 15 | XAVideo, 16 | XALocation, 17 | Application, 18 | # Utilities 19 | AppleScript, 20 | XAPredicate, 21 | # System Features 22 | XAClipboard, 23 | XASpotlight, 24 | # Alerts, Dialogs, Menus, and Notifications 25 | XAFilePicker, 26 | XAFolderPicker, 27 | XAApplicationPicker, 28 | XADialog, 29 | XAFileNameDialog, 30 | XAColorPicker, 31 | XAColorPickerStyle, 32 | XAMenu, 33 | # Constants 34 | VERSION, 35 | application_classes, 36 | # XAFinderExtension, 37 | # Methods 38 | current_application, 39 | running_applications, 40 | active_browser, 41 | ) 42 | 43 | old_module = sys.modules["PyXA"] 44 | 45 | # Adds apps as methods on PyXA module, e.g. PyXA.Calendar() --> XACalendarApplication instance 46 | for index, app_name in enumerate(application_classes): 47 | wrapper_name = app_name.title().replace(" ", "") 48 | setattr( 49 | old_module, 50 | wrapper_name, 51 | lambda local_app_name=app_name: Application(local_app_name), 52 | ) 53 | 54 | # JIT imports 55 | module_map = { 56 | "XACommandDetector": ".Additions.Speech", 57 | "XASpeech": ".Additions.Speech", 58 | "XASpeechRecognizer": ".Additions.Speech", 59 | "XACamera": ".Additions.Devices", 60 | "XAMicrophone": ".Additions.Devices", 61 | "XAScreen": ".Additions.Devices", 62 | "XALSM": ".Additions.Learn", 63 | "SDEFParser": ".Additions.Utils", 64 | "AppBuilder": ".Additions.Utils", 65 | "XAMenuBar": ".Additions.UI", 66 | "XAAlertStyle": ".Additions.UI", 67 | "XAAlert": ".Additions.UI", 68 | "XANotification": ".Additions.UI", 69 | "XAHUD": ".Additions.UI", 70 | "RSSFeed": ".Additions.Web", 71 | } 72 | 73 | 74 | class module(ModuleType): 75 | def __getattr__(self, attr): 76 | if attr in old_module.__dict__: 77 | return getattr(old_module, attr) 78 | 79 | if attr in module_map: 80 | module = importlib.import_module(module_map[attr], "PyXA") 81 | return getattr(module, attr) 82 | 83 | 84 | sys.modules["PyXA"] = module("PyXA") 85 | -------------------------------------------------------------------------------- /PyXA/apps/Alfred.py: -------------------------------------------------------------------------------- 1 | """.. versionadded:: 0.0.8 2 | 3 | Control Alfred using JXA-like syntax. 4 | """ 5 | 6 | from PyXA import XABaseScriptable 7 | 8 | 9 | class XAAlfredApplication(XABaseScriptable.XASBApplication): 10 | """A class for managing and interacting with Alfred.app. 11 | 12 | .. versionadded:: 0.0.8 13 | """ 14 | 15 | def __init__(self, properties): 16 | super().__init__(properties) 17 | 18 | def search(self, query: str): 19 | """Shows Alfred with the given search query 20 | 21 | :param query: The term(s) to search 22 | :type query: str 23 | 24 | .. versionadded:: 0.0.8 25 | """ 26 | self.xa_scel.search_(query) 27 | 28 | def action(self, items: list[str]): 29 | """Shows Alfred actions for the given file/folder/item. 30 | 31 | :param items: A list of item paths 32 | :type items: list[str] 33 | 34 | .. versionadded:: 0.0.8 35 | """ 36 | self.xa_scel.action_asType_(items, None) 37 | 38 | def run_workflow(self, workflow: str, trigger: str, argument: str): 39 | """Runs the given workflow with the specified trigger and argument. 40 | 41 | :param workflow: The workflow to run 42 | :type workflow: str 43 | :param trigger: The trigger to run the workflow with 44 | :type trigger: str 45 | :param argument: The argument to pass alongside the trigger 46 | :type argument: str 47 | 48 | .. versionadded:: 0.0.8 49 | """ 50 | self.xa_scel.runTrigger_inWorkflow_withArgument_(trigger, workflow, argument) 51 | 52 | def reload_workflow(self, workflow_uid: str): 53 | """Reloads the workflow with the given UID or Bundle ID 54 | 55 | :param workflow: The UID or Bundle ID of the workflow to reload 56 | :type workflow: str 57 | 58 | .. versionadded:: 0.0.8 59 | """ 60 | self.xa_scel.reloadWorkflow_(workflow_uid) 61 | 62 | def set_configuration( 63 | self, variable_name: str, value: str, workflow: str, exportable: bool = False 64 | ): 65 | """Sets the workflow configuration variable with the given name. 66 | 67 | :param variable_name: The configuration variable to set 68 | :type variable_name: str 69 | :param value: The value to assign to the configuration variable 70 | :type value: str 71 | :param workflow: The bundle ID of the workflow to make the change in 72 | :type workflow: str 73 | :param exportable: Whether the variable is fine for export (whether the Don't Export box is unchecked), defaults to False 74 | :type exportable: bool, optional 75 | 76 | .. versionadded:: 0.0.8 77 | """ 78 | self.xa_scel.setConfiguration_toValue_inWorkflow_exportable_( 79 | variable_name, value, workflow, exportable 80 | ) 81 | 82 | def remove_configuration(self, variable_name: str, workflow: str): 83 | """Removes the workflow configuration variable with the given name. 84 | 85 | :param variable_name: The configuration variable to remove 86 | :type variable_name: str 87 | :param workflow: The bundle ID of the workflow to make the change in 88 | :type workflow: str 89 | 90 | .. versionadded:: 0.0.8 91 | """ 92 | self.xa_scel.removeConfiguration_inWorkflow_(variable_name, workflow) 93 | 94 | def set_theme(self, theme_name: str): 95 | """Sets the Alfred theme to the given theme name. 96 | 97 | :param theme_name: The name of the desired theme 98 | :type theme_name: str 99 | 100 | .. versionadded:: 0.0.8 101 | """ 102 | self.xa_scel.setTheme_(theme_name) 103 | -------------------------------------------------------------------------------- /PyXA/apps/Console.py: -------------------------------------------------------------------------------- 1 | """.. versionadded:: 0.0.5 2 | 3 | Control the macOS Console application using JXA-like syntax. 4 | """ 5 | 6 | from enum import Enum 7 | from AppKit import NSFileManager, NSURL 8 | 9 | from PyXA import XABase 10 | from PyXA.XABase import OSType 11 | from PyXA import XABaseScriptable 12 | from ..XAProtocols import XACanOpenPath 13 | 14 | 15 | class XAConsoleApplication(XABaseScriptable.XASBApplication): 16 | """A class for managing and interacting with Console.app. 17 | 18 | .. versionadded:: 0.0.5 19 | """ 20 | 21 | def select_device(self, uuid: str) -> "XAConsoleApplication": 22 | """Select a device. 23 | 24 | :param uuid: The UUID of the device to select 25 | :type uuid: str 26 | :return: The application ject 27 | :rtype: XAConsoleApplication 28 | 29 | .. versionadded:: 0.0.5 30 | """ 31 | self.xa_scel.selectDevice_(uuid) 32 | return self 33 | -------------------------------------------------------------------------------- /PyXA/apps/Flow.py: -------------------------------------------------------------------------------- 1 | """.. versionadded:: 0.1.0 2 | 3 | Control Flow using JXA-like syntax. 4 | """ 5 | 6 | from datetime import timedelta 7 | 8 | from PyXA import XABaseScriptable 9 | 10 | 11 | class XAFlowApplication(XABaseScriptable.XASBApplication): 12 | """A class for managing and interacting with Flow.app. 13 | 14 | .. versionadded:: 0.1.0 15 | """ 16 | 17 | def __init__(self, properties): 18 | super().__init__(properties) 19 | 20 | def start(self) -> str: 21 | """Starts or resumes the current session. 22 | 23 | :return: The name of the current session 24 | :rtype: str 25 | 26 | .. versionadded:: 0.1.0 27 | """ 28 | return self.xa_scel.start() 29 | 30 | def stop(self) -> str: 31 | """Stops the current session. 32 | 33 | :return: The name of the stopped session 34 | :rtype: str 35 | 36 | .. versionadded:: 0.1.0 37 | """ 38 | return self.xa_scel.stop() 39 | 40 | def skip(self) -> str: 41 | """Skips the current session. 42 | 43 | :return: The name of the next pending session. 44 | :rtype: str 45 | 46 | .. versionadded:: 0.1.0 47 | """ 48 | return self.xa_scel.skip() 49 | 50 | def previous(self) -> str: 51 | """Reloads the current or previous session. 52 | 53 | :return: The name of the next pending session 54 | :rtype: str 55 | 56 | .. versionadded:: 0.1.0 57 | """ 58 | return self.xa_scel.previous() 59 | 60 | def reset(self) -> str: 61 | """Resets the session progress. 62 | 63 | :return: The name of the next pending session 64 | :rtype: str 65 | 66 | .. versionadded:: 0.1.0 67 | """ 68 | return self.xa_scel.reset() 69 | 70 | def show(self) -> str: 71 | """Shows the Flow app window. 72 | 73 | :return: The name of the current session 74 | :rtype: str 75 | 76 | .. versionadded:: 0.1.0 77 | """ 78 | return self.xa_scel.show() 79 | 80 | def hide(self) -> str: 81 | """Hides the Flow app window. 82 | 83 | :return: The name of the current session 84 | :rtype: str 85 | 86 | .. versionadded:: 0.1.0 87 | """ 88 | return self.xa_scel.hide() 89 | 90 | def get_phase(self) -> str: 91 | """Gets the current phase (e.g. Flow or Break) 92 | 93 | :return: The name of the current session 94 | :rtype: str 95 | 96 | .. versionadded:: 0.1.0 97 | """ 98 | return self.xa_scel.getPhase() 99 | 100 | def get_time(self) -> timedelta: 101 | """Gets the remaining time of the current session. 102 | 103 | :return: The remaining time of the current session 104 | :rtype: timedelta 105 | 106 | .. versionadded:: 0.1.0 107 | """ 108 | time_strs = self.xa_scel.getTime().split(":") 109 | return timedelta(minutes=int(time_strs[0]), seconds=int(time_strs[1])) 110 | -------------------------------------------------------------------------------- /PyXA/apps/Hammerspoon.py: -------------------------------------------------------------------------------- 1 | """.. versionadded:: 0.0.8 2 | 3 | Control Hammerspoon using JXA-like syntax. 4 | """ 5 | 6 | from typing import Any 7 | 8 | from PyXA import XABaseScriptable 9 | 10 | 11 | class XAHammerspoonApplication(XABaseScriptable.XASBApplication): 12 | """A class for managing and interacting with Hammerspoon.app. 13 | 14 | .. versionadded:: 0.0.8 15 | """ 16 | 17 | def __init__(self, properties): 18 | super().__init__(properties) 19 | 20 | @property 21 | def name(self) -> str: 22 | """The name of the application.""" 23 | return self.xa_scel.name() 24 | 25 | @property 26 | def frontmost(self) -> bool: 27 | """Whether Hammerspoon is the active application.""" 28 | return self.xa_scel.frontmost() 29 | 30 | @frontmost.setter 31 | def frontmost(self, frontmost: bool): 32 | self.set_property("frontmost", frontmost) 33 | 34 | @property 35 | def version(self) -> str: 36 | """The version of Hammerspoon.app.""" 37 | return self.xa_scel.version() 38 | 39 | def execute_lua_code(self, code: str) -> Any: 40 | """Executes Lua code via Hammerspoon, with support for all Hammerspoon features. 41 | 42 | :param code: The Lua code to execute 43 | :type code: str 44 | :return: The Lua code execution result 45 | :rtype: Any 46 | 47 | .. note:: 48 | 49 | In order for this to work, you must add `hs.allowAppleScript(true)` to your Hammerspoon config. 50 | 51 | :Example: 52 | 53 | >>> import PyXA 54 | >>> app = PyXA.Application("hammerspoon") 55 | >>> app.execute_lua_code(\"\"\" 56 | >>> app = hs.appfinder.appFromName("Finder") 57 | >>> app:activate() 58 | >>> app:selectMenuItem({"Window", "Bring All to Front"}) 59 | >>> \"\"\") 60 | 61 | .. versionadded:: 0.0.8 62 | """ 63 | return self.xa_scel.executeLuaCode_(code) 64 | -------------------------------------------------------------------------------- /PyXA/apps/RStudio.py: -------------------------------------------------------------------------------- 1 | """.. versionadded:: 0.1.0 2 | 3 | Control RStudio using JXA-like syntax. 4 | """ 5 | 6 | from typing import Any 7 | from PyXA import XABaseScriptable 8 | 9 | 10 | class XARStudioApplication(XABaseScriptable.XASBApplication): 11 | """A class for interacting with RStudio.app. 12 | 13 | .. versionadded:: 0.1.0 14 | """ 15 | 16 | def __init__(self, properties): 17 | super().__init__(properties) 18 | 19 | def cmd(self, cmd: str): 20 | """Executes R code in RStudio, does NOT return the execution result. 21 | 22 | :param cmd: The R code to evaluate 23 | :type cmd: str 24 | 25 | :Example: 26 | 27 | >>> import PyXA 28 | >>> app = PyXA.Application("RStudio") 29 | >>> app.cmd("5*5") 30 | 31 | .. versionadded:: 0.1.0 32 | """ 33 | self.xa_scel.cmd_(cmd) 34 | -------------------------------------------------------------------------------- /docs/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 35b8fa53c860f84e7af04148c3525ae6 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_images/CPUMonitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_images/CPUMonitor.png -------------------------------------------------------------------------------- /docs/_images/HelloMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_images/HelloMenu.png -------------------------------------------------------------------------------- /docs/_images/JWSTMenuBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_images/JWSTMenuBar.png -------------------------------------------------------------------------------- /docs/_images/MenuItemImages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_images/MenuItemImages.png -------------------------------------------------------------------------------- /docs/_images/PrintHi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_images/PrintHi.png -------------------------------------------------------------------------------- /docs/_images/PrintHiImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_images/PrintHiImage.png -------------------------------------------------------------------------------- /docs/_images/PyXALogoTransparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_images/PyXALogoTransparent.png -------------------------------------------------------------------------------- /docs/_sources/about/index.rst.txt: -------------------------------------------------------------------------------- 1 | Package Overview 2 | ================ 3 | 4 | What is PyXA? 5 | ############# 6 | 7 | Python for Automation, or PyXA for short, is a wrapper around several macOS frameworks that enables AppleScript- and JXA-like control over macOS applications from within Python. PyXA's objects and methods are based on applications' scripting dictionaries and coupled with additional automation features supported by Apple's macOS APIs. 8 | 9 | PyXA was created with the goals of: 10 | 11 | 1. Simplifying the way automation tasks can be accomplished via Python 12 | 2. Introducing new features to macOS application scripting by simplifying complex procedures into simple, declarative methods 13 | 3. Disambiguating the capabilities of application scripting on macOS by providing easy-to-follow documentation throughout the entire project 14 | 15 | PyXA fills a gap where currently available frameworks ultimately fall short: it aims to be easy to learn for users accustomed to Python (or users who _must_ use Python). To that end, the package's documentation contains numerous examples of how to use just about every method, and additional examples are provided covering specific use cases. PyXA's code also serves as a source of examples for how to use `PyObjC `_ to interact with various macOS frameworks. 16 | 17 | Is PyXA for Me? 18 | ############### 19 | 20 | PyXA is not intended to replace AppleScript or even to cover 100% of AppleScript's capabilities. Instead, PyXA is meant to provide general convenience in accomplishing AppleScript and other automation tasks via Python, for the most commonly used applications. If you need a complete Apple Event bridge, or if you find that PyXA cannot handle your particular use case, consider using `appscript `_ or one of its derivatives. If you just need something that works in most circumstances, that has abundant examples for you to reference, and supports some additional automation features (such as opening Maps to a specific address), then PyXA might be a good fit for you. 21 | -------------------------------------------------------------------------------- /docs/_sources/bugs.rst.txt: -------------------------------------------------------------------------------- 1 | Bugs 2 | ==== 3 | 4 | Bugs in PyXA 5 | ************ 6 | 7 | If you find a bug within any of the code in `PyXA's GitHub Repository`_, please create a new issue on GitHub that describes the bug, the circumstances that cause the bug to occur, a description of your configuration, and any potential solutions that you might have thought of. After creating an issue, if you have the time and expertise to implement the fix, you can create a new pull request containing your changes. Make sure to follow the `Guidelines for Contributing to PyXA's Code`_. 8 | 9 | Documentation Bugs 10 | ****************** 11 | 12 | If you find a bug in this documentation, please create a new issue on `PyXA's GitHub Repository`_. If you have an idea for a potential fix, please include a description of the fix within the issue. After creating an issue, if you have the time and expertise to implement the fix, you can create a new pull request containing your changes. Make sure to follow the `Guidelines for Contributing to PyXA's Documentation`_. 13 | 14 | .. _PyXA's GitHub Repository: https://github.com/SKaplanOfficial/PyXA/issues 15 | .. _Guidelines for Contributing to PyXA's Code: https://github.com/SKaplanOfficial/PyXA/blob/main/CONTRIBUTING.md#code 16 | .. _Guidelines for Contributing to PyXA's Documentation: https://github.com/SKaplanOfficial/PyXA/blob/main/CONTRIBUTING.md#documentation -------------------------------------------------------------------------------- /docs/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. PyXA documentation master file, created by 2 | sphinx-quickstart on Sat May 28 10:21:18 2022. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. image:: _static/assets/PyXALogoTransparent.png 7 | :alt: PyXA Logo 8 | 9 | 10 | PyXA Documentation 11 | ================== 12 | 13 | Python for Automation is a wrapper around Apple's Scripting Bridge framework that enables AppleScript- and JXA-like control over macOS applications from within Python. 14 | 15 | .. toctree:: 16 | :maxdepth: 3 17 | :caption: Contents: 18 | 19 | about/index 20 | tutorial/index 21 | reference/index 22 | bugs 23 | 24 | Indices and tables 25 | ================== 26 | 27 | * :ref:`genindex` 28 | * :ref:`modindex` 29 | * :ref:`search` 30 | 31 | .. note:: 32 | This project is under active development. -------------------------------------------------------------------------------- /docs/_sources/reference/additions/devices.rst.txt: -------------------------------------------------------------------------------- 1 | Devices Module 2 | ============== 3 | 4 | .. automodule:: PyXA.Additions.Devices 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/additions/learn.rst.txt: -------------------------------------------------------------------------------- 1 | Learn Module 2 | ============ 3 | 4 | .. automodule:: PyXA.Additions.Learn 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/additions/speech.rst.txt: -------------------------------------------------------------------------------- 1 | Speech Module 2 | ============= 3 | 4 | .. automodule:: PyXA.Additions.Speech 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/additions/ui.rst.txt: -------------------------------------------------------------------------------- 1 | UI Module 2 | ========= 3 | 4 | .. automodule:: PyXA.Additions.UI 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/additions/utils.rst.txt: -------------------------------------------------------------------------------- 1 | Utils Module 2 | ============ 3 | 4 | .. automodule:: PyXA.Additions.Utils 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/additions/web.rst.txt: -------------------------------------------------------------------------------- 1 | Web Module 2 | ========== 3 | 4 | .. automodule:: PyXA.Additions.Web 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/arc.rst.txt: -------------------------------------------------------------------------------- 1 | Arc Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.Arc 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/automator.rst.txt: -------------------------------------------------------------------------------- 1 | Automator Module Reference 2 | ========================== 3 | 4 | .. automodule:: PyXA.apps.Automator 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/bike.rst.txt: -------------------------------------------------------------------------------- 1 | Bike Module Reference 2 | ===================== 3 | 4 | .. automodule:: PyXA.apps.Bike 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/calculator.rst.txt: -------------------------------------------------------------------------------- 1 | Calculator Module Reference 2 | =========================== 3 | 4 | .. automodule:: PyXA.apps.Calculator 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/calendar.rst.txt: -------------------------------------------------------------------------------- 1 | Calendar Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Calendar 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/cardhop.rst.txt: -------------------------------------------------------------------------------- 1 | Cardhop Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Cardhop 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/chromium.rst.txt: -------------------------------------------------------------------------------- 1 | Chromium Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Chromium 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/console.rst.txt: -------------------------------------------------------------------------------- 1 | Console Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Console 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/contacts.rst.txt: -------------------------------------------------------------------------------- 1 | Contacts Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Contacts 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/dictionary.rst.txt: -------------------------------------------------------------------------------- 1 | Dictionary Module Reference 2 | =========================== 3 | 4 | .. automodule:: PyXA.apps.Dictionary 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/drafts.rst.txt: -------------------------------------------------------------------------------- 1 | Drafts Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.Drafts 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/fantastical.rst.txt: -------------------------------------------------------------------------------- 1 | Fantastical Module Reference 2 | ============================ 3 | 4 | .. automodule:: PyXA.apps.Fantastical 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/finder.rst.txt: -------------------------------------------------------------------------------- 1 | Finder Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.Finder 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/flow.rst.txt: -------------------------------------------------------------------------------- 1 | Flow Module Reference 2 | ===================== 3 | 4 | .. automodule:: PyXA.apps.Flow 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/fontbook.rst.txt: -------------------------------------------------------------------------------- 1 | FontBook Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.FontBook 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/hammerspoon.rst.txt: -------------------------------------------------------------------------------- 1 | Hammerspoon Module Reference 2 | ============================ 3 | 4 | .. automodule:: PyXA.apps.Hammerspoon 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/iina.rst.txt: -------------------------------------------------------------------------------- 1 | IINA+ Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.IINA 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/imageevents.rst.txt: -------------------------------------------------------------------------------- 1 | Image Events Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.ImageEvents 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/iterm.rst.txt: -------------------------------------------------------------------------------- 1 | iTerm Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.iTerm 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/iwork.rst.txt: -------------------------------------------------------------------------------- 1 | iWork Base Reference 2 | ==================== 3 | 4 | .. automodule:: PyXA.apps.iWorkApplicationBase 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/keynote.rst.txt: -------------------------------------------------------------------------------- 1 | Keynote Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Keynote 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/mail.rst.txt: -------------------------------------------------------------------------------- 1 | Mail Module Reference 2 | ===================== 3 | 4 | .. automodule:: PyXA.apps.Mail 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/maps.rst.txt: -------------------------------------------------------------------------------- 1 | Maps Module Reference 2 | ===================== 3 | 4 | .. automodule:: PyXA.apps.Maps 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/messages.rst.txt: -------------------------------------------------------------------------------- 1 | Messages Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Messages 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/music.rst.txt: -------------------------------------------------------------------------------- 1 | Music Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.Music 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/notes.rst.txt: -------------------------------------------------------------------------------- 1 | Notes Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.Notes 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/numbers.rst.txt: -------------------------------------------------------------------------------- 1 | Numbers Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Notes 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/omnioutliner.rst.txt: -------------------------------------------------------------------------------- 1 | OmniOutliner Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.OmniOutliner 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/omniweb.rst.txt: -------------------------------------------------------------------------------- 1 | OmniWeb Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.OmniWeb 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/pages.rst.txt: -------------------------------------------------------------------------------- 1 | Pages Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.Pages 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/pathfinder.rst.txt: -------------------------------------------------------------------------------- 1 | Path Finder Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.PathFinder 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/photos.rst.txt: -------------------------------------------------------------------------------- 1 | Photos Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.PhotosApp 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/preview.rst.txt: -------------------------------------------------------------------------------- 1 | Preview Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Preview 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/quicktimeplayer.rst.txt: -------------------------------------------------------------------------------- 1 | QuickTime Module Reference 2 | ========================== 3 | 4 | .. automodule:: PyXA.apps.QuickTimePlayer 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/reminders.rst.txt: -------------------------------------------------------------------------------- 1 | Reminders Module Reference 2 | ========================== 3 | 4 | .. automodule:: PyXA.apps.Reminders 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/rstudio.rst.txt: -------------------------------------------------------------------------------- 1 | RStudio Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.RStudio 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/safari.rst.txt: -------------------------------------------------------------------------------- 1 | Safari Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.Safari 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/shortcuts.rst.txt: -------------------------------------------------------------------------------- 1 | Shortcuts Module Reference 2 | ========================== 3 | 4 | .. automodule:: PyXA.apps.Shortcuts 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/spotify.rst.txt: -------------------------------------------------------------------------------- 1 | Spotify Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Spotify 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/stocks.rst.txt: -------------------------------------------------------------------------------- 1 | Stocks Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.Stocks 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/systemevents.rst.txt: -------------------------------------------------------------------------------- 1 | System Events Module Reference 2 | ============================== 3 | 4 | .. automodule:: PyXA.apps.SystemEvents 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/systempreferences.rst.txt: -------------------------------------------------------------------------------- 1 | System Preferences Module Reference 2 | =================================== 3 | 4 | .. automodule:: PyXA.apps.SystemPreferences 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/terminal.rst.txt: -------------------------------------------------------------------------------- 1 | Terminal Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Terminal 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/textedit.rst.txt: -------------------------------------------------------------------------------- 1 | TextEdit Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.TextEdit 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/tv.rst.txt: -------------------------------------------------------------------------------- 1 | TV Module Reference 2 | =================== 3 | 4 | .. automodule:: PyXA.apps.TV 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/apps/vlc.rst.txt: -------------------------------------------------------------------------------- 1 | VLC Module Reference 2 | ==================== 3 | 4 | .. automodule:: PyXA.apps.VLC 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/index.rst.txt: -------------------------------------------------------------------------------- 1 | Code Documentation and Reference 2 | ================================ 3 | 4 | Top-level PyXA Modules 5 | ---------------------- 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | xabase 10 | xabasescriptable 11 | xatypes 12 | xaprotocols 13 | xaerrors 14 | 15 | First-Party Application Module Reference 16 | ---------------------------------------- 17 | .. toctree:: 18 | :maxdepth: 2 19 | 20 | apps/automator 21 | apps/calculator 22 | apps/calendar 23 | apps/console 24 | apps/contacts 25 | apps/dictionary 26 | apps/finder 27 | apps/fontbook 28 | apps/imageevents 29 | apps/keynote 30 | apps/mail 31 | apps/maps 32 | apps/messages 33 | apps/music 34 | apps/notes 35 | apps/numbers 36 | apps/pages 37 | apps/photos 38 | apps/preview 39 | apps/quicktimeplayer 40 | apps/reminders 41 | apps/safari 42 | apps/shortcuts 43 | apps/stocks 44 | apps/systemevents 45 | apps/systempreferences 46 | apps/terminal 47 | apps/textedit 48 | apps/tv 49 | 50 | Third-Party Application Module Reference 51 | ---------------------------------------- 52 | .. toctree:: 53 | :maxdepth: 2 54 | 55 | apps/arc 56 | apps/bike 57 | apps/cardhop 58 | apps/chromium 59 | apps/fantastical 60 | apps/flow 61 | apps/drafts 62 | apps/hammerspoon 63 | apps/iina 64 | apps/iterm 65 | apps/omnioutliner 66 | apps/omniweb 67 | apps/pathfinder 68 | apps/spotify 69 | apps/vlc 70 | apps/rstudio 71 | 72 | PyXA Additions 73 | -------------- 74 | .. toctree:: 75 | :maxdepth: 2 76 | 77 | additions/learn 78 | additions/devices 79 | additions/speech 80 | additions/ui 81 | additions/utils 82 | additions/web -------------------------------------------------------------------------------- /docs/_sources/reference/xabase.rst.txt: -------------------------------------------------------------------------------- 1 | XABase Module 2 | ============= 3 | 4 | .. automodule:: PyXA.XABase 5 | :members: 6 | :undoc-members: 7 | :special-members: 8 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/xabasescriptable.rst.txt: -------------------------------------------------------------------------------- 1 | XABaseScriptable Module 2 | ======================= 3 | 4 | .. automodule:: PyXA.XABaseScriptable 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/xaerrors.rst.txt: -------------------------------------------------------------------------------- 1 | XAErrors Module 2 | =============== 3 | 4 | .. automodule:: PyXA.XAErrors 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/xaprotocols.rst.txt: -------------------------------------------------------------------------------- 1 | XAProtocols Module 2 | ================== 3 | 4 | .. automodule:: PyXA.XAProtocols 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/reference/xatypes.rst.txt: -------------------------------------------------------------------------------- 1 | XATypes Module 2 | ============== 3 | 4 | .. automodule:: PyXA.XATypes 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/automator/index.rst.txt: -------------------------------------------------------------------------------- 1 | Automator Module 2 | ================ 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | Overview 9 | ######## 10 | PyXA supports all of Automator's OSA features, including but not limited to creating and executing workflows, managing Automator actions and their settings, and interacting with execution return values. PyXA can create workflows and variables, assign and arrange actions, and modify the attributes thereof. PyXA can also observe the execution of workflow files, allowing you to use existing automation workflows aongside PyXA and Python in general. 11 | 12 | Automator Tutorials 13 | ################### 14 | There is currently one tutorial for the Automator module: 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | 19 | tutorial1 20 | 21 | Automator Examples 22 | ################## 23 | The examples below provide an overview of the capabilities of the Automator module. 24 | 25 | Example 1 - Creating workflows from scratch 26 | ******************************************* 27 | 28 | The example below creates a workflow that displays a notification, waits five seconds, then starts the screen saver. The process for creating workflows begins with making a new workflow object, adding it to the list of workflows, and saving it to the disk. Without saving here, you may encounter errors as some methods and actions require access to the workflow file. With an empty workflow created, the next step is to add actions, which is most easily done by name. Next, you must retrieve a mutable form of the actions; you can think of the original ones as a template that you've now made a copy of. From there, you can change the value of settings however you desire. 29 | 30 | .. code-block:: python 31 | :linenos: 32 | 33 | import PyXA 34 | app = PyXA.Application("Automator") 35 | 36 | # Create and save a new workflow 37 | new_workflow = app.make("workflow", {"name": "New Workflow"}) 38 | app.workflows().push(new_workflow) 39 | new_workflow.save() 40 | 41 | # Add actions to the workflow 42 | action1 = app.automator_actions().by_name("Display Notification") 43 | action2 = app.automator_actions().by_name("Pause") 44 | action3 = app.automator_actions().by_name("Start Screen Saver") 45 | app.add(action1, new_workflow) 46 | app.add(action2, new_workflow) 47 | app.add(action3, new_workflow) 48 | 49 | # Obtain actions in mutable form and change their settings 50 | actions = new_workflow.automator_actions() 51 | notification_text = actions[0].settings().by_name("title") 52 | notification_text.set_property("value", "PyXA Notification") 53 | 54 | pause_duration = actions[1].settings().by_name("pauseDuration") 55 | pause_duration.set_property("value", 5) 56 | 57 | # Run the workflow 58 | new_workflow.execute() 59 | 60 | Example 2 - Running existing workflows 61 | ************************************** 62 | 63 | In the short example below, we open an existing workflow file, run it, and display the execution's results. 64 | 65 | .. code-block:: python 66 | :linenos: 67 | 68 | import PyXA 69 | app = PyXA.Application("Automator") 70 | 71 | app.open("/Users/exampleuser/Downloads/Example.workflow") 72 | workflow = app.workflows().by_name("Example.workflow") 73 | workflow.execute() 74 | 75 | print(workflow.execution_result) 76 | 77 | Automator Resources 78 | ################### 79 | - `Automator User Guide - Apple Support `_ 80 | 81 | For all classes, methods, and inherited members of the Automator module, see the :ref:`Automator Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/bike/index.rst.txt: -------------------------------------------------------------------------------- 1 | Bike Module Overview 2 | ==================== 3 | 4 | Bike Resources 5 | ############## 6 | - `Creating Scripts - Bike Guide `_ 7 | - `Using Scripts - Bike Guide `_ 8 | - `Bike Extensions Wiki `_ 9 | 10 | For all classes, methods, and inherited members of the Bike module, see the :ref:`Bike Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/calculator/index.rst.txt: -------------------------------------------------------------------------------- 1 | Calculator Module Overview 2 | ========================== 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | PyXA enables limited scripting functionalities in Calculator.app, despite no official scripting support for it. Currently, the calculator's scripting functionalities are entirely supported by UI scripting, however additional features are planned for future development work. 9 | 10 | Using :func:`XACalculatorApplication.input`, you can command the Calculator to execute a sequence of button clicks. The sequence must be a continuous string (no spaces). The valid characters are numbers `0-9`, `+`, `-`, `*`, `/`, `%`, `~`, `=`, and `c`. Their meanings are as follows: 11 | 12 | - `+`, `-`, `*`, and `/` correspond to their usual operation buttons. 13 | - `%` designates the percentage button. 14 | - `~` corresponds to the negation button. 15 | - `=` represents the equals button. 16 | - `c` denotes the clear button. 17 | 18 | Calculator Tutorials 19 | #################### 20 | There are currently no tutorials for working with the Calculator application. 21 | 22 | Calculator Examples 23 | ################### 24 | The examples below provide an overview of the capabilities of the Calculator module. They do not provide any output. 25 | .. For more in-depth examples that show output and provide more detailed explanations, refer to the previous section (:ref:`Tutorials`). 26 | 27 | Example 1 - Performing Operations in Calculator.app 28 | *************************************************** 29 | 30 | This example uses :func:`XACalculatorApplication.input` to calculate the result of an expression, then retrieves the result using :func:`XACalculatorApplication.current_value`. 31 | 32 | .. code-block:: python 33 | :linenos: 34 | 35 | import PyXA 36 | app = PyXA.Application("Calculator") 37 | app.input("3.14159265*2*3*5*5*5=") 38 | x = app.current_value() 39 | print(x) 40 | 41 | Calculator Resources 42 | #################### 43 | - `Calculator User Guide - Apple Support `_ 44 | 45 | For all classes, methods, and inherited members of the Calculator module, see the :ref:`Calculator Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/cardhop/index.rst.txt: -------------------------------------------------------------------------------- 1 | Cardhop Module Overview 2 | ======================= 3 | 4 | Cardhop Resources 5 | ################# 6 | - `Cardhop Integration With Other Apps Help `_ 7 | - 8 | For all classes, methods, and inherited members of the Cardhop module, see the :ref:`Cardhop Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/console/index.rst.txt: -------------------------------------------------------------------------------- 1 | Console Module Overview 2 | ======================= 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | PyXA has fully supports all scripting features of Console.app, but there is minimal support (from Apple) in the first place in that regard. Future versions of PyXA might explore expanding the feature offering through UI scripting, utilization of Objective-C frameworks, and other means. 9 | 10 | Console Tutorials 11 | ################# 12 | There are currently no tutorials for the Console module. 13 | 14 | Console Examples 15 | ################ 16 | .. The examples below provide an overview of the capabilities of the Chromium module. They do not provide any output. For more in-depth examples that show output and provide more detailed explanations, refer to the previous section (:ref:`Chromium Tutorials`). 17 | 18 | Example 1 - Coming Soon 19 | **************************************** 20 | 21 | An example will be added soon. 22 | 23 | .. .. code-block:: python 24 | .. :linenos: 25 | 26 | .. import PyXA 27 | .. from time import sleep 28 | 29 | .. # Open URL in new tab 30 | .. app = PyXA.Application("Chromium") 31 | .. app.activate() 32 | .. app.open("http://apple.com") 33 | 34 | .. # Wait for tab to finish loading 35 | .. tab = app.front_window().tabs().last() 36 | .. while tab.loading: 37 | .. sleep(0.1) 38 | 39 | .. # Save the tab's content 40 | .. tab.save("/Users/exampleuser/Downloads/apple-site") 41 | 42 | Console Resources 43 | ################# 44 | - `Console User Guide - Apple Support `_ 45 | 46 | For all classes, methods, and inherited members of the Console module, see the :ref:`Console Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/contacts/index.rst.txt: -------------------------------------------------------------------------------- 1 | Contacts Module Overview 2 | ======================== 3 | 4 | For all classes, methods, and inherited members of the Contacts module, see the :ref:`Contacts Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/dictionary/index.rst.txt: -------------------------------------------------------------------------------- 1 | Dictionary Module Overview 2 | ========================== 3 | 4 | For all classes, methods, and inherited members of the Dictionary module, see the :ref:`Dictionary Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/drafts/index.rst.txt: -------------------------------------------------------------------------------- 1 | Drafts Module Overview 2 | ====================== 3 | 4 | For all classes, methods, and inherited members of the Drafts module, see the :ref:`Drafts Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/fantastical/index.rst.txt: -------------------------------------------------------------------------------- 1 | Fantastical Module Overview 2 | =========================== 3 | 4 | The Fantastical module provides access to Fantastical's features from within PyXA, making use of both the application's scripting dictionary as well as its URL scheme. 5 | 6 | Fantastical Examples 7 | #################### 8 | 9 | Example 1 - Interacting with Currently Selected Calendar Items 10 | ************************************************************** 11 | 12 | .. code-block:: python 13 | 14 | import PyXA 15 | app = PyXA.Application("Fantastical") 16 | items = app.selected_calendar_items() 17 | urls = [item.show_url.url for item in items] 18 | print(urls) 19 | # ['x-fantastical://show?item=7d627e52-ae3d-39eb-b86b-57b037f92cab&calendarIdentifier=A5E06B53-667F-42EE-A6FD-99609F6711E3&date=2022-02-21%2000:00', 'x-fantastical://show?item=e4bcc8c4-cd34-3c1d-b273-def4ecd47eae&calendarIdentifier=A5E06B53-667F-42EE-A6FD-99609F6711E3&date=2022-02-14%2000:00', ...] 20 | 21 | Example 2 - Using Natural Language to Create Events 22 | *************************************************** 23 | 24 | .. code-block:: python 25 | 26 | import PyXA 27 | app = PyXA.Application("Fantastical") 28 | app.parse_sentence("Meeting from 2pm to 3 today") 29 | app.parse_sentence("Joe's birthday August 26th all day") 30 | app.parse_sentence("Computer Science Homework due on Tuesday") 31 | app.parse_sentence("Vacation from August 26 to September 2") 32 | app.parse_sentence("Meeting at 2pm today alert 20 minutes before") 33 | app.parse_sentence("Attend Apple Event at 1 Infinite Loop, Cupertino, CA on September 14 at 9am") 34 | app.parse_sentence("Remind me to clean on Wednesday") 35 | 36 | Fantastical Resources 37 | ##################### 38 | - `Fantastical Integration With Other Apps Help `_ 39 | - `Fantastical Guide - Calendar.com `_ 40 | 41 | For all classes, methods, and inherited members of the Fantastical module, see the :ref:`Fantastical Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/finder/index.rst.txt: -------------------------------------------------------------------------------- 1 | Finder Module Overview 2 | ====================== 3 | 4 | For all classes, methods, and inherited members of the Finder module, see the :ref:`Finder Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/flow/index.rst.txt: -------------------------------------------------------------------------------- 1 | Flow Module Overview 2 | ==================== 3 | 4 | The Flow module allows you to programmatically control Flow's timer sessions from within your Python scripts. 5 | 6 | Flow Examples 7 | ############# 8 | 9 | Example 1 - Run session only while a specific app is open 10 | ********************************************************* 11 | 12 | One possible use case of the Flow module is automatically starting Flow sessions based on the context of the system. For example, you might want to start a Flow session when you first open Notes, then only allow the session counter to continue as long as you're using the Notes app (in other words, if you get distracted and wander over to YouTube, the session pauses until you get back on track). The code below shows how to use PyXA to implement this use case. 13 | 14 | .. code-block:: python 15 | 16 | import PyXA 17 | from time import sleep 18 | 19 | flow = PyXA.Application("Flow") 20 | in_session = False 21 | 22 | while True: 23 | apps = PyXA.running_applications().localized_name() 24 | if "Notes" in apps and not in_session: 25 | flow.start() 26 | in_session = True 27 | elif "Notes" not in apps: 28 | flow.stop() 29 | in_session = False 30 | sleep(1) 31 | 32 | Based on this code, you can create scripts for managing context-based Flow sessions informed by many metrics--or as few as you need. 33 | 34 | Flow Resources 35 | ############## 36 | - `Flow API/Scripts `_ -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/fontbook/index.rst.txt: -------------------------------------------------------------------------------- 1 | Font Book Module Overview 2 | ========================= 3 | 4 | For all classes, methods, and inherited members of the Font Book module, see the :ref:`Font Book Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/hammerspoon/index.rst.txt: -------------------------------------------------------------------------------- 1 | Hammerspoon Module Overview 2 | =========================== 3 | 4 | The Hammerspoon module provides the ability to run Hammerspoon Lua scripts from within PyXA. To do this, simply call the :func:`~PyXA.apps.Hammerspoon.XAHammerspoonApplication.execute_lua_code` method and supply a Lua script as an argument. You can then utilize the value returned by the Lua script in your Python program. 5 | 6 | .. code-block:: Python 7 | 8 | import PyXA 9 | app = PyXA.Application("hammerspoon") 10 | result = app.execute_lua_code(""" 11 | app = hs.appfinder.appFromName("Finder") 12 | window = app:mainWindow() 13 | return window:title() 14 | """) 15 | print(result) 16 | # Recents 17 | 18 | For all classes, methods, and inherited members of the Hammerspoon module, see the :ref:`Hammerspoon Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/index.rst.txt: -------------------------------------------------------------------------------- 1 | Application Module Overviews 2 | ============================ 3 | 4 | First-Party Application Modules Overviews 5 | ----------------------------------------- 6 | 7 | .. toctree:: 8 | :maxdepth: 1 9 | 10 | automator/index 11 | calculator/index 12 | calendar/index 13 | console/index 14 | contacts/index 15 | dictionary/index 16 | finder/index 17 | fontbook/index 18 | imageevents/index 19 | keynote/index 20 | mail/index 21 | maps/index 22 | messages/index 23 | music/index 24 | notes/index 25 | numbers/index 26 | pages/index 27 | photos/index 28 | preview/index 29 | quicktimeplayer/index 30 | reminders/index 31 | safari/index 32 | shortcuts/index 33 | stocks/index 34 | systemevents/index 35 | systempreferences/index 36 | terminal/index 37 | textedit/index 38 | tv/index 39 | 40 | Third-Party Application Module Overviews 41 | ---------------------------------------- 42 | 43 | .. toctree:: 44 | :maxdepth: 1 45 | 46 | bike/index 47 | cardhop/index 48 | chromium/index 49 | drafts/index 50 | fantastical/index 51 | flow/index 52 | hammerspoon/index 53 | iterm/index 54 | omnioutliner/index 55 | spotify/index 56 | vlc/index 57 | rstudio/index -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/iterm/index.rst.txt: -------------------------------------------------------------------------------- 1 | iTerm Module Overview 2 | ===================== -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/keynote/index.rst.txt: -------------------------------------------------------------------------------- 1 | Keynote Module Overview 2 | ======================= 3 | 4 | For all classes, methods, and inherited members of the Keynote module, see the :ref:`Keynote Module Reference` and :ref:`iWork Base Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/mail/index.rst.txt: -------------------------------------------------------------------------------- 1 | Mail Module Overview 2 | ==================== 3 | 4 | For all classes, methods, and inherited members of the Mail module, see the :ref:`Mail Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/maps/index.rst.txt: -------------------------------------------------------------------------------- 1 | Maps Module Overview 2 | ==================== 3 | 4 | For all classes, methods, and inherited members of the Maps module, see the :ref:`Maps Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/messages/index.rst.txt: -------------------------------------------------------------------------------- 1 | Messages Module Overview 2 | ======================== 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | PyXA supports all of the OSA features for Messages.app. 9 | 10 | Messages Tutorials 11 | ################## 12 | There are currently no tutorials for the Messages module. 13 | 14 | Messages Resources 15 | ################## 16 | - `Messages User Guide - Apple Support `_ 17 | 18 | For all classes, methods, and inherited members of the Messages module, see the :ref:`Messages Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/music/index.rst.txt: -------------------------------------------------------------------------------- 1 | Music Module Overview 2 | ===================== 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | The entirety of Music's scripting interface is available via PyXA. 9 | 10 | Music Tutorials 11 | ############### 12 | There are currently no tutorials for the Music module. 13 | 14 | Music Examples 15 | ############## 16 | The examples below provide an overview of the capabilities of the Music module. 17 | 18 | Example 1 - Playback Control 19 | **************************** 20 | 21 | .. code-block:: python 22 | :linenos: 23 | 24 | import PyXA 25 | app = PyXA.Application("Music") 26 | 27 | # Play/Pause/Stop/Resume 28 | app.play() 29 | app.pause() 30 | app.stop() 31 | app.playpause() 32 | 33 | # Fast-forward/Rewind 34 | app.fast_forward() 35 | app.rewind() 36 | app.resume() 37 | 38 | Example 2 - Add Current Track to a Playlist 39 | ******************************************* 40 | 41 | .. code-block:: python 42 | :linenos: 43 | 44 | import PyXA 45 | app = PyXA.Music() 46 | 47 | # Gather info about current track 48 | title = app.current_track.name 49 | artist = app.current_track.artist 50 | album = app.current_track.album 51 | 52 | # Save track to library 53 | library = app.sources().by_name("Library") 54 | app.current_track.duplicate(library) 55 | 56 | # Get the saved track object 57 | saved_track = app.tracks().filter("name", "==", title).filter("artist", "==", artist).by_album(album) 58 | 59 | # Add track to playlist 60 | playlist = app.playlists().by_name("test") 61 | saved_track.move(playlist) 62 | 63 | Example 3 - Make a Playlist of Tracks in a Given Genre 64 | ****************************************************** 65 | 66 | .. code-block:: python 67 | :linenos: 68 | 69 | import PyXA 70 | app = PyXA.Music() 71 | 72 | # Get a list of all soundtrack tracks 73 | soundtracks = app.tracks().filter("genre", "==", "Soundtrack") 74 | 75 | # Create a new playlist 76 | prototype = app.make("playlist", {"name": "Soundtracks"}) 77 | new_playlist = app.playlists().push(prototype) 78 | 79 | # Add soundtracks to the new playlist 80 | new_playlist.add_tracks(soundtracks) 81 | 82 | For all classes, methods, and inherited members of the Music module, see the :ref:`Music Module Reference` and :ref:`Media Application Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/numbers/index.rst.txt: -------------------------------------------------------------------------------- 1 | Numbers Module Overview 2 | ======================= 3 | 4 | For all classes, methods, and inherited members of the Numbers module, see the :ref:`Numbers Module Reference` and :ref:`iWork Base Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/omnioutliner/index.rst.txt: -------------------------------------------------------------------------------- 1 | OmniOutliner Module Overview 2 | ============================ 3 | 4 | For all classes, methods, and inherited members of the OmniOutliner module, see the :ref:`OmniOutliner Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/pages/index.rst.txt: -------------------------------------------------------------------------------- 1 | Pages Module Overview 2 | ===================== 3 | 4 | For all classes, methods, and inherited members of the Pages module, see the :ref:`Pages Module Reference` and :ref:`iWork Base Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/photos/index.rst.txt: -------------------------------------------------------------------------------- 1 | Photos Module Overview 2 | ====================== 3 | 4 | For all classes, methods, and inherited members of the Photos module, see the :ref:`Photos Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/preview/index.rst.txt: -------------------------------------------------------------------------------- 1 | Preview Module Overview 2 | ======================= 3 | 4 | For all classes, methods, and inherited members of the Preview module, see the :ref:`Preview Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/quicktimeplayer/index.rst.txt: -------------------------------------------------------------------------------- 1 | QuickTime Module Overview 2 | ========================= 3 | 4 | For all classes, methods, and inherited members of the QuickTime module, see the :ref:`QuickTime Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/reminders/index.rst.txt: -------------------------------------------------------------------------------- 1 | Reminders Module Overview 2 | ========================= 3 | 4 | For all classes, methods, and inherited members of the Reminders module, see the :ref:`Reminders Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/rstudio/index.rst.txt: -------------------------------------------------------------------------------- 1 | RStudio Module Overview 2 | ======================= 3 | 4 | -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/safari/index.rst.txt: -------------------------------------------------------------------------------- 1 | Safari Module Overview 2 | ====================== 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | PyXA has full nearly complete feature support for Safari, but some functionalities, such as saving a document, are currently unavailable. These will be implemented in future versions of the Safari module. 9 | 10 | 11 | Safari Tutorials 12 | ################## 13 | There are currently no tutorials for the Safari module. 14 | 15 | Safari Examples 16 | ############### 17 | The examples below provide an overview of the capabilities of the Safari module. For more in-depth examples that show output and provide more detailed explanations, refer to the previous section (:ref:`Safari Tutorials`). 18 | 19 | Example 1 - Using Safari Methods and Attributes 20 | *********************************************** 21 | 22 | This example provides an overview of the most common methods and attributes of the Safari module. 23 | 24 | .. code-block:: python 25 | :linenos: 26 | 27 | import PyXA 28 | 29 | # Open URL in new tab 30 | safari = PyXA.Application("Safari") 31 | 32 | # Get open windows, documents, and tabs 33 | window1 = safari.front_window() 34 | window2 = safari.windows()[1] 35 | documents = safari.documents() 36 | current_doc = safari.current_document 37 | tabs = window1.tabs() 38 | current_tab = window1.current_tab 39 | 40 | # Get properties of documents 41 | urls = documents.url() 42 | names = documents.name() 43 | html = current_doc.source() 44 | 45 | # Get properties of tabs 46 | urls = tabs.url() 47 | texts = tabs.text() 48 | name = current_tab.name() 49 | 50 | # Filter documents and tabs 51 | doc1 = documents.by_url("https://apple.com") 52 | doc2 = documents.by_name("Apple") 53 | tab1 = tabs.by_index(1) 54 | tab2 = tabs.by_visible(True) 55 | 56 | # Bulk document operations 57 | documents.add_to_reading_list() 58 | documents.email() 59 | documents.do_javascript("alert('Testing 1 2 3');") 60 | documents.search("Example") 61 | 62 | # Bulk tab operations 63 | tabs.reload() 64 | tabs.add_to_reading_list() 65 | tabs.email() 66 | tabs.do_javascript("alert('Hello!');") 67 | tabs.search("Example") 68 | tabs.move_to(window2) 69 | tabs.duplicate_to(window2) 70 | 71 | # Sub-array operations 72 | some_tabs = tabs[3:5] 73 | some_tabs.close() 74 | 75 | Safari Resources 76 | ################## 77 | - `Safari Quick Start Guide `_ 78 | 79 | For all classes, methods, and inherited members of the Safari module, see the :ref:`Safari Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/shortcuts/index.rst.txt: -------------------------------------------------------------------------------- 1 | Shortcuts Module Overview 2 | ========================= 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | Most of Shortcuts.app's scripting interface is available via PyXA, however some significant features are currently limited by sandboxing constraints. PyXA is able to interact with existing shortcuts, including run them, but it is currently unable to create new shortcuts or shortcut folders. That said, it is possible to use Shortcuts links to install new shortcuts. It would be feasible to use functional, atomically constructed shortcuts (i.e. each shortcut accomplishes a single task and returns a transformed value) to construct larger sequences of actions, effectively re-instituting an ability to create shortcuts. For now, that is left as an exercise for PyXA users. Future versions of PyXA may utilize the Shortcuts URI scheme, in combination with the Intents framework, to re-implement these features in a more straightforward way. 9 | 10 | > [!NOTE] 11 | > In most cases, to work with shortcuts, you should use the 'Shortcuts Events' application as used in the examples below. This allows you to work with shortcuts without having to open the Shortcuts app. 12 | 13 | Shortcuts Tutorials 14 | ################### 15 | There are currently no tutorials for the Shortcuts module. 16 | 17 | Shortcuts Examples 18 | ################## 19 | The examples below provide an overview of the capabilities of the Shortcuts module. They do not provide any output. For more in-depth examples that show output and provide more detailed explanations, refer to the previous section (:ref:`Shortcuts Tutorials`). 20 | 21 | Example 1 - Run shortcuts and receive their return values 22 | ********************************************************* 23 | 24 | The example below activates Chromium.app, opens Apple's website in a new tab, waits for the tab to finish loading, then saves the site's resources (e.g. HTML, CSS, JavaScript, and images) to a location on the disk. Note the use of a full URL, beginning with "http", as well as a full file path, beginning with "/". Both a full URL and full file path are necessary in order for this example to operate successfully. 25 | 26 | .. code-block:: python 27 | :linenos: 28 | 29 | import PyXA 30 | app = PyXA.Application("Shortcuts Events") 31 | 32 | # Get shortcuts by name 33 | sqrt = app.shortcuts().by_name("sqrt(x)") 34 | sin = app.shortcuts().by_name("sin(x)") 35 | 36 | # Run sqrt function, get first entry in output array 37 | root = sqrt.run(81)[0] 38 | print(root) 39 | 40 | # Run sin function, get first entry in output array 41 | sin_root = sin.run(root)[0] 42 | print(sin_root) 43 | 44 | Example 2 - Combine shortcut output with Python 45 | *********************************************** 46 | 47 | This example highlights how you can intertwine PyXA, Shortcuts, and Python to carry out more complex processes. The example below uses a shortcut to obtain the source HTML of the Google homepage, then uses Python's tempfile module alongside PyXA's :func:`PyXA.Safari.XASafariApplication.open` method to display a local HTML file in the browser. 48 | 49 | .. code-block:: python 50 | :linenos: 51 | 52 | import PyXA 53 | import tempfile 54 | 55 | # Get the source of webpage, using a shortcut 56 | app = PyXA.Application("Shortcuts Events") 57 | s1 = app.shortcuts().by_name("Get HTML") 58 | source = s1.run("http://google.com")[0] 59 | 60 | # Create a temporary HTML file 61 | temp = tempfile.NamedTemporaryFile(suffix=".html") 62 | temp.write(bytes(source, "UTF-8")) 63 | 64 | # Open the HTML file 65 | PyXA.application("Safari").open(temp.name) 66 | sleep(0.5) 67 | temp.close() 68 | 69 | Shortcuts Resources 70 | ################### 71 | - `Shortcuts for macOS User Guide - Apple Support `_ 72 | 73 | For all classes, methods, and inherited members of the Shortcuts module, see the :ref:`Shortcuts Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/spotify/index.rst.txt: -------------------------------------------------------------------------------- 1 | Spotify Module Overview 2 | ======================= 3 | 4 | -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/stocks/index.rst.txt: -------------------------------------------------------------------------------- 1 | Stocks Module Overview 2 | ====================== 3 | 4 | For all classes, methods, and inherited members of the Stocks module, see the :ref:`Stocks Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/systemevents/index.rst.txt: -------------------------------------------------------------------------------- 1 | System Events Module Overview 2 | ============================= 3 | 4 | The Terminal module enables control over Terminal.app from within Python, including the ability to run Terminal script and receive the execution return value. 5 | 6 | System Events Examples 7 | ###################### 8 | 9 | Example 1 - Sorting the Desktop 10 | ******************************* 11 | 12 | .. code-block:: python 13 | 14 | import PyXA 15 | app = PyXA.Application("System Events") 16 | 17 | # Set the desktop picture 18 | app.current_desktop.picture = "/Users/exampleUser/Desktop/Images/Background.png" 19 | 20 | # Toggle darkmode 21 | app.appearance_preferences.dark_mode = not app.appearance_preferences.dark_mode 22 | 23 | # # Add a login item -- This opens the Documents folder upon login 24 | new_item = app.make("login item", {"path": "/Users/exampleUser/Documents"}) 25 | app.login_items().push(new_item) 26 | 27 | # Start the current screensaver 28 | app.current_screen_saver.start() 29 | 30 | This example uses PyXA to sort files on the desktop into appropriate category folders. 31 | 32 | .. code-block:: python 33 | 34 | import PyXA 35 | app = PyXA.Application("System Events") 36 | 37 | desktop_files = app.desktop_folder.files() 38 | desktop_folders = app.desktop_folder.folders() 39 | 40 | # Create sorting bin folders 41 | images_folder = app.make("folder", {"name": "Images"}) 42 | videos_folder = app.make("folder", {"name": "Videos"}) 43 | audio_folder = app.make("folder", {"name": "Audio"}) 44 | documents_folder = app.make("folder", {"name": "Documents"}) 45 | desktop_folders.push(images_folder, videos_folder, audio_folder, documents_folder) 46 | 47 | # Sort images 48 | image_predicate = "name ENDSWITH '.png' OR name ENDSWITH '.jpg' OR name ENDSWITH '.jpeg' OR name ENDSWITH '.aiff'" 49 | image_files = desktop_files.filter(image_predicate) 50 | image_files.move_to(images_folder) 51 | 52 | # Sort videos 53 | video_predicate = "name ENDSWITH '.mov' OR name ENDSWITH '.mp4' OR name ENDSWITH '.avi' OR name ENDSWITH '.m4v'" 54 | video_files = desktop_files.filter(video_predicate) 55 | video_files.move_to(videos_folder) 56 | 57 | # Sort audio 58 | audio_predicate = "name ENDSWITH '.mp3' OR name ENDSWITH '.ogg'" 59 | audio_files = desktop_files.filter(audio_predicate) 60 | audio_files.move_to(audio_folder) 61 | 62 | # Sort remaining (documents) 63 | desktop_files.move_to(documents_folder) 64 | 65 | System Events Resources 66 | ####################### 67 | - `System Events - AppleScript: The Definitive Guide `_ 68 | 69 | For all classes, methods, and inherited members of the System Events module, see the :ref:`System Events Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/systempreferences/index.rst.txt: -------------------------------------------------------------------------------- 1 | System Preferences Module Overview 2 | ================================== 3 | 4 | For all classes, methods, and inherited members of the System Preferences module, see the :ref:`System Preferences Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/terminal/index.rst.txt: -------------------------------------------------------------------------------- 1 | Terminal Module Overview 2 | ======================== 3 | 4 | The Terminal module enables control over Terminal.app from within Python, including the ability to run Terminal script and receive the execution return value. 5 | 6 | Terminal Examples 7 | ################# 8 | 9 | Example 1 - Using Terminal methods and attributes 10 | ************************************************* 11 | 12 | This example showcases many of the methods and attributes available for use in the Terminal module. 13 | 14 | .. code-block:: python 15 | 16 | import PyXA 17 | app = PyXA.Application("Terminal") 18 | 19 | # Get information about the current tab 20 | tab = app.current_tab 21 | print(tab.custom_title) 22 | print(tab.processes) 23 | print(tab.number_of_rows, tab.number_of_columns) 24 | # Terminal 25 | # ( 26 | # login, 27 | # "-zsh", 28 | # python 29 | # ) 30 | # 24 80 31 | 32 | # Set tab properties 33 | tab.custom_title = "Testing 1 2 3" 34 | tab.number_of_rows = 50 35 | tab.title_displays_custom_title = True 36 | 37 | # Run scripts and utilize return values 38 | value = app.do_script("ls", return_result=True) 39 | print("Number of items:", len(value["stdout"].split("\n")) - 1) 40 | 41 | value = app.do_script("ping www.google.com -c 1", return_result=True) 42 | if "1 packets received" in value["stdout"]: 43 | print("Online!") 44 | else: 45 | print("Offline!") 46 | 47 | # Modify settings 48 | settings = tab.current_settings 49 | settings.background_color = PyXA.XAColor(255, 0, 0) 50 | settings.font_size = 10 51 | 52 | Terminal Resources 53 | ################## 54 | - `Terminal User Guide - Apple Support `_ 55 | 56 | For all classes, methods, and inherited members of the Terminal module, see the :ref:`Terminal Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/tv/index.rst.txt: -------------------------------------------------------------------------------- 1 | TV Module Overview 2 | ================== 3 | 4 | For all classes, methods, and inherited members of the TV module, see the :ref:`TV Module Reference` and :ref:`Media Application Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/apps/vlc/index.rst.txt: -------------------------------------------------------------------------------- 1 | VLC Module Overview 2 | =================== 3 | 4 | VLC Examples 5 | ############ 6 | 7 | Example 1 - Working with VLC methods and attributes 8 | *************************************************** 9 | 10 | This example provides a general overview of the functionalities supported by the VLC module. Additional examples can be found in the code reference for this module. 11 | 12 | .. code-block:: python 13 | :linenos: 14 | 15 | import PyXA 16 | app = PyXA.Application("VLC") 17 | 18 | # Open or get (without opening) files and URLs 19 | app.open("/Users/exampleUser/ExampleFile.m4v") 20 | app.open("https://upload.wikimedia.org/wikipedia/commons/transcoded/e/e1/Black_Hole_Merger_Simulation_GW170104.webm/Black_Hole_Merger_Simulation_GW170104.webm.1080p.vp9.webm") 21 | app.get_url("https://upload.wikimedia.org/wikipedia/commons/transcoded/e/e1/Black_Hole_Merger_Simulation_GW170104.webm/Black_Hole_Merger_Simulation_GW170104.webm.1080p.vp9.webm") 22 | 23 | # Control playback 24 | app.stop() 25 | app.play() 26 | app.previous() 27 | app.next() 28 | app.step_forward() 29 | app.step_backward() 30 | app.current_time = app.current_time + 5 31 | 32 | # Control volume 33 | app.volume_up() 34 | app.volume_down() 35 | app.mute() 36 | app.audio_volume = 256 37 | 38 | # Control the VLC window 39 | app.fullscreen() 40 | app.fullscreen_mode = False 41 | app.front_window.bounds = (0, 0, 500, 500) 42 | app.zoomed = True 43 | 44 | # Utilize information about playback 45 | file = app.path_of_current_item 46 | file.show_in_finder() 47 | 48 | if app.audio_volume > 256: 49 | app.audio_volume = 256 50 | 51 | 52 | VLC Resources 53 | ############# 54 | - `TextEdit User Guide - Apple Support `_ 55 | 56 | For all classes, methods, and inherited members of the VLC module, see the :ref:`VLC Module Reference`. -------------------------------------------------------------------------------- /docs/_sources/tutorial/appscript.rst.txt: -------------------------------------------------------------------------------- 1 | Using Appscript to Work With Unsupported Applications 2 | ===================================================== 3 | 4 | PyXA aims to be have fine-grained documentation on a per-application basis, which greatly limits its ability to interact with applications outside of the ones explicitly mentioned in this documentation. To make up for this limitation, PyXA falls back to `appscript `_ when no PyXA definition exists for an application. This allows you to interact with any AppleScript-compatible application, through appscript, while having access to the additional features of PyXA for an ever-expanding set of applications. 5 | 6 | Converting Between Appscript and PyXA Types 7 | ------------------------------------------- 8 | 9 | -------------------------------------------------------------------------------- /docs/_sources/tutorial/devices.rst.txt: -------------------------------------------------------------------------------- 1 | Device Interaction 2 | ================== 3 | 4 | PyXA offers a _Devices_ addition that provides a simple interface to your device's hardware such as its camera, microphone, and screen. 5 | 6 | Device Classes 7 | -------------- 8 | 9 | The following device classes are available: 10 | 11 | - :class:`~PyXA.Additions.Devices.XACamera` - for capturing photos and videos 12 | - :class:`~PyXA.Additions.Devices.XAMicrophone` - for recording audio 13 | - :class:`~PyXA.Additions.Devices.XAScreen` - for capturing screenshots and screen recordings 14 | 15 | An overview of each class is provided below. 16 | 17 | Camera 18 | --------------------------- 19 | 20 | The :class:`~PyXA.Additions.Devices.XACamera` class provides two methods: one to capture photos (:func:`~PyXA.Additions.Devices.XACamera.capture`) and another to record videos (:func:`~PyXA.Additions.Devices.XACamera.record`). Both methods return an instance of the corresponding PyXA class—either :class:`~PyXA.XABase.XAImage` or :class:`~PyXA.XABase.XAVideo`—that can be used alongside other areas of PyXA. 21 | 22 | For example, to capture a photo and save it to the desktop, you could use the following code: 23 | 24 | .. code-block:: python 25 | 26 | import PyXA 27 | import os 28 | 29 | cam = PyXA.XACamera() 30 | img = cam.capture() 31 | homedir = os.path.expanduser("~") 32 | img.save(f"{homedir}/Desktop/test.png") 33 | 34 | You can combine this with other PyXA features to create powerful automations. For example, you could use the :class:`~PyXA.Additions.Speech.XASpeech` class to speak any text detected in the image: 35 | 36 | .. code-block:: python 37 | 38 | import PyXA 39 | 40 | cam = PyXA.XACamera() 41 | img = cam.capture() 42 | img_text = img.extract_text() 43 | 44 | PyXA.XASpeech(img_text).speak() 45 | 46 | Microphone 47 | ---------- 48 | 49 | The :class:`~PyXA.Additions.Devices.XAMicrophone` class provides a single method, :func:`~PyXA.Additions.Devices.XAMicrophone.record`, that records audio from the device's microphone and returns an instance of the :class:`~PyXA.XABase.XAAudio` class. 50 | 51 | For example, to record 5 seconds of audio and play it back, you could use the following code: 52 | 53 | .. code-block:: python 54 | 55 | import PyXA 56 | import os 57 | 58 | mic = PyXA.XAMicrophone() 59 | homedir = os.path.expanduser("~") 60 | recording = mic.record(f"{homedir}/Downloads/test.wav", 5) 61 | recording.play() 62 | 63 | Screen 64 | ------ 65 | 66 | PyXA's :class:`~PyXA.Additions.Devices.XAScreen` class provides methods for capturing screenshots and screen recordings. Each method returns either a :class:`~PyXA.XABase.XAImage` or :class:`~PyXA.XABase.XAVideo` object. The available methods are: 67 | 68 | - :func:`~PyXA.Additions.Devices.XAScreen.capture` - captures a screenshot 69 | - :func:`~PyXA.Additions.Devices.XAScreen.capture_rect` - captures a screenshot of a specific area of the screen 70 | - :func:`~PyXA.Additions.Devices.XAScreen.capture_window` - captures a screenshot of a specific window 71 | - :func:`~PyXA.Additions.Devices.XAScreen.record` - records a screen recording -------------------------------------------------------------------------------- /docs/_sources/tutorial/tips_tricks.rst.txt: -------------------------------------------------------------------------------- 1 | Tips and Tricks 2 | =============== 3 | 4 | 1. Know when and when not to chain commands. You might be tempted to use a batch operation such as `PyXA.Application("Notes").notes().plaintext()` to obtain the text of each note, but then you will _only_ have the unicode text, not references to the note objects. If you're going to need the note objects, you should store a reference to the list of notes in a separate variable, then run batch operations via that reference. On the other hand, you should make use of PyXA's command chaining where reasonable to improve the overall clarity of your code and maintain its syntactic similarity to JXA. 5 | 6 | 2. Use :class:`~PyXA.XABase.XAList` and its child classes whenever dealing with lists of PyXA objects. Bulk methods on :class:`~PyXA.XABase.XAList` objects are often significantly faster (sometimes over 56x faster) than using non-bulk methods and regular iteration over a list. -------------------------------------------------------------------------------- /docs/_sources/tutorial/ui_scripting.rst.txt: -------------------------------------------------------------------------------- 1 | UI Scripting 2 | ============ 3 | 4 | PyXA supports using System Events to script the UI of otherwise non-scriptable applications. In fact, PyXA uses this functionality to provide scripting features for several applications, including Maps and Stocks. 5 | 6 | The process for scripting an application's UI starts with getting its window object, from which you can call various methods, such as :func:`~PyXA.apps.SystemEvents.XASystemEventsWindow.groups` and :func:`~PyXA.apps.SystemEvents.XASystemEventsWindow.toolbars`, to obtain lists of UI elements. These methods provide access to all UI element types listed in the System Events scripting dictionary. Lists of elements obtained in this fashion are instances of :class:`~PyXA.apps.SystemEvents.XASystemEventsUIElementList`, a subclass of :class:`~PyXA.XABase.XAList`. You can use bulk methods on a list of UI elements to retrieve information about the list's contents. For example, you can call :func:`~PyXA.apps.SystemEvents.XASystemEventsUIElementList.object_description` to get the accessibility or role description of all elements in the list. List filtration methods such as :func:`~PyXA.apps.SystemEvents.XASystemEventsUIElementList.by_object_description` allow you to efficiently access elements with particular property values. 7 | 8 | Retrieving an element from an :class:`~PyXA.apps.SystemEvents.XASystemEventsUIElementList` object will return a instance of :class:`~PyXA.apps.SystemEvents.XASystemEventsUIElement`. You can then obtain the properties of the UI element via the object's attributes. Upon doing so, the reference to the AppleScript scripting object will be evaluated, causing one or more Apple Events to be sent. This behavior makes it possible to quickly traverse the UI hierarchy without sending unnecessary Apple Events and causing slowdowns. 9 | 10 | Once you have a reference to a specific UI element, you can call methods such as :func:`~PyXA.apps.SystemEvents.XASystemEventsButton.click` to carry out actions on that element, or you can obtain a list of actions by calling :func:`~PyXA.apps.SystemEvents.XASystemEventsUIElement.actions`. Call :func:`~PyXA.apps.SystemEvents.XASystemEventsAction.perform` to perform a particular action. 11 | 12 | An example of this process is provided below. 13 | 14 | .. code-block:: python 15 | 16 | from time import sleep 17 | import PyXA 18 | 19 | podcasts = PyXA.Application("Podcasts") 20 | 21 | # Get the list of podcast playback controls 22 | playback_buttons = podcasts.front_window.groups()[0].groups()[0].groups()[0].groups()[0].groups()[0].groups()[0].groups()[1].groups()[0].groups()[0].groups()[2].groups()[0].groups()[0].buttons() 23 | 24 | # Get buttons by property value 25 | rewind_button = playback_buttons.by_object_description("Rewind") 26 | play_button = playback_buttons.by_object_description("Play") 27 | skip_button = playback_buttons.by_object_description("Skip") 28 | 29 | # Click the buttons 30 | play_button.click() 31 | sleep(1) 32 | skip_button.click() 33 | sleep(1) 34 | rewind_button.click() 35 | 36 | In this example, we obtain a list of buttons by traversing the UI hierarchy of the Podcasts app to reach the specific group containing the rewind, play, and skip forward buttons at the top of the window. You can use macOS's built-in `Accessibility Inspector` application to help identify the element hierarchy. Once we have the list of buttons, we obtain references to each individual button according to its object description. We then call the :func:`~PyXA.apps.SystemEvents.XASystemEventsButton.click` method of each button to observe its effect. -------------------------------------------------------------------------------- /docs/_static/assets/CPUMonitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/assets/CPUMonitor.png -------------------------------------------------------------------------------- /docs/_static/assets/Example3_Notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/assets/Example3_Notes.png -------------------------------------------------------------------------------- /docs/_static/assets/HelloMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/assets/HelloMenu.png -------------------------------------------------------------------------------- /docs/_static/assets/JWSTMenuBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/assets/JWSTMenuBar.png -------------------------------------------------------------------------------- /docs/_static/assets/MenuItemImages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/assets/MenuItemImages.png -------------------------------------------------------------------------------- /docs/_static/assets/PrintHi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/assets/PrintHi.png -------------------------------------------------------------------------------- /docs/_static/assets/PrintHiImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/assets/PrintHiImage.png -------------------------------------------------------------------------------- /docs/_static/assets/PyXALogoLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/assets/PyXALogoLight.png -------------------------------------------------------------------------------- /docs/_static/assets/PyXALogoTransparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/assets/PyXALogoTransparent.png -------------------------------------------------------------------------------- /docs/_static/css/badge_only.css: -------------------------------------------------------------------------------- 1 | .clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/Roboto-Slab-Bold.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/Roboto-Slab-Bold.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/Roboto-Slab-Regular.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/Roboto-Slab-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/Roboto-Slab-Regular.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/lato-bold-italic.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/lato-bold-italic.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/lato-bold.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/lato-bold.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/lato-normal-italic.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/lato-normal-italic.woff2 -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/lato-normal.woff -------------------------------------------------------------------------------- /docs/_static/css/fonts/lato-normal.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/css/fonts/lato-normal.woff2 -------------------------------------------------------------------------------- /docs/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | const DOCUMENTATION_OPTIONS = { 2 | VERSION: '0.2.3', 3 | LANGUAGE: 'en', 4 | COLLAPSE_INDEX: false, 5 | BUILDER: 'html', 6 | FILE_SUFFIX: '.html', 7 | LINK_SUFFIX: '.html', 8 | HAS_SOURCE: true, 9 | SOURCELINK_SUFFIX: '.txt', 10 | NAVIGATION_WITH_KEYS: false, 11 | SHOW_SEARCH_SUMMARY: true, 12 | ENABLE_SEARCH_SHORTCUTS: true, 13 | }; -------------------------------------------------------------------------------- /docs/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/file.png -------------------------------------------------------------------------------- /docs/_static/graphviz.css: -------------------------------------------------------------------------------- 1 | /* 2 | * graphviz.css 3 | * ~~~~~~~~~~~~ 4 | * 5 | * Sphinx stylesheet -- graphviz extension. 6 | * 7 | * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | 12 | img.graphviz { 13 | border: 0; 14 | max-width: 100%; 15 | } 16 | 17 | object.graphviz { 18 | max-width: 100%; 19 | } 20 | -------------------------------------------------------------------------------- /docs/_static/js/badge_only.js: -------------------------------------------------------------------------------- 1 | !function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}}); -------------------------------------------------------------------------------- /docs/_static/js/html5shiv-printshiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); -------------------------------------------------------------------------------- /docs/_static/js/html5shiv.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); -------------------------------------------------------------------------------- /docs/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/minus.png -------------------------------------------------------------------------------- /docs/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/_static/plus.png -------------------------------------------------------------------------------- /docs/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/docs/objects.inv -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42"] 3 | build-backend = "setuptools.build_meta" -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = mac-pyxa 3 | version = 0.3.0.1 4 | author = Stephen Kaplan 5 | author_email = stephen.kaplan@maine.edu 6 | description = A package for accomplish AppleScript automation tasks using Python syntax. 7 | long_description = file: README.md 8 | long_description_content_type = text/markdown 9 | url = https://github.com/SKaplanOfficial/PyXA 10 | project_urls = 11 | Bug Tracker = https://github.com/SKaplanOfficial/PyXA/issues 12 | classifiers = 13 | Programming Language :: Python :: 3 14 | License :: OSI Approved :: MIT License 15 | Operating System :: OS Independent 16 | 17 | [options] 18 | packages = find: 19 | python_requires = >=3.10 20 | install_requires = 21 | pyobjc-core == 9.* 22 | pyobjc-framework-AVFoundation == 9.* 23 | pyobjc-framework-EventKit == 9.* 24 | pyobjc-framework-Quartz == 9.* 25 | pyobjc-framework-ScriptingBridge == 9.* 26 | pyobjc-framework-NaturalLanguage == 9.* 27 | pyobjc-framework-CoreLocation == 9.* 28 | pyobjc-framework-Vision == 9.* 29 | pyobjc-framework-CoreMedia == 9.* 30 | pyobjc-framework-Photos == 9.* 31 | pyobjc-framework-Speech == 9.* 32 | pyobjc-framework-LatentSemanticMapping == 9.* 33 | pyobjc-framework-ApplicationServices == 9.* 34 | pyobjc-framework-CoreText == 9.* 35 | pyobjc-framework-libdispatch == 9.* 36 | pyobjc-framework-datadetection == 9.* 37 | requests == 2.28.* 38 | beautifulsoup4 == 4.11.* 39 | macimg == 0.0.3 -------------------------------------------------------------------------------- /sphinx/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | github: 18 | @make html 19 | @cp -a build/html/. ../docs 20 | 21 | # Catch-all target: route all unknown targets to Sphinx using the new 22 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 23 | %: Makefile 24 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 25 | -------------------------------------------------------------------------------- /sphinx/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /sphinx/source/_static/assets/CPUMonitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/sphinx/source/_static/assets/CPUMonitor.png -------------------------------------------------------------------------------- /sphinx/source/_static/assets/Example3_Notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/sphinx/source/_static/assets/Example3_Notes.png -------------------------------------------------------------------------------- /sphinx/source/_static/assets/HelloMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/sphinx/source/_static/assets/HelloMenu.png -------------------------------------------------------------------------------- /sphinx/source/_static/assets/JWSTMenuBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/sphinx/source/_static/assets/JWSTMenuBar.png -------------------------------------------------------------------------------- /sphinx/source/_static/assets/MenuItemImages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/sphinx/source/_static/assets/MenuItemImages.png -------------------------------------------------------------------------------- /sphinx/source/_static/assets/PrintHi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/sphinx/source/_static/assets/PrintHi.png -------------------------------------------------------------------------------- /sphinx/source/_static/assets/PrintHiImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/sphinx/source/_static/assets/PrintHiImage.png -------------------------------------------------------------------------------- /sphinx/source/_static/assets/PyXALogoLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/sphinx/source/_static/assets/PyXALogoLight.png -------------------------------------------------------------------------------- /sphinx/source/_static/assets/PyXALogoTransparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/sphinx/source/_static/assets/PyXALogoTransparent.png -------------------------------------------------------------------------------- /sphinx/source/about/index.rst: -------------------------------------------------------------------------------- 1 | Package Overview 2 | ================ 3 | 4 | What is PyXA? 5 | ############# 6 | 7 | Python for Automation, or PyXA for short, is a wrapper around several macOS frameworks that enables AppleScript- and JXA-like control over macOS applications from within Python. PyXA's objects and methods are based on applications' scripting dictionaries and coupled with additional automation features supported by Apple's macOS APIs. 8 | 9 | PyXA was created with the goals of: 10 | 11 | 1. Simplifying the way automation tasks can be accomplished via Python 12 | 2. Introducing new features to macOS application scripting by simplifying complex procedures into simple, declarative methods 13 | 3. Disambiguating the capabilities of application scripting on macOS by providing easy-to-follow documentation throughout the entire project 14 | 15 | PyXA fills a gap where currently available frameworks ultimately fall short: it aims to be easy to learn for users accustomed to Python (or users who _must_ use Python). To that end, the package's documentation contains numerous examples of how to use just about every method, and additional examples are provided covering specific use cases. PyXA's code also serves as a source of examples for how to use `PyObjC `_ to interact with various macOS frameworks. 16 | 17 | Is PyXA for Me? 18 | ############### 19 | 20 | PyXA is not intended to replace AppleScript or even to cover 100% of AppleScript's capabilities. Instead, PyXA is meant to provide general convenience in accomplishing AppleScript and other automation tasks via Python, for the most commonly used applications. If you need a complete Apple Event bridge, or if you find that PyXA cannot handle your particular use case, consider using `appscript `_ or one of its derivatives. If you just need something that works in most circumstances, that has abundant examples for you to reference, and supports some additional automation features (such as opening Maps to a specific address), then PyXA might be a good fit for you. 21 | -------------------------------------------------------------------------------- /sphinx/source/bugs.rst: -------------------------------------------------------------------------------- 1 | Bugs 2 | ==== 3 | 4 | Bugs in PyXA 5 | ************ 6 | 7 | If you find a bug within any of the code in `PyXA's GitHub Repository`_, please create a new issue on GitHub that describes the bug, the circumstances that cause the bug to occur, a description of your configuration, and any potential solutions that you might have thought of. After creating an issue, if you have the time and expertise to implement the fix, you can create a new pull request containing your changes. Make sure to follow the `Guidelines for Contributing to PyXA's Code`_. 8 | 9 | Documentation Bugs 10 | ****************** 11 | 12 | If you find a bug in this documentation, please create a new issue on `PyXA's GitHub Repository`_. If you have an idea for a potential fix, please include a description of the fix within the issue. After creating an issue, if you have the time and expertise to implement the fix, you can create a new pull request containing your changes. Make sure to follow the `Guidelines for Contributing to PyXA's Documentation`_. 13 | 14 | .. _PyXA's GitHub Repository: https://github.com/SKaplanOfficial/PyXA/issues 15 | .. _Guidelines for Contributing to PyXA's Code: https://github.com/SKaplanOfficial/PyXA/blob/main/CONTRIBUTING.md#code 16 | .. _Guidelines for Contributing to PyXA's Documentation: https://github.com/SKaplanOfficial/PyXA/blob/main/CONTRIBUTING.md#documentation -------------------------------------------------------------------------------- /sphinx/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | import os 14 | import sys 15 | sys.path.insert(0, os.path.abspath('../..')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'PyXA' 21 | copyright = '2023, Stephen Kaplan' 22 | author = 'Stephen Kaplan' 23 | 24 | # The full version, including alpha/beta/rc tags 25 | release = '0.2.3' 26 | 27 | 28 | # -- General configuration --------------------------------------------------- 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = [ 34 | 'sphinx.ext.autodoc', 35 | 'sphinx.ext.autosectionlabel', 36 | 'sphinx.ext.autosummary', 37 | 'sphinx.ext.inheritance_diagram', 38 | 'sphinx.ext.todo', 39 | 'sphinx.ext.viewcode', 40 | 'autodocsumm', 41 | 'sphinx_automodapi.automodapi', 42 | 'sphinx_automodapi.smart_resolver', 43 | 'sphinx_enum_extend', 44 | ] 45 | 46 | # Add any paths that contain templates here, relative to this directory. 47 | templates_path = ['_templates'] 48 | 49 | # List of patterns, relative to source directory, that match files and 50 | # directories to ignore when looking for source files. 51 | # This pattern also affects html_static_path and html_extra_path. 52 | exclude_patterns = [] 53 | 54 | 55 | # -- Options for HTML output ------------------------------------------------- 56 | 57 | # The theme to use for HTML and HTML Help pages. See the documentation for 58 | # a list of builtin themes. 59 | # 60 | html_theme = 'sphinx_rtd_theme' 61 | 62 | # Add any paths that contain custom static files (such as style sheets) here, 63 | # relative to this directory. They are copied after the builtin static files, 64 | # so a file named "default.css" will overwrite the builtin "default.css". 65 | html_static_path = ['_static'] 66 | 67 | numfig = True 68 | todo_include_todos = True 69 | #todo_link_only = True 70 | 71 | autodoc_default_options = {"autosummary": True} -------------------------------------------------------------------------------- /sphinx/source/index.rst: -------------------------------------------------------------------------------- 1 | .. PyXA documentation master file, created by 2 | sphinx-quickstart on Sat May 28 10:21:18 2022. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | .. image:: _static/assets/PyXALogoTransparent.png 7 | :alt: PyXA Logo 8 | 9 | 10 | PyXA Documentation 11 | ================== 12 | 13 | Python for Automation is a wrapper around Apple's Scripting Bridge framework that enables AppleScript- and JXA-like control over macOS applications from within Python. 14 | 15 | .. toctree:: 16 | :maxdepth: 3 17 | :caption: Contents: 18 | 19 | about/index 20 | tutorial/index 21 | reference/index 22 | bugs 23 | 24 | Indices and tables 25 | ================== 26 | 27 | * :ref:`genindex` 28 | * :ref:`modindex` 29 | * :ref:`search` 30 | 31 | .. note:: 32 | This project is under active development. -------------------------------------------------------------------------------- /sphinx/source/reference/additions/devices.rst: -------------------------------------------------------------------------------- 1 | Devices Module 2 | ============== 3 | 4 | .. automodule:: PyXA.Additions.Devices 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/additions/learn.rst: -------------------------------------------------------------------------------- 1 | Learn Module 2 | ============ 3 | 4 | .. automodule:: PyXA.Additions.Learn 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/additions/speech.rst: -------------------------------------------------------------------------------- 1 | Speech Module 2 | ============= 3 | 4 | .. automodule:: PyXA.Additions.Speech 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/additions/ui.rst: -------------------------------------------------------------------------------- 1 | UI Module 2 | ========= 3 | 4 | .. automodule:: PyXA.Additions.UI 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/additions/utils.rst: -------------------------------------------------------------------------------- 1 | Utils Module 2 | ============ 3 | 4 | .. automodule:: PyXA.Additions.Utils 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/additions/web.rst: -------------------------------------------------------------------------------- 1 | Web Module 2 | ========== 3 | 4 | .. automodule:: PyXA.Additions.Web 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/arc.rst: -------------------------------------------------------------------------------- 1 | Arc Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.Arc 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/automator.rst: -------------------------------------------------------------------------------- 1 | Automator Module Reference 2 | ========================== 3 | 4 | .. automodule:: PyXA.apps.Automator 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/bike.rst: -------------------------------------------------------------------------------- 1 | Bike Module Reference 2 | ===================== 3 | 4 | .. automodule:: PyXA.apps.Bike 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/calculator.rst: -------------------------------------------------------------------------------- 1 | Calculator Module Reference 2 | =========================== 3 | 4 | .. automodule:: PyXA.apps.Calculator 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/calendar.rst: -------------------------------------------------------------------------------- 1 | Calendar Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Calendar 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/cardhop.rst: -------------------------------------------------------------------------------- 1 | Cardhop Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Cardhop 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/chromium.rst: -------------------------------------------------------------------------------- 1 | Chromium Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Chromium 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/console.rst: -------------------------------------------------------------------------------- 1 | Console Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Console 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/contacts.rst: -------------------------------------------------------------------------------- 1 | Contacts Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Contacts 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/dictionary.rst: -------------------------------------------------------------------------------- 1 | Dictionary Module Reference 2 | =========================== 3 | 4 | .. automodule:: PyXA.apps.Dictionary 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/drafts.rst: -------------------------------------------------------------------------------- 1 | Drafts Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.Drafts 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/fantastical.rst: -------------------------------------------------------------------------------- 1 | Fantastical Module Reference 2 | ============================ 3 | 4 | .. automodule:: PyXA.apps.Fantastical 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/finder.rst: -------------------------------------------------------------------------------- 1 | Finder Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.Finder 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/flow.rst: -------------------------------------------------------------------------------- 1 | Flow Module Reference 2 | ===================== 3 | 4 | .. automodule:: PyXA.apps.Flow 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/fontbook.rst: -------------------------------------------------------------------------------- 1 | FontBook Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.FontBook 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/hammerspoon.rst: -------------------------------------------------------------------------------- 1 | Hammerspoon Module Reference 2 | ============================ 3 | 4 | .. automodule:: PyXA.apps.Hammerspoon 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/iina.rst: -------------------------------------------------------------------------------- 1 | IINA+ Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.IINA 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/imageevents.rst: -------------------------------------------------------------------------------- 1 | Image Events Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.ImageEvents 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/iterm.rst: -------------------------------------------------------------------------------- 1 | iTerm Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.iTerm 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/iwork.rst: -------------------------------------------------------------------------------- 1 | iWork Base Reference 2 | ==================== 3 | 4 | .. automodule:: PyXA.apps.iWorkApplicationBase 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/keynote.rst: -------------------------------------------------------------------------------- 1 | Keynote Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Keynote 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/mail.rst: -------------------------------------------------------------------------------- 1 | Mail Module Reference 2 | ===================== 3 | 4 | .. automodule:: PyXA.apps.Mail 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/maps.rst: -------------------------------------------------------------------------------- 1 | Maps Module Reference 2 | ===================== 3 | 4 | .. automodule:: PyXA.apps.Maps 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/messages.rst: -------------------------------------------------------------------------------- 1 | Messages Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Messages 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/music.rst: -------------------------------------------------------------------------------- 1 | Music Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.Music 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/notes.rst: -------------------------------------------------------------------------------- 1 | Notes Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.Notes 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/numbers.rst: -------------------------------------------------------------------------------- 1 | Numbers Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Notes 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/omnioutliner.rst: -------------------------------------------------------------------------------- 1 | OmniOutliner Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.OmniOutliner 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/omniweb.rst: -------------------------------------------------------------------------------- 1 | OmniWeb Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.OmniWeb 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/pages.rst: -------------------------------------------------------------------------------- 1 | Pages Module Reference 2 | ====================== 3 | 4 | .. automodule:: PyXA.apps.Pages 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/pathfinder.rst: -------------------------------------------------------------------------------- 1 | Path Finder Module Reference 2 | ============================= 3 | 4 | .. automodule:: PyXA.apps.PathFinder 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/photos.rst: -------------------------------------------------------------------------------- 1 | Photos Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.PhotosApp 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/preview.rst: -------------------------------------------------------------------------------- 1 | Preview Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Preview 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/quicktimeplayer.rst: -------------------------------------------------------------------------------- 1 | QuickTime Module Reference 2 | ========================== 3 | 4 | .. automodule:: PyXA.apps.QuickTimePlayer 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/reminders.rst: -------------------------------------------------------------------------------- 1 | Reminders Module Reference 2 | ========================== 3 | 4 | .. automodule:: PyXA.apps.Reminders 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/rstudio.rst: -------------------------------------------------------------------------------- 1 | RStudio Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.RStudio 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/safari.rst: -------------------------------------------------------------------------------- 1 | Safari Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.Safari 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/shortcuts.rst: -------------------------------------------------------------------------------- 1 | Shortcuts Module Reference 2 | ========================== 3 | 4 | .. automodule:: PyXA.apps.Shortcuts 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/spotify.rst: -------------------------------------------------------------------------------- 1 | Spotify Module Reference 2 | ======================== 3 | 4 | .. automodule:: PyXA.apps.Spotify 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/stocks.rst: -------------------------------------------------------------------------------- 1 | Stocks Module Reference 2 | ======================= 3 | 4 | .. automodule:: PyXA.apps.Stocks 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/systemevents.rst: -------------------------------------------------------------------------------- 1 | System Events Module Reference 2 | ============================== 3 | 4 | .. automodule:: PyXA.apps.SystemEvents 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/systempreferences.rst: -------------------------------------------------------------------------------- 1 | System Preferences Module Reference 2 | =================================== 3 | 4 | .. automodule:: PyXA.apps.SystemPreferences 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/terminal.rst: -------------------------------------------------------------------------------- 1 | Terminal Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.Terminal 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/textedit.rst: -------------------------------------------------------------------------------- 1 | TextEdit Module Reference 2 | ========================= 3 | 4 | .. automodule:: PyXA.apps.TextEdit 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/tv.rst: -------------------------------------------------------------------------------- 1 | TV Module Reference 2 | =================== 3 | 4 | .. automodule:: PyXA.apps.TV 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/apps/vlc.rst: -------------------------------------------------------------------------------- 1 | VLC Module Reference 2 | ==================== 3 | 4 | .. automodule:: PyXA.apps.VLC 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/index.rst: -------------------------------------------------------------------------------- 1 | Code Documentation and Reference 2 | ================================ 3 | 4 | Top-level PyXA Modules 5 | ---------------------- 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | xabase 10 | xabasescriptable 11 | xatypes 12 | xaprotocols 13 | xaerrors 14 | 15 | First-Party Application Module Reference 16 | ---------------------------------------- 17 | .. toctree:: 18 | :maxdepth: 2 19 | 20 | apps/automator 21 | apps/calculator 22 | apps/calendar 23 | apps/console 24 | apps/contacts 25 | apps/dictionary 26 | apps/finder 27 | apps/fontbook 28 | apps/imageevents 29 | apps/keynote 30 | apps/mail 31 | apps/maps 32 | apps/messages 33 | apps/music 34 | apps/notes 35 | apps/numbers 36 | apps/pages 37 | apps/photos 38 | apps/preview 39 | apps/quicktimeplayer 40 | apps/reminders 41 | apps/safari 42 | apps/shortcuts 43 | apps/stocks 44 | apps/systemevents 45 | apps/systempreferences 46 | apps/terminal 47 | apps/textedit 48 | apps/tv 49 | 50 | Third-Party Application Module Reference 51 | ---------------------------------------- 52 | .. toctree:: 53 | :maxdepth: 2 54 | 55 | apps/arc 56 | apps/bike 57 | apps/cardhop 58 | apps/chromium 59 | apps/fantastical 60 | apps/flow 61 | apps/drafts 62 | apps/hammerspoon 63 | apps/iina 64 | apps/iterm 65 | apps/omnioutliner 66 | apps/omniweb 67 | apps/pathfinder 68 | apps/spotify 69 | apps/vlc 70 | apps/rstudio 71 | 72 | PyXA Additions 73 | -------------- 74 | .. toctree:: 75 | :maxdepth: 2 76 | 77 | additions/learn 78 | additions/devices 79 | additions/speech 80 | additions/ui 81 | additions/utils 82 | additions/web -------------------------------------------------------------------------------- /sphinx/source/reference/xabase.rst: -------------------------------------------------------------------------------- 1 | XABase Module 2 | ============= 3 | 4 | .. automodule:: PyXA.XABase 5 | :members: 6 | :undoc-members: 7 | :special-members: 8 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/xabasescriptable.rst: -------------------------------------------------------------------------------- 1 | XABaseScriptable Module 2 | ======================= 3 | 4 | .. automodule:: PyXA.XABaseScriptable 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/xaerrors.rst: -------------------------------------------------------------------------------- 1 | XAErrors Module 2 | =============== 3 | 4 | .. automodule:: PyXA.XAErrors 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/xaprotocols.rst: -------------------------------------------------------------------------------- 1 | XAProtocols Module 2 | ================== 3 | 4 | .. automodule:: PyXA.XAProtocols 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/reference/xatypes.rst: -------------------------------------------------------------------------------- 1 | XATypes Module 2 | ============== 3 | 4 | .. automodule:: PyXA.XATypes 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/automator/index.rst: -------------------------------------------------------------------------------- 1 | Automator Module 2 | ================ 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | Overview 9 | ######## 10 | PyXA supports all of Automator's OSA features, including but not limited to creating and executing workflows, managing Automator actions and their settings, and interacting with execution return values. PyXA can create workflows and variables, assign and arrange actions, and modify the attributes thereof. PyXA can also observe the execution of workflow files, allowing you to use existing automation workflows aongside PyXA and Python in general. 11 | 12 | Automator Tutorials 13 | ################### 14 | There is currently one tutorial for the Automator module: 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | 19 | tutorial1 20 | 21 | Automator Examples 22 | ################## 23 | The examples below provide an overview of the capabilities of the Automator module. 24 | 25 | Example 1 - Creating workflows from scratch 26 | ******************************************* 27 | 28 | The example below creates a workflow that displays a notification, waits five seconds, then starts the screen saver. The process for creating workflows begins with making a new workflow object, adding it to the list of workflows, and saving it to the disk. Without saving here, you may encounter errors as some methods and actions require access to the workflow file. With an empty workflow created, the next step is to add actions, which is most easily done by name. Next, you must retrieve a mutable form of the actions; you can think of the original ones as a template that you've now made a copy of. From there, you can change the value of settings however you desire. 29 | 30 | .. code-block:: python 31 | :linenos: 32 | 33 | import PyXA 34 | app = PyXA.Application("Automator") 35 | 36 | # Create and save a new workflow 37 | new_workflow = app.make("workflow", {"name": "New Workflow"}) 38 | app.workflows().push(new_workflow) 39 | new_workflow.save() 40 | 41 | # Add actions to the workflow 42 | action1 = app.automator_actions().by_name("Display Notification") 43 | action2 = app.automator_actions().by_name("Pause") 44 | action3 = app.automator_actions().by_name("Start Screen Saver") 45 | app.add(action1, new_workflow) 46 | app.add(action2, new_workflow) 47 | app.add(action3, new_workflow) 48 | 49 | # Obtain actions in mutable form and change their settings 50 | actions = new_workflow.automator_actions() 51 | notification_text = actions[0].settings().by_name("title") 52 | notification_text.set_property("value", "PyXA Notification") 53 | 54 | pause_duration = actions[1].settings().by_name("pauseDuration") 55 | pause_duration.set_property("value", 5) 56 | 57 | # Run the workflow 58 | new_workflow.execute() 59 | 60 | Example 2 - Running existing workflows 61 | ************************************** 62 | 63 | In the short example below, we open an existing workflow file, run it, and display the execution's results. 64 | 65 | .. code-block:: python 66 | :linenos: 67 | 68 | import PyXA 69 | app = PyXA.Application("Automator") 70 | 71 | app.open("/Users/exampleuser/Downloads/Example.workflow") 72 | workflow = app.workflows().by_name("Example.workflow") 73 | workflow.execute() 74 | 75 | print(workflow.execution_result) 76 | 77 | Automator Resources 78 | ################### 79 | - `Automator User Guide - Apple Support `_ 80 | 81 | For all classes, methods, and inherited members of the Automator module, see the :ref:`Automator Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/bike/index.rst: -------------------------------------------------------------------------------- 1 | Bike Module Overview 2 | ==================== 3 | 4 | Bike Resources 5 | ############## 6 | - `Creating Scripts - Bike Guide `_ 7 | - `Using Scripts - Bike Guide `_ 8 | - `Bike Extensions Wiki `_ 9 | 10 | For all classes, methods, and inherited members of the Bike module, see the :ref:`Bike Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/calculator/index.rst: -------------------------------------------------------------------------------- 1 | Calculator Module Overview 2 | ========================== 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | PyXA enables limited scripting functionalities in Calculator.app, despite no official scripting support for it. Currently, the calculator's scripting functionalities are entirely supported by UI scripting, however additional features are planned for future development work. 9 | 10 | Using :func:`XACalculatorApplication.input`, you can command the Calculator to execute a sequence of button clicks. The sequence must be a continuous string (no spaces). The valid characters are numbers `0-9`, `+`, `-`, `*`, `/`, `%`, `~`, `=`, and `c`. Their meanings are as follows: 11 | 12 | - `+`, `-`, `*`, and `/` correspond to their usual operation buttons. 13 | - `%` designates the percentage button. 14 | - `~` corresponds to the negation button. 15 | - `=` represents the equals button. 16 | - `c` denotes the clear button. 17 | 18 | Calculator Tutorials 19 | #################### 20 | There are currently no tutorials for working with the Calculator application. 21 | 22 | Calculator Examples 23 | ################### 24 | The examples below provide an overview of the capabilities of the Calculator module. They do not provide any output. 25 | .. For more in-depth examples that show output and provide more detailed explanations, refer to the previous section (:ref:`Tutorials`). 26 | 27 | Example 1 - Performing Operations in Calculator.app 28 | *************************************************** 29 | 30 | This example uses :func:`XACalculatorApplication.input` to calculate the result of an expression, then retrieves the result using :func:`XACalculatorApplication.current_value`. 31 | 32 | .. code-block:: python 33 | :linenos: 34 | 35 | import PyXA 36 | app = PyXA.Application("Calculator") 37 | app.input("3.14159265*2*3*5*5*5=") 38 | x = app.current_value() 39 | print(x) 40 | 41 | Calculator Resources 42 | #################### 43 | - `Calculator User Guide - Apple Support `_ 44 | 45 | For all classes, methods, and inherited members of the Calculator module, see the :ref:`Calculator Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/cardhop/index.rst: -------------------------------------------------------------------------------- 1 | Cardhop Module Overview 2 | ======================= 3 | 4 | Cardhop Resources 5 | ################# 6 | - `Cardhop Integration With Other Apps Help `_ 7 | - 8 | For all classes, methods, and inherited members of the Cardhop module, see the :ref:`Cardhop Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/console/index.rst: -------------------------------------------------------------------------------- 1 | Console Module Overview 2 | ======================= 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | PyXA has fully supports all scripting features of Console.app, but there is minimal support (from Apple) in the first place in that regard. Future versions of PyXA might explore expanding the feature offering through UI scripting, utilization of Objective-C frameworks, and other means. 9 | 10 | Console Tutorials 11 | ################# 12 | There are currently no tutorials for the Console module. 13 | 14 | Console Examples 15 | ################ 16 | .. The examples below provide an overview of the capabilities of the Chromium module. They do not provide any output. For more in-depth examples that show output and provide more detailed explanations, refer to the previous section (:ref:`Chromium Tutorials`). 17 | 18 | Example 1 - Coming Soon 19 | **************************************** 20 | 21 | An example will be added soon. 22 | 23 | .. .. code-block:: python 24 | .. :linenos: 25 | 26 | .. import PyXA 27 | .. from time import sleep 28 | 29 | .. # Open URL in new tab 30 | .. app = PyXA.Application("Chromium") 31 | .. app.activate() 32 | .. app.open("http://apple.com") 33 | 34 | .. # Wait for tab to finish loading 35 | .. tab = app.front_window().tabs().last() 36 | .. while tab.loading: 37 | .. sleep(0.1) 38 | 39 | .. # Save the tab's content 40 | .. tab.save("/Users/exampleuser/Downloads/apple-site") 41 | 42 | Console Resources 43 | ################# 44 | - `Console User Guide - Apple Support `_ 45 | 46 | For all classes, methods, and inherited members of the Console module, see the :ref:`Console Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/contacts/index.rst: -------------------------------------------------------------------------------- 1 | Contacts Module Overview 2 | ======================== 3 | 4 | For all classes, methods, and inherited members of the Contacts module, see the :ref:`Contacts Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/dictionary/index.rst: -------------------------------------------------------------------------------- 1 | Dictionary Module Overview 2 | ========================== 3 | 4 | For all classes, methods, and inherited members of the Dictionary module, see the :ref:`Dictionary Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/drafts/index.rst: -------------------------------------------------------------------------------- 1 | Drafts Module Overview 2 | ====================== 3 | 4 | For all classes, methods, and inherited members of the Drafts module, see the :ref:`Drafts Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/fantastical/index.rst: -------------------------------------------------------------------------------- 1 | Fantastical Module Overview 2 | =========================== 3 | 4 | The Fantastical module provides access to Fantastical's features from within PyXA, making use of both the application's scripting dictionary as well as its URL scheme. 5 | 6 | Fantastical Examples 7 | #################### 8 | 9 | Example 1 - Interacting with Currently Selected Calendar Items 10 | ************************************************************** 11 | 12 | .. code-block:: python 13 | 14 | import PyXA 15 | app = PyXA.Application("Fantastical") 16 | items = app.selected_calendar_items() 17 | urls = [item.show_url.url for item in items] 18 | print(urls) 19 | # ['x-fantastical://show?item=7d627e52-ae3d-39eb-b86b-57b037f92cab&calendarIdentifier=A5E06B53-667F-42EE-A6FD-99609F6711E3&date=2022-02-21%2000:00', 'x-fantastical://show?item=e4bcc8c4-cd34-3c1d-b273-def4ecd47eae&calendarIdentifier=A5E06B53-667F-42EE-A6FD-99609F6711E3&date=2022-02-14%2000:00', ...] 20 | 21 | Example 2 - Using Natural Language to Create Events 22 | *************************************************** 23 | 24 | .. code-block:: python 25 | 26 | import PyXA 27 | app = PyXA.Application("Fantastical") 28 | app.parse_sentence("Meeting from 2pm to 3 today") 29 | app.parse_sentence("Joe's birthday August 26th all day") 30 | app.parse_sentence("Computer Science Homework due on Tuesday") 31 | app.parse_sentence("Vacation from August 26 to September 2") 32 | app.parse_sentence("Meeting at 2pm today alert 20 minutes before") 33 | app.parse_sentence("Attend Apple Event at 1 Infinite Loop, Cupertino, CA on September 14 at 9am") 34 | app.parse_sentence("Remind me to clean on Wednesday") 35 | 36 | Fantastical Resources 37 | ##################### 38 | - `Fantastical Integration With Other Apps Help `_ 39 | - `Fantastical Guide - Calendar.com `_ 40 | 41 | For all classes, methods, and inherited members of the Fantastical module, see the :ref:`Fantastical Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/finder/index.rst: -------------------------------------------------------------------------------- 1 | Finder Module Overview 2 | ====================== 3 | 4 | For all classes, methods, and inherited members of the Finder module, see the :ref:`Finder Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/flow/index.rst: -------------------------------------------------------------------------------- 1 | Flow Module Overview 2 | ==================== 3 | 4 | The Flow module allows you to programmatically control Flow's timer sessions from within your Python scripts. 5 | 6 | Flow Examples 7 | ############# 8 | 9 | Example 1 - Run session only while a specific app is open 10 | ********************************************************* 11 | 12 | One possible use case of the Flow module is automatically starting Flow sessions based on the context of the system. For example, you might want to start a Flow session when you first open Notes, then only allow the session counter to continue as long as you're using the Notes app (in other words, if you get distracted and wander over to YouTube, the session pauses until you get back on track). The code below shows how to use PyXA to implement this use case. 13 | 14 | .. code-block:: python 15 | 16 | import PyXA 17 | from time import sleep 18 | 19 | flow = PyXA.Application("Flow") 20 | in_session = False 21 | 22 | while True: 23 | apps = PyXA.running_applications().localized_name() 24 | if "Notes" in apps and not in_session: 25 | flow.start() 26 | in_session = True 27 | elif "Notes" not in apps: 28 | flow.stop() 29 | in_session = False 30 | sleep(1) 31 | 32 | Based on this code, you can create scripts for managing context-based Flow sessions informed by many metrics--or as few as you need. 33 | 34 | Flow Resources 35 | ############## 36 | - `Flow API/Scripts `_ -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/fontbook/index.rst: -------------------------------------------------------------------------------- 1 | Font Book Module Overview 2 | ========================= 3 | 4 | For all classes, methods, and inherited members of the Font Book module, see the :ref:`Font Book Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/hammerspoon/index.rst: -------------------------------------------------------------------------------- 1 | Hammerspoon Module Overview 2 | =========================== 3 | 4 | The Hammerspoon module provides the ability to run Hammerspoon Lua scripts from within PyXA. To do this, simply call the :func:`~PyXA.apps.Hammerspoon.XAHammerspoonApplication.execute_lua_code` method and supply a Lua script as an argument. You can then utilize the value returned by the Lua script in your Python program. 5 | 6 | .. code-block:: Python 7 | 8 | import PyXA 9 | app = PyXA.Application("hammerspoon") 10 | result = app.execute_lua_code(""" 11 | app = hs.appfinder.appFromName("Finder") 12 | window = app:mainWindow() 13 | return window:title() 14 | """) 15 | print(result) 16 | # Recents 17 | 18 | For all classes, methods, and inherited members of the Hammerspoon module, see the :ref:`Hammerspoon Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/index.rst: -------------------------------------------------------------------------------- 1 | Application Module Overviews 2 | ============================ 3 | 4 | First-Party Application Modules Overviews 5 | ----------------------------------------- 6 | 7 | .. toctree:: 8 | :maxdepth: 1 9 | 10 | automator/index 11 | calculator/index 12 | calendar/index 13 | console/index 14 | contacts/index 15 | dictionary/index 16 | finder/index 17 | fontbook/index 18 | imageevents/index 19 | keynote/index 20 | mail/index 21 | maps/index 22 | messages/index 23 | music/index 24 | notes/index 25 | numbers/index 26 | pages/index 27 | photos/index 28 | preview/index 29 | quicktimeplayer/index 30 | reminders/index 31 | safari/index 32 | shortcuts/index 33 | stocks/index 34 | systemevents/index 35 | systempreferences/index 36 | terminal/index 37 | textedit/index 38 | tv/index 39 | 40 | Third-Party Application Module Overviews 41 | ---------------------------------------- 42 | 43 | .. toctree:: 44 | :maxdepth: 1 45 | 46 | bike/index 47 | cardhop/index 48 | chromium/index 49 | drafts/index 50 | fantastical/index 51 | flow/index 52 | hammerspoon/index 53 | iterm/index 54 | omnioutliner/index 55 | spotify/index 56 | vlc/index 57 | rstudio/index -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/iterm/index.rst: -------------------------------------------------------------------------------- 1 | iTerm Module Overview 2 | ===================== -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/keynote/index.rst: -------------------------------------------------------------------------------- 1 | Keynote Module Overview 2 | ======================= 3 | 4 | For all classes, methods, and inherited members of the Keynote module, see the :ref:`Keynote Module Reference` and :ref:`iWork Base Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/mail/index.rst: -------------------------------------------------------------------------------- 1 | Mail Module Overview 2 | ==================== 3 | 4 | For all classes, methods, and inherited members of the Mail module, see the :ref:`Mail Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/maps/index.rst: -------------------------------------------------------------------------------- 1 | Maps Module Overview 2 | ==================== 3 | 4 | For all classes, methods, and inherited members of the Maps module, see the :ref:`Maps Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/messages/index.rst: -------------------------------------------------------------------------------- 1 | Messages Module Overview 2 | ======================== 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | PyXA supports all of the OSA features for Messages.app. 9 | 10 | Messages Tutorials 11 | ################## 12 | There are currently no tutorials for the Messages module. 13 | 14 | Messages Resources 15 | ################## 16 | - `Messages User Guide - Apple Support `_ 17 | 18 | For all classes, methods, and inherited members of the Messages module, see the :ref:`Messages Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/music/index.rst: -------------------------------------------------------------------------------- 1 | Music Module Overview 2 | ===================== 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | The entirety of Music's scripting interface is available via PyXA. 9 | 10 | Music Tutorials 11 | ############### 12 | There are currently no tutorials for the Music module. 13 | 14 | Music Examples 15 | ############## 16 | The examples below provide an overview of the capabilities of the Music module. 17 | 18 | Example 1 - Playback Control 19 | **************************** 20 | 21 | .. code-block:: python 22 | :linenos: 23 | 24 | import PyXA 25 | app = PyXA.Application("Music") 26 | 27 | # Play/Pause/Stop/Resume 28 | app.play() 29 | app.pause() 30 | app.stop() 31 | app.playpause() 32 | 33 | # Fast-forward/Rewind 34 | app.fast_forward() 35 | app.rewind() 36 | app.resume() 37 | 38 | Example 2 - Add Current Track to a Playlist 39 | ******************************************* 40 | 41 | .. code-block:: python 42 | :linenos: 43 | 44 | import PyXA 45 | app = PyXA.Music() 46 | 47 | # Gather info about current track 48 | title = app.current_track.name 49 | artist = app.current_track.artist 50 | album = app.current_track.album 51 | 52 | # Save track to library 53 | library = app.sources().by_name("Library") 54 | app.current_track.duplicate(library) 55 | 56 | # Get the saved track object 57 | saved_track = app.tracks().filter("name", "==", title).filter("artist", "==", artist).by_album(album) 58 | 59 | # Add track to playlist 60 | playlist = app.playlists().by_name("test") 61 | saved_track.move(playlist) 62 | 63 | Example 3 - Make a Playlist of Tracks in a Given Genre 64 | ****************************************************** 65 | 66 | .. code-block:: python 67 | :linenos: 68 | 69 | import PyXA 70 | app = PyXA.Music() 71 | 72 | # Get a list of all soundtrack tracks 73 | soundtracks = app.tracks().filter("genre", "==", "Soundtrack") 74 | 75 | # Create a new playlist 76 | prototype = app.make("playlist", {"name": "Soundtracks"}) 77 | new_playlist = app.playlists().push(prototype) 78 | 79 | # Add soundtracks to the new playlist 80 | new_playlist.add_tracks(soundtracks) 81 | 82 | For all classes, methods, and inherited members of the Music module, see the :ref:`Music Module Reference` and :ref:`Media Application Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/numbers/index.rst: -------------------------------------------------------------------------------- 1 | Numbers Module Overview 2 | ======================= 3 | 4 | For all classes, methods, and inherited members of the Numbers module, see the :ref:`Numbers Module Reference` and :ref:`iWork Base Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/omnioutliner/index.rst: -------------------------------------------------------------------------------- 1 | OmniOutliner Module Overview 2 | ============================ 3 | 4 | For all classes, methods, and inherited members of the OmniOutliner module, see the :ref:`OmniOutliner Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/pages/index.rst: -------------------------------------------------------------------------------- 1 | Pages Module Overview 2 | ===================== 3 | 4 | For all classes, methods, and inherited members of the Pages module, see the :ref:`Pages Module Reference` and :ref:`iWork Base Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/photos/index.rst: -------------------------------------------------------------------------------- 1 | Photos Module Overview 2 | ====================== 3 | 4 | For all classes, methods, and inherited members of the Photos module, see the :ref:`Photos Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/preview/index.rst: -------------------------------------------------------------------------------- 1 | Preview Module Overview 2 | ======================= 3 | 4 | For all classes, methods, and inherited members of the Preview module, see the :ref:`Preview Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/quicktimeplayer/index.rst: -------------------------------------------------------------------------------- 1 | QuickTime Module Overview 2 | ========================= 3 | 4 | For all classes, methods, and inherited members of the QuickTime module, see the :ref:`QuickTime Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/reminders/index.rst: -------------------------------------------------------------------------------- 1 | Reminders Module Overview 2 | ========================= 3 | 4 | For all classes, methods, and inherited members of the Reminders module, see the :ref:`Reminders Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/rstudio/index.rst: -------------------------------------------------------------------------------- 1 | RStudio Module Overview 2 | ======================= 3 | 4 | -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/safari/index.rst: -------------------------------------------------------------------------------- 1 | Safari Module Overview 2 | ====================== 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | PyXA has full nearly complete feature support for Safari, but some functionalities, such as saving a document, are currently unavailable. These will be implemented in future versions of the Safari module. 9 | 10 | 11 | Safari Tutorials 12 | ################## 13 | There are currently no tutorials for the Safari module. 14 | 15 | Safari Examples 16 | ############### 17 | The examples below provide an overview of the capabilities of the Safari module. For more in-depth examples that show output and provide more detailed explanations, refer to the previous section (:ref:`Safari Tutorials`). 18 | 19 | Example 1 - Using Safari Methods and Attributes 20 | *********************************************** 21 | 22 | This example provides an overview of the most common methods and attributes of the Safari module. 23 | 24 | .. code-block:: python 25 | :linenos: 26 | 27 | import PyXA 28 | 29 | # Open URL in new tab 30 | safari = PyXA.Application("Safari") 31 | 32 | # Get open windows, documents, and tabs 33 | window1 = safari.front_window() 34 | window2 = safari.windows()[1] 35 | documents = safari.documents() 36 | current_doc = safari.current_document 37 | tabs = window1.tabs() 38 | current_tab = window1.current_tab 39 | 40 | # Get properties of documents 41 | urls = documents.url() 42 | names = documents.name() 43 | html = current_doc.source() 44 | 45 | # Get properties of tabs 46 | urls = tabs.url() 47 | texts = tabs.text() 48 | name = current_tab.name() 49 | 50 | # Filter documents and tabs 51 | doc1 = documents.by_url("https://apple.com") 52 | doc2 = documents.by_name("Apple") 53 | tab1 = tabs.by_index(1) 54 | tab2 = tabs.by_visible(True) 55 | 56 | # Bulk document operations 57 | documents.add_to_reading_list() 58 | documents.email() 59 | documents.do_javascript("alert('Testing 1 2 3');") 60 | documents.search("Example") 61 | 62 | # Bulk tab operations 63 | tabs.reload() 64 | tabs.add_to_reading_list() 65 | tabs.email() 66 | tabs.do_javascript("alert('Hello!');") 67 | tabs.search("Example") 68 | tabs.move_to(window2) 69 | tabs.duplicate_to(window2) 70 | 71 | # Sub-array operations 72 | some_tabs = tabs[3:5] 73 | some_tabs.close() 74 | 75 | Safari Resources 76 | ################## 77 | - `Safari Quick Start Guide `_ 78 | 79 | For all classes, methods, and inherited members of the Safari module, see the :ref:`Safari Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/shortcuts/index.rst: -------------------------------------------------------------------------------- 1 | Shortcuts Module Overview 2 | ========================= 3 | 4 | .. contents:: Table of Contents 5 | :depth: 3 6 | :local: 7 | 8 | Most of Shortcuts.app's scripting interface is available via PyXA, however some significant features are currently limited by sandboxing constraints. PyXA is able to interact with existing shortcuts, including run them, but it is currently unable to create new shortcuts or shortcut folders. That said, it is possible to use Shortcuts links to install new shortcuts. It would be feasible to use functional, atomically constructed shortcuts (i.e. each shortcut accomplishes a single task and returns a transformed value) to construct larger sequences of actions, effectively re-instituting an ability to create shortcuts. For now, that is left as an exercise for PyXA users. Future versions of PyXA may utilize the Shortcuts URI scheme, in combination with the Intents framework, to re-implement these features in a more straightforward way. 9 | 10 | > [!NOTE] 11 | > In most cases, to work with shortcuts, you should use the 'Shortcuts Events' application as used in the examples below. This allows you to work with shortcuts without having to open the Shortcuts app. 12 | 13 | Shortcuts Tutorials 14 | ################### 15 | There are currently no tutorials for the Shortcuts module. 16 | 17 | Shortcuts Examples 18 | ################## 19 | The examples below provide an overview of the capabilities of the Shortcuts module. They do not provide any output. For more in-depth examples that show output and provide more detailed explanations, refer to the previous section (:ref:`Shortcuts Tutorials`). 20 | 21 | Example 1 - Run shortcuts and receive their return values 22 | ********************************************************* 23 | 24 | The example below activates Chromium.app, opens Apple's website in a new tab, waits for the tab to finish loading, then saves the site's resources (e.g. HTML, CSS, JavaScript, and images) to a location on the disk. Note the use of a full URL, beginning with "http", as well as a full file path, beginning with "/". Both a full URL and full file path are necessary in order for this example to operate successfully. 25 | 26 | .. code-block:: python 27 | :linenos: 28 | 29 | import PyXA 30 | app = PyXA.Application("Shortcuts Events") 31 | 32 | # Get shortcuts by name 33 | sqrt = app.shortcuts().by_name("sqrt(x)") 34 | sin = app.shortcuts().by_name("sin(x)") 35 | 36 | # Run sqrt function, get first entry in output array 37 | root = sqrt.run(81)[0] 38 | print(root) 39 | 40 | # Run sin function, get first entry in output array 41 | sin_root = sin.run(root)[0] 42 | print(sin_root) 43 | 44 | Example 2 - Combine shortcut output with Python 45 | *********************************************** 46 | 47 | This example highlights how you can intertwine PyXA, Shortcuts, and Python to carry out more complex processes. The example below uses a shortcut to obtain the source HTML of the Google homepage, then uses Python's tempfile module alongside PyXA's :func:`PyXA.Safari.XASafariApplication.open` method to display a local HTML file in the browser. 48 | 49 | .. code-block:: python 50 | :linenos: 51 | 52 | import PyXA 53 | import tempfile 54 | 55 | # Get the source of webpage, using a shortcut 56 | app = PyXA.Application("Shortcuts Events") 57 | s1 = app.shortcuts().by_name("Get HTML") 58 | source = s1.run("http://google.com")[0] 59 | 60 | # Create a temporary HTML file 61 | temp = tempfile.NamedTemporaryFile(suffix=".html") 62 | temp.write(bytes(source, "UTF-8")) 63 | 64 | # Open the HTML file 65 | PyXA.application("Safari").open(temp.name) 66 | sleep(0.5) 67 | temp.close() 68 | 69 | Shortcuts Resources 70 | ################### 71 | - `Shortcuts for macOS User Guide - Apple Support `_ 72 | 73 | For all classes, methods, and inherited members of the Shortcuts module, see the :ref:`Shortcuts Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/spotify/index.rst: -------------------------------------------------------------------------------- 1 | Spotify Module Overview 2 | ======================= 3 | 4 | -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/stocks/index.rst: -------------------------------------------------------------------------------- 1 | Stocks Module Overview 2 | ====================== 3 | 4 | For all classes, methods, and inherited members of the Stocks module, see the :ref:`Stocks Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/systemevents/index.rst: -------------------------------------------------------------------------------- 1 | System Events Module Overview 2 | ============================= 3 | 4 | The Terminal module enables control over Terminal.app from within Python, including the ability to run Terminal script and receive the execution return value. 5 | 6 | System Events Examples 7 | ###################### 8 | 9 | Example 1 - Sorting the Desktop 10 | ******************************* 11 | 12 | .. code-block:: python 13 | 14 | import PyXA 15 | app = PyXA.Application("System Events") 16 | 17 | # Set the desktop picture 18 | app.current_desktop.picture = "/Users/exampleUser/Desktop/Images/Background.png" 19 | 20 | # Toggle darkmode 21 | app.appearance_preferences.dark_mode = not app.appearance_preferences.dark_mode 22 | 23 | # # Add a login item -- This opens the Documents folder upon login 24 | new_item = app.make("login item", {"path": "/Users/exampleUser/Documents"}) 25 | app.login_items().push(new_item) 26 | 27 | # Start the current screensaver 28 | app.current_screen_saver.start() 29 | 30 | This example uses PyXA to sort files on the desktop into appropriate category folders. 31 | 32 | .. code-block:: python 33 | 34 | import PyXA 35 | app = PyXA.Application("System Events") 36 | 37 | desktop_files = app.desktop_folder.files() 38 | desktop_folders = app.desktop_folder.folders() 39 | 40 | # Create sorting bin folders 41 | images_folder = app.make("folder", {"name": "Images"}) 42 | videos_folder = app.make("folder", {"name": "Videos"}) 43 | audio_folder = app.make("folder", {"name": "Audio"}) 44 | documents_folder = app.make("folder", {"name": "Documents"}) 45 | desktop_folders.push(images_folder, videos_folder, audio_folder, documents_folder) 46 | 47 | # Sort images 48 | image_predicate = "name ENDSWITH '.png' OR name ENDSWITH '.jpg' OR name ENDSWITH '.jpeg' OR name ENDSWITH '.aiff'" 49 | image_files = desktop_files.filter(image_predicate) 50 | image_files.move_to(images_folder) 51 | 52 | # Sort videos 53 | video_predicate = "name ENDSWITH '.mov' OR name ENDSWITH '.mp4' OR name ENDSWITH '.avi' OR name ENDSWITH '.m4v'" 54 | video_files = desktop_files.filter(video_predicate) 55 | video_files.move_to(videos_folder) 56 | 57 | # Sort audio 58 | audio_predicate = "name ENDSWITH '.mp3' OR name ENDSWITH '.ogg'" 59 | audio_files = desktop_files.filter(audio_predicate) 60 | audio_files.move_to(audio_folder) 61 | 62 | # Sort remaining (documents) 63 | desktop_files.move_to(documents_folder) 64 | 65 | System Events Resources 66 | ####################### 67 | - `System Events - AppleScript: The Definitive Guide `_ 68 | 69 | For all classes, methods, and inherited members of the System Events module, see the :ref:`System Events Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/systempreferences/index.rst: -------------------------------------------------------------------------------- 1 | System Preferences Module Overview 2 | ================================== 3 | 4 | For all classes, methods, and inherited members of the System Preferences module, see the :ref:`System Preferences Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/terminal/index.rst: -------------------------------------------------------------------------------- 1 | Terminal Module Overview 2 | ======================== 3 | 4 | The Terminal module enables control over Terminal.app from within Python, including the ability to run Terminal script and receive the execution return value. 5 | 6 | Terminal Examples 7 | ################# 8 | 9 | Example 1 - Using Terminal methods and attributes 10 | ************************************************* 11 | 12 | This example showcases many of the methods and attributes available for use in the Terminal module. 13 | 14 | .. code-block:: python 15 | 16 | import PyXA 17 | app = PyXA.Application("Terminal") 18 | 19 | # Get information about the current tab 20 | tab = app.current_tab 21 | print(tab.custom_title) 22 | print(tab.processes) 23 | print(tab.number_of_rows, tab.number_of_columns) 24 | # Terminal 25 | # ( 26 | # login, 27 | # "-zsh", 28 | # python 29 | # ) 30 | # 24 80 31 | 32 | # Set tab properties 33 | tab.custom_title = "Testing 1 2 3" 34 | tab.number_of_rows = 50 35 | tab.title_displays_custom_title = True 36 | 37 | # Run scripts and utilize return values 38 | value = app.do_script("ls", return_result=True) 39 | print("Number of items:", len(value["stdout"].split("\n")) - 1) 40 | 41 | value = app.do_script("ping www.google.com -c 1", return_result=True) 42 | if "1 packets received" in value["stdout"]: 43 | print("Online!") 44 | else: 45 | print("Offline!") 46 | 47 | # Modify settings 48 | settings = tab.current_settings 49 | settings.background_color = PyXA.XAColor(255, 0, 0) 50 | settings.font_size = 10 51 | 52 | Terminal Resources 53 | ################## 54 | - `Terminal User Guide - Apple Support `_ 55 | 56 | For all classes, methods, and inherited members of the Terminal module, see the :ref:`Terminal Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/tv/index.rst: -------------------------------------------------------------------------------- 1 | TV Module Overview 2 | ================== 3 | 4 | For all classes, methods, and inherited members of the TV module, see the :ref:`TV Module Reference` and :ref:`Media Application Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/apps/vlc/index.rst: -------------------------------------------------------------------------------- 1 | VLC Module Overview 2 | =================== 3 | 4 | VLC Examples 5 | ############ 6 | 7 | Example 1 - Working with VLC methods and attributes 8 | *************************************************** 9 | 10 | This example provides a general overview of the functionalities supported by the VLC module. Additional examples can be found in the code reference for this module. 11 | 12 | .. code-block:: python 13 | :linenos: 14 | 15 | import PyXA 16 | app = PyXA.Application("VLC") 17 | 18 | # Open or get (without opening) files and URLs 19 | app.open("/Users/exampleUser/ExampleFile.m4v") 20 | app.open("https://upload.wikimedia.org/wikipedia/commons/transcoded/e/e1/Black_Hole_Merger_Simulation_GW170104.webm/Black_Hole_Merger_Simulation_GW170104.webm.1080p.vp9.webm") 21 | app.get_url("https://upload.wikimedia.org/wikipedia/commons/transcoded/e/e1/Black_Hole_Merger_Simulation_GW170104.webm/Black_Hole_Merger_Simulation_GW170104.webm.1080p.vp9.webm") 22 | 23 | # Control playback 24 | app.stop() 25 | app.play() 26 | app.previous() 27 | app.next() 28 | app.step_forward() 29 | app.step_backward() 30 | app.current_time = app.current_time + 5 31 | 32 | # Control volume 33 | app.volume_up() 34 | app.volume_down() 35 | app.mute() 36 | app.audio_volume = 256 37 | 38 | # Control the VLC window 39 | app.fullscreen() 40 | app.fullscreen_mode = False 41 | app.front_window.bounds = (0, 0, 500, 500) 42 | app.zoomed = True 43 | 44 | # Utilize information about playback 45 | file = app.path_of_current_item 46 | file.show_in_finder() 47 | 48 | if app.audio_volume > 256: 49 | app.audio_volume = 256 50 | 51 | 52 | VLC Resources 53 | ############# 54 | - `TextEdit User Guide - Apple Support `_ 55 | 56 | For all classes, methods, and inherited members of the VLC module, see the :ref:`VLC Module Reference`. -------------------------------------------------------------------------------- /sphinx/source/tutorial/appscript.rst: -------------------------------------------------------------------------------- 1 | Using Appscript to Work With Unsupported Applications 2 | ===================================================== 3 | 4 | PyXA aims to be have fine-grained documentation on a per-application basis, which greatly limits its ability to interact with applications outside of the ones explicitly mentioned in this documentation. To make up for this limitation, PyXA falls back to `appscript `_ when no PyXA definition exists for an application. This allows you to interact with any AppleScript-compatible application, through appscript, while having access to the additional features of PyXA for an ever-expanding set of applications. 5 | 6 | Converting Between Appscript and PyXA Types 7 | ------------------------------------------- 8 | 9 | -------------------------------------------------------------------------------- /sphinx/source/tutorial/devices.rst: -------------------------------------------------------------------------------- 1 | Device Interaction 2 | ================== 3 | 4 | PyXA offers a _Devices_ addition that provides a simple interface to your device's hardware such as its camera, microphone, and screen. 5 | 6 | Device Classes 7 | -------------- 8 | 9 | The following device classes are available: 10 | 11 | - :class:`~PyXA.Additions.Devices.XACamera` - for capturing photos and videos 12 | - :class:`~PyXA.Additions.Devices.XAMicrophone` - for recording audio 13 | - :class:`~PyXA.Additions.Devices.XAScreen` - for capturing screenshots and screen recordings 14 | 15 | An overview of each class is provided below. 16 | 17 | Camera 18 | --------------------------- 19 | 20 | The :class:`~PyXA.Additions.Devices.XACamera` class provides two methods: one to capture photos (:func:`~PyXA.Additions.Devices.XACamera.capture`) and another to record videos (:func:`~PyXA.Additions.Devices.XACamera.record`). Both methods return an instance of the corresponding PyXA class—either :class:`~PyXA.XABase.XAImage` or :class:`~PyXA.XABase.XAVideo`—that can be used alongside other areas of PyXA. 21 | 22 | For example, to capture a photo and save it to the desktop, you could use the following code: 23 | 24 | .. code-block:: python 25 | 26 | import PyXA 27 | import os 28 | 29 | cam = PyXA.XACamera() 30 | img = cam.capture() 31 | homedir = os.path.expanduser("~") 32 | img.save(f"{homedir}/Desktop/test.png") 33 | 34 | You can combine this with other PyXA features to create powerful automations. For example, you could use the :class:`~PyXA.Additions.Speech.XASpeech` class to speak any text detected in the image: 35 | 36 | .. code-block:: python 37 | 38 | import PyXA 39 | 40 | cam = PyXA.XACamera() 41 | img = cam.capture() 42 | img_text = img.extract_text() 43 | 44 | PyXA.XASpeech(img_text).speak() 45 | 46 | Microphone 47 | ---------- 48 | 49 | The :class:`~PyXA.Additions.Devices.XAMicrophone` class provides a single method, :func:`~PyXA.Additions.Devices.XAMicrophone.record`, that records audio from the device's microphone and returns an instance of the :class:`~PyXA.XABase.XAAudio` class. 50 | 51 | For example, to record 5 seconds of audio and play it back, you could use the following code: 52 | 53 | .. code-block:: python 54 | 55 | import PyXA 56 | import os 57 | 58 | mic = PyXA.XAMicrophone() 59 | homedir = os.path.expanduser("~") 60 | recording = mic.record(f"{homedir}/Downloads/test.wav", 5) 61 | recording.play() 62 | 63 | Screen 64 | ------ 65 | 66 | PyXA's :class:`~PyXA.Additions.Devices.XAScreen` class provides methods for capturing screenshots and screen recordings. Each method returns either a :class:`~PyXA.XABase.XAImage` or :class:`~PyXA.XABase.XAVideo` object. The available methods are: 67 | 68 | - :func:`~PyXA.Additions.Devices.XAScreen.capture` - captures a screenshot 69 | - :func:`~PyXA.Additions.Devices.XAScreen.capture_rect` - captures a screenshot of a specific area of the screen 70 | - :func:`~PyXA.Additions.Devices.XAScreen.capture_window` - captures a screenshot of a specific window 71 | - :func:`~PyXA.Additions.Devices.XAScreen.record` - records a screen recording -------------------------------------------------------------------------------- /sphinx/source/tutorial/tips_tricks.rst: -------------------------------------------------------------------------------- 1 | Tips and Tricks 2 | =============== 3 | 4 | 1. Know when and when not to chain commands. You might be tempted to use a batch operation such as `PyXA.Application("Notes").notes().plaintext()` to obtain the text of each note, but then you will _only_ have the unicode text, not references to the note objects. If you're going to need the note objects, you should store a reference to the list of notes in a separate variable, then run batch operations via that reference. On the other hand, you should make use of PyXA's command chaining where reasonable to improve the overall clarity of your code and maintain its syntactic similarity to JXA. 5 | 6 | 2. Use :class:`~PyXA.XABase.XAList` and its child classes whenever dealing with lists of PyXA objects. Bulk methods on :class:`~PyXA.XABase.XAList` objects are often significantly faster (sometimes over 56x faster) than using non-bulk methods and regular iteration over a list. -------------------------------------------------------------------------------- /sphinx/source/tutorial/ui_scripting.rst: -------------------------------------------------------------------------------- 1 | UI Scripting 2 | ============ 3 | 4 | PyXA supports using System Events to script the UI of otherwise non-scriptable applications. In fact, PyXA uses this functionality to provide scripting features for several applications, including Maps and Stocks. 5 | 6 | The process for scripting an application's UI starts with getting its window object, from which you can call various methods, such as :func:`~PyXA.apps.SystemEvents.XASystemEventsWindow.groups` and :func:`~PyXA.apps.SystemEvents.XASystemEventsWindow.toolbars`, to obtain lists of UI elements. These methods provide access to all UI element types listed in the System Events scripting dictionary. Lists of elements obtained in this fashion are instances of :class:`~PyXA.apps.SystemEvents.XASystemEventsUIElementList`, a subclass of :class:`~PyXA.XABase.XAList`. You can use bulk methods on a list of UI elements to retrieve information about the list's contents. For example, you can call :func:`~PyXA.apps.SystemEvents.XASystemEventsUIElementList.object_description` to get the accessibility or role description of all elements in the list. List filtration methods such as :func:`~PyXA.apps.SystemEvents.XASystemEventsUIElementList.by_object_description` allow you to efficiently access elements with particular property values. 7 | 8 | Retrieving an element from an :class:`~PyXA.apps.SystemEvents.XASystemEventsUIElementList` object will return a instance of :class:`~PyXA.apps.SystemEvents.XASystemEventsUIElement`. You can then obtain the properties of the UI element via the object's attributes. Upon doing so, the reference to the AppleScript scripting object will be evaluated, causing one or more Apple Events to be sent. This behavior makes it possible to quickly traverse the UI hierarchy without sending unnecessary Apple Events and causing slowdowns. 9 | 10 | Once you have a reference to a specific UI element, you can call methods such as :func:`~PyXA.apps.SystemEvents.XASystemEventsButton.click` to carry out actions on that element, or you can obtain a list of actions by calling :func:`~PyXA.apps.SystemEvents.XASystemEventsUIElement.actions`. Call :func:`~PyXA.apps.SystemEvents.XASystemEventsAction.perform` to perform a particular action. 11 | 12 | An example of this process is provided below. 13 | 14 | .. code-block:: python 15 | 16 | from time import sleep 17 | import PyXA 18 | 19 | podcasts = PyXA.Application("Podcasts") 20 | 21 | # Get the list of podcast playback controls 22 | playback_buttons = podcasts.front_window.groups()[0].groups()[0].groups()[0].groups()[0].groups()[0].groups()[0].groups()[1].groups()[0].groups()[0].groups()[2].groups()[0].groups()[0].buttons() 23 | 24 | # Get buttons by property value 25 | rewind_button = playback_buttons.by_object_description("Rewind") 26 | play_button = playback_buttons.by_object_description("Play") 27 | skip_button = playback_buttons.by_object_description("Skip") 28 | 29 | # Click the buttons 30 | play_button.click() 31 | sleep(1) 32 | skip_button.click() 33 | sleep(1) 34 | rewind_button.click() 35 | 36 | In this example, we obtain a list of buttons by traversing the UI hierarchy of the Podcasts app to reach the specific group containing the rewind, play, and skip forward buttons at the top of the window. You can use macOS's built-in `Accessibility Inspector` application to help identify the element hierarchy. Once we have the list of buttons, we obtain references to each individual button according to its object description. We then call the :func:`~PyXA.apps.SystemEvents.XASystemEventsButton.click` method of each button to observe its effect. -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SKaplanOfficial/PyXA/10a596798f5c86cc0948f3bad397cd57d383eb61/tests/__init__.py -------------------------------------------------------------------------------- /tests/test_base_scriptable.py: -------------------------------------------------------------------------------- 1 | import AppKit 2 | import PyXA 3 | import time 4 | import unittest 5 | 6 | class TestMessages(unittest.TestCase): 7 | def setUp(self): 8 | self.app = PyXA.Application("Messages") 9 | self.app.activate() 10 | 11 | start = time.time() 12 | success = False 13 | while time.time() - start < 5: 14 | if self.app.frontmost: 15 | success = True 16 | break 17 | time.sleep(0.1) 18 | 19 | if not success: 20 | raise TimeoutError 21 | 22 | def test_scriptable_application_type(self): 23 | self.assertIsInstance(self.app, PyXA.XABaseScriptable.XASBApplication) 24 | 25 | def test_scriptable_types(self): 26 | self.assertIsInstance(self.app.windows(), PyXA.XABaseScriptable.XASBWindowList) 27 | 28 | self.assertIsInstance(self.app.windows()[0], PyXA.apps.Messages.XAMessagesWindow) 29 | 30 | def test_scriptable_windowlist_attributes_and_methods(self): 31 | windows = self.app.windows() 32 | win = windows[0] 33 | 34 | # XASBWindowList methods & content 35 | self.assertIsInstance(windows.name(), list) 36 | self.assertIsInstance(windows.id(), list) 37 | self.assertIsInstance(windows.index(), list) 38 | self.assertIsInstance(windows.bounds(), list) 39 | self.assertIsInstance(windows.closeable(), list) 40 | self.assertIsInstance(windows.resizable(), list) 41 | self.assertIsInstance(windows.visible(), list) 42 | self.assertIsInstance(windows.zoomable(), list) 43 | self.assertIsInstance(windows.zoomed(), list) 44 | 45 | self.assertEqual(windows.by_name(windows.name()[0]), win) 46 | self.assertEqual(windows.by_id(windows.id()[0]), win) 47 | self.assertEqual(windows.by_index(windows.index()[0]), win) 48 | self.assertEqual(windows.by_bounds(windows.bounds()[0]), win) 49 | self.assertEqual(windows.by_closeable(windows.closeable()[0]), win) 50 | self.assertEqual(windows.by_resizable(windows.resizable()[0]), win) 51 | self.assertEqual(windows.by_visible(windows.visible()[0]), win) 52 | self.assertEqual(windows.by_zoomable(windows.zoomable()[0]), win) 53 | self.assertEqual(windows.by_zoomed(windows.zoomed()[0]), win) 54 | 55 | windows.collapse() 56 | self.assertEqual(all([win.miniaturized for win in windows]), True) 57 | 58 | windows.uncollapse() 59 | self.assertEqual(any([win.miniaturized for win in windows]), False) 60 | 61 | def test_scriptable_window_attributes_and_methods(self): 62 | windows = self.app.windows() 63 | win = windows[0] 64 | win2 = self.app.front_window 65 | win3 = windows.by_name(win.name) 66 | 67 | self.assertEqual(win, win2) 68 | self.assertEqual(win, win3) 69 | 70 | self.assertIsInstance(win.name, str) 71 | self.assertIsInstance(win.id, int) 72 | self.assertIsInstance(win.index, int) 73 | self.assertIsInstance(win.bounds, tuple) 74 | self.assertIsInstance(win.closeable, bool) 75 | self.assertIsInstance(win.resizable, bool) 76 | self.assertIsInstance(win.visible, bool) 77 | self.assertIsInstance(win.zoomable, bool) 78 | self.assertIsInstance(win.zoomed, bool) 79 | 80 | win.collapse() 81 | if hasattr(win, "miniaturized"): 82 | self.assertEqual(win.miniaturized, True) 83 | elif hasattr(win, "minimized"): 84 | self.assertEqual(win.minimized, True) 85 | elif hasattr(win, "collapsed"): 86 | self.assertEqual(win.collapsed, True) 87 | 88 | win.uncollapse() 89 | if hasattr(win, "miniaturized"): 90 | self.assertEqual(win.miniaturized, False) 91 | elif hasattr(win, "minimized"): 92 | self.assertEqual(win.minimized, False) 93 | elif hasattr(win, "collapsed"): 94 | self.assertEqual(win.collapsed, False) 95 | 96 | win.bounds = (100, 100, 1024, 768) 97 | self.assertEqual(win.bounds, (100, 100, 1024, 768)) 98 | 99 | win.visible = False 100 | self.assertEqual(win.visible, False) 101 | 102 | win.visible = True 103 | self.assertEqual(win.visible, True) 104 | 105 | win.zoomed = True 106 | self.assertEqual(win.zoomed, True) 107 | 108 | win.zoomed = False 109 | self.assertEqual(win.zoomed, False) 110 | 111 | if __name__ == '__main__': 112 | unittest.main() -------------------------------------------------------------------------------- /tests/test_contacts.py: -------------------------------------------------------------------------------- 1 | import PyXA 2 | import unittest 3 | import AppKit 4 | import ScriptingBridge 5 | 6 | class TestContacts(unittest.TestCase): 7 | def setUp(self): 8 | self.app = PyXA.Application("Contacts") 9 | 10 | def test_iwork_application_type(self): 11 | self.assertIsInstance(self.app, PyXA.XABaseScriptable.XASBApplication) 12 | self.assertIsInstance(self.app, PyXA.apps.Contacts.XAContactsApplication) 13 | 14 | def test_contacts_attrs_and_methods(self): 15 | self.assertIsInstance(self.app.name, str) 16 | self.assertIsInstance(self.app.frontmost, bool) 17 | self.assertIsInstance(self.app.version, str) 18 | self.assertIsInstance(self.app.my_card, PyXA.apps.Contacts.XAContactsPerson) 19 | self.assertIsInstance(self.app.unsaved, bool) 20 | self.assertIsInstance(self.app.selection, PyXA.apps.Contacts.XAContactsPersonList) 21 | self.assertIsInstance(self.app.default_country_code, str) 22 | 23 | self.assertIsInstance(self.app.my_card.xa_elem, ScriptingBridge.SBObject) 24 | self.assertIsInstance(self.app.selection.xa_elem, AppKit.NSArray) 25 | 26 | def test_contacts_lists(self): 27 | groups = self.app.groups() 28 | people = self.app.people() 29 | 30 | self.assertIsInstance(groups, PyXA.apps.Contacts.XAContactsGroupList) 31 | self.assertIsInstance(groups[0], PyXA.apps.Contacts.XAContactsGroup) 32 | self.assertIsInstance(groups[0].xa_elem, ScriptingBridge.SBObject) 33 | 34 | self.assertIsInstance(groups.name(), list) 35 | if len(groups.name()) > 0: 36 | self.assertIsInstance(groups.name()[0], str) 37 | 38 | self.assertIsInstance(people, PyXA.apps.Contacts.XAContactsPersonList) 39 | self.assertIsInstance(people[0], PyXA.apps.Contacts.XAContactsPerson) 40 | self.assertIsInstance(people[0].xa_elem, ScriptingBridge.SBObject) 41 | 42 | self.assertIsInstance(people.name(), list) 43 | if len(people.name()) > 0: 44 | self.assertIsInstance(people.name()[0], str) 45 | 46 | 47 | 48 | if __name__ == '__main__': 49 | unittest.main() -------------------------------------------------------------------------------- /tests/test_database_events.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, timedelta 2 | from time import sleep 3 | 4 | import AppKit 5 | import PyXA 6 | import unittest 7 | import ScriptingBridge 8 | 9 | from PyXA.XABase import XAColor, XALocation, XAURL, XAPath 10 | from PyXA.XABaseScriptable import XASBApplication 11 | from PyXA.apps.DatabaseEvents import XADatabaseEventsApplication, XADatabaseEventsDatabaseList, XADatabaseEventsDatabase, XADatabaseEventsRecordList, XADatabaseEventsRecord, XADatabaseEventsFieldList, XADatabaseEventsField 12 | 13 | class TestDatabaseEvents(unittest.TestCase): 14 | def setUp(self): 15 | self.app = PyXA.Application("Database Events") 16 | 17 | def test_database_events_application(self): 18 | self.assertIsInstance(self.app, XASBApplication) 19 | self.assertIsInstance(self.app, XADatabaseEventsApplication) 20 | 21 | self.assertIsInstance(self.app.quit_delay, int) 22 | self.assertIsInstance(self.app.databases(), XADatabaseEventsDatabaseList) 23 | self.assertIsInstance(self.app.databases()[0], XADatabaseEventsDatabase) 24 | self.assertIsInstance(self.app.databases()[0].xa_elem, ScriptingBridge.SBObject) 25 | 26 | def test_database_events_database(self): 27 | dbs = self.app.databases() 28 | 29 | self.assertIsInstance(dbs.location(), list) 30 | self.assertIsInstance(dbs.location()[0], XAPath) 31 | 32 | self.assertIsInstance(dbs.name(), list) 33 | self.assertIsInstance(dbs.name()[0], str) 34 | 35 | self.assertIsInstance(dbs.store_type(), list) 36 | self.assertIsInstance(dbs.store_type()[0], XADatabaseEventsApplication.StoreType) 37 | 38 | def test_database_events_record(self): 39 | pass 40 | 41 | def test_database_events_field(self): 42 | pass -------------------------------------------------------------------------------- /tests/test_iwork.py: -------------------------------------------------------------------------------- 1 | import PyXA 2 | import unittest 3 | 4 | class TestiWork(unittest.TestCase): 5 | def setUp(self): 6 | self.pages = PyXA.Application("Pages") 7 | self.numbers = PyXA.Application("Numbers") 8 | self.keynote = PyXA.Application("Keynote") 9 | 10 | def test_iwork_application_type(self): 11 | self.assertIsInstance(self.pages, PyXA.XABaseScriptable.XASBApplication) 12 | self.assertIsInstance(self.numbers, PyXA.XABaseScriptable.XASBApplication) 13 | self.assertIsInstance(self.keynote, PyXA.XABaseScriptable.XASBApplication) 14 | 15 | self.assertIsInstance(self.pages, PyXA.apps.iWorkApplicationBase.XAiWorkApplication) 16 | self.assertIsInstance(self.numbers, PyXA.apps.iWorkApplicationBase.XAiWorkApplication) 17 | self.assertIsInstance(self.keynote, PyXA.apps.iWorkApplicationBase.XAiWorkApplication) 18 | 19 | self.assertIsInstance(self.pages, PyXA.apps.Pages.XAPagesApplication) 20 | self.assertIsInstance(self.numbers, PyXA.apps.Numbers.XANumbersApplication) 21 | self.assertIsInstance(self.keynote, PyXA.apps.Keynote.XAKeynoteApplication) 22 | 23 | def test_iwork_new_document(self): 24 | d1 = self.pages.new_document() 25 | d2 = self.numbers.new_document() 26 | d3 = self.keynote.new_document() 27 | 28 | self.assertIsInstance(d1, PyXA.apps.iWorkApplicationBase.XAiWorkDocument) 29 | self.assertIsInstance(d2, PyXA.apps.iWorkApplicationBase.XAiWorkDocument) 30 | self.assertIsInstance(d3, PyXA.apps.iWorkApplicationBase.XAiWorkDocument) 31 | 32 | self.assertIsInstance(d1, PyXA.apps.Pages.XAPagesDocument) 33 | self.assertIsInstance(d2, PyXA.apps.Numbers.XANumbersDocument) 34 | self.assertIsInstance(d3, PyXA.apps.Keynote.XAKeynoteDocument) 35 | 36 | def test_iwork_containers(self): 37 | d1 = self.pages.documents()[0] 38 | d2 = self.numbers.documents()[0] 39 | d3 = self.keynote.documents()[0] 40 | 41 | pages = d1.pages() 42 | sheets = d2.sheets() 43 | slides = d3.slides() 44 | 45 | self.assertIsInstance(pages, PyXA.apps.iWorkApplicationBase.XAiWorkContainerList) 46 | self.assertIsInstance(sheets, PyXA.apps.iWorkApplicationBase.XAiWorkContainerList) 47 | self.assertIsInstance(slides, PyXA.apps.iWorkApplicationBase.XAiWorkContainerList) 48 | 49 | self.assertIsInstance(pages, PyXA.apps.Pages.XAPagesContainerList) 50 | self.assertIsInstance(sheets, PyXA.apps.Numbers.XANumbersContainerList) 51 | self.assertIsInstance(slides, PyXA.apps.Keynote.XAKeynoteContainerList) 52 | 53 | self.assertIsInstance(pages, PyXA.apps.Pages.XAPagesPageList) 54 | self.assertIsInstance(sheets, PyXA.apps.Numbers.XANumbersSheetList) 55 | self.assertIsInstance(slides, PyXA.apps.Keynote.XAKeynoteSlideList) 56 | 57 | i1 = pages[0] 58 | i2 = sheets[0] 59 | i3 = slides[0] 60 | 61 | self.assertIsInstance(i1, PyXA.apps.iWorkApplicationBase.XAiWorkContainer) 62 | self.assertIsInstance(i2, PyXA.apps.iWorkApplicationBase.XAiWorkContainer) 63 | self.assertIsInstance(i3, PyXA.apps.iWorkApplicationBase.XAiWorkContainer) 64 | 65 | self.assertIsInstance(i1, PyXA.apps.Pages.XAPagesContainer) 66 | self.assertIsInstance(i2, PyXA.apps.Numbers.XANumbersContainer) 67 | self.assertIsInstance(i3, PyXA.apps.Keynote.XAKeynoteContainer) 68 | 69 | self.assertIsInstance(i1, PyXA.apps.Pages.XAPagesPage) 70 | self.assertIsInstance(i2, PyXA.apps.Numbers.XANumbersSheet) 71 | self.assertIsInstance(i3, PyXA.apps.Keynote.XAKeynoteSlide) 72 | 73 | if __name__ == '__main__': 74 | unittest.main() -------------------------------------------------------------------------------- /tests/test_shortcuts.py: -------------------------------------------------------------------------------- 1 | import PyXA 2 | import time 3 | import unittest 4 | 5 | class TestShortcuts(unittest.TestCase): 6 | def setUp(self): 7 | self.app = PyXA.Application("Shortcuts") 8 | self.folders = self.app.folders() 9 | self.shortcuts = self.app.shortcuts() 10 | 11 | def test_shortcuts_application_type(self): 12 | self.assertIsInstance(self.app, PyXA.apps.Shortcuts.XAShortcutsApplication) 13 | self.assertIsInstance(self.app, PyXA.XABaseScriptable.XASBApplication) 14 | 15 | def test_folders_type(self): 16 | self.assertIsInstance(self.folders, PyXA.XABase.XAList) 17 | 18 | def test_shortcuts_type(self): 19 | self.assertIsInstance(self.shortcuts, PyXA.XABase.XAList) 20 | 21 | def test_folder_type(self): 22 | self.assertIsInstance(self.folders[0], PyXA.apps.Shortcuts.XAShortcutFolder) 23 | 24 | def test_shortcut_type(self): 25 | self.assertIsInstance(self.shortcuts[0], PyXA.apps.Shortcuts.XAShortcut) 26 | 27 | def test_folders_name(self): 28 | names = self.folders.name() 29 | self.assertIsInstance(names, list) 30 | self.assertIsInstance(names[0], str) 31 | 32 | def test_shortcuts_name(self): 33 | names = self.shortcuts.name() 34 | self.assertIsInstance(names, list) 35 | self.assertIsInstance(names[0], str) 36 | 37 | def test_folder_eq(self): 38 | folder1 = self.app.folders({"name": "PyXA Test Folder"})[0] 39 | folder2 = self.folders.by_name("PyXA Test Folder") 40 | self.assertEqual(folder1, folder2) 41 | 42 | def test_shortcut_eq(self): 43 | shortcut1 = self.app.shortcuts({"name": "PyXA Test"})[0] 44 | shortcut2 = self.shortcuts.by_name("PyXA Test") 45 | self.assertEqual(shortcut1, shortcut2) 46 | 47 | def test_folder_shortcuts(self): 48 | all_shortcuts = self.folders.shortcuts() 49 | shortcut = all_shortcuts[0][0] 50 | self.assertIsInstance(shortcut, PyXA.apps.Shortcuts.XAShortcut) 51 | 52 | def test_shortcuts_quit(self): 53 | self.app.quit() 54 | time.sleep(0.5) 55 | running_apps = PyXA.running_applications() 56 | self.assertNotIn(self.app, running_apps) 57 | 58 | if __name__ == '__main__': 59 | unittest.main() -------------------------------------------------------------------------------- /tests/test_textedit.py: -------------------------------------------------------------------------------- 1 | import PyXA 2 | import time 3 | import unittest 4 | 5 | class TestTextEdit(unittest.TestCase): 6 | def setUp(self): 7 | self.app = PyXA.Application("TextEdit") 8 | 9 | def test_textedit_application_type(self): 10 | self.assertIsInstance(self.app, PyXA.apps.TextEdit.XATextEditApplication) 11 | self.assertIsInstance(self.app, PyXA.XABaseScriptable.XASBApplication) 12 | 13 | def test_textedit_app_attributes(self): 14 | self.app.activate() 15 | timeout = 0 16 | while timeout < 10: 17 | time.sleep(0.1) 18 | if self.app.frontmost: 19 | break 20 | timeout += 1 21 | if timeout == 10: 22 | self.fail("TextEdit did not become active") 23 | 24 | self.assertEqual(self.app.name, "TextEdit") 25 | self.assertEqual(self.app.version, "1.18") 26 | 27 | def test_textedit_make_documents(self): 28 | new_doc = self.app.make("document", {"text": "This is a test!"}) 29 | doc1 = self.app.documents().push(new_doc) 30 | doc2 = self.app.new_document("Example.txt", "Hello, world!") 31 | 32 | self.assertIsInstance(doc1, PyXA.apps.TextEdit.XATextEditDocument) 33 | self.assertIsInstance(doc2, PyXA.apps.TextEdit.XATextEditDocument) 34 | self.assertIsInstance(doc1.text, PyXA.XABase.XAText) 35 | self.assertIsInstance(doc2.text, PyXA.XABase.XAText) 36 | self.assertEqual(str(doc1.text), "This is a test!") 37 | self.assertEqual(str(doc2.text), "Hello, world!") 38 | 39 | doc1.append("1 2 3") 40 | doc2.prepend("a b c") 41 | 42 | self.assertEqual(str(doc1.text), "This is a test!1 2 3") 43 | self.assertEqual(str(doc2.text), "a b cHello, world!") 44 | 45 | def test_textedit_window_methods(self): 46 | self.app.front_window.miniaturized = True 47 | time.sleep(1) 48 | self.assertEqual(self.app.front_window.miniaturized, True) 49 | 50 | time.sleep(0.5) 51 | self.app.front_window.miniaturized = False 52 | self.assertEqual(self.app.front_window.miniaturized, False) 53 | print("here") 54 | 55 | def test_textedit_list_types(self): 56 | self.assertIsInstance(self.app.windows(), PyXA.XABaseScriptable.XASBWindowList) 57 | self.assertIsInstance(self.app.documents(), PyXA.apps.TextEdit.XATextEditDocumentList) 58 | 59 | def test_textedit_object_types(self): 60 | self.assertIsInstance(self.app.windows()[0], PyXA.apps.TextEdit.XATextEditWindow) 61 | self.assertIsInstance(self.app.documents()[0], PyXA.apps.TextEdit.XATextEditDocument) 62 | self.assertIsInstance(self.app.front_window, PyXA.apps.TextEdit.XATextEditWindow) 63 | self.assertIsInstance(self.app.front_window.document, PyXA.apps.TextEdit.XATextEditDocument) 64 | 65 | def test_textedit_doc_list_attribute_methods(self): 66 | docs = self.app.documents() 67 | l1 = docs.properties() 68 | l2 = docs.path() 69 | l3 = docs.name() 70 | l4 = docs.modified() 71 | 72 | self.assertEqual(all(isinstance(x, list) for x in [l1, l2, l3, l4]), True) 73 | 74 | d1 = docs.by_properties(l1[0]) 75 | d2 = docs.by_path(l2[0]) 76 | d3 = docs.by_name(l3[0]) 77 | d4 = docs.by_modified(l4[0]) 78 | 79 | self.assertEqual(all(isinstance(x, PyXA.apps.TextEdit.XATextEditDocument) for x in [d1, d2, d3, d4]), True) 80 | 81 | self.assertIsInstance(l1[0], dict) 82 | self.assertIsInstance(l2[0], PyXA.XABase.XAPath) 83 | self.assertIsInstance(l3[0], str) 84 | self.assertIsInstance(l4[0], bool) 85 | 86 | if __name__ == '__main__': 87 | unittest.main() --------------------------------------------------------------------------------