diff --git a/syncplay/client.py b/syncplay/client.py index a79e465..d6effd9 100644 --- a/syncplay/client.py +++ b/syncplay/client.py @@ -71,6 +71,8 @@ class SyncplayClient(object): self.lastControlPasswordAttempt = None self.serverVersion = "0.0.0" + self.serverFeatures = {} + self.lastRewindTime = None self.lastLeftTime = 0 self.lastPausedOnLeaveTime = None @@ -201,7 +203,7 @@ class SyncplayClient(object): if pauseChange and paused and currentLength > constants.PLAYLIST_LOAD_NEXT_FILE_MINIMUM_LENGTH\ and abs(position - currentLength ) < constants.PLAYLIST_LOAD_NEXT_FILE_TIME_FROM_END_THRESHOLD: self.playlist.advancePlaylistCheck() - elif pauseChange and utils.meetsMinVersion(self.serverVersion, constants.USER_READY_MIN_VERSION): + elif pauseChange and self.serverFeatures["readiness"]: if currentLength == 0 or currentLength == -1 or\ not (not self.playlist.notJustChangedPlaylist() and abs(position - currentLength ) < constants.PLAYLIST_LOAD_NEXT_FILE_TIME_FROM_END_THRESHOLD): pauseChange = self._toggleReady(pauseChange, paused) @@ -508,13 +510,25 @@ class SyncplayClient(object): size = 0 return filename, size - def setServerVersion(self, version): + def setServerVersion(self, version, featureList): self.serverVersion = version - self.checkForFeatureSupport() + self.checkForFeatureSupport(featureList) - def checkForFeatureSupport(self): + def checkForFeatureSupport(self, featureList): + self.serverFeatures = { + "featureList": utils.meetsMinVersion(self.serverVersion, constants.FEATURE_LIST_MIN_VERSION), + "sharedPlaylists": utils.meetsMinVersion(self.serverVersion, constants.SHARED_PLAYLIST_MIN_VERSION), + "chat": utils.meetsMinVersion(self.serverVersion, constants.CHAT_MIN_VERSION), + "readiness": utils.meetsMinVersion(self.serverVersion, constants.USER_READY_MIN_VERSION), + "managedRooms": utils.meetsMinVersion(self.serverVersion, constants.CONTROLLED_ROOMS_MIN_VERSION) + } + if featureList: + self.serverFeatures.update(featureList) if not utils.meetsMinVersion(self.serverVersion, constants.SHARED_PLAYLIST_MIN_VERSION): self.ui.showErrorMessage(getMessage("shared-playlists-not-supported-by-server-error").format(constants.SHARED_PLAYLIST_MIN_VERSION, self.serverVersion)) + elif not self.serverFeatures["sharedPlaylists"]: + self.ui.showErrorMessage(getMessage("shared-playlists-disabled-by-server-error")) + self.ui.setFeatures(self.serverFeatures) def getSanitizedCurrentUserFile(self): if self.userlist.currentUser.file: @@ -570,7 +584,11 @@ class SyncplayClient(object): return self._protocol and self._protocol.logged and self.userlist.currentUser.room def sharedPlaylistIsEnabled(self): - return self._config['sharedPlaylistEnabled'] + if self.serverFeatures.has_key("sharedPlaylists") and not self.serverFeatures["sharedPlaylists"]: + sharedPlaylistEnabled = False + else: + sharedPlaylistEnabled = self._config['sharedPlaylistEnabled'] + return sharedPlaylistEnabled def connected(self): readyState = self._config['readyAtStart'] if self.userlist.currentUser.isReady() is None else self.userlist.currentUser.isReady() @@ -1004,13 +1022,12 @@ class SyncplayUserlist(object): self._roomUsersChanged = True def isReadinessSupported(self): - # TODO: Return False if server is run with --disable-ready if not utils.meetsMinVersion(self._client.serverVersion,constants.USER_READY_MIN_VERSION): return False elif self.onlyUserInRoomWhoSupportsReadiness(): return False else: - return True + return self._client.serverFeatures["readiness"] def isRoomSame(self, room): if room and self.currentUser.room and self.currentUser.room == room: @@ -1293,6 +1310,9 @@ class UiManager(object): def fileSwitchFoundFiles(self): self.__ui.fileSwitchFoundFiles() + def setFeatures(self, featureList): + self.__ui.setFeatures(featureList) + def showDebugMessage(self, message): if constants.DEBUG_MODE and message.rstrip(): sys.stderr.write("{}{}\n".format(time.strftime(constants.UI_TIME_FORMAT, time.localtime()),message.rstrip())) diff --git a/syncplay/constants.py b/syncplay/constants.py index dfbab0c..37f1fd7 100644 --- a/syncplay/constants.py +++ b/syncplay/constants.py @@ -80,6 +80,7 @@ CONTROLLED_ROOMS_MIN_VERSION = "1.3.0" USER_READY_MIN_VERSION = "1.3.0" SHARED_PLAYLIST_MIN_VERSION = "1.4.0" CHAT_MIN_VERSION = "1.5.0" +FEATURE_LIST_MIN_VERSION = "1.5.0" MPC_PATHS = [ r"c:\program files (x86)\mpc-hc\mpc-hc.exe", r"c:\program files\mpc-hc\mpc-hc.exe", diff --git a/syncplay/messages_de.py b/syncplay/messages_de.py index 6529800..bd715d8 100644 --- a/syncplay/messages_de.py +++ b/syncplay/messages_de.py @@ -136,6 +136,7 @@ de = { "not-supported-by-server-error" : u"Dieses Feature wird vom Server nicht unterstützt. Es wird ein Server mit Syncplay Version {}+ benötigt, aktuell verwendet wird jedoch Version {}.", #minVersion, serverVersion "shared-playlists-not-supported-by-server-error" : "The shared playlists feature may not be supported by the server. To ensure that it works correctly requires a server running Syncplay {}+, but the server is running Syncplay {}.", #minVersion, serverVersion # TODO: Translate + "shared-playlists-disabled-by-server-error" : "The shared playlist feature has been disabled in the server configuration. To use this feature you will need to connect to a different server.", # TODO: Translate "invalid-seek-value" : u"Ungültige Zeitangabe", "invalid-offset-value" : u"Ungültiger Offset-Wert", diff --git a/syncplay/messages_en.py b/syncplay/messages_en.py index 7bb63c6..7c2a3f9 100644 --- a/syncplay/messages_en.py +++ b/syncplay/messages_en.py @@ -136,6 +136,7 @@ en = { "not-supported-by-server-error" : "This feature is not supported by the server. The feature requires a server running Syncplay {}+, but the server is running Syncplay {}.", #minVersion, serverVersion "shared-playlists-not-supported-by-server-error" : "The shared playlists feature may not be supported by the server. To ensure that it works correctly requires a server running Syncplay {}+, but the server is running Syncplay {}.", #minVersion, serverVersion + "shared-playlists-disabled-by-server-error" : "The shared playlist feature has been disabled in the server configuration. To use this feature you will need to connect to a different server.", "invalid-seek-value" : u"Invalid seek value", "invalid-offset-value" : u"Invalid offset value", diff --git a/syncplay/messages_ru.py b/syncplay/messages_ru.py index 81ecf7c..1c54910 100644 --- a/syncplay/messages_ru.py +++ b/syncplay/messages_ru.py @@ -136,6 +136,7 @@ ru = { "not-supported-by-server-error" : u"Эта возможность не поддерживается сервером. The feature requires a server running Syncplay {}+, but the server is running Syncplay {}.", #minVersion, serverVersion #TODO: Translate into Russian "shared-playlists-not-supported-by-server-error" : "The shared playlists feature may not be supported by the server. To ensure that it works correctly requires a server running Syncplay {}+, but the server is running Syncplay {}.", #minVersion, serverVersion # TODO: Translate + "shared-playlists-disabled-by-server-error" : "The shared playlist feature has been disabled in the server configuration. To use this feature you will need to connect to a different server.", # TODO: Translate "invalid-seek-value" : u"Некорректное значение для перемотки", "invalid-offset-value" : u"Некорректное смещение", diff --git a/syncplay/protocols.py b/syncplay/protocols.py index 096f19d..1df4f02 100644 --- a/syncplay/protocols.py +++ b/syncplay/protocols.py @@ -80,10 +80,11 @@ class SyncClientProtocol(JSONCommandProtocol): version = hello["version"] if hello.has_key("version") else None version = hello["realversion"] if hello.has_key("realversion") else version # Used for 1.2.X compatibility motd = hello["motd"] if hello.has_key("motd") else None - return username, roomName, version, motd + features = hello["features"] if hello.has_key("features") else None + return username, roomName, version, motd, features def handleHello(self, hello): - username, roomName, version, motd = self._extractHelloArguments(hello) + username, roomName, version, motd, featureList = self._extractHelloArguments(hello) if not username or not roomName or not version: self.dropWithError(getMessage("hello-server-error").format(hello)) else: @@ -95,7 +96,7 @@ class SyncClientProtocol(JSONCommandProtocol): self._client.ui.showMessage(getMessage("connected-successful-notification")) self._client.connected() self._client.sendFile() - self._client.setServerVersion(version) + self._client.setServerVersion(version, featureList) def sendHello(self): hello = {} @@ -370,6 +371,7 @@ class SyncServerProtocol(JSONCommandProtocol): hello["version"] = clientVersion # Used so 1.2.X client works on newer server hello["realversion"] = syncplay.version hello["motd"] = self._factory.getMotd(userIp, username, room, clientVersion) + hello["features"] = self._factory.getFeatures() self.sendMessage({"Hello": hello}) @requireLogged diff --git a/syncplay/server.py b/syncplay/server.py index 397dd41..90c811a 100644 --- a/syncplay/server.py +++ b/syncplay/server.py @@ -15,6 +15,7 @@ from syncplay.utils import RoomPasswordProvider, NotControlledRoom, RandomString class SyncFactory(Factory): def __init__(self, password='', motdFilePath=None, isolateRooms=False, salt=None, disableReady=False,chat =False): + self.isolateRooms = isolateRooms print getMessage("welcome-server-notification").format(syncplay.version) if password: password = hashlib.md5(password).hexdigest() @@ -41,6 +42,14 @@ class SyncFactory(Factory): setBy = room.getSetBy() watcher.sendState(position, paused, doSeek, setBy, forcedUpdate) + def getFeatures(self): + features = dict() + features["isolateRooms"] = self.isolateRooms + features["readiness"] = not self.disableReady + features["managedRooms"] = True + features["chat"] = self.chat + return features + def getMotd(self, userIp, username, room, clientVersion): oldClient = False if constants.WARN_OLD_CLIENTS: diff --git a/syncplay/ui/consoleUI.py b/syncplay/ui/consoleUI.py index 7cf6dbe..d5af043 100644 --- a/syncplay/ui/consoleUI.py +++ b/syncplay/ui/consoleUI.py @@ -86,6 +86,9 @@ class ConsoleUI(threading.Thread): def fileSwitchFoundFiles(self): pass + def setFeatures(self, featureList): + pass + def showMessage(self, message, noTimestamp=False): message = message.encode(sys.stdout.encoding, 'replace') if noTimestamp: diff --git a/syncplay/ui/gui.py b/syncplay/ui/gui.py index 40eb494..447ab4c 100644 --- a/syncplay/ui/gui.py +++ b/syncplay/ui/gui.py @@ -325,6 +325,14 @@ class MainWindow(QtGui.QMainWindow): # TODO: Prompt user return None + def setFeatures(self, featureList): + if not featureList["readiness"]: + self.readyPushButton.setEnabled(False) + if not featureList["chat"]: + self.chatFrame.setEnabled(False) + if not featureList["sharedPlaylists"]: + self.playlistGroup.setEnabled(False) + def showMessage(self, message, noTimestamp=False): message = unicode(message) message = message.replace(u"&", u"&").replace(u'"', u""").replace(u"<", u"<").replace(">", u">")