示例#1
0
 def install_file(self, user_file, font_path, commit=True, clear=True):
     doc_cache = DocumentCache()
     
     #If the file does not exist the following will fail
     doc_cache.add(user_file)
     
     #Install the file into every cached skin font file
     for skin_file in self.__doc_cache.list_files():
         res_folder = self._get_res_folder(skin_file)
         res_file = self._get_res_filename(res_folder, user_file)
         
         #If an specific res file exists...
         if os.path.isfile(res_file):
             self._install_file(doc_cache, res_file, skin_file, font_path)
         
         #Otherwise use the dafault fallback
         else:
             self._install_file(doc_cache, user_file, skin_file, font_path)
     
     #If save was requested
     if commit:
         self.__doc_cache.write_all()
         
         #Clear cached docs after write (if requested)
         if clear:
             self.__doc_cache.clear_all()
示例#2
0
    def install_file(self, user_file, font_path, commit=True, clear=True):
        doc_cache = DocumentCache()

        # If the file does not exist the following will fail
        doc_cache.add(user_file)

        # Install the file into every cached skin font file
        for skin_file in self.__doc_cache.list_files():
            res_folder = self._get_res_folder(skin_file)
            res_file = self._get_res_filename(res_folder, user_file)

            # If an specific res file exists...
            if os.path.isfile(res_file):
                self._install_file(doc_cache, res_file, skin_file, font_path)

            # Otherwise use the dafault fallback
            else:
                self._install_file(doc_cache, user_file, skin_file, font_path)

        # If save was requested
        if commit:
            self.__doc_cache.write_all()

            # Clear cached docs after write (if requested)
            if clear:
                self.__doc_cache.clear_all()
示例#3
0
    def __init__(self):
        self.__installed_names = []
        self.__doc_cache = DocumentCache()

        # Check if the environment is sane
        check_skin_writability()

        # Initialize the doc cache with found files
        for file in self._list_skin_include_files():
            self.__doc_cache.add(file)
示例#4
0
 def __init__(self):
     self.__installed_names = []
     self.__doc_cache = DocumentCache()
     
     #Check if the environment is sane
     check_skin_writability()
     
     #Initialize the doc cache with found files
     for file in self._list_skin_include_files():
         self.__doc_cache.add(file)
示例#5
0
class IncludeManager:
    __installed_names = None
    __doc_cache = None
    
    
    def _list_skin_include_files(self):
        include_list = []
        skin_path = xbmc.translatePath("special://skin/")
        
        #Go into each dir. Could be 720, 1080...
        for dir_item in os.listdir(skin_path):
            dir_path = os.path.join(skin_path, dir_item)
            if os.path.isdir(dir_path):
                file = os.path.join(dir_path, "includes.xml")
                if case_file_exists(file):
                    include_list.append(file)
                
                file = os.path.join(dir_path, "Includes.xml")
                if case_file_exists(file):
                    include_list.append(file)
        
        return include_list
    
    
    def __init__(self):
        self.__installed_names = []
        self.__doc_cache = DocumentCache()
        
        #Check if the environment is sane
        check_skin_writability()
        
        #Initialize the doc cache with found files
        for file in self._list_skin_include_files():
            self.__doc_cache.add(file)
    
    
    def is_name_installed(self, name):
        return name in self.__installed_names
    
    
    def add_include(self, name, node):
        for file in self.__doc_cache.list_files():
            doc = self.__doc_cache.read(file)
            doc.getroot().append(node)
            self.__installed_names.append(name)
    
    
    def install_file(self, file, commit=True, clear=True):
        get_logger().info('install include: %s' % file)
        tree = ET.parse(file)
        
        #Handle all includes
        for item in tree.getroot().findall("include"):
            name = item.get("name")
            if name is None:
                get_logger().warning('Only named includes are supported.')
            
            elif self.is_name_installed(name):
                get_logger().warning('Include name "%s" already installed' % name)
            
            else:
                self.add_include(name, item)
        
        #If a save was requested
        if commit:
            self.__doc_cache.write_all()
            
            #If we where requested to clear the cached docs
            if clear:
                self.__doc_cache.clear_all()
    
    
    def remove_installed_names(self):
        self.__doc_cache.rollback_all()
    
    
    def cleanup(self):
        self.remove_installed_names()
    
    
    def __del__(self):
        self.cleanup()
