<commit_before># -*- coding: utf8 - *-
"""
    tmuxp.cli
    ~~~~~~~~~

    :copyright: Copyright 2013 Tony Narlock.
    :license: BSD, see LICENSE for details
"""

import os
import sys
import argparse
import logging
import kaptan
from . import config
from distutils.util import strtobool
from . import log, util, exc, WorkspaceBuilder, Server
import pkg_resources

__version__ = pkg_resources.require("tmuxp")[0].version

logger = logging.getLogger(__name__)

config_dir = os.path.expanduser('~/.tmuxp/')
cwd_dir = os.getcwd() + '/'

def query_yes_no(question, default="yes"):
    """Ask a yes/no question via raw_input() and return their answer.

    "question" is a string that is presented to the user.
    "default" is the presumed answer if the user just hits <Enter>.
        It must be "yes" (the default), "no" or None (meaning
        an answer is required of the user).

    The "answer" return value is one of "yes" or "no".

    License MIT: http://code.activestate.com/recipes/577058/
    """
    valid = {"yes": "yes",   "y": "yes",  "ye": "yes",
             "no": "no",     "n": "no"}
    if default == None:
        prompt = " [y/n] "
    elif default == "yes":
        prompt = " [Y/n] "
    elif default == "no":
        prompt = " [y/N] "
    else:
        raise ValueError("invalid default answer: '%s'" % default)

    while True:
        sys.stdout.write(question + prompt)
        choice = raw_input().lower()
        if default is not None and choice == '':
            return strtobool(default)
        elif choice in valid.keys():
            return strtobool(valid[choice])
        else:
            sys.stdout.write("Please respond with 'yes' or 'no' "
                             "(or 'y' or 'n').\n")

def setupLogger(logger=None, level='INFO'):
    '''setup logging for CLI use.

    :param logger: instance of logger
    :type logger: :py:class:`Logger`
    '''
    if not logger:
        logger = logging.getLogger()
    if not logger.handlers:
        channel = logging.StreamHandler()
        channel.setFormatter(log.LogFormatter())
        logger.setLevel(level)
        logger.addHandler(channel)

def startup(config_dir):
    ''' Initialize CLI.

    :param config_dir: Config directory to search
    :type config_dir: string
    '''

    if not os.path.exists(config_dir):
        os.makedirs(config_dir)

def build_workspace(config_file, args):
    ''' build config workspace.

    :param config_file: full path to config file
    :param type: string
    '''
    logger.info('building %s.' % config_file)

    sconfig = kaptan.Kaptan()
    sconfig = sconfig.import_config(config_file).get()
    sconfig = config.expand(sconfig)
    sconfig = config.trickle(sconfig)

    t = Server(
        socket_name=args.socket_name,
        socket_path=args.socket_path
    )

    try:
        builder = WorkspaceBuilder(sconf=sconfig, server=t)
    except exc.EmptyConfigException:
        logger.error('%s is empty or parsed no config data' % config_file)
        return

    tmux_bin = util.which('tmux')

    try:
        builder.build()

        if 'TMUX' in os.environ:
            if query_yes_no('Already inside TMUX, load session?'):
                del os.environ['TMUX']
                os.execl(tmux_bin, 'tmux', 'switch-client', '-t', sconfig[
                         'session_name'])

        os.execl(tmux_bin, 'tmux', 'attach-session', '-t', sconfig[
                 'session_name'])
    except exc.TmuxSessionExists as e:
        attach_session = query_yes_no(e.message + ' Attach?')

        if 'TMUX' in os.environ:
            del os.environ['TMUX']
            os.execl(tmux_bin, 'tmux', 'switch-client', '-t', sconfig[
                     'session_name'])

        if attach_session:
            os.execl(tmux_bin, 'tmux', 'attach-session', '-t', sconfig[
                     'session_name'])
        return

def subcommand_load(args):
    if args.list_configs:
        startup(config_dir)
        configs_in_user = config.in_dir(config_dir)
        configs_in_cwd = config.in_cwd()

        output = ''

        if not configs_in_user:
            output += '# %s: \n\tNone found.\n' % config_dir
        else:
            output += '# %s: \n\t%s\n' % (
                config_dir, ', '.join(configs_in_user)
            )

        if configs_in_cwd:
            output += '# current directory:\n\t%s' % (
                ', '.join(configs_in_cwd)
            )

        print(output)

    elif args.configs:
        if '.' in args.configs:
            args.configs.remove('.')
            if config.in_cwd():
                args.configs.append(config.in_cwd()[0])
            else:
                print('No tmuxp configs found in current directory.')

        for configfile in args.configs:
            file_user = os.path.join(config_dir, configfile)
            file_cwd = os.path.join(cwd_dir, configfile)
            if os.path.exists(file_cwd) and os.path.isfile(file_cwd):
                build_workspace(file_cwd, args)
            elif os.path.exists(file_user) and os.path.isfile(file_user):
                build_workspace(file_user, args)
            else:
                logger.error('%s not found.' % configfile)

def subcommand_attach_session(args):
    commands = []
    try:
        ctext = args.session_name[0]
    except IndexError as e:
        return

    t = Server()
    try:
        session = [s for s in t.sessions if s.get('session_name') == ctext][0]
    except IndexError as e:
        print('Session not found.')
        return

    if 'TMUX' in os.environ:
        del os.environ['TMUX']
        session.switch_client()
        print('Inside tmux client, switching client.')
    else:
        session.attach_session()
        print('Attaching client.')

def subcommand_kill_session(args):
    commands = []
    ctext = args.session_name[0]

    t = Server()
    sessions = [s for s in t.sessions if s.get('session_name') == ctext]

    if (len(sessions) == 1):
        proc = sessions[0].kill_session()
        if proc.stderr:
            print(proc.stderr)

        print(proc.stdout)

def cli_parser():

    parser = argparse.ArgumentParser(
        description='''\
        Launch tmux workspace. Help documentation: <http://tmuxp.rtfd.org>.
        ''',
    )

    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(title='subcommands',
                                       description='valid subcommands',
                                       help='additional help')

    kill_session = subparsers.add_parser('kill-session')
    kill_session.set_defaults(callback=subcommand_kill_session)

    kill_session.add_argument(
        dest='session_name',
        nargs='*',
        type=str,
        default=None,
    )

    attach_session = subparsers.add_parser('attach-session')
    attach_session.set_defaults(callback=subcommand_attach_session)

    attach_session.add_argument(
        dest='session_name',
        nargs='*',
        type=str,
        default=None,
    )

    load = subparsers.add_parser('load')

    load.add_argument(
        '-l', '--list', dest='list_configs', action='store_true',
        help='List config files available')

    load.add_argument(
        dest='configs',
        nargs='*',
        type=str,
        default=None,
        help='''\
        List of config files to launch session from.

        Checks current working directory (%s) then $HOME/.tmuxp directory (%s).

            $ tmuxp .

        will check launch a ~/.pullv.yaml / ~/.pullv.json from the cwd.
        ''' % (cwd_dir + '/', config_dir)
    )
    load.set_defaults(callback=subcommand_load)

    parser.add_argument('--log-level', dest='log_level', default='INFO',
                        metavar='log-level',
                        help='Log level e.g. INFO, DEBUG, ERROR')

    parser.add_argument('-L', dest='socket_name', default=None,
                        metavar='socket-name')

    parser.add_argument('-S', dest='socket_path', default=None,
                        metavar='socket-path')

    parser.add_argument(
        '-v', '--version', dest='version', action='store_true',
        help='Prints the tmuxp version')

    return parser

def main():

    parser = cli_parser()

    args = parser.parse_args()

    setupLogger(level=args.log_level.upper())
    try:
        util.version()
    except Exception as e:
        logger.error(e)
        sys.exit()

    if args.callback is subcommand_load:
        subcommand_load(args)
    elif args.callback is subcommand_attach_session:
        subcommand_attach_session(args)
    elif args.callback is subcommand_kill_session:
        subcommand_kill_session(args)
    else:
        if args.version:
            print('tmuxp %s' % __version__)

        parser.print_help()

def complete(cline, cpoint):

    parser = argparse.ArgumentParser()
    parser.add_argument('-L', dest='socket_name', default=None,
                        metavar='socket-name')

    parser.add_argument('-S', dest='socket_path', default=None,
                        metavar='socket-path')

    parser.add_argument(
        dest='ctexta',
        nargs='*',
        type=str,
        default=None,
    )

    args = parser.parse_args()
    ctext = cline.replace('tmuxp ', '')

    commands = []
    commands.extend(['attach-session', 'kill-session', 'load'])

    commands = [c for c in commands if ctext in c]

    if args.socket_path:
        ctext = ctext.replace(args.socket_path or None, '')

    if args.socket_name:
        ctext = ctext.replace(args.socket_name or None, '')

    t = Server(
        socket_name=args.socket_name or None,
        socket_path=args.socket_path or None
    )

    def session_complete(command, commands, ctext):
        if ctext.startswith(command + ' '):
            commands[:] = []
            ctext_subargs = ctext.replace(command + ' ', '')

            sessions = [s.get('session_name') for s in t._sessions]
            commands.extend([c for c in sessions if ctext_subargs in c])

    def config_complete(command, commands, ctext):
        if ctext.startswith(command + ' '):
            commands[:] = []
            ctext_subargs = ctext.replace(command + ' ', '')
            configs = []

            configs += ['./' + c for c in config.in_dir(cwd_dir)]
            configs += ['./' + c for c in config.in_cwd()]
            configs += [os.path.join(config_dir, c)
                        for c in config.in_dir(config_dir)]
            commands += [c for c in configs if c.startswith(ctext_subargs)]

    session_complete('attach-session', commands, ctext)
    session_complete('kill-session', commands, ctext)
    config_complete('load', commands, ctext)

    print(' \n'.join(commands))
<commit_msg>TODO placeholder for checking for oh-my-zsh window renaming issue with DISABLE_AUTO_TITLE<commit_after># -*- coding: utf8 - *-
"""
    tmuxp.cli
    ~~~~~~~~~

    :copyright: Copyright 2013 Tony Narlock.
    :license: BSD, see LICENSE for details
"""

import os
import sys
import argparse
import logging
import kaptan
from . import config
from distutils.util import strtobool
from . import log, util, exc, WorkspaceBuilder, Server
import pkg_resources

__version__ = pkg_resources.require("tmuxp")[0].version

logger = logging.getLogger(__name__)

config_dir = os.path.expanduser('~/.tmuxp/')
cwd_dir = os.getcwd() + '/'

def query_yes_no(question, default="yes"):
    """Ask a yes/no question via raw_input() and return their answer.

    "question" is a string that is presented to the user.
    "default" is the presumed answer if the user just hits <Enter>.
        It must be "yes" (the default), "no" or None (meaning
        an answer is required of the user).

    The "answer" return value is one of "yes" or "no".

    License MIT: http://code.activestate.com/recipes/577058/
    """
    valid = {"yes": "yes",   "y": "yes",  "ye": "yes",
             "no": "no",     "n": "no"}
    if default == None:
        prompt = " [y/n] "
    elif default == "yes":
        prompt = " [Y/n] "
    elif default == "no":
        prompt = " [y/N] "
    else:
        raise ValueError("invalid default answer: '%s'" % default)

    while True:
        sys.stdout.write(question + prompt)
        choice = raw_input().lower()
        if default is not None and choice == '':
            return strtobool(default)
        elif choice in valid.keys():
            return strtobool(valid[choice])
        else:
            sys.stdout.write("Please respond with 'yes' or 'no' "
                             "(or 'y' or 'n').\n")

def setupLogger(logger=None, level='INFO'):
    '''setup logging for CLI use.

    :param logger: instance of logger
    :type logger: :py:class:`Logger`
    '''
    if not logger:
        logger = logging.getLogger()
    if not logger.handlers:
        channel = logging.StreamHandler()
        channel.setFormatter(log.LogFormatter())
        logger.setLevel(level)
        logger.addHandler(channel)

def startup(config_dir):
    ''' Initialize CLI.

    :param config_dir: Config directory to search
    :type config_dir: string
    '''

    if not os.path.exists(config_dir):
        os.makedirs(config_dir)

