#!/usr/bin/env ruby
#
# Copyright 2007-2009 David Shakaryan <omp@gentoo.org>
# Copyright 2007-2009 Brenden Matthews <brenden@diddyinc.com>
#
# Distributed under the terms of the GNU General Public License v3
#
# Special thanks to Christoph for a patch.
#

require 'getoptlong'
require 'tempfile'
require 'iconv'

argv = Array.new

quiet = false
url_only = false
help = false
filename = 'pasta'
want_xclip = true
xclip_buf = ''

# Pipe?
begin
	stdin = STDIN.read_nonblock(4096)
rescue Errno::EAGAIN
	# We just ignore this
end

opts = GetoptLong.new(
	[ '--help',     '-h', GetoptLong::NO_ARGUMENT       ],
	[ '--filename', '-f', GetoptLong::REQUIRED_ARGUMENT ],
	[ '--quiet',    '-q', GetoptLong::NO_ARGUMENT       ],
	[ '--url',      '-u', GetoptLong::NO_ARGUMENT       ],
	[ '--no-clip',  '-n', GetoptLong::NO_ARGUMENT       ]
)

opts.each do |opt, arg|
	case opt
	when '--help'
		help = true
	when '--filename'
		filename = arg
	when '--quiet'
		quiet = true
	when '--url'
		url_only = true
	when '--no-clip'
		want_xclip = false
	end
end

ARGV.each do |a| argv << a end

nocurl = false
curl = %x{curl --version 2> /dev/null}
if curl.empty?
	nocurl = true
	$stderr.puts 'Error: curl missing or not in path.  Cannot continue.'
	$stderr.puts
end

xclip = %x{which xclip 2> /dev/null}
if xclip.empty?
	want_xclip = false
end

if (ARGV.size < 1 and (stdin.nil? or stdin.empty?)) or help or nocurl
	$stderr.puts 'Usage:  ompload [-h|--help] [options] [file(s)]'
	$stderr.puts '  -q, --quiet     Only output errors and warnings'
	$stderr.puts '  -u, --url       Only output URL when finished'
	$stderr.puts '  -f, --filename  Filename to use when posting data'
	$stderr.puts '                  from stdin'
	$stderr.puts '  -n, --no-clip   Disable copying of URL to clipboard'
	$stderr.puts '                  (this feature uses the xclip tool)'
	$stderr.puts
	$stderr.puts '  You can supply a list of files or data via stdin (or both)'
	$stderr.puts
	$stderr.puts '  This script requires a copy of cURL in the path,'
	$stderr.puts '  and will automatically copy the list of URLs to.'
	$stderr.puts '  the X11 clipboard if the `xclip\' program is'
	$stderr.puts '  available in your PATH.'
	Process.exit
end

errors = 0

wait = 5

Url = 'http://ompldr.org/'
Max_size = 2**30

used_stdin = false
first = true

argv.each do |arg|
	if stdin.nil? and !used_stdin and !File.file?(arg)
		$stderr.puts "Invalid argument '#{arg}': file does not exist (or is not a regular file)."
		errors += 1
		next
	elsif !arg.empty? and File.size(arg) > Max_size
		$stderr.puts "Error omploading '#{arg}': file exceeds " + (Max_size).to_s + " bytes (size was " + File.size(arg).to_s + ")."
		errors += 1
		next
	end

	if !first
		# try not to hammer the server
		puts 'Sleeping for ' + wait.to_s + 's' if !quiet and !url_only
		sleep(wait)
	else
		first = false
	end

	tmp = Tempfile.new(filename)
	if !stdin.nil? and !used_stdin
		# upload from stdin
		puts "Progress for '#{arg}'" if !quiet and !url_only
		if quiet or url_only
			p = IO.popen("curl -s -F 'file1=@-;filename=\"#{filename}\"' #{Url}upload -o '#{tmp.path}'", "w+")
		else
			p = IO.popen("curl -# -F 'file1=@-;filename=\"#{filename}\"' #{Url}upload -o '#{tmp.path}'", "w+")
		end
		p.puts stdin
		p.close_write
		Process.wait
		used_stdin = true
	else
		# upload file
		puts "Progress for '#{arg}'" if !quiet and !url_only
		# escape quotes
		tmp_path = arg.gsub('"', '\"')
		if quiet or url_only
			%x{curl -s -F file1=@"#{tmp_path}" #{Url}upload -o '#{tmp.path}'}
		else
			%x{curl -# -F file1=@"#{tmp_path}" #{Url}upload -o '#{tmp.path}'}
		end
	end
	if !File.size?(tmp.path)
		$stderr.puts "Error omploading '#{arg}'"
		errors += 1
		next
	end
	output = IO.read(tmp.path)
	output = Iconv.conv('ASCII//IGNORE//TRANSLIT', 'UTF-8', output)

	# parse for an ID
	if output =~ /View file: <a href="v([A-Za-z0-9+\/]+)">/
		id = $1
		puts "Omploaded '#{arg}' to #{Url}v#{id}" if !quiet
		xclip_buf += "#{Url}v#{id}\n" unless !want_xclip
		wait = 5
	elsif output =~ /Slow down there, cowboy\./
		wait += 60
		argv << arg
		$stderr.puts "Got throttled when trying to ompload '#{arg}'"
		$stderr.puts "Increasing wait and attempting to continue..."
		errors += 1
	else
		$stderr.puts "Error omploading '#{arg}'"
		errors += 1
	end

end

if want_xclip and !xclip_buf.empty?
	p = IO.popen("xclip", "w+")
	p.puts xclip_buf
end

if !quiet and !url_only
	if errors < 1
		puts "Success."
	else
		puts "Finished with #{errors} errors."
	end
end

