drone_api 0.1.0 → 0.2.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/.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