def set_launch_at_startup(self, launch): defaults = NSUserDefaults.standardUserDefaults() lwdomain = defaults.persistentDomainForName_('loginwindow') lwdomain = Conversion.pythonCollectionFromPropertyList(lwdomain) if lwdomain is None: lwdomain = dict() if 'AutoLaunchedApplicationDictionary' not in lwdomain: lwdomain['AutoLaunchedApplicationDictionary'] = list() launchedApps = lwdomain['AutoLaunchedApplicationDictionary'] ourPath = NSBundle.mainBundle().bundlePath() ourEntry = None for entry in launchedApps: if entry.get('Path') == ourPath: ourEntry = entry break if launch and ourEntry is None: launchInfo = dict(Path=ourPath, Hide=NO) launchedApps.append(launchInfo) elif ourEntry is not None: launchedApps.remove(ourEntry) lwdomain = Conversion.propertyListFromPythonCollection(lwdomain) defaults.setPersistentDomain_forName_(lwdomain, 'loginwindow') defaults.synchronize()
def test_deserializePropertyList(self): in_val = {"a": 42} for fmt in ("xml", "binary"): data = Conversion.serializePropertyList(in_val, fmt) out_val = Conversion.deserializePropertyList(data) self.assertEqual(in_val, out_val) self.assertRaises(ValueError, Conversion.deserializePropertyList, data[:-2])
def test_fromPythonDecimal(self): d = decimal.Decimal("42.5") self.assertIsInstance(d, decimal.Decimal) v = Conversion.fromPythonDecimal(d) self.assertIsInstance(v, Cocoa.NSDecimalNumber) self.assertEqual(str(v), "42.5")
def get_xquartz_open_windows(): """ Get info on all open XQuartz windows. Requires pyobjc-framework-Quartz (install with pip) :return: a list of open windows as python dictionaries """ try: from Quartz import CGWindowListCopyWindowInfo, kCGWindowListOptionAll, kCGNullWindowID from PyObjCTools import Conversion except ImportError: return None # need to use kCGWindowListOptionAll to include windows that are not currently on screen (e.g. minimized) windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID) # then filter for XQuartz main windows open_windows = [ window for window in windows if window['kCGWindowOwnerName'] == "XQuartz" and window['kCGWindowLayer'] == 0 and 'kCGWindowName' in window.keys() and window['kCGWindowName'] not in ['', 'X11 Application Menu', 'X11 Preferences'] ] # convert from NSDictionary to python dictionary open_windows = Conversion.pythonCollectionFromPropertyList(open_windows) return open_windows
def convert_date_for_py(self, date): if date is not None: date = Conversion.pythonCollectionFromPropertyList(date) pst = pytz.timezone("US/Pacific") date = RemoteSource.convert_date_for_py( self, pst.localize(date)) # normalizes utc return date
def _get_macos_pref(self, key): """Get a specific macOS preference key.""" value = CFPreferencesCopyAppValue(key, BUNDLE_ID) # Casting NSArrays and NSDictionaries to native Python types. # This a workaround for 10.6, where PyObjC doesn't seem to # support as many common operations such as list concatenation # between Python and ObjC objects. if isinstance(value, NSArray) or isinstance(value, NSDictionary): value = Conversion.pythonCollectionFromPropertyList(value) return value
def test_serializePropertyList(self): self.assertRaises(ValueError, Conversion.serializePropertyList, {}, "invalid") v = Conversion.serializePropertyList({"a": 42}, "xml") self.assertTrue(bytes(v).startswith(b"<?xml")) v = Conversion.serializePropertyList({"a": 42}, "binary") self.assertTrue(bytes(v).startswith(b"bplist")) self.assertRaises(ValueError, Conversion.serializePropertyList, {"a": 42}, "ascii") self.assertRaises( ValueError, Conversion.serializePropertyList, Cocoa.NSObject.alloc().init(), "xml", )
def _convert_pyobjc_objects(pref): ''' Types get returned as ObjectiveC classes from PyObjC and salt has a hard time writing those out, so this function will convert NSDictionary and NSArray object to normal list and dictionary python objects. ''' if isinstance(pref, Foundation.NSDate): log.debug('mac_prefs._convert_pyobjc_objects - ' 'converting "{}" NSDate to string...'.format(pref)) return str(pref) return Conversion.pythonCollectionFromPropertyList(pref)
def read(path): ''' Read the entire contents of the property list at the specified path path An absolute path to a property list (.plist) file, including the extension .. code-block:: bash salt '*' plist.read <path> ''' return Conversion.pythonCollectionFromPropertyList(_read_plist(path))
def test_deserializePropertyList(self): in_val = {"a": 42} for fmt in ("xml", "binary"): data = Conversion.serializePropertyList(in_val, fmt) out_val = Conversion.deserializePropertyList(data) self.assertEqual(in_val, out_val) bytes_data = bytes(data) out_val = Conversion.deserializePropertyList(bytes_data) self.assertEqual(in_val, out_val) if fmt == "xml": str_data = bytes_data.decode("utf-8") out_val = Conversion.deserializePropertyList(str_data) self.assertEqual(in_val, out_val) self.assertRaises(ValueError, Conversion.deserializePropertyList, data[:-2])
def test_propertyListFromPythonCollection(self): for value, result_type in ( ({ "a": 42 }, Cocoa.NSDictionary), ([42], Cocoa.NSArray), ((42, ), Cocoa.NSArray), ({42}, Cocoa.NSSet), (frozenset({42}), Cocoa.NSSet), (datetime.datetime.now(), Cocoa.NSDate), (datetime.date.today(), Cocoa.NSDate), ): with self.subTest(value): v = Conversion.propertyListFromPythonCollection(value) self.assertIsInstance(v, result_type) self.assertEqual(v, value) with self.subTest("decimal"): v = Conversion.propertyListFromPythonCollection(decimal.Decimal(1)) self.assertIsInstance(v, Cocoa.NSDecimalNumber) with self.subTest("invalid dict"): with self.assertRaises(TypeError): Conversion.propertyListFromPythonCollection({42: 43}) with self.subTest("unknown type"): with self.assertRaises(TypeError): Conversion.propertyListFromPythonCollection(dir) with self.subTest("conversion helper"): def helper(v): return str(v) v = Conversion.propertyListFromPythonCollection(dir, helper) self.assertEqual(v, str(dir)) with self.subTest("nested conversion"): value = [{"a": 42}, {"b": [1]}, {()}] v = Conversion.propertyListFromPythonCollection(value) self.assertIsInstance(v[0], Cocoa.NSDictionary) self.assertIsInstance(v[1], Cocoa.NSDictionary) self.assertIsInstance(v[1]["b"], Cocoa.NSArray) self.assertIsInstance(v[2], Cocoa.NSSet) self.assertIsInstance(next(iter(v[2])), Cocoa.NSArray)
def add_task(self, task): '''Add a new task to the remote''' print "Adding new task" properties = NSDictionary.dictionaryWithObjectsAndKeys_( task.name, 'name', Conversion.propertyListFromPythonCollection(task.lastModifiedDate), 'modificationDate', 'Pending', 'tagNames', task.notes, 'notes') # Conversion.propertyListFromPythonCollection(task.dueDate), 'dueDate', if task.dueDate is not None and type(task.dueDate) != str: destination_list = self.get_list("Upcoming") date_string = task.dueDate.strftime("%Y-%m-%d %H:%M:%S") print date_string date = NSDate.dateWithString_(date_string + " +0000") properties = NSDictionary.dictionaryWithObjectsAndKeys_( task.name, 'name', Conversion.propertyListFromPythonCollection( task.lastModifiedDate), 'modificationDate', date, 'dueDate', 'Pending', 'tagNames', task.notes, 'notes') else: destination_list = self.get_list(self.status_to_names.get( "Inbox")) #todo send proper state enum todo = self._app.classForScriptingClass_( 'to do').alloc().initWithProperties_(properties) destination_list.toDos().addObject_(todo) for destination_list in self.list_sources.values(): todo = self.get_pending_task(destination_list) if todo: break return todo.id(), todo
def get_xquartz_open_windows(): """ Get info on all open XQuartz windows. Requires pyobjc-framework-Quartz (install with pip) :return: a list of open windows as python dictionaries """ # pyobjc-framework-Quartz can segfault if the wrong version is installed logger = logging.getLogger(__name__) p = subprocess.Popen([sys.executable, "-c", "import Quartz"]) p.communicate() if p.returncode == -signal.SIGSEGV: logger.warning( "Import of pyobjc-framework-Quartz failed due to a segmentation fault. " "The installed version is incompatible with your system.") return None try: from Quartz import ( CGWindowListCopyWindowInfo, kCGWindowListExcludeDesktopElements, kCGNullWindowID, ) from PyObjCTools import Conversion except ImportError: # pragma: no cover logger.warning( "Import of pyobjc-framework-Quartz failed. Try installing with pip." ) return None # need to use kCGWindowListExcludeDesktopElements to include windows # that are not currently on screen (e.g. minimized). # kCGWindowListExcludeDesktopElements | kCGWindowListOptionOnScreenOnly # will exclude minimized windows. Use KEEP_XQUARTZ if this is an issue. windows = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID) # then filter for XQuartz main windows open_windows = [ window for window in windows if window["kCGWindowOwnerName"] == "XQuartz" and window["kCGWindowLayer"] == 0 and window["kCGWindowBounds"]["X"] != 0 and window["kCGWindowBounds"]["Y"] != 0 ] # convert from NSDictionary to python dictionary open_windows = Conversion.pythonCollectionFromPropertyList(open_windows) return open_windows
def read_keys(path, keys): ''' Read values of keys described by a dict. Each dict entry is traversed until it has no child dict. path An absolute path to a property list (.plist) file, including the extension keys A dict describing a key or nested keys, with any leaf values used to look up the corresponding plist value. ''' dataObject = _read_plist(path) collector = {} _objects_for_dict(dataObject, keys, collector) return Conversion.pythonCollectionFromPropertyList(collector)
def _parse_json_or_plist_file(self, file_path): """Parse the file. Start with plist, then JSON.""" try: data = FoundationPlist.readPlist(file_path) self.type = "plist" self.file_path = file_path return Conversion.pythonCollectionFromPropertyList(data) except Exception: pass try: with open(file_path, "r") as f: data = json.load(f) self.type = "json" self.file_path = file_path return data except Exception: pass return {}
def get_preferences(platform): """Return a dictonary of the preferences from the current profile key. If no profile is set the plugin will use the 'default' profile key. Multiple profiles to be set in the 'com.clburlison.munki.s3Repo' preference domain. Swithing between the profiles can be done by changing the S3REPO_PROFILE environment variable. """ # If this is running on a non-mac platform cheat and use environment vars if platform == 'non-mac': if os.environ.get('bucket_name') is None: print("Environment variable 'bucket_name' is not set!") sys.exit(1) if os.environ.get('AWS_REGION') is None: print("Environment variable 'AWS_REGION' is not set!") sys.exit(1) prefs = { 'bucket': os.environ.get('bucket_name'), 'region': os.environ.get('AWS_REGION'), } return prefs profile = os.environ.get('S3REPO_PROFILE') or 'default' if profile is not 'default': print("DEBUG: Currently using the '{}' profile".format(profile)) pref = CFPreferencesCopyAppValue(profile, BUNDLE) if pref is None: sys.stderr.write("ERROR: s3Repo plugin is not properly configured. \n" "Please follow the setup guide: " "https://github.com/clburlison/" "Munki-s3Repo-Plugin#setup \n") exit(1) # Remove the AWS_PROFILE env variable. The s3Repo Plugin is overriding # all of these variables in the bot3.session and this can causes # issues if the profile is not properly set. try: del os.environ['AWS_PROFILE'] except (KeyError): pass # Return a python dictonary of our preferences return Conversion.pythonCollectionFromPropertyList(pref)
def save(data): data = data.copy() try: for k, v in data.iteritems(): if v is None: data[k] = "" elif k == prefs.MOVIES_DIRECTORY.key: if isinstance(v, str): data[k] = filename_type_to_os_filename(v) plist = Conversion.propertyListFromPythonCollection(data) except: print "WARNING!! Error while converting the settings dictionary to a property list:" print data raise else: domain = bundle.getBundleIdentifier() defaults = NSUserDefaults.standardUserDefaults() defaults.setPersistentDomain_forName_(plist, domain) defaults.synchronize()
def load(): domain = bundle.getBundleIdentifier() plist = NSUserDefaults.standardUserDefaults().persistentDomainForName_(domain) try: pydict = Conversion.pythonCollectionFromPropertyList(plist) except: print "WARNING!! Error while converting the preference property list to python dictionary:" print plist # Sanitize the dictionary we just got, some value might be of type which can # cause massive problems when being pickled. if pydict is not None: for k, v in pydict.iteritems(): if type(v) is objc._pythonify.OC_PythonFloat: pydict[k] = float(v) elif type(v) is objc._pythonify.OC_PythonInt: pydict[k] = int(v) elif type(v) is objc._pythonify.OC_PythonLong: pydict[k] = long(v) elif k == prefs.MOVIES_DIRECTORY.key: pydict[k] = os_filename_to_filename_type(v) return pydict
def load(): domain = bundle.getBundleIdentifier() plist = NSUserDefaults.standardUserDefaults().persistentDomainForName_( domain) try: pydict = Conversion.pythonCollectionFromPropertyList(plist) except: print "WARNING!! Error while converting the preference property list to python dictionary:" print plist # Sanitize the dictionary we just got, some value might be of type which can # cause massive problems when being pickled. if pydict is not None: for k, v in pydict.iteritems(): if type(v) is objc._pythonify.OC_PythonFloat: pydict[k] = float(v) elif type(v) is objc._pythonify.OC_PythonInt: pydict[k] = int(v) elif type(v) is objc._pythonify.OC_PythonLong: pydict[k] = long(v) elif k == prefs.MOVIES_DIRECTORY.key: pydict[k] = os_filename_to_filename_type(v) return pydict
def test_toPythonDecimal(self): v = Cocoa.NSDecimalNumber.decimalNumberWithString_(u"42.5") d = Conversion.toPythonDecimal(v) self.assertIsInstance(d, decimal.Decimal) self.assertEqual(str(d), "42.5")
def myNewParser(result): tempResult = NSString.alloc().initWithString_(unicode(result)) print tempResult resultDict = tempResult.nsstring().propertyListFromStringsFileFormat() return Conversion.pythonCollectionFromPropertyList(resultDict)
def run_module(): module_args = dict( state=dict( type="str", choices=("present", "absent"), required=False, default="present", ), host=dict(type="str", required=False, default=CF.kCFPreferencesAnyHost), user=dict(type="str", required=False, default=CF.kCFPreferencesCurrentUser), domain=dict(type="str", required=False, default="NSGlobalDomain"), key=dict(type="raw", required=True), # container_types is necessary if you want to be able to # create entirely missing keys (past the top-level key). container_types=dict(type="raw", required=False, default=None), value=dict(type="raw", required=False, default=None), value_type=dict(type="str", required=False, default=None), merge_value=dict(type="bool", required=False, default=False), ) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) result = dict(changed=False) params = module.params.copy() if params["host"].strip() == "currentHost": params["host"] = CF.kCFPreferencesCurrentHost elif not params["host"].strip() or params["host"] == "anyHost": params["host"] = CF.kCFPreferencesAnyHost if not params["user"].strip() or params["user"] == "currentUser": params["user"] = CF.kCFPreferencesCurrentUser if params["domain"] == "NSGlobalDomain": params["domain"] = CF.kCFPreferencesAnyApplication def fail(msg): module.fail_json(msg=msg, **result) key_list = params["key"] if not key_list: fail("key cannot be empty") elif type(key_list) != list: key_list = [key_list] elif len(key_list) < 1: fail("key cannot be an empty list") # The first container type is always a dict (AFAIK that's how # preferences work), so you don't need to include that. num_container_types_needed = len(key_list) - 1 container_types = params["container_types"] if container_types is None: container_types = [None] * num_container_types_needed else: if not isinstance(container_types, list): container_types = [container_types] CONTAINER_TYPE_STR_TO_CLS = {"list": list, "dict": dict, "array": list} # Ansible doesn't like it if you put things that can't be serialized # into JSON into the data structures that it owns, and which it will # eventually try to put into the response. Make a copy. container_types = container_types[:] for idx, container_type in enumerate(container_types): try: container_types[idx] = CONTAINER_TYPE_STR_TO_CLS[ container_type] except KeyError: fail(f"Unknown container type {container_type}") if len(container_types) == (num_container_types_needed + 1): # Allow user to tell us that the first container is a # dict, which it always is in preferences, AFAIK. (See # also my comment above where I introduce # num_container_types_needed.) if container_types[0] != dict: fail( f"If you want to pass {num_container_types_needed + 1}" f" value(s) in container_types (rather than" f" {num_container_types_needed} value(s), which is/are" f' all that are required), the first element must be "dict"' ) del container_types[0] elif len(container_types) != num_container_types_needed: fail(f"container_types must have {num_container_types_needed}" " element(s)") # Copying these into the result to ease debugging. Note that # these may be different than some of the info Ansible prints/puts # into the result for you, since it'll be filling in the module's # parameters, but the below gives you a bit more information about # how this module *parsed* your args. for params_key in ("host", "user", "domain"): result[params_key] = params[params_key] result["key_list"] = key_list new_value = params["value"] if new_value is None: fail("Cannot handle new value of None") value_type = params["value_type"] or None if value_type is not None: try: value_type = PREF_VALUE_TYPES[value_type] except KeyError: fail("Type %r invalid, must be one of: %s" % (value_type, ", ".join(PREF_VALUE_TYPES))) merge_value = params["merge_value"] if merge_value: if params["state"] == "absent": fail("Cannot use merge_value with state=absent") if not isinstance(new_value, (dict, list)): fail("merge_value can only be used with dict or list values") if params["state"] == "present": if new_value is None: fail("Must give value with state=present") if value_type: try: new_value = coerce_to_type(new_value, value_type) except ModuleFail as ex: result.update(ex.result) fail(ex.message) else: assert params["state"] == "absent" if new_value == "": new_value = None if new_value is not None: fail("Cannot provide value with state=absent") top_key = ensure_key_is_str(key_list[0]) top_value = CF.CFPreferencesCopyValue(top_key, params["domain"], params["user"], params["host"]) top_value = Conversion.pythonCollectionFromPropertyList(top_value) result["old_value"] = copy.deepcopy(top_value) # Drill down to the container we need to modify. top_container = container = {top_key: top_value} for key_idx, key in enumerate(key_list[:-1]): next_container_type = container_types[key_idx] if type(container) == dict: key = ensure_key_is_str(key) if key not in container or container[key] is None: if next_container_type: container[key] = next_container_type() else: fail(f"No container at {key_list[key_idx:]!r}") elif type(container) == list: key = int(key) if key == len(container): container.append(None) elif key > len(container): fail(f"Index {key} is longer" f" than the list at key(s)) {key_list[:key_idx]}") elif next_container_type and container[key] is None: container.append(next_container_type()) else: raise Exception("Should never get here") container = container[key] if next_container_type and type(container) != next_container_type: fail(f"Expected container type {next_container_type.__name__}" f" (key_idx={key_idx}) at {key_list[: key_idx + 1]!r}" f" but found type {type(container).__name__} instead") if key_idx == 0 and container is not top_value: top_value = container # Do the modification on the leaf container. changed = False last_key = key_list[-1] if type(container) == dict: last_key = ensure_key_is_str(last_key) elif type(container) == list: last_key = int(key) if params["state"] == "absent": if type(container) == dict: if last_key in container: del container[last_key] changed = True elif type(container) == list: if last_key < len(container): del container[last_key] changed = True else: assert params["state"] == "present", repr(params["state"]) if type(container) == dict: old_value = container.get(last_key) elif type(container) == list: last_key = int(last_key) if last_key < len(container): old_value = container[last_key] elif last_key == len(container): assert new_value is not None old_value = None container.append(old_value) else: fail(f"Key index {last_key} is longer" " than the list at {key_list}") if old_value is None: container[last_key] = new_value changed = True elif merge_value: if type(old_value) != type(new_value): module.fail_json(msg="Cannot merge {} and {}".format( type(old_value).__name__, type(new_value).__name__)) elif type(old_value) == list: for elem in new_value: if elem not in old_value: old_value.append(elem) changed = True elif type(old_value) == dict: changed = merge_dicts(new_value, old_value) else: raise Exception("Should never get here") elif old_value != new_value: container[last_key] = new_value changed = True # Note that setting a preference to None (NULL) is the same as # deleting the preference, so getting None here just means we # deleted the preference entirely (state=absent). new_value = top_container.get(top_key) result["new_value"] = new_value if changed and not module.check_mode: CF.CFPreferencesSetValue( top_key, new_value, params["domain"], params["user"], params["host"], ) CF.CFPreferencesSynchronize(params["domain"], params["user"], params["host"]) result["changed"] = True # in the event of a successful module execution, you will want to # simple AnsibleModule.exit_json(), passing the key/value results module.exit_json(**result)
def test_pythonCollectionFromPropertyList(self): with self.subTest("dict"): value = Cocoa.NSDictionary.dictionaryWithDictionary_({"a": 42}) self.assertIsInstance(value, Cocoa.NSDictionary) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIsInstance(v, dict) self.assertEqual(v, {"a": 42}) self.assertNotIsInstance(next(iter(v.keys())), objc.pyobjc_unicode) with self.subTest("list/tuple"): value = Cocoa.NSArray.arrayWithArray_(["a", 42]) self.assertIsInstance(value, Cocoa.NSArray) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIsInstance(v, list) self.assertEqual(v, ["a", 42]) with self.subTest("set"): value = Cocoa.NSSet.setWithSet_({"a", 42}) self.assertIsInstance(value, Cocoa.NSSet) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIsInstance(v, set) self.assertEqual(v, {"a", 42}) with self.subTest("bytes"): value = Cocoa.NSData.dataWithData_(b"hello") self.assertIsInstance(value, Cocoa.NSData) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIsInstance(v, bytes) self.assertEqual(v, b"hello") with self.subTest("str"): value = Cocoa.NSString.stringWithString_("hello").nsstring() self.assertIsInstance(value, Cocoa.NSString) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIsInstance(v, str) self.assertEqual(v, "hello") with self.subTest("float"): value = Cocoa.NSNumber.numberWithDouble_(1.5) self.assertIsInstance(value, Cocoa.NSNumber) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIsInstance(v, float) self.assertNotIsInstance(v, OC_PythonFloat) self.assertEqual(v, 1.5) with self.subTest("int"): value = Cocoa.NSNumber.numberWithLong_(42) self.assertIsInstance(value, Cocoa.NSNumber) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIsInstance(v, int) self.assertNotIsInstance(v, OC_PythonFloat) self.assertEqual(v, 42) with self.subTest("date"): value = Cocoa.NSDate.date() self.assertIsInstance(value, Cocoa.NSDate) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIsInstance(v, datetime.datetime) with self.subTest("decimal"): value = Cocoa.NSDecimalNumber.decimalNumberWithString_("42.5") self.assertIsInstance(value, Cocoa.NSDecimalNumber) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIsInstance(v, decimal.Decimal) self.assertEqual(v, decimal.Decimal("42.5")) with self.subTest("None"): value = Cocoa.NSNull.null() self.assertIsInstance(value, Cocoa.NSNull) v = Conversion.pythonCollectionFromPropertyList(value) self.assertIs(v, None) with self.subTest("unknown type"): value = Cocoa.NSObject.alloc().init() with self.assertRaises(TypeError): Conversion.pythonCollectionFromPropertyList(value) with self.subTest("conversion helper"): def helper(value): return str(value) value = Cocoa.NSObject.alloc().init() v = Conversion.pythonCollectionFromPropertyList(value, helper) self.assertEqual(v, str(value)) with self.subTest("nested"): value = Cocoa.NSMutableArray.array() value.append(Cocoa.NSArray.arrayWithArray_([1, 2])) value.append( Cocoa.NSDictionary.dictionaryWithDictionary_( {42: Cocoa.NSArray.arrayWithArray_([4, 5])})) value.append( Cocoa.NSSet.setWithSet_( {Cocoa.NSArray.arrayWithArray_([4, 5])})) v = Conversion.pythonCollectionFromPropertyList(value) # self.assertEqual(v, value) self.assertIsInstance(v, list) self.assertEqual(len(v), 3) self.assertIsInstance(v[0], list) self.assertEqual(v[0], [1, 2]) self.assertIsInstance(v[1], dict) self.assertIsInstance(v[1][42], list) self.assertEqual(v[1][42], [4, 5]) self.assertIsInstance(v[2], set) self.assertIsInstance(next(iter(v[2])), tuple) self.assertEqual(next(iter(v[2])), (4, 5))
def corefoundation_to_native(collection): native = Conversion.pythonCollectionFromPropertyList(collection) CFRelease(collection) return native
def native_to_corefoundation(native): return Conversion.propertyListFromPythonCollection(native)
def corefoundation_to_native(collection): if collection is None: # nullptr return None native = Conversion.pythonCollectionFromPropertyList(collection) CFRelease(collection) return native
def do_aperture_libraryX(d): # python version has dates like: datetime.datetime(2012, 10, 7, 8, 27, 23) d1 = Conversion.pythonCollectionFromPropertyList(d) # d1['kMDItemPath'] = "/Volumes/Taos/model/Heidi Klum.aplibrary/" # fixed library for testing, query can return different order! # d1['kMDItemPath'] = u"/Volumes/Brandywine/Aperture Library—Rialto—lib 23G.aplibrary/" s = d1['kMDItemPath'] print s print_dict(d) print_dict(d1) # # invoke lsdb on the original library file, to get the vol_id, file_id for use when recording # the rest of the info from the library file # # except mysql.connector.Error as err: # if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: # print("Username or password %r and %r?" % (config['user'], config['password'])) # elif err.errno == errorcode.ER_BAD_DB_ERROR: # print "Database %r does not exist." % config['database'] # else: # print 'err:', err # finally: # # ns_dict = NSDictionary.dictionaryWithContentsOfFile_(s+"/Info.plist") d1.update(Conversion.pythonCollectionFromPropertyList(ns_dict)) if d1['CFBundleShortVersionString'] == "2.1": print "convert version 2.1 library" sys.exit() ns_dict = NSDictionary.dictionaryWithContentsOfFile_(s+"/Aperture.aplib/DataModelVersion.plist") d1.update(Conversion.pythonCollectionFromPropertyList(ns_dict)) print d1['databaseUuid'] print_dict(d1) # { # DatabaseMinorVersion = 119; # DatabaseVersion = 110; # createDate = "2012-02-23 19:27:27 +0000"; # databaseUuid = GJVtWD2pRnGz3Qin9Gze4g; # isIPhotoLibrary = 0; # masterCount = 35; # projectCompatibleBackToVersion = 6; # projectVersion = 6; # versionCount = 35; # } # set theDBPosixPath to theApLibPosixPath & "/Database/Library.apdb" dbPath = s + "/Database/Library.apdb" print dbPath import sqlite3 print sqlite3.version # The version number of this module, as a string. This is not the version of the SQLite library. print sqlite3.version_info # The version number of this module, as a tuple of integers. This is not the version of the SQLite library. print sqlite3.sqlite_version # The version number of the run-time SQLite library, as a string. print sqlite3.sqlite_version_info # The version number of the run-time SQLite library, as a tuple of integers. conn = sqlite3.connect(dbPath) print conn cursor = conn.cursor() # overall conunts cursor.execute("SELECT count(*) FROM RKMaster") # print cursor.fetchall() # or use fetchone() print [r for r in cursor]
print('\033[{0};{1};{2}m'.format(font_style.get(style, 0), fg_colours.get(fgcolour, 37), bg_colours.get(bgcolour, 40))) # Get a NSDictionary prefs = SCPreferencesCreate(None, '', None) network = SCPreferencesPathGetValue(prefs,'/NetworkServices') # Display the NSDictionary change_termainal_font(fgcolour='white', style='bold', bgcolour='red') print('=' * 40) print('Before') print('=' * 40) print(network) # Display the python dictionary change_termainal_font(fgcolour='white', style='bold', bgcolour='green') print('=' * 40) print('After with function') print('=' * 40) new_dict = {} convert_to_dict(network, new_dict) print(json.dumps(new_dict, indent=4)) # Display the python dictionary using the conversion tool change_termainal_font(fgcolour='white', style='bold', bgcolour='blue') print('=' * 40) print('After with PyObjCTools') print('=' * 40) print(json.dumps(Conversion.pythonCollectionFromPropertyList(network), indent=4)) print('=' * 40) change_termainal_font(reset=True)
def get(descriptor): if descriptor == prefs.MOVIES_DIRECTORY: return os.path.join(MOVIES_DIRECTORY_PARENT, "Miro") elif descriptor == prefs.NON_VIDEO_DIRECTORY: return os.path.expanduser('~/Desktop') elif descriptor == prefs.GETTEXT_PATHNAME: return os.path.abspath(resources.path("../locale")) elif descriptor == prefs.RUN_AT_STARTUP: defaults = NSUserDefaults.standardUserDefaults() lwdomain = defaults.persistentDomainForName_('loginwindow') lwdomain = Conversion.pythonCollectionFromPropertyList(lwdomain) if lwdomain is None: lwdomain = dict() if 'AutoLaunchedApplicationDictionary' not in lwdomain: lwdomain['AutoLaunchedApplicationDictionary'] = list() launchedApps = lwdomain['AutoLaunchedApplicationDictionary'] ourPath = NSBundle.mainBundle().bundlePath() ourEntry = None for entry in launchedApps: if entry.get('Path') == ourPath: ourEntry = entry break return ourEntry is None elif descriptor == prefs.SUPPORT_DIRECTORY: path = os.path.join(SUPPORT_DIRECTORY_PARENT, "Miro") os.environ['APPDATA'] = path # This is for the Bittorent module try: os.makedirs(path) except: pass return path elif descriptor == prefs.ICON_CACHE_DIRECTORY: return _makeSupportFilePath('icon-cache') elif descriptor == prefs.SQLITE_PATHNAME: return _makeSupportFilePath('sqlitedb') elif descriptor == prefs.LOG_PATHNAME: return _makeSupportFilePath('dtv-log') elif descriptor == prefs.DOWNLOADER_LOG_PATHNAME: return _makeSupportFilePath('dtv-downloader-log') elif descriptor == prefs.HTTP_PROXY_ACTIVE: return _getProxyInfo('HTTPEnable', 0) == 1 elif descriptor == prefs.HTTP_PROXY_HOST: return _getProxyInfo('HTTPProxy') elif descriptor == prefs.HTTP_PROXY_PORT: return _getProxyInfo('HTTPPort', 0) elif descriptor == prefs.HTTP_PROXY_IGNORE_HOSTS: return _getProxyInfo('ExceptionsList', list()) elif descriptor == prefs.HTTP_PROXY_AUTHORIZATION_USERNAME: return _getProxyAuthInfo('username') elif descriptor == prefs.HTTP_PROXY_AUTHORIZATION_PASSWORD: return _getProxyAuthInfo('password') return descriptor.default