kingpin 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
1
+ 0.6.0
@@ -0,0 +1,5 @@
1
+ ---
2
+ protocol: http
3
+ host: localhost
4
+ port: 4269
5
+ namespace: '/api/1.0'
data/kingpin.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{kingpin}
8
- s.version = "0.5.1"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jan Roesner"]
@@ -25,11 +25,13 @@ Gem::Specification.new do |s|
25
25
  "README.rdoc",
26
26
  "Rakefile",
27
27
  "VERSION",
28
+ "config/kingpin.yml",
28
29
  "kingpin.gemspec",
29
30
  "lib/http_client.rb",
31
+ "lib/king_pin.rb",
30
32
  "lib/kingpin.rb",
31
- "lib/pin_caster.rb",
32
33
  "lib/pincaster.rb",
34
+ "lib/pincaster_config.rb",
33
35
  "lib/pincaster_layer.rb",
34
36
  "lib/pincaster_pin.rb",
35
37
  "spec/pincaster_spec.rb",
data/lib/http_client.rb CHANGED
@@ -2,7 +2,6 @@ class HttpClient
2
2
 
3
3
  require 'net/http'
4
4
  require "cgi"
5
- require "benchmark"
6
5
 
7
6
  def initialize(protocol, host, port, namespace=nil)
8
7
  @http = Net::HTTP.new(host, port)
@@ -46,7 +45,7 @@ class HttpClient
46
45
 
47
46
  # redefines the resource path including the namespace
48
47
  def resource_path(resource)
49
- @namespace.nil? ? resource : "/" + @namespace + resource
48
+ @namespace.nil? ? resource : @namespace + resource
50
49
  end
51
50
 
52
51
  # rebuild a uri in details, so that another protocol, host, port and GET params can be specified, after Net::HTTP was created
