|
| 1 | +#!/usr/bin/env ruby |
| 2 | + |
| 3 | +#-- |
| 4 | +# Upload script for Finder! |
| 5 | +# Version 0.1 |
| 6 | +# Copyright (c) 2008 Andrew Turner |
| 7 | +# Copyright (c) 2005 Bill Stilwell ([email protected]) |
| 8 | +#++ |
| 9 | + |
| 10 | +require 'net/http' |
| 11 | +require 'rexml/document' |
| 12 | +require 'uri' |
| 13 | +require 'cgi' |
| 14 | +require 'optparse' |
| 15 | +require 'ostruct' |
| 16 | +require 'yaml' |
| 17 | +require 'multipart' |
| 18 | + |
| 19 | +$finder_path = "http://finder.subie" |
| 20 | +#BATCH_FILE_FORMAT = "kml" |
| 21 | +BATCH_FILE_FORMAT = "shp" |
| 22 | + |
| 23 | +def login( username, password ) |
| 24 | + uri = URI.parse($finder_path) |
| 25 | + res = Net::HTTP.new(uri.host, uri.port).start do |http| |
| 26 | + #make the initial get to get the JSESSION cookie |
| 27 | + post = Net::HTTP::Post.new("/sessions") |
| 28 | + post.set_form_data( {'login' => username, 'password' => password} ) |
| 29 | + response = http.request(post) |
| 30 | + case response |
| 31 | + when Net::HTTPFound |
| 32 | + puts "Badger got a cookie (logged in)" |
| 33 | + else |
| 34 | + puts "No cookies for badger (login failed)" |
| 35 | + end |
| 36 | + # get original cookie contains _f1gc_session=blahblahblah |
| 37 | + cookie = response.response['set-cookie'] |
| 38 | + end |
| 39 | +end |
| 40 | + |
| 41 | +def upload( query,cookie = nil ) |
| 42 | + url = URI.parse($finder_path) |
| 43 | + req = Net::HTTP::Post.new("/overlays.xml") |
| 44 | + req["Cookie"] = cookie |
| 45 | + req.set_multipart_form_data(query) |
| 46 | + res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) } |
| 47 | +end |
| 48 | + |
| 49 | + |
| 50 | +def metadata(overlay_id, params, cookie = nil ) |
| 51 | + url = URI.parse($finder_path) |
| 52 | + req = Net::HTTP::Put.new("/overlays/#{overlay_id}.xml") |
| 53 | + req["Cookie"] = cookie |
| 54 | + req.set_form_data(params) |
| 55 | + res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) } |
| 56 | +end |
| 57 | + |
| 58 | + |
| 59 | +if __FILE__ == $0 |
| 60 | + |
| 61 | + # Parse the command line options |
| 62 | + options = OpenStruct.new |
| 63 | + opts = OptionParser.new |
| 64 | + opts.banner = "Usage: badger.rb [options] filename" |
| 65 | + opts.on("-e [USERNAME]", "--user [USERNAME]", "GeoCommons account username") {|username| options.username = username } |
| 66 | + opts.on("-p [PASSWORD]", "--password [PASSWORD]", "GeoCommons password") {|password| options.password = password } |
| 67 | + opts.on("-f FILE", "--file FILE", "--overlay FILE", "File to upload") {|overlay| options.overlay = overlay } |
| 68 | + opts.on("-t=[TITLE]", "--title=[TITLE]", "Title of the overlay") {|title| options.title = title } |
| 69 | + opts.on("-d=[DESCRIPTION]", "--description=[DESCRIPTION]", "--desc=[DESCRIPTION]", "Description of the overlay") {|description| options.description = description } |
| 70 | + opts.on("--tags=[TAGS]", Array, "Tags to be applied (comma separated)") {|tags| options.tags = tags} |
| 71 | + opts.on("--is-private", "Set visibility to private") {|private| options.private = private} |
| 72 | + opts.on("-s", "Store the credentials to a configuration file") {|save| options.save = save} |
| 73 | + opts.on("--meta=[METAFILE]", "Metadata Filename") {|metadata| options.metadata = metadata} |
| 74 | + opts.on("--batch=[DIRECTORY]", "Batch upload a directory") {|batch| options.batch = batch} |
| 75 | + opts.on("--finder=[FINDER URL]", "Finder web address") {|finder| options.finder = finder; $finder_path = finder} |
| 76 | + opts.on("-c", "Provide a terminal interface to get username and password") {|terminal| options.terminal = terminal} |
| 77 | + |
| 78 | + opts.on_tail("-h", "--help", "Show this message") do |
| 79 | + puts opts |
| 80 | + exit |
| 81 | + end |
| 82 | + |
| 83 | + files = opts.parse(ARGV) |
| 84 | + if options.batch |
| 85 | + files = Dir.glob(options.batch.gsub(/\/$/,'') + "/*.xml") |
| 86 | + elsif files.length == 0 |
| 87 | + raise "You must specify at least one file or a batch upload directory!" |
| 88 | + end |
| 89 | + |
| 90 | + # Split the tags |
| 91 | + if options.tags |
| 92 | + options.tags.each do |tag| |
| 93 | + tag.gsub!(/^(.*) (.*)$/, '"\1 \2"') |
| 94 | + end |
| 95 | + end |
| 96 | + |
| 97 | + # if options.terminal |
| 98 | + # options.username = ask("Enter your Finder! username: ") {|q| q.echo = false} unless options.username |
| 99 | + # options.password = ask("Enter your Finder! password: ") {|q| q.echo = false} unless options.password |
| 100 | + # options.finder = ask("Enter the URL to Finder!: ") {|q| q.echo = false} unless options.finder |
| 101 | + # options.batch = ask("Batch upload directory?: ") {|q| q.echo = false} unless options.batch |
| 102 | + # end |
| 103 | + |
| 104 | + # Optionally load or save the login credentials to a stored file |
| 105 | + # TODO: store the password as a hash |
| 106 | + if test ?r, "#{ENV['HOME']}/.geocommonsrc" |
| 107 | + config = YAML.load(File.open("#{ENV['HOME']}/.geocommonsrc")) |
| 108 | + options.username = config['username'] if ! options.username |
| 109 | + options.password = config['password'] if ! options.password |
| 110 | + else |
| 111 | + # puts "No config file, consider running with -s to create one." |
| 112 | + end |
| 113 | + |
| 114 | + if options.save |
| 115 | + conf = { |
| 116 | + "username" => options.username, |
| 117 | + "password" => options.password, |
| 118 | + } |
| 119 | + File.open("#{ENV['HOME']}/.geocommonsrc", "w") { |f| YAML.dump(conf, f)} |
| 120 | + puts "Config file saved." |
| 121 | + end |
| 122 | + |
| 123 | + ids=[] |
| 124 | + cookie = options.username.nil? ? nil : login(options.username, options.password) |
| 125 | + for overlay in files |
| 126 | + if options.batch |
| 127 | + options.metadata = overlay |
| 128 | + overlay = options.metadata.gsub(/\.xml/,'') |
| 129 | + else |
| 130 | + overlay = overlay.gsub(/\.shp/, '') |
| 131 | + end |
| 132 | + |
| 133 | + shp = "#{overlay}.shp" |
| 134 | + shx = "#{overlay}.shx" |
| 135 | + dbf = "#{overlay}.dbf" |
| 136 | + xml = "#{overlay}.xml" |
| 137 | + |
| 138 | + puts "Overlay: #{overlay}" |
| 139 | + |
| 140 | + # Upload the overlay file |
| 141 | + raise "File #{overlay} doesn't exist or isn't readable." if ! test ?r, shp |
| 142 | + shpfile = File.open( shp ) |
| 143 | + shxfile = File.open( shx ) |
| 144 | + dbffile = File.open( dbf ) |
| 145 | + #xmlfile = File.open( xml ) |
| 146 | + params = {} |
| 147 | + params["overlay[shp]"] = shpfile |
| 148 | + params["overlay[shx]"] = shxfile |
| 149 | + params["overlay[dbf]"] = dbffile |
| 150 | + |
| 151 | + response = upload(params, cookie) |
| 152 | + |
| 153 | + shpfile.close |
| 154 | + shxfile.close |
| 155 | + dbffile.close |
| 156 | + |
| 157 | + case response |
| 158 | + when Net::HTTPCreated |
| 159 | + ids << response.header["location"] |
| 160 | + else |
| 161 | + puts "error uploading file: #{response.body}." |
| 162 | + next |
| 163 | + end |
| 164 | + puts response.message.inspect |
| 165 | + overlay_id = response.header["location"].match(/(\d+)\.xml/)[1] |
| 166 | + |
| 167 | + # Upload the overlay metadata |
| 168 | + params = {} |
| 169 | + mapping = {"overlay_meta"=>["lineage", "metadata_url", "contact_address", "contact_phone", |
| 170 | + "citation_url", "shared", "description", "contact_name", |
| 171 | + "english_reference_date"], "overlay"=>["name"]} |
| 172 | + |
| 173 | + if options.metadata |
| 174 | + f = File.open(xml) |
| 175 | + overlay = REXML::Document.new(f) |
| 176 | + f.close() |
| 177 | + |
| 178 | + mapping.each do |set, attributes| |
| 179 | + attributes.each do |attribute| |
| 180 | + value = overlay.elements["//#{set.gsub(/_/,'-')}/#{attribute.gsub(/_/,'-')}"] |
| 181 | + params["#{set}[#{attribute}]"] = value.text unless value.nil? |
| 182 | + end |
| 183 | + end |
| 184 | + |
| 185 | + tags = REXML::XPath.match(overlay, "//tag/name").collect { |t| t.text } |
| 186 | + params["overlay[tag_list]"] = tags |
| 187 | + |
| 188 | + |
| 189 | + else |
| 190 | + params["overlay[name]"] = options.title if options.title |
| 191 | + params["overlay_meta[description]"] = options.description if options.description |
| 192 | + params["overlay[tag_list]"] = options.tags.join(" ") if options.tags |
| 193 | + params["overlay_meta[shared]"] = options.private ? false : true |
| 194 | + end |
| 195 | + |
| 196 | + response = metadata(overlay_id, params, cookie) |
| 197 | + |
| 198 | + case response |
| 199 | + when Net::HTTPOK |
| 200 | + puts "Uploaded! #{ids.last.gsub(/\.xml/,'')}" |
| 201 | + |
| 202 | + else |
| 203 | + |
| 204 | + puts "no files uploaded." |
| 205 | + puts response.body |
| 206 | + end |
| 207 | + end |
| 208 | + |
| 209 | + |
| 210 | +end |
0 commit comments