def migrate_from_pickled_fav():
    """
    This function moves existing pickled favourites in
    the new json file used for the favourites.
    The new format (json) appeared in 0.2.17~beta04
    All user with version >= 0.2.17 will use favourites in the JSON format
    Maybe we can remove the migration check on version 0.2.20?
    """

    # Move all pickled existing favs in json file
    fav_pickle_fp = os.path.join(Script.get_info('profile'), "favourites.pickle")
    if xbmcvfs.exists(fav_pickle_fp):
        Script.log('Start favourites migration from pickle file to json file')
        new_fav_dict = {}
        with storage.PersistentDict("favourites.pickle") as db:
            new_fav_dict = dict(db)
        # Fix old fav
        for item_hash, item_dict in new_fav_dict.items():
            if 'params' in item_dict and isinstance(item_dict['params'], listing.Params):
                new_fav_dict[item_hash]['params'] = dict(new_fav_dict[item_hash]['params'])
                try:
                    del new_fav_dict[item_hash]['params']['item_dict']['params']
                except Exception:
                    pass
            if 'properties' in item_dict:
                if isinstance(item_dict['properties'], listing.Property):
                    new_fav_dict[item_hash]['properties'] = dict(new_fav_dict[item_hash]['properties'])
        fav_json_fp = os.path.join(Script.get_info('profile'), "favourites.json")
        with open(fav_json_fp, 'w') as f:
            json.dump(new_fav_dict, f, indent=4)
        xbmcvfs.delete(fav_pickle_fp)
def grab_tv_guide(menu_id, menu):
    xmltv_url = get_xmltv_url(menu_id)
    Script.log('xmltv url of {}: {}'.format(menu_id, xmltv_url))

    xmltv_fn = os.path.basename(urlparse(xmltv_url).path)
    Script.log('xmltv filename of {}: {}'.format(menu_id, xmltv_fn))

    xmltv_fp = os.path.join(Script.get_info('profile'), xmltv_fn)

    # Remove old xmltv files of this country
    dirs, files = xbmcvfs.listdir(Script.get_info('profile'))
    for fn in files:
        if xmltv_infos[menu_id]['keyword'] in fn and fn != xmltv_fn:
            Script.log('Remove old xmltv file: {}'.format(fn))
            xbmcvfs.delete(os.path.join(Script.get_info('profile'), fn))

    # Check if we need to download a fresh xmltv file
    if not xbmcvfs.exists(xmltv_fp):
        Script.log("xmltv file of {} for today does not exist, let's download it".format(menu_id))
        r = urlquick.get(xmltv_url)
        with open(xmltv_fp, 'wb') as f:
            f.write(r.content)

    # Grab programmes in xmltv file
    programmes = read_current_programmes(xmltv_fp)

    # Use the channel as key
    tv_guide = {}
    for programme in programmes:
        programme = programme_post_treatment(programme)
        tv_guide[programme['channel']] = programme

    return tv_guide
Esempio n. 3
0
def download_xmltv_file(country_id, day_delta=0):
    """Try to download XMLTV file of country_id for today + day_delta.

    Args:
        country_id (str)
        day_delta (int): 0: Today, 1: Tomorrow,...
    Returns:
        str: xmltv filepath.
    """
    # Retrieve URL
    xmltv_url = get_xmltv_url(country_id, day_delta=day_delta)
    Script.log('xmltv url of {} country with day_delta {}: {}'.format(
        country_id, day_delta, xmltv_url))

    # Compute dst filepath
    xmltv_fn = os.path.basename(urlparse(xmltv_url).path)
    Script.log('xmltv filename: {}'.format(xmltv_fn))
    xmltv_fp = os.path.join(Script.get_info('profile'), xmltv_fn)

    # Remove old xmltv files of this country
    dirs, files = xbmcvfs.listdir(Script.get_info('profile'))
    today = datetime.date.today()
    for fn in files:
        if xmltv_infos[country_id]['keyword'] not in fn:
            continue
        try:
            file_date_s = fn.split(
                xmltv_infos[country_id]['keyword'])[1].split('.xml')[0]
            file_date = datetime_strptime(file_date_s, '%Y%m%d').date()
            if file_date < today:
                Script.log('Remove old xmltv file: {}'.format(fn))
                xbmcvfs.delete(os.path.join(Script.get_info('profile'), fn))
        except Exception:
            pass

    # Check if we need to download a fresh xmltv file
    need_to_downlod_xmltv_file = False
    if not xbmcvfs.exists(xmltv_fp):
        Script.log(
            "xmltv file of {} for today does not exist, let's download it".
            format(country_id))
        need_to_downlod_xmltv_file = True
    else:
        # Check if we have the last version of the file
        current_file_md5 = compute_md5(xmltv_fp)
        remote_file_md5 = get_remote_xmltv_md5(country_id, day_delta=day_delta)
        print(current_file_md5)
        print(remote_file_md5)
        if current_file_md5 != remote_file_md5:
            Script.log(
                "A new version of xmltv file of {} for today exists, let's download it"
                .format(country_id))
            need_to_downlod_xmltv_file = True

    if need_to_downlod_xmltv_file:
        r = urlquick.get(xmltv_url, max_age=-1)
        with open(xmltv_fp, 'wb') as f:
            f.write(r.content)
    return xmltv_fp
