Merge pull request #111 from mcarlton00/function-shuffle

Code reorganizing
This commit is contained in:
mcarlton00 2022-01-08 13:54:24 -05:00 committed by GitHub
commit a81e125a29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 717 additions and 809 deletions

View File

@ -1,57 +0,0 @@
from __future__ import division, absolute_import, print_function, unicode_literals
import xbmc
import xbmcgui
from .loghandler import LazyLogger
log = LazyLogger(__name__)
class BitrateDialog(xbmcgui.WindowXMLDialog):
slider_control = None
bitrate_label = None
initial_bitrate_value = 0
selected_transcode_value = 0
def __init__(self, *args, **kwargs):
log.debug("BitrateDialog: __init__")
xbmcgui.WindowXML.__init__(self, *args, **kwargs)
def onInit(self):
log.debug("ActionMenu: onInit")
self.action_exitkeys_id = [10, 13]
self.slider_control = self.getControl(3000)
self.slider_control.setInt(self.initial_bitrate_value, 400, 100, 15000)
self.bitrate_label = self.getControl(3030)
bitrate_label_string = str(self.slider_control.getInt()) + " Kbs"
self.bitrate_label.setLabel(bitrate_label_string)
def onFocus(self, control_id):
pass
def doAction(self, action_id):
pass
def onMessage(self, message):
log.debug("ActionMenu: onMessage: {0}".format(message))
def onAction(self, action):
bitrate_label_string = str(self.slider_control.getInt()) + " Kbs"
self.bitrate_label.setLabel(bitrate_label_string)
if action.getId() == 10: # ACTION_PREVIOUS_MENU
self.close()
elif action.getId() == 92: # ACTION_NAV_BACK
self.close()
elif action.getId() == 7: # ENTER
self.selected_transcode_value = self.slider_control.getInt()
self.close()
def onClick(self, control_id):
if control_id == 3000:
log.debug("ActionMenu: Selected Item: {0}".format(control_id))

View File

@ -17,10 +17,10 @@ import xbmcaddon
from .downloadutils import DownloadUtils
from .loghandler import LazyLogger
from .jsonrpc import JsonRpc, get_value
from .translation import string_load
from .datamanager import DataManager
from .utils import get_art
from .utils import translate_string
from .kodi_utils import HomeWindow
from .item_functions import get_art
downloadUtils = DownloadUtils()
log = LazyLogger(__name__)
@ -70,8 +70,8 @@ class CacheArtwork(threading.Thread):
log.debug("cache_delete_for_links")
progress = xbmcgui.DialogProgress()
progress.create(string_load(30281))
progress.update(30, string_load(30347))
progress.create(translate_string(30281))
progress.update(30, translate_string(30347))
item_image_url_part = "Items/%s/Images/" % item_id
item_image_url_part = item_image_url_part.replace("/", "%2f")
@ -82,7 +82,7 @@ class CacheArtwork(threading.Thread):
result = JsonRpc('Settings.GetSettingValue').execute(web_query)
xbmc_webserver_enabled = result['result']['value']
if not xbmc_webserver_enabled:
xbmcgui.Dialog().ok(string_load(30294), string_load(30295))
xbmcgui.Dialog().ok(translate_string(30294), translate_string(30295))
return
params = {"properties": ["url"]}
@ -90,7 +90,7 @@ class CacheArtwork(threading.Thread):
textures = json_result.get("result", {}).get("textures", [])
log.debug("texture ids: {0}".format(textures))
progress.update(70, string_load(30346))
progress.update(70, translate_string(30346))
delete_count = 0
for texture in textures:
@ -104,10 +104,10 @@ class CacheArtwork(threading.Thread):
del textures
progress.update(100, string_load(30125))
progress.update(100, translate_string(30125))
progress.close()
xbmcgui.Dialog().ok(string_load(30281), '{}: {}'.format(string_load(30344), delete_count))
xbmcgui.Dialog().ok(translate_string(30281), '{}: {}'.format(translate_string(30344), delete_count))
def cache_artwork_interactive(self):
log.debug("cache_artwork_interactive")
@ -119,21 +119,21 @@ class CacheArtwork(threading.Thread):
result = JsonRpc('Settings.GetSettingValue').execute(web_query)
xbmc_webserver_enabled = result['result']['value']
if not xbmc_webserver_enabled:
xbmcgui.Dialog().ok(string_load(30294), '{} - {}'.format(string_load(30295), string_load(30355)))
xbmcgui.Dialog().ok(translate_string(30294), '{} - {}'.format(translate_string(30295), translate_string(30355)))
xbmc.executebuiltin('ActivateWindow(servicesettings)')
return
result_report = []
# ask questions
question_delete_unused = xbmcgui.Dialog().yesno(string_load(30296), string_load(30297))
question_cache_images = xbmcgui.Dialog().yesno(string_load(30299), string_load(30300))
question_delete_unused = xbmcgui.Dialog().yesno(translate_string(30296), translate_string(30297))
question_cache_images = xbmcgui.Dialog().yesno(translate_string(30299), translate_string(30300))
delete_canceled = False
# now do work - delete unused
if question_delete_unused:
delete_pdialog = xbmcgui.DialogProgress()
delete_pdialog.create(string_load(30298), "")
delete_pdialog.create(translate_string(30298), "")
index = 0
params = {"properties": ["url"]}
@ -171,9 +171,9 @@ class CacheArtwork(threading.Thread):
delete_canceled = True
break
result_report.append(string_load(30385) + str(len(textures)))
result_report.append(string_load(30386) + str(len(unused_texture_ids)))
result_report.append(string_load(30387) + str(index))
result_report.append(translate_string(30385) + str(len(textures)))
result_report.append(translate_string(30386) + str(len(unused_texture_ids)))
result_report.append(translate_string(30387) + str(index))
del textures
del jellyfin_texture_urls
@ -187,7 +187,7 @@ class CacheArtwork(threading.Thread):
# now do work - cache images
if question_cache_images:
cache_pdialog = xbmcgui.DialogProgress()
cache_pdialog.create(string_load(30301), "")
cache_pdialog.create(translate_string(30301), "")
cache_report = self.cache_artwork(cache_pdialog)
cache_pdialog.close()
del cache_pdialog
@ -196,12 +196,12 @@ class CacheArtwork(threading.Thread):
if len(result_report) > 0:
msg = "\r\n".join(result_report)
xbmcgui.Dialog().textviewer(string_load(30125), msg, usemono=True)
xbmcgui.Dialog().textviewer(translate_string(30125), msg, usemono=True)
def cache_artwork_background(self):
log.debug("cache_artwork_background")
dp = xbmcgui.DialogProgressBG()
dp.create(string_load(30301), "")
dp.create(translate_string(30301), "")
result_text = None
try:
result_text = self.cache_artwork(dp)
@ -238,7 +238,7 @@ class CacheArtwork(threading.Thread):
if self.stop_all_activity:
return None
progress.update(0, string_load(30359))
progress.update(0, translate_string(30359))
texture_urls = set()
@ -268,7 +268,7 @@ class CacheArtwork(threading.Thread):
# get the password
xbmc_password = get_value("services.webserverpassword")
progress.update(0, string_load(30356))
progress.update(0, translate_string(30356))
params = {"properties": ["url"]}
json_result = JsonRpc('Textures.GetTextures').execute(params)
@ -278,7 +278,7 @@ class CacheArtwork(threading.Thread):
if self.stop_all_activity:
return
progress.update(0, string_load(30357))
progress.update(0, translate_string(30357))
texture_urls = set()
for texture in textures:
@ -296,7 +296,7 @@ class CacheArtwork(threading.Thread):
if self.stop_all_activity:
return
progress.update(0, string_load(30358))
progress.update(0, translate_string(30358))
jellyfin_texture_urls = self.get_jellyfin_artwork(progress)
if jellyfin_texture_urls is None:
@ -347,7 +347,7 @@ class CacheArtwork(threading.Thread):
break
result_report = []
result_report.append(string_load(30302) + str(len(texture_urls)))
result_report.append(string_load(30303) + str(len(missing_texture_urls)))
result_report.append(string_load(30304) + str(count_done))
result_report.append(translate_string(30302) + str(len(texture_urls)))
result_report.append(translate_string(30303) + str(len(missing_texture_urls)))
result_report.append(translate_string(30304) + str(count_done))
return result_report

View File

@ -1,55 +0,0 @@
# Gnu General Public License - see LICENSE.TXT
from __future__ import division, absolute_import, print_function, unicode_literals
from uuid import uuid4
from kodi_six.utils import py2_decode
import xbmcaddon
import xbmc
import xbmcvfs
from .kodi_utils import HomeWindow
from .loghandler import LazyLogger
log = LazyLogger(__name__)
class ClientInformation:
@staticmethod
def get_device_id():
window = HomeWindow()
client_id = window.get_property("client_id")
if client_id:
return client_id
jellyfin_guid_path = py2_decode(xbmc.translatePath("special://temp/jellycon_guid"))
log.debug("jellyfin_guid_path: {0}".format(jellyfin_guid_path))
guid = xbmcvfs.File(jellyfin_guid_path)
client_id = guid.read()
guid.close()
if not client_id:
# Needs to be captilized for backwards compat
client_id = uuid4().hex.upper()
log.debug("Generating a new guid: {0}".format(client_id))
guid = xbmcvfs.File(jellyfin_guid_path, 'w')
guid.write(client_id)
guid.close()
log.debug("jellyfin_client_id (NEW): {0}".format(client_id))
else:
log.debug("jellyfin_client_id: {0}".format(client_id))
window.set_property("client_id", client_id)
return client_id
@staticmethod
def get_version():
addon = xbmcaddon.Addon()
version = addon.getAddonInfo("version")
return version
@staticmethod
def get_client():
return 'Kodi JellyCon'

View File

@ -1,41 +0,0 @@
from __future__ import division, absolute_import, print_function, unicode_literals
import threading
import xbmc
from .loghandler import LazyLogger
from resources.lib.functions import show_menu
log = LazyLogger(__name__)
class ContextMonitor(threading.Thread):
stop_thread = False
def run(self):
item_id = None
log.debug("ContextMonitor Thread Started")
while not xbmc.Monitor().abortRequested() and not self.stop_thread:
if xbmc.getCondVisibility("Window.IsActive(fullscreenvideo) | Window.IsActive(visualisation)"):
xbmc.sleep(1000)
else:
if xbmc.getCondVisibility("Window.IsVisible(contextmenu)"):
if item_id:
xbmc.executebuiltin("Dialog.Close(contextmenu,true)")
params = {}
params["item_id"] = item_id
show_menu(params)
container_id = xbmc.getInfoLabel("System.CurrentControlID")
item_id = xbmc.getInfoLabel("Container(" + str(container_id) + ").ListItem.Property(id)")
xbmc.sleep(100)
log.debug("ContextMonitor Thread Exited")
def stop_monitor(self):
log.debug("ContextMonitor Stop Called")
self.stop_thread = True

View File

@ -1,7 +1,6 @@
# Gnu General Public License - see LICENSE.TXT
from __future__ import division, absolute_import, print_function, unicode_literals
from collections import defaultdict
import threading
import hashlib
import os
@ -12,9 +11,9 @@ from .downloadutils import DownloadUtils
from .loghandler import LazyLogger
from .item_functions import extract_item_info
from .kodi_utils import HomeWindow
from .translation import string_load
from .tracking import timer
from .filelock import FileLock
from .utils import translate_string
import xbmc
import xbmcaddon
@ -268,8 +267,8 @@ def clear_cached_server_data():
del_count += 1
log.debug('Deleted {} files'.format(del_count))
msg = string_load(30394)
xbmcgui.Dialog().ok(string_load(30393), msg)
msg = translate_string(30394)
xbmcgui.Dialog().ok(translate_string(30393), msg)
def clear_old_cache_data():

205
resources/lib/dialogs.py Normal file
View File

