PlexKodiConnect/resources/lib/windows/server_select.py
2018-09-30 13:16:48 +02:00

224 lines
7.2 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
:module: plexkodiconnect.userselect
:synopsis: This module shows a dialog to let one choose between different Plex
(home) users
"""
from __future__ import absolute_import, division, unicode_literals
from logging import getLogger
import xbmc
import xbmcgui
from . import kodigui
from .connection import plexapp
from .. import backgroundthread, utils, plex_functions as PF, variables as v
LOG = getLogger('PLEX.' + __name__)
class UserThumbTask(backgroundthread.Task):
def setup(self, users, callback):
self.users = users
self.callback = callback
return self
def run(self):
for user in self.users:
if self.isCanceled():
return
thumb, back = user.thumb, ''
self.callback(user, thumb, back)
class ServerListItem(kodigui.ManagedListItem):
def init(self):
self.dataSource.on('completed:reachability', self.onUpdate)
self.dataSource.on('started:reachability', self.onUpdate)
return self
def safeSetProperty(self, key, value):
# For if we catch the item in the middle of being removed
try:
self.setProperty(key, value)
return True
except AttributeError:
return False
def safeSetLabel(self, value):
# For if we catch the item in the middle of being removed
try:
self.setLabel(value)
return True
except AttributeError:
return False
def onUpdate(self, **kwargs):
if not self.listItem: # ex. can happen on Kodi shutdown
return
if not self.dataSource.isSupported or not self.dataSource.isReachable():
if self.dataSource.pendingReachabilityRequests > 0:
self.safeSetProperty('status', 'refreshing.gif')
else:
self.safeSetProperty('status', 'unreachable.png')
else:
self.safeSetProperty('status', self.dataSource.isSecure and 'secure.png' or '')
self.safeSetProperty('current', plexapp.SERVERMANAGER.selectedServer == self.dataSource and '1' or '')
self.safeSetLabel(self.dataSource.name)
def onDestroy(self):
self.dataSource.off('completed:reachability', self.onUpdate)
self.dataSource.off('started:reachability', self.onUpdate)
class ServerSelectWindow(kodigui.BaseWindow):
xmlFile = 'script-plex-server_select.xml'
path = v.ADDON_PATH
theme = 'Main'
res = '1080i'
width = 1920
height = 1080
USER_LIST_ID = 101
PIN_ENTRY_GROUP_ID = 400
HOME_BUTTON_ID = 500
SERVER_LIST_ID = 260
def __init__(self, *args, **kwargs):
self.tasks = None
self.server = None
self.aborted = False
self.serverList = None
kodigui.BaseWindow.__init__(self, *args, **kwargs)
def onFirstInit(self):
self.serverList = kodigui.ManagedControlList(self,
self.SERVER_LIST_ID,
10)
self.start()
def onAction(self, action):
try:
ID = action.getId()
if 57 < ID < 68:
if not xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format(self.PIN_ENTRY_GROUP_ID)):
item = self.userList.getSelectedItem()
if not item.dataSource.isProtected:
return
self.setFocusId(self.PIN_ENTRY_GROUP_ID)
self.pinEntryClicked(ID + 142)
return
elif 142 <= ID <= 149: # JumpSMS action
if not xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format(self.PIN_ENTRY_GROUP_ID)):
item = self.userList.getSelectedItem()
if not item.dataSource.isProtected:
return
self.setFocusId(self.PIN_ENTRY_GROUP_ID)
self.pinEntryClicked(ID + 60)
return
elif ID in (xbmcgui.ACTION_NAV_BACK, xbmcgui.ACTION_BACKSPACE):
if xbmc.getCondVisibility('ControlGroup({0}).HasFocus(0)'.format(self.PIN_ENTRY_GROUP_ID)):
self.pinEntryClicked(211)
return
except:
utils.ERROR()
kodigui.BaseWindow.onAction(self, action)
def onClick(self, controlID):
if controlID == self.USER_LIST_ID:
item = self.userList.getSelectedItem()
if item.dataSource.isProtected:
self.setFocusId(self.PIN_ENTRY_GROUP_ID)
else:
self.userSelected(item)
elif 200 < controlID < 212:
self.pinEntryClicked(controlID)
elif controlID == self.HOME_BUTTON_ID:
self.home_button_clicked()
def onFocus(self, controlID):
if controlID == self.USER_LIST_ID:
item = self.userList.getSelectedItem()
item.setProperty('editing.pin', '')
def showServers(self, from_refresh=False, mouse=False):
selection = None
if from_refresh:
mli = self.serverList.getSelectedItem()
if mli:
selection = mli.dataSource
else:
plexapp.refreshResources()
servers = sorted(
plexapp.SERVERMANAGER.getServers(),
key=lambda x: (x.owned and '0' or '1') + x.name.lower()
)
servers = PF.plex_gdm()
items = []
for s in servers:
item = ServerListItem(s.name,
not s.owned and s.owner or '',
data_source=s).init()
item.onUpdate()
item.setProperty(
'current',
plexapp.SERVERMANAGER.selectedServer == s and '1' or '')
items.append(item)
if len(items) > 1:
items[0].setProperty('first', '1')
items[-1].setProperty('last', '1')
elif items:
items[0].setProperty('only', '1')
self.serverList.replaceItems(items)
self.getControl(800).setHeight((min(len(items), 9) * 100) + 80)
if selection:
for mli in self.serverList:
if mli.dataSource == selection:
self.serverList.selectItem(mli.pos())
if not from_refresh and items and not mouse:
self.setFocusId(self.SERVER_LIST_ID)
def start(self):
self.setProperty('busy', '1')
self.showServers()
self.setProperty('initialized', '1')
self.setProperty('busy', '')
def home_button_clicked(self):
"""
Action taken if user clicked the home button
"""
self.server = None
self.aborted = True
self.doClose()
def finished(self):
for task in self.tasks:
task.cancel()
def start():
"""
Hit this function to open a dialog to choose the Plex user
Returns
=======
tuple (server, aborted)
server : PlexServer
Or None if server switch failed or aborted by the server
aborted : bool
True if the server cancelled the dialog
"""
w = ServerSelectWindow.open()
server, aborted = w.server, w.aborted
del w
return server, aborted