diff --git a/.gitmodules b/.gitmodules index ef5b754..b2e3d3b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,10 +1,10 @@ [submodule "vim/bundle/vundle"] path = vim/bundle/vundle - url = git@github.com:gmarik/vundle.git + url = https://github.com/gmarik/vundle.git ignore = dirty [submodule "oh-my-zsh"] path = oh-my-zsh - url = git@github.com:balkian/oh-my-zsh.git -[submodule "bin"] - path = bin - url = https://github.com/balkian/personal-scripts.git + url = https://github.com/balkian/oh-my-zsh.git +[submodule "i3-wm-scripts"] + path = bin/i3-wm-scripts + url = https://github.com/yiuin/i3-wm-scripts.git diff --git a/bin b/bin deleted file mode 160000 index 405a3e1..0000000 --- a/bin +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 405a3e196bcabeb9a49abddea0ffbea7c44f850a diff --git a/bin/README b/bin/README new file mode 100644 index 0000000..ea19512 --- /dev/null +++ b/bin/README @@ -0,0 +1,2 @@ +Here I will be posting my personal scripts (either written by me or found on the internet). +Feel free to use them and email me if you have any comment or question. diff --git a/bin/bashrc b/bin/bashrc new file mode 100644 index 0000000..ed83f3d --- /dev/null +++ b/bin/bashrc @@ -0,0 +1,125 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +[ -z "$PS1" ] && return + +# don't put duplicate lines in the history. See bash(1) for more options +# ... or force ignoredups and ignorespace +HISTCONTROL=ignoredups:ignorespace + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) +HISTSIZE=1000 +HISTFILESIZE=2000 + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# make less more friendly for non-text input files, see lesspipe(1) +[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color) color_prompt=yes;; + xterm) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + export PROMPT_COMMAND='PS1="\\[\033[1;\`if [[ \$? = "0" ]]; then echo "32m\\]"; else echo "31m\\]"; fi\`[\!]\\[\033[0m\]\u@\h \W: "' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi + +unset color_prompt force_color_prompt + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac + +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + alias grep='grep --color=auto' + alias fgrep='fgrep --color=auto' + alias egrep='egrep --color=auto' +fi + +# some more ls aliases +alias ll='ls -alhF' +alias la='ls -A' +alias l='ls -CF' + +# Add an "alert" alias for long running commands. Use like so: +# sleep 10; alert +alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if [ -f /etc/bash_completion ] && ! shopt -oq posix; then + . /etc/bash_completion +fi +export CDPATH=~:/media/Datos:/home/balkian + +if [ "$TERM" = "linux" ]; then + alias logout="clear && logout && exit" +else + alias logout="exit 0" +fi +export PYTHONSTARTUP=/home/$USER/.pythonrc +export PATH=$PATH:/var/lib/gems/1.8/bin + +setWindowTitle() { + echo -ne "\e]2;$*\a" +} +updateWindowTitle() { + setWindowTitle "${HOSTNAME%%.*}:${PWD/$HOME/~}" +} +PROMPT_COMMAND=$PROMPT_COMMAND updateWindowTitle + +function findHere() { ex=$1; shift; grep -R $* $ex .;} + diff --git a/bin/change-xfce4-alt-tab.sh b/bin/change-xfce4-alt-tab.sh new file mode 100755 index 0000000..baa54e6 --- /dev/null +++ b/bin/change-xfce4-alt-tab.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# @balkian +# Changes the behaviour of the window cycling in xfce4 +# +# Extracted from: http://askubuntu.com/questions/136052/cycle-windows-over-all-workspaces-in-xfce-while-being-able-to-cycle-over-one-wo +# + +OLD_VALUE=$(xfconf-query -c xfwm4 -p /general/cycle_workspaces) + +if [ $OLD_VALUE == "true" ]; then + echo 'will now disable workspace cycling' + NEW_VALUE="false" +fi + +if [ $OLD_VALUE == "false" ]; then + echo 'will now turn on workspace cycling' + NEW_VALUE="true" +fi + +xfconf-query -c xfwm4 -p /general/cycle_workspaces -s $NEW_VALUE diff --git a/bin/changedisplay.sh b/bin/changedisplay.sh new file mode 100755 index 0000000..26ed7dd --- /dev/null +++ b/bin/changedisplay.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# Author: Andrew Martin +# Credit: http://ubuntuforums.org/showthread.php?t=1309247 +echo "Enter the primary display from the following:" # prompt for the display +xrandr --prop | grep "[^dis]connected" | cut --delimiter=" " -f1 # query connected monitors + +read choice # read the users's choice of monitor + +xrandr --output $choice --primary # set the primary monitor + + + diff --git a/bin/cpcuevana.sh b/bin/cpcuevana.sh new file mode 100755 index 0000000..83b509c --- /dev/null +++ b/bin/cpcuevana.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# Script to copy Cuevana files to your home directory. +# Tested only with one cuevana instance at a time. +# @author: balkian + +destfile="$HOME/VideoCuevana$$" +info=($(lsof -c /npview/i | grep -i /tmp/flash | awk '{print $2; print $9}')) +dir="/proc/${info[0]}/fd" +file=${info[1]} +#echo "pid" $pid +#echo "file" $file +fdn=$(ls -l $dir | grep $file | awk '{print $8}') +cp $dir/$fdn $destfile && echo "Video copied successfully to $destfile." && echo "Enjoy" diff --git a/bin/dmenu.sh b/bin/dmenu.sh new file mode 100755 index 0000000..eb61099 --- /dev/null +++ b/bin/dmenu.sh @@ -0,0 +1,27 @@ +#!/bin/sh +#http://unix.stackexchange.com/questions/50539/inconsistent-behaviour-of-wmctrl-i-a-win + +# source dmenu config file if it exists +if [ -f $HOME/.dmenurc ]; then + . $HOME/.dmenurc +else + DMENU='dmenu -i' +fi + +# get list of all windows, and their count +wmctrl_output=$(wmctrl -lx) +win_count=$(echo "$wmctrl_output" | wc -l) +# get rid of the hostname and the number in the 2nd column +hostname=$(uname -n) +win_list=$(echo "$wmctrl_output" | \ + sed -r -e 's/[^@]'$hostname'//' | \ + sed -r -e 's/ [0-9][0-9]? / /') + +# select a window ($target) and extract its id ($target_id) +target=$(echo "$win_list" | $DMENU -l $win_count -p "Switch to: ") +target_id=$(echo "$target" | cut -d' ' -f1) + +# switch to target window +cmd="wmctrl -i -a \"$target_id\"" +eval "$cmd" + diff --git a/bin/dual-monitor b/bin/dual-monitor new file mode 120000 index 0000000..0029e18 --- /dev/null +++ b/bin/dual-monitor @@ -0,0 +1 @@ +dual-monitor.sputnik \ No newline at end of file diff --git a/bin/dual-monitor.sputnik b/bin/dual-monitor.sputnik new file mode 100755 index 0000000..9c22065 --- /dev/null +++ b/bin/dual-monitor.sputnik @@ -0,0 +1 @@ + xrandr --auto --output eDP1 --primary --right-of DP1 diff --git a/bin/elecciones.sh b/bin/elecciones.sh new file mode 100755 index 0000000..f5f1501 --- /dev/null +++ b/bin/elecciones.sh @@ -0,0 +1,5 @@ +#!/bin/bash +cd /tmp +wget http://www3.upm.es/elecciones/resultados/#1 -O resultados + + diff --git a/bin/flasher.sh b/bin/flasher.sh new file mode 100755 index 0000000..17ae561 --- /dev/null +++ b/bin/flasher.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# Script to copy/link Cuevana files to your home directory or play them with your default video player. +# Tested only with one cuevana instance at a time. +# The video can be played, but it's deleted when the flash player is closed (unless you copied it). +# @author: balkian + +if [ -z "$1" ]; then + PLAYER=parole; +else + PLAYER=$1; +fi + +destfile="$HOME/VideoCuevana$$" +# PID1=$(pgrep -f flash) +# info=($(lsof -p $PID1 | grep -i /tmp/flash | awk '{print $2; print $9}')) +# dir="/proc/${info[0]}/fd" +# file=${info[1]} +# #echo "pid" $pid +# #echo "file" $file +# fdn=$(ls -l $dir | grep $file | awk '{print $9}') +files=$(sudo lsof 2>/dev/null | grep "Pepper Data" | awk '{gsub(/[a-z]/,"",$4);print "/proc/"$2"/fd/"$4}' | uniq -u) + +echo "Files:" $files +for file in $files; do + + sel=$(zenity --list --radiolist --text "Select action for: $file" --column "pick" --column "Option" TRUE "play" FALSE "copy" FALSE "link") + case $sel in + play) + sudo $PLAYER $file + ;; + link) + sudo ln -s $file $destfile && echo "Video linked successfully to $destfile." && echo "Enjoy" + sudo chown $USER:$USER $destfile + ;; + copy) + sudo cp $file $destfile && echo "Video copied successfully to $destfile." && echo "Enjoy" + sudo chown $USER:$USER $destfile + ;; + esac + +done; diff --git a/bin/gnome-terminal b/bin/gnome-terminal new file mode 100755 index 0000000..7bd0cde --- /dev/null +++ b/bin/gnome-terminal @@ -0,0 +1,2 @@ +#!/bin/bash +one-window 'gnome-terminal' 'xdotool windowfocus $WID & xdotool key ctrl+shift+t' diff --git a/bin/goear.sh b/bin/goear.sh new file mode 100755 index 0000000..520a3d0 --- /dev/null +++ b/bin/goear.sh @@ -0,0 +1,70 @@ +#bin/bash +resultado=/tmp/resultado +canciones=/tmp/canciones +enlaces=/tmp/enlaces +titulos=/tmp/titulos +#Pedimos al usuario el titulo de la canción. +echo "Introduce el título de la canción o del artista:" +read TITULO + +if [ ! -d "goear" ] +then + mkdir goear +fi +#Descargamos el PHP correspondiente al título. +wget http://goear.com/search.php?q="$TITULO" -O $resultado + +#La línea 130 contiene todos los enlaces a goear... de risa pero bueno. +head -130 $resultado | tail -1 > $canciones + +#Mediante ER, obtenemos una lista de canciones y una lista de enlaces. +egrep -o 'listen/......./[^"]*' $canciones > $enlaces +egrep -o '"Escuchar[^"]*' $canciones > $titulos + +#Mostramos al usuario los que ha encontrado en la primera página. +Linea=1 +cat $titulos | while read line; + do { + echo $Linea: ${line:9} + let 'Linea += 1' + } + done + +#Si no encuentra nada, sale. +CONDICION=`wc -l $titulos | awk '{print $1}'` +if [ $CONDICION == 0 ]; then + echo "No hay resultados. Prueba buscando otra cosa." + rm $resultado $canciones $enlaces $titulos + exit +fi + +#Leemos qué canción quiere el usuario bajarse. +echo "¿Cuál te quieres bajar? Indica el número:" +read NUMERO + +#Concatenamos http://www.goear.com con el contenido de aBajar.txt. +#PD: Alguien sabe hacerlo de manera más sencilla? +GOEAR=http://www.goear.com/ +aBajar=`head -$NUMERO $enlaces | tail -1` +for LISTEN in $aBajar +do + ENLACE=${GOEAR}${LISTEN} +done +echo $ENLACE + +#A partir de aquí el script no es mío, pero es muy sencillo de leer. +fileid=`echo $ENLACE | cut -d '/' -f 5` +xmlurl="http://www.goear.com/tracker758.php?f="$fileid +infoline=`wget -qO- $xmlurl | grep ".mp3"` +mp3url=`echo $infoline | cut -d '"' -f6` +artist=`echo $infoline | cut -d '"' -f10` +title=`echo $infoline | cut -d '"' -f12` +filename=goear/"$artist-$title.mp3" +wget $mp3url -O "$filename" +rm $resultado $canciones $enlaces $titulos + +echo "¿Quieres reproducirla?[Y/n]" +read RES +if [ -z "$RES" -o "$RES" = "Y" -o "$RES" = "y" ];then + mplayer "$filename"; +fi; diff --git a/bin/i3-one-instance b/bin/i3-one-instance new file mode 100755 index 0000000..e23aa77 --- /dev/null +++ b/bin/i3-one-instance @@ -0,0 +1,5 @@ +#!/bin/sh +python2 $HOME/.bin/i3-wm-scripts/nextmatch.py $* +if [ $? -gt 0 ]; then + $* & sleep 0.1 && python2 $HOME/.bin/i3-wm-scripts/nextmatch.py $* +fi diff --git a/bin/i3-one-tmux b/bin/i3-one-tmux new file mode 100755 index 0000000..1b3f9ce --- /dev/null +++ b/bin/i3-one-tmux @@ -0,0 +1,11 @@ +#!/bin/zsh +python2 $HOME/.bin/i3-wm-scripts/nextmatch.py urxvt +if [ $? -gt 0 ]; then + urxvt & sleep 0.1 && python2 $HOME/.bin/i3-wm-scripts/nextmatch.py urxvt +fi +if [ "$#" -gt 0 ]; then + eval "tmux neww" + sleep 0.2 + xdotool type "$*" + xdotool key Return +fi diff --git a/bin/i3-wm-scripts b/bin/i3-wm-scripts new file mode 160000 index 0000000..4773352 --- /dev/null +++ b/bin/i3-wm-scripts @@ -0,0 +1 @@ +Subproject commit 477335215dd1fff4f23b82afbb92e7ad1bd4552e diff --git a/bin/icon_spotify.png b/bin/icon_spotify.png new file mode 100644 index 0000000..a640f7d Binary files /dev/null and b/bin/icon_spotify.png differ diff --git a/bin/one-instance b/bin/one-instance new file mode 100755 index 0000000..79206ed --- /dev/null +++ b/bin/one-instance @@ -0,0 +1,24 @@ +#!/bin/bash +if [ "x$1" != "x" ] +then + pgrep -l -u "$USER" -f "$1" | egrep -v "/bin/bash|/bin/sh" | grep -vq "$$" + if [ $? == "0" ] + then + WID=`xdotool search --class $1 | head -1` + wmctrl -i -a $WID + if [ "x$2" != "x" ] + then + eval "$2" + fi + else + if [ "x$3" == "x" ] + then + /usr/bin/$1 + else + eval "$3" + fi + fi +else + echo "Usage: one-instance program-name [extra action]" +fi + diff --git a/bin/one-instance (copy) b/bin/one-instance (copy) new file mode 100755 index 0000000..d0f7e95 --- /dev/null +++ b/bin/one-instance (copy) @@ -0,0 +1,27 @@ +#!/bin/bash +if [ "x$1" != "x" ] +then + pgrep -fx $1 1> /dev/null + if [ $? == "0" ] + then + echo "running" + ps aux | grep terminator > /home/balkian/LOG + WID=`xdotool search --class $1 | head -1` + wmctrl -i -a $WID + if [ "x$2" != "x" ] + then + eval "$2" + fi + else + if [ "x$3" == "x" ] + then + echo "not running" + /usr/bin/$1 + else + eval "$3" + fi + fi +else + echo "Usage: one-instance program-name [extra action]" +fi + diff --git a/bin/one-terminator.sh b/bin/one-terminator.sh new file mode 100755 index 0000000..3cd18b4 --- /dev/null +++ b/bin/one-terminator.sh @@ -0,0 +1,10 @@ +#!/bin/bash +pgrep -u "$USER" gnome-terminal | grep -qv "$$" +if [ "$?" == "0" ]; then + WID=`xdotool search --class "terminator" | head -1` + xdotool windowfocus $WID + xdotool key ctrl+shift+t + #wmctrl -i -a $WID +else + /usr/bin/gnome-terminal +fi diff --git a/bin/one-tmux b/bin/one-tmux new file mode 100755 index 0000000..7b063c3 --- /dev/null +++ b/bin/one-tmux @@ -0,0 +1,27 @@ +#!/bin/bash +TERMINAL_EMULATOR='urxvt' +tab=1 +pgrep -l -u "$USER" -f "$TERMINAL_EMULATOR" | egrep -v "/bin/zsh|/bin/bash|/bin/sh" | grep -vq "$$" +if [ $? != "0" ] +then + /usr/bin/$TERMINAL_EMULATOR & + sleep 1 + tab=0 +fi +WID=`xdotool search --class $TERMINAL_EMULATOR | tail -1` +wmctrl -i -a $WID +if [ "x$1" != "x" ] +then + if [ "x$1" == "xhelp" ] + then + echo "Usage: $0 [command-in-new-window]" + else + if [ $tab == 1 ] + then + eval "tmux neww" + sleep 0.2 + fi + xdotool type "$*" + xdotool key Return + fi +fi diff --git a/bin/play-europa.sh b/bin/play-europa.sh new file mode 100755 index 0000000..039d668 --- /dev/null +++ b/bin/play-europa.sh @@ -0,0 +1,2 @@ +#!/bin/bash +rtmpdump --live --quiet --buffer 3000 -r rtmp://antena3fms35geobloqueolivefs.fplive.net/antena3fms35geobloqueolive-live/ --playpath stream-europafm | mplayer -vo null -idle - diff --git a/bin/play-hitfm.sh b/bin/play-hitfm.sh new file mode 100755 index 0000000..dcade42 --- /dev/null +++ b/bin/play-hitfm.sh @@ -0,0 +1,2 @@ +#!/bin/bash +mplayer -vo null -idle http://ice.5.c3.audiovideoweb.com:8000/4c3ice5500 diff --git a/bin/play-kiss.sh b/bin/play-kiss.sh new file mode 100755 index 0000000..b9a446b --- /dev/null +++ b/bin/play-kiss.sh @@ -0,0 +1,2 @@ +#!/bin/bash +rtmpdump --live --quiet --buffer 3000 -r rtmp://kissfm.es.flash3.glb.ipercast.net/kissfm.es-live --playpath aac.stream | mplayer -vo null -idle - diff --git a/bin/play-m80.sh b/bin/play-m80.sh new file mode 100755 index 0000000..f4cc511 --- /dev/null +++ b/bin/play-m80.sh @@ -0,0 +1,2 @@ +#!/bin/bash +curl -s http://4633.live.streamtheworld.com/M80RADIOAAC | mplayer -vo null -idle - diff --git a/bin/playlist-radios.xml b/bin/playlist-radios.xml new file mode 100644 index 0000000..c8cf0e6 --- /dev/null +++ b/bin/playlist-radios.xml @@ -0,0 +1,36 @@ + + + Playlist + + + rtmp://antena3fms35geobloqueolivefs.fplive.net/antena3fms35geobloqueolive-live/stream-europafm + EuropaFM + + 0 + network-caching=1000 + + + + http://4633.live.streamtheworld.com:80/M80RADIO_SC + M80 Radio + 125287770 + + 1 + network-caching=1000 + + + + rtmp://kissfm.es.flash3.glb.ipercast.net/kissfm.es-live/aac.stream + KISSFM + + 2 + network-caching=1000 + + + + + + + + + diff --git a/bin/replace-accented.sh b/bin/replace-accented.sh new file mode 100755 index 0000000..95af1f5 --- /dev/null +++ b/bin/replace-accented.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# Note: input should end with a newline + +LINES='' +while read LINE; do + echo $LINE | sed 's/á/a/g' | sed 's/Á/A/g' | sed 's/é/e/g' | sed 's/É/E/g' | sed 's/í/i/g' | sed 's/Í/I/g' | sed 's/ó/o/g' | sed 's/Ó/O/g' | sed 's/ú/u/g' | sed 's/Ú/U/g' | sed 's/ñ/n/g' | sed 's/Ñ/N/g' | sed 's/ü/u/g' | sed 's/Ü/U/g' +done + +exit 0 diff --git a/bin/single-monitor b/bin/single-monitor new file mode 120000 index 0000000..0b0e919 --- /dev/null +++ b/bin/single-monitor @@ -0,0 +1 @@ +single-monitor.sputnik \ No newline at end of file diff --git a/bin/single-monitor.sputnik b/bin/single-monitor.sputnik new file mode 100755 index 0000000..e24550b --- /dev/null +++ b/bin/single-monitor.sputnik @@ -0,0 +1 @@ + xrandr --auto --output eDP1 --primary --output DP1 --off diff --git a/bin/spotify-notify.py b/bin/spotify-notify.py new file mode 100644 index 0000000..f3e299a --- /dev/null +++ b/bin/spotify-notify.py @@ -0,0 +1,417 @@ +#!/usr/bin/python + +# Spotify-notify +# +# v0.6d (28th aug 11) +# by JonW (jon.neverwinter@gmail.com) +# patched 20110907 by Jansen Price (sumpygump@gmail.com) +# patched 20120729 by Jansen Price (sumpygump@gmail.com) and brandl.matthaeus +# +# Original by SveinT (sveint@gmail.com) +# up to v0.5.2 (27th jan 11) + + +import dbus + +import gobject, gtk, os, tempfile, sys, time, re, indicate, urllib2 +from optparse import OptionParser +from subprocess import * + +# The url to use when fetching spotify track information. +SPOTIFY_OPEN_URL = "http://open.spotify.com/track/" + +# The path to this application's directory. +APPLICATION_DIR = sys.path[0] + "/" + +# The file path to spotify. If empty, it will try to auto detect. +SPOTIFY_PROCESS_NAME = 'spotify' + +# How often to check if spotify has been closed (in milliseconds). +SPOTIFY_CLOSED_CHECK = 20000 + +class SpotifyNotify(): + + spotifyPath = '' + + tryToReconnect = False + + tmpfile = False + + def __init__(self, debugger): + self.debug = debugger + self.spotifyservice = False + + self.prev = 0 + self.new = False + self.prevMeta = {} + self.notifyid = 0 + + self.connect() + + def __del__(self): + if SpotifyNotify and SpotifyNotify.tmpfile: + SpotifyNotify.tmpfile.close() + + def connect(self): + self.debug.out("Connecting to spotify.") + self.bus = dbus.Bus(dbus.Bus.TYPE_SESSION) + + try: + self.spotifyservice = self.bus.get_object( + 'com.spotify.qt', + '/org/mpris/MediaPlayer2' + ) + SpotifyNotify.tryToReconnect = False + except Exception, e: + self.spotifyservice = False + self.debug.out("Failed to connect.") + self.debug.out(e) + + def executeCommand(self, key): + if not key: + return + + self.connect() + self.debug.out("Running command: {0}".format(key)) + self.cmd = self.spotifyservice.get_dbus_method(key, 'org.mpris.MediaPlayer2.Player') + self.cmd() + + def pollChange(self): + try: + self.spotifyservice = self.bus.get_object('com.spotify.qt', '/') + self.cmd = self.spotifyservice.get_dbus_method( + 'GetMetadata', + 'org.freedesktop.MediaPlayer2' + ) + self.new = self.cmd() + except Exception, e: + self.debug.out('Spotify service not connected.') + SpotifyNotify.tryToReconnect = True + + if (self.prev != self.new): + self.trackChange(self.new) + self.prev = self.new + + return 1 + + def trackChange(self, *trackChange): + if not trackChange[0]: + return + + self.prev = trackChange[0] + + trackInfo = {} + trackMap = { + 'artist' : 'xesam:artist', + 'album' : 'xesam:album', + 'title' : 'xesam:title', + 'year' : 'xesam:contentCreated', + 'trackhash' : 'mpris:trackid', + 'arturl' : 'mpris:artUrl' + } + + # Fetch the track information for the notification window. + for key in trackMap: + if not trackMap[key] in trackChange[0]: + continue + piece = trackChange[0][trackMap[key]] + if key == 'year': + piece = str(piece[:4]) + elif isinstance(piece, list): + piece = ", ".join(piece) + + if not isinstance(piece, str): + piece = str(piece) + + trackInfo[key] = piece.encode('utf-8') + + if not self.prevMeta\ + or not SpotifyNotify.tmpfile\ + or 'iconfilename' not in self.prevMeta\ + or self.prevMeta['artist'] != trackInfo['artist']\ + or self.prevMeta['album'] != trackInfo['album']: + trackInfo['iconfilename'] = self.retrieveCoverImage(trackInfo) + + cover_image = '' + + if 'iconfilename' in trackInfo: + cover_image = trackInfo['iconfilename'] + elif 'iconfilename' in self.prevMeta: + cover_image = self.prevMeta['iconfilename'] + trackInfo['iconfilename'] = cover_image + + if cover_image == '': + cover_image = APPLICATION_DIR + 'icon_spotify.png' + + self.prevMeta = trackInfo + + # Connect to notification interface on DBUS. + self.notifyservice = self.bus.get_object( + 'org.freedesktop.Notifications', + '/org/freedesktop/Notifications' + ) + self.notifyservice = dbus.Interface( + self.notifyservice, + "org.freedesktop.Notifications" + ) + notifyText = "{0}\n{1}".format( + trackInfo['title'], + trackInfo['album'] + ) + if len(trackInfo['year']) > 0: + notifyText += " ({0})".format(trackInfo['year']) + + # Send track change information to stdout + print "Changing track : {0} | {1} | {2} ({3})".format( + trackInfo['artist'], + trackInfo['title'], + trackInfo['album'], + trackInfo['year'] + ) + + # The second param is the replace id, so get the notify id back, + # store it, and send it as the replacement on the next call. + self.notifyid = self.notifyservice.Notify( + "Spotify-notify", + self.notifyid, + cover_image, + trackInfo['artist'], + notifyText, + [], + {}, + 2000 + ) + + def retrieveCoverImage(self, trackInfo): + if 'arturl' in trackInfo: + self.debug.out("Simply retrieving image from {0}".format(trackInfo['arturl'])) + iconfilename = self.fetchCoverImage(trackInfo['arturl']) + else: + #if (trackInfo['trackhash'][0:14] == 'spotify:local:'): + # self.debug.out("Track is a local file. No art available.") + # return '' + + self.debug.out("Attempting to fetch image from spotify") + iconfilename = self.fetchCoverImageSpotify( + trackInfo['artist'], + trackInfo['album'], + trackInfo['trackhash'] + ) + return iconfilename + + def fetchCoverImageSpotify(self, artist, album, trackhash): + try: + trackid = trackhash.split(":")[2] + url = SPOTIFY_OPEN_URL + trackid + tracksite = urllib2.urlopen(url).read() + + # Attempt to get the image url from the open graph image meta tag. + imageurl = False + metaMatch = re.search( + ']*property\s*=\s*["\']og:image["\'][^\>]*/?>', + tracksite + ) + if metaMatch: + contentMatch = re.search( + 'content\s*=\s*["\']([^\"\']*)["\']', + metaMatch.group(0) + ) + if contentMatch: + imageurl = contentMatch.group(1) + + if not imageurl: + self.debug.out("No cover available.") + raise() + + return self.fetchCoverImage(imageurl) + except Exception, e: + self.debug.out("Couldn't fetch cover image.") + self.debug.out(e) + + return '' + + def fetchCoverImage(self, url): + # Close the temporary image file, we are going to make a new one. + if SpotifyNotify.tmpfile: + SpotifyNotify.tmpfile.close() + SpotifyNotify.tmpfile = False + + try: + SpotifyNotify.tmpfile = tempfile.NamedTemporaryFile() + tmpfilename = SpotifyNotify.tmpfile.name + self.debug.out("Album art tmp filepath: {0}".format(tmpfilename)) + + coverfile = urllib2.urlopen(url) + SpotifyNotify.tmpfile.write(coverfile.read()) + SpotifyNotify.tmpfile.flush() + return tmpfilename + except Exception, e: + self.debug.out("Couldn't fetch cover image.") + self.debug.out(e) + + return '' + + @staticmethod + def startSpotify(Debug): + if not SpotifyNotify.spotifyPath: + Debug.out("No spotify process identifier found.") + return + + ident = SpotifyNotify.spotifyPath + Debug.out("Looking for spotify as: {0}".format(ident)) + + procs = SpotifyNotify.checkForProcess( + 'ps x | grep "{0}" | grep -v grep'.format(ident), + Debug + ) + if len(procs): + Debug.out("Spotify process found as: {0}".format(" ".join(procs[0]))) + return + + Debug.out("Starting new Spotify now.") + + FNULL = open('/dev/null', 'w') + spid = Popen([ident], stdout=FNULL, stderr=FNULL).pid + if spid: + Debug.out("Spotify started, pid: {0}.".format(spid)) + else: + Debug.out("Spotify could not be started.") + + @staticmethod + def checkForClosedSpotify(SN, Debug): + if not SpotifyNotify.spotifyPath: + Debug.out("No spotify process identifier found.") + return False + + ident = SpotifyNotify.spotifyPath + Debug.out("Looking for spotify as: {0}".format(ident)) + + procs = SpotifyNotify.checkForProcess( + 'ps x | grep "{0}" | grep -v grep'.format(ident), + Debug + ) + if len(procs): + Debug.out("Spotify process found as: {0}".format(" ".join(procs[0]))) + + if (SpotifyNotify.tryToReconnect): + SN.connect() + + return True + + if SpotifyNotify.tmpfile: + SpotifyNotify.tmpfile.close() + + Debug.out("Spotify has been closed, therefore I die.") + exit(0) + + @staticmethod + def preventDuplicate(Debug): + mypid = os.getpid() + Debug.out("My pid: {0}".format(mypid)) + + proc = SpotifyNotify.checkForProcess('ps -p {0}'.format(mypid), Debug) + if not proc[0][3]: + return + + process = proc[0][3] + search = 'ps -C {0}'.format(process) + + Debug.out("Looking for other processes named: {0}".format(process).strip()) + + if process == 'python': + if not sys.argv[0]: + Debug.out("Process started using python, cannot determine script name.") + return + + search = 'ps ax | grep "python {0}" | grep -v grep'.format(sys.argv[0]) + + for line in SpotifyNotify.checkForProcess(search, Debug): + if int(line[0]) != mypid: + print("This program was already running.") + Debug.out("I am a duplicate. I shall end myself. ({0})".format(" ".join(line))) + exit(0) + + @staticmethod + def checkForProcess(proc, Debug): + output = [] + + for line in Popen(proc, shell=True, stdout=PIPE).stdout: + fields = line.split() + if not fields[0].isdigit(): + continue + + output.append(fields) + + return output + +class DebugMe(): + def __init__(self, toggle): + if toggle: + self.output = True + else: + self.output = False + + def out(self, msg): + if not self.output: + return + + print(">> {0}".format(msg)) + +if __name__ == "__main__": + parser = OptionParser() + parser.add_option( + '-a', + '--action', + dest = 'action', + default = None, + type = 'choice', + choices = ['playPause', 'play', 'pause', 'next', 'previous'], + help = 'Music player actions (playPause/play/pause/next/previous).' + ) + parser.add_option( + '-n', + '--skip_notify', + dest = 'skipNotify', + action = 'store_true', + default = False, + help = 'Song change notifications will be turned off.' + ) + parser.add_option( + '-d', + '--debug', + dest = 'debug', + action = 'store_true', + default = False, + help = 'Debug messages will be displayed.' + ) + + (options, args) = parser.parse_args() + + Debug = DebugMe(options.debug) + print("Spotify-notify v0.6") + + if SPOTIFY_PROCESS_NAME: + SpotifyNotify.spotifyPath = SPOTIFY_PROCESS_NAME + else: + print "Spotify is not running" + sys.exit(0) + + SN = SpotifyNotify(Debug) + + if options.action: + action = options.action + action = action[0:1].upper() + action[1:] + SN.executeCommand(action) + + SpotifyNotify.preventDuplicate(Debug) + + try: + indicateserver = indicate.indicate_server_ref_default() + indicateserver.set_type("music.spotify") + indicateserver.set_desktop_file("/usr/share/applications/spotify.desktop") + indicateserver.show() + except: + pass + SN.pollChange() + print "Done" + diff --git a/bin/spotify-remote.py b/bin/spotify-remote.py new file mode 100755 index 0000000..a85d44f --- /dev/null +++ b/bin/spotify-remote.py @@ -0,0 +1,420 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +''' + Spoify-remote + Modified version of Spotify-notify that runs once when invoked instead of looping. + v0.6d (28th aug 11) + by JonW (jon.neverwinter@gmail.com) + patched 20110907 by Jansen Price (sumpygump@gmail.com) + patched 20120729 by Jansen Price (sumpygump@gmail.com) and brandl.matthaeus + modified 20130405 by Fernando Sánchez (balkian@gmail.com) + + Original by SveinT (sveint@gmail.com) + up to v0.5.2 (27th jan 11) +''' + +import dbus + +import gobject, gtk, os, tempfile, sys, time, re, indicate, urllib2 +from optparse import OptionParser +from subprocess import * + +# The url to use when fetching spotify track information. +SPOTIFY_OPEN_URL = "http://open.spotify.com/track/" + +# The path to this application's directory. +APPLICATION_DIR = sys.path[0] + "/" + +# The file path to spotify. If empty, it will try to auto detect. +SPOTIFY_PROCESS_NAME = 'spotify' + +# How often to check if spotify has been closed (in milliseconds). +SPOTIFY_CLOSED_CHECK = 20000 + +class SpotifyNotify(): + + spotifyPath = '' + + tryToReconnect = False + + tmpfile = False + + def __init__(self, debugger): + self.debug = debugger + self.spotifyservice = False + + self.prev = 0 + self.new = False + self.prevMeta = {} + self.notifyid = 0 + + self.connect() + + def __del__(self): + if SpotifyNotify and SpotifyNotify.tmpfile: + SpotifyNotify.tmpfile.close() + + def connect(self): + self.debug.out("Connecting to spotify.") + self.bus = dbus.Bus(dbus.Bus.TYPE_SESSION) + + try: + self.spotifyservice = self.bus.get_object( + 'com.spotify.qt', + '/org/mpris/MediaPlayer2' + ) + SpotifyNotify.tryToReconnect = False + except Exception, e: + self.spotifyservice = False + self.debug.out("Failed to connect.") + self.debug.out(e) + + def executeCommand(self, key): + if not key: + return + + self.connect() + self.debug.out("Running command: {0}".format(key)) + self.cmd = self.spotifyservice.get_dbus_method(key, 'org.mpris.MediaPlayer2.Player') + self.cmd() + + def pollChange(self): + try: + self.spotifyservice = self.bus.get_object('com.spotify.qt', '/') + self.cmd = self.spotifyservice.get_dbus_method( + 'GetMetadata', + 'org.freedesktop.MediaPlayer2' + ) + self.new = self.cmd() + except Exception, e: + self.debug.out('Spotify service not connected.') + SpotifyNotify.tryToReconnect = True + + if (self.prev != self.new): + self.trackChange(self.new) + self.prev = self.new + + return 1 + + def trackChange(self, *trackChange): + if not trackChange[0]: + return + + self.prev = trackChange[0] + + trackInfo = {} + trackMap = { + 'artist' : 'xesam:artist', + 'album' : 'xesam:album', + 'title' : 'xesam:title', + 'year' : 'xesam:contentCreated', + 'trackhash' : 'mpris:trackid', + 'arturl' : 'mpris:artUrl' + } + + # Fetch the track information for the notification window. + for key in trackMap: + if not trackMap[key] in trackChange[0]: + continue + piece = trackChange[0][trackMap[key]] + if key == 'year': + piece = str(piece[:4]) + elif isinstance(piece, list): + piece = ", ".join(piece) + + if not isinstance(piece, str): + piece = str(piece) + + trackInfo[key] = piece.encode('utf-8') + + if not self.prevMeta\ + or not SpotifyNotify.tmpfile\ + or 'iconfilename' not in self.prevMeta\ + or self.prevMeta['artist'] != trackInfo['artist']\ + or self.prevMeta['album'] != trackInfo['album']: + trackInfo['iconfilename'] = self.retrieveCoverImage(trackInfo) + + cover_image = '' + + if 'iconfilename' in trackInfo: + cover_image = trackInfo['iconfilename'] + elif 'iconfilename' in self.prevMeta: + cover_image = self.prevMeta['iconfilename'] + trackInfo['iconfilename'] = cover_image + + if cover_image == '': + cover_image = APPLICATION_DIR + 'icon_spotify.png' + + self.prevMeta = trackInfo + + # Connect to notification interface on DBUS. + self.notifyservice = self.bus.get_object( + 'org.freedesktop.Notifications', + '/org/freedesktop/Notifications' + ) + self.notifyservice = dbus.Interface( + self.notifyservice, + "org.freedesktop.Notifications" + ) + notifyText = "{0}\n{1}".format( + trackInfo['title'], + trackInfo['album'] + ) + if len(trackInfo['year']) > 0: + notifyText += " ({0})".format(trackInfo['year']) + + # Send track change information to stdout + print "Changing track : {0} | {1} | {2} ({3})".format( + trackInfo['artist'], + trackInfo['title'], + trackInfo['album'], + trackInfo['year'] + ) + + # The second param is the replace id, so get the notify id back, + # store it, and send it as the replacement on the next call. + self.notifyid = self.notifyservice.Notify( + "Spotify-notify", + self.notifyid, + cover_image, + trackInfo['artist'], + notifyText, + [], + {}, + 2000 + ) + + def retrieveCoverImage(self, trackInfo): + if 'arturl' in trackInfo: + self.debug.out("Simply retrieving image from {0}".format(trackInfo['arturl'])) + iconfilename = self.fetchCoverImage(trackInfo['arturl']) + else: + #if (trackInfo['trackhash'][0:14] == 'spotify:local:'): + # self.debug.out("Track is a local file. No art available.") + # return '' + + self.debug.out("Attempting to fetch image from spotify") + iconfilename = self.fetchCoverImageSpotify( + trackInfo['artist'], + trackInfo['album'], + trackInfo['trackhash'] + ) + return iconfilename + + def fetchCoverImageSpotify(self, artist, album, trackhash): + try: + trackid = trackhash.split(":")[2] + url = SPOTIFY_OPEN_URL + trackid + tracksite = urllib2.urlopen(url).read() + + # Attempt to get the image url from the open graph image meta tag. + imageurl = False + metaMatch = re.search( + ']*property\s*=\s*["\']og:image["\'][^\>]*/?>', + tracksite + ) + if metaMatch: + contentMatch = re.search( + 'content\s*=\s*["\']([^\"\']*)["\']', + metaMatch.group(0) + ) + if contentMatch: + imageurl = contentMatch.group(1) + + if not imageurl: + self.debug.out("No cover available.") + raise() + + return self.fetchCoverImage(imageurl) + except Exception, e: + self.debug.out("Couldn't fetch cover image.") + self.debug.out(e) + + return '' + + def fetchCoverImage(self, url): + # Close the temporary image file, we are going to make a new one. + if SpotifyNotify.tmpfile: + SpotifyNotify.tmpfile.close() + SpotifyNotify.tmpfile = False + + try: + SpotifyNotify.tmpfile = tempfile.NamedTemporaryFile() + tmpfilename = SpotifyNotify.tmpfile.name + self.debug.out("Album art tmp filepath: {0}".format(tmpfilename)) + + coverfile = urllib2.urlopen(url) + SpotifyNotify.tmpfile.write(coverfile.read()) + SpotifyNotify.tmpfile.flush() + return tmpfilename + except Exception, e: + self.debug.out("Couldn't fetch cover image.") + self.debug.out(e) + + return '' + + @staticmethod + def startSpotify(Debug): + if not SpotifyNotify.spotifyPath: + Debug.out("No spotify process identifier found.") + return + + ident = SpotifyNotify.spotifyPath + Debug.out("Looking for spotify as: {0}".format(ident)) + + procs = SpotifyNotify.checkForProcess( + 'ps x | grep "{0}" | grep -v grep'.format(ident), + Debug + ) + if len(procs): + Debug.out("Spotify process found as: {0}".format(" ".join(procs[0]))) + return + + Debug.out("Starting new Spotify now.") + + FNULL = open('/dev/null', 'w') + spid = Popen([ident], stdout=FNULL, stderr=FNULL).pid + if spid: + Debug.out("Spotify started, pid: {0}.".format(spid)) + else: + Debug.out("Spotify could not be started.") + + @staticmethod + def checkForClosedSpotify(SN, Debug): + if not SpotifyNotify.spotifyPath: + Debug.out("No spotify process identifier found.") + return False + + ident = SpotifyNotify.spotifyPath + Debug.out("Looking for spotify as: {0}".format(ident)) + + procs = SpotifyNotify.checkForProcess( + 'ps x | grep "{0}" | grep -v grep'.format(ident), + Debug + ) + if len(procs): + Debug.out("Spotify process found as: {0}".format(" ".join(procs[0]))) + + if (SpotifyNotify.tryToReconnect): + SN.connect() + + return True + + if SpotifyNotify.tmpfile: + SpotifyNotify.tmpfile.close() + + Debug.out("Spotify has been closed, therefore I die.") + exit(0) + + @staticmethod + def preventDuplicate(Debug): + mypid = os.getpid() + Debug.out("My pid: {0}".format(mypid)) + + proc = SpotifyNotify.checkForProcess('ps -p {0}'.format(mypid), Debug) + if not proc[0][3]: + return + + process = proc[0][3] + search = 'ps -C {0}'.format(process) + + Debug.out("Looking for other processes named: {0}".format(process).strip()) + + if process == 'python': + if not sys.argv[0]: + Debug.out("Process started using python, cannot determine script name.") + return + + search = 'ps ax | grep "python {0}" | grep -v grep'.format(sys.argv[0]) + + for line in SpotifyNotify.checkForProcess(search, Debug): + if int(line[0]) != mypid: + print("This program was already running.") + Debug.out("I am a duplicate. I shall end myself. ({0})".format(" ".join(line))) + exit(0) + + @staticmethod + def checkForProcess(proc, Debug): + output = [] + + for line in Popen(proc, shell=True, stdout=PIPE).stdout: + fields = line.split() + if not fields[0].isdigit(): + continue + + output.append(fields) + + return output + +class DebugMe(): + def __init__(self, toggle): + if toggle: + self.output = True + else: + self.output = False + + def out(self, msg): + if not self.output: + return + + print(">> {0}".format(msg)) + +if __name__ == "__main__": + parser = OptionParser() + parser.add_option( + '-a', + '--action', + dest = 'action', + default = None, + type = 'choice', + choices = ['playPause', 'play', 'pause', 'next', 'previous'], + help = 'Music player actions (playPause/play/pause/next/previous).' + ) + parser.add_option( + '-n', + '--skip_notify', + dest = 'skipNotify', + action = 'store_true', + default = False, + help = 'Song change notifications will be turned off.' + ) + parser.add_option( + '-d', + '--debug', + dest = 'debug', + action = 'store_true', + default = False, + help = 'Debug messages will be displayed.' + ) + + (options, args) = parser.parse_args() + + Debug = DebugMe(options.debug) + print("Spotify-notify v0.6") + + if SPOTIFY_PROCESS_NAME: + SpotifyNotify.spotifyPath = SPOTIFY_PROCESS_NAME + else: + print "Spotify is not running" + sys.exit(0) + + SN = SpotifyNotify(Debug) + + if options.action: + action = options.action + action = action[0:1].upper() + action[1:] + SN.executeCommand(action) + + SpotifyNotify.preventDuplicate(Debug) + + try: + indicateserver = indicate.indicate_server_ref_default() + indicateserver.set_type("music.spotify") + indicateserver.set_desktop_file("/usr/share/applications/spotify.desktop") + indicateserver.show() + except: + pass + SN.pollChange() + print "Done" + diff --git a/bin/spotify-remote.sh b/bin/spotify-remote.sh new file mode 100755 index 0000000..49d760e --- /dev/null +++ b/bin/spotify-remote.sh @@ -0,0 +1,114 @@ +#!/bin/bash +# Extracted from: http://ubuntuforums.org/showthread.php?t=1797848 +# User: azzid +# Modified by Balkian +# Collect DBUS_SESSION_BUS_ADDRESS from running process +function set_dbus_adress +{ + USER=$1 + PROCESS=$2 + PID=`pgrep -o -u $USER $PROCESS` + ENVIRON=/proc/$PID/environ + + if [ -e $ENVIRON ] + then + export `grep -z DBUS_SESSION_BUS_ADDRESS $ENVIRON` + else + echo "Unable to set DBUS_SESSION_BUS_ADDRESS." + exit 1 + fi +} + +function spotify_cmd +{ + dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.$1 1> /dev/null +} + +function spotify_query +{ + qdbus org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get org.mpris.MediaPlayer2.Player PlaybackStatus +} + +function spotify_metadata +{ + qdbus com.spotify.qt / org.freedesktop.MediaPlayer2.GetMetadata +} + +function spotify_notify +{ + metadata=`spotify_metadata` + echo "Metadata: $metadata" + title=`echo "$metadata" | grep title | cut -d' ' -f2-` + artist=`echo "$metadata" | grep artist | cut -d' ' -f2-` + image=`echo "$metadata" | grep artUrl | cut -d' ' -f3` + wget $image -O /tmp/image + echo "notifying $title" + notify-send "$artist" "$title" --icon=/tmp/image +} + +function quit_message +{ + echo "Usage: `basename $0` {play|pause|playpause|next|previous|stop|playstatus|}" + exit 1 +} + +# Count arguments, must be 1 +if [ "$#" -ne "1" ] +then + echo -e "You must supply exactly one argument!\n" + quit_message +fi + +# Check if DBUS_SESSION is set +if [ -z $DBUS_SESSION_BUS_ADDRESS ] + then + #echo "DBUS_SESSION_BUS_ADDRESS not set. Guessing." + set_dbus_adress `whoami` spotify +fi + +case "$1" in + play) + spotify_cmd Play + spotify_notify + ;; + pause) + spotify_cmd Pause + spotify_notify + ;; + playpause) + spotify_cmd PlayPause + spotify_notify + ;; + next) + spotify_cmd Next + spotify_notify + ;; + previous) + spotify_cmd Previous + spotify_notify + ;; + stop) + spotify_cmd Stop + spotify_notify + ;; + spotify:user:*) + spotify_cmd "OpenUri string:$1" + spotify_cmd Play + spotify_notify + ;; + spotify:*:*) + spotify_cmd "OpenUri string:$1" + ;; + playstatus) + spotify_query + ;; + metadata) + spotify_metadata; + ;; + *) + echo -e "Bad argument.\n" + quit_message + ;; +esac + +exit 0 diff --git a/bin/start-eclipse.sh b/bin/start-eclipse.sh new file mode 100644 index 0000000..b2ccd8b --- /dev/null +++ b/bin/start-eclipse.sh @@ -0,0 +1,17 @@ +#!/bin/bash +cd $(dirname $(dirname $0)) +eclipse/eclipse -vm jre1.6.0_20/bin/ || failed=1 +if [ $failed -eq 1 ]; then + + zenity --warning --title "Error executing eclipse's launcher" --text "Eclipse couldn't be found in $(pwd), please, modify $0 script to point to the right location" || exit + file=$(zenity --file-selection --title "Select the right executable"); + vm=$(zenity --file-selection --title "Select virtual machine"); + + echo $file; + if [ -n "$file" ]; then + if [ -n "$vm" ]; then + virt=" -vm $vm"; + fi + $file $virt + fi +fi diff --git a/bin/terminator b/bin/terminator new file mode 100755 index 0000000..e0cde22 --- /dev/null +++ b/bin/terminator @@ -0,0 +1,2 @@ +#!/bin/bash +one-window "terminator" "xdotool windowfocus \$WID & xdotool key ctrl+shift+t;" "/usr/bin/terminator $*" diff --git a/bin/tmux-zoom.sh b/bin/tmux-zoom.sh new file mode 100755 index 0000000..65b4991 --- /dev/null +++ b/bin/tmux-zoom.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Copyright (c) 2012 Juan Ignacio Pumarino, jipumarino@gmail.com +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# Instructions +# ------------ +# +# 1. Install this script and give it execute permission somewhere in your PATH. +# For example: +# +# $ mkdir -p ~/bin +# $ wget https://raw.github.com/jipumarino/tmux-zoom/master/tmux-zoom.sh -O ~/bin/tmux-zoom.sh +# $ chmod +x ~/bin/tmux-zoom.sh +# +# 2. Add a shortcut in your ~/.tmux.conf file: +# +# bind C-k run "tmux-zoom.sh" +# +# 3. When using this shortcut, the current tmux pane will open in a new window by itself. +# Running it again in the zoomed window will return it to its original pane. You can have +# as many zoomed windows as you want. + +current=$(tmux display-message -p '#W-#I-#P') +list=$(tmux list-window) + +[[ "$current" =~ ^(.*)-([0-9]+)-([0-9]+) ]] +current_window=${BASH_REMATCH[1]} +current_pane=${BASH_REMATCH[2]}-${BASH_REMATCH[3]} +new_zoom_window=ZOOM-$current_pane + +if [[ $current_window =~ ZOOM-([0-9]+)-([0-9+]) ]]; then + if [ "$(tmux list-panes | wc -l)" -gt 1 ]; then + tmux display-message "other panes exist" + exit 0 + fi + old_zoom_window=ZOOM-${BASH_REMATCH[1]}-${BASH_REMATCH[2]} + tmux select-window -t ${BASH_REMATCH[1]} \; select-pane -t ${BASH_REMATCH[2]} \; swap-pane -s $old_zoom_window.0 \; kill-window -t $old_zoom_window +elif [[ $list =~ $new_zoom_window ]]; then + tmux select-window -t $new_zoom_window +else + if [ "$(tmux list-panes | wc -l)" -eq 1 ]; then + tmux display-message "already zoomed" + exit 0 + fi + tmux new-window -d -n $new_zoom_window \; swap-pane -s $new_zoom_window.0 \; select-window -t $new_zoom_window +fi diff --git a/bin/unlock-livebox.py b/bin/unlock-livebox.py new file mode 100644 index 0000000..4db9c8a --- /dev/null +++ b/bin/unlock-livebox.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import telnetlib, time + +# Poner esto a 0 para deshabilitar las opciones del menú +# o a 1 para habilitarlas +HABILITAR = 1; + +tn = telnetlib.Telnet ( "192.168.1.1" ); +tn.read_until("login: "); +tn.write("LBV2techno\n"); +tn.read_until("Password: "); +tn.write("1901b95ae4295d613abf9eabae0b9d40\n"); +for i in `range(1,3)`: + tn.write("\n"); + tn.write("rg_conf_set wbm/settings/pages/backuprestore %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/pages/vpn %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/pages/fax %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/pages/log %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/pages/licence %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/pages/community %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/pages/visio %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/pages/livezoom %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/pages/hsiab %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/network/dhcp %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/network/ftlock %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/network/ftlock %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/network/tvrouted %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/services/professionnal %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/services/rtcphone %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/services/universal_phone %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/services/wifipushbutton %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/services/msgwaiting %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/test/sipdev %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/test/fmdev %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/network/h323 %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("rg_conf_set wbm/settings/services/wpspushbutton %i\n" % HABILITAR); + tn.read_until("Returned 0"); + tn.write("save\n"); + time.sleep(2); + tn.write("reboot\n"); diff --git a/bin/volume-down.sh b/bin/volume-down.sh new file mode 100755 index 0000000..ce11826 --- /dev/null +++ b/bin/volume-down.sh @@ -0,0 +1,2 @@ +#!/bin/sh +pacmd dump|awk --non-decimal-data '$1~/set-sink-volume/{system ("pacmd "$1" "$2" "$3-1000)}' diff --git a/bin/volume-toggle-mute.sh b/bin/volume-toggle-mute.sh new file mode 100755 index 0000000..089bf89 --- /dev/null +++ b/bin/volume-toggle-mute.sh @@ -0,0 +1,2 @@ +#!/bin/sh +pacmd dump|awk --non-decimal-data '$1~/set-sink-mute/{system ("pacmd "$1" "$2" "($3=="yes"?"no":"yes"))}' diff --git a/bin/volume-up.sh b/bin/volume-up.sh new file mode 100755 index 0000000..626be12 --- /dev/null +++ b/bin/volume-up.sh @@ -0,0 +1,2 @@ +#!/bin/sh +pacmd dump|awk --non-decimal-data '$1~/set-sink-volume/{system ("pacmd "$1" "$2" "$3+1000)}' diff --git a/bin/winfuncs.sh b/bin/winfuncs.sh new file mode 100755 index 0000000..f3e20db --- /dev/null +++ b/bin/winfuncs.sh @@ -0,0 +1,194 @@ +#!/bin/bash +# Extracted from:http://forum.xfce.org/viewtopic.php?id=6841 ¡ +#todo: +# cancel for tile functions +# determine what windows are maximized and re-max after the "window select" function +# determine what windows are non-resizable by the user so that the script doesn't resize them +# cascade also shaded windows + +# which workspace we're on +function get_workspace { + if [[ "$DTOP" == "" ]] ; then + DTOP=`xdotool get_desktop` + fi +} + +function is_desktop { + xwininfo -id "$*" | grep '"Desktop"' + return "$?" +} + +function get_visible_window_ids { + if (( ${#WDOWS[@]} == 0 )) ; then + WDOWS=(`xdotool search --desktop $DTOP --onlyvisible "" 2>/dev/null`) + fi +} + +function get_desktop_dim { + #desktop dimensions + if (( ${#DIM[@]} == 0 )) ; then + DIM=(`wmctrl -d | egrep "^0" | sed 's/.*DG: \([0-9]*x[0-9]*\).*/\1/g' | sed 's/x/ /g'`) + fi +} + +function win_showdesktop { + get_workspace + get_visible_window_ids + + command="search --desktop $DTOP \"\"" + + if (( ${#WDOWS[@]} > 0 )) ; then + command="$command windowminimize %@" + else + command="$command windowraise %@" + fi + + echo "$command" | xdotool - +} + +function win_tile_two { + get_desktop_dim + wid1=`xdotool selectwindow 2>/dev/null` + + is_desktop "$wid1" && return + + wid2=`xdotool selectwindow 2>/dev/null` + + is_desktop "$wid2" && return + + half_w=`expr ${DIM[0]} / 2` + + commands="windowsize $wid1 $half_w ${DIM[1]}" + commands="$commands windowsize $wid2 $half_w ${DIM[1]}" + commands="$commands windowmove $wid1 0 0" + commands="$commands windowmove $wid2 $half_w 0" + commands="$commands windowraise $wid1" + commands="$commands windowraise $wid2" + + wmctrl -i -r $wid1 -b remove,maximized_vert,maximized_horz + wmctrl -i -r $wid2 -b remove,maximized_vert,maximized_horz + + echo "$commands" | xdotool - +} + +function win_tile { + get_workspace + get_visible_window_ids + + (( ${#WDOWS[@]} < 1 )) && return; + + get_desktop_dim + + # determine how many rows and columns we need + cols=`echo "sqrt(${#WDOWS[@]})" | bc` + rows=$cols + wins=`expr $rows \* $cols` + + if (( "$wins" < "${#WDOWS[@]}" )) ; then + cols=`expr $cols + 1` + wins=`expr $rows \* $cols` + if (( "$wins" < "${#WDOWS[@]}" )) ; then + rows=`expr $rows + 1` + wins=`expr $rows \* $cols` + fi + fi + + (( $cols < 1 )) && cols=1; + (( $rows < 1 )) && rows=1; + + win_w=`expr ${DIM[0]} / $cols` + win_h=`expr ${DIM[1]} / $rows` + + # do tiling + x=0; y=0; commands="" + for window in ${WDOWS[@]} ; do + wmctrl -i -r $window -b remove,maximized_vert,maximized_horz + + commands="$commands windowsize $window $win_w $win_h" + commands="$commands windowmove $window `expr $x \* $win_w` `expr $y \* $win_h`" + + x=`expr $x + 1` + if (( $x > `expr $cols - 1` )) ; then + x=0 + y=`expr $y + 1` + fi + done + + echo "$commands" | xdotool - +} + +function win_cascade { + get_workspace + get_visible_window_ids + + (( ${#WDOWS[@]} < 1 )) && return; + + x=0; y=0; commands="" + for window in ${WDOWS[@]} ; do + wmctrl -i -r $window -b remove,maximized_vert,maximized_horz + + commands="$commands windowsize $window 640 480" + commands="$commands windowmove $window $x $y" + + x=`expr $x + 22` + y=`expr $y + 22` + done + + echo "$commands" | xdotool - +} + +function win_select { + get_workspace + get_visible_window_ids + + (( ${#WDOWS[@]} < 1 )) && return; + + # store window positions and widths + i=0 + for window in ${WDOWS[@]} ; do + GEO=`xdotool getwindowgeometry $window | grep Geometry | sed 's/.* \([0-9].*\)/\1/g'`; + height[$i]=`echo $GEO | sed 's/\(.*\)x.*/\1/g'` + width[$i]=`echo $GEO | sed 's/.*x\(.*\)/\1/g'` + + # ( xwininfo gives position not ignoring titlebars and borders, unlike xdotool ) + POS=(`xwininfo -stats -id $window | grep 'geometry ' | sed 's/.*[-+]\([0-9]*[-+][0-9*]\)/\1/g' | sed 's/[+-]/ /g'`) + posx[$i]=${POS[0]} + posy[$i]=${POS[1]} + + i=`expr $i + 1` + done + + # tile windows + win_tile + + # select a window + wid=`xdotool selectwindow 2>/dev/null` + + is_desktop "$wid" && return + + # restore window positions and widths + i=0; commands="" + for (( i=0; $i<${#WDOWS[@]}; i++ )) ; do + commands="$commands windowsize ${WDOWS[i]} ${height[$i]} ${width[$i]}" + commands="$commands windowmove ${WDOWS[i]} ${posx[$i]} ${posy[$i]}" + done + + commands="$commands windowraise $wid" + + echo "$commands" | xdotool - +} + +for command in ${@} ; do + if [[ "$command" == "tile" ]] ; then + win_tile + elif [[ "$command" == "select" ]] ; then + win_select + elif [[ "$command" == "tiletwo" ]] ; then + win_tile_two + elif [[ "$command" == "cascade" ]] ; then + win_cascade + elif [[ "$command" == "showdesktop" ]] ; then + win_showdesktop + fi +done +