Examples

example

# -*- coding: utf-8 -*-
__doc__ = """Generate this page"""
from chut import *  # noqa

TEMPLATE = '''
%(binary)s
=========================================================

.. literalinclude:: ../chut/examples/%(filename)s
   :language: python

Get standalone `%(binary)s <_static/binaries/%(binary)s>`_

'''


@console_script
def example(args):
    fd = open('docs/examples.rst', 'w')
    fd.write((
        '==========================\n'
        'Examples\n'
        '==========================\n\n'))
    for filename in sorted(find('chut/examples -name *.py')):
        try:
            scripts = list(grep('-A1 -E @.*console_script', filename))
        except OSError:
            continue
        if not scripts:
            continue
        filename = path.basename(filename)
        scripts = [s[4:].split('(')[0] for s in scripts if s[0] != '@']
        binary = scripts[0].replace('_', '-')
        fd.write(TEMPLATE % dict(filename=filename, binary=binary))
    fd.close()

Get standalone example

github-clone

# -*- coding: utf-8 -*-
from chut import *


@console_script
def github_clone(args):
    """Usage: %prog [<user>]

    Clone all github repository for a user using ssh
    """
    user = args['<user>'] or 'gawel'
    page = wget('-O- https://github.com/%s?tab=repositories' % user)
    for line in page | grep('href="/%s/' % user) | grep('-v title='):
        repo = line.split('"')[1]
        name = repo.split('/', 1)[-1]
        if not test.d(name) and name not in ('followers', 'following'):
            try:
                git('clone', 'git@github.com:%s' % repo.strip('/')) > 1
            except OSError:
                pass

if __name__ == '__main__':
    github_clone()

Get standalone github-clone

rfsync

# -*- coding: utf-8 -*-
from chut import *  # NOQA
import sys


@console_script(fmt='msg')
def rfsync(args):
    """
    Usage: %prog [-p] <host>:<path> [-- <find_options>...]
           %prog [-] [<destination>] [-- <rsync_options>...]
           %prog -h

    Find some files on a remote server and sync them on a local directory using
    rsync

    Examples:

        $ rfsync gawel@example.com:~/ -- -name "*.avi" | rfsync
        $ rfsync gawel@example.com:~/ -- -size +100M | rfsync ~/Movies -- -q

    """
    remote = args.get('<host>:<path>')
    if remote not in (None, '-') and ':' in remote:
        host, p = remote.split(':')
        srv = ssh(host)
        options = []
        for a in args.get('<find_options>', []) or []:
            if '*' in a:
                a = '"%s"' % a
            options.append(a)
        options = ' '.join(options)
        done = set()
        for line in srv.find(p, options, shell=True):
            line = line.strip()
            if args['-p']:
                line = path.dirname(line)
            if line not in done:
                done.add(line)
                print(srv.join(line))
    else:
        destination = args['<host>:<path>'] or args['<destination>'] or '.'
        destination = path.expanduser(path.expandvars(destination))
        options = ' '.join(args.get('<rsync_options>', [])) or '-aP'
        targets = sys.stdin.readlines()
        targets = [t.strip('\n/') for t in targets]
        targets = [t.strip('/ ') for t in targets if t.strip('/ ')]
        targets = sorted(set(targets))
        if not targets:
            return 1
        if '-q' not in options:
            info('$ rsync %s \\\n\t%s \\\n\t%s',
                 options,
                 ' \\\n\t'.join(targets),
                 destination)
        rsync(options, ' '.join(targets), destination, shell=True) > 1

Get standalone rfsync

ssh-copy-id

from chut import * # NOQA


@console_script
def ssh_copy_id(args):
    """
    Usage: %prog <host>
           %prog <pubkey> <host>
    """
    stdin = None
    pubkey = args['<pubkey>']

    if not pubkey and env.SSH_AUTH_SOCK:
        ret = str(sh['ssh-add']('-L', combine_stderr=True))
        if ret.succeeded:
            stdin = stdin(ret.strip() + '\n')

    if stdin is None:
        if not pubkey:
            pubkey = path.expanduser('~/.ssh/id_rsa.pub')
        if not test.e(pubkey):
            print('Cant find a valid key')
            return 1
        stdin = cat(pubkey)

    srv = ssh(args['<host>'])
    if stdin | srv(("umask 077; test -d .ssh || mkdir .ssh;"
                    "cat >> .ssh/authorized_keys")):
        print('Key added to %s' % (args['<host>'],))
        print('Trying to cat %s~/.ssh/authorized_keys...' % srv)
        srv.cat('~/.ssh/authorized_keys') | tail('-n1') > 1
        return 0
    print('Failed to add key')
    return 1

if __name__ == '__main__':
    ssh_copy_id()

Get standalone ssh-copy-id

ssh-mount

# -*- coding: utf-8 -*-
from chut import *  # noqa

__version__ = "0.17"


