def process_image(ctx, source_image, dst_filename, width, height=None, crop=False): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ im = find_imagemagick( ctx.build_state.config['IMAGEMAGICK_EXECUTABLE']) quality = get_quality(source_image) resize_key = str(width) if height is not None: resize_key += 'x' + str(height) cmdline = [im, source_image] if crop: cmdline += ['-resize', resize_key + '^', '-gravity', 'Center', '-extent', resize_key] else: cmdline += ['-resize', resize_key] cmdline += ['-auto-orient', '-quality', str(quality), dst_filename] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def merge_pot(self, from_filenames, to_filename): msgcat = locate_executable('msgcat') cmdline = [msgcat, "--use-first"] cmdline.extend(from_filenames) cmdline.extend(("-o", to_filename)) reporter.report_debug_info('msgcat cmd line', cmdline) portable_popen(cmdline).wait()
def build_thumbnail_artifact(artifact): artifact.ensure_dir() vfilter = 'thumbnail,scale={rw}:{rh},crop={tw}:{th}'.format( rw=resize_dim.width, rh=resize_dim.height, tw=crop_dim.width, th=crop_dim.height, ) cmdline = [ ffmpeg, '-loglevel', '-8', '-ss', get_timecode(seek), # Input seeking since it's faster '-i', source_video, '-vf', vfilter, '-frames:v', '1', '-qscale:v', str(get_ffmpeg_quality(quality)), artifact.dst_filename, ] reporter.report_debug_info('ffmpeg cmd line', cmdline) proc = portable_popen(cmdline) if proc.wait() != 0: raise RuntimeError( 'ffmpeg exited with code {}'.format(proc.returncode)) if not os.path.exists(artifact.dst_filename): msg = ('Unable to create video thumbnail for {!r}. Maybe the seek ' 'is outside of the video duration?') raise RuntimeError(msg.format(source_video))
def process_image(ctx, source_image, dst_filename, width=None, height=None, mode=ThumbnailMode.DEFAULT, quality=None, offset=None, zoom=None): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ if width is None and height is None: raise ValueError("Must specify at least one of width or height.") im = find_imagemagick(ctx.build_state.config["IMAGEMAGICK_EXECUTABLE"]) if quality is None: quality = get_quality(source_image) resize_key = '' offset_key = '' gravity = 'Center' zoom_key = '100%' if width is not None: resize_key += str(width) if height is not None: resize_key += 'x' + str(height) if offset is not None and len(offset) == 2: offset_key = '%+d%+d' % ((offset[0] - width / 2), (offset[1] - height / 2)) gravity = 'NorthWest' if zoom is not None: zoom_key = '%d' % zoom + '%' print(gravity, offset_key, zoom_key, dst_filename) if mode == ThumbnailMode.STRETCH: resize_key += "!" cmdline = [im, source_image, "-auto-orient"] if mode == ThumbnailMode.CROP: cmdline += [ '-resize', zoom_key, '-gravity', gravity, '-extent', resize_key + offset_key, ] else: cmdline += ["-resize", resize_key] cmdline += ["-strip", "-colorspace", "sRGB"] cmdline += ["-quality", str(quality), dst_filename] reporter.report_debug_info("imagemagick cmd line", cmdline) portable_popen(cmdline).wait()
def merge_pot(self, from_filenames, to_filename): msgcat=locate_executable('msgcat') cmdline=[msgcat, "--use-first"] cmdline.extend(from_filenames) cmdline.extend(("-o", to_filename)) reporter.report_debug_info('msgcat cmd line', cmdline) portable_popen(cmdline).wait()
def build_artifact(self, artifact): ctx = get_ctx() source_out = self.build_state.make_named_temporary("less") map_out = self.build_state.make_named_temporary("less-sourcemap") here = os.path.dirname(self.source.source_filename) cmdline = [ "lessc", "--no-js", "--include-path=%s" % here, "--source-map=%s" % map_out, self.source.source_filename, source_out, ] reporter.report_debug_info("lessc cmd line", cmdline) proc = portable_popen(cmdline) if proc.wait() != 0: raise RuntimeError("lessc failed") with open(map_out) as f: dep_base = os.path.dirname(map_out) for dep in json.load(f).get("sources") or (): ctx.record_dependency(os.path.join(dep_base, dep)) artifact.replace_with_file(source_out)
def add(self, text, source): if not text in self.translations.keys(): self.translations[text] = [] reporter.report_debug_info('added to translation memory : ', truncate(text)) if not source in self.translations[text]: self.translations[text].append(source)
def process_image(ctx, source_image, dst_filename, width, height=None, crop=False): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ im = find_imagemagick(ctx.build_state.config['IMAGEMAGICK_EXECUTABLE']) quality = get_quality(source_image) resize_key = str(width) if height is not None: resize_key += 'x' + str(height) cmdline = [im, source_image] if crop: cmdline += [ '-resize', resize_key + '^', '-gravity', 'Center', '-extent', resize_key ] else: cmdline += ['-resize', resize_key] cmdline += ['-auto-orient', '-quality', str(quality), dst_filename] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def build_artifact(self, artifact): ctx = get_ctx() source_out = self.build_state.make_named_temporary('less') map_out = self.build_state.make_named_temporary('less-sourcemap') here = os.path.dirname(self.source.source_filename) exe = self.build_state.config['LESSC_EXECUTABLE'] if exe is None: exe = 'lessc' cmdline = [ exe, '--no-js', '--include-path=%s' % here, '--source-map=%s' % map_out, self.source.source_filename, source_out ] reporter.report_debug_info('lessc cmd line', cmdline) proc = portable_popen(cmdline) if proc.wait() != 0: raise RuntimeError('lessc failed') with open(map_out) as f: for dep in json.load(f).get('sources') or (): ctx.record_dependency(os.path.join(here, dep)) artifact.replace_with_file(source_out) @ctx.sub_artifact(artifact_name=artifact.artifact_name + '.map', sources=[self.source.source_filename]) def build_less_sourcemap_artifact(artifact): artifact.replace_with_file(map_out)
def parse_templates(self, to_filename): pybabel=locate_executable('pybabel') if pybabel is None: pybabel="/usr/bin/pybabel" cmdline=[pybabel, 'extract', '-F', 'babel.cfg', "-o", to_filename, "./"] reporter.report_debug_info('pybabel cmd line', cmdline) portable_popen(cmdline).wait()
def process_svg_image( ctx, source_image, dst_filename, width=None, height=None, mode=None, ): if width is None and height is None: raise ValueError("Must specify at least one of width or height.") # Because Lektor doesn't have a generic find program (only imagemagick), # only *nix is supported for simplicity. Imagemagick will be used as the # fallback on Windows, but it won't work well... if os.name == 'nt': return process_image(ctx, source_image, dst_filename, width, height, mode, 85) inkscape = locate_executable('inkscape') cmdline = [inkscape, source_image] if width is not None: cmdline += ["-w", str(width)] if height is not None: cmdline += ["-h", str(height)] # FIXME: This will only work with inkscape 1.0+ cmdline += ["--export-filename", dst_filename] reporter.report_debug_info("inkscape cmd line", cmdline) portable_popen(cmdline).wait()
def build_artifact(self, artifact): ctx = get_ctx() source_out = self.build_state.make_named_temporary('less') map_out = self.build_state.make_named_temporary('less-sourcemap') here = os.path.dirname(self.source.source_filename) exe = self.build_state.config['LESSC_EXECUTABLE'] if exe is None: exe = 'lessc' cmdline = [exe, '--no-js', '--include-path=%s' % here, '--source-map=%s' % map_out, self.source.source_filename, source_out] reporter.report_debug_info('lessc cmd line', cmdline) proc = portable_popen(cmdline) if proc.wait() != 0: raise RuntimeError('lessc failed') with open(map_out) as f: for dep in json.load(f).get('sources') or (): ctx.record_dependency(os.path.join(here, dep)) artifact.replace_with_file(source_out) @ctx.sub_artifact(artifact_name=artifact.artifact_name + '.map', sources=[self.source.source_filename]) def build_less_sourcemap_artifact(artifact): artifact.replace_with_file(map_out)
def _msg_merge(self): """Merges an existing <language>.po file with .pot file""" msgmerge = locate_executable('msgmerge') cmdline = [ msgmerge, self.FILENAME_PATTERN % self.language, "contents.pot", "-U", "-N", "--backup=simple" ] reporter.report_debug_info('msgmerge cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def _msg_fmt(self, locale_dirname): """Compile an existing <language>.po file into a .mo file""" msgfmt = locate_executable('msgfmt') cmdline = [ msgfmt, self.FILENAME_PATTERN % self.language, "-o", join(locale_dirname, "contents.mo") ] reporter.report_debug_info('msgfmt cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def _msg_init(self): """Generates the first <language>.po file""" msginit = locate_executable('msginit') cmdline = [ msginit, "-i", "contents.pot", "-l", self.language, "-o", self.FILENAME_PATTERN % self.language, "--no-translator" ] reporter.report_debug_info('msginit cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def parse_templates(self, to_filename): pybabel = locate_executable('pybabel') cmdline = [ pybabel, 'extract', '-F', 'babel.cfg', "-o", to_filename, "./" ] reporter.report_debug_info('pybabel cmd line', cmdline) try: portable_popen(cmdline).wait() except TypeError as err: traceback.print_exc(file=sys.stderr) print(err)
def build_thumbnail_artifact(artifact): resize_key = str(width) if height is not None: resize_key += 'x' + str(height) artifact.ensure_dir() cmdline = [im, source_image, '-resize', resize_key, '-auto-orient', '-quality', str(quality), artifact.dst_filename] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def translate_tag(self, s, *args, **kwargs): if not self.enabled: return s # no operation s = s.strip() ctx = get_ctx() if self.content_language==ctx.locale: translations.add(s,'(dynamic)') reporter.report_debug_info('added to translation memory (dynamic): ', truncate(s)) return s else: translator = gettext.translation("contents", join(self.i18npath,'_compiled'), languages=[ctx.locale], fallback = True) return trans(translator, s)
def build_thumbnail_artifact(artifact): resize_key = str(width) if height is not None: resize_key += 'x' + str(height) artifact.ensure_dir() cmdline = [ im, source_image, '-resize', resize_key, '-quality', str(quality), artifact.dst_filename ] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def process_image( ctx, source_image, dst_filename, width=None, height=None, mode=ThumbnailMode.DEFAULT, quality=None, ): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ if width is None and height is None: raise ValueError("Must specify at least one of width or height.") im = find_imagemagick(ctx.build_state.config["IMAGEMAGICK_EXECUTABLE"]) if quality is None: quality = get_quality(source_image) resize_key = "" if width is not None: resize_key += str(width) if height is not None: resize_key += "x" + str(height) if mode == ThumbnailMode.STRETCH: resize_key += "!" cmdline = [im, source_image, "-auto-orient"] if mode == ThumbnailMode.CROP: cmdline += [ "-resize", resize_key + "^", "-gravity", "Center", "-extent", resize_key, ] else: cmdline += ["-resize", resize_key] cmdline += ["-strip", "-colorspace", "sRGB"] cmdline += ["-quality", str(quality), dst_filename] reporter.report_debug_info("imagemagick cmd line", cmdline) portable_popen(cmdline).wait()
def process_image(ctx, source_image, dst_filename, width=None, height=None, mode=ThumbnailMode.DEFAULT, quality=None): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ if width is None and height is None: raise ValueError("Must specify at least one of width or height.") im = find_imagemagick(ctx.build_state.config['IMAGEMAGICK_EXECUTABLE']) if quality is None: quality = get_quality(source_image) resize_key = '' if width is not None: resize_key += str(width) if height is not None: resize_key += 'x' + str(height) if mode == ThumbnailMode.STRETCH: resize_key += '!' cmdline = [im, source_image, '-auto-orient'] if mode == ThumbnailMode.CROP: cmdline += [ '-resize', resize_key + '^', '-gravity', 'Center', '-extent', resize_key ] else: cmdline += ['-resize', resize_key] cmdline += ['-quality', str(quality), dst_filename] reporter.report_debug_info('imagemagick cmd line', cmdline) portable_popen(cmdline).wait()
def process_image( ctx, source_image, dst_filename, width=None, height=None, mode=None, quality=None, extra_params=None, ): """Build image from source image, optionally compressing and resizing. "source_image" is the absolute path of the source in the content directory, "dst_filename" is the absolute path of the target in the output directory. """ if width is None and height is None: raise ValueError("Must specify at least one of width or height.") im = find_imagemagick(ctx.build_state.config["IMAGEMAGICK_EXECUTABLE"]) if quality is None: quality = get_quality(source_image) resize_key = "" if width is not None: resize_key += str(width) if height is not None: resize_key += "x" + str(height) cmdline = [im, source_image, "-auto-orient"] cmdline += ["-resize", resize_key] if extra_params: cmdline.extend(extra_params) cmdline += ["-quality", str(quality), dst_filename] reporter.report_debug_info("imagemagick cmd line", cmdline) portable_popen(cmdline).wait()
def build_thumbnail_artifact(artifact): artifact.ensure_dir() vfilter = "thumbnail,scale={rw}:{rh},crop={tw}:{th}".format( rw=resize_dim.width, rh=resize_dim.height, tw=crop_dim.width, th=crop_dim.height, ) cmdline = [ ffmpeg, "-loglevel", "-8", "-ss", get_timecode(seek), # Input seeking since it's faster "-i", source_video, "-vf", vfilter, "-frames:v", "1", "-qscale:v", str(get_ffmpeg_quality(quality)), artifact.dst_filename, ] reporter.report_debug_info("ffmpeg cmd line", cmdline) proc = portable_popen(cmdline) if proc.wait() != 0: raise RuntimeError("ffmpeg exited with code {}".format(proc.returncode)) if not os.path.exists(artifact.dst_filename): msg = ( "Unable to create video thumbnail for {!r}. Maybe the seek " "is outside of the video duration?" ) raise RuntimeError(msg.format(source_video))
def _msg_fmt(self, locale_dirname): """Compile an existing <language>.po file into a .mo file""" msgfmt=locate_executable('msgfmt') cmdline=[msgfmt, self.FILENAME_PATTERN%self.language, "-o", join(locale_dirname,"contents.mo")] reporter.report_debug_info('msgfmt cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def add(self, text, source): if not text in self.translations.keys(): self.translations[text]=[] reporter.report_debug_info('added to translation memory : ', truncate(text)) if not source in self.translations[text]: self.translations[text].append(source)
def parse_templates(self, to_filename): pybabel=locate_executable('pybabel') cmdline=[pybabel, 'extract', '-F', 'babel.cfg', "-o", to_filename, "./"] reporter.report_debug_info('pybabel cmd line', cmdline) portable_popen(cmdline).wait()
def _msg_init(self): """Generates the first <language>.po file""" msginit=locate_executable('msginit') cmdline=[msginit, "-i", "contents.pot", "-l", self.language, "-o", self.FILENAME_PATTERN%self.language, "--no-translator"] reporter.report_debug_info('msginit cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()
def _msg_merge(self): """Merges an existing <language>.po file with .pot file""" msgmerge=locate_executable('msgmerge') cmdline=[msgmerge, self.FILENAME_PATTERN%self.language, "contents.pot", "-U", "-N", "--backup=simple"] reporter.report_debug_info('msgmerge cmd line', cmdline) portable_popen(cmdline, cwd=self.i18npath).wait()