script.cinematic/addon.py

165 lines
6.3 KiB
Python
Raw Permalink Normal View History

2021-03-15 14:35:24 +00:00
import xbmc
import xbmcgui
import xbmcaddon
import xbmcvfs
import json
import random
import sys
2021-03-19 00:21:09 +00:00
import tmdb
2021-03-15 14:35:24 +00:00
ADDON = xbmcaddon.Addon()
CWD = ADDON.getAddonInfo('path').decode('utf-8')
#CWD = ADDON.getAddonInfo('path') # for kodi 19
2021-03-19 14:22:54 +00:00
# reads program names from JSON files and returns a dict
2021-03-15 15:33:10 +00:00
def list_programs(cinematic_path):
dirs, files = xbmcvfs.listdir(cinematic_path)
2021-03-15 15:54:39 +00:00
programs = {}
2021-03-15 15:33:10 +00:00
for filename in files:
if filename.endswith('.json'):
2021-03-15 15:54:39 +00:00
filehandle = xbmcvfs.File(cinematic_path + filename)
program_json = filehandle.read()
filehandle.close()
program_data = json.loads(program_json)
programs[program_data['name']] = filename
2021-03-15 15:33:10 +00:00
return programs
2021-03-19 14:22:54 +00:00
# shows the selection dialog with program names, returns JSON filename
2021-03-15 15:54:39 +00:00
def show_dialog(programs):
entries = programs.keys()
dialog = xbmcgui.Dialog()
ret = dialog.select('Cinematic: Select a program', entries)
del dialog
return programs[entries[ret]]
2021-03-19 14:22:54 +00:00
# get a number of random files from a directory
2021-03-15 14:35:24 +00:00
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
2021-03-19 14:22:54 +00:00
# reads the JSON file and conducts a pre-program for the feature movie
2021-03-15 20:02:42 +00:00
def conduct_program(program_file, feature):
2021-03-15 14:35:24 +00:00
filehandle = xbmcvfs.File(program_file)
program_json = filehandle.read()
filehandle.close()
program_data = json.loads(program_json)
2021-03-15 16:13:26 +00:00
program = []
2021-03-15 14:35:24 +00:00
for item in program_data['items']:
settings = item['settings']
if settings['source'] == 'file':
2021-03-15 16:13:26 +00:00
entry = {'type': 'video', 'data': settings['location']}
program.append(entry)
2021-03-15 14:35:24 +00:00
elif settings['source'] == 'dir':
2021-03-15 16:13:26 +00:00
for location in files_from_dir(settings['count'], settings['location']):
entry = {'type': 'video', 'data': location}
program.append(entry)
2021-03-16 16:46:19 +00:00
elif settings['source'] == 'tmdbtrailer':
2021-03-19 12:54:04 +00:00
TMDB = tmdb.Tmdb(apikey = settings['apikey'], language = settings['language'])
tmdbid = int(feature['tmdbid'])
2021-03-18 21:11:37 +00:00
imdbid = feature['imdbid']
choice = settings['choice']
trailertype = settings['type']
count = settings['count']
2021-03-18 21:11:37 +00:00
if not tmdbid:
2021-03-19 00:21:09 +00:00
tmdbid = TMDB.get_tmdbid(imdbid)
2021-03-16 17:30:37 +00:00
if tmdbid:
2021-03-19 12:54:04 +00:00
movies = TMDB.get_recommendations(tmdbid, choice)
2021-03-16 17:30:37 +00:00
random.shuffle(movies)
2021-03-19 12:54:04 +00:00
trailers = TMDB.get_trailers(movies, trailertype, count)
2021-03-16 17:30:37 +00:00
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']}
2021-03-15 16:13:26 +00:00
program.append(entry)
2021-03-16 18:59:30 +00:00
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)
2021-03-15 14:35:24 +00:00
elif settings['source'] == 'feature':
2021-03-15 20:02:42 +00:00
entry = {'type': 'video', 'data': feature['file']}
2021-03-15 16:13:26 +00:00
program.append(entry)
return program
2021-03-19 14:22:54 +00:00
# fetches information on the feature movie
2021-03-15 20:02:42 +00:00
def get_feature(movieid):
query = '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovieDetails", "params": {"movieid": %s, "properties": ["file", "mpaa", "uniqueid"]}, "id": "1"}' % movieid
2021-03-15 20:02:42 +00:00
json_response = xbmc.executeJSONRPC(query)
response = json.loads(json_response)
2021-03-16 17:30:37 +00:00
if not 'tmdb' in response['result']['moviedetails']['uniqueid']:
response['result']['moviedetails']['uniqueid']['tmdb'] = 0
2021-03-18 21:11:37 +00:00
if not 'imdb' in response['result']['moviedetails']['uniqueid']:
response['result']['moviedetails']['uniqueid']['tmdb'] = ''
2021-03-15 20:02:42 +00:00
feature = {
'label': response['result']['moviedetails']['label'],
'file': response['result']['moviedetails']['file'],
'mpaa': response['result']['moviedetails']['mpaa'],
2021-03-18 21:11:37 +00:00
'tmdbid': response['result']['moviedetails']['uniqueid']['tmdb'],
'imdbid': response['result']['moviedetails']['uniqueid']['imdb']
2021-03-15 20:02:42 +00:00
}
return feature
2021-03-19 14:22:54 +00:00
# entry point
2021-03-15 16:13:26 +00:00
if __name__ == '__main__':
cinematic_path = ADDON.getSettingString('cinematic_path')
2021-03-19 14:34:44 +00:00
# collect info about the selected feature movie
movieid = xbmc.getInfoLabel('ListItem.DBID').decode('utf-8')
2021-03-15 20:02:42 +00:00
feature = get_feature(movieid)
print(feature)
2021-03-19 14:34:44 +00:00
# let user select one of the JSON programs
2021-03-15 16:13:26 +00:00
programs = list_programs(cinematic_path)
program_file = cinematic_path + show_dialog(programs)
2021-03-15 14:35:24 +00:00
2021-03-19 14:34:44 +00:00
# conduct and show playlist
program = conduct_program(program_file, feature)
2021-03-15 14:35:24 +00:00
print('=== playlist')
2021-03-15 16:13:26 +00:00
for entry in program:
print(" * [%s] -- %s" % (entry['type'], entry['data'].encode('utf-8')))
2021-03-19 14:34:44 +00:00
# close modal movie information window
if xbmc.getCondVisibility('Window.IsVisible(MovieInformation)'):
xbmc.executebuiltin('Dialog.Close(MovieInformation)')
2021-03-19 14:34:44 +00:00
"""
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:
2021-03-19 14:34:44 +00:00
# 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'])
2021-03-19 14:34:44 +00:00
# start playback
xbmc.Player().play(playlist)
xbmc.sleep(500)
2021-03-19 14:34:44 +00:00
# wait until program is finished
while xbmc.getCondVisibility('Player.HasMedia'):
xbmc.sleep(100)