kingpin 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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