diff --git a/syncplay/__init__.py b/syncplay/__init__.py index 829690e..9104651 100644 --- a/syncplay/__init__.py +++ b/syncplay/__init__.py @@ -1,3 +1,3 @@ -version = '1.1.9' +version = '1.2.0' milestone = 'Tequila' projectURL = 'http://uriziel.github.com/syncplay/' \ No newline at end of file diff --git a/syncplay/client.py b/syncplay/client.py index f2b4b83..db7ab5b 100644 --- a/syncplay/client.py +++ b/syncplay/client.py @@ -49,7 +49,7 @@ class SyncplayClient(object): def __init__(self, playerClass, ui, args): self.protocolFactory = SyncClientFactory(self) self.ui = UiManager(self, ui) - self.userlist = SyncplayUserlist(self.ui) + self.userlist = SyncplayUserlist(self.ui, self) if(args.room == None or args.room == ''): args.room = 'default' self.defaultRoom = args.room @@ -266,6 +266,10 @@ class SyncplayClient(object): def getRoom(self): return self.userlist.currentUser.room + def getUserList(self): + if(self._protocol and self._protocol.logged): + self._protocol.sendList() + def getPassword(self): return self._serverPassword @@ -302,11 +306,12 @@ class SyncplayClient(object): self.ui.promptFor("Press enter to exit\n") class SyncplayUser(object): - def __init__(self, username = None, room = None, file_ = None): + def __init__(self, username = None, room = None, file_ = None, position = 0): self.username = username self.room = room self.file = file_ - + self.lastPosition = position + def setFile(self, filename, duration, size): file_ = { "name": filename, @@ -327,10 +332,11 @@ class SyncplayUser(object): return self.username < other.username class SyncplayUserlist(object): - def __init__(self, ui): + def __init__(self, ui, client): self.currentUser = SyncplayUser() self._users = {} - self.ui = ui + self.ui = ui + self._client = client def __showUserChangeMessage(self, username, room, file_): if (room and not file_): @@ -355,10 +361,10 @@ class SyncplayUserlist(object): message = "Your file differs in the following way(s): " + ", ".join(differences) self.ui.showMessage(message) - def addUser(self, username, room, file_, noMessage = False): + def addUser(self, username, room, file_, position = 0, noMessage = False): if(username == self.currentUser.username): return - user = SyncplayUser(username, room, file_) + user = SyncplayUser(username, room, file_, position) self._users[username] = user if(not noMessage): self.__showUserChangeMessage(username, room, file_) @@ -387,7 +393,11 @@ class SyncplayUserlist(object): self.addUser(username, room, file_) def __addUserWithFileToList(self, rooms, user): - file_key = '\'{}\' ({})'.format(user.file['name'], self.ui.formatTime(user.file['duration'])) + if(self.currentUser.username == user.username): + currentPosition = self.ui.formatTime(self._client.getGlobalPosition()) + else: + currentPosition = self.ui.formatTime(user.lastPosition) + file_key = '\'{}\' ({}/{})'.format(user.file['name'], currentPosition, self.ui.formatTime(user.file['duration'])) if (not rooms[user.room].has_key(file_key)): rooms[user.room][file_key] = {} rooms[user.room][file_key][user.username] = user @@ -407,7 +417,10 @@ class SyncplayUserlist(object): self.__addUserWithFileToList(rooms, user) else: self.__addUserWithoutFileToList(rooms, user) - self.__addUserWithFileToList(rooms, self.currentUser) + if(self.currentUser.file): + self.__addUserWithFileToList(rooms, self.currentUser) + else: + self.__addUserWithoutFileToList(rooms, self.currentUser) return rooms def __addDifferentFileMessageIfNecessary(self, user, message): diff --git a/syncplay/protocols.py b/syncplay/protocols.py index 1920c3f..704a5e1 100644 --- a/syncplay/protocols.py +++ b/syncplay/protocols.py @@ -143,8 +143,9 @@ class SyncClientProtocol(JSONCommandProtocol): roomName = room[0] for user in room[1].iteritems(): userName = user[0] - file_ = user[1] if user[1] <> {} else None - self._client.userlist.addUser(userName, roomName, file_, noMessage=True) + file_ = user[1]['file'] if user[1]['file'] <> {} else None + position = user[1]['position'] + self._client.userlist.addUser(userName, roomName, file_, position, noMessage=True) self._client.userlist.showUserList() def sendList(self): @@ -314,16 +315,20 @@ class SyncServerProtocol(JSONCommandProtocol): user[username]["event"] = event self.sendSet({"user": user}) - def _addUserOnList(self, userlist, watcher): + def _addUserOnList(self, userlist, roomPositions, watcher): if (not userlist.has_key(watcher.room)): userlist[watcher.room] = {} - userlist[watcher.room][watcher.name] = watcher.file if watcher.file else {} - + roomPositions[watcher.room] = watcher.getRoomPosition() + userlist[watcher.room][watcher.name] = { + "file": watcher.file if watcher.file else {}, + "position": roomPositions[watcher.room] if roomPositions[watcher.room] else 0 + } def sendList(self): userlist = {} + roomPositions = {} watchers = self._factory.getAllWatchers(self) for watcher in watchers.itervalues(): - self._addUserOnList(userlist, watcher) + self._addUserOnList(userlist, roomPositions, watcher) self.sendMessage({"List": userlist}) @requireLogged diff --git a/syncplay/server.py b/syncplay/server.py index cbed09c..9a49a6c 100644 --- a/syncplay/server.py +++ b/syncplay/server.py @@ -74,16 +74,20 @@ class SyncFactory(Factory): self._rooms.pop(room) self._roomStates.pop(room) + def getRoomPausedAndPosition(self, room): + position = self._roomStates[room]["position"] + paused = self._roomStates[room]["paused"] + if (not paused): + timePassedSinceSet = time.time() - self._roomStates[room]["lastUpdate"] + position += timePassedSinceSet + return paused, position + def sendState(self, watcherProtocol, doSeek = False, senderLatency = 0, forcedUpdate = False): watcher = self.getWatcher(watcherProtocol) if(not watcher): return room = watcher.room - position = self._roomStates[room]["position"] - paused = self._roomStates[room]["paused"] - if(not paused): - timePassedSinceSet = time.time() - self._roomStates[room]["lastUpdate"] - position += timePassedSinceSet + paused, position = self.getRoomPausedAndPosition(room) setBy = self._roomStates[room]["setBy"] watcher.paused = paused watcher.position = position @@ -219,6 +223,10 @@ class Watcher(object): else: return self.position < b.position + def getRoomPosition(self): + _, position = self.factory.getRoomPausedAndPosition(self.room) + return position + def scheduleSendState(self, when=1): self._sendStateTimer = task.LoopingCall(self.sendState) self._sendStateTimer.start(when, True) @@ -234,4 +242,4 @@ class Watcher(object): def deactivate(self): if(self._sendStateTimer): self._sendStateTimer.stop() - \ No newline at end of file + diff --git a/syncplay/ui/consoleUI.py b/syncplay/ui/consoleUI.py index fde8c3d..7ddd26d 100644 --- a/syncplay/ui/consoleUI.py +++ b/syncplay/ui/consoleUI.py @@ -79,7 +79,7 @@ class ConsoleUI(threading.Thread): self._syncplayClient.setPosition(self._syncplayClient.playerPositionBeforeLastSeek) self._syncplayClient.playerPositionBeforeLastSeek = tmp_pos elif data == "l": - self._syncplayClient.userlist.showUserList() + self._syncplayClient.getUserList() elif data == "p": self._syncplayClient.setPaused(not self._syncplayClient.getPlayerPaused()) elif data == 'help':