From 665956b84cf349662596a5293fb547adb22bc0f1 Mon Sep 17 00:00:00 2001 From: Et0h Date: Mon, 26 Dec 2016 11:29:12 +0000 Subject: [PATCH] Add maximum character limits to user-definable elements which appear in GUI/OSD to keep everything on screen --- buildPy2exe.py | 2 +- syncplay/client.py | 1 + syncplay/constants.py | 6 ++++++ syncplay/server.py | 10 +++++++++- syncplay/ui/GuiConfiguration.py | 3 +++ syncplay/ui/gui.py | 2 ++ syncplay/utils.py | 17 +++++++++++++++++ 7 files changed, 39 insertions(+), 2 deletions(-) diff --git a/buildPy2exe.py b/buildPy2exe.py index 5682c77..20e671b 100644 --- a/buildPy2exe.py +++ b/buildPy2exe.py @@ -685,7 +685,7 @@ info = dict( options={'py2exe': { 'dist_dir': OUT_DIR, 'packages': 'PySide.QtUiTools', - 'includes': 'twisted, sys, encodings, datetime, os, time, math, PySide, liburl, ast', + 'includes': 'twisted, sys, encodings, datetime, os, time, math, PySide, liburl, ast, unicodedata', 'excludes': 'venv, _ssl, doctest, pdb, unittest, win32clipboard, win32file, win32pdh, win32security, win32trace, win32ui, winxpgui, win32pipe, win32process, Tkinter', 'dll_excludes': 'msvcr71.dll, MSVCP90.dll, POWRPROF.dll', 'optimize': 2, diff --git a/syncplay/client.py b/syncplay/client.py index 932686c..28a6b7c 100644 --- a/syncplay/client.py +++ b/syncplay/client.py @@ -588,6 +588,7 @@ class SyncplayClient(object): def sendChat(self,message): if self._protocol and self._protocol.logged: + message = utils.truncateText(message,constants.MAX_CHAT_MESSAGE_LENGTH) self._protocol.sendChatMessage(message) def sendRoom(self): diff --git a/syncplay/constants.py b/syncplay/constants.py index f941d2e..c9191ec 100644 --- a/syncplay/constants.py +++ b/syncplay/constants.py @@ -56,6 +56,12 @@ PLAYLIST_MAX_CHARACTERS = 10000 PLAYLIST_MAX_ITEMS = 250 VLC_LISTEN_FOR_STDOUT = False # Changing to True this could break VLC 3 on Windows +# Maximum character lengths (for client and server) +MAX_CHAT_MESSAGE_LENGTH = 50 # Number of displayed characters +MAX_USERNAME_LENGTH = 12 # Number of displayed characters +MAX_ROOM_NAME_LENGTH = 35 # Number of displayed characters +MAX_FILENAME_LENGTH = 250 # Number of displayed characters + # Options for the File Switch feature: FOLDER_SEARCH_FIRST_FILE_TIMEOUT = 15.0 # Secs - How long to wait to find the first file in folder search (to take account of HDD spin up) FOLDER_SEARCH_TIMEOUT = 6.0 # Secs - How long to wait until searches in folder to update cache are aborted (after first file is found) diff --git a/syncplay/server.py b/syncplay/server.py index a6f9d70..399325a 100644 --- a/syncplay/server.py +++ b/syncplay/server.py @@ -11,7 +11,7 @@ import codecs import os from string import Template import argparse -from syncplay.utils import RoomPasswordProvider, NotControlledRoom, RandomStringGenerator, meetsMinVersion, playlistIsValid +from syncplay.utils import RoomPasswordProvider, NotControlledRoom, RandomStringGenerator, meetsMinVersion, playlistIsValid, truncateText class SyncFactory(Factory): def __init__(self, password='', motdFilePath=None, isolateRooms=False, salt=None, disableReady=False,disableChat=False): @@ -72,11 +72,13 @@ class SyncFactory(Factory): return "" def addWatcher(self, watcherProtocol, username, roomName): + roomName = truncateText(roomName, constants.MAX_ROOM_NAME_LENGTH) username = self._roomManager.findFreeUsername(username) watcher = Watcher(self, watcherProtocol, username) self.setWatcherRoom(watcher, roomName, asJoin=True) def setWatcherRoom(self, watcher, roomName, asJoin=False): + roomName = truncateText(roomName, constants.MAX_ROOM_NAME_LENGTH) self._roomManager.moveWatcher(watcher, roomName) if asJoin: self.sendJoinMessage(watcher) @@ -145,6 +147,7 @@ class SyncFactory(Factory): self._roomManager.broadcastRoom(watcher, lambda w: w.sendControlledRoomAuthStatus(False, watcher.getName(), room._name)) def sendChat(self,watcher,message): + message = truncateText(message, constants.MAX_CHAT_MESSAGE_LENGTH) messageDict={"message":message,"username" : watcher.getName()} self._roomManager.broadcastRoom(watcher, lambda w: w.sendChatMessage(messageDict)) @@ -192,6 +195,7 @@ class RoomManager(object): return watchers def moveWatcher(self, watcher, roomName): + roomName = truncateText(roomName, constants.MAX_ROOM_NAME_LENGTH) self.removeWatcher(watcher) room = self._getRoom(roomName) room.addWatcher(watcher) @@ -218,6 +222,7 @@ class RoomManager(object): del self._rooms[room.getName()] def findFreeUsername(self, username): + username = truncateText(username,constants.MAX_USERNAME_LENGTH) allnames = [] for room in self._rooms.itervalues(): for watcher in room.getWatchers(): @@ -392,6 +397,9 @@ class Watcher(object): reactor.callLater(0.1, self._scheduleSendState) def setFile(self, file_): + print file_ + if file_ and file_.has_key("name"): + file_["name"] = truncateText(file_["name"],constants.MAX_FILENAME_LENGTH) self._file = file_ self._server.sendFileUpdate(self) diff --git a/syncplay/ui/GuiConfiguration.py b/syncplay/ui/GuiConfiguration.py index 7de7295..5d6c77b 100644 --- a/syncplay/ui/GuiConfiguration.py +++ b/syncplay/ui/GuiConfiguration.py @@ -542,6 +542,9 @@ class ConfigDialog(QtGui.QDialog): self.defaultroomLabel.setObjectName("room") self.defaultroomTextbox.setObjectName("room") + self.usernameTextbox.setMaxLength(constants.MAX_USERNAME_LENGTH) + self.defaultroomTextbox.setMaxLength(constants.MAX_ROOM_NAME_LENGTH) + self.connectionSettingsLayout = QtGui.QGridLayout() self.connectionSettingsLayout.addWidget(self.hostLabel, 0, 0) self.connectionSettingsLayout.addWidget(self.hostCombobox, 0, 1) diff --git a/syncplay/ui/gui.py b/syncplay/ui/gui.py index a7523d3..b5475f2 100644 --- a/syncplay/ui/gui.py +++ b/syncplay/ui/gui.py @@ -1058,6 +1058,7 @@ class MainWindow(QtGui.QMainWindow): window.outputlabel = QtGui.QLabel(getMessage("notifications-heading-label")) window.chatInput = QtGui.QLineEdit() + window.chatInput.setMaxLength(constants.MAX_CHAT_MESSAGE_LENGTH) window.chatInput.returnPressed.connect(self.sendChatMessage) window.chatButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'email_go.png'), getMessage("sendmessage-label")) @@ -1112,6 +1113,7 @@ class MainWindow(QtGui.QMainWindow): window.listLayout.addWidget(window.listSplit) window.roomInput = QtGui.QLineEdit() + window.roomInput.setMaxLength(constants.MAX_ROOM_NAME_LENGTH) window.roomInput.returnPressed.connect(self.joinRoom) window.roomButton = QtGui.QPushButton(QtGui.QIcon(self.resourcespath + 'door_in.png'), getMessage("joinroom-label")) diff --git a/syncplay/utils.py b/syncplay/utils.py index 9eafe82..a7eedac 100644 --- a/syncplay/utils.py +++ b/syncplay/utils.py @@ -11,6 +11,7 @@ import random import string import urllib import ast +import unicodedata folderSearchEnabled = True @@ -160,6 +161,22 @@ def blackholeStdoutForFrozenWindow(): sys.stdout = Blackhole() del Blackhole +def truncateText(unicodeText, maxLength): + try: + unicodeText = unicodedata.normalize('NFC', unicodeText) + except: + pass + try: + maxSaneLength= maxLength*5 + if len(unicodeText) > maxSaneLength: + unicodeText = unicode(unicodeText.encode("utf-8")[:maxSaneLength], "utf-8", errors="ignore") + while len(unicodeText) > maxLength: + unicodeText = unicode(unicodeText.encode("utf-8")[:-1], "utf-8", errors="ignore") + return unicodeText + except: + pass + return "" + # Relate to file hashing / difference checking: def stripfilename(filename, stripURL):