Skip to content

Commit fd45c0d

Browse files
committed
Initial commit of bager to git
0 parents  commit fd45c0d

16 files changed

+673
-0
lines changed

badger.rb

+210
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
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

badger_ui/.DS_Store

6 KB
Binary file not shown.

badger_ui/badger.jar

7.1 MB
Binary file not shown.

badger_ui/f1/badger.rb

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
require 'net/http'
2+
require 'rexml/document'
3+
require 'uri'
4+
require 'cgi'
5+
require 'optparse'
6+
require 'ostruct'
7+
require 'yaml'
8+
require 'open-uri'
9+
require 'f1/multipart'
10+
11+
12+
class Badger
13+
def initialize(finder_path,login,password)
14+
@finder_path = finder_path
15+
@login = login
16+
@password = password
17+
@cookie = login(login, password)
18+
raise "Login Failure" if @cookie.nil?
19+
end
20+
21+
def process(stem)
22+
overlay_url = upload_shapefile(stem)
23+
metadata = metadata_params(stem)
24+
upload_metadata(overlay_url, metadata, @cookie)
25+
attribute_data = attribute_params(overlay_url, stem, @cookie)
26+
update_attributes("#{overlay_url.sub(/\.xml$/,'')}/attributes", attribute_data, @cookie)
27+
end
28+
29+
private
30+
def login( username, password )
31+
uri = URI.parse(@finder_path)
32+
res = Net::HTTP.new(uri.host, uri.port).start do |http|
33+
#make the initial get to get the JSESSION cookie
34+
post = Net::HTTP::Post.new("/sessions")
35+
post.set_form_data( {'login' => username, 'password' => password} )
36+
response = http.request(post)
37+
case response
38+
when Net::HTTPFound
39+
puts "Badger got a cookie (logged in)"
40+
return response.response['set-cookie']
41+
else
42+
puts "No cookies for badger (login failed)"
43+
return nil
44+
end
45+
# get original cookie contains _f1gc_session=blahblahblah
46+
end
47+
end
48+
49+
def metadata_params(stem)
50+
mapping = {"overlay_meta"=>["lineage", "metadata_url", "contact_address", "contact_phone",
51+
"citation_url", "shared", "description", "contact_name",
52+
"english_reference_date"], "overlay"=>["name", "tag_cache"]}
53+
54+
# read in the metadata
55+
xml = "#{stem}.xml"
56+
raise IOError, "Metadata XML not found: #{xml}" unless File.exists?(xml)
57+
f = File.open(xml)
58+
metadata = REXML::Document.new(f)
59+
f.close()
60+
61+
params = Hash.new
62+
mapping.each do |set, attributes|
63+
attributes.each do |attribute|
64+
value = metadata.elements["//#{set.gsub(/_/,'-')}/#{attribute.gsub(/_/,'-')}"]
65+
params["#{set}[#{attribute}]"] = value.text unless value.nil?
66+
if(attribute == "tag_cache")
67+
params["#{set}[tag_list]"] = value.text unless value.nil?
68+
end
69+
end
70+
end
71+
return params
72+
end
73+
74+
def attribute_params(resource, stem, cookie=nil)
75+
# read in the metadata
76+
xml = "#{stem}.xml"
77+
raise IOError, "Metadata XML not found: #{xml}" unless File.exists?(xml)
78+
f = File.open(xml)
79+
metadata = REXML::Document.new(f)
80+
f.close()
81+
82+
url = URI.parse(resource)
83+
req = Net::HTTP::Get.new(url.path)
84+
req["Cookie"] = cookie
85+
response = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
86+
87+
current_metadata = REXML::Document.new(response.body)
88+
89+
new_attributes = metadata.root.elements["overlay-meta"].elements["data-attributes"]
90+
current_attributes = current_metadata.root.elements["overlay-meta"].elements["data-attributes"]
91+
92+
# now we actually need to build the request
93+
params = {}
94+
attributes = []
95+
# yes... I know
96+
current_attributes.elements.each do |child|
97+
a = {"original_name" => child.elements["original-name"].text, "id" => child.elements["id"].text}
98+
new_attributes.elements.each do |new_child|
99+
if new_child.elements["original-name"].text == child.elements["original-name"].text
100+
attributes << a.merge({"name" => new_child.elements["name"].text, "description" => new_child.elements["description"].text})
101+
break
102+
end
103+
end
104+
end
105+
106+
attributes.each_with_index do |a,i|
107+
a.each_pair do |k,v|
108+
params["data_attributes[#{i}][#{k}]"] = v
109+
end
110+
end
111+
112+
return params
113+
end
114+
115+
def upload_shapefile(stem)
116+
# generate the filenames
117+
shp = "#{stem}.shp"; shx = "#{stem}.shx"; dbf = "#{stem}.dbf"
118+
raise IOError, "File not found: #{shp}" unless File.exists?(shp)
119+
total_file_size = File.size(shp) + File.size(dbf) + File.size(shx)
120+
raise StandardError, "File is too large to upload: #{shp}" if (total_file_size > 10485760) # 10 MB
121+
# open the shapefile components
122+
shpfile = File.open(shp); shxfile = File.open(shx); dbffile = File.open(dbf)
123+
response = upload({"overlay[shp]" => shpfile, "overlay[dbf]" => dbffile, "overlay[shx]" => shxfile}, @cookie)
124+
shpfile.close; shxfile.close; dbffile.close
125+
if response.is_a?(Net::HTTPCreated)
126+
return response.header["location"]
127+
else
128+
raise StandardError, "Upload Failure: #{response.body} for #{stem}"
129+
end
130+
end
131+
132+
def upload( query,cookie = nil )
133+
url = URI.parse(@finder_path)
134+
req = Net::HTTP::Post.new("/overlays.xml")
135+
req["Cookie"] = cookie
136+
req.set_multipart_form_data(query)
137+
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
138+
end
139+
140+
def upload_metadata(resource, params, cookie=nil)
141+
url = URI.parse(resource)
142+
req = Net::HTTP::Put.new(url.path)
143+
req["Cookie"] = cookie
144+
req.set_form_data(params)
145+
response = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
146+
if response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPRedirection)
147+
return response
148+
else
149+
raise StandardError, "Metadata Fail: #{response.body} for #{resource}"
150+
end
151+
end
152+
153+
def update_attributes(resource, params, cookie=nil)
154+
upload_metadata(resource, params, cookie)
155+
end
156+
end

0 commit comments

Comments
 (0)