示例#1
0
    def check_inputstream_addon():

        try:
            addon_enabled = control.addon_details('inputstream.adaptive').get('enabled')
        except KeyError:
            addon_enabled = False

        leia_plus = control.kodi_version() >= 18.0

        first_time_file = control.join(control.dataPath, 'first_time')

        if not addon_enabled and not file_exists(first_time_file) and leia_plus:

            try:

                yes = control.yesnoDialog(control.lang(30014))

                if yes:
                    control.enable_addon('inputstream.adaptive')
                    control.infoDialog(control.lang(30402))

                with open(first_time_file, 'a'):
                    pass

            except Exception:

                pass
示例#2
0
    def play(self, url, query=None, resolved_mode=True):

        if url in [self.live_link_cy, self.live_link_gr]:

            title = 'Alpha'
            icon = control.icon()

        elif query:

            title = query
            icon = control.addonmedia('news.png')

        else:

            title = None
            icon = None

        stream = self.resolve(url)
        meta = {'title': title}
        dash = 'm3u8' in stream and control.kodi_version() >= 18.0

        directory.resolve(
            url=stream, meta=meta, dash=dash, icon=icon,
            mimetype='application/vnd.apple.mpegurl' if '.m3u8' in stream else None,
            manifest_type='hls' if '.m3u8' in stream else None, resolved_mode=resolved_mode
        )
示例#3
0
def play(url):

    try:
        addon_enabled = control.addon_details('inputstream.adaptive').get(
            'enabled')
    except KeyError:
        addon_enabled = False

    mimetype = None
    manifest_type = None

    leia_plus = control.kodi_version() >= 18.0

    stream = resolve(url)

    if '.m3u8' in stream:

        manifest_type = 'hls'
        mimetype = 'application/vnd.apple.mpegurl'

    elif '.mpd' in stream:

        manifest_type = 'mpd'

    dash = addon_enabled and ('.m3u8' in stream or '.mpd' in stream)

    directory.resolve(stream,
                      dash=dash and leia_plus,
                      mimetype=mimetype,
                      manifest_type=manifest_type)
示例#4
0
    def install():

        if control.conditional_visibility('System.Platform.Linux') and not (
                path.exists(control.transPath(xbmc_path))
                or path.exists(control.transPath(home_path))):

            control.okDialog(heading='AliveGR', line1=control.lang(30323))

            return False

        elif path.exists(control.transPath(xbmc_path)) or path.exists(
                control.transPath(home_path)):

            return True

        elif control.kodi_version() >= 18.0 and not control.condVisibility(
                'System.HasAddon(pvr.iptvsimple)'):

            control.execute('InstallAddon(pvr.iptvsimple)')

            return True

        elif control.condVisibility('System.HasAddon(pvr.iptvsimple)'):

            return 'enabled'

        else:

            return False