def build_workspace(config_file, args):
    ''' build config workspace.

    :param config_file: full path to config file
    :param type: string
    '''
    logger.info('building %s.' % config_file)

    sconfig = kaptan.Kaptan()
    sconfig = sconfig.import_config(config_file).get()
    sconfig = config.expand(sconfig)
    sconfig = config.trickle(sconfig)

    t = Server(
        socket_name=args.socket_name,
        socket_path=args.socket_path
    )

    try:
        builder = WorkspaceBuilder(sconf=sconfig, server=t)
    except exc.EmptyConfigException:
        logger.error('%s is empty or parsed no config data' % config_file)
        return

    tmux_bin = util.which('tmux')

    try:
        builder.build()

        if 'TMUX' in os.environ:
            if query_yes_no('Already inside TMUX, load session?'):
                del os.environ['TMUX']
                os.execl(tmux_bin, 'tmux', 'switch-client', '-t', sconfig[
                         'session_name'])

        os.execl(tmux_bin, 'tmux', 'attach-session', '-t', sconfig[
                 'session_name'])
    except exc.TmuxSessionExists as e:
        attach_session = query_yes_no(e.message + ' Attach?')

        if 'TMUX' in os.environ:
            del os.environ['TMUX']
            os.execl(tmux_bin, 'tmux', 'switch-client', '-t', sconfig[
                     'session_name'])

        if attach_session:
            os.execl(tmux_bin, 'tmux', 'attach-session', '-t', sconfig[
                     'session_name'])
        return

def subcommand_load(args):
    if args.list_configs:
        startup(config_dir)
        configs_in_user = config.in_dir(config_dir)
        configs_in_cwd = config.in_cwd()

        output = ''

        if not configs_in_user:
            output += '# %s: \n\tNone found.\n' % config_dir
        else:
            output += '# %s: \n\t%s\n' % (
                config_dir, ', '.join(configs_in_user)
            )

        if configs_in_cwd:
            output += '# current directory:\n\t%s' % (
                ', '.join(configs_in_cwd)
            )

        print(output)

    elif args.configs:
        if '.' in args.configs:
            args.configs.remove('.')
            if config.in_cwd():
                args.configs.append(config.in_cwd()[0])
            else:
                print('No tmuxp configs found in current directory.')

        for configfile in args.configs:
            file_user = os.path.join(config_dir, configfile)
            file_cwd = os.path.join(cwd_dir, configfile)
            if os.path.exists(file_cwd) and os.path.isfile(file_cwd):
                build_workspace(file_cwd, args)
            elif os.path.exists(file_user) and os.path.isfile(file_user):
                build_workspace(file_user, args)
            else:
                logger.error('%s not found.' % configfile)

def subcommand_attach_session(args):
    commands = []
    try:
        ctext = args.session_name[0]
    except IndexError as e:
        return

    t = Server()
    try:
        session = [s for s in t.sessions if s.get('session_name') == ctext][0]
    except IndexError as e:
        print('Session not found.')
        return

    if 'TMUX' in os.environ:
        del os.environ['TMUX']
        session.switch_client()
        print('Inside tmux client, switching client.')
    else:
        session.attach_session()
        print('Attaching client.')

def subcommand_kill_session(args):
    commands = []
    ctext = args.session_name[0]

    t = Server()
    sessions = [s for s in t.sessions if s.get('session_name') == ctext]

    if (len(sessions) == 1):
        proc = sessions[0].kill_session()
        if proc.stderr:
            print(proc.stderr)

        print(proc.stdout)

def cli_parser():

    parser = argparse.ArgumentParser(
        description='''\
        Launch tmux workspace. Help documentation: <http://tmuxp.rtfd.org>.
        ''',
    )

    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(title='subcommands',
                                       description='valid subcommands',
                                       help='additional help')

    kill_session = subparsers.add_parser('kill-session')
    kill_session.set_defaults(callback=subcommand_kill_session)

    kill_session.add_argument(
        dest='session_name',
        nargs='*',
        type=str,
        default=None,
    )

    attach_session = subparsers.add_parser('attach-session')
    attach_session.set_defaults(callback=subcommand_attach_session)

    attach_session.add_argument(
        dest='session_name',
        nargs='*',
        type=str,
        default=None,
    )

    load = subparsers.add_parser('load')

    load.add_argument(
        '-l', '--list', dest='list_configs', action='store_true',
        help='List config files available')

    load.add_argument(
        dest='configs',
        nargs='*',
        type=str,
        default=None,
        help='''\
        List of config files to launch session from.

        Checks current working directory (%s) then $HOME/.tmuxp directory (%s).

            $ tmuxp .

        will check launch a ~/.pullv.yaml / ~/.pullv.json from the cwd.
        ''' % (cwd_dir + '/', config_dir)
    )
    load.set_defaults(callback=subcommand_load)

    parser.add_argument('--log-level', dest='log_level', default='INFO',
                        metavar='log-level',
                        help='Log level e.g. INFO, DEBUG, ERROR')

    parser.add_argument('-L', dest='socket_name', default=None,
                        metavar='socket-name')

    parser.add_argument('-S', dest='socket_path', default=None,
                        metavar='socket-path')

    parser.add_argument(
        '-v', '--version', dest='version', action='store_true',
        help='Prints the tmuxp version')

    return parser

def main():

    parser = cli_parser()

    args = parser.parse_args()

    setupLogger(level=args.log_level.upper())
    try:
        util.version()
    except Exception as e:
        logger.error(e)
        sys.exit()

    if args.callback is subcommand_load:
        subcommand_load(args)
    elif args.callback is subcommand_attach_session:
        subcommand_attach_session(args)
    elif args.callback is subcommand_kill_session:
        subcommand_kill_session(args)
    else:
        if args.version:
            print('tmuxp %s' % __version__)

        parser.print_help()

def complete(cline, cpoint):

    parser = argparse.ArgumentParser()
    parser.add_argument('-L', dest='socket_name', default=None,
                        metavar='socket-name')

    parser.add_argument('-S', dest='socket_path', default=None,
                        metavar='socket-path')

    parser.add_argument(
        dest='ctexta',
        nargs='*',
        type=str,
        default=None,
    )

    args = parser.parse_args()
    ctext = cline.replace('tmuxp ', '')

    commands = []
    commands.extend(['attach-session', 'kill-session', 'load'])

    commands = [c for c in commands if ctext in c]

    if args.socket_path:
        ctext = ctext.replace(args.socket_path or None, '')

    if args.socket_name:
        ctext = ctext.replace(args.socket_name or None, '')

    t = Server(
        socket_name=args.socket_name or None,
        socket_path=args.socket_path or None
    )

    def session_complete(command, commands, ctext):
        if ctext.startswith(command + ' '):
            commands[:] = []
            ctext_subargs = ctext.replace(command + ' ', '')

            sessions = [s.get('session_name') for s in t._sessions]
            commands.extend([c for c in sessions if ctext_subargs in c])

    def config_complete(command, commands, ctext):
        if ctext.startswith(command + ' '):
            commands[:] = []
            ctext_subargs = ctext.replace(command + ' ', '')
            configs = []

            configs += ['./' + c for c in config.in_dir(cwd_dir)]
            configs += ['./' + c for c in config.in_cwd()]
            configs += [os.path.join(config_dir, c)
                        for c in config.in_dir(config_dir)]
            commands += [c for c in configs if c.startswith(ctext_subargs)]

    session_complete('attach-session', commands, ctext)
    session_complete('kill-session', commands, ctext)
    config_complete('load', commands, ctext)

    print(' \n'.join(commands))

# check for oh-my-zsh
# you are using oh-my-zsh without DISABLE_AUTO_TITLE, this can cause unexpected
# behavior with tmux window renaming. Let me uncomment for you?
<|endoftext|>


<commit_before>class ToDoItem(object):
	"""docstring for ToDoItem"""
	def __init__(self, content, complete = False, *args):
		self.content = content
		self.complete = complete
		self.args = args
		<commit_msg>fix __init__() method for ToDoItem class to pass none boolean complete test<commit_after>class ToDoItem(object):
	"""docstring for ToDoItem"""
	def __init__(self, content, complete = False, *args):
		self.content = content
		if type(complete) != type(True):
			self.complete = False
		else:
			self.complete = complete
		self.args = args
		<|endoftext|>


<commit_before>#!/usr/bin/python

# Written by Antonio Galea - 2010/11/18
# Distributed under Gnu LGPL 3.0
# see http://www.gnu.org/licenses/lgpl-3.0.txt

import sys, struct, zlib, os
from optparse import OptionParser

DEFAULT_DEVICE = "0x0483:0xdf11"

def named(tuple, names):
    return dict(zip(names.split(), tuple))

def consume(fmt, data, names):
    n = struct.calcsize(fmt)
    return named(struct.unpack(fmt, data[:n]), names), data[n:]

def cstring(string):
    return string.split("\0", 1)[0]

def compute_crc(data):
    return 0xFFFFFFFF & -zlib.crc32(data) - 1

def parse(file, dump_images=False):
    print('File: "%s"' % file)
    data = open(file, "rb").read()
    crc = compute_crc(data[:-4])
    prefix, data = consume("<5sBIB", data, "signature version size targets")
    print("%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d" % prefix)
    for t in range(prefix["targets"]):
        tprefix, data = consume(
            "<6sBI255s2I", data, "signature altsetting named name size elements"
        )
        tprefix["num"] = t
        if tprefix["named"]:
            tprefix["name"] = cstring(tprefix["name"])
        else:
            tprefix["name"] = ""
        print(
            '%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d'
            % tprefix
        )
        tsize = tprefix["size"]
        target, data = data[:tsize], data[tsize:]
        for e in range(tprefix["elements"]):
            eprefix, target = consume("<2I", target, "address size")
            eprefix["num"] = e
            print("  %(num)d, address: 0x%(address)08x, size: %(size)d" % eprefix)
            esize = eprefix["size"]
            image, target = target[:esize], target[esize:]
            if dump_images:
                out = "%s.target%d.image%d.bin" % (file, t, e)
                open(out, "wb").write(image)
                print('    DUMPED IMAGE TO "%s"' % out)
        if len(target):
            print("target %d: PARSE ERROR" % t)
    suffix = named(struct.unpack("<4H3sBI", data[:16]), "device product vendor dfu ufd len crc")
    print(
        "usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x"
        % suffix
    )
    if crc != suffix["crc"]:
        print("CRC ERROR: computed crc32 is 0x%08x" % crc)
    data = data[16:]
    if data:
        print("PARSE ERROR")

def build(file, targets, device=DEFAULT_DEVICE):
    data = b""
    for t, target in enumerate(targets):
        tdata = b""
        for image in target:
            # pad image to 8 bytes (needed at least for L476)
            pad = (8 - len(image["data"]) % 8) % 8
            image["data"] = image["data"] + bytes(bytearray(8)[0:pad])
            #
            tdata += struct.pack("<2I", image["address"], len(image["data"])) + image["data"]
        tdata = (
            struct.pack("<6sBI255s2I", b"Target", 0, 1, b"ST...", len(tdata), len(target)) + tdata
        )
        data += tdata
    data = struct.pack("<5sBIB", b"DfuSe", 1, len(data) + 11, len(targets)) + data
    v, d = map(lambda x: int(x, 0) & 0xFFFF, device.split(":", 1))
    data += struct.pack("<4H3sB", 0, d, v, 0x011A, b"UFD", 16)
    crc = compute_crc(data)
    data += struct.pack("<I", crc)
    open(file, "wb").write(data)

if __name__ == "__main__":
    usage = """
%prog [-d|--dump] infile.dfu
%prog {-b|--build} address:file.bin [-b address:file.bin ...] [{-D|--device}=vendor:device] outfile.dfu"""
    parser = OptionParser(usage=usage)
    parser.add_option(
        "-b",
        "--build",
        action="append",
        dest="binfiles",
        help="build a DFU file from given BINFILES",
        metavar="BINFILES",
    )
    parser.add_option(
        "-D",
        "--device",
        action="store",
        dest="device",
        help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE,
        metavar="DEVICE",
    )
    parser.add_option(
        "-d",
        "--dump",
        action="store_true",
        dest="dump_images",
        default=False,
        help="dump contained images to current directory",
    )
    (options, args) = parser.parse_args()

    if options.binfiles and len(args) == 1:
        target = []
        for arg in options.binfiles:
            try:
                address, binfile = arg.split(":", 1)
            except ValueError:
                print("Address:file couple '%s' invalid." % arg)
                sys.exit(1)
            try:
                address = int(address, 0) & 0xFFFFFFFF
            except ValueError:
                print("Address %s invalid." % address)
                sys.exit(1)
            if not os.path.isfile(binfile):
                print("Unreadable file '%s'." % binfile)
                sys.exit(1)
            target.append({"address": address, "data": open(binfile, "rb").read()})
        outfile = args[0]
        device = DEFAULT_DEVICE
        if options.device:
            device = options.device
        try:
            v, d = map(lambda x: int(x, 0) & 0xFFFF, device.split(":", 1))
        except:
            print("Invalid device '%s'." % device)
            sys.exit(1)
        build(outfile, [target], device)
    elif len(args) == 1:
        infile = args[0]
        if not os.path.isfile(infile):
            print("Unreadable file '%s'." % infile)
            sys.exit(1)
        parse(infile, dump_images=options.dump_images)
    else:
        parser.print_help()
        sys.exit(1)
<commit_msg>tools/dfu.py: Make tool work with python3 when parsing DFU files.<commit_after>#!/usr/bin/python

# Written by Antonio Galea - 2010/11/18
# Distributed under Gnu LGPL 3.0
# see http://www.gnu.org/licenses/lgpl-3.0.txt

import sys, struct, zlib, os
from optparse import OptionParser

DEFAULT_DEVICE = "0x0483:0xdf11"

def named(tuple, names):
    return dict(zip(names.split(), tuple))

def consume(fmt, data, names):
    n = struct.calcsize(fmt)
    return named(struct.unpack(fmt, data[:n]), names), data[n:]

def cstring(string):
    return string.split(b"\0", 1)[0]

def compute_crc(data):
    return 0xFFFFFFFF & -zlib.crc32(data) - 1

def parse(file, dump_images=False):
    print('File: "%s"' % file)
    data = open(file, "rb").read()
    crc = compute_crc(data[:-4])
    prefix, data = consume("<5sBIB", data, "signature version size targets")
    print("%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d" % prefix)
    for t in range(prefix["targets"]):
        tprefix, data = consume(
            "<6sBI255s2I", data, "signature altsetting named name size elements"
        )
        tprefix["num"] = t
        if tprefix["named"]:
            tprefix["name"] = cstring(tprefix["name"])
        else:
            tprefix["name"] = ""
        print(
            '%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d'
            % tprefix
        )
        tsize = tprefix["size"]
        target, data = data[:tsize], data[tsize:]
        for e in range(tprefix["elements"]):
            eprefix, target = consume("<2I", target, "address size")
            eprefix["num"] = e
            print("  %(num)d, address: 0x%(address)08x, size: %(size)d" % eprefix)
            esize = eprefix["size"]
            image, target = target[:esize], target[esize:]
            if dump_images:
                out = "%s.target%d.image%d.bin" % (file, t, e)
                open(out, "wb").write(image)
                print('    DUMPED IMAGE TO "%s"' % out)
        if len(target):
            print("target %d: PARSE ERROR" % t)
    suffix = named(struct.unpack("<4H3sBI", data[:16]), "device product vendor dfu ufd len crc")
    print(
        "usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x"
        % suffix
    )
    if crc != suffix["crc"]:
        print("CRC ERROR: computed crc32 is 0x%08x" % crc)
    data = data[16:]
    if data:
        print("PARSE ERROR")

def build(file, targets, device=DEFAULT_DEVICE):
    data = b""
    for t, target in enumerate(targets):
        tdata = b""
        for image in target:
            # pad image to 8 bytes (needed at least for L476)
            pad = (8 - len(image["data"]) % 8) % 8
            image["data"] = image["data"] + bytes(bytearray(8)[0:pad])
            #
            tdata += struct.pack("<2I", image["address"], len(image["data"])) + image["data"]
        tdata = (
            struct.pack("<6sBI255s2I", b"Target", 0, 1, b"ST...", len(tdata), len(target)) + tdata
        )
        data += tdata
    data = struct.pack("<5sBIB", b"DfuSe", 1, len(data) + 11, len(targets)) + data
    v, d = map(lambda x: int(x, 0) & 0xFFFF, device.split(":", 1))
    data += struct.pack("<4H3sB", 0, d, v, 0x011A, b"UFD", 16)
    crc = compute_crc(data)
    data += struct.pack("<I", crc)
    open(file, "wb").write(data)

if __name__ == "__main__":
    usage = """
%prog [-d|--dump] infile.dfu
%prog {-b|--build} address:file.bin [-b address:file.bin ...] [{-D|--device}=vendor:device] outfile.dfu"""
    parser = OptionParser(usage=usage)
    parser.add_option(
        "-b",
        "--build",
        action="append",
        dest="binfiles",
        help="build a DFU file from given BINFILES",
        metavar="BINFILES",
    )
    parser.add_option(
        "-D",
        "--device",
        action="store",
        dest="device",
        help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE,
        metavar="DEVICE",
    )
    parser.add_option(
        "-d",
        "--dump",
        action="store_true",
        dest="dump_images",
        default=False,
        help="dump contained images to current directory",
    )
    (options, args) = parser.parse_args()

    if options.binfiles and len(args) == 1:
        target = []
        for arg in options.binfiles:
            try:
                address, binfile = arg.split(":", 1)
            except ValueError:
                print("Address:file couple '%s' invalid." % arg)
                sys.exit(1)
            try:
                address = int(address, 0) & 0xFFFFFFFF
            except ValueError:
                print("Address %s invalid." % address)
                sys.exit(1)
            if not os.path.isfile(binfile):
                print("Unreadable file '%s'." % binfile)
                sys.exit(1)
            target.append({"address": address, "data": open(binfile, "rb").read()})
        outfile = args[0]
        device = DEFAULT_DEVICE
        if options.device:
            device = options.device
        try:
            v, d = map(lambda x: int(x, 0) & 0xFFFF, device.split(":", 1))
        except:
            print("Invalid device '%s'." % device)
            sys.exit(1)
        build(outfile, [target], device)
    elif len(args) == 1:
        infile = args[0]
        if not os.path.isfile(infile):
            print("Unreadable file '%s'." % infile)
            sys.exit(1)
        parse(infile, dump_images=options.dump_images)
    else:
        parser.print_help()
        sys.exit(1)
<|endoftext|>


<commit_before>#!/usr/bin/env python
# encoding: utf-8

from __future__ import division, print_function
import numpy as np
from scipy.integrate import ode

def zodeint(func, y0, t):
    """Simple wraper around scipy.integrate.ode for complex valued problems.

    :param func: Right hand side of the equation dy/dt = f(t, y)
    :param y0: Initial value at t = t[0]
    :param t: Sequence of time points for whihc to solve for y
    :returns: y[len(t), len(y0)]

    """
    integrator = ode(func) \
            .set_integrator('zvode', with_jacobian=False) \
            .set_initial_value(y0)

    y = np.empty((len(t), len(y0)), dtype=complex)
    y[0] = y0

    for i in xrange(1, len(t)):
        integrator.integrate(t[i])
        if not integrator.successful():
            print('WARNING: Integrator failed')
            break
        y[i] = integrator.y

    return t[:i+1], y[:i+1]
<commit_msg>Correct complex integrator for scalar equations<commit_after>#!/usr/bin/env python
# encoding: utf-8

from __future__ import division, print_function
import numpy as np
from scipy.integrate import ode

def zodeint(func, y0, t, **kwargs):
    """Simple wraper around scipy.integrate.ode for complex valued problems.

    :param func: Right hand side of the equation dy/dt = f(t, y)
    :param y0: Initial value at t = t[0]
    :param t: Sequence of time points for whihc to solve for y
    :returns: y[len(t), len(y0)]

    """
    y0 = np.array([y0]) if np.isscalar(y0) else y0
    integrator = ode(func) \
            .set_integrator('zvode', with_jacobian=False, **kwargs) \
            .set_initial_value(y0)

    y = np.empty((len(t), len(y0)), dtype=complex)
    y[0] = y0

    for i in xrange(1, len(t)):
        integrator.integrate(t[i])
        if not integrator.successful():
            print('WARNING: Integrator failed')
            break
        y[i] = integrator.y

    return t[:i+1], y[:i+1]
<|endoftext|>


<commit_before>
import sys, os
import py
import tox

class VirtualEnv(object):
    def __init__(self, envconfig=None, session=None):
        self.envconfig = envconfig
        self.session = session
        self.path = envconfig.envdir
        self.path_deps = self.path.join(".deps")
        self.path_python = self.path.join(".python")

    def __repr__(self):
        return "<VirtualEnv at %r>" %(self.path)

    def getcommandpath(self, name=None):
        if name is None:
            return self.envconfig.envpython
        return self.envconfig.envbindir.join(name, abs=True)

    def _ispython3(self):
        return "python3" in str(self.envconfig.basepython)

    def update(self):
        """ return status string for updating actual venv to match configuration.
            if status string is empty, all is ok.
        """
        report = self.session.report
        name = self.envconfig.envname
        if not self.iscorrectpythonenv():
            if not self.path_python.check():
                report.action("creating virtualenv %s" % name)
            else:
                report.action("recreating virtualenv %s "
                    "(configchange/partial install detected)" % name)
            try:
                self.create()
            except tox.exception.UnsupportedInterpreter:
                return sys.exc_info()[1]
            except tox.exception.InterpreterNotFound:
                return sys.exc_info()[1]
            try:
                self.install_deps()
            except tox.exception.InvocationError:
                v = sys.exc_info()[1]
                return "could not install deps %r" %(
                        ",".join(self.envconfig.deps))
        else:
            report.action("reusing existing matching virtualenv %s" %
                (self.envconfig.envname,))

    def iscorrectpythonenv(self):
        if self.path_python.check():
            s = self.path_python.read()
            executable = self.getconfigexecutable()
            if s == executable:
                return self.matchingdependencies()
        return False

    def _getconfigdeps(self):
        return [self.session._resolve_pkg(dep) for dep in self.envconfig.deps]

    def matchingdependencies(self):
        if self.path_deps.check():
            configdeps = self._getconfigdeps()
            for depline in self.path_deps.readlines(cr=0):
                depline = depline.strip()
                if not depline:
                    continue
                parts = depline.rsplit(" ", 1)
                if len(parts) > 1:
                    dep, digest = parts
                    print "X"
                    print configdeps
                    print depline
                    if dep not in configdeps:
                        return False
                    path = py.path.local(dep)
                    if not path.check() or getdigest(path) != digest:
                        return False
                else:
                    dep = depline
                    if dep not in configdeps:
                        return False
                configdeps.remove(dep)
            if not configdeps: # no deps left
                return True
        return False

    def _writedeps(self, deps):
        lines = []
        for dep in deps:
            path = py.path.local(dep)
            if path.check():
                depline = "%s %s" %(dep, getdigest(path))
            else:
                depline = dep
            lines.append(depline)
        self.path_deps.write("\n".join(lines))

    def getconfigexecutable(self):
        python = self.envconfig.basepython
        if not python:
            python = sys.executable
        return find_executable(str(python))

    def getsupportedinterpreter(self):
        if sys.platform == "win32" and self._ispython3():
            raise tox.exception.UnsupportedInterpreter(
                "python3/virtualenv3 is buggy on windows")
        if sys.platform == "win32" and self.envconfig.basepython and \
                "jython" in self.envconfig.basepython:
            raise tox.exception.UnsupportedInterpreter(
                "Jython/Windows does not support installing scripts")
        config_executable = self.getconfigexecutable()
        if not config_executable:
            raise tox.exception.InterpreterNotFound(self.envconfig.basepython)
        return config_executable

    def create(self):
        #if self.getcommandpath("activate").dirpath().check():
        #    return
        config_interpreter = self.getsupportedinterpreter()
        args = ['virtualenv' + (self._ispython3() and "3" or "")]
        args.append('--no-site-packages')
        if not self._ispython3() and self.envconfig.distribute:
            args.append('--distribute')
        if sys.platform == "win32":
            f, path, _ = py.std.imp.find_module("virtualenv")
            f.close()
            args[:1] = [str(config_interpreter), str(path)]
        else:
            args.extend(["-p", str(config_interpreter)])
        self.session.make_emptydir(self.path)
        basepath = self.path.dirpath()
        basepath.ensure(dir=1)
        old = py.path.local()
        try:
            basepath.chdir()
            args.append(self.path.basename)
            self._pcall(args, venv=False)
            if self._ispython3():
                self.easy_install(["-U", "distribute"])
        finally:
            old.chdir()
        self.path_python.write(str(config_interpreter))

    def install_sdist(self, sdistpath):
        self._install([sdistpath])

    def install_deps(self):
        deps = self._getconfigdeps()
        self.session.report.action("installing dependencies %s" %(deps))
        self._install(deps)
        self._writedeps(deps)

    def easy_install(self, args):
        argv = ["easy_install"] + args
        self._pcall(argv)

    def pip_install(self, args):
        argv = ["pip", "install"] + args
        if self.envconfig.downloadcache:
            self.envconfig.downloadcache.ensure(dir=1)
            argv.append("--download-cache=%s" %
                self.envconfig.downloadcache)
        self._pcall(argv)

    def _install(self, args):
        if not args:
            return
        if self._ispython3():
            self.easy_install(args)
        else:
            self.pip_install(args)

    def test(self):
        self.session.make_emptydir(self.envconfig.envtmpdir)
        cwd = self.envconfig.changedir
        env = os.environ.copy()
        env['PATH'] = str(self.envconfig.envbindir) + os.pathsep + env['PATH']
        for argv in self.envconfig.commands:
            try:
                self._pcall(argv, log=-1, cwd=cwd, env=env)
            except tox.exception.InvocationError:
                return True

    def _pcall(self, args, venv=True, log=None, cwd=None, env=None):
        if venv:
            args = [self.getcommandpath(args[0])] + args[1:]
        if log is None:
            log = self.path.ensure("log", dir=1)
        return self.session.pcall(args, log=log, cwd=cwd, env=env)

