[REQUEST] Editing/Changing this addon
#1
Can someone with some scripting/programming experience please help me edit this py script to suit my needs?

It is a script that scans through your TV DB, and plays random episodes, but the first unwatched episode of that season.

Thanks to Roman_V_M that gave me the script, in this thread http://forum.xbmc.org/showthread.php?tid=166925

My only problem with the script is, that I dont want sitcoms included, and also not any of my daughters shows, I watch enough Dora The Explorer when she is awake Blush

So I thought that I would be able to open and make some changes, but boy, was I wrong! Some common sense would say that just adding a if statement somewhere to filter out any episodes shorter than say 30mins will work fine, or if anyone has any ideas?

Here is the download to the script:
https://disk.yandex.com/public/?hash=s9b...lAE4dT4%3D

And here is the code
Code:
# -*- coding: utf-8 -*-

import json, random, datetime
import xbmc, xbmcgui

IGNORE = []

def json_query(query):
    xbmc_request = json.dumps(query)
    result = xbmc.executeJSONRPC(xbmc_request)
    return json.loads(result)

def main():
    dt = datetime.datetime.now()
    seed_value = dt.day * 1000 + dt.hour * 100 + dt.minute * 10 + dt.second + dt.microsecond
    random.seed(seed_value)
    shows_query = {
    'jsonrpc': '2.0',
    'method': 'VideoLibrary.GetTVShows',
    'params': { 'properties': ['episode', 'watchedepisodes'],
                'sort': {'order': 'ascending', 'method': 'label'}},
    'id': '1'}
    shows_list = json_query(shows_query)['result']['tvshows']
    for item in shows_list:
        if item['watchedepisodes'] < item['episode']:
            unwatched = True
            break
    else:
        unwatched = False
    while unwatched:
        show = shows_list[random.randint(0, len(shows_list) - 1)]
        if show['watchedepisodes'] < show['episode'] and show['tvshowid'] not in IGNORE:
            seasons_query = {
            'jsonrpc': '2.0',
            'method': 'VideoLibrary.GetSeasons',
            'params': { 'tvshowid': show['tvshowid'],
                        'properties': ['episode', 'watchedepisodes', 'season'],
                        'sort': {'order': 'ascending', 'method': 'season'}},
            'id': '1'}
            seasons = json_query(seasons_query)['result']['seasons']
            for season in seasons:
                if season['watchedepisodes'] < season['episode']:
                    episodes_query = {
                    'jsonrpc': '2.0',
                    'method': 'VideoLibrary.GetEpisodes',
                    'params': { 'tvshowid': show['tvshowid'],
                                'season': season['season'],
                                'properties': ['file']},
                    'id': '1'}
                    episodes = json_query(episodes_query)['result']['episodes']
                    break
            play_command = {
                    'jsonrpc': '2.0',
                    'method': 'Player.Open',
                    'params': {'item': {'file': episodes[season['watchedepisodes']]['file']},
                    'options':{'resume': True}},
                    'id': '1'}
            json_query(play_command)
            subtitles_on = {
                    'jsonrpc': '2.0',
                    'method': 'Player.SetSubtitle',
                    'params': {'subtitle': 'on'},
                    'id': '1'}
            json_query(subtitles_on)
            break
    else:
        dialog = xbmcgui.Dialog()
        dialog.ok('Oops!', 'No unwatched episodes\nto play.')

if __name__ == '__main__':
    main()
Reply
#2
I'm not a skilled scripter but i think i can manage that. (won't be today)
Could be a fun script to use for myself.
Reply
#3
awesome. thanks alot Smile
Reply
#4
I am learning as well, so I might have a look.

The length of the show might be a little difficult. Would there be a specific genre you would like to remove? This script should remove all TV shows with 'Children' in the genre.

Code:
# -*- coding: utf-8 -*-

import json, random, datetime
import xbmc, xbmcgui

IGNORE = []

def json_query(query):
    xbmc_request = json.dumps(query)
    result = xbmc.executeJSONRPC(xbmc_request)
    return json.loads(result)

