#!/usr/bin/env ruby # quick hack by Barclay Osborn # barclay@redgeek.net # # Yes, I know it's not the "rails way" require 'find' require 'ftools' require 'rubygems' require 'image_science' require 'active_record' require 'exifr' ############### Configuration # Site allowed, with resize options # Sizes are max sizes (will not be resized otherwise), retaining # aspect ratio, listed (w,h). # Keys in 'thumbnails' is the tag name # If you want mephisto's UI seamless, retain the # 'tiny' and 'thumb' sizes # If true, auto-article will automatically create an article with the # image in it. See the "article.body" assigned near the end of the # program. $sites = { 'your-domain.com' => { 'resize' => [600,400], 'thumbnails' => { 'tiny' => [50,50], 'thumb' => [120,120], 'mid' => [400,400], }, 'auto-article' => 0, }, 'another-domain.com' => { 'resize' => [800,800], 'thumbnails' => { 'tiny' => [50,50], 'thumb' => [120,120], 'mid' => [400,400], }, 'auto-article' => 1, } } # Threshold between using img.thumbnail and img.resize $thumb_thres = 200 # Extensions to search for (case insensitive) $exts = [ '.jpg', '.jpeg', ] # And their mime type mappings $content_type = { '.jpg' => 'image/jpeg', '.jpeg' => 'image/jpeg', } # various DB fields. Should be generalized $site_id = 1; $user_id = 1; $author_id = 1; $filter_id = 1; $site = ARGV.shift # The rails root: sitedir = "#{ENV['HOME']}/#{$site}/http" # Where to look for images to insert: srcdir = "#{sitedir}/data" ############### Functions def newAsset( name, file, tag, w, h, parent ) ext = File.extname( file ) ext = ext.downcase asset = Asset.new asset.content_type = $content_type[ext] asset.filename = File.basename( name ) asset.title = asset.filename asset.size = File.size( file ) asset.width = w asset.height = h asset.site_id = $site_id if !parent.nil? asset.thumbnails_count = $sites[$site]['thumbnails'].keys.length else asset.thumbnails_count = 0 end asset.user_id = $user_id if !tag.nil? asset.thumbnail = tag end return asset end ############### Validation params = {} site_ok = 0 $sites.keys.each do |s| if $site == s site_ok = 1 params = $sites[$site] puts "Checking #{$site} ... " end end if 0 == site_ok puts "site must be one of: " $sites.keys.each do |s| puts " #{s}" end exit end ############### Find potential files files = [] Find.find( srcdir ) do |path| if !FileTest.directory?(path) && File.size(path).nonzero? $exts.each do |ext| if File.extname( path ).downcase.eql?( ext.downcase ) files << path end end end end ############### Query the DB require "#{sitedir}/config/environment" additions = [] files.each do |file| additions = [] bname = File.basename( file ) print "checking file #{bname} ... " record = Asset.find( :first, :conditions => ['filename in (?)', bname] ) if !record.nil? print "skipping\n" else puts "not found, inserting" date = EXIFR::JPEG.new(file).date_time if date.nil? date = Time.now end outdir = "#{sitedir}/public/assets/#{date.year}/#{date.month}/#{date.day}" FileUtils.mkdir_p( outdir ) ext = File.extname( file ) outbase = "#{outdir}/" + File.basename( file, ext ) ext = ext.downcase ImageScience.with_image( file ) do |img| w = img.width h = img.height if w.zero? || h.zero? print " bogus image size: (#{w}x#{f})!\n" next end # save out the resized image, then work through the rest max_w = params['resize'][0] max_h = params['resize'][1] outfile = "#{outbase}#{ext}" outfile_tmp = "#{outbase}_tmp#{ext}" if w > max_w || h > max_h scale = [max_h.to_f / w.to_f, max_h.to_f / h.to_f].min new_w = (scale * w.to_f).to_i new_h = (scale * h.to_f).to_i img.resize( new_w, new_h ) do |lrg| lrg.save outfile_tmp end else img.save outfile_tmp end asset = newAsset( outfile, outfile_tmp, nil, new_w, new_h, true ) additions << [asset,outfile_tmp,outfile] params['thumbnails'].keys.each do |tag| if tag.eql?( 'RESIZE' ) next end max_w = params['thumbnails'][tag][0] max_h = params['thumbnails'][tag][1] outfile = "#{outbase}_#{tag}#{ext}" outfile_tmp = "#{outbase}_#{tag}_tmp#{ext}" if max_w < $thumb_thres && max_h < $thumb_thres img.thumbnail(max_w) do |thumb| thumb.save outfile_tmp asset = newAsset( outfile, outfile_tmp, tag, thumb.width, thumb.height, false ) additions << [asset,outfile_tmp,outfile] end else if w > max_w || h > max_h scale = [max_w.to_f / w.to_f, max_h.to_f / h.to_f].min new_w = (scale * w.to_f).to_i new_h = (scale * h.to_f).to_i img.resize( new_w, new_h ) do |img2| img2.save outfile_tmp end else img.save outfile_tmp end asset = newAsset( outfile, outfile_tmp, tag, new_w, new_h, false ) additions << [asset,outfile_tmp,outfile] end end end parent = additions.shift Asset.transaction { parent[0].created_at = date parent[0].save! FileUtils.mv( parent[1], parent[2] ) additions.each do |a| a[0].created_at = date a[0].parent_id = parent[0].id a[0].save! FileUtils.mv( a[1], a[2] ) end } if $sites[$site]['auto-article'].nonzero? article = Article.new article.version = 1 article.user_id = $user_id article.title = parent[0].title article.body = "![#{parent[0].title}][1]\n\n [1]: #{parent[0].public_filename}\n" article.published_at = date article.created_at = date article.updated_at = date article.author = $author_id # article.versioned_type = 'Article' article.site_id = $site_id article.filter = 'smartypants_filter' article.save! end end end