From cb4bba508bb4b648ac72df2423eac89d3b3be44f Mon Sep 17 00:00:00 2001 From: John Bintz Date: Sun, 12 Sep 2010 09:25:45 -0400 Subject: [PATCH] oops, stupid gitignore --- .gitignore | 1 - bin/minicomic-backend | 36 ++++ lib/minicomic-backend/config_loader.rb | 85 ++++++++ lib/minicomic-backend/file_processor.rb | 198 ++++++++++++++++++ lib/minicomic-backend/filter.rb | 60 ++++++ lib/minicomic-backend/image_processing.rb | 61 ++++++ lib/minicomic-backend/input_filter.rb | 10 + lib/minicomic-backend/output_filter.rb | 17 ++ lib/minicomic-backend/pagination.rb | 47 +++++ lib/minicomic-backend/print_handling.rb | 70 +++++++ lib/minicomic-backend/scheduler.rb | 99 +++++++++ lib/minicomic-backend/svg_to_temp_bitmap.rb | 120 +++++++++++ .../temp_bitmap_to_paginated_print.rb | 47 +++++ lib/minicomic-backend/temp_bitmap_to_print.rb | 17 ++ lib/minicomic-backend/temp_bitmap_to_web.rb | 31 +++ 15 files changed, 898 insertions(+), 1 deletion(-) create mode 100755 bin/minicomic-backend create mode 100644 lib/minicomic-backend/config_loader.rb create mode 100644 lib/minicomic-backend/file_processor.rb create mode 100644 lib/minicomic-backend/filter.rb create mode 100644 lib/minicomic-backend/image_processing.rb create mode 100644 lib/minicomic-backend/input_filter.rb create mode 100644 lib/minicomic-backend/output_filter.rb create mode 100644 lib/minicomic-backend/pagination.rb create mode 100644 lib/minicomic-backend/print_handling.rb create mode 100644 lib/minicomic-backend/scheduler.rb create mode 100644 lib/minicomic-backend/svg_to_temp_bitmap.rb create mode 100644 lib/minicomic-backend/temp_bitmap_to_paginated_print.rb create mode 100644 lib/minicomic-backend/temp_bitmap_to_print.rb create mode 100644 lib/minicomic-backend/temp_bitmap_to_web.rb diff --git a/.gitignore b/.gitignore index d3a31bb..692263c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ .project .DS_Store coverage/ -minicomic-backend diff --git a/bin/minicomic-backend b/bin/minicomic-backend new file mode 100755 index 0000000..7e1b4df --- /dev/null +++ b/bin/minicomic-backend @@ -0,0 +1,36 @@ +#!/usr/bin/ruby + +require 'yaml' +begin + require 'home_run' +rescue LoadError + STDERR.puts "Install home_run for faster date handling" +end + +require 'time' + +begin + require 'minicomic-backend' +rescue LoadError + $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) + require 'minicomic-backend' +end + +require 'minicomic-backend/config_loader' +require 'minicomic-backend/file_processor' + +if !ARGV[0] + STDERR.puts "Usage: #{File.basename(__FILE__)} " + exit 0 +end + +if !File.exists?(ARGV[0]) + STDERR.puts "#{ARGV[0]} doesn't exist!" + exit 1 +end + +config_loader = ConfigLoader.new +config = config_loader.load(ARGV[0]) + +file_processor = FileProcessor.new(config) +file_processor.process! diff --git a/lib/minicomic-backend/config_loader.rb b/lib/minicomic-backend/config_loader.rb new file mode 100644 index 0000000..3a054f9 --- /dev/null +++ b/lib/minicomic-backend/config_loader.rb @@ -0,0 +1,85 @@ +require 'minicomic-backend/scheduler' + +class ConfigLoader + def load(file) + config = load_yaml(file) + + if !config['Global'] + return false + end + + global = config['Global'] + + if !global['path'] + return false + end + + if !global['page_index_format'] + global['page_index_format'] = count_pattern(global['path']) + end + + files = [] + fileinfo_by_file = {} + + if global['pages'] + files = global['pages'].collect do |f| + result = nil + case f.class.to_s + when 'String' + result = global['path'] + f + if f == "blank" + fileinfo_by_file[result] = { 'file' => f } + end + when 'Hash' + if f['file'] + case f['file'].class.to_s + when 'String' + result = global['path'] + f['file'] + fileinfo_by_file[result] = f + when 'Array' + result = f['file'].collect { |sub_f| global['path'] + sub_f } + fileinfo_by_file[result.join(",")] = f + end + else + result = f + end + end + result + end + else + if global['match'] + re = Regexp.new(global['match']) + + files = Dir[global['path'] + '/*'].sort.collect do |filename| + if matches = re.match(filename) + filename + end + end.compact + end + end + + global['files'] = files + global['fileinfo_by_file'] = fileinfo_by_file + + config['Global'] = global + + scheduler = Scheduler.instance + config.each do |type, info| + if type != "Global" + if info['schedule'] + info['publish_dates'] = scheduler.schedule(info['schedule'], files.length) + end + end + end + + config + end + + def load_yaml(file) + YAML::load(File.open(file, "r")) + end + + def count_pattern(path) + "%0#{Math.log10(Dir[path].length).ceil}d" + end +end diff --git a/lib/minicomic-backend/file_processor.rb b/lib/minicomic-backend/file_processor.rb new file mode 100644 index 0000000..ab7588e --- /dev/null +++ b/lib/minicomic-backend/file_processor.rb @@ -0,0 +1,198 @@ +require 'minicomic-backend/svg_to_temp_bitmap' +require 'minicomic-backend/temp_bitmap_to_web' +require 'minicomic-backend/temp_bitmap_to_print' +require 'minicomic-backend/temp_bitmap_to_paginated_print' + +class FileProcessor + attr_accessor :config, :paginated_source_files, :page_index + + def initialize(config) + @page_index = 0 + @config = config + @paginated_source_files = {} + end + + def process! + @config['Global']['files'].each do |filename| + ok, fileinfo, filename = verify_filename(filename) + + if ok + filename_display = (filename.instance_of? Array) ? filename.join(", ") : filename + + puts "Examining #{filename_display}..." + + config.each do |type, info| + if type != "Global" + fileinfo_key = (filename.instance_of? Array) ? filename.join(",") : filename + + file_fileinfo = (@config['Global']['fileinfo_by_file'][fileinfo_key]) ? @config['Global']['fileinfo_by_file'][fileinfo_key] : {} + + file_fileinfo = info.dup.merge(fileinfo).merge(file_fileinfo) + + input_obj, output_obj, targets = construct_filters_and_targets(filename, file_fileinfo, ok) + + if determine_rebuild(targets, filename) + any_rebuilt = true + + puts "Rebuilding #{filename_display} (#{type})..." + puts " Using #{filename} as a source" + puts " and writing to #{targets.inspect}" + + do_build(targets, filename, input_obj, output_obj) + end + if info['is_paginated'] + if !@paginated_source_files[type]; @paginated_source_files[type] = []; end + @paginated_source_files[type] << targets + end + end + end + + @page_index += 1 + end + end + + config.each do |type, info| + if info['is_paginated'] + output = TempBitmapToPaginatedPrint + + output_obj = output.instance + output_obj.config = info.dup + + output_obj.paginate(paginated_source_files[type].flatten) + end + end + end + + def verify_filename(filename) + ok = true + fileinfo = {} + + if filename.instance_of? Hash + if filename['blank'] + ok = false + @config.each do |type, info| + if info['is_paginated'] + if !@paginated_source_files[type] + @paginated_source_files[type] = [] + end + @paginated_source_files[type] << nil + end + end + @page_index += 1 + else + if filename['file'] + fileinfo = filename + filename = fileinfo['file'] + else + ok = false + end + end + else + if @config['Global'] + if @config['Global']['match'] + ok = Regexp.new(@config['Global']['match']).match(filename) + end + end + end + + [ ok, fileinfo, filename ] + end + + def build_filename_parts(match_data) + filename_parts = { + 'page_index' => sprintf(@config['Global']['page_index_format'], @page_index) + } + + if match_data.is_a? MatchData + all, index, title = match_data.to_a + else + index = @page_index - 1 + title = "" + end + + if @config['Global']['title'] + title = @config['Global']['title'].gsub("{index}", index).gsub("{title}", title) + end + + filename_parts['index'] = index.to_i + filename_parts['title'] = title + + filename_parts + end + + def construct_filters_and_targets(filename, info, match_data) + input = nil; output = nil + + extension = File.extname((filename.instance_of? Array) ? filename[0] : filename).downcase + + case extension + when ".svg" + case File.extname(info['target']).downcase + when ".jpg", ".jpeg", ".png", ".gif" + input = ::SVGToTempBitmap + output = ::TempBitmapToWeb + when ".pdf" + input = ::SVGToTempBitmap + output = (info['is_paginated']) ? ::TempBitmapToPaginatedPrint : ::TempBitmapToPrint + end + end + + if !input; raise "No input handler for #{extension} defined"; end + if !output; raise "No output handler for #{File.extname(info['target']).downcase} defined"; end + + input_obj = input.new + input_obj.config = info + + output_obj = output.new + output_obj.config = info + + if info['is_paginated'] + output_obj.config['target'] += "-{page_index}.png" + end + + targets = output_obj.targets(build_filename_parts(match_data)) + + [ input_obj, output_obj, targets ] + end + + def file_mtime(file) + File.mtime(file) + end + + def determine_rebuild(targets, filename) + rebuild = false + + [ targets ].flatten.each do |t| + if !File.exists?(t) + rebuild = true + break + else + [ filename ].flatten.each do |f| + if File.basename(f) != "blank" + if file_mtime(f) > file_mtime(t) + rebuild = true + break + end + end + end + end + end + + rebuild + end + + def do_build(targets, filename, input_obj, output_obj) + tmp_files = input_obj.build(filename) + + case tmp_files.class.to_s + when "String" + output_obj.build(tmp_files, targets) + when "Array" + [0, 1].each do |i| + output_obj.build(tmp_files[i], targets[i], (i == 0) ? "left" : "right") + end + end + + input_obj.cleanup + end +end diff --git a/lib/minicomic-backend/filter.rb b/lib/minicomic-backend/filter.rb new file mode 100644 index 0000000..772b63a --- /dev/null +++ b/lib/minicomic-backend/filter.rb @@ -0,0 +1,60 @@ +require 'fileutils' + +class Filter + @config = {} + @cleanup = [] + + attr_accessor :config, :cleanup + + def initialize + @config = {} + @cleanup = [] + end + + def cleanup + @cleanup.each do |f| + FileUtils.rm(f) if File.file?(f) + end + end + + def recalc_pixels + if @config['print'] + if !@config['dpi']; raise "DPI not defined"; end + if (@config['dpi'].to_i.to_s) != @config['dpi'].to_s; raise "DPI not integer"; end + if @config['width_inches'] && (@config['width_inches'].to_f != 0) + @config['width'] = (@config['width_inches'].to_f * @config['dpi'].to_f).to_i + else + @config.delete('width') + end + if @config['height_inches'] && (@config['height_inches'].to_f != 0) + @config['height'] = (@config['height_inches'].to_f * @config['dpi'].to_f).to_i + else + @config.delete('height') + end + + if (!@config['width'] && !@config['height']) + raise "No dimensions defined!" + end + end + end + + # + # Set the config + # + def config=(c) + @config = c + + recalc_pixels + end + + # + # Get the dimensions of a file + # + def get_dimensions(input) + dimensions = nil + IO.popen("identify -format '%w,%h' \"#{input}\"") do |fh| + dimensions = fh.readlines.first.split(",").collect { |d| d.to_i } + end + dimensions + end +end diff --git a/lib/minicomic-backend/image_processing.rb b/lib/minicomic-backend/image_processing.rb new file mode 100644 index 0000000..b3cca47 --- /dev/null +++ b/lib/minicomic-backend/image_processing.rb @@ -0,0 +1,61 @@ +module ImageProcessing + def setup_inkscape(target) + params = [] + + width = @config['width'] + height = @config['height'] + inkscape_target = target + + if @config['rotate'] + case @config['rotate'] + when 90, -90 + t = width; width = height; height = t + inkscape_target = target + "-pre.png" + end + end + + if width && (width.to_i != 0) + params << "-w #{width}" + end + if height && (height.to_i != 0) + params << "-h #{height}" + end + + [ params, inkscape_target ] + end + + # + # Build a PNG from an SVG file + # + def inkscape(input, target) + params, inkscape_target = setup_inkscape(target) + + call_system("inkscape -e \"#{inkscape_target}\" -y 1.0 #{params.join(" ")} \"#{input}\"") + + handle_inkscape_rotation(inkscape_target, target) + end + + def handle_inkscape_rotation(inkscape_target, target) + if @config['rotate'] + command = [ + "\"#{inkscape_target}\"", + "-rotate #{@config['rotate']}", + "\"#{target}\"" + ] + + convert(command) + File.unlink(inkscape_target) + end + end + + def convert(command, verbose = false) + if verbose + puts "convert " + (verbose ? "-verbose " : "" ) + [ command ].flatten.join(" ") + end + call_system("convert " + (verbose ? "-verbose " : "" ) + [ command ].flatten.join(" ")) + end + + def call_system(command) + Kernel.system(command) + end +end diff --git a/lib/minicomic-backend/input_filter.rb b/lib/minicomic-backend/input_filter.rb new file mode 100644 index 0000000..70085f7 --- /dev/null +++ b/lib/minicomic-backend/input_filter.rb @@ -0,0 +1,10 @@ +require 'minicomic-backend/filter' + +class InputFilter < Filter + attr_accessor :output_filename + + def initialize + super + @output_filename = "tmp.png" + end +end diff --git a/lib/minicomic-backend/output_filter.rb b/lib/minicomic-backend/output_filter.rb new file mode 100644 index 0000000..1279e71 --- /dev/null +++ b/lib/minicomic-backend/output_filter.rb @@ -0,0 +1,17 @@ +require File.dirname(__FILE__) + '/Filter.rb' + +class OutputFilter < Filter + # + # get the output filename for this filter + # + def filename(info) + target = @config['target'] + info.each { |k,v| target = target.gsub("{#{k}}", v.to_s) } + target + end + + # + # get the output targets for this filter + # + def targets(info); filename(info); end +end diff --git a/lib/minicomic-backend/pagination.rb b/lib/minicomic-backend/pagination.rb new file mode 100644 index 0000000..3d17cf3 --- /dev/null +++ b/lib/minicomic-backend/pagination.rb @@ -0,0 +1,47 @@ +# +# Code to help with pagination +# +module Pagination + def paginate(files) + if !files.instance_of? Array; raise "File list must be an array"; end + if files.length == 0; raise "File list cannot be empty"; end + if (files.length % 4) != 0; raise "File list must be divisible by 4"; end + + tmp_pdf_files = [] + sheet_faces = setup_sheet_faces(files) + + sheet_faces.each_index do |i| + f = @config['target'] + "-#{i}.pdf" + process_pagination(f, i, sheet_faces.length, *sheet_faces[i]) + tmp_pdf_files << f + end + + system("pdfjoin #{tmp_pdf_files.collect { |f| "\"#{f}\"" }.join(" ")} --outfile \"#{@config['target']}\"") + end + + def setup_sheet_faces(files) + number_of_sheet_faces = (files.length / 4) * 2 + + sheet_faces = [] + + is_right = 1 + is_descending = 1 + sheet_face_index = 0 + + files.each do |file| + if !sheet_faces[sheet_face_index]; sheet_faces[sheet_face_index] = []; end + + sheet_faces[sheet_face_index][is_right] = file + is_right = 1 - is_right + + sheet_face_index += is_descending + + if sheet_face_index == number_of_sheet_faces + sheet_face_index -= 1 + is_descending = -1 + end + end + + sheet_faces + end +end diff --git a/lib/minicomic-backend/print_handling.rb b/lib/minicomic-backend/print_handling.rb new file mode 100644 index 0000000..1016a48 --- /dev/null +++ b/lib/minicomic-backend/print_handling.rb @@ -0,0 +1,70 @@ +module PrintHandling + # + # calculate the page size in PPI + # + def calculate_page_size + ok = false + + if @config['dpi'] + if @config['page_size'] + case @config['page_size'].downcase + when "letter", "letter_portrait" + page_width = 8.5; page_height = 11; ok = true + when "letter_landscape" + page_width = 11; page_height = 8.5; ok = true + when "half_letter_landscape" + page_width = 5.5; page_height = 8.5; ok = true + end + else + if @config['page_width_inches'] && @config['page_height_inches'] + page_width = @config['page_width_inches'] + page_height = @config['page_height_inches'] + ok = true + end + end + + if ok + page_width *= @config['dpi'].to_i + page_height *= @config['dpi'].to_i + end + end + + if !ok + page_width = @config['page_width'] + page_height = @config['page_height'] + end + + [ page_width, page_height ] + end + + # + # align the provided image on a white page + # + def build_for_print(input, output, side = "none") + page_width, page_height = calculate_page_size + command = [ + "-density #{@config['dpi']}", + "-size #{page_width.to_i}x#{page_height.to_i}", + "xc:white" + ] + + case side + when "none" + command << "-gravity Center" + when "left" + command << "-gravity East" + when "right" + command << "-gravity West" + end + + command << "-draw 'image Over 0,0 0,0 \"#{input}\"'" + + if output[0,1] == "|" + command << output[1..-1] + else + command << "\"#{output}\"" + end + + convert(command) + end +end diff --git a/lib/minicomic-backend/scheduler.rb b/lib/minicomic-backend/scheduler.rb new file mode 100644 index 0000000..8425d67 --- /dev/null +++ b/lib/minicomic-backend/scheduler.rb @@ -0,0 +1,99 @@ +require 'singleton' + +class Scheduler + include Singleton + + WEEKLY = [ 7 ] + DAILY = [ 1 ] + + def skip_to_dow(date, dow) + if dow.is_a? String + dow = Date::DAYNAMES.collect { |d| d.downcase }.index(dow.downcase) + end + + if dow.is_a? Fixnum + while date.wday != dow + date += 1 + end + end + date + end + + def ok_to_add(date, index, prior, breaks) + ok = true + breaks.each do |i| + if i['from'] && i['to'] + if (i['from'] <= date) && (i['to'] >= date) + ok = false + end + end + + if i['at_index'] && i['for_days'] && prior + if i['at_index'] == index + ok = (date > (prior + i['for_days'])) + end + end + end + ok + end + + def schedule(parameters, to_produce) + dates = [] + + if parameters['start'] + current = parameters['start'] + prior = nil + + breaks = parameters['breaks'] || [] + + all_strings = true + parameters['interval'].each do |i| + if !i.is_a? String + all_strings = false + break + end + end + + if all_strings + parameters['interval'].each_index do |i| + interval = parameters['interval'].shift + if current == skip_to_dow(current, interval) + parameters['interval'].unshift(interval) + break + else + parameters['interval'].push(interval) + end + end + end + + index = 0 + while dates.length < to_produce + interval = parameters['interval'].shift + + what_to_add = nil + + if interval.is_a? String + current = skip_to_dow(current, interval) + + what_to_add = 1 + end + + if ok_to_add(current, index, prior, breaks) + dates << current + prior = current + index += 1 + end + + if interval.is_a? Fixnum + what_to_add = interval + end + + current += what_to_add + + parameters['interval'] << interval + end + end + + dates + end +end diff --git a/lib/minicomic-backend/svg_to_temp_bitmap.rb b/lib/minicomic-backend/svg_to_temp_bitmap.rb new file mode 100644 index 0000000..703cc90 --- /dev/null +++ b/lib/minicomic-backend/svg_to_temp_bitmap.rb @@ -0,0 +1,120 @@ +require 'minicomic-backend/print_handling' +require 'minicomic-backend/image_processing' +require 'minicomic-backend/input_filter' + +class SVGToTempBitmap < InputFilter + include PrintHandling, ImageProcessing + + # + # select which build method to use based on the number of provided images. + # + def build(input) + (input.instance_of? Array) ? multiple(input) : single(input) + end + + # + # process a single input file, possibly splitting it into two output files if it's a spread + # + def single(input) + filename = Dir.pwd + '/' + @output_filename + inkscape(Dir.pwd + '/' + input, filename) + @cleanup << filename + + if @config['spread'] + targets = build_spread(filename) + @cleanup.concat targets + return targets + end + + filename + end + + def build_spread(filename) + width, height = get_dimensions(filename) + targets = [] + + [ [ "left", 0 ], [ "right", width / 2 ] ].each do |side, offset| + target = filename + "-#{side}.png" + command = [ + "\"#{filename}\"", + "-gravity Northwest", + "-crop #{width/2}x#{height}+#{offset}+0", + "+repage", + "\"#{target}\"" + ] + + convert(command) + + targets << target + end + + targets + end + + # + # combine multiple input files onto a single page-sized canvas. + # images are added left-to-right and top-to-bottom starting from the top-left of the page. + # leave a grid square blank by passing the filename "/blank". + # + def multiple(files) + if @config['spread']; raise "Spreads and grids combined do not make sense"; end + + width, height = @config['grid'].split("x").collect { |f| f.to_f } + + page_width, page_height = calculate_page_size + + grid_width = page_width / width + grid_height = page_height / height + + joined_files = join_files(files, width) + + command = [ + "-size #{page_width}x#{page_height}", + "xc:white" + ] + + command.concat generate_joined_files_command(joined_files, grid_width, grid_height) + + command << "\"#{@output_filename}\"" + + convert(command) + + @cleanup.concat joined_files.collect { |file, x, y| file } + @cleanup << @output_filename + + @output_filename + end + + def join_files(files, width) + joined_files = [] + + files.each_index do |i| + x = i % width + y = (i / width).floor + + if files[i].split('/').last != "blank" + tmp_file = @output_filename + "-#{i}.png" + inkscape(Dir.pwd + '/' + files[i], tmp_file) + + joined_files << [ tmp_file, x, y ] + end + end + + joined_files + end + + def generate_joined_files_command(files, grid_width, grid_height) + command = [] + + files.each do |file, x, y| + image_width, image_height = get_dimensions(file) + + x_offset = (grid_width - image_width) / 2 + y_offset = (grid_height - image_height) / 2 + + command << "\"#{file}\" -geometry +#{x * grid_width + x_offset}+#{y * grid_height + y_offset} -composite" + end + + command + end +end diff --git a/lib/minicomic-backend/temp_bitmap_to_paginated_print.rb b/lib/minicomic-backend/temp_bitmap_to_paginated_print.rb new file mode 100644 index 0000000..c83a29d --- /dev/null +++ b/lib/minicomic-backend/temp_bitmap_to_paginated_print.rb @@ -0,0 +1,47 @@ +require 'minicomic-backend/output_filter' +require 'minicomic-backend/print_handling' +require 'minicomic-backend/pagination' +require 'minicomic-backend/image_processing' + +# +# Convert bitmap files to a paginated print-ready file +# +class TempBitmapToPaginatedPrint < OutputFilter + include PrintHandling, Pagination, ImageProcessing + + def build(input, output, side = "none") + build_for_print(input, output, side) + end + + def targets(info) + (@config['spread'] == true) ? [ filename(info) + "-left.png", filename(info) + "-right.png" ] : filename(info) + end + + def process_pagination(output, face, total_faces, left, right) + page_width, page_height = calculate_page_size + + commands = [ + "-size #{page_width * 2}x#{page_height}", + "xc:white" + ] + + left_creep = 0 + right_creep = 0 + if @config['page_thickness'] + max_creep = (total_faces / 2) + + left_creep = ((max_creep - (face - max_creep).abs) * @config['page_thickness'].to_f * @config['dpi'].to_i).floor + right_creep = ((max_creep - (total_faces - face - max_creep).abs) * @config['page_thickness'].to_f * @config['dpi'].to_i).floor + end + + if left + commands << "\"#{left}\" -geometry +#{left_creep.to_i}+0 -composite" + end + if right + commands << "\"#{right}\" -geometry +#{(page_width + right_creep).to_i}+0 -composite" + end + commands << "-colorspace RGB -depth 8 pnm:- | sam2p -c:lzw -m:dpi:#{(72.0 * (72.0 / @config['dpi'].to_f))} - PDF:\"#{output}\"" + + convert(commands) + end +end diff --git a/lib/minicomic-backend/temp_bitmap_to_print.rb b/lib/minicomic-backend/temp_bitmap_to_print.rb new file mode 100644 index 0000000..be2a1e8 --- /dev/null +++ b/lib/minicomic-backend/temp_bitmap_to_print.rb @@ -0,0 +1,17 @@ +require 'minicomic-backend/output_filter' +require 'minicomic-backend/print_handling' + +# +# Convert a bitmap to a single page print for proofing +# +class TempBitmapToPrint < OutputFilter + include PrintHandling + + def build(input, output) + build_for_print(input, "| pbm:- | sam2p -c:lzw -m:dpi:#{calculate_dpi} - PDF:\"#{output}\"") + end + + def calculate_dpi + (72.0 * (72.0 / @config['dpi'].to_f)) + end +end diff --git a/lib/minicomic-backend/temp_bitmap_to_web.rb b/lib/minicomic-backend/temp_bitmap_to_web.rb new file mode 100644 index 0000000..25a4c44 --- /dev/null +++ b/lib/minicomic-backend/temp_bitmap_to_web.rb @@ -0,0 +1,31 @@ +require 'minicomic-backend/output_filter' +require 'minicomic-backend/image_processing' +require 'fileutils' + +# +# Process an input file for the Web +# +class TempBitmapToWeb < OutputFilter + include ImageProcessing + + def build(input, output) + FileUtils.mkdir_p(File.split(output).first) + quality = @config['quality'] ? @config['quality'] : 80 + convert("\"#{input}\" -quality #{quality} \"#{output}\"") + end + + def filename(info) + info['date'] = @config['publish_dates'][info['index'].to_i - 1].strftime(@config['date_format']) + info['subdir'] = '' + if @config['subdirs'] + @config['subdirs'].each do |dir, subdir_info| + if Range.new(subdir_info['from'].to_i, subdir_info['to'].to_i).include? info['index'].to_i + info['subdir'] = dir + File::SEPARATOR + break + end + end + end + + super(info) + end +end