# HG changeset patch # User Jeff Hammel # Date 1435702692 25200 # Node ID a2d199008a837f12a9d37467448346c7b6c70d5c # Parent 25622fb5906d54f2c0feab69bdb44896e9dced76# Parent eec5b7abff2bd5fa4b7715f876d1f8ff1ce93578 wtf diff -r 25622fb5906d -r a2d199008a83 .bashrc --- a/.bashrc Wed May 27 15:55:29 2015 -0700 +++ b/.bashrc Tue Jun 30 15:18:12 2015 -0700 @@ -463,20 +463,6 @@ ### functions for version control systems -svndance(){ -# do the svn import dance! -if (( $# )) -then - svn import $1 - cd .. - rm -rf $OLDPWD - svn co $1 $OLDPWD - cd $OLDPWD -else - return 1 -fi -} - difffiles() { # which files are diffed; could use `lsdiff` grep '^+++ ' $@ | sed 's/+++ b\///' @@ -492,12 +478,6 @@ combinediff <(git diff) <(git diff --cached) } -hg-add-commit() { - # add a file + commit - MESSAGE=$(hg add $@) - hg commit -m "${MESSAGE}" -} - hg-update-all() { # update all hg repositories in the current directory for i in *; @@ -607,16 +587,7 @@ ### include overrides for commands source ~/.bash_overrides -### cognet customizations -export BASTION_SERVER=bastion-east-1c.cognet.tv -export BASTION_USER=jhammel -export KEYS_DIR=/home/jhammel/.ssh -COGNET_BASHRC=~/cognet/bin/.bashrc -if [ -e "${COGNET_BASHRC}" ] -then - . ${COGNET_BASHRC} -fi - +### deactivate any virtualenvs if type deactivate &> /dev/null then deactivate diff -r 25622fb5906d -r a2d199008a83 .fluxbox/keys --- a/.fluxbox/keys Wed May 27 15:55:29 2015 -0700 +++ b/.fluxbox/keys Tue Jun 30 15:18:12 2015 -0700 @@ -78,6 +78,7 @@ Control Mod1 v :ExecCommand xterm -e '/home/jhammel/k0s/bin/textshaper -c -i' Control Mod1 x :ExecCommand xkill Control Mod1 y :ExecCommand /home/jhammel/python/pypi.py "$(xclip -o)"| xclip -i # pypi package summary +Control Mod1 z :ExecCommand xzoom Control Mod1 0 :ExecCommand xclip -o | sed 's/^[-+]//' | xclip -i # strip leading +s Control Shift / :ExecCommand /home/jhammel/bin/keyshelp.sh # hotkeys help @@ -88,7 +89,6 @@ # v: ? # w: ? # y: ? -# z: zoom? # `l` could go to launch to free up `s` # alternately, `l` -> `local resource`, diff -r 25622fb5906d -r a2d199008a83 bin/log.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/log.sh Tue Jun 30 15:18:12 2015 -0700 @@ -0,0 +1,13 @@ +#!/bin/bash + +BASEDIR=${HOME}/cisco/log +STAMP=$(date +"%Y%m%d") +FILENAME="${BASEDIR}/${STAMP}.txt" + +if [[ -e "${FILENAME}" ]] +then + echo "emacs -nw +`wc -l ${FILENAME}` ${FILENAME}" + emacs -nw +`wc -l "${FILENAME}"` +else + emacs -nw ${FILENAME} +fi diff -r 25622fb5906d -r a2d199008a83 bin/tofile.sh --- a/bin/tofile.sh Wed May 27 15:55:29 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -/home/jhammel/docs/projects/ims/workflow/tofile.sh \ No newline at end of file diff -r 25622fb5906d -r a2d199008a83 python/example/sendmail.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/example/sendmail.py Tue Jun 30 15:18:12 2015 -0700 @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" + +See: +- http://pymotw.com/2/smtplib/ +- http://www.mkyong.com/python/how-do-send-email-in-python-via-smtplib/ +- https://github.com/CognitiveNetworks/daily-reports/blob/master/send_added_tv_count.py +""" + +import argparse +import email.utils +import os +import smtplib +import sys +from email.mime.text import MIMEText + +__all__ = ['main'] + +class MailSender(object): + + def __init__(self, host, sender, password, port=587, type='plain'): + self.host = host + self.sender = sender + self.password = password + self.port = port + self.type = type + + def __call__(self, message, *recipients, **headers): + + assert recipients + + # construct the message + msg = MIMEText(message, self.type) + headers.setdefault('From', self.sender) + headers.setdefault('To', ','.join(recipients)) + for key, value in headers.items(): + msg[key] = value + + # connect to mail server + server = smtplib.SMTP(self.host, self.port) + try: + server.set_debuglevel(True) + + # identify ourselves, prompting server for supported features + server.ehlo() + + # If we can encrypt this session, do it + if server.has_extn('STARTTLS'): + server.starttls() + server.ehlo() # re-identify ourselves over TLS connection + + # login + server.login(self.sender, self.password) + + # send the email + server.sendmail(self.sender, recipients, msg.as_string()) + finally: + server.quit() + +def main(args=sys.argv[1:]): + + # parse command line + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('host') + parser.add_argument('sender') + parser.add_argument('password') + parser.add_argument('-r', '--recipients', dest='recipients', + nargs='+', required=True, + help="recipients") + parser.add_argument('-m', '--message', dest='message', required=True) + parser.add_argument('--port', dest='port', type=int, default=587, + help="port to connect to [DEFAULT: %(default)s]") + options = parser.parse_args(args) + + message = options.message + + # instantiate sender + sender = MailSender(options.host, options.sender, options.password, options.port) + + # send email + sender(message, *options.recipients) + + +if __name__ == '__main__': + main() diff -r 25622fb5906d -r a2d199008a83 python/example/slice.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/example/slice.py Tue Jun 30 15:18:12 2015 -0700 @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +slice a arbitrarily sized list +""" + +# imports +import argparse +import os +import subprocess +import sys + +__all__ = ['slice', 'main', 'Parser'] + +def slice(container, n_chunks): + size = int(len(container)/(n_chunks-1)) + retval = [] + start = 0 + for i in range(n_chunks-1): + retval.append(container[start:start+size]) + start += size + retval.append(container[start:]) + return retval + +class Parser(argparse.ArgumentParser): + """CLI option parser""" + def __init__(self, **kwargs): + kwargs.setdefault('description', __doc__) + argparse.ArgumentParser.__init__(self, **kwargs) + self.add_argument('N', type=int, + help="number of chunks") + self.add_argument('-M', '--len', dest='length', type=int, default=29, + help="length of list [DEFAULT: %(default)s]") + self.options = None + + def parse_args(self, *args, **kw): + options = argparse.ArgumentParser.parse_args(self, *args, **kw) + self.validate(options) + self.options = options + return options + + def validate(self, options): + """validate options""" + +def main(args=sys.argv[1:]): + """CLI""" + + # parse command line options + parser = Parser() + options = parser.parse_args(args) + + # generate list + seq = range(options.length) + + # chunk list + output = slice(seq, options.N) + + # print output + for chunk in output: + print (",".join([str(i) for i in chunk])) + +if __name__ == '__main__': + main() + diff -r 25622fb5906d -r a2d199008a83 python/ffslice.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ffslice.py Tue Jun 30 15:18:12 2015 -0700 @@ -0,0 +1,168 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +slice a clip with `ffmpeg`: + +ffmpeg -ss <00:00:00> -t -i -q 1 # + +--ss = start time ; + +-t = length of video to create from the start time in seconds. +""" + +# imports +import argparse +import os +import subprocess +import sys + +# module globals +__all__ = ['main', 'Parser'] +here = os.path.dirname(os.path.realpath(__file__)) +string = (str, unicode) + + +def ensure_dir(directory): + """ensure a directory exists""" + if os.path.exists(directory): + assert os.path.isdir(directory) + return directory + os.makedirs(directory) + return directory + + +def convert_seconds_to_hhmmss(time_sec): + """converts `time_sec` to (hh,mm,ss)""" + + hh = int(time_sec / 3600) + mm = int((time_sec % 3600) / 60) + ss = int((time_sec % 3600) % 60) + return (hh,mm,ss) + + +def format_seconds_to_hhmmss(time_sec, separator=':'): + """converts `time_sec` to string 'hh:mm:ss'""" + return separator.join(['{:0>2d}'.format(i) + for i in convert_seconds_to_hhmmss(time_sec)]) + + +def duration(clip, ffprobe='ffprobe'): + """get the duration in seconds using `ffprobe` from ffmpeg""" + + command = [ffprobe, clip] + assert os.path.exists(clip), "Missing clip, duration not available" + + # probe the file + try: + output = subprocess.check_output(command, stderr=subprocess.STDOUT) + # (for some reason, ffprobe sends output to stderr) + except subprocess.CalledProcessError as e: + print (e.output) + raise + + duration = None + for line in output.splitlines(): + # Parse the output of `ffprobe` + # look for a line like: + # Duration: 00:00:59.73, start: 0.000000, bitrate: 7783 kb/s + + line = line.strip() + if line.startswith("Duration:"): + if duration: + raise AssertionError("Duplicate duration - already found: {}".format(duration)) + line = line.split(',')[0] + duration = line.split(':', 1)[1].strip() + + if duration: + hh, mm, ss = [float(i) for i in duration.split(':')] + duration = 3600*hh + 60*mm + ss + + return duration + + +class FFSliceParser(argparse.ArgumentParser): + """fflice CLI option parser""" + + default_slice_time = 300. + + def __init__(self): + argparse.ArgumentParser.__init__(self, description=__doc__) + self.add_argument('clips', metavar='clip', nargs='+', help="clips to slice") + self.add_argument('-d', '--directory', dest='directory', + default=os.getcwd(), + help="output directory [DEFAULT: %(default)s]") + self.add_argument('--durations', '--print-durations', dest='print_durations', + action='store_true', default=False, + help="print durations and exit") + self.add_argument('-n', dest='number', type=int, + help="number of slices") + self.add_argument('-t', '--time', dest='slice_time', + type=float, + help="time of each slice [DEFAULT: {}]".format(self.default_slice_time)) + self.add_argument('--dry-run', dest='dry_run', + action='store_true', default=False, + help="print out what will be done") + self.add_argument('--hhmmss', dest='hhmmss', + action='store_true', default=False, + help="display times in 'hh:mm:ss' format; thedefault is in seconds") + + self.add_argument('-v', '--verbose', dest='verbose', + action='store_true', default=False, + help="be verbose") + self.options = None + + def parse_args(self, *args, **kw): + options = argparse.ArgumentParser.parse_args(self, *args, **kw) + self.validate(options) + self.options = options + return options + + def validate(self, options): + """validate options""" + + missing = [clip for clip in options.clips + if not os.path.exists(clip)] + if missing: + self.error("Not found: {}".format(', '.join(missing))) + + if options.slice_time and options.number: + self.error("Cannot specify slice time and number of slices") + # TODO: allow specification of both + elif options.slice_time is None and options.number is None: + options.slice_time = self.default_slice_time + + ensure_dir(options.directory) + + def format_seconds(self, seconds): + """format seconds to string""" + if self.options.hhmmss: + return format_seconds_to_hhmmss(seconds) + return '{:.2}'.format(seconds) + + +def main(args=sys.argv[1:]): + """CLI""" + + # parse command line options + parser = FFSliceParser() + options = parser.parse_args(args) + + # compute durations + durations = {clip: duration(clip) for clip in options.clips} + if options.print_durations: + returncode = 0 + total = 0. + for clip in options.clips: + _duration = durations[clip] + if _duration is None: + print ("Duration not found: '{}'".format(clip)) + returncode = 1 + else: + print ('{} : {}'.format(clip, + parser.format_seconds(_duration))) + sys.exit(returncode) + +if __name__ == '__main__': + main() + diff -r 25622fb5906d -r a2d199008a83 python/slice.py --- a/python/slice.py Wed May 27 15:55:29 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -slice a arbitrarily sized list -""" - -# imports -import argparse -import os -import subprocess -import sys - -__all__ = ['slice', 'main', 'Parser'] - -def slice(container, n_chunks): - size = int(len(container)/(n_chunks-1)) - retval = [] - start = 0 - for i in range(n_chunks-1): - retval.append(container[start:start+size]) - start += size - retval.append(container[start:]) - return retval - -class Parser(argparse.ArgumentParser): - """CLI option parser""" - def __init__(self, **kwargs): - kwargs.setdefault('description', __doc__) - argparse.ArgumentParser.__init__(self, **kwargs) - self.add_argument('N', type=int, - help="number of chunks") - self.add_argument('-M', '--len', dest='length', type=int, default=29, - help="length of list [DEFAULT: %(default)s]") - self.options = None - - def parse_args(self, *args, **kw): - options = argparse.ArgumentParser.parse_args(self, *args, **kw) - self.validate(options) - self.options = options - return options - - def validate(self, options): - """validate options""" - -def main(args=sys.argv[1:]): - """CLI""" - - # parse command line options - parser = Parser() - options = parser.parse_args(args) - - # generate list - seq = range(options.length) - - # chunk list - output = slice(seq, options.N) - - # print output - for chunk in output: - print (",".join([str(i) for i in chunk])) - -if __name__ == '__main__': - main() -