mirror of
https://github.com/jellyfin/jellycon.git
synced 2025-02-21 22:30:48 +00:00
Merge pull request #111 from mcarlton00/function-shuffle
Code reorganizing
This commit is contained in:
commit
a81e125a29
@ -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))
|
@ -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
|
||||
|
@ -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'
|
@ -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
|
@ -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
205
resources/lib/dialogs.py
Normal 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
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -10,7 +10,6 @@ import traceback
|
||||
|
||||
from six import ensure_text
|
||||
from kodi_six import xbmc, xbmcaddon
|
||||
from six.moves.urllib.parse import urlparse
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -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]))
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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()
|
@ -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())
|
||||
|
@ -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__)
|
||||
|
@ -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):
|
||||
|
@ -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)
|
@ -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
|
||||
|
@ -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']
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user