@console_script(fmt='msg')
def ssh_mount(args):
    """
    Usage: %prog [options] [<server>] [<mountpoint>]

    Use sshfs/fusermount to mount/umount your remote servers

    By default ~ is mounted but you can set the mountpoints in ~/.ssh/sshfs:

    [mountpoints]
    myserver = ./path

    Options:
    -u, --umount        Umount
    %options
    """
    env.lc_all = 'C'
    server = args['<server>']
    if not server:
        if not args['--umount']:
            sh.mount() | grep('--color=never fuse.sshfs') > 1
        else:
            for line in sh.mount() | grep('--color=never fuse.sshfs'):
                dirname = line.split(' ')[2]
                info('umount %s', dirname)
                sh.fusermount('-u', dirname) > 0
        return 0
    dirname = path.expanduser('~/mnt/%s' % server)
    if sh.mount() | grep(dirname):
        info('umount %s', dirname)
        sh.fusermount('-u', dirname) > 0
    if args['--umount']:
        return 0
    if not test.d(dirname):
        mkdir('-p', dirname)
    cfg = ini('~/.ssh/sshfs')
    mountpoint = '%s:%s' % (
        server,
        args['<mountpoint>'] or cfg['mountpoints'][server] or '.'
    )
    info('mount %s to %s', mountpoint, dirname)
    sh.sshfs(mountpoint, dirname) > 1

Get standalone ssh-mount

safe-upgrade

# -*- coding: utf-8 -*-
from chut import * # noqa


@console_script
def safe_upgrade(args):
    """Usage: %prog

    Update && upgrade a debian based system
    """
    sudo.aptitude('update') > 1
    sudo.aptitude('safe-upgrade') > 1

Get standalone safe-upgrade

translate

# -*- coding: utf-8 -*-
from chut import *  # NOQA
import atexit
import six
import sys
import os

__version__ = "0.17"

__doc__ = """
Usage: %prog [options] [-] [<text>...]

This script use chut and casperjs to build an interactive translator

Examples:

    $ echo "hello" | translate -
    $ translate -l fr:en bonjour
    $ translate -i

Options:

    -l LANGS, --langs=LANGS     Langs [default: en:fr]
    -i, --interactive           Translate line by line in interactive mode
    -h, --help                  Show this help
    %options
"""

SCRIPT = six.b("""
system = require('system')
require('casper').create()
  .start('http://translate.google.com/#' + system.env['TR_PAIR'], function(){
      this.fill('form#gt-form', {text: system.env['TR_TEXT']}, false)})
  .waitForSelector('span.hps', function() {
      this.echo(this.fetchText('#result_box'))
      results = this.evaluate(function() {
          results = document.querySelectorAll('table.gt-baf-table tr')
          return Array.prototype.map.call(results, function(e) {
              if (!/colspan/.exec(e.innerHTML))
                  return e.innerText.replace(/\\n/,': ')
              else
                  return ''
          })
      })
      this.echo(results.join(''))
}).run()
""")


@console_script(doc=__doc__)
def translate(args):
    if not which('casperjs'):
        print('You must install casperjs first')
        return 1
    env.tr_pair = args['--langs'].replace(':', '|')
    script = str(mktemp('--tmpdir translate-XXXX.js'))
    atexit.register(rm(script))
    stdin(SCRIPT) > script

    def show_result():
        try:
            for line in sh.casperjs(script):
                if line:
                    if ':' in line:
                        line = '- ' + line
                    print(line)
        except:
            pass

    if args['--interactive'] or not (args['-'] or args['<text>']):
        import readline
        hist = os.path.join(os.path.expanduser('~'), '.translate_history')
        if test.f(hist):
            readline.read_history_file(hist)
        atexit.register(readline.write_history_file, hist)
        while True:
            try:
                tr_text = six.moves.input('%s: ' % env.tr_pair)
                tr_text = tr_text.strip()
            except KeyboardInterrupt:
                return
            else:
                if tr_text == 'q':
                    return
                elif tr_text == 's':
                    env.tr_pair = '|'.join(reversed(env.tr_pair.split('|')))
                elif tr_text.startswith(('lang ', 'l ')):
                    tr_pair = tr_text.split(' ', 1)[1]
                    env.tr_pair = tr_pair.replace(':', '|').strip()
                elif tr_text:
                    env.tr_text = tr_text
                    show_result()
    elif args['-']:
        env.tr_text = sys.stdin.read()
    elif args['<text>']:
        env.tr_text = ' '.join(args['<text>'])
    show_result()

if __name__ == '__main__':
    translate()

Get standalone translate

vlserie

# -*- coding: utf-8 -*-
from chut import *  # noqa
import shutil
import sys
import re

__version__ = "0.17"

_episode = re.compile(
    r'[^0-9]+(?P<s>[0-9]+)\s*(x|e|episode)\s*(?P<e>[0-9]+)[^0-9]+')


def extract_numbers(f):
    m = _episode.search(f.lower())
    if m:
        m = m.groupdict()
        return int(m['s']), int(m['e'])


