Source code for coherence.backends.appletrailers_storage

# -*- coding: utf-8 -*-

# Licensed under the MIT license
# http://opensource.org/licenses/mit-license.php

# Copyright 2008, Benjamin Kampmann <ben.kampmann@googlemail.com>
# Copyright 2018, Pol Canelles <canellestudi@gmail.com>

'''
AppleTrailersStore
------------------

This is a Media Backend that allows you to access the Trailers from Apple.com.

Example to run from python script::

    from coherence.base import Coherence
    from twisted.internet import reactor

    coherence = Coherence(
        {'logmode': 'info',
         'plugin': {'backend': 'AppleTrailersStore',
                    'name': 'Cohen3 AppleTrailersStore',
                    'proxy': 'no',
                    },
         }
    )
    reactor.run()

Example to run from console::

    cohen3 --plugin=backend:AppleTrailersStore,proxy:no

.. note:: you need the cohen 3 package installed to run the plugin from
          a console.

.. versionchanged:: 0.8.3
   The Container class has been removed
'''

from coherence.upnp.core import DIDLLite
from coherence.upnp.core.utils import ReverseProxyUriResource
from coherence.backends.models.items import BackendVideoItem
from coherence.backends.models.stores import BackendVideoStore


[docs]class AppleTrailerProxy(ReverseProxyUriResource): ''' Tha AppleTrailerProxy ia a Resource that takes care to render the result gotten from our server :class:`~coherence.backends.appletrailers_storage.AppleTrailersStore` .. warning:: The ReverseProxyUriResource is not able to handle https requests, so... better stick to non proxy until properly handled. ''' def __init__(self, uri): super(AppleTrailerProxy, self).__init__(uri)
[docs] def render(self, request): request.requestHeaders.setRawHeaders( b'user-agent', [b'QuickTime/7.6.2 (qtver=7.6.2;os=Windows NT 5.1Service Pack 3)']) return super(AppleTrailerProxy, self).render(request)
[docs]class Trailer(BackendVideoItem): ''' A backend item object which represents an Apple Trailer. This class will hold all information regarding the trailer. .. versionchanged:: 0.8.3 Refactored using the class :class:`~coherence.backends.models.items.BackendVideoItem` ''' is_proxy = False proxy_cls = AppleTrailerProxy mimetype = 'video/quicktime' def __init__(self, parent_id, item_id, urlbase, **kwargs): super(Trailer, self).__init__( parent_id, item_id, urlbase, **kwargs) self.runtime = kwargs.get('runtime', None) self.rating = kwargs.get('rating', None) self.post_date = kwargs.get('post_date', None) self.release_date = kwargs.get('release_date', None) self.studio = kwargs.get('studio', None) self.title = f'{self.name} [{self.release_date}]'
[docs]class AppleTrailersStore(BackendVideoStore): ''' The media server for Apple Trailers. .. versionchanged:: 0.8.3 Refactored using the class :class:`~coherence.backends.models.stores.BackendVideoStore` ''' logCategory = 'apple_trailers' implements = ['MediaServer'] upnp_protocols = [ 'http-get:*:video/quicktime:*', 'http-get:*:video/mp4:*'] root_url = b'http://www.apple.com/trailers/home/xml/current.xml' root_find_items = './movieinfo' root_id = 0 item_cls = Trailer item_type = 'http-get:*:video/quicktime:*'
[docs] def parse_item(self, item): info_keys = { 'info/title': 'title', 'info/director': 'director', 'info/runtime': 'runtime', 'info/rating': 'rating', 'info/postdate': 'post_date', 'info/releasedate': 'release_date', 'info/studio': 'studio', 'info/description': 'description', 'poster/location': 'image', 'preview/large': 'url', 'cast/name': 'actors', 'genre/name': 'genres', } has_multiple_values = ['cast/name', 'genre/name'] data = {'id': item.get('id')} for search_key, key in info_keys.items(): v = None if search_key not in has_multiple_values: v = item.find(f'./{search_key}').text else: lv = item.findall(f'./{search_key}') if isinstance(lv, list): v = [e.text for e in lv] if v not in [None, '']: data[key] = v duration = None if 'runtime' in data: hours = 0 minutes = 0 seconds = 0 duration = data['runtime'] try: hours, minutes, seconds = duration.split(':') except ValueError: try: minutes, seconds = duration.split(':') except ValueError: seconds = duration duration = f'{int(hours):d}:{int(minutes):02d}:{int(seconds):02d}' data['duration'] = duration try: data['video_size'] = item.find( './preview/large').get('filesize', None) except Exception: data['video_size'] = None return data
[docs] def add_item(self, data): # print('add_item: {}'.format(data)) trailer = super(AppleTrailersStore, self).add_item(data) trailer.item.res.duration = data['duration'] # Todo: maybe this should be refactored into BackendVideoStore? if self.server.coherence.config.get('transcoding', 'no') == 'yes': dlna_pn = 'DLNA.ORG_PN=AVC_TS_BL_CIF15_AAC' dlna_tags = DIDLLite.simple_dlna_tags[:] dlna_tags[2] = 'DLNA.ORG_CI=1' url = self.urlbase + str(trailer.id) + '?transcoded=mp4' new_res = DIDLLite.Resource( url, f'http-get:*:{"video/mp4"}:{";".join([dlna_pn] + dlna_tags)}') new_res.size = None new_res.duration = data['duration'] trailer.item.res.append(new_res) dlna_pn = 'DLNA.ORG_PN=JPEG_TN' dlna_tags = DIDLLite.simple_dlna_tags[:] dlna_tags[2] = 'DLNA.ORG_CI=1' dlna_tags[3] = 'DLNA.ORG_FLAGS=00f00000000000000000000000000000' url = self.urlbase + str( trailer.id) + '?attachment=poster&transcoded=thumb&type=jpeg' new_res = DIDLLite.Resource( url, f'http-get:*:{"image/jpeg"}:{";".join([dlna_pn] + dlna_tags)}') new_res.size = None # new_res.resolution = '160x160' trailer.item.res.append(new_res) if not hasattr(trailer.item, 'attachments'): trailer.item.attachments = {} trailer.item.attachments['poster'] = (data['image']) # noqa pylint: disable=E1101 return trailer