示例#6
0
 def __init__(self, script_path):
     self.__installed_names = []
     self.__installed_fonts = []
     self.__doc_cache = DocumentCache()
     self.script_path = script_path
示例#7
0
class FontManager(object, SkinUtilsFontManager):
    FONTS = {
        "script.module.iptvlib-font_MainMenu":
        "script.module.iptvlib-NotoSans-Bold.ttf",
        "script.module.iptvlib-font30_title":
        "script.module.iptvlib-NotoSans-Bold.ttf",
        "script.module.iptvlib-font30":
        "script.module.iptvlib-NotoSans-Regular.ttf",
        "script.module.iptvlib-font14":
        "script.module.iptvlib-NotoSans-Regular.ttf",
        "script.module.iptvlib-font12":
        "script.module.iptvlib-NotoSans-Regular.ttf",
    }
    script_path = None

    def __init__(self, script_path):
        self.__installed_names = []
        self.__installed_fonts = []
        self.__doc_cache = DocumentCache()
        self.script_path = script_path

    def check_fonts(self):
        if 'skin.estuary' == get_skin_name():
            raise FontManagerException(FontManagerException.INSTALL_NOT_NEEDED)

        if self.is_restart_needed():
            raise FontManagerException(FontManagerException.RESTART_NEEDED)

        if get_current_skin_path() != get_local_skin_path():
            if not self.is_writable():
                raise FontManagerException(
                    FontManagerException.INSTALL_NOT_NEEDED)
            raise FontManagerException(FontManagerException.INSTALL_NEEDED)

        else:
            if not os.path.isdir(get_local_skin_path()):
                raise FontManagerException(FontManagerException.INSTALL_NEEDED)
            for f in self._list_skin_font_files():
                self.__doc_cache.add(f)
            self.install_fonts()

    def install_fonts(self):
        xml_path = os.path.join(self.script_path, "resources", "skins",
                                "Default", "720p", "font.xml")
        font_dir = os.path.join(self.script_path, "resources", "skins",
                                "Default", "fonts")
        self.install_file(xml_path, font_dir)
        reload_skin()

    @staticmethod
    def install_skin():
        copy_skin_to_userdata(ask_user=False)

    @staticmethod
    def is_writable():
        # type: () -> bool
        skin_path = get_local_skin_path()
        return not os.access(skin_path,
                             os.W_OK) or not do_write_test(skin_path)

    @staticmethod
    def is_restart_needed():
        # type: () -> bool
        current_skin_path = get_current_skin_path()
        local_skin_path = get_local_skin_path()

        if os.path.isdir(
                local_skin_path) and current_skin_path != local_skin_path:
            if is_invalid_local_skin():
                time_suffix = datetime.now().strftime('%Y%m%d%H%M%S')
                shutil.move(local_skin_path,
                            local_skin_path + '-skinutils-' + time_suffix)
                copy_skin_to_userdata(ask_user=False)
            return True
        return False