Esempio n. 4
0
def delete_favourites(plugin):
    """Callback function of 'Delete favourites' setting button

    Args:
        plugin (codequick.script.Script)
    """

    Script.log('Delete favourites db')
    xbmcvfs.delete(
        os.path.join(Script.get_info('profile'), 'favourites.pickle'))
    xbmcvfs.delete(os.path.join(Script.get_info('profile'), 'favourites.json'))
    Script.notify(Script.localize(30374), '')
def clear_cache(plugin):
    # Callback function of clear cache setting button

    # Clear urlquick cache
    urlquick.cache_cleanup(-1)
    Script.notify(plugin.localize(30371), '')

    # Remove all tv guides
    dirs, files = xbmcvfs.listdir(Script.get_info('profile'))
    for fn in files:
        if '.xml' in fn and fn != 'settings.xml':
            Script.log('Remove xmltv file: {}'.format(fn))
            xbmcvfs.delete(os.path.join(Script.get_info('profile'), fn))
Esempio n. 6
0
def check_addon(addonid, minVersion=False):
    """Checks if selected add-on is installed."""
    try:
        curVersion = Script.get_info("version", addonid)
        if minVersion and LooseVersion(curVersion) < LooseVersion(minVersion):
            Script.log(
                '{addon} {curVersion} doesn\'t setisfy required version {minVersion}.'
                .format(addon=addonid,
                        curVersion=curVersion,
                        minVersion=minVersion))
            Dialog().ok(
                "Error",
                "{minVersion} version of {addon} is required to play this content."
                .format(addon=addonid, minVersion=minVersion))
            return False
        return True
    except RuntimeError:
        Script.log('{addon} is not installed.'.format(addon=addonid))
        if not _install_addon(addonid):
            # inputstream is missing on system
            Dialog().ok(
                "Error",
                "[B]{addon}[/B] is missing on your Kodi install. This add-on is required to play this content."
                .format(addon=addonid))
            return False
        return True
Esempio n. 7
0
def grab_tv_guide(menu_id):
    try:
        xmltv_url = get_xmltv_url(menu_id)
        Script.log('xmltv url of {}: {}'.format(menu_id, xmltv_url))

        xmltv_fn = os.path.basename(urlparse(xmltv_url).path)
        Script.log('xmltv filename of {}: {}'.format(menu_id, xmltv_fn))

        xmltv_fp = os.path.join(Script.get_info('profile'), xmltv_fn)

        # Remove old xmltv files of this country
        dirs, files = xbmcvfs.listdir(Script.get_info('profile'))
        for fn in files:
            if xmltv_infos[menu_id]['keyword'] in fn and fn != xmltv_fn:
                Script.log('Remove old xmltv file: {}'.format(fn))
                xbmcvfs.delete(os.path.join(Script.get_info('profile'), fn))

        # Check if we need to download a fresh xmltv file
        if not xbmcvfs.exists(xmltv_fp):
            Script.log(
                "xmltv file of {} for today does not exist, let's download it".
                format(menu_id))
            r = urlquick.get(xmltv_url)
            with open(xmltv_fp, 'wb') as f:
                f.write(r.content)

        # Grab programmes in xmltv file
        programmes = read_current_programmes(xmltv_fp)

        # Use the channel as key
        tv_guide = {}
        for programme in programmes:
            programme = programme_post_treatment(programme)
            tv_guide[programme['channel']] = programme

        return tv_guide
    except Exception as e:
        Script.notify(Script.localize(LABELS['TV guide']),
                      Script.localize(
                          LABELS['An error occurred while getting TV guide']),
                      display_time=7000)
        Script.log('xmltv module failed with error: {}'.format(
            e, lvl=Script.ERROR))
        return {}
Esempio n. 8
0
def _install_addon(addonid):
    """Install addon."""
    try:
        # See if there's an installed repo that has it
        executebuiltin('InstallAddon({})'.format(addonid), wait=True)

        # Check if add-on exists!
        version = Script.get_info("version", addonid)

        Script.log('{addon} {version} add-on installed from repo.'.format(
            addon=addonid, version=version))
        return True
    except RuntimeError:
        Script.log('{addon} add-on not installed.'.format(addon=addonid))
        return False
Esempio n. 9
0
def geoip():
    """Get country code based on IP address

    Returns:
        str: Country code (e.g. FR)
    """
    # better service - https://geoftv-a.akamaihd.net/ws/edgescape.json
    try:
        resp = urlquick.get('https://geoftv-a.akamaihd.net/ws/edgescape.json', max_age=-1)
        data = json.loads(resp.text)
        if 'reponse' in data:
            return data['reponse']['geo_info']['country_code']
    except Exception:
        pass
    Script.notify(Script.get_info('name'), Script.localize(30724), icon=Script.NOTIFY_WARNING)
    Script.log('Failed to get country code based on IP address', lvl=Script.WARNING)
    return None
def get_item_media_path(item_media_path):
    """Get full path or URL of an item_media

    Args:
        item_media_path (str or list): Partial media path of the item (e.g. channels/fr/tf1.png)
    Returns:
        str: Full path or URL of the item_pedia
    """
    full_path = ''

    # Local image in ressources/media folder
    if type(item_media_path) is list:
        full_path = os.path.join(Script.get_info("path"), "resources", "media",
                                 *(item_media_path))

    # Remote image with complete URL
    elif 'http' in item_media_path:
        full_path = item_media_path

    # Image in our resource.images add-on
    else:
        full_path = 'resource://resource.images.catchuptvandmore/' + item_media_path

    return utils.ensure_native_str(full_path)
def get_item_media_path(item_media_path):
    """Get full path or URL of an item_media

    Args:
        item_media_path (str or list): Partial media path of the item (e.g. channels/fr/tf1.png)
    Returns:
        str: Full path or URL of the item_pedia
    """
    full_path = ''

    # Local image in ressources/media folder
    if type(item_media_path) is list:
        full_path = os.path.join(Script.get_info("path"), "resources", "media",
                                 *(item_media_path))

    # Remote image with complete URL
    elif 'http' in item_media_path:
        full_path = item_media_path

    # Remote image on our images repo
    else:
        full_path = 'https://github.com/Catch-up-TV-and-More/images/raw/master/' + item_media_path

    return utils.ensure_native_str(full_path)
# Local imports
# delete_for_submission_start
from resources.lib.vpn import add_vpn_context
# delete_for_submission_end
from resources.lib.kodi_utils import get_kodi_version
import resources.lib.favourites as fav
<<<<<<< HEAD:plugin.video.catchuptvandmore/resources/lib/menu_utils.py

from resources.lib.addon_utils import get_item_label
from resources.lib.migration_utils import migrate_old_menus_settings
=======
>>>>>>> cf69920d1ba10a4558544c5d79d7c35f56d3e2c3:resources/lib/menu_utils.py

from resources.lib.addon_utils import get_item_label

MENUS_SETTINGS_FP = os.path.join(Script.get_info('profile'), "menus_settings.json")
"""
Json file that keeps, for each menu of the addon,
what elements are hidden and the order of items in each menu

"""


"""Utility functions to deal with user menus settings

"""


