#!/usr/bin/env ruby #-- # Upload script for flickr # Version 0.1 # Copyright (c) 2005 Bill Stilwell (bill@marginalia.org) #++ require 'net/http' require 'uri' require 'cgi' require 'optparse' require 'ostruct' require 'rexml/document' require 'multipartpost' require 'yaml' def post( query, headers={} ) Net::HTTP.start('www.flickr.com') do | con | con.post("/tools/uploader_go.gne", query, headers); end end options = OpenStruct.new opts = OptionParser.new opts.banner = "Usage: rflick.rb [options] filename" opts.on("-e [EMAIL]", "--email [EMAIL]", "Flickr email account") {|email| options.email = email } opts.on("-p [PASSWORD]", "--password [PASSWORD]", "Flickr password") {|password| options.password = password } opts.on("-f FILE", "--file FILE", "--photo FILE", "File to upload") {|photo| options.photo = photo } opts.on("-t=[TITLE]", "--title=[TITLE]", "Title of the photo") {|title| options.title = title } opts.on("-d=[DESCRIPTION]", "--description=[DESCRIPTION]", "--desc=[DESCRIPTION]", "Description of the photo") {|description| options.description = description } opts.on("--tags=[TAGS]", Array, "Tags to be applied (comma separated)") {|tags| options.tags = tags} opts.on("--is-private", "Set visibility to private") {|private| options.private = private} opts.on("--friend", "--friends", "Set friend viewing") { |friend| options.friend = friend } opts.on("--family", "Set family viewing") { |family| options.family = family } opts.on("-s", "--save", "Save options to config file") { |save| options.save = save } opts.on_tail("-h", "--help", "Show this message") do puts opts exit end files = opts.parse(ARGV) if files.length == 0 raise "You must specify at least one file!" end if options.tags options.tags.each do |tag| tag.gsub!(/^(.*) (.*)$/, '"\1 \2"') end end if test ?r, "#{ENV['HOME']}/.rflickrc" config = YAML.load(File.open("#{ENV['HOME']}/.rflickrc")) options.email = config['email'] if ! options.email options.password = config['password'] if ! options.password else puts "No config file, consider running with -s to create one." end if options.save conf = { "email" => options.email, "password" => options.password, } File.open("#{ENV['HOME']}/.rflickrc", "w") { |f| YAML.dump(conf, f)} puts "Config file saved." end params = { "email" => options.email, "password" => options.password, } params["title"] = options.title if options.title params["description"] = options.description if options.description params["tags"] = options.tags.join(" ") if options.tags params["is_public"] = 0 if options.private params["is_friend"] = 1 if options.friend params["is_family"] = 1 if options.family ids=[] for photo in files raise "File #{photo} doesn't exist or isn't readable." if ! test ?r, photo file = File.new( photo ) params["photo"] = file mp = MultipartPost.new query,header = mp.prepare_query(params) file.close response = post(query,header) xml = REXML::Document.new(response.body) status = xml.elements["/uploader/status"].text if status == "ok" ids.push(xml.elements["/uploader/photoid"].text); puts "#{photo} uploaded succesfully." elsif status == "fail" puts "Failure: #{xml.elements["/uploader/verbose"].text} (Code: #{xml.elements["/uploader/error"].text})" else puts "Unknown status message returned" end end if ids.size > 0 puts "Success! http://www.flickr.com/tools/uploader_edit.gne?ids=#{ids.join(',')}." else puts "no files uploaded." end