From eb27fe2c6aeda31f788deb1066073f0c06e72f9e Mon Sep 17 00:00:00 2001 From: Uriziel Date: Fri, 11 Jan 2013 00:43:52 +0100 Subject: [PATCH] Added PlayerFactory --- syncplay/clientManager.py | 12 +------- syncplay/constants.py | 2 +- syncplay/players/__init__.py | 9 ++++++ syncplay/players/basePlayer.py | 25 ++++++++++++++++ syncplay/players/mpc.py | 28 ++++++++++++++++-- syncplay/players/mplayer.py | 27 +++++++++++++++++- syncplay/players/playerFactory.py | 16 +++++++++++ syncplay/ui/ConfigurationGetter.py | 46 ++++++++---------------------- syncplay/ui/GuiConfiguration.py | 23 ++++++++------- 9 files changed, 128 insertions(+), 60 deletions(-) create mode 100644 syncplay/players/playerFactory.py diff --git a/syncplay/clientManager.py b/syncplay/clientManager.py index 63cc15a..043a5f6 100644 --- a/syncplay/clientManager.py +++ b/syncplay/clientManager.py @@ -3,21 +3,11 @@ from syncplay.ui.ConfigurationGetter import ConfigurationGetter from syncplay import ui from syncplay.messages import getMessage -try: - from syncplay.players.mpc import MPCHCAPIPlayer -except ImportError: - MPCHCAPIPlayer = None -from syncplay.players.mplayer import MplayerPlayer - class SyncplayClientManager(object): def run(self): config = ConfigurationGetter().getConfiguration() interface = ui.getUi(graphical=not config["noGui"]) - syncplayClient = None - if(config['playerType'] == "mpc"): - syncplayClient = SyncplayClient(MPCHCAPIPlayer, interface, config) - elif(config['playerType'] == "mplayer"): - syncplayClient = SyncplayClient(MplayerPlayer, interface, config) + syncplayClient = SyncplayClient(config["playerClass"], interface, config) if(syncplayClient): interface.addClient(syncplayClient) syncplayClient.start(config['host'], config['port']) diff --git a/syncplay/constants.py b/syncplay/constants.py index 1112572..b3f0881 100644 --- a/syncplay/constants.py +++ b/syncplay/constants.py @@ -37,7 +37,7 @@ MPC_PATHS = [ "C:\Program Files (x86)\Combined Community Codec Pack\MPC\mpc-hc.exe", "C:\Program Files\MPC HomeCinema (x64)\mpc-hc64.exe", ] - +MPLAYER_PATHS = ["mplayer2", "mplayer"] #Changing these is usually not something you're looking for PLAYER_ASK_DELAY = 0.1 PING_MOVING_AVERAGE_WEIGHT = 0.85 diff --git a/syncplay/players/__init__.py b/syncplay/players/__init__.py index e69de29..8a84a1a 100644 --- a/syncplay/players/__init__.py +++ b/syncplay/players/__init__.py @@ -0,0 +1,9 @@ +from syncplay.players.mplayer import MplayerPlayer +try: + from syncplay.players.mpc import MPCHCAPIPlayer +except ImportError: + from syncplay.players.basePlayer import DummyPlayer + MPCHCAPIPlayer = DummyPlayer + +def getAvailablePlayers(): + return [MPCHCAPIPlayer, MplayerPlayer] \ No newline at end of file diff --git a/syncplay/players/basePlayer.py b/syncplay/players/basePlayer.py index 327850b..7e3367c 100644 --- a/syncplay/players/basePlayer.py +++ b/syncplay/players/basePlayer.py @@ -45,3 +45,28 @@ class BasePlayer(object): ''' def setSpeed(self, value): raise NotImplementedError() + + ''' + @return: list of strings + ''' + @staticmethod + def getDefaultPlayerPathsList(): + raise NotImplementedError() + + ''' + @type path: string + ''' + @staticmethod + def isValidPlayerPath(path): + raise NotImplementedError() + + +class DummyPlayer(BasePlayer): + + @staticmethod + def getDefaultPlayerPathsList(): + return [] + + @staticmethod + def isValidPlayerPath(path): + return False \ No newline at end of file diff --git a/syncplay/players/mpc.py b/syncplay/players/mpc.py index b1b286f..eeacba7 100644 --- a/syncplay/players/mpc.py +++ b/syncplay/players/mpc.py @@ -9,7 +9,8 @@ import re from syncplay.utils import retry from syncplay import constants from syncplay.messages import getMessage - +import os.path + class MpcHcApi: def __init__(self): self.callbacks = self.__Callbacks() @@ -328,9 +329,10 @@ class MPCHCAPIPlayer(BasePlayer): @staticmethod def run(client, playerPath, filePath, args): + args.extend(['/open', '/new']) mpc = MPCHCAPIPlayer(client) mpc._mpcApi.callbacks.onConnected = lambda: mpc.initPlayer(filePath if(filePath) else None) - mpc._mpcApi.startMpc(playerPath, args) + mpc._mpcApi.startMpc(MPCHCAPIPlayer.getExpandedPath(playerPath), args) return mpc def __lockAsking(self): @@ -453,3 +455,25 @@ class MPCHCAPIPlayer(BasePlayer): def sendCustomCommand(self, cmd, val): self._mpcApi.sendRawCommand(cmd, val) + + @staticmethod + def getDefaultPlayerPathsList(): + return constants.MPC_PATHS + + @staticmethod + def isValidPlayerPath(path): + if(MPCHCAPIPlayer.getExpandedPath(path)): + return True + return False + + @staticmethod + def getExpandedPath(path): + if(os.path.isfile(path)): + if(path[-10:] == 'mpc-hc.exe' or path[-12:] == 'mpc-hc64.exe'): + return path + if(os.path.isfile(path + "\\mpc-hc.exe")): + path += "\\mpc-hc.exe" + return path + if(os.path.isfile(path + "\\mpc-hc64.exe")): + path += "\\mpc-hc64.exe" + return path \ No newline at end of file diff --git a/syncplay/players/mplayer.py b/syncplay/players/mplayer.py index 3931f5b..4f6b50f 100644 --- a/syncplay/players/mplayer.py +++ b/syncplay/players/mplayer.py @@ -4,6 +4,7 @@ import threading from syncplay.players.basePlayer import BasePlayer from syncplay import constants from syncplay.messages import getMessage +import os class MplayerPlayer(BasePlayer): speedSupported = True @@ -125,8 +126,32 @@ class MplayerPlayer(BasePlayer): @staticmethod def run(client, playerPath, filePath, args): - mplayer = MplayerPlayer(client, playerPath, filePath, args) + mplayer = MplayerPlayer(client, MplayerPlayer.getExpandedPath(playerPath), filePath, args) return mplayer + + @staticmethod + def getDefaultPlayerPathsList(): + l = [] + for path in constants.MPLAYER_PATHS: + p = MplayerPlayer.getExpandedPath(path) + if p: + l.append(p) + return l + + @staticmethod + def isValidPlayerPath(path): + if("mplayer" in path and MplayerPlayer.getExpandedPath(path)): + return True + return False + + @staticmethod + def getExpandedPath(path): + if os.access(path, os.X_OK): + return path + for path in os.environ['PATH'].split(':'): + path = os.path.join(os.path.realpath(path), path) + if os.access(path, os.X_OK): + return path def drop(self): self._listener.sendLine('quit') diff --git a/syncplay/players/playerFactory.py b/syncplay/players/playerFactory.py new file mode 100644 index 0000000..05ef171 --- /dev/null +++ b/syncplay/players/playerFactory.py @@ -0,0 +1,16 @@ +import syncplay.players + +class PlayerFactory(object): + def __init__(self): + self._players = syncplay.players.getAvailablePlayers() + + def getAvailablePlayerPaths(self): + l = [] + for player in self._players: + l.extend(player.getDefaultPlayerPathsList()) + return l + + def getPlayerByPath(self, path): + for player in self._players: + if(player.isValidPlayerPath(path)): + return player \ No newline at end of file diff --git a/syncplay/ui/ConfigurationGetter.py b/syncplay/ui/ConfigurationGetter.py index 1500fb6..563217b 100644 --- a/syncplay/ui/ConfigurationGetter.py +++ b/syncplay/ui/ConfigurationGetter.py @@ -4,6 +4,7 @@ import os import sys from syncplay import constants, utils from syncplay.messages import getMessage +from syncplay.players.playerFactory import PlayerFactory try: from syncplay.ui.GuiConfiguration import GuiConfiguration except ImportError: @@ -28,7 +29,7 @@ class ConfigurationGetter(object): "playerPath": None, "file": None, "playerArgs": [], - "playerType": None, + "playerClass": None, } # @@ -39,7 +40,7 @@ class ConfigurationGetter(object): "port", "name", "playerPath", - "playerType", + "playerClass", ] self._iniStructure = { @@ -64,14 +65,15 @@ class ConfigurationGetter(object): self._argparser.add_argument('file', metavar='file', type=str, nargs='?', help=getMessage("en", "file-argument")) self._argparser.add_argument('_args', metavar='options', type=str, nargs='*', help=getMessage("en", "args-argument")) + + self._playerFactory = PlayerFactory() + def _validateArguments(self): for key in self._required: if(key == "playerPath"): - if(self._isPlayerMPCAndValid(self._config["playerPath"])): - self._config["playerType"] = "mpc" - self.__addSpecialMPCFlags() - elif(self._isMplayerPathAndValid(self._config["playerPath"])): - self._config["playerType"] = "mplayer" + player = self._playerFactory.getPlayerByPath(self._config["playerPath"]) + if(player): + self._config["playerClass"] = player else: raise InvalidConfigValue("Player path is not set properly") elif(key == "host"): @@ -98,32 +100,6 @@ class ConfigurationGetter(object): key = "noGui" self._config[key] = val - def _isPlayerMPCAndValid(self, path): - if(os.path.isfile(path)): - if(path[-10:] == 'mpc-hc.exe' or path[-12:] == 'mpc-hc64.exe'): - return True - if(os.path.isfile(path + "\\mpc-hc.exe")): - path += "\\mpc-hc.exe" - return True - if(os.path.isfile(path + "\\mpc-hc64.exe")): - path += "\\mpc-hc64.exe" - return True - return False - - def __addSpecialMPCFlags(self): - self._config['playerArgs'].extend(['/open', '/new']) - - def _isMplayerPathAndValid(self, playerPath): - if("mplayer" in playerPath): - if os.access(playerPath, os.X_OK): - return True - for path in os.environ['PATH'].split(':'): - path = os.path.join(os.path.realpath(path), playerPath) - if os.access(path, os.X_OK): - self._config['playerPath'] = path - return True - return False - def _splitPortAndHost(self, host): port = constants.DEFAULT_PORT if not self._config["port"] else self._config["port"] if(host): @@ -170,7 +146,9 @@ class ConfigurationGetter(object): print getMessage("en", "missing-arguments-error") sys.exit() elif(GuiConfiguration): - return GuiConfiguration(self._config).getProcessedConfiguration() + gc = GuiConfiguration(self._config) + gc.setAvailablePaths(self._playerFactory.getAvailablePlayerPaths()) + return gc.getProcessedConfiguration() def __wasOptionChanged(self, parser, section, option): if (parser.has_option(section, option)): diff --git a/syncplay/ui/GuiConfiguration.py b/syncplay/ui/GuiConfiguration.py index b437764..3190860 100644 --- a/syncplay/ui/GuiConfiguration.py +++ b/syncplay/ui/GuiConfiguration.py @@ -1,6 +1,5 @@ import pygtk import os -from syncplay import constants pygtk.require('2.0') import gtk gtk.set_interactive(False) @@ -10,6 +9,7 @@ from syncplay.messages import getMessage class GuiConfiguration: def __init__(self, config): self.config = config + self._availablePlayerPaths = [] self.closedAndNotSaved = False self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_title(getMessage("en", "config-window-title")) @@ -46,14 +46,13 @@ class GuiConfiguration: self.userEntry = self._addLabeledEntryToVbox(getMessage("en", "username-label"), config['name'], vbox, lambda __, _: self._saveDataAndLeave()) self.roomEntry = self._addLabeledEntryToVbox(getMessage("en", "room-label"), config['room'], vbox, lambda __, _: self._saveDataAndLeave()) self.passEntry = self._addLabeledEntryToVbox(getMessage("en", "password-label"), config['password'], vbox, lambda __, _: self._saveDataAndLeave()) - self.mpcEntry = self._addLabeledEntryToVbox(getMessage("en", "path-label"), self._tryToFillUpMpcPath(config['playerPath']), vbox, lambda __, _: self._saveDataAndLeave()) + self.mpcEntry = self._addLabeledEntryToVbox(getMessage("en", "path-label"), self._tryToFillPlayerPath(), vbox, lambda __, _: self._saveDataAndLeave()) - def _tryToFillUpMpcPath(self, playerPath): - if(playerPath == None): - for path in constants.MPC_PATHS: - if(os.path.isfile(path)): - return path - return playerPath + def _tryToFillPlayerPath(self): + for path in self._availablePlayerPaths: + if(os.path.isfile(path)): + return path + return self.config["playerPath"] def getProcessedConfiguration(self): if(self.closedAndNotSaved): @@ -91,10 +90,12 @@ class GuiConfiguration: vbox.add(hbox) hbox.show() return entry - + + def setAvailablePaths(self, paths): + self._availablePlayerPaths = paths + class WindowClosed(Exception): - def __init__(self): - Exception.__init__(self) + pass