coach4rb 0.0.1
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.
- 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
|