add dynamic image colage http image server for menu items

This commit is contained in:
faush01
2019-12-09 16:40:55 +11:00
parent 1c259461fb
commit 783d482f36
3 changed files with 198 additions and 1 deletions

View File

@@ -0,0 +1,185 @@
import xbmcvfs
import xbmc
import base64
import re
from urlparse import urlparse
import threading
import httplib
import io
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from PIL import ImageFilter, Image, ImageOps
from .simple_logging import SimpleLogging
from .datamanager import DataManager
from .downloadutils import DownloadUtils
from .utils import getArt
PORT_NUMBER = 24276
log = SimpleLogging(__name__)
def get_image_links(url):
download_utils = DownloadUtils()
server = download_utils.getServer()
if server is None:
return []
url = re.sub("(?i)limit=[0-9]+", "limit=4", url)
url = url.replace("{ItemLimit}", "4")
url = re.sub("(?i)SortBy=[a-zA-Z]+", "SortBy=Random", url)
if not re.search('limit=', url, re.IGNORECASE):
url += "&Limit=4"
if not re.search('sortBy=', url, re.IGNORECASE):
url += "&SortBy=Random"
data_manager = DataManager()
result = data_manager.GetContent(url)
items = result.get("Items")
if not items:
return []
art_urls = []
for iteem in items:
art = getArt(item=iteem, server=server)
art_urls.append(art)
return art_urls
def build_image(path):
log.debug("build_image()")
log.debug("Request Path : {0}", path)
request_path = path[1:]
if request_path == "favicon.ico":
return []
decoded_url = base64.b64decode(request_path)
log.debug("decoded_url : {0}", decoded_url)
image_urls = get_image_links(decoded_url)
width, height = 500, 750
collage = Image.new('RGB', (width, height), (5, 5, 5))
cols = 2
rows = 2
thumbnail_width = int(width / cols)
thumbnail_height = int(height / rows)
size = thumbnail_width, thumbnail_height
image_count = 0
for art in image_urls:
thumb_url = art.get("thumb")
if thumb_url:
url_bits = urlparse(thumb_url.strip())
host_name = url_bits.hostname
port = url_bits.port
user_name = url_bits.username
user_password = url_bits.password
url_path = url_bits.path
url_query = url_bits.query
server = "%s:%s" % (host_name, port)
url_full_path = url_path + "?" + url_query
log.debug("Adding Image : {0} {1} {2}", image_count, server, url_full_path)
conn = httplib.HTTPConnection(server)
conn.request("GET", url_full_path)#"/emby/Items/32907/Images/Primary?maxHeight=635&tag=b06948152c2c1203ceedd66721a18f6f&quality=90")
image_responce = conn.getresponse()
image_data = image_responce.read()
loaded_image = Image.open(io.BytesIO(image_data))
image = ImageOps.fit(loaded_image, (size), method=Image.ANTIALIAS, bleed=0.0, centering=(0.5, 0.5))
x = int(image_count % cols) * thumbnail_width
y = int(image_count/cols) * thumbnail_height
collage.paste(image, (x, y))
del image_data
del loaded_image
del image
image_count += 1
del image_urls
imgByteArr = io.BytesIO()
collage.save(imgByteArr, format='JPEG')
image_bytes = imgByteArr.getvalue()
return image_bytes
class HttpImageHandler(BaseHTTPRequestHandler):
def log_message(self, format, *args):
log_line = format % args
log.debug(log_line)
return
def do_GET(self):
log.debug("HttpImageHandler:do_GET()")
self.serve_image()
return
def do_HEAD(self):
log.debug("HttpImageHandler:do_HEAD()")
self.send_response(200)
self.end_headers()
return
def do_QUIT(self):
log.debug("HttpImageHandler:do_QUIT()")
self.send_response(200)
self.end_headers()
return
def serve_image(self):
image_bytes = build_image(self.path)
self.send_response(200)
self.send_header('Content-type', 'image/jpeg')
self.send_header('Content-Length', str(len(image_bytes)))
self.end_headers()
self.wfile.write(image_bytes)
class HttpImageServerThread(threading.Thread):
keep_running = True
def __init__(self):
threading.Thread.__init__(self)
def stop(self):
self.keep_running = False
log.debug("HttpImageServerThread:stop called")
try:
conn = httplib.HTTPConnection("localhost:%d" % PORT_NUMBER)
conn.request("QUIT", "/")
conn.getresponse()
except Exception as err:
pass
def run(self):
log.debug("HttpImageServerThread:started")
server = HTTPServer(('', PORT_NUMBER), HttpImageHandler)
while self.keep_running:
server.handle_request()
log.debug("HttpImageServerThread:exiting")

View File

@@ -4,6 +4,7 @@
import sys
import json
import urllib
import base64
import xbmcplugin
import xbmcaddon
@@ -155,13 +156,15 @@ def show_movie_years(params):
item_url = get_emby_url("{server}/emby/Users/{userid}/Items", params)
art = {"thumb": "http://localhost:24276/" + base64.b64encode(item_url)}
content_url = urllib.quote(item_url)
url = sys.argv[0] + ("?url=" +
content_url +
"&mode=GET_CONTENT" +
"&media_type=movies")
log.debug("addMenuDirectoryItem: {0} - {1}", name, url)
addMenuDirectoryItem(name, url)
addMenuDirectoryItem(name, url, art=art)
xbmcplugin.endOfDirectory(int(sys.argv[1]))
@@ -234,6 +237,8 @@ def show_movie_pages(params):
item_data['path'] = item_url
item_data['media_type'] = 'movies'
item_data["art"] = {"thumb": "http://localhost:24276/" + base64.b64encode(item_url)}
collections.append(item_data)
start_index = start_index + page_limit

View File

@@ -23,6 +23,7 @@ from resources.lib.server_detect import checkServer
from resources.lib.library_change_monitor import LibraryChangeMonitor
from resources.lib.datamanager import clear_old_cache_data
from resources.lib.tracking import set_timing_enabled
from resources.lib.image_server import HttpImageServerThread
settings = xbmcaddon.Addon()
@@ -63,6 +64,10 @@ try:
except Exception as error:
log.error("Error with initial service auth: {0}", error)
image_server = HttpImageServerThread()
image_server.start()
# set up all the services
monitor = Service()
playback_service = PlaybackService(monitor)
@@ -155,6 +160,8 @@ while not xbmc.abortRequested:
xbmc.sleep(1000)
image_server.stop()
# call stop on the library update monitor
library_change_monitor.stop()