Exemplo n.º 1
0
class NetflixService(object):
    """
    Netflix addon service
    """
    def __init__(self):
        # init kodi helper (for logging)
        self.kodi_helper = KodiHelper()

        self.last_schedule_check = datetime.now()
        self.schedule_check_interval = int(
            self.kodi_helper.get_setting('schedule_check_interval'))
        self.startidle = 0
        self.freq = int('0' + self.kodi_helper.get_setting('auto_update'))

        # pick & store a port for the MSL service
        msl_port = select_unused_port()
        self.kodi_helper.set_setting('msl_service_port', str(msl_port))
        self.kodi_helper.log(msg='[MSL] Picked Port: ' + str(msl_port))

        # pick & store a port for the internal Netflix HTTP proxy service
        ns_port = select_unused_port()
        self.kodi_helper.set_setting('netflix_service_port', str(ns_port))
        self.kodi_helper.log(msg='[NS] Picked Port: ' + str(ns_port))

        # server defaults
        TCPServer.allow_reuse_address = True

        # configure the MSL Server
        self.msl_server = TCPServer(('127.0.0.1', msl_port),
                                    MSLHttpRequestHandler)
        self.msl_server.server_activate()
        self.msl_server.timeout = 1

        # configure the Netflix Data Server
        self.ns_server = TCPServer(('127.0.0.1', ns_port),
                                   NetflixHttpRequestHandler)
        self.ns_server.server_activate()
        self.ns_server.timeout = 1

    def _start_servers(self):
        # start thread for MLS servie
        msl_thread = threading.Thread(target=self.msl_server.serve_forever)
        msl_thread.daemon = True
        msl_thread.start()

        # start thread for Netflix HTTP service
        ns_thread = threading.Thread(target=self.ns_server.serve_forever)
        ns_thread.daemon = True
        ns_thread.start()

    def _shutdown(self):
        # MSL service shutdown sequence
        self.msl_server.server_close()
        self.msl_server.socket.close()
        self.msl_server.shutdown()
        self.kodi_helper.log(msg='Stopped MSL Service')

        # Netflix service shutdown sequence
        self.ns_server.server_close()
        self.ns_server.socket.close()
        self.ns_server.shutdown()
        self.kodi_helper.log(msg='Stopped HTTP Service')

    def _is_idle(self):
        if self.kodi_helper.get_setting('wait_idle') != 'true':
            return True

        lastidle = xbmc.getGlobalIdleTime()
        if xbmc.Player().isPlaying():
            self.startidle = lastidle
        if lastidle < self.startidle:
            self.startidle = 0
        idletime = lastidle - self.startidle
        return idletime >= 300

    def _update_running(self):
        update = self.kodi_helper.get_setting('update_running') or 'false'
        if update != 'false':
            starttime = strp(update, '%Y-%m-%d %H:%M')
            if (starttime + timedelta(hours=6)) <= datetime.now():
                self.kodi_helper.set_setting('update_running', 'false')
                self.kodi_helper.log(
                    'Canceling previous library update - duration > 6 hours',
                    xbmc.LOGWARNING)
            else:
                self.kodi_helper.log('DB Update already running')
                return True
        return False

    def run(self):
        """
        Main loop. Runs until xbmc.Monitor requests abort
        """
        self._start_servers()
        monitor = xbmc.Monitor()
        while not monitor.abortRequested():
            try:
                if self.library_update_scheduled() and self._is_idle():
                    self.update_library()
            except RuntimeError as exc:
                self.kodi_helper.log('RuntimeError: {}'.format(exc),
                                     xbmc.LOGERROR)
            if monitor.waitForAbort(5):
                break
        self._shutdown()

    def library_update_scheduled(self):
        """
        Checks if the scheduled time for a library update has been reached
        """
        now = datetime.now()
        next_schedule_check = (self.last_schedule_check +
                               timedelta(minutes=self.schedule_check_interval))

        if not self.freq or now <= next_schedule_check:
            self.kodi_helper.log('Auto-update disabled or schedule check '
                                 'interval not complete yet ({} / {}).'.format(
                                     now, next_schedule_check))
            return False

        self.last_schedule_check = now
        time = self.kodi_helper.get_setting('update_time') or '00:00'
        lastrun_date = (self.kodi_helper.get_setting('last_update')
                        or '1970-01-01')

        lastrun_full = lastrun_date + ' ' + time[0:5]
        lastrun = strp(lastrun_full, '%Y-%m-%d %H:%M')
        freqdays = [0, 1, 2, 5, 7][self.freq]
        nextrun = lastrun + timedelta(days=freqdays)

        self.kodi_helper.log(
            'It\'s currently {}, next run is scheduled for {}'.format(
                now, nextrun))

        return now >= nextrun

    def update_library(self):
        """
        Triggers an update of the local Kodi library
        """
        if not self._update_running():
            self.kodi_helper.log('Triggering library update', xbmc.LOGNOTICE)
            xbmc.executebuiltin(
                ('XBMC.RunPlugin(plugin://{}/?action=export-new-episodes'
                 '&inbackground=True)').format(
                     self.kodi_helper.get_addon().getAddonInfo('id')))
