pattulus
1/11/2013 - 11:16 PM

Dropzone Destination for filing images to a Jekyll uploads folder and returning Markdown links to relative paths

Dropzone Destination for filing images to a Jekyll uploads folder and returning Markdown links to relative paths

#!/usr/bin/ruby

# Dropzone Destination Info
# Name: Jekyll Image Filer
# Description: Files images in a Jekyll repo
# Handles: NSFilenamesPboardType
# Creator: Brett Terpstra
# URL: http://brettterpstra.com
# IconURL: http://brettterpstra.com/destinations/icons/jekyllfiler.png
# OptionsNIB: ChooseFolder
# Events: Dragged, Clicked

# Moves image files to the base folder selected in preferences and returns Markdown links
# Drag one or more image files:
# * creates /YYYY/MM/ folders as needed
# * does not overwrite existing files (_01, _02, ...)
# * returns inline Markdown image links for uploaded files (default set below)
#
# Click the destination:
# * convert link(s) in the clipboard to the opposite format (inline/reference)

require 'fileutils'
require 'logger'

$link_type = "liquid" # default Markdown or Liquid tag style: 'liquid', 'inline' or 'reference'

def e_sh(str)
  str.to_s.gsub(/(?=[^a-zA-Z0-9_.\/\-\x7F-\xFF\n])/, '\\').gsub(/\n/, "'\n'").sub(/^$/, "''")
end

def dragged
  # log = Logger.new(File.expand_path('~/Desktop/ImageFiler.log'),10,1024000)
  $dz.determinate(true)
  $dz.begin("Handling files")
  input = $items
  percent = filedcount = errorcount = 0
  inc = 100 / input.length
  urls = []
  input.each {|file_path|
    $dz.begin("Filing #{File.basename(file_path)}...")
    $dz.percent(percent)

    if File.basename(file_path) =~ /\.(jpeg|jpg|png|gif)$/
      # log.info(file_path)
      extension = File.basename(file_path).match(/\.(jpeg|jpg|png|gif)$/)[0]
      target_file = File.basename(file_path).gsub(/#{extension}$/,'').strip
      target_dir = ENV['EXTRA_PATH'] + "/" + Time.now.strftime('%Y/%m/').strip
      FileUtils.mkdir_p target_dir unless (File.directory? target_dir)

      while File.exists?(File.join(target_dir, target_file + extension)) do
        target_file = target_file + "_00" unless target_file =~ /_\d+/
        target_file.next!
      end

      target = File.join(target_dir, target_file + extension)

      begin
        # log.info("Copying #{file_path} to #{target}")
        FileUtils.cp(file_path,target)
        # compress the target file
        res = ""
        case File.extname(target)
        when /jpe?g/
          # log.info("Compressing JPEG")
          if File.exists?('/usr/local/bin/jpegoptim')
            res = %x{/usr/local/bin/jpegoptim -fopt --strip-all -m60 "#{target}"}
          end
        when /png/
          # log.info("Compressing PNG")
          if File.exists?('/usr/local/bin/pngcrush')
            res = %x{/usr/local/bin/pngcrush -q -ow "#{target}"}
          end
        end
        # log.info(res)
        if $link_type == "reference"
          urls.push("[#{target_file.gsub(/[^a-z0-9]/i,'')}]: #{target.gsub(/^.*?\/source/,'')}")
        elsif $link_type == "liquid"
          width = %x{sips -g pixelWidth "#{target}"|tail -n 1}.gsub(/pixelWidth: /,'').strip
          height = %x{sips -g pixelHeight "#{target}"|tail -n 1}.gsub(/pixelHeight: /,'').strip
          imgclass = width.to_i > 300 ? "aligncenter" : "alignright"
          urls.push("{% img #{imgclass} #{width} #{height} #{target.gsub(/^.*?\/source/,'')} %}")
        else
          urls.push("![](#{target.gsub(/^.*?\/source/,'')})")
        end
        filedcount += 1
      rescue => e
        # log.warn("FAILED filing #{File.basename(file_path)}: #{e}")
        errorcount += 1
        %x{/usr/local/bin/growlnotify -a "Dropzone.app" -s -m "Couldn't file #{File.basename(file_path)}" -t "Jekyll Image Filer"} if File.exists?("/usr/local/bin/growlnotify")
      end
    else
      errorcount += 1
    end
    percent = percent + inc
  }
  if filedcount > 0
    output = "Filed #{filedcount} images"
  else
    output = "No images filed"
  end
  output += ", #{errorcount} errors" if errorcount > 0
  # log.info(output)
  # log.close
  $dz.finish(output)
  $dz.url(false)
  %x{echo #{e_sh urls.join("\n")}|pbcopy}
  Process.exit
end

def clicked
  $dz.determinate(false)
  $dz.begin("Converting link format")
  input = %x{__CF_USER_TEXT_ENCODING=$UID:0x8000100:0x8000100 pbpaste}.strip
  if input =~ /^\!\[.*\)/
    input.gsub!(/\!\[(.*)\]\((.*?)\)/) { |match|
      title = $1 == '' ? '' : %Q{ "#{$1}"}
      path = $2
      link = path.gsub(/.*\/(.+)\.(jpg|png|gif|jpeg|svg)$/,"\\1").gsub(/[^a-z0-9]/i,'').downcase
      "[#{link}]: #{path}#{title}"
    }
  elsif input =~ /^\[.*?\]\: .*?\.(jpg|png|gif|jpeg|svg)( ".*?")?/
    input.gsub!(/^\[(.*?)\]\: (.*?\.(jpg|png|gif|jpeg|svg))( ".*?")?/,"![\\1](\\2\\4)")
  else
    $dz.error("Wrong format in clipboard")
  end
  $dz.finish("Clipboard link format converted")
  $dz.url(false)
  %x{echo #{e_sh input}|pbcopy}
end