Skip to content

Instantly share code, notes, and snippets.

@KAYLukas
Created February 12, 2013 18:16
Show Gist options
  • Save KAYLukas/4771978 to your computer and use it in GitHub Desktop.
Save KAYLukas/4771978 to your computer and use it in GitHub Desktop.
Event driven library updating
import resources.lib.utils as utils
import xbmc
from ctypes import *
block_duration = 60*1000#1 minute
#Listens for changes in the selected libraries.
#If a change occurs in some folder of some library all
#selected libraries are updated.
def listen():
utils.log("Starting to listen for any changes to the sources")
while not xbmc.abortRequested:
updateSources()
if DirectoryChanged(libs, block_duration) and not xbmc.abortRequested:
updateLibs()
def updateSources():
global libs
libs = []
if ListeningForMusicChanges():
libs = libs + getSource("music")
if ListeningForVideoChanges():
libs = libs + getSource("video")
def getSource(type):
json_request = '{ "jsonrpc" : "2.0", "method": "Files.GetSources", "id": 1, "params" : '+\
'{"media": "' + type + '"}}'
response = xbmc.executeJSONRPC(json_request)
response = eval(response)
return [source['file'] for source in response['result']['sources']]
def updateLibs():
if ListeningForMusicChanges():
xbmc.executebuiltin('UpdateLibrary(music)')
if ListeningForVideoChanges():
xbmc.executebuiltin('UpdateLibrary(video)')
def ListeningForMusicChanges():
return utils.getSetting("auto_update_music_change") == "true"
def ListeningForVideoChanges():
return utils.getSetting("auto_update_video_change") == "true"
#-------------Windows only code----------------------
#windows only code, for portability this should be moved to another file
#and then something like:
#import platform
#if platform.system() == 'Windows':
# from WindowsChangeListener import *
#elif platform.system() == 'Linux':
# from LinuxChangeListener import *
#else:
# from FallBackListener import *#Some polling listener which looks at last changed attributes
FILE_NOTIFY_CHANGE_FILE_NAME = 1
FILE_NOTIFY_CHANGE_DIR_NAME = 2
FILE_NOTIFY_CHANGE_ATTRIBUTES = 4
FILE_NOTIFY_CHANGE_SIZE = 8
FILE_NOTIFY_CHANGE_LAST_WRITE = 16
FILE_NOTIFY_CHANGE_SECURITY = 256
flags = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE
#this function creates handles for each directory
#waits for any changes in the whole directory tree by calling WaitForMultipleObjects
#if a timeout occurs false is returned, otherwise true is returned.
#all handles are also closed in this function
#no effort is made to preserve handles between calls, as dirs variable could change between
#every call.
def DirectoryChanged(dirs, timeout):
handles = [generateChangeHandle(dir) for dir in dirs]
handles = [handle for handle in handles if handle != 0]
handles = toCHandles(handles)
status = windll.kernel32.WaitForMultipleObjects(len(handles), handles, False, timeout)
closeHandles(*handles)
return status < 258
def generateChangeHandle(dir):
return windll.kernel32.FindFirstChangeNotificationW(unicode(dir), True, flags)
#converts a list of handles in to an c array of handles
def toCHandles(handles):
array_type = c_void_p * len(handles)
result = array_type(*handles)
return result
#closes all handles
def closeHandles(*handles):
for handle in handles:
windll.kernel32.FindCloseChangeNotification(handle)
import resources.lib.utils as utils
from service import AutoUpdater
import ChangeListener
import thread
#Listen for changes
thread.start_new_thread(ChangeListener.listen())
#run the program
utils.log("Update Library Service starting...")
AutoUpdater().runProgram()
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Translated using Transifex web application. For support, or if you would like to to help out, please visit your language team! -->
<!-- English language-Team URL: http://www.transifex.com/projects/p/xbmc-addons/language/en/ -->
<!-- Report language file syntax bugs at: alanwww1@xbmc.org -->
<strings>
<string id="30000">XBMC Library Auto Update</string>
<string id="30001">General</string>
<string id="30002">Video</string>
<string id="30003">Music</string>
<string id="30004">Update Video Library</string>
<string id="30005">Update Music Library</string>
<string id="30006">Show Notifications</string>
<string id="30007">Run during playback</string>
<string id="30008">Startup Delay (minutes)</string>
<string id="30009">Used Advanced Timer</string>
<string id="30010">Amount of time between updates (hours)</string>
<string id="30011">Cron Expression</string>
<!-- specific paths -->
<string id="30020">Update Specific Path 1</string>
<string id="30021">Update Specific Path 2</string>
<string id="30022">Update Specific Path 3</string>
<string id="30023">Video Path</string>
<!-- disclaimer -->
<string id="30030">Read Disclaimer</string>
<string id="30031">Video Paths Disclaimer</string>
<string id="30032">Path must already be a video source with content</string>
<string id="30033">Path must match source path exactly to scan</string>
<!-- cleaning -->
<string id="30040">Cleaning</string>
<string id="30041">Clean Libraries</string>
<string id="30042">Verify Sources Before Clean</string>
<string id="30043">Frequency</string>
<string id="30044">After Update</string>
<string id="30045">Once Per Day</string>
<string id="30046">Once Per Week</string>
<string id="30047">Once Per Month</string>
<string id="30048">Clean Video Library</string>
<string id="30049">Clean Music Library</string>
<string id="30050">Error Cleaning Database</string>
<string id="30051">Prompt User Before Cleaning Library</string>
<string id="30052">A database clean is scheduled to run</string>
<string id="30053">Would you like to run it now?</string>
<string id="30054">Library to clean</string>
<string id="30055">Both</string>
<string id="30056">Video Cron Expression</string>
<string id="30057">Music Cron Expression</string>
<!-- manual run -->
<string id="30060">Update will run again </string>
<string id="30061">Do you wish to manually run an update?</string>
<!-- Directory watcher -->
<string id="40002">Automatically update library on directory change</string>
<string id="40003">Automatically update library on directory change</string>
</strings>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<settings>
<category id="general" label="30001">
<setting id="startup_delay" type="enum" values="0|1|2|3|4|5" label="30008" default="0" />
<setting id="notify_next_run" type="bool" label="30006" default="true" />
<setting id="run_during_playback" type="bool" label="30007" default="false" />
<setting id="last_run" type="text" label="last_run" default="0" visible="false" />
</category>
<category id="video_timer" label="30002">
<setting id="update_video" type="bool" label="30004" default="true" />
<setting id="video_advanced_timer" type="bool" label="30009" default="false" enable="eq(-1,true)"/>
<setting id="video_timer" type="enum" values="1|2|4|6|12|24" label="30010" default="2" enable="!eq(-1,true) + eq(-2,true)" visible="!eq(-1,true)" />
<setting id="video_cron_expression" type="text" label="30011" visible="eq(-2,true)" enable="eq(-2,true) + eq(-3,true)" default="0 * * * *" />
<setting id="auto_update_video_change" type="bool" label="40003" default="false" />
<setting type="sep" />
<setting id="help_button" type="action" action="RunScript(special://home/addons/service.libraryautoupdate/disclaimer.py)" label="30030" />
<!-- custom paths -->
<setting id="use_custom_1_path" type="bool" label="30020" default="false" />
<setting id="custom_1_advanced_timer" type="bool" label="30009" default="false" enable="eq(-1,true)" visible="eq(-1,true)" />
<setting id="custom_1_timer" type="enum" values="1|2|4|6|12|24" label="30010" default="2" enable="!eq(-1,true) + eq(-2,true)" visible="!eq(-1,true) + eq(-2,true)" />
<setting id="custom_1_cron_expression" type="text" label="30011" enable="eq(-2,true) + eq(-3,true)" default="0 * * * *" visible="eq(-2,true) + eq(-3,true)" />
<setting id="custom_1_scan_path" type="folder" label="30023" enable="eq(-4,true)" visible="eq(-4,true)" />
<!-- custom 2 -->
<setting id="use_custom_2_path" type="bool" label="30021" default="false" />
<setting id="custom_2_advanced_timer" type="bool" label="30009" default="false" enable="eq(-1,true)" visible="eq(-1,true)" />
<setting id="custom_2_timer" type="enum" values="1|2|4|6|12|24" label="30010" default="2" enable="!eq(-1,true) + eq(-2,true)" visible="!eq(-1,true) + eq(-2,true)" />
<setting id="custom_2_cron_expression" type="text" label="30011" enable="eq(-2,true) + eq(-3,true)" default="0 * * * *" visible="eq(-2,true) + eq(-3,true)" />
<setting id="custom_2_scan_path" type="folder" label="30023" enable="eq(-4,true)" visible="eq(-4,true)" />
<!-- custom 3 -->
<setting id="use_custom_3_path" type="bool" label="30022" default="false" />
<setting id="custom_3_advanced_timer" type="bool" label="30009" default="false" enable="eq(-1,true)" visible="eq(-1,true)" />
<setting id="custom_3_timer" type="enum" values="1|2|4|6|12|24" label="30010" default="2" enable="!eq(-1,true) + eq(-2,true)" visible="!eq(-1,true) + eq(-2,true)" />
<setting id="custom_3_cron_expression" type="text" label="30011" enable="eq(-2,true) + eq(-3,true)" default="0 * * * *" visible="eq(-2,true) + eq(-3,true)" />
<setting id="custom_3_scan_path" type="folder" label="30023" enable="eq(-4,true)" visible="eq(-4,true)" />
</category>
<category id="music_timer" label="30003">
<setting id="update_music" type="bool" label="30005" default="false" />
<setting id="music_advanced_timer" type="bool" label="30009" default="false" enable="eq(-1,true)" />
<setting id="music_timer" type="enum" values="1|2|4|6|12|24" label="30010" default="2" enable="!eq(-1,true) + eq(-2,true)" visible="!eq(-1,true)" />
<setting id="music_cron_expression" type="text" label="30011" enable="eq(-2,true) + eq(-3,true)" default="0 * * * *" visible="eq(-2,true)" />
<setting id="auto_update_music_change" type="bool" label="40002" default="false" />
</category>
<category id="clean_timer" label="30040">
<setting id="clean_libraries" type="bool" label="30041" default="false" />
<setting id="library_to_clean" type="enum" lvalues="30055|30002|30003" label="30054" default="0" enable="eq(-1,true)" />
<setting id="verify_paths" type="bool" label="30042" default="false" enable="eq(-2,true)"/>
<setting id="user_confirm_clean" type="bool" label="30051" default="false" enable="eq(-3,true)" />
<setting id="clean_timer" type="enum" lvalues="30044|30045|30046|30047|30011" label="30043" default="0" enable="eq(-4,true)" />
<setting id="clean_video_cron_expression" type="text" label="30056" default="0 0 * * *" enable="eq(-5,true)" visible="eq(-1,4)" />
<setting id="clean_music_cron_expression" type="text" label="30057" default="0 2 * * *" enable="eq(-6,true)" visible="eq(-2,4)" />
</category>
</settings>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment