neuron-client 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/README.md +34 -8
  2. data/lib/neuron-client.rb +61 -12
  3. data/lib/neuron-client/{connection.rb → admin_connection.rb} +7 -7
  4. data/lib/neuron-client/api.rb +48 -31
  5. data/lib/neuron-client/membase_connection.rb +18 -0
  6. data/lib/neuron-client/model/admin/ad.rb +22 -0
  7. data/lib/neuron-client/model/admin/ad_zone.rb +15 -0
  8. data/lib/neuron-client/model/admin/base.rb +91 -0
  9. data/lib/neuron-client/model/admin/blocked_referer.rb +12 -0
  10. data/lib/neuron-client/model/admin/blocked_user_agent.rb +12 -0
  11. data/lib/neuron-client/model/admin/geo_target.rb +16 -0
  12. data/lib/neuron-client/model/admin/report.rb +15 -0
  13. data/lib/neuron-client/model/admin/s3_file.rb +12 -0
  14. data/lib/neuron-client/model/admin/zone.rb +15 -0
  15. data/lib/neuron-client/model/base.rb +38 -0
  16. data/lib/neuron-client/model/common/ad.rb +40 -0
  17. data/lib/neuron-client/model/common/ad_calculations.rb +329 -0
  18. data/lib/neuron-client/model/common/ad_zone.rb +17 -0
  19. data/lib/neuron-client/model/common/base.rb +67 -0
  20. data/lib/neuron-client/model/common/blocked_referer.rb +16 -0
  21. data/lib/neuron-client/model/common/blocked_user_agent.rb +16 -0
  22. data/lib/neuron-client/model/common/geo_target.rb +16 -0
  23. data/lib/neuron-client/model/common/report.rb +21 -0
  24. data/lib/neuron-client/model/common/s3_file.rb +16 -0
  25. data/lib/neuron-client/model/common/zone.rb +22 -0
  26. data/lib/neuron-client/model/common/zone_calculations.rb +41 -0
  27. data/lib/neuron-client/model/membase/ad.rb +31 -0
  28. data/lib/neuron-client/model/membase/ad_zone.rb +11 -0
  29. data/lib/neuron-client/model/membase/blocked_referer.rb +18 -0
  30. data/lib/neuron-client/model/membase/blocked_user_agent.rb +18 -0
  31. data/lib/neuron-client/model/membase/geo_target.rb +11 -0
  32. data/lib/neuron-client/model/membase/report.rb +11 -0
  33. data/lib/neuron-client/model/membase/s3_file.rb +11 -0
  34. data/lib/neuron-client/model/membase/zone.rb +19 -0
  35. data/lib/neuron-client/model/models.rb +14 -0
  36. data/lib/neuron-client/version.rb +1 -1
  37. data/neuron-client.gemspec +18 -11
  38. data/spec/fixtures/vcr_cassettes/s3_file.yml +186 -4
  39. data/spec/lib/admin_connection_spec.rb +82 -0
  40. data/spec/lib/api_spec.rb +80 -0
  41. data/spec/lib/membase_connection_spec.rb +27 -0
  42. data/spec/lib/model/admin/ad_spec.rb +34 -0
  43. data/spec/lib/model/admin/ad_zone_spec.rb +19 -0
  44. data/spec/lib/model/admin/base_spec.rb +11 -0
  45. data/spec/lib/model/admin/blocked_referer_spec.rb +11 -0
  46. data/spec/lib/model/admin/blocked_user_agent_spec.rb +11 -0
  47. data/spec/lib/model/admin/geo_target_spec.rb +30 -0
  48. data/spec/lib/model/admin/report_spec.rb +21 -0
  49. data/spec/lib/model/admin/s3_spec.rb +11 -0
  50. data/spec/lib/model/admin/zone_spec.rb +21 -0
  51. data/spec/lib/model/base_spec.rb +89 -0
  52. data/spec/lib/model/common/ad_calculations_spec.rb +1148 -0
  53. data/spec/lib/model/common/ad_spec.rb +11 -0
  54. data/spec/lib/model/common/ad_zone_spec.rb +11 -0
  55. data/spec/lib/model/common/base_spec.rb +11 -0
  56. data/spec/lib/model/common/blocked_referer_spec.rb +11 -0
  57. data/spec/lib/model/common/blocked_user_agent_spec.rb +11 -0
  58. data/spec/lib/model/common/geo_target_spec.rb +11 -0
  59. data/spec/lib/model/common/report_spec.rb +11 -0
  60. data/spec/lib/model/common/s3_spec.rb +11 -0
  61. data/spec/lib/model/common/zone_calculations_spec.rb +54 -0
  62. data/spec/lib/model/common/zone_spec.rb +11 -0
  63. data/spec/lib/model/membase/ad_spec.rb +50 -0
  64. data/spec/lib/model/membase/ad_zone_spec.rb +11 -0
  65. data/spec/lib/model/membase/base_spec.rb +11 -0
  66. data/spec/lib/model/membase/blocked_referer_spec.rb +30 -0
  67. data/spec/lib/model/membase/blocked_user_agent_spec.rb +30 -0
  68. data/spec/lib/model/membase/geo_target_spec.rb +11 -0
  69. data/spec/lib/model/membase/report_spec.rb +11 -0
  70. data/spec/lib/model/membase/s3_spec.rb +11 -0
  71. data/spec/lib/model/membase/zone_spec.rb +28 -0
  72. data/spec/lib/old_spec.rb +192 -149
  73. data/spec/lib/s3_file_spec.rb +45 -42
  74. data/spec/spec_helper.rb +2 -1
  75. metadata +296 -57
  76. data/lib/neuron-client/ad.rb +0 -39
  77. data/lib/neuron-client/ad_zone.rb +0 -16
  78. data/lib/neuron-client/blocked_referer.rb +0 -12
  79. data/lib/neuron-client/blocked_user_agent.rb +0 -12
  80. data/lib/neuron-client/connected.rb +0 -138
  81. data/lib/neuron-client/geo_target.rb +0 -16
  82. data/lib/neuron-client/real_time_stats.rb +0 -0
  83. data/lib/neuron-client/report.rb +0 -20
  84. data/lib/neuron-client/s3_file.rb +0 -10
  85. data/lib/neuron-client/zone.rb +0 -16
data/README.md CHANGED
@@ -5,31 +5,57 @@ Neuron Client Gem
5
5
  Setup
6
6
  =====
7
7
 
8
- Neuron::Client::API.configure do |config|
9
- config.admin_url = "https://example.com"
10
- config.admin_key = "secret"
11
- end
8
+ Connect to the admin server for read/write access to exposed models:
12
9
 
10
+ Neuron::Client::API.default_api.configure do |config|
11
+ config.connection_type = :admin
12
+ config.admin_url = "https://example.com"
13
+ config.admin_key = "secret"
14
+ end
15
+
16
+ Short form to copy and paste into console:
17
+
18
+ Neuron::Client::API.default_api.configure {|config| config.connection_type = :admin; config.admin_url = 'http://localhost:3000'; config.admin_key = 'secret'}
19
+
20
+
21
+ Connect to the Membase (or Memcached) Server for limited read access to some exposed models:
22
+
23
+ Neuron::Client::API.default_api.configure do |config|
24
+ config.connection_type = :membase
25
+ config.membase_servers = "127.0.0.1:11211"
26
+ end
27
+
28
+ Short form to copy and paste into console:
29
+
30
+ Neuron::Client::API.default_api.configure {|config| config.connection_type = :membase; config.membase_servers = '127.0.0.1:11211'}
31
+
32
+ Create a new API, configure and use it for one specific model:
33
+
34
+ api = Neuron::Client::API.new
35
+ api.configure {|config| config.connection_type = :membase; config.membase_servers = '127.0.0.1:11211'}
36
+ Neuron::Client::Model::Ad.api = api
13
37
 
14
38
  Zones
15
39
  =====
16
40
 
41
+ *Note: many finder methods are not available when using a Membase connection. Objects are read-only when using a Membase connection.
42
+
17
43
  Create a zone:
18
44
 
19
- zone = Neuron::Client::Zone.new(:slug => 'test', :response_type => 'Redirect')
45
+ zone = Neuron::Client::Model::Zone.new(:slug => 'test', :response_type => 'Redirect')
20
46
  zone.save
21
47
 
22
48
  ... or simply:
23
49
 
24
- Neuron::Client::Zone.create(:slug => 'test', :response_type => 'Redirect')
50
+ Neuron::Client::Model::Zone.create(:slug => 'test', :response_type => 'Redirect')
25
51
 
26
52
  List all zones:
27
53
 
28
- Neuron::Client::Zone.all # => Array of Zone objects (with limited attributes)
54
+ Neuron::Client::Model::Zone.all # => Array of Zone objects (with limited attributes)
29
55
 
30
56
  Find a zone by ID:
31
57
 
