timetree 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/timetree.svg)](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
|