74 copylist = [] |
77 copylist = [] |
75 if print_info: |
78 if print_info: |
76 self.logger.info('Content copy items from %s to %s' % (input.dir,os.path.join(self.output,output.dir))) |
79 self.logger.info('Content copy items from %s to %s' % (input.dir,os.path.join(self.output,output.dir))) |
77 |
80 |
78 if input.__class__.__name__ == "ContentInput": |
81 if input.__class__.__name__ == "ContentInput": |
79 copylist = self.create_copy_list(content=self.configuration.layered_content(), |
82 copylist = self.create_copy_list(content=self.configuration.layered_content(empty_folders=True), |
80 input=input.dir, |
83 input=input.dir, |
81 output=os.path.join(self.output,output.dir), |
84 output=os.path.join(self.output,output.dir), |
82 include_pattern=input.get_include_pattern(), |
85 include_pattern=input.get_include_pattern(), |
83 exclude_pattern=input.get_exclude_pattern(), |
86 exclude_pattern=input.get_exclude_pattern(), |
84 files=input.get_filelist(), |
87 files=input.get_filelist(), |
89 if input.dir != None: |
92 if input.dir != None: |
90 fulldir = os.path.abspath(os.path.join(self.configuration.get_project().get_storage().get_path(),input.dir)) |
93 fulldir = os.path.abspath(os.path.join(self.configuration.get_project().get_storage().get_path(),input.dir)) |
91 else: |
94 else: |
92 fulldir = self.configuration.get_project().get_storage().get_path() |
95 fulldir = self.configuration.get_project().get_storage().get_path() |
93 |
96 |
94 data = container.DataContainer() |
97 data = container.DataContainer() |
95 for root, dirs, files in os.walk(fulldir): |
98 for root, dirs, files in os.walk(fulldir): |
96 for f in files: |
99 for f in files: |
97 filepath = utils.resourceref.norm(os.path.join(root, f)) |
100 filepath = utils.resourceref.norm(os.path.join(root, f)) |
98 key = utils.resourceref.replace_dir(filepath,fulldir,"") |
101 key = utils.resourceref.replace_dir(filepath,fulldir,"") |
99 data.add_value(key,filepath) |
102 data.add_value(key,filepath) |
100 #data.add_value(filepath,filepath) |
103 |
|
104 # If the root contains no directories and no files, it is |
|
105 # an empty directory and needs to be added |
|
106 if not dirs and not files: |
|
107 filepath = utils.resourceref.norm(root) |
|
108 key = utils.resourceref.replace_dir(filepath,fulldir,"") |
|
109 data.add_value(key,filepath) |
|
110 |
101 copylist = self.create_copy_list(content=data, |
111 copylist = self.create_copy_list(content=data, |
102 input=input.dir, |
112 input=input.dir, |
103 output=os.path.join(self.output,output.dir), |
113 output=os.path.join(self.output,output.dir), |
104 include_pattern=input.get_include_pattern(), |
114 include_pattern=input.get_include_pattern(), |
105 exclude_pattern=input.get_exclude_pattern(), |
115 exclude_pattern=input.get_exclude_pattern(), |
109 external=True) |
119 external=True) |
110 else: |
120 else: |
111 logging.getLogger('cone.content').warning("Unknown input %s" % (input.__class__.__name__)) |
121 logging.getLogger('cone.content').warning("Unknown input %s" % (input.__class__.__name__)) |
112 |
122 |
113 fullcopylist += copylist |
123 fullcopylist += copylist |
114 |
124 |
|
125 # Sort to make automated testing easier (list always in same order) |
|
126 fullcopylist.sort() |
|
127 |
115 return fullcopylist |
128 return fullcopylist |
116 |
129 |
117 def generate(self, context=None): |
130 def generate(self, context=None): |
118 """ |
131 """ |
119 Generate the given implementation. |
132 Generate the given implementation. |
120 """ |
133 """ |
|
134 #assert context, "No Context given for generation!" |
|
135 self.context = context |
121 self.logger.info('Generating') |
136 self.logger.info('Generating') |
122 self.create_output() |
137 self.create_output() |
123 return |
138 return |
124 |
139 |
125 def create_output(self,layers=None): |
140 def create_output(self,layers=None): |
126 """ |
141 """ |
127 Create the output directory from the content folder files |
142 Create the output directory from the content folder files |
128 """ |
143 """ |
129 if not self.errors: |
144 if not self.errors: |
130 datacontainer = self.configuration.layered_content(layers) |
|
131 #root = self.configuration.get_root() |
|
132 copylist = self.get_full_copy_list(True) |
145 copylist = self.get_full_copy_list(True) |
133 for copy_item in copylist: |
146 for copy_item in copylist: |
134 sourceref = copy_item[0] |
147 source_path = copy_item[0] |
135 targetfile = copy_item[1] |
148 target_path = copy_item[1] |
136 external = copy_item[2] |
149 external = copy_item[2] |
137 |
150 |
138 self.logger.info('Copy from %s to %s' % (sourceref,targetfile)) |
151 self.logger.info('Copy from %s to %s' % (source_path,target_path)) |
139 if not os.path.exists(os.path.dirname(targetfile)): |
152 |
140 os.makedirs(os.path.dirname(targetfile)) |
153 # Open file resource if the source is a file |
141 if not external: |
154 file_res = None |
142 outfile = open(targetfile,"wb") |
155 if not external and not self.configuration.get_storage().is_folder(source_path): |
143 res = self.configuration.get_storage().open_resource(sourceref,"rb") |
156 file_res = self.configuration.get_storage().open_resource(source_path, "rb") |
144 outfile.write(res.read()) |
157 elif external and os.path.isfile(source_path): |
|
158 file_res = open(source_path, 'rb') |
|
159 |
|
160 # Copy file or create empty directory |
|
161 if file_res: |
|
162 try: self._copy_file(file_res, target_path) |
|
163 finally: file_res.close() |
145 else: |
164 else: |
146 shutil.copyfile(sourceref,targetfile) |
165 path = os.path.join(self.context.output, target_path) |
|
166 if not os.path.exists(path): os.makedirs(path) |
147 return |
167 return |
148 else: |
168 else: |
149 self.logger.error('Plugin had errors! Bailing out!') |
169 self.logger.error('Plugin had errors! Bailing out!') |
150 |
170 |
|
171 def _copy_file(self, source_file, target_file_path): |
|
172 outfile = self.context.create_file(target_file_path, implementation=self) |
|
173 try: |
|
174 # Copy data in chunks of max 2 MB to avoid |
|
175 # memory errors with very large files |
|
176 while True: |
|
177 data = source_file.read(2 * 1024 * 1024) |
|
178 if data: outfile.write(data) |
|
179 else: break |
|
180 finally: |
|
181 outfile.close() |
151 |
182 |
152 def create_copy_list(self, **kwargs): |
183 def create_copy_list(self, **kwargs): |
153 """ |
184 """ |
154 Return a list copy list where each element is a (from,to) tuple |
185 Return a list copy list where each element is a (from, to, is_external) tuple |
155 """ |
186 """ |
156 datacontainer = kwargs.get('content',None) |
187 datacontainer = kwargs.get('content',None) |
157 input_dir = kwargs.get('input','') |
188 input_dir = kwargs.get('input','') |
158 output_dir = kwargs.get('output','') |
189 output_dir = kwargs.get('output','') |
159 output_file = kwargs.get('output_file','') |
190 output_file = kwargs.get('output_file','') |
197 contentfiles = utils.resourceref.neg_filter_resources(contentfiles,filter_regexp) |
228 contentfiles = utils.resourceref.neg_filter_resources(contentfiles,filter_regexp) |
198 for outfile in contentfiles: |
229 for outfile in contentfiles: |
199 sourcefile = "" |
230 sourcefile = "" |
200 targetfile = "" |
231 targetfile = "" |
201 |
232 |
202 if input_dir != None and outfile.startswith(input_dir): |
233 # For the startswith() check, make sure that input dir has a trailing slash |
|
234 if input_dir and input_dir[-1] != '/': input_dir_check = input_dir + '/' |
|
235 else: input_dir_check = input_dir |
|
236 |
|
237 if input_dir != None and (input_dir == outfile or outfile.startswith(input_dir_check)): |
203 sourcefile = datacontainer.get_value(outfile) |
238 sourcefile = datacontainer.get_value(outfile) |
204 if flatten: |
239 if flatten: |
205 targetfile = utils.resourceref.join_refs([output_dir, os.path.basename(outfile)]) |
240 targetfile = utils.resourceref.join_refs([output_dir, os.path.basename(outfile)]) |
206 targetfile = utils.resourceref.norm(targetfile) |
241 targetfile = utils.resourceref.norm(targetfile) |
207 else: |
242 else: |
218 targetfile = utils.resourceref.replace_dir(sourcefile,fulldir,output_dir) |
253 targetfile = utils.resourceref.replace_dir(sourcefile,fulldir,output_dir) |
219 |
254 |
220 if output_file: |
255 if output_file: |
221 #Renaming output if defined |
256 #Renaming output if defined |
222 targetfile = targetfile.replace(os.path.basename(targetfile), output_file) |
257 targetfile = targetfile.replace(os.path.basename(targetfile), output_file) |
223 |
258 |
224 if sourcefile and targetfile: |
259 if sourcefile and targetfile: |
225 copylist.append((sourcefile,targetfile, external)) |
260 copylist.append((sourcefile,targetfile,external)) |
226 return copylist |
261 return copylist |
227 |
262 |
|
263 def uses_layer(self, layer): |
|
264 layered_content = layer.layered_content().list_keys() |
|
265 for f in self.get_full_copy_list(): |
|
266 for file in layered_content: |
|
267 if utils.resourceref.norm(os.path.join(utils.resourceref.get_path(layer.get_path()), 'content', file)) == f[0]: |
|
268 return True |
|
269 return False |
|
270 |
|
271 def uses_layers(self, layers, context): |
|
272 # Use the base implementation to check with refs first |
|
273 if super(ContentImpl, self).uses_layers(layers, context): |
|
274 return True |
|
275 |
|
276 # Then check if any of the files in the copy list come from the layers |
|
277 copy_list = self.get_full_copy_list() |
|
278 for layer in layers: |
|
279 layered_content = layer.layered_content().list_keys() |
|
280 for f in copy_list: |
|
281 for file in layered_content: |
|
282 if utils.resourceref.norm(os.path.join(utils.resourceref.get_path(layer.get_path()), 'content', file)) == f[0]: |
|
283 return True |
|
284 return False |
|
285 |
|
286 |
228 class ContentImplReaderBase(object): |
287 class ContentImplReaderBase(object): |
229 FILE_EXTENSIONS = ['content', 'contentml'] |
288 FILE_EXTENSIONS = ['content', 'contentml'] |
230 |
289 |
231 @classmethod |
290 @classmethod |
232 def read_impl(cls, resource_ref, configuration, etree): |
291 def read_impl(cls, resource_ref, configuration, etree): |
249 |
308 |
250 return impl |
309 return impl |
251 |
310 |
252 class ContentImplReader1(ContentImplReaderBase, plugin.ReaderBase): |
311 class ContentImplReader1(ContentImplReaderBase, plugin.ReaderBase): |
253 NAMESPACE = 'http://www.s60.com/xml/content/1' |
312 NAMESPACE = 'http://www.s60.com/xml/content/1' |
|
313 NAMESPACE_ID = 'contentml1' |
|
314 ROOT_ELEMENT_NAME = 'content' |
254 parser_class = contentmlparser.Content1Parser |
315 parser_class = contentmlparser.Content1Parser |
|
316 |
|
317 @classmethod |
|
318 def get_schema_data(cls): |
|
319 return pkg_resources.resource_string('contentplugin', 'xsd/contentml.xsd') |
255 |
320 |
256 class ContentImplReader2(ContentImplReaderBase, plugin.ReaderBase): |
321 class ContentImplReader2(ContentImplReaderBase, plugin.ReaderBase): |
257 NAMESPACE = 'http://www.s60.com/xml/content/2' |
322 NAMESPACE = 'http://www.s60.com/xml/content/2' |
|
323 NAMESPACE_ID = 'contentml2' |
|
324 ROOT_ELEMENT_NAME = 'content' |
258 parser_class = contentmlparser.Content2Parser |
325 parser_class = contentmlparser.Content2Parser |
|
326 |
|
327 @classmethod |
|
328 def get_schema_data(cls): |
|
329 return pkg_resources.resource_string('contentplugin', 'xsd/contentml2.xsd') |