dyndrop 0.0.1 → 0.0.2

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.
@@ -0,0 +1,40 @@
1
+ require "net/https"
2
+ require "multi_json"
3
+
4
+ module Dyndrop
5
+ module TraceHelpers
6
+
7
+ def request_trace(request)
8
+ return nil unless request
9
+ info = ["REQUEST: #{request[:method]} #{request[:url]}"]
10
+ info << "REQUEST_HEADERS:"
11
+ info << header_trace(request[:headers])
12
+ info << "REQUEST_BODY: #{request[:body]}" if request[:body]
13
+ info.join("\n")
14
+ end
15
+
16
+
17
+ def response_trace(response)
18
+ return nil unless response
19
+ info = ["RESPONSE: [#{response[:status]}]"]
20
+ info << "RESPONSE_HEADERS:"
21
+ info << header_trace(response[:headers])
22
+ info << "RESPONSE_BODY:"
23
+ begin
24
+ parsed_body = MultiJson.load(response[:body])
25
+ info << MultiJson.dump(parsed_body, :pretty => true)
26
+ rescue
27
+ info << "#{response[:body]}"
28
+ end
29
+ info.join("\n")
30
+ end
31
+
32
+ private
33
+
34
+ def header_trace(headers)
35
+ headers.sort.map do |key, value|
36
+ " #{key} : #{value}"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,28 @@
1
+ require "multi_json"
2
+ require "tmpdir"
3
+
4
+ require "dyndrop/baseclient"
5
+
6
+ require "dyndrop/errors"
7
+
8
+ module Dyndrop::V1
9
+ class Base < Dyndrop::BaseClient
10
+
11
+ def get_token(email, payload)
12
+ post("1", "users", email, "tokens", :content => :json, :accept => :json, :payload => payload)
13
+ end
14
+
15
+ # Users
16
+ def create_user(payload)
17
+ # no JSON response
18
+ post("users", :content => :json, :payload => payload)
19
+ end
20
+
21
+ # Applications
22
+ def instances(name)
23
+ get("apps", name, "instances", :accept => :json)[:instances]
24
+ end
25
+
26
+
27
+ end
28
+ end
@@ -0,0 +1,114 @@
1
+ module Dyndrop::V1
2
+ # The primary API entrypoint. Wraps a BaseClient to provide nicer return
3
+ # values. Initialize with the target and, optionally, an auth token. These
4
+ # are the only two internal states.
5
+ class Client
6
+
7
+ attr_reader :base
8
+
9
+ # Create a new Client for interfacing with the given target.
10
+ #
11
+ # A token may also be provided to skip the login step.
12
+ def initialize(target = "http://api.dyndrop.com", token = nil)
13
+ @base = Base.new(target, token)
14
+ end
15
+
16
+ def version
17
+ 1
18
+ end
19
+
20
+ # The current target URL of the client.
21
+ def target
22
+ @base.target
23
+ end
24
+
25
+ # Current authentication token.
26
+ def token
27
+ @base.token
28
+ end
29
+
30
+ # Set the authentication token.
31
+ def token=(token)
32
+ @base.token = token
33
+ end
34
+
35
+ # Current proxy user. Usually nil.
36
+ def proxy
37
+ @base.proxy
38
+ end
39
+
40
+ # Set the proxy user for the client. Must be authorized as an
41
+ # administrator for this to have any effect.
42
+ def proxy=(email)
43
+ @base.proxy = email
44
+ end
45
+
46
+ # Is the client tracing API requests?
47
+ def trace
48
+ @base.trace
49
+ end
50
+
51
+ # Set the tracing flag; if true, API requests and responses will be
52
+ # printed out.
53
+ def trace=(bool)
54
+ @base.trace = bool
55
+ end
56
+
57
+ # The current log. See +log=+.
58
+ def log
59
+ @base.log
60
+ end
61
+
62
+ # Set the logging mode. Mode can be one of:
63
+ #
64
+ # [+String+] Name of a file to log the last 10 requests to.
65
+ # [+Array+] Array to append with log data (a Hash).
66
+ # [+IO+] An IO object to write to.
67
+ # [+false+] No logging.
68
+ def log=(mode)
69
+ @base.log = mode
70
+ end
71
+
72
+ # The currently authenticated user.
73
+ def current_user
74
+ if user = info[:user]
75
+ user(user)
76
+ end
77
+ end
78
+
79
+ def current_space
80
+ nil
81
+ end
82
+
83
+ def current_org
84
+ nil
85
+ end
86
+
87
+
88
+ # Retrieve target metadata.
89
+ def info
90
+ @base.info
91
+ end
92
+
93
+ def login(username, password)
94
+ @base.token = Dyndrop::AuthToken.from_token_info(@base.get_token(username, {:password => password}))
95
+ end
96
+
97
+
98
+ # Create a user on the target and return a User object representing them.
99
+ def register(email, password)
100
+ @base.create_user(:email => email, :password => password)
101
+ user(email)
102
+ end
103
+
104
+ # Clear client token. No requests are made for this.
105
+ def logout
106
+ @base.token = nil
107
+ end
108
+
109
+ # Is an authentication token set on the client?
110
+ def logged_in?
111
+ !!@base.token
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,129 @@
1
+ require "dyndrop/validator"
2
+
3
+ module Dyndrop::V1
4
+ module BaseClientMethods
5
+ end
6
+
7
+ module ClientMethods
8
+ end
9
+
10
+ module ModelMagic
11
+ attr_accessor :guid_name
12
+
13
+ def read_locations
14
+ @read_locations ||= {}
15
+ end
16
+
17
+ def write_locations
18
+ @write_locations ||= {}
19
+ end
20
+
21
+ def read_only_attributes
22
+ @read_only_attributes ||= []
23
+ end
24
+
25
+ def on_client(&blk)
26
+ ClientMethods.module_eval(&blk)
27
+ end
28
+
29
+ def on_base_client(&blk)
30
+ BaseClientMethods.module_eval(&blk)
31
+ end
32
+
33
+ def define_client_methods(klass = self)
34
+ singular = klass.object_name
35
+ plural = klass.plural_object_name
36
+
37
+ base_singular = klass.base_object_name
38
+ base_plural = klass.plural_base_object_name
39
+
40
+ on_base_client do
41
+ define_method(base_singular) do |guid|
42
+ get(base_plural, guid, :accept => :json)
43
+ end
44
+
45
+ define_method(:"create_#{base_singular}") do |payload|
46
+ post(base_plural, :content => :json, :accept => :json, :payload => payload)
47
+ end
48
+
49
+ define_method(:"delete_#{base_singular}") do |guid|
50
+ delete(base_plural, guid)
51
+ true
52
+ end
53
+
54
+ define_method(:"update_#{base_singular}") do |guid, payload|
55
+ put(base_plural, guid, :content => :json, :payload => payload)
56
+ end
57
+
58
+ define_method(base_plural) do |*args|
59
+ get(base_plural, :accept => :json)
60
+ end
61
+ end
62
+
63
+ on_client do
64
+ if klass.guid_name
65
+ define_method(:"#{singular}_by_#{klass.guid_name}") do |guid|
66
+ obj = send(singular, guid)
67
+ obj if obj.exists?
68
+ end
69
+ end
70
+
71
+ define_method(singular) do |*args|
72
+ guid, _ = args
73
+ klass.new(guid, self)
74
+ end
75
+
76
+ define_method(plural) do |*args|
77
+ options, _ = args
78
+ options ||= {}
79
+
80
+ @base.send(base_plural).collect do |json|
81
+ klass.new(json[klass.guid_name], self, json)
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ def attribute(name, type, opts = {})
88
+ default = opts[:default]
89
+ is_guid = opts[:guid]
90
+ read_only = opts[:read_only]
91
+ write_only = opts[:write_only]
92
+ has_default = opts.key?(:default)
93
+
94
+ read_locations[name] = Array(opts[:read] || opts[:at] || name) unless write_only
95
+ write_locations[name] = Array(opts[:write] || opts[:at] || name) unless read_only
96
+
97
+ read_only_attributes << name if read_only
98
+
99
+ self.guid_name = name if is_guid
100
+
101
+ define_method(name) do
102
+ return @guid if @guid && is_guid
103
+
104
+ read = read_manifest
105
+ read.key?(name) ? read[name] : default
106
+ end
107
+
108
+ define_method(:"#{name}=") do |val|
109
+ unless has_default && val == default
110
+ Dyndrop::Validator.validate_type(val, type)
111
+ end
112
+
113
+ @guid = val if is_guid
114
+
115
+ @manifest ||= {}
116
+
117
+ old = read_manifest[name]
118
+ @changes[name] = [old, val] if old != val
119
+
120
+ write_to = read_only ? self.class.read_locations : self.class.write_locations
121
+
122
+ put(val, @manifest, write_to[name])
123
+ end
124
+
125
+ private name if write_only
126
+ private :"#{name}=" if read_only
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,39 @@
1
+ module Dyndrop
2
+ module Validator
3
+ class << self
4
+ def value_matches?(val, type)
5
+ case type
6
+ when Class
7
+ val.is_a?(type)
8
+ when Regexp
9
+ val.is_a?(String) && val =~ type
10
+ when :url
11
+ value_matches?(val, URI::regexp(%w(http https)))
12
+ when :https_url
13
+ value_matches?(val, URI::regexp("https"))
14
+ when :boolean
15
+ val.is_a?(TrueClass) || val.is_a?(FalseClass)
16
+ when Array
17
+ val.all? do |x|
18
+ value_matches?(x, type.first)
19
+ end
20
+ when Hash
21
+ val.is_a?(Hash) &&
22
+ type.all? { |name, subtype|
23
+ val.key?(name) && value_matches?(val[name], subtype)
24
+ }
25
+ when nil
26
+ true
27
+ else
28
+ val.is_a?(Object.const_get(type.to_s.capitalize))
29
+ end
30
+ end
31
+
32
+ def validate_type(val, type)
33
+ unless value_matches?(val, type)
34
+ raise Dyndrop::Mismatch.new(type, val)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,4 +1,4 @@
1
1
  module Dyndrop # :nodoc:
2
2
  # Dyndrop library version number.
3
- VERSION = "0.0.1".freeze
3
+ VERSION = "0.0.2".freeze
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dyndrop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -19,7 +19,19 @@ executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
+ - LICENSE
23
+ - lib/dyndrop.rb
24
+ - lib/dyndrop/baseclient.rb
22
25
  - lib/dyndrop/version.rb
26
+ - lib/dyndrop/client.rb
27
+ - lib/dyndrop/auth_token.rb
28
+ - lib/dyndrop/errors.rb
29
+ - lib/dyndrop/rest_client.rb
30
+ - lib/dyndrop/validator.rb
31
+ - lib/dyndrop/trace_helpers.rb
32
+ - lib/dyndrop/v1/client.rb
33
+ - lib/dyndrop/v1/model_magic.rb
34
+ - lib/dyndrop/v1/base.rb
23
35
  homepage: http://github.com/dyndrop/dyndrop
24
36
  licenses: []
25
37
  post_install_message: