This class manages a list of search paths and helps to find and open application-bound resources (files). :param base: default value for :meth:`add_path` calls. :param opener: callable used to open resources. :param cachemode: controls which lookups are cached. One
| 2262 | |
| 2263 | |
| 2264 | class ResourceManager(object): |
| 2265 | ''' This class manages a list of search paths and helps to find and open |
| 2266 | application-bound resources (files). |
| 2267 | |
| 2268 | :param base: default value for :meth:`add_path` calls. |
| 2269 | :param opener: callable used to open resources. |
| 2270 | :param cachemode: controls which lookups are cached. One of 'all', |
| 2271 | 'found' or 'none'. |
| 2272 | ''' |
| 2273 | |
| 2274 | def __init__(self, base='./', opener=open, cachemode='all'): |
| 2275 | self.opener = open |
| 2276 | self.base = base |
| 2277 | self.cachemode = cachemode |
| 2278 | |
| 2279 | #: A list of search paths. See :meth:`add_path` for details. |
| 2280 | self.path = [] |
| 2281 | #: A cache for resolved paths. ``res.cache.clear()`` clears the cache. |
| 2282 | self.cache = {} |
| 2283 | |
| 2284 | def add_path(self, path, base=None, index=None, create=False): |
| 2285 | ''' Add a new path to the list of search paths. Return False if the |
| 2286 | path does not exist. |
| 2287 | |
| 2288 | :param path: The new search path. Relative paths are turned into |
| 2289 | an absolute and normalized form. If the path looks like a file |
| 2290 | (not ending in `/`), the filename is stripped off. |
| 2291 | :param base: Path used to absolutize relative search paths. |
| 2292 | Defaults to :attr:`base` which defaults to ``os.getcwd()``. |
| 2293 | :param index: Position within the list of search paths. Defaults |
| 2294 | to last index (appends to the list). |
| 2295 | |
| 2296 | The `base` parameter makes it easy to reference files installed |
| 2297 | along with a python module or package:: |
| 2298 | |
| 2299 | res.add_path('./resources/', __file__) |
| 2300 | ''' |
| 2301 | base = os.path.abspath(os.path.dirname(base or self.base)) |
| 2302 | path = os.path.abspath(os.path.join(base, os.path.dirname(path))) |
| 2303 | path += os.sep |
| 2304 | if path in self.path: |
| 2305 | self.path.remove(path) |
| 2306 | if create and not os.path.isdir(path): |
| 2307 | os.makedirs(path) |
| 2308 | if index is None: |
| 2309 | self.path.append(path) |
| 2310 | else: |
| 2311 | self.path.insert(index, path) |
| 2312 | self.cache.clear() |
| 2313 | return os.path.exists(path) |
| 2314 | |
| 2315 | def __iter__(self): |
| 2316 | ''' Iterate over all existing files in all registered paths. ''' |
| 2317 | search = self.path[:] |
| 2318 | while search: |
| 2319 | path = search.pop() |
| 2320 | if not os.path.isdir(path): continue |
| 2321 | for name in os.listdir(path): |