Пример #1
0
def progressbar(left,
                index,
                total,
                right=None,
                skip=False,
                charset=3,
                mid_color=None):
    if right is None:
        right = '%s/%s ' % (index + 1, total
                            )  # Because index starts at 0 by default

    barload = COLS - len(right)
    if skip:
        div = int(total / barload)
        if div <= 0:
            div = 1

        if index > 1 and index % div != 0:
            return  # Only print if progress bar advances

        left = '(Skipping) %s' % left

    # Progress section
    spaced = False  # Put spaces in between progress bar characters
    advance = ['▮', '█', '▰', '⣿', '◼', '.', '⬜'][charset]
    remain = ['▯', '░', '▱', '⣀', '▭', ' ', '⣿'][charset]

    load = COLS - len(right) - len(left)
    mod = 1 if load % 2 == 0 else 0
    progress = int(index * barload / total) - len(left)
    if progress < 0:
        progress = 0

    # Left
    bar = ANSI.color(left, 'yellow')
    # Middle
    if mid_color is not None:
        bar += ANSI.color(mid_color)
    for i in range(load):
        if i == progress and mid_color is not None:
            bar += ANSI.color('reset')

        if spaced and i % 2 == mod:
            bar += ' '
        elif i < progress:
            bar += advance
        else:
            bar += remain
    # Right
    bar += ANSI.color(right, 'cyan')

    ANSI.move_column(1)
    print(bar, end='')
    sys.stdout.flush()
Пример #2
0
def load_data():
    def load():
        try:
            with open(displays.DATA_FILE, 'rb') as file:
                global ARRANGEMENT
                ARRANGEMENT = pickle.load(file)
                return True
        except IOError:
            return False

    success = load()

    if success:
        print(ANSI.color('Successfully loaded!', 'green'))
    elif displays.find():
        success = load()

    return success
Пример #3
0
def split():
    print('Splitting images...')
    start = time.time()
    converted = 0
    total = len(IMAGES)

    for index, image_file in enumerate(IMAGES):
        fname, ext = os.path.splitext(image_file)
        base = os.path.basename(fname)

        skip = False
        # Check if the glob gets expanded to existing files.
        # If it does, skip this image (already tiles for it)
        for some_file in glob.iglob('%s%s_*' % (PREFIX, base)):
            skip = True
            break
        else:  # Split the image
            try:
                image = Image.open(image_file)
            except IOError:
                progressclear()
                print(
                    ANSI.color('Error: could not open "%s"' % image_file,
                               'red'))
                continue
            tiles = []

            imgw, imgh = image.size
            arrw, arrh = DIMENSIONS

            # Scale arrangement to best fit image
            # ===================================
            # Ratios
            imgr = imgw * 1.0 / imgh
            arrr = arrw * 1.0 / arrh

            scalew = False
            scaleh = False
            scale = 1
            xoffset = 0
            yoffset = 0
            new_arrw = 0
            new_arrh = 0

            # Image is smaller than arrangement
            if imgw < arrw and imgh < arrh:
                if imgr <= arrr:
                    scalew = True
                elif imgr > arrr:
                    scaleh = True
            # Image is larger than arrangement
            elif imgw > arrw and imgh > arrh:
                if imgr <= arrr:
                    scalew = True
                elif imgr > arrr:
                    scaleh = True
            # Image is wider than arrangement
            elif imgw > arrw:
                scaleh = True
            # Image is longer than arrangement
            elif imgh > arrh:
                scalew = True

            if scalew:
                scale = imgw * 1.0 / arrw
                new_arrh = int(arrh * scale)
                new_arrw = imgw
            elif scaleh:
                scale = imgh * 1.0 / arrh
                new_arrw = int(arrw * scale)
                new_arrh = imgh

            # Center arrangement if image is wider or longer
            if new_arrw < imgw:
                xoffset = int((imgw - new_arrw) / 2.0)
            if new_arrh < imgh:
                yoffset = int((imgh - new_arrh) / 2.0)

            new_arrangement = copy.deepcopy(ARRANGEMENT)

            for display in new_arrangement:
                display.w = int(display.w * scale)
                display.h = int(display.h * scale)
                display.x = int(display.x * scale) + xoffset
                display.y = int(display.y * scale) + yoffset

            for tile_index, display in enumerate(new_arrangement):
                area = (
                    display.x,  # Start x
                    display.y,  # Start y
                    display.x + display.w,  # End x
                    display.y + display.h  # End y
                )
                tile = image.crop(area)
                tile.save('%s%s_%d%s' % (PREFIX, base, tile_index, ext))

            converted += 1

        progressbar('"%s"' % image_file, index, total, skip=skip)

    end = time.time()
    progressclear()
    print(ANSI.color('Complete!', 'green'))

    duration = int(end - start)
    print('Tiled %s images in %s seconds' % (ANSI.color(
        str(converted), 'cyan'), ANSI.color(str(duration), 'cyan')))
