Move FileSwitchManager to Client and use in PlaylistManager

This commit is contained in:
Et0h 2016-01-31 15:11:01 +00:00
parent 5016e9d102
commit 42817b9087
2 changed files with 151 additions and 174 deletions

View File

@ -5,8 +5,9 @@ import re
import sys
import ast
import random
import threading
from twisted.internet.protocol import ClientFactory
from twisted.internet import reactor, task, defer
from twisted.internet import reactor, task, defer, threads
from functools import wraps
from copy import deepcopy
from syncplay.protocols import SyncClientProtocol
@ -119,7 +120,9 @@ class SyncplayClient(object):
self.__playerReady = defer.Deferred()
self._warnings = self._WarningManager(self._player, self.userlist, self.ui, self)
self.fileSwitch = FileSwitchManager(self)
self.playlist = SyncplayPlaylist(self)
if constants.LIST_RELATIVE_CONFIGS and self._config.has_key('loadedRelativePaths') and self._config['loadedRelativePaths']:
paths = "; ".join(self._config['loadedRelativePaths'])
self.ui.showMessage(getMessage("relative-config-notification").format(paths), noPlayer=True, noTimestamp=True)
@ -460,16 +463,6 @@ class SyncplayClient(object):
self.sendFile()
self.playlist.changeToPlaylistIndexFromFilename(filename)
def findFilenameInDirectories(self, filename):
# TODO: Replace this with the code in gui.py
directoryList = self._config["mediaSearchDirectories"]
if filename and directoryList:
for directory in directoryList:
for root, dirs, files in os.walk(directory):
if filename in files:
return os.path.join(root,filename)
return None
def openFile(self, filePath, resetPosition=False):
self._player.openFile(filePath, resetPosition)
@ -1397,8 +1390,7 @@ class SyncplayPlaylist():
self._ui.showErrorMessage(getMessage("cannot-add-unsafe-path-error").format(filename))
return
else:
path = self._client.findFilenameInDirectories(filename)
# TODO: Find Path properly
path = self._client.fileSwitch.findFilepath(filename)
if path:
self._client.openFile(path, resetPosition)
else:
@ -1536,4 +1528,129 @@ class SyncplayPlaylist():
self._previousPlaylistRoom = currentRoom
def _playlistBufferNeedsUpdating(self, newPlaylist):
return self._previousPlaylist <> self._playlist and self._playlist <> newPlaylist
return self._previousPlaylist <> self._playlist and self._playlist <> newPlaylist
class FileSwitchManager(object):
def __init__(self, client):
self._client = client
self.fileSwitchTimer = task.LoopingCall(self.updateInfo)
self.mediaFilesCache = {}
self.filenameWatchlist = []
self.currentDirectory = None
self.mediaDirectories = None
self.lock = threading.Lock()
self.folderSearchEnabled = True
self.disabledDir = None
self.newInfo = False
self.currentlyUpdating = False
self.newInfo = False
self.newWatchlist = []
self.fileSwitchTimer.start(constants.FOLDER_SEARCH_DOUBLE_CHECK_INTERVAL, True)
def setClient(self, newClient):
self.client = newClient
def setCurrentDirectory(self, curDir):
self.currentDirectory = curDir
self.updateInfo()
def setMediaDirectories(self, mediaDirs):
self.mediaDirectories = mediaDirs
self.updateInfo()
def checkForFileSwitchUpdate(self, bob=None):
if bob is not None:
print bob
if self.newInfo:
self.newInfo = False
self.infoUpdated()
def updateInfo(self):
if len(self.filenameWatchlist) > 0 or len(self.mediaFilesCache) == 0 and self.currentlyUpdating == False:
threads.deferToThread(self._updateInfoThread).addCallback(self.checkForFileSwitchUpdate)
def setFilenameWatchlist(self, unfoundFilenames):
self.filenameWatchlist = unfoundFilenames
def _updateInfoThread(self):
if not self.folderSearchEnabled:
if self.areWatchedFilenamesInCurrentDir():
self.newInfo = True
return
with self.lock:
try:
self.currentlyUpdating = True
dirsToSearch = self.mediaDirectories
if dirsToSearch:
newMediaFilesCache = {}
startTime = time.time()
for directory in dirsToSearch:
for root, dirs, files in os.walk(directory):
newMediaFilesCache[root] = files
if time.time() - startTime > constants.FOLDER_SEARCH_TIMEOUT:
self.disabledDir = directory
self.folderSearchEnabled = False
if self.areWatchedFilenamesInCurrentDir():
self.newInfo = True
return
if self.mediaFilesCache <> newMediaFilesCache:
self.mediaFilesCache = newMediaFilesCache
self.newInfo = True
elif self.areWatchedFilenamesInCurrentDir():
self.newInfo = True
finally:
self.currentlyUpdating = False
def infoUpdated(self):
if self.areWatchedFilenamesInCache() or self.areWatchedFilenamesInCurrentDir():
self.updateListOfWhoIsPlayingWhat()
def updateListOfWhoIsPlayingWhat(self):
self._client.showUserList()
def findFilepath(self, filename):
if filename is None:
return
if self.currentDirectory is not None:
candidatePath = os.path.join(self.currentDirectory,filename)
if os.path.isfile(candidatePath):
return candidatePath
if self.mediaFilesCache is not None:
for directory in self.mediaFilesCache:
files = self.mediaFilesCache[directory]
if len(files) > 0 and filename in files:
filepath = os.path.join(directory, filename)
if os.path.isfile(filepath):
return filepath
def areWatchedFilenamesInCurrentDir(self):
if self.filenameWatchlist is not None and self.currentDirectory is not None:
for filename in self.filenameWatchlist:
potentialPath = os.path.join(self.currentDirectory,filename)
if os.path.isfile(potentialPath):
return True
def areWatchedFilenamesInCache(self):
if self.filenameWatchlist is not None:
for filename in self.filenameWatchlist:
if self.isFilenameInCache(filename):
return True
def isFilenameInCurrentDir(self, filename):
if filename is not None and self.currentDirectory is not None:
potentialPath = os.path.join(self.currentDirectory,filename)
if os.path.isfile(potentialPath):
return True
def isFilenameInCache(self, filename):
if filename is not None and self.mediaFilesCache is not None:
for directory in self.mediaFilesCache:
files = self.mediaFilesCache[directory]
if filename in files:
return True

