1# Copyright 2013 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""A Resource is a file and its various associated canonical names.""" 6 7import codecs 8import os 9 10 11class Resource(object): 12 """Represents a file found via a path search.""" 13 14 def __init__(self, toplevel_dir, absolute_path, binary=False): 15 self.toplevel_dir = toplevel_dir 16 self.absolute_path = absolute_path 17 self._contents = None 18 self._binary = binary 19 20 @property 21 def relative_path(self): 22 """The path to the file from the top-level directory""" 23 return os.path.relpath(self.absolute_path, self.toplevel_dir) 24 25 @property 26 def unix_style_relative_path(self): 27 return self.relative_path.replace(os.sep, '/') 28 29 @property 30 def name(self): 31 """The dotted name for this resource based on its relative path.""" 32 return self.name_from_relative_path(self.relative_path) 33 34 @staticmethod 35 def name_from_relative_path(relative_path): 36 dirname = os.path.dirname(relative_path) 37 basename = os.path.basename(relative_path) 38 modname = os.path.splitext(basename)[0] 39 if len(dirname): 40 name = dirname.replace(os.path.sep, '.') + '.' + modname 41 else: 42 name = modname 43 return name 44 45 @property 46 def contents(self): 47 if self._contents: 48 return self._contents 49 if not os.path.exists(self.absolute_path): 50 raise Exception('%s not found.' % self.absolute_path) 51 if self._binary: 52 f = open(self.absolute_path, mode='rb') 53 else: 54 f = codecs.open(self.absolute_path, mode='r', encoding='utf-8') 55 self._contents = f.read() 56 f.close() 57 return self._contents 58