Implemented getMessage across syncplay.

This commit is contained in:
daniel-123 2013-01-05 23:17:18 +01:00
parent d1cd71f8eb
commit 9dd4f7cc0f
11 changed files with 63 additions and 58 deletions

View File

@ -20,7 +20,5 @@ class SyncplayClientManager(object):
interface.addClient(syncplayClient) interface.addClient(syncplayClient)
syncplayClient.start(config['host'], config['port']) syncplayClient.start(config['host'], config['port'])
else: else:
interface.showErrorMessage("Unable to start client") interface.showErrorMessage(getMessage("en", "unable-to-start-client-error"))

View File

@ -23,6 +23,7 @@ COMMANDS_LIST = ["l", "list", "users"]
COMMANDS_PAUSE = ["p", "play", "pause"] COMMANDS_PAUSE = ["p", "play", "pause"]
COMMANDS_ROOM = ["r", "room"] COMMANDS_ROOM = ["r", "room"]
COMMANDS_HELP = ['help', 'h', '?', '/?', '\?'] COMMANDS_HELP = ['help', 'h', '?', '/?', '\?']
MPC_MIN_VER = "1.6.4"
MPC_PATHS = [ MPC_PATHS = [
"C:\Program Files (x86)\MPC-HC\mpc-hc.exe", "C:\Program Files (x86)\MPC-HC\mpc-hc.exe",
"C:\Program Files\MPC-HC\mpc-hc.exe", "C:\Program Files\MPC-HC\mpc-hc.exe",

View File

@ -52,6 +52,7 @@ en = {
"enter-to-exit-prompt" : "Press enter to exit\n", "enter-to-exit-prompt" : "Press enter to exit\n",
# Client errors # Client errors
"missing-arguments-error" : "Some necessary arguments are missing, refer to --help",
"server-timeout-error" : "Connection with server timed out", "server-timeout-error" : "Connection with server timed out",
"mpc-slave-error" : "Unable to start MPC in slave mode!", "mpc-slave-error" : "Unable to start MPC in slave mode!",
"mpc-version-insufficient-error" : "MPC version not sufficient, please use `mpc-hc` >= `{}`", "mpc-version-insufficient-error" : "MPC version not sufficient, please use `mpc-hc` >= `{}`",

View File

@ -8,6 +8,7 @@ from syncplay.players.basePlayer import BasePlayer
import re 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
class MpcHcApi: class MpcHcApi:
def __init__(self): def __init__(self):
@ -40,7 +41,7 @@ class MpcHcApi:
args = "%s /slave %s" % (" ".join(args), str(self.__listener.hwnd)) args = "%s /slave %s" % (" ".join(args), str(self.__listener.hwnd))
win32api.ShellExecute(0, "open", path, args, None, 1) win32api.ShellExecute(0, "open", path, args, None, 1)
if(not self.__locks.mpcStart.wait(constants.MPC_OPEN_MAX_WAIT_TIME)): if(not self.__locks.mpcStart.wait(constants.MPC_OPEN_MAX_WAIT_TIME)):
raise self.NoSlaveDetectedException("Unable to start MPC in slave mode!") raise self.NoSlaveDetectedException(getMessage("en", "mpc-slave-error"))
self.__mpcExistenceChecking.start() self.__mpcExistenceChecking.start()
def openFile(self, filePath): def openFile(self, filePath):
@ -350,12 +351,12 @@ class MPCHCAPIPlayer(BasePlayer):
def __dropIfNotSufficientVersion(self): def __dropIfNotSufficientVersion(self):
self._mpcApi.askForVersion() self._mpcApi.askForVersion()
if(not self.__versionUpdate.wait(0.1) or not self._mpcApi.version): if(not self.__versionUpdate.wait(0.1) or not self._mpcApi.version):
self.__mpcError("MPC version not sufficient, please use `mpc-hc` >= `1.6.4`") self.__mpcError(getMessage("en", "mpc-version-insufficient-error").format(MPC_MIN_VER))
self.__client.stop(True) self.__client.stop(True)
def __testMpcReady(self): def __testMpcReady(self):
if(not self.__preventAsking.wait(10)): if(not self.__preventAsking.wait(10)):
raise Exception("Player failed opening file") raise Exception(getMessage("en", "player-file-open-error"))
def __makePing(self): def __makePing(self):
try: try:

View File

@ -3,6 +3,7 @@ import re
import threading 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
class MplayerPlayer(BasePlayer): class MplayerPlayer(BasePlayer):
speedSupported = True speedSupported = True
@ -16,8 +17,8 @@ class MplayerPlayer(BasePlayer):
try: try:
self._listener = self.__Listener(self, playerPath, filePath, args) self._listener = self.__Listener(self, playerPath, filePath, args)
except ValueError: except ValueError:
self._client.ui.showMessage("Syncplay using mplayer requires you to provide file when starting") self._client.ui.showMessage(getMessage("en", "mplayer-file-required-notification"))
self._client.ui.showMessage("Usage example: syncplay [options] [url|path/]filename") self._client.ui.showMessage(getMessage("en", "mplayer-file-required-notification/example"))
self._client.stop(True) self._client.stop(True)
return return
self._listener.setDaemon(True) self._listener.setDaemon(True)

View File

@ -4,6 +4,7 @@ import json
import syncplay import syncplay
from functools import wraps from functools import wraps
import time import time
from syncplay.messages import getMessage
class JSONCommandProtocol(LineReceiver): class JSONCommandProtocol(LineReceiver):
def handleMessages(self, messages): def handleMessages(self, messages):
@ -20,7 +21,7 @@ class JSONCommandProtocol(LineReceiver):
elif command == "Error": elif command == "Error":
self.handleError(message[1]) self.handleError(message[1])
else: else:
self.dropWithError("Unknown Command\n" + message[1]) #TODO: log, not drop self.dropWithError(getMessage("en", "unknown-command-server-error").format(message[1])) #TODO: log, not drop
def printReceived(self, line): #TODO: remove def printReceived(self, line): #TODO: remove
#print ">>i", line #print ">>i", line
@ -38,7 +39,7 @@ class JSONCommandProtocol(LineReceiver):
try: try:
messages = json.loads(line) messages = json.loads(line)
except: except:
self.dropWithError("Not a json encoded string\n" + line) self.dropWithError(getMessage("en", "not-json-server-error").format(line))
return return
self.handleMessages(messages) self.handleMessages(messages)
@ -81,14 +82,14 @@ class SyncClientProtocol(JSONCommandProtocol):
def handleHello(self, hello): def handleHello(self, hello):
username, roomName, version = self._extractHelloArguments(hello) username, roomName, version = self._extractHelloArguments(hello)
if(not username or not roomName or not version): if(not username or not roomName or not version):
self.dropWithError("Not enough Hello arguments\n" + hello) self.dropWithError(getMessage("en", "hello-server-error").format(hello))
elif(version.split(".")[0:2] != syncplay.version.split(".")[0:2]): elif(version.split(".")[0:2] != syncplay.version.split(".")[0:2]):
self.dropWithError("Mismatch between versions of client and server\n" + hello) self.dropWithError(getMessage("en", "version-mismatch-server-error".format(hello)))
else: else:
self._client.setUsername(username) self._client.setUsername(username)
self._client.setRoom(roomName) self._client.setRoom(roomName)
self.logged = True self.logged = True
self._client.ui.showMessage("Successfully connected to server") self._client.ui.showMessage(getMessage("en", "connected-successful-notification"))
self._client.sendFile() self._client.sendFile()
def sendHello(self): def sendHello(self):
@ -232,12 +233,12 @@ class SyncServerProtocol(JSONCommandProtocol):
@wraps(f) @wraps(f)
def wrapper(self, *args, **kwds): def wrapper(self, *args, **kwds):
if(not self._logged): if(not self._logged):
self.dropWithError("You must be known to server before sending this command") self.dropWithError(getMessage("en", "not-known-server-error"))
return f(self, *args, **kwds) return f(self, *args, **kwds)
return wrapper return wrapper
def dropWithError(self, error): def dropWithError(self, error):
print "Client drop: %s -- %s" % (self.transport.getPeer().host, error) print getMessage("en", "client-drop-server-error").format((self.transport.getPeer().host, error))
self.sendError(error) self.sendError(error)
self.drop() self.drop()
@ -260,19 +261,19 @@ class SyncServerProtocol(JSONCommandProtocol):
def _checkPassword(self, serverPassword): def _checkPassword(self, serverPassword):
if(self._factory.password): if(self._factory.password):
if(not serverPassword): if(not serverPassword):
self.dropWithError("Password required") self.dropWithError(getMessage("en", "password-required-server-error"))
return False return False
if(serverPassword != self._factory.password): if(serverPassword != self._factory.password):
self.dropWithError("Wrong password supplied") self.dropWithError(getMessage("en", "wrong-password-server-error"))
return False return False
return True return True
def handleHello(self, hello): def handleHello(self, hello):
username, serverPassword, roomName, roomPassword, version = self._extractHelloArguments(hello) username, serverPassword, roomName, roomPassword, version = self._extractHelloArguments(hello)
if(not username or not roomName or not version): if(not username or not roomName or not version):
self.dropWithError("Not enough Hello arguments") self.dropWithError(getMessage("en", "hello-server-error"))
elif(version.split(".")[0:2] != syncplay.version.split(".")[0:2]): elif(version.split(".")[0:2] != syncplay.version.split(".")[0:2]):
self.dropWithError("Mismatch between versions of client and server") self.dropWithError(getMessage("en", "version-mismatch-server-error"))
else: else:
if(not self._checkPassword(serverPassword)): if(not self._checkPassword(serverPassword)):
return return

View File

@ -8,10 +8,11 @@ from syncplay.protocols import SyncServerProtocol
import time import time
from syncplay import constants from syncplay import constants
import threading import threading
from syncplay.messages import getMessage
class SyncFactory(Factory): class SyncFactory(Factory):
def __init__(self, password = ''): def __init__(self, password = ''):
print "Welcome to Syncplay server, ver. {0}".format(syncplay.version) print getMessage("en", "welcome-server-notification").format(syncplay.version)
if(password): if(password):
password = hashlib.md5(password).hexdigest() password = hashlib.md5(password).hexdigest()
self.password = password self.password = password
@ -44,7 +45,7 @@ class SyncFactory(Factory):
watcher = Watcher(self, watcherProtocol, username, roomName) watcher = Watcher(self, watcherProtocol, username, roomName)
with self._roomUpdate: with self._roomUpdate:
self._rooms[roomName][watcherProtocol] = watcher self._rooms[roomName][watcherProtocol] = watcher
print "{0}({2}) connected to room '{1}'".format(username, roomName, watcherProtocol.transport.getPeer().host) print getMessage("en", "client-connected-room-server-notification").format(username, roomName, watcherProtocol.transport.getPeer().host)
reactor.callLater(0.1, watcher.scheduleSendState) reactor.callLater(0.1, watcher.scheduleSendState)
l = lambda w: w.sendUserSetting(username, roomName, None, {"joined": True}) l = lambda w: w.sendUserSetting(username, roomName, None, {"joined": True})
self.broadcast(watcherProtocol, l) self.broadcast(watcherProtocol, l)
@ -151,7 +152,7 @@ class SyncFactory(Factory):
self._removeWatcherFromTheRoom(watcherProtocol) self._removeWatcherFromTheRoom(watcherProtocol)
watcher.deactivate() watcher.deactivate()
self._deleteRoomIfEmpty(watcher.room) self._deleteRoomIfEmpty(watcher.room)
print "{0} left server".format(watcher.name) print getMessage("en", "client-left-server-notification").format(watcher.name)
def watcherGetUsername(self, watcherProtocol): def watcherGetUsername(self, watcherProtocol):
return self.getWatcher(watcherProtocol).name return self.getWatcher(watcherProtocol).name

View File

@ -3,6 +3,7 @@ import argparse
import os import os
import sys import sys
from syncplay import constants from syncplay import constants
from syncplay.messages import getMessage
try: try:
from syncplay.ui.GuiConfiguration import GuiConfiguration from syncplay.ui.GuiConfiguration import GuiConfiguration
except ImportError: except ImportError:
@ -49,19 +50,19 @@ class ConfigurationGetter(object):
# #
#Watch out for the method self._overrideConfigWithArgs when you're adding custom multi-word command line arguments #Watch out for the method self._overrideConfigWithArgs when you're adding custom multi-word command line arguments
# #
self._argparser = argparse.ArgumentParser(description='Solution to synchronize playback of multiple MPlayer and MPC-HC instances over the network.', self._argparser = argparse.ArgumentParser(description=getMessage("en", "argument-description"),
epilog='If no options supplied values from configuration file will be used') epilog=getMessage("en", "argument-epilog"))
self._argparser.add_argument('--no-gui', action='store_true', help='show no GUI') self._argparser.add_argument('--no-gui', action='store_true', help=getMessage("en", "nogui-argument"))
self._argparser.add_argument('-a', '--host', metavar='hostname', type=str, help='server\'s address') self._argparser.add_argument('-a', '--host', metavar='hostname', type=str, help=getMessage("en", "host-argument"))
self._argparser.add_argument('-n', '--name', metavar='username', type=str, help='desired username') self._argparser.add_argument('-n', '--name', metavar='username', type=str, help=getMessage("en", "name-argument"))
self._argparser.add_argument('-d', '--debug', action='store_true', help='debug mode') self._argparser.add_argument('-d', '--debug', action='store_true', help=getMessage("en", "debug-argument"))
self._argparser.add_argument('-g', '--force-gui-prompt', action='store_true', help='make configuration prompt appear') self._argparser.add_argument('-g', '--force-gui-prompt', action='store_true', help=getMessage("en", "force-gui-prompt-argument"))
self._argparser.add_argument('--no-store', action='store_true', help='don\'t store values in .syncplay') self._argparser.add_argument('--no-store', action='store_true', help=getMessage("en", "no-store-argument"))
self._argparser.add_argument('-r', '--room', metavar='room', type=str, nargs='?', help='default room') self._argparser.add_argument('-r', '--room', metavar='room', type=str, nargs='?', help=getMessage("en", "room-argument"))
self._argparser.add_argument('-p', '--password', metavar='password', type=str, nargs='?', help='server password') self._argparser.add_argument('-p', '--password', metavar='password', type=str, nargs='?', help=getMessage("en", "password-argument"))
self._argparser.add_argument('--player-path', metavar='path', type=str, help='path to your player executable') self._argparser.add_argument('--player-path', metavar='path', type=str, help=getMessage("en", "player-path-argument"))
self._argparser.add_argument('file', metavar='file', type=str, nargs='?', help='file to play') 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='player options, if you need to pass options starting with - prepend them with single \'--\' argument') self._argparser.add_argument('_args', metavar='options', type=str, nargs='*', help=getMessage("en", "args-argument"))
def _validateArguments(self): def _validateArguments(self):
for key in self._required: for key in self._required:
@ -176,7 +177,7 @@ class ConfigurationGetter(object):
def _promptForMissingArguments(self): def _promptForMissingArguments(self):
if(self._config['noGui']): if(self._config['noGui']):
print "Some necessary arguments are missing, refer to --help" print getMessage("en", "missing-arguments-error")
sys.exit() sys.exit()
elif(GuiConfiguration): elif(GuiConfiguration):
return GuiConfiguration(self._config).getProcessedConfiguration() return GuiConfiguration(self._config).getProcessedConfiguration()
@ -228,8 +229,8 @@ class ServerConfigurationGetter(object):
return self._args return self._args
def _prepareArgParser(self): def _prepareArgParser(self):
self._argparser = argparse.ArgumentParser(description='Solution to synchronize playback of multiple MPlayer and MPC-HC instances over the network. Server instance', self._argparser = argparse.ArgumentParser(description=getMessage("en", "server-argument-description"),
epilog='If no options supplied _config values will be used') epilog=getMessage("en", "server-argument-epilog"))
self._argparser.add_argument('--port', metavar='port', type=str, nargs='?', help='server TCP port') self._argparser.add_argument('--port', metavar='port', type=str, nargs='?', help=getMessage("en", "server-port-argument"))
self._argparser.add_argument('--password', metavar='password', type=str, nargs='?', help='server password') self._argparser.add_argument('--password', metavar='password', type=str, nargs='?', help=getMessage("en", "server-password-argument"))
self._argparser.add_argument('--isolate-rooms', action='store_true', help='should rooms be isolated?') self._argparser.add_argument('--isolate-rooms', action='store_true', help=getMessage("en", "server-isolate-room-argument"))

View File

@ -11,7 +11,7 @@ class GuiConfiguration:
self.config = config self.config = config
self.closedAndNotSaved = False self.closedAndNotSaved = False
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title("Syncplay Configuration") self.window.set_title(getMessage("en", "config-window-title"))
self.window.connect("delete_event", lambda w, e: self._windowClosed()) self.window.connect("delete_event", lambda w, e: self._windowClosed())
vbox = gtk.VBox(False, 0) vbox = gtk.VBox(False, 0)
self.window.add(vbox) self.window.add(vbox)
@ -41,11 +41,11 @@ class GuiConfiguration:
else: else:
host = config['host']+":"+str(config['port']) host = config['host']+":"+str(config['port'])
self.hostEntry = self._addLabeledEntryToVbox('Host: ', host, vbox, lambda __, _: self._saveDataAndLeave()) self.hostEntry = self._addLabeledEntryToVbox(getMessage("en", "host-label"), host, vbox, lambda __, _: self._saveDataAndLeave())
self.userEntry = self._addLabeledEntryToVbox('Username: ', config['name'], vbox, lambda __, _: self._saveDataAndLeave()) self.userEntry = self._addLabeledEntryToVbox(getMessage("en", "username-label"), config['name'], vbox, lambda __, _: self._saveDataAndLeave())
self.roomEntry = self._addLabeledEntryToVbox('Default room (optional): ', config['room'], vbox, lambda __, _: self._saveDataAndLeave()) self.roomEntry = self._addLabeledEntryToVbox(getMessage("en", "room-label"), config['room'], vbox, lambda __, _: self._saveDataAndLeave())
self.passEntry = self._addLabeledEntryToVbox('Server password (optional): ', config['password'], vbox, lambda __, _: self._saveDataAndLeave()) self.passEntry = self._addLabeledEntryToVbox(getMessage("en", "password-label"), config['password'], vbox, lambda __, _: self._saveDataAndLeave())
self.mpcEntry = self._addLabeledEntryToVbox('Path to player executable: ', self._tryToFillUpMpcPath(config['playerPath']), vbox, lambda __, _: self._saveDataAndLeave()) self.mpcEntry = self._addLabeledEntryToVbox(getMessage("en", "path-label"), self._tryToFillUpMpcPath(config['playerPath']), vbox, lambda __, _: self._saveDataAndLeave())
def _tryToFillUpMpcPath(self, playerPath): def _tryToFillUpMpcPath(self, playerPath):
if(playerPath == None): if(playerPath == None):

View File

@ -109,14 +109,14 @@ class ConsoleUI(threading.Thread):
if(self._tryAdvancedCommands(data)): if(self._tryAdvancedCommands(data)):
return return
if (command.group('command') not in constants.COMMANDS_HELP): if (command.group('command') not in constants.COMMANDS_HELP):
self.showMessage("Unrecognized command") self.showMessage(getMessage("en", "unrecognized-command-notification"))
self.showMessage("Available commands:", True) self.showMessage(getMessage("en", "commandlist-notification"), True)
self.showMessage("\tr [name] - change room", True) self.showMessage(getMessage("en", "commandlist-notification/room"), True)
self.showMessage("\tl - show user list", True) self.showMessage(getMessage("en", "commandlist-notification/list"), True)
self.showMessage("\tu - undo last seek", True) self.showMessage(getMessage("en", "commandlist-notification/undo"), True)
self.showMessage("\tp - toggle pause", True) self.showMessage(getMessage("en", "commandlist-notification/pause"), True)
self.showMessage("\t[s][+-]time - seek to the given value of time, if + or - is not specified it's absolute time in seconds or min:sec", True) self.showMessage(getMessage("en", "commandlist-notification/seek"), True)
self.showMessage("\th - this help", True) self.showMessage(getMessage("en", "commandlist-notification/help"), True)
self.showMessage("Syncplay version: {}".format(syncplay.version), True) self.showMessage(getMessage("en", "syncplay-version-notification").format(syncplay.version), True)
self.showMessage("More info available at: {}".format(syncplay.projectURL), True) self.showMessage(getMessage("en", "more-info-notification").format(syncplay.projectURL), True)

View File

@ -33,7 +33,7 @@ def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
break break
except ExceptionToCheck, e: except ExceptionToCheck, e:
if logger: if logger:
msg = "%s, Retrying in %d seconds..." % (str(e), mdelay) msg = getMessage("en", "retrying-notification").format(str(e), mdelay)
logger.warning(msg) logger.warning(msg)
time.sleep(mdelay) time.sleep(mdelay)
mtries -= 1 mtries -= 1