def getdigest(path):
    try:
        from hashlib import md5
    except ImportError:
        from md5 import md5
    f = path.open("rb")
    s = f.read()
    f.close()
    return md5(s).hexdigest()

if sys.platform != "win32":
    def find_executable(name):
        return py.path.local.sysfind(name)

else:
    win32map = {
            'python': sys.executable,
            'python2.4': "c:\python24\python.exe",
            'python2.5': "c:\python25\python.exe",
            'python2.6': "c:\python26\python.exe",
            'python2.7': "c:\python27\python.exe",
            'python3.1': "c:\python31\python.exe",
            'jython': "c:\jython2.5.1\jython.bat",
    }
    def find_executable(name):
        p = py.path.local(name)
        if p.check(file=1):
            return p
        actual = win32map.get(name, None)
        if actual:
            actual = py.path.local(actual)
            if actual.check():
                return actual

<commit_msg>remove debug prints<commit_after>
import sys, os
import py
import tox

class VirtualEnv(object):
    def __init__(self, envconfig=None, session=None):
        self.envconfig = envconfig
        self.session = session
        self.path = envconfig.envdir
        self.path_deps = self.path.join(".deps")
        self.path_python = self.path.join(".python")

    def __repr__(self):
        return "<VirtualEnv at %r>" %(self.path)

    def getcommandpath(self, name=None):
        if name is None:
            return self.envconfig.envpython
        return self.envconfig.envbindir.join(name, abs=True)

    def _ispython3(self):
        return "python3" in str(self.envconfig.basepython)

    def update(self):
        """ return status string for updating actual venv to match configuration.
            if status string is empty, all is ok.
        """
        report = self.session.report
        name = self.envconfig.envname
        if not self.iscorrectpythonenv():
            if not self.path_python.check():
                report.action("creating virtualenv %s" % name)
            else:
                report.action("recreating virtualenv %s "
                    "(configchange/partial install detected)" % name)
            try:
                self.create()
            except tox.exception.UnsupportedInterpreter:
                return sys.exc_info()[1]
            except tox.exception.InterpreterNotFound:
                return sys.exc_info()[1]
            try:
                self.install_deps()
            except tox.exception.InvocationError:
                v = sys.exc_info()[1]
                return "could not install deps %r" %(
                        ",".join(self.envconfig.deps))
        else:
            report.action("reusing existing matching virtualenv %s" %
                (self.envconfig.envname,))

    def iscorrectpythonenv(self):
        if self.path_python.check():
            s = self.path_python.read()
            executable = self.getconfigexecutable()
            if s == executable:
                return self.matchingdependencies()
        return False

    def _getconfigdeps(self):
        return [self.session._resolve_pkg(dep) for dep in self.envconfig.deps]

    def matchingdependencies(self):
        if self.path_deps.check():
            configdeps = self._getconfigdeps()
            for depline in self.path_deps.readlines(cr=0):
                depline = depline.strip()
                if not depline:
                    continue
                parts = depline.rsplit(" ", 1)
                if len(parts) > 1:
                    dep, digest = parts
                    if dep not in configdeps:
                        return False
                    path = py.path.local(dep)
                    if not path.check() or getdigest(path) != digest:
                        return False
                else:
                    dep = depline
                    if dep not in configdeps:
                        return False
                configdeps.remove(dep)
            if not configdeps: # no deps left
                return True
        return False

    def _writedeps(self, deps):
        lines = []
        for dep in deps:
            path = py.path.local(dep)
            if path.check():
                depline = "%s %s" %(dep, getdigest(path))
            else:
                depline = dep
            lines.append(depline)
        self.path_deps.write("\n".join(lines))

    def getconfigexecutable(self):
        python = self.envconfig.basepython
        if not python:
            python = sys.executable
        return find_executable(str(python))

    def getsupportedinterpreter(self):
        if sys.platform == "win32" and self._ispython3():
            raise tox.exception.UnsupportedInterpreter(
                "python3/virtualenv3 is buggy on windows")
        if sys.platform == "win32" and self.envconfig.basepython and \
                "jython" in self.envconfig.basepython:
            raise tox.exception.UnsupportedInterpreter(
                "Jython/Windows does not support installing scripts")
        config_executable = self.getconfigexecutable()
        if not config_executable:
            raise tox.exception.InterpreterNotFound(self.envconfig.basepython)
        return config_executable

    def create(self):
        #if self.getcommandpath("activate").dirpath().check():
        #    return
        config_interpreter = self.getsupportedinterpreter()
        args = ['virtualenv' + (self._ispython3() and "3" or "")]
        args.append('--no-site-packages')
        if not self._ispython3() and self.envconfig.distribute:
            args.append('--distribute')
        if sys.platform == "win32":
            f, path, _ = py.std.imp.find_module("virtualenv")
            f.close()
            args[:1] = [str(config_interpreter), str(path)]
        else:
            args.extend(["-p", str(config_interpreter)])
        self.session.make_emptydir(self.path)
        basepath = self.path.dirpath()
        basepath.ensure(dir=1)
        old = py.path.local()
        try:
            basepath.chdir()
            args.append(self.path.basename)
            self._pcall(args, venv=False)
            if self._ispython3():
                self.easy_install(["-U", "distribute"])
        finally:
            old.chdir()
        self.path_python.write(str(config_interpreter))

    def install_sdist(self, sdistpath):
        self._install([sdistpath])

    def install_deps(self):
        deps = self._getconfigdeps()
        self.session.report.action("installing dependencies %s" %(deps))
        self._install(deps)
        self._writedeps(deps)

    def easy_install(self, args):
        argv = ["easy_install"] + args
        self._pcall(argv)

    def pip_install(self, args):
        argv = ["pip", "install"] + args
        if self.envconfig.downloadcache:
            self.envconfig.downloadcache.ensure(dir=1)
            argv.append("--download-cache=%s" %
                self.envconfig.downloadcache)
        self._pcall(argv)

    def _install(self, args):
        if not args:
            return
        if self._ispython3():
            self.easy_install(args)
        else:
            self.pip_install(args)

    def test(self):
        self.session.make_emptydir(self.envconfig.envtmpdir)
        cwd = self.envconfig.changedir
        env = os.environ.copy()
        env['PATH'] = str(self.envconfig.envbindir) + os.pathsep + env['PATH']
        for argv in self.envconfig.commands:
            try:
                self._pcall(argv, log=-1, cwd=cwd, env=env)
            except tox.exception.InvocationError:
                return True

    def _pcall(self, args, venv=True, log=None, cwd=None, env=None):
        if venv:
            args = [self.getcommandpath(args[0])] + args[1:]
        if log is None:
            log = self.path.ensure("log", dir=1)
        return self.session.pcall(args, log=log, cwd=cwd, env=env)

def getdigest(path):
    try:
        from hashlib import md5
    except ImportError:
        from md5 import md5
    f = path.open("rb")
    s = f.read()
    f.close()
    return md5(s).hexdigest()

if sys.platform != "win32":
    def find_executable(name):
        return py.path.local.sysfind(name)

else:
    win32map = {
            'python': sys.executable,
            'python2.4': "c:\python24\python.exe",
            'python2.5': "c:\python25\python.exe",
            'python2.6': "c:\python26\python.exe",
            'python2.7': "c:\python27\python.exe",
            'python3.1': "c:\python31\python.exe",
            'jython': "c:\jython2.5.1\jython.bat",
    }
    def find_executable(name):
        p = py.path.local(name)
        if p.check(file=1):
            return p
        actual = win32map.get(name, None)
        if actual:
            actual = py.path.local(actual)
            if actual.check():
                return actual

<|endoftext|>


<commit_before># filtering regular expressions, used to strip out annoyances like ads,
# web bugs and the like from feeds
import re, degunk

# uncomment this if you have made changes to the degunk module
# reload(degunk)

filter_list = [
  # don't mess with breaks
  degunk.Re('(
]*>)', 0, '
'),
  # Blegs
  degunk.Re('<a href="http://www.bloglines.com/sub/.*?'),
  degunk.Re('<a href="http://del.icio.us/post.*?'),
  degunk.Re('<a href="http://digg.com/submit.*?'),
  degunk.Re('<a href="http://www.furl.net/storeIt.jsp.*?'),
  degunk.Re('<a href="http://ma.gnolia.com/bookmarklet/add.*?'),
  degunk.Re('<a href="http://www.propeller.com/submit.*?'),
  degunk.Re('<a href="http://reddit.com/submit.*?'),
  degunk.Re('<a href="http://www.sphere.com/search\\?q=sphereit.*?'),
  degunk.Re('<a href="http://www.stumbleupon.com/submit.*?'),
  degunk.Re('<a href="http://tailrank.com/share/.*?'),
  degunk.Re('<a href="http://technorati.com/faves\\?add.*?'),
  degunk.Re('<a href="http://www.feedburner.com/fb/a/emailFlare.*?'),
  degunk.Re('<a href="http://slashdot.org/bookmark.pl.*?'),
  degunk.Re('<a href="http://www.facebook.com/sharer?.php.*?'),
  degunk.Re('<a href="http://www.google.com/bookmarks/mark.*?'),
  degunk.Re('<a href="http://blinklist.com.*?'),
  degunk.Re('<a href="http://del.irio.us.*?'),
  degunk.Re('<a href="http://www.kaboodle.com.*?'),
  degunk.Re('<a href="http://www.newsvine.com.*?'),
  degunk.Re('<p class="addtoany_.*?
', re.MULTILINE + re.DOTALL),
  degunk.Re(']*href="[^"]*addtoany.com.*?', re.MULTILINE + re.DOTALL),
  degunk.Re('
.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'<a href="http://www.pheedcontent.com.*?\s*'),
  degunk.Re('<div class="zemanta.*?
', re.MULTILINE + re.DOTALL),
  degunk.Re('
Follow us on Twitter.*?
',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  degunk.Re('<div class="tweetmeme_button".*?
',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  degunk.Re('
<a href="[^"]*sharethis.com.*?
',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  degunk.Re(']*.tweetmeme.com.*?',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  degunk.Re(']* href="http://twitter.com/home/[?]status.*?',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  # Feedburner annoyances
  degunk.Re(']*>]*>'),
  degunk.Re('
]*/~./)[^"]*">'
            ']*>
'),
  degunk.Re(''),
  # web bugs dumb enough to reveal themselves
  degunk.Re(']*width="1"[^>]*height="1"[^>]*>'),
  degunk.Re(']*height="1"[^>]*width="1"[^>]*>'),
  # Google ads
  degunk.Re('(
)?]*href="http://[a-z]*ads.googleadservices[^>]*>'
            '[^<>]*<img [^<>]*>(
)?', re.MULTILINE),
  degunk.Re(']*href="http://www.google.com/ads_by_google[^>]*>[^<>]*',
            re.MULTILINE),
  degunk.Re('
<map[^>]*><area[^>]*href="http://imageads.google.*?
',
            re.MULTILINE),
  # Wordpress stats
  degunk.Re(']*src="http://feeds.wordpress[^>]*>'),
  # Falk AG ads
  degunk.Re('

\s*.*?]*>.*?'
            '