def main():
    dt = datetime.datetime.now()
    seed_value = dt.day * 1000 + dt.hour * 100 + dt.minute * 10 + dt.second + dt.microsecond
    random.seed(seed_value)
    shows_query = {
    'jsonrpc': '2.0',
    'method': 'VideoLibrary.GetTVShows',
    'params': { 'properties': ['episode', 'watchedepisodes','genre'],
                'sort': {'order': 'ascending', 'method': 'label'}},
    'id': '1'}
    shows_list = json_query(shows_query)['result']['tvshows']
    for item in shows_list:
        if item['watchedepisodes'] < item['episode']:
            unwatched = True
            break
    else:
        unwatched = False
    while unwatched:
        show = shows_list[random.randint(0, len(shows_list) - 1)]
        if show['watchedepisodes'] < show['episode'] and show['tvshowid'] not in IGNORE and "Children" not in show['genre']:
            seasons_query = {
            'jsonrpc': '2.0',
            'method': 'VideoLibrary.GetSeasons',
            'params': { 'tvshowid': show['tvshowid'],
                        'properties': ['episode', 'watchedepisodes', 'season'],
                        'sort': {'order': 'ascending', 'method': 'season'}},
            'id': '1'}
            seasons = json_query(seasons_query)['result']['seasons']
            for season in seasons:
                if season['watchedepisodes'] < season['episode']:
                    episodes_query = {
                    'jsonrpc': '2.0',
                    'method': 'VideoLibrary.GetEpisodes',
                    'params': { 'tvshowid': show['tvshowid'],
                                'season': season['season'],
                                'properties': ['file']},
                    'id': '1'}
                    episodes = json_query(episodes_query)['result']['episodes']
                    break
            play_command = {
                    'jsonrpc': '2.0',
                    'method': 'Player.Open',
                    'params': {'item': {'file': episodes[season['watchedepisodes']]['file']},
                    'options':{'resume': True}},
                    'id': '1'}
            json_query(play_command)
            subtitles_on = {
                    'jsonrpc': '2.0',
                    'method': 'Player.SetSubtitle',
                    'params': {'subtitle': 'on'},
                    'id': '1'}
            json_query(subtitles_on)
            break
    else:
        dialog = xbmcgui.Dialog()
        dialog.ok('Oops!', 'No unwatched episodes\nto play.')

if __name__ == '__main__':
    main()
Reply
#5
Thanks! Is it possible to exclude more than one genre? Would love to exclude, children, animation and documentary.
Reply
#6
Sure, its not an elegant addition, but you could just change this,
Code:
if show['watchedepisodes'] < show['episode'] and show['tvshowid'] not in IGNORE and "Children" not in show['genre']:

to this
Code:
if show['watchedepisodes'] < show['episode'] and show['tvshowid'] not in IGNORE and "Children" not in show['genre'] and "Animation" not in show['genre'] and "Documentary" not in show['genre']:
Reply
#7
Thanks alot. One last thing, how difficult would it be to make the addon not play one episode, but instead load like 5 items to a playlist.

And make a popup show up with the show name an episode title/number that is being played.
Reply
#8
instead of a long AND statement for each exclusion,

simply define a list at the top of the script

IGNORE_IDS = []
IGNORE_GENRES = ['children', 'romance', 'foo', 'bar']

Then change your IF statement to:

if show['watchedepisodes'] < show['episode'] and show['tvshowid'] not in IGNORE_IDS and show['genre'] not in IGNORE_GENRES:
Reply
#9
And, yes - possible to add 5x ep's to a playlist