data/lib/king_pin.rb ADDED
@@ -0,0 +1,99 @@
1
+ ###
2
+ # Kingpin - makes models pinnable
3
+ ###
4
+
5
+ module Kingpin
6
+ class << self.class.superclass
7
+ def pinnable(*args)
8
+ include KingpinInstanceMethods
9
+ self.kingpin_args = args
10
+ named_scope :nearby, lambda { |point, radius| { :conditions => ["id in (?)", point.nearby_ids(radius)] } }
11
+ after_save :autopin if (!!args.first[:autopin] rescue false)
12
+ end
13
+ end
14
+ end
15
+
16
+ ###
17
+ # KingpinInstanceMethods - provides models new instance methods
18
+ ###
19
+
20
+ module KingpinInstanceMethods
21
+ def self.included(base)
22
+ base.extend KingpinClassMethods
23
+ end
24
+
25
+ # add a Pincaster record for self with in layer: self.class
26
+ def add_pin
27
+ Pincaster.add_record(self)
28
+ end
29
+
30
+ # returns the Pincaster pin for self
31
+ def pin
32
+ Pincaster.get_record(self)
33
+ end
34
+
35
+ # deletes the Pincaster pin for self
36
+ def delete_pin!
37
+ Pincaster.delete_record(self)
38
+ end
39
+
40
+ # returns nearby found record_ids in same layer as self, radius meters away, number of results limited to limit
41
+ def nearby_ids(radius, limit=nil)
42
+ JSON.parse(Pincaster.nearby(self, radius, limit))["matches"].map{|p| p["key"]}
43
+ end
44
+
45
+ # returns nearby found records in same layer as self, radius metera away, number of results limited to limit
46
+ def nearby(radius, limit=nil)
47
+ self.class.find(nearby_ids(radius, limit))
48
+ end
49
+
50
+ # returns objects longitude depending on configured method name for access as well as DEG or RAD configuration
51
+ def pin_lng
52
+ if not !!self.class.kingpin_args[:methods]
53
+ [:longitude, :long, :lng, :lgt, :lgdt].each do |l|
54
+ if self.respond_to?(l)
55
+ return !!self.class.kingpin_args[:rad] ? self.send(l).to_f * 180 / Math::PI : self.send(l)
56
+ end
57
+ end
58
+ return nil
59
+ else
60
+ return !!self.class.kingpin_args[:rad] ? self.send(self.class.kingpin_args[:methods][:lng]).to_f * 180.0 / Math::PI : self.send(self.class.kingpin_args[:methods][:lng])
61
+ end
62
+ end
63
+
64
+ # returns objects latitude depending on configured method name for access as well as DEG or RAD configuration
65
+ def pin_lat
66
+ if not !!self.class.kingpin_args[:methods]
67
+ [:latitude, :lati, :ltt, :ltd, :lat].each do |l|
68
+ if self.respond_to?(l)
69
+ return !!self.class.kingpin_args[:rad] ? self.send(l).to_f * 180 / Math::PI : self.send(l)
70
+ end
71
+ end
72
+ return nil
73
+ else
74
+ return !!self.class.kingpin_args[:rad] ? self.send(self.class.kingpin_args[:methods][:lat]).to_f * 180.0 / Math::PI : self.send(self.class.kingpin_args[:methods][:lat])
75
+ end
76
+ end
77
+
78
+ # automatically adds a pin via after_save hook for self in case autopin option was set to true for self's AR model
79
+ def autopin
80
+ self.add_pin
81
+ end
82
+
83
+ end
84
+
85
+ ###
86
+ # KingpinClassMethods - provides models new class methods
87
+ ###
88
+
89
+ module KingpinClassMethods
90
+
91
+ def kingpin_args=(args)
92
+ @@kingpin_args = args.empty? ? nil : args
93
+ end
94
+
95
+ def kingpin_args
96
+ @@kingpin_args.first rescue {:methods => nil, :rad => false, :autopin => false}
97
+ end
98
+
99
+ end
data/lib/kingpin.rb CHANGED
@@ -1,103 +1 @@
1
- ###
2
- # Kingpin - makes models pinnable
3
- ###
4
-
5
- module Kingpin
6
- class << self.class.superclass
7
- def pinnable(*args)
8
- include KingpinInstanceMethods
9
- self.kingpin_args = args
10
- named_scope :nearby, lambda { |point, radius| { :conditions => ["id in (?)", point.nearby_ids(radius)] } }
11
- after_save :autopin if !!args.first[:autopin]
12
- end
13
- end
14
- end
15
-
16
- ###
17
- # PinInstanceMethods - provides models new instance methods
18
- ###
19
-
20
- module KingpinInstanceMethods
21
- def self.included(base)
22
- base.extend KingpinClassMethods
23
- end
24
-
25
- # add a Pincaster record for self with in layer: self.class
26
- def add_pin
27
- Pincaster.add_record(self)
28
- end
29
-
30
- # returns the Pincaster pin for self
31
- def pin
32
- Pincaster.get_record(self)
33
- end
34
-
35
- # deletes the Pincaster pin for self
36
- def delete_pin!
37
- Pincaster.delete_record(self)
38
- end
39
-
40
- # returns nearby found record_ids in same layer as self, radius meters away, number of results limited to limit
41
- def nearby_ids(radius, limit=nil)
42
- JSON.parse(Pincaster.nearby(self, radius, limit))["matches"].map{|p| p["key"]}
43
- end
44
-
45
- # returns nearby found records in same layer as self, radius metera away, number of results limited to limit
46
- def nearby(radius, limit=nil)
47
- self.class.find(nearby_ids(radius, limit))
48
- end
49
-
50
- # returns objects longitude depending on configured method name for access as well as DEG or RAD configuration
51
- def pin_lng
52
- if self.class.kingpin_args.nil?
53
- [:longitude, :long, :lng, :lgt, :lgdt].each do |l|
54
- return self.send(l) if self.respond_to?(l)
55
- end
56
- return nil
57
- else
58
- if !!self.class.kingpin_args[:methods]
59
- return !!self.class.kingpin_args[:rad] ? self.send(self.class.kingpin_args[:methods][:lng]).to_f * 180.0 / Math::PI : self.send(self.class.kingpin_args[:methods][:lng])
60
- else
61
- return self.send(self.class.kingpin_args[:methods][:lng])
62
- end
63
- end
64
- end
65
-
66
- # returns objects latitude depending on configured method name for access as well as DEG or RAD configuration
67
- def pin_lat
68
- if self.class.kingpin_args.nil?
69
- [:latitude, :lati, :ltt, :ltd, :lat].each do |l|
70
- return self.send(l) if self.respond_to?(l)
71
- end
72
- return nil
73
- else
74
- if !!self.class.kingpin_args[:methods]
75
- return !!self.class.kingpin_args[:rad] ? self.send(self.class.kingpin_args[:methods][:lat]).to_f * 180.0 / Math::PI : self.send(self.class.kingpin_args[:methods][:lat])
76
- else
77
- return self.send(self.class.kingpin_args[:methods][:lat])
78
- end
79
- end
80
- end
81
-
82
- # automatically adds a pin for self in case autopin option was set to true for self's AR model
83
- def autopin
84
- self.add_pin
85
- end
86
-
87
- end
88
-
89
- ###
90
- # PinClassMethods - provides models new class methods
91
- ###
92
-
93
- module KingpinClassMethods
94
-
95
- def kingpin_args=(args)
96
- @@kingpin_args = args
97
- end
98
-
99
- def kingpin_args
100
- @@kingpin_args.first
101
- end
102
-
103
- end
1
+ Dir[File.dirname(__FILE__) + "/*.rb"].each { |file| require file }
data/lib/pincaster.rb CHANGED
@@ -1 +1,109 @@
1
- Dir[File.dirname(__FILE__) + "/*.rb"].each { |file| require file }
1
+ require 'json'
2
+ require 'yaml'
3
+ require 'pincaster_layer'
4
+ require 'pincaster_pin'
5
+ require 'pincaster_config'
6
+
7
+ class Pincaster
8
+
9
+ # returns an existing http client properly configured or creates a new one once
10
+ def self.client
11
+ @@http_client ||= HttpClient.new(self.config.protocol, self.config.host, self.config.port, self.config.namespace)
12
+ end
13
+
14
+ # Pincaster server is still alive?
15
+ def self.is_alive?
16
+ self.client.send_request('GET', '/system/ping.json').code == "200" ? true : false rescue false
17
+ end
18
+
19
+ # shutdown Pincaster server immediately
20
+ def self.shutdown!
21
+ begin
22
+ self.client.send_request('POST', '/system/shutdown.json')
23
+ rescue Exception => e
24
+ case e.message
25
+ when "end of file reached"
26
+ return true
27
+ else
28
+ return false
29
+ end
30
+ end
31
+ end
32
+
33
+ # returns all known layers
34
+ def self.layers
35
+ JSON.parse(self.client.send_request('GET', '/layers/index.json').body)["layers"]
36
+ end
37
+
38
+ # returns true if Pincaster already has the given layer
39
+ def self.has_layer?(layer)
40
+ raise "Layer has to be a string" if not layer.is_a?(String)
41
+ self.layers.detect{|l| l["name"] == layer}.nil? ? false : true rescue false
42
+ end
43
+
44
+ # adds a new layer with name of the given string
45
+ def self.add_layer(layer)
46
+ raise "Layer has to be a string" if not layer.is_a?(String)
47
+ self.client.send_request('POST', "/layers/#{layer}.json").code == "200" ? true : false rescue false
48
+ end
49
+
50
+ # deletes the layer with the given name
51
+ def self.delete_layer!(layer)
52
+ raise "Layer has to be a string" if not layer.is_a?(String)
53
+ self.client.send_request('DELETE', "/layers/#{layer}.json").code == "200" ? true : false rescue false
54
+ end
55
+
56
+ # return a layer object for the layer that was searched for
57
+ def self.layer(layer)
58
+ raise "Layer has to be a string" if not layer.is_a?(String)
59
+ PincasterLayer.new(self.layers.select{|l| l["name"] == layer})
60
+ end
61
+
62
+ # adds a new record as well as creates a layer for it if the latter does not exist already
63
+ def self.add_record(record)
64
+ raise "Can't add a record without geocoordinates lng, lat" if record.pin_lng.nil? or record.pin_lat.nil?
65
+ Pincaster.add_layer(record.class.to_s) if not Pincaster.has_layer?(record.class.to_s)
66
+ self.client.send_request('PUT',
67
+ "/records/#{record.class.to_s}/#{record.id}.json",
68
+ nil,
69
+ nil,
70
+ {:_loc => "#{record.pin_lat},#{record.pin_lng}"}).code == "200" ? true : false
71
+ end
72
+
73
+ # returns a pin object for the given ActiveRecord object
74
+ def self.get_record(record)
75
+ PincasterPin.new(JSON.parse(self.client.send_request('GET', "/records/#{record.class.to_s}/#{record.id}.json").body)) rescue nil
76
+ end
77
+
78
+ # deletes the Pincaster record for the given ActiveRecord object
79
+ def self.delete_record(record)
80
+ self.client.send_request('DELETE', "/records/#{record.class.to_s}/#{record.id}.json").code == "200" ? true : false
81
+ end
82
+
83
+ # returns all pins nearby given record, maximum radius meters away, returns limit number of pins
84
+ def self.nearby(record, radius, limit)
85
+ limit ||= 2000
86
+ raise "Given #{record.class.to_s} has not lng or lat." if record.pin_lng.nil? or record.pin_lat.nil?
87
+ self.client.send_request('GET',
88
+ "/search/#{record.class.to_s}/nearby/#{record.pin_lat.to_s},#{record.pin_lng.to_s}.json",
89
+ nil,
90
+ nil,
91
+ {:radius => radius.to_s, :limit => limit}).body
92
+ end
93
+
94
+ # loads local config, or users one if he provided any
95
+ def self.load_config
96
+ begin
97
+ config = YAML.load_file(Rails.root.to_s + "/config/kingpin.yml")
98
+ rescue
99
+ config = YAML.load_file(File.dirname(__FILE__).to_s + "/../config/kingpin.yml")
100
+ end
101
+ PincasterConfig.new(config)
102
+ end
103
+
104
+ # returns config
105
+ def self.config
106
+ @@config ||= self.load_config
107
+ end
108
+
109
+ end
@@ -0,0 +1,17 @@
1
+ class PincasterConfig
2
+
3
+ attr_accessor :raw_config
4
+
5
+ def initialize(config_hash)
6
+ @raw_config = config_hash
7
+ splat_config
8
+ end
9
+
10
+ def splat_config
11
+ @raw_config.each_pair do |key, value|
12
+ self.class.send(:attr_accessor, key.to_sym)
13
+ self.send(key.to_s+"=", value)
14
+ end
15
+ end
16
+
17
+ end
@@ -1,9 +1,18 @@
1
1
  class PincasterLayer
