Esempio n. 1
0
    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()
Esempio n. 2
0
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
Esempio n. 3
0
    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()
Esempio n. 4
0
    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
Esempio n. 5
0
 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
Esempio n. 6
0
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)
Esempio n. 7
0
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))
Esempio n. 8
0
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)
Esempio n. 9
0
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
Esempio n. 10
0
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)
Esempio n. 11
0
 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 {}
Esempio n. 12
0
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)
Esempio n. 13
0
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
Esempio n. 14
0
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
Esempio n. 15
0
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
Esempio n. 16
0
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)
Esempio n. 17
0
def corefoundation_to_native(collection):
    native = Conversion.pythonCollectionFromPropertyList(collection)
    CFRelease(collection)
    return native
Esempio n. 18
0
def myNewParser(result):
    tempResult = NSString.alloc().initWithString_(unicode(result))
    print tempResult
    resultDict = tempResult.nsstring().propertyListFromStringsFileFormat()
    return Conversion.pythonCollectionFromPropertyList(resultDict)
Esempio n. 19
0
    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))
Esempio n. 20
0
def corefoundation_to_native(collection):
    if collection is None:  # nullptr
        return None
    native = Conversion.pythonCollectionFromPropertyList(collection)
    CFRelease(collection)
    return native
        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)
Esempio n. 22
0
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]