32
- Neuron::Client::Zone.find(zone_id)
58
+ Neuron::Client::Model::Zone.find(zone_id)
33
59
 
34
60
  Update a zone:
35
61
 
data/lib/neuron-client.rb CHANGED
@@ -1,16 +1,42 @@
1
+ require "active_support/core_ext"
1
2
  require "neuron-client/version"
3
+ require "neuron-client/admin_connection"
4
+ require "neuron-client/membase_connection"
2
5
  require "neuron-client/api"
3
- require "neuron-client/connection"
4
- require "neuron-client/connected"
5
- require "neuron-client/ad"
6
- require "neuron-client/ad_zone"
7
- require "neuron-client/blocked_referer"
8
- require "neuron-client/blocked_user_agent"
9
- require "neuron-client/geo_target"
10
- require "neuron-client/real_time_stats"
11
- require "neuron-client/report"
12
- require "neuron-client/s3_file"
13
- require "neuron-client/zone"
6
+
7
+ require "neuron-client/model/common/base"
8
+ require "neuron-client/model/common/ad_calculations"
9
+ require "neuron-client/model/common/ad"
10
+ require "neuron-client/model/common/ad_zone"
11
+ require "neuron-client/model/common/blocked_referer"
12
+ require "neuron-client/model/common/blocked_user_agent"
13
+ require "neuron-client/model/common/geo_target"
14
+ require "neuron-client/model/common/report"
15
+ require "neuron-client/model/common/s3_file"
16
+ require "neuron-client/model/common/zone_calculations"
17
+ require "neuron-client/model/common/zone"
18
+
19
+ require "neuron-client/model/admin/base"
20
+ require "neuron-client/model/admin/ad"
21
+ require "neuron-client/model/admin/ad_zone"
22
+ require "neuron-client/model/admin/blocked_referer"
23
+ require "neuron-client/model/admin/blocked_user_agent"
24
+ require "neuron-client/model/admin/geo_target"
25
+ require "neuron-client/model/admin/report"
26
+ require "neuron-client/model/admin/s3_file"
27
+ require "neuron-client/model/admin/zone"
28
+
29
+ require "neuron-client/model/membase/ad"
30
+ require "neuron-client/model/membase/ad_zone"
31
+ require "neuron-client/model/membase/blocked_referer"
32
+ require "neuron-client/model/membase/blocked_user_agent"
33
+ require "neuron-client/model/membase/geo_target"
34
+ require "neuron-client/model/membase/report"
35
+ require "neuron-client/model/membase/s3_file"
36
+ require "neuron-client/model/membase/zone"
37
+
38
+ require "neuron-client/model/base"
39
+ require "neuron-client/model/models"
14
40
 
15
41
  class Object
16
42
  def blank?
@@ -22,4 +48,27 @@ class Object
22
48
  def present?
23
49
  !self.blank?
24
50
  end
25
- end
51
+ end
52
+
53
+ # lifted completely from the ruby facets gem source:
54
+ # /lib/core-uncommon/facets/module/cattr.rb
55
+ def Module
56
+ def cattr_writer(*syms)
57
+ syms.flatten.each do |sym|
58
+ module_eval(<<-EOS, __FILE__, __LINE__)
59
+ unless defined? @@#{sym}
60
+ @@#{sym} = nil
61
+ end
62
+
63
+ def self.#{sym}=(obj)
64
+ @@#{sym} = obj
65
+ end
66
+
67
+ def #{sym}=(obj)
68
+ @@#{sym}=(obj)
69
+ end
70
+ EOS
71
+ end
72
+ return syms
73
+ end
74
+ end
@@ -3,7 +3,7 @@ require 'yajl'
3
3
 
4
4
  module Neuron
5
5
  module Client
6
- class Connection
6
+ class AdminConnection
7
7
  def initialize(url, key)
8
8
  @url = url
9
9
  @key = key
@@ -19,7 +19,7 @@ module Neuron
19
19
 
20
20
  def get(path="", attrs={})
21
21
  format = attrs.delete(:format) || :json
