Site icon Blog ARC Optimizer

Contrôler macOS avec Python —

Contrôler macOS avec Python —


Dans cette astuce rapide, extraite de Python utileStuart étudie les moyens de contrôler le système d’exploitation Windows avec Python.

En travaillant sur un Mac, nous pouvons contrôler presque tout sur le système en utilisant pyobjc, le pont Python-Objective-C. Apple rend la plupart de son système d’exploitation contrôlable via le module AppKit, et pyobjc donne à Python l’accès à tout cela. Cela sera très utile si nous connaissons déjà la manière AppKit de faire ce que nous voulons, mais avec un peu d’exploration, il est possible de se frayer un chemin à travers les API du système d’exploitation.

Essayons un exemple. Tout d’abord, nous aurons besoin pyobjcqui peut être installé avec pip install pyobjc. Cela installera toute une liste de ponts API du système d’exploitation, permettant d’accéder à toutes sortes d’aspects de macOS. Pour l’instant, nous allons considérer AppKitqui est l’outil utilisé pour créer et contrôler des applications en cours d’exécution sur un bureau Mac.

Nous pouvons lister toutes les applications en cours d’exécution avec AppKit :

Python 3.9.6 (default, Oct 18 2022, 12:41:40) 
[Clang 14.0.0 (clang-1400.0.29.202)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from AppKit import NSWorkspace
>>> NSWorkspace.sharedWorkspace().runningApplications() 
(
    "<NSRunningApplication: 0x60000145c000 (com.apple.loginwindow - 148) LSASN:{hi=0x0;lo=0x6006}>",
    "<NSRunningApplication: 0x60000145c080 (com.apple.backgroundtaskmanagement.agent - 475) LSASN:{hi=0x0;lo=0xb00b}>",
    "<NSRunningApplication: 0x60000145c100 (com.apple.WindowManager - 474) LSASN:{hi=0x0;lo=0xc00c}>",
    "<NSRunningApplication: 0x60000145c180 (com.apple.CoreLocationAgent - 500) LSASN:{hi=0x0;lo=0xe00e}>",
    "<NSRunningApplication: 0x60000145c980 (com.apple.Terminal - 1302) LSASN:{hi=0x0;lo=0x24024}>",
    "<NSRunningApplication: 0x60000145ca00 (com.apple.Safari - 1303) LSASN:{hi=0x0;lo=0x25025}>",
    "<NSRunningApplication: 0x60000145cb80 (com.apple.Spotlight - 1310) LSASN:{hi=0x0;lo=0x28028}>",
    "<NSRunningApplication: 0x60000145cc00 (com.apple.finder - 1306) LSASN:{hi=0x0;lo=0x29029}>",
)
>>> 

Cela donnera une longue liste de NSRunningApplication objets. Chacun correspond à une application spécifique en cours d’exécution sur le bureau. Beaucoup sont des applications « invisibles » (des choses qui s’exécutent mais n’affichent pas nécessairement une fenêtre), mais d’autres sont des choses que nous pourrions considérer comme des applications réelles que nous pouvons voir, telles que Safari, Terminal, etc. NSRunningApplication est documenté sur developer.apple.com, où ses propriétés peuvent être vues. Par exemple, chaque application a un localizedName et un bundleIdentifier:

>>> for nsapp in NSWorkspace.sharedWorkspace().runningApplications():
...   print(f"{nsapp.localizedName()} -> {nsapp.bundleIdentifier()}")
... 
loginwindow -> com.apple.loginwindow
BackgroundTaskManagementAgent -> com.apple.backgroundtaskmanagement.agent
WindowManager -> com.apple.WindowManager
CoreLocationAgent -> com.apple.CoreLocationAgent
Terminal -> com.apple.Terminal
Safari -> com.apple.Safari
Spotlight -> com.apple.Spotlight
Finder -> com.apple.finder

Nous pouvons également voir qu’un NSRunningApplication l’objet a un Activer fonction, que nous pouvons appeler pour activer cette application comme si nous avions cliqué sur son icône dans le Dock. Donc, pour trouver Safari puis l’activer, nous utiliserions cette fonction d’activation. L’appel à activate nécessite une valeur pour optionscomme le décrit la documentation, et qui doit également être importé depuis AppKit :

>>> from AppKit import NSWorkspace, NSApplicationActivateIgnoringOtherApps
>>> safari_list = [x for x in NSWorkspace.sharedWorkspace().runningApplications()
    if x.bundleIdentifier() == 'com.apple.Safari']
>>> safari = safari_list[0]
>>> safari.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)

Safari est maintenant activé.

Recherche de versions Python des API macOS

Trouver le nom de quelque chose en Python qui correspond au nom Objective-C peut être un peu délicat. Comme indiqué dans le code ci-dessus, l’Objective-C activate la fonction s’appelle activateWithOptions_ en Python. Il existe un ensemble de règles pour cette traduction de nom, qui la documentation pyobjc expliquemais il peut parfois être plus rapide d’utiliser celui de Python dir() pour afficher toutes les propriétés d’un objet, puis sélectionner celle qui semble la plus plausible :

>>> print(len(dir(safari)))
452

Aie! Notre safari exemple d’un NSRunningApplication a 452 propriétés! Eh bien, celui que nous voulons s’appelle probablement quelque chose comme « activer », donc :

>>> print([x for x in dir(safari) if "activate" in x.lower()])
['activateWithOptions_', 'activateWithOptions_']

Ah ! Donc activateWithOptions_ est le nom de la fonction que nous devons appeler. De même, le nom de l’option que nous voulons transmettre à cette fonction se trouve dans AppKit lui-même :

>>> [x for x in dir(AppKit) if "ignoringotherapps" in x.lower()]
['NSApplicationActivateIgnoringOtherApps']

Ce processus peut parfois sembler un peu exploratoire, mais il est également possible de faire tout ce qu’Objective-C peut faire à partir de Python.

Cet article est extrait de Python utiledisponible sur SitePoint Premium et auprès des revendeurs de livres numériques.






Source link
Quitter la version mobile