add_playlist_command = {
'jsonrpc': '2.0',
'method': 'Playlist.Add',
'params': {'playlistid':1, 'item': {'file': episodes[season['watchedepisodes']]['file']},
'id': '1'}
json_query(add_playlist_command)

You may also want to clear the playlist before starting to add items:

clear_playlist_command = {
'jsonrpc': '2.0',
'method': 'Playlist.Clear',
'params': {'playlistid':1},
'id': '1'}
json_query(clear_playlist_command)

You will also need to use the below play command instead:

play_command = {
'jsonrpc': '2.0',
'method': 'Player.Open',
'params': {'item': {'playlistid':1}},
'id': '1'}
json_query(play_command)
Reply
#10
Awesome awesome awesome ... Thanks a million guys.
Reply
#11
Good on ya, Stanley. I was getting a little nauseated working through the jsonrpcAPI page on the wiki.

I will look to add those to the script with the appropriate loops and escapes when I next get a chance.

Do the playlist commands create an ad-hoc, temporary playlist, or will one have to be created/found and referenced earlier in the script?
Reply
#12
One last request, to make this script complete and awesome. A popup box to come up when the next episode plays, that shows the show name, episode number and episode title.
Reply
#13
This script just creates the playlist then exits. It doesnt control what happens after that.

I suppose instead of exiting it could call another while loop, that waits 5 seconds before checking the name of the file currently playing against the name of the file playing 5 seconds ago, and when there is a difference it creates a notification on the screen. But I dont know how to make that notification while a video is playing.

Code:
# -*- coding: utf-8 -*-

import json, random, datetime, sys
import xbmc, xbmcgui

IGNORE = []

def json_query(query):
    xbmc_request = json.dumps(query)
    result = xbmc.executeJSONRPC(xbmc_request)
    return json.loads(result)

def main():
    #clears the playlist
    clear_playlist_command = {
    'jsonrpc': '2.0',
    'method': 'Playlist.Clear',
    'params': {'playlistid':1},
    'id': '1'}
    json_query(clear_playlist_command)

    item_count_max = 5

    dt = datetime.datetime.now()
    seed_value = dt.day * 1000 + dt.hour * 100 + dt.minute * 10 + dt.second + dt.microsecond
    random.seed(seed_value)
    shows_query = {
    'jsonrpc': '2.0',
    'method': 'VideoLibrary.GetTVShows',
    'params': { 'properties': ['episode', 'watchedepisodes','genre'],
                'sort': {'order': 'ascending', 'method': 'label'}},
    'id': '1'}
    shows_list = json_query(shows_query)['result']['tvshows']
    unwatched_show_count = 0
    for item in shows_list:
        if item['watchedepisodes'] == 0:
            unwatched_show_count += 1

    #--> check how many items there are unwatched, if there are fewer than 5, limit the playlist to that number    
    if unwatched_show_count < 5:
        item_count_max = unwatched_show_count

    for item in shows_list:
        if item['watchedepisodes'] < item['episode']:
            unwatched = True
            item_count = 0
            break
        else:
            unwatched = False

    while unwatched:
        
        while item_count < item_count_max:
            show = shows_list[random.randint(0, len(shows_list) - 1)]
            if show['watchedepisodes'] < show['episode'] and show['tvshowid'] not in IGNORE and "Children" not in show['genre']:
                
                seasons_query = {
                'jsonrpc': '2.0',
                'method': 'VideoLibrary.GetSeasons',
                'params': { 'tvshowid': show['tvshowid'],
                            'properties': ['episode', 'watchedepisodes', 'season'],
                            'sort': {'order': 'ascending', 'method': 'season'}},
                'id': '1'}
                seasons = json_query(seasons_query)['result']['seasons']
                for season in seasons:
                    if season['watchedepisodes'] < season['episode']:
                        episodes_query = {
                        'jsonrpc': '2.0',
                        'method': 'VideoLibrary.GetEpisodes',
                        'params': { 'tvshowid': show['tvshowid'],
                                    'season': season['season'],
                                    'properties': ['file']},
                        'id': '1'}
                        episodes = json_query(episodes_query)['result']['episodes']
                        break
                item_count += 1
                add_playlist_command = {
                    'jsonrpc': '2.0',
                    'method': 'Playlist.Add',
                    'params': {'playlistid':1,
                                'item': {'file': episodes[season['watchedepisodes']]['file']}},
                    'id': '1'}
                json_query(add_playlist_command)          
        play_command = {
        'jsonrpc': '2.0',
        'method': 'Player.Open',
        'params': {'item': {'playlistid':1}},
        'id': '1'}
        json_query(play_command)
        subtitles_on = {
                'jsonrpc': '2.0',
                'method': 'Player.SetSubtitle',
                'params': {'subtitle': 'on'},
                'id': '1'}
        json_query(subtitles_on)
        break
        sys.exit

    else:
        dialog = xbmcgui.Dialog()
        dialog.ok('Oops!', 'No unwatched episodes\nto play.')#"""

if __name__ == '__main__':
    main()
Reply
#14
For the popup, I would make the script a service (if not already)

Then, have below (tested and confirmed working)

Code:
def getCurrentVideo():
    video = None
    video_query = {
               'jsonrpc': '2.0',
               'method': 'Player.GetItem',
               'params': {'playerid': 1, 'properties': ['file', 'title']},
               'id': '1'}
    result = json_query(video_query)
    if(result and 'result' in result):
        video = result['result']['item']
        if video['title'] == '':
            video['title'] = video['file']
    return video

last_video = getCurrentVideo()
while ( not xbmc.abortRequested ):
    xbmc.sleep(1000)  #sleep 1000ms (1s)
    current_video = getCurrentVideo()
    if (current_video != None and current_video != last_video):
        title = 'Random Episode'
        message = 'Now playing: %s' % current_video['title']
        time = 5000 #ms to show popup for (5s)
        xbmc.executebuiltin('Notification(%s, %s, %d)'%(title,message, time))
    last_video = current_video

Just noticed you wanted to get episode details, you would just need to change 'params': {'playerid': 1, 'properties': ['file', 'title']}, to 'params': {'playerid': 1, 'properties': ['file', 'showtitle', 'episode', 'title']},
then change:
message = 'Now playing: %s - %s - %s' % (current_video['showtitle'], current_video['episode'], current_video['title'])
might also edit the if ('title' == '') to something else or remove
Reply
#15
Maybe Player.Onplay could be used to add the notification to the start of a new video playing, rather than constantly checking for changes?

Also, if the script was set up as a service, it would have to be running constantly, right?

That would mean the call to run the Def to generate the playlist would need to occur within your "while ( not xbmc.abortRequested ):". Correct?

How would you then trigger that call? Would the service have to running seperately from the other script? Would the script start the service, in which case, how would it know to kill it again?
Reply

Logout Mark Read Team Forum Stats Members Help
[REQUEST] Editing/Changing this addon0