mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2025-05-10 19:35:07 +00:00
Remove old code
This commit is contained in:
parent
e4e5881ffc
commit
ce47644868
10 changed files with 6 additions and 1761 deletions
|
@ -33,80 +33,6 @@ class API(object):
|
|||
'''
|
||||
return (playcount or 1) if played else None
|
||||
|
||||
|
||||
|
||||
|
||||
def get_userdata(self):
|
||||
# Default
|
||||
favorite = False
|
||||
likes = None
|
||||
playcount = None
|
||||
played = False
|
||||
last_played = None
|
||||
resume = 0
|
||||
|
||||
try:
|
||||
userdata = self.item['UserData']
|
||||
except KeyError: # No userdata found.
|
||||
pass
|
||||
else:
|
||||
favorite = userdata['IsFavorite']
|
||||
likes = userdata.get('Likes')
|
||||
|
||||
last_played = userdata.get('LastPlayedDate')
|
||||
if last_played:
|
||||
last_played = last_played.split('.')[0].replace('T', " ")
|
||||
|
||||
if userdata['Played']:
|
||||
# Playcount is tied to the watch status
|
||||
played = True
|
||||
playcount = userdata['PlayCount']
|
||||
if playcount == 0:
|
||||
playcount = 1
|
||||
|
||||
if last_played is None:
|
||||
last_played = self.get_date_created()
|
||||
|
||||
playback_position = userdata.get('PlaybackPositionTicks')
|
||||
if playback_position:
|
||||
resume = playback_position / 10000000.0
|
||||
|
||||
return {
|
||||
|
||||
'Favorite': favorite,
|
||||
'Likes': likes,
|
||||
'PlayCount': playcount,
|
||||
'Played': played,
|
||||
'LastPlayedDate': last_played,
|
||||
'Resume': resume
|
||||
}
|
||||
|
||||
def get_people(self):
|
||||
# Process People
|
||||
director = []
|
||||
writer = []
|
||||
cast = []
|
||||
|
||||
if 'People' in self.item:
|
||||
for person in self.item['People']:
|
||||
|
||||
type_ = person['Type']
|
||||
name = person['Name']
|
||||
|
||||
if type_ == 'Director':
|
||||
director.append(name)
|
||||
elif type_ == 'Actor':
|
||||
cast.append(name)
|
||||
elif type_ in ('Writing', 'Writer'):
|
||||
writer.append(name)
|
||||
|
||||
return {
|
||||
|
||||
'Director': director,
|
||||
'Writer': writer,
|
||||
'Cast': cast
|
||||
}
|
||||
|
||||
def get_actors(self):
|
||||
cast = []
|
||||
|
||||
|
@ -125,40 +51,6 @@ class API(object):
|
|||
|
||||
return cast
|
||||
|
||||
def get_media_streams(self):
|
||||
|
||||
video_tracks = []
|
||||
audio_tracks = []
|
||||
subtitle_languages = []
|
||||
|
||||
try:
|
||||
media_streams = self.item['MediaSources'][0]['MediaStreams']
|
||||
|
||||
except KeyError:
|
||||
if not self.item.get("MediaStreams"):
|
||||
return None
|
||||
media_streams = self.item['MediaStreams']
|
||||
|
||||
for media_stream in media_streams:
|
||||
# Sort through Video, Audio, Subtitle
|
||||
stream_type = media_stream['Type']
|
||||
|
||||
if stream_type == "Video":
|
||||
self._video_stream(video_tracks, media_stream)
|
||||
|
||||
elif stream_type == "Audio":
|
||||
self._audio_stream(audio_tracks, media_stream)
|
||||
|
||||
elif stream_type == "Subtitle":
|
||||
subtitle_languages.append(media_stream.get('Language', "Unknown"))
|
||||
|
||||
return {
|
||||
|
||||
'video': video_tracks,
|
||||
'audio': audio_tracks,
|
||||
'subtitle': subtitle_languages
|
||||
}
|
||||
|
||||
def media_streams(self, video, audio, subtitles):
|
||||
return {
|
||||
'video': video or [],
|
||||
|
@ -247,21 +139,6 @@ class API(object):
|
|||
|
||||
return resume
|
||||
|
||||
def get_studios(self):
|
||||
# Process Studios
|
||||
studios = []
|
||||
try:
|
||||
studio = self.item['SeriesStudio']
|
||||
studios.append(self.validate_studio(studio))
|
||||
|
||||
except KeyError:
|
||||
for studio in self.item['Studios']:
|
||||
|
||||
name = studio['Name']
|
||||
studios.append(self.validate_studio(name))
|
||||
|
||||
return studios
|
||||
|
||||
def validate_studio(self, studio_name):
|
||||
# Convert studio for Kodi to properly detect them
|
||||
studios = {
|
||||
|
@ -277,36 +154,6 @@ class API(object):
|
|||
}
|
||||
return studios.get(studio_name.lower(), studio_name)
|
||||
|
||||
def get_genres(self):
|
||||
|
||||
all_genres = ""
|
||||
genres = self.item.get('Genres', self.item.get('SeriesGenres'))
|
||||
|
||||
if genres:
|
||||
all_genres = " / ".join(genres)
|
||||
|
||||
return all_genres
|
||||
|
||||
def get_date_created(self):
|
||||
|
||||
try:
|
||||
date_added = self.item['DateCreated']
|
||||
date_added = date_added.split('.')[0].replace('T', " ")
|
||||
except KeyError:
|
||||
date_added = None
|
||||
|
||||
return date_added
|
||||
|
||||
def get_premiere_date(self):
|
||||
|
||||
try:
|
||||
premiere = self.item['PremiereDate']
|
||||
premiere = premiere.split('.')[0].replace('T', " ")
|
||||
except KeyError:
|
||||
premiere = None
|
||||
|
||||
return premiere
|
||||
|
||||
def get_overview(self, overview=None):
|
||||
|
||||
overview = overview or self.item.get('Overview')
|
||||
|
@ -321,24 +168,6 @@ class API(object):
|
|||
|
||||
return overview
|
||||
|
||||
def get_tagline(self):
|
||||
|
||||
try:
|
||||
tagline = self.item['Taglines'][0]
|
||||
except IndexError:
|
||||
tagline = None
|
||||
|
||||
return tagline
|
||||
|
||||
def get_provider(self, name):
|
||||
|
||||
try:
|
||||
provider = self.item['ProviderIds'][name]
|
||||
except KeyError:
|
||||
provider = None
|
||||
|
||||
return provider
|
||||
|
||||
def get_mpaa(self):
|
||||
# Convert more complex cases
|
||||
mpaa = self.item.get('OfficialRating', "")
|
||||
|
@ -352,15 +181,6 @@ class API(object):
|
|||
|
||||
return mpaa
|
||||
|
||||
def get_country(self):
|
||||
|
||||
try:
|
||||
country = self.item['ProductionLocations'][0]
|
||||
except (IndexError, KeyError):
|
||||
country = None
|
||||
|
||||
return country
|
||||
|
||||
def get_file_path(self, path=None):
|
||||
|
||||
if path is None:
|
||||
|
|
|
@ -273,117 +273,3 @@ def normalize_string(text):
|
|||
text = unicodedata.normalize('NFKD', unicode(text, 'utf-8')).encode('ascii', 'ignore')
|
||||
|
||||
return text
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
#################################################################################################
|
||||
# Utility methods
|
||||
|
||||
def getScreensaver():
|
||||
# Get the current screensaver value
|
||||
result = JSONRPC('Settings.getSettingValue').execute({'setting': "screensaver.mode"})
|
||||
try:
|
||||
return result['result']['value']
|
||||
except KeyError:
|
||||
return ""
|
||||
|
||||
def setScreensaver(value):
|
||||
# Toggle the screensaver
|
||||
params = {
|
||||
'setting': "screensaver.mode",
|
||||
'value': value
|
||||
}
|
||||
result = JSONRPC('Settings.setSettingValue').execute(params)
|
||||
log.info("Toggling screensaver: %s %s" % (value, result))
|
||||
|
||||
def convertDate(date):
|
||||
try:
|
||||
date = datetime.strptime(date, "%Y-%m-%dT%H:%M:%SZ")
|
||||
except (ImportError, TypeError):
|
||||
# TypeError: attribute of type 'NoneType' is not callable
|
||||
# Known Kodi/python error
|
||||
date = datetime(*(time.strptime(date, "%Y-%m-%dT%H:%M:%SZ")[0:6]))
|
||||
|
||||
return date
|
||||
|
||||
|
||||
def indent(elem, level=0):
|
||||
# Prettify xml trees
|
||||
i = "\n" + level*" "
|
||||
if len(elem):
|
||||
if not elem.text or not elem.text.strip():
|
||||
elem.text = i + " "
|
||||
if not elem.tail or not elem.tail.strip():
|
||||
elem.tail = i
|
||||
for elem in elem:
|
||||
indent(elem, level+1)
|
||||
if not elem.tail or not elem.tail.strip():
|
||||
elem.tail = i
|
||||
else:
|
||||
if level and (not elem.tail or not elem.tail.strip()):
|
||||
elem.tail = i
|
||||
|
||||
def profiling(sortby="cumulative"):
|
||||
# Will print results to Kodi log
|
||||
def decorator(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
import cProfile
|
||||
import pstats
|
||||
|
||||
pr = cProfile.Profile()
|
||||
|
||||
pr.enable()
|
||||
result = func(*args, **kwargs)
|
||||
pr.disable()
|
||||
|
||||
s = StringIO.StringIO()
|
||||
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
|
||||
ps.print_stats()
|
||||
log.info(s.getvalue())
|
||||
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
#################################################################################################
|
||||
# Addon utilities
|
||||
|
||||
|
||||
def verify_advancedsettings():
|
||||
# Track the existance of <cleanonupdate>true</cleanonupdate>
|
||||
# incompatible with plugin paths
|
||||
log.info("verifying advanced settings")
|
||||
if settings('useDirectPaths') != "0": return
|
||||
|
||||
path = xbmc.translatePath("special://userdata/").decode('utf-8')
|
||||
xmlpath = "%sadvancedsettings.xml" % path
|
||||
|
||||
try:
|
||||
xmlparse = etree.parse(xmlpath)
|
||||
except: # Document is blank or missing
|
||||
return
|
||||
else:
|
||||
root = xmlparse.getroot()
|
||||
|
||||
video = root.find('videolibrary')
|
||||
if video is not None:
|
||||
cleanonupdate = video.find('cleanonupdate')
|
||||
if cleanonupdate is not None and cleanonupdate.text == "true":
|
||||
log.warn("cleanonupdate disabled")
|
||||
video.remove(cleanonupdate)
|
||||
|
||||
try:
|
||||
indent(root)
|
||||
except: pass
|
||||
etree.ElementTree(root).write(xmlpath)
|
||||
|
||||
xbmcgui.Dialog().ok(heading=language(29999), line1=language(33097))
|
||||
xbmc.executebuiltin('RestartApp')
|
||||
return True
|
||||
return
|
||||
"""
|
||||
|
|
|
@ -80,272 +80,7 @@ def tvtunes_nfo(path, urls):
|
|||
indent(xml)
|
||||
write_xml(etree.tostring(xml, 'UTF-8'), path)
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#################################################################################################
|
||||
|
||||
import inspect
|
||||
import json
|
||||
import logging
|
||||
import sqlite3
|
||||
import StringIO
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import urllib
|
||||
import unicodedata
|
||||
import xml.etree.ElementTree as etree
|
||||
from datetime import datetime
|
||||
from uuid import uuid4
|
||||
|
||||
|
||||
import xbmc
|
||||
import xbmcaddon
|
||||
import xbmcgui
|
||||
import xbmcplugin
|
||||
import xbmcvfs
|
||||
|
||||
#################################################################################################
|
||||
|
||||
log = logging.getLogger("EMBY."+__name__)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
||||
|
||||
|
||||
#################################################################################################
|
||||
# Utility methods
|
||||
|
||||
def getScreensaver():
|
||||
# Get the current screensaver value
|
||||
result = JSONRPC('Settings.getSettingValue').execute({'setting': "screensaver.mode"})
|
||||
try:
|
||||
return result['result']['value']
|
||||
except KeyError:
|
||||
return ""
|
||||
|
||||
def setScreensaver(value):
|
||||
# Toggle the screensaver
|
||||
params = {
|
||||
'setting': "screensaver.mode",
|
||||
'value': value
|
||||
}
|
||||
result = JSONRPC('Settings.setSettingValue').execute(params)
|
||||
log.info("Toggling screensaver: %s %s" % (value, result))
|
||||
|
||||
def convertDate(date):
|
||||
try:
|
||||
date = datetime.strptime(date, "%Y-%m-%dT%H:%M:%SZ")
|
||||
except (ImportError, TypeError):
|
||||
# TypeError: attribute of type 'NoneType' is not callable
|
||||
# Known Kodi/python error
|
||||
date = datetime(*(time.strptime(date, "%Y-%m-%dT%H:%M:%SZ")[0:6]))
|
||||
|
||||
return date
|
||||
|
||||
def normalize_string(text):
|
||||
# For theme media, do not modify unless
|
||||
# modified in TV Tunes
|
||||
text = text.replace(":", "")
|
||||
text = text.replace("/", "-")
|
||||
text = text.replace("\\", "-")
|
||||
text = text.replace("<", "")
|
||||
text = text.replace(">", "")
|
||||
text = text.replace("*", "")
|
||||
text = text.replace("?", "")
|
||||
text = text.replace('|', "")
|
||||
text = text.strip()
|
||||
# Remove dots from the last character as windows can not have directories
|
||||
# with dots at the end
|
||||
text = text.rstrip('.')
|
||||
text = unicodedata.normalize('NFKD', unicode(text, 'utf-8')).encode('ascii', 'ignore')
|
||||
|
||||
return text
|
||||
|
||||
def indent(elem, level=0):
|
||||
# Prettify xml trees
|
||||
i = "\n" + level*" "
|
||||
if len(elem):
|
||||
if not elem.text or not elem.text.strip():
|
||||
elem.text = i + " "
|
||||
if not elem.tail or not elem.tail.strip():
|
||||
elem.tail = i
|
||||
for elem in elem:
|
||||
indent(elem, level+1)
|
||||
if not elem.tail or not elem.tail.strip():
|
||||
elem.tail = i
|
||||
else:
|
||||
if level and (not elem.tail or not elem.tail.strip()):
|
||||
elem.tail = i
|
||||
|
||||
def profiling(sortby="cumulative"):
|
||||
# Will print results to Kodi log
|
||||
def decorator(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
import cProfile
|
||||
import pstats
|
||||
|
||||
pr = cProfile.Profile()
|
||||
|
||||
pr.enable()
|
||||
result = func(*args, **kwargs)
|
||||
pr.disable()
|
||||
|
||||
s = StringIO.StringIO()
|
||||
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
|
||||
ps.print_stats()
|
||||
log.info(s.getvalue())
|
||||
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
#################################################################################################
|
||||
# Addon utilities
|
||||
|
||||
def sourcesXML():
|
||||
# To make Master lock compatible
|
||||
path = xbmc.translatePath("special://profile/").decode('utf-8')
|
||||
xmlpath = "%ssources.xml" % path
|
||||
|
||||
try:
|
||||
xmlparse = etree.parse(xmlpath)
|
||||
except: # Document is blank or missing
|
||||
root = etree.Element('sources')
|
||||
else:
|
||||
root = xmlparse.getroot()
|
||||
|
||||
|
||||
video = root.find('video')
|
||||
if video is None:
|
||||
video = etree.SubElement(root, 'video')
|
||||
etree.SubElement(video, 'default', attrib={'pathversion': "1"})
|
||||
|
||||
# Add elements
|
||||
count = 2
|
||||
for source in root.findall('.//path'):
|
||||
if source.text == "smb://":
|
||||
count -= 1
|
||||
|
||||
if count == 0:
|
||||
# sources already set
|
||||
break
|
||||
else:
|
||||
# Missing smb:// occurences, re-add.
|
||||
for i in range(0, count):
|
||||
source = etree.SubElement(video, 'source')
|
||||
etree.SubElement(source, 'name').text = "Emby"
|
||||
etree.SubElement(source, 'path', attrib={'pathversion': "1"}).text = "smb://"
|
||||
etree.SubElement(source, 'allowsharing').text = "true"
|
||||
# Prettify and write to file
|
||||
try:
|
||||
indent(root)
|
||||
except: pass
|
||||
etree.ElementTree(root).write(xmlpath)
|
||||
|
||||
def passwordsXML():
|
||||
|
||||
# To add network credentials
|
||||
path = xbmc.translatePath("special://userdata/").decode('utf-8')
|
||||
xmlpath = "%spasswords.xml" % path
|
||||
|
||||
try:
|
||||
xmlparse = etree.parse(xmlpath)
|
||||
except: # Document is blank or missing
|
||||
root = etree.Element('passwords')
|
||||
else:
|
||||
root = xmlparse.getroot()
|
||||
|
||||
dialog = xbmcgui.Dialog()
|
||||
credentials = settings('networkCreds')
|
||||
if credentials:
|
||||
# Present user with options
|
||||
option = dialog.select(language(33075), [language(33076), language(33077)])
|
||||
|
||||
if option < 0:
|
||||
# User cancelled dialog
|
||||
return
|
||||
|
||||
elif option == 1:
|
||||
# User selected remove
|
||||
for paths in root.getiterator('passwords'):
|
||||
for path in paths:
|
||||
if path.find('.//from').text == "smb://%s/" % credentials:
|
||||
paths.remove(path)
|
||||
log.info("Successfully removed credentials for: %s" % credentials)
|
||||
etree.ElementTree(root).write(xmlpath)
|
||||
break
|
||||
else:
|
||||
log.info("Failed to find saved server: %s in passwords.xml" % credentials)
|
||||
|
||||
settings('networkCreds', value="")
|
||||
xbmcgui.Dialog().notification(
|
||||
heading=language(29999),
|
||||
message="%s %s" % (language(33078), credentials),
|
||||
icon="special://home/addons/plugin.video.emby/icon.png",
|
||||
time=1000,
|
||||
sound=False)
|
||||
return
|
||||
|
||||
elif option == 0:
|
||||
# User selected to modify
|
||||
server = dialog.input(language(33083), credentials)
|
||||
if not server:
|
||||
return
|
||||
else:
|
||||
# No credentials added
|
||||
dialog.ok(heading=language(29999), line1=language(33082))
|
||||
server = dialog.input(language(33084))
|
||||
if not server:
|
||||
return
|
||||
|
||||
# Network username
|
||||
user = dialog.input(language(33079))
|
||||
if not user:
|
||||
return
|
||||
# Network password
|
||||
password = dialog.input(heading=language(33080), option=xbmcgui.ALPHANUM_HIDE_INPUT)
|
||||
if not password:
|
||||
return
|
||||
|
||||
# Add elements
|
||||
for path in root.findall('.//path'):
|
||||
if path.find('.//from').text.lower() == "smb://%s/" % server.lower():
|
||||
# Found the server, rewrite credentials
|
||||
topath = "smb://%s:%s@%s/" % (user, password, server)
|
||||
path.find('.//to').text = topath.replace("\\", ";")
|
||||
break
|
||||
else:
|
||||
# Server not found, add it.
|
||||
path = etree.SubElement(root, 'path')
|
||||
etree.SubElement(path, 'from', attrib={'pathversion': "1"}).text = "smb://%s/" % server
|
||||
topath = "smb://%s:%s@%s/" % (user, password, server)
|
||||
etree.SubElement(path, 'to', attrib={'pathversion': "1"}).text = topath.replace("\\", ";")
|
||||
# Force Kodi to see the credentials without restarting
|
||||
xbmcvfs.exists(topath)
|
||||
|
||||
# Add credentials
|
||||
settings('networkCreds', value=server)
|
||||
log.info("Added server: %s to passwords.xml" % server)
|
||||
# Prettify and write to file
|
||||
try:
|
||||
indent(root)
|
||||
except: pass
|
||||
etree.ElementTree(root).write(xmlpath)
|
||||
|
||||
dialog.notification(
|
||||
heading=language(29999),
|
||||
message="%s %s" % (language(33081), server),
|
||||
icon="special://home/addons/plugin.video.emby/icon.png",
|
||||
time=1000,
|
||||
sound=False)
|
||||
|
||||
def verify_advancedsettings():
|
||||
# Track the existance of <cleanonupdate>true</cleanonupdate>
|
||||
# incompatible with plugin paths
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue