actual scripts

This commit is contained in:
Timothy Allen 2015-06-15 01:58:20 +02:00
parent 7c4bc93b3c
commit 5b9d32f886
7 changed files with 406 additions and 0 deletions

143
backup_mpd_playlist.py Executable file
View File

@ -0,0 +1,143 @@
#!/usr/bin/env python
# Back up the state of MPD (current playlist and so on)
import ast
import datetime
import os
import re
import sys
import pprint
import mpd
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-s", "--server", dest="host",
help="set the MPD hostname (default: localhost)", metavar="HOST")
parser.add_option("-p", "--port", dest="port",
help="set the MPD port (default: 6600)", metavar="6600")
parser.add_option("-d", dest="dest",
help="save or load the backup to directory <DIR>", metavar="DIR")
parser.add_option("-l", dest="load", action="store_true",
help="load the last backup")
parser.add_option("-f", "--file", dest="load_file",
help="load the backup in file <FILE>", metavar="FILE")
(options, args) = parser.parse_args()
host = options.host or 'localhost'
port = options.port or '6600'
backup_dir = options.dest or '/var/lib/mpd/backups'
now = datetime.datetime.now().strftime("%Y%m%d@%H:%M")
client = mpd.MPDClient()
client.timeout = 10
client.idletimeout = 10
client.connect(host, port)
# Get the contents of the most recent backup
all_backups = [os.path.join(backup_dir, f) for f in os.listdir(backup_dir) if f.startswith('mpd_state')]
last_backup = max(all_backups, key=os.path.getctime) if all_backups else []
backup_output = open(last_backup).read() if last_backup else ''
if options.load or options.load_file:
# Override the last backup if the user desires
if options.load_file:
if not os.path.exists(options.load_file):
sys.exit("No such file: " + options.load_file)
backup_output = open(options.load_file).read()
# load file into backup_output
backup = ast.literal_eval(backup_output)
# Check server and port
if backup['src'] != host+":"+port:
if not sys.stdin.isatty():
sys.exit("Error: Backup is from a different server or port.")
c = raw_input("Error: Backup is from a different server or port. Continue? (y/N) ").rstrip('\n')
if c != 'Y' and c != 'y':
sys.exit("Exiting.")
# Clear playlist
client.clear()
# Load songs
for song in backup['playlist']:
try:
client.add(song)
except mpd.CommandError as e:
print("File not found: %s" % e)
pass
# Parse and communicate extra info
if 'repeat' in backup:
client.repeat(backup['repeat'])
if 'random' in backup:
client.random(backup['random'])
if 'single' in backup:
client.single(backup['single'])
if 'consume' in backup:
client.consume(backup['consume'])
id = None
if 'current' in backup:
for song in client.playlistinfo():
if song['file'] == backup['current']:
id = song['id']
print song['file']
print id
next
if not id:
print "Error: Can't find currently-playing song on playlist."
if 'time' in backup and id:
client.seekid(id, backup['time'])
if 'state' in backup:
if backup['state'] == 'play':
client.play()
elif backup['state'] == 'pause':
client.pause(1)
elif backup['state'] == 'stop':
client.stop()
# setvol returns an error, for some reason
# mpd.CommandError: [52@0] {setvol} problems setting volume
#if 'volume' in backup:
# client.setvol(backup['volume'])
else:
# Get current state
get_status = client.status()
get_playlist = client.playlistinfo()
get_currentsong = client.currentsong()
state = {}
playlist = []
for song in get_playlist:
playlist.append(song["file"])
state = dict(
playlist = playlist,
src = host+":"+port,
consume = get_status['consume'],
current = get_currentsong['file'] if get_currentsong['file'] else '',
time = get_status['time'].split(":")[0] if get_status['time'] else '',
random = get_status['random'],
repeat = get_status['repeat'],
single = get_status['single'],
state = get_status['state'],
volume = get_status['volume'],
)
pp = pprint.PrettyPrinter(indent=4)
current_output = pp.pformat(state)
# We don't care if the volume or currently-playing song has changed, only
# the playlist
strip = re.compile(r'\s*?[\'\"](consume|current|random|repeat|single|state|time|volume)[\'\"]:\s*?[\'\"].*?[\'\"],?');
curr = strip.sub('', current_output)
prev = strip.sub('', backup_output)
# Only copy if the current playlist has changed
if current_output != backup_output:
new_backup_file = os.path.join(backup_dir, 'mpd_state' + "-" + now)
# Write backup
new_backup = open(new_backup_file, 'w')
new_backup.write(current_output)
new_backup.close()
client.close()
client.disconnect()
# vim: set expandtab shiftwidth=4 softtabstop=4 textwidth=79:

20
decode_mime.pl Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/perl
use Email::MIME;
use warnings;
use strict;
unless ($ARGV[0] and -f $ARGV[0]) {
die "pass in the filename of the email as an argument.";
}
open FILE, "<$ARGV[0]";
undef $/;
my $email = <FILE>;
my $parsed = Email::MIME->new($email);
my @parts = $parsed->parts;
foreach my $el (@parts) {
print $el->body;
last;
}

81
detect_bluetooth.py Executable file
View File

@ -0,0 +1,81 @@
#!/usr/bin/env python
# Ensure that the default device gets set to bluetooth when a bluetooth
# device is plugged in
#
# This allows the system volume meter to set the volume
#
# Also make it not full volume too (currently 50%)
#
# Timothy Allen <tim@treehouse.org.za>
import dbus
import gobject
import atexit
import re
from subprocess import Popen, PIPE
from dbus.mainloop.glib import DBusGMainLoop
def get_sinks():
sinks = Popen(["pacmd", "list-sinks"], shell=False, stdout=PIPE).communicate()[0]
m = re.findall(r"name: <(.*?)>", sinks)
return m
def get_default_sink():
sinks = Popen(["pacmd", "info"], shell=False, stdout=PIPE).communicate()[0]
m = re.findall(r"Default sink name: (.*?)\s", sinks)
return m
def set_default_sink(sink):
print "Setting sink: %s" % sink
Popen(["pacmd", "set-default-sink", sink], shell=False, stdout=PIPE).communicate()[0]
# Volume is a percent
def set_volume(sink, volume):
print "Setting volume for sink %s to: %d" % (sink, volume)
volume = str(int(65536*(float(str(volume).strip("%"))/100)))
Popen(["pacmd", "set-sink-volume", sink, volume], shell=False, stdout=PIPE).communicate()[0]
def device_change(name, value, iface=None, path=None):
#print "Name: %s \nValue: %s\nInterface: %s \nPath: %s" % (name, value, iface, path)
if (value == "connected"):
# set path as default pulse device
for sink in get_sinks():
if re.match("bluez", sink):
set_default_sink(sink)
# change volume
set_volume(sink, volume)
# elif (value == "disconnected"):
# # change default device is there's one sink left
# sinks = get_sinks()
# if isinstance(sinks, basestring):
# set_default_sink(sink)
# else:
# set_default_sink(initial_sink)
# Volume is a value out of 100
volume=50
loop = gobject.MainLoop()
dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)
#bluez = bus.get_object("org.bluez", "/");
#manager = dbus.Interface(bluez, "org.bluez.Manager")
#adapter = dbus.Interface(manager.DefaultAdapter(), "org.bluez.Adapter")
#proxy = bus.get_object("org.bluez", manager.DefaultAdapter())
bus.add_signal_receiver(device_change,
signal_name=None,
dbus_interface="org.bluez.Audio",
interface_keyword="iface",
path_keyword="path")
initial_sink = get_default_sink();
atexit.register(loop.quit)
loop.run()
# vi: filetype=python:expandtab:shiftwidth=4:softtabstop=4:tw=0

71
get_firefox_tabs.py Executable file
View File