示例#5
0
        def set_controls(self):

            # Username label
            self.username_label = pyxbmct.Label(control.lang(30152))
            self.placeControl(self.username_label, 0, 0)
            # Username input
            self.user_input = pyxbmct.Edit(control.lang(30152))
            self.placeControl(self.user_input, 1, 0)
            # Password label
            self.password_label = pyxbmct.Label(control.lang(30153))
            self.placeControl(self.password_label, 2, 0)
            # Password input
            if control.kodi_version() >= 18.0:
                self.pass_input = pyxbmct.Edit(control.lang(30153))
                self.placeControl(self.pass_input, 3, 0)
                self.pass_input.setType(6, control.lang(30153))
            else:
                self.pass_input = pyxbmct.Edit(control.lang(30153),
                                               isPassword=True)
                self.placeControl(self.pass_input, 3, 0)
            # Submit button
            self.submit_button = pyxbmct.Button(control.lang(30154))
            self.placeControl(self.submit_button, 4, 0)
            self.connect(self.submit_button, lambda: self.submit(True))
            # Cancel button
            self.cancel_button = pyxbmct.Button(control.lang(30064))
            self.placeControl(self.cancel_button, 5, 0)
            self.connect(self.cancel_button, self.close)
    def stations(self):

        self.list = self.get_stations()

        if self.list is None:
            return

        self.list = sorted(self.list, key=lambda k: k['album'].lower())

        for item in self.list:

            refresh = {'title': 30015, 'query': {'action': 'refresh'}}
            cache_clear = {'title': 30002, 'query': {'action': 'cache_clear'}}
            info_cm = {'title': 30020, 'query': {'action': 'info_cm'}}
            station_info = {
                'title': 30016,
                'query': {
                    'action': 'description',
                    'text': item['comment']
                }
            }
            history = {
                'title': 30017,
                'query': {
                    'action': 'history',
                    'url': item['history']
                }
            }

            if control.kodi_version() < 17.0:
                item.update({
                    'cm': [refresh, cache_clear, history],
                    'action': 'play',
                    'isFolder': 'False'
                })
            else:
                item.update({
                    'cm':
                    [refresh, cache_clear, history, station_info, info_cm],
                    'action':
                    'play',
                    'isFolder':
                    'False'
                })

        for count, item in list(enumerate(self.list, start=1)):
            item.setdefault('tracknumber', count)

        control.sortmethods()
        control.sortmethods('album')
        control.sortmethods('genre')
        control.sortmethods('listeners')

        directory.add(self.list, infotype='music')
def play(url):

    if not any(['.m3u8' in url, '.mpd' in url, 'radiostreaming' in url]):
        url = resolve(url)

    dash = ('.m3u8' in url or '.mpd' in url) and control.kodi_version() >= 18.0

    directory.resolve(
        url,
        dash=dash,
        mimetype='application/vnd.apple.mpegurl' if 'm3u8' in url else None,
        manifest_type='hls' if 'm3u8' in url else None)
示例#8
0
def rtmp_enable():

    if control.kodi_version() < 17.0:

        control.infoDialog(control.lang(30322))
        return

    try:

        enabled = control.addon_details('inputstream.rtmp').get('enabled')

    except Exception:

        enabled = False

    try:

        if enabled:

            control.infoDialog(control.lang(30276))
            return

        else:

            xbmc_path = control.join('special://xbmc', 'addons',
                                     'inputstream.rtmp')
            home_path = control.join('special://home', 'addons',
                                     'inputstream.rtmp')

            if path.exists(control.transPath(xbmc_path)) or path.exists(
                    control.transPath(home_path)):

                yes = control.yesnoDialog(control.lang(30277))

                if yes:

                    control.enable_addon('inputstream.rtmp')
                    control.infoDialog(control.lang(30402))

            else:

                try:

                    control.execute('InstallAddon(inputstream.rtmp)')

                except Exception:

                    control.okDialog(heading='AliveGR',
                                     line1=control.lang(30323))

    except Exception:

        control.infoDialog(control.lang(30279))
示例#9
0
    def play(self, url):

        if control.setting('debug') == 'false':
            stream = cache.get(self.resolve, 96, url)
        else:
            stream = self.resolve(url)

        if stream is None:
            return

        m3u8_dash = 'm3u8' in stream and control.kodi_version() >= 18.0

        directory.resolve(
            stream, dash=any(['.mpd' in stream, m3u8_dash]),
            mimetype='application/vnd.apple.mpegurl' if m3u8_dash else None,
            manifest_type='hls' if m3u8_dash else None
        )
def play(url):

    if '.m3u8' not in url:
        url = resolve(url)

    dash = ('.m3u8' in url or '.mpd' in url) and control.kodi_version() >= 18.0

    meta = None

    if url == LIVE_LINK:
        meta = {'title': 'ANT1'}

    directory.resolve(
        url, dash=dash, meta=meta,
        mimetype='application/vnd.apple.mpegurl' if 'm3u8' in url else None,
        manifest_type='hls' if 'm3u8' in url else None
    )
