timetree 0.0.1 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +53 -3
- data/lib/timetree.rb +9 -12
- data/lib/timetree/activity.rb +49 -0
- data/lib/timetree/api_error.rb +29 -0
- data/lib/timetree/base_model.rb +138 -0
- data/lib/timetree/calendar.rb +82 -0
- data/lib/timetree/client.rb +145 -107
- data/lib/timetree/configuration.rb +5 -1
- data/lib/timetree/event.rb +144 -0
- data/lib/timetree/http_command.rb +79 -0
- data/lib/timetree/label.rb +11 -0
- data/lib/timetree/user.rb +13 -0
- data/lib/timetree/version.rb +1 -1
- data/timetree.gemspec +1 -0
- metadata +24 -3
- data/lib/timetree/models.rb +0 -282
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6acdee0d0822340b25b56705ae9ffb72e031a831c44755b87004471bb015c65
|
4
|
+
data.tar.gz: cf2be6cc1d35cdb59d686b6caed4fd967919369eafceb3867bd0cf5f0459d37a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f10a43690969abeae928366c13face88ed28fd3507e6fcd1b708e8bca0d61bc7772dbeaf9d9bff92d3bd24ac55e122aa5a6d84595aa7f8aa312581f682b8d491
|
7
|
+
data.tar.gz: 91a90869f53fde95f56cd7d0f987d7b376fb5db7ddcff15cbf86b66e1b6bedf90110f158ec4a9eb8b0893934d825c07af1a73f24e8f460f5488fe331fc7682af
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# TimeTree
|
1
|
+
# Simple TimeTree apis client
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/timetree)
|
4
4
|
|
@@ -30,14 +30,64 @@ Set `access_token` to the value you got by above:
|
|
30
30
|
```ruby
|
31
31
|
# using configure
|
32
32
|
TimeTree.configure do |config|
|
33
|
-
config.
|
33
|
+
config.token = '<YOUR_ACCESS_TOKEN>'
|
34
34
|
end
|
35
35
|
client = TimeTree::Client.new
|
36
36
|
|
37
37
|
# using initializer
|
38
38
|
client = TimeTree::Client.new('<YOUR_ACCESS_TOKEN>')
|
39
39
|
|
40
|
-
#
|
40
|
+
# get a current user's information
|
41
|
+
user = client.current_user
|
42
|
+
=> #<TimeTree::User id:xxx_u001>
|
43
|
+
user.name
|
44
|
+
=> "USER Name 001"
|
45
|
+
|
46
|
+
# get current user's calendars
|
47
|
+
cals = client.calendars
|
48
|
+
=> [#<TimeTree::Calendar id:xxx_cal001>, #<TimeTree::Calendar id:xxx_cal002>, ...]
|
49
|
+
|
50
|
+
cal = cals.first
|
51
|
+
cal.name
|
52
|
+
=> "Calendar Name 001"
|
53
|
+
|
54
|
+
# get upcoming events on the calendar
|
55
|
+
evs = cal.upcoming_events
|
56
|
+
=> [#<TimeTree::Event id:xxx_ev001>, #<TimeTree::Event id:xxx_ev002>, ...]
|
57
|
+
ev = evs.first
|
58
|
+
ev.title
|
59
|
+
=> "Event Name 001"
|
60
|
+
|
61
|
+
# updates an event
|
62
|
+
ev.title += ' Updated'
|
63
|
+
ev.start_at = Time.parse('2020-06-20 09:00 +09:00')
|
64
|
+
ev.end_at = Time.parse('2020-06-20 10:00 +09:00')
|
65
|
+
ev.update
|
66
|
+
=> #<TimeTree::Event id:xxx_ev001>
|
67
|
+
|
68
|
+
# creates an event
|
69
|
+
copy_ev = ev.dup
|
70
|
+
new_ev = copy_ev.create
|
71
|
+
=> #<TimeTree::Event id:xxx_newev001>
|
72
|
+
|
73
|
+
# deletes an event
|
74
|
+
ev.delete
|
75
|
+
=> true
|
76
|
+
|
77
|
+
# creates comment to an event
|
78
|
+
ev.create_comment 'HOGE HOGE message.'
|
79
|
+
=> #<TimeTree::Activity id:xxx_act001>
|
80
|
+
|
81
|
+
# check apis error response
|
82
|
+
begin
|
83
|
+
ev.delete
|
84
|
+
ev.delete # 404 Error occured.
|
85
|
+
rescue TimeTree::ApiError => e
|
86
|
+
e
|
87
|
+
=> #<TimeTree::ApiError title:Not Found, status:404>
|
88
|
+
e.response
|
89
|
+
=> #<Faraday::Response>
|
90
|
+
end
|
41
91
|
```
|
42
92
|
|
43
93
|
## Contributing
|
data/lib/timetree.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
].sort.each do |f|
|
10
|
-
require f
|
11
|
-
end
|
3
|
+
require 'zeitwerk'
|
4
|
+
loader = Zeitwerk::Loader.for_gem
|
5
|
+
loader.inflector.inflect(
|
6
|
+
'timetree' => 'TimeTree'
|
7
|
+
)
|
8
|
+
loader.setup
|
12
9
|
|
10
|
+
# module for TimeTree apis client
|
13
11
|
module TimeTree
|
12
|
+
class Error < StandardError
|
13
|
+
end
|
14
14
|
class << self
|
15
15
|
def configure
|
16
16
|
yield configuration
|
@@ -20,7 +20,4 @@ module TimeTree
|
|
20
20
|
@configuration ||= Configuration.new
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
24
|
-
class Error < StandardError
|
25
|
-
end
|
26
23
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TimeTree
|
4
|
+
# Model for TimeTree comment.
|
5
|
+
class Activity < BaseModel
|
6
|
+
# @return [String]
|
7
|
+
attr_accessor :content
|
8
|
+
# @return [Time]
|
9
|
+
attr_accessor :updated_at
|
10
|
+
# @return [Time]
|
11
|
+
attr_accessor :created_at
|
12
|
+
# calendar's id.
|
13
|
+
# @return [String]
|
14
|
+
attr_accessor :calendar_id
|
15
|
+
# event's id.
|
16
|
+
# @return [String]
|
17
|
+
attr_accessor :event_id
|
18
|
+
|
19
|
+
TIME_FIELDS = %i[updated_at created_at].freeze
|
20
|
+
|
21
|
+
#
|
22
|
+
# Creates a comment to the associated event.
|
23
|
+
#
|
24
|
+
# @return [TimeTree::Activity]
|
25
|
+
# @raise [TimeTree::Error] if @client is not set.
|
26
|
+
# @raise [TimeTree::Error] if the calendar_id property is not set.
|
27
|
+
# @raise [TimeTree::Error] if the event_id property is not set.
|
28
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
29
|
+
# @since 0.0.1
|
30
|
+
def create
|
31
|
+
raise Error, '@client is nil.' if @client.nil?
|
32
|
+
raise Error, 'calendar_id is required.' if calendar_id.nil?
|
33
|
+
raise Error, 'event_id is required.' if event_id.nil?
|
34
|
+
|
35
|
+
@client.create_activity calendar_id, event_id, data_params
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# convert to a TimeTree request body format.
|
40
|
+
#
|
41
|
+
# @return [Hash]
|
42
|
+
# @since 0.0.1
|
43
|
+
def data_params
|
44
|
+
{
|
45
|
+
data: { attributes: { content: content } }
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TimeTree
|
4
|
+
# TimeTree apis client error object.
|
5
|
+
class ApiError < StandardError
|
6
|
+
# @return [Faraday::Response]
|
7
|
+
attr_reader :response
|
8
|
+
# @return [String]
|
9
|
+
attr_reader :type
|
10
|
+
# @return [String]
|
11
|
+
attr_reader :title
|
12
|
+
# @return [String]
|
13
|
+
attr_reader :errors
|
14
|
+
# @return [Integer]
|
15
|
+
attr_reader :status
|
16
|
+
|
17
|
+
def initialize(response)
|
18
|
+
@response = response
|
19
|
+
@type = response.body[:type]
|
20
|
+
@title = response.body[:title]
|
21
|
+
@errors = response.body[:errors]
|
22
|
+
@status = response.status
|
23
|
+
end
|
24
|
+
|
25
|
+
def inspect
|
26
|
+
"\#<#{self.class}:#{object_id} title:#{@title}, status:#{@status}>"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module TimeTree
|
6
|
+
# TimeTree base model object.
|
7
|
+
class BaseModel
|
8
|
+
# @return [Array<Hash<String,String>>]
|
9
|
+
attr_accessor :relationships
|
10
|
+
# @return [String]
|
11
|
+
attr_reader :id
|
12
|
+
# @return [String]
|
13
|
+
attr_reader :type
|
14
|
+
|
15
|
+
# @param data [Hash]
|
16
|
+
# TimeTree apis's response data.
|
17
|
+
# @param included [Hash]
|
18
|
+
# @param client [TimeTree::Client]
|
19
|
+
# @return [TimeTree::User, TimeTree::Label, TimeTree::Calendar, TimeTree::Event, TimeTree::Activity]
|
20
|
+
# A TimeTree model object that be based on the type.
|
21
|
+
# @raise [TimeTree::Error] if the type property is not set.
|
22
|
+
# @since 0.0.1
|
23
|
+
def self.to_model(data, included: nil, client: nil)
|
24
|
+
id = data[:id]
|
25
|
+
type = data[:type]
|
26
|
+
raise Error, 'type is required.' if type.nil?
|
27
|
+
|
28
|
+
attributes = data[:attributes] || {}
|
29
|
+
relationships = data[:relationships] || {}
|
30
|
+
params = {
|
31
|
+
id: id,
|
32
|
+
type: type,
|
33
|
+
client: client,
|
34
|
+
attributes: attributes,
|
35
|
+
relationships: relationships,
|
36
|
+
included: included
|
37
|
+
}
|
38
|
+
|
39
|
+
case type
|
40
|
+
when 'user'
|
41
|
+
User.new(**params)
|
42
|
+
when 'label'
|
43
|
+
Label.new(**params)
|
44
|
+
when 'calendar'
|
45
|
+
Calendar.new(**params)
|
46
|
+
when 'event'
|
47
|
+
Event.new(**params)
|
48
|
+
when 'activity'
|
49
|
+
Activity.new(**params)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize(id:, type:, client: nil, attributes: nil, relationships: nil, included: nil)
|
54
|
+
@id = id
|
55
|
+
@type = type
|
56
|
+
@client = client
|
57
|
+
set_attributes attributes
|
58
|
+
set_relationships relationships, included
|
59
|
+
end
|
60
|
+
|
61
|
+
def inspect
|
62
|
+
"\#<#{self.class}:#{object_id} id:#{id}>"
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def to_model(data)
|
68
|
+
self.class.to_model data, client: @client
|
69
|
+
end
|
70
|
+
|
71
|
+
def set_attributes(attributes)
|
72
|
+
return unless attributes.is_a? Hash
|
73
|
+
return if attributes.empty?
|
74
|
+
|
75
|
+
setter_methods = self.class.instance_methods.select { |method| method.to_s.end_with? '=' }
|
76
|
+
attributes.each do |key, value|
|
77
|
+
setter = "#{key.to_sym}=".to_sym
|
78
|
+
next unless setter_methods.include? setter
|
79
|
+
|
80
|
+
if defined?(self.class::TIME_FIELDS) && self.class::TIME_FIELDS.include?(key)
|
81
|
+
value = Time.parse value
|
82
|
+
end
|
83
|
+
instance_variable_set "@#{key}", value
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def set_relationships(relationships, included)
|
88
|
+
return unless relationships.is_a? Hash
|
89
|
+
return if relationships.empty?
|
90
|
+
return unless defined? self.class::RELATIONSHIPS
|
91
|
+
return if self.class::RELATIONSHIPS.empty?
|
92
|
+
|
93
|
+
self.class::RELATIONSHIPS.each do |key|
|
94
|
+
relation = relationships[key]
|
95
|
+
next unless relation
|
96
|
+
next unless relation[:data]
|
97
|
+
|
98
|
+
@relationships ||= {}
|
99
|
+
@relationships[key] = relation[:data]
|
100
|
+
end
|
101
|
+
|
102
|
+
return if included.nil?
|
103
|
+
return unless included.is_a? Array
|
104
|
+
return if included.empty?
|
105
|
+
|
106
|
+
set_relationship_data_if_included(included)
|
107
|
+
end
|
108
|
+
|
109
|
+
def set_relationship_data_if_included(included)
|
110
|
+
@_relation_data_dic = {}
|
111
|
+
included.each do |data|
|
112
|
+
item = to_model(data)
|
113
|
+
next unless item
|
114
|
+
|
115
|
+
@_relation_data_dic[item.type] ||= {}
|
116
|
+
@_relation_data_dic[item.type][item.id] = item
|
117
|
+
end
|
118
|
+
detect_relation_data = lambda { |type, id|
|
119
|
+
return unless @_relation_data_dic[type]
|
120
|
+
|
121
|
+
@_relation_data_dic[type][id]
|
122
|
+
}
|
123
|
+
@relationships.each do |key, id_data|
|
124
|
+
relation_data = nil
|
125
|
+
if id_data.is_a? Array
|
126
|
+
relation_data = []
|
127
|
+
id_data.each do |d|
|
128
|
+
item = detect_relation_data.call(d[:type], d[:id])
|
129
|
+
relation_data << item if item
|
130
|
+
end
|
131
|
+
elsif id_data.is_a? Hash
|
132
|
+
relation_data = detect_relation_data.call(id_data[:type], id_data[:id])
|
133
|
+
end
|
134
|
+
instance_variable_set "@#{key}", relation_data if relation_data
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TimeTree
|
4
|
+
# Model for TimeTree calendar.
|
5
|
+
class Calendar < BaseModel
|
6
|
+
# @return [String]
|
7
|
+
attr_accessor :name
|
8
|
+
# @return [String]
|
9
|
+
attr_accessor :description
|
10
|
+
# @return [String]
|
11
|
+
attr_accessor :color
|
12
|
+
# @return [Integer]
|
13
|
+
attr_accessor :order
|
14
|
+
# @return [String]
|
15
|
+
attr_accessor :image_url
|
16
|
+
# @return [Time]
|
17
|
+
attr_accessor :created_at
|
18
|
+
|
19
|
+
TIME_FIELDS = %i[created_at].freeze
|
20
|
+
RELATIONSHIPS = %i[labels members].freeze
|
21
|
+
|
22
|
+
#
|
23
|
+
# Get the event's information.
|
24
|
+
#
|
25
|
+
# @param event_id [String]
|
26
|
+
# event's id.
|
27
|
+
# @return [TimeTree::Event]
|
28
|
+
# @raise [TimeTree::Error] if @client is not set.
|
29
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
30
|
+
# @since 0.0.1
|
31
|
+
def event(event_id)
|
32
|
+
raise Error, '@client is nil.' if @client.nil?
|
33
|
+
|
34
|
+
@client.event id, event_id
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Get the events' information after a request date.
|
39
|
+
#
|
40
|
+
# @param days [Integer]
|
41
|
+
# The number of days to get.
|
42
|
+
# @param timezone [String]
|
43
|
+
# Timezone.
|
44
|
+
# @return [Array<TimeTree::Event>]
|
45
|
+
# @raise [TimeTree::Error] if @client is not set.
|
46
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
47
|
+
# @since 0.0.1
|
48
|
+
def upcoming_events(days: 7, timezone: 'UTC')
|
49
|
+
raise Error, '@client is nil.' if @client.nil?
|
50
|
+
|
51
|
+
@client.upcoming_events id, days: days, timezone: timezone
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Get a calendar's label information used in event.
|
56
|
+
#
|
57
|
+
# @return [Array<TimeTree::Label>]
|
58
|
+
# @raise [TimeTree::Error] if @client is not set.
|
59
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
60
|
+
# @since 0.0.1
|
61
|
+
def labels
|
62
|
+
return @labels if defined? @labels
|
63
|
+
raise Error, '@client is nil.' if @client.nil?
|
64
|
+
|
65
|
+
@labels = @client.calendar_labels id
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Get a calendar's member information.
|
70
|
+
#
|
71
|
+
# @return [Array<TimeTree::User>]
|
72
|
+
# @raise [TimeTree::Error] if @client is not set.
|
73
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
74
|
+
# @since 0.0.1
|
75
|
+
def members
|
76
|
+
return @members if defined? @members
|
77
|
+
raise Error, '@client is nil.' if @client.nil?
|
78
|
+
|
79
|
+
@members = @client.calendar_members id
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/timetree/client.rb
CHANGED
@@ -1,99 +1,137 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'time'
|
4
|
-
require 'faraday'
|
5
|
-
require 'faraday_middleware'
|
6
|
-
|
7
3
|
module TimeTree
|
4
|
+
# TimeTree apis client.
|
8
5
|
class Client
|
9
6
|
API_HOST = 'https://timetreeapis.com'
|
10
|
-
|
7
|
+
# @return [String]
|
8
|
+
attr_reader :token
|
9
|
+
# @return [Integer]
|
11
10
|
attr_reader :ratelimit_limit
|
11
|
+
# @return [Integer]
|
12
12
|
attr_reader :ratelimit_remaining
|
13
|
+
# @return [Time]
|
13
14
|
attr_reader :ratelimit_reset_at
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
@
|
18
|
-
|
19
|
-
end
|
16
|
+
# @param token [String] a TimeTree's access token.
|
17
|
+
def initialize(token = nil)
|
18
|
+
@token = token || TimeTree.configuration.token
|
19
|
+
raise Error, 'token is required.' unless ready_token?
|
20
20
|
|
21
|
-
|
22
|
-
limit_info = nil
|
23
|
-
if @ratelimit_limit
|
24
|
-
limit_info = " ratelimit:#{@ratelimit_remaining}/#{@ratelimit_limit}"
|
25
|
-
end
|
26
|
-
if @ratelimit_reset_at
|
27
|
-
limit_info = "#{limit_info}, reset_at:#{@ratelimit_reset_at.strftime('%m/%d %R')}"
|
28
|
-
end
|
29
|
-
"\#<#{self.class}:#{object_id}#{limit_info}>"
|
21
|
+
@http_cmd = HttpCommand.new(API_HOST, self)
|
30
22
|
end
|
31
23
|
|
32
24
|
#
|
33
|
-
#
|
25
|
+
# Get current user information.
|
34
26
|
#
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
27
|
+
# @return [TimeTree::User]
|
28
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
29
|
+
# @since 0.0.1
|
30
|
+
def current_user
|
31
|
+
res = @http_cmd.get '/user'
|
32
|
+
raise ApiError, res if res.status != 200
|
39
33
|
|
40
34
|
to_model res.body[:data]
|
41
35
|
end
|
42
36
|
|
43
37
|
#
|
44
|
-
#
|
38
|
+
# Get a single calendar's information.
|
45
39
|
#
|
46
|
-
|
40
|
+
# @param cal_id [String] calendar's id.
|
41
|
+
# @param include_relationships [Array<symbol>]
|
42
|
+
# includes association's object in the response.
|
43
|
+
# @return [TimeTree::Calendar]
|
44
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
45
|
+
# @since 0.0.1
|
47
46
|
def calendar(cal_id, include_relationships: nil)
|
48
47
|
params = relationships_params(include_relationships, Calendar::RELATIONSHIPS)
|
49
|
-
res = get "/calendars/#{cal_id}", params
|
50
|
-
raise if res.status != 200
|
48
|
+
res = @http_cmd.get "/calendars/#{cal_id}", params
|
49
|
+
raise ApiError, res if res.status != 200
|
51
50
|
|
52
51
|
to_model(res.body[:data], included: res.body[:included])
|
53
52
|
end
|
54
53
|
|
54
|
+
#
|
55
|
+
# Get calendar list that current user can access.
|
56
|
+
#
|
57
|
+
# @param include_relationships [Array<symbol>]
|
58
|
+
# includes association's object in the response.
|
59
|
+
# @return [Array<TimeTree::Calendar>]
|
60
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
61
|
+
# @since 0.0.1
|
55
62
|
def calendars(include_relationships: nil)
|
56
63
|
params = relationships_params(include_relationships, Calendar::RELATIONSHIPS)
|
57
|
-
res = get '/calendars', params
|
58
|
-
raise if res.status != 200
|
64
|
+
res = @http_cmd.get '/calendars', params
|
65
|
+
raise ApiError, res if res.status != 200
|
59
66
|
|
60
67
|
included = res.body[:included]
|
61
68
|
res.body[:data].map { |item| to_model(item, included: included) }
|
62
69
|
end
|
63
70
|
|
71
|
+
#
|
72
|
+
# Get a calendar's label information used in event.
|
73
|
+
#
|
74
|
+
# @param cal_id [String] calendar's id.
|
75
|
+
# @return [Array<TimeTree::Label>]
|
76
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
77
|
+
# @since 0.0.1
|
64
78
|
def calendar_labels(cal_id)
|
65
|
-
res = get "/calendars/#{cal_id}/labels"
|
66
|
-
raise if res.status != 200
|
79
|
+
res = @http_cmd.get "/calendars/#{cal_id}/labels"
|
80
|
+
raise ApiError, res if res.status != 200
|
67
81
|
|
68
82
|
res.body[:data].map { |item| to_model(item) }
|
69
83
|
end
|
70
84
|
|
85
|
+
#
|
86
|
+
# Get a calendar's member information.
|
87
|
+
#
|
88
|
+
# @param cal_id [String] calendar's id.
|
89
|
+
# @return [Array<TimeTree::User>]
|
90
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
91
|
+
# @since 0.0.1
|
71
92
|
def calendar_members(cal_id)
|
72
|
-
res = get "/calendars/#{cal_id}/members"
|
73
|
-
raise if res.status != 200
|
93
|
+
res = @http_cmd.get "/calendars/#{cal_id}/members"
|
94
|
+
raise ApiError, res if res.status != 200
|
74
95
|
|
75
96
|
res.body[:data].map { |item| to_model item }
|
76
97
|
end
|
77
98
|
|
78
99
|
#
|
79
|
-
#
|
100
|
+
# Get the event's information.
|
80
101
|
#
|
81
|
-
|
102
|
+
# @param cal_id [String] calendar's id.
|
103
|
+
# @param event_id [String] event's id.
|
104
|
+
# @param include_relationships [Array<symbol>]
|
105
|
+
# includes association's object in the response.
|
106
|
+
# @return [TimeTree::Event]
|
107
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
108
|
+
# @since 0.0.1
|
82
109
|
def event(cal_id, event_id, include_relationships: nil)
|
83
110
|
params = relationships_params(include_relationships, Event::RELATIONSHIPS)
|
84
|
-
res = get "/calendars/#{cal_id}/events/#{event_id}", params
|
85
|
-
raise if res.status != 200
|
111
|
+
res = @http_cmd.get "/calendars/#{cal_id}/events/#{event_id}", params
|
112
|
+
raise ApiError, res if res.status != 200
|
86
113
|
|
87
114
|
ev = to_model(res.body[:data], included: res.body[:included])
|
88
115
|
ev.calendar_id = cal_id
|
89
116
|
ev
|
90
117
|
end
|
91
118
|
|
119
|
+
#
|
120
|
+
# Get the events' information after a request date.
|
121
|
+
#
|
122
|
+
# @param cal_id[String] calendar's id.
|
123
|
+
# @param days [Integer] The number of days to get.
|
124
|
+
# @param timezone [String] Timezone.
|
125
|
+
# @param include_relationships [Array<symbol>]
|
126
|
+
# includes association's object in the response.
|
127
|
+
# @return [Array<TimeTree::Event>]
|
128
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
129
|
+
# @since 0.0.1
|
92
130
|
def upcoming_events(cal_id, days: 7, timezone: 'UTC', include_relationships: nil)
|
93
131
|
params = relationships_params(include_relationships, Event::RELATIONSHIPS)
|
94
132
|
params.merge!(days: days, timezone: timezone)
|
95
|
-
res = get "/calendars/#{cal_id}/upcoming_events", params
|
96
|
-
raise if res.status != 200
|
133
|
+
res = @http_cmd.get "/calendars/#{cal_id}/upcoming_events", params
|
134
|
+
raise ApiError, res if res.status != 200
|
97
135
|
|
98
136
|
included = res.body[:included]
|
99
137
|
res.body[:data].map do |item|
|
@@ -103,38 +141,70 @@ module TimeTree
|
|
103
141
|
end
|
104
142
|
end
|
105
143
|
|
144
|
+
#
|
145
|
+
# Creates an event to the calendar.
|
146
|
+
#
|
147
|
+
# @param cal_id [String] calendar's id.
|
148
|
+
# @param params [Hash] TimeTree request body format.
|
149
|
+
# @return [TimeTree::Event]
|
150
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
151
|
+
# @since 0.0.1
|
106
152
|
def create_event(cal_id, params)
|
107
|
-
res = post "/calendars/#{cal_id}/events", params
|
108
|
-
raise if res.status != 201
|
153
|
+
res = @http_cmd.post "/calendars/#{cal_id}/events", params
|
154
|
+
raise ApiError, res if res.status != 201
|
109
155
|
|
110
156
|
ev = to_model res.body[:data]
|
111
157
|
ev.calendar_id = cal_id
|
112
158
|
ev
|
113
159
|
end
|
114
160
|
|
161
|
+
#
|
162
|
+
# Updates an event.
|
163
|
+
#
|
164
|
+
# @param cal_id [String] calendar's id.
|
165
|
+
# @param event_id [String] event's id.
|
166
|
+
# @param params [Hash]
|
167
|
+
# event's information specified in TimeTree request body format.
|
168
|
+
# @return [TimeTree::Event]
|
169
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
170
|
+
# @since 0.0.1
|
115
171
|
def update_event(cal_id, event_id, params)
|
116
|
-
res = put "/calendars/#{cal_id}/events/#{event_id}", params
|
117
|
-
raise if res.status != 200
|
172
|
+
res = @http_cmd.put "/calendars/#{cal_id}/events/#{event_id}", params
|
173
|
+
raise ApiError, res if res.status != 200
|
118
174
|
|
119
175
|
ev = to_model res.body[:data]
|
120
176
|
ev.calendar_id = cal_id
|
121
177
|
ev
|
122
178
|
end
|
123
179
|
|
180
|
+
#
|
181
|
+
# Deletes an event.
|
182
|
+
#
|
183
|
+
# @param cal_id [String] calendar's id.
|
184
|
+
# @param event_id [String] event's id.
|
185
|
+
# @return [true] if the operation succeeded.
|
186
|
+
# @raise [TimeTree::ApiError] if the http response status will not success.
|
187
|
+
# @since 0.0.1
|
124
188
|
def delete_event(cal_id, event_id)
|
125
|
-
res = delete "/calendars/#{cal_id}/events/#{event_id}"
|
126
|
-
raise if res.status != 204
|
189
|
+
res = @http_cmd.delete "/calendars/#{cal_id}/events/#{event_id}"
|
190
|
+
raise ApiError, res if res.status != 204
|
127
191
|
|
128
192
|
true
|
129
193
|
end
|
130
194
|
|
131
195
|
#
|
132
|
-
#
|
196
|
+
# Creates comment to an event.
|
133
197
|
#
|
134
|
-
|
198
|
+
# @param cal_id [String] calendar's id.
|
199
|
+
# @param event_id [String] event's id.
|
200
|
+
# @param params [Hash]
|
201
|
+
# comment's information specified in TimeTree request body format.
|
202
|
+
# @return [TimeTree::Activity]
|
203
|
+
# @raise [TimeTree::ApiError] if the nhttp response status is not success.
|
204
|
+
# @since 0.0.1
|
135
205
|
def create_activity(cal_id, event_id, params)
|
136
|
-
res = post "/calendars/#{cal_id}/events/#{event_id}/activities", params
|
137
|
-
raise if res.status != 201
|
206
|
+
res = @http_cmd.post "/calendars/#{cal_id}/events/#{event_id}/activities", params
|
207
|
+
raise ApiError, res if res.status != 201
|
138
208
|
|
139
209
|
activity = to_model res.body[:data]
|
140
210
|
activity.calendar_id = cal_id
|
@@ -142,21 +212,22 @@ module TimeTree
|
|
142
212
|
activity
|
143
213
|
end
|
144
214
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
params = {}
|
155
|
-
relationships ||= default
|
156
|
-
params[:include] = relationships.join ',' if relationships.is_a? Array
|
157
|
-
params
|
215
|
+
def inspect
|
216
|
+
limit_info = nil
|
217
|
+
if @ratelimit_limit
|
218
|
+
limit_info = " ratelimit:#{@ratelimit_remaining}/#{@ratelimit_limit}"
|
219
|
+
end
|
220
|
+
if @ratelimit_reset_at
|
221
|
+
limit_info = "#{limit_info}, reset_at:#{@ratelimit_reset_at.strftime('%m/%d %R')}"
|
222
|
+
end
|
223
|
+
"\#<#{self.class}:#{object_id}#{limit_info}>"
|
158
224
|
end
|
159
225
|
|
226
|
+
#
|
227
|
+
# update ratelimit properties
|
228
|
+
#
|
229
|
+
# @param res [Faraday::Response]
|
230
|
+
# apis http response.
|
160
231
|
def update_ratelimit(res)
|
161
232
|
limit = res.headers['x-ratelimit-limit']
|
162
233
|
remaining = res.headers['x-ratelimit-remaining']
|
@@ -166,54 +237,21 @@ module TimeTree
|
|
166
237
|
@ratelimit_reset_at = Time.at reset.to_i if reset
|
167
238
|
end
|
168
239
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
logger.debug "Response status:#{res.status}, body:#{res.body}"
|
174
|
-
res
|
240
|
+
private
|
241
|
+
|
242
|
+
def to_model(data, included: nil)
|
243
|
+
TimeTree::BaseModel.to_model data, client: self, included: included
|
175
244
|
end
|
176
245
|
|
177
|
-
def
|
178
|
-
|
179
|
-
res = connection.put path do |req|
|
180
|
-
req.headers['Content-Type'] = 'application/json'
|
181
|
-
req.body = params.to_json
|
182
|
-
end
|
183
|
-
update_ratelimit(res)
|
184
|
-
logger.debug "Response status:#{res.status}, body:#{res.body}"
|
185
|
-
res
|
246
|
+
def ready_token?
|
247
|
+
@token.is_a?(String) && !@token.empty?
|
186
248
|
end
|
187
249
|
|
188
|
-
def
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end
|
194
|
-
update_ratelimit(res)
|
195
|
-
logger.debug "Response status:#{res.status}, body:#{res.body}"
|
196
|
-
res
|
197
|
-
end
|
198
|
-
|
199
|
-
def delete(path, params = {})
|
200
|
-
@logger.debug "DELETE #{API_HOST}#{path} params:#{params}"
|
201
|
-
res = connection.delete path, params
|
202
|
-
update_ratelimit(res)
|
203
|
-
logger.debug "Response status:#{res.status}, body:#{res.body}"
|
204
|
-
res
|
205
|
-
end
|
206
|
-
|
207
|
-
def connection
|
208
|
-
Faraday.new(
|
209
|
-
url: API_HOST,
|
210
|
-
headers: {
|
211
|
-
'Accept' => 'application/vnd.timetree.v1+json',
|
212
|
-
'Authorization' => "Bearer #{@access_token}"
|
213
|
-
}
|
214
|
-
) do |builder|
|
215
|
-
builder.response :json, parser_options: { symbolize_names: true }, content_type: /\bjson$/
|
216
|
-
end
|
250
|
+
def relationships_params(relationships, default)
|
251
|
+
params = {}
|
252
|
+
relationships ||= default
|
253
|
+
params[:include] = relationships.join ',' if relationships.is_a? Array
|
254
|
+
params
|
217
255
|
end
|
218
256
|
end
|
219
257
|
end
|