dotiw 4.0.1 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
- source "http://rubygems.org"
5
+ source 'http://rubygems.org'
4
6
 
5
- gem "rails", "~> 4.0"
7
+ gem 'rails', '~> 4.0'
6
8
 
7
- gemspec path: "../"
9
+ gemspec path: '../'
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
- source "http://rubygems.org"
5
+ source 'http://rubygems.org'
4
6
 
5
- gem "rails", "~> 5.0.0"
7
+ gem 'rails', '~> 5.0.0'
6
8
 
7
- gemspec path: "../"
9
+ gemspec path: '../'
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
- source "http://rubygems.org"
5
+ source 'http://rubygems.org'
4
6
 
5
- gem "rails", "~> 5.1"
7
+ gem 'rails', '~> 5.1.0'
6
8
 
7
- gemspec path: "../"
9
+ gemspec path: '../'
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file was generated by Appraisal
4
+
5
+ source 'http://rubygems.org'
6
+
7
+ gem 'rails', '~> 5.2.0'
8
+
9
+ gemspec path: '../'
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file was generated by Appraisal
4
+
5
+ source 'http://rubygems.org'
6
+
7
+ gem 'rails', '~> 6.0.0'
8
+
9
+ gemspec path: '../'
@@ -1,30 +1,41 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'i18n'
4
4
 
5
- # Rails hacks
6
- if defined?(ActionView::Helpers)
7
- require 'dotiw/action_view_ext/helpers/date_helper'
8
- end
5
+ require 'active_support'
6
+ require 'active_support/core_ext'
9
7
 
10
8
  module DOTIW
9
+ extend ActiveSupport::Autoload
10
+
11
+ eager_autoload do
12
+ autoload :VERSION, 'dotiw/version'
13
+ autoload :TimeHash, 'dotiw/time_hash'
14
+ autoload :Methods, 'dotiw/methods'
15
+ end
16
+
11
17
  extend self
12
-
13
- autoload :VERSION, 'dotiw/version'
14
- autoload :TimeHash, 'dotiw/time_hash'
15
18
 
16
19
  DEFAULT_I18N_SCOPE = :'datetime.dotiw'
17
20
 
18
- def init_i18n
21
+ def init_i18n!
19
22
  I18n.load_path.unshift(*locale_files)
20
23
  I18n.reload!
21
24
  end
22
25
 
23
- protected
26
+ protected
27
+
24
28
  # Returns all locale files shipped with library
25
29
  def locale_files
26
30
  Dir[File.join(File.dirname(__FILE__), 'dotiw', 'locale', '**/*')]
27
31
  end
28
32
  end # DOTIW
29
33
 
30
- DOTIW.init_i18n
34
+ DOTIW.init_i18n!
35
+
36
+ begin
37
+ require 'action_view'
38
+ require_relative 'dotiw/action_view/helpers/date_helper'
39
+ rescue LoadError
40
+ # TODO: don't rely on exception
41
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView
4
+ module Helpers
5
+ module DateHelper
6
+ alias_method :_distance_of_time_in_words, :distance_of_time_in_words
7
+ alias_method :_time_ago_in_words, :time_ago_in_words
8
+
9
+ include DOTIW::Methods
10
+
11
+ def distance_of_time_in_words(from_time, to_time = 0, include_seconds_or_options = {}, options = {})
12
+ return _distance_of_time_in_words(from_time, to_time, options) if options.delete(:vague)
13
+ super
14
+ end
15
+
16
+ def distance_of_time_in_percent(from_time, current_time, to_time, options = {})
17
+ options[:precision] ||= 0
18
+ distance = to_time - from_time
19
+ result = ((current_time - from_time) / distance) * 100
20
+ number_with_precision(result, options).to_s + '%'
21
+ end
22
+ end # DateHelper
23
+ end # Helpers
24
+ end # ActionView
@@ -2,45 +2,52 @@ ar:
2
2
  datetime:
3
3
  dotiw:
4
4
  seconds:
5
- one: ثانية
5
+ zero: ثانية
6
+ one: ثانية واحدة
6
7
  two: ثانيتين
7
- few: "%{count} ثواني"
8
- many: "%{count} ثواني"
9
- other: "%{count} ثواني"
8
+ few: "%{count} توانٍ"
9
+ many: "%{count} ثانية"
10
+ other: "%{count} ثانية"
10
11
  minutes:
11
- one: دقيقة
12
+ zero: دقيقة
13
+ one: دقيقة واحدة
12
14
  two: دقيقتين
13
15
  few: "%{count} دقائق"
14
- many: "%{count} دقائق"
15
- other: "%{count} دقائق"
16
+ many: "%{count} دقيقة"
17
+ other: "%{count} دقيقة"
16
18
  hours:
17
- one: ساعة
19
+ zero: ساعة
20
+ one: ساعة واحدة
18
21
  two: ساعتين
19
22
  few: "%{count} ساعات"
20
- many: "%{count} ساعات"
21
- other: "%{count} ساعات"
23
+ many: "%{count} ساعة"
24
+ other: "%{count} ساعة"
22
25
  days:
23
- one: يوم
24
- two: يومان
25
- few: "%{count} أيام"
26
- many: "%{count} أيام"
27
- other: "%{count} أيام"
26
+ zero: يوم
27
+ one: يوم واحد
28
+ two: يومين
29
+ few: "%{count} أيام"
30
+ many: "%{count} يومًا"
31
+ other: "%{count} يوم"
28
32
  weeks:
29
- one: أسبوع
30
- two: إسبوعين
33
+ zero: أسبوع
34
+ one: أسبوع واحدة
35
+ two: أسبوعين
31
36
  few: "%{count} أسابيع"
32
37
  many: "%{count} أسابيع"
33
- other: "%{count} أسابيع"
38
+ other: "%{count} أسيوع"
34
39
  months:
35
- one: شهر
40
+ zero: شهر
41
+ one: شهر واحد
36
42
  two: شهرين
37
43
  few: "%{count} أشهر"
38
- many: "%{count} أشهر"
39
- other: "%{count} أشهر"
44
+ many: "%{count} شهراً"
45
+ other: "%{count} شهر"
40
46
  years:
41
- one: سنة
42
- two: سنتان
43
- few: "%{count} سنوات"
44
- many: "%{count} سنوات"
45
- other: "%{count} سنوات"
46
- less_than_x: أقل من %{distance}
47
+ zero: عام
48
+ one: عام واحد
49
+ two: عامين
50
+ few: "%{count} أعوام"
51
+ many: "%{count} عاماً"
52
+ other: "%{count} عام"
53
+ less_than_x: "%{distance} أقل من"
@@ -4,29 +4,36 @@ pl:
4
4
  seconds:
5
5
  one: "1 sekunda"
6
6
  few: "%{count} sekundy"
7
+ many: "%{count} sekund"
7
8
  other: "%{count} sekund"
8
9
  minutes:
9
10
  one: "1 minuta"
10
11
  few: "%{count} minuty"
12
+ many: "%{count} minut"
11
13
  other: "%{count} minut"
12
14
  hours:
13
15
  one: "1 godzina"
14
16
  few: "%{count} godziny"
17
+ many: "%{count} godzin"
15
18
  other: "%{count} godzin"
16
19
  days:
17
20
  one: "1 dzień"
18
21
  few: "%{count} dni"
22
+ many: "%{count} dni"
19
23
  other: "%{count} dni"
20
24
  weeks:
21
25
  one: "1 tydzień"
22
26
  few: "%{count} tygodnie"
27
+ many: "%{count} tygodni"
23
28
  other: "%{count} tygodni"
24
29
  months:
25
30
  one: "1 miesiąc"
26
31
  few: "%{count} miesiące"
32
+ many: "%{count} miesięcy"
27
33
  other: "%{count} miesięcy"
28
34
  years:
29
35
  one: "1 rok"
30
36
  few: "%{count} lata"
37
+ many: "%{count} lat"
31
38
  other: "%{count} lat"
32
39
  less_than_x: "mniej niż %{distance}"
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DOTIW
4
+ module Methods
5
+ def distance_of_time_in_words_hash(from_time, to_time, options = {})
6
+ from_time = from_time.to_time if !from_time.is_a?(Time) && from_time.respond_to?(:to_time)
7
+ to_time = to_time.to_time if !to_time.is_a?(Time) && to_time.respond_to?(:to_time)
8
+
9
+ DOTIW::TimeHash.new(nil, from_time, to_time, options).to_hash
10
+ end
11
+
12
+ def distance_of_time(seconds, options = {})
13
+ options[:include_seconds] ||= true
14
+ _display_time_in_words DOTIW::TimeHash.new(seconds, nil, nil, options).to_hash, options
15
+ end
16
+
17
+ def distance_of_time_in_words(from_time, to_time = 0, include_seconds_or_options = {}, options = {})
18
+ if include_seconds_or_options.is_a?(Hash)
19
+ options = include_seconds_or_options
20
+ else
21
+ options[:include_seconds] ||= !!include_seconds_or_options
22
+ end
23
+ return distance_of_time(from_time, options) if to_time == 0
24
+
25
+ hash = distance_of_time_in_words_hash(from_time, to_time, options)
26
+ _display_time_in_words(hash, options)
27
+ end
28
+
29
+ def time_ago_in_words(from_time, include_seconds_or_options = {})
30
+ distance_of_time_in_words(from_time, Time.current, include_seconds_or_options)
31
+ end
32
+
33
+ private
34
+
35
+ def _display_time_in_words(hash, options = {})
36
+ options.reverse_merge!(
37
+ include_seconds: false
38
+ ).symbolize_keys!
39
+
40
+ include_seconds = options.delete(:include_seconds)
41
+ hash.delete(:seconds) if !include_seconds && hash[:minutes]
42
+
43
+ options[:except] = Array.wrap(options[:except]).map!(&:to_sym) if options[:except]
44
+ options[:only] = Array.wrap(options[:only]).map!(&:to_sym) if options[:only]
45
+
46
+ # Remove all the values that are nil or excluded. Keep the required ones.
47
+ hash.delete_if do |key, value|
48
+ value.nil? || value.zero? ||
49
+ options[:except]&.include?(key) ||
50
+ (options[:only] && !options[:only].include?(key))
51
+ end
52
+
53
+ i18n_scope = options.delete(:scope) || DOTIW::DEFAULT_I18N_SCOPE
54
+ if hash.empty?
55
+ fractions = DOTIW::TimeHash::TIME_FRACTIONS
56
+ fractions &= options[:only] if options[:only]
57
+ fractions -= options[:except] if options[:except]
58
+
59
+ I18n.with_options locale: options[:locale], scope: i18n_scope do |locale|
60
+ # e.g. try to format 'less than 1 days', fallback to '0 days'
61
+ return locale.translate :less_than_x,
62
+ distance: locale.translate(fractions.first, count: 1),
63
+ default: locale.translate(fractions.first, count: 0)
64
+ end
65
+ end
66
+
67
+ output = []
68
+ I18n.with_options locale: options[:locale], scope: i18n_scope do |locale|
69
+ output = hash.map { |key, value| locale.t(key, count: value) }
70
+ end
71
+
72
+ options.delete(:except)
73
+ options.delete(:only)
74
+ highest_measures = options.delete(:highest_measures)
75
+ highest_measures = 1 if options.delete(:highest_measure_only)
76
+ output = output[0...highest_measures] if highest_measures
77
+
78
+ options[:words_connector] ||= I18n.translate :'datetime.dotiw.words_connector',
79
+ default: :'support.array.words_connector',
80
+ locale: options[:locale]
81
+ options[:two_words_connector] ||= I18n.translate :'datetime.dotiw.two_words_connector',
82
+ default: :'support.array.two_words_connector',
83
+ locale: options[:locale]
84
+ options[:last_word_connector] ||= I18n.translate :'datetime.dotiw.last_word_connector',
85
+ default: :'support.array.last_word_connector',
86
+ locale: options[:locale]
87
+
88
+ output.to_sentence(options)
89
+ end
90
+ end
91
+ end # DOTIW
@@ -1,25 +1,25 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module DOTIW
4
4
  class TimeHash
5
- TIME_FRACTIONS = [:seconds, :minutes, :hours, :days, :weeks, :months, :years]
6
-
7
- attr_accessor :distance, :smallest, :largest, :from_time, :to_time
8
-
9
- def initialize(distance, from_time = nil, to_time = nil, options = {})
10
- self.output = ActiveSupport::OrderedHash.new
11
- self.options = options
12
- self.distance = distance
13
- self.from_time = from_time || Time.current
14
- self.to_time = to_time || (@to_time_not_given = true && self.from_time + self.distance.seconds)
15
- self.smallest, self.largest = [self.from_time, self.to_time].minmax
16
- self.to_time += 1.hour if @to_time_not_given && self.smallest.dst? && !self.largest.dst?
17
- self.to_time -= 1.hour if @to_time_not_given && !self.smallest.dst? && self.largest.dst?
18
- self.smallest, self.largest = [self.from_time, self.to_time].minmax
19
- self.distance ||= begin
5
+ TIME_FRACTIONS = %i[seconds minutes hours days weeks months years].freeze
6
+
7
+ attr_reader :distance, :smallest, :largest, :from_time, :to_time
8
+
9
+ def initialize(distance, from_time, to_time = nil, options = {})
10
+ @output = {}
11
+ @options = options
12
+ @distance = distance
13
+ @from_time = from_time || Time.current
14
+ @to_time = to_time || (@to_time_not_given = true && @from_time + distance.seconds)
15
+ @smallest, @largest = [@from_time, @to_time].minmax
16
+ @to_time += 1.hour if @to_time_not_given && smallest.dst? && !largest.dst?
17
+ @to_time -= 1.hour if @to_time_not_given && !smallest.dst? && largest.dst?
18
+ @smallest, @largest = [@from_time, @to_time].minmax
19
+ @distance ||= begin
20
20
  d = largest - smallest
21
- d -= 1.hour if self.smallest.dst? && !self.largest.dst?
22
- d += 1.hour if !self.smallest.dst? && self.largest.dst?
21
+ d -= 1.hour if smallest.dst? && !largest.dst?
22
+ d += 1.hour if !smallest.dst? && largest.dst?
23
23
  d
24
24
  end
25
25
 
@@ -30,16 +30,16 @@ module DOTIW
30
30
  output
31
31
  end
32
32
 
33
- private
34
- attr_accessor :options, :output
33
+ private
34
+
35
+ attr_reader :options, :output
35
36
 
36
37
  def build_time_hash
37
38
  if accumulate_on = options.delete(:accumulate_on)
38
39
  accumulate_on = accumulate_on.to_sym
39
- if accumulate_on == :years
40
- return build_time_hash
41
- end
42
- TIME_FRACTIONS.index(accumulate_on).downto(0) { |i| self.send("build_#{TIME_FRACTIONS[i]}") }
40
+ return build_time_hash if accumulate_on == :years
41
+
42
+ TIME_FRACTIONS.index(accumulate_on).downto(0) { |i| send("build_#{TIME_FRACTIONS[i]}") }
43
43
  else
44
44
  while distance > 0
45
45
  if distance < 1.minute
@@ -63,23 +63,23 @@ module DOTIW
63
63
 
64
64
  def build_seconds
65
65
  output[:seconds] = distance.to_i
66
- self.distance = 0
66
+ @distance = 0
67
67
  end
68
68
 
69
69
  def build_minutes
70
- output[:minutes], self.distance = distance.divmod(1.minute.to_i)
70
+ output[:minutes], @distance = distance.divmod(1.minute.to_i)
71
71
  end
72
72
 
73
73
  def build_hours
74
- output[:hours], self.distance = distance.divmod(1.hour.to_i)
74
+ output[:hours], @distance = distance.divmod(1.hour.to_i)
75
75
  end
76
76
 
77
77
  def build_days
78
- output[:days], self.distance = distance.divmod(1.day.to_i) if output[:days].nil?
78
+ output[:days], @distance = distance.divmod(1.day.to_i) unless output[:days]
79
79
  end
80
80
 
81
81
  def build_weeks
82
- output[:weeks], self.distance = distance.divmod(1.week.to_i) if output[:weeks].nil?
82
+ output[:weeks], @distance = distance.divmod(1.week.to_i) unless output[:weeks]
83
83
  end
84
84
 
85
85
  def build_months
@@ -110,7 +110,7 @@ module DOTIW
110
110
  if weeks < 0
111
111
  # Convert the last month to a week and add to total
112
112
  months -= 1
113
- last_month = largest.advance(:months => -1)
113
+ last_month = largest.advance(months: -1)
114
114
  days_in_month = Time.days_in_month(last_month.month, last_month.year)
115
115
  weeks += days_in_month / 7
116
116
  days += days_in_month % 7
@@ -118,6 +118,12 @@ module DOTIW
118
118
  days -= 7
119
119
  weeks += 1
120
120
  end
121
+
122
+ if weeks == -1
123
+ months -= 1
124
+ weeks = 4
125
+ days -= 4
126
+ end
121
127
  end
122
128
 
123
129
  if months < 0
@@ -131,9 +137,9 @@ module DOTIW
131
137
  output[:weeks] = weeks
132
138
  output[:days] = days
133
139
 
134
- total_days, self.distance = distance.abs.divmod(1.day.to_i)
140
+ total_days, @distance = distance.abs.divmod(1.day.to_i)
135
141
 
136
- [total_days, self.distance]
142
+ [total_days, @distance]
137
143
  end
138
144
  end # TimeHash
139
145
  end # DOTIW