Added PlayerFactory

This commit is contained in:
Uriziel 2013-01-11 00:43:52 +01:00
parent 298247b145
commit eb27fe2c6a
9 changed files with 128 additions and 60 deletions

View File

@ -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'])

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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')

View File

@ -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

View File

@ -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)):

View File

@ -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