22
- RestClient.get("#{@url}/#{[path, format].select(&:present?).join(".")}?#{query_string(attrs)}",
22
+ RestClient.get("#{@url}/#{[path, format].select(&:present?).join(".")}?#{query_string(attrs)}",
23
23
  format.present? ? {:content_type => format, :accept => format} : {}) do |response, request, result, &block|
24
24
  # follow redirection
25
25
  if [301, 302, 307].include? response.code
@@ -37,8 +37,8 @@ module Neuron
37
37
 
38
38
  def post(path="", form={}, attrs={})
39
39
  format = attrs.delete(:format) || :json
40
- RestClient.post("#{@url}/#{[path, format].select(&:present?).join(".")}?#{query_string(attrs)}",
41
- (format == :json ? Yajl.dump(form) : form),
40
+ RestClient.post("#{@url}/#{[path, format].select(&:present?).join(".")}?#{query_string(attrs)}",
41
+ (format == :json ? Yajl.dump(form) : form),
42
42
  format.present? ? {:content_type => format, :accept => format} : {}) do |response, request, result, &block|
43
43
  case response.code
44
44
  when 201
@@ -53,8 +53,8 @@ module Neuron
53
53
 
54
54
  def put(path="", form={}, attrs={})
55
55
  format = attrs.delete(:format) || :json
56
- RestClient.put("#{@url}/#{[path, format].select(&:present?).join(".")}?#{query_string}",
57
- (format == :json ? Yajl.dump(form) : form),
56
+ RestClient.put("#{@url}/#{[path, format].select(&:present?).join(".")}?#{query_string}",
57
+ (format == :json ? Yajl.dump(form) : form),
58
58
  format.present? ? {:content_type => format, :accept => format} : {}) do |response, request, result, &block|
59
59
  case response.code
60
60
  when 200
@@ -69,7 +69,7 @@ module Neuron
69
69
 
70
70
  def delete(path="", attrs={})
71
71
  format = attrs.delete(:format) || :json
72
- RestClient.delete("#{@url}/#{[path, format].select(&:present?).join(".")}?#{query_string(attrs)}",
72
+ RestClient.delete("#{@url}/#{[path, format].select(&:present?).join(".")}?#{query_string(attrs)}",
73
73
  format.present? ? {:content_type => format, :accept => format} : {}) do |response, request, result, &block|
74
74
  case response.code
75
75
  when 200
@@ -1,45 +1,62 @@
1
1
  module Neuron
2
2
  module Client
3
-
4
- # Neuron::Client::API.configure do |config|
5
- # config.admin_url = "https://example.com"
6
- # config.admin_key = "secret"
7
- # end
8
- #
9
- # Neuron::Client::API.connection
10
3
  class API
11
4
  autoload :OpenStruct, "ostruct"
12
- class << self
13
- attr_accessor :connection
5
+ attr_accessor :connection
14
6
 
15
- def reset!
16
- self.connection = nil
17
- @config = nil
18
- end
7
+ def configure
8
+ yield config
9
+ inclusion(config, :connection_type, [:admin, :membase])
10
+
11
+ configure_admin_connection if config.connection_type == :admin
12
+ configure_membase_connection if config.connection_type == :membase
13
+
14
+ self
15
+ end
16
+
17
+ def connection_type
18
+ @config.connection_type
19
+ end
19
20
 
20
- def configure
21
- @config ||= OpenStruct.new
22
- yield @config
23
- required(@config, :admin_url)
24
- required(@config, :admin_key)
25
- begin
26
- URI.parse(@config.admin_url)
27
- rescue
28
- raise "Invalid admin_url: #{@config.admin_url}"
29
- end
30
- self.connection = Connection.new(@config.admin_url, @config.admin_key)
31
- true
21
+ private
22
+
23
+ def config
24
+ @config ||= OpenStruct.new
25
+ end
26
+
27
+ def required(obj, attrib)
28
+ val = obj.send(attrib)
29
+ if val.nil? || (val.respond_to?(:empty?) && val.empty?)
30
+ raise "Missing: #{attrib}"
32
31
  end
32
+ end
33
33
 
34
- private
34
+ def inclusion(obj, attrib, valid_values)
35
+ val = obj.send(attrib)
36
+ raise "Inclusion: #{attrib} must be one of #{valid_values.join(', ')}" if !valid_values.include?(val)
37
+ end
35
38
 
36
- def required(obj, attrib)
37
- val = obj.send(attrib)
38
- if val.nil? || (val.respond_to?(:empty?) && val.empty?)
39
- raise "Missing: #{attrib}"
40
- end
39
+ def configure_admin_connection
40
+ required(config, :admin_url)
41
+ required(config, :admin_key)
42
+ begin
43
+ URI.parse(config.admin_url)
44
+ rescue
45
+ raise "Invalid admin_url: #{config.admin_url}"
41
46
  end
47
+ self.connection = AdminConnection.new(config.admin_url, config.admin_key)
48
+ end
49
+
50
+ def configure_membase_connection
51
+ required(@config, :membase_servers)
52
+ self.connection = MembaseConnection.new(config.membase_servers)
53
+ end
54
+
55
+ class << self
56
+ attr_accessor :default_api
42
57
  end
43
58
  end
59
+
60
+ API.default_api = API.new
44
61
  end
45
62
  end
@@ -0,0 +1,18 @@
1
+ require 'dalli'
2
+
3
+ module Neuron
4
+ module Client
5
+ class MembaseConnection
6
+
7
+ attr_reader :client
8
+
9
+ def initialize(servers)
10
+ @client = Dalli::Client.new(servers)
11
+ end
12
+
13
+ def get(key)
14
+ @client.get(key)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module Neuron
2
+ module Client
3
+ module Model
4
+ module Admin
5
+ class Ad < Common::Ad
6
+ include Base
7
+
8
+ # deliveries
9
+ attr_accessor :total_impressed, :today_impressed
10
+
11
+ def recent(statistic, parameters)
12
+ self.class.connection.get("ads/#{id}/recent/#{statistic}", parameters)
13
+ end
14
+
15
+ def unlink(zone_id)
16
+ self.class.connection.delete("ads/#{id}/zones/#{zone_id}")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module Neuron
2
+ module Client
3
+ module Model
4
+ module Admin
5
+ class AdZone < Common::AdZone
6
+ include Base
7
+
8
+ def self.unlink(ad_id, zone_id)
9
+ self.connection.delete("zones/#{zone_id}/ads/#{ad_id}")
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,91 @@
1
+ module Neuron
2
+ module Client
3
+ module Model
4
+ module Admin
5
+ module Base
6
+ def attributes
7
+ self.class.attributes || []
8
+ end
9
+
10
+ def to_hash(*except)
11
+ hash = {}
12
+ attributes.reject{|a| except.collect(&:to_sym).include?(a.to_sym)}.each do |attribute|
13
+ value = send(attribute)
14
+ hash[attribute] = value unless value.nil?
15
+ end
16
+ hash
17
+ end
18
+
19
+ def new_record?
20
+ id.nil?
21
+ end
22
+
23
+ def save
24
+ @errors = catch :errors do
25
+ if new_record?
26
+ response = self.class.connection.post("#{self.class.superclass.resources_name}", {self.class.superclass.resource_name => self.to_hash(:errors, :updated_at, :created_at)})
27
+ self.id = response[self.class.superclass.resource_name][self.class.remote_id]
28
+ else
29
+ response = self.class.connection.put("#{self.class.superclass.resources_name}/#{id}", {self.class.superclass.resource_name => self.to_hash(:errors, :updated_at, :created_at)})
30
+ end
31
+ []
32
+ end
33
+
34
+ @errors.empty?
35
+ end
36
+
37
+ def update_attributes(attrs={})
38
+ @errors = catch :errors do
39
+ response = self.class.connection.put("#{self.class.superclass.resources_name}/#{id}", {self.class.superclass.resource_name => attrs})
40
+ attrs.each do |key, value|
41
+ self.send("#{key}=", value) if self.respond_to?("#{key}=")
42
+ end
43
+ []
44
+ end
45
+
46
+ @errors.empty?
47
+ end
48
+
49
+ def valid?
50
+ @errors.empty?
51
+ end
52
+
53
+ def destroy
54
+ self.class.connection.delete("#{superclass.resources_name}/#{id}")
55
+ end
56
+
57
+ def self.included(base)
58
+ base.send(:attr_accessor, :errors)
59
+ base.extend(ClassMethods)
60
+ end
61
+
62
+ module ClassMethods
63
+ def find(id)
64
+ response = self.connection.get("#{superclass.resources_name}/#{id}")
65
+ model = nil
66
+ model = self.new(response[superclass.resource_name]) if response.present?
67
+ model
68
+ end
69
+
70
+ def all
71
+ response = self.connection.get("#{superclass.resources_name}")
72
+ response.map{|hash| self.new(hash[superclass.resource_name])}
73
+ end
74
+
75
+ def create(attrs={})
76
+ @errors = catch (:errors) do
77
+ return create!(attrs)
78
+ end
79
+ nil
80
+ end
81
+
82
+ def create!(attrs={})
83
+ response = self.connection.post("#{superclass.resources_name}", {superclass.resource_name => attrs})
84
+ self.new(response[superclass.resource_name])
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,12 @@
1
+ module Neuron
2
+ module Client
3
+ module Model
4
+ module Admin
5
+ class BlockedReferer < Common::BlockedReferer
6
+ include Base
7
+
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end