def get_menus_settings():
    """Get menus settings dict from json file
Esempio n. 13
0
from codequick import Script, utils
from kodi_six import xbmc
from kodi_six import xbmcvfs
from kodi_six import xbmcgui

# Local imports
# delete_for_submission_start
from resources.lib.vpn import add_vpn_context
# delete_for_submission_end
from resources.lib.kodi_utils import get_kodi_version
import resources.lib.favourites as fav

from resources.lib.addon_utils import get_item_label
from resources.lib.migration_utils import migrate_old_menus_settings

MENUS_SETTINGS_FP = os.path.join(Script.get_info('profile'),
                                 "menus_settings.json")
"""
Json file that keeps, for each menu of the addon,
what elements are hidden and the order of items in each menu

"""
"""Utility functions to deal with user menus settings

"""


def get_menus_settings():
    """Get menus settings dict from json file

    Returns:
def migrate_old_menus_settings(menus_settings_fp):
    """
    This function moves old user settings concerning hidden menu
    and items order in
    the new json file used for that purpose.
    The feature (json) appeared in 0.2.17~betaXX
    All user with version >= 0.2.17 will use item settings in the JSON format
    Maybe we can remove the migration check on version 0.2.20?
    """

    # If the json file already exists, the migration has already be done
    if xbmcvfs.exists(menus_settings_fp):
        return

    # We directly read the XML setting file (faster than 'xbmcaddon.Addon().getSetting(s)')
    addon_settings_fp = os.path.join(Script.get_info('profile'), "settings.xml")
    if not xbmcvfs.exists(addon_settings_fp):
        return

    Script.log('Start item settings migration to json file')
    j = {}

    skeletons = [
        "root",
        "live_tv",
        "replay",
        'websites',
        "fr_live",
        "ch_live",
        "uk_live",
        "wo_live",
        "be_live",
        "jp_live",
        "ca_live",
        "us_live",
        "pl_live",
        "es_live",
        "tn_live",
        "it_live",
        "nl_live",
        "cn_live",
        "fr_replay",
        "ch_replay",
        "uk_replay",
        "wo_replay",
        "be_replay",
        "jp_replay",
        "ca_replay",
        "us_replay",
        "es_replay",
        "tn_replay",
        "it_replay",
        "nl_replay",
        "cn_replay"
    ]

    tree = ET.parse(addon_settings_fp)
    old_settings = {}
    for elem in tree.findall('setting'):
        if 'id' in elem.attrib:
            setting_id = elem.attrib['id']
            if 'value' in elem.attrib:
                # Kodi 17 case
                setting_value = elem.attrib['value']
            else:
                # Kodi 18 and 19 case
                setting_value = elem.text
            # try:
            #     print('Setting: "{}" --> "{}"'.format(setting_id, setting_value))
            # except Exception:
            #     pass
            old_settings[setting_id] = setting_value

    for skeleton in skeletons:
        current_menu = importlib.import_module('resources.lib.skeletons.' +
                                               skeleton).menu
        for setting_id, setting_value in old_settings.items():
            order = False
            if '.order' in setting_id:
                setting_id = setting_id.split('.')[0]
                order = True
            if setting_id in current_menu:
                item_infos = current_menu[setting_id]
                if setting_value != "":
                    if order:
                        if item_infos['order'] != int(setting_value):
                            if skeleton not in j:
                                j[skeleton] = {}
                            if setting_id not in j[skeleton]:
                                j[skeleton][setting_id] = {}
                            j[skeleton][setting_id]['order'] = int(setting_value)
                    else:
                        if setting_value.lower() == "false" and item_infos['enabled'] is True:
                            if skeleton not in j:
                                j[skeleton] = {}
                            if setting_id not in j[skeleton]:
                                j[skeleton][setting_id] = {}
                            j[skeleton][setting_id]['hidden'] = True

    # Save new item settings json
    with open(menus_settings_fp, 'w') as f:
        json.dump(j, f, indent=4)
Esempio n. 15
0
# Copyright: (c) 2016, Chamchenko
# GNU General Public License v2.0+ (see LICENSE.txt or https://www.gnu.org/licenses/gpl-2.0.txt)
# This file is part of plugin.video.shahid

import xbmc

from codequick.utils import urljoin_partial
from codequick import Script

