comparison piecrust/processing/util.py @ 206:cba781477bd0

processing: Add `concat`, `uglifyjs` and `cleancss` processors.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 18 Jan 2015 12:13:28 -0800
parents
children 46025a1b5434
comparison
equal deleted inserted replaced
205:e725af1d48fb 206:cba781477bd0
1 import os.path
2 import time
3 import logging
4 import yaml
5 from piecrust.processing.base import Processor
6
7
8 logger = logging.getLogger(__name__)
9
10
11 class _ConcatInfo(object):
12 timestamp = 0
13 files = None
14 delim = "\n"
15
16
17 class ConcatProcessor(Processor):
18 PROCESSOR_NAME = 'concat'
19
20 def __init__(self):
21 super(ConcatProcessor, self).__init__()
22 self._cache = {}
23
24 def matches(self, path):
25 return path.endswith('.concat')
26
27 def getDependencies(self, path):
28 info = self._load(path)
29 return info.files
30
31 def getOutputFilenames(self, filename):
32 return [filename[:-7]]
33
34 def process(self, path, out_dir):
35 dirname, filename = os.path.split(path)
36 out_path = os.path.join(out_dir, filename[:-7])
37 info = self._load(path)
38 if not info.files:
39 raise Exception("No files specified in: %s" %
40 os.path.relpath(path, self.app.root_dir))
41
42 logger.debug("Concatenating %d files to: %s" %
43 (len(info.files), out_path))
44 encoded_delim = info.delim.encode('utf8')
45 with open(out_path, 'wb') as ofp:
46 for p in info.files:
47 with open(p, 'rb') as ifp:
48 ofp.write(ifp.read())
49 if info.delim:
50 ofp.write(encoded_delim)
51 return True
52
53 def _load(self, path):
54 cur_time = time.time()
55 info = self._cache.get(path)
56 if (info is not None and
57 (cur_time - info.timestamp <= 1 or
58 os.path.getmtime(path) < info.timestamp)):
59 return info
60
61 if info is None:
62 info = _ConcatInfo()
63 self._cache[path] = info
64
65 with open(path, 'r') as fp:
66 config = yaml.load(fp)
67
68 info.files = config.get('files', [])
69 info.delim = config.get('delim', "\n")
70 info.timestamp = cur_time
71
72 path_mode = config.get('path_mode', 'relative')
73 if path_mode == 'relative':
74 dirname, _ = os.path.split(path)
75 info.files = [os.path.join(dirname, f) for f in info.files]
76 elif path_mode == 'absolute':
77 info.files = [os.path.join(self.app.root_dir, f)
78 for f in info.files]
79 else:
80 raise Exception("Unknown path mode: %s" % path_mode)
81
82 return info
83