comparison piecrust/processing/base.py @ 852:4850f8c21b6e

core: Start of the big refactor for PieCrust 3.0. * Everything is a `ContentSource`, including assets directories. * Most content sources are subclasses of the base file-system source. * A source is processed by a "pipeline", and there are 2 built-in pipelines, one for assets and one for pages. The asset pipeline is vaguely functional, but the page pipeline is completely broken right now. * Rewrite the baking process as just running appropriate pipelines on each content item. This should allow for better parallelization.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 17 May 2017 00:11:48 -0700
parents c4b3a7fd2f87
children 08e02c2a2a1a
comparison
equal deleted inserted replaced
851:2c7e57d80bba 852:4850f8c21b6e
1 import shutil
2 import os.path 1 import os.path
3 import logging 2 import logging
4 3
5 4
6 logger = logging.getLogger(__name__) 5 logger = logging.getLogger(__name__)
9 PRIORITY_FIRST = -1 8 PRIORITY_FIRST = -1
10 PRIORITY_NORMAL = 0 9 PRIORITY_NORMAL = 0
11 PRIORITY_LAST = 1 10 PRIORITY_LAST = 1
12 11
13 12
14 class PipelineContext(object): 13 FORCE_BUILD = object()
15 def __init__(self, worker_id, app, out_dir, tmp_dir, force=None): 14
16 self.worker_id = worker_id 15
17 self.app = app 16 class ProcessorContext:
18 self.out_dir = out_dir 17 def __init__(self, pipeline, pipeline_ctx):
19 self.tmp_dir = tmp_dir 18 self.ignore_patterns = []
20 self.force = force 19 self.extra_processors = []
21 self.record = None 20 self._pipeline = pipeline
22 self._additional_ignore_patterns = [] 21 self._pipeline_ctx = pipeline_ctx
23 22
24 @property 23 @property
25 def is_first_worker(self): 24 def tmp_dir(self):
26 return self.worker_id == 0 25 return self._pipeline.tmp_dir
27 26
28 @property 27 @property
29 def is_pipeline_process(self): 28 def out_dir(self):
30 return self.worker_id < 0 29 return self._pipeline_ctx.out_dir
31 30
32 def addIgnorePatterns(self, patterns): 31 @property
33 self._additional_ignore_patterns += patterns 32 def worker_id(self):
33 return self._pipeline_ctx.worker_id
34
35 @property
36 def is_main_process(self):
37 return self._pipeline_ctx.is_main_process
34 38
35 39
36 class Processor(object): 40 class Processor(object):
37 PROCESSOR_NAME = None 41 PROCESSOR_NAME = None
38 42
61 65
62 def process(self, path, out_dir): 66 def process(self, path, out_dir):
63 pass 67 pass
64 68
65 69
66 class CopyFileProcessor(Processor): 70 class ExternalProcessException(Exception):
67 PROCESSOR_NAME = 'copy' 71 def __init__(self, stderr_data):
72 self.stderr_data = stderr_data
68 73
69 def __init__(self): 74 def __str__(self):
70 super(CopyFileProcessor, self).__init__() 75 return self.stderr_data
71 self.priority = PRIORITY_LAST
72
73 def matches(self, path):
74 return True
75
76 def getOutputFilenames(self, filename):
77 return [filename]
78
79 def process(self, path, out_dir):
80 out_path = os.path.join(out_dir, os.path.basename(path))
81 logger.debug("Copying: %s -> %s" % (path, out_path))
82 shutil.copyfile(path, out_path)
83 return True
84 76
85 77
86 class SimpleFileProcessor(Processor): 78 class SimpleFileProcessor(Processor):
87 def __init__(self, extensions=None): 79 def __init__(self, extensions=None):
88 super(SimpleFileProcessor, self).__init__() 80 super(SimpleFileProcessor, self).__init__()
107 return self._doProcess(path, out_path) 99 return self._doProcess(path, out_path)
108 100
109 def _doProcess(self, in_path, out_path): 101 def _doProcess(self, in_path, out_path):
110 raise NotImplementedError() 102 raise NotImplementedError()
111 103
112
113 class ExternalProcessException(Exception):
114 def __init__(self, stderr_data):
115 self.stderr_data = stderr_data
116
117 def __str__(self):
118 return self.stderr_data
119
120