28a3c7a3fdf0f39cb85918d3f97f0dbb964b69e0
[naja.git] / naja / resources / loader.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',
13                             path)
14 import pygame
15
16
17 class ResourceNotFound(Exception):
18     pass
19
20
21 class Loader(object):
22     CONVERT_ALPHA = True
23
24     def __init__(self, resource_module, language=None):
25         self.resource_module = resource_module
26         self.lang_dialect = language
27         self.language = language.split('_', 1)[0] if language else None
28         self._cache = {}
29
30     def create_resource_path(self, *path_fragments):
31         return resource_filename(self.resource_module,
32                                  os.path.join(*path_fragments))
33
34     def get_resource_path(self, *path_fragments):
35         for mod, full_path_fragments in self.lang_locations(path_fragments):
36             path = resource_filename(mod, os.path.join(*full_path_fragments))
37             if os.path.exists(path):
38                 return path
39         raise ResourceNotFound(os.path.join(*path_fragments))
40
41     def lang_locations(self, path_fragments):
42         '''
43         For each resource module, yield:
44         * (<module>, (<lang>_<dialect>, <path>))
45         * (<module>, (<lang>, <path>))
46         * (<module>, (<path>, ))
47         '''
48         for module in (self.resource_module,):
49             if self.lang_dialect:
50                 yield (module, (self.lang_dialect,) + path_fragments)
51             if self.language != self.lang_dialect:
52                 yield (module, (self.language,) + path_fragments)
53             yield (module, path_fragments)
54
55     def get_file(self, *path_fragments, **kw):
56         mode = kw.get('mode', "rU")
57         try:
58             path = self.get_resource_path(*path_fragments)
59         except ResourceNotFound:
60             if 'w' in mode:
61                 path = self.create_resource_path(*path_fragments)
62             else:
63                 raise
64         return file(path, mode)
65
66     def get_image(self, *name_fragments, **kw):
67         transforms = kw.get('transforms', ())
68         basedir = kw.get('basedir', 'images')
69
70         path = (basedir,) + name_fragments
71
72         if path not in self._cache:
73             fn = self.get_resource_path(*path)
74             image = pygame.image.load(fn)
75             if self.CONVERT_ALPHA:
76                 if not pygame.display.get_init():
77                     print >> sys.stderr, ("Display not initialized, "
78                                           "image '%s' not loaded."
79                                           % os.path.join(*path))
80                     return
81                 image = image.convert_alpha(pygame.display.get_surface())
82             self._cache[path] = image
83
84         key = (path, transforms)
85         if key not in self._cache:
86             image = self._cache[path]
87             for mutator in transforms:
88                 image = mutator(image)
89             self._cache[key] = image
90
91         return self._cache[key]
92
93     def get_font(self, file_name, font_size):
94         basedir = 'fonts'
95         key = (basedir, file_name, font_size)
96
97         if key not in self._cache:
98             fn = self.get_resource_path(basedir, file_name)
99             self._cache[key] = pygame.font.Font(fn, font_size)
100
101         return self._cache[key]