Exemplo n.º 1
0
def add_method(cls_name, selector_name, fn, type_encoding):
    cls = ObjCClass(cls_name).ptr

    selector = sel(selector_name)

    if c.class_getInstanceMethod(cls, selector):
        error(
            'Failed to add method, class {} already provides method {}'.format(
                cls_name, selector_name))
        return

    parsed_types = parse_types(type_encoding)
    restype = parsed_types[0]
    argtypes = parsed_types[1]

    IMPTYPE = CFUNCTYPE(restype, *argtypes)
    imp = IMPTYPE(fn)
    retain_global(imp)

    did_add = c.class_addMethod(cls, selector, imp,
                                c_char_p(type_encoding.encode('utf-8')))
    if not did_add:
        error('Failed to add class method')

    return did_add
Exemplo n.º 2
0
def _flake8_annotations(path, options):
    import os

    _tmp = os.environ.get('TMPDIR', os.environ.get('TMP'))
    _output_file = os.path.join(_tmp, 'blackmamba.flake8.txt')

    annotations = []

    for o in options:
        try:
            from flake8.main import application

            if os.path.exists(_output_file):
                os.remove(_output_file)

            o = list(o)
            o.insert(0, path)
            o.extend([
                '-j',
                '0',  # Disable subprocess
                '--output-file={}'.format(_output_file)
            ])
            app = application.Application()
            app.run(o)
            del app

            annotations.extend(_parse_flake8_output(path, _output_file))
        except Exception as e:
            log.error('flake8 failed: {}'.format(str(e)))

    if os.path.exists(_output_file):
        os.remove(_output_file)

    return annotations
Exemplo n.º 3
0
def run_script(script_name, full_path=False, delay=None):
    if not full_path and script_name.startswith('/'):
        script_name = script_name[1:]

    if not script_exists(script_name, full_path):
        error('run_script: script does not exist {}'.format(script_name))
        return

    if full_path:
        docs_root = os.path.expanduser('~/Documents/')
        script_name = script_name[len(docs_root):]

    encoded_name = urllib.parse.quote_plus(script_name,
                                           safe='',
                                           encoding=None,
                                           errors=None)
    url = 'pythonista3://{}?action=run'.format(encoded_name)

    if delay:

        def make_open_url(url):
            def open():
                webbrowser.open(url)

            return open

        ui.delay(make_open_url(url), delay)
    else:
        webbrowser.open(url)
Exemplo n.º 4
0
def check():
    if not get_config_value('update.enabled', True):
        return

    timestamp = _timestamp()
    last_check = _get_last_update_check() or timestamp
    if last_check + get_config_value('update.interval', 86400) > timestamp:
        return
    _set_last_update_check(timestamp)

    info('Checking for Black Mamba updates...')

    local_release = get_local_release()
    latest_release = _get_latest_release()

    if not latest_release:
        error('Failed to fetch latest release version info')
        return

    if local_release:
        if local_release['tag_name'] == latest_release['tag_name']:
            info('No updates available, you are up to date')
            return

        info('New version available, selfupdate.py will be executed')
        import blackmamba.ide.script as script
        if system.PYTHONISTA_BUNDLE_VERSION >= 311015:
            # 311015 introduced script queues, no need for delay
            delay = None
        else:
            delay = 0.5
        script.run_script('site-packages-3/blackmamba/script/selfupdate.py', delay=delay)

    else:
        info('Missing installed version info, you should use the installer')
Exemplo n.º 5
0
def swizzle(cls_name, selector_name, fn):
    cls = ObjCClass(cls_name).ptr

    new_selector_name = SWIZZLED_SELECTOR_PREFIX + selector_name
    new_selector = sel(new_selector_name)

    if c.class_getInstanceMethod(cls, new_selector):
        error('Skipping swizzling, already responds to {} selector'.format(
            new_selector_name))
        return

    selector = sel(selector_name)
    method = c.class_getInstanceMethod(cls, selector)
    if not method:
        error('Failed to get {} instance method'.format(selector_name))
        return

    type_encoding = c.method_getTypeEncoding(method)
    parsed_types = parse_types(type_encoding)
    restype = parsed_types[0]
    argtypes = parsed_types[1]

    IMPTYPE = CFUNCTYPE(restype, *argtypes)
    imp = IMPTYPE(fn)
    retain_global(imp)

    did_add = c.class_addMethod(cls, new_selector, imp, type_encoding)

    if not did_add:
        error('Failed to add {} method'.format(new_selector_name))
        return

    new_method = c.class_getInstanceMethod(cls, new_selector)
    method_exchangeImplementations(method, new_method)