示例#11
0
    def play(self, url):

        resolved = self.resolve(url)

        if 'youtu' in resolved:
            resolved = self.yt_session(resolved)

        if isinstance(resolved, tuple):

            stream, plot = resolved
            meta = {'plot': plot}

        else:

            stream = resolved
            meta = None

        icon = None

        if url == self.radio_link:

            meta = {'title': 'Skai Radio 100.3FM'}

        elif url == self.live_link:

            meta = {'title': 'Skai Live TV'}
            icon = control.icon()

        dash = ('dash' in stream or '.mpd' in stream
                or 'm3u8' in stream) and control.kodi_version() >= 18.0

        directory.resolve(url=stream,
                          meta=meta,
                          dash=dash,
                          icon=icon,
                          mimetype='application/vnd.apple.mpegurl'
                          if 'm3u8' in stream else None,
                          manifest_type='hls' if '.m3u8' in stream else None)
示例#12
0
    def play(self, url):

        if '.mp4' in url or '.m3u8' in url:

            stream = url

        else:

            html = client.request(url)

            stream = re.search("video/mp4.+?'(.+?)'", html, re.S).group(1)

        try:
            addon_enabled = control.addon_details('inputstream.adaptive').get('enabled')
        except KeyError:
            addon_enabled = False

        dash = '.m3u8' in url and control.kodi_version() >= 18.0 and addon_enabled and control.setting('hls_dash') == 'true'

        if dash:
            directory.resolve(stream, dash=dash, mimetype='application/vnd.apple.mpegurl', manifest_type='hls')
        else:
            directory.resolve(stream)
示例#13
0
    def play(self, url):

        resolved = self.resolve(url)

        if 'youtu' in resolved:
            resolved = self.yt_session(resolved)

        if isinstance(resolved, tuple):

            stream, plot = resolved
            meta = {'plot': plot}

        else:

            stream = resolved
            meta = None

        icon = None

        if url == self.live_link:

            icon = {
                'poster': control.icon(),
                'icon': control.icon(),
                'thumb': control.icon()
            }

        dash = ('dash' in stream or '.mpd' in stream
                or 'm3u8' in stream) and control.kodi_version() >= 18.0

        directory.resolve(url=stream,
                          meta=meta,
                          dash=dash,
                          icon=icon,
                          mimetype='application/vnd.apple.mpegurl'
                          if 'm3u8' in stream else None,
                          manifest_type='hls' if '.m3u8' in stream else None)
    def live(self):

        lang = 'www' if self.lang == 'en' else self.lang

        stream = self.resolve_live(lang=lang)

        if control.setting(
                'quality_live') == '2' and control.kodi_version() >= 18.0:

            dash = True
            manifest_type = 'hls'
            mimetype = 'application/vnd.apple.mpegurl'

        else:

            dash = False
            manifest_type = None
            mimetype = None

        directory.resolve(stream,
                          meta={'title': 'Euronews'},
                          dash=dash,
                          manifest_type=manifest_type,
                          mimetype=mimetype)
