File: cli.rb

package info (click to toggle)
ruby-geocoder 1.5.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 732 kB
  • sloc: ruby: 6,173; makefile: 3
file content (121 lines) | stat: -rw-r--r-- 3,954 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
require 'geocoder'
require 'optparse'

module Geocoder
  class Cli

    def self.run(args, out = STDOUT)
      show_url  = false
      show_json = false

      # remove arguments that are probably coordinates so they are not
      # processed as arguments (eg: -31.96047031,115.84274631)
      coords = args.select{ |i| i.match(/^-\d/) }
      args -= coords

      OptionParser.new{ |opts|
        opts.banner = "Usage:\n    geocode [options] <location>"
        opts.separator "\nOptions: "

        opts.on("-k <key>", "--key <key>",
          "Key for geocoding API (usually optional). Enclose multi-part keys in quotes and separate parts by spaces") do |key|
          if (key_parts = key.split(/\s+/)).size > 1
            Geocoder.configure(:api_key => key_parts)
          else
            Geocoder.configure(:api_key => key)
          end
        end

        opts.on("-l <language>", "--language <language>",
          "Language of output (see API docs for valid choices)") do |language|
          Geocoder.configure(:language => language)
        end

        opts.on("-p <proxy>", "--proxy <proxy>",
          "HTTP proxy server to use (user:pass@host:port)") do |proxy|
          Geocoder.configure(:http_proxy => proxy)
        end

        opts.on("-s <service>", Geocoder::Lookup.all_services_except_test, "--service <service>",
          "Geocoding service: #{Geocoder::Lookup.all_services_except_test * ', '}") do |service|
          Geocoder.configure(:lookup => service.to_sym)
          Geocoder.configure(:ip_lookup => service.to_sym)
        end

        opts.on("-t <seconds>", "--timeout <seconds>",
          "Maximum number of seconds to wait for API response") do |timeout|
          Geocoder.configure(:timeout => timeout.to_i)
        end

        opts.on("-j", "--json", "Print API's raw JSON response") do
          show_json = true
        end

        opts.on("-u", "--url", "Print URL for API query instead of result") do
          show_url = true
        end

        opts.on_tail("-v", "--version", "Print version number") do
          require "geocoder/version"
          out << "Geocoder #{Geocoder::VERSION}\n"
          exit
        end

        opts.on_tail("-h", "--help", "Print this help") do
          out << "Look up geographic information about a location.\n\n"
          out << opts
          out << "\nCreated and maintained by Alex Reisner, available under the MIT License.\n"
          out << "Report bugs and contribute at http://github.com/alexreisner/geocoder\n"
          exit
        end
      }.parse!(args)

      # concatenate args with coords that might have been removed
      # before option processing
      query = (args + coords).join(" ")

      if query == ""
        out << "Please specify a location (run `geocode -h` for more info).\n"
        exit 1
      end

      if show_url and show_json
        out << "You can only specify one of -j and -u.\n"
        exit 2
      end

      if show_url
        q = Geocoder::Query.new(query)
        out << q.url + "\n"
        exit 0
      end

      if show_json
        q = Geocoder::Query.new(query)
        out << q.lookup.send(:fetch_raw_data, q) + "\n"
        exit 0
      end

      if (result = Geocoder.search(query).first)
        nominatim = Geocoder::Lookup.get(:nominatim)
        lines = [
          ["Latitude",       result.latitude],
          ["Longitude",      result.longitude],
          ["Full address",   result.address],
          ["City",           result.city],
          ["State/province", result.state],
          ["Postal code",    result.postal_code],
          ["Country",        result.country],
          ["Map",            nominatim.map_link_url(result.coordinates)],
        ]
        lines.each do |line|
          out << (line[0] + ": ").ljust(18) + line[1].to_s + "\n"
        end
        exit 0
      else
        out << "Location '#{query}' not found.\n"
        exit 1
      end
    end
  end
end