coach4rb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +8 -0
- data/coach4rb.gemspec +29 -0
- data/lib/coach4rb.rb +64 -0
- data/lib/coach4rb/builder.rb +142 -0
- data/lib/coach4rb/client.rb +116 -0
- data/lib/coach4rb/coach.rb +836 -0
- data/lib/coach4rb/json_response_parser.rb +11 -0
- data/lib/coach4rb/mixin/as_hash.rb +34 -0
- data/lib/coach4rb/mixin/auto_constructor.rb +71 -0
- data/lib/coach4rb/mixin/basic_auth.rb +23 -0
- data/lib/coach4rb/mixin/iterable.rb +40 -0
- data/lib/coach4rb/mixin/track_reader.rb +24 -0
- data/lib/coach4rb/mixin/track_writer.rb +19 -0
- data/lib/coach4rb/privacy.rb +11 -0
- data/lib/coach4rb/proxy.rb +143 -0
- data/lib/coach4rb/resource/entity.rb +47 -0
- data/lib/coach4rb/resource/entry.rb +126 -0
- data/lib/coach4rb/resource/page.rb +74 -0
- data/lib/coach4rb/resource/partnership.rb +37 -0
- data/lib/coach4rb/resource/sport.rb +19 -0
- data/lib/coach4rb/resource/subscription.rb +47 -0
- data/lib/coach4rb/resource/user.rb +49 -0
- data/lib/coach4rb/response_parser.rb +11 -0
- data/lib/coach4rb/version.rb +3 -0
- data/test/test_access_proxy.rb +58 -0
- data/test/test_client.rb +41 -0
- data/test/test_coach_client.rb +21 -0
- data/test/test_coach_entry.rb +141 -0
- data/test/test_coach_partnership.rb +115 -0
- data/test/test_coach_subscription.rb +110 -0
- data/test/test_coach_user.rb +191 -0
- data/test/test_entity.rb +63 -0
- data/test/test_entry_resource.rb +36 -0
- data/test/test_helper.rb +3 -0
- data/test/test_page.rb +82 -0
- data/test/test_partnership_resource.rb +69 -0
- data/test/test_sport_resource.rb +33 -0
- data/test/test_subscription_resource.rb +74 -0
- data/test/test_user_resource.rb +104 -0
- data/tools/.keep +0 -0
- metadata +190 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module Coach4rb
|
2
|
+
|
3
|
+
module Mixin
|
4
|
+
|
5
|
+
module AsHash
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.send :include, InstanceMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
|
14
|
+
# Converts this object to a hash.
|
15
|
+
#
|
16
|
+
def to_hash
|
17
|
+
variables = instance_variables
|
18
|
+
hash = {}
|
19
|
+
variables.each do |name|
|
20
|
+
key = name.to_s.sub(/^@/, '')
|
21
|
+
hash[key.to_sym] = instance_variable_get(name)
|
22
|
+
end
|
23
|
+
hash
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :to_h, :to_hash
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Coach4rb
|
2
|
+
|
3
|
+
module Mixin
|
4
|
+
|
5
|
+
# This module provides an auto constructor and automatically provides
|
6
|
+
# setters and getters for instance variables.
|
7
|
+
#
|
8
|
+
# The instance variables are created by the given hash
|
9
|
+
# which is passed to the constructor.
|
10
|
+
#
|
11
|
+
# The keys in the hash are used as instance variable names and the corresponding
|
12
|
+
# values are used to initialize the instance variable values.
|
13
|
+
#
|
14
|
+
# ==== Examples
|
15
|
+
#
|
16
|
+
# class Test
|
17
|
+
# include Behaviours::AutoConstructor
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# test = Test.new { name: 'alex' }
|
21
|
+
# test.name # => 'alex'
|
22
|
+
#
|
23
|
+
module AutoConstructor
|
24
|
+
|
25
|
+
def self.included(base)
|
26
|
+
base.send :include, InstanceMethods
|
27
|
+
end
|
28
|
+
|
29
|
+
module InstanceMethods
|
30
|
+
|
31
|
+
# Creates a object using the keys and values given in the hash.
|
32
|
+
#
|
33
|
+
# == Parameters:
|
34
|
+
# @param a_hash [Hash] declaring the instance variables. The keys define the variable names
|
35
|
+
# and the corresponding values the initial values.
|
36
|
+
#
|
37
|
+
# @return [Object] the object specified by the given hash.
|
38
|
+
def initialize(a_hash={})
|
39
|
+
raise 'Param a_hash is not a hash!' unless a_hash.is_a? Hash
|
40
|
+
a_hash.each do |key, value|
|
41
|
+
instance_variable_set("@#{key}", value)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# Provides hash-like access on the properties of this object.
|
47
|
+
# @param key [Symbol] used to access the corresponding property.
|
48
|
+
#
|
49
|
+
def [](key)
|
50
|
+
if value = instance_variable_get("@#{key}")
|
51
|
+
value
|
52
|
+
else
|
53
|
+
send key rescue nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# Provides hash-like access on the properties of this object.
|
59
|
+
# @param key [Symbol] used to access the corresponding property.
|
60
|
+
#
|
61
|
+
def []=(key,value)
|
62
|
+
instance_variable_set("@#{key}",value)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Coach4rb
|
2
|
+
|
3
|
+
module Mixin
|
4
|
+
|
5
|
+
module BasicAuth
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.send :include, InstanceMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
|
13
|
+
def basic_auth_encryption(username, password)
|
14
|
+
'Basic ' + Base64.encode64("#{username}:#{password}").chomp
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Coach4rb
|
2
|
+
|
3
|
+
module Mixin
|
4
|
+
|
5
|
+
module Iterable
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.send :include, InstanceMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
|
13
|
+
def has_next?
|
14
|
+
link = self.next
|
15
|
+
link ? link[:href] : false
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def next
|
20
|
+
links.detect { |link| link[:description] == 'next'}
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def has_previous?
|
25
|
+
link = previous
|
26
|
+
link ? link[:href] : false
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def previous
|
31
|
+
links.detect { |link| link[:description] == 'previous'}
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Coach4rb
|
2
|
+
|
3
|
+
module Mixin
|
4
|
+
|
5
|
+
|
6
|
+
module TrackReader
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.send :include, InstanceMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
|
14
|
+
def read_track
|
15
|
+
Base64.decode64(track)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Coach4rb
|
2
|
+
|
3
|
+
# This module provides global access to the cyber coach resources in the scope
|
4
|
+
# of the given user credentials.
|
5
|
+
#
|
6
|
+
module Proxy
|
7
|
+
|
8
|
+
# This class provides an interface that all subclasses must implement.
|
9
|
+
#
|
10
|
+
class Base
|
11
|
+
include Mixin::BasicAuth
|
12
|
+
|
13
|
+
attr_reader :coach
|
14
|
+
|
15
|
+
# Base access proxy which is extended by the subclasses to provide more specific access to the coach client.
|
16
|
+
#
|
17
|
+
# @param [Coach] coach
|
18
|
+
#
|
19
|
+
def initialize(coach)
|
20
|
+
@coach = coach
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def username
|
25
|
+
raise 'Not implemented!'
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def password
|
30
|
+
raise 'Not implemented!'
|
31
|
+
end
|
32
|
+
|
33
|
+
# Always returns an empty hash.
|
34
|
+
# @return [Hash]
|
35
|
+
#
|
36
|
+
def proxy_options
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# Tests if the provided user credentials are valid.
|
42
|
+
# @return [Boolean]
|
43
|
+
#
|
44
|
+
def valid?
|
45
|
+
begin
|
46
|
+
coach.authenticate(username, password)
|
47
|
+
rescue
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Delegates all messages send to this proxy to the coach client
|
54
|
+
#
|
55
|
+
def method_missing(meth, *args, &block)
|
56
|
+
params = *args
|
57
|
+
|
58
|
+
# handle options hash
|
59
|
+
if params.last.is_a?(Hash) # if last param is a hash then it's a option hash.
|
60
|
+
params[-1] = params.last.merge(proxy_options)
|
61
|
+
else # otherwise add a option hash with the given proxy options.
|
62
|
+
params << proxy_options
|
63
|
+
end
|
64
|
+
|
65
|
+
# check if coach responds to the message meth / or method meth
|
66
|
+
if coach.respond_to?(meth)
|
67
|
+
begin # try to pass the options hash
|
68
|
+
coach.send meth, *params, &block
|
69
|
+
rescue # otherwise do it without options hash
|
70
|
+
coach.send meth, *args, &block
|
71
|
+
end
|
72
|
+
else
|
73
|
+
raise 'Error: Method missing in coach!'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
# This class provides a general access proxy for the cyber coach service.
|
80
|
+
# It is used to have global access to the cuber coach service in the perspective of a specific user.
|
81
|
+
#
|
82
|
+
class Access < Base
|
83
|
+
|
84
|
+
attr_reader :username, :password
|
85
|
+
|
86
|
+
# Creates an access proxy which provides global access to the cyber coach in the scope of the
|
87
|
+
# given user credentials.
|
88
|
+
#
|
89
|
+
# @param [String] username
|
90
|
+
# @param [String] password
|
91
|
+
# @param [Coach] coach
|
92
|
+
#
|
93
|
+
def initialize(username, password, coach)
|
94
|
+
@username = username
|
95
|
+
@password = password
|
96
|
+
@coach = coach
|
97
|
+
@base64 = basic_auth_encryption(@username, @password)
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
# Returns an hash with basic auth http options.
|
102
|
+
# @return [Hash]
|
103
|
+
#
|
104
|
+
def proxy_options
|
105
|
+
{authorization: @base64}
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
# This class provides an invalid access proxy which will always fail.
|
112
|
+
#
|
113
|
+
class InvalidAccess < Base
|
114
|
+
|
115
|
+
# Returns always false.
|
116
|
+
# @return [FalseClass]
|
117
|
+
#
|
118
|
+
def valid?
|
119
|
+
false
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
# Returns always nil.
|
124
|
+
# @return [NilClass]
|
125
|
+
#
|
126
|
+
def username
|
127
|
+
nil
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
# Returns always nil.
|
132
|
+
# @return [NilClass]
|
133
|
+
#
|
134
|
+
def password
|
135
|
+
nil
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Coach4rb
|
2
|
+
|
3
|
+
module Resource
|
4
|
+
|
5
|
+
class Entity
|
6
|
+
|
7
|
+
include Mixin::AutoConstructor
|
8
|
+
include Mixin::Iterable
|
9
|
+
include Mixin::AsHash
|
10
|
+
include Enumerable
|
11
|
+
|
12
|
+
attr_accessor :uri, :links
|
13
|
+
|
14
|
+
def self.from_coach(param)
|
15
|
+
a_hash = param.dup
|
16
|
+
a_hash[:links] ||= []
|
17
|
+
self.new a_hash
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def each(&block)
|
22
|
+
instance_variables.each do |variable|
|
23
|
+
value = instance_variable_get(variable)
|
24
|
+
block.call variable, value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def [](key)
|
30
|
+
case key
|
31
|
+
when Symbol
|
32
|
+
super(key)
|
33
|
+
else
|
34
|
+
raise 'Error: param not supported!'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def entity_path
|
40
|
+
raise 'Not implemented!'
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Coach4rb
|
2
|
+
|
3
|
+
module Resource
|
4
|
+
|
5
|
+
class Entry < Entity
|
6
|
+
|
7
|
+
attr_accessor :id, :uri, :datecreated, :datemodified,
|
8
|
+
:entrydate, :comment, :entryduration,
|
9
|
+
:subscription, :entrylocation
|
10
|
+
|
11
|
+
alias_method :created, :datecreated
|
12
|
+
alias_method :modified, :datemodified
|
13
|
+
|
14
|
+
alias_method :entry_date, :entrydate
|
15
|
+
alias_method :entry_location, :entrylocation
|
16
|
+
|
17
|
+
|
18
|
+
def self.from_coach(a_hash)
|
19
|
+
entry_type = get_type(a_hash)
|
20
|
+
raise 'Error: Entry type not supported!' unless CLASS.keys.include?(entry_type)
|
21
|
+
|
22
|
+
entry = a_hash[entry_type].dup
|
23
|
+
entry[:datecreated] = Time.at(entry[:datecreated]/1000).to_datetime if entry[:datecreated]
|
24
|
+
entry[:datemodified] = Time.at(entry[:datemodified]/1000).to_datetime if entry[:datemodified]
|
25
|
+
entry[:subscription] = Resource::Subscription.from_coach entry[:subscription] if entry[:subscription]
|
26
|
+
entry[:links] ||= []
|
27
|
+
|
28
|
+
klass = CLASS[entry_type] # pick the right class to create the entry
|
29
|
+
klass.new(entry)
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def type
|
34
|
+
raise 'Not implemented!'
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def self.get_type(a_hash)
|
41
|
+
a_hash.keys.first
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
class Running < Entry
|
48
|
+
|
49
|
+
include Mixin::TrackReader
|
50
|
+
|
51
|
+
attr_accessor :coursetype, :courselength, :numberofrounds, :track
|
52
|
+
|
53
|
+
alias_method :course_type, :coursetype
|
54
|
+
alias_method :course_length, :courselength
|
55
|
+
alias_method :number_of_rounds, :numberofrounds
|
56
|
+
|
57
|
+
|
58
|
+
def type
|
59
|
+
:running
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
class Boxing < Entry
|
66
|
+
|
67
|
+
attr_accessor :roundduration, :numberofrounds
|
68
|
+
|
69
|
+
alias_method :round_duration, :roundduration
|
70
|
+
alias_method :number_of_rounds, :numberofrounds
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
def type
|
75
|
+
:boxing
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
class Soccer < Entry
|
82
|
+
|
83
|
+
def type
|
84
|
+
:soccer
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
class Cycling < Entry
|
91
|
+
|
92
|
+
include Mixin::TrackReader
|
93
|
+
|
94
|
+
attr_accessor :coursetype, :courselength, :numberofrounds,
|
95
|
+
:bicycletype, :track
|
96
|
+
|
97
|
+
alias_method :course_type, :coursetype
|
98
|
+
alias_method :course_length, :courselength
|
99
|
+
alias_method :number_of_rounds, :numberofrounds
|
100
|
+
alias_method :bicycle_type, :bicycletype
|
101
|
+
|
102
|
+
|
103
|
+
def type
|
104
|
+
:cycling
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
class Entry
|
111
|
+
|
112
|
+
# lookup table which associates the types to the correct classes.
|
113
|
+
CLASS = {
|
114
|
+
# :type => Class
|
115
|
+
:entryrunning => Running,
|
116
|
+
:entrysoccer => Soccer,
|
117
|
+
:entryboxing => Boxing,
|
118
|
+
:entrycycling => Cycling
|
119
|
+
}
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|