-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript_helpers.rb
147 lines (122 loc) · 3.98 KB
/
script_helpers.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# frozen_string_literal: true
require 'csv'
module ScriptHelpers
HELP_TEXT = "
You need to specifiy an admin user (use the email) and a CSV to process:
ie: rails \"proposals:batch:ACTION[admin@example.org,../some-file.csv]\"
Not found proposals will be skipped"
CSV_TEXT = "
CSV format must follow this specification:
1st line is treated as header and must containt the fields: id, state, text_ca, text_es, text_.., address
Rest of the lines must containt values for the corresponding headers
"
def process_csv(args)
raise ArgumentError if args.admin.blank?
raise ArgumentError if args.csv.blank?
admin = Decidim::User.find_by(admin: true, email: args.admin)
raise AdminError, "#{args.admin} not found or not and admin" unless admin
table = CSV.parse(File.read(args.csv), headers: true)
table.each_with_index do |line, index|
print "##{index} (#{100 * (index + 1) / table.count}%): "
begin
yield(admin, line)
rescue UnprocessableError => e
show_error(e.message)
rescue ActiveRecord::RecordInvalid => e
show_error(e.message)
rescue AlreadyProcessedError => e
show_warning(e.message)
end
end
rescue ArgumentError => e
puts
show_error(e.message)
show_help
rescue CSV::MalformedCSVError => e
puts
show_error(e.message)
show_csv_format
rescue AdminError => e
show_error(e.message)
end
def proposal_from_id(id)
proposal = Decidim::Proposals::Proposal.find_by(id: id)
raise UnprocessableError, "Proposal [#{id}] not found!" unless proposal
proposal
end
def show_error(msg)
puts "\e[31mERROR:\e[0m #{msg}"
end
def show_warning(msg)
puts "\e[33mWARN:\e[0m #{msg}"
end
def show_success(msg)
puts " \e[32m#{msg}\e[0m"
end
def normalize(line)
values = { answer: {}, cost_report: {}, execution_period: {} }
line.each do |key, value|
case key
when /^id$/i
values[:id] = value
when /^estat$|^status$|^state$/i
values[:state] = value
when /^text (.*)catal[à|a](.*)|^text_ca$|^answer\/ca$/i
values[:answer][:ca] = value
when /^text (.*)castell[a|à](.*)|^text_es$|^answer\/es$/i
values[:answer][:es] = value
when /^adreça$|^dirección$|^address$/i
values[:address] = value
when /^cost$/i
values[:cost] = value
when /^informe de cost$/i
values[:cost_report][:ca] = value
when /^per[ií]ode d['’]execuci[oó]$/i
values[:execution_period][:ca] = value
end
end
raise_if_field_not_found(:id, values)
values
end
def emails_from(text)
text.scan(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i)
end
def url_for_proposal(proposal)
# "https://#{proposal.organization.host}/processes/#{proposal.participatory_space.slug}/f/#{proposal.component.id}/proposals/#{proposal.id}"
"https://www.decidim.barcelona/processes/#{proposal.participatory_space.slug}/f/#{proposal.component.id}/proposals/#{proposal.id}"
end
def raise_if_field_not_found(field, values)
raise UnprocessableError, "#{field.upcase} field not found for [#{values[:id]}]" unless values[field].present?
end
def normalize_state(state)
case state
when /^evaluating|En avaluació|En evaluación|Acceptada parcialment|Aceptada parcialmente$/i
'en_avaluacio'
when /^accepted|Acceptada|Aceptada$/i
'acceptada'
when /^rejected|Rebutjada|Rechazada$/i
'rebutjada'
when /^withdrawn|retirat|retirada$/i
'withdrawn'
else
raise UnprocessableError, "State [#{state}] cannot be parsed"
end
end
def parse_links(texts)
texts.map do |lang, text|
[lang, text.nil? ? nil : Decidim::ContentRenderers::LinkRenderer.new((text).strip).render.gsub("\n", "<br>")]
end.to_h
end
def show_help
puts HELP_TEXT
end
def show_csv_format
puts CSV_TEXT
end
class AdminError < StandardError
end
class UnprocessableError < StandardError
end
class AlreadyProcessedError < StandardError
end
end