From aa1142492ac7d2deeae681b7b7027479af0c89ac Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Mon, 12 Mar 2018 23:13:39 +0200 Subject: Pyobjc rocks --- README.md | 1 + machammer/process.py | 72 +++++++++++++++++++++++++++++++++++++++------------- tests.py | 30 +++++++++++++++++++++- 3 files changed, 85 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index f95c1b1..9c85c6c 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ### System Requirements - OS X (tested with 10.11-10.13) +- Python 2.7 OR 3.6 (or later) ### Example diff --git a/machammer/process.py b/machammer/process.py index 252cb2a..c5db83d 100755 --- a/machammer/process.py +++ b/machammer/process.py @@ -1,5 +1,11 @@ # -*- coding: utf-8 -*- +try: + import CoreFoundation + from AppKit import NSWorkspace, NSUserDefaults, NSRunningApplication +except ImportError: + raise Exception('Sorry, but it looks like your Python installation lacks PyObjc support') + from . import defaults from .functions import call, tell_app @@ -39,34 +45,66 @@ def open(name): class Prefs(object): + def __init__(self, domain): - self._prefs = defaults.as_dict(domain) - - def __getattr__(self, k): - try: - return self._prefs[k] - except AttributeError: - return super(Prefs, self).getattr(k) - - def __setattr__(self, k, v): - print('Setting attribute: %s' % k) - self._prefs[k] = v + self.domain = domain + args = [self.domain, CoreFoundation.kCFPreferencesCurrentUser, CoreFoundation.kCFPreferencesAnyHost] + self.keys = CoreFoundation.CFPreferencesCopyKeyList(*args) + self.prefs = CoreFoundation.CFPreferencesCopyMultiple(self.keys, *args) + + if not self.prefs: + raise ValueError('Invalid domain: %s' % self.domain) + + def get(self, key): + if key not in self.keys: + raise Exception('Invalid key: %s' % key) + + return self.prefs.get(key) + + def set(self, key, value): + CoreFoundation.CFPreferencesSetAppValue(key, value, self.domain) class App(object): - def __init__(self, domain): + + ws = NSWorkspace.sharedWorkspace() + + def __init__(self, domain=None, name=None): + if not (domain or name): + raise Exception('Name or domain must be provided') + self.domain = domain - self.prefs = Prefs(domain) + self.prefs = Prefs(self.domain) + self.apps = NSRunningApplication.runningApplicationsWithBundleIdentifier_(self.domain) + + if self.apps: + self.app = self.apps[0] + name = name or self.app.localizedName() + + self.name = name + + def is_running(self): + running = self.ws.runningApplications() + return self.domain in [a.bundleIdentifier() for a in running] + + def tell(self): + raise NotImplementedError('Scripting support not implemented') + + def activate(self): + raise NotImplementedError() def launch(self): - pass + return self.ws.launchApplication_(self.name) + def is_active(self): + return self.app.isActive() + def quit(self): - pass + return self.app.terminate() def is_installed(self): - return False + raise NotImplementedError() def version(self): - return False + raise NotImplementedError() diff --git a/tests.py b/tests.py index c85ac26..c3f75e9 100755 --- a/tests.py +++ b/tests.py @@ -127,7 +127,7 @@ class NetworkTestCase(TestCase): self.assertTrue(network.is_wired(True)) -class AppsTestCase(TestCase): +class VersionsTestCase(TestCase): def setUp(self): self.profile = system_profiler.SystemProfile('Applications') @@ -150,6 +150,34 @@ class AppsTestCase(TestCase): self.assertLess(functions.os_version(), 10.14) +class AppsTestCase(TestCase): + + def setUp(self): + self.key = 'NSNavLastRootDirectory' + self.app = process.App('com.apple.Terminal') + + def test_get_prefs(self): + path = os.path.expanduser(self.app.prefs.get(self.key)) + self.assertTrue(os.path.exists(path)) + + def test_set_prefs(self): + self.app.prefs.set(self.key, '/tmp') + + def test_is_running(self): + self.assertTrue(self.app.is_running()) + + def test_launch(self): + self.assertTrue(self.app.launch()) + + def test_quit(self): + app = process.App('com.apple.Stickies', 'Stickies') + app.launch() + #app.quit() + + def test_is_active(self): + self.assertTrue(self.app.is_active()) + + class InstallerTestCase(TestCase): def setUp(self): self.pkg = os.getenv('MH_PKG') -- cgit v1.2.3