Skip to content

Commit

Permalink
Update documentation for 0.0.8
Browse files Browse the repository at this point in the history
SKaplanOfficial committed Aug 19, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 5d60761 commit 107bc13
Showing 149 changed files with 14,439 additions and 7,400 deletions.
41 changes: 40 additions & 1 deletion PyXA/XABase.py
Original file line number Diff line number Diff line change
@@ -409,7 +409,7 @@ def __init__(self, properties: dict, object_class: type = None, filter: Union[di
self.xa_elem = XAPredicate().from_dict(filter).evaluate(self.xa_elem)

def by_property(self, property: str, value: Any) -> XAObject:
"""Retrieves the element whose property value matches the given value, if one exists.
"""Retrieves the first element whose property value matches the given value, if one exists.
:param property: The property to match
:type property: str
@@ -418,6 +418,14 @@ def by_property(self, property: str, value: Any) -> XAObject:
:return: The matching element, if one is found
:rtype: XAObject
:Example:
>>> import PyXA
>>> app = PyXA.application("Photos")
>>> photo = app.media_items().by_property("id", "CB24FE9F-E9DC-4A5C-A0B0-CC779B1CEDCE/L0/001")
>>> print(photo)
<<class 'PyXA.apps.PhotosApp.XAPhotosMediaItem'>id=CB24FE9F-E9DC-4A5C-A0B0-CC779B1CEDCE/L0/001>
.. versionadded:: 0.0.6
"""
predicate = XAPredicate()
@@ -436,6 +444,9 @@ def containing(self, property: str, value: str) -> XAObject:
:return: The matching element, if one is found
:rtype: XAObject
.. deprecated:: 0.0.8
Use :func:`filter` instead.
.. versionadded:: 0.0.6
"""
predicate = XAPredicate()
@@ -460,6 +471,34 @@ def filter(self, filter: str, comparison_operation: Union[str, None] = None, val
:return: The filter XAList object
:rtype: XAList
:Example 1: Get the last file sent by you (via this machine) in Messages.app
>>> import PyXA
>>> app = PyXA.application("Messages")
>>> last_file_transfer = app.file_transfers().filter("direction", "==", app.MessageDirection.OUTGOING)[-1]
>>> print(last_file_transfer)
<<class 'PyXA.apps.Messages.XAMessagesFileTransfer'>Test.jpg>
:Example 2: Get the list of favorite photos/videos from Photos.app
>>> import PyXA
>>> app = PyXA.application("Photos")
>>> favorites = app.media_items().filter("favorite", "==", True)
>>> print(favorites)
<<class 'PyXA.apps.PhotosApp.XAPhotosMediaItemList'>['CB24FE9F-E9DC-4A5C-A0B0-CC779B1CEDCE/L0/001', 'EFEB7F37-8373-4972-8E43-21612F597185/L0/001', ...]>
.. note::
For properties that appear to be boolean but fail to return expected filter results, try using the corresponding 0 or 1 value instead.
:Example 3: Provide a custom format string
>>> import PyXA
>>> app = PyXA.application("Photos")
>>> photo = app.media_items().filter("id == 'CB24FE9F-E9DC-4A5C-A0B0-CC779B1CEDCE/L0/001'")[0]
>>> print(photo)
<<class 'PyXA.apps.PhotosApp.XAPhotosMediaItem'>id=CB24FE9F-E9DC-4A5C-A0B0-CC779B1CEDCE/L0/001>
.. versionadded:: 0.0.8
"""
if comparison_operation is not None and value1 is not None:
2 changes: 1 addition & 1 deletion PyXA/apps/PhotosApp.py
Original file line number Diff line number Diff line change
@@ -372,7 +372,7 @@ def favorite(self) -> List[bool]:
.. versionadded:: 0.0.6
"""
return list(self.xa_elem.arrayByApplyingSelector_("properties"))
return list(self.xa_elem.arrayByApplyingSelector_("favorite"))

def date(self) -> List[datetime]:
"""Gets the date of each media item in the list.
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
<p align="center"><img src="https://raw.githubusercontent.com/SKaplanOfficial/PyXA/main/docs/_static/assets/PyXALogoTransparent.png" alt="The dark logo for PyXA" height="250px"></p>

# Python for Automation
Python for Automation, or PyXA for short, is a wrapper around Apple's Scripting Bridge framework that enables AppleScript- and JXA-like control over macOS applications from within Python. PyXA delivers intuitive application scripting by mapping existing AppleScript specifiers and commands, defined in sdef files, to per-application Python classes and associated methods. PyXA then expands on the capabilities of AppleScript by interfacing with low-level Objective-C frameworks.
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.

PyXA was created with the goals of:
1. Simplifying the way AppleScript tasks can be accomplished via Python
2. Disambiguating the capabilities of application scripting on macOS by providing easy-to-follow documentation throughout the entire project
3. Introducing new features to macOS application scripting by creating simple, JXA-like methods for complex Objective-C procedures
1. Simplifying the way automation tasks can be accomplished via Python
2. Introducing new features to macOS application scripting by simplifying complex procedures into simple, declarative methods
3. Disambiguating the capabilities of application scripting on macOS by providing easy-to-follow documentation throughout the entire project

PyXA is not intended to replace AppleScript; rather, it is meant to provide general convenience in accomplishing AppleScript tasks via Python. PyXA fills a gap where currently available frameworks ultimately fall short: it aims to be easy to learn. Unlike other Objc wrappers, PyXA's methods are hard-coded and documented inline, meaning that you can spend less time searching for answers and more time automating your life.
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](https://pyobjc.readthedocs.io/en/latest/) to interact with various macOS frameworks.

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](https://appscript.sourceforge.io) 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.

# Feature Overview
- Support for most AppleScript commands in built-in macOS applications (in progress)
- Scripting capabilities for several non-scriptable applications by using APIs, URI schemes, and other methods
- Support for direct operations on non-scriptable applications (e.g. `PyXA.application("Maps").front_window.collapse()`)
- Command Chaining similar to JXA (e.g. `PyXA.application("Reminders").lists()[0].reminders().title()`)
- Properties of scriptable elements accessible via object attributes (e.g. `note.name`, `tab.URL`, or `track.artist`)
- Support for UI scripting of non-scriptable applications
- Fast enumeration of scriptable objects
- Automatic translation of clipboard items to PyXA objects
- Support for compiling and executing AppleScript scripts via NSAppleScript
- Full access to and control over the system clipboard

# Some Examples
## Example 1: Open a URL in Safari and print the loaded page.
@@ -93,6 +98,16 @@ When run, the above script creates a note in the Notes application similar to th

![A note in the Notes app showing a summary of reminders and events for the day](https://raw.githubusercontent.com/SKaplanOfficial/PyXA/main/docs/_static/assets/Example3_Notes.png)

## Example 4: Copy your last sent file in iMessage to the clipboard
Lastly, PyXA has several convenient features for working with lists, interacting with the clipboard, and more soon to come. The example below highlights the simplicity of filtering lists of scriptable objects and setting the content of the clipboard. The filter method of PyXA's :class:`XABase.XAList` class enables straightforward construction of predicates to efficiently filter lists by. The content property of the :class:`XABase.XAClipboard` class can be set to both literal values and PyXA objects, allowing for concise scripts like the one below.

```python
import PyXA
app = PyXA.application("Messages")
last_file_transfer = app.file_transfers().filter("direction", "==", app.MessageDirection.OUTGOING)[-1]
PyXA.XAClipboard().content = last_file_transfer
```

# Installation
To install the latest version of PyXA on macOS, use the following pip command:
```
2 changes: 1 addition & 1 deletion docs/.buildinfo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 919f25b3b70a97f849cd814ca029f9e5
config: af95dfa14f640587e81b8083e20038a0
tags: 645f666f9bcd5a90fca523b33c5a78b7
3 changes: 1 addition & 2 deletions docs/_modules/PyXA/PyXA.html
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PyXA.PyXA &mdash; PyXA 0.0.7 documentation</title>
<title>PyXA.PyXA &mdash; PyXA 0.0.8 documentation</title>
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/graphviz.css" type="text/css" />
@@ -39,7 +39,6 @@
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../about/index.html">Project Overview</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tutorial/index.html">Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tutorial/index.html#application-modules">Application Modules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference/index.html">Code Documentation and Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../bugs.html">Bugs</a></li>
</ul>
Loading

0 comments on commit 107bc13

Please sign in to comment.