Merge branch 'master' of git://github.com/Uriziel/syncplay
This commit is contained in:
commit
bbee87932a
@ -1,3 +1,3 @@
|
||||
version = '1.2.7'
|
||||
milestone = 'Biscuit'
|
||||
version = '1.2.8'
|
||||
milestone = 'Hammer'
|
||||
projectURL = 'http://syncplay.pl/'
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
#coding:utf8
|
||||
import hashlib
|
||||
import os.path
|
||||
import time
|
||||
@ -9,8 +8,9 @@ from syncplay.protocols import SyncClientProtocol
|
||||
from syncplay import utils, constants
|
||||
from syncplay.messages import getMessage
|
||||
import threading
|
||||
from syncplay.constants import PRIVACY_SENDHASHED_MODE, PRIVACY_DONTSEND_MODE,\
|
||||
from syncplay.constants import PRIVACY_SENDHASHED_MODE, PRIVACY_DONTSEND_MODE, \
|
||||
PRIVACY_HIDDENFILENAME, FILENAME_STRIP_REGEX
|
||||
import collections
|
||||
# <MAL DISABLE>
|
||||
libMal = None
|
||||
'''try:
|
||||
@ -19,8 +19,9 @@ except ImportError:
|
||||
libMal = None
|
||||
'''
|
||||
# </MAL DISABLE>
|
||||
|
||||
class SyncClientFactory(ClientFactory):
|
||||
def __init__(self, client, retry = constants.RECONNECT_RETRIES):
|
||||
def __init__(self, client, retry=constants.RECONNECT_RETRIES):
|
||||
self._client = client
|
||||
self.retry = retry
|
||||
self._timesTried = 0
|
||||
@ -42,7 +43,7 @@ class SyncClientFactory(ClientFactory):
|
||||
self._timesTried += 1
|
||||
self._client.ui.showMessage(getMessage("en", "reconnection-attempt-notification"))
|
||||
self.reconnecting = True
|
||||
reactor.callLater(0.1*(2**self._timesTried), connector.connect)
|
||||
reactor.callLater(0.1 * (2 ** self._timesTried), connector.connect)
|
||||
else:
|
||||
message = getMessage("en", "disconnection-notification")
|
||||
self._client.ui.showErrorMessage(message)
|
||||
@ -68,7 +69,7 @@ class SyncplayClient(object):
|
||||
self._player = None
|
||||
self.givenmalprivacywarning = False
|
||||
if(config['room'] == None or config['room'] == ''):
|
||||
config['room'] = config['name'] # ticket #58
|
||||
config['room'] = config['name'] # ticket #58
|
||||
self.defaultRoom = config['room']
|
||||
self.playerPositionBeforeLastSeek = 0.0
|
||||
self.setUsername(config['name'])
|
||||
@ -302,7 +303,7 @@ class SyncplayClient(object):
|
||||
return
|
||||
try:
|
||||
size = os.path.getsize(path)
|
||||
except OSError: #file not accessible (stream?)
|
||||
except OSError: # file not accessible (stream?)
|
||||
size = 0
|
||||
rawfilename = filename
|
||||
filename, size = self.__executePrivacySettings(filename, size)
|
||||
@ -382,7 +383,7 @@ class SyncplayClient(object):
|
||||
reactor.connectTCP(host, port, self.protocolFactory)
|
||||
reactor.run()
|
||||
|
||||
def stop(self, promptForAction = False):
|
||||
def stop(self, promptForAction=False):
|
||||
if not self._running:
|
||||
return
|
||||
self._running = False
|
||||
@ -434,7 +435,7 @@ class SyncplayClient(object):
|
||||
|
||||
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._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
|
||||
@ -443,7 +444,7 @@ class SyncplayClient(object):
|
||||
|
||||
|
||||
class SyncplayUser(object):
|
||||
def __init__(self, username = None, room = None, file_ = None, position = 0):
|
||||
def __init__(self, username=None, room=None, file_=None, position=0):
|
||||
self.username = username
|
||||
self.room = room
|
||||
self.file = file_
|
||||
@ -466,8 +467,13 @@ class SyncplayUser(object):
|
||||
return sameName and sameSize and sameDuration
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.username < other.username
|
||||
return self.username.lower() < other.username.lower()
|
||||
|
||||
def __repr__(self, *args, **kwargs):
|
||||
if(self.file):
|
||||
return "{}: {} ({}, {})".format(self.username, self.file['name'], self.file['duration'], self.file['size'])
|
||||
else:
|
||||
return "{}".format(self.username)
|
||||
|
||||
class MalUpdater(object):
|
||||
def __init__(self, username, password, ui):
|
||||
@ -509,7 +515,7 @@ class MalUpdater(object):
|
||||
if(len(results) > 0):
|
||||
result = results[0]
|
||||
message = "Updating MAL with: \"{}\", episode: {}".format(result.mainTitle, result.episodeBeingWatched)
|
||||
reactor.callFromThread(self._ui.showMessage,(message),)
|
||||
reactor.callFromThread(self._ui.showMessage, (message),)
|
||||
options = {"tags": ["syncplay"]}
|
||||
manager.updateEntryOnMal(result, options)
|
||||
self._filename = "" # Make sure no updates will be performed until switch
|
||||
@ -550,7 +556,7 @@ class SyncplayUserlist(object):
|
||||
message = getMessage("en", "file-differences-notification") + ", ".join(differences)
|
||||
self.ui.showMessage(message)
|
||||
|
||||
def addUser(self, username, room, file_, position = 0, noMessage = False):
|
||||
def addUser(self, username, room, file_, position=0, noMessage=False):
|
||||
if(username == self.currentUser.username):
|
||||
self.currentUser.lastPosition = position
|
||||
return
|
||||
@ -623,29 +629,35 @@ class SyncplayUserlist(object):
|
||||
if(self.currentUser.room not in rooms):
|
||||
rooms[self.currentUser.room] = []
|
||||
rooms[self.currentUser.room].append(self.currentUser)
|
||||
|
||||
rooms = self.sortList(rooms)
|
||||
self.ui.showUserList(self.currentUser, rooms)
|
||||
|
||||
def clearList(self):
|
||||
self._users = {}
|
||||
|
||||
def sortList(self, rooms):
|
||||
for room in rooms:
|
||||
rooms[room] = sorted(rooms[room])
|
||||
rooms = collections.OrderedDict(sorted(rooms.items(), key=lambda s: s[0].lower()))
|
||||
return rooms
|
||||
|
||||
class UiManager(object):
|
||||
def __init__(self, client, ui):
|
||||
self._client = client
|
||||
self.__ui = ui
|
||||
|
||||
def showMessage(self, message, noPlayer = False, noTimestamp = False):
|
||||
def showMessage(self, message, noPlayer=False, noTimestamp=False):
|
||||
if(not noPlayer): self.showOSDMessage(message)
|
||||
self.__ui.showMessage(message, noTimestamp)
|
||||
|
||||
def showUserList(self, currentUser, rooms):
|
||||
self.__ui.showUserList(currentUser, rooms)
|
||||
|
||||
def showOSDMessage(self, message, duration = constants.OSD_DURATION):
|
||||
def showOSDMessage(self, message, duration=constants.OSD_DURATION):
|
||||
if(self._client._player):
|
||||
self._client._player.displayMessage(message, duration * 1000)
|
||||
|
||||
def showErrorMessage(self, message, criticalerror = False):
|
||||
def showErrorMessage(self, message, criticalerror=False):
|
||||
self.__ui.showErrorMessage(message, criticalerror)
|
||||
|
||||
def promptFor(self, prompt):
|
||||
|
||||
@ -8,6 +8,8 @@ UI_TIME_FORMAT = "[%X] "
|
||||
CONFIG_NAMES = [".syncplay", "syncplay.ini"] #Syncplay searches first to last
|
||||
DEFAULT_CONFIG_NAME_WINDOWS = "syncplay.ini"
|
||||
DEFAULT_CONFIG_NAME_LINUX = ".syncplay"
|
||||
RECENT_CLIENT_THRESHOLD = "1.2.7" #This and higher considered 'recent' clients (no warnings)
|
||||
WARN_OLD_CLIENTS = True #Use MOTD to inform old clients to upgrade
|
||||
|
||||
#Changing these might be ok
|
||||
REWIND_THRESHOLD = 4
|
||||
|
||||
@ -163,6 +163,9 @@ en = {
|
||||
|
||||
"help-tooltip" : "Opens the Syncplay.pl user guide.",
|
||||
|
||||
# Server messages to client
|
||||
"new-syncplay-available-motd-message" : "<NOTICE> You are using Syncplay {} but a newer version is available from http://syncplay.pl </NOTICE>", #ClientVersion
|
||||
|
||||
# Server notifications
|
||||
"welcome-server-notification" : "Welcome to Syncplay server, ver. {0}", #version
|
||||
"client-connected-room-server-notification" : "{0}({2}) connected to room '{1}'", #username, host, room
|
||||
|
||||
@ -291,9 +291,9 @@ class SyncServerProtocol(JSONCommandProtocol):
|
||||
return
|
||||
self._factory.addWatcher(self, username, roomName, roomPassword)
|
||||
self._logged = True
|
||||
self.sendHello()
|
||||
self.sendHello(version)
|
||||
|
||||
def sendHello(self):
|
||||
def sendHello(self, clientVersion):
|
||||
hello = {}
|
||||
username = self._factory.watcherGetUsername(self)
|
||||
hello["username"] = username
|
||||
@ -301,7 +301,7 @@ class SyncServerProtocol(JSONCommandProtocol):
|
||||
room = self._factory.watcherGetRoom(self)
|
||||
if(room): hello["room"] = {"name": room}
|
||||
hello["version"] = syncplay.version
|
||||
hello["motd"] = self._factory.getMotd(userIp, username, room)
|
||||
hello["motd"] = self._factory.getMotd(userIp, username, room, clientVersion)
|
||||
self.sendMessage({"Hello": hello})
|
||||
|
||||
@requireLogged
|
||||
|
||||
@ -136,15 +136,24 @@ class SyncFactory(Factory):
|
||||
position += timePassedSinceSet
|
||||
return paused, position
|
||||
|
||||
def getMotd(self, userIp, username, room):
|
||||
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("en","new-syncplay-available-motd-message").format(clientVersion)
|
||||
motd = "{}\n{}".format(motdwarning, motd)
|
||||
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")
|
||||
elif oldClient:
|
||||
return getMessage("en", "new-syncplay-available-motd-message").format(clientVersion)
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
from syncplay.ui.gui import MainWindow as GraphicalUI
|
||||
try:
|
||||
from syncplay.ui.gui import MainWindow as GraphicalUI
|
||||
except ImportError:
|
||||
pass
|
||||
from syncplay.ui.consoleUI import ConsoleUI
|
||||
|
||||
def getUi(graphical=True):
|
||||
|
||||
@ -211,7 +211,7 @@ class MainWindow(QtGui.QMainWindow):
|
||||
t = self._syncplayClient.getUserOffset() + sign * t
|
||||
self._syncplayClient.setUserOffset(t)
|
||||
else:
|
||||
self.showMessage("Invalid offset value", True)
|
||||
self.showErrorMessage("Invalid offset value")
|
||||
|
||||
def openUserGuide(self):
|
||||
if sys.platform.startswith('linux'):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user