def resolve(url,
            meta=None,
            icon=None,
            dash=False,
            manifest_type=None,
            inputstream_type='adaptive',
            headers=None,
            mimetype=None,
            resolved_mode=True,
            live=False,
            verify=True):
    """
    Prepares a resolved url into a listitem for playback

    :param url: Requires a string or unicode, append required urlencoded headers with pipe |
    :param meta: a dictionary with listitem keys: values
    :param icon: String
    :param dash: Boolean
    :param manifest_type: String
    :param inputstream_type: String 99.9% of the time it is adaptive
    :param headers: dictionary or urlencoded string
    :param mimetype: String
    :return: None
    """

    from tulip.init import syshandle

    # Fail gracefully instead of making Kodi complain.
    if not url:
        from kodi_six.xbmc import log
        log('URL was not provided, failure to resolve stream')
        return

    if not headers and '|' in url:
        url, sep, headers = url.rpartition('|')
    elif headers:
        if isinstance(headers, basestring):
            if headers.startswith('|'):
                headers = headers[1:]
        elif isinstance(headers, dict):
            headers = urlencode(headers)

    if not verify and 'verifypeer' not in headers:

        if headers:
            headers += '&verifypeer=false'
        else:
            headers = 'verifypeer=false'

    if not dash and headers:
        url = '|'.join([url, headers])

    item = control.item(path=url)

    if icon is not None:
        item.setArt({'icon': icon, 'thumb': icon})

    if meta is not None:
        item.setInfo(type='Video', infoLabels=meta)

    krypton_plus = control.kodi_version() >= 17.0

    try:
        isa_enabled = control.addon_details('inputstream.adaptive').get(
            'enabled')
    except KeyError:
        isa_enabled = False

    if dash and krypton_plus and isa_enabled:

        if not manifest_type:

            manifest_type = 'mpd'

        if not mimetype:

            mimetype = 'application/xml+dash'

        item.setContentLookup(False)
        item.setMimeType('{0}'.format(mimetype))
        item.setProperty('inputstreamaddon',
                         'inputstream.{}'.format(inputstream_type))
        item.setProperty(
            'inputstream.{0}.manifest_type'.format(inputstream_type),
            manifest_type)

        if headers:

            item.setProperty(
                "inputstream.{0}.stream_headers".format(inputstream_type),
                headers)

    elif mimetype:

        item.setContentLookup(False)
        item.setMimeType('{0}'.format(mimetype))

    if dash and live:
        item.setProperty(
            'inputstream.{}.manifest_update_parameter'.format(
                inputstream_type), '&start_seq=$START_NUMBER$')

    if resolved_mode:
        control.resolve(syshandle, True, item)
    else:
        control.player().play(url, item)