View File

@ -10,8 +10,7 @@ import re
import os
from syncplay.utils import formatTime, sameFilename, sameFilesize, sameFileduration, RoomPasswordProvider, formatSize, isURL
from functools import wraps
from twisted.internet import task, threads
import threading
from twisted.internet import task
lastCheckedForUpdates = None
class UserlistItemDelegate(QtGui.QStyledItemDelegate):
@ -260,148 +259,7 @@ class MainWindow(QtGui.QMainWindow):
else:
super(MainWindow.PlaylistWidget, self).dropEvent(event)
class FileSwitchManager(object):
def __init__(self):
self.fileSwitchTimer = task.LoopingCall(self.updateInfo)
self.fileSwitchTimer.start(constants.FOLDER_SEARCH_DOUBLE_CHECK_INTERVAL, True)
mediaFilesCache = {}
filenameWatchlist = []
currentDirectory = None
mediaDirectories = None
lock = threading.Lock()
client = None
currentWindow = None
folderSearchEnabled = True
disabledDir = None
newInfo = False
currentlyUpdating = False
@staticmethod
def setWindow(window):
MainWindow.FileSwitchManager.currentWindow = window
@staticmethod
def setClient(newClient):
MainWindow.FileSwitchManager.client = newClient
@staticmethod
def setCurrentDirectory(curDir):
MainWindow.FileSwitchManager.currentDirectory = curDir
MainWindow.FileSwitchManager.updateInfo()
@staticmethod
def setMediaDirectories(mediaDirs):
MainWindow.FileSwitchManager.mediaDirectories = mediaDirs
MainWindow.FileSwitchManager.updateInfo()
@staticmethod
def checkForUpdate(self=None):
if MainWindow.FileSwitchManager.newInfo:
MainWindow.FileSwitchManager.newInfo = False
MainWindow.FileSwitchManager.infoUpdated()
@staticmethod
def updateInfo():
if len(MainWindow.FileSwitchManager.filenameWatchlist) > 0 or len(MainWindow.FileSwitchManager.mediaFilesCache) == 0 and MainWindow.FileSwitchManager.currentlyUpdating == False:
threads.deferToThread(MainWindow.FileSwitchManager._updateInfoThread).addCallback(MainWindow.FileSwitchManager.checkForUpdate)
@staticmethod
def setFilenameWatchlist(unfoundFilenames):
MainWindow.FileSwitchManager.filenameWatchlist = unfoundFilenames
@staticmethod
def _updateInfoThread():
if not MainWindow.FileSwitchManager.folderSearchEnabled:
if MainWindow.FileSwitchManager.areWatchedFilenamesInCurrentDir():
MainWindow.FileSwitchManager.newInfo = True
return
with MainWindow.FileSwitchManager.lock:
try:
MainWindow.FileSwitchManager.currentlyUpdating = True
dirsToSearch = MainWindow.FileSwitchManager.mediaDirectories
if dirsToSearch:
newMediaFilesCache = {}
startTime = time.time()
for directory in dirsToSearch:
for root, dirs, files in os.walk(directory):
newMediaFilesCache[root] = files
if time.time() - startTime > constants.FOLDER_SEARCH_TIMEOUT:
if MainWindow.FileSwitchManager.client is not None and MainWindow.FileSwitchManager.currentWindow is not None:
MainWindow.FileSwitchManager.disabledDir = directory
MainWindow.FileSwitchManager.folderSearchEnabled = False
if MainWindow.FileSwitchManager.areWatchedFilenamesInCurrentDir():
MainWindow.FileSwitchManager.newInfo = True
return
if MainWindow.FileSwitchManager.mediaFilesCache <> newMediaFilesCache:
MainWindow.FileSwitchManager.mediaFilesCache = newMediaFilesCache
MainWindow.FileSwitchManager.newInfo = True
elif MainWindow.FileSwitchManager.areWatchedFilenamesInCurrentDir():
MainWindow.FileSwitchManager.newInfo = True
finally:
MainWindow.FileSwitchManager.currentlyUpdating = False
@staticmethod
def infoUpdated():
if MainWindow.FileSwitchManager.areWatchedFilenamesInCache() or MainWindow.FileSwitchManager.areWatchedFilenamesInCurrentDir():
MainWindow.FileSwitchManager.updateListOfWhoIsPlayingWhat()
@staticmethod
def updateListOfWhoIsPlayingWhat():
if MainWindow.FileSwitchManager.client is not None:
MainWindow.FileSwitchManager.client.showUserList()
@staticmethod
def findFilepath(filename):
if filename is None:
return
if MainWindow.FileSwitchManager.currentDirectory is not None:
candidatePath = os.path.join(MainWindow.FileSwitchManager.currentDirectory,filename)
if os.path.isfile(candidatePath):
return candidatePath
if MainWindow.FileSwitchManager.mediaFilesCache is not None:
for directory in MainWindow.FileSwitchManager.mediaFilesCache:
files = MainWindow.FileSwitchManager.mediaFilesCache[directory]
if len(files) > 0 and filename in files:
filepath = os.path.join(directory, filename)
if os.path.isfile(filepath):
return filepath
@staticmethod
def areWatchedFilenamesInCurrentDir():
if MainWindow.FileSwitchManager.filenameWatchlist is not None and MainWindow.FileSwitchManager.currentDirectory is not None:
for filename in MainWindow.FileSwitchManager.filenameWatchlist:
potentialPath = os.path.join(MainWindow.FileSwitchManager.currentDirectory,filename)
if os.path.isfile(potentialPath):
return True
@staticmethod
def areWatchedFilenamesInCache():
if MainWindow.FileSwitchManager.filenameWatchlist is not None:
for filename in MainWindow.FileSwitchManager.filenameWatchlist:
if MainWindow.FileSwitchManager.isFilenameInCache(filename):
return True
@staticmethod
def isFilenameInCurrentDir(filename):
if filename is not None and MainWindow.FileSwitchManager.currentDirectory is not None:
potentialPath = os.path.join(MainWindow.FileSwitchManager.currentDirectory,filename)
if os.path.isfile(potentialPath):
return True
@staticmethod
def isFilenameInCache(filename):
if filename is not None and MainWindow.FileSwitchManager.mediaFilesCache is not None:
for directory in MainWindow.FileSwitchManager.mediaFilesCache:
files = MainWindow.FileSwitchManager.mediaFilesCache[directory]
if filename in files:
return True
class topSplitter(QtGui.QSplitter):
def createHandle(self):
@ -427,14 +285,13 @@ class MainWindow(QtGui.QMainWindow):
def addClient(self, client):
self._syncplayClient = client
MainWindow.FileSwitchManager.setClient(client)
self.roomInput.setText(self._syncplayClient.getRoom())
self.config = self._syncplayClient.getConfig()
try:
self.playlistGroup.blockSignals(True)
self.playlistGroup.setChecked(self.config['sharedPlaylistEnabled'])
self.playlistGroup.blockSignals(False)
self.FileSwitchManager.setMediaDirectories(self.config["mediaSearchDirectories"])
self._syncplayClient.fileSwitch.setMediaDirectories(self.config["mediaSearchDirectories"])
self.updateReadyState(self.config['readyAtStart'])
autoplayInitialState = self.config['autoplayInitialState']
if autoplayInitialState is not None:
@ -467,6 +324,7 @@ class MainWindow(QtGui.QMainWindow):
else:
self.newMessage(time.strftime(constants.UI_TIME_FORMAT, time.localtime()) + message + "<br />")
@needsClient
def getFileSwitchState(self, filename):
if filename:
if filename == getMessage("nofile-note"):
@ -476,19 +334,20 @@ class MainWindow(QtGui.QMainWindow):
if isURL(filename):
return constants.FILEITEM_SWITCH_STREAM_SWITCH
elif filename not in self.newWatchlist:
if MainWindow.FileSwitchManager.findFilepath(filename):
if self._syncplayClient.fileSwitch.findFilepath(filename):
return constants.FILEITEM_SWITCH_FILE_SWITCH
else:
self.newWatchlist.extend([filename])
return constants.FILEITEM_SWITCH_NO_SWITCH
@needsClient
def showUserList(self, currentUser, rooms):
self._usertreebuffer = QtGui.QStandardItemModel()
self._usertreebuffer.setHorizontalHeaderLabels(
(getMessage("roomuser-heading-label"), getMessage("size-heading-label"), getMessage("duration-heading-label"), getMessage("filename-heading-label") ))
usertreeRoot = self._usertreebuffer.invisibleRootItem()
if self._syncplayClient.userlist.currentUser.file and self._syncplayClient.userlist.currentUser.file and os.path.isfile(self._syncplayClient.userlist.currentUser.file["path"]):
MainWindow.FileSwitchManager.setCurrentDirectory(os.path.dirname(self._syncplayClient.userlist.currentUser.file["path"]))
self._syncplayClient.fileSwitch.setCurrentDirectory(os.path.dirname(self._syncplayClient.userlist.currentUser.file["path"]))
for room in rooms:
self.newWatchlist = []
@ -577,7 +436,7 @@ class MainWindow(QtGui.QMainWindow):
self.listTreeView.setRootIsDecorated(False)
self.listTreeView.expandAll()
self.updateListGeometry()
MainWindow.FileSwitchManager.setFilenameWatchlist(self.newWatchlist)
self._syncplayClient.fileSwitch.setFilenameWatchlist(self.newWatchlist)
self.checkForDisabledDir()
@needsClient
@ -588,6 +447,7 @@ class MainWindow(QtGui.QMainWindow):
def shufflePlaylist(self):
self._syncplayClient.playlist.shufflePlaylist()
@needsClient
def openPlaylistMenu(self, position):
indexes = self.playlist.selectedIndexes()
if sys.platform.startswith('win'):
@ -606,7 +466,7 @@ class MainWindow(QtGui.QMainWindow):
if isURL(firstFile):
menu.addAction(QtGui.QPixmap(resourcespath + "world_go.png"), getMessage("openstreamurl-menu-label"), lambda: self.openFile(firstFile))
else:
pathFound = MainWindow.FileSwitchManager.findFilepath(firstFile)
pathFound = self._syncplayClient.fileSwitch.findFilepath(firstFile)
if pathFound:
menu.addAction(QtGui.QPixmap(resourcespath + "film_go.png"), getMessage("openmedia-menu-label"), lambda: self.openFile(pathFound))
menu.addAction(QtGui.QPixmap(resourcespath + "delete.png"), getMessage("removefromplaylist-menu-label"), lambda: self.deleteSelectedPlaylistItems())
@ -656,7 +516,7 @@ class MainWindow(QtGui.QMainWindow):
if isURL(filename):
menu.addAction(QtGui.QPixmap(resourcespath + "world_go.png"), getMessage("openusersstream-menu-label").format(shortUsername), lambda: self.openFile(filename))
else:
pathFound = MainWindow.FileSwitchManager.findFilepath(filename)
pathFound = self._syncplayClient.fileSwitch.findFilepath(filename)
if pathFound:
menu.addAction(QtGui.QPixmap(resourcespath + "film_go.png"), getMessage("openusersfile-menu-label").format(shortUsername), lambda: self.openFile(pathFound))
else:
@ -664,10 +524,11 @@ class MainWindow(QtGui.QMainWindow):
menu.exec_(self.listTreeView.viewport().mapToGlobal(position))
@needsClient
def checkForDisabledDir(self):
if MainWindow.FileSwitchManager.disabledDir is not None and MainWindow.FileSwitchManager.currentWindow is not None:
self.showErrorMessage(getMessage("folder-search-timeout-error").format(MainWindow.FileSwitchManager.disabledDir))
MainWindow.FileSwitchManager.disabledDir = None
if self._syncplayClient.fileSwitch.disabledDir is not None and self._syncplayClient.fileSwitch.currentWindow is not None:
self.showErrorMessage(getMessage("folder-search-timeout-error").format(self._syncplayClient.fileSwitch.disabledDir))
self._syncplayClient.fileSwitch.disabledDir = None
def updateListGeometry(self):
try:
@ -697,13 +558,14 @@ class MainWindow(QtGui.QMainWindow):
self.readyPushButton.blockSignals(False)
self.updateReadyIcon()
@needsClient
def playlistItemClicked(self, item):
# TODO: Integrate into client.py code
filename = item.data()
if isURL(filename):
self._syncplayClient._player.openFile(filename)
else:
pathFound = MainWindow.FileSwitchManager.findFilepath(filename)
pathFound = self._syncplayClient.fileSwitch.findFilepath(filename)
if pathFound:
self._syncplayClient._player.openFile(pathFound)
else:
@ -723,11 +585,11 @@ class MainWindow(QtGui.QMainWindow):
if isURL(filename):
self._syncplayClient._player.openFile(filename)
else:
pathFound = MainWindow.FileSwitchManager.findFilepath(filename)
pathFound = self._syncplayClient.fileSwitch.findFilepath(filename)
if pathFound:
self._syncplayClient._player.openFile(pathFound)
else:
MainWindow.FileSwitchManager.updateInfo()
self._syncplayClient.fileSwitch.updateInfo()
self.showErrorMessage(getMessage("switch-file-not-found-error").format(filename))
@needsClient
@ -861,7 +723,7 @@ class MainWindow(QtGui.QMainWindow):
if sys.platform.startswith('win'):
fileName = fileName.replace("/", "\\")
self.mediadirectory = os.path.dirname(fileName)
self.FileSwitchManager.setCurrentDirectory(self.mediadirectory)
self._syncplayClient.fileSwitch.setCurrentDirectory(self.mediadirectory)
self.saveMediaBrowseSettings()
self._syncplayClient._player.openFile(fileName)
@ -888,7 +750,7 @@ class MainWindow(QtGui.QMainWindow):
if sys.platform.startswith('win'):
fileName = fileName.replace("/", "\\")
self.mediadirectory = os.path.dirname(fileName)
self.FileSwitchManager.setCurrentDirectory(self.mediadirectory)
self._syncplayClient.fileSwitch.setCurrentDirectory(self.mediadirectory)
self.saveMediaBrowseSettings()
self.addFileToPlaylist(fileName)
self.updatingPlaylist = False
@ -1529,8 +1391,6 @@ class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
FileSwitchManager = self.FileSwitchManager()
FileSwitchManager.setWindow(self)
self.newWatchlist = []
self.publicServerList = []
self.lastCheckedForUpdates = None