@ -0,0 +1,205 @@
from __future__ import division, absolute_import, print_function, unicode_literals
import xbmcgui
from .loghandler import LazyLogger
from .utils import translate_string, send_event_notification
log = LazyLogger(__name__)
class BitrateDialog(xbmcgui.WindowXMLDialog):
slider_control = None
bitrate_label = None
initial_bitrate_value = 0
selected_transcode_value = 0
def __init__(self, *args, **kwargs):
log.debug("BitrateDialog: __init__")
xbmcgui.WindowXML.__init__(self, *args, **kwargs)
def onInit(self):
log.debug("ActionMenu: onInit")
self.action_exitkeys_id = [10, 13]
self.slider_control = self.getControl(3000)
self.slider_control.setInt(self.initial_bitrate_value, 400, 100, 15000)
self.bitrate_label = self.getControl(3030)
bitrate_label_string = str(self.slider_control.getInt()) + " Kbs"
self.bitrate_label.setLabel(bitrate_label_string)
def onFocus(self, control_id):
pass
def doAction(self, action_id):
pass
def onMessage(self, message):
log.debug("ActionMenu: onMessage: {0}".format(message))
def onAction(self, action):
bitrate_label_string = str(self.slider_control.getInt()) + " Kbs"
self.bitrate_label.setLabel(bitrate_label_string)
if action.getId() == 10: # ACTION_PREVIOUS_MENU
self.close()
elif action.getId() == 92: # ACTION_NAV_BACK
self.close()
elif action.getId() == 7: # ENTER
self.selected_transcode_value = self.slider_control.getInt()
self.close()
def onClick(self, control_id):
if control_id == 3000:
log.debug("ActionMenu: Selected Item: {0}".format(control_id))
class ResumeDialog(xbmcgui.WindowXMLDialog):
resumePlay = -1
resumeTimeStamp = ""
action_exitkeys_id = None
def __init__(self, *args, **kwargs):
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
log.debug("ResumeDialog INITIALISED")
def onInit(self):
self.action_exitkeys_id = [10, 13]
self.getControl(3010).setLabel(self.resumeTimeStamp)
self.getControl(3011).setLabel(translate_string(30237))
def onFocus(self, controlId):
pass
def doAction(self, actionID):
pass
def onClick(self, controlID):
if controlID == 3010:
self.resumePlay = 0
self.close()
if controlID == 3011:
self.resumePlay = 1
self.close()
def setResumeTime(self, timeStamp):
self.resumeTimeStamp = timeStamp
def getResumeAction(self):
return self.resumePlay
class SafeDeleteDialog(xbmcgui.WindowXMLDialog):
confirm = False
message = "Demo Message"
heading = "Demo Heading"
action_exitkeys_id = None
def __init__(self, *args, **kwargs):
log.debug("SafeDeleteDialog: __init__")
xbmcgui.WindowXML.__init__(self, *args, **kwargs)
def onInit(self):
log.debug("SafeDeleteDialog: onInit")
self.action_exitkeys_id = [10, 13]
message_control = self.getControl(3)
message_control.setText(self.message)
message_control = self.getControl(4)
message_control.setLabel(self.heading)
def onFocus(self, controlId):
pass
def doAction(self, actionID):
pass
def onMessage(self, message):
log.debug("SafeDeleteDialog: onMessage: {0}".format(message))
def onAction(self, action):
if action.getId() == 10: # ACTION_PREVIOUS_MENU
self.close()
elif action.getId() == 92: # ACTION_NAV_BACK
self.close()
else:
log.debug("SafeDeleteDialog: onAction: {0}".format(action.getId()))
def onClick(self, controlID):
if controlID == 1:
self.confirm = True
self.close()
elif controlID == 2:
self.confirm = False
self.close()
class PlayNextDialog(xbmcgui.WindowXMLDialog):
action_exitkeys_id = None
episode_info = None
play_called = False
def __init__(self, *args, **kwargs):
log.debug("PlayNextDialog: __init__")
xbmcgui.WindowXML.__init__(self, *args, **kwargs)
def onInit(self):
log.debug("PlayNextDialog: onInit")
self.action_exitkeys_id = [10, 13]
index = self.episode_info.get("IndexNumber", -1)
series_name = self.episode_info.get("SeriesName")
next_epp_name = "Episode %02d - (%s)" % (index, self.episode_info.get("Name", "n/a"))
series_label = self.getControl(3011)
series_label.setLabel(series_name)
series_label = self.getControl(3012)
series_label.setLabel(next_epp_name)
def onFocus(self, control_id):
pass
def doAction(self, action_id):
pass
def onMessage(self, message):
log.debug("PlayNextDialog: onMessage: {0}".format(message))
def onAction(self, action):
if action.getId() == 10: # ACTION_PREVIOUS_MENU
self.close()
elif action.getId() == 92: # ACTION_NAV_BACK
self.close()
else:
log.debug("PlayNextDialog: onAction: {0}".format(action.getId()))
def onClick(self, control_id):
if control_id == 3013:
log.debug("PlayNextDialog: Play Next Episode")
self.play_called
self.close()
next_item_id = self.episode_info.get("Id")
log.debug("Playing Next Episode: {0}".format(next_item_id))
play_info = {}
play_info["item_id"] = next_item_id
play_info["auto_resume"] = "-1"
play_info["force_transcode"] = False
send_event_notification("jellycon_play_action", play_info)
elif control_id == 3014:
self.close()
def set_episode_info(self, info):
self.episode_info = info
def get_play_called(self):
return self.play_called

View File

@ -10,12 +10,10 @@ import sys
import re
from .datamanager import DataManager
from .kodi_utils import HomeWindow
from .downloadutils import DownloadUtils
from .translation import string_load
from .loghandler import LazyLogger
from .item_functions import add_gui_item, ItemDetails
from .utils import send_event_notification
from .utils import send_event_notification, translate_string
from .tracking import timer
log = LazyLogger(__name__)
@ -28,7 +26,7 @@ def get_content(url, params):
default_sort = params.get("sort")
media_type = params.get("media_type", None)
if not media_type:
xbmcgui.Dialog().ok(string_load(30135), string_load(30139))
xbmcgui.Dialog().ok(translate_string(30135), translate_string(30139))
log.debug("URL: {0}".format(url))
log.debug("MediaType: {0}".format(media_type))
@ -78,8 +76,8 @@ def get_content(url, params):
progress = None
if settings.getSetting('showLoadProgress') == "true":
progress = xbmcgui.DialogProgress()
progress.create(string_load(30112))
progress.update(0, string_load(30113))
progress.create(translate_string(30112))
progress.update(0, translate_string(30113))
# update url for paging
start_index = 0
@ -167,7 +165,7 @@ def get_content(url, params):
log.debug("No view id for view type:{0}".format(view_key))
if progress is not None:
progress.update(100, string_load(30125))
progress.update(100, translate_string(30125))
progress.close()
return
@ -290,7 +288,7 @@ def process_directory(url, progress, params, use_cache_data=False):
if progress is not None:
percent_done = (float(current_item) / float(item_count)) * 100
progress.update(int(percent_done), string_load(30126) + str(current_item))
progress.update(int(percent_done), translate_string(30126) + str(current_item))
current_item = current_item + 1
if detected_type is not None:
@ -387,7 +385,7 @@ def process_directory(url, progress, params, use_cache_data=False):
item_details = ItemDetails()
item_details.id = first_season_item.id
item_details.name = string_load(30290)
item_details.name = translate_string(30290)
item_details.art = first_season_item.art
item_details.play_count = played
item_details.overlay = overlay

View File

@ -6,8 +6,6 @@ import xbmcaddon
import requests
import hashlib
import ssl
import gzip
import json
from six.moves.urllib.parse import urlparse
from base64 import b64encode
@ -17,10 +15,9 @@ from kodi_six.utils import py2_decode
from six import ensure_text
from .kodi_utils import HomeWindow
from .clientinfo import ClientInformation
from .loghandler import LazyLogger
from .translation import string_load
from .tracking import timer
from .utils import get_device_id, get_version, translate_string
log = LazyLogger(__name__)
@ -342,7 +339,7 @@ class DownloadUtils:
def get_server(self):
settings = xbmcaddon.Addon()
#For migration from storing URL parts to just one URL
# For migration from storing URL parts to just one URL
if settings.getSetting('ipaddress') != "" and settings.getSetting('ipaddress') != "<none>":
log.info("Migrating to new server url storage")
url = ("http://" if settings.getSetting('protocol') == "0" else "https://") + settings.getSetting('ipaddress') + ":" + settings.getSetting('port')
@ -431,7 +428,6 @@ class DownloadUtils:
return artwork
def image_url(self, item_id, art_type, index, width, height, image_tag, server):
# test imageTag e3ab56fe27d389446754d0fb04910a34
@ -506,8 +502,8 @@ class DownloadUtils:
if secure or not userid:
auth_ok = self.authenticate()
if auth_ok == "":
xbmcgui.Dialog().notification(string_load(30316),
string_load(30044),
xbmcgui.Dialog().notification(translate_string(30316),
translate_string(30044),
icon="special://home/addons/plugin.video.jellycon/icon.png")
return ""
if not userid:
@ -517,8 +513,8 @@ class DownloadUtils:
user_image = 'DefaultUser.png'
if userid == "":
xbmcgui.Dialog().notification(string_load(30316),
string_load(30045),
xbmcgui.Dialog().notification(translate_string(30316),
translate_string(30045),
icon="special://home/addons/plugin.video.jellycon/icon.png")
log.debug("userid: {0}".format(userid))
@ -573,10 +569,9 @@ class DownloadUtils:
return ""
def get_auth_header(self, authenticate=True):
client_info = ClientInformation()
txt_mac = client_info.get_device_id()
version = client_info.get_version()
client = client_info.get_client()
txt_mac = get_device_id()
version = get_version()
client = 'Kodi JellyCon'
settings = xbmcaddon.Addon()
device_name = settings.getSetting('deviceName')
@ -668,7 +663,7 @@ class DownloadUtils:
user_and_pass = b64encode(b"%s:%s" % (user_name, user_password)).decode("ascii")
head["Authorization"] = 'Basic %s' % user_and_pass
head["User-Agent"] = "JellyCon-" + ClientInformation().get_version()
head["User-Agent"] = "JellyCon-" + get_version()
http_request = getattr(requests, method.lower())
@ -687,7 +682,6 @@ class DownloadUtils:
else:
data = http_request(url, headers=head)
if data.status_code == 200:
if headers is not None and isinstance(headers, dict):
@ -707,8 +701,8 @@ class DownloadUtils:
log.error("HTTP response error for {0}: {1} {2}".format(url, data.status_code, data.content))
if suppress is False:
xbmcgui.Dialog().notification(string_load(30316),
'{}: {}'.format(string_load(30200), data.content),
xbmcgui.Dialog().notification(translate_string(30316),
'{}: {}'.format(translate_string(30200), data.content),
icon="special://home/addons/plugin.video.jellycon/icon.png")
try:
result = data.json()
@ -719,6 +713,6 @@ class DownloadUtils:
log.error("{0}".format(format_exc()))
log.error("Unable to connect to {0} : {1}".format(server, msg))
if not suppress:
xbmcgui.Dialog().notification(string_load(30316),
xbmcgui.Dialog().notification(translate_string(30316),
str(msg),
icon="special://home/addons/plugin.video.jellycon/icon.png")

View File

@ -90,6 +90,7 @@ import sys
import time
import errno
class FileLock(object):
""" A file locking mechanism that has context-manager support so
you can use it in a ``with`` statement. This should be relatively cross

View File

@ -7,7 +7,6 @@ import os
import time
import cProfile
import pstats
import json
from six import StringIO
import xbmcplugin
@ -16,18 +15,16 @@ import xbmcaddon
import xbmc
from .downloadutils import DownloadUtils, load_user_details
from .utils import get_art, send_event_notification, convert_size
from .utils import convert_size, translate_string, get_version
from .item_functions import get_art
from .kodi_utils import HomeWindow
from .clientinfo import ClientInformation
from .datamanager import DataManager, clear_cached_server_data
from .server_detect import check_server, check_connection_speed
from .loghandler import LazyLogger
from .menu_functions import display_main_menu, display_menu, show_movie_alpha_list, show_tvshow_alpha_list, show_genre_list, show_search, show_movie_pages
from .translation import string_load
from .server_sessions import show_server_sessions
from .action_menu import ActionMenu
from .bitrate_dialog import BitrateDialog
from .safe_delete_dialog import SafeDeleteDialog
from .dialogs import BitrateDialog, SafeDeleteDialog
from .widgets import get_widget_content, get_widget_content_cast, check_for_new_content
from . import trakttokodi
from .cache_images import CacheArtwork
@ -63,7 +60,7 @@ def main_entry_point():
pr.enable()
log.debug("Running Python: {0}".format(sys.version_info))
log.debug("Running JellyCon: {0}".format(ClientInformation().get_version()))
log.debug("Running JellyCon: {0}".format(get_version()))
log.debug("Kodi BuildVersion: {0}".format(xbmc.getInfoLabel("System.BuildVersion")))
log.debug("Kodi Version: {0}".format(kodi_version))
log.debug("Script argument data: {0}".format(sys.argv))
@ -298,15 +295,15 @@ def delete(item_id):
final_name += item_name
if not item.get("CanDelete", False):
xbmcgui.Dialog().ok(string_load(30135), string_load(30417), final_name)
xbmcgui.Dialog().ok(translate_string(30135), translate_string(30417), final_name)
return
return_value = xbmcgui.Dialog().yesno(string_load(30091), '{}\n{}'.format(final_name, string_load(30092)))
return_value = xbmcgui.Dialog().yesno(translate_string(30091), '{}\n{}'.format(final_name, translate_string(30092)))
if return_value:
log.debug('Deleting Item: {0}'.format(item_id))
url = '{server}/Items/' + item_id
progress = xbmcgui.DialogProgress()
progress.create(string_load(30052), string_load(30053))
progress.create(translate_string(30052), translate_string(30053))
downloadUtils.download_url(url, method="DELETE")
progress.close()
check_for_new_content()
@ -357,37 +354,37 @@ def show_menu(params):
action_items = []
if result["Type"] in ["Episode", "Movie", "Music", "Video", "Audio", "TvChannel", "Program"]:
li = xbmcgui.ListItem(string_load(30314))
li = xbmcgui.ListItem(translate_string(30314))
li.setProperty('menu_id', 'play')
action_items.append(li)
if result["Type"] in ["Season", "MusicAlbum", "Playlist"]:
li = xbmcgui.ListItem(string_load(30317))
li = xbmcgui.ListItem(translate_string(30317))
li.setProperty('menu_id', 'play_all')
action_items.append(li)
if result["Type"] in ["Episode", "Movie", "Video", "TvChannel", "Program"]:
li = xbmcgui.ListItem(string_load(30275))
li = xbmcgui.ListItem(translate_string(30275))
li.setProperty('menu_id', 'transcode')
action_items.append(li)
if result["Type"] in ["Episode", "Movie", "Music", "Video", "Audio"]:
li = xbmcgui.ListItem(string_load(30402))
li = xbmcgui.ListItem(translate_string(30402))
li.setProperty('menu_id', 'add_to_playlist')
action_items.append(li)
if result["Type"] in ("Movie", "Series"):
li = xbmcgui.ListItem(string_load(30307))
li = xbmcgui.ListItem(translate_string(30307))
li.setProperty('menu_id', 'play_trailer')
action_items.append(li)
if result["Type"] == "Episode" and result["ParentId"] is not None:
li = xbmcgui.ListItem(string_load(30327))
li = xbmcgui.ListItem(translate_string(30327))
li.setProperty('menu_id', 'view_season')
action_items.append(li)
if result["Type"] in ("Series", "Season", "Episode"):
li = xbmcgui.ListItem(string_load(30354))
li = xbmcgui.ListItem(translate_string(30354))
li.setProperty('menu_id', 'view_series')
action_items.append(li)
@ -401,26 +398,26 @@ def show_menu(params):
progress = user_data.get("PlaybackPositionTicks", 0) != 0
played = user_data.get("Played", False)
if not played or progress:
li = xbmcgui.ListItem(string_load(30270))
li = xbmcgui.ListItem(translate_string(30270))
li.setProperty('menu_id', 'mark_watched')
action_items.append(li)
if played or progress:
li = xbmcgui.ListItem(string_load(30271))
li = xbmcgui.ListItem(translate_string(30271))
li.setProperty('menu_id', 'mark_unwatched')
action_items.append(li)
if user_data.get("IsFavorite", False) is False:
li = xbmcgui.ListItem(string_load(30272))
li = xbmcgui.ListItem(translate_string(30272))
li.setProperty('menu_id', 'jellyfin_set_favorite')
action_items.append(li)
else:
li = xbmcgui.ListItem(string_load(30273))
li = xbmcgui.ListItem(translate_string(30273))
li.setProperty('menu_id', 'jellyfin_unset_favorite')
action_items.append(li)
can_delete = result.get("CanDelete", False)
if can_delete:
li = xbmcgui.ListItem(string_load(30274))
li = xbmcgui.ListItem(translate_string(30274))
li.setProperty('menu_id', 'delete')
action_items.append(li)
@ -430,20 +427,20 @@ def show_menu(params):
li.setProperty('menu_id', 'safe_delete')
action_items.append(li)
li = xbmcgui.ListItem(string_load(30398))
li = xbmcgui.ListItem(translate_string(30398))
li.setProperty('menu_id', 'refresh_server')
action_items.append(li)
li = xbmcgui.ListItem(string_load(30281))
li = xbmcgui.ListItem(translate_string(30281))
li.setProperty('menu_id', 'refresh_images')
action_items.append(li)
if result["Type"] in ["Movie", "Series"]:
li = xbmcgui.ListItem(string_load(30399))
li = xbmcgui.ListItem(translate_string(30399))
li.setProperty('menu_id', 'hide')
action_items.append(li)
li = xbmcgui.ListItem(string_load(30401))
li = xbmcgui.ListItem(translate_string(30401))
li.setProperty('menu_id', 'info')
action_items.append(li)
@ -670,7 +667,7 @@ def populate_listitem(item_id):
result = downloadUtils.download_url(url)
log.debug("populate_listitem item info: {0}".format(result))
item_title = result.get("Name", string_load(30280))
item_title = result.get("Name", translate_string(30280))
list_item = xbmcgui.ListItem(label=item_title)
@ -777,13 +774,13 @@ def search_results(params):
item_type = item_type.lower()
if item_type == 'movie':
heading_type = string_load(30231)
heading_type = translate_string(30231)
content_type = 'movies'
elif item_type == 'series':
heading_type = string_load(30229)
heading_type = translate_string(30229)
content_type = 'tvshows'
elif item_type == 'episode':
heading_type = string_load(30235)
heading_type = translate_string(30235)
content_type = 'episodes'
params["name_format"] = "Episode|episode_name_format"
elif item_type == "music" or item_type == "audio" or item_type == "musicalbum":
@ -802,7 +799,7 @@ def search_results(params):
home_window = HomeWindow()
last_search = home_window.get_property("last_search")
kb = xbmc.Keyboard()
kb.setHeading(heading_type.capitalize() + ' ' + string_load(30246).lower())
kb.setHeading(heading_type.capitalize() + ' ' + translate_string(30246).lower())
kb.setDefault(last_search)
kb.doModal()
@ -829,8 +826,8 @@ def search_results(params):
progress = None
if settings.getSetting('showLoadProgress') == "true":
progress = xbmcgui.DialogProgress()
progress.create(string_load(30112))
progress.update(0, string_load(30113))
progress.create(translate_string(30112))
progress.update(0, translate_string(30113))
# what type of search
if item_type == "person":
@ -903,7 +900,7 @@ def search_results(params):
xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
if progress is not None:
progress.update(100, string_load(30125))
progress.update(100, translate_string(30125))
progress.close()
@ -1014,7 +1011,7 @@ def play_item_trailer(item_id):
trailer_text.append(name)
dialog = xbmcgui.Dialog()
resp = dialog.select(string_load(30308), trailer_text)
resp = dialog.select(translate_string(30308), trailer_text)
if resp > -1:
trailer = trailer_list[resp]
log.debug("SelectedTrailer: {0}".format(trailer))

View File

@ -16,7 +16,7 @@ import io
from .loghandler import LazyLogger
from .datamanager import DataManager
from .downloadutils import DownloadUtils
from .utils import get_art
from .item_functions import get_art
pil_loaded = False
try:
@ -187,7 +187,6 @@ class HttpImageHandler(BaseHTTPRequestHandler):
class HttpImageServerThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.keep_running = True

View File

@ -6,16 +6,13 @@ from six.moves.urllib.parse import quote
from datetime import datetime
from collections import defaultdict
import xbmc
import xbmcaddon
import xbmcgui
from .utils import get_art, datetime_from_string
from .utils import datetime_from_string
from .loghandler import LazyLogger
from .downloadutils import DownloadUtils
from .kodi_utils import HomeWindow
from six import ensure_text
log = LazyLogger(__name__)
@ -25,9 +22,6 @@ addon_instance = xbmcaddon.Addon()
addon_path = addon_instance.getAddonInfo('path')
PLUGINPATH = xbmc.translatePath(os.path.join(addon_path))
download_utils = DownloadUtils()
home_window = HomeWindow()
class ItemDetails:
@ -250,6 +244,7 @@ def extract_item_info(item, gui_options):
people = item.get("People", [])
if people is not None:
cast = []
download_utils = DownloadUtils()
for person in people:
person_type = person.get("Type")
if person_type == "Director":
@ -615,3 +610,87 @@ def add_gui_item(url, item_details, display_options, folder=True, default_sort=F
list_item.setProperty(key, value)
return u, list_item, folder
def get_art(item, server):
download_utils = DownloadUtils()
art = {
'thumb': '',
'fanart': '',
'poster': '',
'banner': '',
'clearlogo': '',
'clearart': '',
'discart': '',
'landscape': '',
'tvshow.fanart': '',
'tvshow.poster': '',
'tvshow.clearart': '',
'tvshow.clearlogo': '',
'tvshow.banner': '',
'tvshow.landscape': ''
}
image_tags = item.get("ImageTags", {})
if image_tags and image_tags.get("Primary"):
art['thumb'] = download_utils.get_artwork(item, "Primary", server=server)
item_type = item["Type"]
if item_type == "Genre":
art['poster'] = download_utils.get_artwork(item, "Primary", server=server)
elif item_type == "Episode":
art['tvshow.poster'] = download_utils.get_artwork(item, "Primary", parent=True, server=server)
art['tvshow.clearart'] = download_utils.get_artwork(item, "Art", parent=True, server=server)
art['clearart'] = download_utils.get_artwork(item, "Art", parent=True, server=server)
art['tvshow.clearlogo'] = download_utils.get_artwork(item, "Logo", parent=True, server=server)
art['clearlogo'] = download_utils.get_artwork(item, "Logo", parent=True, server=server)
art['tvshow.banner'] = download_utils.get_artwork(item, "Banner", parent=True, server=server)
art['banner'] = download_utils.get_artwork(item, "Banner", parent=True, server=server)
art['tvshow.landscape'] = download_utils.get_artwork(item, "Thumb", parent=True, server=server)
art['landscape'] = download_utils.get_artwork(item, "Thumb", parent=True, server=server)
art['tvshow.fanart'] = download_utils.get_artwork(item, "Backdrop", parent=True, server=server)
art['fanart'] = download_utils.get_artwork(item, "Backdrop", parent=True, server=server)
elif item_type == "Season":
art['tvshow.poster'] = download_utils.get_artwork(item, "Primary", parent=True, server=server)
art['season.poster'] = download_utils.get_artwork(item, "Primary", parent=False, server=server)
art['poster'] = download_utils.get_artwork(item, "Primary", parent=False, server=server)
art['tvshow.clearart'] = download_utils.get_artwork(item, "Art", parent=True, server=server)
art['clearart'] = download_utils.get_artwork(item, "Art", parent=True, server=server)
art['tvshow.clearlogo'] = download_utils.get_artwork(item, "Logo", parent=True, server=server)
art['clearlogo'] = download_utils.get_artwork(item, "Logo", parent=True, server=server)
art['tvshow.banner'] = download_utils.get_artwork(item, "Banner", parent=True, server=server)
art['season.banner'] = download_utils.get_artwork(item, "Banner", parent=False, server=server)
art['banner'] = download_utils.get_artwork(item, "Banner", parent=False, server=server)
art['tvshow.landscape'] = download_utils.get_artwork(item, "Thumb", parent=True, server=server)
art['season.landscape'] = download_utils.get_artwork(item, "Thumb", parent=False, server=server)
art['landscape'] = download_utils.get_artwork(item, "Thumb", parent=False, server=server)
art['tvshow.fanart'] = download_utils.get_artwork(item, "Backdrop", parent=True, server=server)
art['fanart'] = download_utils.get_artwork(item, "Backdrop", parent=True, server=server)
elif item_type == "Series":
art['tvshow.poster'] = download_utils.get_artwork(item, "Primary", parent=False, server=server)
art['poster'] = download_utils.get_artwork(item, "Primary", parent=False, server=server)
art['tvshow.clearart'] = download_utils.get_artwork(item, "Art", parent=False, server=server)
art['clearart'] = download_utils.get_artwork(item, "Art", parent=False, server=server)
art['tvshow.clearlogo'] = download_utils.get_artwork(item, "Logo", parent=False, server=server)
art['clearlogo'] = download_utils.get_artwork(item, "Logo", parent=False, server=server)
art['tvshow.banner'] = download_utils.get_artwork(item, "Banner", parent=False, server=server)
art['banner'] = download_utils.get_artwork(item, "Banner", parent=False, server=server)
art['tvshow.landscape'] = download_utils.get_artwork(item, "Thumb", parent=False, server=server)
art['landscape'] = download_utils.get_artwork(item, "Thumb", parent=False, server=server)
art['tvshow.fanart'] = download_utils.get_artwork(item, "Backdrop", parent=False, server=server)
art['fanart'] = download_utils.get_artwork(item, "Backdrop", parent=False, server=server)
elif item_type == "Movie" or item_type == "BoxSet":
art['poster'] = download_utils.get_artwork(item, "Primary", server=server)
art['landscape'] = download_utils.get_artwork(item, "Thumb", server=server)
art['banner'] = download_utils.get_artwork(item, "Banner", server=server)
art['clearlogo'] = download_utils.get_artwork(item, "Logo", server=server)
art['clearart'] = download_utils.get_artwork(item, "Art", server=server)
art['discart'] = download_utils.get_artwork(item, "Disc", server=server)
art['fanart'] = download_utils.get_artwork(item, "Backdrop", server=server)
if not art['fanart']:
art['fanart'] = download_utils.get_artwork(item, "Backdrop", parent=True, server=server)
return art

View File

@ -10,7 +10,6 @@ import traceback
from six import ensure_text
from kodi_six import xbmc, xbmcaddon
from six.moves.urllib.parse import urlparse
##################################################################################################

View File

@ -14,9 +14,9 @@ import xbmcaddon
from .downloadutils import DownloadUtils
from .kodi_utils import add_menu_directory_item, HomeWindow
from .loghandler import LazyLogger
from .translation import string_load
from .datamanager import DataManager
from .utils import get_art, get_jellyfin_url
from .utils import get_jellyfin_url, translate_string
from .item_functions import get_art
log = LazyLogger(__name__)
downloadUtils = DownloadUtils()
@ -253,7 +253,7 @@ def show_movie_pages(menu_params):
"&mode=GET_CONTENT" +
"&media_type=" + collection["media_type"])
log.debug("addMenuDirectoryItem: {0} - {1} - {2}".format(collection.get('title'), url, collection.get("art")))
add_menu_directory_item(collection.get('title', string_load(30250)), url, art=collection.get("art"))
add_menu_directory_item(collection.get('title', translate_string(30250)), url, art=collection.get("art"))
xbmcplugin.endOfDirectory(int(sys.argv[1]))
@ -334,7 +334,7 @@ def show_genre_list(menu_params):
"&mode=GET_CONTENT" +
"&media_type=" + collection["media_type"])
log.debug("addMenuDirectoryItem: {0} - {1} - {2}".format(collection.get('title'), url, collection.get("art")))
add_menu_directory_item(collection.get('title', string_load(30250)), url, art=collection.get("art"))
add_menu_directory_item(collection.get('title', translate_string(30250)), url, art=collection.get("art"))
xbmcplugin.endOfDirectory(int(sys.argv[1]))
@ -400,7 +400,7 @@ def show_movie_alpha_list(menu_params):
url = (sys.argv[0] + "?url=" + quote(collection['path']) +
"&mode=GET_CONTENT&media_type=" + collection["media_type"])
log.debug("addMenuDirectoryItem: {0} ({1})".format(collection.get('title'), url))
add_menu_directory_item(collection.get('title', string_load(30250)), url, art=collection.get("art"))
add_menu_directory_item(collection.get('title', translate_string(30250)), url, art=collection.get("art"))
xbmcplugin.endOfDirectory(int(sys.argv[1]))
@ -461,7 +461,7 @@ def show_tvshow_alpha_list(menu_params):
url = (sys.argv[0] + "?url=" + quote(collection['path']) +
"&mode=GET_CONTENT&media_type=" + collection["media_type"])
log.debug("addMenuDirectoryItem: {0} ({1})".format(collection.get('title'), url))
add_menu_directory_item(collection.get('title', string_load(30250)), url, art=collection.get("art"))
add_menu_directory_item(collection.get('title', translate_string(30250)), url, art=collection.get("art"))
xbmcplugin.endOfDirectory(int(sys.argv[1]))
@ -470,13 +470,13 @@ def display_main_menu():
handle = int(sys.argv[1])
xbmcplugin.setContent(handle, 'files')
add_menu_directory_item(string_load(30406),
add_menu_directory_item(translate_string(30406),
"plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=library")
add_menu_directory_item(string_load(30407),
add_menu_directory_item(translate_string(30407),
"plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=show_global_types")
add_menu_directory_item(string_load(30408),
add_menu_directory_item(translate_string(30408),
"plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=show_custom_widgets")
add_menu_directory_item(string_load(30409),
add_menu_directory_item(translate_string(30409),
"plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=addon_items")
xbmcplugin.endOfDirectory(handle)
@ -507,9 +507,9 @@ def display_menu(params):
def show_global_types(params):
handle = int(sys.argv[1])
add_menu_directory_item(string_load(30256),
add_menu_directory_item(translate_string(30256),
"plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=global_list_movies")
add_menu_directory_item(string_load(30261),
add_menu_directory_item(translate_string(30261),
"plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=global_list_tvshows")
xbmcplugin.endOfDirectory(handle)
@ -531,7 +531,7 @@ def display_homevideos_type(menu_params, view):
base_params["ImageTypeLimit"] = 1
path = get_jellyfin_url("{server}/Users/{userid}/Items", base_params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=homevideos"
add_menu_directory_item(view_name + string_load(30405), url)
add_menu_directory_item(view_name + translate_string(30405), url)
# In progress home movies
params = {}
@ -541,7 +541,7 @@ def display_homevideos_type(menu_params, view):
params["Limit"] = "{ItemLimit}"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=homevideos"
add_menu_directory_item(view_name + string_load(30267) + " (" + show_x_filtered_items + ")", url)
add_menu_directory_item(view_name + translate_string(30267) + " (" + show_x_filtered_items + ")", url)
# Recently added
params = {}
@ -555,21 +555,21 @@ def display_homevideos_type(menu_params, view):
params["Limit"] = "{ItemLimit}"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=homevideos"
add_menu_directory_item(view_name + string_load(30268) + " (" + show_x_filtered_items + ")", url)
add_menu_directory_item(view_name + translate_string(30268) + " (" + show_x_filtered_items + ")", url)
xbmcplugin.endOfDirectory(handle)
def display_addon_menu(params):
add_menu_directory_item(string_load(30246), "plugin://plugin.video.jellycon/?mode=SEARCH")
add_menu_directory_item(string_load(30017), "plugin://plugin.video.jellycon/?mode=SHOW_SERVER_SESSIONS")
add_menu_directory_item(string_load(30012), "plugin://plugin.video.jellycon/?mode=CHANGE_USER")
add_menu_directory_item(string_load(30011), "plugin://plugin.video.jellycon/?mode=DETECT_SERVER_USER")
add_menu_directory_item(string_load(30435), "plugin://plugin.video.jellycon/?mode=DETECT_CONNECTION_SPEED")
add_menu_directory_item(string_load(30254), "plugin://plugin.video.jellycon/?mode=SHOW_SETTINGS")
add_menu_directory_item(string_load(30395), "plugin://plugin.video.jellycon/?mode=CLEAR_CACHE")
add_menu_directory_item(string_load(30293), "plugin://plugin.video.jellycon/?mode=CACHE_ARTWORK")
add_menu_directory_item(translate_string(30246), "plugin://plugin.video.jellycon/?mode=SEARCH")
add_menu_directory_item(translate_string(30017), "plugin://plugin.video.jellycon/?mode=SHOW_SERVER_SESSIONS")
add_menu_directory_item(translate_string(30012), "plugin://plugin.video.jellycon/?mode=CHANGE_USER")
add_menu_directory_item(translate_string(30011), "plugin://plugin.video.jellycon/?mode=DETECT_SERVER_USER")
add_menu_directory_item(translate_string(30435), "plugin://plugin.video.jellycon/?mode=DETECT_CONNECTION_SPEED")
add_menu_directory_item(translate_string(30254), "plugin://plugin.video.jellycon/?mode=SHOW_SETTINGS")
add_menu_directory_item(translate_string(30395), "plugin://plugin.video.jellycon/?mode=CLEAR_CACHE")
add_menu_directory_item(translate_string(30293), "plugin://plugin.video.jellycon/?mode=CACHE_ARTWORK")
add_menu_directory_item("Clone default skin", "plugin://plugin.video.jellycon/?mode=CLONE_SKIN")
handle = int(sys.argv[1])
@ -579,7 +579,7 @@ def display_addon_menu(params):
def display_tvshow_type(menu_params, view):
handle = int(sys.argv[1])
view_name = string_load(30261)
view_name = translate_string(30261)
if view is not None:
view_name = view.get("Name")
@ -597,7 +597,7 @@ def display_tvshow_type(menu_params, view):
base_params["Recursive"] = True
path = get_jellyfin_url("{server}/Users/{userid}/Items", base_params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows"
add_menu_directory_item(view_name + string_load(30405), url)
add_menu_directory_item(view_name + translate_string(30405), url)
# Favorite TV Shows
params = {}
@ -605,7 +605,7 @@ def display_tvshow_type(menu_params, view):
params["Filters"] = "IsFavorite"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows"
add_menu_directory_item(view_name + string_load(30414), url)
add_menu_directory_item(view_name + translate_string(30414), url)
# Tv Shows with unplayed
params = {}
@ -613,7 +613,7 @@ def display_tvshow_type(menu_params, view):
params["IsPlayed"] = False
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows"
add_menu_directory_item(view_name + string_load(30285), url)
add_menu_directory_item(view_name + translate_string(30285), url)
# In progress episodes
params = {}
@ -626,7 +626,7 @@ def display_tvshow_type(menu_params, view):
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none"
url += "&name_format=" + quote('Episode|episode_name_format')
add_menu_directory_item(view_name + string_load(30267) + " (" + show_x_filtered_items + ")", url)
add_menu_directory_item(view_name + translate_string(30267) + " (" + show_x_filtered_items + ")", url)
# Latest Episodes
params = {}
@ -637,7 +637,7 @@ def display_tvshow_type(menu_params, view):
params["IncludeItemTypes"] = "Episode"
path = get_jellyfin_url("{server}/Users/{userid}/Items/Latest", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows&sort=none"
add_menu_directory_item(view_name + string_load(30288) + " (" + show_x_filtered_items + ")", url)
add_menu_directory_item(view_name + translate_string(30288) + " (" + show_x_filtered_items + ")", url)
# Recently Added
params = {}
@ -650,7 +650,7 @@ def display_tvshow_type(menu_params, view):
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none"
url += "&name_format=" + quote('Episode|episode_name_format')
add_menu_directory_item(view_name + string_load(30268) + " (" + show_x_filtered_items + ")", url)
add_menu_directory_item(view_name + translate_string(30268) + " (" + show_x_filtered_items + ")", url)
# Next Up Episodes
params = {}
@ -664,19 +664,19 @@ def display_tvshow_type(menu_params, view):
path = get_jellyfin_url("{server}/Shows/NextUp", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none"
url += "&name_format=" + quote('Episode|episode_name_format')
add_menu_directory_item(view_name + string_load(30278) + " (" + show_x_filtered_items + ")", url)
add_menu_directory_item(view_name + translate_string(30278) + " (" + show_x_filtered_items + ")", url)
# TV Show Genres
path = "plugin://plugin.video.jellycon/?mode=GENRES&item_type=tvshow"
if view is not None:
path += "&parent_id=" + view.get("Id")
add_menu_directory_item(view_name + string_load(30325), path)
add_menu_directory_item(view_name + translate_string(30325), path)
# TV Show Alpha picker
path = "plugin://plugin.video.jellycon/?mode=TVSHOW_ALPHA"
if view is not None:
path += "&parent_id=" + view.get("Id")
add_menu_directory_item(view_name + string_load(30404), path)
add_menu_directory_item(view_name + translate_string(30404), path)
xbmcplugin.endOfDirectory(handle)
@ -696,7 +696,7 @@ def display_music_type(menu_params, view):
params["IncludeItemTypes"] = "MusicAlbum"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbums"
add_menu_directory_item(view_name + string_load(30320), url)
add_menu_directory_item(view_name + translate_string(30320), url)
# recently added
params = {}
@ -706,7 +706,7 @@ def display_music_type(menu_params, view):
params["Limit"] = "{ItemLimit}"
path = get_jellyfin_url("{server}/Users/{userid}/Items/Latest", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbums"
add_menu_directory_item(view_name + string_load(30268) + " (" + show_x_filtered_items + ")", url)
add_menu_directory_item(view_name + translate_string(30268) + " (" + show_x_filtered_items + ")", url)
# recently played
params = {}
@ -720,7 +720,7 @@ def display_music_type(menu_params, view):
params["SortOrder"] = "Descending"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbum"
add_menu_directory_item(view_name + string_load(30349) + " (" + show_x_filtered_items + ")", url)
add_menu_directory_item(view_name + translate_string(30349) + " (" + show_x_filtered_items + ")", url)
# most played
params = {}
@ -734,7 +734,7 @@ def display_music_type(menu_params, view):
params["SortOrder"] = "Descending"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbum"
add_menu_directory_item(view_name + string_load(30353) + " (" + show_x_filtered_items + ")", url)
add_menu_directory_item(view_name + translate_string(30353) + " (" + show_x_filtered_items + ")", url)
# artists
params = {}
@ -743,7 +743,7 @@ def display_music_type(menu_params, view):
params["ImageTypeLimit"] = 1
path = get_jellyfin_url("{server}/Artists/AlbumArtists", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicArtists"
add_menu_directory_item(view_name + string_load(30321), url)
add_menu_directory_item(view_name + translate_string(30321), url)
xbmcplugin.endOfDirectory(handle)
@ -763,7 +763,7 @@ def display_musicvideos_type(params, view):
params["Fields"] = "{field_filters}"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=musicvideos"
add_menu_directory_item(view_name + string_load(30405), url)
add_menu_directory_item(view_name + translate_string(30405), url)
xbmcplugin.endOfDirectory(handle)
@ -782,7 +782,7 @@ def display_livetv_type(menu_params, view):
params["Fields"] = "{field_filters}"
path = get_jellyfin_url("{server}/LiveTv/Channels", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=livetv"
add_menu_directory_item(view_name + string_load(30360), url)
add_menu_directory_item(view_name + translate_string(30360), url)
# programs
params = {}
@ -793,7 +793,7 @@ def display_livetv_type(menu_params, view):
params["EnableTotalRecordCount"] = False
path = get_jellyfin_url("{server}/LiveTv/Programs/Recommended", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=livetv"
add_menu_directory_item(view_name + string_load(30361), url)
add_menu_directory_item(view_name + translate_string(30361), url)
# recordings
params = {}
@ -804,7 +804,7 @@ def display_livetv_type(menu_params, view):
params["EnableTotalRecordCount"] = False
path = get_jellyfin_url("{server}/LiveTv/Recordings", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=livetv"
add_menu_directory_item(view_name + string_load(30362), url)
add_menu_directory_item(view_name + translate_string(30362), url)
xbmcplugin.endOfDirectory(handle)
@ -813,7 +813,7 @@ def display_movies_type(menu_params, view):
handle = int(sys.argv[1])
xbmcplugin.setContent(handle, 'files')
view_name = string_load(30256)
view_name = translate_string(30256)
if view is not None:
view_name = view.get("Name")
@ -836,7 +836,7 @@ def display_movies_type(menu_params, view):
# All Movies
path = get_jellyfin_url("{server}/Users/{userid}/Items", base_params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies"
add_menu_directory_item('{}{}'.format(view_name, string_load(30405)), url)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30405)), url)
# Favorite Movies
params = {}
@ -846,7 +846,7 @@ def display_movies_type(menu_params, view):
params["Filters"] = "IsFavorite"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies"
add_menu_directory_item('{}{}'.format(view_name, string_load(30414)), url)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30414)), url)
# Unwatched Movies
params = {}
@ -856,7 +856,7 @@ def display_movies_type(menu_params, view):
params["IsPlayed"] = False
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies"
add_menu_directory_item('{}{}'.format(view_name, string_load(30285)), url)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30285)), url)
# Recently Watched Movies
params = {}
@ -869,7 +869,7 @@ def display_movies_type(menu_params, view):
params["Limit"] = "{ItemLimit}"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none"
add_menu_directory_item('{}{} ({})'.format(view_name, string_load(30349), show_x_filtered_items), url)
add_menu_directory_item('{}{} ({})'.format(view_name, translate_string(30349), show_x_filtered_items), url)
# Resumable Movies
params = {}
@ -880,7 +880,7 @@ def display_movies_type(menu_params, view):
params["Limit"] = "{ItemLimit}"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none"
add_menu_directory_item('{}{} ({})'.format(view_name, string_load(30267), show_x_filtered_items), url)
add_menu_directory_item('{}{} ({})'.format(view_name, translate_string(30267), show_x_filtered_items), url)
# Recently Added Movies
params = {}
@ -892,7 +892,7 @@ def display_movies_type(menu_params, view):
params["Filters"] = "IsNotFolder"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none"
add_menu_directory_item('{}{} ({})'.format(view_name, string_load(30268), show_x_filtered_items), url)
add_menu_directory_item('{}{} ({})'.format(view_name, translate_string(30268), show_x_filtered_items), url)
# Collections
params = {}
@ -904,49 +904,49 @@ def display_movies_type(menu_params, view):
params["Recursive"] = True
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=boxsets"
add_menu_directory_item('{}{}'.format(view_name, string_load(30410)), url)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30410)), url)
# Favorite Collections
params["Filters"] = "IsFavorite"
path = get_jellyfin_url("{server}/Users/{userid}/Items", params)
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=boxsets"
add_menu_directory_item('{}{}'.format(view_name, string_load(30415)), url)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30415)), url)
# Genres
path = "plugin://plugin.video.jellycon/?mode=GENRES&item_type=movie"
if view is not None:
path += "&parent_id=" + view.get("Id")
add_menu_directory_item('{}{}'.format(view_name, string_load(30325)), path)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30325)), path)
# Pages
path = "plugin://plugin.video.jellycon/?mode=MOVIE_PAGES"
if view is not None:
path += "&parent_id=" + view.get("Id")
add_menu_directory_item('{}{}'.format(view_name, string_load(30397)), path)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30397)), path)
# Alpha Picker
path = "plugin://plugin.video.jellycon/?mode=MOVIE_ALPHA"
if view is not None:
path += "&parent_id=" + view.get("Id")
add_menu_directory_item('{}{}'.format(view_name, string_load(30404)), path)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30404)), path)
# Years
path = "plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=show_movie_years"
if view is not None:
path += "&parent_id=" + view.get("Id")
add_menu_directory_item('{}{}'.format(view_name, string_load(30411)), path)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30411)), path)
# Decades
path = "plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=show_movie_years&group=true"
if view is not None:
path += "&parent_id=" + view.get("Id")
add_menu_directory_item('{}{}'.format(view_name, string_load(30412)), path)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30412)), path)
# Tags
path = "plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=show_movie_tags"
if view is not None:
path += "&parent_id=" + view.get("Id")
add_menu_directory_item('{}{}'.format(view_name, string_load(30413)), path)
add_menu_directory_item('{}{}'.format(view_name, translate_string(30413)), path)
xbmcplugin.endOfDirectory(handle)
@ -1061,34 +1061,34 @@ def show_widgets():
add_menu_directory_item("All Movies",
'plugin://plugin.video.jellycon/library/movies')
add_menu_directory_item(string_load(30257) + " (" + show_x_filtered_items + ")",
add_menu_directory_item(translate_string(30257) + " (" + show_x_filtered_items + ")",
'plugin://plugin.video.jellycon/?mode=WIDGET_CONTENT&type=recent_movies')
add_menu_directory_item(string_load(30258) + " (" + show_x_filtered_items + ")",
add_menu_directory_item(translate_string(30258) + " (" + show_x_filtered_items + ")",
'plugin://plugin.video.jellycon/?mode=WIDGET_CONTENT&type=inprogress_movies')
add_menu_directory_item(string_load(30269) + " (" + show_x_filtered_items + ")",
add_menu_directory_item(translate_string(30269) + " (" + show_x_filtered_items + ")",
'plugin://plugin.video.jellycon/?mode=WIDGET_CONTENT&type=random_movies')
add_menu_directory_item(string_load(30403) + " (" + show_x_filtered_items + ")",
add_menu_directory_item(translate_string(30403) + " (" + show_x_filtered_items + ")",
'plugin://plugin.video.jellycon/?mode=WIDGET_CONTENT&type=movie_recommendations')
add_menu_directory_item(string_load(30287) + " (" + show_x_filtered_items + ")",
add_menu_directory_item(translate_string(30287) + " (" + show_x_filtered_items + ")",
'plugin://plugin.video.jellycon/?mode=WIDGET_CONTENT&type=recent_tvshows')
add_menu_directory_item(string_load(30263) + " (" + show_x_filtered_items + ")",
add_menu_directory_item(translate_string(30263) + " (" + show_x_filtered_items + ")",
'plugin://plugin.video.jellycon/?mode=WIDGET_CONTENT&type=recent_episodes')
add_menu_directory_item(string_load(30264) + " (" + show_x_filtered_items + ")",
add_menu_directory_item(translate_string(30264) + " (" + show_x_filtered_items + ")",
'plugin://plugin.video.jellycon/?mode=WIDGET_CONTENT&type=inprogress_episodes')
add_menu_directory_item(string_load(30265) + " (" + show_x_filtered_items + ")",
add_menu_directory_item(translate_string(30265) + " (" + show_x_filtered_items + ")",
'plugin://plugin.video.jellycon/?mode=WIDGET_CONTENT&type=nextup_episodes')
xbmcplugin.endOfDirectory(int(sys.argv[1]))
def show_search():
add_menu_directory_item(string_load(30231), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Movie')
add_menu_directory_item(string_load(30229), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Series')
add_menu_directory_item(string_load(30235), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Episode')
add_menu_directory_item(string_load(30337), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Audio')
add_menu_directory_item(string_load(30338), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=MusicAlbum')
add_menu_directory_item(string_load(30339), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Person')
add_menu_directory_item(translate_string(30231), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Movie')
add_menu_directory_item(translate_string(30229), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Series')
add_menu_directory_item(translate_string(30235), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Episode')
add_menu_directory_item(translate_string(30337), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Audio')
add_menu_directory_item(translate_string(30338), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=MusicAlbum')
add_menu_directory_item(translate_string(30339), 'plugin://plugin.video.jellycon/?mode=NEW_SEARCH&item_type=Person')
xbmcplugin.endOfDirectory(int(sys.argv[1]))

View File

@ -4,7 +4,7 @@ import threading
import time
import xbmc
from .functions import show_menu
from .loghandler import LazyLogger
from .widgets import check_for_new_content
from .tracking import timer
@ -12,6 +12,39 @@ from .tracking import timer
log = LazyLogger(__name__)
class ContextMonitor(threading.Thread):
stop_thread = False
def run(self):
item_id = None
log.debug("ContextMonitor Thread Started")
while not xbmc.Monitor().abortRequested() and not self.stop_thread:
if xbmc.getCondVisibility("Window.IsActive(fullscreenvideo) | Window.IsActive(visualisation)"):
xbmc.sleep(1000)
else:
if xbmc.getCondVisibility("Window.IsVisible(contextmenu)"):
if item_id:
xbmc.executebuiltin("Dialog.Close(contextmenu,true)")
params = {}
params["item_id"] = item_id
show_menu(params)
container_id = xbmc.getInfoLabel("System.CurrentControlID")
item_id = xbmc.getInfoLabel("Container(" + str(container_id) + ").ListItem.Property(id)")
xbmc.sleep(100)
log.debug("ContextMonitor Thread Exited")
def stop_monitor(self):
log.debug("ContextMonitor Stop Called")
self.stop_thread = True
class LibraryChangeMonitor(threading.Thread):
last_library_change_check = 0

View File

@ -1,13 +1,12 @@
from __future__ import division, absolute_import, print_function, unicode_literals
import xbmc
import xbmcaddon
import xbmcgui
from .loghandler import LazyLogger
log = LazyLogger(__name__)
class PictureViewer(xbmcgui.WindowXMLDialog):
picture_url = None
action_exitkeys_id = None

View File

@ -4,22 +4,21 @@ from __future__ import division, absolute_import, print_function, unicode_litera
import xbmc
import xbmcgui
import xbmcaddon
import xbmcvfs
from datetime import timedelta
import json
import os
import base64
from six.moves.urllib.parse import urlparse
import re
from six.moves.urllib.parse import urlencode
from .loghandler import LazyLogger
from .downloadutils import DownloadUtils
from .resume_dialog import ResumeDialog
from .utils import PlayUtils, get_art, send_event_notification, convert_size
from .dialogs import ResumeDialog
from .utils import send_event_notification, convert_size, get_device_id, translate_string
from .kodi_utils import HomeWindow
from .translation import string_load
from .datamanager import DataManager, clear_old_cache_data
from .item_functions import extract_item_info, add_gui_item
from .clientinfo import ClientInformation
from .item_functions import extract_item_info, add_gui_item, get_art
from .cache_images import CacheArtwork
from .picture_viewer import PictureViewer
from .tracking import timer
@ -50,7 +49,7 @@ def play_all_files(items, play_items=True):
return
if playback_info.get("ErrorCode") is not None:
error_string = playback_info.get("ErrorCode")
xbmcgui.Dialog().notification(string_load(30316),
xbmcgui.Dialog().notification(translate_string(30316),
error_string,
icon="special://home/addons/plugin.video.jellycon/icon.png")
return
@ -63,7 +62,7 @@ def play_all_files(items, play_items=True):
selected_media_source = sources[0]
source_id = selected_media_source.get("Id")
playurl, playback_type, listitem_props = PlayUtils().get_play_url(selected_media_source, play_session_id)
playurl, playback_type, listitem_props = get_play_url(selected_media_source, play_session_id)
log.info("Play URL: {0} PlaybackType: {1} ListItem Properties: {2}".format(playurl, playback_type, listitem_props))
if playurl is None:
@ -82,7 +81,7 @@ def play_all_files(items, play_items=True):
item["Overview"] = playback_type_string
# add title decoration is needed
item_title = item.get("Name", string_load(30280))
item_title = item.get("Name", translate_string(30280))
list_item = xbmcgui.ListItem(label=item_title)
# add playurl and data to the monitor
@ -150,7 +149,7 @@ def add_to_playlist(play_info):
return
if playback_info.get("ErrorCode") is not None:
error_string = playback_info.get("ErrorCode")
xbmcgui.Dialog().notification(string_load(30316),
xbmcgui.Dialog().notification(translate_string(30316),
error_string,
icon="special://home/addons/plugin.video.jellycon/icon.png")
return
@ -163,7 +162,7 @@ def add_to_playlist(play_info):
selected_media_source = sources[0]
source_id = selected_media_source.get("Id")
playurl, playback_type, listitem_props = PlayUtils().get_play_url(selected_media_source, play_session_id)
playurl, playback_type, listitem_props = get_play_url(selected_media_source, play_session_id)
log.info("Play URL: {0} PlaybackType: {1} ListItem Properties: {2}".format(playurl, playback_type, listitem_props))
if playurl is None:
@ -182,7 +181,7 @@ def add_to_playlist(play_info):
item["Overview"] = playback_type_string
# add title decoration is needed
item_title = item.get("Name", string_load(30280))
item_title = item.get("Name", translate_string(30280))
list_item = xbmcgui.ListItem(label=item_title)
# add playurl and data to the monitor
@ -301,7 +300,7 @@ def play_file(play_info):
return
if playback_info.get("ErrorCode") is not None:
error_string = playback_info.get("ErrorCode")
xbmcgui.Dialog().notification(string_load(30316),
xbmcgui.Dialog().notification(translate_string(30316),
error_string,
icon="special://home/addons/plugin.video.jellycon/icon.png")
return
@ -332,7 +331,7 @@ def play_file(play_info):
label2 = __build_label2_from(source)
items.append(xbmcgui.ListItem(label=label, label2=label2))
dialog = xbmcgui.Dialog()
resp = dialog.select(string_load(30309), items, useDetails=True)
resp = dialog.select(translate_string(30309), items, useDetails=True)
if resp > -1:
selected_media_source = media_sources[resp]
else:
@ -377,7 +376,7 @@ def play_file(play_info):
return
log.debug("play_session_id: {0}".format(play_session_id))
playurl, playback_type, listitem_props = PlayUtils().get_play_url(selected_media_source, play_session_id)
playurl, playback_type, listitem_props = get_play_url(selected_media_source, play_session_id)
log.info("Play URL: {0} Playback Type: {1} ListItem Properties: {2}".format(playurl, playback_type, listitem_props))
if playurl is None:
@ -396,7 +395,7 @@ def play_file(play_info):
result["Overview"] = playback_type_string
# add title decoration is needed
item_title = result.get("Name", string_load(30280))
item_title = result.get("Name", translate_string(30280))
# extract item info from result
gui_options = {}
@ -763,7 +762,7 @@ def audio_subs_pref(url, list_item, media_source, item_id, audio_stream_index, s
playurlprefs += "&AudioStreamIndex=%s" % select_audio_index
elif len(audio_streams) > 1:
resp = dialog.select(string_load(30291), audio_streams)
resp = dialog.select(translate_string(30291), audio_streams)
if resp > -1:
# User selected audio
selected = audio_streams[resp]
@ -785,7 +784,7 @@ def audio_subs_pref(url, list_item, media_source, item_id, audio_stream_index, s
playurlprefs += "&SubtitleStreamIndex=%s" % select_subs_index
elif len(subtitle_streams) > 1:
resp = dialog.select(string_load(30292), subtitle_streams)
resp = dialog.select(translate_string(30292), subtitle_streams)
if resp == 0:
# User selected no subtitles
pass
@ -867,7 +866,7 @@ def external_subs(media_source, list_item, item_id):
if direct_stream_sub_select == "0" or (len(externalsubs) == 1 and not direct_stream_sub_select == "2"):
list_item.setSubtitles(externalsubs)
else:
resp = xbmcgui.Dialog().select(string_load(30292), sub_names)
resp = xbmcgui.Dialog().select(translate_string(30292), sub_names)
if resp > -1:
selected_sub = externalsubs[resp]
log.debug("External Subtitle Selected: {0}".format(selected_sub))
@ -1058,7 +1057,7 @@ def stop_all_playback():
clear_entries.append(item)
if data.get('playback_type') == 'Transcode':
device_id = ClientInformation().get_device_id()
device_id = get_device_id()
url = "{server}/Videos/ActiveEncodings?DeviceId=%s" % device_id
download_utils.download_url(url, method="DELETE")
@ -1116,6 +1115,145 @@ def get_playing_data():
return {}
def get_play_url(media_source, play_session_id):
log.debug("get_play_url - media_source: {0}", media_source)
# check if strm file Container
if media_source.get('Container') == 'strm':
log.debug("Detected STRM Container")
playurl, listitem_props = get_strm_details(media_source)
if playurl is None:
log.debug("Error, no strm content")
return None, None, None
else:
return playurl, "0", listitem_props
# get all the options
addon_settings = xbmcaddon.Addon()
server = download_utils.get_server()
use_https = addon_settings.getSetting('protocol') == "1"
verify_cert = addon_settings.getSetting('verify_cert') == 'true'
allow_direct_file_play = addon_settings.getSetting('allow_direct_file_play') == 'true'
can_direct_play = media_source["SupportsDirectPlay"]
can_direct_stream = media_source["SupportsDirectStream"]
can_transcode = media_source["SupportsTranscoding"]
container = media_source["Container"]
playurl = None
playback_type = None
# check if file can be directly played
if allow_direct_file_play and can_direct_play:
direct_path = media_source["Path"]
direct_path = direct_path.replace("\\", "/")
direct_path = direct_path.strip()
# handle DVD structure
if container == "dvd":
direct_path = direct_path + "/VIDEO_TS/VIDEO_TS.IFO"
elif container == "bluray":
direct_path = direct_path + "/BDMV/index.bdmv"
if direct_path.startswith("//"):
direct_path = "smb://" + direct_path[2:]
log.debug("playback_direct_path: {0}".format(direct_path))
if xbmcvfs.exists(direct_path):
playurl = direct_path
playback_type = "0"
# check if file can be direct streamed/played
if (can_direct_stream or can_direct_play) and playurl is None:
item_id = media_source.get('Id')
playurl = ("%s/Videos/%s/stream" +
"?static=true" +
"&PlaySessionId=%s" +
"&MediaSourceId=%s")
playurl = playurl % (server, item_id, play_session_id, item_id)
if use_https and not verify_cert:
playurl += "|verifypeer=false"
playback_type = "1"
# check is file can be transcoded
if can_transcode and playurl is None:
item_id = media_source.get('Id')
device_id = get_device_id()
user_token = download_utils.authenticate()
playback_bitrate = addon_settings.getSetting("force_max_stream_bitrate")
bitrate = int(playback_bitrate) * 1000
playback_max_width = addon_settings.getSetting("playback_max_width")
audio_codec = addon_settings.getSetting("audio_codec")
audio_playback_bitrate = addon_settings.getSetting("audio_playback_bitrate")
audio_bitrate = int(audio_playback_bitrate) * 1000
audio_max_channels = addon_settings.getSetting("audio_max_channels")
playback_video_force_8 = addon_settings.getSetting("playback_video_force_8") == "true"
transcode_params = {
"MediaSourceId": item_id,
"DeviceId": device_id,
"PlaySessionId": play_session_id,
"api_key": user_token,
"SegmentContainer": "ts",
"VideoCodec": "h264",
"VideoBitrate": bitrate,
"MaxWidth": playback_max_width,
"AudioCodec": audio_codec,
"TranscodingMaxAudioChannels": audio_max_channels,
"AudioBitrate": audio_bitrate
}
if playback_video_force_8:
transcode_params.update({"MaxVideoBitDepth": "8"})
transcode_path = urlencode(transcode_params)
playurl = "%s/Videos/%s/master.m3u8?%s" % (server, item_id, transcode_path)
if use_https and not verify_cert:
playurl += "|verifypeer=false"
playback_type = "2"
return playurl, playback_type, []
def get_strm_details(media_source):
playurl = None
listitem_props = []
contents = media_source.get('Path').encode('utf-8') # contains contents of strm file with linebreaks
line_break = '\r'
if '\r\n' in contents:
line_break = '\r\n'
elif '\n' in contents:
line_break = '\n'
lines = contents.split(line_break)
for line in lines:
line = line.strip()
log.debug("STRM Line: {0}".format(line))
if line.startswith('#KODIPROP:'):
match = re.search('#KODIPROP:(?P<item_property>[^=]+?)=(?P<property_value>.+)', line)
if match:
item_property = match.group('item_property')
property_value = match.group('property_value')
log.debug("STRM property found: {0} value: {1}".format(item_property, property_value))
listitem_props.append((item_property, property_value))
else:
log.debug("STRM #KODIPROP incorrect format")
elif line.startswith('#'):
# unrecognized, treat as comment
log.debug("STRM unrecognized line identifier, ignored")
elif line != '':
playurl = line
log.debug("STRM playback url found")
log.debug("Playback URL: {0} ListItem Properties: {1}".format(playurl, listitem_props))
return playurl, listitem_props
class Service(xbmc.Player):
def __init__(self, *args):

View File

@ -1,16 +1,13 @@
from __future__ import division, absolute_import, print_function, unicode_literals
import json
import os
import threading
import xbmc
import xbmcgui
import xbmcaddon
from .loghandler import LazyLogger
from .play_utils import send_event_notification
from .kodi_utils import HomeWindow
from .dialogs import PlayNextDialog
log = LazyLogger(__name__)
@ -97,67 +94,3 @@ class PlayNextService(threading.Thread):
def stop_servcie(self):
log.debug("PlayNextService Stop Called")
self.stop_thread = True
class PlayNextDialog(xbmcgui.WindowXMLDialog):
action_exitkeys_id = None
episode_info = None
play_called = False
def __init__(self, *args, **kwargs):
log.debug("PlayNextDialog: __init__")
xbmcgui.WindowXML.__init__(self, *args, **kwargs)
def onInit(self):
log.debug("PlayNextDialog: onInit")
self.action_exitkeys_id = [10, 13]
index = self.episode_info.get("IndexNumber", -1)
series_name = self.episode_info.get("SeriesName")
next_epp_name = "Episode %02d - (%s)" % (index, self.episode_info.get("Name", "n/a"))
series_label = self.getControl(3011)
series_label.setLabel(series_name)
series_label = self.getControl(3012)
series_label.setLabel(next_epp_name)
def onFocus(self, control_id):
pass
def doAction(self, action_id):
pass
def onMessage(self, message):
log.debug("PlayNextDialog: onMessage: {0}".format(message))
def onAction(self, action):
if action.getId() == 10: # ACTION_PREVIOUS_MENU
self.close()
elif action.getId() == 92: # ACTION_NAV_BACK
self.close()
else:
log.debug("PlayNextDialog: onAction: {0}".format(action.getId()))
def onClick(self, control_id):
if control_id == 3013:
log.debug("PlayNextDialog: Play Next Episode")
self.play_called
self.close()
next_item_id = self.episode_info.get("Id")
log.debug("Playing Next Episode: {0}".format(next_item_id))
play_info = {}
play_info["item_id"] = next_item_id
play_info["auto_resume"] = "-1"
play_info["force_transcode"] = False
send_event_notification("jellycon_play_action", play_info)
elif control_id == 3014:
self.close()
def set_episode_info(self, info):
self.episode_info = info
def get_play_called(self):
return self.play_called

View File

@ -1,45 +0,0 @@
# Gnu General Public License - see LICENSE.TXT
from __future__ import division, absolute_import, print_function, unicode_literals
import xbmcgui
from .loghandler import LazyLogger
from .translation import string_load
log = LazyLogger(__name__)
class ResumeDialog(xbmcgui.WindowXMLDialog):
resumePlay = -1
resumeTimeStamp = ""
action_exitkeys_id = None
def __init__(self, *args, **kwargs):
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
log.debug("ResumeDialog INITIALISED")
def onInit(self):
self.action_exitkeys_id = [10, 13]
self.getControl(3010).setLabel(self.resumeTimeStamp)
self.getControl(3011).setLabel(string_load(30237))
def onFocus(self, controlId):
pass
def doAction(self, actionID):
pass
def onClick(self, controlID):
if controlID == 3010:
self.resumePlay = 0
self.close()
if controlID == 3011:
self.resumePlay = 1
self.close()
def setResumeTime(self, timeStamp):
self.resumeTimeStamp = timeStamp
def getResumeAction(self):
return self.resumePlay

View File

@ -1,57 +0,0 @@
# Gnu General Public License - see LICENSE.TXT
from __future__ import division, absolute_import, print_function, unicode_literals
import xbmc
import xbmcgui
from .loghandler import LazyLogger
log = LazyLogger(__name__)
class SafeDeleteDialog(xbmcgui.WindowXMLDialog):
confirm = False
message = "Demo Message"
heading = "Demo Heading"
action_exitkeys_id = None
def __init__(self, *args, **kwargs):
log.debug("SafeDeleteDialog: __init__")
xbmcgui.WindowXML.__init__(self, *args, **kwargs)
def onInit(self):
log.debug("SafeDeleteDialog: onInit")
self.action_exitkeys_id = [10, 13]
message_control = self.getControl(3)
message_control.setText(self.message)
message_control = self.getControl(4)
message_control.setLabel(self.heading)
def onFocus(self, controlId):
pass
def doAction(self, actionID):
pass
def onMessage(self, message):
log.debug("SafeDeleteDialog: onMessage: {0}".format(message))
def onAction(self, action):
if action.getId() == 10: # ACTION_PREVIOUS_MENU
self.close()
elif action.getId() == 92: # ACTION_NAV_BACK
self.close()
else:
log.debug("SafeDeleteDialog: onAction: {0}".format(action.getId()))
def onClick(self, controlID):
if controlID == 1:
self.confirm = True
self.close()
elif controlID == 2:
self.confirm = False
self.close()

View File

@ -3,9 +3,7 @@ from __future__ import division, absolute_import, print_function, unicode_litera
import socket
import json
from six.moves.urllib.parse import urlparse
import requests
import ssl
import time
import hashlib
from datetime import datetime
@ -19,9 +17,7 @@ from kodi_six.utils import py2_decode
from .kodi_utils import HomeWindow
from .downloadutils import DownloadUtils, save_user_details, load_user_details
from .loghandler import LazyLogger
from .translation import string_load
from .utils import datetime_from_string
from .clientinfo import ClientInformation
from .utils import datetime_from_string, translate_string, get_version
log = LazyLogger(__name__)
@ -44,7 +40,7 @@ def check_connection_speed():
url = server + "/playback/bitratetest?size=%s" % test_data_size
head = du.get_auth_header(True)
head["User-Agent"] = "JellyCon-" + ClientInformation().get_version()
head["User-Agent"] = "JellyCon-{}".format(get_version())
request_details = {
"stream": True,
@ -138,8 +134,8 @@ def get_server_details():
log.debug("Sending UDP Data: {0}".format(message))
progress = xbmcgui.DialogProgress()
progress.create('{} : {}'.format(__addon_name__, string_load(30373)))
progress.update(0, string_load(30374))
progress.create('{} : {}'.format(__addon_name__, translate_string(30373)))
progress.update(0, translate_string(30374))
xbmc.sleep(1000)
server_count = 0
@ -148,7 +144,7 @@ def get_server_details():
while True:
try:
server_count += 1
progress.update(server_count * 10, '{}: {}'.format(string_load(30375), server_count))
progress.update(server_count * 10, '{}: {}'.format(translate_string(30375), server_count))
xbmc.sleep(1000)
data, addr = sock.recvfrom(1024)
servers.append(json.loads(data))
@ -188,7 +184,7 @@ def check_server(force=False, change_user=False, notify=False):
server_list = []
for server in server_info:
server_item = xbmcgui.ListItem(server.get("Name", string_load(30063)))
server_item = xbmcgui.ListItem(server.get("Name", translate_string(30063)))
sub_line = server.get("Address")
server_item.setLabel2(sub_line)
server_item.setProperty("address", server.get("Address"))
@ -197,21 +193,21 @@ def check_server(force=False, change_user=False, notify=False):
server_list.append(server_item)
if len(server_list) > 0:
return_index = xbmcgui.Dialog().select('{} : {}'.format(__addon_name__, string_load(30166)),
return_index = xbmcgui.Dialog().select('{} : {}'.format(__addon_name__, translate_string(30166)),
server_list,
useDetails=True)
if return_index != -1:
server_url = server_info[return_index]["Address"]
if not server_url:
return_index = xbmcgui.Dialog().yesno(__addon_name__, '{}\n{}'.format(string_load(30282), string_load(30370)))
return_index = xbmcgui.Dialog().yesno(__addon_name__, '{}\n{}'.format(translate_string(30282), translate_string(30370)))
if not return_index:
xbmc.executebuiltin("ActivateWindow(Home)")
return
while True:
kb = xbmc.Keyboard()
kb.setHeading(string_load(30372))
kb.setHeading(translate_string(30372))
if server_url:
kb.setDefault(server_url)
else:
@ -227,19 +223,19 @@ def check_server(force=False, change_user=False, notify=False):
log.debug("Testing_Url: {0}".format(public_lookup_url))
progress = xbmcgui.DialogProgress()
progress.create('{} : {}'.format(__addon_name__, string_load(30376)))
progress.update(0, string_load(30377))
progress.create('{} : {}'.format(__addon_name__, translate_string(30376)))
progress.update(0, translate_string(30377))
result = du.download_url(public_lookup_url, authenticate=False)
progress.close()
if result:
xbmcgui.Dialog().ok('{} : {}'.format(__addon_name__, string_load(30167)),
xbmcgui.Dialog().ok('{} : {}'.format(__addon_name__, translate_string(30167)),
server_url)
break
else:
return_index = xbmcgui.Dialog().yesno('{} : {}'.format(__addon_name__, string_load(30135)),
return_index = xbmcgui.Dialog().yesno('{} : {}'.format(__addon_name__, translate_string(30135)),
server_url,
string_load(30371))
translate_string(30371))
if not return_index:
xbmc.executebuiltin("ActivateWindow(Home)")
return
@ -336,15 +332,15 @@ def check_server(force=False, change_user=False, notify=False):
selected_id = len(users) - 1
if current_username:
selection_title = string_load(30180) + " (" + current_username + ")"
selection_title = translate_string(30180) + " (" + current_username + ")"
else:
selection_title = string_load(30180)
selection_title = translate_string(30180)
# add manual login
user_item = xbmcgui.ListItem(string_load(30365))
user_item = xbmcgui.ListItem(translate_string(30365))
art = {"Thumb": "DefaultUser.png"}
user_item.setArt(art)
user_item.setLabel2(string_load(30366))
user_item.setLabel2(translate_string(30366))
user_item.setProperty("secure", "true")
user_item.setProperty("manual", "true")
users.append(user_item)
@ -367,7 +363,7 @@ def check_server(force=False, change_user=False, notify=False):
if manual:
kb = xbmc.Keyboard()
kb.setHeading(string_load(30005))
kb.setHeading(translate_string(30005))
if current_username:
kb.setDefault(current_username)
kb.doModal()
@ -387,7 +383,7 @@ def check_server(force=False, change_user=False, notify=False):
# if not saving passwords but have a saved ask to clear it
if not allow_password_saving and saved_password:
clear_password = xbmcgui.Dialog().yesno(string_load(30368), string_load(30369))
clear_password = xbmcgui.Dialog().yesno(translate_string(30368), translate_string(30369))
if clear_password:
settings.setSetting("saved_user_password_" + hashed_username, "")
@ -398,7 +394,7 @@ def check_server(force=False, change_user=False, notify=False):
else:
kb = xbmc.Keyboard()
kb.setHeading(string_load(30006))
kb.setHeading(translate_string(30006))
kb.setHiddenInput(True)
kb.doModal()
if kb.isConfirmed():
@ -407,7 +403,7 @@ def check_server(force=False, change_user=False, notify=False):
# should we save the password
if allow_password_saving:
save_password = xbmcgui.Dialog().yesno(string_load(30363), string_load(30364))
save_password = xbmcgui.Dialog().yesno(translate_string(30363), translate_string(30364))
if save_password:
log.debug("Saving password for fast user switching: {0}".format(hashed_username))
settings.setSetting("saved_user_password_" + hashed_username, kb.getText())

View File

@ -6,7 +6,7 @@ import xbmcplugin
from .downloadutils import DownloadUtils
from .loghandler import LazyLogger
from .utils import get_art
from .item_functions import get_art
from .datamanager import DataManager
log = LazyLogger(__name__)

View File

@ -2,15 +2,13 @@
from __future__ import division, absolute_import, print_function, unicode_literals
from six.moves.urllib.parse import quote, unquote
import encodings
import xbmc
import xbmcgui
from .loghandler import LazyLogger
from .datamanager import DataManager
from .translation import string_load
from .utils import translate_string
log = LazyLogger(__name__)
dataManager = DataManager()
@ -20,11 +18,11 @@ icon = xbmc.translatePath('special://home/addons/plugin.video.jellycon/icon.png'
def not_found(content_string):
xbmcgui.Dialog().notification('JellyCon', '{}: {}'.format(string_load(30305), content_string), icon=icon, sound=False)
xbmcgui.Dialog().notification('JellyCon', '{}: {}'.format(translate_string(30305), content_string), icon=icon, sound=False)
def playback_starting(content_string):
xbmcgui.Dialog().notification('JellyCon', '{}: {}'.format(string_load(30306), content_string), icon=icon, sound=False)
xbmcgui.Dialog().notification('JellyCon', '{}: {}'.format(translate_string(30306), content_string), icon=icon, sound=False)
def search(item_type, query):

View File

@ -1,16 +0,0 @@
from __future__ import division, absolute_import, print_function, unicode_literals
import xbmcaddon
from .loghandler import LazyLogger
from kodi_six.utils import py2_encode
log = LazyLogger(__name__)
addon = xbmcaddon.Addon()
def string_load(string_id):
try:
return py2_encode(addon.getLocalizedString(string_id))
except Exception as e:
log.error('Failed String Load: {0} ({1})', string_id, e)
return str(string_id)

View File

@ -4,29 +4,27 @@ from __future__ import division, absolute_import, print_function, unicode_litera
import xbmcaddon
import xbmc
import xbmcvfs
from kodi_six.utils import py2_encode, py2_decode
import binascii
import string
import random
import json
import base64
import time
import math
from datetime import datetime
import calendar
import re
from uuid import uuid4
from six import ensure_text, ensure_binary
from six.moves.urllib.parse import urlencode
from .downloadutils import DownloadUtils
from .loghandler import LazyLogger
from .clientinfo import ClientInformation
from .kodi_utils import HomeWindow
# hack to get datetime strptime loaded
throwaway = time.strptime('20110101', '%Y%m%d')
# define our global download utils
downloadUtils = DownloadUtils()
log = LazyLogger(__name__)
@ -39,150 +37,6 @@ def get_jellyfin_url(base_url, params):
return base_url + "?" + url_params
###########################################################################
class PlayUtils:
@staticmethod
def get_play_url(media_source, play_session_id):
log.debug("get_play_url - media_source: {0}", media_source)
# check if strm file Container
if media_source.get('Container') == 'strm':
log.debug("Detected STRM Container")
playurl, listitem_props = PlayUtils().get_strm_details(media_source)
if playurl is None:
log.debug("Error, no strm content")
return None, None, None
else:
return playurl, "0", listitem_props
# get all the options
addon_settings = xbmcaddon.Addon()
server = downloadUtils.get_server()
use_https = addon_settings.getSetting('protocol') == "1"
verify_cert = addon_settings.getSetting('verify_cert') == 'true'
allow_direct_file_play = addon_settings.getSetting('allow_direct_file_play') == 'true'
can_direct_play = media_source["SupportsDirectPlay"]
can_direct_stream = media_source["SupportsDirectStream"]
can_transcode = media_source["SupportsTranscoding"]
container = media_source["Container"]
playurl = None
playback_type = None
# check if file can be directly played
if allow_direct_file_play and can_direct_play:
direct_path = media_source["Path"]
direct_path = direct_path.replace("\\", "/")
direct_path = direct_path.strip()
# handle DVD structure
if container == "dvd":
direct_path = direct_path + "/VIDEO_TS/VIDEO_TS.IFO"
elif container == "bluray":
direct_path = direct_path + "/BDMV/index.bdmv"
if direct_path.startswith("//"):
direct_path = "smb://" + direct_path[2:]
log.debug("playback_direct_path: {0}".format(direct_path))
if xbmcvfs.exists(direct_path):
playurl = direct_path
playback_type = "0"
# check if file can be direct streamed/played
if (can_direct_stream or can_direct_play) and playurl is None:
item_id = media_source.get('Id')
playurl = ("%s/Videos/%s/stream" +
"?static=true" +
"&PlaySessionId=%s" +
"&MediaSourceId=%s")
playurl = playurl % (server, item_id, play_session_id, item_id)
if use_https and not verify_cert:
playurl += "|verifypeer=false"
playback_type = "1"
# check is file can be transcoded
if can_transcode and playurl is None:
item_id = media_source.get('Id')
client_info = ClientInformation()
device_id = client_info.get_device_id()
user_token = downloadUtils.authenticate()
playback_bitrate = addon_settings.getSetting("force_max_stream_bitrate")
bitrate = int(playback_bitrate) * 1000
playback_max_width = addon_settings.getSetting("playback_max_width")
audio_codec = addon_settings.getSetting("audio_codec")
audio_playback_bitrate = addon_settings.getSetting("audio_playback_bitrate")
audio_bitrate = int(audio_playback_bitrate) * 1000
audio_max_channels = addon_settings.getSetting("audio_max_channels")
playback_video_force_8 = addon_settings.getSetting("playback_video_force_8") == "true"
transcode_params = {
"MediaSourceId": item_id,
"DeviceId": device_id,
"PlaySessionId": play_session_id,
"api_key": user_token,
"SegmentContainer": "ts",
"VideoCodec": "h264",
"VideoBitrate": bitrate,
"MaxWidth": playback_max_width,
"AudioCodec": audio_codec,
"TranscodingMaxAudioChannels": audio_max_channels,
"AudioBitrate": audio_bitrate
}
if playback_video_force_8:
transcode_params.update({"MaxVideoBitDepth": "8"})
transcode_path = urlencode(transcode_params)
playurl = "%s/Videos/%s/master.m3u8?%s" % (server, item_id, transcode_path)
if use_https and not verify_cert:
playurl += "|verifypeer=false"
playback_type = "2"
return playurl, playback_type, []
@staticmethod
def get_strm_details(media_source):
playurl = None
listitem_props = []
contents = media_source.get('Path').encode('utf-8') # contains contents of strm file with linebreaks
line_break = '\r'
if '\r\n' in contents:
line_break = '\r\n'
elif '\n' in contents:
line_break = '\n'
lines = contents.split(line_break)
for line in lines:
line = line.strip()
log.debug("STRM Line: {0}".format(line))
if line.startswith('#KODIPROP:'):
match = re.search('#KODIPROP:(?P<item_property>[^=]+?)=(?P<property_value>.+)', line)
if match:
item_property = match.group('item_property')
property_value = match.group('property_value')
log.debug("STRM property found: {0} value: {1}".format(item_property, property_value))
listitem_props.append((item_property, property_value))
else:
log.debug("STRM #KODIPROP incorrect format")
elif line.startswith('#'):
# unrecognized, treat as comment
log.debug("STRM unrecognized line identifier, ignored")
elif line != '':
playurl = line
log.debug("STRM playback url found")
log.debug("Playback URL: {0} ListItem Properties: {1}".format(playurl, listitem_props))
return playurl, listitem_props
def get_checksum(item):
userdata = item['UserData']
checksum = "%s_%s_%s_%s_%s_%s_%s" % (
@ -198,88 +52,6 @@ def get_checksum(item):
return checksum
def get_art(item, server):
art = {
'thumb': '',
'fanart': '',
'poster': '',
'banner': '',
'clearlogo': '',
'clearart': '',
'discart': '',
'landscape': '',
'tvshow.fanart': '',
'tvshow.poster': '',
'tvshow.clearart': '',
'tvshow.clearlogo': '',
'tvshow.banner': '',
'tvshow.landscape': ''
}
image_tags = item.get("ImageTags", {})
if image_tags and image_tags.get("Primary"):
art['thumb'] = downloadUtils.get_artwork(item, "Primary", server=server)
item_type = item["Type"]
if item_type == "Genre":
art['poster'] = downloadUtils.get_artwork(item, "Primary", server=server)
elif item_type == "Episode":
art['tvshow.poster'] = downloadUtils.get_artwork(item, "Primary", parent=True, server=server)
art['tvshow.clearart'] = downloadUtils.get_artwork(item, "Art", parent=True, server=server)
art['clearart'] = downloadUtils.get_artwork(item, "Art", parent=True, server=server)
art['tvshow.clearlogo'] = downloadUtils.get_artwork(item, "Logo", parent=True, server=server)
art['clearlogo'] = downloadUtils.get_artwork(item, "Logo", parent=True, server=server)
art['tvshow.banner'] = downloadUtils.get_artwork(item, "Banner", parent=True, server=server)
art['banner'] = downloadUtils.get_artwork(item, "Banner", parent=True, server=server)
art['tvshow.landscape'] = downloadUtils.get_artwork(item, "Thumb", parent=True, server=server)
art['landscape'] = downloadUtils.get_artwork(item, "Thumb", parent=True, server=server)
art['tvshow.fanart'] = downloadUtils.get_artwork(item, "Backdrop", parent=True, server=server)
art['fanart'] = downloadUtils.get_artwork(item, "Backdrop", parent=True, server=server)
elif item_type == "Season":
art['tvshow.poster'] = downloadUtils.get_artwork(item, "Primary", parent=True, server=server)
art['season.poster'] = downloadUtils.get_artwork(item, "Primary", parent=False, server=server)
art['poster'] = downloadUtils.get_artwork(item, "Primary", parent=False, server=server)
art['tvshow.clearart'] = downloadUtils.get_artwork(item, "Art", parent=True, server=server)
art['clearart'] = downloadUtils.get_artwork(item, "Art", parent=True, server=server)
art['tvshow.clearlogo'] = downloadUtils.get_artwork(item, "Logo", parent=True, server=server)
art['clearlogo'] = downloadUtils.get_artwork(item, "Logo", parent=True, server=server)
art['tvshow.banner'] = downloadUtils.get_artwork(item, "Banner", parent=True, server=server)
art['season.banner'] = downloadUtils.get_artwork(item, "Banner", parent=False, server=server)
art['banner'] = downloadUtils.get_artwork(item, "Banner", parent=False, server=server)
art['tvshow.landscape'] = downloadUtils.get_artwork(item, "Thumb", parent=True, server=server)
art['season.landscape'] = downloadUtils.get_artwork(item, "Thumb", parent=False, server=server)
art['landscape'] = downloadUtils.get_artwork(item, "Thumb", parent=False, server=server)
art['tvshow.fanart'] = downloadUtils.get_artwork(item, "Backdrop", parent=True, server=server)
art['fanart'] = downloadUtils.get_artwork(item, "Backdrop", parent=True, server=server)
elif item_type == "Series":
art['tvshow.poster'] = downloadUtils.get_artwork(item, "Primary", parent=False, server=server)
art['poster'] = downloadUtils.get_artwork(item, "Primary", parent=False, server=server)
art['tvshow.clearart'] = downloadUtils.get_artwork(item, "Art", parent=False, server=server)
art['clearart'] = downloadUtils.get_artwork(item, "Art", parent=False, server=server)
art['tvshow.clearlogo'] = downloadUtils.get_artwork(item, "Logo", parent=False, server=server)
art['clearlogo'] = downloadUtils.get_artwork(item, "Logo", parent=False, server=server)
art['tvshow.banner'] = downloadUtils.get_artwork(item, "Banner", parent=False, server=server)
art['banner'] = downloadUtils.get_artwork(item, "Banner", parent=False, server=server)
art['tvshow.landscape'] = downloadUtils.get_artwork(item, "Thumb", parent=False, server=server)
art['landscape'] = downloadUtils.get_artwork(item, "Thumb", parent=False, server=server)
art['tvshow.fanart'] = downloadUtils.get_artwork(item, "Backdrop", parent=False, server=server)
art['fanart'] = downloadUtils.get_artwork(item, "Backdrop", parent=False, server=server)
elif item_type == "Movie" or item_type == "BoxSet":
art['poster'] = downloadUtils.get_artwork(item, "Primary", server=server)
art['landscape'] = downloadUtils.get_artwork(item, "Thumb", server=server)
art['banner'] = downloadUtils.get_artwork(item, "Banner", server=server)
art['clearlogo'] = downloadUtils.get_artwork(item, "Logo", server=server)
art['clearart'] = downloadUtils.get_artwork(item, "Art", server=server)
art['discart'] = downloadUtils.get_artwork(item, "Disc", server=server)
art['fanart'] = downloadUtils.get_artwork(item, "Backdrop", server=server)
if not art['fanart']:
art['fanart'] = downloadUtils.get_artwork(item, "Backdrop", parent=True, server=server)
return art
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
@ -330,3 +102,47 @@ def convert_size(size_bytes):
p = math.pow(1024, i)
s = round(size_bytes / p, 2)
return "%s %s" % (s, size_name[i])
def translate_string(string_id):
try:
addon = xbmcaddon.Addon()
return py2_encode(addon.getLocalizedString(string_id))
except Exception as e:
log.error('Failed String Load: {0} ({1})', string_id, e)
return str(string_id)
def get_device_id():
window = HomeWindow()
client_id = window.get_property("client_id")
if client_id:
return client_id
jellyfin_guid_path = py2_decode(xbmc.translatePath("special://temp/jellycon_guid"))
log.debug("jellyfin_guid_path: {0}".format(jellyfin_guid_path))
guid = xbmcvfs.File(jellyfin_guid_path)
client_id = guid.read()
guid.close()
if not client_id:
# Needs to be captilized for backwards compat
client_id = uuid4().hex.upper()
log.debug("Generating a new guid: {0}".format(client_id))
guid = xbmcvfs.File(jellyfin_guid_path, 'w')
guid.write(client_id)
guid.close()
log.debug("jellyfin_client_id (NEW): {0}".format(client_id))
else:
log.debug("jellyfin_client_id: {0}".format(client_id))
window.set_property("client_id", client_id)
return client_id
def get_version():
addon = xbmcaddon.Addon()
version = addon.getAddonInfo("version")
return version

View File

@ -13,10 +13,10 @@ import xbmcgui
from .functions import play_action
from .loghandler import LazyLogger
from . import clientinfo
from . import downloadutils
from .jsonrpc import JsonRpc
from .kodi_utils import HomeWindow
from .utils import get_device_id
log = LazyLogger(__name__)
@ -35,8 +35,7 @@ class WebSocketClient(threading.Thread):
self.monitor = xbmc.Monitor()
self.retry_count = 0
self.client_info = clientinfo.ClientInformation()
self.device_id = self.client_info.get_device_id()
self.device_id = get_device_id()
self._library_monitor = library_change_monitor
@ -106,7 +105,6 @@ class WebSocketClient(threading.Thread):
params["audio_stream_index"] = audio_stream_index
play_action(params)
def _playstate(self, data):
command = data['Command']

View File

@ -286,7 +286,6 @@ def get_widget_content(handle, params):
url_params["Fields"] = "{field_filters}"
url_params["ImageTypeLimit"] = 1
url_params["IsMissing"] = False
in_progress = False
if widget_type == "recent_movies":
xbmcplugin.setContent(handle, 'movies')
@ -370,7 +369,6 @@ def get_widget_content(handle, params):
inprogress_url_params["IsVirtualUnaired"] = False
inprogress_url_params["IncludeItemTypes"] = "Episode"
inprogress_url_params["Limit"] = 20
in_progress = True
elif widget_type == "movie_recommendations":
suggested_items_url_params = {}
@ -402,7 +400,7 @@ def get_widget_content(handle, params):
set_id = 0
id_list = ",".join(ids)
log.debug("Recommended Items : {0}".format(len(ids), id_list))
log.debug("Recommended Items : {0}".format(len(ids)))
url_params["Ids"] = id_list
items_url = get_jellyfin_url(url_verb, url_params)
@ -410,7 +408,7 @@ def get_widget_content(handle, params):
list_items, detected_type, total_records = process_directory(
items_url, None, params, use_cached_widget_data)
# Combine In Progress and Next Up Episodes, apend next up after In Progress
# Combine In Progress and Next Up Episodes, append next up after In Progress
if widget_type == "nextup_episodes":
inprogress_url = get_jellyfin_url(
inprogress_url_verb, inprogress_url_params)

View File

@ -15,9 +15,8 @@ from resources.lib.kodi_utils import HomeWindow
from resources.lib.widgets import set_background_image, set_random_movies
from resources.lib.websocket_client import WebSocketClient
from resources.lib.menu_functions import set_library_window_values
from resources.lib.context_monitor import ContextMonitor
from resources.lib.server_detect import check_server, check_safe_delete_available, check_connection_speed
from resources.lib.library_change_monitor import LibraryChangeMonitor
from resources.lib.monitors import LibraryChangeMonitor, ContextMonitor
from resources.lib.datamanager import clear_old_cache_data
from resources.lib.tracking import set_timing_enabled
from resources.lib.image_server import HttpImageServerThread