Пример #4
0
                exit(0)
            else:  # Base64 shared arrangement
                import base64
                fname = displays.DATA_FILE

                decoded = ''
                try:
                    decoded = base64.b64decode(config)
                except Exception:
                    pass

                if decoded != '':
                    try:
                        with open(fname, 'wb') as file:
                            file.write(decoded)
                            print(ANSI.color('Successfully recorded!',
                                             'green'))
                            exit(0)
                    except Exception:
                        pass

                print(
                    ANSI.color(
                        'Error storing arrangement data in "%s"' % fname,
                        'red'))
        else:
            print(usage)
        exit(0)
    elif command == 'clean':
        if num_args == 2:
            pass
        elif num_args == 3:
Пример #5
0
def print_arrangement(_arrangement, max_height=12):
    lines_printed = 0

    # Make a copy of the array to keep the originals intact
    arrangement = copy.deepcopy(_arrangement)

    # Scale down dimensions to display in terminal
    maxh = max([display.h for display in arrangement])
    div = maxh / max_height
    for display in arrangement:
        display.w = int(display.w / div)
        display.h = int(display.h / div)
        display.x = int(display.x / div)
        display.y = int(display.y / div)

    # Draw displays from left to right
    arrangement.sort(key=lambda display: display.x)
    _arrangement.sort(key=lambda display: display.x)

    print_inside = all([len(str(_arrangement[i])) <= arrangement[i].w - 2 for i in range(len(arrangement))])
    if not print_inside:
        print(ANSI.color(' '.join([str(display) for display in _arrangement]), 'cyan'))
        lines_printed += 1

    total_lines = max([display.y + display.h for display in arrangement])
    lines = {num : ('', 0) for num in range(total_lines)}
    for index in range(len(arrangement)):
        display = arrangement[index]
        _display = _arrangement[index]

        (w, h, x, y) = (display.w, display.h, display.x, display.y)

        box = {
            'top_left'    : '┌',
            'top_right'   : '┐',
            'bottom_left' : '└',
            'bottom_right': '┘',
            'horiz'       : '─',
            'vert'        : '│'
        }

        # Because python 2 cannot use 'nonlocal' keyword
        outer = { 'index': 0 }

        def prnt_line(text, num):
            current_line = lines[ outer['index'] ]
            current_text = current_line[0]
            current_num  = current_line[1]

            # Multi-layer arrangements overlap with padding that gets printed
            new_start = (x - 1) * 2
            if (
                new_start > 0
                and current_num > new_start
                and current_text[new_start:].strip(' ') == '' # Content is only spaces (OK to overwrite)
            ):
                current_text = current_text[:new_start]
                current_num = new_start

            lines[ outer['index'] ] = (current_text + text, current_num + num)
            outer['index'] += 1

        # y offset
        for i in range(y):
            n = (w - 1) * 2
            prnt_line(' ' * n, n)

        # First line
        n = (w - 2) * 2
        prnt_line(box['top_left'] + box['horiz'] * n + box['top_right'], n + 2)

        # Middle lines
        vlines = h - 2
        vmid = int(vlines / 2) + (0 if vlines % 2 == 0 else 1)
        for i in range(vlines):
            text = ''
            n = (w - 2) * 2

            if (print_inside and i + 1 == vmid):
                dims = str(_display)
                text = dims.center(n, ' ')

                if display.mirrored:
                    text = text.replace(dims, ANSI.color(dims, 'yellow', 'black'))
            else:
                text = ' ' * n

            prnt_line(box['vert'] + text + box['vert'], n + 2)

        # Last line
        n = (w - 2) * 2
        prnt_line(box['bottom_left'] + box['horiz'] * n + box['bottom_right'], n + 2)

        # x padding for future displays which go further down
        while outer['index'] < total_lines:
            n = (w - 1) * 2
            prnt_line(' ' * n, n)

    for num, line in lines.items():
        print(line[0])
    lines_printed += total_lines

    if any([display.mirrored for display in arrangement]):
        print('Note: %s displays are mirrored' % ANSI.color('highlighted', 'yellow', 'black'))
        lines_printed += 1

    return lines_printed