Exemplo n.º 2
0
from resources.lib.NetflixHttpRequestHandler import NetflixHttpRequestHandler

# helper function to select an unused port on the host machine
def select_unused_port():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('127.0.0.1', 0))
    addr, port = sock.getsockname()
    sock.close()
    return port

kodi_helper = KodiHelper()

# pick & store a port for the MSL service
msl_port = select_unused_port()
kodi_helper.set_setting('msl_service_port', str(msl_port))
kodi_helper.log(msg='[MSL] Picked Port: ' + str(msl_port))

# pick & store a port for the internal Netflix HTTP proxy service
ns_port = select_unused_port()
kodi_helper.set_setting('netflix_service_port', str(ns_port))
kodi_helper.log(msg='[NS] Picked Port: ' + str(ns_port))

# server defaults
SocketServer.TCPServer.allow_reuse_address = True

# configure the MSL Server
msl_server = SocketServer.TCPServer(('127.0.0.1', msl_port), MSLHttpRequestHandler)
msl_server.server_activate()
msl_server.timeout = 1

# configure the Netflix Data Server
Exemplo n.º 3
0
from resources.lib.Navigation import Navigation
from resources.lib.Library import Library

# Setup plugin
plugin_handle = int(sys.argv[1])
base_url = sys.argv[0]

# init plugin libs
kodi_helper = KodiHelper(
    plugin_handle=plugin_handle,
    base_url=base_url
)
library = Library(
    root_folder=kodi_helper.base_data_path,
    library_settings=kodi_helper.get_custom_library_settings(),
    log_fn=kodi_helper.log
)
navigation = Navigation(
    kodi_helper=kodi_helper,
    library=library,
    base_url=base_url,
    log_fn=kodi_helper.log
)
kodi_helper.set_library(library=library)

if __name__ == '__main__':
    # Call the router function and pass the plugin call parameters to it.
    # We use string slicing to trim the leading '?' from the plugin call paramstring
    kodi_helper.log('Started (Version ' + kodi_helper.version + ')')
    navigation.router(paramstring=sys.argv[2][1:])
Exemplo n.º 4
0
# Created on: 13.01.2017
# License: MIT https://goo.gl/5bMj3H
"""Kodi plugin for Netflix (https://netflix.com)"""

import sys
from resources.lib.KodiHelper import KodiHelper
from resources.lib.Navigation import Navigation
from resources.lib.Library import Library

# Setup plugin
PLUGIN_HANDLE = int(sys.argv[1])
BASE_URL = sys.argv[0]
# We use string slicing to trim the leading ? from the plugin call paramstring
REQUEST_PARAMS = sys.argv[2][1:]

# init plugin libs
KODI_HELPER = KodiHelper(plugin_handle=PLUGIN_HANDLE, base_url=BASE_URL)
LIBRARY = Library(root_folder=KODI_HELPER.base_data_path,
                  library_settings=KODI_HELPER.get_custom_library_settings(),
                  log_fn=KODI_HELPER.log)
NAVIGATION = Navigation(kodi_helper=KODI_HELPER,
                        library=LIBRARY,
                        base_url=BASE_URL,
                        log_fn=KODI_HELPER.log)
KODI_HELPER.set_library(library=LIBRARY)

if __name__ == '__main__':
    # Call the router function and pass the plugin call parameters to it.
    KODI_HELPER.log('Started (Version ' + KODI_HELPER.version + ')')
    NAVIGATION.router(paramstring=REQUEST_PARAMS)
Exemplo n.º 5
0
    :return: int - Free port
    """
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('127.0.0.1', 0))
    _, port = sock.getsockname()
    sock.close()
    return port


# init kodi helper (for logging)
KODI_HELPER = KodiHelper()

# pick & store a port for the MSL service
MSL_PORT = select_unused_port()
KODI_HELPER.set_setting('msl_service_port', str(MSL_PORT))
KODI_HELPER.log(msg='[MSL] Picked Port: ' + str(MSL_PORT))

# pick & store a port for the internal Netflix HTTP proxy service
NS_PORT = select_unused_port()
KODI_HELPER.set_setting('netflix_service_port', str(NS_PORT))
KODI_HELPER.log(msg='[NS] Picked Port: ' + str(NS_PORT))

# server defaults
TCPServer.allow_reuse_address = True

# configure the MSL Server
MSL_SERVER = TCPServer(('127.0.0.1', MSL_PORT), MSLHttpRequestHandler)
MSL_SERVER.server_activate()
MSL_SERVER.timeout = 1

# configure the Netflix Data Server