Added PlayerFactory
This commit is contained in:
parent
298247b145
commit
eb27fe2c6a
@ -3,21 +3,11 @@ from syncplay.ui.ConfigurationGetter import ConfigurationGetter
|
|||||||
from syncplay import ui
|
from syncplay import ui
|
||||||
from syncplay.messages import getMessage
|
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):
|
class SyncplayClientManager(object):
|
||||||
def run(self):
|
def run(self):
|
||||||
config = ConfigurationGetter().getConfiguration()
|
config = ConfigurationGetter().getConfiguration()
|
||||||
interface = ui.getUi(graphical=not config["noGui"])
|
interface = ui.getUi(graphical=not config["noGui"])
|
||||||
syncplayClient = None
|
syncplayClient = SyncplayClient(config["playerClass"], interface, config)
|
||||||
if(config['playerType'] == "mpc"):
|
|
||||||
syncplayClient = SyncplayClient(MPCHCAPIPlayer, interface, config)
|
|
||||||
elif(config['playerType'] == "mplayer"):
|
|
||||||
syncplayClient = SyncplayClient(MplayerPlayer, interface, config)
|
|
||||||
if(syncplayClient):
|
if(syncplayClient):
|
||||||
interface.addClient(syncplayClient)
|
interface.addClient(syncplayClient)
|
||||||
syncplayClient.start(config['host'], config['port'])
|
syncplayClient.start(config['host'], config['port'])
|
||||||
|
|||||||
@ -37,7 +37,7 @@ MPC_PATHS = [
|
|||||||
"C:\Program Files (x86)\Combined Community Codec Pack\MPC\mpc-hc.exe",
|
"C:\Program Files (x86)\Combined Community Codec Pack\MPC\mpc-hc.exe",
|
||||||
"C:\Program Files\MPC HomeCinema (x64)\mpc-hc64.exe",
|
"C:\Program Files\MPC HomeCinema (x64)\mpc-hc64.exe",
|
||||||
]
|
]
|
||||||
|
MPLAYER_PATHS = ["mplayer2", "mplayer"]
|
||||||
#Changing these is usually not something you're looking for
|
#Changing these is usually not something you're looking for
|
||||||
PLAYER_ASK_DELAY = 0.1
|
PLAYER_ASK_DELAY = 0.1
|
||||||
PING_MOVING_AVERAGE_WEIGHT = 0.85
|
PING_MOVING_AVERAGE_WEIGHT = 0.85
|
||||||
|
|||||||
@ -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]
|
||||||
@ -45,3 +45,28 @@ class BasePlayer(object):
|
|||||||
'''
|
'''
|
||||||
def setSpeed(self, value):
|
def setSpeed(self, value):
|
||||||
raise NotImplementedError()
|
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
|
||||||
@ -9,7 +9,8 @@ import re
|
|||||||
from syncplay.utils import retry
|
from syncplay.utils import retry
|
||||||
from syncplay import constants
|
from syncplay import constants
|
||||||
from syncplay.messages import getMessage
|
from syncplay.messages import getMessage
|
||||||
|
import os.path
|
||||||
|
|
||||||
class MpcHcApi:
|
class MpcHcApi:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.callbacks = self.__Callbacks()
|
self.callbacks = self.__Callbacks()
|
||||||
@ -328,9 +329,10 @@ class MPCHCAPIPlayer(BasePlayer):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run(client, playerPath, filePath, args):
|
def run(client, playerPath, filePath, args):
|
||||||
|
args.extend(['/open', '/new'])
|
||||||
mpc = MPCHCAPIPlayer(client)
|
mpc = MPCHCAPIPlayer(client)
|
||||||
mpc._mpcApi.callbacks.onConnected = lambda: mpc.initPlayer(filePath if(filePath) else None)
|
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
|
return mpc
|
||||||
|
|
||||||
def __lockAsking(self):
|
def __lockAsking(self):
|
||||||
@ -453,3 +455,25 @@ class MPCHCAPIPlayer(BasePlayer):
|
|||||||
|
|
||||||
def sendCustomCommand(self, cmd, val):
|
def sendCustomCommand(self, cmd, val):
|
||||||
self._mpcApi.sendRawCommand(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
|
||||||
@ -4,6 +4,7 @@ import threading
|
|||||||
from syncplay.players.basePlayer import BasePlayer
|
from syncplay.players.basePlayer import BasePlayer
|
||||||
from syncplay import constants
|
from syncplay import constants
|
||||||
from syncplay.messages import getMessage
|
from syncplay.messages import getMessage
|
||||||
|
import os
|
||||||
|
|
||||||
class MplayerPlayer(BasePlayer):
|
class MplayerPlayer(BasePlayer):
|
||||||
speedSupported = True
|
speedSupported = True
|
||||||
@ -125,8 +126,32 @@ class MplayerPlayer(BasePlayer):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run(client, playerPath, filePath, args):
|
def run(client, playerPath, filePath, args):
|
||||||
mplayer = MplayerPlayer(client, playerPath, filePath, args)
|
mplayer = MplayerPlayer(client, MplayerPlayer.getExpandedPath(playerPath), filePath, args)
|
||||||
return mplayer
|
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):
|
def drop(self):
|
||||||
self._listener.sendLine('quit')
|
self._listener.sendLine('quit')
|
||||||
|
|||||||
16
syncplay/players/playerFactory.py
Normal file
16
syncplay/players/playerFactory.py
Normal 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
|
||||||
@ -4,6 +4,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from syncplay import constants, utils
|
from syncplay import constants, utils
|
||||||
from syncplay.messages import getMessage
|
from syncplay.messages import getMessage
|
||||||
|
from syncplay.players.playerFactory import PlayerFactory
|
||||||
try:
|
try:
|
||||||
from syncplay.ui.GuiConfiguration import GuiConfiguration
|
from syncplay.ui.GuiConfiguration import GuiConfiguration
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -28,7 +29,7 @@ class ConfigurationGetter(object):
|
|||||||
"playerPath": None,
|
"playerPath": None,
|
||||||
"file": None,
|
"file": None,
|
||||||
"playerArgs": [],
|
"playerArgs": [],
|
||||||
"playerType": None,
|
"playerClass": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -39,7 +40,7 @@ class ConfigurationGetter(object):
|
|||||||
"port",
|
"port",
|
||||||
"name",
|
"name",
|
||||||
"playerPath",
|
"playerPath",
|
||||||
"playerType",
|
"playerClass",
|
||||||
]
|
]
|
||||||
|
|
||||||
self._iniStructure = {
|
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('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._argparser.add_argument('_args', metavar='options', type=str, nargs='*', help=getMessage("en", "args-argument"))
|
||||||
|
|
||||||
|
|
||||||
|
self._playerFactory = PlayerFactory()
|
||||||
|
|
||||||
def _validateArguments(self):
|
def _validateArguments(self):
|
||||||
for key in self._required:
|
for key in self._required:
|
||||||
if(key == "playerPath"):
|
if(key == "playerPath"):
|
||||||
if(self._isPlayerMPCAndValid(self._config["playerPath"])):
|
player = self._playerFactory.getPlayerByPath(self._config["playerPath"])
|
||||||
self._config["playerType"] = "mpc"
|
if(player):
|
||||||
self.__addSpecialMPCFlags()
|
self._config["playerClass"] = player
|
||||||
elif(self._isMplayerPathAndValid(self._config["playerPath"])):
|
|
||||||
self._config["playerType"] = "mplayer"
|
|
||||||
else:
|
else:
|
||||||
raise InvalidConfigValue("Player path is not set properly")
|
raise InvalidConfigValue("Player path is not set properly")
|
||||||
elif(key == "host"):
|
elif(key == "host"):
|
||||||
@ -98,32 +100,6 @@ class ConfigurationGetter(object):
|
|||||||
key = "noGui"
|
key = "noGui"
|
||||||
self._config[key] = val
|
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):
|
def _splitPortAndHost(self, host):
|
||||||
port = constants.DEFAULT_PORT if not self._config["port"] else self._config["port"]
|
port = constants.DEFAULT_PORT if not self._config["port"] else self._config["port"]
|
||||||
if(host):
|
if(host):
|
||||||
@ -170,7 +146,9 @@ class ConfigurationGetter(object):
|
|||||||
print getMessage("en", "missing-arguments-error")
|
print getMessage("en", "missing-arguments-error")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
elif(GuiConfiguration):
|
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):
|
def __wasOptionChanged(self, parser, section, option):
|
||||||
if (parser.has_option(section, option)):
|
if (parser.has_option(section, option)):
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import pygtk
|
import pygtk
|
||||||
import os
|
import os
|
||||||
from syncplay import constants
|
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk
|
import gtk
|
||||||
gtk.set_interactive(False)
|
gtk.set_interactive(False)
|
||||||
@ -10,6 +9,7 @@ from syncplay.messages import getMessage
|
|||||||
class GuiConfiguration:
|
class GuiConfiguration:
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
self._availablePlayerPaths = []
|
||||||
self.closedAndNotSaved = False
|
self.closedAndNotSaved = False
|
||||||
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||||
self.window.set_title(getMessage("en", "config-window-title"))
|
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.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.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.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):
|
def _tryToFillPlayerPath(self):
|
||||||
if(playerPath == None):
|
for path in self._availablePlayerPaths:
|
||||||
for path in constants.MPC_PATHS:
|
if(os.path.isfile(path)):
|
||||||
if(os.path.isfile(path)):
|
return path
|
||||||
return path
|
return self.config["playerPath"]
|
||||||
return playerPath
|
|
||||||
|
|
||||||
def getProcessedConfiguration(self):
|
def getProcessedConfiguration(self):
|
||||||
if(self.closedAndNotSaved):
|
if(self.closedAndNotSaved):
|
||||||
@ -91,10 +90,12 @@ class GuiConfiguration:
|
|||||||
vbox.add(hbox)
|
vbox.add(hbox)
|
||||||
hbox.show()
|
hbox.show()
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
|
def setAvailablePaths(self, paths):
|
||||||
|
self._availablePlayerPaths = paths
|
||||||
|
|
||||||
class WindowClosed(Exception):
|
class WindowClosed(Exception):
|
||||||
def __init__(self):
|
pass
|
||||||
Exception.__init__(self)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user