From 8e16d7cc004b0f8dc4a6104e1a207f6c5bac2f13 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Mon, 4 Jan 2010 22:55:50 -0500 Subject: [PATCH] more filter separation --- Makefile | 4 ++ classes/Filter.rb | 23 ++++---- classes/InputFilter.rb | 5 ++ classes/OutputFilter.rb | 17 ++++++ minicomic-backend.rb | 112 +++++++++++++++++++------------------- tests/TestFilter.rb | 6 +- tests/TestOutputFilter.rb | 17 ++++++ tests/TestScheduler.rb | 2 - 8 files changed, 110 insertions(+), 76 deletions(-) create mode 100644 Makefile create mode 100644 classes/InputFilter.rb create mode 100644 classes/OutputFilter.rb create mode 100644 tests/TestOutputFilter.rb diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..827017c --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +.PHONY : test + +test : + testrb -b tests/* diff --git a/classes/Filter.rb b/classes/Filter.rb index e92b4d1..36c6e78 100644 --- a/classes/Filter.rb +++ b/classes/Filter.rb @@ -1,19 +1,16 @@ -require 'singleton' - class Filter - include Singleton @config = {} @cleanup = [] attr_accessor :config, :cleanup - + def initialize @config = {} @cleanup = [] end def cleanup - @cleanup.each do |f| + @cleanup.each do |f| if File.exists? f; File.unlink(f); end end end @@ -31,8 +28,8 @@ class Filter @config['height'] = (@config['height_inches'].to_f * @config['dpi'].to_f).to_i else @config.delete('height') - end - + end + if (!@config['width'] && !@config['height']) raise "No dimensions defined!" end @@ -44,7 +41,7 @@ class Filter # def config=(c) @config = c - + recalc_pixels end @@ -57,7 +54,7 @@ class Filter width = @config['width'] height = @config['height'] inkscape_target = target - + if @config['rotate'] case @config['rotate'] when 90, -90 @@ -68,16 +65,16 @@ class Filter if width && (width.to_i != 0); params << "-w #{width} "; end if height && (height.to_i != 0); params << "-h #{height} "; end - - system("inkscape -e \"#{inkscape_target}\" -y 1.0 #{params.join(" ")} \"#{input}\"") - + + system("inkscape -e \"#{inkscape_target}\" -y 1.0 #{params.join(" ")} \"#{input}\"") + if @config['rotate'] command = [ "\"#{inkscape_target}\"", "-rotate #{@config['rotate']}", "\"#{target}\"" ] - + convert(command) File.unlink(inkscape_target) end diff --git a/classes/InputFilter.rb b/classes/InputFilter.rb new file mode 100644 index 0000000..97de32f --- /dev/null +++ b/classes/InputFilter.rb @@ -0,0 +1,5 @@ +require 'filter' + +class InputFilter < Filter + OutputFilename = "tmp.png" +end diff --git a/classes/OutputFilter.rb b/classes/OutputFilter.rb new file mode 100644 index 0000000..1279e71 --- /dev/null +++ b/classes/OutputFilter.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/minicomic-backend.rb b/minicomic-backend.rb index 633c88e..7a9183f 100755 --- a/minicomic-backend.rb +++ b/minicomic-backend.rb @@ -3,10 +3,8 @@ require 'yaml' require 'time' -require File.dirname(__FILE__) + '/classes/Filter.rb' - -class InputFilter < Filter - OutputFilename = "tmp.png" +Dir[File.dirname(__FILE__) + "/classes/*.rb"].each do |file| + require file end class OutputFilter < Filter @@ -15,9 +13,9 @@ class OutputFilter < Filter # def filename(info) target = @config['target'] - info.each { |k,v| target = target.gsub("{#{k}}", v.to_s) } + info.each { |k,v| target = target.gsub("{#{k}}", v.to_s) } target - end + end # # get the output targets for this filter @@ -44,7 +42,7 @@ module PrintHandling page_width = @config['page_width_inches'] page_height = @config['page_height_inches'] end - + page_width *= @config['dpi'] page_height *= @config['dpi'] else @@ -65,7 +63,7 @@ module PrintHandling "-size #{page_width.to_i}x#{page_height.to_i}", "xc:white" ] - + case side when "none" command << "-gravity Center" @@ -82,21 +80,21 @@ module PrintHandling else command << "\"#{output}\"" end - + convert(command) end end class SVGToTempBitmap < InputFilter include PrintHandling - + # # 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 # @@ -108,7 +106,7 @@ class SVGToTempBitmap < InputFilter if @config['spread'] width, height = get_dimensions(filename) targets = [] - + [ [ "left", 0 ], [ "right", width / 2 ] ].each do |side, offset| target = filename + "-#{side}.png" command = [ @@ -118,16 +116,16 @@ class SVGToTempBitmap < InputFilter "+repage", "\"#{target}\"" ] - + convert(command) - + targets << target @cleanup << target end - + return targets end - + return filename end @@ -138,23 +136,23 @@ class SVGToTempBitmap < InputFilter # 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 } joined_files = [] - + page_width, page_height = calculate_page_size - + grid_width = page_width / width grid_height = page_height / height - + 0.upto(files.length - 1) do |i| x = i % width y = (i / width).floor - + if files[i].split('/').last != "blank" tmp_svg_output = OutputFilename + "-#{i}.png" inkscape(Dir.pwd + '/' + files[i], tmp_svg_output) - + joined_files << [ tmp_svg_output, x, y ] @cleanup << tmp_svg_output end @@ -164,20 +162,20 @@ class SVGToTempBitmap < InputFilter "-size #{page_width}x#{page_height}", "xc:white" ] - + joined_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 << OutputFilename - + convert(command) - + @cleanup << OutputFilename OutputFilename end @@ -191,11 +189,11 @@ class TempBitmapToWeb < OutputFilter quality = @config['quality'] ? @config['quality'] : 80 convert("\"#{input}\" -quality #{quality} \"#{output}\"") end - + def filename(info) if !@config['start_date']; raise "Must define a start date!"; end if !@config['period']; raise "Must define a period!"; end - + index = info['index'].to_i if index == 0 && @config['announce_date'] comic_date = @config['announce_date'] @@ -210,7 +208,7 @@ class TempBitmapToWeb < OutputFilter when "weekly" weeks_from_start = index end - + if @config['delay_at_index'] && @config['delay_length_weeks'] if index >= @config['delay_at_index'] weeks_from_start += @config['delay_length_weeks'] @@ -219,7 +217,7 @@ class TempBitmapToWeb < OutputFilter comic_date = Time.parse(@config['start_date']) + ((((day_of_week + weeks_from_start * 7) * 24) + 6) * 60 * 60) end - + info['date'] = comic_date.strftime("%Y-%m-%d") super(info) end @@ -247,9 +245,9 @@ module Pagination 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 @@ -262,7 +260,7 @@ module Pagination 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 end @@ -292,12 +290,12 @@ class TempBitmapToPaginatedPrint < OutputFilter 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'] @@ -306,7 +304,7 @@ class TempBitmapToPaginatedPrint < OutputFilter 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 @@ -371,7 +369,7 @@ if global['pages'] end else re = Regexp.new(global['match']) - + files = Dir[global['path']].sort.collect do |filename| if matches = re.match(filename) filename @@ -405,20 +403,20 @@ files.each do |filename| if ok filename_display = (filename.instance_of? Array) ? filename.join(", ") : filename - + puts "Examining #{filename_display}..." - + filename_parts = { 'page_index' => sprintf(page_index_format, page_index) } - + if matches - all, index, title = matches.to_a + all, index, title = matches.to_a else index = page_index - 1 title = "" end - + if global['title']; title = global['title'].gsub("{index}", index).gsub("{title}", title); end filename_parts['index'] = index filename_parts['title'] = title @@ -428,7 +426,7 @@ files.each do |filename| input = nil; output = nil fileinfo_key = (filename.instance_of? Array) ? filename.join(",") : filename - + file_fileinfo = (fileinfo_by_file[fileinfo_key]) ? fileinfo_by_file[fileinfo_key] : {} extension = File.extname((filename.instance_of? Array) ? filename[0] : filename).downcase @@ -450,7 +448,7 @@ files.each do |filename| input_obj = input.instance input_obj.config = info.dup.merge(fileinfo).merge(file_fileinfo) - + output_obj = output.instance output_obj.config = info.dup.merge(fileinfo).merge(file_fileinfo) @@ -459,9 +457,9 @@ files.each do |filename| end targets = output_obj.targets(filename_parts) - + rebuild = false - + [ targets ].flatten.each do |t| if !File.exists?(t) rebuild = true @@ -470,12 +468,12 @@ files.each do |filename| if File.basename(f) != "blank" if File.mtime(f) > File.mtime(t) rebuild = true - end + end end end end - end - + end + if rebuild any_rebuilt = true @@ -496,7 +494,7 @@ files.each do |filename| output_files << targets[i] end end - + input_obj.cleanup end if info['is_paginated'] @@ -505,11 +503,11 @@ files.each do |filename| end if info['rsync'] if !rsync_files_by_target[info['rsync']]; rsync_files_by_target[info['rsync']] = []; end - rsync_files_by_target[info['rsync']] << targets + rsync_files_by_target[info['rsync']] << targets end end end - + page_index += 1 end end @@ -517,13 +515,13 @@ 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 - + if info['rsync'] system("echo '#{rsync_files_by_target[info['rsync']].join("\n")}' | rsync -vru --files-from=- . #{info['rsync']}") end diff --git a/tests/TestFilter.rb b/tests/TestFilter.rb index 7b756a4..7a7ae73 100644 --- a/tests/TestFilter.rb +++ b/tests/TestFilter.rb @@ -1,5 +1,3 @@ -#!/usr/bin/ruby - require 'rubygems' require 'test/unit' require 'mockfs/override' @@ -28,7 +26,7 @@ class TestFilter < Test::Unit::TestCase 'dpi' => 10 } end - + [ 'width', 'height' ].each do |dim| assert_raise RuntimeError do @filter.config = { @@ -44,4 +42,4 @@ class TestFilter < Test::Unit::TestCase assert_equal(10, @filter.config['width']) end end -end \ No newline at end of file +end diff --git a/tests/TestOutputFilter.rb b/tests/TestOutputFilter.rb new file mode 100644 index 0000000..52d54d3 --- /dev/null +++ b/tests/TestOutputFilter.rb @@ -0,0 +1,17 @@ +require 'rubygems' +require 'test/unit' +require 'mocha' +require File.dirname(__FILE__) + '/../classes/OutputFilter.rb' + +class TestOutputFilter < Test::Unit::TestCase + def setup + @of = OutputFilter.new + @of.stubs(:recalc_pixels) + end + + def test_filename + @of.config = { 'target' => 'test{test}{test2}test3' } + assert_equal 'testtest4test5test3', @of.filename({ 'test' => 'test4', 'test2' => 'test5' }) + end +end + diff --git a/tests/TestScheduler.rb b/tests/TestScheduler.rb index 3625110..88dbeb8 100644 --- a/tests/TestScheduler.rb +++ b/tests/TestScheduler.rb @@ -1,5 +1,3 @@ -#!/usr/bin/ruby - require 'rubygems' require 'test/unit' require File.dirname(__FILE__) + '/../classes/Scheduler.rb'