-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support for CSV and multiple columns #2
Merged
+494
−83
Merged
Changes from 15 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
63ce5e2
Remove not found `url` gem
sauloperez 25099f6
Gitignore common files
sauloperez d78c4d1
Extract email parsing into class
sauloperez 2bda8f9
Replace send calls to public method
sauloperez 49ff9fd
Improve a bit specs wording
sauloperez 51d8269
Accept email data as a hash and store as metadata
sauloperez de60604
Enable toggling the parser from config
sauloperez 1725a9d
Read CSV format
sauloperez ff02492
Accept CSV header and unlimited columns
sauloperez 09be41a
Refactor parsers naming
sauloperez c526a25
Use stdlib's CSV interface
sauloperez 2f231e8
Increase #register_users test coverage
sauloperez 2173809
Doc Metadata mode and better config key
sauloperez 89793ac
Move email and name normalization to parser
sauloperez d5deb11
Remove unnecessary chomp
sauloperez df36834
Memoize header row parsing
sauloperez 8e93c27
Fix flaky spec
sauloperez File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,3 +18,7 @@ spec/decidim_dummy_app | |
|
||
# default development application | ||
development_app | ||
|
||
.byebug_history | ||
.ruby-version | ||
tags |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
app/commands/decidim/direct_verifications/verification/base_parser.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
module DirectVerifications | ||
module Verification | ||
# Abstract class all concrete parsers should inherit from. They are expected to implement | ||
# #header, #lines, and #parse_data methods. | ||
class BaseParser | ||
EMAIL_REGEXP = /([A-Z0-9+._-]+@[A-Z0-9._-]+\.[A-Z0-9_-]+)\b/i.freeze | ||
|
||
def initialize(txt) | ||
@txt = txt | ||
@emails = {} | ||
end | ||
|
||
def to_h | ||
lines.each do |line| | ||
EMAIL_REGEXP.match(line) do |match| | ||
email = normalize(match[0]) | ||
emails[email] = parse_data(email, line, header) | ||
end | ||
end | ||
|
||
emails | ||
end | ||
|
||
private | ||
|
||
attr_reader :txt, :emails | ||
|
||
def normalize(value) | ||
value.to_s.downcase | ||
end | ||
end | ||
end | ||
end | ||
end |
40 changes: 40 additions & 0 deletions
40
app/commands/decidim/direct_verifications/verification/metadata_parser.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# frozen_string_literal: true | ||
|
||
require "csv" | ||
|
||
module Decidim | ||
module DirectVerifications | ||
module Verification | ||
class MetadataParser < BaseParser | ||
def header | ||
header_row = lines[0].chomp | ||
column_names = tokenize(header_row) | ||
column_names.map(&:to_sym).map(&:downcase) | ||
end | ||
|
||
def lines | ||
@lines ||= StringIO.new(txt).readlines | ||
end | ||
|
||
def parse_data(email, line, header) | ||
tokens = tokenize(line) | ||
|
||
hash = {} | ||
header.each_with_index do |column, index| | ||
value = tokens[index].strip | ||
next if value.include?(email) | ||
|
||
hash[column] = value | ||
end | ||
hash | ||
end | ||
|
||
private | ||
|
||
def tokenize(line) | ||
CSV.parse(line)[0] | ||
end | ||
end | ||
end | ||
end | ||
end |
40 changes: 40 additions & 0 deletions
40
app/commands/decidim/direct_verifications/verification/name_parser.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# frozen_string_literal: true | ||
|
||
module Decidim | ||
module DirectVerifications | ||
module Verification | ||
class NameParser < BaseParser | ||
LINE_DELIMITER = /[\r\n;,]/.freeze | ||
NON_ALPHA_CHARS = /[^[:print:]]|[\"\$\<\>\|\\]/.freeze | ||
|
||
def header | ||
nil | ||
end | ||
|
||
def lines | ||
txt.split(LINE_DELIMITER) | ||
end | ||
|
||
def parse_data(email, line, _header) | ||
name = parse_name(email, line) | ||
name = strip_non_alpha_chars(name) | ||
name.presence || fallback_name(email) | ||
end | ||
|
||
private | ||
|
||
def strip_non_alpha_chars(str) | ||
(str.presence || "").gsub(NON_ALPHA_CHARS, "").strip | ||
end | ||
|
||
def parse_name(email, line) | ||
line.split(email).first | ||
end | ||
|
||
def fallback_name(email) | ||
email.split("@").first | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be worth documenting how to do that with an example and a link to PostgreSQL's docs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A link to PostgreSQL's docs? what do you mean? how to export a csv from a sql table?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought people may not be familiar with PostgreSQL JSON operators and it's worth pointing at the docs and show how it could be queried like in CoopCat-Confederacio-de-Cooperatives/decidim-coopcat#2 (comment).