2
2
 
3
- attr_accessor :layer_hash
3
+ attr_reader :layer_hash
4
4
 
5
- def initialize(layer_hash)
6
- @layer_hash = layer_hash
5
+ def initialize(layer_array)
6
+ @layer_hash = layer_array.first
7
+ splat_layer
8
+ end
9
+
10
+ # provides an accessor for every pin value that came back from Pincaster
11
+ def splat_layer
12
+ @layer_hash.each_pair do |key, value|
13
+ self.class.send(:attr_accessor, key.to_sym)
14
+ self.send(key.to_s + "=", value)
15
+ end
7
16
  end
8
17
 
9
18
  end
data/lib/pincaster_pin.rb CHANGED
@@ -1,13 +1,22 @@
1
1
  class PincasterPin
2
2
 
3
- attr_accessor :pin_hash
3
+ attr_reader :pin_hash
4
4
 
5
5
  def initialize(pin_hash)
6
6
  @pin_hash = pin_hash
7
+ splat_pin
8
+ end
9
+
10
+ # provides an accessor for every pin value that came back from Pincaster
11
+ def splat_pin
12
+ @pin_hash.each_pair do |key, value|
13
+ self.class.send(:attr_accessor, key.to_sym)
14
+ self.send(key.to_s + "=", value)
15
+ end
7
16
  end
