Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[script.module.jurialmunkey] 0.1.18 #2624

Merged
merged 1 commit into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion script.module.jurialmunkey/addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.module.jurialmunkey" name="jurialmunkey common" provider-name="jurialmunkey" version="0.1.2">
<addon id="script.module.jurialmunkey" name="jurialmunkey common" provider-name="jurialmunkey" version="0.1.18">
<requires>
<import addon="xbmc.python" version="3.0.1"/>
<import addon="script.module.requests" version="2.9.1"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# XBMC Media Center language file
# Addon Name: TheMovieDb Helper
# Addon id: plugin.video.themoviedb.helper
# Addon Provider: jurialmunkey
msgid ""
msgstr ""
"Project-Id-Version: XBMC-Addons\n"
"Report-Msgid-Bugs-To: [email protected]\n"
"POT-Creation-Date: 2014-10-26 17:05+0000\n"
"PO-Revision-Date: 2024-04-21 13:42+0300\n"
"Last-Translator: Oskari Lavinto <[email protected]>\n"
"Language-Team: Finnish\n"
"Language: fi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.4.2\n"

#: /request.py
msgctxt "#32001"
msgid "Suppressing retries for {} seconds"
msgstr "Keskeytetään uudelleenyritykset {} sekunniksi"

#: /request.py
msgctxt "#32002"
msgid "ConnectionError: {}"
msgstr "Yhteysvirhe: {}"
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ def ret_cache(self):
return self._cache

@kodi_try_except_internal_traceback('lib.addon.cache get_cache')
def get_cache(self, cache_name):
def get_cache(self, cache_name, cache_only=False):
self.ret_cache()
cur_time = -1 if cache_only else None # Set negative time value if cache_only so we always get cache even if expired
cache_name = get_filecache_name(cache_name or '')
return self._cache.get(cache_name)
return self._cache.get(cache_name, cur_time=cur_time)

@kodi_try_except_internal_traceback('lib.addon.cache set_cache')
def set_cache(self, my_object, cache_name, cache_days=14, force=False, fallback=None):
Expand Down Expand Up @@ -67,9 +68,14 @@ def use_cache(
cache_name = format_name(cache_name, *args, **kwargs)
for k, v in cache_strip:
cache_name = cache_name.replace(k, v)
my_cache = self.get_cache(cache_name) if not cache_refresh else None

my_cache = None
if cache_only or not cache_refresh:
my_cache = self.get_cache(cache_name, cache_only=cache_only)

if my_cache:
return my_cache

if not cache_only:
if headers:
kwargs['headers'] = headers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
class ProgressDialog(object):
""" ContextManager for DialogProgressBG use in with statement """

def __init__(self, title='', message='', total=100, logging=1):
def __init__(self, title='', message='', total=100, logging=1, background=True):
self.logging = logging
self.background = background
self._create(title, message, total)

def __enter__(self):
Expand All @@ -21,7 +22,7 @@ def kodi_log(msg, level=0):
Logger('[script.module.jurialmunkey]\n').kodi_log(msg, level)

def _create(self, title='', message='', total=100):
self._pd = xbmcgui.DialogProgressBG()
self._pd = xbmcgui.DialogProgressBG() if self.background else xbmcgui.DialogProgress()
self._pd.create(title, message)
self._count = 0
self._total = total
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ def get_write_path(self, folder, join_addon_data=True, make_dir=True):
def get_file_path(self, folder, filename, join_addon_data=True, make_dir=True):
return validate_join(self.get_write_path(folder, join_addon_data, make_dir), filename)

def dumps_to_file(self, data, folder, filename, indent=2, join_addon_data=True):
from json import dump
path = self.get_file_path(folder, filename, join_addon_data)
with xbmcvfs.File(path, 'w') as file:
dump(data, file, indent=indent)
return path

def delete_file(self, folder, filename, join_addon_data=True):
xbmcvfs.delete(self.get_file_path(folder, filename, join_addon_data, make_dir=False))

def delete_folder(self, folder, join_addon_data=True, force=False, check_exists=False):
path = self.get_write_path(folder, join_addon_data, make_dir=False)
if check_exists and not xbmcvfs.exists(path):
return
xbmcvfs.rmdir(path, force=force)


def json_loads(obj):
import json
Expand Down Expand Up @@ -111,3 +127,15 @@ def write_skinfile(filename=None, folders=None, content=None, hashvalue=None, ha

if checksum:
xbmc.executebuiltin('Skin.SetString({},{})'.format(checksum, make_hash(content)))


def get_files_in_folder(folder, regex):
import re
return [x for x in xbmcvfs.listdir(folder)[1] if re.match(regex, x)]


def read_file(filepath):
content = ''
with xbmcvfs.File(filepath) as vfs_file:
content = vfs_file.read()
return content
129 changes: 129 additions & 0 deletions script.module.jurialmunkey/resources/modules/jurialmunkey/jsnrpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from xbmc import executeJSONRPC
from jurialmunkey.parser import try_int


def get_jsonrpc(method=None, params=None, query_id=1):
if not method:
return {}
query = {
"jsonrpc": "2.0",
"method": method,
"id": query_id}
if params:
query["params"] = params
try:
from json import dumps, loads
jrpc = executeJSONRPC(dumps(query))
response = loads(jrpc)
except Exception as exc:
from jurialmunkey.logger import Logger
Logger(log_name='[script.module.jurialmunkey]').kodi_log(f'JSONRPC Error:\n{exc}', 1)
response = {}
if 'error' in response:
from jurialmunkey.logger import Logger
Logger(log_name='[script.module.jurialmunkey]').kodi_log(f'JSONRPC Error:\n{query}\n{response}', 1)
return response


def get_library(dbtype=None, properties=None, filterr=None):
if dbtype == "movie":
method = "VideoLibrary.GetMovies"
elif dbtype == "tvshow":
method = "VideoLibrary.GetTVShows"
elif dbtype == "episode":
method = "VideoLibrary.GetEpisodes"
else:
return

params = {"properties": properties or ["title"]}
if filterr:
params['filter'] = filterr

response = get_jsonrpc(method, params)
return response.get('result')


def get_num_credits(dbtype, person):
if dbtype == 'movie':
filterr = {
"or": [
{"field": "actor", "operator": "contains", "value": person},
{"field": "director", "operator": "contains", "value": person},
{"field": "writers", "operator": "contains", "value": person}]}
elif dbtype == 'tvshow':
filterr = {
"or": [
{"field": "actor", "operator": "contains", "value": person},
{"field": "director", "operator": "contains", "value": person}]}
elif dbtype == 'episode':
filterr = {
"or": [
{"field": "actor", "operator": "contains", "value": person},
{"field": "director", "operator": "contains", "value": person},
{"field": "writers", "operator": "contains", "value": person}]}
else:
return
response = get_library(dbtype, filterr=filterr)
try:
return response['limits']['total']
except (AttributeError, KeyError):
return 0


def get_details(dbid, dbtype, key):
json_info = get_jsonrpc(
method=f'VideoLibrary.Get{dbtype.capitalize()}Details',
params={f'{dbtype}id': dbid, "properties": [key]})
try:
return json_info['result'][f'{dbtype}details'][key]
except (AttributeError, KeyError):
return


def set_tags(dbid=None, dbtype=None, tags=None):
if not dbid or not dbtype or not tags:
return

old_db_tags = set(get_details(dbid, dbtype, key='tag') or [])
new_db_tags = old_db_tags | set(tags)

if new_db_tags == old_db_tags:
return

return get_jsonrpc(
method=f'VideoLibrary.Set{dbtype.capitalize()}Details',
params={f'{dbtype}id': dbid, "tag": list(new_db_tags)})


def set_watched(dbid=None, dbtype=None, plays=1):
if not dbid or not dbtype:
return

playcount = get_details(dbid, dbtype, key='playcount') or 0
playcount = try_int(playcount) + plays

return get_jsonrpc(
method=f'VideoLibrary.Set{dbtype.capitalize()}Details',
params={f'{dbtype}id': dbid, "playcount": playcount})


def set_playprogress(filename, position, total):
method = "Files.SetFileDetails"
params = {"file": filename, "media": "video", "resume": {"position": position, "total": total}}
return get_jsonrpc(method=method, params=params)


def get_directory(url, properties=None):
method = "Files.GetDirectory"
properties = properties or [
"title", "year", "originaltitle", "imdbnumber", "premiered", "streamdetails", "size",
"firstaired", "season", "episode", "showtitle", "file", "tvshowid", "thumbnail"]
params = {
"directory": url,
"media": "files",
"properties": properties}
response = get_jsonrpc(method, params)
try:
return response['result']['files'] or [{}]
except KeyError:
return [{}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Module: default
# Author: jurialmunkey
# License: GPL v.3 https://www.gnu.org/copyleft/gpl.html

class Container():
def __init__(self, handle, paramstring, **params):
self.handle = handle
self.paramstring = paramstring
self.params = params

@staticmethod
def get_list_item(label='', label2='', path='', offscreen=True, is_folder=True):
from xbmcgui import ListItem
return (
path,
ListItem(label=label, label2=label2, path=path, offscreen=offscreen),
is_folder,
)

def add_items(self, items, update_listing=False, plugin_category='', container_content=''):
if self.handle is None:
return
import xbmcplugin
xbmcplugin.addDirectoryItems(handle=self.handle, items=items)
xbmcplugin.setPluginCategory(self.handle, plugin_category) # Container.PluginCategory
xbmcplugin.setContent(self.handle, container_content) # Container.Content
xbmcplugin.endOfDirectory(self.handle, updateListing=update_listing)
Original file line number Diff line number Diff line change
Expand Up @@ -119,25 +119,33 @@ def __init__(self, dict_obj, list_name, log_threshold=0.001, logging=True):
self.log_threshold = log_threshold
self.timer_a = timer() if logging else None

@property
def total_time(self):
try:
return self._total_time
except AttributeError:
self._total_time = timer() - self.timer_a
return self._total_time

def __enter__(self):
return self

def __exit__(self, exc_type, exc_value, exc_traceback):
if not self.timer_a:
return
timer_z = timer()
total_time = timer_z - self.timer_a
if total_time > self.log_threshold:
self.list_obj.append(total_time)
if self.total_time > self.log_threshold:
self.list_obj.append(self.total_time)


class TimerFunc():
kodi_log = None

def __init__(self, timer_name, log_threshold=0.05, inline=False, kodi_log=None):
""" ContextManager for timing code blocks and outputing to log """
self.inline = ' ' if inline else '\n'
self.timer_name = timer_name
self.log_threshold = log_threshold
self.kodi_log = kodi_log or Logger().kodi_log
self.kodi_log = self.kodi_log or kodi_log or Logger().kodi_log
self.timer_a = timer()

def __enter__(self):
Expand All @@ -146,5 +154,6 @@ def __enter__(self):
def __exit__(self, exc_type, exc_value, exc_traceback):
timer_z = timer()
total_time = timer_z - self.timer_a
if total_time > self.log_threshold:
self.kodi_log(f'{self.timer_name}{self.inline}{total_time:.3f} sec', 1)
if total_time <= self.log_threshold:
return
self.kodi_log(f'{self.timer_name}{self.inline}{total_time:.3f} sec', 1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from importlib import import_module


def importmodule(module_name, import_attr=None):
module = import_module(module_name)
if not import_attr:
return module
return getattr(module, import_attr)


def lazyimport(global_dict, module_name, import_as=None, import_attr=None):
global_name = import_as or import_attr or module_name
if not global_dict[global_name]:
module = import_module(module_name)
global_dict[global_name] = getattr(module, import_attr) if import_attr else module


def lazyimport_module(global_dict, module_name, import_as=None, import_attr=None):
def decorator(func):
def wrapper(*args, **kwargs):
lazyimport(global_dict, module_name, import_as, import_attr)
return func(*args, **kwargs)
return wrapper
return decorator


def lazyimport_modules(global_dict, list_kwargs):
def decorator(func):
def wrapper(*args, **kwargs):
for i in list_kwargs:
lazyimport(global_dict, **i)
return func(*args, **kwargs)
return wrapper
return decorator
Loading
Loading