@ -0,0 +1,71 @@
#!/usr/bin/python
#
# Taken in part from https://gist.github.com/ssokolow/35097553e5173935e597
import glob, json, os, re
def get_tab_metadata(tab):
grp_id = None
grp_data = tab.get('extData', {}).get('tabview-tab', {})
if grp_data:
grp_data = json.loads(grp_data)
if grp_data:
grp_id = grp_data.get('groupID', None)
del grp_data
content = tab['entries'][-1] # -1 is most recent
return {
'index' : tab.get('index'),
'group' : grp_id,
'title' : content.get('title', content.get('url')),
'url' : content.get('url'),
'pinned': tab.get('pinned', False)
}
def get_tabgroups(data):
windows = []
for window in data['windows']:
grp_names = json.loads(window.get('extData', {}).get(
'tabview-group', '{}'))
grp_names = {int(x): grp_names[x]['title'] for x in grp_names.keys()}
tabs = []
for tab in window['tabs']:
tabs.append(get_tab_metadata(tab))
# Group the tabs by group ID and then replace the IDs with the
# group names without risking naming collisions
groups = {}
for tab in tabs:
groups.setdefault(tab['group'], []).append(tab)
groups = [(grp_names.get(k, None), v) for k, v in groups.items()]
groups.sort() # TODO: Sort case-insensitively
windows.append(groups)
return windows
def print_tabs(groups):
for pos, window in enumerate(groups):
#print 'Window ' + str(pos+1)
for group, tabs in window:
if not group and all(x.get('pinned') for x in tabs):
grp_name = 'Window ' + str(pos+1) + ' | Pinned Tabs'
else:
grp_name = group or 'Unnamed'
print 'Window ' + str(pos+1) + ' | Group: ' + grp_name
for x in tabs:
print '\t' + x['title']
print '\t' + x['url']
print
filenames = glob.glob(os.path.expanduser('~/.mozilla/firefox/*/sessionstore-backups/recovery.js'))
for filename in filenames:
with open(filename, 'r') as fobj:
data = json.load(fobj)
groups = get_tabgroups(data)
print_tabs(groups)
# vim: expandtab shiftwidth=4 softtabstop=4 tw=500

6
lock_screen Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
source ~/bin/get_dbus_session
dbus-send --type=method_call --dest=org.gnome.ScreenSaver \
/org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock

76
netflix-screensaver.py Executable file
View File

@ -0,0 +1,76 @@
#!/usr/bin/env python
# Send a signal to DBus to inhibit the screensaver
# if Netflix is running (and playing a movie)
#
# Timothy Allen <tim@treehouse.org.za>
import dbus
import gobject
import atexit
from re import match, search
from time import sleep
from subprocess import Popen, PIPE
from dbus.mainloop.glib import DBusGMainLoop
debugging=0
loop = gobject.MainLoop()
dbus_loop = DBusGMainLoop()
bus = dbus.SessionBus(mainloop=dbus_loop)
screensaver = bus.get_object("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver");
def debug(text):
if debugging:
print text
# Inhibit
def inhibit():
debug("Inhibiting...")
return screensaver.Inhibit("netflix-desktop", "Playing a movie", dbus_interface="org.freedesktop.ScreenSaver")
# Uninhibit
def uninhibit(cookie):
if match("\d{2,}", str(cookie)):
debug("Uninhibiting...")
# Should return None
return screensaver.UnInhibit(cookie, dbus_interface="org.freedesktop.ScreenSaver")
else:
debug("No cookie, not uninhibiting")
return None
atexit.register(loop.quit)
if loop.is_running:
cookie=None
netflix_on=False
while True:
# Get process list
ps = Popen(['ps', 'ax'], shell=False, stdout=PIPE).communicate()[0]
# Search for the netflix process (and Silverlight to
# only inhibit if a movie is playing)
#if search("netflix-desktop", ps):
if search("netflix-desktop", ps) and search("Silverlight", ps):
netflix_on=True
else:
netflix_on=False
if netflix_on == True and cookie == None:
cookie = inhibit()
atexit.register(uninhibit, cookie)
debug(cookie)
elif netflix_on == False and cookie != None:
cookie = uninhibit(cookie)
try:
atexit.unregister(uninhibit)
except (SyntaxError, AttributeError):
debug("No unregister for atexit. We must be running on an earlier version of python. No problem.")
pass
debug(cookie)
sleep(30)
loop.run()
# vi: filetype=python:expandtab:shiftwidth=4:softtabstop=4:tw=0

9
set_volume Executable file
View File

@ -0,0 +1,9 @@
#!/bin/dash
if [ -z "$1" ] || [ -n "$(echo $1|sed 's/[0-9]//g')" ]; then
echo "Usage: $0 <volume 0-100>"
exit
fi
pacmd set-sink-volume 0 $(($1 * 65536/100)) >/dev/null
exit $?