XBMC_VERSION = int(
    xbmc.getInfoLabel("System.BuildVersion").split('-')[0].split('.')[0])
INPUTSTREAM_PROP = 'inputstream' if XBMC_VERSION >= 19 else 'inputstreamaddon'

#Add-on related
ADDON_ID = 'plugin.video.shahid'
ADDON_NAME = Script.get_info('name')
SETTINGS_LOC = Script.get_info('profile')
ADDON_PATH = Script.get_info('path')
ADDON_VERSION = Script.get_info('version')
ICON = Script.get_info('icon')
FANART = Script.get_info('fanart')
Hide_Clips = Script.setting.get_boolean('Hide_Clips')
HIDE_PREMIUM = Script.setting.get_boolean('Hide_Premium')
MODE_KIDS = Script.setting.get_boolean('Mode_Kids')
QUALITY = Script.setting.get_string('Quality').replace('p', '')
EMAIL = Script.setting.get_string('username')
PASSWORD = Script.setting.get_string('password')
Movie_Category_Mode = Script.setting.get_string('Movie_Category_Mode')
Show_Category_Mode = Script.setting.get_string('Show_Category_Mode')
language = xbmc.getLanguage(xbmc.ISO_639_1)
if language != 'ar' and language != 'en':
# Inspired by https://gitlab.com/ronie/script.kodi.loguploader/blob/master/default.py

import os
import re

import xbmc
import xbmcvfs
import xbmcgui
import pyqrcode

from codequick import Script
import urlquick

from resources.lib.labels import LABELS

PROFILE = Script.get_info('profile')
CWD = Script.get_info('path')
URL = 'https://paste.kodi.tv/'
LOGPATH = xbmc.translatePath('special://logpath')
LOGFILE = os.path.join(LOGPATH, 'kodi.log')
REPLACES = (
    ('//.+?:.+?@', '//USER:PASSWORD@'),
    ('password.*', 'password*******LINE_DELETED*********'),
    ('login.*', 'login******LINE_DELETED**********'),
    ('Password.*', 'Password*******LINE_DELETED*********'),
    ('Login.*', 'Login******LINE_DELETED**********'),
    ('email.*', 'email******LINE_DELETED**********'),
    ('<user>.+?</user>', '<user>USER</user>'),
    ('<pass>.+?</pass>', '<pass>PASSWORD</pass>'),
)
Esempio n. 17
0
import json
from builtins import str
from builtins import range
from kodi_six import xbmc
from kodi_six import xbmcgui
from kodi_six import xbmcvfs

from codequick import utils, storage, Script, listing
from hashlib import md5

import resources.lib.mem_storage as mem_storage
from resources.lib.migration_utils import migrate_from_pickled_fav
from resources.lib.kodi_utils import get_selected_item_art, get_selected_item_label, get_selected_item_params, get_selected_item_stream, get_selected_item_info
from resources.lib.addon_utils import get_item_label, get_item_media_path

FAV_JSON_FP = os.path.join(Script.get_info('profile'), "favourites.json")


def get_fav_dict_from_json():
    """Get favourites dict from favourites.json

    Returns:
        dict: Favourites dict
    """

    migrate_from_pickled_fav()
    if not xbmcvfs.exists(FAV_JSON_FP):
        return {}
    try:
        with open(FAV_JSON_FP) as f:
            return json.load(f)
except ImportError:
    from urllib import urlencode
import socket

# Kodi imports
from codequick import Script
from kodi_six import xbmcgui

# Local imports
from resources.lib.addon_utils import get_item_label, get_item_media_path
from resources.lib.xmltv import grab_programmes

PLUGIN_KODI_PATH = "plugin://plugin.video.catchuptvandmore"

# Json file that keeps user settings concerning Kodi Live TV integration made by IPTV Manager
TV_INTEGRATION_SETTINGS_FP = os.path.join(Script.get_info('profile'),
                                          "tv_integration_settings.json")
"""Utility functions to deal with user tv integration settings

"""


def get_tv_integration_settings():
    """Get tv integration settings dict from json file

    Returns:
        dict: Tv integration settings
    """
    try:
        with open(TV_INTEGRATION_SETTINGS_FP) as f:
            settings = json.load(f)