Exemplo n.º 6
0
def _register_key_command(input, modifier_flags, function, title=None):
    if not UIApplication.sharedApplication().respondsToSelector_(
            sel('originalkeyCommands')):
        swizzle('UIApplication', 'keyCommands', _blackmamba_keyCommands)

    selector_name = _key_command_selector_name(input, modifier_flags)
    selector = sel(selector_name)
    obj = UIApplication.sharedApplication()

    info('Registering key command "{}" ({})'.format(
        _shortcut_name(input, modifier_flags), title
        or 'No discoverability title'))

    if not callable(function):
        error('Skipping, provided function is not callable')
        return False

    if obj.respondsToSelector_(selector):
        error('Skipping, method {} already registered'.format(selector_name))
        return False

    def key_command_action(_sel, _cmd, sender):
        function()

    IMPTYPE = CFUNCTYPE(None, c_void_p, c_void_p, c_void_p)
    imp = IMPTYPE(key_command_action)
    retain_global(imp)

    cls = c.object_getClass(obj.ptr)
    type_encoding = c_char_p('v@:@'.encode('utf-8'))
    did_add = c.class_addMethod(cls, selector, imp, type_encoding)
    if not did_add:
        error('Failed to add key command method {}'.format(selector_name))
        return False

    if isinstance(modifier_flags, UIKeyModifier):
        modifier_flags = modifier_flags.value

    if title:
        kc = UIKeyCommand.keyCommandWithInput_modifierFlags_action_discoverabilityTitle_(
            ns(input), modifier_flags, selector, ns(title))
    else:
        kc = UIKeyCommand.keyCommandWithInput_modifierFlags_action_(
            ns(input), modifier_flags, selector)

    _key_commands.append(kc)
    return True
Exemplo n.º 7
0
def tableView_itemsForBeginningDragSession_atIndexPath_(
        _self, _cmd, tv_ptr, session_ptr, index_path_ptr):
    global _dragged_item_path

    if not _path_items:
        return ns([]).ptr

    section = ObjCInstance(index_path_ptr).section()
    row = ObjCInstance(index_path_ptr).row()

    if section >= 0 and section < len(_path_items) and row >= 0 and row < len(
            _path_items[section]):
        path = _path_items[section][row]

        type_identifier = _type_identifier(path)
        if not type_identifier:
            error('Failed to provide data, file does not exists?')
            return ns([]).ptr

        suggested_name = _suggested_name(path)

        provider = NSItemProvider.alloc().init()
        provider.registerFileRepresentationForTypeIdentifier_fileOptions_visibility_loadHandler_(
            type_identifier, 0, 0, _load_data)

        if not provider:
            error('Failed to create item provider.')
            return ns([]).ptr

        if suggested_name:
            provider.setSuggestedName(suggested_name)

        item = UIDragItem.alloc().initWithItemProvider_(provider)
        if not item:
            error('Failed to create drag item.')
            return ns([]).ptr

        _dragged_item_path = path
        return ns([item]).ptr

    return ns([]).ptr
Exemplo n.º 8
0
def _check_compatibility():
    import blackmamba.update
    info('Pythonista {} ({})'.format(system.PYTHONISTA_VERSION,
                                     system.PYTHONISTA_BUNDLE_VERSION))

    local_release = blackmamba.update.get_local_release()
    if local_release:
        info('Black Mamba {} (tag {})'.format(__version__,
                                              local_release['tag_name']))
    else:
        info(
            'Black Mamba {} (tag unknown, not installed via installation script)'
            .format(__version__))

    if system.PYTHONISTA_BUNDLE_VERSION > _LATEST_VERSION_COMPATIBILITY_TEST[0]:
        error(
            'Installed Black Mamba version is not tested with current version of Pythonista'
        )
        error('Latest compatibility tests were made with Pythonista {} ({})'.
              format(_LATEST_VERSION_COMPATIBILITY_TEST[1],
                     _LATEST_VERSION_COMPATIBILITY_TEST[0]))
        error('Update Black Mamba or use at your own risk')
Exemplo n.º 9
0
def _main(config=None):
    # It's here because Sphinx doesn't show documentation for decorated
    # functions
    from blackmamba.config import update_config_with_dict, get_config_value
    import sys
    info('Black Mamba initialization...')
    if system.PYTHONISTA_BUNDLE_VERSION < 320000:
        error('Black Mamba supports Pythonista >= 3.2 only.')
        return
    if not sys.version_info.major == 3:
        error('Black Mamba supports Python 3 only')
        return
    if sys.version_info.minor < 6:
        error('Black Mamba support Python 3.6+ only')
        return
    if config:
        update_config_with_dict(config)
    _check_compatibility()
    if get_config_value('general.register_key_commands', True):
        _register_default_key_commands()
        _register_ios11_default_key_commands()
    info('Black Mamba initialized')
    _check_for_updates()
Exemplo n.º 10
0
#!python3

import requests
import traceback
from blackmamba.log import error

try:
    exec(requests.get('http://bit.ly/get-blackmamba').text)

except Exception:
    error('Failed to fetch & execute installer')
    error(traceback.format_exc())
Exemplo n.º 11
0
    def __call__(self, *args):
        if self._regular_calling_convention():
            # First arg is pointer to block, hide it from user
            return self._func(self._block_ptr, *args)

        error('Not implemented calling convention, block not called')