示例#16
0
    def run(self, query=None):

        if 'Greek' not in str(self.langs).split(','):

            control.directory(self.syshandle)
            control.infoDialog(control.lang(30002))

            return

        if not control.conditional_visibility(
                'System.HasAddon(script.module.futures)') and is_py2:

            if 17.0 <= control.kodi_version() <= 18.9:
                control.execute('InstallAddon(script.module.futures)')
                control.sleep(1500)

            elif 16.0 <= control.kodi_version() <= 16.2:
                control.okDialog('Subtitles.gr', control.lang(30229))
                return

        dup_removal = False

        if not query:

            with concurrent.futures.ThreadPoolExecutor(5) as executor:

                if control.condVisibility('Player.HasVideo'):
                    infolabel_prefix = 'VideoPlayer'
                else:
                    infolabel_prefix = 'ListItem'

                title = control.infoLabel('{0}.Title'.format(infolabel_prefix))

                if re.search(r'[^\x00-\x7F]+', title) is not None:

                    title = control.infoLabel(
                        '{0}.OriginalTitle'.format(infolabel_prefix))

                title = unicodedata.normalize('NFKD',
                                              title).encode('ascii', 'ignore')
                title = py3_dec(title)
                year = control.infoLabel('{0}.Year'.format(infolabel_prefix))
                tvshowtitle = control.infoLabel(
                    '{0}.TVshowtitle'.format(infolabel_prefix))
                season = control.infoLabel(
                    '{0}.Season'.format(infolabel_prefix))

                if len(season) == 1:

                    season = '0' + season

                episode = control.infoLabel(
                    '{0}.Episode'.format(infolabel_prefix))

                if len(episode) == 1:
                    episode = '0' + episode

                if 's' in episode.lower():
                    season, episode = '0', episode[-1:]

                if tvshowtitle != '':  # episode

                    title_query = '{0} {1}'.format(tvshowtitle, title)
                    season_episode_query = '{0} S{1} E{2}'.format(
                        tvshowtitle, season, episode)
                    season_episode_query_nospace = '{0} S{1}E{2}'.format(
                        tvshowtitle, season, episode)

                    threads = [
                        executor.submit(self.subtitlesgr,
                                        season_episode_query_nospace),
                        executor.submit(self.xsubstv, season_episode_query),
                        executor.submit(self.podnapisi, season_episode_query),
                        executor.submit(self.vipsubs, season_episode_query)
                    ]

                    dup_removal = True

                    log_debug('Dual query used for subtitles search: ' +
                              title_query + ' / ' + season_episode_query)

                    if control.setting('queries') == 'true':

                        threads.extend([
                            executor.submit(self.subtitlesgr, title_query),
                            executor.submit(self.vipsubs, title_query),
                            executor.submit(self.podnapisi, title_query),
                            executor.submit(self.subtitlesgr,
                                            season_episode_query)
                        ])

                elif year != '':  # movie

                    query = '{0} ({1})'.format(title, year)

                    threads = [
                        executor.submit(self.subtitlesgr, query),
                        executor.submit(self.xsubstv, query),
                        executor.submit(self.vipsubs, query),
                        executor.submit(self.podnapisi, query)
                    ]

                else:  # file

                    query, year = control.cleanmovietitle(title)

                    if year != '':

                        query = '{0} ({1})'.format(query, year)

                    threads = [
                        executor.submit(self.subtitlesgr, query),
                        executor.submit(self.xsubstv, query),
                        executor.submit(self.vipsubs, query),
                        executor.submit(self.podnapisi, query)
                    ]

                for future in concurrent.futures.as_completed(threads):

                    item = future.result()

                    if not item:
                        continue

                    self.list.extend(item)

                if not dup_removal:

                    log_debug('Query used for subtitles search: ' + query)

                self.query = query

                self.query = py3_dec(self.query)

        else:

            with concurrent.futures.ThreadPoolExecutor(5) as executor:

                query = py3_dec(query)

                threads = [
                    executor.submit(self.subtitlesgr, query),
                    executor.submit(self.xsubstv, query),
                    executor.submit(self.vipsubs, query),
                    executor.submit(self.podnapisi, query)
                ]

                for future in concurrent.futures.as_completed(threads):

                    item = future.result()

                    if not item:
                        continue

                    self.list.extend(item)

        if len(self.list) == 0:

            control.directory(self.syshandle)

            return

        f = []

        # noinspection PyUnresolvedReferences
        f += [i for i in self.list if i['source'] == 'xsubstv']
        f += [i for i in self.list if i['source'] == 'subtitlesgr']
        f += [i for i in self.list if i['source'] == 'podnapisi']
        f += [i for i in self.list if i['source'] == 'vipsubs']

        self.list = f

        if dup_removal:

            self.list = [
                dict(t) for t in {tuple(d.items())
                                  for d in self.list}
            ]

        for i in self.list:

            try:

                if i['source'] == 'xsubstv':
                    i['name'] = u'[xsubstv] {0}'.format(i['name'])
                elif i['source'] == 'podnapisi':
                    i['name'] = u'[podnapisi] {0}'.format(i['name'])
                elif i['source'] == 'vipsubs':
                    i['name'] = u'[vipsubs] {0}'.format(i['name'])

            except Exception:

                pass

        if control.setting('sorting') == '1':
            key = 'source'
        elif control.setting('sorting') == '2':
            key = 'downloads'
        elif control.setting('sorting') == '3':
            key = 'rating'
        else:
            key = 'title'

        self.list = sorted(self.list,
                           key=lambda k: k[key].lower(),
                           reverse=control.setting('sorting')
                           in ['1', '2', '3'])

        for i in self.list:

            u = {'action': 'download', 'url': i['url'], 'source': i['source']}
            u = '{0}?{1}'.format(self.sysaddon, urlencode(u))

            item = control.item(label='Greek', label2=i['name'])
            item.setArt({'icon': str(i['rating'])[:1], 'thumb': 'el'})
            item.setProperty('sync', 'false')
            item.setProperty('hearing_imp', 'false')

            control.addItem(handle=self.syshandle,
                            url=u,
                            listitem=item,
                            isFolder=False)

        control.directory(self.syshandle)
