placemaker 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ gem 'curb'
4
+ gem 'nokogiri'
5
+
6
+ group :test do
7
+ gem 'rspec', '1.3.0'
8
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,14 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ curb (0.7.9)
5
+ nokogiri (1.4.4)
6
+ rspec (1.3.0)
7
+
8
+ PLATFORMS
9
+ ruby
10
+
11
+ DEPENDENCIES
12
+ curb
13
+ nokogiri
14
+ rspec (= 1.3.0)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Justin S. Leitgeb
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,76 @@
1
+ = Description
2
+
3
+ Yahoo! Placemaker is a freely available geoparsing Web service. It helps developers make their applications location-aware by
4
+ identifying places in unstructured and atomic content - feeds, web pages, news, status updates - and returning geographic metadata
5
+ for geographic indexing and markup.
6
+
7
+ This library is a Ruby interface for accessing the {Yahoo PlaceMaker API}[http://developer.yahoo.com/geo/placemaker/].
8
+
9
+ = Installation
10
+
11
+ Assuming that you've set up your ruby environment to pull gems from GitHub
12
+ (see {the GitHub instructions if you haven't yet done this}[http://gems.github.com]),
13
+ install placemaker with the following command:
14
+
15
+ sudo gem install jsl-placemaker
16
+
17
+ = Usage
18
+
19
+ The following is an example of using the Placemaker gem to read places in a standard feed. You'll have to get a Yahoo App ID first if you haven't
20
+ already done so.
21
+
22
+ require 'placemaker'
23
+ p = Placemaker::Client.new(:appid => YOUR_APP_ID, :document_url => 'http://feeds.feedburner.com/wooster', :document_type => 'text/xml')
24
+ p.fetch!
25
+
26
+ This will make a call to the Placemaker service and populate the Placemaker::Client object with data about the places in the content that you
27
+ sent to Yahoo. The information that you'll be interested in may be divided into "documents" and "meta-data."
28
+
29
+ You can also use placemaker with a document that you upload. Use +document_content+ in the configuration options instead of +document_url+, and
30
+ make sure to set the appropriate value for +document_type+. Acceptable mime types are text/plain, text/html, text/xml, text/rss, application/xml,
31
+ and application/rss+xml. The following is an example of using jsl-placemaker to encode content that you upload:
32
+
33
+ p = Placemaker::Client.new(:appid => YOUR_APP_ID, :document_content => 'railsconf was in las vegas this year', :document_type => 'text/plain')
34
+ p.fetch!
35
+
36
+ Afterwards, you have access to the same Placemaker::Client methods as if you had pointed placemaker to a +document_url+.
37
+
38
+ == Documents
39
+
40
+ Once you've run the +fetch!+ method on the Placemaker::Client, you may invoke the method +documents+ which will return a set of Placemaker::Document
41
+ objects corresponding to each of the entries in the feed given to the placemaker service. For example, if you gave a +document_url+ pointing
42
+ to a feed containing 15 entries, there will be 15 documents in the resulting client object.
43
+
44
+ The following are methods that you may invoke on each of the Placemaker::Document objects to find out more about the place information that
45
+ Yahoo was able to glean from the input document:
46
+
47
+ * place_details - Returns a Placemaker::Location object that is a container for one named place mentioned in the document
48
+ * administrative_scope - Returns a Placemaker::Location object that is a container for the smallest administrative place that best describes the document
49
+ * geographic_scope - Returns a Placemaker::Location object that is a container for the smallest place that best describes the document
50
+ * extents - Returns a Placemaker::Extents object that is a container for the the map extents covering the places mentioned in the document
51
+
52
+ Below is a summary of the methods that these objects respond to. You may wish to browse the Placemaker rdoc files for these classes to see
53
+ for more details.
54
+
55
+ === Placemaker::Location
56
+
57
+ Placemaker::Location objects contain a woe_id, name, location_type and centroid.
58
+
59
+ * woe_id - permanent identifier for the place
60
+ * name - fully qualified name for the place
61
+ * location_type - type name for the place
62
+ * centroid - centroid for the place, responds to +lat+ and +lng+
63
+
64
+ === Placemaker::Extents
65
+
66
+ Placemaker::Extents are bounding boxes for an area of interest. They respond to methods for +center+, +south_west+ and +north_east+. In
67
+ all of these cases, they return a Placemaker::Coordinates object responding to +lat+ and +lng+.
68
+
69
+ == Meta-data
70
+
71
+ The request to the Yahoo place coding service returns information about the request. You may invoke the methods +processing_time+,
72
+ +version+, and +document_length+ to find out more about the request.
73
+
74
+ = Author
75
+
76
+ Justin S. Leitgeb, justin@phq.org
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ require 'rake'
5
+ require 'spec/rake/spectask'
6
+ require 'rake/rdoctask'
7
+
8
+ require 'lib/placemaker'
9
+
10
+ desc 'Test the plugin.'
11
+ Spec::Rake::SpecTask.new(:spec) do |t|
12
+ t.spec_opts = ["--format", "progress", "--colour"]
13
+ t.libs << 'lib'
14
+ t.verbose = true
15
+ end
16
+
17
+ desc "Run all the tests"
18
+ task :default => :spec
19
+
20
+ desc 'Generate documentation'
21
+ Rake::RDocTask.new(:rdoc) do |rdoc|
22
+ rdoc.rdoc_dir = 'rdoc'
23
+ rdoc.title = 'Placemaker'
24
+ rdoc.options << '--line-numbers' << '--inline-source'
25
+ rdoc.rdoc_files.include('README.rdoc')
26
+ rdoc.rdoc_files.include('lib/placemaker/**/*.rb')
27
+ end
28
+
@@ -0,0 +1,75 @@
1
+ require 'placemaker/xml_parser'
2
+
3
+ module Placemaker
4
+
5
+ # Main interface to the Placemaker API.
6
+ class Client
7
+ POST_FIELDS = %w[ appid document_content document_url document_type document_title
8
+ auto_disambiguate focus_woe_id input_language output_type ].map{|f| f.to_sym}
9
+
10
+ def initialize(options = {})
11
+ @options = options
12
+ @options[:appid] ||= ENV['PLACEMAKER_APPID']
13
+
14
+ @xml_parser = Placemaker::XmlParser.new('NODOC')
15
+
16
+ verify_content_set
17
+ verify_document_type_set
18
+ end
19
+
20
+ # Fetches the place information for input parameters from the Yahoo Placemaker service
21
+ def fetch!
22
+ fields = POST_FIELDS.reject{|f| @options[f].nil? }.map do |f|
23
+ # Change ruby-form fields to url type, e.g., document_content => documentContent
24
+ cgi_param = f.to_s.gsub(/\_(.)/) {|s| s.upcase}.gsub('_', '').sub(/url/i, 'URL')
25
+ Curl::PostField.content(cgi_param, @options[f])
26
+ end
27
+
28
+ res = Curl::Easy.http_post('http://wherein.yahooapis.com/v1/document', *fields)
29
+ @xml_parser = Placemaker::XmlParser.new(res.body_str)
30
+ end
31
+
32
+ # Returns a collection of Placemaker::Document items as containers for content location information
33
+ def documents
34
+ @xml_parser.documents
35
+ end
36
+
37
+ # time in seconds to process the document
38
+ def processing_time
39
+ @xml_parser.processing_time
40
+ end
41
+
42
+ # version of the software used to process the document
43
+ def version
44
+ @xml_parser.version
45
+ end
46
+
47
+ # length in bytes of the document
48
+ def document_length
49
+ @xml_parser.document_length
50
+ end
51
+
52
+ # Create convenience methods to access post fields from the @options hash, mostly for testing.
53
+ POST_FIELDS.each do |f|
54
+ define_method(f) do # def appid
55
+ @options[f] # @options[:appid]
56
+ end # end
57
+ end
58
+
59
+ private
60
+
61
+ def verify_document_type_set
62
+ valid_types = %w[
63
+ text/plain
64
+ text/html text/xml text/rss
65
+ application/xml application/rss+xml
66
+ ]
67
+
68
+ raise ArgumentError, "Document type must be in #{valid_types.join(', ')}" unless valid_types.include?(@options[:document_type])
69
+ end
70
+
71
+ def verify_content_set
72
+ raise ArgumentError, "Either document_url or document_content must be set" if (@options[:document_content].nil? && @options[:document_url].nil?)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,13 @@
1
+ module Placemaker
2
+ class Coordinates
3
+ include Placemaker::XmlHelper
4
+
5
+ def lat
6
+ @nodeset.search('.//xmlns:latitude', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').inner_text.to_f
7
+ end
8
+
9
+ def lng
10
+ @nodeset.search('.//xmlns:longitude', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').inner_text.to_f
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ require 'placemaker/xml_helper'
2
+ require 'placemaker/place_details'
3
+ require 'placemaker/location'
4
+ require 'placemaker/extents'
5
+ require 'placemaker/reference'
6
+
7
+ module Placemaker
8
+
9
+ class Document
10
+ include Placemaker::XmlHelper
11
+
12
+ # Returns a Placemaker::Location object that is a container for one named place mentioned in the document
13
+ def place_details
14
+ @nodeset.search('.//xmlns:placeDetails', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').map do |p|
15
+ Placemaker::PlaceDetails.new(p)
16
+ end
17
+ end
18
+
19
+ # Returns a Placemaker::Location object that is a container for the smallest administrative place that best describes the document
20
+ def administrative_scope
21
+ as = @nodeset.search('.//xmlns:administrativeScope', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').first
22
+ Placemaker::Location.new(as) unless as.nil?
23
+ end
24
+
25
+ # Returns a Placemaker::Location object that is a container for the smallest place that best describes the document
26
+ def geographic_scope
27
+ gs = @nodeset.search('.//xmlns:geographicScope', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').first
28
+ Placemaker::Location.new(gs) unless gs.nil?
29
+ end
30
+
31
+ # Returns a Placemaker::Extents object that is a container for the the map extents covering the places mentioned in the document
32
+ def extents
33
+ extents = @nodeset.search('.//xmlns:extents', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').first
34
+ Placemaker::Extents.new(extents) unless extents.nil?
35
+ end
36
+
37
+ def reference_list
38
+ @nodeset.search('.//xmlns:referenceList[1]/xmlns:reference', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').map do |reference|
39
+ Placemaker::Reference.new(reference)
40
+ end
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,25 @@
1
+ require 'placemaker/coordinates'
2
+
3
+ module Placemaker
4
+
5
+ # container for the the map extents covering the places mentioned in the document
6
+ class Extents
7
+ include Placemaker::XmlHelper
8
+
9
+ # coordinates of center (WGS84)
10
+ def center
11
+ Placemaker::Coordinates.new(@nodeset.search('.//xmlns:center', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema'))
12
+ end
13
+
14
+ # coordinates of southwest corner of bounding box (WGS84)
15
+ def south_west
16
+ Placemaker::Coordinates.new(@nodeset.search('.//xmlns:southWest', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema'))
17
+ end
18
+
19
+ # coordinates of northeast corner of bounding box (WGS84)
20
+ def north_east
21
+ Placemaker::Coordinates.new(@nodeset.search('.//xmlns:northEast', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema'))
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,35 @@
1
+ require 'placemaker/coordinates'
2
+
3
+ module Placemaker
4
+
5
+ # Parses and contains data for +place+, +administrative scope+ and +geographic scope+ elements.
6
+ class Location
7
+ include Placemaker::XmlHelper
8
+
9
+ # permanent identifier for the place
10
+ def woe_id
11
+ nested_node('woeId').to_i
12
+ end
13
+
14
+ # fully qualified name for the place
15
+ def name
16
+ nested_node('name')
17
+ end
18
+
19
+ # place type name for the place
20
+ def location_type
21
+ nested_node('type')
22
+ end
23
+
24
+ # centroid for the place
25
+ def centroid
26
+ Placemaker::Coordinates.new(@nodeset.search('.//xmlns:centroid', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema'))
27
+ end
28
+
29
+ private
30
+
31
+ def nested_node(name)
32
+ @nodeset.search(".//xmlns:#{name}", 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').inner_text
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ module Placemaker
2
+
3
+ # container for one named place mentioned in the document
4
+ class PlaceDetails
5
+ include Placemaker::XmlHelper
6
+
7
+ # Returns a Placemaker::Location object as a container for place information.
8
+ def place
9
+ Placemaker::Location.new(@nodeset.search('.//xmlns:place', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema'))
10
+ end
11
+
12
+ # type of match (0=text or text and coordinates, 1=coordinates only)
13
+ def match_type
14
+ nested_node('matchType').to_i
15
+ end
16
+
17
+ # relative weight of the place within the document (range 1-100)
18
+ def weight
19
+ nested_node('weight').to_i
20
+ end
21
+
22
+ # confidence that the document mentions the place (range 1-10)
23
+ def confidence
24
+ nested_node('confidence').to_i
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ module Placemaker
2
+
3
+ class Reference
4
+ include Placemaker::XmlHelper
5
+
6
+ def woe_ids
7
+ nested_node('woeIds')
8
+ end
9
+
10
+ def start
11
+ nested_node('start')
12
+ end
13
+
14
+ def end
15
+ nested_node('end')
16
+ end
17
+
18
+ def is_plain_text_marker
19
+ nested_node('isPlainTextMarker')
20
+ end
21
+
22
+ def text
23
+ nested_node('text')
24
+ end
25
+
26
+ def type
27
+ nested_node('type')
28
+ end
29
+
30
+ def xpath
31
+ nested_node('xpath')
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ module Placemaker
2
+ module XmlHelper
3
+ def initialize(nodeset)
4
+ @nodeset = nodeset
5
+ end
6
+
7
+ # Returns the inner text of a node with the given name under the current @nodeset
8
+ def nested_node(name)
9
+ @nodeset.search(".//xmlns:#{name}", 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').inner_text
10
+ end
11
+
12
+ private :nested_node
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ require 'placemaker/document'
2
+
3
+ module Placemaker
4
+ class XmlParser
5
+ def initialize(xml_body)
6
+ @body = xml_body
7
+ @xml = Nokogiri::XML(xml_body)
8
+ end
9
+
10
+ # time in seconds to process the document
11
+ def processing_time
12
+ @xml.xpath('.//xmlns:processingTime', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').inner_text.to_f
13
+ end
14
+
15
+ # version of the software used to process the document
16
+ def version
17
+ @xml.xpath('.//xmlns:version', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').inner_text.strip
18
+ end
19
+
20
+ # length in bytes of the document
21
+ def document_length
22
+ @xml.xpath('.//xmlns:documentLength', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').inner_text.to_i
23
+ end
24
+
25
+ # Returns a set of Placemaker::Document objects as containers for content location information
26
+ def documents
27
+ @xml.xpath('//xmlns:document', 'xmlns' => 'http://wherein.yahooapis.com/v1/schema').map do |d|
28
+ Placemaker::Document.new(d)
29
+ end
30
+ end
31
+
32
+ end
33
+ end
data/lib/placemaker.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'curb'
3
+ require 'nokogiri'
4
+ require 'cgi'
5
+
6
+ dir = File.dirname(__FILE__)
7
+ $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
8
+
9
+ require 'placemaker/client'