示例#8
0
class FontManager:
    __installed_names = None
    __installed_fonts = None
    __doc_cache = None
    
    
    def _list_skin_font_files(self):
        font_xml_list = []
        skin_path = xbmc.translatePath("special://skin/")
        
        #Go into each dir. Could be 720, 1080...
        for dir_item in os.listdir(skin_path):
            dir_path = os.path.join(skin_path, dir_item)
            if os.path.isdir(dir_path):
                #Try with font.xml
                file = os.path.join(dir_path, "font.xml")
                if case_file_exists(file):
                    font_xml_list.append(file)
                
                #Don't try the next step on windows, wasted time
                file = os.path.join(dir_path, "Font.xml")
                if case_file_exists(file):
                    font_xml_list.append(file)
        
        return font_xml_list
    
    
    def __init__(self):
        self.__installed_names = []
        self.__installed_fonts = []
        self.__doc_cache = DocumentCache()
        
        #Check if the environment is sane
        check_skin_writability()
        
        #Initialize the doc cache with the skin's files
        for file in self._list_skin_font_files():
            self.__doc_cache.add(file)
    
    
    def is_name_installed(self, name):
        return name in self.__installed_names
    
    
    def is_font_installed(self, file):
        return file in self.__installed_fonts
    
    
    def _get_font_attr(self, node, name):
        attrnode = node.find(name)
        if attrnode is not None:
            return attrnode.text
    
    
    def _copy_font_file(self, file):
        skin_font_path = xbmc.translatePath("special://skin/fonts/")
        file_name = os.path.basename(file)
        dest_file = os.path.join(skin_font_path, file_name)
        
        #TODO: Unix systems could use symlinks
        
        #Check if it's already there
        if dest_file not in self.__installed_fonts:
            self.__installed_fonts.append(dest_file)
            
            #Overwrite if file exists
            shutil.copyfile(file, dest_file)
    
    
    def _add_font_attr(self, fontdef, name, value):
        attr = ET.SubElement(fontdef, name)
        attr.text = value
        attr.tail = "\n\t\t\t"
        return attr
    
    
    def _install_font_def(self, skin_file, name, filename, size, style="", aspect="", linespacing=""):
        #Add it to the registry
        self.__installed_names.append(name)
        
        #Get the parsed skin font file
        font_doc = self.__doc_cache.read(skin_file)
        
        #Iterate over all the fontsets on the file
        for fontset in font_doc.getroot().findall("fontset"):
            fontset.findall("font")[-1].tail = "\n\t\t"
            fontdef = ET.SubElement(fontset, "font")
            fontdef.text, fontdef.tail = "\n\t\t\t", "\n\t"
            
            self._add_font_attr(fontdef, "name", name)
            
            #We get the full file path to the font, so let's basename
            self._add_font_attr(fontdef, "filename", os.path.basename(filename))
            self._copy_font_file(filename)
            
            last = self._add_font_attr(fontdef, "size", size)
            
            if style:
                if style in ["normal", "bold", "italics", "bolditalics"]:
                    last = self._add_font_attr(fontdef, "style", style)
                
                else:
                    raise FontXmlError(
                        "Font '%s' has an invalid style definition: %s"
                        % (name, style)
                    )
            
            if aspect:
                last = self._add_font_attr(fontdef, "aspect", aspect)
            
            if linespacing:
                last = self._add_font_attr(fontdef, "linespacing", linespacing)
            
            last.tail = "\n\t\t"
    
    
    def _install_file(self, doc_cache, user_file, skin_file, font_path):
        user_doc = doc_cache.read(user_file)
        
        #Handle only the first fontset
        fontset = user_doc.getroot().find("fontset")
        if len(fontset):
            #Every font definition inside it
            for item in fontset.findall("font"):
                name = self._get_font_attr(item, "name")
                
                #Basic check for malformed defs.
                if name is None:
                    raise FontXmlError("Malformed XML: No name for font definition.")
                
                #Omit already defined fonts
                elif not self.is_name_installed(name):
                    font_file_path = os.path.join(
                        font_path, self._get_font_attr(item, "filename")
                    )
                    self._install_font_def(
                        skin_file,
                        name,
                        font_file_path,
                        self._get_font_attr(item, "size"),
                        self._get_font_attr(item, "style"),
                        self._get_font_attr(item, "aspect"),
                        self._get_font_attr(item, "linespacing")
                    )
    
    
    def _get_res_folder(self, path):
        return os.path.basename(os.path.dirname(path))
    
    
    def _get_res_filename(self, res_folder, user_file):
        path, ext = os.path.splitext(user_file)
        return path + '-' + res_folder + ext
    
    
    def install_file(self, user_file, font_path, commit=True, clear=True):
        doc_cache = DocumentCache()
        
        #If the file does not exist the following will fail
        doc_cache.add(user_file)
        
        #Install the file into every cached skin font file
        for skin_file in self.__doc_cache.list_files():
            res_folder = self._get_res_folder(skin_file)
            res_file = self._get_res_filename(res_folder, user_file)
            
            #If an specific res file exists...
            if os.path.isfile(res_file):
                self._install_file(doc_cache, res_file, skin_file, font_path)
            
            #Otherwise use the dafault fallback
            else:
                self._install_file(doc_cache, user_file, skin_file, font_path)
        
        #If save was requested
        if commit:
            self.__doc_cache.write_all()
            
            #Clear cached docs after write (if requested)
            if clear:
                self.__doc_cache.clear_all()
    
    
    def remove_font(self, name):
        pass
    
    
    def remove_installed_names(self):
        self.__doc_cache.rollback_all()
    
    
    def remove_installed_fonts(self):
        for item in self.__installed_fonts:
            if not try_remove_file(item):
                get_logger().error(
                    'Failed removing font file "%s". XBMC may still be using it.' % item
                )
    
    
    def cleanup(self):
        self.remove_installed_names()
        
        #Reload skin so font files are no longer in use, and then delete them
        reload_skin()
        self.remove_installed_fonts()
    
    
    def __del__(self):
        self.cleanup()
示例#9
0
class IncludeManager:
    __installed_names = None
    __doc_cache = None

    def _list_skin_include_files(self):
        include_list = []
        skin_path = xbmc.translatePath("special://skin/")

        # Go into each dir. Could be 720, 1080...
        for dir_item in os.listdir(skin_path):
            dir_path = os.path.join(skin_path, dir_item)
            if os.path.isdir(dir_path):
                file = os.path.join(dir_path, "includes.xml")
                if case_file_exists(file):
                    include_list.append(file)

                file = os.path.join(dir_path, "Includes.xml")
                if case_file_exists(file):
                    include_list.append(file)

        return include_list

    def __init__(self):
        self.__installed_names = []
        self.__doc_cache = DocumentCache()

        # Check if the environment is sane
        check_skin_writability()

        # Initialize the doc cache with found files
        for file in self._list_skin_include_files():
            self.__doc_cache.add(file)

    def is_name_installed(self, name):
        return name in self.__installed_names

    def add_include(self, name, node):
        for file in self.__doc_cache.list_files():
            doc = self.__doc_cache.read(file)
            doc.getroot().append(node)
            self.__installed_names.append(name)

    def install_file(self, file, commit=True, clear=True):
        get_logger().info('install include: %s' % file)
        tree = ET.parse(file)

        # Handle all includes
        for item in tree.getroot().findall("include"):
            name = item.get("name")
            if name is None:
                get_logger().warning('Only named includes are supported.')

            elif self.is_name_installed(name):
                get_logger().warning('Include name "%s" already installed' %
                                     name)

            else:
                self.add_include(name, item)

        # If a save was requested
        if commit:
            self.__doc_cache.write_all()

            # If we where requested to clear the cached docs
            if clear:
                self.__doc_cache.clear_all()

    def remove_installed_names(self):
        self.__doc_cache.rollback_all()

    def cleanup(self):
        self.remove_installed_names()

    def __del__(self):
        self.cleanup()
示例#10
0
class FontManager:
    __installed_names = None
    __installed_fonts = None
    __doc_cache = None

    def _list_skin_font_files(self):
        font_xml_list = []
        skin_path = xbmc.translatePath("special://skin/")

        # Go into each dir. Could be 720, 1080...
        for dir_item in os.listdir(skin_path):
            dir_path = os.path.join(skin_path, dir_item)
            if os.path.isdir(dir_path):
                # Try with font.xml
                file = os.path.join(dir_path, "font.xml")
                if case_file_exists(file):
                    font_xml_list.append(file)

                # Don't try the next step on windows, wasted time
                file = os.path.join(dir_path, "Font.xml")
                if case_file_exists(file):
                    font_xml_list.append(file)

        return font_xml_list

    def __init__(self):
        self.__installed_names = []
        self.__installed_fonts = []
        self.__doc_cache = DocumentCache()

        # Check if the environment is sane
        check_skin_writability()

        # Initialize the doc cache with the skin's files
        for file in self._list_skin_font_files():
            self.__doc_cache.add(file)

    def is_name_installed(self, name):
        return name in self.__installed_names

    def is_font_installed(self, file):
        return file in self.__installed_fonts

    def _get_font_attr(self, node, name):
        attrnode = node.find(name)
        if attrnode is not None:
            return attrnode.text

    def _copy_font_file(self, file):
        skin_font_path = xbmc.translatePath("special://skin/fonts/")
        file_name = os.path.basename(file)
        dest_file = os.path.join(skin_font_path, file_name)

        # TODO: Unix systems could use symlinks

        # Check if it's already there
        if dest_file not in self.__installed_fonts:
            self.__installed_fonts.append(dest_file)

            # Overwrite if file exists
            shutil.copyfile(file, dest_file)

    def _add_font_attr(self, fontdef, name, value):
        attr = ET.SubElement(fontdef, name)
        attr.text = value
        attr.tail = "\n\t\t\t"
        return attr

    def _install_font_def(self,
                          skin_file,
                          name,
                          filename,
                          size,
                          style="",
                          aspect="",
                          linespacing=""):
        # Add it to the registry
        self.__installed_names.append(name)

        # Get the parsed skin font file
        font_doc = self.__doc_cache.read(skin_file)

        # Iterate over all the fontsets on the file
        for fontset in font_doc.getroot().findall("fontset"):
            fontset.findall("font")[-1].tail = "\n\t\t"
            fontdef = ET.SubElement(fontset, "font")
            fontdef.text, fontdef.tail = "\n\t\t\t", "\n\t"

            self._add_font_attr(fontdef, "name", name)

            # We get the full file path to the font, so let's basename
            self._add_font_attr(fontdef, "filename",
                                os.path.basename(filename))
            self._copy_font_file(filename)

            last = self._add_font_attr(fontdef, "size", size)

            if style:
                if style in [
                        "normal", "bold", "italics", "bolditalics", "lighten"
                ]:
                    last = self._add_font_attr(fontdef, "style", style)

                else:
                    raise FontXmlError(
                        "Font '%s' has an invalid style definition: %s" %
                        (name, style))

            if aspect:
                last = self._add_font_attr(fontdef, "aspect", aspect)

            if linespacing:
                last = self._add_font_attr(fontdef, "linespacing", linespacing)

            last.tail = "\n\t\t"

    def _install_file(self, doc_cache, user_file, skin_file, font_path):
        user_doc = doc_cache.read(user_file)

        # Handle only the first fontset
        fontset = user_doc.getroot().find("fontset")
        if len(fontset):
            # Every font definition inside it
            for item in fontset.findall("font"):
                name = self._get_font_attr(item, "name")

                # Basic check for malformed defs.
                if name is None:
                    raise FontXmlError(
                        "Malformed XML: No name for font definition.")

                # Omit already defined fonts
                elif not self.is_name_installed(name):
                    font_file_path = os.path.join(
                        font_path, self._get_font_attr(item, "filename"))
                    self._install_font_def(
                        skin_file, name, font_file_path,
                        self._get_font_attr(item, "size"),
                        self._get_font_attr(item, "style"),
                        self._get_font_attr(item, "aspect"),
                        self._get_font_attr(item, "linespacing"))

    def _get_res_folder(self, path):
        return os.path.basename(os.path.dirname(path))

    def _get_res_filename(self, res_folder, user_file):
        path, ext = os.path.splitext(user_file)
        return path + '-' + res_folder + ext

    def install_file(self, user_file, font_path, commit=True, clear=True):
        doc_cache = DocumentCache()

        # If the file does not exist the following will fail
        doc_cache.add(user_file)

        # Install the file into every cached skin font file
        for skin_file in self.__doc_cache.list_files():
            res_folder = self._get_res_folder(skin_file)
            res_file = self._get_res_filename(res_folder, user_file)

            # If an specific res file exists...
            if os.path.isfile(res_file):
                self._install_file(doc_cache, res_file, skin_file, font_path)

            # Otherwise use the dafault fallback
            else:
                self._install_file(doc_cache, user_file, skin_file, font_path)

        # If save was requested
        if commit:
            self.__doc_cache.write_all()

            # Clear cached docs after write (if requested)
            if clear:
                self.__doc_cache.clear_all()

    def remove_font(self, name):
        pass

    def remove_installed_names(self):
        self.__doc_cache.rollback_all()

    def remove_installed_fonts(self):
        for item in self.__installed_fonts:
            if not try_remove_file(item):
                get_logger().error(
                    'Failed removing font file "%s". XBMC may still be using it.'
                    % item)

    def cleanup(self):
        self.remove_installed_names()

        # Reload skin so font files are no longer in use, and then delete them
        reload_skin()
        self.remove_installed_fonts()

    def __del__(self):
        self.cleanup()