.*?
', re.IGNORECASE + re.DOTALL),
  degunk.Re(']*>]*>'),
  # Empty paragraphs used as spacers in front of ads
  degunk.Re('

'),
  degunk.Re(r'

\s*
\s*', re.MULTILINE),
  degunk.Re(r'\s*(
)?
\s*
\s*
\s*', re.MULTILINE),
  # DoubleClick ads
  degunk.Re(']*href="http://ad.doubleclick.net[^>]*>.*?',
            re.MULTILINE),
  degunk.Re('
ADVERTISEMENT.*?
'),
  # Yahoo ads
  degunk.Re('
.*?
'),
  # Commindo ads
  degunk.Re('<div.*]*commindo-media.*?
',
            re.MULTILINE + re.DOTALL),
  # annoying forms inside posts, e.g. Russell Beattie
  degunk.Re('<form.*?</form>', re.IGNORECASE + re.DOTALL),
  # Weblogs Inc, ads
  degunk.Re('
]*href="http://feeds.gawker.com[^>]*>[^<>]*'
            ']*src="http://feeds.gawker.com[^<>]*>
',
            re.MULTILINE),
  # annoying Weblogs Inc. footer
  degunk.Re('<h([0-9])></h\1>'),
  degunk.Re(']*>Permalink.*?]*>'
            'Email this.*?Comments',
            re.IGNORECASE + re.DOTALL),
  degunk.Re('

SPONSORED BY.*?
'),
  # Engadget ads
  degunk.Re('

SPONSORED BY.*?
\s*', re.MULTILINE),
  degunk.Re('<p.*?originally appeared on.*?terms for use of feeds.*?
',
            re.MULTILINE),
  # Gawker cross-shilling
  degunk.Re('
]*>Comment on this post\s*
Related.*',
            re.IGNORECASE + re.DOTALL),
  degunk.Re('
.*?
', re.IGNORECASE + re.DOTALL),
  # Pheedo ads
  degunk.Re('
Presented By:
[^<>]*
<a href="http://ads.pheedo'
            '.*?
.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re(']*href="http://[^">]*pheedo.com.*?',
            re.MULTILINE + re.DOTALL),
  degunk.Re(']*src="http://[^">]*pheedo.com.*?>',
            re.MULTILINE + re.DOTALL),
  # Broken Pheedo links for IEEE Spectrum
  degunk.ReUrl(url=r'http://pheedo.com\1',
               regex_url=r'http://www.pheedo.com(.*)'),
  # Triggit ads
  degunk.Re('(
)*]*triggit.com.*?>', re.MULTILINE + re.DOTALL),
  # Web bugs
  degunk.Re(']*quantserve.com.*?>', re.MULTILINE + re.DOTALL),
  degunk.Re(']*invitemedia.com[^>]*>',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  # Mediafed ads
  degunk.Re('
'),
  # IDFuel URLs should point to full article, not teaser
  degunk.ReUrl(url=r'http://www.idfuel.com/index.php?p=\1&more=1',
               regex_url=r'http://www.idfuel.com/index.php\?p=([0-9]*)'),
  # Strip The Register redirection that causes link_already() to fail
  degunk.ReUrl(
    url=r'\1', regex_url=r'http://go.theregister.com/feed/(http://.*)'),
  # Same for I Cringely
  degunk.ReUrl(
  url=r'http://www.pbs.org/cringely/\1',
  regex_url=r'http://www.pbs.org/cringely/rss1/redir/cringely/(.*)'),
  # Register ads
  degunk.Re('Advertisement
'),
  degunk.Re('
]*href="http://whitepapers.theregister.co.uk.*?
',
            re.MULTILINE),
  # Inquirer blegging
  degunk.Re('
.*
'),
  # Feediz ads
  degunk.Re('
.*?feediz.com.*?
', re.MULTILINE + re.DOTALL),
  degunk.Re(']*feediz.com.*?', re.MULTILINE + re.DOTALL),
  # Salon ads
  degunk.Re('
]*>]*>
]*>'),
  # RWW ads
  degunk.Re('
.*?
'),
  # bypass Digg
  degunk.Dereference('digg.com', '
<a href="([^"]*)"'),
  # DoubleClick ads
  degunk.Re('<a href="http://[^"]*doubleclick.*?',
            re.MULTILINE + re.DOTALL),
  # If I want to share, I can do it myself, thanks
  degunk.Re('
.*?
', re.MULTILINE + re.DOTALL),
  # Daily Python URL should link to actual articles, not to itself
  degunk.UseFirstLink('http://www.pythonware.com/daily/'),
  degunk.ReTitle('\\1', '
.*?(.*?)',
                 re.MULTILINE + re.DOTALL),
  # Inquirer clutter
  degunk.Re('
[^<>]*<a href="http://www.theinquirer.net[^<>]*>'
            '[^<>]*Read the full article.*', re.MULTILINE + re.DOTALL),
  degunk.Re('
[^<>]*<a href="http://www.theinquirer.net.*?',
            re.MULTILINE),
  # List apart T-shirt shilling
  degunk.Re('
Hide Your Shame: The A List Apart Store'
            '.*?
', re.MULTILINE + re.DOTALL),
  # Other misc shilling
  degunk.Re('
.*<a href="http://www.beyondsecurity.com.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re('<fieldset class="zemanta-related">.*?
',
            re.MULTILINE + re.DOTALL),
  # possibly caused by bugs in feedparser
  degunk.Re('
[.>]
', 0, '
', iterate=True),
  # unwarranted multiple empty lines
  degunk.Re('
\s*(
\s*)+', 0, '
'),
  degunk.Re('

'),
  degunk.Re('
]*>
'),
  degunk.Re('
-
'),
  degunk.Re(']*>', 0, '', iterate=True),
  # junk
  degunk.Re('', 0, ''),
  # unwarranted final empty lines
  degunk.Re('(
\s*)+$'),
  # leftover from blegs or ads
  degunk.Re('-\s+(-\s+)+'),
  # GigaOM annoyances
  degunk.Re(r']*src="http://stats.wordpress.com.*?>'),
  degunk.Re(r'\s*
]*>\s*
\s*<a href="http://t.gigaom.com/.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'
\s*<a href="http://events.gigaom.com/.*',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'
\s*<a href="http://pro.gigaom.com/.*',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'\s*
]*>\s*
\s*<a href="http://gigaom.com/sponsor.*?
',
            re.MULTILINE + re.DOTALL),
  # Guardian Related sidebar
  degunk.Re(r'<div class="related" style="float.*?
',
            re.MULTILINE + re.DOTALL),
  # PopSci Related sidebar
  degunk.Re(r'<div class="relatedinfo".*?
', re.MULTILINE + re.DOTALL),
  # Ars Technica
  degunk.Re(r']* title="Click here to continue reading.*?',
            re.MULTILINE + re.DOTALL),
  degunk.Re(']*>[^<>]*'
            ']*brief_icons.*?',
            re.MULTILINE + re.DOTALL),
  # Coding Horror
  degunk.Re(r'
.*?\[advertisement\].*?
',
            re.MULTILINE + re.DOTALL),
  # Fooducate
  degunk.Re(r'
]*>Get Fooducated.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'
[^>]*<a href="http://alpha.fooducate.com.*?
',
            re.MULTILINE + re.DOTALL),
  # ReadWriteWeb ads
  degunk.Re(r'
Sponsor
.*?
',
            re.MULTILINE + re.DOTALL),
  # Laughing Squid
  degunk.Re('

\s*
\\s*'
            '.*?Laughing Squid Web Hosting.

',
            re.MULTILINE + re.DOTALL),
  ]
<commit_msg>get rid of Bluekai web bugs<commit_after># filtering regular expressions, used to strip out annoyances like ads,
# web bugs and the like from feeds
import re, degunk

# uncomment this if you have made changes to the degunk module
# reload(degunk)

filter_list = [
  # don't mess with breaks
  degunk.Re('(
]*>)', 0, '
'),
  # Blegs
  degunk.Re('<a href="http://www.bloglines.com/sub/.*?'),
  degunk.Re('<a href="http://del.icio.us/post.*?'),
  degunk.Re('<a href="http://digg.com/submit.*?'),
  degunk.Re('<a href="http://www.furl.net/storeIt.jsp.*?'),
  degunk.Re('<a href="http://ma.gnolia.com/bookmarklet/add.*?'),
  degunk.Re('<a href="http://www.propeller.com/submit.*?'),
  degunk.Re('<a href="http://reddit.com/submit.*?'),
  degunk.Re('<a href="http://www.sphere.com/search\\?q=sphereit.*?'),
  degunk.Re('<a href="http://www.stumbleupon.com/submit.*?'),
  degunk.Re('<a href="http://tailrank.com/share/.*?'),
  degunk.Re('<a href="http://technorati.com/faves\\?add.*?'),
  degunk.Re('<a href="http://www.feedburner.com/fb/a/emailFlare.*?'),
  degunk.Re('<a href="http://slashdot.org/bookmark.pl.*?'),
  degunk.Re('<a href="http://www.facebook.com/sharer?.php.*?'),
  degunk.Re('<a href="http://www.google.com/bookmarks/mark.*?'),
  degunk.Re('<a href="http://blinklist.com.*?'),
  degunk.Re('<a href="http://del.irio.us.*?'),
  degunk.Re('<a href="http://www.kaboodle.com.*?'),
  degunk.Re('<a href="http://www.newsvine.com.*?'),
  degunk.Re('<p class="addtoany_.*?
', re.MULTILINE + re.DOTALL),
  degunk.Re(']*href="[^"]*addtoany.com.*?', re.MULTILINE + re.DOTALL),
  degunk.Re('
.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'<a href="http://www.pheedcontent.com.*?\s*'),
  degunk.Re('<div class="zemanta.*?
', re.MULTILINE + re.DOTALL),
  degunk.Re('
Follow us on Twitter.*?
',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  degunk.Re('<div class="tweetmeme_button".*?
',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  degunk.Re('
<a href="[^"]*sharethis.com.*?
',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  degunk.Re(']*.tweetmeme.com.*?',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  degunk.Re(']* href="http://twitter.com/home/[?]status.*?',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  # Feedburner annoyances
  degunk.Re(']*>]*>'),
  degunk.Re('
]*/~./)[^"]*">'
            ']*>
'),
  degunk.Re(''),
  # web bugs dumb enough to reveal themselves
  degunk.Re(']*width="1"[^>]*height="1"[^>]*>'),
  degunk.Re(']*height="1"[^>]*width="1"[^>]*>'),
  degunk.Re(']*width="0"[^>]*height="0"[^>]*>'),
  degunk.Re(']*height="0"[^>]*width="0"[^>]*>'),
  # Google ads
  degunk.Re('(
)?]*href="http://[a-z]*ads.googleadservices[^>]*>'
            '[^<>]*<img [^<>]*>(
)?', re.MULTILINE),
  degunk.Re(']*href="http://www.google.com/ads_by_google[^>]*>[^<>]*',
            re.MULTILINE),
  degunk.Re('
<map[^>]*><area[^>]*href="http://imageads.google.*?
',
            re.MULTILINE),
  # Wordpress stats
  degunk.Re(']*src="http://feeds.wordpress[^>]*>'),
  # Falk AG ads
  degunk.Re('

\s*.*?]*>.*?'
            '
.*?
', re.IGNORECASE + re.DOTALL),
  degunk.Re(']*>]*>'),
  # Empty paragraphs used as spacers in front of ads
  degunk.Re('

'),
  degunk.Re(r'

\s*
\s*', re.MULTILINE),
  degunk.Re(r'\s*(
)?
\s*
\s*
\s*', re.MULTILINE),
  # DoubleClick ads
  degunk.Re(']*href="http://ad.doubleclick.net[^>]*>.*?',
            re.MULTILINE),
  degunk.Re('
ADVERTISEMENT.*?
'),
  # Yahoo ads
  degunk.Re('
.*?
'),
  # Commindo ads
  degunk.Re('<div.*]*commindo-media.*?
',
            re.MULTILINE + re.DOTALL),
  # annoying forms inside posts, e.g. Russell Beattie
  degunk.Re('<form.*?</form>', re.IGNORECASE + re.DOTALL),
  # Weblogs Inc, ads
  degunk.Re('
]*href="http://feeds.gawker.com[^>]*>[^<>]*'
            ']*src="http://feeds.gawker.com[^<>]*>
',
            re.MULTILINE),
  # annoying Weblogs Inc. footer
  degunk.Re('<h([0-9])></h\1>'),
  degunk.Re(']*>Permalink.*?]*>'
            'Email this.*?Comments',
            re.IGNORECASE + re.DOTALL),
  degunk.Re('

SPONSORED BY.*?
'),
  # Engadget ads
  degunk.Re('

SPONSORED BY.*?
\s*', re.MULTILINE),
  degunk.Re('<p.*?originally appeared on.*?terms for use of feeds.*?
',
            re.MULTILINE),
  # Gawker cross-shilling
  degunk.Re('
]*>Comment on this post\s*
Related.*',
            re.IGNORECASE + re.DOTALL),
  degunk.Re('
.*?
', re.IGNORECASE + re.DOTALL),
  # Pheedo ads
  degunk.Re('
Presented By:
[^<>]*
<a href="http://ads.pheedo'
            '.*?
.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re(']*href="http://[^">]*pheedo.com.*?',
            re.MULTILINE + re.DOTALL),
  degunk.Re(']*src="http://[^">]*pheedo.com.*?>',
            re.MULTILINE + re.DOTALL),
  # Broken Pheedo links for IEEE Spectrum
  degunk.ReUrl(url=r'http://pheedo.com\1',
               regex_url=r'http://www.pheedo.com(.*)'),
  # Triggit ads
  degunk.Re('(
)*]*triggit.com.*?>', re.MULTILINE + re.DOTALL),
  # Web bugs
  degunk.Re(']*quantserve.com.*?>', re.MULTILINE + re.DOTALL),
  degunk.Re(']*invitemedia.com[^>]*>',
            re.MULTILINE + re.DOTALL + re.IGNORECASE),
  # Mediafed ads
  degunk.Re('
'),
  # IDFuel URLs should point to full article, not teaser
  degunk.ReUrl(url=r'http://www.idfuel.com/index.php?p=\1&more=1',
               regex_url=r'http://www.idfuel.com/index.php\?p=([0-9]*)'),
  # Strip The Register redirection that causes link_already() to fail
  degunk.ReUrl(
    url=r'\1', regex_url=r'http://go.theregister.com/feed/(http://.*)'),
  # Same for I Cringely
  degunk.ReUrl(
  url=r'http://www.pbs.org/cringely/\1',
  regex_url=r'http://www.pbs.org/cringely/rss1/redir/cringely/(.*)'),
  # Register ads
  degunk.Re('Advertisement
'),
  degunk.Re('
]*href="http://whitepapers.theregister.co.uk.*?
',
            re.MULTILINE),
  # Inquirer blegging
  degunk.Re('
.*
'),
  # Feediz ads
  degunk.Re('
.*?feediz.com.*?
', re.MULTILINE + re.DOTALL),
  degunk.Re(']*feediz.com.*?', re.MULTILINE + re.DOTALL),
  # Salon ads
  degunk.Re('
]*>]*>
]*>'),
  # RWW ads
  degunk.Re('
.*?
'),
  # bypass Digg
  degunk.Dereference('digg.com', '
<a href="([^"]*)"'),
  # DoubleClick ads
  degunk.Re('<a href="http://[^"]*doubleclick.*?',
            re.MULTILINE + re.DOTALL),
  # If I want to share, I can do it myself, thanks
  degunk.Re('
.*?
', re.MULTILINE + re.DOTALL),
  # Daily Python URL should link to actual articles, not to itself
  degunk.UseFirstLink('http://www.pythonware.com/daily/'),
  degunk.ReTitle('\\1', '
.*?(.*?)',
                 re.MULTILINE + re.DOTALL),
  # Inquirer clutter
  degunk.Re('
[^<>]*<a href="http://www.theinquirer.net[^<>]*>'
            '[^<>]*Read the full article.*', re.MULTILINE + re.DOTALL),
  degunk.Re('
[^<>]*<a href="http://www.theinquirer.net.*?',
            re.MULTILINE),
  # List apart T-shirt shilling
  degunk.Re('
Hide Your Shame: The A List Apart Store'
            '.*?
', re.MULTILINE + re.DOTALL),
  # Other misc shilling
  degunk.Re('
.*<a href="http://www.beyondsecurity.com.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re('<fieldset class="zemanta-related">.*?
',
            re.MULTILINE + re.DOTALL),
  # possibly caused by bugs in feedparser
  degunk.Re('
[.>]
', 0, '
', iterate=True),
  # unwarranted multiple empty lines
  degunk.Re('
\s*(
\s*)+', 0, '
'),
  degunk.Re('

'),
  degunk.Re('
]*>
'),
  degunk.Re('
-
'),
  degunk.Re(']*>', 0, '', iterate=True),
  # junk
  degunk.Re('', 0, ''),
  # unwarranted final empty lines
  degunk.Re('(
\s*)+$'),
  # leftover from blegs or ads
  degunk.Re('-\s+(-\s+)+'),
  # GigaOM annoyances
  degunk.Re(r']*src="http://stats.wordpress.com.*?>'),
  degunk.Re(r'\s*
]*>\s*
\s*<a href="http://t.gigaom.com/.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'
\s*<a href="http://events.gigaom.com/.*',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'
\s*<a href="http://pro.gigaom.com/.*',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'\s*
]*>\s*
\s*<a href="http://gigaom.com/sponsor.*?
',
            re.MULTILINE + re.DOTALL),
  # Guardian Related sidebar
  degunk.Re(r'<div class="related" style="float.*?
',
            re.MULTILINE + re.DOTALL),
  # PopSci Related sidebar
  degunk.Re(r'<div class="relatedinfo".*?
', re.MULTILINE + re.DOTALL),
  # Ars Technica
  degunk.Re(r']* title="Click here to continue reading.*?',
            re.MULTILINE + re.DOTALL),
  degunk.Re(']*>[^<>]*'
            ']*brief_icons.*?',
            re.MULTILINE + re.DOTALL),
  # Coding Horror
  degunk.Re(r'
.*?\[advertisement\].*?
',
            re.MULTILINE + re.DOTALL),
  # Fooducate
  degunk.Re(r'
]*>Get Fooducated.*?
',
            re.MULTILINE + re.DOTALL),
  degunk.Re(r'
[^>]*<a href="http://alpha.fooducate.com.*?
',
            re.MULTILINE + re.DOTALL),
  # ReadWriteWeb ads
  degunk.Re(r'
Sponsor
.*?
',
            re.MULTILINE + re.DOTALL),
  # Laughing Squid
  degunk.Re('

\s*
\\s*'
            '.*?Laughing Squid Web Hosting.

',
            re.MULTILINE + re.DOTALL),
  ]
<|endoftext|>


<commit_before>#!/usr/bin/env python3

"""
Author: Tyler Nivin (github.com/twn346)
File: transform.py
Purpose: Used to rename directories to fit a specific naming scheme
i.e. Challenge #0001 [Easy]
"""

import glob
import os
import re
# import string

# assuming this script is in the same directory as the
# challenges you want to rename

test = glob.glob('*')
test.remove('transform.py')

def update_challenge_dir_name_hard(oldName):

    temp = oldName.split()
    # location of the challenge number in the string.
    loc = [i for i, number in enumerate(temp) if re.search('##*', number)]

    # the current challenge number.
    currNum = temp[loc[0]]

    # n is the number of digits in the challenge number.
    # I will use this to know how many zeroes to enter.
    n = len(currNum) - 1

    newNum = '#' + '0'*(4-n) + currNum[-n:]

    newTitle = 'Challenge ' + newNum + ' [Hard]'

    # Try to tease out the challenge name...
    notName = [i for i, number in enumerate(temp)
               if re.search('##*|challenge|\[hard\]|\[difficult\]',
                            number, re.IGNORECASE)]

    # I squashed several "single" filters down to one OR'd filter.
    # This is the syntax for the "single" filters.
    # notName += [i for i, number in enumerate(temp)
    #             if re.search('challenge', number, re.IGNORECASE)]

    i = 0
    for curr in notName:
        temp.pop(curr - i)
        i += 1

    if len(temp) > 0:
        challengeName = " " + " ".join(temp)
    else:
        challengeName = ""

    newTitle = newTitle + challengeName
    return newTitle

def update_challenge_dir_name_intermediate(oldName):

    # print('DEBUG: ' + oldName)
    temp = oldName.split()
    # location of the challenge number in the string.
    loc = [i for i, number in enumerate(temp) if re.search('##*', number)]

    # the current challenge number.
    currNum = temp[loc[0]]

    # n is the number of digits in the challenge number.
    # I will use this to know how many zeroes to enter.
    n = len(currNum) - 1

    newNum = '#' + '0'*(4-n) + currNum[-n:]

    newTitle = 'Challenge ' + newNum + ' [Intermediate]'

    # Try to tease out the challenge name...

    notName = [i for i, number in enumerate(temp)
               if re.search('##*|challenge|\[intermediate\]|\[medium\]',
                            number, re.IGNORECASE)]

    # I squashed several "single" filters down to one OR'd filter.
    # This is the syntax for the "single" filters.
    # notName += [i for i, number in enumerate(temp)
    #             if re.search('challenge', number, re.IGNORECASE)]

    i = 0
    for curr in notName:
        temp.pop(curr - i)
        i += 1

    if len(temp) > 0:
        challengeName = " " + " ".join(temp)
    else:
        challengeName = ""

    newTitle = newTitle + challengeName
    return newTitle

#
for each in test:
    if each != update_challenge_dir_name_intermediate(each):
        # os.rename(each, update_challenge_dir_name_intermediate(each))
        print(update_challenge_dir_name_intermediate(each))
<commit_msg>rewrite transform.py entirely. Now handles all three levels on script call, has one function for the renaming instead of several for each level, and can be ran from where it lives at the top of the repo.<commit_after>#!/usr/bin/env python3

"""
Author: Tyler Nivin
Github: github.com/twn346
File: transform.py
Purpose: Used to rename directories to fit a specific naming scheme
i.e. Challenge 0001: {challenge title}
"""

import glob
import os
import regex

# This script will run on the Easy Medium and Hard directories.

def update_challenge_dir_name(oldName, difficulty):
    '''Update the specified challenge dirs names. Returns original name if it
    suspects that it would fail a valid transformation.'''

    temp = oldName.split()

    # Find the current challenge number.

    # This will match the first number in the string.
    # The extra stuff on either side makes sure that it will not match strings
    # longer than the specified amount in the middle.
    match = regex.search(r'(?<=[^\d]|^)\d{1,5}(?=[^\d]|$)', oldName)

    # n is the number of digits in the challenge number.
    # I will use this to know how many zeroes to enter.
    if (match):
        currNum = match.group()
        n = len(currNum)

        # Handle challenges that have multiple iterations, such as 166b
        if (regex.match(r'[.\S]', oldName[match.end()])):
            newNum = ' ' + '0'*(4-n-1) + currNum[-n:]
            newNum += oldName[match.end()] + ' '
        else:
            newNum = ' ' + '0'*(4-n) + currNum[-n:] + ' '
    else:
        return oldName

    newTitle = 'Challenge' + newNum + difficulty.capitalize()

    # Try to tease out the challenge name...
    # First, remove the number we found earlier from the string...

    notName = [i for i, number in enumerate(temp)
               if regex.search(currNum + r'|' +
                               r'challenge|' + difficulty,
                               number, regex.IGNORECASE)]

    # I squashed several "single" filters down to one OR'd filter.
    # This is the syntax for the "single" filters.
    # notName += [i for i, number in enumerate(temp)
    #             if re.search('challenge', number, re.IGNORECASE)]

    i = 0
    for curr in notName:
        temp.pop(curr - i)
        i += 1

    if len(temp) > 0:
        challengeName = ": " + " ".join(temp)
    else:
        challengeName = ""

    newTitle = newTitle + challengeName
    return newTitle

def main():

    levels = ['easy', 'intermediate', 'hard']

    for level in levels:
        rawChallengeNames = glob.glob(level + ' Challenges/*')

        numCharsToRemove = len(level + ' Challenges/')

        # remove the directory from the name
        challengeNames = list(map(lambda x: x[numCharsToRemove:],
                                  rawChallengeNames))

        for each in challengeNames:
            if each != update_challenge_dir_name(each, level):
                # os.rename(each, update_challenge_dir_name(each, level))
                print(each + ' <::> ' + update_challenge_dir_name(each, level))
        print(level.capitalize() + ' Challenges!')
    return

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before># main.py - Entry-point for `list-tree'
# author: Ben Simner
'''Implements list-tree

Attempts to imitate ls in operation and arguments, but instead displays as a tree-view
'''

import os
import time
import math
import stat
import pwd
import grp
from docopt import docopt
from collections import namedtuple

def main():
    doc = '''
Usage:
    lt [--color=<when>] [--max-depth=<depth>] [-aABFhlR] [<dir>]

Options:
    <dir>                   Directory to read from
    --color=<when>          Colorize the output, can be 'never', 'auto' or 'always' [default: always]
    --max-depth=<depth>     Maximum depth to branch to [default: 3]
    -a --all                Do not ignore entries starting with .
    -A --almost-all         Like -a except do not list implied . and ..
    -B --ignore-backups     Do not list entries ending with ~
    -F --classify           Append indicator to entries
    -h --human-readable     With -l, print human-readable sizes
    -l                      Use long-list format
    -R --no-recursive       Do not recursively print directories
'''
    args = docopt(doc)
    _main(**args)

def _main(**argv):
    cwd = os.getcwd()

    global MAX_DEPTH
    global COLOR_MODE
    global LIST_ALL
    global IGNORE_BACKUPS
    global LONG_LIST
    global HUMAN_READABLE
    global NO_RECUR
    global CLASSIFY

    MAX_DEPTH = int(argv['--max-depth'])
    COLOR_MODE = argv['--color']

    if argv['--all']:
        LIST_ALL = 2
    elif argv['--almost-all']:
        LIST_ALL = 1
    else:
        LIST_ALL = 0

    if argv['<dir>']:
        cwd = argv['<dir>']

    IGNORE_BACKUPS = argv.get('--ignore-backups', False)
    HUMAN_READABLE = argv.get('--human-readable', False)
    LONG_LIST = argv.get('-l', False)
    NO_RECUR = argv.get('--no-recursive', False)
    CLASSIFY = argv.get('--classify', False)

    if COLOR_MODE == 'never':
        bcolors.no_col()

    if LONG_LIST:
        lines = print_tree(os.path.realpath(cwd))
        print_long_list_fmt(lines)
    else:
        lines = print_tree(os.path.realpath(cwd))
        for struct in lines:
            print(struct.pretty_str)

def print_long_list_fmt(lines):
    # generate prefixes
    prefix_strs = []
    max_lens = [0]*7
    for struct in lines:
        if struct.path:
            prefixs = []
            attrs = get_attributes(struct.path)

            prefix = attrs.file_mode
            prefixs.append(prefix)
            if len(prefix) > max_lens[0]:
                max_lens[0] = len(prefix)

            prefix = str(attrs.hlink_count)
            prefixs.append(prefix)
            if len(prefix) > max_lens[1]:
                max_lens[2] = len(prefix)

            prefix = pwd.getpwuid(attrs.user_id).pw_name
            prefixs.append(prefix)
            if len(prefix) > max_lens[3]:
                max_lens[3] = len(prefix)

            prefix = grp.getgrgid(attrs.group_id).gr_name
            prefixs.append(prefix)
            if len(prefix) > max_lens[4]:
                max_lens[4] = len(prefix)

            prefix = ''
            if not HUMAN_READABLE:
                prefix += str(attrs.size) + 'B'
            else:
                if attrs.size <= 0:
                    prefix += '0B'
                else:
                    log = round(math.log(attrs.size, 10))
                    if log < 3:
                        prefix += str(attrs.size) + 'B'
                    elif log < 6:
                        prefix += '%.3f' % (attrs.size / 1024) + 'KB'
                    elif log < 9:
                        prefix += '%.3f' % (attrs.size / (1024 ** 2)) + 'MB'
                    else:
                        prefix += '%.3f' % (attrs.size / (1024 ** 3)) + 'GB'

            prefixs.append(prefix)
            if len(prefix) > max_lens[5]:
                max_lens[5] = len(prefix)

            prefix = ''
            prefix += time.strftime('%b %d %Y %H:%M', time.gmtime(attrs.last_modified))
            prefixs.append(prefix)
            if len(prefix) > max_lens[6]:
                max_lens[6] = len(prefix)

            prefix_strs.append(prefixs)
        else:
            prefix_strs.append(['', '', ''])

    for prefixs, struct in zip(prefix_strs, lines):
        prefix = ''
        for p, max_len in zip(prefixs, max_lens):
            prefix += p + ' '*(3 + max_len - len(p))
        print(prefix + ' ' + struct.pretty_str)

class bcolors:
    '''ANSI escape sequences'''
    HEADER = '\033[95m'
    CYAN = '\033[36m'
    BLUE = '\033[94m'
    GREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

    @staticmethod
    def no_col():
        '''Disables ANSI escape sequencies'''
        bcolors.HEADER = ''
        bcolors.BLUE = ''
        bcolors.GREEN = ''
        bcolors.WARNING = ''
        bcolors.FAIL = ''
        bcolors.ENDC = ''
        bcolors.BOLD = ''
        bcolors.UNDERLINE = ''

Attributes = namedtuple('FileAttributes', ['size',
                                            'executable',
                                            'file_mode',
                                            'islink',
                                            'ispipe',
                                            'isdoor',
                                            'issock',
                                            'hlink_count',
                                            'user_id',
                                            'group_id',
                                            'last_modified'])

def get_attributes(path):
    st = os.stat(path)

    return Attributes(
        st.st_size,
        os.access(path, os.X_OK),
        stat.filemode(st.st_mode),
        os.path.islink(path),
        stat.S_ISFIFO(st.st_mode),
        stat.S_ISDOOR(st.st_mode),
        stat.S_ISSOCK(st.st_mode),
        st.st_nlink,
        st.st_uid,
        st.st_gid,
        st.st_mtime
    )

def get_print_string_file(path, indent=''):
    '''returns the printstring for some file with realpath 'path'
    includes ANSI color tags
    given some indent
    '''
    s = indent + '|-- '
    f = os.path.basename(path)

    col = ''
    x = ''

    attr = get_attributes(path)

    if attr.executable:
        col = bcolors.BOLD + bcolors.GREEN
        x += '*'
    if attr.islink:
        col = bcolors.BOLD + bcolors.CYAN
        x += '@'
    if attr.isdoor:
        x += '>'
    if attr.issock:
        x += '='
    if attr.ispipe:
        x += '|'

    s += col + f + bcolors.ENDC
    if CLASSIFY:
        s += bcolors.BOLD + x + bcolors.ENDC

    return s

def get_print_string_dir(path, indent=''):
    '''returns the printstring for some dir with realpath 'path'
    includes ANSI color tags
    given some indent
    '''
    s = indent
    d = os.path.basename(path)

    x = ''

    attr = get_attributes(path)
    col = bcolors.BOLD + bcolors.BLUE

    if attr.islink:
        col = bcolors.BOLD + bcolors.CYAN
        x += '@'
    if attr.isdoor:
        x += '>'
    if attr.issock:
        x += '='
    if attr.ispipe:
        x += '|'

    if x == '':
        x += '/'

    s += col + d + bcolors.ENDC

    if CLASSIFY:
        s += x

    return s

PrettyStruct = namedtuple('File', ['pretty_str', 'path'])

def print_tree(wd, level=0, indent='', indent_char=' ', last_dir=False):
    '''Returns pretty-prints tree structure starting at 'wd' i.e.:
        wd/
          |-- file1
          |-- file2*
          |-- dir@
          |-- |-- file3
          |-- |-- file4*
          |-- other_dir/
              |-- file5
              |-- file5

    on each dir the level increases by 1
    '''
    lines = []

    # take indent up to this level and add a single level of indent
    if not last_dir and level > 0:
        post_indent = indent + '|' + indent_char*2
    else:
        post_indent = indent + indent_char*2

    s = get_print_string_dir(wd, indent=indent + '|-- ')
    lines.append(PrettyStruct(s, wd))

    if level == MAX_DEPTH:
        return lines

    # with NO_RECUR flag only write top-level directory contents
    if NO_RECUR and level > 0:
        return lines

    files = []
    dirs = []

    for f in os.listdir(wd):

        if f.startswith('.'):
            if LIST_ALL == 0:
                continue

        if f.endswith('~'):
            if IGNORE_BACKUPS:
                continue

        fs = wd + '/' + f
        if os.path.isdir(fs):
            dirs.append(fs)
        elif os.path.isfile(fs):
            files.append(fs)

    if LIST_ALL == 2:
        lines.append(PrettyStruct(post_indent + '|-- .', None))
        lines.append(PrettyStruct(post_indent + '|-- ..', None))

    for f in files:
        s = get_print_string_file(f, indent=post_indent)
        lines.append(PrettyStruct(s, f))

    for d in dirs:
        last = False
        if d == dirs[-1]:
            last = True
        lines.extend(print_tree(d,
                                level=level+1,
                                indent=post_indent,
                                indent_char=indent_char,
                                last_dir=last))

    if len(dirs) == 0 and len(files) == 0:
        lines.append(PrettyStruct(post_indent + '|-- ..', None))

    return lines
<commit_msg>Make long-list output whitespace nicer<commit_after># main.py - Entry-point for `list-tree'
# author: Ben Simner
'''Implements list-tree

Attempts to imitate ls in operation and arguments, but instead displays as a tree-view
'''

import os
import time
import math
import stat
import pwd
import grp
from docopt import docopt
from collections import namedtuple

def main():
    doc = '''
Usage:
    lt [--color=<when>] [--max-depth=<depth>] [-aABFhlR] [<dir>]

Options:
    <dir>                   Directory to read from
    --color=<when>          Colorize the output, can be 'never', 'auto' or 'always' [default: always]
    --max-depth=<depth>     Maximum depth to branch to [default: 3]
    -a --all                Do not ignore entries starting with .
    -A --almost-all         Like -a except do not list implied . and ..
    -B --ignore-backups     Do not list entries ending with ~
    -F --classify           Append indicator to entries
    -h --human-readable     With -l, print human-readable sizes
    -l                      Use long-list format
    -R --no-recursive       Do not recursively print directories
'''
    args = docopt(doc)
    _main(**args)

def _main(**argv):
    cwd = os.getcwd()

    global MAX_DEPTH
    global COLOR_MODE
    global LIST_ALL
    global IGNORE_BACKUPS
    global LONG_LIST
    global HUMAN_READABLE
    global NO_RECUR
    global CLASSIFY

    MAX_DEPTH = int(argv['--max-depth'])
    COLOR_MODE = argv['--color']

    if argv['--all']:
        LIST_ALL = 2
    elif argv['--almost-all']:
        LIST_ALL = 1
    else:
        LIST_ALL = 0

    if argv['<dir>']:
        cwd = argv['<dir>']

    IGNORE_BACKUPS = argv.get('--ignore-backups', False)
    HUMAN_READABLE = argv.get('--human-readable', False)
    LONG_LIST = argv.get('-l', False)
    NO_RECUR = argv.get('--no-recursive', False)
    CLASSIFY = argv.get('--classify', False)

    if COLOR_MODE == 'never':
        bcolors.no_col()

    if LONG_LIST:
        lines = print_tree(os.path.realpath(cwd))
        print_long_list_fmt(lines)
    else:
        lines = print_tree(os.path.realpath(cwd))
        for struct in lines:
            print(struct.pretty_str)

def print_long_list_fmt(lines):
    # generate prefixes
    prefix_strs = []
    max_lens = [0]*6
    for struct in lines:
        if struct.path:
            prefixs = []
            attrs = get_attributes(struct.path)

            prefix = attrs.file_mode
            prefixs.append(prefix)
            if len(prefix) > max_lens[0]:
                max_lens[0] = len(prefix)

            prefix = str(attrs.hlink_count)
            prefixs.append(prefix)
            if len(prefix) > max_lens[1]:
                max_lens[1] = len(prefix)

            prefix = pwd.getpwuid(attrs.user_id).pw_name
            prefixs.append(prefix)
            if len(prefix) > max_lens[2]:
                max_lens[2] = len(prefix)

            prefix = grp.getgrgid(attrs.group_id).gr_name
            prefixs.append(prefix)
            if len(prefix) > max_lens[3]:
                max_lens[3] = len(prefix)

            prefix = ''
            if not HUMAN_READABLE:
                prefix += str(attrs.size) + 'B'
            else:
                if attrs.size <= 0:
                    prefix += '0B'
                else:
                    log = round(math.log(attrs.size, 10))
                    if log < 3:
                        prefix += str(attrs.size) + 'B'
                    elif log < 6:
                        prefix += '%.1f' % (attrs.size / 1024) + 'KB'
                    elif log < 9:
                        prefix += '%.1f' % (attrs.size / (1024 ** 2)) + 'MB'
                    else:
                        prefix += '%.1f' % (attrs.size / (1024 ** 3)) + 'GB'

            prefixs.append(prefix)
            if len(prefix) > max_lens[4]:
                max_lens[4] = len(prefix)

            prefix = ''
            prefix += time.strftime('%b %d %Y %H:%M', time.gmtime(attrs.last_modified))
            prefixs.append(prefix)
            if len(prefix) > max_lens[5]:
                max_lens[5] = len(prefix)

            prefix_strs.append(prefixs)
        else:
            prefix_strs.append(['', '', ''])

    for prefixs, struct in zip(prefix_strs, lines):
        prefix = ''
        for p, max_len in zip(prefixs, max_lens):
            prefix += p + ' '*(2 + max_len - len(p))
        print(prefix + ' ' + struct.pretty_str)

class bcolors:
    '''ANSI escape sequences'''
    HEADER = '\033[95m'
    CYAN = '\033[36m'
    BLUE = '\033[94m'
    GREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

    @staticmethod
    def no_col():
        '''Disables ANSI escape sequencies'''
        bcolors.HEADER = ''
        bcolors.BLUE = ''
        bcolors.GREEN = ''
        bcolors.WARNING = ''
        bcolors.FAIL = ''
        bcolors.ENDC = ''
        bcolors.BOLD = ''
        bcolors.UNDERLINE = ''

Attributes = namedtuple('FileAttributes', ['size',
                                            'executable',
                                            'file_mode',
                                            'islink',
                                            'ispipe',
                                            'isdoor',
                                            'issock',
                                            'hlink_count',
                                            'user_id',
                                            'group_id',
                                            'last_modified'])

def get_attributes(path):
    st = os.stat(path)

    return Attributes(
        st.st_size,
        os.access(path, os.X_OK),
        stat.filemode(st.st_mode),
        os.path.islink(path),
        stat.S_ISFIFO(st.st_mode),
        stat.S_ISDOOR(st.st_mode),
        stat.S_ISSOCK(st.st_mode),
        st.st_nlink,
        st.st_uid,
        st.st_gid,
        st.st_mtime
    )

def get_print_string_file(path, indent=''):
    '''returns the printstring for some file with realpath 'path'
    includes ANSI color tags
    given some indent
    '''
    s = indent + '|-- '
    f = os.path.basename(path)

    col = ''
    x = ''

    attr = get_attributes(path)

    if attr.executable:
        col = bcolors.BOLD + bcolors.GREEN
        x += '*'
    if attr.islink:
        col = bcolors.BOLD + bcolors.CYAN
        x += '@'
    if attr.isdoor:
        x += '>'
    if attr.issock:
        x += '='
    if attr.ispipe:
        x += '|'

    s += col + f + bcolors.ENDC
    if CLASSIFY:
        s += bcolors.BOLD + x + bcolors.ENDC

    return s

def get_print_string_dir(path, indent=''):
    '''returns the printstring for some dir with realpath 'path'
    includes ANSI color tags
    given some indent
    '''
    s = indent
    d = os.path.basename(path)

    x = ''

    attr = get_attributes(path)
    col = bcolors.BOLD + bcolors.BLUE

    if attr.islink:
        col = bcolors.BOLD + bcolors.CYAN
        x += '@'
    if attr.isdoor:
        x += '>'
    if attr.issock:
        x += '='
    if attr.ispipe:
        x += '|'

    if x == '':
        x += '/'

    s += col + d + bcolors.ENDC

    if CLASSIFY:
        s += x

    return s

PrettyStruct = namedtuple('File', ['pretty_str', 'path'])

def print_tree(wd, level=0, indent='', indent_char=' ', last_dir=False):
    '''Returns pretty-prints tree structure starting at 'wd' i.e.:
        wd/
          |-- file1
          |-- file2*
          |-- dir@
          |-- |-- file3
          |-- |-- file4*
          |-- other_dir/
              |-- file5
              |-- file5

    on each dir the level increases by 1
    '''
    lines = []

    # take indent up to this level and add a single level of indent
    if not last_dir and level > 0:
        post_indent = indent + '|' + indent_char*2
    else:
        post_indent = indent + indent_char*2

    s = get_print_string_dir(wd, indent=indent + '|-- ')
    lines.append(PrettyStruct(s, wd))

    if level == MAX_DEPTH:
        return lines

    # with NO_RECUR flag only write top-level directory contents
    if NO_RECUR and level > 0:
        return lines

    files = []
    dirs = []

    for f in os.listdir(wd):

        if f.startswith('.'):
            if LIST_ALL == 0:
                continue

        if f.endswith('~'):
            if IGNORE_BACKUPS:
                continue

        fs = wd + '/' + f
        if os.path.isdir(fs):
            dirs.append(fs)
        elif os.path.isfile(fs):
            files.append(fs)

    if LIST_ALL == 2:
        lines.append(PrettyStruct(post_indent + '|-- .', None))
        lines.append(PrettyStruct(post_indent + '|-- ..', None))

    for f in files:
        s = get_print_string_file(f, indent=post_indent)
        lines.append(PrettyStruct(s, f))

    for d in dirs:
        last = False
        if d == dirs[-1]:
            last = True
        lines.extend(print_tree(d,
                                level=level+1,
                                indent=post_indent,
                                indent_char=indent_char,
                                last_dir=last))

    if len(dirs) == 0 and len(files) == 0:
        lines.append(PrettyStruct(post_indent + '|-- ..', None))

    return lines
<|endoftext|>


<commit_before>#!/usr/bin/python

import sys, os
from lib import *
from pprint import pprint

def authorize_from_config(filename):
    c = config.app_config(filename)
    return authorize.authorize(c['key'], c['secret'], c['callback'])

def usage():
    print('usage: ./tumb_borg.py <blogname> <filename> [<config-filename>]')
    print('to see what would be posted: ./tumb_borg.py <filenames>')
    sys.exit(1)

def validate_arguments(argv):
    if len(argv) < 3 \
    and (len (argv) is 1 and not os.path.exists(argv[1])):
        usage()

# generator for poems from a filename
def poems_from_file(filename):
    return (process.to_dictionary(poem) \
            for poem \
            in process.generate_poems(filename))

# ./tumb_borg.py <blogname> <filename> [<config-filename>]
def batch_post_poems(blogname, filename, setting):
    def get_batch_tags(filename):
        c = config.app_config(filename)
        return c['batch-tags']

    batch = get_batch_tags(os.path.realpath(setting))
    auth  = authorize_from_config( \
            os.path.realpath(setting))
    # store the key for now TODO: implement
    # store(app_config())
    # check that the user can post to this blog TODO: implement
    # post poems
    def post_poems(auth,    \
            ident,          \
            poem_generator, \
            BATCH="poem, poetry, spilled ink"):
        def queue_text_post(payload):
            return { 'type': 'text',
                    'state': 'queue',
                    'tags':  ', '.join(payload['tags']) + ", " + BATCH,
                    'body':  '\n'.join(payload['content']),
                    'title': '// %s' % payload['title'] }
        for poem in (queue_text_post(p) for p in poem_generator):
            print(poem)
            print(auth.post('blog/%s/post' % ident, \
                    params=poem))
    post_poems(auth, \
            blogname, \
            poems_from_file(filename), \
            batch
            )

if __name__ == "__main__":
    validate_arguments(sys.argv)

    if len(sys.argv) < 3:
        print('Found the following poems:')
        for poem in poems_from_file( \
                os.path.realpath(sys.argv[1])):
            interactive.print_poem_full(poem)
    else:
        # ./tumb_borg.py <blogname> <filename> [<settings-file>]
        if len(sys.argv) < 4: # TODO: Make this default argument-able
            settings = 'app.secret.yml'
        else:
            settings = sys.argv[3]
        batch_post_poems(sys.argv[1], sys.argv[2], settings)

    print('Finished!')
<commit_msg>add first layer saving technologies<commit_after>#!/usr/bin/python

import sys, os
from lib import *
from pprint import pprint

def authorize_from_config(filename):
    c = config.app_config(filename)
    return authorize.authorize(c['key'], c['secret'], c['callback'])

def usage():
    print('usage: ./tumb_borg.py <blogname> <filename> [<config-filename>]')
    print('to see what would be posted: ./tumb_borg.py <filenames>')
    sys.exit(1)

def validate_arguments(argv):
    if len(argv) < 3 \
    and (len (argv) is 1 and not os.path.exists(argv[1])):
        usage()

# generator for poems from a filename
def poems_from_file(filename):
    return (process.to_dictionary(poem) \
            for poem \
            in process.generate_poems(filename))

# ./tumb_borg.py <blogname> <filename> [<config-filename>]
def batch_post_poems(blogname, filename, setting):
    def get_batch_tags(filename):
        c = config.app_config(filename)
        return c['batch-tags']

    batch = get_batch_tags(os.path.realpath(setting))
    auth  = authorize_from_config( \
            os.path.realpath(setting))
    # store the key for now TODO: implement
    # store(app_config())
    # check that the user can post to this blog TODO: implement
    # post poems
    def post_poems(auth,    \
            ident,          \
            poem_generator, \
            BATCH="poem, poetry, spilled ink"):
        def queue_text_post(payload):
            return { 'type': 'text',
                    'state': 'queue',
                    'tags':  ', '.join(payload['tags']) + ", " + BATCH,
                    'body':  '\n'.join(payload['content']),
                    'title': '// %s' % payload['title'] }
        for poem in (queue_text_post(p) for p in poem_generator):
            print(poem)
            print(auth.post('blog/%s/post' % ident, \
                    params=poem))
    post_poems(auth, \
            blogname, \
            poems_from_file(filename), \
            batch
            )

if __name__ == "__main__":
    validate_arguments(sys.argv)

    if len(sys.argv) < 3:
        print('Found the following poems:')
        poems = poems_from_file(os.path.realpath(sys.argv[1]))
        for poem in poems:
            interactive.print_poem_full(poem)
        poems = poems_from_file(os.path.realpath(sys.argv[1]))
        interactive.save_poems('test.txt', poems)
    else:
        # ./tumb_borg.py <blogname> <filename> [<settings-file>]
        if len(sys.argv) < 4: # TODO: Make this default argument-able
            settings = 'app.secret.yml'
        else:
            settings = sys.argv[3]
        batch_post_poems(sys.argv[1], sys.argv[2], settings)

    print('Finished!')
<|endoftext|>