Exemple #1
0
class Resource:
    """Common code for backgrounds and tilesets"""

    resourceName = None  # to be overridden in Tileset and Background
    configGroupName = None
    """represents a complete tileset"""
    # pylint: disable=too-many-instance-attributes

    cache = {}

    def __new__(cls, name):
        return cls.cache.get(name) or cls.cache.get(
            cls.__name(name)) or cls.__build(name)

    @classmethod
    def __directories(cls):
        """where to look for resources"""
        result = QStandardPaths.locateAll(
            QStandardPaths.GenericDataLocation,
            'kmahjongglib/{}s'.format(cls.resourceName),
            QStandardPaths.LocateDirectory)
        result.insert(
            0,
            os.path.join('share', 'kmahjongglib',
                         '{}s'.format(cls.resourceName)))
        return (x for x in result if os.path.exists(x))

    @classmethod
    def locate(cls, which):
        """locate the file with a resource"""
        for directory in cls.__directories():
            path = os.path.join(directory, which)
            if os.path.exists(path):
                return path
        logException('cannot find kmahjongg%s %s in %s' %
                     (cls.resourceName, which, cls.__directories()))

    @classmethod
    def loadAll(cls):
        """loads all available resources into cache"""
        resourceDirectories = cls.__directories()
        for directory in resourceDirectories:
            for name in os.listdir(directory):
                if name.endswith('.desktop'):
                    if not name.endswith(
                            'alphabet.desktop') and not name.endswith(
                                'egypt.desktop'):
                        cls(os.path.join(directory, name))

    @classmethod
    def available(cls):
        """ready for the selector dialog, default first"""
        cls.loadAll()
        return sorted(set(cls.cache.values()),
                      key=lambda x: x.desktopFileName != 'default')

    @classmethod
    def __noTilesetFound(cls):
        """No resources found"""
        directories = '\n\n' + '\n'.join(cls.__directories())
        logException(
            i18n(
                'cannot find any %1 in the following directories, '
                'is libkmahjongg installed?', cls.resourceName) +
            directories)  # TODO: nicht schoen

    @staticmethod
    def __name(path):
        """extract the name from path: this is the filename minus the .desktop ending"""
        return os.path.split(path)[1].replace('.desktop', '')

    @classmethod
    def __build(cls, name):
        """build a new Resource. name is either a full file path or a desktop name. None stands for 'default'."""
        result = object.__new__(cls)
        if os.path.exists(name):
            result.path = name
            result.desktopFileName = cls.__name(name)
        else:
            result.desktopFileName = name or 'default'
            result.path = cls.locate(result.desktopFileName + '.desktop')
            if not result.path:
                result.path = cls.locate('default.desktop')
                result.desktopFileName = 'default'
                if not result.path:
                    cls.__noTilesetFound()
                else:
                    logWarning(i18n('cannot find %1, using default', name))

        cls.cache[result.desktopFileName] = result
        cls.cache[result.path] = result
        return result

    def __init__(self, dummyName):
        """continue __build"""
        self.group = KConfig(self.path).group(self.configGroupName)

        self.name = self.group.readEntry("Name") or i18n("unknown name")
        self.author = self.group.readEntry("Author") or i18n("unknown author")
        self.description = self.group.readEntry("Description") or i18n(
            "no description available")
        self.authorEmail = self.group.readEntry("AuthorEmail") or i18n(
            "no E-Mail address available")

        # Version control
        resourceVersion = self.group.readInteger("VersionFormat", default=0)
        # Format is increased when we have incompatible changes, meaning that
        # older clients are not able to use the remaining information safely
        if resourceVersion > RESOURCEFORMAT:
            logException('version file / program: %d/%d' %
                         (resourceVersion, RESOURCEFORMAT))

    def __str__(self):
        return "%s id=%d name=%s, name id=%d" % \
            (self.resourceName, id(self), self.desktopFileName, id(self.desktopFileName))

    @staticmethod
    def current():
        """the currently wanted tileset. If not yet defined, do so"""
        pass