@console_script(fmt='brief')
def vlserie(args):
    """
    Usage: %prog [options] [<season> <episode>]

    Play the serie contained in the current folder. File names should be
    formated like SXXEXX. Also load subtitles if any.

    Store the latest play in ~/.vlserie. So you dont have to remember it
    yourself.

    Require vlc or mplayer.

    Options:

    -s TIME, --start=TIME   Start at (float)
    -l, --latest            Play latest instead of next
    -f, --freeplayer        Play in freeplayer
    --loop                  Loop over episodes
    %options
    """

    config = ini('~/.vlserie')
    config.write()

    player = config.player.binary or 'vlc'
    player_opts = config[player]
    if env.display:
        options = player_opts.xoptions
    else:
        options = player_opts.fboptions
    if args['--start']:
        options += ' --start-time ' + args['--start']
    debug('Using %s player', player)

    pwd = path.abspath('.')

    def play(filename, episode):
        filename = path.abspath(filename)
        dirname, filename = path.split(filename)
        cd(dirname)
        if args['--freeplayer']:
            cmdline = (
                "%s %r --play-and-exit --sout "
                "'#transcode{vcodec=mp2v,vb=4096,scale=1,audio-sync,soverlay}:"
                "duplicate{dst=std{access=udp,mux=ts,dst=212.27.38.253:1234}}'"
            ) % (options, filename)
        elif player in ('vlc', 'cvlc'):
            cmdline = (
                '%s -f --play-and-exit --qt-minimal-view %r'
            ) % (options, filename)
        elif player == 'mplayer':
            cmdline = '%s -fs %r' % (options, filename)
        else:
            error('Unknown player %r', player)
            sys.exit(1)
        srts = find(pwd, '-iregex ".*%s\(x\|E\)%02i.*srt"' % episode,
                    shell=True)
        for srt in sorted(srts):
            if '  ' in srt:
                new = srt.replace('  ', ' ')
                shutil.move(srt, new)
                srt = new
            if player in ('vlc', 'cvlc'):
                cmdline += ' --sub-file %r' % srt
            elif player == 'mplayer':
                cmdline += ' -sub %r' % srt
        subs = find(pwd, '-iregex ".*%s\(x\|E\)%02i.*sub"' % episode,
                    shell=True)
        for sub in sorted(subs):
            if player == 'mplayer':
                sub = sub.lstrip('./')
                cmdline += ' -vobsub %r' % sub[:-4]
        cmd = sh[player](cmdline, combine_stderr=True, shell=True)
        info(repr(cmd))
        serie = config[pwd]
        serie.latest = filename
        config.write()
        try:
            cmd > 1
        except OSError:
            pass
        if not args['--loop']:
            sys.exit(0)

    serie = config[pwd]

    filenames = find(
        ('. -iregex '
         '".*[0-9]+\s*\(e\|x\|episode\)\s*[0-9]+.*'
         '\(avi\|wmv\|mkv\|mp4\)"'),
        shell=True)
    filenames = [path.abspath(f) for f in filenames]
    filenames = sorted([(extract_numbers(f), f) for f in filenames])
    filenames = [(e, f) for e, f in filenames if f is not None]

    if args['<season>']:
        episode = int(args['<season>']), int(args['<episode>'])
        filenames = [(x, f) for x, f in filenames if x >= episode]
    elif serie.latest:
        episode = extract_numbers(serie.latest.lower())
        if args['--latest']:
            filenames = [(x, f) for x, f in filenames if x >= episode]
        else:
            filenames = [(x, f) for x, f in filenames if x > episode]

    for episode, filename in filenames:
        play(filename, episode)


@console_script(fmt='brief')
def freeplayer(args):
    """Usage: %prog [options] [<stream>]

    -s      Serve freeplayer page
    """
    if args["-s"]:
        with open('/tmp/settings.html', 'w') as fd:
            fd.write(settings)
        nc('-l -p 8080 -q 1 < /tmp/settings.html', shell=True) > 0
        info('freeplayer initialized')
        return
    stream = args['<stream>']
    if stream.startswith('https://'):
        stream.replace('https://', 'http://')
    cmdline = (
        "%r --play-and-exit --sout "
        "'#transcode{vcodec=mp2v,vb=4096,scale=1,audio-sync,soverlay}:"
        "duplicate{dst=std{access=udp,mux=ts,dst=212.27.38.253:1234}}'"
    ) % stream
    cmd = sh['vlc'](cmdline, combine_stderr=True, shell=True)
    info(repr(cmd))
    cmd > 1

settings = '''HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n
<html><body background="ts://127.0.0.1"></body></html>'''

Get standalone vlserie

webapp

# -*- coding: utf-8 -*-
from chut import * # noqa
requires('webob', 'waitress')
import webob


def application(environ, start_response):
    req = webob.Request(environ)
    resp = webob.Response()
    resp.text = req.path_info
    return resp(environ, start_response)


@console_script
def webapp(args):
    """
    Usage: %prog [--upgrade-deps]
    """
    serve(application, port=4000)

Get standalone webapp