[AutomaticSystemCleanup]V0.1.9:
[enigma2-plugins.git] / automaticcleanup / src / plugin.py
1 # -*- coding: utf-8 -*-
2 #
3 #  AutomaticCleanup E2
4 #
5 #  $Id$
6 #
7 #  Coded by JuSt611  2011
8 #  Derived from Automatic Timerlist Cleanup plugin written by Dr. Best
9 #  and EMC plugin written by moveq
10 #  and placed in the public domain. They have my thanks.
11 #  Support: http://www.i-have-a-dreambox.com/wbb2/thread.php?threadid=159095
12 #
13 #  Provided with no warranties of any sort.
14 #
15 #  This plugin is licensed under the Creative Commons 
16 #  Attribution-NonCommercial-ShareAlike 3.0 Unported 
17 #  License. To view a copy of this license, visit
18 #  http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
19 #  Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
20 #
21 #  Alternatively, this plugin may be distributed and executed on hardware which
22 #  is licensed by Dream Multimedia GmbH.
23
24 #  This plugin is NOT free software. It is open source, you are allowed to
25 #  modify it (if you keep the license), but it may not be commercially 
26 #  distributed other than under the conditions noted above.
27 #
28
29 # for localized messages
30 from . import _
31
32 # Plugin definition
33 from Plugins.Plugin import PluginDescriptor
34
35 # Enigma
36 from enigma import eTimer
37 from time import mktime, strftime, strptime, time, localtime
38
39 # Timer
40 from timer import TimerEntry
41
42 # OS
43 from glob import glob
44 from os import path, remove, listdir
45
46 # GUI (Components)
47 from Components.ActionMap import ActionMap
48 from Components.Sources.StaticText import StaticText
49
50 # Configuration
51 from Components.config import config, ConfigSubsection, ConfigSelection, getConfigListEntry, ConfigYesNo, ConfigText
52 from Components.Sources.StaticText import StaticText
53
54 # MessageBox
55 from Screens.MessageBox import MessageBox
56
57 # GUI (Screens)
58 from Screens.Screen import Screen
59 from Components.ConfigList import ConfigListScreen
60
61 # GUI (Summary)
62 from Screens.Setup import SetupSummary
63
64
65 ###############################################################################        
66 VERSION = "0.1.9"
67 # History:
68 # 0.1.2 First public version
69 # 0.1.3 Prevention of timerlist cleanup if duplicated with EMC plugin
70 #       Fix producing crash of Softwaremanager
71 #       Show version in print messages for ease of crashlog check
72 # 0.1.4 Option added to cleanup orphaned movie files
73 #       Delete expired disabled timerlist entries, except those marked "repeated"
74 #       Performance improvement: Check timerentry StateChange only if option
75 #       "Timerlist cleanup immediately after recording" is set
76 #       Help button added
77 #       Cleanup crashlog feature invalidated for DMM plugin feed distribution
78 # 0.1.5 Fix infinite loop when timerlist cleanup is set to option "immediately after recording"
79 # 0.1.6 Fix crash if settings backup file date ends with "2"
80 # 0.1.7 Cleanup of orphaned movie files modified to support EMC v3
81 # 0.1.8 Performance improvement: avoid duplicate cleanup of orphaned movie files if EMC movie_homepath is same as E2 moviePath
82 # 0.1.9 Remove orphaned files in movie path marked for E2 smooth deletion (during session start only, to avoid conflicting E2)
83 #               Simplify translation code: Setting the os LANGUAGE variable isn't needed anymore
84 ###############################################################################  
85 pluginPrintname = "[AutomaticCleanup Ver. %s]" %VERSION
86 DEBUG = False # If set True, plugin won't remove any file physically, instead prints file names in log for verification purposes
87 ###############################################################################
88
89 config.plugins.AutomaticCleanup = ConfigSubsection()
90 config.plugins.AutomaticCleanup.deleteCrashlogsOlderThan = ConfigSelection(default = "-1",
91         choices = [("-1",_("void"))])
92 config.plugins.AutomaticCleanup.keepCrashlogs = ConfigSelection(default = "-1",
93         choices = [("-1",_("all"))])
94 config.plugins.AutomaticCleanup.deleteSettingsOlderThan = ConfigSelection(default = "-1",
95         choices = [("-1",_("cleanup disabled")),("183",_("older than 6 months")),("91",_("older than 3 months")),("28",_("older than 4 weeks")),("14",_("older than 2 weeks")),("7",_("older than 1 week"))])
96 config.plugins.AutomaticCleanup.keepSettings = ConfigSelection(default = "-1",
97         choices = [("-1",_("all")), ("10",_("last 10")),("5",_("last 5")),("3",_("last 3")),("2",_("last 2")),("1",_("only last one"))])
98 config.plugins.AutomaticCleanup.deleteTimersOlderThan = ConfigSelection(default = "-1",
99         choices = [("-1",_("cleanup disabled")),("42",_("older than 6 weeks")),("28",_("older than 4 weeks")),("14",_("older than 2 weeks")),("7",_("older than 1 week")),("3",_("older than 3 days")),("1",_("older than 1 day")),("0",_("immediately after recording"))])
100 config.plugins.AutomaticCleanup.deleteOrphanedMovieFiles = ConfigYesNo(default = False)
101
102
103 class AutomaticCleanupSetup(Screen, ConfigListScreen): # config
104
105         skin = """
106                 <screen name="SystemCleanup" position="center,center" size="630,315" title="Automatic System Cleanup Setup" >
107                         <ePixmap pixmap="skin_default/buttons/red.png" position="5,5" zPosition="0" size="140,40" transparent="1" alphatest="on" />
108                         <ePixmap pixmap="skin_default/buttons/green.png" position="165,5" zPosition="0" size="140,40" transparent="1" alphatest="on" />
109                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="325,5" zPosition="0" size="140,40" transparent="1" alphatest="on" />
110                         <ePixmap pixmap="skin_default/buttons/blue.png" position="485,5" zPosition="0" size="140,40" transparent="1" alphatest="on" />
111                         
112                         <widget render="Label" source="key_red" position="5,5" size="140,40" zPosition="2" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
113                         <widget render="Label" source="key_green" position="165,5" size="140,40" zPosition="2" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
114                         <widget render="Label" source="key_yellow" position="325,5" size="140,40" zPosition="2" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
115
116                         <widget name="config" position="5,60" size="620,155" scrollbarMode="showOnDemand" />
117
118                         <ePixmap pixmap="skin_default/div-h.png" position="0,220" zPosition="1" size="630,2" />
119                         <widget source="help" render="Label" position="5,235" size="620,75" font="Regular;21" /> 
120                 </screen>"""
121
122         def __init__(self, session):
123                 Screen.__init__(self, session)
124                 
125                 #Summary
126                 self.setup_title = _("Automatic System Cleanup Setup")
127
128                 self.onChangedEntry = []                
129
130                 self.list = [
131                         getConfigListEntry(_("Delete system setting backups"), config.plugins.AutomaticCleanup.deleteSettingsOlderThan,
132                                 _("Specify, how long system setting backups shall be kept at most (even if maximum number is not yet exceeded). Latest backup will be kept anyway!")),
133                         getConfigListEntry(_("Maximum number of system setting backups"), config.plugins.AutomaticCleanup.keepSettings,
134                                 _("Maximum number of system setting backups to keep, regardless of retention period.")),
135                         getConfigListEntry(_("Delete orphaned movie files"), config.plugins.AutomaticCleanup.deleteOrphanedMovieFiles,
136                                 _("If enabled, orphaned movie files will be automatically deleted from movie directories.")),
137                         getConfigListEntry(_("Delete crashlogs"), config.plugins.AutomaticCleanup.deleteCrashlogsOlderThan,
138                                 _('Sorry, this feature is not available due to license reasons. To get the full version, please search the web for "dreambox automaticcleanup."')),
139                         getConfigListEntry(_("Maximum number of crashlogs"), config.plugins.AutomaticCleanup.keepCrashlogs,
140                                 _('Sorry, this feature is not available due to license reasons. To get the full version, please search the web for "dreambox automaticcleanup."')),
141                         ]
142
143                 try:
144                         # try to import EMC module to check for its existence
145                         from Plugins.Extensions.EnhancedMovieCenter.EnhancedMovieCenter import EnhancedMovieCenterMenu 
146                         self.EMC_timer_autocln = config.EMC.timer_autocln.value
147                 except ImportError, ie:
148                         print pluginPrintname, "EMC not installed:", ie
149                         self.EMC_timer_autocln = False
150                         
151                 if self.EMC_timer_autocln: # Timer cleanup enabled in EMC plugin?
152                         self.list.append(getConfigListEntry(_("Delete timerlist entries"), config.plugins.AutomaticCleanup.deleteTimersOlderThan,
153                                 _("Timerlist cleanup is enabled in EMC plugin! To avoid crashes, we won't delete entries whilst this option is enabled in EMC."))) # Avoid duplicate cleanup
154                 else:
155                         self.list.append(getConfigListEntry(_("Delete timerlist entries"), config.plugins.AutomaticCleanup.deleteTimersOlderThan,
156                                 _("Specify, how long expired timer list entries shall be kept at most. Deactivated repeat timer entries won't be deleted ever.")))
157                         
158                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
159                 
160                 def selectionChanged():
161                         if self["config"].current:
162                                 self["config"].current[1].onDeselect(self.session)
163                         self["config"].current = self["config"].getCurrent()
164                         if self["config"].current:
165                                 self["config"].current[1].onSelect(self.session)
166                         for x in self["config"].onSelectionChanged:
167                                 x()
168                                 
169                 self["config"].selectionChanged = selectionChanged
170                 self["config"].onSelectionChanged.append(self.configHelp)
171
172                 # Initialize Buttons
173                 self["key_red"] = StaticText(_("Cancel"))
174                 self["key_green"] = StaticText(_("OK"))
175                 self["key_yellow"] = StaticText(_("Help"))
176
177                 self["help"] = StaticText()             
178
179                 # Define Actions                
180                 self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
181                         {
182                         "red": self.keyCancel,
183                         "green": self.keySave,
184                         "yellow": self.keyHelp,         
185                         "cancel": self.keyCancel,
186                         "save": self.keySave,
187                         "ok": self.keySave,
188                         }, -2)
189
190                 # Trigger change
191                 self.changed()
192
193                 self.onLayoutFinish.append(self.setCustomTitle)
194
195         def setCustomTitle(self):
196                 self.setTitle(' '.join((_("Automatic System Cleanup Setup"), _("Ver."), VERSION)))
197
198         def configHelp(self):
199                 self["help"].text = self["config"].getCurrent()[2]
200
201         def changed(self):
202                 for x in self.onChangedEntry:
203                         try:
204                                 x()
205                         except Exception:
206                                 pass    
207                         
208         def getCurrentEntry(self):
209                 return self["config"].getCurrent()[0]
210
211         def getCurrentValue(self):
212                 return str(self["config"].getCurrent()[1].getText())
213
214         def createSummary(self):
215                 return SetupSummary
216                 
217         def keyHelp(self):            
218                 self.session.open(MessageBox,
219                         _('Cleanup timerlist, orphaned movie files and stored setting backups automatically.\n\nModify the settings to match your preferences. More detailed explanations given with each adjustable option.'), 
220                         MessageBox.TYPE_INFO)
221
222
223 class AutomaticCleanup:
224         if DEBUG:
225                 checkInterval = 60 * 3 # check timerlist every 3 minutes
226         else:
227                 checkInterval = 60 * 60 * 24 # check timerlist every 24 hours
228
229         def __init__(self, session):
230                 self.session = session
231                 if DEBUG: print pluginPrintname, "Starting in debugging mode..."
232                 else: print pluginPrintname, "Starting AutomaticCleanup..."
233                 self.timer = eTimer() # check timer
234                 self.timer.callback.append(self.doCleanup)
235                 self.initialState = True
236                 self.doCleanup() # always check immediately after starting plugin
237                 self.initialState = False
238                 config.plugins.AutomaticCleanup.deleteSettingsOlderThan.addNotifier(self.configChange, initial_call = False)
239                 config.plugins.AutomaticCleanup.keepSettings.addNotifier(self.configChange, initial_call = False)
240                 config.plugins.AutomaticCleanup.deleteOrphanedMovieFiles.addNotifier(self.configChange, initial_call = False)
241                 config.plugins.AutomaticCleanup.deleteTimersOlderThan.addNotifier(self.configChange, initial_call = False)
242                 self.session.nav.RecordTimer.on_state_change.append(self.timerentryOnStateChange)
243                 
244         def configChange(self, configElement = None):
245                 # config was changed in setup
246                 if self.timer.isActive(): # stop timer if running
247                         self.timer.stop()
248                 print pluginPrintname, "Setup values have changed"
249                 if self.cleanupEnabled(): # check only if feature is enabled
250                         print pluginPrintname, "Next automatic timerlist cleanup at ", strftime("%c", localtime(time()+120))
251                         self.timer.startLongTimer(120) # check timerlist in 2 minutes after changing 
252                 else:
253                         print pluginPrintname, "Cleanup disabled"
254                         
255         def doCleanup(self):
256                 if self.timer.isActive(): # stop timer if running
257                         self.timer.stop()
258                 if self.cleanupEnabled(): # check only if feature is enabled
259                         self.cleanupSettings()
260                         self.cleanupMovies()
261                         self.cleanupTimerlist()
262                         print pluginPrintname, "Next automatic cleanup at", strftime("%c", localtime(time()+self.checkInterval))
263                         self.timer.startLongTimer(self.checkInterval) # check again after x secs
264                 else:
265                         print pluginPrintname, "Cleanup disabled"
266                 
267         def cleanupSettings(self):
268                 if int(config.plugins.AutomaticCleanup.keepSettings.value) > -1 or int(config.plugins.AutomaticCleanup.deleteSettingsOlderThan.value) > -1: # check only if feature is enabled
269                         print pluginPrintname, "Cleaning up setting backups"
270                         self.backupPath = self.getBackupPath()
271                         if (path.exists(self.backupPath) == False):
272                                 print pluginPrintname, "No backup directory available!"
273                                 return
274                         self.settingList = glob(self.backupPath + '/*-enigma2settingsbackup.tar.gz')
275                         self.numSettings = len(self.settingList)
276                         if self.numSettings == 0:
277                                 print pluginPrintname, "No deletable setting backup found!"
278                         else:
279                                 self.settingList.sort()
280                                 self.filterSettings()
281                 else:
282                         print pluginPrintname, "Setting backups cleanup disabled"
283                                 
284         def filterSettings(self):
285                 self.deleteList = [ ]
286                 
287                 keep = int(config.plugins.AutomaticCleanup.keepSettings.value)
288                 if keep > -1: # don't keep all setting backups
289                         if keep > self.numSettings:
290                                 print pluginPrintname, "Found %i setting backup(s), keeping max %i" %(self.numSettings+1, keep) # increment for uncounted latest
291                         else:
292                                 print pluginPrintname, "Keeping the %i latest settings"  % keep
293                                 # add all settings > config.plugins.AutomaticCleanup.keepSettings.value
294                                 # to a new list. the settings in this new list will be deleted later.
295                                 self.deleteList = self.settingList[0 : self.numSettings - keep + 1] # increment for uncounted latest
296
297                 if int(config.plugins.AutomaticCleanup.deleteSettingsOlderThan.value) > -1:
298                         print pluginPrintname, "Searching for outdated setting backup(s)"
299                         now = int(time())
300                         # 86400 = one day in seconds
301                         deleteOlderThan = now - 86400 * int(config.plugins.AutomaticCleanup.deleteSettingsOlderThan.value)
302                         
303                         if keep > -1: # don't keep all settings
304                                 # start checking the range in self.settingList which wasn't copied to
305                                 # self.deleteList
306                                 i = self.numSettings - keep + 1 # increment for uncounted latest
307                                 # if there are less settings than we want to keep, check the
308                                 # whole settings list
309                                 if i < 0:
310                                         i = 0
311                         else:
312                                 i = 0
313                         
314                         while i < self.numSettings:
315                                 self.backupPath = self.getBackupPath()
316                                 backupDatePos = self.settingList[i].rfind('/') + 1
317                                 backupDate = self.settingList[i][backupDatePos:backupDatePos + 10]
318                                 if DEBUG: print pluginPrintname, "Backup path: %s, file: %s, date: %s"  %(self.backupPath, self.settingList[i], backupDate)
319                                 settingTime = mktime(strptime(backupDate, "%Y-%m-%d"))
320                                 if int(settingTime) > deleteOlderThan:
321                                         break
322                                 self.deleteList.append(self.settingList[i])
323                                 i += 1
324                         
325                         print pluginPrintname, "Found %i outdated setting backup(s)"  % i
326
327                 for setting in self.deleteList:
328                         if DEBUG: print pluginPrintname, "Setting backup to delete:", setting
329                         else: remove(setting)
330
331                 print pluginPrintname, "Deleted %i setting backup(s)"  % len(self.deleteList)
332                                                 
333         def getBackupPath(self):        
334                 try:
335                         # try to import SoftwareManager module to check for its existence
336                         from Plugins.SystemPlugins.SoftwareManager.plugin import UpdatePluginMenu
337                         backuppath = config.plugins.configurationbackup.backuplocation.value
338                 except ImportError, ie:
339                         print pluginPrintname, "SoftwareManager not installed:", ie
340                         backuppath = '/media/hdd/'
341                 if backuppath.endswith('/'): return (backuppath + 'backup')
342                 else: return (backuppath + '/backup')           
343                 
344         def cleanupTimerlist(self):
345                 try:
346                         # try to import EMC module to check for its existence
347                         from Plugins.Extensions.EnhancedMovieCenter.EnhancedMovieCenter import EnhancedMovieCenterMenu 
348                         self.EMC_timer_autocln = config.EMC.timer_autocln.value
349                 except ImportError, ie:
350                         print pluginPrintname, "EMC not installed:", ie
351                         self.EMC_timer_autocln = False
352                         
353                 if int(config.plugins.AutomaticCleanup.deleteTimersOlderThan.value) > -1:  # check only if feature is enabled
354                         if self.EMC_timer_autocln:      # Duplicate cleanup?
355                                 print pluginPrintname, "Timerlist cleanup skipped because it is already enabled in EMC" # we skip check to avoid crash
356                         else:
357                                 expiration = time() - int(config.plugins.AutomaticCleanup.deleteTimersOlderThan.value) * 86400 # calculate end time for comparison with processed timers
358                                 print pluginPrintname, "Cleaning up timerlist-entries older than", strftime("%c", localtime(expiration))
359                                 if not DEBUG:
360                                         self.session.nav.RecordTimer.processed_timers = [timerentry for timerentry in self.session.nav.RecordTimer.processed_timers if timerentry.repeated or (timerentry.end and timerentry.end > expiration)] # cleanup timerlist
361                 else:
362                         print pluginPrintname, "Timerlist cleanup disabled"
363                 
364         def timerentryOnStateChange(self, timer):
365                 if int(config.plugins.AutomaticCleanup.deleteTimersOlderThan.value) == 0 and timer.state == TimerEntry.StateEnded and timer.cancelled is not True: #if enabled, timerentry ended and it was not cancelled by user
366                         print pluginPrintname, "Timerentry has been changed to StateEnd"
367                         self.cleanupTimerlist() # and check if entries have to be cleaned up in the timerlist
368                 
369         def cleanupMovies(self):
370                 if config.plugins.AutomaticCleanup.deleteOrphanedMovieFiles.value: # check only if feature is enabled
371                         print pluginPrintname, "Cleaning up orphaned movies"
372                         moviePath = []
373                         excludePath = []
374                         
375                         from Components.UsageConfig import defaultMoviePath
376                         if defaultMoviePath().endswith('/'): moviePath.append(defaultMoviePath())
377                         else: moviePath.append(defaultMoviePath() + "/")
378                         if config.usage.instantrec_path.value.endswith('/'): excludePath.append(config.usage.instantrec_path.value)
379                         else: excludePath.append(config.usage.instantrec_path.value + "/")                      
380                         if config.usage.timeshift_path.value.endswith('/'): excludePath.append(config.usage.timeshift_path.value)
381                         else: excludePath.append(config.usage.timeshift_path.value + "/")
382
383                         try:
384                                 # try to import EMC module to check for its existence
385                                 from Plugins.Extensions.EnhancedMovieCenter.EnhancedMovieCenter import EnhancedMovieCenterMenu
386                                 if config.EMC.movie_homepath.value:
387                                         path = config.EMC.movie_homepath.value
388                                         if not path.endswith("/"): path += "/"
389                                         if path not in moviePath:
390                                                 moviePath.append(path)
391                                 try: # with v3 name
392                                         if len(config.EMC.movie_trashcan_path.value) > 1:       # Trashpath specified?
393                                                 if DEBUG: print pluginPrintname, "EMC v3 trashcan path is", config.EMC.movie_trashcan_path.value
394                                                 if config.EMC.movie_trashcan_path.value.endswith('/'): excludePath.append(config.EMC.movie_trashcan_path.value)
395                                                 else: excludePath.append(config.EMC.movie_trashcan_path.value + "/")
396                                 except KeyError, ke:
397                                         print pluginPrintname, "EMC v3 trashcan path not specified", ke
398                                         try: # else with v2 name
399                                                 if len(config.EMC.movie_trashpath.value) > 1:   # Trashpath specified?
400                                                         if DEBUG: print pluginPrintname, "EMC v2 trashcan path is", config.EMC.movie_trashpath.value
401                                                         if config.EMC.movie_trashpath.value.endswith('/'): excludePath.append(config.EMC.movie_trashpath.value)
402                                                         else: excludePath.append(config.EMC.movie_trashpath.value + "/")
403                                         except KeyError, ke:
404                                                 print pluginPrintname, "EMC v2 trashcan path not specified", ke
405                         except ImportError, ie:
406                                 print pluginPrintname, "EMC not installed:", ie
407
408                         if len(moviePath) == 0:
409                                 print pluginPrintname, "No movies found!"
410                         else:
411                                 for f in range(len(excludePath)):
412                                         if excludePath[f].startswith("/hdd"): excludePath[f] = "/media" + excludePath[f]
413                                 print pluginPrintname, "Movie path:", moviePath
414                                 print pluginPrintname, "Excluded movie path:", excludePath
415                                 for checkPath in moviePath:     
416                                         self.filterMovies(str(checkPath), excludePath)                          
417                 else:
418                         print pluginPrintname, "Orphaned movies cleanup disabled"
419
420         def filterMovies(self, scanPath, exclude = []):
421                 if not scanPath.endswith("/"): scanPath += "/"
422                 if scanPath.startswith("/hdd"): scanPath = "/media" + scanPath
423                 if not path.exists(scanPath) or scanPath in exclude: return
424                 if DEBUG: print pluginPrintname, "Checking moviepath:", scanPath
425
426                 if self.initialState: 
427                         extensions =[".ts.ap", ".ts.cuts", ".ts.cutsr", ".ts.gm", ".ts.meta", ".ts.sc", ".eit", ".png", ".ts_mp.jpg", ".ts.del", ".ts.ap.del", ".ts.cuts.del", ".ts.cutsr.del", ".ts.gm.del", ".ts.meta.del", ".ts.sc.del", ".eit.del"] # include orphaned files marked for E2 smooth deletion
428                 else:
429                         extensions = [".ts.ap", ".ts.cuts", ".ts.cutsr", ".ts.gm", ".ts.meta", ".ts.sc", ".eit", ".png", ".ts_mp.jpg"]
430
431                 for p in listdir(scanPath):
432                         if path.isdir(scanPath + p):
433                                 try: self.filterMovies(scanPath + p, exclude)
434                                 except: pass
435                         else:
436                                 for ext in extensions:
437                                         if p.endswith(ext):
438                                                 if not path.exists(scanPath + p.replace(ext, ".ts")):                                                   
439                                                         if DEBUG:
440                                                                 print pluginPrintname, "Deletable orphaned movie file:", scanPath + p
441                                                         else:
442                                                                 remove(scanPath + p)
443                                                                 print pluginPrintname, "Orphaned movie file deleted:", scanPath + p
444                                                 break
445
446         def cleanupEnabled(self):
447                 if int(config.plugins.AutomaticCleanup.deleteTimersOlderThan.value) > -1 or \
448                    int(config.plugins.AutomaticCleanup.keepSettings.value) > -1 or \
449                    int(config.plugins.AutomaticCleanup.deleteSettingsOlderThan.value) > -1 or \
450                    config.plugins.AutomaticCleanup.deleteOrphanedMovieFiles.value:
451                         return True
452                 else:
453                         return False
454
455
456 def autostart(session, **kwargs):
457         AutomaticCleanup(session) # start plugin at sessionstart
458
459 def setup(session, **kwargs):
460         session.open(AutomaticCleanupSetup) # start setup
461
462 def startSetup(menuid):
463         if menuid != "system": # show setup only in system level menu
464                 return []
465         return [(_("System cleanup"), setup, "AutomaticCleanup", 46)]
466         
467 def Plugins(**kwargs):
468         return [PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART], fnc = autostart), PluginDescriptor(name="System cleanup", description=_("Automatic System Cleanup Setup"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup) ]