From a99f7fb2412c5869919f0afe282d6e3d734eb162 Mon Sep 17 00:00:00 2001 From: Uriziel Date: Tue, 26 Jun 2012 18:19:27 +0200 Subject: [PATCH] New... everything --- setup.py | 12 -- setup_common.py | 4 +- setup_py2exe.py | 2 +- sync_mpc.py | 7 +- sync_mpc_api.py | 17 ++ sync_mplayer.py | 6 +- syncplay/client.py | 17 +- syncplay/mpc_api.py | 320 ++++++++++++++++++++++++++++++ syncplay/players/mpc_using_api.py | 71 +++++++ syncplay/server.py | 2 +- syncplay/utils.py | 62 +++--- 11 files changed, 457 insertions(+), 63 deletions(-) delete mode 100755 setup.py create mode 100644 sync_mpc_api.py create mode 100644 syncplay/mpc_api.py create mode 100644 syncplay/players/mpc_using_api.py diff --git a/setup.py b/setup.py deleted file mode 100755 index 07ff07e..0000000 --- a/setup.py +++ /dev/null @@ -1,12 +0,0 @@ -#coding:utf8 - -from setuptools import setup -from setup_common import common_info - -info = dict( - common_info, - scripts = ['sync_mplayer.py', 'sync_mpc.py', 'run_sync_server.py'], -) - -setup(**info) - diff --git a/setup_common.py b/setup_common.py index c21e5bd..ab117ee 100644 --- a/setup_common.py +++ b/setup_common.py @@ -4,9 +4,9 @@ from setuptools import find_packages common_info = dict( name = 'SyncPlay', - version = '0.2', + version = '0.7', author = 'Tomasz Kowalczyk, Uriziel', - author_email = 'code@fluxid.pl', + author_email = 'code@fluxid.pl, urizieli@gmail.com', description = 'Solution to synchronize playback of multiple MPlayer and MPC-HC instances over the network.', packages = find_packages(exclude=['venv']), install_requires = ['Twisted>=11.1'], diff --git a/setup_py2exe.py b/setup_py2exe.py index 7450081..6130fb9 100644 --- a/setup_py2exe.py +++ b/setup_py2exe.py @@ -7,7 +7,7 @@ from setup_common import common_info info = dict( common_info, - console = ['sync_mplayer.py', 'sync_mpc.py', 'run_sync_server.py'], + console = ['sync_mplayer.py', 'sync_mpc_api.py', 'sync_mpc.py', 'run_sync_server.py'], ) setup(**info) diff --git a/sync_mpc.py b/sync_mpc.py index 1875a31..1ed15b6 100755 --- a/sync_mpc.py +++ b/sync_mpc.py @@ -8,10 +8,7 @@ from syncplay.players import mpc from syncplay import utils if __name__ == '__main__': - host, port, name, args = utils.get_configuration() - #host = 'localhost' - #port = 9000 - #name = 'Bosman' - manager = client.Manager(host, port, name, lambda m: mpc.run_mpc(m)) + args = utils.get_configuration() + manager = client.Manager(args.host, args.port, args.name, lambda m: mpc.run_mpc(m)) thread.start_new_thread(utils.stdin_thread, (manager,)) manager.start() diff --git a/sync_mpc_api.py b/sync_mpc_api.py new file mode 100644 index 0000000..6f6e73a --- /dev/null +++ b/sync_mpc_api.py @@ -0,0 +1,17 @@ +#coding:utf8 +import thread +import sys + +from twisted.internet import reactor +from syncplay import client +from syncplay.players import mpc_using_api + +from syncplay import utils + +if __name__ == '__main__': + args = utils.get_configuration() + if(args.mpc_path == None): + sys.exit("You must supply mpc-path on first run") + manager = client.Manager(args.host, args.port, args.name, lambda m: mpc_using_api.run_mpc(m, args.mpc_path, args.file, args.args)) + thread.start_new_thread(utils.stdin_thread, (manager,)) + manager.start() diff --git a/sync_mplayer.py b/sync_mplayer.py index e61ef69..015a796 100755 --- a/sync_mplayer.py +++ b/sync_mplayer.py @@ -9,9 +9,9 @@ from syncplay.players import mplayer from syncplay import utils if __name__ == '__main__': - host, port, name, args = utils.get_configuration() - args.extend(('-slave', '-msglevel', 'all=1:global=4')) - manager = client.Manager(host, port, name, lambda m: mplayer.run_mplayer(m, 'mplayer', args)) + args = utils.get_configuration() + args.args.extend(('-slave', '-msglevel', 'all=1:global=4')) + manager = client.Manager(args.host, args.port, args.name, lambda m: mplayer.run_mplayer(m, 'mplayer', args.args)) thread.start_new_thread(utils.stdin_thread, (manager,)) manager.start() diff --git a/syncplay/client.py b/syncplay/client.py index 80ccb43..c208b62 100644 --- a/syncplay/client.py +++ b/syncplay/client.py @@ -47,9 +47,9 @@ class SyncClientProtocol(CommandProtocol): else: who, where, what = args[0], args[1], None if what: - print '%s is present and is playing \'%s\' in a room %s' % (who, what, where) + print '%s is present and is playing \'%s\' in a room \'%s\'' % (who, what, where) else: - print '%s is present in a room %s' % (who, where) + print '%s is present in a room \'%s\'' % (who, where) @arg_count(4, 5) def handle_connected_state(self, args): @@ -233,8 +233,8 @@ class Manager(object): def init_player(self, player): self.player = player if self.last_global_update: - self.player.set_position(self.get_global_position()) - self.player.set_paused(self.global_paused) + self.player.set_position(0) + self.player.set_paused(True) self.schedule_ask_player() def init_protocol(self, protocol): @@ -284,7 +284,7 @@ class Manager(object): return self.counter += 10 self.protocol.send_seek(self.counter, time.time(), self.player_position) - print 'You seeked to', format_time(self.player_position) + print self.name,'seeked to', format_time(self.player_position) def send_filename(self): if self.protocol and self.player_filename: @@ -413,11 +413,10 @@ class Manager(object): self.player.set_position(position) #self.player.set_paused(True) print "Rewind due to time difference" - changed = True + if self.player_paused and not paused: self.player_paused_at = None self.player.set_paused(False) - changed = True if self.global_noted_pause_change != paused: print '%s unpaused' % name elif paused and not self.player_paused: @@ -426,9 +425,9 @@ class Manager(object): print '%s paused' % name if diff < 0: self.player.set_paused(True) - changed = True self.global_noted_pause_change = paused - + changed = True + if changed: self.ask_player() diff --git a/syncplay/mpc_api.py b/syncplay/mpc_api.py new file mode 100644 index 0000000..d578f29 --- /dev/null +++ b/syncplay/mpc_api.py @@ -0,0 +1,320 @@ +#coding:utf8 + +import win32con, win32api, win32gui, ctypes, ctypes.wintypes +import sys, os, thread + +class MPC_API: + def __init__(self): + self.listener = None + thread.start_new_thread(self.__Listener, (self,)) + while(self.listener == None): continue + + self.loadstate = None + self.playstate = None + self.fileplaying = None + self.fileduration = None + self.lastfileposition = None + self.position_request_warden = False + self.seek_warden = False + self.callbacks = self.__CALLBACKS() + + def register_listener(self, listener): + self.listener = listener + + def is_api_ready(self): + self.__mpc_ready_in_slave_mode() + file_state_ok = self.loadstate == self.__MPC_LOADSTATE.MLS_CLOSED or self.loadstate == self.__MPC_LOADSTATE.MLS_LOADED or self.loadstate == None + listener_ok = self.listener <> None and self.listener.mpc_handle <> None + return (file_state_ok and listener_ok) + + def is_file_ready(self): + self.__mpc_ready_in_slave_mode() + return (self.loadstate == self.__MPC_LOADSTATE.MLS_LOADED and self.fileplaying and self.playstate <> None) + + def start_mpc(self, path, args = ()): + is_starting = os.spawnl(os.P_NOWAIT, path, ' ' + ' '.join(args),' /open /new /slave %s ' % str(self.listener.hwnd)) #can be switched with win32api.ShellExecute + while(self.listener.mpc_handle == None and is_starting): continue + + def open_file(self, file_path): + self.__mpc_ready_in_slave_mode() + self.listener.SendCommand(self.__API_COMMANDS.CMD_OPENFILE, file_path) + + def is_paused(self): + self.__mpc_ready_in_slave_mode() + return (self.playstate <> self.__MPC_PLAYSTATE.PS_PLAY and self.playstate <> None) + + def pause(self): + self.__mpc_ready_in_slave_mode() + if(not self.is_paused()): + self.listener.SendCommand(self.__API_COMMANDS.CMD_PLAYPAUSE) + while(not self.is_paused()): self.__mpc_ready_in_slave_mode() + + def unpause(self): + self.__mpc_ready_in_slave_mode() + if(self.is_paused()): + self.listener.SendCommand(self.__API_COMMANDS.CMD_PLAYPAUSE) + while(self.is_paused()): self.__mpc_ready_in_slave_mode() + + def playpause(self): + self.__mpc_ready_in_slave_mode() + tmp = self.playstate + self.listener.SendCommand(self.__API_COMMANDS.CMD_PLAYPAUSE) + while(tmp == self.playstate): self.__mpc_ready_in_slave_mode() + + def ask_for_current_position(self): + self.__mpc_ready_in_slave_mode() + if(not self.position_request_warden): + self.position_request_warden = True + self.listener.SendCommand(self.__API_COMMANDS.CMD_GETCURRENTPOSITION) + while(self.position_request_warden and not self.callbacks.on_update_position): self.__mpc_ready_in_slave_mode() + return self.lastfileposition + + def seek(self, position): + self.__mpc_ready_in_slave_mode() + self.seek_warden = True + self.listener.SendCommand(self.__API_COMMANDS.CMD_SETPOSITION, unicode(position)) + while(self.seek_warden): + continue + + def __mpc_ready_in_slave_mode(self): + if not win32gui.IsWindow(self.listener.mpc_handle): + raise MPC_API.NoSlaveDetectedException("MPC Slave Window not detected") + + def handle_command(self,cmd, value): + #print '>>>'+hex(cmd).upper(), value + if (cmd == self.__API_COMMANDS.CMD_CONNECT): + self.listener.mpc_handle = int(value) + if(self.callbacks.on_connected): + self.callbacks.on_connected() + elif(cmd == self.__API_COMMANDS.CMD_STATE): + self.loadstate = int(value) + elif(cmd == self.__API_COMMANDS.CMD_PLAYMODE): + self.playstate = int(value) + if(self.callbacks.on_update_playstate): self.callbacks.on_update_playstate(self.playstate) + elif(cmd == self.__API_COMMANDS.CMD_NOWPLAYING): + if(self.callbacks.on_file_ready): self.callbacks.on_file_ready() + self.fileplaying = value.split('|')[3].split('\\').pop() + if(self.callbacks.on_update_filename): self.callbacks.on_update_filename(self.fileplaying) + self.fileduration = int(value.split('|')[4]) + if(self.callbacks.on_update_file_duration): self.callbacks.on_update_file_duration(self.fileplaying) + elif(cmd == self.__API_COMMANDS.CMD_CURRENTPOSITION): + self.lastfileposition = float(value) + self.position_request_warden = False + if(self.callbacks.on_update_position): self.callbacks.on_update_position(self.lastfileposition) + elif(cmd == self.__API_COMMANDS.CMD_NOTIFYSEEK): + self.seek_warden = False + if(self.lastfileposition <> float(value)): #Notify seek is sometimes sent twice + self.lastfileposition = float(value) + if(self.callbacks.on_seek): self.callbacks.on_seek(self.lastfileposition) + else: + pass + + class NoSlaveDetectedException(Exception): + def __init__(self, message): + Exception.__init__(self, message) + + class __CALLBACKS: + def __init__(self): + self.on_connected = None + self.on_seek = None + self.on_update_filename = None + self.on_update_file_duration = None + self.on_update_position = None + self.on_update_playstate = None + self.on_file_ready = None + + class __MPC_LOADSTATE: + MLS_CLOSED = 0 + MLS_LOADING = 1 + MLS_LOADED = 2 + MLS_CLOSING = 3 + + class __MPC_PLAYSTATE: + PS_PLAY = 0 + PS_PAUSE = 1 + PS_STOP = 2 + PS_UNUSED = 3 + + ''' + class MPC_OSDDATA(): + _fields_ = [ + ('nMsgPos'), + ('nDurationMS'), + ('strMsg') + ] + ''' + class __API_COMMANDS(): + # Send after connection + # Par 1 : MPC window handle (command should be send to this HWnd) + CMD_CONNECT = 0x50000000 + # Send when opening or closing file + # Par 1 : current state (see MPC_LOADSTATE enum) + CMD_STATE = 0x50000001 + # Send when playing, pausing or closing file + # Par 1 : current play mode (see MPC_PLAYSTATE enum) + CMD_PLAYMODE = 0x50000002 + # Send after opening a new file + # Par 1 : title + # Par 2 : author + # Par 3 : description + # Par 4 : complete filename (path included) + # Par 5 : duration in seconds + CMD_NOWPLAYING = 0x50000003 + # List of subtitle tracks + # Par 1 : Subtitle track name 0 + # Par 2 : Subtitle track name 1 + # ... + # Par n : Active subtitle track, -1 if subtitles disabled + # + # if no subtitle track present, returns -1 + # if no file loaded, returns -2 + CMD_LISTSUBTITLETRACKS = 0x50000004 + # List of audio tracks + # Par 1 : Audio track name 0 + # Par 2 : Audio track name 1 + # ... + # Par n : Active audio track + # + # if no audio track present, returns -1 + # if no file loaded, returns -2 + CMD_LISTAUDIOTRACKS = 0x50000005 + # Send current playback position in responce + # of CMD_GETCURRENTPOSITION. + # Par 1 : current position in seconds + CMD_CURRENTPOSITION = 0x50000007 + # Send the current playback position after a jump. + # (Automatically sent after a seek event). + # Par 1 : new playback position (in seconds). + CMD_NOTIFYSEEK = 0x50000008 + # Notify the end of current playback + # (Automatically sent). + # Par 1 : none. + CMD_NOTIFYENDOFSTREAM = 0x50000009 + # List of files in the playlist + # Par 1 : file path 0 + # Par 2 : file path 1 + # ... + # Par n : active file, -1 if no active file + CMD_PLAYLIST = 0x50000006 + # ==== Commands from host to MPC + # Open new file + # Par 1 : file path + CMD_OPENFILE = 0xA0000000 + # Stop playback, but keep file / playlist + CMD_STOP = 0xA0000001 + # Stop playback and close file / playlist + CMD_CLOSEFILE = 0xA0000002 + # Pause or restart playback + CMD_PLAYPAUSE = 0xA0000003 + # Add a new file to playlist (did not start playing) + # Par 1 : file path + CMD_ADDTOPLAYLIST = 0xA0001000 + # Remove all files from playlist + CMD_CLEARPLAYLIST = 0xA0001001 + # Start playing playlist + CMD_STARTPLAYLIST = 0xA0001002 + CMD_REMOVEFROMPLAYLIST = 0xA0001003 # TODO + # Cue current file to specific position + # Par 1 : new position in seconds + CMD_SETPOSITION = 0xA0002000 + # Set the audio delay + # Par 1 : new audio delay in ms + CMD_SETAUDIODELAY = 0xA0002001 + # Set the subtitle delay + # Par 1 : new subtitle delay in ms + CMD_SETSUBTITLEDELAY = 0xA0002002 + # Set the active file in the playlist + # Par 1 : index of the active file, -1 for no file selected + # DOESNT WORK + CMD_SETINDEXPLAYLIST = 0xA0002003 + # Set the audio track + # Par 1 : index of the audio track + CMD_SETAUDIOTRACK = 0xA0002004 + # Set the subtitle track + # Par 1 : index of the subtitle track, -1 for disabling subtitles + CMD_SETSUBTITLETRACK = 0xA0002005 + # Ask for a list of the subtitles tracks of the file + # return a CMD_LISTSUBTITLETRACKS + CMD_GETSUBTITLETRACKS = 0xA0003000 + # Ask for the current playback position, + # see CMD_CURRENTPOSITION. + # Par 1 : current position in seconds + CMD_GETCURRENTPOSITION = 0xA0003004 + # Jump forward/backward of N seconds, + # Par 1 : seconds (negative values for backward) + CMD_JUMPOFNSECONDS = 0xA0003005 + # Ask for a list of the audio tracks of the file + # return a CMD_LISTAUDIOTRACKS + CMD_GETAUDIOTRACKS = 0xA0003001 + # Ask for the properties of the current loaded file + # return a CMD_NOWPLAYING + CMD_GETNOWPLAYING = 0xA0003002 + # Ask for the current playlist + # return a CMD_PLAYLIST + CMD_GETPLAYLIST = 0xA0003003 + # Toggle FullScreen + CMD_TOGGLEFULLSCREEN = 0xA0004000 + # Jump forward(medium) + CMD_JUMPFORWARDMED = 0xA0004001 + # Jump backward(medium) + CMD_JUMPBACKWARDMED = 0xA0004002 + # Increase Volume + CMD_INCREASEVOLUME = 0xA0004003 + # Decrease volume + CMD_DECREASEVOLUME = 0xA0004004 + # Shader toggle + CMD_SHADER_TOGGLE = 0xA0004005 + # Close App + CMD_CLOSEAPP = 0xA0004006 + # show host defined OSD message string + CMD_OSDSHOWMESSAGE = 0xA0005000 + + class __Listener: + def SendCommand(self, cmd, message = ''): + #print "<<<" + (hex(cmd).upper()), str(message) + if not win32gui.IsWindow(self.mpc_handle): + raise MPC_API.NoSlaveDetectedException("MPC Slave Window not detected") + cs = self.__COPYDATASTRUCT() + cs.dwData = cmd; + cs.lpData = ctypes.cast(ctypes.c_wchar_p(message), ctypes.c_void_p) + utf_size_multiplier = 2 if sys.maxunicode < 65536 else 4 + cs.cbData = utf_size_multiplier*len(message)+1 + ptr= ctypes.addressof(cs) + win32api.SendMessage(self.mpc_handle, win32con.WM_COPYDATA, self.hwnd, ptr) + class __COPYDATASTRUCT(ctypes.Structure): + _fields_ = [ + ('dwData', ctypes.wintypes.LPARAM), + ('cbData', ctypes.wintypes.DWORD), + ('lpData', ctypes.c_void_p) + ] + def __init__(self, mpc_api): + message_map = { + win32con.WM_COPYDATA: self.OnCopyData + } + wc = win32gui.WNDCLASS() + wc.lpfnWndProc = message_map + wc.lpszClassName = 'MPCApiListener' + hinst = wc.hInstance = win32api.GetModuleHandle(None) + classAtom = win32gui.RegisterClass(wc) + self.hwnd = win32gui.CreateWindow ( + classAtom, + "ListenerGUI", + 0, + 0, + 0, + win32con.CW_USEDEFAULT, + win32con.CW_USEDEFAULT, + 0, + 0, + hinst, + None + ) + self.__PCOPYDATASTRUCT = ctypes.POINTER(self.__COPYDATASTRUCT) + self.mpc_api = mpc_api + self.mpc_handle = None + mpc_api.register_listener(self) + win32gui.PumpMessages() + + def OnCopyData(self, hwnd, msg, wparam, lparam): + pCDS = ctypes.cast(lparam, self.__PCOPYDATASTRUCT) + self.mpc_api.handle_command(pCDS.contents.dwData, ctypes.wstring_at(pCDS.contents.lpData)) diff --git a/syncplay/players/mpc_using_api.py b/syncplay/players/mpc_using_api.py new file mode 100644 index 0000000..5a5c8b5 --- /dev/null +++ b/syncplay/players/mpc_using_api.py @@ -0,0 +1,71 @@ +#coding:utf8 +from ..mpc_api import MPC_API + +class MPCHCAPIPlayer(object): + def __init__(self, manager, host = None): + self.manager = manager + self.mpc_api = MPC_API() + + self.pinged = False + self.tmp_filename = None + self.tmp_position = None + + def drop(self): + pass + + def set_speed(self, value): + pass + + def make_ping(self): + self.ask_for_status() + + def set_paused(self, value): + try: + if value: + self.mpc_api.pause() + else: + self.mpc_api.unpause() + except: + self.mpc_error() + + def set_position(self, value): + try: + self.mpc_api.seek(value) + except: + self.mpc_error() + + def ask_for_status(self): + position = None + filename = None + paused = None + if(not self.pinged): + self.manager.init_player(self) + self.pinged = True + else: + try: + if(self.mpc_api.is_file_ready()): + position = self.mpc_api.ask_for_current_position() + filename = self.mpc_api.fileplaying + paused = self.mpc_api.is_paused() + + position = float(position) + self.tmp_position = position + if filename != self.tmp_filename: + self.tmp_filename = filename + self.manager.update_filename(str(filename)) + self.manager.update_player_status(paused, position) + except MPC_API.NoSlaveDetectedException: + self.mpc_error() + + def mpc_error(self): + if self.manager.running: + print 'Failed to connect to MPC-HC API!' + self.manager.stop() + + +def run_mpc(manager, mpc_path, file_path, args): + mpc = MPCHCAPIPlayer(manager) + mpc.mpc_api.callbacks.on_file_ready = mpc.make_ping + mpc.mpc_api.callbacks.on_connected = lambda: mpc.mpc_api.open_file(file_path) if(file_path) else None + mpc.mpc_api.start_mpc(mpc_path, args) + diff --git a/syncplay/server.py b/syncplay/server.py index 1d8eb6e..9e00d7a 100644 --- a/syncplay/server.py +++ b/syncplay/server.py @@ -183,7 +183,7 @@ class WatcherInfo(object): self.counter = 0 class SyncFactory(Factory): - def __init__(self, min_pause_lock = 3, update_time_limit = 1): + def __init__(self, min_pause_lock = 1, update_time_limit = 1): self.watchers = dict() self.paused = {} self.paused['default'] = True diff --git a/syncplay/utils.py b/syncplay/utils.py index c40e13d..dead29c 100644 --- a/syncplay/utils.py +++ b/syncplay/utils.py @@ -104,38 +104,40 @@ def stdin_thread(manager): 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='host', type=str, nargs='?', help='server\'s address') - parser.add_argument('name', metavar='name', type=str, nargs='?', help='desired username') - parser.add_argument('args', metavar='opts', type=str, nargs='*', help='player options, if you need to pass options starting with - prepend them with single \'--\' argument') + 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(allow_no_value=True) - config.read(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'syncplay.ini')) + 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): - host = config.get('sync', 'host') - else: - host = args.host - if(args.name == None): - name = config.get('sync', 'name') - else: - name = args.name + 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: - sys.exit("Host or username not specified") - - with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'syncplay.ini'), 'wb') as configfile: - try: - config.set('sync', 'host' ,host) - config.set('sync', 'name' ,name) - except ConfigParser.NoSectionError: - config.add_section('sync') - config.set('sync', 'host' ,host) - config.set('sync', 'name' ,name) - config.write(configfile) - - if ':' in host: - host, port = host.split(':', 1) - port = int(port) + 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: - port = 8999 - return host,port,name,args.args + args.port = 8999 + return args