示例#17
0
    def info(self):

        separator = '[CR]' if control.setting('wrap_labels') == '0' else ' '

        try:
            disclaimer = control.addonInfo('disclaimer').decode('utf-8')
        except (UnicodeEncodeError, UnicodeDecodeError, AttributeError):
            disclaimer = control.addonInfo('disclaimer')

        self.list = [
            {
                'title': control.lang(30331),
                'action': 'welcome',
                'icon': control.addonInfo('icon'),
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30105),
                'action': 'dmca',
                'plot': disclaimer,
                'icon': control.addonmedia(
                    addonid=ART_ID, theme='icons', icon='dmca.png', media_subfolder=False
                ),
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30290),
                'action': 'pp',
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30295),
                'action': 'toggle_debug',
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30341),
                'action': 'kodi_log_upload',
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30296),
                'action': 'force',
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30260).format(separator),
                'action': 'open_link',
                'url': SUPPORT,
                'plot': 'Git repo',
                'icon': control.addonmedia(
                    addonid=ART_ID, theme='icons', icon='bitbucket.png', media_subfolder=False
                ),
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30141) + ': [COLOR cyan]' + PAYPAL + '[/COLOR]',
                'action': 'open_link',
                'url': PAYPAL,
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30142) + ': [COLOR cyan]' + PATREON + '[/COLOR]',
                'action': 'open_link',
                'url': PATREON,
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30256).format(separator, control.addonInfo('version')),
                'action': 'force',
                'plot': control.lang(30265),
                'icon': control.addonInfo('icon'),
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            ,
            {
                'title': control.lang(30257).format(separator, control.addon('script.module.tulip').getAddonInfo('version')),
                'action': 'force',
                'plot': control.lang(30265),
                'icon': control.addon('script.module.tulip').getAddonInfo('icon'),
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            # ,
            # {
            #     'title': control.lang(30294).format(separator, control.addon('script.module.streamlink.base').getAddonInfo('version')),
            #     'action': 'force',
            #     'image': control.addon('script.module.streamlink.base').getAddonInfo('icon'),
            #     'plot': control.lang(30265),
            #     'isFolder': 'False',
            #     'isPlayable': 'False'
            # }
            ,
            {
                'title': control.lang(30258).format(separator, control.kodi_version()),
                'action': 'system_info',
                'plot': control.lang(30263),
                'icon': control.addonmedia(addonid=ART_ID, theme='icons', icon='kodi.png', media_subfolder=False),
                'isFolder': 'False',
                'isPlayable': 'False'
            }
        ]

        try:

            rurl_enabled = control.addon_details('script.module.resolveurl').get('enabled')

        except Exception:

            rurl_enabled = False

        if rurl_enabled:

            resolveurl = {

                'title': control.lang(30264).format(separator, control.addon('script.module.resolveurl').getAddonInfo('version')),
                'action': 'other_addon_settings',
                'query': 'script.module.resolveurl',
                'plot': control.lang(30265),
                'icon': control.addon('script.module.resolveurl').getAddonInfo('icon'),
                'isFolder': 'False',
                'isPlayable': 'False'

            }

            self.list.insert(-2, resolveurl)

        directory.add(self.list, content='movies')
