Advertisement
Guest User

PseudoTV Added Interleave Rules

a guest
Jun 29th, 2013
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 49.50 KB | None | 0 0
  1. #   Copyright (C) 2011 Jason Anderson
  2. #
  3. #
  4. # This file is part of PseudoTV.
  5. #
  6. # PseudoTV is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # PseudoTV is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with PseudoTV.  If not, see <http://www.gnu.org/licenses/>.
  18.  
  19. import xbmc, xbmcgui, xbmcaddon
  20. import subprocess, os
  21. import time, threading
  22. import datetime
  23. import sys, re
  24. import random
  25.  
  26. from Globals import *
  27. from Playlist import PlaylistItem
  28.  
  29.  
  30.  
  31. class RulesList:
  32.     def __init__(self):
  33.         self.ruleList = [BaseRule(), ScheduleChannelRule(), HandleChannelLogo(), NoShowRule(), DontAddChannel(), EvenShowsRule(), ForceRandom(), ForceRealTime(), ForceResume(), HandleIceLibrary(), InterleaveChannel(), OnlyUnWatchedRule(), OnlyWatchedRule(), AlwaysPause(), PlayShowInOrder(), RenameRule(), SetResetTime()]
  34.  
  35.  
  36.     def getRuleCount(self):
  37.         return len(self.ruleList)
  38.  
  39.  
  40.     def getRule(self, index):
  41.         while index < 0:
  42.             index += len(self.ruleList)
  43.  
  44.         while index >= len(self.ruleList):
  45.             index -= len(self.ruleList)
  46.  
  47.         return self.ruleList[index]
  48.  
  49.  
  50.  
  51. class BaseRule:
  52.     def __init__(self):
  53.         self.name = ""
  54.         self.description = ""
  55.         self.optionLabels = []
  56.         self.optionValues = []
  57.         self.myId = 0
  58.         self.actions = 0
  59.  
  60.  
  61.     def getName(self):
  62.         return self.name
  63.  
  64.  
  65.     def getTitle(self):
  66.         return self.name
  67.  
  68.  
  69.     def getOptionCount(self):
  70.         return len(self.optionLabels)
  71.  
  72.  
  73.     def onAction(self, act, optionindex):
  74.         return ''
  75.  
  76.  
  77.     def getOptionLabel(self, index):
  78.         if index >= 0 and index < self.getOptionCount():
  79.             return self.optionLabels[index]
  80.  
  81.         return ''
  82.  
  83.  
  84.     def getOptionValue(self, index):
  85.         if index >= 0 and index < len(self.optionValues):
  86.             return self.optionValues[index]
  87.  
  88.         return ''
  89.  
  90.  
  91.     def getRuleIndex(self, channeldata):
  92.         index = 0
  93.  
  94.         for rule in channeldata.ruleList:
  95.             if rule == self:
  96.                 return index
  97.  
  98.             index += 1
  99.  
  100.         return -1
  101.  
  102.  
  103.     def getId(self):
  104.         return self.myId
  105.  
  106.  
  107.     def runAction(self, actionid, channelList, param):
  108.         return param
  109.  
  110.  
  111.     def copy(self):
  112.         return BaseRule()
  113.  
  114.  
  115.     def log(self, msg, level = xbmc.LOGDEBUG):
  116.         log("Rule " + self.getTitle() + ": " + msg, level)
  117.  
  118.  
  119.     def validate(self):
  120.         pass
  121.  
  122.  
  123.     def reset(self):
  124.         self.__init__()
  125.  
  126.  
  127.     def validateTextBox(self, optionindex, length):
  128.         if len(self.optionValues[optionindex]) > length:
  129.             self.optionValues[optionindex] = self.optionValues[optionindex][:length]
  130.  
  131.  
  132.     def onActionTextBox(self, act, optionindex):
  133.         action = act.getId()
  134.  
  135.         if act.getId() == ACTION_SELECT_ITEM:
  136.             keyb = xbmc.Keyboard(self.optionValues[optionindex], self.name, False)
  137.             keyb.doModal()
  138.  
  139.             if keyb.isConfirmed():
  140.                 self.optionValues[optionindex] = keyb.getText()
  141.  
  142.         button = act.getButtonCode()
  143.  
  144.         # Upper-case values
  145.         if button >= 0x2f041 and button <= 0x2f05b:
  146.             self.optionValues[optionindex] += chr(button - 0x2F000)
  147.  
  148.         # Lower-case values
  149.         if button >= 0xf041 and button <= 0xf05b:
  150.             self.optionValues[optionindex] += chr(button - 0xEFE0)
  151.  
  152.         # Numbers
  153.         if action >= ACTION_NUMBER_0 and action <= ACTION_NUMBER_9:
  154.             self.optionValues[optionindex] += chr(action - ACTION_NUMBER_0 + 48)
  155.  
  156.         # Backspace
  157.         if button == 0xF008:
  158.             if len(self.optionValues[optionindex]) >= 1:
  159.                 self.optionValues[optionindex] = self.optionValues[optionindex][:-1]
  160.  
  161.         # Delete
  162.         if button == 0xF02E:
  163.             self.optionValues[optionindex] = ''
  164.  
  165.         # Space
  166.         if button == 0xF020:
  167.             self.optionValues[optionindex] += ' '
  168.  
  169.         if xbmc.getCondVisibility("Window.IsVisible(10111)"):
  170.             self.log("shutdown window is visible")
  171.             xbmc.executebuiltin("Dialog.close(10111)")
  172.  
  173.  
  174.     def onActionDateBox(self, act, optionindex):
  175.         self.log("onActionDateBox")
  176.  
  177.         if act.getId() == ACTION_SELECT_ITEM:
  178.             dlg = xbmcgui.Dialog()
  179.             info = dlg.numeric(1, self.optionLabels[optionindex], self.optionValues[optionindex])
  180.  
  181.             if info != None:
  182.                 self.optionValues[optionindex] = info
  183.  
  184.  
  185.     def onActionTimeBox(self, act, optionindex):
  186.         self.log("onActionTimeBox")
  187.         action = act.getId()
  188.  
  189.         if action == ACTION_SELECT_ITEM:
  190.             dlg = xbmcgui.Dialog()
  191.             info = dlg.numeric(2, self.optionLabels[optionindex], self.optionValues[optionindex])
  192.  
  193.             if info != None:
  194.                 if info[0] == ' ':
  195.                     info = info[1:]
  196.  
  197.                 if len(info) == 4:
  198.                     info = "0" + info
  199.  
  200.                 self.optionValues[optionindex] = info
  201.  
  202.         button = act.getButtonCode()
  203.  
  204.         # Numbers
  205.         if action >= ACTION_NUMBER_0 and action <= ACTION_NUMBER_9:
  206.             value = action - ACTION_NUMBER_0
  207.             length = len(self.optionValues[optionindex])
  208.  
  209.             if length == 0:
  210.                 if value <= 2:
  211.                     self.optionValues[optionindex] = chr(value + 48)
  212.             elif length == 1:
  213.                 if int(self.optionValues[optionindex][0]) == 2:
  214.                     if value < 4:
  215.                         self.optionValues[optionindex] += chr(value + 48)
  216.                 else:
  217.                     self.optionValues[optionindex] += chr(value + 48)
  218.             elif length == 2:
  219.                 if value < 6:
  220.                     self.optionValues[optionindex] += ":" + chr(value + 48)
  221.             elif length < 5:
  222.                 self.optionValues[optionindex] += chr(value + 48)
  223.  
  224.         # Backspace
  225.         if button == 0xF008:
  226.             if len(self.optionValues[optionindex]) >= 1:
  227.                 if len(self.optionValues[optionindex]) == 4:
  228.                     self.optionValues[optionindex] = self.optionValues[optionindex][:-1]
  229.  
  230.                 self.optionValues[optionindex] = self.optionValues[optionindex][:-1]
  231.  
  232.  
  233.     def validateTimeBox(self, optionindex):
  234.         values = []
  235.         broken = False
  236.  
  237.         try:
  238.             values.append(int(self.optionValues[optionindex][0]))
  239.             values.append(int(self.optionValues[optionindex][1]))
  240.             values.append(int(self.optionValues[optionindex][3]))
  241.             values.append(int(self.optionValues[optionindex][4]))
  242.         except:
  243.             self.optionValues[optionindex] = "00:00"
  244.             return
  245.  
  246.         if values[0] > 2:
  247.             broken = True
  248.  
  249.         if values[0] == 2:
  250.             if values[1] > 3:
  251.                 broken = True
  252.  
  253.         if values[2] > 5:
  254.             broken = True
  255.  
  256.         if broken:
  257.             self.optionValues[optionindex] = "00:00"
  258.             return
  259.  
  260.  
  261.     def onActionSelectBox(self, act, optionindex):
  262.         if act.getId() == ACTION_SELECT_ITEM:
  263.             optioncount = len(self.selectBoxOptions[optionindex])
  264.             cursel = -1
  265.  
  266.             for i in range(optioncount):
  267.                 if self.selectBoxOptions[optionindex][i] == self.optionValues[optionindex]:
  268.                     cursel = i
  269.                     break
  270.  
  271.             cursel += 1
  272.  
  273.             if cursel >= optioncount:
  274.                 cursel = 0
  275.  
  276.             self.optionValues[optionindex] = self.selectBoxOptions[optionindex][cursel]
  277.  
  278.  
  279.     def onActionDaysofWeekBox(self, act, optionindex):
  280.         self.log("onActionDaysofWeekBox")
  281.  
  282.         if act.getId() == ACTION_SELECT_ITEM:
  283.             keyb = xbmc.Keyboard(self.optionValues[optionindex], self.name, False)
  284.             keyb.doModal()
  285.  
  286.             if keyb.isConfirmed():
  287.                 self.optionValues[optionindex] = keyb.getText().upper()
  288.  
  289.         button = act.getButtonCode()
  290.  
  291.         # Remove the shift key if it's there
  292.         if button >= 0x2F041 and button <= 0x2F05B:
  293.             button -= 0x20000
  294.  
  295.         # Pressed some character
  296.         if button >= 0xF041 and button <= 0xF05B:
  297.             button -= 0xF000
  298.  
  299.             # Check for UMTWHFS
  300.             if button == 85 or button == 77 or button == 84 or button == 87 or button == 72 or button == 70 or button == 83:
  301.                 # Check to see if it's already in the string
  302.                 loc = self.optionValues[optionindex].find(chr(button))
  303.  
  304.                 if loc != -1:
  305.                     self.optionValues[optionindex] = self.optionValues[optionindex][:loc] + self.optionValues[optionindex][loc + 1:]
  306.                 else:
  307.                     self.optionValues[optionindex] += chr(button)
  308.  
  309.         # Backspace
  310.         if button == 0xF008:
  311.             if len(self.optionValues[optionindex]) >= 1:
  312.                 self.optionValues[optionindex] = self.optionValues[optionindex][:-1]
  313.  
  314.         if xbmc.getCondVisibility("Window.IsVisible(10111)"):
  315.             self.log("shutdown window is visible")
  316.             xbmc.executebuiltin("Dialog.close(10111)")
  317.  
  318.  
  319.     def validateDaysofWeekBox(self, optionindex):
  320.         self.log("validateDaysofWeekBox")
  321.         daysofweek = "UMTWHFS"
  322.         newstr = ''
  323.  
  324.         for day in daysofweek:
  325.             loc = self.optionValues[optionindex].find(day)
  326.  
  327.             if loc != -1:
  328.                 newstr += day
  329.  
  330.         self.optionValues[optionindex] = newstr
  331.  
  332.  
  333.     def validateDigitBox(self, optionindex, minimum, maximum, default):
  334.         if len(self.optionValues[optionindex]) == 0:
  335.             return
  336.  
  337.         try:
  338.             val = int(self.optionValues[optionindex])
  339.  
  340.             if val >= minimum and val <= maximum:
  341.                 self.optionValues[optionindex] = str(val)
  342.  
  343.             return
  344.         except:
  345.             pass
  346.  
  347.         self.optionValues[optionindex] = str(default)
  348.  
  349.  
  350.     def onActionDigitBox(self, act, optionindex):
  351.         action = act.getId()
  352.  
  353.         if action == ACTION_SELECT_ITEM:
  354.             dlg = xbmcgui.Dialog()
  355.             value = dlg.numeric(0, self.optionLabels[optionindex], self.optionValues[optionindex])
  356.  
  357.             if value != None:
  358.                 self.optionValues[optionindex] = value
  359.  
  360.         button = act.getButtonCode()
  361.  
  362.         # Numbers
  363.         if action >= ACTION_NUMBER_0 and action <= ACTION_NUMBER_9:
  364.             self.optionValues[optionindex] += chr(action - ACTION_NUMBER_0 + 48)
  365.  
  366.         # Backspace
  367.         if button == 0xF008:
  368.             if len(self.optionValues[optionindex]) >= 1:
  369.                 self.optionValues[optionindex] = self.optionValues[optionindex][:-1]
  370.  
  371.         # Delete
  372.         if button == 0xF02E:
  373.             self.optionValues[optionindex] = ''
  374.  
  375.  
  376.  
  377. class RenameRule(BaseRule):
  378.     def __init__(self):
  379.         self.name = "Set Channel Name"
  380.         self.optionLabels = ['New Channel Name']
  381.         self.optionValues = ['']
  382.         self.myId = 1
  383.         self.actions = RULES_ACTION_FINAL_MADE | RULES_ACTION_FINAL_LOADED
  384.  
  385.  
  386.     def copy(self):
  387.         return RenameRule()
  388.  
  389.  
  390.     def getTitle(self):
  391.         if len(self.optionValues[0]) > 0:
  392.             return 'Rename Channel to ' + self.optionValues[0]
  393.  
  394.         return self.name
  395.  
  396.  
  397.     def onAction(self, act, optionindex):
  398.         self.onActionTextBox(act, optionindex)
  399.         self.validate()
  400.         return self.optionValues[optionindex]
  401.  
  402.  
  403.     def validate(self):
  404.         self.validateTextBox(0, 18)
  405.  
  406.  
  407.     def runAction(self, actionid, channelList, channeldata):
  408.         if actionid == RULES_ACTION_FINAL_MADE or actionid == RULES_ACTION_FINAL_LOADED:
  409.             self.validate()
  410.             channeldata.name = self.optionValues[0]
  411.  
  412.         return channeldata
  413.  
  414.  
  415.  
  416. class NoShowRule(BaseRule):
  417.     def __init__(self):
  418.         self.name = "Don't Include a Show"
  419.         self.optionLabels = ['Show Name']
  420.         self.optionValues = ['']
  421.         self.myId = 2
  422.         self.actions = RULES_ACTION_LIST
  423.  
  424.  
  425.     def copy(self):
  426.         return NoShowRule()
  427.  
  428.  
  429.     def getTitle(self):
  430.         if len(self.optionValues[0]) > 0:
  431.             return "Don't Include '" + self.optionValues[0] + "'"
  432.  
  433.         return self.name
  434.  
  435.  
  436.     def onAction(self, act, optionindex):
  437.         self.onActionTextBox(act, optionindex)
  438.         self.validate()
  439.         return self.optionValues[optionindex]
  440.  
  441.  
  442.     def validate(self):
  443.         self.validateTextBox(0, 20)
  444.  
  445.  
  446.     def runAction(self, actionid, channelList, filelist):
  447.         if actionid == RULES_ACTION_LIST:
  448.             self.validate()
  449.             opt = self.optionValues[0].lower()
  450.             realindex = 0
  451.  
  452.             for index in range(len(filelist)):
  453.                 item = filelist[realindex]
  454.                 loc = item.find(',')
  455.  
  456.                 if loc > -1:
  457.                     loc2 = item.find("//")
  458.  
  459.                     if loc2 > -1:
  460.                         showname = item[loc + 1:loc2]
  461.                         showname = showname.lower()
  462.  
  463.                         if showname.find(opt) > -1:
  464.                             filelist.pop(realindex)
  465.                             realindex -= 1
  466.  
  467.                 realindex += 1
  468.  
  469.         return filelist
  470.  
  471.  
  472.  
  473. class ScheduleChannelRule(BaseRule):
  474.     def __init__(self):
  475.         self.name = "Best-Effort Channel Scheduling"
  476.         self.optionLabels = ['Channel Number', 'Days of the Week (UMTWHFS)', 'Time (HH:MM)', 'Episode Count', 'Starting Episode', 'Starting Date (DD/MM/YYYY)']
  477.         self.optionValues = ['0', '', '00:00', '1', '1', '']
  478.         self.myId = 3
  479.         self.actions = RULES_ACTION_START | RULES_ACTION_BEFORE_CLEAR | RULES_ACTION_FINAL_MADE | RULES_ACTION_FINAL_LOADED
  480.         self.clearedcount = 0
  481.         self.appended = False
  482.         self.hasRun = False
  483.         self.nextScheduledTime = 0
  484.         self.startIndex = 0
  485.  
  486.  
  487.     def copy(self):
  488.         return ScheduleChannelRule()
  489.  
  490.  
  491.     def getTitle(self):
  492.         if len(self.optionValues[0]) > 0:
  493.             return "Schedule Channel " + self.optionValues[0]
  494.  
  495.         return self.name
  496.  
  497.  
  498.     def onAction(self, act, optionindex):
  499.         if optionindex == 0:
  500.             self.onActionDigitBox(act, optionindex)
  501.  
  502.         if optionindex == 1:
  503.             self.onActionDaysofWeekBox(act, optionindex)
  504.  
  505.         if optionindex == 2:
  506.             self.onActionTimeBox(act, optionindex)
  507.  
  508.         if optionindex == 3:
  509.             self.onActionDigitBox(act, optionindex)
  510.  
  511.         if optionindex == 4:
  512.             self.onActionDigitBox(act, optionindex)
  513.  
  514.         if optionindex == 5:
  515.             self.onActionDateBox(act, optionindex)
  516.  
  517.         self.validate()
  518.         return self.optionValues[optionindex]
  519.  
  520.  
  521.     def validate(self):
  522.         self.validateDigitBox(0, 1, 1000, '')
  523.         self.validateDaysofWeekBox(1)
  524.         self.validateTimeBox(2)
  525.         self.validateDigitBox(3, 1, 1000, 1)
  526.         self.validateDigitBox(4, 1, 1000, 1)
  527.  
  528.  
  529.     def runAction(self, actionid, channelList, channeldata):
  530.         self.log("runAction " + str(actionid))
  531.  
  532.         if actionid == RULES_ACTION_START:
  533.             self.clearedcount = 0
  534.             self.hasRun = False
  535.             self.nextScheduledTime = 0
  536.  
  537.         if actionid == RULES_ACTION_BEFORE_CLEAR:
  538.             self.clearedcount = channeldata.Playlist.size()
  539.  
  540.             if channeldata.totalTimePlayed > 0:
  541.                 self.appended = True
  542.             else:
  543.                 self.appended = False
  544.  
  545.         # When resetting the channel, make sure the starting episode and date are correct.
  546.         # Work backwards from the current ep and date to set the current date to today and proper ep
  547.         if actionid == RULES_ACTION_FINAL_MADE and self.hasRun == False:
  548.             curchan = channeldata.channelNumber
  549.             ADDON_SETTINGS.setSetting('Channel_' + str(curchan) + '_lastscheduled', '0')
  550.  
  551.             for rule in channeldata.ruleList:
  552.                 if rule.getId() == self.myId:
  553.                     rule.reverseStartingEpisode()
  554.                     rule.nextScheduledTime = 0
  555.  
  556.         if (actionid == RULES_ACTION_FINAL_MADE or actionid == RULES_ACTION_FINAL_LOADED) and (self.hasRun == False):
  557.             self.runSchedulingRules(channelList, channeldata)
  558.  
  559.         return channeldata
  560.  
  561.  
  562.     def reverseStartingEpisode(self):
  563.         self.log("reverseStartingEpisode")
  564.         tmpdate = 0
  565.  
  566.         try:
  567.             tmpdate = time.mktime(time.strptime(self.optionValues[5] + " " + self.optionValues[2], "%d/%m/%Y %H:%M"))
  568.         except:
  569.             pass
  570.  
  571.         if tmpdate > 0:
  572.             count = 0
  573.             currentdate = int(time.time())
  574.  
  575.             while tmpdate > currentdate:
  576.                 thedate = datetime.datetime.fromtimestamp(currentdate)
  577.                 self.optionValues[5] = thedate.strftime("%d/%m/%Y")
  578.                 self.determineNextTime()
  579.  
  580.                 if self.nextScheduledTime > 0:
  581.                     count += 1
  582.                     currentdate = self.nextScheduledTime + (60 * 60 * 24)
  583.                 else:
  584.                     break
  585.  
  586.             try:
  587.                 startep = int(self.optionValues[4])
  588.                 count = startep - count
  589.  
  590.                 if count > 0:
  591.                     self.optionValues[4] = str(count)
  592.                     thedate = datetime.datetime.fromtimestamp(int(time.time()))
  593. #                        self.optionValues[5] = thedate.strftime(xbmc.getRegion("dateshort"))
  594.                     self.optionValues[5] = thedate.strftime("%d/%m/%Y")
  595.                     self.saveOptions(channeldata)
  596.             except:
  597.                 pass
  598.  
  599.  
  600.     def runSchedulingRules(self, channelList, channeldata):
  601.         self.log("runSchedulingRules")
  602.         curchan = channelList.runningActionChannel
  603.         self.hasRun = True
  604.  
  605.         try:
  606.             self.startIndex = int(ADDON_SETTINGS.getSetting('Channel_' + str(curchan) + '_lastscheduled'))
  607.         except:
  608.             self.startIndex = 0
  609.  
  610.         if self.appended == True:
  611.             self.startIndex -= self.clearedcount - channeldata.Playlist.size()
  612.  
  613.         if self.startIndex < channeldata.playlistPosition:
  614.             self.startIndex = channeldata.fixPlaylistIndex(channeldata.playlistPosition + 1)
  615.  
  616.             if self.startIndex == 0:
  617.                 self.log("Currently playing the last item, odd")
  618.                 return
  619.  
  620.         # Have all scheduling rules determine the next scheduling time
  621.         self.determineNextTime()
  622.         minimum = self
  623.  
  624.         for rule in channeldata.ruleList:
  625.             if rule.getId() == self.myId:
  626.                 if rule.nextScheduledTime == 0:
  627.                     rule.determineNextTime()
  628.  
  629.                 rule.startIndex = self.startIndex
  630.                 rule.hasRun = True
  631.  
  632.                 if rule.nextScheduledTime < minimum.nextScheduledTime or minimum.nextScheduledTime == 0:
  633.                     minimum = rule
  634.  
  635.         added = True
  636.         newstart = 0
  637.  
  638.         while added == True and minimum.nextScheduledTime != 0:
  639.             added = minimum.addScheduledShow(channelList, channeldata, self.appended)
  640.             newstart = minimum.startIndex
  641.  
  642.             # Determine the new minimum
  643.             if added:
  644.                 minimum.determineNextTime()
  645.  
  646.                 for rule in channeldata.ruleList:
  647.                     if rule.getId() == self.myId:
  648.                         rule.startIndex = newstart
  649.  
  650.                         if rule.nextScheduledTime < minimum.nextScheduledTime or minimum.nextScheduledTime == 0:
  651.                             minimum = rule
  652.  
  653.         ADDON_SETTINGS.setSetting('Channel_' + str(curchan) + '_lastscheduled', str(newstart))
  654.         # Write the channel playlist to a file
  655.         channeldata.Playlist.save(CHANNELS_LOC + 'channel_' + str(curchan) + '.m3u')
  656.  
  657.  
  658.     # Fill in nextScheduledTime
  659.     def determineNextTime(self):
  660.         self.optionValues[5] = self.optionValues[5].replace(' ', '0')
  661.         self.log("determineNextTime " + self.optionValues[5] + " " + self.optionValues[2])
  662.         starttime = 0
  663.         daysofweek = 0
  664.  
  665.         if len(self.optionValues[2]) != 5 or self.optionValues[2][2] != ':':
  666.             self.log("Invalid time")
  667.             self.nextScheduledTime = 0
  668.             return
  669.  
  670.         try:
  671.             # This is how it should be, but there is a bug in XBMC preventing this
  672. #            starttime = time.mktime(time.strptime(self.optionValues[5] + " " + self.optionValues[2], xbmc.getRegion("dateshort") + " %H:%M"))
  673.             starttime = time.mktime(time.strptime(self.optionValues[5] + " " + self.optionValues[2], "%d/%m/%Y %H:%M"))
  674.         except:
  675.             self.log("Invalid date or time")
  676.             self.nextScheduledTime = 0
  677.             return
  678.  
  679.         try:
  680.             tmp = self.optionValues[1]
  681.  
  682.             if tmp.find('M') > -1:
  683.                 daysofweek |= 1
  684.  
  685.             if tmp.find('T') > -1:
  686.                 daysofweek |= 2
  687.  
  688.             if tmp.find('W') > -1:
  689.                 daysofweek |= 4
  690.  
  691.             if tmp.find('H') > -1:
  692.                 daysofweek |= 8
  693.  
  694.             if tmp.find('F') > -1:
  695.                 daysofweek |= 16
  696.  
  697.             if tmp.find('S') > -1:
  698.                 daysofweek |= 32
  699.  
  700.             if tmp.find('U') > -1:
  701.                 daysofweek |= 64
  702.         except:
  703.             self.log("Invalid date or time")
  704.             self.nextScheduledTime = 0
  705.             return
  706.  
  707.         thedate = datetime.datetime.fromtimestamp(starttime)
  708.         delta = datetime.timedelta(days=1)
  709.  
  710.         # If no day selected, assume every day
  711.         if daysofweek == 0:
  712.             daysofweek = 127
  713.  
  714.         # Determine the proper day of the week
  715.         while True:
  716.             if daysofweek & (1 << thedate.weekday()) > 0:
  717.                 break
  718.  
  719.             thedate += delta
  720.  
  721.         self.nextScheduledTime = int(time.mktime(thedate.timetuple()))
  722.  
  723.  
  724.     def saveOptions(self, channeldata):
  725.         curchan = channeldata.channelNumber
  726.         curruleid = self.getRuleIndex(channeldata) + 1
  727.         ADDON_SETTINGS.setSetting('Channel_' + str(curchan) + '_rule_' + str(curruleid) + '_opt_5', self.optionValues[4])
  728.         ADDON_SETTINGS.setSetting('Channel_' + str(curchan) + '_rule_' + str(curruleid) + '_opt_6', self.optionValues[5])
  729.  
  730.  
  731.     # Add a single show (or shows) to the channel at nextScheduledTime
  732.     # This needs to modify the startIndex value if something is added
  733.     def addScheduledShow(self, channelList, channeldata, appending):
  734.         self.log("addScheduledShow")
  735.         chan = 0
  736.         epcount = 0
  737.         startingep = 0
  738.         curchan = channeldata.channelNumber
  739.         curruleid = self.getRuleIndex(channeldata)
  740.         currentchantime = channelList.lastExitTime + channeldata.totalTimePlayed
  741.  
  742.         if channeldata.Playlist.size() == 0:
  743.             return False
  744.  
  745.         try:
  746.             chan = int(self.optionValues[0])
  747.             epcount = int(self.optionValues[3])
  748.             startingep = int(self.optionValues[4]) - 1
  749.         except:
  750.             pass
  751.  
  752.         if startingep < 0:
  753.             startingep = 0
  754.  
  755.         # If the next scheduled show has already passed, then skip it
  756.         if currentchantime > self.nextScheduledTime:
  757.             thedate = datetime.datetime.fromtimestamp(self.nextScheduledTime)
  758.             delta = datetime.timedelta(days=1)
  759.             thedate += delta
  760.             self.optionValues[4] = str(startingep + epcount)
  761. #            self.optionValues[5] = thedate.strftime(xbmc.getRegion("dateshort"))
  762.             self.optionValues[5] = thedate.strftime("%d/%m/%Y")
  763.             self.log("Past the scheduled date and time, skipping")
  764.             self.saveOptions(channeldata)
  765.             return True
  766.  
  767.         if chan > channelList.maxChannels or chan < 1 or epcount < 1:
  768.             self.log("channel number is invalid")
  769.             return False
  770.  
  771.         if len(channelList.channels) < chan or channelList.channels[chan - 1].isSetup == False:
  772.             if channelList.myOverlay.isMaster:
  773.                 channelList.setupChannel(chan, True, True, False)
  774.             else:
  775.                 channelList.setupChannel(chan, True, False, False)
  776.  
  777.         if channelList.channels[chan - 1].Playlist.size() < 1:
  778.             self.log("scheduled channel isn't valid")
  779.             return False
  780.  
  781.         # If the total time played value hasn't been updated
  782.         if appending == False:
  783.             timedif = self.nextScheduledTime - channelList.lastExitTime
  784.         else:
  785.             # If the total time played value HAS been updated
  786.             timedif = self.nextScheduledTime + channeldata.totalTimePlayed - channelList.myOverlay.timeStarted
  787.  
  788.         showindex = 0
  789.  
  790.         # Find the proper location to insert the show(s)
  791.         while timedif > 120 or showindex < self.startIndex:
  792.             timedif -= channeldata.getItemDuration(showindex)
  793.             showindex = channeldata.fixPlaylistIndex(showindex + 1)
  794.  
  795.             # Shows that there was a looparound, so exit.
  796.             if showindex == 0:
  797.                 self.log("Couldn't find a location for the show")
  798.                 return False
  799.  
  800.         # If there is nothing after the selected show index and the time is still
  801.         # too far away, don't do anything
  802.         if (channeldata.Playlist.size() - (showindex + 1) <= 0) and (timedif < -300):
  803.             return False
  804.  
  805.         # rearrange episodes to get an optimal time
  806.         if timedif < -300 and channeldata.isRandom:
  807.             # This is a crappy way to do it, but implementing a subset sum algorithm is
  808.             # a bit daunting at the moment.  Plus this uses a minimum amount of memory, so as
  809.             # a background task it works well.
  810.             lasttime = int(abs(timedif))
  811.  
  812.             # Try a maximum of 5 loops
  813.             for loops in range(5):
  814.                 newtime = self.rearrangeShows(showindex, lasttime, channeldata, channelList)
  815.  
  816.                 if channelList.threadPause() == False:
  817.                     return False
  818.  
  819.                 # If no match found, then stop
  820.                 # If the time difference is less than 2 minutes, also stop
  821.                 if newtime == lasttime or newtime < 120:
  822.                     break
  823.  
  824.                 lasttime = newtime
  825.  
  826.         for i in range(epcount):
  827.             item = PlaylistItem()
  828.             item.duration = channelList.channels[chan - 1].getItemDuration(startingep + i)
  829.             item.filename = channelList.channels[chan - 1].getItemFilename(startingep + i)
  830.             item.description = channelList.channels[chan - 1].getItemDescription(startingep + i)
  831.             item.title = channelList.channels[chan - 1].getItemTitle(startingep + i)
  832.             item.episodetitle = channelList.channels[chan - 1].getItemEpisodeTitle(startingep + i)
  833.             channeldata.Playlist.itemlist.insert(showindex, item)
  834.             channeldata.Playlist.totalDuration += item.duration
  835.             showindex += 1
  836.  
  837.         thedate = datetime.datetime.fromtimestamp(self.nextScheduledTime)
  838.         delta = datetime.timedelta(days=1)
  839.         thedate += delta
  840.         self.startIndex = showindex
  841.         self.optionValues[4] = str(startingep + epcount + 1)
  842. #        self.optionValues[5] = thedate.strftime(xbmc.getRegion("dateshort"))
  843.         self.optionValues[5] = thedate.strftime("%d/%m/%Y")
  844.         self.saveOptions(channeldata)
  845.         self.log("successfully scheduled at index " + str(self.startIndex))
  846.         return True
  847.  
  848.  
  849.     def rearrangeShows(self, showindex, timedif, channeldata, channelList):
  850.         self.log("rearrangeShows " + str(showindex) + " " + str(timedif))
  851.         self.log("start index: " + str(self.startIndex) + ", end index: " + str(showindex))
  852.         matchdur = timedif
  853.         matchidxa = 0
  854.         matchidxb = 0
  855.  
  856.         if self.startIndex >= showindex:
  857.             self.log("Invalid indexes")
  858.             return timedif
  859.  
  860.         if channeldata.Playlist.size() - (showindex + 1) <= 0:
  861.             self.log("No shows after the show index")
  862.             return timedif
  863.  
  864.         for curindex in range(self.startIndex, showindex + 1):
  865.             neededtime = channeldata.getItemDuration(curindex) - timedif
  866.  
  867.             if channelList.threadPause() == False:
  868.                 return timedif
  869.  
  870.             if neededtime > 0:
  871.                 for inx in range(showindex + 1, channeldata.Playlist.size()):
  872.                     curtime = channeldata.getItemDuration(inx) - neededtime
  873.  
  874.                     if abs(curtime) < matchdur:
  875.                         matchdur = abs(curtime)
  876.                         matchidxa = curindex
  877.                         matchidxb = inx
  878.  
  879.         # swap curindex with inx
  880.         if matchdur < abs(timedif):
  881.             self.log("Found with a new timedif of " + str(matchdur) + "!  Swapping " + str(matchidxa) + " with " + str(matchidxb))
  882.             plitema = channeldata.Playlist.itemlist[matchidxa]
  883.             plitemb = channeldata.Playlist.itemlist[matchidxb]
  884.             channeldata.Playlist.itemlist[matchidxa] = plitemb
  885.             channeldata.Playlist.itemlist[matchidxb] = plitema
  886.             return matchdur
  887.  
  888.         self.log("No match found")
  889.         return timedif
  890.  
  891.  
  892.  
  893. class OnlyWatchedRule(BaseRule):
  894.     def __init__(self):
  895.         self.name = "Only Played Watched Items"
  896.         self.optionLabels = []
  897.         self.optionValues = []
  898.         self.myId = 4
  899.         self.actions = RULES_ACTION_JSON
  900.  
  901.  
  902.     def copy(self):
  903.         return OnlyWatchedRule()
  904.  
  905.  
  906.     def runAction(self, actionid, channelList, filedata):
  907.         if actionid == RULES_ACTION_JSON:
  908.             playcount = re.search('"playcount" *: *([0-9]*?),', filedata)
  909.             pc = 0
  910.  
  911.             try:
  912.                 pc = int(playcount.group(1))
  913.             except:
  914.                 pc = 0
  915.  
  916.             if pc == 0:
  917.                 return ''
  918.  
  919.         return filedata
  920.  
  921.  
  922.  
  923. class DontAddChannel(BaseRule):
  924.     def __init__(self):
  925.         self.name = "Don't Play This Channel"
  926.         self.optionLabels = []
  927.         self.optionValues = []
  928.         self.myId = 5
  929.         self.actions = RULES_ACTION_FINAL_MADE | RULES_ACTION_FINAL_LOADED
  930.  
  931.  
  932.     def copy(self):
  933.         return DontAddChannel()
  934.  
  935.  
  936.     def runAction(self, actionid, channelList, channeldata):
  937.         if actionid == RULES_ACTION_FINAL_MADE or actionid == RULES_ACTION_FINAL_LOADED:
  938.             channeldata.isValid = False
  939.  
  940.         return channeldata
  941.  
  942.  
  943.  
  944. class InterleaveChannel(BaseRule):
  945.     def __init__(self):
  946.         self.name = "Interleave Another Channel"
  947.         self.optionLabels = ['Channel Number', 'Min Interleave Count', 'Max Interleave Count', 'Starting Episode', 'Play # Episodes', 'Start Position']
  948.         self.optionValues = ['0', '1', '1', '1', '1', '1']
  949.         self.myId = 6
  950.         self.actions = RULES_ACTION_LIST
  951.  
  952.  
  953.     def copy(self):
  954.         return InterleaveChannel()
  955.  
  956.  
  957.     def getTitle(self):
  958.         if len(self.optionValues[0]) > 0:
  959.             return "Interleave Channel " + self.optionValues[0]
  960.  
  961.         return self.name
  962.  
  963.  
  964.     def onAction(self, act, optionindex):
  965.         self.onActionDigitBox(act, optionindex)
  966.         self.validate()
  967.         return self.optionValues[optionindex]
  968.  
  969.  
  970.     def validate(self):
  971.         self.validateDigitBox(0, 1, 1000, 0)
  972.         self.validateDigitBox(1, 1, 100, 1)
  973.         self.validateDigitBox(2, 1, 100, 1)
  974.         self.validateDigitBox(3, 1, 10000, 1)
  975.         self.validateDigitBox(4, 1, 10000, 1)
  976.         self.validateDigitBox(5, 1, 1, 1)
  977.  
  978.  
  979.     def runAction(self, actionid, channelList, filelist):
  980.         if actionid == RULES_ACTION_LIST:
  981.             self.log("runAction")
  982.             chan = 0
  983.             minint = 0
  984.             maxint = 0
  985.             startingep = 0
  986.             numbereps = 0
  987.             startfrom = 1
  988.             curchan = channelList.runningActionChannel
  989.             curruleid = channelList.runningActionId
  990.             self.validate()
  991.  
  992.             try:
  993.                 chan = int(self.optionValues[0])
  994.                 minint = int(self.optionValues[1])
  995.                 maxint = int(self.optionValues[2])
  996.                 startingep = int(self.optionValues[3])
  997.                 numbereps = int(self.optionValues[4])
  998.                 startfrom = int(self.optionValues[5])
  999.  
  1000.             except:
  1001.                 self.log("Except when reading params")
  1002.  
  1003.             if chan > channelList.maxChannels or chan < 1 or minint < 1 or maxint < 1 or startingep < 1 or numbereps < 1:
  1004.                 return filelist
  1005.  
  1006.             if minint > maxint:
  1007.                 v = minint
  1008.                 minint = maxint
  1009.                 maxint = v
  1010.  
  1011.             if len(channelList.channels) < chan or channelList.channels[chan - 1].isSetup == False:
  1012.                 if channelList.myOverlay.isMaster:
  1013.                     channelList.setupChannel(chan, True, True, False)
  1014.                 else:
  1015.                     channelList.setupChannel(chan, True, False, False)
  1016.  
  1017.             if channelList.channels[chan - 1].Playlist.size() < 1:
  1018.                 self.log("The target channel is empty")
  1019.                 return filelist
  1020.  
  1021.             if startfrom > 0:
  1022.                 startfrom = 1
  1023.             else:
  1024.                 startfrom = 0
  1025.  
  1026.             startfrom -= 1
  1027.            
  1028.             realindex = random.randint(minint, maxint)
  1029.             startindex = 0
  1030.             # Use more memory, but greatly speed up the process by just putting everything into a new list
  1031.             newfilelist = []
  1032.             self.log("Length of original list: " + str(len(filelist)))
  1033.  
  1034.             realindex += startfrom
  1035.  
  1036.             while realindex < len(filelist):
  1037.                 if channelList.threadPause() == False:
  1038.                     return filelist
  1039.  
  1040.                 while startindex < realindex:
  1041.                     newfilelist.append(filelist[startindex])
  1042.                     startindex += 1
  1043.  
  1044.                 # Added FOR loop to iterate interleaving multiple-continuous episodes from chosen channel
  1045.                 for i in range(numbereps):
  1046.                     newstr = str(channelList.channels[chan - 1].getItemDuration(startingep - 1)) + ',' + channelList.channels[chan - 1].getItemTitle(startingep - 1)
  1047.                     newstr += "//" + channelList.channels[chan - 1].getItemEpisodeTitle(startingep - 1)
  1048.                     newstr += "//" + channelList.channels[chan - 1].getItemDescription(startingep - 1) + '\n' + channelList.channels[chan - 1].getItemFilename(startingep - 1)
  1049.                     newfilelist.append(newstr)
  1050.                     # Moved startingep to FOR loop - otherwise it just adds the same file multiple times
  1051.                     startingep += 1
  1052.                    
  1053.                 realindex += random.randint(minint, maxint)
  1054.                
  1055.    
  1056.             while startindex < len(filelist):
  1057.                 newfilelist.append(filelist[startindex])
  1058.                 startindex += 1
  1059.  
  1060.             startingep = channelList.channels[chan - 1].fixPlaylistIndex(startingep) + 1
  1061.             # Write starting episode
  1062.             self.optionValues[2] = str(startingep)
  1063.             ADDON_SETTINGS.setSetting('Channel_' + str(curchan) + '_rule_' + str(curruleid + 1) + '_opt_4', self.optionValues[2])
  1064.             self.log("Done interleaving, new length is " + str(len(newfilelist)))
  1065.             return newfilelist
  1066.  
  1067.         return filelist
  1068.  
  1069.  
  1070.  
  1071. class ForceRealTime(BaseRule):
  1072.     def __init__(self):
  1073.         self.name = "Force Real-Time Mode"
  1074.         self.optionLabels = []
  1075.         self.optionValues = []
  1076.         self.myId = 7
  1077.         self.actions = RULES_ACTION_BEFORE_TIME
  1078.  
  1079.  
  1080.     def copy(self):
  1081.         return ForceRealTime()
  1082.  
  1083.  
  1084.     def runAction(self, actionid, channelList, channeldata):
  1085.         if actionid == RULES_ACTION_BEFORE_TIME:
  1086.             channeldata.mode &= ~MODE_STARTMODES
  1087.             channeldata.mode |= MODE_REALTIME
  1088.  
  1089.         return channeldata
  1090.  
  1091.  
  1092.  
  1093. class AlwaysPause(BaseRule):
  1094.     def __init__(self):
  1095.         self.name = "Pause When Not Watching"
  1096.         self.optionLabels = []
  1097.         self.optionValues = []
  1098.         self.myId = 8
  1099.         self.actions = RULES_ACTION_BEFORE_TIME
  1100.  
  1101.  
  1102.     def copy(self):
  1103.         return AlwaysPause()
  1104.  
  1105.  
  1106.     def runAction(self, actionid, channelList, channeldata):
  1107.         if actionid == RULES_ACTION_BEFORE_TIME:
  1108.             channeldata.mode |= MODE_ALWAYSPAUSE
  1109.  
  1110.         return channeldata
  1111.  
  1112.  
  1113. class ForceResume(BaseRule):
  1114.     def __init__(self):
  1115.         self.name = "Force Resume Mode"
  1116.         self.optionLabels = []
  1117.         self.optionValues = []
  1118.         self.myId = 9
  1119.         self.actions = RULES_ACTION_BEFORE_TIME
  1120.  
  1121.  
  1122.     def copy(self):
  1123.         return ForceResume()
  1124.  
  1125.  
  1126.     def runAction(self, actionid, channelList, channeldata):
  1127.         if actionid == RULES_ACTION_BEFORE_TIME:
  1128.             channeldata.mode &= ~MODE_STARTMODES
  1129.             channeldata.mode |= MODE_RESUME
  1130.  
  1131.         return channeldata
  1132.  
  1133.  
  1134.  
  1135. class ForceRandom(BaseRule):
  1136.     def __init__(self):
  1137.         self.name = "Force Random Mode"
  1138.         self.optionLabels = []
  1139.         self.optionValues = []
  1140.         self.myId = 10
  1141.         self.actions = RULES_ACTION_BEFORE_TIME
  1142.  
  1143.  
  1144.     def copy(self):
  1145.         return ForceRandom()
  1146.  
  1147.  
  1148.     def runAction(self, actionid, channelList, channeldata):
  1149.         if actionid == RULES_ACTION_BEFORE_TIME:
  1150.             channeldata.mode &= ~MODE_STARTMODES
  1151.             channeldata.mode |= MODE_RANDOM
  1152.  
  1153.         return channeldata
  1154.  
  1155.  
  1156.  
  1157. class OnlyUnWatchedRule(BaseRule):
  1158.     def __init__(self):
  1159.         self.name = "Only Played Unwatched Items"
  1160.         self.optionLabels = []
  1161.         self.optionValues = []
  1162.         self.myId = 11
  1163.         self.actions = RULES_ACTION_JSON
  1164.  
  1165.  
  1166.     def copy(self):
  1167.         return OnlyUnWatchedRule()
  1168.  
  1169.  
  1170.     def runAction(self, actionid, channelList, filedata):
  1171.         if actionid == RULES_ACTION_JSON:
  1172.             playcount = re.search('"playcount" *: *([0-9]*?),', filedata)
  1173.             pc = 0
  1174.  
  1175.             try:
  1176.                 pc = int(playcount.group(1))
  1177.             except:
  1178.                 pc = 0
  1179.  
  1180.             if pc > 0:
  1181.                 return ''
  1182.  
  1183.         return filedata
  1184.  
  1185.  
  1186.  
  1187. class PlayShowInOrder(BaseRule):
  1188.     def __init__(self):
  1189.         self.name = "Play TV Shows In Order"
  1190.         self.optionLabels = []
  1191.         self.optionValues = []
  1192.         self.showInfo = []
  1193.         self.myId = 12
  1194.         self.actions = RULES_ACTION_START | RULES_ACTION_JSON | RULES_ACTION_LIST
  1195.  
  1196.  
  1197.     def copy(self):
  1198.         return PlayShowInOrder()
  1199.  
  1200.  
  1201.     def runAction(self, actionid, channelList, param):
  1202.         if actionid == RULES_ACTION_START:
  1203.             del self.showInfo[:]
  1204.  
  1205.         if actionid == RULES_ACTION_JSON:
  1206.             self.storeShowInfo(channelList, param)
  1207.  
  1208.         if actionid == RULES_ACTION_LIST:
  1209.             return self.sortShows(channelList, param)
  1210.  
  1211.         return param
  1212.  
  1213.  
  1214.     def storeShowInfo(self, channelList, filedata):
  1215.         # Store the filename, season, and episode number
  1216.         match = re.search('"file" *: *"(.*?)",', filedata)
  1217.  
  1218.         if match:
  1219.             showtitle = re.search('"showtitle" *: *"(.*?)"', filedata)
  1220.             season = re.search('"season" *: *(.*?),', filedata)
  1221.             episode = re.search('"episode" *: *(.*?),', filedata)
  1222.  
  1223.             try:
  1224.                 seasonval = int(season.group(1))
  1225.                 epval = int(episode.group(1))
  1226.                 self.showInfo.append([showtitle.group(1), match.group(1).replace("\\\\", "\\"), seasonval, epval])
  1227.             except:
  1228.                 pass
  1229.  
  1230.  
  1231.     def sortShows(self, channelList, filelist):
  1232.         if len(self.showInfo) == 0:
  1233.             return filelist
  1234.  
  1235.         newfilelist = []
  1236.         self.showInfo.sort(key=lambda seep: seep[3])
  1237.         self.showInfo.sort(key=lambda seep: seep[2])
  1238.         self.showInfo.sort(key=lambda seep: seep[0])
  1239.  
  1240.         # Create a new array. It will have 2 dimensions.  The first dimension is a certain show.  This show
  1241.         # name is in index 0 of the second dimension.  The currently used index is in index 1.  The other
  1242.         # items are the file names in season / episode order.
  1243.         showlist = []
  1244.         curshow = self.showInfo[0][0]
  1245.         showlist.append([])
  1246.         showlist[0].append(curshow.lower())
  1247.         showlist[0].append(0)
  1248.  
  1249.         for item in self.showInfo:
  1250.             if channelList.threadPause() == False:
  1251.                 return filelist
  1252.  
  1253.             if item[0] != curshow:
  1254.                 curshow = item[0]
  1255.                 showlist.append([])
  1256.                 showlist[-1].append(curshow.lower())
  1257.                 showlist[-1].append(0)
  1258.  
  1259.             showstr = self.findInFileList(filelist, item[1])
  1260.  
  1261.             if len(showstr) > 0:
  1262.                 showlist[-1].append(showstr)
  1263.  
  1264.         curindex = 0
  1265.  
  1266.         for item in filelist:
  1267.             if channelList.threadPause() == False:
  1268.                 return filelist
  1269.  
  1270.             # First, get the current show for the entry
  1271.             pasttime = item.find(',')
  1272.  
  1273.             if pasttime > -1:
  1274.                 endofshow = item.find("//")
  1275.  
  1276.                 if endofshow > -1:
  1277.                     show = item[pasttime + 1:endofshow].lower()
  1278.  
  1279.                     for entry in showlist:
  1280.                         if entry[0] == show:
  1281.                             if len(entry) == 2:
  1282.                                 break
  1283.  
  1284.                             filelist[curindex] = entry[entry[1] + 2]
  1285.                             entry[1] += 1
  1286.  
  1287.                             if entry[1] > (len(entry) - 3):
  1288.                                 entry[1] = 0
  1289.  
  1290.                             break
  1291.  
  1292.             curindex += 1
  1293.  
  1294.         return filelist
  1295.  
  1296.  
  1297.     def findInFileList(self, filelist, text):
  1298.         text = text.lower()
  1299.  
  1300.         for item in filelist:
  1301.             tmpitem = item.lower()
  1302.  
  1303.             if tmpitem.find(text) > -1:
  1304.                 return item
  1305.  
  1306.         return ''
  1307.  
  1308.  
  1309.  
  1310. class SetResetTime(BaseRule):
  1311.     def __init__(self):
  1312.         self.name = "Reset Every x Days"
  1313.         self.optionLabels = ['Number of Days']
  1314.         self.optionValues = ['5']
  1315.         self.myId = 13
  1316.         self.actions = RULES_ACTION_START
  1317.  
  1318.  
  1319.     def copy(self):
  1320.         return SetResetTime()
  1321.  
  1322.  
  1323.     def getTitle(self):
  1324.         if len(self.optionValues[0]) > 0:
  1325.             if self.optionValues[0] == '1':
  1326.                 return "Reset Every Day"
  1327.             else:
  1328.                 return "Reset Every " + self.optionValues[0] + " Days"
  1329.  
  1330.         return self.name
  1331.  
  1332.  
  1333.     def onAction(self, act, optionindex):
  1334.         self.onActionDigitBox(act, optionindex)
  1335.         self.validate()
  1336.         return self.optionValues[optionindex]
  1337.  
  1338.  
  1339.     def validate(self):
  1340.         self.validateDigitBox(0, 1, 50, '')
  1341.  
  1342.  
  1343.     def runAction(self, actionid, channelList, channeldata):
  1344.         if actionid == RULES_ACTION_START:
  1345.             curchan = channeldata.channelNumber
  1346.             numdays = 0
  1347.  
  1348.             try:
  1349.                 numdays = int(self.optionValues[0])
  1350.             except:
  1351.                 pass
  1352.  
  1353.             if numdays <= 0:
  1354.                 self.log("Invalid day count: " + str(numdays))
  1355.                 return channeldata
  1356.  
  1357.             rightnow = int(time.time())
  1358.             nextreset = rightnow
  1359.  
  1360.             try:
  1361.                 nextreset = int(ADDON_SETTINGS.getSetting('Channel_' + str(curchan) + '_SetResetTime'))
  1362.             except:
  1363.                 pass
  1364.  
  1365.             if rightnow >= nextreset:
  1366.                 channeldata.isValid = False
  1367.                 ADDON_SETTINGS.setSetting('Channel_' + str(curchan) + '_changed', 'True')
  1368.                 nextreset = rightnow + (60 * 60 * 24 * numdays)
  1369.                 ADDON_SETTINGS.setSetting('Channel_' + str(curchan) + '_SetResetTime', str(nextreset))
  1370.  
  1371.         return channeldata
  1372.  
  1373.  
  1374.  
  1375. class HandleIceLibrary(BaseRule):
  1376.     def __init__(self):
  1377.         self.name = "IceLibrary Streams"
  1378.         self.optionLabels = ['Include Streams']
  1379.         self.optionValues = ['Yes']
  1380.         self.myId = 14
  1381.         self.actions = RULES_ACTION_START | RULES_ACTION_FINAL_MADE | RULES_ACTION_FINAL_LOADED
  1382.         self.selectBoxOptions = [["Yes", "No"]]
  1383.  
  1384.  
  1385.     def copy(self):
  1386.         return HandleIceLibrary()
  1387.  
  1388.  
  1389.     def getTitle(self):
  1390.         if self.optionValues[0] == 'Yes':
  1391.             return 'Include IceLibrary Streams'
  1392.         else:
  1393.             return 'Exclude IceLibrary Streams'
  1394.  
  1395.  
  1396.     def onAction(self, act, optionindex):
  1397.         self.onActionSelectBox(act, optionindex)
  1398.         return self.optionValues[optionindex]
  1399.  
  1400.  
  1401.     def runAction(self, actionid, channelList, channeldata):
  1402.         if actionid == RULES_ACTION_START:
  1403.             self.storedIceLibValue = channelList.incIceLibrary
  1404.             self.log("Option for IceLibrary is " + self.optionValues[0])
  1405.  
  1406.             if self.optionValues[0] == 'Yes':
  1407.                 channelList.incIceLibrary = True
  1408.             else:
  1409.                 channelList.incIceLibrary = False
  1410.         elif actionid == RULES_ACTION_FINAL_MADE or actionid == RULES_ACTION_FINAL_LOADED:
  1411.             channelList.incIceLibrary = self.storedIceLibValue
  1412.  
  1413.         return channeldata
  1414.  
  1415.  
  1416.  
  1417. class HandleChannelLogo(BaseRule):
  1418.     def __init__(self):
  1419.         self.name = "Channel Logo"
  1420.         self.optionLabels = ['Display the Logo']
  1421.         self.optionValues = ['Yes']
  1422.         self.myId = 15
  1423.         self.actions = RULES_ACTION_OVERLAY_SET_CHANNEL | RULES_ACTION_OVERLAY_SET_CHANNEL_END
  1424.         self.selectBoxOptions = [["Yes", "No"]]
  1425.  
  1426.  
  1427.     def copy(self):
  1428.         return HandleChannelLogo()
  1429.  
  1430.  
  1431.     def getTitle(self):
  1432.         if self.optionValues[0] == 'Yes':
  1433.             return 'Display the Channel Logo'
  1434.         else:
  1435.             return 'Hide the Channel Logo'
  1436.  
  1437.  
  1438.     def onAction(self, act, optionindex):
  1439.         self.onActionSelectBox(act, optionindex)
  1440.         return self.optionValues[optionindex]
  1441.  
  1442.  
  1443.     def runAction(self, actionid, overlay, channeldata):
  1444.         if actionid == RULES_ACTION_OVERLAY_SET_CHANNEL:
  1445.             self.storedLogoValue = overlay.showChannelBug
  1446.  
  1447.             if self.optionValues[0] == 'Yes':
  1448.                 overlay.showChannelBug = True
  1449.                 self.log("setting channel bug to true")
  1450.             else:
  1451.                 overlay.showChannelBug = False
  1452.         elif actionid == RULES_ACTION_OVERLAY_SET_CHANNEL_END:
  1453.             overlay.showChannelBug = self.storedLogoValue
  1454.             self.log("set channel bug to " + str(overlay.showChannelBug))
  1455.  
  1456.         return channeldata
  1457.  
  1458.  
  1459.  
  1460. class EvenShowsRule(BaseRule):
  1461.     def __init__(self):
  1462.         self.name = "Even Show Distribution"
  1463.         self.optionLabels = ['Same Show Eps in a Row']
  1464.         self.optionValues = ['2']
  1465.         self.myId = 16
  1466.         self.actions = RULES_ACTION_LIST
  1467.  
  1468.  
  1469.     def copy(self):
  1470.         return EvenShowsRule()
  1471.  
  1472.  
  1473.     def getTitle(self):
  1474.         return self.name
  1475.  
  1476.  
  1477.     def onAction(self, act, optionindex):
  1478.         self.onActionDigitBox(act, optionindex)
  1479.         self.validate()
  1480.         return self.optionValues[optionindex]
  1481.  
  1482.  
  1483.     def validate(self):
  1484.         self.validateDigitBox(0, 1, 20, 1)
  1485.  
  1486.  
  1487.     def runAction(self, actionid, channelList, filelist):
  1488.         if actionid == RULES_ACTION_LIST:
  1489.             self.validate()
  1490.            
  1491.             try:
  1492.                 opt = int(self.optionValues[0])
  1493.                 self.log("Allowed shows in a row: " + str(opt))
  1494.                 lastshow = ''
  1495.                 realindex = 0
  1496.                 inarow = 0
  1497.  
  1498.                 for index in range(len(filelist)):
  1499.                     item = filelist[index]
  1500.                     self.log("index " + str(index) + " is " + item)
  1501.                     loc = item.find(',')
  1502.  
  1503.                     if loc > -1:
  1504.                         loc2 = item.find("//")
  1505.  
  1506.                         if loc2 > -1:
  1507.                             showname = item[loc + 1:loc2]
  1508.                             showname = showname.lower()
  1509.  
  1510.                             if showname == lastshow:
  1511.                                 inarow += 1
  1512.                                 self.log("same show now at " + str(inarow))
  1513.                                
  1514.                                 if inarow >= opt:
  1515.                                     nextline = self.insertNewShow(filelist, lastshow, index)
  1516.                                    
  1517.                                     if nextline == '':
  1518.                                         filelist = filelist[:index]
  1519.                                         return filelist
  1520.                                     else:
  1521.                                         filelist.insert(index, nextline)
  1522.                                         lastshow = ''
  1523.                             else:
  1524.                                 lastshow = showname
  1525.                                 self.log("new show: " + lastshow)
  1526.                                 inarow = 0
  1527.             except:
  1528.                 pass
  1529.  
  1530.         return filelist
  1531.        
  1532.        
  1533.     def insertNewShow(self, filelist, lastshow, startindex):
  1534.         self.log("insertNewShow: " + str(startindex) + ", " + str(len(filelist)))
  1535.         for index in range(startindex + 1, len(filelist)):
  1536.             item = filelist[index]
  1537.             self.log("insertNewShow index " + str(index) + " is " + item)
  1538.             loc = item.find(',')
  1539.  
  1540.             if loc > -1:
  1541.                 loc2 = item.find("//")
  1542.  
  1543.                 if loc2 > -1:
  1544.                     showname = item[loc + 1:loc2]
  1545.                     showname = showname.lower()
  1546.  
  1547.                     if showname != lastshow:
  1548.                         self.log("insertNewShow found " + showname)
  1549.                         filelist.pop(index)
  1550.                         return item
  1551.                        
  1552.         return ''
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement