File indexing completed on 2024-04-21 04:01:51
0001 # -*- coding: utf-8 -*- 0002 0003 """ 0004 Authors of original libkmahjongg in C++: 0005 Copyright (C) 1997 Mathias Mueller <in5y158@public.uni-hamburg.de> 0006 Copyright (C) 2006 Mauricio Piacentini <mauricio@tabuleiro.com> 0007 0008 this adapted python code: 0009 Copyright (C) 2008-2016 Wolfgang Rohdewald <wolfgang@rohdewald.de> 0010 0011 SPDX-License-Identifier: GPL-2.0 0012 0013 """ 0014 0015 import os 0016 from qt import QStandardPaths 0017 from log import logWarning, logException 0018 from kde import KConfig 0019 from mi18n import i18n 0020 0021 RESOURCEFORMAT = 1 # as long as backgrounds and tilesets are synchronous in their versions 0022 0023 0024 class Resource: 0025 0026 """Common code for backgrounds and tilesets""" 0027 0028 resourceName = None # to be overridden in Tileset and Background 0029 configGroupName = None 0030 0031 """represents a complete tileset""" 0032 # pylint: disable=too-many-instance-attributes 0033 0034 cache = {} 0035 0036 def __new__(cls, name): 0037 return cls.cache.get(name) or cls.cache.get(cls.__name(name)) or cls.__build(name) 0038 0039 @classmethod 0040 def __directories(cls): 0041 """where to look for resources""" 0042 result = QStandardPaths.locateAll( 0043 QStandardPaths.GenericDataLocation, 0044 'kmahjongglib/{}s'.format(cls.resourceName), QStandardPaths.LocateDirectory) 0045 result.insert(0, os.path.join('share', 'kmahjongglib', '{}s'.format(cls.resourceName))) 0046 return (x for x in result if os.path.exists(x)) 0047 0048 @classmethod 0049 def locate(cls, which): 0050 """locate the file with a resource""" 0051 for directory in cls.__directories(): 0052 path = os.path.join(directory, which) 0053 if os.path.exists(path): 0054 return path 0055 logException('cannot find kmahjongg%s %s in %s' % (cls.resourceName, which, cls.__directories())) 0056 return None 0057 0058 @classmethod 0059 def loadAll(cls): 0060 """loads all available resources into cache""" 0061 resourceDirectories = cls.__directories() 0062 for directory in resourceDirectories: 0063 for name in os.listdir(directory): 0064 if name.endswith('.desktop'): 0065 if not name.endswith('alphabet.desktop') and not name.endswith('egypt.desktop'): 0066 cls(os.path.join(directory, name)) 0067 0068 @classmethod 0069 def available(cls): 0070 """ready for the selector dialog, default first""" 0071 cls.loadAll() 0072 return sorted(set(cls.cache.values()), key=lambda x: x.desktopFileName != 'default') 0073 0074 @classmethod 0075 def __noTilesetFound(cls): 0076 """No resources found""" 0077 directories = '\n\n' + '\n'.join(cls.__directories()) 0078 logException( 0079 i18n( 0080 'cannot find any %1 in the following directories, ' 0081 'is libkmahjongg installed?', cls.resourceName) + directories) # TODO: nicht schoen 0082 0083 @staticmethod 0084 def __name(path): 0085 """extract the name from path: this is the filename minus the .desktop ending""" 0086 return os.path.split(path)[1].replace('.desktop', '') 0087 0088 @classmethod 0089 def __build(cls, name): 0090 """build a new Resource. name is either a full file path or a desktop name. None stands for 'default'.""" 0091 result = object.__new__(cls) 0092 if os.path.exists(name): 0093 result.path = name 0094 result.desktopFileName = cls.__name(name) 0095 else: 0096 result.desktopFileName = name or 'default' 0097 result.path = cls.locate(result.desktopFileName + '.desktop') 0098 if not result.path: 0099 result.path = cls.locate('default.desktop') 0100 result.desktopFileName = 'default' 0101 if not result.path: 0102 cls.__noTilesetFound() 0103 else: 0104 logWarning(i18n('cannot find %1, using default', name)) 0105 0106 cls.cache[result.desktopFileName] = result 0107 cls.cache[result.path] = result 0108 return result 0109 0110 def __init__(self, unusedName): 0111 """continue __build""" 0112 self.group = KConfig(self.path).group(self.configGroupName) 0113 0114 self.name = self.group.readEntry("Name") or i18n("unknown name") 0115 self.author = self.group.readEntry("Author") or i18n("unknown author") 0116 self.description = self.group.readEntry( 0117 "Description") or i18n( 0118 "no description available") 0119 self.authorEmail = self.group.readEntry( 0120 "AuthorEmail") or i18n( 0121 "no E-Mail address available") 0122 0123 # Version control 0124 resourceVersion = self.group.readInteger("VersionFormat", default=0) 0125 # Format is increased when we have incompatible changes, meaning that 0126 # older clients are not able to use the remaining information safely 0127 if resourceVersion > RESOURCEFORMAT: 0128 logException('version file / program: %d/%d' % (resourceVersion, RESOURCEFORMAT)) 0129 0130 def __str__(self): 0131 return "%s id=%d name=%s, name id=%d" % \ 0132 (self.resourceName, id(self), self.desktopFileName, id(self.desktopFileName)) 0133 0134 @staticmethod 0135 def current(): 0136 """the currently wanted tileset. If not yet defined, do so"""