8
17
 
9
18
  # returns the ActiveRecord:id of this pin's matching ActiveRecord object
10
19
  def id
11
- @pin_hash["key"]
20
+ key
12
21
  end
13
22
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kingpin
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 5
9
- - 1
10
- version: 0.5.1
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jan Roesner
@@ -98,11 +98,13 @@ files:
98
98
  - README.rdoc
99
99
  - Rakefile
100
100
  - VERSION
101
+ - config/kingpin.yml
101
102
  - kingpin.gemspec
102
103
  - lib/http_client.rb
104
+ - lib/king_pin.rb
103
105
  - lib/kingpin.rb
104
- - lib/pin_caster.rb
105
106
  - lib/pincaster.rb
107
+ - lib/pincaster_config.rb
106
108
  - lib/pincaster_layer.rb
107
109
  - lib/pincaster_pin.rb
108
110
  - spec/pincaster_spec.rb
data/lib/pin_caster.rb DELETED
@@ -1,89 +0,0 @@
1
- require 'json'
2
- require 'pincaster_layer'
3
- require 'pincaster_pin'
4
-
5
- class Pincaster
6
-
7
- @@http_client = HttpClient.new('http','localhost',4269)
8
-
9
- # Pincaster server is still alive?
10
- def self.is_alive?
11
- @@http_client.send_request('GET', '/api/1.0/system/ping.json').code == "200" ? true : false rescue false
12
- end
13
-
14
- # shutdown Pincaster server immediately
15
- def self.shutdown!
16
- begin
17
- @@http_client.send_request('POST', '/api/1.0/system/shutdown.json')
18
- rescue Exception => e
19
- case e.message
20
- when "end of file reached"
21
- return true
22
- else
23
- return false
24
- end
25
- end
26
- end
27
-
28
- # returns all known layers
29
- def self.layers
30
- JSON.parse(@@http_client.send_request('GET', '/api/1.0/layers/index.json').body)["layers"]
31
- end
32
-
33
- # returns true if Pincaster already has the given layer
34
- def self.has_layer?(layer)
35
- raise "Layer has to be a string" if not layer.is_a?(String)
36
- self.layers.detect{|l| l["name"] == layer}.nil? ? false : true rescue false
37
- end
38
-
39
- # adds a new layer with name of the given string
40
- def self.add_layer(layer)
41
- raise "Layer has to be a string" if not layer.is_a?(String)
42
- @@http_client.send_request('POST', "/api/1.0/layers/#{layer}.json").code == "200" ? true : false rescue false
43
- end
44
-
45
- # deletes the layer with the given name
46
- def self.delete_layer!(layer)
47
- raise "Layer has to be a string" if not layer.is_a?(String)
48
- @@http_client.send_request('DELETE', "/api/1.0/layers/#{layer}.json").code == "200" ? true : false rescue false
49
- end
50
-
51
- # return a layer object for the layer that was searched for
52
- def self.layer(layer)
53
- raise "Layer has to be a string" if not layer.is_a?(String)
54
- PincasterLayer.new(self.layers.select{|l| l["name"] == layer})
55
- end
56
-
57
- # adds a new record as well as creates a layer for it if the latter does not exist already
58
- def self.add_record(record)
59
- raise "Can't add a record without geocoordinates lng, lat" if record.pin_lng.nil? or record.pin_lat.nil?
60
- Pincaster.add_layer(record.class.to_s) if not Pincaster.has_layer?(record.class.to_s)
61
- @@http_client.send_request('PUT',
62
- "/api/1.0/records/#{record.class.to_s}/#{record.id}.json",
63
- nil,
64
- nil,
65
- {:_loc => "#{record.pin_lat},#{record.pin_lng}"}).code == "200" ? true : false
66
- end
67
-
68
- # returns a pin object for the given ActiveRecord object
69
- def self.get_record(record)
70
- PincasterPin.new(JSON.parse(@@http_client.send_request('GET', "/api/1.0/records/#{record.class.to_s}/#{record.id}.json").body)) rescue nil
71
- end
72
-
73
- # deletes the Pincaster record for the given ActiveRecord object
74
- def self.delete_record(record)
75
- @@http_client.send_request('DELETE', "/api/1.0/records/#{record.class.to_s}/#{record.id}.json").code == "200" ? true : false
76
- end
77
-
78
- # returns all pins nearby given record, maximum radius meters away, returns limit number of pins
79
- def self.nearby(record, radius, limit)
80
- limit ||= 2000
81
- raise "Given #{record.class.to_s} has not lng or lat." if record.pin_lng.nil? or record.pin_lat.nil?
82
- @@http_client.send_request('GET',
83
- "/api/1.0/search/#{record.class.to_s}/nearby/#{record.pin_lat.to_s},#{record.pin_lng.to_s}.json",
84
- nil,
85
- nil,
86
- {:radius => radius.to_s, :limit => limit}).body
87
- end
88
-
89
- end