📄 chn_class.py
字号:
#===============================================================================
# Import the default modules
#===============================================================================
from logging import thread
import settings
import threading
import xbmc, xbmcgui
import sys, os
#===============================================================================
# Make global object available
#===============================================================================
import common
import config
import controls
import contextmenu
import settings
#import chn_class
logFile = sys.modules['__main__'].globalLogFile
uriHandler = sys.modules['__main__'].globalUriHandler
#===============================================================================
# register the channels
#===============================================================================
# register = sys.modules['progwindow']
# register.channelRegister.append('chn_rtl.Channel("uzg-channelwindow.xml", config.rootDir, config.skinFolder)')
#===============================================================================
# main Channel Class
#===============================================================================
class Channel(xbmcgui.WindowXML):
"""
main class from which all channels inherit
"""
#==============================================================================
def __init__(self, *args, **kwargs):
""" NOT USER EDITABLE
Initialisation of the class. All class variables should be instantiated here
"""
self.listItems = []
self.folderHistory = [] # top one contains selected position in PREVIOUS Folder
self.folderHistorySelectedPosition = [] # top one contains the url of the CURRENT Folder
self.parentItem = None
self.folderIcon = "xot_defaultfolder.png"
if kwargs.has_key("channelCode"):
self.channelCode = kwargs["channelCode"]
logFile.debug("ChannelCode present: %s", self.channelCode)
else:
self.channelCode = ""
logFile.debug("No channelCode present")
self.initialUri = "" #uri that is used for the episodeList. NOT mainListUri
self.windowInitialised = False
#self.keysLocked = 0 #0=False, 1=True, >1 True and already new commands
self.loggedOn = False
self.progressBarItemLimit = 50
# set timer timeout for keyupdown
self.timerTimeOut = 0.5
self.videoUpdateLock = threading.Lock()
# initialise user defined variables
self.InitialiseVariables()
# update image file names: point to local folder if not present in skin
self.icon = self.GetImageLocation(self.icon)
self.iconLarge = self.GetImageLocation(self.iconLarge)
self.folderIcon = self.GetImageLocation(self.folderIcon)
self.noImage = self.GetImageLocation(self.noImage)
self.backgroundImage = self.GetImageLocation(self.backgroundImage)
self.backgroundImage16x9 = self.GetImageLocation(self.backgroundImage16x9)
# plugin stuff
self.pluginMode = False
#===============================================================================
# define class variables
#===============================================================================
def InitialiseVariables(self):
"""
Used for the initialisation of user defined parameters. All should be
present, but can be adjusted
"""
#logFile.debug("Starting IntialiseVariables from chn_class.py")
# call base function first to ensure all variables are there
# chn_class.Channel.InitialiseVariables(self)
self.icon = ""
self.iconLarge = ""
self.noImage = ""
self.backgroundImage = "" # if not specified, the one defined in the skin is used
self.backgroundImage16x9 = "" # if not specified, the one defined in the skin is used
self.channelName = "Channel Class"
self.channelDescription = "This is the channelclass on which all channels are based"
self.moduleName = "chn_class.py"
self.maxXotVersion = "1.0.0"
self.sortOrder = 255 #max 255 channels
self.buttonID = 0
self.onUpDownUpdateEnabled = True
self.contextMenuItems = []
self.mainListUri = ""
self.baseUrl = ""
self.playerUrl = ""
self.passWord = ""
self.userName = ""
self.logonUrl = ""
self.requiresLogon = False
self.asxAsfRegex = '<[^\s]*REF href[^"]+"([^"]+)"' # default regex for parsing ASX/ASF files
self.episodeItemRegex = '' # used for the ParseMainList
self.episodeSort = True
self.videoItemRegex = '' # used for the CreateVideoItem
self.folderItemRegex = '' # used for the CreateFolderItem
self.mediaUrlRegex = '' # used for the UpdateVideoItem
#==========================================================================
# non standard items
return True
#==============================================================================
# Inherited from xbmcgui.WindowXML
#==============================================================================
def onInit(self):
""" NOT USER EDITABLE
Initialisation of class after the GUI has been loaded. This happens every
time. Triggered by doModal in the ShowEpisodeWindow Methode
"""
try:
logFile.info("onInit(): Window Initalized for %s", self.moduleName)
if not self.windowInitialised:
logFile.debug("Initializing %s Gui for the first time", self.channelName)
# set background
if self.getResolution() in controls.RESOLUTION_16x9 and self.backgroundImage16x9!="":
self.getControl(controls.EP_BACKGROUND).setImage(self.backgroundImage16x9)
logFile.debug("Resolution=%s, %s", self.getResolution(), self.backgroundImage16x9)
elif self.getResolution() in controls.RESOLUTION_4x3 and self.backgroundImage!="":
self.getControl(controls.EP_BACKGROUND).setImage(self.backgroundImage)
logFile.debug("Resolution=%s, %s", self.getResolution(), self.backgroundImage)
# make sure the history is cleared!
logFile.debug("Clearing Folder History")
del self.folderHistory[:]
del self.folderHistorySelectedPosition [:]
# add initialUri to root and give it the default image and no description.
# the latter two are used for clearing the fields while loading a new list
_tmpItem = common.clistItem("", self.initialUri)
_tmpItem.description = "Please wait while loading data"
_tmpItem.thumb = self.noImage
self.ShowData(_tmpItem)
self.folderHistory.append(_tmpItem)
self.folderHistorySelectedPosition.append(0)
# logging on
logFile.debug("LogonCheck")
self.loggedOn = self.LogOn(self.userName, self.passWord)
#make sure keys are unlocked upon init
#self.keysLocked = 0
if not self.loggedOn:
logFile.error('Not logged on...exiting')
self.close()
else:
# create new rootItem and fetch it's items
rootItem = common.clistItem("root", self.initialUri)
rootItem.items = self.ProcessFolderList(self.initialUri)
rootItem.thumb = self.noImage
# clear history and add the rootitem
del self.folderHistory[:]
self.folderHistory.append(rootItem)
# now display the items.
self.listItems = rootItem.items
self.DisplayFolderList(self.listItems, 0)
self.windowInitialised = True
logFile.debug("%s Gui has been initialised for the first time", self.channelName)
else:
logFile.debug("%s GUI window already Initialized", self.channelName)
except:
logFile.critical("Error initialising the %s Window.", self.channelName , exc_info=True)
#===============================================================================
# Init for plugin
#===============================================================================
def initPlugin(self):
"""
Special initialisation for plugin version
"""
# create dummy history item
self.folderHistory.append(common.clistItem("Dummy Plugin item", ""))
self.pluginMode = True
#==============================================================================
def onAction(self, action):
""" NOT USER EDITABLE
Action Method for handling all actions except the clicking. This one should
only be inherited, not overwriten
"""
logFile.debug("OnAction detected on control %s (ThrdID=%s)", self.getFocusId(),thread.get_ident())
try:
#logFile.debug("FocusId=%s",self.getFocusId())
if action in controls.ACTION_UPDOWN:
#if (self.getFocus() == self.getControl(controls.EP_LIST)):
if (self.getFocusId() == controls.EP_LIST):
try:
logFile.debug("Cancelling and starting onKeyUpDown timer")
# cancel the timer is present
try:
self.timerUpDown.cancel()
except:
pass
# start a new one
self.timerUpDown = threading.Timer(self.timerTimeOut, self.onUpDown)
self.timerUpDown.start()
except:
logFile.critical("Error in locking mechanism")
elif action == controls.ACTION_PARENT_DIR or action == controls.ACTION_PREVIOUS_MENU:
try:
logFile.debug("Removing items from historystack")
self.folderHistory.pop()
# release the video update lock if present
try:
self.videoUpdateLock.release()
except:
# if it wasn't locked, pass the exception
pass
if self.folderHistory == []:
self.onExit()
else:
# go back an folder, clear list, process the folder and stuff the
# content back in the list
self.listItems = self.folderHistory[-1].items
if len(self.listItems) < 1:
# the caching did not work. Start retrieving it
self.listItems = self.ProcessFolderList(self.folderHistory[-1].url)
self.DisplayFolderList(self.listItems, self.folderHistorySelectedPosition.pop())
except:
logFile.critical("Cannot perform a good BACK action. Closing!", exc_info=True)
self.onExit()
# elif action == controls.ACTION_SELECT_ITEM:
# self.onClick(self.getFocusId())
elif action in controls.ACTION_CONTEXT_MENU_CONTROLS: # and self.keysLocked < 1:
logFile.debug("showing contextmenu")
self.onActionFromContextMenu()
else:
pass
#logFile.warning("Action %s on ControlID %s was not recognised! No action taken", action, self.getFocus())
except:
logFile.warning('Action Failed, or could not determine action', exc_info=True)
#===============================================================================
# Customizable actions
#===============================================================================
def onFocus(self, controlID):
""""
onFocus(self, int controlID)
This function has been implemented and works
"""
#==============================================================================
def onClick(self, controlID):
"""
Catching of clicking (Select/OK)
"""
logFile.debug("OnClick detected on controlID = %s", controlID)
try:
# check if the Episode List is active
logFile.debug("Trying to determine what to do with the onClick")
if controlID == controls.EP_LIST:
logFile.debug("OnClick detected on EPList")
position = self.getCurrentListPosition()
item = self.listItems[position]
# Determine type of item
if item.type == 'video':
# if not complete, update
logFile.debug("Detected Video file")
if not item.complete:
item = self.UpdateVideoItem(item)
# if the mediaUrl is not filled: item is not complete
if item.mediaurl == "":
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -