Skip to content

Instantly share code, notes, and snippets.

@aenniw
Last active January 14, 2021 16:24
Show Gist options
  • Save aenniw/4f97fd3210b41d13f92275aeacda2826 to your computer and use it in GitHub Desktop.
Save aenniw/4f97fd3210b41d13f92275aeacda2826 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import multiprocessing as mp
import argparse
import requests
import logging
import shutil
import os
extensions = [
'avi', 'AVI',
'mkv', 'MKV',
'mp4', 'MP4',
'mpg', 'MPG'
]
class EmbyThumbnails:
def __init__(self, url, token):
self.url = url
self.token = token
self.items = {}
def __get_extension(self, size):
size = str(size)
extension = int(size[:-3])
units = int(size[-3:])
while extension > 4294967 or extension == 4294967 and units >= 296:
extension -= 4294967
if units >= 296:
units -= 296
else:
units = 1000 + units - 296
extension -= 1
return extension
def __download_cover(self, id, origFile, size):
filename = '%s.%s' % (
'.'.join(origFile.split('.')[:-1]), self.__get_extension(size))
os.makedirs(os.path.dirname(filename), exist_ok=True)
with open(filename, 'wb') as f:
resp = requests.get(
'%s/emby/Items/%s/Images/Primary?MaxWidth=200&MaxHeight=300&Format=jpg' % (self.url, id))
f.write(resp.content)
os.chmod(filename, 0o644)
logging.info('donwloaded [%s]', filename)
def load_metadata(self):
libraryPaths = []
for libraryPath in requests.get('%s/emby/Library/PhysicalPaths?api_key=%s' % (self.url, self.token)).json():
path = '/'.join(libraryPath.split('/')[:-1])
if path not in libraryPaths:
libraryPaths.append(path)
self.items = {}
for library in requests.get('%s/emby/Items?api_key=%s' % (self.url, self.token)).json()['Items']:
for item in requests.get(
'%s/emby/Items?Recursive=true&ParentId=%s&Fields=Path&api_key=%s' %
(self.url, library['Id'], self.token)).json()['Items']:
if 'Path' not in item:
continue
itemType = item['Type']
if itemType not in ['Movie', 'Episode']:
continue
for libraryPath in libraryPaths:
if item['Path'].startswith(libraryPath):
path = item['Path'][len(libraryPath):]
self.items[path] = item['Id' if itemType ==
'Movie' else 'SeriesId']
break
logging.info('loaded [%d] entries', len(self.items))
def process_file(self, paths):
self.__download_cover(
self.items[paths[1]], paths[2] + paths[1], os.path.getsize(paths[0]))
def generate(self, src, dst):
if src.endswith('/'):
src = src[:-1]
if dst.endswith('/'):
dst = dst[:-1]
shutil.rmtree(dst)
files = []
for r, d, f in os.walk(src):
for file in f:
path = os.path.join(r, file)
relPath = path[len(src):]
if file.split('.')[-1] in extensions and relPath in self.items:
files.append((path, relPath, dst))
logging.info('detected [%s] files', len(files))
with mp.Pool(processes=mp.cpu_count()) as p:
results = p.map(self.process_file, files)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
optional = parser._action_groups.pop()
required = parser.add_argument_group('required arguments')
required.add_argument('-u', '--url', required=True)
required.add_argument("-t", "--token", required=True)
required.add_argument("-s", "--src-dir", required=True)
required.add_argument("-d", "--dst-dir", required=True)
parser._action_groups.append(optional)
args = parser.parse_args()
logging.basicConfig(format='%(asctime)s | %(levelname)s | %(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO)
thumbnails = EmbyThumbnails(args.url, args.token)
thumbnails.load_metadata()
thumbnails.generate(args.src_dir, args.dst_dir)

Emby to SamyGo B650 thumbnail exporter

usage:

./emby-thumbnails.py -u http://192.168.0.1:8096 -t 4a4cr9eaddda4e0283099ec02aa81d02 -s /media/library -d /meadiathumbnails
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment