forest_liana 1.4.6 → 1.4.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6dac4da1a71a663bfdd2f36870f8e5ccbc150b03
4
- data.tar.gz: ffc0af068f5056eaa86920ca86dcdc3097509d85
3
+ metadata.gz: bdc8fcb5df5a924d7903d9105b26b30810ef6a52
4
+ data.tar.gz: cd688dccec28feaf5a66f0ea47b7c0bed89ee051
5
5
  SHA512:
6
- metadata.gz: 06f4028b47406055fec5ff180cc966fafdef44b8b3dfbc1e756cf85a716647852e85db519480582d20d919ca98029d607b67de7acd2bfa7bbb9866bb565e9cb5
7
- data.tar.gz: ea027353665909b1c751896a84ccd0e96db8e0b97c4d5cf35a21c5f9bfe775adc3deb0c879a0e8d909e9912e32543acbe523c25d01a58d19ff271a740a0401c0
6
+ metadata.gz: 0ea7d3bb580c5cee0a84f80aff39d3d1c44d65c4ecdc2b694f0531e36c3edc1e12e0591b5a2c64838e04081675fcc09672a56323dc026a43ebcde19f7f5b3ddc
7
+ data.tar.gz: 0832ca416bd830169ea4bb3926fa839a0b245d4e8ea0c1d13732b4cbe9cd794c8dad561ad2ac6bb12496eeb209637f91e12759559830b424c229a22592e81534
@@ -2,6 +2,7 @@ module ForestLiana
2
2
  class SessionsController < ActionController::Base
3
3
 
4
4
  def create
5
+ @error_message = nil
5
6
  @user_class = ForestLiana.user_class_name.constantize rescue nil
6
7
 
7
8
  user = check_user
@@ -10,7 +11,10 @@ module ForestLiana
10
11
  if token
11
12
  render json: { token: token }, serializer: nil
12
13
  else
13
- if !has_internal_authentication? && ForestLiana.allowed_users.empty?
14
+ if @error_message
15
+ render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
16
+ [{ detail: @error_message }]), status: :unauthorized
17
+ elsif !has_internal_authentication? && ForestLiana.allowed_users.empty?
14
18
  render serializer: nil, json: JSONAPI::Serializer.serialize_errors(
15
19
  [{ detail: 'Forest cannot retrieve any users for the project ' \
16
20
  'you\'re trying to unlock.' }]), status: :unauthorized
@@ -51,27 +55,35 @@ module ForestLiana
51
55
  end
52
56
 
53
57
  def encode_token(user)
54
- JWT.encode({
55
- exp: Time.now.to_i + 2.weeks.to_i,
56
- data: {
57
- id: user['id'],
58
- type: 'users',
58
+ if ForestLiana.auth_key.nil?
59
+ @error_message = "Your Forest auth key seems to be missing. Can " \
60
+ "you check that you properly set a Forest auth key in the " \
61
+ "forest_liana initializer?"
62
+ FOREST_LOGGER.error @error_message
63
+ nil
64
+ else
65
+ JWT.encode({
66
+ exp: Time.now.to_i + 2.weeks.to_i,
59
67
  data: {
60
- email: user['email'],
61
- first_name: user['first_name'],
62
- last_name: user['last_name'],
63
- teams: user['teams']
64
- },
65
- relationships: {
66
- renderings: {
67
- data: [{
68
- type: 'renderings',
69
- id: params['renderingId']
70
- }]
68
+ id: user['id'],
69
+ type: 'users',
70
+ data: {
71
+ email: user['email'],
72
+ first_name: user['first_name'],
73
+ last_name: user['last_name'],
74
+ teams: user['teams']
75
+ },
76
+ relationships: {
77
+ renderings: {
78
+ data: [{
79
+ type: 'renderings',
80
+ id: params['renderingId']
81
+ }]
82
+ }
71
83
  }
72
84
  }
73
- }
74
- } , ForestLiana.auth_key, 'HS256')
85
+ }, ForestLiana.auth_key, 'HS256')
86
+ end
75
87
  end
76
88
  end
77
89
  end
@@ -3,8 +3,25 @@ module ForestLiana
3
3
  attr_accessor :record
4
4
 
5
5
  def initialize(resource, params)
6
+ @timezone_offset = params[:timezone].to_i
6
7
  super(resource, params)
7
- @populates = {}
8
+ end
9
+
10
+ def client_timezone
11
+ ActiveSupport::TimeZone[@timezone_offset].name
12
+ end
13
+
14
+ def get_format
15
+ case @params[:time_range].try(:downcase)
16
+ when 'day'
17
+ '%d/%m/%Y'
18
+ when 'week'
19
+ 'W%W-%Y'
20
+ when 'month'
21
+ '%b %Y'
22
+ when 'year'
23
+ '%Y'
24
+ end
8
25
  end
9
26
 
10
27
  def perform
@@ -16,34 +33,17 @@ module ForestLiana
16
33
 
17
34
  @params[:filters].try(:each) do |filter|
18
35
  operator, filter_value = OperatorValueParser.parse(filter[:value])
19
- conditions << OperatorValueParser.get_condition(filter[:field],
20
- operator, filter_value, @resource)
36
+ conditions << OperatorValueParser.get_condition(filter[:field],
37
+ operator, filter_value, @resource, @params[:timezone])
21
38
  end
22
39
 
23
40
  value = value.where(conditions.join(filter_operator))
24
41
  end
25
42
 
26
- value = value.send(time_range, group_by_date_field)
27
- value = value.group(group_by_field || :id) if group_by_field
28
-
43
+ value = value.send(time_range, group_by_date_field, { time_zone: client_timezone })
29
44
  value = value.send(@params[:aggregate].downcase, @params[:aggregate_field])
30
45
  .map do |k, v|
31
- if k.kind_of?(Array)
32
- {
33
- label: k[0],
34
- values: {
35
- key: populate(k[1]),
36
- value: v
37
- }
38
- }
39
- else
40
- {
41
- label: k,
42
- values: {
43
- value: v
44
- }
45
- }
46
- end
46
+ { label: k.strftime(get_format), values: { value: v }}
47
47
  end
48
48
 
49
49
  @record = Model::Stat.new(value: value)
@@ -55,30 +55,6 @@ module ForestLiana
55
55
  "#{@resource.table_name}.#{@params[:group_by_date_field]}"
56
56
  end
57
57
 
58
- def group_by_field
59
- field_name = @params[:group_by_field]
60
- association = @resource.reflect_on_association(field_name) if field_name
61
-
62
- if association
63
- association.foreign_key
64
- else
65
- field_name
66
- end
67
- end
68
-
69
- def populate(id)
70
- @populates[id] ||= begin
71
- field_name = @params[:group_by_field]
72
- association = @resource.reflect_on_association(field_name)
73
-
74
- if association
75
- association.klass.find(id)
76
- else
77
- id
78
- end
79
- end
80
- end
81
-
82
58
  def time_range
83
59
  "group_by_#{@params[:time_range].try(:downcase) || 'month'}"
84
60
  end
@@ -21,8 +21,9 @@ module ForestLiana
21
21
  PERIODS_PREVIOUS_X_DAYS = /^\$previous(\d+)Days$/;
22
22
  PERIODS_X_DAYS_TO_DATE = /^\$(\d+)DaysToDate$/;
23
23
 
24
- def initialize(value)
24
+ def initialize(value, timezone)
25
25
  @value = value
26
+ @timezone_offset = timezone.to_i
26
27
  end
27
28
 
28
29
  def is_interval_date_value
@@ -55,6 +56,11 @@ module ForestLiana
55
56
  false
56
57
  end
57
58
 
59
+ def to_client_timezone(date)
60
+ # NOTICE: By default, Rails store the dates without timestamp in the database.
61
+ date - @timezone_offset.hours
62
+ end
63
+
58
64
  def get_interval_date_filter
59
65
  return nil unless is_interval_date_value()
60
66
 
@@ -62,20 +68,22 @@ module ForestLiana
62
68
  return "<= '#{Time.now}'" if @value == PERIODS_PAST
63
69
 
64
70
  if @value == PERIODS_TODAY
65
- return "BETWEEN '#{Time.now.beginning_of_day}' AND " +
66
- "'#{Time.now.end_of_day}'"
71
+ return "BETWEEN '#{to_client_timezone(Time.now.beginning_of_day)}' " +
72
+ "AND '#{to_client_timezone(Time.now.end_of_day)}'"
67
73
  end
68
74
 
69
75
  match = PERIODS_PREVIOUS_X_DAYS.match(@value)
70
76
  if match && match[1]
71
- return "BETWEEN '#{Integer(match[1]).day.ago.beginning_of_day}'" +
72
- " AND '#{1.day.ago.end_of_day}'"
77
+ return "BETWEEN '" +
78
+ "#{to_client_timezone(Integer(match[1]).day.ago.beginning_of_day)}'" +
79
+ " AND '#{to_client_timezone(1.day.ago.end_of_day)}'"
73
80
  end
74
81
 
75
82
  match = PERIODS_X_DAYS_TO_DATE.match(@value)
76
83
  if match && match[1]
77
- return "BETWEEN '#{(Integer(match[1]) - 1).day.ago.beginning_of_day}'" +
78
- " AND '#{Time.now}'"
84
+ return "BETWEEN '" +
85
+ "#{to_client_timezone((Integer(match[1]) - 1).day.ago.beginning_of_day)}'" +
86
+ " AND '#{to_client_timezone(Time.now)}'"
79
87
  end
80
88
 
81
89
  duration = PERIODS[@value.to_sym][:duration]
@@ -85,11 +93,13 @@ module ForestLiana
85
93
  to_date = PERIODS[@value.to_sym][:to_date]
86
94
 
87
95
  if to_date
88
- from = Time.now.send("beginning_of_#{period_of_time}")
89
- to = Time.now
96
+ from = to_client_timezone(Time.now.send("beginning_of_#{period_of_time}"))
97
+ to = to_client_timezone(Time.now)
90
98
  else
91
- from = duration.send(period).ago.send("beginning_of_#{period_of_time}")
92
- to = 1.send(period).ago.send("end_of_#{period_of_time}")
99
+ from = to_client_timezone(duration.send(period).ago
100
+ .send("beginning_of_#{period_of_time}"))
101
+ to = to_client_timezone(1.send(period).ago
102
+ .send("end_of_#{period_of_time}"))
93
103
  end
94
104
  "BETWEEN '#{from}' AND '#{to}'"
95
105
  end
@@ -98,20 +108,22 @@ module ForestLiana
98
108
  return nil unless has_previous_interval()
99
109
 
100
110
  if @value == PERIODS_TODAY
101
- return "BETWEEN '#{1.day.ago.beginning_of_day}' AND " +
102
- "'#{1.day.ago.end_of_day}'"
111
+ return "BETWEEN '#{to_client_timezone(1.day.ago.beginning_of_day)}' AND " +
112
+ "'#{to_client_timezone(1.day.ago.end_of_day)}'"
103
113
  end
104
114
 
105
115
  match = PERIODS_PREVIOUS_X_DAYS.match(@value)
106
116
  if match && match[1]
107
- return "BETWEEN '#{(Integer(match[1]) * 2).day.ago.beginning_of_day}'" +
108
- " AND '#{(Integer(match[1]) + 1).day.ago.end_of_day}'"
117
+ return "BETWEEN '" +
118
+ "#{to_client_timezone((Integer(match[1]) * 2).day.ago.beginning_of_day)}'" +
119
+ " AND '#{to_client_timezone((Integer(match[1]) + 1).day.ago.end_of_day)}'"
109
120
  end
110
121
 
111
122
  match = PERIODS_X_DAYS_TO_DATE.match(@value)
112
123
  if match && match[1]
113
- return "BETWEEN '#{((Integer(match[1]) * 2) - 1).day.ago.beginning_of_day}'" +
114
- " AND '#{Integer(match[1]).day.ago}'"
124
+ return "BETWEEN '" +
125
+ "#{to_client_timezone(((Integer(match[1]) * 2) - 1).day.ago.beginning_of_day)}'" +
126
+ " AND '#{to_client_timezone(Integer(match[1]).day.ago)}'"
115
127
  end
116
128
 
117
129
  duration = PERIODS[@value.to_sym][:duration]
@@ -121,13 +133,14 @@ module ForestLiana
121
133
  to_date = PERIODS[@value.to_sym][:to_date]
122
134
 
123
135
  if to_date
124
- from = (duration).send(period).ago
125
- .send("beginning_of_#{period_of_time}")
126
- to = (duration).send(period).ago
136
+ from = to_client_timezone((duration).send(period).ago
137
+ .send("beginning_of_#{period_of_time}"))
138
+ to = to_client_timezone((duration).send(period).ago)
127
139
  else
128
- from = (duration * 2).send(period).ago
129
- .send("beginning_of_#{period_of_time}")
130
- to = (1 + duration).send(period).ago.send("end_of_#{period_of_time}")
140
+ from = to_client_timezone((duration * 2).send(period).ago
141
+ .send("beginning_of_#{period_of_time}"))
142
+ to = to_client_timezone((1 + duration).send(period).ago
143
+ .send("end_of_#{period_of_time}"))
131
144
  end
132
145
  "BETWEEN '#{from}' AND '#{to}'"
133
146
  end
@@ -31,10 +31,12 @@ module ForestLiana
31
31
  [operator, value_comparison]
32
32
  end
33
33
 
34
- def self.get_condition(field, operator, value, resource)
34
+ def self.get_condition(field, operator, value, resource, timezone)
35
35
  field_name = self.get_field_name(field, resource)
36
36
 
37
- operator_date_interval_parser = OperatorDateIntervalParser.new(value)
37
+ operator_date_interval_parser = OperatorDateIntervalParser
38
+ .new(value, timezone)
39
+
38
40
  if operator_date_interval_parser.is_interval_date_value()
39
41
  filter = operator_date_interval_parser.get_interval_date_filter()
40
42
  "#{field_name} #{filter}"
@@ -4,6 +4,7 @@ module ForestLiana
4
4
 
5
5
  def perform
6
6
  if @params[:group_by_field]
7
+ timezone_offset = @params[:timezone].to_i
7
8
  value = @resource
8
9
  conditions = []
9
10
  filter_operator = ''
@@ -14,7 +15,7 @@ module ForestLiana
14
15
  @params[:filters].try(:each) do |filter|
15
16
  operator, filter_value = OperatorValueParser.parse(filter[:value])
16
17
  conditions << OperatorValueParser.get_condition(filter[:field],
17
- operator, filter_value, @resource)
18
+ operator, filter_value, @resource, @params[:timezone])
18
19
  end
19
20
  end
20
21
 
@@ -30,6 +31,8 @@ module ForestLiana
30
31
  if @resource.respond_to?(:defined_enums) &&
31
32
  @resource.defined_enums.has_key?(@params[:group_by_field])
32
33
  key = @resource.defined_enums[@params[:group_by_field]].invert[key]
34
+ elsif @resource.columns_hash[@params[:group_by_field]].type == :datetime
35
+ key = (key + timezone_offset.hours).strftime('%d/%m/%Y %T')
33
36
  end
34
37
 
35
38
  { key: key, value: value }
@@ -79,7 +79,7 @@ module ForestLiana
79
79
  values.split(',').each do |value|
80
80
  operator, value = OperatorValueParser.parse(value)
81
81
  conditions << OperatorValueParser.get_condition(field, operator,
82
- value, @resource)
82
+ value, @resource, @params[:timezone])
83
83
  end
84
84
  end
85
85
 
@@ -171,7 +171,8 @@ module ForestLiana
171
171
  @records = @records
172
172
  .joins(field.to_sym)
173
173
 
174
- operator_date_interval_parser = OperatorDateIntervalParser.new(value)
174
+ operator_date_interval_parser = OperatorDateIntervalParser.new(value,
175
+ @params[:timezone])
175
176
  if operator_date_interval_parser.is_interval_date_value()
176
177
  filter = operator_date_interval_parser.get_interval_date_filter()
177
178
  @records = @records.where("#{association.table_name}.#{subfield} #{filter}")
@@ -15,7 +15,7 @@ module ForestLiana
15
15
  @params[:filters].try(:each) do |filter|
16
16
  operator, filter_value = OperatorValueParser.parse(filter[:value])
17
17
  conditions << OperatorValueParser.get_condition(filter[:field],
18
- operator, filter_value, @resource)
18
+ operator, filter_value, @resource, @params[:timezone])
19
19
  end
20
20
 
21
21
  valueCurrent = valueCurrent.where(conditions.join(filter_operator))
@@ -26,7 +26,8 @@ module ForestLiana
26
26
  conditions = []
27
27
  @params[:filters].try(:each) do |filter|
28
28
  operator, filter_value = OperatorValueParser.parse(filter[:value])
29
- operator_date_interval_parser = OperatorDateIntervalParser.new(filter_value)
29
+ operator_date_interval_parser = OperatorDateIntervalParser
30
+ .new(filter_value, @params[:timezone])
30
31
  if operator_date_interval_parser.has_previous_interval()
31
32
  field_name = OperatorValueParser.get_field_name(filter[:field], @resource)
32
33
  filter = operator_date_interval_parser
@@ -35,7 +36,7 @@ module ForestLiana
35
36
  filter_date_interval = true
36
37
  else
37
38
  conditions << OperatorValueParser.get_condition(filter[:field],
38
- operator, filter_value, @resource)
39
+ operator, filter_value, @resource, @params[:timezone])
39
40
  end
40
41
  end
41
42
 
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "1.4.6"
2
+ VERSION = "1.4.7"
3
3
  end
@@ -4,7 +4,8 @@ module ForestLiana
4
4
  test 'StringField page 1 size 15' do
5
5
  getter = ResourcesGetter.new(StringField, {
6
6
  page: { size: 15, number: 1 },
7
- sort: '-id'
7
+ sort: '-id',
8
+ timezone: '-08:00'
8
9
  })
9
10
  getter.perform
10
11
  records = getter.records
@@ -19,7 +20,8 @@ module ForestLiana
19
20
  test 'StringField page 2 size 10' do
20
21
  getter = ResourcesGetter.new(StringField, {
21
22
  page: { size: 10, number: 2 },
22
- sort: '-id'
23
+ sort: '-id',
24
+ timezone: '-08:00'
23
25
  })
24
26
  getter.perform
25
27
  records = getter.records
@@ -34,7 +36,8 @@ module ForestLiana
34
36
  test 'StringField sort by field' do
35
37
  getter = ResourcesGetter.new(StringField, {
36
38
  page: { size: 10, number: 1 },
37
- sort: '-field'
39
+ sort: '-field',
40
+ timezone: '-08:00'
38
41
  })
39
42
  getter.perform
40
43
  records = getter.records
@@ -50,7 +53,8 @@ module ForestLiana
50
53
  test 'Sort by a belongs_to association' do
51
54
  getter = ResourcesGetter.new(BelongsToField, {
52
55
  page: { size: 10, number: 1 },
53
- sort: 'has_one_field.id'
56
+ sort: 'has_one_field.id',
57
+ timezone: '-08:00'
54
58
  })
55
59
  getter.perform
56
60
  records = getter.records
@@ -65,7 +69,8 @@ module ForestLiana
65
69
  test 'Sort by a has_one association' do
66
70
  getter = ResourcesGetter.new(HasOneField, {
67
71
  page: { size: 10, number: 1 },
68
- sort: '-belongs_to_field.id'
72
+ sort: '-belongs_to_field.id',
73
+ timezone: '-08:00'
69
74
  })
70
75
  getter.perform
71
76
  records = getter.records
@@ -84,7 +89,8 @@ module ForestLiana
84
89
  'created_at' => '>2015-06-18 08:00:00',
85
90
  'owner:name' => 'Arnaud Besnier'
86
91
  },
87
- filterType: 'and'
92
+ filterType: 'and',
93
+ timezone: '-08:00'
88
94
  })
89
95
  getter.perform
90
96
  records = getter.records
@@ -101,7 +107,8 @@ module ForestLiana
101
107
  getter = ResourcesGetter.new(Tree, {
102
108
  page: { size: 10, number: 1 },
103
109
  sort: '-name',
104
- filter: { 'owner:name' => 'Arnaud Besnier' }
110
+ filter: { 'owner:name' => 'Arnaud Besnier' },
111
+ timezone: '-08:00'
105
112
  })
106
113
  getter.perform
107
114
  records = getter.records
@@ -117,7 +124,8 @@ module ForestLiana
117
124
  getter = ResourcesGetter.new(Owner, {
118
125
  page: { size: 10, number: 1 },
119
126
  filter: { 'updated_at' => '$previousYear' },
120
- filterType: 'and'
127
+ filterType: 'and',
128
+ timezone: '-08:00'
121
129
  })
122
130
  getter.perform
123
131
  records = getter.records
@@ -132,7 +140,8 @@ module ForestLiana
132
140
  getter = ResourcesGetter.new(Tree, {
133
141
  page: { size: 10, number: 1 },
134
142
  filter: { 'owner:updated_at' => '$previousYear' },
135
- filterType: 'and'
143
+ filterType: 'and',
144
+ timezone: '-08:00'
136
145
  })
137
146
  getter.perform
138
147
  records = getter.records
@@ -148,7 +157,8 @@ module ForestLiana
148
157
  page: { size: 10, number: 1 },
149
158
  filter: {
150
159
  'owner:updated_at' => 'Sat Jul 02 2016 11:52:00 GMT-0400 (EDT)',
151
- }
160
+ },
161
+ timezone: '-08:00'
152
162
  })
153
163
  getter.perform
154
164
  records = getter.records
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_liana
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.6
4
+ version: 1.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Munda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-29 00:00:00.000000000 Z
11
+ date: 2016-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails