summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/concerns/rrule_humanizer.rb49
-rw-r--r--app/models/node.rb7
-rw-r--r--app/models/node_action.rb25
3 files changed, 64 insertions, 17 deletions
diff --git a/app/models/concerns/rrule_humanizer.rb b/app/models/concerns/rrule_humanizer.rb
index 8231de8..07141c1 100644
--- a/app/models/concerns/rrule_humanizer.rb
+++ b/app/models/concerns/rrule_humanizer.rb
@@ -15,8 +15,8 @@ module RruleHumanizer
15 }.freeze 15 }.freeze
16 16
17 ORDINAL_NAMES = { 17 ORDINAL_NAMES = {
18 de: { 1=>"ersten", 2=>"zweiten", 3=>"dritten", 4=>"vierten", -1=>"letzten", -2=>"vorletzten" }, 18 de: { 1=>"ersten", 2=>"zweiten", 3=>"dritten", 4=>"vierten", 5=>"fünften", -1=>"letzten", -2=>"vorletzten" },
19 en: { 1=>"first", 2=>"second", 3=>"third", 4=>"fourth", -1=>"last", -2=>"second-to-last" } 19 en: { 1=>"first", 2=>"second", 3=>"third", 4=>"fourth", 5=>"fifth", -1=>"last", -2=>"second-to-last" }
20 }.freeze 20 }.freeze
21 21
22 MONTH_NAMES = { 22 MONTH_NAMES = {
@@ -35,7 +35,8 @@ module RruleHumanizer
35 ordinals = ORDINAL_NAMES[loc] || ORDINAL_NAMES[:en] 35 ordinals = ORDINAL_NAMES[loc] || ORDINAL_NAMES[:en]
36 months = MONTH_NAMES[loc] || MONTH_NAMES[:en] 36 months = MONTH_NAMES[loc] || MONTH_NAMES[:en]
37 37
38 days = byday&.split(",")&.map do |d| 38 byday_values = byday&.split(",")
39 days = byday_values&.map do |d|
39 if d =~ /^(-?\d+)([A-Z]{2})$/ 40 if d =~ /^(-?\d+)([A-Z]{2})$/
40 "#{ordinals[$1.to_i]} #{weekdays[$2]}" 41 "#{ordinals[$1.to_i]} #{weekdays[$2]}"
41 else 42 else
@@ -43,6 +44,32 @@ module RruleHumanizer
43 end 44 end
44 end 45 end
45 46
47 excluded_monthly_ordinal = nil
48 excluded_monthly_weekday = nil
49 selected_monthly_ordinals = nil
50 selected_monthly_weekday = nil
51 if freq == "MONTHLY" && byday_values.present?
52 ordinal_days = byday_values.map { |d| d.match(/^([1-5])([A-Z]{2})$/) }
53 if ordinal_days.all?
54 positions = ordinal_days.map { |match| match[1].to_i }.uniq.sort
55 weekdays_in_rule = ordinal_days.map { |match| match[2] }.uniq
56 if weekdays_in_rule.size == 1
57 selected_monthly_ordinals = positions
58 selected_monthly_weekday = weekdays_in_rule.first
59 missing_positions = (1..5).to_a - positions
60 if positions.size == 4 && missing_positions.size == 1
61 excluded_monthly_ordinal = missing_positions.first
62 excluded_monthly_weekday = selected_monthly_weekday
63 end
64 end
65 end
66 end
67
68 join_ordinals = lambda do |ordinal_values, conjunction|
69 names = ordinal_values.map { |ordinal| ordinals[ordinal] }
70 names.size > 1 ? "#{names[0..-2].join(', ')} #{conjunction} #{names.last}" : names.first
71 end
72
46 base = 73 base =
47 case loc 74 case loc
48 when :de 75 when :de
@@ -59,14 +86,26 @@ module RruleHumanizer
59 interval == 2 ? "Alle zwei Wochen" : "Wöchentlich" 86 interval == 2 ? "Alle zwei Wochen" : "Wöchentlich"
60 end 87 end
61 when "MONTHLY" 88 when "MONTHLY"
62 days ? "Jeden #{days.join(' und ')} im Monat" : "Monatlich" 89 if excluded_monthly_ordinal
90 "Jeden #{weekdays[excluded_monthly_weekday]} im Monat, außer dem #{ordinals[excluded_monthly_ordinal]} #{weekdays[excluded_monthly_weekday]}"
91 elsif selected_monthly_ordinals
92 "Jeden #{join_ordinals.call(selected_monthly_ordinals, 'und')} #{weekdays[selected_monthly_weekday]} im Monat"
93 else
94 days ? "Jeden #{days.join(' und ')} im Monat" : "Monatlich"
95 end
63 end 96 end
64 else 97 else
65 case freq 98 case freq
66 when "WEEKLY" 99 when "WEEKLY"
67 days ? "#{interval == 2 ? 'Every other' : 'Every'} #{days.join(' and ')}" : (interval == 2 ? "Every other week" : "Weekly") 100 days ? "#{interval == 2 ? 'Every other' : 'Every'} #{days.join(' and ')}" : (interval == 2 ? "Every other week" : "Weekly")
68 when "MONTHLY" 101 when "MONTHLY"
69 days ? "Every #{days.join(' and ')} of the month" : "Monthly" 102 if excluded_monthly_ordinal
103 "Every #{weekdays[excluded_monthly_weekday]} of the month, except the #{ordinals[excluded_monthly_ordinal]} #{weekdays[excluded_monthly_weekday]}"
104 elsif selected_monthly_ordinals
105 "Every #{join_ordinals.call(selected_monthly_ordinals, 'and')} #{weekdays[selected_monthly_weekday]} of the month"
106 else
107 days ? "Every #{days.join(' and ')} of the month" : "Monthly"
108 end
70 end 109 end
71 end 110 end
72 return nil unless base 111 return nil unless base
diff --git a/app/models/node.rb b/app/models/node.rb
index 6ca607d..717f5b4 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -268,9 +268,12 @@ class Node < ApplicationRecord
268 parent.nil? ? [slug] : parent.path_to_root.push(slug) 268 parent.nil? ? [slug] : parent.path_to_root.push(slug)
269 end 269 end
270 270
271 def computed_unique_name
272 path = path_to_root[1..-1].join("/") # excluding root
273 end
274
271 def current_unique_name 275 def current_unique_name
272 path = path_to_root[1..-1] # excluding root 276 self.unique_name = computed_unique_name
273 self.unique_name = path.join("/")
274 end 277 end
275 278
276 def update_unique_name 279 def update_unique_name
diff --git a/app/models/node_action.rb b/app/models/node_action.rb
index 39935c7..792ae1e 100644
--- a/app/models/node_action.rb
+++ b/app/models/node_action.rb
@@ -82,21 +82,23 @@ class NodeAction < ApplicationRecord
82 # user agent, ever. Success only -- rejected attempts are not 82 # user agent, ever. Success only -- rejected attempts are not
83 # logged. 83 # logged.
84 84
85 def self.record!(node:, action:, user: nil, page: nil, locale: nil, **extra) 85 def self.record!(node:, action:, user: nil, page: nil, locale: nil,
86 occurred_at: nil, inferred_from: nil, **extra)
86 create!( 87 create!(
87 :node => node, 88 :node => node,
88 :page => page, 89 :page => page,
89 :user => user, 90 :user => user,
90 :action => action, 91 :action => action,
91 :locale => locale, 92 :locale => locale,
92 :occurred_at => Time.now, 93 :occurred_at => occurred_at || Time.now,
93 :metadata => { 94 :inferred_from => inferred_from,
95 :metadata => {
94 "username" => user&.login, 96 "username" => user&.login,
95 "human_readable_node_name" => Globalize.with_locale(I18n.default_locale) { 97 "human_readable_node_name" => Globalize.with_locale(I18n.default_locale) {
96 node&.head&.title || node&.draft&.title 98 node&.head&.title || node&.draft&.title
97 }, 99 },
98 }.merge(extra.stringify_keys) 100 }.merge(extra.stringify_keys)
99 ) 101 )
100 end 102 end
101 103
102 # Computes the publish-entry diff between an outgoing head and the 104 # Computes the publish-entry diff between an outgoing head and the
@@ -113,7 +115,10 @@ class NodeAction < ApplicationRecord
113 title_of = ->(page) { page&.translations&.find_by(:locale => default)&.title } 115 title_of = ->(page) { page&.translations&.find_by(:locale => default)&.title }
114 diff = { :title => { "from" => title_of.call(old_page), 116 diff = { :title => { "from" => title_of.call(old_page),
115 "to" => title_of.call(new_page) } } 117 "to" => title_of.call(new_page) } }
116 return diff unless old_page 118 unless old_page
119 diff[:author] = { "from" => nil, "to" => new_page.user&.login } if new_page.user
120 return diff
121 end
117 122
118 old_author, new_author = old_page.user&.login, new_page.user&.login 123 old_author, new_author = old_page.user&.login, new_page.user&.login
119 diff[:author] = { "from" => old_author, "to" => new_author } if old_author != new_author 124 diff[:author] = { "from" => old_author, "to" => new_author } if old_author != new_author