00ebe1c44632e7ffed580161fdc9d8c2464598e6
[naja.git] / naja / resources.py
1 import os
2 import sys
3
4 try:
5     from pkg_resources import resource_filename
6 except ImportError:
7     # OK, we're most likely running under py2exe, so this is safe
8     # (for values of safe that are unconcerned about py2exe being involved)
9     def resource_filename(mod, path):
10         # There are better ways of doing this, but I've spent too much
11         # time going down this rabbithole already
12         return os.path.join(os.path.dirname(__file__), '..', 'data', path)
13 import pygame
14
15
16 class ResourceNotFound(Exception):
17     pass
18
19
20 class Resources(object):
21     CONVERT_ALPHA = True
22
23     def __init__(self, resource_module, language=None):
24         self.resource_module = resource_module
25         self.lang_dialect = language
26         self.language = language.split('_', 1)[0] if language else None
27         self._cache = {}
28
29     def create_resource_path(self, *path_fragments):
30         return resource_filename(self.resource_module,
31                                  os.path.join(*path_fragments))
32
33     def get_resource_path(self, *path_fragments):
34         for mod, full_path_fragments in self.lang_locations(path_fragments):
35             path = resource_filename(mod, os.path.join(*full_path_fragments))
36             if os.path.exists(path):
37                 return path
38         raise ResourceNotFound(os.path.join(*path_fragments))
39
40     def lang_locations(self, path_fragments):
41         '''
42         For each resource module, yield:
43         * (<module>, (<lang>_<dialect>, <path>))
44         * (<module>, (<lang>, <path>))
45         * (<module>, (<path>, ))
46         '''
47         for module in (self.resource_module,):
48             if self.lang_dialect:
49                 yield (module, (self.lang_dialect,) + path_fragments)
50             if self.language != self.lang_dialect:
51                 yield (module, (self.language,) + path_fragments)
52             yield (module, path_fragments)
53
54     def get_file(self, *path_fragments, **kw):
55         mode = kw.get('mode', "rU")
56         try:
57             path = self.get_resource_path(*path_fragments)
58         except ResourceNotFound:
59             if 'w' in mode:
60                 path = self.create_resource_path(*path_fragments)
61             else:
62                 raise
63         return file(path, mode)
64
65     def get_image(self, *name_fragments, **kw):
66         transforms = kw.get('transforms', ())
67         basedir = kw.get('basedir', 'images')
68
69         path = (basedir,) + name_fragments
70
71         if path not in self._cache:
72             fn = self.get_resource_path(*path)
73             image = pygame.image.load(fn)
74             if self.CONVERT_ALPHA:
75                 if not pygame.display.get_init():
76                     print >> sys.stderr, ("Display not initialized, "
77                                           "image '%s' not loaded."
78                                           % os.path.join(*path))
79                     return
80                 image = image.convert_alpha(pygame.display.get_surface())
81             self._cache[path] = image
82
83         key = (path, transforms)
84         if key not in self._cache:
85             image = self._cache[path]
86             for mutator in transforms:
87                 image = mutator(image)
88             self._cache[key] = image
89
90         return self._cache[key]
91
92     def get_font(self, file_name, font_size):
93         basedir = 'fonts'
94         key = (basedir, file_name, font_size)
95
96         if key not in self._cache:
97             fn = self.get_resource_path(basedir, file_name)
98             self._cache[key] = pygame.font.Font(fn, font_size)
99
100         return self._cache[key]
101
102
103 resources = Resources('data')