diff options
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/androidbackup.sh | 143 | ||||
-rwxr-xr-x | bin/atmux | 122 | ||||
-rwxr-xr-x | bin/autostart | 4 | ||||
-rw-r--r-- | bin/backup-profiles | 10 | ||||
-rwxr-xr-x | bin/functions.sh | 176 | ||||
-rwxr-xr-x | bin/helloworld.sh | 2 | ||||
-rw-r--r-- | bin/letter | 71 | ||||
-rwxr-xr-x | bin/mirssi | 12 | ||||
-rw-r--r-- | bin/mpc | 38 | ||||
-rwxr-xr-x | bin/notify_irssi_server.pl | 62 | ||||
-rwxr-xr-x | bin/notify_mpd | 45 | ||||
-rwxr-xr-x | bin/run_once | 4 | ||||
-rwxr-xr-x | bin/scvim-test | 7 | ||||
-rwxr-xr-x | bin/set_volume | 50 | ||||
-rw-r--r-- | bin/stikked | 115 | ||||
-rw-r--r-- | bin/supercollider.vim | 347 | ||||
-rw-r--r-- | bin/syncmpdpl | 209 | ||||
-rwxr-xr-x | bin/tmux-test | 53 | ||||
-rw-r--r-- | bin/torrentSort.py | 220 |
19 files changed, 1690 insertions, 0 deletions
diff --git a/bin/androidbackup.sh b/bin/androidbackup.sh new file mode 100755 index 0000000..ee95f01 --- /dev/null +++ b/bin/androidbackup.sh @@ -0,0 +1,143 @@ +#!/bin/bash + +if [ -e $HOME/bin/functions.sh ] +then + . $HOME/bin/functions.sh +else + exit 0 +fi + +## CONFIGURATION +ADB=adb + +function help() +{ + echo "Android data backup/restore" + echo "Usage:" + echo -e "\t [backup|restoredata|restoreapk] [device]" + exit 0 +} + +function _backup() +{ + adb -s $DEVICE pull /data/system/packages.list . + cat packages.list | while read line + do + read name dir <<< $(echo $line | awk '{ print $1 " " $4 }') + #echo $dir + apk=$($ADB shell bash -c "ls /data/app/${name}* 2> /dev/null") + if [ -n $exists ] + then + echo $name $apk + else + echo LALALALALAAA $name + fi + echo "" + done +} + +function _restoreapk() { + mkdir -p done skipped + apps=$(ls -1 | grep -c apk) + num=1 + for i in *.apk + do + if [ $i = "done" -o $i = "skipped" ] + then + continue + fi + echo_green "Application $i ($num/$apps)" + + name=$(echo $i | sed 's/-[0-9].apk//') + existing=$($ADB shell sh -c "ls /data/app*/${name}* 2> /dev/null") + echo $existing + if [ -n "$existing" ] + then + echo $i already installed + mv $i skipped + continue + fi + echo " Restore apk? [1|0] (default 1)" + echo -en " " + read inst + inst=${inst:=1} + + if [ $inst -eq 1 ] + then + $ADB install $i + mv $i done + else + echo -e " Skipping...\n\n" + mv $i skipped + fi + let num=num+1 + done +} + +function _restoredata() +{ + mkdir -p done skipped + apps=$(ls -l | grep -v skipped | grep -v done | grep -c '^d') + num=1 + for i in * + do + if [ $i = "done" -o $i = "skipped" ] + then + continue + fi + + echo_green "Application $i ($num/$apps)" + if [ $(adb shell ls -l /data/data | grep -c $i) -lt 1 ] + then + echo_red " not installed, skipping.\n\n" + mv $i skipped + continue + fi + + echo " Restore data? [1|0] (default 0)" + echo -en " " + read inst + inst=${inst:=0} + + if [ $inst -eq 1 ] + then + if [ $i = "com.android.providers.telephony" ] + then + echo -e "SMS/CALLS" + $ADB push $i/databases/mmssms.db /data/data/$i/databases + $ADB shell chmod 660 /data/data/$i/databases/mmssms.db + $ADB shell toolbox chown 1001:1001 /data/data/$i/databases/mmssms.db + $ADB shell killall system_server + mv $i done + else + own=$($ADB shell ls -l /data/data/ | grep $i | head -n 1 | awk '{ print $3}') + echo -e " User $own\n\n" + mute $ADB push $i /data/data/$i + mute $ADB shell chown $own:$own /data/data/$i/* + mute $ADB shell chown $own:$own /data/data/$i/*/* + mute $ADB shell chown $own:$own /data/data/$i/*/*/* + mv $i done + fi + else + echo -e " Skipping...\n\n" + mv $i skipped + fi + let num=num+1 + done +} + +case $1 in + backup) + _backup + ;; + restoredata) + _restoredata + ;; + restoreapk) + _restoreapk + ;; + *) + help + exit 0 + ;; +esac diff --git a/bin/atmux b/bin/atmux new file mode 100755 index 0000000..7601693 --- /dev/null +++ b/bin/atmux @@ -0,0 +1,122 @@ +#!/bin/bash + +if [ -e $HOME/bin/functions.sh ] +then + . $HOME/bin/functions.sh +else + echo "functions.sh not found" + exit 0 +fi + +# override tmux +tmux='tmux' + +## CONFIGURATION +# session name +sn=${1:-atmux} + +# try to attach earlier session +tmux attach-session -t $sn && exit 0 +#or continue + +# default path +case $sn in + # window definitions + # path:command:custom-name + "thesis") + dpath=/home/konni/dropbox/documents/uni/12ss/BA/breite-quellen/thesis + windows="-:-" + windows+="matlab:echo bla" + ;; + "mako") + dpath=/extra/src/cyanogenmod-10.1 + dcmd=". environment_mako" + windows="-:-" + windows+="-:-" + windows+=" device/lge/mako:-" + windows+=" out/target/product/mako:-" + ;; + "ville_dev") + dpath=/extra/src/cyanogenmod-10.1 + dcmd=". environment_ville" + windows="-:-" + windows+=" -:-" + windows+=" device/htc/ville:-" + windows+=" device/htc/msm8960-common:-" + windows+=" kernel/htc/msm8960:-" + windows+=" vendor/htc:-" + windows+=" out/target/product/ville:-" + ;; + "ville") + dpath=/extra/src/cyanogenmod-jellybean + dcmd=". environment_ville" + windows="-:-" + windows+=" -:-" + windows+=" device/htc/ville:-" + windows+=" device/htc/msm8960-common:-" + windows+=" kernel/htc/msm8960:-" + windows+=" vendor/htc:-" + windows+=" out/target/product/ville:-" + ;; + *) + dpath=$HOME + windows="-:-" +esac + + +# enter default path +mute pushd $dpath + +# prepare windows +num=1 +for window in $windows +do + # parse configuration + read wpath wcmd <<< $(echo $window | sed 's/:/\ /g') + + # set path + unset tpath + if [ $wpath != "-" ] + then + tpath=$wpath + fi + + + if [ $num -eq 1 ] + then + # start new session + $tmux new-session -d -s "$sn" $tname + # set default path for new windows + $tmux set-option -t "$sn" default-path $dpath + else + # create new window in session + $tmux new-window -t "$sn:$num" $tname + fi + + # execute default command + if [ -n "$dcmd" ] + then + $tmux send-keys -t "$n:$num" "$dcmd" C-m + fi + + # change path + if [ -n "$tpath" ] + then + $tmux send-keys -t "$n:$num" "cd $tpath" C-m + fi + + # execute custom command + unset tcmd + if [ "$wcmd" != "-" ] + then + tcmd=$wcmd + $tmux send-keys -t "$n:$num" "$tcmd" C-m + fi + + let num=num+1 +done + +# select window #1 and attach to session +$tmux select-window -t "$sn:1" +$tmux attach-session -t "$sn" + diff --git a/bin/autostart b/bin/autostart new file mode 100755 index 0000000..f341864 --- /dev/null +++ b/bin/autostart @@ -0,0 +1,4 @@ +#!/bin/bash +dropbox start & +owncloud & +compton --config ~/.config/compton.conf -b diff --git a/bin/backup-profiles b/bin/backup-profiles new file mode 100644 index 0000000..2f87701 --- /dev/null +++ b/bin/backup-profiles @@ -0,0 +1,10 @@ +#!/bin/bash + +cd /tmp +tar cvfz firefox.tgz $1/.mozilla/firefox/david.runge-backup +gpg -e -r 'David Runge <david.runge@frqrec.com>' firefox.tgz +mv -f firefox.tgz.gpg $1/Dropbox/sync + +tar cvfz thunderbird.tgz $1/.thunderbird/david.runge +gpg -e -r 'David Runge <david.runge@frqrec.com>' thunderbird.tgz +mv -f thunderbird.tgz.gpg $1/Dropbox/sync diff --git a/bin/functions.sh b/bin/functions.sh new file mode 100755 index 0000000..951def5 --- /dev/null +++ b/bin/functions.sh @@ -0,0 +1,176 @@ +#!/bin/bash +# some functions + +# zsh color output +# echo "$FG[46]$FX[blink]Hello, World" + +function echo_green() { + echo -e '\E[1;32m'$*'\E[0m' +} + +function echo_red() { + echo -e '\E[1;31m'$*'\E[0m' +} + +function echo_magenta() { + echo -e '\E[1;35m'$*'\E[0m' +} + +function echo_cyan() { + echo -e '\E[1;36m'$*'\E[0m' +} + +# log text ... +function log() { + date=`date "+%Y-%m-%d %H:%M:%S"` + if [ -n $VERBOSE ] + then + echo $date $@ | tee -a $LOGFILE + fi + [ -n $LOGFILE ] && echo $date $@ >> $LOGFILE +} + +function log_green() { + date=`date "+%Y-%m-%d %H:%M:%S"` + if [ -n $VERBOSE ] + then + echo_green $date $@ + fi + [ -n $LOGFILE ] && echo $date $@ >> $LOGFILE +} + +function log_red() { + date=`date "+%Y-%m-%d %H:%M:%S"` + if [ -n $VERBOSE ] + then + echo_red $date $@ + fi + [ -n $LOGFILE ] && echo $date $@ >> $LOGFILE +} + +function log_magenta() { + date=`date "+%Y-%m-%d %H:%M:%S"` + if [ -n $VERBOSE ] + then + echo_magenta $date $@ + fi + [ -n $LOGFILE ] && echo $date $@ >> $LOGFILE +} + +function log_cyan() { + date=`date "+%Y-%m-%d %H:%M:%S"` + if [ -n $VERBOSE ] + then + echo_cyan $date $@ + fi + [ -n $LOGFILE ] && echo $date $@ >> $LOGFILE +} + +function notify() { + title="$1" + text="$2" + echo 'naughty.notify({title = "'$title'", text = "'$text'"})' | awesome-client +} + +# mute command +function mute() { + $@ > /dev/null 2> /dev/null +} + +# run pidfile command +function run() { + pidfile=$1 + shift + command=$@ + + exec $command > /dev/null 2> /dev/null & + pid=$! + sleep 0.25 + npid=$(pidof -s $1) + if [ -n "$npid" ] && [ $npid -ne $pid ] + then + pid=$npid + fi + echo $pid > $pidfile + log_green executed $command"\n" +} + +# run_once $pidfile $command[] +function run_once() { + pidfile=/tmp/run/lock/$1 + shift + command=$@ + + mkdir -p $(dirname $pidfile) + + if [ -f $pidfile ]; + then + pid=`head -n 1 $pidfile` + running=$(ps -u $(whoami) -p $pid | grep '^[ ]*'$pid) + if [ -z "$running" ] + then + log_cyan stale pidfile found + rm -f $pidfile + + npid=$(pidof -s $1) + if [ -n "$npid" ] + then + log_green "pidfile updated\n" + echo $npid > $pidfile + else + run $pidfile $command + fi + + else + log_cyan "active pidfile found\n" + fi + else + pid=`ps | grep "$command" | grep -v grep | head -n 1 | awk '{ print $1 }'` + if [ -z "$pid" ] + then + log_green not running + run $pidfile $command + else + log_cyan "pidfile updated\n" + echo $pid > $pidfile + fi + fi +} + +# run_auto $file +function run_auto() { + file=$1 + . $file + + cur_host=`hostname` + case $cur_host in + annoyance|silence|remembrance) + cur_area=private + ;; + c*|s*) + cur_area=unixpool + ;; + esac + + if [ $area != $cur_area -a $area != "any" ] + then + log_magenta invalid_area $(basename $file)"\n" + return + fi + + if [ $host != $cur_host -a $host != "any" ] + then + log_magenta invalid_host $(basename $file)"\n" + return + fi + + if [ $allow_multiple -eq 1 ] + then + log_green run $(basename $file) + run /dev/null $command + else + log_green run_once $(basename $file) + run_once `basename $file` $command + fi +} + diff --git a/bin/helloworld.sh b/bin/helloworld.sh new file mode 100755 index 0000000..7ee4df0 --- /dev/null +++ b/bin/helloworld.sh @@ -0,0 +1,2 @@ +#!/bin/bash +notify-send 'Hello world!' 'This is an example notification.' --icon=dialog-information diff --git a/bin/letter b/bin/letter new file mode 100644 index 0000000..87e2c34 --- /dev/null +++ b/bin/letter @@ -0,0 +1,71 @@ +#!/bin/bash +# Create a letter + +# Configuration +template=~/documents/letter_template.tex +dir=~/documents/`date +%Y` +texdir=$dir/tex +editor=/usr/bin/vim +reader=/usr/bin/mupdf + +function mkpdf () { + pdflatex -shell-escape $1.tex + EXT=(aux log) + for i in ${EXT[*]} + do +rm -v $1.$i + done +} + +# Preparation +mkdir -p $dir +mkdir -p $texdir + +named=0 +while [ $named -eq 0 ] +do +read -p "Enter document name: " REPLY + docname=`echo $REPLY | sed 's/\ /_/g'` + docdate="`date +%Y-%m-%d`" + doc=$dir/${docdate}_${docname} + tex=$dir/${docdate}_${docname}.tex + pdf=$dir/${docdate}_${docname}.pdf + if [ -e $pdf ] + then +read -p "Document already exists. Overwrite? (y/N) " REPLY + [ "$REPLY" == "y" ] || continue +fi + +read -p "Create document \"$pdf\"? (Y/n) " REPLY + [ "$REPLY" == "y" -o x"$REPLY" == x ] && named=1 +done + +cd $dir +cp $template $tex + +$editor $tex +mkpdf $doc +$reader $pdf + +finished=0 +while [ $finished -eq 0 ] +do +read -p "Finished editing? (Y/n) " REPLY + if [ "$REPLY" == "y" -o x"$REPLY" == x ] + then +finished=1 + else + $editor $tex + mkpdf $doc + $reader $pdf + fi +done + +read -p "Keep a copy of the .tex file? (Y/n) " REPLY +if [ "$REPLY" == "y" -o x"$REPLY" == x ] +then +mv $tex $texdir +else +rm $tex +fi + diff --git a/bin/mirssi b/bin/mirssi new file mode 100755 index 0000000..7ce8257 --- /dev/null +++ b/bin/mirssi @@ -0,0 +1,12 @@ +#!/bin/bash +# start notification daemon +# connect to server and open port +# kill notification daemon + +PATH=$HOME/bin/:$PATH +notify_irssi_server.pl &> /dev/null & +pid=$! + +ssh -R 7090:localhost:7090 frq + +kill $pid @@ -0,0 +1,38 @@ +#!/bin/bash +file=/tmp/mpdhost + +if [ -e $file ] +then + mpdhost=$(cat $file) +else + case $(hostname) in + "dvzrv") + mpdhost=dvzrv + ;; + *) + mpdhost=homey + ;; + esac +fi + +case $1 in + "switch") + case "$mpdhost" in + "dvzrv") + mpdhost=homey + ;; + *) + mpdhost=dvzrv + ;; + esac + echo $mpdhost > $file + echo switched to $mpdhost + shift + ;; + "host") + echo $mpdhost + exit 0 + ;; +esac + +/usr/bin/mpc -h $mpdhost "$@" diff --git a/bin/notify_irssi_server.pl b/bin/notify_irssi_server.pl new file mode 100755 index 0000000..e1c7b80 --- /dev/null +++ b/bin/notify_irssi_server.pl @@ -0,0 +1,62 @@ +#!/usr/bin/perl +# +use IO::Socket; +my $sock = new IO::Socket::INET ( + LocalHost => '127.0.0.1', + LocalPort => '7090', + Proto => 'tcp', + Listen => 1, + Reuse => 1, +); +die "Could not create socket: $!\n" unless $sock; + +while(true) { + my $new_sock = $sock->accept(); + while(<$new_sock>) { + my ($server, $channel, $text, $active) = split(/:::/); + #print "$_\n"; + my ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(); + # zero padding + if ($hour < 10) { + $hour = "0$hour"; + } + if ($minute < 10) { + $minute = "0$minute"; + } + if ($channel =~ m/#/ ) { + $timeout = 10; + } + else { + if ($channel =~ m/bitlbee/ ) { + $timeout = 10; + } + else { + $timeout = 5; + } + } + + ## filter invalid chars + # allowed: [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] + $text =~ s/[^\x01-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]//go; + # # restricted:[#x1-#x8][#xB-#xC][#xE-#x1F][#x7F-#x84][#x86-#x9F] + $text =~ s/[\x01-\x08\x0B-\x0C\x0E-\x1F\x7F-\x84\x86-\x9F]//go; + + ## replace otr information + $text =~ s/^03/OTR:\ /; + + ## remove ' + $text =~ s/\'//g; + + ## remove " + $text =~ s/\"//g; + + print "message({action=\"new\", timeout=$timeout, active=$active, title=\"$hour:$minute $channel\", text=\"$text\"})\n"; + ## AWESOME custom function + system("echo 'message({action=\"new\", timeout=$timeout, active=$active, title=\"$hour:$minute $channel\", text=\"$text\"})' | awesome-client"); + ## AWESOME + # system("echo 'notify_irssi=naughty.notify({timeout = $timeout, title = \"$hour:$minute $channel\", text = \"$text\"})' | awesome-client"); + ## NOTIFY-SEND timeout in ms + # system("notify-send -t $timeout*1000 \"$hour:$minute $channel\" \"$text\""); + } +} +close($sock); diff --git a/bin/notify_mpd b/bin/notify_mpd new file mode 100755 index 0000000..36d8345 --- /dev/null +++ b/bin/notify_mpd @@ -0,0 +1,45 @@ +#!/bin/bash +mpc "$@" > /dev/null +lines=`mpc | wc -l` + +if [ $lines -gt 1 ]; +then + line1="`mpc | head -n 1`" + line2="`mpc | head -n 3 | tail -n 2 | sed 's/[a-z]*\:\ off//g'`" + + status="`echo $line2 | awk '{ print $1 }'`" + position="`echo $line2 | awk '{ print $3 }'`" + position="($position)" + volume="[`echo $line2 | awk '{ print $5 $6 }' | sed 's/volume\://' | sed 's/repeat\://'`]" + + repeat="`echo $line2 | grep -c 'repeat: on' | sed 's/1/r/' | sed 's/0//'`" + random="`echo $line2 | grep -c 'random: on' | sed 's/1/z/' | sed 's/0//'`" + single="`echo $line2 | grep -c 'single: on' | sed 's/1/s/' | sed 's/0//'`" + consume="`echo $line2 | grep -c 'consume: on' | sed 's/1/c/' | sed 's/0//'`" + flags="[$repeat$random$single$consume]" + + title="$line1" + text="$status $position $flags $volume" + +else + line="`mpc | sed 's/[a-z]*\:\ off//g'`" + + volume="[`echo $line | awk '{ print $2 }'`]" + + repeat="`echo $line | grep -c 'repeat: on' | sed 's/1/r/' | sed 's/0//'`" + random="`echo $line | grep -c 'random: on' | sed 's/1/z/' | sed 's/0//'`" + single="`echo $line | grep -c 'single: on' | sed 's/1/s/' | sed 's/0//'`" + consume="`echo $line | grep -c 'consume: on' | sed 's/1/c/' | sed 's/0//'`" + flags="[$repeat$random$single$consume]" + + title="not playing" + text="$flags $volume" +fi + +## AWESOME +#echo 'naughty.destroy(notify_mpc)' | awesome-client +#echo 'notify_mpc=naughty.notify({title = "'$title'", text = "'$text'"})' | awesome-client + +## NOTIFY-SEND +notify-send -t 2000 "$title" "$text" + diff --git a/bin/run_once b/bin/run_once new file mode 100755 index 0000000..3829f7e --- /dev/null +++ b/bin/run_once @@ -0,0 +1,4 @@ +#!/bin/bash +#Alternative +pgrep $@ > /dev/null || ($@ &) + diff --git a/bin/scvim-test b/bin/scvim-test new file mode 100755 index 0000000..fc3d18b --- /dev/null +++ b/bin/scvim-test @@ -0,0 +1,7 @@ +#!/bin/sh + +tmux new-session -d -s SuperCollider -A +tmux split-window -t SuperCollider:1 -h -p 25 +tmux send-keys -t SuperCollider:1.1 dmesg C-m +tmux att -t SuperCollider + diff --git a/bin/set_volume b/bin/set_volume new file mode 100755 index 0000000..3168870 --- /dev/null +++ b/bin/set_volume @@ -0,0 +1,50 @@ +#!/bin/bash + +FUNCTIONS=$HOME/bin/functions.sh +[ -e $FUNCTIONS ] || exit 1 +. $FUNCTIONS + +LED=/sys/class/leds/0003:17EF:6009.0004:amber:mute/brightness + +function increase_volume() +{ + mute amixer sset Master 10%+ +} + +function decrease_volume() +{ + mute amixer sset Master 10%- +} + +function toggle_volume() +{ + state=$(amixer sget Master | grep -o '\[o[n|f]*\]' | head -n 1) + case "$state" in + "[on]") + mute amixer sset Master mute + mute amixer sset Headphone mute + mute amixer sset Speaker mute + echo 1 > $LED + ;; + "[off]") + mute amixer sset Master unmute + mute amixer sset Headphone unmute + mute amixer sset Speaker unmute + echo 0 > $LED + ;; + esac +} + +case "$1" in + increase) + increase_volume + ;; + decrease) + decrease_volume + ;; + toggle) + toggle_volume + ;; + *) + ;; +esac diff --git a/bin/stikked b/bin/stikked new file mode 100644 index 0000000..b209208 --- /dev/null +++ b/bin/stikked @@ -0,0 +1,115 @@ +#! /usr/bin/env python2 + +import argparse +import os +import sys +import pycurl +import StringIO +import subprocess +import urllib + +## CONFIGURATION { +user='example-user' +apiurl='http://paste.giev.de/api/create' +## } + + +def main(): + global verbose + + # parse arguments + parser = argparse.ArgumentParser(prog='stikked') + parser.add_argument('-V', '--version', action='version', version='%(prog)s 0.1') + parser.add_argument('-v', '--verbose', action='store_true', dest='verbose', help='verbose mode', default=False) + parser.add_argument('-s', dest='syntax', action='store', help='syntax to highlight', default='text') + parser.add_argument('-p', dest='private', action='store_true', help='set paste to private', default=False) + parser.add_argument('-t', dest='title', action='store', help='set title of paste') + parser.add_argument('fname', metavar='FILE|-', help='file to paste or - for stdin') + args = parser.parse_args() + if args.verbose: + verbose = args.verbose + print args + + # private + private = '1' if args.private else '0' + + # from stdin + if args.fname == '-': + title = args.title if args.title else 'stdin' + text=sys.stdin.read() + syntax=args.syntax + + # from file + else: + fname = args.fname + + if not os.path.isfile(fname): + print "No such file: {0}".format(fname) + sys.exit(1) + else: + title = args.title if args.title else os.path.split(fname)[1] + + if args.syntax == 'text': + ext = os.path.splitext(fname)[1][1:] + syntax = _detect_syntax(ext) + else: + syntax = args.syntax + + fopen = file(fname, 'r') + text = fopen.read() + + _paste(text, title, syntax, private) + + +# send paste to server +def _paste(text, title, syntax, private): + postparams = [ + ('text', text), + ('name', user), + ('title', title), + ('lang', syntax), + ('private', private)] + + postfields=urllib.urlencode(postparams) + + curl = pycurl.Curl() + curl.setopt(pycurl.URL, apiurl) + curl.setopt(pycurl.POST, True) + curl.setopt(pycurl.POSTFIELDS, postfields) + # Fixes the HTTP/1.1 417 Expectation Failed Bug + header = [] + header.append("Expect: ") + curl.setopt(pycurl.HTTPHEADER, header) + curl.setopt(pycurl.NOPROGRESS, True) + b = StringIO.StringIO() + curl.setopt(pycurl.WRITEFUNCTION, b.write) + curl.perform() + print b.getvalue(); + + # copy to primary clipboard + xsel_proc = xsel_proc = subprocess.Popen(['xsel', '-pi'], stdin=subprocess.PIPE) + xsel_proc.communicate(b.getvalue()) + + +# more possible of course +def _detect_syntax(ext): + if ext == 'h': + syntax='c' + elif ext == 'log': + syntax='logcat' + elif ext == "py": + syntax = 'python' + elif ext == "pl": + syntax = 'perl' + elif ext == "patch": + syntax = 'diff' + elif ext == 'c' or ext == 'cpp' or ext == 'java' or ext == 'sh': + syntax=ext + else: + syntax='text' + + return syntax + + +if __name__ == '__main__': + main() diff --git a/bin/supercollider.vim b/bin/supercollider.vim new file mode 100644 index 0000000..92b2512 --- /dev/null +++ b/bin/supercollider.vim @@ -0,0 +1,347 @@ +"SuperCollider/Vim interaction scripts +"Copyright 2007 Alex Norman +" +"This file is part of SCVIM. +" +"SCVIM is free software: you can redistribute it and/or modify +"it under the terms of the GNU General Public License as published by +"the Free Software Foundation, either version 3 of the License, or +"(at your option) any later version. +" +"SCVIM is distributed in the hope that it will be useful, +"but WITHOUT ANY WARRANTY; without even the implied warranty of +"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +"GNU General Public License for more details. +" +"You should have received a copy of the GNU General Public License +"along with SCVIM. If not, see <http://www.gnu.org/licenses/>. + +"au VimLeave + +"if exists("$SCVIM_DIR") == 0 +" echo "$SCVIM_DIR must be defined for SCVIM to work" +" finish +"endif + + +"source the syntax file as it can change +"so $SCVIM_DIR/syntax/supercollider.vim +runtime! syntax/supercollider.vim + +if exists("loaded_scvim") || &cp + finish +endif +let loaded_scvim = 1 + +"first if SCVIM_CACHE_DIR is defined, use that, +"otherwise use ~/.scvim +if exists("$SCVIM_CACHE_DIR") + let s:scvim_cache_dir = $SCVIM_CACHE_DIR +else + let s:scvim_cache_dir = $HOME . "/.scvim" + let $SCVIM_CACHE_DIR = s:scvim_cache_dir +endif + +"source the scvimrc file if it exists +if filereadable($HOME . "/.scvimrc") + source $HOME/.scvimrc +end + +"add the cache dir to +set runtimepath+=$SCVIM_CACHE_DIR + +if exists("g:sclangKillOnExit") + let s:sclangKillOnExit = g:sclangKillOnExit +else + let s:sclangKillOnExit = 1 +endif + +if exists("g:sclangPipeLoc") + let s:sclangPipeLoc = g:sclangPipeLoc +else + let s:sclangPipeLoc = "/tmp/sclang-pipe" +endif +let $SCVIM_PIPE_LOC = s:sclangPipeLoc + +if exists("g:sclangPipeAppPidLoc") + let s:sclangPipeAppPidLoc = g:sclangPipeAppPidLoc +else + let s:sclangPipeAppPidLoc = "/tmp/sclangpipe_app-pid" +endif +let $SCVIM_PIPE_PID_LOC = s:sclangPipeAppPidLoc + +if exists("g:sclangTerm") + let s:sclangTerm = g:sclangTerm +else + let s:sclangTerm = "xterm -e" +endif + +if exists("g:sclangPipeApp") + let s:sclangPipeApp = g:sclangPipeApp +else + let s:sclangPipeApp = "sclangpipe_app" +endif + +"function SClangRunning() +" if s:sclang_pid != 0 && `pidof "#{$sclangsclangPipeApp_no_quotes}"`.chomp != "" +" return true +" else +" $sclang_pid = 0 +" return false +" end +"end + + +function! FindOuterMostBlock() + "search backwards for parens dont wrap + let l:search_expression_up = "call searchpair('(', '', ')', 'bW'," . + \"'synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scComment\" || " . + \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scString\" || " . + \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scSymbol\"')" + "search forward for parens, don't wrap + let l:search_expression_down = "call searchpair('(', '', ')', 'W'," . + \"'synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scComment\" || " . + \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scString\" || " . + \"synIDattr(synID(line(\".\"), col(\".\"), 0), \"name\") =~? \"scSymbol\"')" + + "save our current cursor position + let l:returnline = line(".") + let l:returncol = col(".") + + "if we're on an opening paren then we should actually go to the closing one to start the search + "if buf[l:returnline][l:returncol-1,1] == "(" + if strpart(getline(line(".")),col(".") - 1,1) == "(" + exe l:search_expression_down + endif + + let l:origline = line(".") + let l:origcol = col(".") + + "these numbers will define our range, first init them to illegal values + let l:range_e = [-1, -1] + let l:range_s = [-1, -1] + + "this is the last line in our search + let l:lastline = line(".") + let l:lastcol = col(".") + + exe l:search_expression_up + + while line(".") != l:lastline || (line(".") == l:lastline && col(".") != l:lastcol) + "keep track of the last line/col we were on + let l:lastline = line(".") + let l:lastcol = col(".") + "go to the matching paren + exe l:search_expression_down + + "if there isn't a match print an error + if l:lastline == line(".") && l:lastcol == col(".") + call cursor(l:returnline,l:returncol) + throw "UnmachedParen at line:" . l:lastline . ", col: " . l:lastcol + endif + + "if this is equal to or later than our original cursor position + if line(".") > l:origline || (line(".") == l:origline && col(".") >= l:origcol) + let l:range_e = [line("."), col(".")] + "go back to opening paren + exe l:search_expression_up + let l:range_s = [line("."), col(".")] + else + "go back to opening paren + exe l:search_expression_up + endif + "find next paren (if there is one) + exe l:search_expression_up + endwhile + + "restore the settings + call cursor(l:returnline,l:returncol) + + if l:range_s[0] == -1 || l:range_s[1] == -1 + throw "OutsideOfParens" + endif + + "return the ranges + return [l:range_s, l:range_e] +endfunction + + +"this causes the sclang pipe / terminal app to be killed when you exit vim, if you don't +"want that to happen then just comment this out +if !exists("loaded_kill_sclang") + if s:sclangKillOnExit + au VimLeave * call SClangKill() + endif + let loaded_kill_sclang = 1 +endif + +"the vim version of SendToSC +function SendToSC(text) + let l:text = substitute(a:text, '\', '\\\\', 'g') + let l:text = substitute(l:text, '"', '\\"', 'g') + let l:cmd = system('echo "' . l:text . '" >> ' . s:sclangPipeLoc) + "let l:cmd = system('echo "' . l:text . '" >> /tmp/test') +endfunction + +function SendLineToSC(linenum) + let cmd = a:linenum . "w! >> " . s:sclangPipeLoc + silent exe cmd + "let cmd = a:linenum . "w! >> /tmp/test" + "silent exe cmd +endfunction + +function! SClang_send() + let cmd = ".w! >> " . s:sclangPipeLoc + exe cmd + if line(".") == a:lastline + call SendToSC('') + "redraw! + endif +endfunction + +function SClangStart() + if !filewritable(s:sclangPipeAppPidLoc) + call system("tmux splitw -h -p 25; tmux send-keys " . s:sclangPipeApp . " C-m; tmux selectp -L; sleep 1; tmux renamew scvim") + else + throw s:sclangPipeAppPidLoc . " exists, is " . s:sclangPipeApp . " running? If not try deleting " . s:sclangPipeAppPidLoc + endif +endfunction + +function SClangKill() + if filewritable(s:sclangPipeAppPidLoc) + call system("tmux selectp -R; tmux send-keys C-c; tmux killp -t scvim.1") + call SendToSC("Server.quitAll;") + :sleep 10m + call system("kill `cat " . s:sclangPipeAppPidLoc . "` && rm " . s:sclangPipeAppPidLoc . " && rm " . s:sclangPipeLoc) + end +endfunction + +function SClangRestart() + if filewritable(s:sclangPipeAppPidLoc) + call system("kill -HUP `cat " . s:sclangPipeAppPidLoc . "`") + else + call SClangStart() + end +endfunction + +function SClang_free(server) + call SendToSC('s.freeAll;') + redraw! +endfunction + +function SClang_thisProcess_stop() + call SendToSC('thisProcess.stop;') + redraw! +endfunction + +function SClang_TempoClock_clear() + call SendToSC('TempoClock.default.clear;') + redraw! +endfunction + +function! SClang_block() + let [blkstart,blkend] = FindOuterMostBlock() + "blkstart[0],blkend[0] call SClang_send() + "these next lines are just a hack, how can i do the above?? + let cmd = blkstart[0] . "," . blkend[0] . " call SClang_send()" + let l:origline = line(".") + let l:origcol = col(".") + exe cmd + call cursor(l:origline,l:origcol) + + ""if the range is just one line + "if blkstart[0] == blkend[0] + " "XXX call SendToSC(strpart(getline(blkstart[0]),blkstart[1] - 1, (blkend[1] - blkstart[1] + 1))) + " call SendLineToSC(blkstart[0]) + "else + " let linen = blkstart[0] - 1 + " "send the first line as it might not be a full line + " "XXX let line = getline(linen) + " "XXX call SendToSC(strpart(line, blkstart[1] - 1)) + " call SendLineToSC(linen) + " let linen += 1 + " let endlinen = blkend[0] + " while linen < endlinen + " "XXX call SendToSC(getline(linen)) + " call SendLineToSC(linen) + " let linen += 1 + " endwhile + " "send the last line as it might not be a full line + " "XXX let line = getline(endlinen) + " "XXX call SendToSC(strpart(line,0,blkend[1])) + " call SendLineToSC(endlinen) + "endif + "call SendToSC('') +endfunction + +function SCdef(subject) + let l:tagfile = s:scvim_cache_dir . "/TAGS_SCDEF" + let l:tagdest = s:scvim_cache_dir . "/doc/tags" + + if !filereadable(l:tagfile) + echo "definition tag cache does not exist, you must run SCVim.updateCaches in supercollider" + let l:dontcare = system("echo 'SC:SCVim SCVim.scd /^' > " . l:tagdest) + exe "help SC:SCVim" + else + let l:dontcare = system("grep SCdef:" . a:subject . " " . l:tagfile . " > " . l:tagdest) + exe "help SCdef:" . a:subject + end +endfun + +function SChelp(subject) + let l:tagfile = s:scvim_cache_dir . "/doc/TAGS_HELP" + let l:tagdest = s:scvim_cache_dir . "/doc/tags" + if !filereadable(l:tagfile) + echo "help tag cache does not exist, you must run SCVim.updateHelpCache in supercollider in order have help docs" + let l:dontcare = system("echo 'SC:SCVim SCVim.scd /^' > $SCVIM_CACHE_DIR/doc/tags") + exe "help SC:SCVim" + return + end + + "the keybindings won't find * but will find ** for some reason + if a:subject == "" + let l:dontcare = system("grep \"SC:Help\" " . l:tagfile . " > " . l:tagdest) + exe "help SC:Help" + elseif a:subject == "*" + let l:dontcare = system("grep \"SC:\\*\" " . l:tagfile . " > " . l:tagdest) + exe "help SC:\*" . a:subject + elseif a:subject == "**" + let l:dontcare = system("grep \"SC:\\*\\*\" " . l:tagfile . " > " . l:tagdest) + exe "help SC:\*\*" . a:subject + else + let l:dontcare = system("grep SC:\"" . a:subject . "\" " . l:tagfile . " > " . l:tagdest) + exe "help SC:" . a:subject + endif +endfun + +" search help files for word under the cursor +" or open the HelpBrowser front page +function! HelpBrowser(subject) + if strlen(a:subject) > 0 && a:subject!~" " && a:subject!~"\t" + let string= "HelpBrowser.openHelpFor" + let format= "(\"" . a:subject . "\");" + let string= string . format + call SendToSC(string) + else + call SendToSC('Help.gui;') + endif +endfunction + +function ListSCObjects(A,L,P) + return system("cat $SCVIM_CACHE_DIR/sc_object_completion") +endfun + +function ListSCHelpItems(A,L,P) + return system("cat $SCVIM_CACHE_DIR/doc/sc_help_completion") +endfun + + +"custom commands (SChelp,SCdef,SClangfree) +com -complete=custom,ListSCHelpItems -nargs=? SChelp call SChelp("<args>") +com -complete=custom,ListSCObjects -nargs=1 SCdef call SCdef("<args>") +com -nargs=1 SClangfree call SClang_free("<args>") +com -nargs=0 SClangStart call SClangStart() +com -nargs=0 SClangKill call SClangKill() +com -nargs=0 SClangRestart call SClangRestart() + +" end supercollider.vim diff --git a/bin/syncmpdpl b/bin/syncmpdpl new file mode 100644 index 0000000..85cf723 --- /dev/null +++ b/bin/syncmpdpl @@ -0,0 +1,209 @@ +#! /usr/bin/env python2 +# -*- coding: utf-8 -*- +# +# script to sync a mpd playlist to a mass storage audio player +# +# needs +# - python-sqlite2 +# - eyed3 +# - python-argparser +# - python-mpd + +import argparse +import os +import sys +import hashlib +import subprocess + +#from time import time +import time +from mpd import (MPDClient, CommandError) + +import shutil + +# set encoding to utf-8 +reload(sys) +sys.setdefaultencoding( "utf-8" ) + +config_dir = '/home/konni/.config/pmsync' +music = '/net/media/music' +playlist = 'sync' +mpdhost = 'innocence' +destination = '/run/media/konni/ville/music' +verbose = False + +def _recode(string): + string = string.replace('"','') + # byte2utf8 + # string = unicode( string, "utf-8", errors="ignore" ) + # utf2byte + string = string.encode('utf-8') + return string + +def main(): + global verbose, playlist, mpdhost, destination + parser = argparse.ArgumentParser(prog='pmsync') + + parser.add_argument('--version', action='version', version='%(prog)s 0.1') + parser.add_argument('-v', '--verbose', action='store_true', dest='verbose', help='verbose mode', default=False) + + parser.add_argument('action', metavar='sync | list | import') + + parser.add_argument('-m', dest='host', metavar='mpdhost', action='store', help='mpd host', default=mpdhost) + parser.add_argument('-p', dest='pl', metavar='playlist', action='store', help='playlist to use', default=playlist) + parser.add_argument('-d', dest='dest', metavar='destination', action='store', help='destination', default=destination) + parser.add_argument('-e', dest='exact', action='store_true', help='exact checking (slow)', default=False) + + args = parser.parse_args() + if args.verbose: + verbose = args.verbose + print args + + ## action sync + if args.action == 'sync': + print '>> syncing \"{0}/{1}\"to \"{2}\"'.format(args.host, args.pl, args.dest) + _sync(args.host, args.pl, args.dest, args.exact) + + ## action list + elif args.action == 'list': + print '>> listing from \"{0}/{1}\"'.format(args.host, args.pl) + _list(args.host, args.pl) + + ## action import + elif args.action == 'import': + print '>> importing from \"{0}\" to playlist \"{1}/{2}\"'.format(args.dest, args.host, args.pl) + port='6600' + CON_ID = {'host':args.host, 'port':port} + client = MPDClient() + mpdConnect(client, CON_ID) + playlistinfo = client.listplaylistinfo(playlist) + for dirname, dirnames, filenames in os.walk(args.dest): + for filename in filenames: + destfile = os.path.join(dirname, filename) + path=destfile.replace(args.dest+"/","") + found = False + for item in playlistinfo: + if item['file'] == path: + found = True + if not found: + print '[x] {0}'.format(path) + client.add(path) + client.rm(args.pl) + client.save(args.pl) + + ## show help if no action called + else: + parser.print_help() + +def _sync(host, pl, dest, exact): + _checkdir(dest) + port='6600' + CON_ID = {'host':host, 'port':port} + client = MPDClient() + mpdConnect(client, CON_ID) + playlistinfo = client.listplaylistinfo(pl) + + ## copy files + print '> copy files' + for item in playlistinfo: + path = item['file'] + srcfile=os.path.join(music, path) + destfile=os.path.join(dest, path) + destdir=os.path.dirname(destfile) + + if not os.path.isdir(destdir): + print '[^] {0}'.format(destdir) + os.makedirs(destdir) + if not os.path.isfile(destfile): + shutil.copyfile(srcfile,destfile) + print '[+] {0}'.format(path) + else: + ## hash based on md5sum or just file size + if exact: + srchash = hashlib.md5(open(srcfile, 'rb').read()).hexdigest() + desthash = hashlib.md5(open(destfile, 'rb').read()).hexdigest() + else: + srchash = os.path.getsize(srcfile) + desthash = os.path.getsize(destfile) + + if srchash != desthash: + shutil.copyfile(srcfile,destfile) + print '[o] {0}'.format(path) + else: + if verbose: + print '[ ] {0}'.format(path) + + print 'done' + + ## clean files + print '> clean files and directories' + for dirname, dirnames, filenames in os.walk(dest): + for filename in filenames: + destfile = os.path.join(dirname, filename) + path=destfile.replace(dest+"/","") + found = False + for item in playlistinfo: + if item['file'] == path: + found = True; + + if not found: + try: + os.remove(destfile) + print '[-] {0}'.format(path) + except OSError: + print 'error removing {0}'.format(destfile) + + ## clean directories + for dirname, dirnames, filenames in os.walk(dest,topdown=False): + if os.listdir(dirname) == [] and dirname != dest: + try: + os.rmdir(dirname) + print '[v] {0}'.format(destdir) + except OSError: + print 'error removing {0} '.format(dirname) + print 'done' + + print '> writing filesystem changes' + subprocess.call("/bin/sync") + + +def _list(host, pl): + port='6600' + CON_ID = {'host':host, 'port':port} + client = MPDClient() + mpdConnect(client, CON_ID) + playlistinfo = client.listplaylistinfo(pl) + + ## output + print '> copy files' + prev_album = '' + for item in playlistinfo: + artist = item['artist'] + album = item['album'] + + if album != prev_album: + print '{0}/{1}'.format(artist, album) + prev_album = album + +def _output(artist, album, track, title, symbol='', extra=''): + output_format = '{symbol:4}{artist:20.20} :: {album:20.20} :: {track:2d} - {title:25.25} {extra}' + print output_format.format(symbol=symbol, artist=artist, album=album, track=track, title=title, extra=extra) + + +def mpdConnect(client, con_id): + """ +Simple wrapper to connect MPD. +""" + try: + client.connect(**con_id) + except SocketError: + return False + return True + +def _checkdir(dir): + if not os.path.isdir(dir): + print "destination not mounted" + sys.exit(1) + +if __name__ == '__main__': + main() diff --git a/bin/tmux-test b/bin/tmux-test new file mode 100755 index 0000000..ba0e5c6 --- /dev/null +++ b/bin/tmux-test @@ -0,0 +1,53 @@ +#!/bin/bash + +###this is going to split the pane into four +###even horizontal panes +tmux split-window -v +sleep 1 +tmux send-keys -t 0 "clear" C-m +tmux select-pane -t 0 + +tmux split-window -v +sleep 1 +tmux select-pane -t 3 + +tmux split-window -v +sleep 1 +tmux select-pane -t 5 + +tmux split-window -v +tmux select-layout even-vertical + + +###this will split each of the four panes +###vertically, resulting in eight seperate +###panes + +for i in 0 2 4 6 +do +tmux select-pane -t $i +tmux split-window -h +sleep 1 +done + + +#this goes to each pane and sends a command, in this case - just identifies the pane. + +tmux select-pane -t 0 +tmux send-keys -t 0 "This is pane 0" C-m +tmux select-pane -t 1 +tmux send-keys -t 1 "This is pane 1" C-m +tmux select-pane -t 2 +tmux send-keys -t 2 "This is pane 2" C-m +tmux select-pane -t 3 +tmux send-keys -t 3 echo "This is pane 3" C-m +tmux select-pane -t 4 +tmux send-keys -t 4 "This is pane 4" C-m +tmux select-pane -t 5 +tmux send-keys -t 5 "This is pane 5" C-m +tmux select-pane -t 6 +tmux send-keys -t 6 "This is pane 6" C-m +tmux select-pane -t 7 +tmux send-keys -t 7 "This is pane 7" C-m +tmux select-pane -t 8 +tmux send-keys -t 8 "This is pane 8" C-m diff --git a/bin/torrentSort.py b/bin/torrentSort.py new file mode 100644 index 0000000..e284a88 --- /dev/null +++ b/bin/torrentSort.py @@ -0,0 +1,220 @@ +#! /usr/bin/python +# simple python script to sort torrents +# modifications by xkonni +# - added folder sorting +# - added htdigest authorisation +# - fixed some minor glitches +# +# original version by jonassw from +# http://forum.xbmc.org/showthread.php?t=60749 + +# << DOCUMENTATION +# +# i) lighttpd configuration for htdigest +# server.modules += ( "mod_auth" ) +# auth.backend = "htdigest" +# auth.backend.htdigest.userfile = "/etc/lighttpd/auth" +# auth.debug = 2 +# auth.require = ( "/RPC2" => +# ( +# "method" => "digest", +# "realm" => "REALM", +# "require" => "valid-user" +# ) +# ) +# ii) i recommend starting this with a basic cron job you may find other +# suggestions like when rtorrent finishes hashing, but for me this caused +# lockups when starting rtorrent (as all downloads return hash_ok) +# +# */5 * * * * for i in /mnt/torrent/tv/*; do torrentSort.py $i > /dev/null; done +# +# DOCUMENTATION >> + + +import xmlrpclib, os, sys, re, shutil + + +class HTTPSDigestTransport(xmlrpclib.SafeTransport): + """ +Transport that uses urllib2 so that we can do Digest authentication. +Based upon code at http://bytes.com/topic/python/answers/509382-solution-xml-rpc-over-proxy +""" + + def __init__(self, username, pw, realm, verbose = None, use_datetime=0): + self.__username = username + self.__pw = pw + self.__realm = realm + self.verbose = verbose + self._use_datetime = use_datetime + + def request(self, host, handler, request_body, verbose): + import urllib2 + + url='https://'+host+handler + if verbose or self.verbose: + print "ProxyTransport URL: [%s]"%url + + request = urllib2.Request(url) + request.add_data(request_body) + # Note: 'Host' and 'Content-Length' are added automatically + request.add_header("User-Agent", self.user_agent) + request.add_header("Content-Type", "text/xml") # Important + + # setup digest authentication + authhandler = urllib2.HTTPDigestAuthHandler() + authhandler.add_password(self.__realm, url, self.__username, self.__pw) + opener = urllib2.build_opener(authhandler) + + #proxy_handler=urllib2.ProxyHandler() + #opener=urllib2.build_opener(proxy_handler) + f=opener.open(request) + return(self.parse_response(f)) + + +def adoptionCandidates(basedir, filename): + dirs = filter(lambda x : os.path.isdir(os.path.join(basedir, x)), os.listdir(basedir)) + + #set filename to lowercase for string comparisons + filename=filename.lower() + + ignoredPhrases = ['-','_'] + + candidates = [] + for dir in dirs: + dirParts = dir.split() + score = 0 + requiredScore = 0 + + for part in dirParts: + if ignoredPhrases.count(part) > 0: + continue + requiredScore = requiredScore + 1 + + #force lower case for string comparison. + part=part.lower() + # replace "'" with "" and add word to list + repPart = part.replace('\'','') + if repPart != part: + dirParts.append(repPart) + requiredScore -= 1 + if filename.find(part) >= 0: + score = score + 1 + if score == requiredScore: + candidates.append( (os.path.join(basedir, dir), score) ) + + return candidates + +def getSeasonNumber(filename): + patterns = [ + '.*S(\d+)E(\d+).*', + '.*S(\d+)(\.)?E(\d+).*', # hopefully matches series.s01.e05.avi + '(\d+)x(\d+).*', + '(\d+)(\d+)(\d+).*' + # commented out regex thought below Season was '4' not 14. Def better way of doing that + #top_gear.14x04.720p_hdtv_x264-fov.mkv + #'.*(\d+)x(\d+).*' + ] + + for pattern in patterns: + p = re.compile(pattern, re.I) + g = p.findall(orphanFile) + if len(g) > 0: + season = int(g[0][0]) + return season + return None + + +def getRtorrentId(filename): + downloads = rtorrent.download_list('') + for dl in downloads: + rfile = rtorrent.d.get_base_filename(dl) + if rfile == filename: + return dl + +# << CONFIGURATION +# i) FOLDER SETTINGS +showLocations = ['/mnt/media/tv'] +allowedSourceLocation = '/mnt/media/torrent/complete/tv' + +# ii) CONNECTION SETTINGS +# - using htdigest authorisation +digestTransport = HTTPSDigestTransport("username", "password", "realm") +rtorrent = xmlrpclib.ServerProxy('http://localhost',transport=digestTransport) +# - not using authorisation +# rtorrent = xmlrpclib.ServerProxy('http://localhost') + +# CONFIGURATION >> + +print '--------------- BEGIN ---------------' +orphanFile = sys.argv[1] +if os.path.isdir(orphanFile): + (fpath, fname) = os.path.split(orphanFile) + fname = os.path.relpath(orphanFile, allowedSourceLocation) + +else: + (fpath, fname) = os.path.split(orphanFile) +print 'File path: %s' % fpath +print 'File name: %s' % fname + +candidates = [] + +if not orphanFile.startswith(allowedSourceLocation): + print 'STOP! This file is not located in %s' % allowedSourceLocation + exit() + +print 'Attempting to find a home for file %s' % orphanFile + +for location in showLocations: + candidates.extend(adoptionCandidates(location, fname)) + +candidates.sort(lambda (da, sa), (db, sb): sb-sa) + +if len(candidates) <= 0: + print 'No one wanted this file :(' + exit() + +for (dir, score) in candidates: + print 'Candidate: %s with score %i' % (dir, score) + +print 'Winner is %s with score %i' % candidates[0] + +if os.path.isdir(orphanFile): + finaldir = candidates[0][0] + +else: + # Determine Season and Episode number + season = getSeasonNumber(fname) + if not season: + print 'STOP! Season could not be determined.' + exit() + + print 'Season was determined to be %i' % season + finaldir = os.path.join(candidates[0][0], 'Season %s' % season) + + # Check if season folder is present + if not os.path.isdir(finaldir): + print 'Season dir doesn\'t exist. Creating now' + os.mkdir(finaldir) + + if os.path.isfile(os.path.join(finaldir, fname)): + print 'error: file already exists, exiting' + sys.exit(1) + + print 'Will move file to %s' % finaldir + + +print 'Requesting id from rtorrent' +rid = getRtorrentId(fname) +print '%s was resolved to rtorrent id: %s' % (fname, rid) + +print 'Pausing rtorrent' +rtorrent.d.pause(rid) + +print 'Updating rtorrent' +rtorrent.d.set_directory(rid, finaldir) + +print 'Moving file' +shutil.move(orphanFile, finaldir) + +print 'Resuming rtorrent' +rtorrent.d.resume(rid) |