def __init__(self, client, playerPath, filePath, args): from twisted.internet import reactor self.reactor = reactor self._client = client self._paused = None self._duration = None self._filename = None self._filepath = None try: self._listener = self.__Listener(self, playerPath, filePath, args) except ValueError: self._client.ui.showMessage(getMessage("en", "mplayer-file-required-notification")) self._client.ui.showMessage(getMessage("en", "mplayer-file-required-notification/example")) self.reactor.callFromThread(self._client.stop, (True),) return self._listener.setDaemon(True) self._listener.start() self._durationAsk = threading.Event() self._filenameAsk = threading.Event() self._pathAsk = threading.Event() self._positionAsk = threading.Event() self._pausedAsk = threading.Event() self._preparePlayer()
def __init__(self, client, playerPath, filePath, args): self._client = client self._paused = None self._duration = None self._filename = None self._filepath = None self._filechanged = False self._durationAsk = threading.Event() self._filenameAsk = threading.Event() self._pathAsk = threading.Event() self._positionAsk = threading.Event() self._pausedAsk = threading.Event() self._vlcready = threading.Event() try: self._listener = self.__Listener(self, playerPath, filePath, args, self._vlcready) except ValueError: self._client.ui.showMessage(getMessage("en", "vlc-failed-connection")) self._client.stop(True) return self._listener.setDaemon(True) self._listener.start() if(not self._vlcready.wait(constants.VLC_OPEN_MAX_WAIT_TIME)): self._vlcready.set() self._client.ui.showMessage(getMessage("en", "vlc-failed-connection")) self._client.stop(True) self._client.initPlayer(self)
def lineReceived(self, line): if "Error parsing option" in line: self.quitReason = getMessage("mpv-version-error") match = self.RE_ANSWER.match(line) if not match: return name, value =[m for m in match.groups() if m] name = name.lower() if name == self.POSITION_QUERY: self._position = float(value) self._positionAsk.set() elif name == "pause": self._paused = bool(value == 'yes') self._pausedAsk.set() elif name == "length": self._duration = float(value) self._durationAsk.set() elif name == "path": self._filepath = value self._pathAsk.set() elif name == "filename": self._filename = value.decode('utf-8') self._filenameAsk.set() elif name == "exiting": if value != 'Quit': if self.quitReason == None: self.quitReason = getMessage("media-player-error").format(value) self.reactor.callFromThread(self._client.ui.showErrorMessage, self.quitReason, True) self.drop()
def __showUserChangeMessage(self, username, room, file_, oldRoom=None): if(room): if self.isRoomSame(room) or self.isRoomSame(oldRoom): showOnOSD = constants.SHOW_SAME_ROOM_OSD else: showOnOSD = constants.SHOW_DIFFERENT_ROOM_OSD hideFromOSD = not showOnOSD if(room and not file_): message = getMessage("en", "room-join-notification").format(username, room) self.ui.showMessage(message, hideFromOSD) elif (room and file_): duration = utils.formatTime(file_['duration']) message = getMessage("en", "playing-notification").format(username, file_['name'], duration) if(self.currentUser.room <> room or self.currentUser.username == username): message += getMessage("en", "playing-notification/room-addendum").format(room) self.ui.showMessage(message, hideFromOSD) if(self.currentUser.file and not self.currentUser.isFileSame(file_) and self.currentUser.room == room): message = getMessage("en", "file-different-notification").format(username) self.ui.showMessage(message, not constants.SHOW_OSD_WARNINGS) differences = [] differentName = not utils.sameFilename(self.currentUser.file['name'], file_['name']) differentSize = not utils.sameFilesize(self.currentUser.file['size'], file_['size']) differentDuration = not utils.sameFileduration(self.currentUser.file['duration'], file_['duration']) if(differentName): differences.append("filename") if(differentSize): differences.append("size") if(differentDuration): differences.append("duration") message = getMessage("en", "file-differences-notification") + ", ".join(differences) self.ui.showMessage(message, not constants.SHOW_OSD_WARNINGS)
def getMotd(self, userIp, username, room, clientVersion): oldClient = False if constants.WARN_OLD_CLIENTS: if not meetsMinVersion(clientVersion, constants.RECENT_CLIENT_THRESHOLD): oldClient = True if self._motdFilePath and os.path.isfile(self._motdFilePath): tmpl = codecs.open(self._motdFilePath, "r", "utf-8-sig").read() args = dict(version=syncplay.version, userIp=userIp, username=username, room=room) try: motd = Template(tmpl).substitute(args) if oldClient: motdwarning = getMessage( "new-syncplay-available-motd-message").format( clientVersion) motd = "{}\n{}".format(motdwarning, motd) return motd if len( motd ) < constants.SERVER_MAX_TEMPLATE_LENGTH else getMessage( "server-messed-up-motd-too-long").format( constants.SERVER_MAX_TEMPLATE_LENGTH, len(motd)) except ValueError: return getMessage( "server-messed-up-motd-unescaped-placeholders") elif oldClient: return getMessage("new-syncplay-available-motd-message").format( clientVersion) else: return ""
def addMiscBox(self, window): window.miscGroup = QtGui.QGroupBox(getMessage("othercommands-heading-label")) window.unseekButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'arrow_undo.png'),getMessage("undoseek-guibuttonlabel")) window.unseekButton.pressed.connect(self.undoSeek) self.unseekButton.setToolTip(getMessage("undoseek-tooltip")) window.miscLayout = QtGui.QHBoxLayout() window.miscLayout.addWidget(window.unseekButton) if constants.MERGE_PLAYPAUSE_BUTTONS == True: window.playpauseButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'control_pause_blue.png'),getMessage("togglepause-guibuttonlabel")) window.playpauseButton.pressed.connect(self.togglePause) window.miscLayout.addWidget(window.playpauseButton) self.playpauseButton.setToolTip(getMessage("togglepause-tooltip")) else: window.playButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'control_play_blue.png'),getMessage("play-guibuttonlabel")) window.playButton.pressed.connect(self.play) window.playButton.setMaximumWidth(60) window.miscLayout.addWidget(window.playButton) window.pauseButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'control_pause_blue.png'),getMessage("pause-guibuttonlabel")) window.pauseButton.pressed.connect(self.pause) window.pauseButton.setMaximumWidth(60) window.miscLayout.addWidget(window.pauseButton) self.playButton.setToolTip(getMessage("play-tooltip")) self.pauseButton.setToolTip(getMessage("pause-tooltip")) window.miscGroup.setLayout(window.miscLayout) window.miscGroup.setFixedSize(window.miscGroup.sizeHint())
def __init__(self, client, playerPath, filePath, args): from twisted.internet import reactor self.reactor = reactor self._client = client self._paused = None self._duration = None self._filename = None self._filepath = None self._filechanged = False self._durationAsk = threading.Event() self._filenameAsk = threading.Event() self._pathAsk = threading.Event() self._positionAsk = threading.Event() self._pausedAsk = threading.Event() self._vlcready = threading.Event() self._vlcclosed = threading.Event() try: self._listener = self.__Listener(self, playerPath, filePath, args, self._vlcready, self._vlcclosed) except ValueError: self._client.ui.showErrorMessage(getMessage("en", "vlc-failed-connection"), True) self.reactor.callFromThread(self._client.stop, (True),) return self._listener.setDaemon(True) self._listener.start() if(not self._vlcready.wait(constants.VLC_OPEN_MAX_WAIT_TIME)): self._vlcready.set() self._client.ui.showErrorMessage(getMessage("en", "vlc-failed-connection"), True) self.reactor.callFromThread(self._client.stop, (True),) self.reactor.callFromThread(self._client.initPlayer, (self),)
def __init__(self, client, playerPath, filePath, args): from twisted.internet import reactor self.reactor = reactor self._client = client self._paused = None self._duration = None self._filename = None self._filepath = None try: self._listener = self.__Listener(self, playerPath, filePath, args) except ValueError: self._client.ui.showMessage( getMessage("en", "mplayer-file-required-notification")) self._client.ui.showMessage( getMessage("en", "mplayer-file-required-notification/example")) self.reactor.callFromThread( self._client.stop, (True), ) return self._listener.setDaemon(True) self._listener.start() self._durationAsk = threading.Event() self._filenameAsk = threading.Event() self._pathAsk = threading.Event() self._positionAsk = threading.Event() self._pausedAsk = threading.Event() self._preparePlayer()
def _prepareArgParser(self): self._argparser = argparse.ArgumentParser(description=getMessage("en", "server-argument-description"), epilog=getMessage("en", "server-argument-epilog")) 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=getMessage("en", "server-password-argument")) self._argparser.add_argument('--isolate-rooms', action='store_true', help=getMessage("en", "server-isolate-room-argument")) self._argparser.add_argument('--motd-file', metavar='file', type=str, nargs='?', help=getMessage("en", "server-motd-argument"))
def addPlaybackLayout(self, window): window.playbackFrame = QtGui.QFrame() window.playbackFrame.setVisible(False) window.playbackFrame.setContentsMargins(0,0,0,0) window.playbackLayout = QtGui.QHBoxLayout() window.playbackLayout.setAlignment(Qt.AlignLeft) window.playbackLayout.setContentsMargins(0,0,0,0) window.playbackFrame.setLayout(window.playbackLayout) window.seekInput = QtGui.QLineEdit() window.seekInput.returnPressed.connect(self.seekFromButton) window.seekButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'clock_go.png'), "") window.seekButton.setToolTip(getMessage("seektime-menu-label")) window.seekButton.pressed.connect(self.seekFromButton) window.seekInput.setText("0:00") window.seekInput.setFixedWidth(60) window.playbackLayout.addWidget(window.seekInput) window.playbackLayout.addWidget(window.seekButton) window.unseekButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'arrow_undo.png'), "") window.unseekButton.setToolTip(getMessage("undoseek-menu-label")) window.unseekButton.pressed.connect(self.undoSeek) window.miscLayout = QtGui.QHBoxLayout() window.playbackLayout.addWidget(window.unseekButton) window.playButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'control_play_blue.png'), "") window.playButton.setToolTip(getMessage("play-menu-label")) window.playButton.pressed.connect(self.play) window.playbackLayout.addWidget(window.playButton) window.pauseButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'control_pause_blue.png'), "") window.pauseButton.setToolTip(getMessage("pause-menu-label")) window.pauseButton.pressed.connect(self.pause) window.playbackLayout.addWidget(window.pauseButton) window.playbackFrame.setMaximumHeight(window.playbackFrame.sizeHint().height()) window.playbackFrame.setMaximumWidth(window.playbackFrame.sizeHint().width()) window.outputLayout.addWidget(window.playbackFrame)
def getMotd(self, userIp, username, room, clientVersion): oldClient = False if constants.WARN_OLD_CLIENTS: if int(clientVersion.replace(".", "")) < int(constants.RECENT_CLIENT_THRESHOLD.replace(".", "")): oldClient = True if self._motdFilePath and os.path.isfile(self._motdFilePath): tmpl = codecs.open(self._motdFilePath, "r", "utf-8-sig").read() args = dict(version=syncplay.version, userIp=userIp, username=username, room=room) try: motd = Template(tmpl).substitute(args) if oldClient: motdwarning = getMessage("new-syncplay-available-motd-message").format(clientVersion) motd = "{}\n{}".format(motdwarning, motd) return ( motd if len(motd) < constants.SERVER_MAX_TEMPLATE_LENGTH else getMessage("server-messed-up-motd-too-long").format( constants.SERVER_MAX_TEMPLATE_LENGTH, len(motd) ) ) except ValueError: return getMessage("server-messed-up-motd-unescaped-placeholders") elif oldClient: return getMessage("new-syncplay-available-motd-message").format(clientVersion) else: return ""
def __showUserChangeMessage(self, username, room, file_): if(room and not file_): message = getMessage("en", "room-join-notification").format(username, room) self.ui.showMessage(message) elif (room and file_): duration = utils.formatTime(file_['duration']) message = getMessage("en", "playing-notification").format(username, file_['name'], duration) if(self.currentUser.room <> room or self.currentUser.username == username): message += getMessage("en", "playing-notification/room-addendum").format(room) self.ui.showMessage(message) if(self.currentUser.file and not self.currentUser.isFileSame(file_) and self.currentUser.room == room): message = getMessage("en", "file-different-notification").format(username) self.ui.showMessage(message) differences = [] differentName = not utils.sameFilename(self.currentUser.file['name'], file_['name']) differentSize = not utils.sameFilesize(self.currentUser.file['size'], file_['size']) differentDuration = not utils.sameFileduration(self.currentUser.file['duration'], file_['duration']) if(differentName): differences.append("filename") if(differentSize): differences.append("size") if(differentDuration): differences.append("duration") message = getMessage("en", "file-differences-notification") + ", ".join(differences) self.ui.showMessage(message)
def __init__(self, client, playerPath, filePath, args): from twisted.internet import reactor self.reactor = reactor self._client = client self._paused = None self._position = 0.0 self._duration = None self._filename = None self._filepath = None self.quitReason = None self.lastLoadedTime = None self.fileLoaded = False self.delayedFilePath = None try: self._listener = self.__Listener(self, playerPath, filePath, args) except ValueError: self._client.ui.showMessage(getMessage("mplayer-file-required-notification")) self._client.ui.showMessage(getMessage("mplayer-file-required-notification/example")) self.drop() return self._listener.setDaemon(True) self._listener.start() self._durationAsk = threading.Event() self._filenameAsk = threading.Event() self._pathAsk = threading.Event() self._positionAsk = threading.Event() self._pausedAsk = threading.Event() self._preparePlayer()
def _create_listener(self, playerPath, filePath, args): try: self._listener = self.__Listener(self, self._playerIPCHandler, playerPath, filePath, args) except ValueError: self._client.ui.showMessage( getMessage("mplayer-file-required-notification")) self._client.ui.showMessage( getMessage("mplayer-file-required-notification/example")) self.drop() return except AttributeError as e: self._client.ui.showErrorMessage("Could not load mpv: " + str(e)) return self._listener.setDaemon(True) self._listener.start() self._durationAsk = threading.Event() self._filenameAsk = threading.Event() self._pathAsk = threading.Event() self._positionAsk = threading.Event() self._pausedAsk = threading.Event() self._preparePlayer()
def __init__(self, client, playerPath, filePath, args): from twisted.internet import reactor self.reactor = reactor self._client = client self._paused = None self._duration = None self._filename = None self._filepath = None self._filechanged = False self._lastVLCPositionUpdate = None self.shownVLCLatencyError = False self._previousPreviousPosition = -2 self._previousPosition = -1 self._position = 0 try: # Hack to fix locale issue without importing locale library self.radixChar = "{:n}".format(1.5)[1:2] if self.radixChar == "" or self.radixChar == "1" or self.radixChar == "5": raise ValueError except: self._client.ui.showErrorMessage( "Failed to determine locale. As a fallback Syncplay is using the following radix character: \".\"." ) self.radixChar = "." self._durationAsk = threading.Event() self._filenameAsk = threading.Event() self._pathAsk = threading.Event() self._positionAsk = threading.Event() self._pausedAsk = threading.Event() self._vlcready = threading.Event() self._vlcclosed = threading.Event() self._listener = None try: self._listener = self.__Listener(self, playerPath, filePath, args, self._vlcready, self._vlcclosed) except ValueError: self._client.ui.showErrorMessage( getMessage("vlc-failed-connection"), True) self.reactor.callFromThread( self._client.stop, True, ) return try: self._listener.setDaemon(True) self._listener.start() if not self._vlcready.wait(constants.VLC_OPEN_MAX_WAIT_TIME): self._vlcready.set() self._client.ui.showErrorMessage( getMessage("vlc-failed-connection"), True) self.reactor.callFromThread( self._client.stop, True, ) self.reactor.callFromThread( self._client.initPlayer, self, ) except: pass
def notMplayer2(self): print getMessage("en", "mplayer2-required") self._listener.sendLine('quit') self.reactor.callFromThread( self._client.stop, (True), )
def __showUserChangeMessage(self, username, room, file_): if(room and not file_): message = getMessage("en", "room-join-notification").format(username, room) self.ui.showMessage(message) elif (room and file_): duration = utils.formatTime(file_['duration']) message = getMessage("en", "playing-notification").format(username, file_['name'], duration) if(self.currentUser.room <> room or self.currentUser.username == username): message += getMessage("en", "playing-notification/room-addendum").format(room) self.ui.showMessage(message) if(self.currentUser.file and not self.currentUser.isFileSame(file_) and self.currentUser.room == room): message = getMessage("en", "file-different-notification").format(username) self.ui.showMessage(message) differences = [] differentName = not utils.sameFilename(self.currentUser.file['name'], file_['name']) differentSize = not utils.sameFilesize(self.currentUser.file['size'], file_['size']) differentDuration = not utils.sameFileduration(self.currentUser.file['duration'], file_['duration']) if(differentName): differences.append("filename") if(differentSize): differences.append("size") if(differentDuration): differences.append("duration") message = getMessage("en", "file-differences-notification") + ", ".join(differences) self.ui.showMessage(message)
def __init__(self, port='', password='', motdFilePath=None, isolateRooms=False, salt=None, disableReady=False, disableChat=False, maxChatMessageLength=constants.MAX_CHAT_MESSAGE_LENGTH, maxUsernameLength=constants.MAX_USERNAME_LENGTH, statsDbFile=None): self.isolateRooms = isolateRooms print(getMessage("welcome-server-notification").format(syncplay.version)) self.port = port if password: password = password.encode('utf-8') password = hashlib.md5(password).hexdigest() self.password = password if salt is None: salt = RandomStringGenerator.generate_server_salt() print(getMessage("no-salt-notification").format(salt)) self._salt = salt self._motdFilePath = motdFilePath self.disableReady = disableReady self.disableChat = disableChat self.maxChatMessageLength = maxChatMessageLength if maxChatMessageLength is not None else constants.MAX_CHAT_MESSAGE_LENGTH self.maxUsernameLength = maxUsernameLength if maxUsernameLength is not None else constants.MAX_USERNAME_LENGTH if not isolateRooms: self._roomManager = RoomManager() else: self._roomManager = PublicRoomManager() if statsDbFile is not None: self._statsDbHandle = DBManager(statsDbFile) self._statsRecorder = StatsRecorder(self._statsDbHandle, self._roomManager) statsDelay = 5*(int(self.port)%10 + 1) self._statsRecorder.startRecorder(statsDelay) else: self._statsDbHandle = None
def mpvVersionErrorCheck(self, line): if "Error parsing option" in line or "Error parsing commandline option" in line: self.quitReason = getMessage("mpv-version-error") elif "Could not open pipe at '/dev/stdin'" in line: self.reactor.callFromThread(self._client.ui.showErrorMessage, getMessage("mpv-version-error"), True) self.drop()
def __init__(self, client, playerPath, filePath, args): from twisted.internet import reactor self.reactor = reactor self._client = client self._paused = None self._position = 0.0 self._duration = None self._filename = None self._filepath = None self.quitReason = None self.lastLoadedTime = None self.fileLoaded = False self.delayedFilePath = None try: self._listener = self.__Listener(self, playerPath, filePath, args) except ValueError: self._client.ui.showMessage(getMessage("mplayer-file-required-notification")) self._client.ui.showMessage(getMessage("mplayer-file-required-notification/example")) self.drop() return self._listener.setDaemon(True) self._listener.start() self._durationAsk = threading.Event() self._filenameAsk = threading.Event() self._pathAsk = threading.Event() self._positionAsk = threading.Event() self._pausedAsk = threading.Event() self._preparePlayer()
def __init__(self, port='', password='', motdFilePath=None, roomsDbFile=None, permanentRoomsFile=None, isolateRooms=False, salt=None, disableReady=False, disableChat=False, maxChatMessageLength=constants.MAX_CHAT_MESSAGE_LENGTH, maxUsernameLength=constants.MAX_USERNAME_LENGTH, statsDbFile=None, tlsCertPath=None): self.isolateRooms = isolateRooms syncplay.messages.setLanguage(syncplay.messages.getInitialLanguage()) print( getMessage("welcome-server-notification").format(syncplay.version)) self.port = port if password: password = password.encode('utf-8') password = hashlib.md5(password).hexdigest() self.password = password if salt is None: salt = RandomStringGenerator.generate_server_salt() print(getMessage("no-salt-notification").format(salt)) self._salt = salt self._motdFilePath = motdFilePath self.roomsDbFile = roomsDbFile self.disableReady = disableReady self.disableChat = disableChat self.maxChatMessageLength = maxChatMessageLength if maxChatMessageLength is not None else constants.MAX_CHAT_MESSAGE_LENGTH self.maxUsernameLength = maxUsernameLength if maxUsernameLength is not None else constants.MAX_USERNAME_LENGTH self.permanentRoomsFile = permanentRoomsFile if permanentRoomsFile is not None and os.path.isfile( permanentRoomsFile) else None self.permanentRooms = self.loadListFromMultilineTextFile( self.permanentRoomsFile ) if self.permanentRoomsFile is not None else [] if not isolateRooms: self._roomManager = RoomManager(self.roomsDbFile, self.permanentRooms) else: self._roomManager = PublicRoomManager() if statsDbFile is not None: self._statsDbHandle = StatsDBManager(statsDbFile) self._statsRecorder = StatsRecorder(self._statsDbHandle, self._roomManager) statsDelay = 5 * (int(self.port) % 10 + 1) self._statsRecorder.startRecorder(statsDelay) else: self._statsDbHandle = None if tlsCertPath is not None: self.certPath = tlsCertPath self._TLSattempts = 0 self._allowTLSconnections(self.certPath) else: self.certPath = None self.options = None self.serverAcceptsTLS = False
def _promptForMissingArguments(self, error=None): if (self._config['noGui']): print getMessage("en", "missing-arguments-error") sys.exit() elif (GuiConfiguration): gc = GuiConfiguration(self._config, error=error) gc.setAvailablePaths(self._playerFactory.getAvailablePlayerPaths()) gc.run() return gc.getProcessedConfiguration()
def displayIP(determineIP): print "---------------------------" displayLocalIPs() print "---------------------------" if determineIP: displayNetworkIP() else: print getMessage("no-ip-notification") print "---------------------------"
def _prepareArgParser(self): self._argparser = argparse.ArgumentParser(description=getMessage("server-argument-description"), epilog=getMessage("server-argument-epilog")) self._argparser.add_argument('--port', metavar='port', type=str, nargs='?', help=getMessage("server-port-argument")) self._argparser.add_argument('--password', metavar='password', type=str, nargs='?', help=getMessage("server-password-argument")) self._argparser.add_argument('--isolate-rooms', action='store_true', help=getMessage("server-isolate-room-argument")) self._argparser.add_argument('--disable-ready', action='store_true', help=getMessage("server-disable-ready-argument")) self._argparser.add_argument('--salt', metavar='salt', type=str, nargs='?', help=getMessage("server-salt-argument")) self._argparser.add_argument('--motd-file', metavar='file', type=str, nargs='?', help=getMessage("server-motd-argument"))
def __init__(self, password='', motdFilePath=None): print getMessage("en", "welcome-server-notification").format(syncplay.version) if(password): password = hashlib.md5(password).hexdigest() self.password = password self._motdFilePath = motdFilePath self._rooms = {} self._roomStates = {} self._roomUpdate = threading.RLock()
def _promptForMissingArguments(self): if(self._config['noGui']): print getMessage("en", "missing-arguments-error") sys.exit() elif(GuiConfiguration): gc = GuiConfiguration(self._config) gc.setAvailablePaths(self._playerFactory.getAvailablePlayerPaths()) gc.run() return gc.getProcessedConfiguration()
def _checkPassword(self, serverPassword): if self._factory.password: if not serverPassword: self.dropWithError(getMessage("password-required-server-error")) return False if serverPassword != self._factory.password: self.dropWithError(getMessage("wrong-password-server-error")) return False return True
def clientConnectionLost(self, connector, reason): if self._timesTried < self.retry: self._timesTried += 1 self._client.ui.showMessage(getMessage("en", "reconnection-attempt-notification")) self.reconnecting = True reactor.callLater(0.1*(2**self._timesTried), connector.connect) else: message = getMessage("en", "disconnection-notification") self._client.ui.showErrorMessage(message)
def _checkPassword(self, serverPassword): if self._factory.password: if not serverPassword: self.dropWithError(getMessage("password-required-server-error")) return False if serverPassword != self._factory.password: self.dropWithError(getMessage("wrong-password-server-error")) return False return True
def showUserList(self, currentUser, rooms): self._usertreebuffer = QtGui.QStandardItemModel() self._usertreebuffer.setColumnCount(2) self._usertreebuffer.setHorizontalHeaderLabels((getMessage("roomuser-heading-label"),getMessage("fileplayed-heading-label"))) usertreeRoot = self._usertreebuffer.invisibleRootItem() for room in rooms: roomitem = QtGui.QStandardItem(room) if room == currentUser.room: font = QtGui.QFont() font.setWeight(QtGui.QFont.Bold) roomitem.setFont(font) blankitem = QtGui.QStandardItem("") roomitem.setFlags(roomitem.flags() & ~Qt.ItemIsEditable) blankitem.setFlags(blankitem.flags() & ~Qt.ItemIsEditable) usertreeRoot.appendRow((roomitem, blankitem)) for user in rooms[room]: useritem = QtGui.QStandardItem(user.username) fileitem = QtGui.QStandardItem("") if user.file: fileitem = QtGui.QStandardItem(u"{} ({})".format(user.file['name'], formatTime(user.file['duration']))) if currentUser.file: sameName = sameFilename(user.file['name'], currentUser.file['name']) sameSize = sameFilesize(user.file['size'], currentUser.file['size']) sameDuration = sameFileduration(user.file['duration'], currentUser.file['duration']) sameRoom = room == currentUser.room differentName = not sameName differentSize = not sameSize differentDuration = not sameDuration if sameName or sameRoom: if differentSize and sameDuration: fileitem = QtGui.QStandardItem(u"{} ({}) ({})".format(user.file['name'], formatTime(user.file['duration']), getMessage("differentsize-note"))) elif differentSize and differentDuration: fileitem = QtGui.QStandardItem(u"{} ({}) ({})".format(user.file['name'], formatTime(user.file['duration']), getMessage("differentsizeandduration-note"))) elif differentDuration: fileitem = QtGui.QStandardItem(u"{} ({}) ({})".format(user.file['name'], formatTime(user.file['duration']), getMessage("differentduration-note"))) if sameRoom and (differentName or differentSize or differentDuration): fileitem.setForeground(QtGui.QBrush(QtGui.QColor(constants.STYLE_DIFFERENTITEM_COLOR))) else: fileitem = QtGui.QStandardItem(getMessage("nofile-note")) if room == currentUser.room: fileitem.setForeground(QtGui.QBrush(QtGui.QColor(constants.STYLE_NOFILEITEM_COLOR))) if currentUser.username == user.username: font = QtGui.QFont() font.setWeight(QtGui.QFont.Bold) useritem.setFont(font) useritem.setFlags(useritem.flags() & ~Qt.ItemIsEditable) fileitem.setFlags(fileitem.flags() & ~Qt.ItemIsEditable) roomitem.appendRow((useritem, fileitem)) self.listTreeModel = self._usertreebuffer self.listTreeView.setModel(self.listTreeModel) self.listTreeView.setItemsExpandable(False) self.listTreeView.expandAll() self.listTreeView.resizeColumnToContents(0) self.listTreeView.resizeColumnToContents(1)
def mpvErrorCheck(self, line): if "Error parsing option" in line or "Error parsing commandline option" in line: self.quitReason = getMessage("mpv-version-error") elif "Could not open pipe at '/dev/stdin'" in line: self.reactor.callFromThread(self._client.ui.showErrorMessage, getMessage("mpv-version-error"), True) self.drop() if constants and any(errormsg in line for errormsg in constants.MPV_ERROR_MESSAGES_TO_REPEAT): self._client.ui.showErrorMessage(line)
def displayNetworkIP(): import socket try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("syncplay.pl",80)) print getMessage("network-ip-notification") print(s.getsockname()[0]) s.close() except: print getMessage("connection-error-notification")
def initWhenConnected(self): try: self._client.ui.showErrorMessage(getMessage("vlc-initial-warning")) if not self._vlcready.wait(constants.VLC_OPEN_MAX_WAIT_TIME): self._vlcready.set() self._client.ui.showErrorMessage(getMessage("vlc-failed-connection"), True) self.reactor.callFromThread(self._client.stop, True,) self.reactor.callFromThread(self._client.initPlayer, self,) except: pass
def mpvErrorCheck(self, line): if "Error parsing option" in line or "Error parsing commandline option" in line: self.quitReason = getMessage("mpv-version-error") elif "Could not open pipe at '/dev/stdin'" in line: self.reactor.callFromThread(self._client.ui.showErrorMessage, getMessage("mpv-version-error"), True) self.drop() if constants and any(errormsg in line for errormsg in constants.MPV_ERROR_MESSAGES_TO_REPEAT): self._client.ui.showErrorMessage(line)
def __init__(self, password="", motdFilePath=None, isolateRooms=False): print getMessage("welcome-server-notification").format(syncplay.version) if password: password = hashlib.md5(password).hexdigest() self.password = password self._motdFilePath = motdFilePath if not isolateRooms: self._roomManager = RoomManager() else: self._roomManager = PublicRoomManager()
def lineReceived(self, line): match, name, value = self.RE_ANSWER.match(line), "", "" if match: name, value = match.group("command"), match.group("argument") if line == "filepath-change-notification": self._filechanged = True t = threading.Thread(target=self._onFileUpdate) t.setDaemon(True) t.start() elif name == "filepath" and value != "no-input": self._filechanged = True if "file://" in value: value = value.replace("file://", "") if not os.path.isfile(value): value = value.lstrip("/") self._filepath = value self._pathAsk.set() elif name == "duration" and (value != "no-input"): self._duration = float(value.replace(",", ".")) self._durationAsk.set() elif name == "playstate": self._paused = ( bool(value != "playing") if (value != "no-input" and self._filechanged == False) else self._client.getGlobalPaused() ) self._pausedAsk.set() elif name == "position": self._position = ( float(value.replace(",", ".")) if (value != "no-input" and self._filechanged == False) else self._client.getGlobalPosition() ) self._positionAsk.set() elif name == "filename": self._filechanged = True self._filename = value.decode("utf-8") self._filenameAsk.set() elif line.startswith("interface-version: "): interface_version = line[19:24] if int(interface_version.replace(".", "")) < int(constants.VLC_INTERFACE_MIN_VERSION.replace(".", "")): self._client.ui.showErrorMessage( getMessage("en", "vlc-interface-version-mismatch").format( str(interface_version), str(constants.VLC_INTERFACE_MIN_VERSION) ) ) elif line[:16] == "VLC media player": vlc_version = line[17:22] if int(vlc_version.replace(".", "")) < int(constants.VLC_MIN_VERSION.replace(".", "")): self._client.ui.showErrorMessage( getMessage("en", "vlc-version-mismatch").format(str(vlc_version), str(constants.VLC_MIN_VERSION)) ) self._vlcready.set() self._listener.sendLine("get-interface-version")
def _prepareArgParser(self): self._argparser = argparse.ArgumentParser(description=getMessage("server-argument-description"), epilog=getMessage("server-argument-epilog")) self._argparser.add_argument('--port', metavar='port', type=str, nargs='?', help=getMessage("server-port-argument")) self._argparser.add_argument('--password', metavar='password', type=str, nargs='?', help=getMessage("server-password-argument")) self._argparser.add_argument('--isolate-rooms', action='store_true', help=getMessage("server-isolate-room-argument")) self._argparser.add_argument('--disable-ready', action='store_true', help=getMessage("server-disable-ready-argument")) self._argparser.add_argument('--disable-chat', action='store_true', help=getMessage("server-chat-argument")) self._argparser.add_argument('--salt', metavar='salt', type=str, nargs='?', help=getMessage("server-salt-argument")) self._argparser.add_argument('--motd-file', metavar='file', type=str, nargs='?', help=getMessage("server-motd-argument")) self._argparser.add_argument('--max-chat-message-length', metavar='maxChatMessageLength', type=int, nargs='?',help=getMessage("server-chat-maxchars-argument").format(constants.MAX_CHAT_MESSAGE_LENGTH))
def _serverPaused(self, setBy): hideFromOSD = not constants.SHOW_SAME_ROOM_OSD if constants.SYNC_ON_PAUSE: self.setPosition(self.getGlobalPosition()) self._player.setPaused(True) madeChangeOnPlayer = True if (self.lastLeftTime < time.time() - constants.OSD_DURATION) or (hideFromOSD == True): self.ui.showMessage(getMessage("pause-notification").format(setBy), hideFromOSD) else: self.ui.showMessage(getMessage("left-paused-notification").format(self.lastLeftUser, setBy), hideFromOSD) return madeChangeOnPlayer
def _slowDownToCoverTimeDifference(self, diff, setBy): if(constants.SLOWDOWN_KICKIN_THRESHOLD < diff and not self._speedChanged): self._player.setSpeed(constants.SLOWDOWN_RATE) self._speedChanged = True self.ui.showMessage(getMessage("en", "slowdown-notification").format(setBy)) elif(self._speedChanged and diff < constants.SLOWDOWN_RESET_THRESHOLD): self._player.setSpeed(1.00) self._speedChanged = False self.ui.showMessage(getMessage("en", "revert-notification")) madeChangeOnPlayer = True return madeChangeOnPlayer
def clientConnectionLost(self, connector, reason): if self._timesTried == 0: self._client.onDisconnect() if self._timesTried < self.retry: self._timesTried += 1 self._client.ui.showMessage(getMessage("en", "reconnection-attempt-notification")) self.reconnecting = True reactor.callLater(0.1*(2**self._timesTried), connector.connect) else: message = getMessage("en", "disconnection-notification") self._client.ui.showErrorMessage(message)
def mpvVersionErrorCheck(self, line): if "Error parsing option" in line or "Error parsing commandline option" in line: self.quitReason = getMessage("mpv-version-error") elif "Could not open pipe at '/dev/stdin'" in line: self.reactor.callFromThread(self._client.ui.showErrorMessage, getMessage("mpv-version-error"), True) self.drop() elif "[ytdl_hook] Your version of youtube-dl is too old" in line: self._client.ui.showErrorMessage(line)
def getMotd(self, userIp, username, room): if(self._motdFilePath and os.path.isfile(self._motdFilePath)): tmpl = codecs.open(self._motdFilePath, "r", "utf-8-sig").read() args = dict(version=syncplay.version, userIp=userIp, username=username, room=room) try: motd = Template(tmpl).substitute(args) return motd if len(motd) < constants.SERVER_MAX_TEMPLATE_LENGTH else getMessage("en", "server-messed-up-motd-too-long").format(constants.SERVER_MAX_TEMPLATE_LENGTH, len(motd)) except ValueError: return getMessage("en", "server-messed-up-motd-unescaped-placeholders") else: return ""
def _promptForMissingArguments(self, error=None): if self._config['noGui'] or not GuiConfiguration: if error: print "{}!".format(error) print getMessage("missing-arguments-error") sys.exit() elif GuiConfiguration: gc = GuiConfiguration(self._config, error=error) gc.setAvailablePaths(self._playerFactory.getAvailablePlayerPaths()) gc.run() return gc.getProcessedConfiguration()
def _slowDownToCoverTimeDifference(self, diff, setBy): if(constants.SLOWDOWN_KICKIN_THRESHOLD < diff and not self._speedChanged): self._player.setSpeed(constants.SLOWDOWN_RATE) self._speedChanged = True self.ui.showMessage(getMessage("en", "slowdown-notification").format(setBy)) elif(self._speedChanged and diff < constants.SLOWDOWN_RESET_THRESHOLD): self._player.setSpeed(1.00) self._speedChanged = False self.ui.showMessage(getMessage("en", "revert-notification")) madeChangeOnPlayer = True return madeChangeOnPlayer
def _promptForMissingArguments(self, error=None): if self._config['noGui'] or not GuiConfiguration: if error: print "{}!".format(error) print getMessage("missing-arguments-error") sys.exit() elif GuiConfiguration: gc = GuiConfiguration(self._config, error=error) gc.setAvailablePaths(self._playerFactory.getAvailablePlayerPaths()) gc.run() return gc.getProcessedConfiguration()
def _slowDownToCoverTimeDifference(self, diff, setBy): hideFromOSD = not constants.SHOW_SLOWDOWN_OSD if self._config['slowdownThreshold'] < diff and not self._speedChanged: self._player.setSpeed(constants.SLOWDOWN_RATE) self._speedChanged = True self.ui.showMessage(getMessage("slowdown-notification").format(setBy), hideFromOSD) elif self._speedChanged and diff < constants.SLOWDOWN_RESET_THRESHOLD: self._player.setSpeed(1.00) self._speedChanged = False self.ui.showMessage(getMessage("revert-notification"), hideFromOSD) madeChangeOnPlayer = True return madeChangeOnPlayer
def handleHello(self, hello): username, serverPassword, roomName, roomPassword, version = self._extractHelloArguments(hello) if not username or not roomName or not version: self.dropWithError(getMessage("hello-server-error")) elif version.split(".")[0:2] != syncplay.version.split(".")[0:2]: self.dropWithError(getMessage("version-mismatch-server-error")) else: if not self._checkPassword(serverPassword): return self._factory.addWatcher(self, username, roomName, roomPassword) self._logged = True self.sendHello(version)
def connectionMade(self): self._client.initProtocol(self) if self._client._clientSupportsTLS: if self._client._serverSupportsTLS: self.sendTLS({"startTLS": "send"}) self._client.ui.showMessage(getMessage("startTLS-initiated")) else: self._client.ui.showErrorMessage(getMessage("startTLS-not-supported-server")) self.sendHello() else: self._client.ui.showMessage(getMessage("startTLS-not-supported-client")) self.sendHello()
def removeWatcher(self, watcherProtocol): watcher = self.getWatcher(watcherProtocol) if(not watcher): return l = lambda w: w.sendUserSetting(watcher.name, watcher.room, None, {"left": True}) self.broadcast(watcherProtocol, l) self._removeWatcherFromTheRoom(watcherProtocol) watcher.deactivate() self._deleteRoomIfEmpty(watcher.room) print getMessage("en", "client-left-server-notification").format(watcher.name) if(self.ircVerbose): self.ircBot.sp_left(watcher.name, watcher.room)
def connectionMade(self): self._client.initProtocol(self) if self._client._clientSupportsTLS: if self._client._serverSupportsTLS: self.sendTLS({"startTLS": "send"}) self._client.ui.showMessage(getMessage("startTLS-initiated")) else: self._client.ui.showErrorMessage(getMessage("startTLS-not-supported-server")) self.sendHello() else: self._client.ui.showMessage(getMessage("startTLS-not-supported-client")) self.sendHello()
def _prepareArgParser(self): self._argparser = argparse.ArgumentParser( description=getMessage("server-argument-description"), epilog=getMessage("server-argument-epilog")) self._argparser.add_argument('--port', metavar='port', type=str, nargs='?', help=getMessage("server-port-argument")) self._argparser.add_argument('--password', metavar='password', type=str, nargs='?', help=getMessage("server-password-argument"), default=os.environ.get('SYNCPLAY_PASSWORD')) self._argparser.add_argument('--isolate-rooms', action='store_true', help=getMessage("server-isolate-room-argument")) self._argparser.add_argument('--disable-ready', action='store_true', help=getMessage("server-disable-ready-argument")) self._argparser.add_argument('--disable-chat', action='store_true', help=getMessage("server-chat-argument")) self._argparser.add_argument('--salt', metavar='salt', type=str, nargs='?', help=getMessage("server-salt-argument"), default=os.environ.get('SYNCPLAY_SALT')) self._argparser.add_argument('--motd-file', metavar='file', type=str, nargs='?', help=getMessage("server-motd-argument")) self._argparser.add_argument('--max-chat-message-length', metavar='maxChatMessageLength', type=int, nargs='?', help=getMessage("server-chat-maxchars-argument").format(constants.MAX_CHAT_MESSAGE_LENGTH)) self._argparser.add_argument('--max-username-length', metavar='maxUsernameLength', type=int, nargs='?', help=getMessage("server-maxusernamelength-argument").format(constants.MAX_USERNAME_LENGTH)) self._argparser.add_argument('--stats-db-file', metavar='file', type=str, nargs='?', help=getMessage("server-stats-db-file-argument"))
def handleHello(self, hello): username, serverPassword, roomName, roomPassword, version = self._extractHelloArguments( hello) if (not username or not roomName or not version): self.dropWithError(getMessage("en", "hello-server-error")) elif (version.split(".")[0:2] != syncplay.version.split(".")[0:2]): self.dropWithError( getMessage("en", "version-mismatch-server-error")) else: if (not self._checkPassword(serverPassword)): return self._factory.addWatcher(self, username, roomName, roomPassword) self._logged = True self.sendHello()
def handleHello(self, hello): username, roomName, version, motd = self._extractHelloArguments(hello) if not username or not roomName or not version: self.dropWithError(getMessage("hello-server-error").format(hello)) else: self._client.setUsername(username) self._client.setRoom(roomName) self.logged = True if motd: self._client.ui.showMessage(motd, True, True) self._client.ui.showMessage(getMessage("connected-successful-notification")) self._client.connected() self._client.sendFile() self._client.setServerVersion(version)
def __init__(self, password='', motdFilePath=None, isolateRooms=False, salt=None, disableReady=False): print getMessage("welcome-server-notification").format(syncplay.version) if password: password = hashlib.md5(password).hexdigest() self.password = password if salt is None: salt = RandomStringGenerator.generate_server_salt() print getMessage("no-salt-notification").format(salt) self._salt = salt self._motdFilePath = motdFilePath self.disableReady = disableReady if not isolateRooms: self._roomManager = RoomManager() else: self._roomManager = PublicRoomManager()
def connectionLost(self, reason): try: if "Invalid DNS-ID" in str(reason.value): self._client._serverSupportsTLS = False elif "tlsv1 alert protocol version" in str(reason.value): self._client._clientSupportsTLS = False elif "certificate verify failed" in str(reason.value): self.dropWithError( getMessage("startTLS-server-certificate-invalid")) elif "mismatched_id=DNS_ID" in str(reason.value): self.dropWithError( getMessage("startTLS-server-certificate-invalid-DNS-ID")) except: pass self._client.destroyProtocol()
def getCalculatedPosition(self): if self.fileLoaded == False: self._client.ui.showDebugMessage( "File not loaded so using GlobalPosition for getCalculatedPosition({})" .format(self._client.getGlobalPosition())) return self._client.getGlobalPosition() if self.lastMPVPositionUpdate is None: self._client.ui.showDebugMessage( "MPV not updated position so using GlobalPosition for getCalculatedPosition ({})" .format(self._client.getGlobalPosition())) return self._client.getGlobalPosition() if self._recentlyReset(): self._client.ui.showDebugMessage( "Recently reset so using self.position for getCalculatedPosition ({})" .format(self._position)) return self._position diff = time.time() - self.lastMPVPositionUpdate if diff > constants.MPV_UNRESPONSIVE_THRESHOLD: self.reactor.callFromThread( self._client.ui.showErrorMessage, getMessage("mpv-unresponsive-error").format(int(diff)), True) self.drop() if diff > constants.PLAYER_ASK_DELAY and not self._paused: self._client.ui.showDebugMessage( "mpv did not response in time, so assuming position is {} ({}+{})" .format(self._position + diff, self._position, diff)) return self._position + diff else: return self._position
def __displayMessageOnOSD(self, warningName): if (constants.OSD_WARNING_MESSAGE_DURATION > self._warnings[warningName]["displayedFor"]): self._ui.showOSDMessage(getMessage("en", warningName ), constants.WARNING_OSD_MESSAGES_LOOP_INTERVAL) self._warnings[warningName]["displayedFor"] += constants.WARNING_OSD_MESSAGES_LOOP_INTERVAL else: self._warnings[warningName]["displayedFor"] = 0 self._warnings[warningName]["timer"].stop()
def getListOfPublicServers(): try: import urllib.request, urllib.parse, urllib.error, syncplay, sys params = urllib.parse.urlencode({'version': syncplay.version, 'milestone': syncplay.milestone, 'release_number': syncplay.release_number, 'language': syncplay.messages.messages["CURRENT"]}) if isMacOS(): import requests response = requests.get(constants.SYNCPLAY_PUBLIC_SERVER_LIST_URL.format(params)) response = response.text else: f = urllib.request.urlopen(constants.SYNCPLAY_PUBLIC_SERVER_LIST_URL.format(params)) response = f.read() response = response.decode('utf-8') response = response.replace("<p>", "").replace("</p>", "").replace("<br />", "").replace("“", "'").replace("”", "'").replace(":’", "'").replace("’", "'").replace("′", "'").replace("\n", "").replace("\r", "") # Fix Wordpress response = ast.literal_eval(response) if response: return response else: raise IOError except: if constants.DEBUG_MODE == True: traceback.print_exc() raise else: raise IOError(getMessage("failed-to-load-server-list-error"))
def getListOfPublicServers(): try: import urllib, syncplay, sys, messages, json params = urllib.urlencode({ 'version': syncplay.version, 'milestone': syncplay.milestone, 'release_number': syncplay.release_number, 'language': messages.messages["CURRENT"] }) f = urllib.urlopen( constants.SYNCPLAY_PUBLIC_SERVER_LIST_URL.format(params)) response = f.read() response = response.replace("<p>", "").replace("</p>", "").replace( "<br />", "").replace("“", "'").replace("”", "'").replace( ":’", "'").replace("’", "'").replace("′", "'").replace( "\n", "").replace("\r", "") # Fix Wordpress response = ast.literal_eval(response) if response: return response else: raise IOError except: raise IOError(getMessage("failed-to-load-server-list-error"))
def handshakeCompleted(self): self._serverCertificateTLS = self.transport.getPeerCertificate() self._subjectTLS = self._serverCertificateTLS.get_subject().CN self._issuerTLS = self._serverCertificateTLS.get_issuer().CN self._expiredTLS = self._serverCertificateTLS.has_expired() self._expireDateTLS = datetime.strptime( self._serverCertificateTLS.get_notAfter().decode('ascii'), '%Y%m%d%H%M%SZ') self._encryptedConnectionTLS = self.transport.protocol._tlsConnection self._connVersionNumberTLS = self._encryptedConnectionTLS.get_protocol_version( ) self._connVersionStringTLS = self._encryptedConnectionTLS.get_protocol_version_name( ) self._cipherNameTLS = self._encryptedConnectionTLS.get_cipher_name() if self._connVersionNumberTLS == 771: self._connVersionNumberTLS = '1.2' elif self._connVersionNumberTLS == 772: self._connVersionNumberTLS = '1.3' self._client.ui.showMessage( getMessage("startTLS-secure-connection-ok").format( self._connVersionStringTLS)) self._client.ui.setSSLMode( True, { 'subject': self._subjectTLS, 'issuer': self._issuerTLS, 'expires': self._expireDateTLS, 'protocolString': self._connVersionStringTLS, 'protocolVersion': self._connVersionNumberTLS, 'cipher': self._cipherNameTLS }) self.sendHello()