import xbmc import xbmcgui import xbmcaddon import xbmcvfs import json import random import sys import tmdb ADDON = xbmcaddon.Addon() CWD = ADDON.getAddonInfo('path').decode('utf-8') #CWD = ADDON.getAddonInfo('path') # for kodi 19 # reads program names from JSON files and returns a dict def list_programs(cinematic_path): dirs, files = xbmcvfs.listdir(cinematic_path) programs = {} for filename in files: if filename.endswith('.json'): filehandle = xbmcvfs.File(cinematic_path + filename) program_json = filehandle.read() filehandle.close() program_data = json.loads(program_json) programs[program_data['name']] = filename return programs # shows the selection dialog with program names, returns JSON filename def show_dialog(programs): entries = programs.keys() dialog = xbmcgui.Dialog() ret = dialog.select('Cinematic: Select a program', entries) del dialog return programs[entries[ret]] # get a number of random files from a directory def files_from_dir(count, location): dirs, files = xbmcvfs.listdir(location) files = random.sample(files, count) for i in range(len(files)): files[i] = location + files[i] return files # reads the JSON file and conducts a pre-program for the feature movie def conduct_program(program_file, feature): filehandle = xbmcvfs.File(program_file) program_json = filehandle.read() filehandle.close() program_data = json.loads(program_json) program = [] for item in program_data['items']: settings = item['settings'] if settings['source'] == 'file': entry = {'type': 'video', 'data': settings['location']} program.append(entry) elif settings['source'] == 'dir': for location in files_from_dir(settings['count'], settings['location']): entry = {'type': 'video', 'data': location} program.append(entry) elif settings['source'] == 'tmdbtrailer': TMDB = tmdb.Tmdb(apikey = settings['apikey'], language = settings['language']) tmdbid = int(feature['tmdbid']) imdbid = feature['imdbid'] choice = settings['choice'] trailertype = settings['type'] count = settings['count'] if not tmdbid: tmdbid = TMDB.get_tmdbid(imdbid) if tmdbid: movies = TMDB.get_recommendations(tmdbid, choice) random.shuffle(movies) trailers = TMDB.get_trailers(movies, trailertype, count) else: print("TODO: this feature has no tmdb id, find someting else to play") trailers = [] for trailer in trailers: entry = {'type': 'video', 'data': trailer['location']} program.append(entry) elif settings['source'] == 'rating': rating = -1 for s in feature['mpaa'].split(): if s.isdigit(): rating = int(s) break if rating > -1: dirs, files = xbmcvfs.listdir(settings['location']) for f in files: if f.startswith(str(rating)+'.'): location = settings['location'] + f break entry = {'type': 'video', 'data': location} program.append(entry) elif settings['source'] == 'feature': entry = {'type': 'video', 'data': feature['file']} program.append(entry) return program # fetches information on the feature movie def get_feature(movieid): query = '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovieDetails", "params": {"movieid": %s, "properties": ["file", "mpaa", "uniqueid"]}, "id": "1"}' % movieid json_response = xbmc.executeJSONRPC(query) response = json.loads(json_response) if not 'tmdb' in response['result']['moviedetails']['uniqueid']: response['result']['moviedetails']['uniqueid']['tmdb'] = 0 if not 'imdb' in response['result']['moviedetails']['uniqueid']: response['result']['moviedetails']['uniqueid']['tmdb'] = '' feature = { 'label': response['result']['moviedetails']['label'], 'file': response['result']['moviedetails']['file'], 'mpaa': response['result']['moviedetails']['mpaa'], 'tmdbid': response['result']['moviedetails']['uniqueid']['tmdb'], 'imdbid': response['result']['moviedetails']['uniqueid']['imdb'] } return feature # entry point if __name__ == '__main__': cinematic_path = ADDON.getSettingString('cinematic_path') # collect info about the selected feature movie movieid = xbmc.getInfoLabel('ListItem.DBID').decode('utf-8') feature = get_feature(movieid) print(feature) # let user select one of the JSON programs programs = list_programs(cinematic_path) program_file = cinematic_path + show_dialog(programs) # conduct and show playlist program = conduct_program(program_file, feature) print('=== playlist') for entry in program: print(" * [%s] -- %s" % (entry['type'], entry['data'])) # close modal movie information window if xbmc.getCondVisibility('Window.IsVisible(MovieInformation)'): xbmc.executebuiltin('Dialog.Close(MovieInformation)') """ TODO: this is not the intended way of playing back the conducted playlist. hints for a better implementation are welcome. the plan is to play each video file in the list separately, so the addon is able to perform further tasks in between, like controlling home automation systems. unfortunately, research has to be done in order to find out how that should be implemented. """ # build kodi style playlist playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() for entry in program: if entry['type'] == 'video': playlist.add(entry['data']) else: # it is planned to implement features other than video playback # e. g. call scripts in home automation to dim the lights print(" unable to handle %s yet" % entry['type']) # start playback xbmc.Player().play(playlist) xbmc.sleep(500) # wait until program is finished while xbmc.getCondVisibility('Player.HasMedia'): xbmc.sleep(100)