import os
from xbmcplugin import setContent
from lib.clients.tmdb.utils.utils import tmdb_get
from lib.db.cached import cache
from lib.db.pickle_db import PickleDatabase
from lib.utils.general.utils import (
remove_from_library,
set_media_infoTag,
set_pluging_category,
)
from lib.utils.kodi.utils import (
ADDON_HANDLE,
ADDON_PATH,
add_directory_items_batch,
apply_section_view,
build_url,
end_of_directory,
make_list_item,
notification,
translation,
)
from lib.utils.views.last_titles import parse_time
def _library_cache_key(mode):
return f"library_view|{mode}"
def _is_stremio_library_item(data):
return data.get("source") == "stremio_catalog" or (
data.get("addon_url")
and data.get("catalog_type")
and (data.get("meta_id") or data.get("ids", {}).get("original_id"))
)
def _normalize_library_mode(mode):
return "tv" if mode == "tv" else "movies"
def _build_stremio_details(data, mode):
ids = data.get("ids", {})
details = {
"title": data.get("title", ""),
"name": data.get("title", ""),
"overview": data.get("overview", ""),
"poster": data.get("poster", ""),
"fanart": data.get("fanart", ""),
"banner": data.get("fanart", ""),
"landscape": data.get("fanart", ""),
"clearart": "",
"clearlogo": "",
"imdb_id": ids.get("imdb_id", ""),
"tvdb_id": ids.get("tvdb_id", ""),
"id": ids.get("tmdb_id", "") or ids.get("original_id", ""),
"genres": data.get("genres", []),
}
if mode == "tv":
details["original_name"] = data.get("title", "")
else:
details["original_title"] = data.get("title", "")
return details
def _build_tmdb_entry(title, data, mode):
ids = data.get("ids", {})
details_path = "tv_details" if mode == "tv" else "movie_details"
details = tmdb_get(details_path, ids.get("tmdb_id"))
if not details:
return None
return {"title": title, "data": data, "details": details, "is_stremio": False}
def _build_stremio_entry(title, data, mode):
return {
"title": title,
"data": data,
"details": _build_stremio_details(data, mode),
"is_stremio": True,
}
def _get_library_entries(items, mode):
cached_entries = cache.get(_library_cache_key(mode))
if cached_entries:
return cached_entries
entries = []
for title, data in items:
if _is_stremio_library_item(data):
entries.append(_build_stremio_entry(title, data, mode))
continue
entry = _build_tmdb_entry(title, data, mode)
if entry:
entries.append(entry)
cache.set(_library_cache_key(mode), entries)
return entries
def _build_library_context_menu(title):
remove_url = build_url("remove_from_library", title=title)
return [(translation(90204), f"RunPlugin({remove_url})")]
def _library_mode_matches(item_mode, mode):
if mode == "tv":
return item_mode == "tv"
return item_mode in ["movie", "movies"]
def _get_stremio_library_url(data, mode):
ids = data.get("ids", {})
meta_id = data.get("meta_id") or ids.get("original_id", "")
if mode == "tv":
if data.get("addon_url") and data.get("catalog_type") and meta_id:
return build_url(
"list_stremio_seasons",
addon_url=data.get("addon_url"),
catalog_type=data.get("catalog_type"),
meta_id=meta_id,
)
return build_url("show_seasons_details", ids=ids, mode=mode)
if data.get("addon_url") and data.get("catalog_type") and meta_id:
return build_url(
"list_stremio_movie",
addon_url=data.get("addon_url"),
catalog_type=data.get("catalog_type"),
meta_id=meta_id,
ids=data.get("ids", {}),
title=data.get("title", ""),
overview=data.get("overview", ""),
poster=data.get("poster", ""),
fanart=data.get("fanart", ""),
genres=data.get("genres", []),
)
return build_url("search", mode=mode, query=data.get("title", ""), ids=ids)
def _get_library_item_url(entry, mode):
data = entry["data"]
ids = data.get("ids", {})
if entry["is_stremio"]:
return _get_stremio_library_url(data, mode)
if mode == "tv":
return build_url("show_seasons_details", ids=ids, mode=mode)
return build_url("search", mode=mode, query=entry["title"], ids=ids)
def show_library_items(mode="tv"):
category = translation(90202) if mode == "tv" else translation(90203)
set_pluging_category(category)
setContent(ADDON_HANDLE, mode)
all_items = list(reversed(PickleDatabase().get_key("jt:lib").items()))
items = []
for title, data in all_items:
item_mode = data.get("mode")
if _library_mode_matches(item_mode, mode):
items.append((title, data))
items = sorted(items, key=parse_time, reverse=True)
directory_items = []
for entry in _get_library_entries(items, mode):
title = entry["title"]
data = entry["data"]
details = entry["details"]
list_item = make_list_item(label=title)
set_media_infoTag(list_item, data=details, mode=_normalize_library_mode(mode))
list_item.addContextMenuItems(_build_library_context_menu(title))
# Keep a simple local fallback icon for entries without artwork.
list_item.setArt({"icon": os.path.join(ADDON_PATH, "resources", "img", "trending.png")})
item_url = _get_library_item_url(entry, mode)
is_folder = mode == "tv"
if mode == "movies":
list_item.setProperty("IsPlayable", "true" if not entry["is_stremio"] else "false")
directory_items.append((item_url, list_item, is_folder))
add_directory_items_batch(directory_items)
end_of_directory(cache=False)
if mode == "tv":
apply_section_view("view.library", content_type="tvshows")
else:
apply_section_view("view.library", content_type="movies")
def remove_library_item(params):
title = params.get("title")
if title:
remove_from_library(title)
from xbmc import executebuiltin
executebuiltin("Container.Refresh")
def clear_library_items(params):
mode = params.get("mode", "tv")
pickle_db = PickleDatabase()
library_items = dict(pickle_db.get_key("jt:lib") or {})
titles_to_remove = []
removed_count = 0
for title, data in library_items.items():
if _library_mode_matches(data.get("mode"), mode):
titles_to_remove.append(title)
removed_count += 1
for title in titles_to_remove:
pickle_db.delete_item("jt:lib", title, commit=False)
if titles_to_remove:
pickle_db.commit()
cache.delete(_library_cache_key("tv"))
cache.delete(_library_cache_key("movies"))
if removed_count:
notification("", translation(90692))
else:
notification("", translation(90693))
return removed_count