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.18"
@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.18"
__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.18"
_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(e(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(e(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