class Location

Constants

COORD_PATTERN
DEFAULT_ACCURACY

Attributes

accuracy[RW]
latitude[RW]
longitude[RW]
name[RW]
place[RW]

Public Class Methods

new(photo) click to toggle source
# File lib/flickru/location.rb, line 19
def initialize photo
  dir   = File.basename File.dirname(photo)
  name, place, accuracy = Location.parse dir
  raise RuntimeError, "#{dir}, name not provided" if name.nil?
  @name = name
  begin
    @place     = place.nil? ? name : place
    @latitude, @longitude = Location.locate @place
    @accuracy  = Location.s_to_accuracy(accuracy ? accuracy : DEFAULT_ACCURACY)
  rescue RuntimeError
    raise if place
    raise RuntimeError, "location #{name} not found" if accuracy
    @place, @latitude, @longitude, @accuracy = nil # no location
  end
end

Private Class Methods

geowiki(place) click to toggle source
# File lib/flickru/location.rb, line 101
def Location.geowiki place
  wiki = open("https://en.wikipedia.org/wiki/#{URI::encode(place)}").read
  tool = open(wiki.tr("\"", "\n").split("\n").grep(/geohack/) \
                  .first.sub(/^\/\//,'http://').sub('&','&')).read
  geo  = tool.split("\n").grep(/<span class="geo"/).first
  latitude  = geo.sub(/^.*"Latitude">/, '').sub(/<\/span>, .*/, '')
  longitude = geo.sub(/.*"Longitude">/, '').sub(/<\/span>.*$/, '')
  latitude + ", " + longitude
end
locate(place) click to toggle source
# File lib/flickru/location.rb, line 63
def Location.locate place
  the_place = place # needed for RuntimeError reporting
  begin
    place = Location.geowiki place \
      if place !~ /^#{COORD_PATTERN}, *#{COORD_PATTERN}$/
    if place =~ /^#{COORD_PATTERN}, *#{COORD_PATTERN}$/
      # latitude, longitude
      [place.sub(/, *#{COORD_PATTERN}$/, ''), place.sub(/^#{COORD_PATTERN}, */, '')]
    else
      raise RuntimeError
    end
  rescue
    raise RuntimeError, "location #{the_place} not found"
  end
end
parse(location) click to toggle source
# File lib/flickru/location.rb, line 51
  def Location.parse location
# TODO special characters MAY be escaped
    idx_accuracy = location.index('#') ? location.index('#') : location.length
    idx_place    = location.index('@') ? location.index('@') : idx_accuracy

    name     = location.sub(/[@#].*$/, '').strip | nil
    place    = location.index('@') ? location.sub(/^.*@/, '').sub(/\#.*$/, '').strip : nil
    accuracy = location.index('#') ? location.sub(/^.*#/, '').strip : nil

    [name, place, accuracy]
  end
s_to_accuracy(str) click to toggle source
# File lib/flickru/location.rb, line 79
def Location.s_to_accuracy str
  case str.downcase
  when "world"   then 1
  when "country" then 3
  when "region"  then 6
  when "city"    then 11
  when "street"  then 16
  else raise ArgumentError, "unknown accuracy label '#{str}'"
  end
end

Public Instance Methods

nil?() click to toggle source
# File lib/flickru/location.rb, line 35
def nil?
  Ruby.assert("@accuracy.nil? implies @latitude.nil? and @longitude.nil?") {
    @accuracy.nil? or not (@latitude.nil? and @longitude.nil?)
  }

  @accuracy.nil?
end
to_s() click to toggle source
# File lib/flickru/location.rb, line 43
def to_s
  place = @place.nil? ? "an undefined place" : @place
  "#{@name.black} at #{place.black} (~#{accuracy_to_s.black}) " +
  "on lat: #{@latitude.black}, lon: #{@longitude.black}"
end

Private Instance Methods

accuracy_to_s() click to toggle source
# File lib/flickru/location.rb, line 90
def accuracy_to_s
  case @accuracy
  when  1 then "world"
  when  3 then "country"
  when  6 then "region"
  when 11 then "city"
  when 16 then "street"
  else         @accuracy
  end
end