示例#18
0
    def info(self):

        separator = '[CR]' if control.setting('wrap_labels') == '0' else ' '

        try:
            disclaimer = control.addonInfo('disclaimer').decode('utf-8')
        except (UnicodeEncodeError, UnicodeDecodeError, AttributeError):
            disclaimer = control.addonInfo('disclaimer')

        self.list = [
            {
                'title': control.lang(30331),
                'action': 'welcome',
                'icon': control.addonInfo('icon'),
                'isFolder': 'False',
                'isPlayable': 'False'
            },
            {
                'title':
                control.lang(30105),
                'action':
                'dmca',
                'plot':
                disclaimer,
                'icon':
                control.addonmedia(addonid=ART_ID,
                                   theme='icons',
                                   icon='dmca.png',
                                   media_subfolder=False),
                'isFolder':
                'False',
                'isPlayable':
                'False'
            },
            {
                'title': control.lang(30290),
                'action': 'pp',
                'isFolder': 'False',
                'isPlayable': 'False'
            },
            {
                'title': '[B]' + control.lang(30110) + '[/B]',
                'action': 'changelog',
                'icon': control.addonInfo('icon'),
                'plot': changelog(get_text=True),
                'isFolder': 'False',
                'isPlayable': 'False'
            },
            {
                'title': control.lang(30295),
                'action': 'toggle_debug',
                'isFolder': 'False',
                'isPlayable': 'False'
            },
            {
                'title': control.lang(30341),
                'action': 'kodi_log_upload',
                'isFolder': 'False',
                'isPlayable': 'False'
            },
            {
                'title': control.lang(30296),
                'action': 'force',
                'isFolder': 'False',
                'isPlayable': 'False'
            },
            {
                'title':
                control.lang(30260).format(separator),
                'action':
                'open_link',
                'url':
                SUPPORT,
                'plot':
                'Git repo',
                'icon':
                control.addonmedia(addonid=ART_ID,
                                   theme='icons',
                                   icon='bitbucket.png',
                                   media_subfolder=False),
                'isFolder':
                'False',
                'isPlayable':
                'False'
            },
            {
                'title':
                control.lang(30141) + ': [COLOR cyan]' + PAYPAL + '[/COLOR]',
                'action': 'open_link',
                'url': PAYPAL,
                'isFolder': 'False',
                'isPlayable': 'False'
            }
            # ,
            # {
            #     'title': control.lang(30142) + ': [COLOR cyan]' + PATREON + '[/COLOR]',
            #     'action': 'open_link',
            #     'url': PATREON,
            #     'isFolder': 'False',
            #     'isPlayable': 'False'
            # }
            ,
            {
                'title':
                control.lang(30256).format(separator,
                                           control.addonInfo('version')),
                'action':
                'force',
                'plot':
                control.lang(30265),
                'icon':
                control.addonInfo('icon'),
                'isFolder':
                'False',
                'isPlayable':
                'False'
            },
            {
                'title':
                control.lang(30257).format(
                    separator,
                    control.addon('script.module.tulip').getAddonInfo(
                        'version')),
                'action':
                'force',
                'plot':
                control.lang(30265),
                'icon':
                control.addon('script.module.tulip').getAddonInfo('icon'),
                'isFolder':
                'False',
                'isPlayable':
                'False'
            },
            {
                'title':
                control.lang(30264).format(
                    separator,
                    control.addon('script.module.resolveurl').getAddonInfo(
                        'version')),
                'action':
                'other_addon_settings',
                'query':
                'script.module.resolveurl',
                'plot':
                control.lang(30265),
                'icon':
                control.addon('script.module.resolveurl').getAddonInfo('icon'),
                'isFolder':
                'False',
                'isPlayable':
                'False'
            },
            {
                'title':
                control.lang(30258).format(separator, control.kodi_version()),
                'action':
                'system_info',
                'plot':
                control.lang(30263),
                'icon':
                control.addonmedia(addonid=ART_ID,
                                   theme='icons',
                                   icon='kodi.png',
                                   media_subfolder=False),
                'isFolder':
                'False',
                'isPlayable':
                'False'
            },
            {
                'title':
                control.lang(30303).format(
                    separator, '.'.join([
                        str(sys.version_info[0]),
                        str(sys.version_info[1]),
                        str(sys.version_info[2])
                    ])),
                'action':
                'system_info',
                'plot':
                control.lang(30263),
                'image':
                'https://www.python.org/static/opengraph-icon-200x200.png',
                'isFolder':
                'False',
                'isPlayable':
                'False'
            }
        ]

        directory.add(self.list, content='movies')