drone_api 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ drone_api.sublime-project
19
+ drone_api.sublime-workspace
data/README.md CHANGED
@@ -42,13 +42,19 @@ This will return a single strike (or nil, if nothing is found). You can also pas
42
42
  > x = c.find :bureau_id => 'YEM001' # Returns an array of 1 element
43
43
  > six_deaths = c.find :deaths => 6
44
44
 
45
- There are some find_by_X methods. They are based on the attribute names of the Strike class. (If you're familiar with Rails, think model find methods). The following are equale to the examples above:
45
+ There are some find_by_X methods. They are based on the attribute names of the Strike class. (If you're familiar with Rails, think model find methods). The following are equal to the examples above:
46
46
 
47
47
  > x = c.find_by_bureau_id 'YEM001'
48
48
  > six_deaths = c.find_by_deaths 6
49
49
 
50
50
  One think to keep in mind. All these finders return an array *except* find_by_number. This returns a single instance, just as Client.find does.
51
51
 
52
+ The finder methods are:
53
+ - find_by_X(value) - Find all where X equals value
54
+ - find_X_gt[e](value) - Finds all where X is greater than [or equal to] value.
55
+ - find_X_lt[e](value) - Finds all where X is less than [or equal to] value.
56
+ - find_X_btwn(low, high) - Finds all where X is between low and high.
57
+
52
58
 
53
59
  ## Contributing
54
60
 
data/lib/drone_api.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'drone_api/client'
2
2
  require 'drone_api/request'
3
3
  require 'drone_api/strike'
4
+ require 'drone_api/geo_json'
4
5
  require 'drone_api/version'
5
6
 
6
7
  module DroneApi
@@ -16,4 +17,5 @@ module DroneApi
16
17
  def self.version
17
18
  "DroneApi version #{DroneApi::VERSION}"
18
19
  end
20
+
19
21
  end
@@ -1,5 +1,16 @@
1
1
  module DroneApi
2
2
  class Client
3
+ def initialize
4
+ @debug = false
5
+ end
6
+
7
+ def debug?
8
+ @debug
9
+ end
10
+
11
+ def set_debug(flag)
12
+ @debug = flag
13
+ end
3
14
 
4
15
  # Returns entire list of strikes
5
16
  #
@@ -19,12 +30,22 @@ module DroneApi
19
30
  end
20
31
 
21
32
  def method_missing(meth, *args, &block)
22
- m = meth.to_s.match(/^find_by_(.+)/)
33
+ if (m = meth.to_s.match(/^find_(.+)_btwn/))
34
+ new_method = "def #{meth}(low, high); find_between :#{m[1]}, low, high; end"
35
+ elsif (m = meth.to_s.match /find_(.+?)_([l|g]te?)/)
36
+ op = m[2].match(/^gt/).nil? ? '<' : '>'
37
+ op = "#{op}=" if m[2].match(/\=$/)
38
+
39
+ new_method = "def #{meth}(val); find_cmp :#{m[1]}, val, '#{op}'; end"
40
+ elsif (m = meth.to_s.match(/^find_by_(.+)/))
41
+ new_method = "def #{meth}(val); find_cmp :#{m[1]}, val, '=='; end"
42
+ args = [args.first]
43
+ end
44
+
23
45
  if m
24
46
  key = m[1].to_sym
25
47
  if Strike.new.respond_to? key
26
- instance_eval "def #{meth}(val); find_equals :#{key}, val; end"
27
- send meth, args.first
48
+ add_finder(meth.to_s, new_method, *args)
28
49
  else
29
50
  super
30
51
  end
@@ -35,8 +56,17 @@ module DroneApi
35
56
 
36
57
  protected
37
58
 
59
+ def add_finder(meth, code, *args)
60
+ instance_eval code
61
+ debug "meth: #{meth}"
62
+ debug "code: #{code}"
63
+ debug "args: #{args}"
64
+ send meth, *args
65
+ end
66
+
38
67
  def find_equals(key, value)
39
68
  key = key.to_sym
69
+ value = value.first if value.is_a? Array
40
70
  value = value.to_s unless value.nil?
41
71
  result = all.select do |s|
42
72
  test = s.send(key)
@@ -49,5 +79,41 @@ module DroneApi
49
79
 
50
80
  end
51
81
 
82
+ def find_cmp(key, value, op)
83
+ key = key.to_sym
84
+ value = value.first if value.is_a? Array
85
+ result = all.select do |s|
86
+ test = s.send(key)
87
+ eval "value #{op} test"
88
+ end
89
+
90
+ result = result.first if key == :number and not result.nil?
91
+ return result
92
+
93
+ end
94
+
95
+ def find_between(key, low, high)
96
+ # low and high have to
97
+ # 1) Be either Integer, Float, date or DateTime and
98
+ # 2) Be the same class
99
+ if low.class != high.class
100
+ raise DroneApi::Error.new "Expected objects of same class; received one #{low.class} and one #{high.class}"
101
+ end
102
+
103
+ if [Date, DateTime, Integer, Float].select {|c| low.is_a? c }.empty?
104
+ raise DroneApi::Error.new "Receieved #{low.class}. Expected Date, DateTime, Integer, or Float."
105
+ end
106
+
107
+ key = key.to_sym
108
+ all.select do |s|
109
+ test = s.send(key)
110
+ test >= low and test <= high
111
+ end
112
+ end
113
+
114
+ def debug(msg)
115
+ puts msg if debug?
116
+ end
117
+
52
118
  end
53
119
  end
@@ -0,0 +1,3 @@
1
+ module DroneApi
2
+ class Error < StandardError; end
3
+ end
@@ -0,0 +1,36 @@
1
+ module DroneApi
2
+ class GeoJson
3
+ attr_accessor :properties, :coordinates
4
+
5
+ def initialize(properties={}, coordinates=[])
6
+ @properties = properties
7
+ @coordinates = coordinates
8
+ end
9
+
10
+ def [](key)
11
+ @properties[key]
12
+ end
13
+
14
+ def []=(key, value)
15
+ @properties[key] = value
16
+ end
17
+
18
+ def to_json(*a)
19
+ {
20
+ "type" => "Feature",
21
+ "properties" => @properties,
22
+ "geometry" => {
23
+ "type" => "Point",
24
+ "coordinates" => @coordinates
25
+ }
26
+ }.to_json(a)
27
+ end
28
+
29
+ def self.json_create(o)
30
+ GeoJson.new(
31
+ o['properties'], o['geometry']['coordinates']
32
+ )
33
+ end
34
+
35
+ end
36
+ end
@@ -1,3 +1,4 @@
1
+ require 'date'
1
2
  require 'json'
2
3
 
3
4
  module DroneApi
@@ -27,28 +28,43 @@ module DroneApi
27
28
  unless data.nil?
28
29
  data = JSON.parse(data) if data.is_a? String
29
30
 
30
- @id = data['_id'] || ''
31
- @number = data['number'].to_i || 0
32
- @country = data['country'] || ''
33
- @date = data['date'] || ''
34
- @town = data['town'] || ''
35
- @location = data['location'] || ''
36
- @deaths = data['deaths'].to_i || 0
37
- @deaths_min = data['deaths_min'].to_i || 0
38
- @deaths_max = data['deaths_max'].to_i || 0
39
- @civilians = data['civilians'].to_i || 0
40
- @injuries = data['injuries'].to_i || 0
41
- @children = data['children'].to_i || 0
42
- @tweet_id = data['tweet_id'] || ''
43
- @bureau_id = data['bureau_id'] || ''
44
- @summary_short = data['bij_summary_short'] || ''
45
- @link = data['bij_link'] || ''
46
- @target = data['target'] || ''
47
- @lat = data['lat'] || ''
48
- @lon = data['lon'] || ''
49
- @articles = data['articles'] || ''
50
- @names = data['names'] || ''
31
+ @id = parse_string(data['_id'])
32
+ @number = parse_int(data['number'])
33
+ @country = parse_string(data['country'])
34
+ @date = parse_date(data['date'])
35
+ @town = parse_string(data['town'])
36
+ @location = parse_string(data['location'])
37
+ @deaths = parse_int(data['deaths'])
38
+ @deaths_min = parse_int(data['deaths_min'])
39
+ @deaths_max = parse_int(data['deaths_max'])
40
+ @civilians = parse_int(data['civilians'])
41
+ @injuries = parse_int(data['injuries'])
42
+ @children = parse_int(data['children'])
43
+ @tweet_id = parse_string(data['tweet_id'])
44
+ @bureau_id = parse_string(data['bureau_id'])
45
+ @summary_short = parse_string(data['bij_summary_short'])
46
+ @link = parse_string(data['bij_link'])
47
+ @target = parse_string(data['target'])
48
+ @lat = parse_string(data['lat'])
49
+ @lon = parse_string(data['lon'])
50
+ @articles = parse_string(data['articles'])
51
+ @names = parse_string(data['names'])
52
+
51
53
  end
52
54
  end
55
+
56
+ private
57
+
58
+ def parse_int(val)
59
+ val.nil? ? 0 : val.to_i
60
+ end
61
+
62
+ def parse_date(val)
63
+ val.nil? ? nil : DateTime.strptime(val, '%Y-%m-%dT%H:%M:%S.%LZ')
64
+ end
65
+
66
+ def parse_string(val)
67
+ val.nil? ? '' : val
68
+ end
53
69
  end
54
70
  end
@@ -1,3 +1,3 @@
1
1
  module DroneApi
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -36,4 +36,26 @@ describe 'DroneApi::Strike' do
36
36
  it { should respond_to(:lon) }
37
37
  it { should respond_to(:articles) }
38
38
  it { should respond_to(:names) }
39
- end
39
+ end
40
+
41
+ describe 'GeoJson' do
42
+ describe '#[]=' do
43
+ it "allows setting @properties" do
44
+ gj = DroneApi::GeoJson.new
45
+ expect { gj[:foo] = :bar }.not_to raise_error
46
+
47
+ gj[:foo].should eq :bar
48
+ end
49
+ end
50
+
51
+ describe '#[]' do
52
+ before do
53
+ @gj = DroneApi::GeoJson.new
54
+ @gj[:foo] = 'bar'
55
+ end
56
+
57
+ it 'allows @properties to be retrieved' do
58
+ @gj[:foo].should eq 'bar'
59
+ end
60
+ end
61
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drone_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-28 00:00:00.000000000 Z
12
+ date: 2013-08-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -42,6 +42,8 @@ files:
42
42
  - drone_api.gemspec
43
43
  - lib/drone_api.rb
44
44
  - lib/drone_api/client.rb
45
+ - lib/drone_api/errors.rb
46
+ - lib/drone_api/geo_json.rb
45
47
  - lib/drone_api/request.rb
46
48
  - lib/drone_api/strike.rb
47
49
  - lib/drone_api/version.rb