Source

playerdo / playerdo / install.py

Full commit
Luke Plant ab19eb5 






Luke Plant 97d1ffe 




Luke Plant ab19eb5 
Luke Plant d06eb0c 
Luke Plant ad09056 








Luke Plant ab19eb5 
Luke Plant 34a5f65 

Luke Plant ad09056 




Luke Plant d06eb0c 
Luke Plant 34a5f65 


Luke Plant ad09056 
Luke Plant 34a5f65 
Luke Plant ad09056 


Luke Plant d06eb0c 
Luke Plant ad09056 


















Luke Plant 34a5f65 











Luke Plant ad09056 


Luke Plant 34a5f65 
Luke Plant d06eb0c 
Luke Plant ad09056 



Luke Plant 34a5f65 

Luke Plant ad09056 
Luke Plant 34a5f65 
Luke Plant d06eb0c 
Luke Plant 34a5f65 





Luke Plant ab19eb5 
Luke Plant 34a5f65 




Luke Plant ab19eb5 

Luke Plant ad09056 
Luke Plant 34a5f65 


Luke Plant ad09056 
Luke Plant ab19eb5 

Luke Plant ad09056 
Luke Plant 34a5f65 


Luke Plant ab19eb5 

Luke Plant ad09056 














































































Luke Plant 34a5f65 





Luke Plant ab19eb5 
Luke Plant ad09056 
Luke Plant 34a5f65 
Luke Plant ad09056 
"""
Installation utilities for keyboard shortcuts
"""
from subprocess import Popen, PIPE, call
import sys


def force_unicode(s):
    if type(s) is not unicode:
        return s.decode('UTF-8')
    else:
        return s


class SettingsInstallerBase(object):

    def get_next_custom_keybinding_name(self, existing):
        # All custom keybindings start with 'custom'
        if len(existing) == 0:
            next_val = 0
        else:
            next_val = max(int(n[len('custom'):]) for n in existing) + 1
        return 'custom' + str(next_val)

    def install_shortcuts(self):
        already_installed = set()
        custom_keybindings = set(self.get_custom_keybindings())
        for d in custom_keybindings:
            action = self.get_keybinding_action(d)
            if action.startswith("player_do "):
                already_installed.add(action.strip())

        commands = ['play', 'pause', 'playpause', 'stop', 'next', 'prev']
        for cmd in commands:
            action = "player_do " + cmd
            display_name = "player_do - " + cmd
            if action not in already_installed:
                keybinding_name = self.get_next_custom_keybinding_name(custom_keybindings)
                self.install_keybinding(keybinding_name, action, display_name)
                custom_keybindings.add(keybinding_name)

    def launch_keybinding_editor(self):
        sys.stdout.write("Launching keybinding editor...\nEdit 'player_do' keybindings in 'Custom shortcuts' section, and close when done.\n")
        errors = []
        success = False
        p = Popen(["which", self.KEYBINDINGS_GUI_EDITOR], stdout=PIPE)
        stdout, stderr = p.communicate(None)
        val = force_unicode(stdout).strip() + " " + " ".join(self.KEYBINDINGS_GUI_EDITOR_ARGS)
        print val
        if val != "":
            call(["nohup %s &" % val], shell=True, stdout=open("/dev/null"), stderr=open("/dev/null"))
            success = True
        if not success:
            sys.stdout.write("Error: Couldn't find program %s for editing keybindings.\n" % self.KEYBINDINGS_GUI_EDITOR)
            raise SystemExit()


class Gnome2SettingsInstallerBase(SettingsInstallerBase):

    def get_custom_keybindings(self):
        try:
            p = Popen([self.CONF_TOOL, "--all-dirs", self.KEYBINDINGS_CONF_PREFIX], stdout=PIPE)
        except OSError:
            raise Exception("Could not use %s to manipulate settings" % self.CONF_TOOL)
        stdout, stderr = p.communicate(None)
        if p.returncode != 0:
            raise Exception("Could not use %s to manipulate settings" % self.CONF_TOOL)
        retval = []
        stdout = force_unicode(stdout)
        for x in stdout.split("\n"):
            x = x.strip()
            if x.startswith(self.KEYBINDINGS_CONF_PREFIX):
                x = x[len(self.KEYBINDINGS_CONF_PREFIX) + 1:]
                if x.startswith("custom"):
                    retval.append(x)
        return retval

    def get_keybinding_action(self, keybinding_name):
        return self.get_gconf_val(self.KEYBINDINGS_CONF_PREFIX + "/" + keybinding_name + "/action")

    def install_keybinding(self, keybinding_name, action, display_name):
        self.set_gconf_val(self.KEYBINDINGS_CONF_PREFIX + "/" + keybinding_name + "/" + "action", action)
        self.set_gconf_val(self.KEYBINDINGS_CONF_PREFIX + "/" + keybinding_name + "/" + "binding", "")
        self.set_gconf_val(self.KEYBINDINGS_CONF_PREFIX + "/" + keybinding_name + "/" + "name", display_name)
        sys.stdout.write("Keybinding slot for action '%s' created\n" % action)

    def get_gconf_val(self,  key):
        p = Popen([self.CONF_TOOL, "--get", key], stdout=PIPE)
        stdout, stderr = p.communicate(None)
        if p.returncode != 0:
            raise Exception("Could not use %s to manipulate settings" % self.CONF_TOOL)
        return force_unicode(stdout)

    def set_gconf_val(self, key, val):
        p = Popen([self.CONF_TOOL, "--type", "string", "--set", key, val], stdout=PIPE)
        stdout, stderr = p.communicate(None)
        if p.returncode != 0:
            raise Exception("Could not use %s to manipulate settings" % self.CONF_TOOL)


class Gnome2SettingsInstaller(Gnome2SettingsInstallerBase):
    CONF_TOOL = "gconftool-2"
    KEYBINDINGS_CONF_PREFIX = "/desktop/gnome/keybindings"
    KEYBINDINGS_GUI_EDITOR = "gnome-keybinding-properties"
    KEYBINDINGS_GUI_EDITOR_ARGS = []


class MateSettingsInstaller(Gnome2SettingsInstallerBase):
    CONF_TOOL = "mateconftool-2"
    KEYBINDINGS_CONF_PREFIX = "/desktop/mate/keybindings"
    KEYBINDINGS_GUI_EDITOR = "mate-keybinding-properties"


class Gnome3SettingsInstaller(SettingsInstallerBase):
    CONF_TOOL = "gsettings"
    KEYBINDINGS_GUI_EDITOR = "gnome-control-center"
    KEYBINDINGS_GUI_EDITOR_ARGS = ["keyboard"]

    KEYBINDINGS_SCHEMA = "org.gnome.settings-daemon.plugins.media-keys"
    KEYBINDINGS_LIST_CUSTOM_KEY = "custom-keybindings"
    KEYBINDINGS_SCHEMA_CUSTOM = "org.gnome.settings-daemon.plugins.media-keys.custom-keybinding"
    KEYBINDINGS_CUSTOM_KEY_PATH = '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/'

    def get_custom_keybindings(self):
        l = self.get_gsettings_val(self.KEYBINDINGS_SCHEMA, None, self.KEYBINDINGS_LIST_CUSTOM_KEY)
        retval = []
        for i in l:
            assert i.startswith(self.KEYBINDINGS_CUSTOM_KEY_PATH)
            val = i.split('/')[-2]
            assert val.startswith('custom')
            retval.append(val)
        return retval

    def get_keybinding_action(self, keybinding_name):
        return self.get_gsettings_val(self.KEYBINDINGS_SCHEMA_CUSTOM,
                                      self.keybinding_path(keybinding_name),
                                      "command")

    def keybinding_path(self, name):
        return self.KEYBINDINGS_CUSTOM_KEY_PATH + name + '/'

    def install_keybinding(self, keybinding_name, action, display_name):
        self.set_gsettings_val(self.KEYBINDINGS_SCHEMA_CUSTOM,
                              self.keybinding_path(keybinding_name), "command", action)
        self.set_gsettings_val(self.KEYBINDINGS_SCHEMA_CUSTOM,
                              self.keybinding_path(keybinding_name), "name", display_name)
        self.set_gsettings_val(self.KEYBINDINGS_SCHEMA_CUSTOM,
                              self.keybinding_path(keybinding_name), "binding", "")

        # Update the list key
        l = self.get_custom_keybindings() # list like ['custom0', 'custom1']
        l.append(keybinding_name)
        self.set_gsettings_val(self.KEYBINDINGS_SCHEMA, None,
                               self.KEYBINDINGS_LIST_CUSTOM_KEY,
                               [self.keybinding_path(n) for n in l]
                               )
        sys.stdout.write("Keybinding slot for action '%s' created\n" % action)

    def get_gsettings_val(self, schema, path, key):
        arg = schema
        if path:
            arg = arg + ":" + path
        p = Popen([self.CONF_TOOL, "get", arg, key], stdout=PIPE)
        stdout, stderr = p.communicate(None)
        if p.returncode != 0:
            raise Exception("Could not use %s to manipulate settings" % self.CONF_TOOL)
        v = force_unicode(stdout)

        return decode_gsettings(v)

    def set_gsettings_val(self, schema, path, key, val):
        arg = schema
        if path:
            arg = arg + ":" + path
        p = Popen([self.CONF_TOOL, "set", arg, key, force_unicode(encode_gsettings(val))], stdout=PIPE)
        stdout, stderr = p.communicate(None)
        if p.returncode != 0:
            raise Exception("Could not use %s to manipulate settings" % self.CONF_TOOL)


def decode_gsettings(v):
    # Looks like some Python based syntax
    if v.startswith('@as []'):
        return []
    else:
        return eval(v)


def encode_gsettings(v):
    return repr(v)


def mk_installer(cls):
    def installer():
        i = cls()
        i.install_shortcuts()
        i.launch_keybinding_editor()
    return installer

install_gnome = mk_installer(Gnome2SettingsInstaller)
install_mate = mk_installer(MateSettingsInstaller)
install_gnome3 = mk_installer(Gnome3SettingsInstaller)