Пример #6
0
def find(prefs=None):
    # Setup
    # ===================================
    pbuddy = '/usr/libexec/PlistBuddy'
    if prefs is None:
        prefs = '/Library/Preferences/com.apple.windowserver.plist'

    if not os.path.isfile(pbuddy):
        print(ANSI.color('Error: could not locate PlistBuddy', 'red'))
        exit(1)
    if not os.path.isfile(prefs):
        print(ANSI.color('Error: could not locate display preferences file', 'red'))
        exit(1)

    def test(command):
        try:
            subprocess.check_call(
                command,
                stdout=DEVNULL,
                stderr=DEVNULL,
                shell=True
            )
        except subprocess.CalledProcessError:
            return False

        return True
    # ===================================

    total_arrangements = 0
    pbuddy_print = lambda n: 'print :DisplayAnyUserSets:%d:' % n
    # Determine number of arrangements
    while test('"%s" -c "%s" "%s"' % (pbuddy, pbuddy_print(total_arrangements), prefs)):
        total_arrangements += 1

    print('Find your display setup:')
    found = False
    for arrangement_index in range(total_arrangements):
        arrangement = []

        print_left = pbuddy_print(arrangement_index)
        display = 0
        while test('"%s" -c "%s%d" "%s"' % (pbuddy, print_left, display, prefs)):
            display_attr = lambda attr: int(
                subprocess.check_output(
                    '"%s" -c "%s%d:%s" "%s"' % (pbuddy, print_left, display, attr, prefs),
                    universal_newlines=True,
                    shell=True
                ).rstrip()
            )

            mirrored = display_attr('Mirrored') == 1
            prefix = '' if mirrored else 'Unmirrored'

            width   = display_attr(prefix + 'Width')
            height  = display_attr(prefix + 'Height')
            originX = display_attr(prefix + 'OriginX')
            originY = display_attr(prefix + 'OriginY')

            arrangement.append(Display(width, height, originX, originY, mirrored))

            display += 1

        # Normalize before printing or saving
        arrangement = normalize(arrangement)

        print()
        num_lines = print_arrangement(arrangement)
        print()
        num_lines += 2 # Two print() 's

        prog = '(%d/%d)' % (arrangement_index + 1, total_arrangements)
        prog = ANSI.color(prog, 'cyan')
        read = input('%s Is this your arrangement? [y/N] ' % prog)
        num_lines += 2 # One for printing the string and one for when you hit enter
        if read and read in 'yY':
            found = True
            fname = DATA_FILE
            try:
                with open(fname, 'wb') as file:
                    pickle.dump(arrangement, file, protocol=2)
                    print(ANSI.color('Successfully recorded!', 'green'))
            except Exception:
                print(ANSI.color('Error storing arrangement data in "%s"' % fname, 'red'))
            break
        else:
            ANSI.clear(num_lines)

    if not found:
        print(ANSI.color('No arrangement chosen. Nothing recorded.', 'red'))

    return found