syncplay/syncplay/utils.py
2012-06-26 18:19:27 +02:00

144 lines
4.7 KiB
Python

#coding:utf8
import os
import re
RE_ARG = re.compile(r"('(?:[^\\']+|\\\\|\\')*'|[^\s']+)(?:\s+|\Z)")
RE_NEED_QUOTING = re.compile(r"[\s'\\]")
RE_QUOTABLE = re.compile(r"['\\]")
RE_UNQUOTABLE = re.compile(r"\\(['\\])")
class InvalidArgumentException(Exception):
pass
def quote_arg(arg):
if isinstance(arg, unicode):
arg = arg.encode('utf8')
elif not isinstance(arg, str):
arg = str(arg)
if not arg or RE_NEED_QUOTING.search(arg):
return "'%s'" % RE_QUOTABLE.sub(r'\\\g<0>', arg)
return arg
def unqote_arg(arg):
if arg.startswith("'") and len(arg) > 1:
arg = RE_UNQUOTABLE.sub(r'\1', arg[1:-1])
return arg.decode('utf8', 'replace')
def _split_args(args):
pos = 0
while pos < len(args):
match = RE_ARG.match(args, pos)
if not match:
raise InvalidArgumentException()
pos = match.end()
yield unqote_arg(match.group(1))
def split_args(args):
try:
return list(_split_args(args))
except InvalidArgumentException:
return None
def join_args(args):
return ' '.join(quote_arg(arg) for arg in args)
def parse_state(args):
if len(args) == 4:
counter, ctime, state, position = args
who_changed_state = None
elif len(args) == 5:
counter, ctime, state, position, who_changed_state = args
else:
return
if not state in ('paused', 'playing'):
return
paused = state == 'paused'
try:
counter = int(counter)
ctime = int(ctime)
position = int(position)
except ValueError:
return
ctime /= 1000.0
position /= 1000.0
return counter, ctime, paused, position, who_changed_state
def find_exec_path(name):
if os.access(name, os.X_OK):
return name
for path in os.environ['PATH'].split(':'):
path = os.path.join(os.path.realpath(path), name)
if os.access(path, os.X_OK):
return path
def format_time(value):
value = int(value*100)
seconds, mseconds = divmod(value, 100)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
return '%02d:%02d:%02d.%02d' % (hours, minutes, seconds, mseconds)
import sys
import ConfigParser
import argparse
def stdin_thread(manager):
try:
fd = sys.stdin.fileno()
while True:
data = os.read(fd, 1024)
if not data:
break
manager.execute_command(data.rstrip('\n\r'))
except:
pass
def get_configuration():
parser = argparse.ArgumentParser(description='Synchronize multiple players over the web.',
epilog='If no options supplied config values will be used')
parser.add_argument('--host', metavar='hostname', type=str, help='server\'s address')
parser.add_argument('--name', metavar='username', type=str, help='desired username')
parser.add_argument('-m', '--mpc-path', metavar='path', type=str, help='path to mpc-hc.exe (only for sync_mpc_api client)')
parser.add_argument('-d','--debug', action='store_true', help='debug mode')
parser.add_argument('-n','--no-store', action='store_true', help='don\'t store values in syncplay.ini')
parser.add_argument('file', metavar='file', type=str, nargs='?', help='file to play')
parser.add_argument('args', metavar='options', type=str, nargs='*', help='player options, if you need to pass options starting with - prepend them with single \'--\' argument')
args = parser.parse_args()
config = ConfigParser.RawConfigParser()
config.read(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'syncplay.ini'))
section_name = 'sync' if not args.debug else 'debug'
try:
if(args.host == None): args.host = config.get(section_name, 'host')
if(args.name == None): args.name = config.get(section_name, 'name')
if(args.mpc_path == None): args.mpc_path = config.get(section_name, 'mpc_path')
except ConfigParser.NoSectionError:
pass
except ConfigParser.NoOptionError:
pass
if(args.host == None or args.name == None):
sys.exit("You must supply name and host on the first run")
if(not args.no_store):
with open(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'syncplay.ini'), 'wb') as configfile:
if(not config.has_section(section_name)):
config.add_section(section_name)
config.set(section_name, 'host', args.host)
config.set(section_name, 'name', args.name)
config.set(section_name, 'mpc_path', args.mpc_path)
config.write(configfile)
if ':' in args.host:
args.host, port = args.host.split(':', 1)
args.port = int(port)
else:
args.port = 8999
return args