[Pkg-alsa-devel] Initial asoundconf

Martin Pitt martin.pitt at ubuntu.com
Thu Aug 18 09:21:49 UTC 2005


Hi Thomas, hi everybody else!

Thomas, as discussed with you the other day, I finished the initial
version of asoundconf with the semantics and configuration structure
we agreed on. It also handles the transition from the
set-default-soundcard configuration structure.

Unfortunately it is too late to include this into Breezy because of
the feature freeze. I regret this since it forces us to introduce a
bad configuration schema into a stable release and maintain the
transition code for a while. Would you be willing to keep this around
for a while?

The program itself works fine, it just lacks a manpage. What do you
think about it?

Thanks,

Martin
-- 
Martin Pitt        http://www.piware.de
Ubuntu Developer   http://www.ubuntu.com
Debian Developer   http://www.debian.org
-------------- next part --------------
#!/usr/bin/env python

# (C) 2005 Canonical Ltd.
# Author: Martin Pitt <martin.pitt at ubuntu.com>
# License: GNU General Public License, version 2 or any later version

# Get and set configuration options in ~/.asoundrc-asoundconf.

import sys, re, os.path

conffile = os.path.expanduser('~/.asoundrc-asoundconf')
userconffile = os.path.expanduser('~/.asoundrc')

setting_re_template = '%s\s*(?:=|\s)\s*([^;,]+)[;,]?$'

def help(): 
	print '''Usage:
asoundconf get <option>
asoundconf set <option> <value>
asoundconf delete <option>
asoundconf check-active
'''

def create_conffile():
    '''Generate a default configuration file with no settings.
    
    Return: True on success, False if file cannot be created.'''

    try:
        open(conffile, 'w').write(
'''# This ALSA configuration file is modified by asoundconf(1). You can modify
# it manually, but settings can be overwritten by asoundconf. You should put your
# customized ALSA configuration into %s instead.
''' % userconffile)
        return True
    except IOError:
        print >> sys.stderr, 'Error: could not create', conffile
        return False

def sds_transition():
    '''Replace set-default-soundcard magic comments in ~/.asoundrc with the
    standard include command for conffile.'''
    
    lines = open(userconffile).readlines()

    start_marker_re = re.compile('### BEGIN set-default-soundcard')
    end_marker_re = re.compile('### END set-default-soundcard')

    userconf = []
    asoundconf = []

    # read up to start comment
    lineno = 0
    found = 0
    for l in lines:
        lineno = lineno+1
        if start_marker_re.match(l):
            found = 1
            break
        userconf.append(l)

    if found:
        # replace magic comment section with include
        userconf.append('<%s>\n' % conffile)
    else:
        # user modified conffile, give up
        return

    # read magic comment section until end marker and add it to asoundconf
    found = 0
    for l in lines[lineno:]:
        lineno = lineno+1
        if end_marker_re.match(l):
            found = 1
            break
        if not l.startswith('#'):
            asoundconf.append(l)
            
    if not found:
        return

    # add the rest to user conf
    userconf = userconf + lines[lineno:]

    # try to write asound configuration
    try:
        open(conffile, 'a').writelines(asoundconf)
    except IOError:
        return # panic out

    # write user configuration
    try:
        open(userconffile, 'w').writelines(userconf)
    except IOError:
        pass
    
def check_active():
    '''Check whether userconffile is included in conffile, thus settings
    actually are active. 
    
    This also performs the transition from the legacy set-default-soundcard
    program. If ~/.asoundrc is not present at all, it is created.
    
    Return True if active, False if not.'''

    if not os.path.exists(userconffile):
        # Create a default file and exit
        try:
            open(userconffile, 'w').write(
'''# User editable ALSA configuration file.

# Include the settings from asoundconf(1) to make them active. If you do not want
# to use asoundconf, just remove the following inclusion.
<%s>
''' % conffile)
            return True
        except IOError:
            print >> sys.stderr, 'Error: could not create', userconffile
            return False

    # file exists, check for set-default-soundcard transition
    sds_transition()

    # check whether we include conffile
    include_re = re.compile('\s*<\s*%s\s*>' % conffile)
    for l in open(userconffile):
        if include_re.match(l):
            return True

    return False

def get(option):
    '''Query the value of given option and print it to stdout.
    
    Return True on success, and False if the value is not yet configured.'''

    setting_re = re.compile(setting_re_template % option)

    try:
        for line in open(conffile):
            m = setting_re.match(line)
            if m:
                print m.group(1).strip()
                return True
        return False
    except IOError:
        return False

def set(option, value):
    '''Set the given option to a new value.
    
    Return True on success, and False on an error.'''

    setting_re = re.compile(setting_re_template % option)
    lines = []
    if not os.path.exists(conffile):
        create_conffile()

    try:
        lines = open(conffile).readlines()
    except IOError:
        return False
        
    newsetting = '%s = %s\n' % (option, value)
    
    # if setting is already present, change it
    found = 0
    for i in xrange(len(lines)):
        if setting_re.match(lines[i]):
            lines[i] = newsetting
            found = 1
            break

    if not found:
        lines.append(newsetting)
        
    # write back file
    try:
        f = open(conffile, 'w')
    except IOError:
        return False
    f.writelines(lines)
    return True

def delete(option):
    '''Delete the given option."
    
    Return True on success, and False on an error.'''

    setting_re = re.compile(setting_re_template % option)
    lines = []
    try:
        lines = open(conffile).readlines()
    except IOError:
        return False
        
    found = 0
    for i in xrange(len(lines)):
        if setting_re.match(lines[i]):
            del lines[i]
            found = 1
            break

    if found:
        # write back file
        try:
            f = open(conffile, 'w')
        except IOError:
            return False
        f.writelines(lines)
    return True

def exit_code(result):
    '''Exit program with code 0 if result is True, otherwise exit with code
    1.'''

    if result:
        sys.exit(0)
    else:
        sys.exit(1)

##
## main
##

if len(sys.argv) < 2 or sys.argv[1] == '--help' or sys.argv[1] == '-h':
        help()
        sys.exit(0)

if sys.argv[1] == 'check-active':
    exit_code(check_active())

if sys.argv[1] == 'get':
    if len(sys.argv) != 3:
        help()
        sys.exit(1)
    exit_code(get(sys.argv[2]))

if sys.argv[1] == 'set':
    if len(sys.argv) != 4:
        help()
        sys.exit(1)
    exit_code(set(sys.argv[2], sys.argv[3]))

if sys.argv[1] == 'delete':
    if len(sys.argv) != 3:
        help()
        sys.exit(1)
    exit_code(delete(sys.argv[2]))

help()
sys.exit(1)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.alioth.debian.org/pipermail/pkg-alsa-devel/attachments/20050818/00bf5a1d/attachment-0003.pgp 


More information about the Pkg-alsa-devel mailing list