cyrus-code-challenge 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/console +6 -0
- data/bin/cyrus-code-challenge +4 -0
- data/bin/test-output +5 -0
- data/data/comma.txt +3 -0
- data/data/pipe.txt +3 -0
- data/data/space.txt +3 -0
- data/env.rb +1 -0
- data/lib/cyrus-code-challenge.rb +11 -0
- data/lib/cyrus-code-challenge/cli-helpers.rb +17 -0
- data/lib/cyrus-code-challenge/cli.rb +88 -0
- data/lib/cyrus-code-challenge/contacts-creator.rb +12 -0
- data/lib/cyrus-code-challenge/contacts.rb +20 -0
- data/lib/cyrus-code-challenge/email-sender.rb +48 -0
- data/lib/cyrus-code-challenge/formatter.rb +35 -0
- data/lib/cyrus-code-challenge/parser.rb +15 -0
- data/lib/cyrus-code-challenge/printer.rb +60 -0
- data/lib/cyrus-code-challenge/sorter.rb +14 -0
- data/lib/cyrus-code-challenge/version.rb +3 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 00a906ea15a9418e3b362053b23b05b5543b1ce4
|
4
|
+
data.tar.gz: bf4024ec6c4b9da07658485ccf0ca552a9856ae4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b7cba27ac2f2193759a8ca045b7754b3ee2af476f4e96ad5aa55d4577473a6a377fc0ddabb5ae0d21bd67fd9992a5029e25decf0cf45c2b089b9365eb75d6fdd
|
7
|
+
data.tar.gz: c3ce74c1ac6706c57c630fdbf1f6a163305f0899a838143cbd60988b53412b3e4db0eb558973a547c84718c2c1d2b7f04f3819fa797750a66bfaeb3e2282d6ac
|
data/bin/console
ADDED
data/bin/test-output
ADDED
data/data/comma.txt
ADDED
data/data/pipe.txt
ADDED
data/data/space.txt
ADDED
data/env.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ENV['PASSWORD']='haribol108'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative '../env'
|
2
|
+
require_relative './cyrus-code-challenge/version'
|
3
|
+
require_relative './cyrus-code-challenge/cli-helpers'
|
4
|
+
require_relative './cyrus-code-challenge/cli'
|
5
|
+
require_relative './cyrus-code-challenge/sorter'
|
6
|
+
require_relative './cyrus-code-challenge/printer'
|
7
|
+
require_relative './cyrus-code-challenge/contacts-creator'
|
8
|
+
require_relative './cyrus-code-challenge/contacts'
|
9
|
+
require_relative './cyrus-code-challenge/formatter'
|
10
|
+
require_relative './cyrus-code-challenge/parser'
|
11
|
+
require_relative './cyrus-code-challenge/email-sender'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CLIHelpers
|
2
|
+
|
3
|
+
def animate
|
4
|
+
sleep 0.01
|
5
|
+
end
|
6
|
+
|
7
|
+
def clear
|
8
|
+
print "\e[2J\e[f"
|
9
|
+
end
|
10
|
+
|
11
|
+
def colorize(text, color_code)
|
12
|
+
"\e[#{color_code}m#{text}\e[0m"
|
13
|
+
end
|
14
|
+
|
15
|
+
def red(text); colorize(text, 31); end
|
16
|
+
def green(text); colorize(text, 32); end
|
17
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class CyrusCodeChallenge::CLI
|
2
|
+
include CLIHelpers
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
ContactsCreator.call
|
6
|
+
@printer = Printer.new
|
7
|
+
greeting
|
8
|
+
end
|
9
|
+
|
10
|
+
def greeting
|
11
|
+
array = "\nWelcome to Brennen's Cyrus Code Challenge Solution!\n".split("")
|
12
|
+
array.each{|x| print green(x);animate}
|
13
|
+
sleep 0.6
|
14
|
+
show_options
|
15
|
+
end
|
16
|
+
|
17
|
+
def show_options
|
18
|
+
array = "Please choose an option:".split("")
|
19
|
+
array.each{|x| print x;animate};sleep 0.6
|
20
|
+
array =
|
21
|
+
%{\n
|
22
|
+
1. Print Output 1
|
23
|
+
2. Print Output 2
|
24
|
+
3. Print Output 3
|
25
|
+
4. Print Entire Solution
|
26
|
+
5. Email Entire Solution
|
27
|
+
}.split("")
|
28
|
+
|
29
|
+
array.each{|x| print x;animate}
|
30
|
+
serve_user
|
31
|
+
end
|
32
|
+
|
33
|
+
def serve_user
|
34
|
+
respond_to_input
|
35
|
+
puts green("\nWould you like to make another selection? (y/n)")
|
36
|
+
offer_another_selection
|
37
|
+
end
|
38
|
+
|
39
|
+
def offer_another_selection
|
40
|
+
input = gets.strip
|
41
|
+
case input
|
42
|
+
when "y", "Y"
|
43
|
+
show_options
|
44
|
+
when "n", "N", "exit", "quit"
|
45
|
+
abort("\nBye for now!")
|
46
|
+
else
|
47
|
+
puts red('Please choose a valid selection:')
|
48
|
+
offer_another_selection
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def respond_to_input
|
53
|
+
input = gets.strip
|
54
|
+
case input
|
55
|
+
when "1"
|
56
|
+
clear;print "------------------------------------------\n"
|
57
|
+
@printer.output_1
|
58
|
+
print "------------------------------------------"
|
59
|
+
when "2"
|
60
|
+
clear;print "------------------------------------------\n"
|
61
|
+
@printer.output_2
|
62
|
+
print "------------------------------------------"
|
63
|
+
when "3"
|
64
|
+
clear;print "------------------------------------------\n"
|
65
|
+
@printer.output_3
|
66
|
+
print "------------------------------------------"
|
67
|
+
when "4"
|
68
|
+
clear;print "------------------------------------------\n"
|
69
|
+
@printer.print_all
|
70
|
+
print "------------------------------------------"
|
71
|
+
when "5"
|
72
|
+
puts "Who should I send this email to?"
|
73
|
+
receiver = gets.strip
|
74
|
+
until receiver =~ /.+@.+\..+/i
|
75
|
+
puts "Please enter valid email address:"
|
76
|
+
receiver = gets.strip
|
77
|
+
end
|
78
|
+
email_sender = EmailSender.new(@printer.email_all, receiver)
|
79
|
+
email_sender.send_email
|
80
|
+
clear;print "Your email was successfully sent to:\n#{receiver}\n"
|
81
|
+
when "exit", "quit", "end", "q"
|
82
|
+
abort("\nBye for now!")
|
83
|
+
else
|
84
|
+
puts red('Please choose a valid selection:')
|
85
|
+
respond_to_input
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class ContactsCreator
|
2
|
+
|
3
|
+
def self.call
|
4
|
+
input_files = File.expand_path("../../data/", File.dirname(__FILE__))
|
5
|
+
Dir.glob("#{input_files}/*.txt") do |txt_file|
|
6
|
+
contacts_info = Parser.new(txt_file).parse
|
7
|
+
contacts_info.each do |contact|
|
8
|
+
Contacts.new(contact[0], contact[1], contact[2], contact[3], contact[4])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
class Contacts
|
4
|
+
attr_accessor :last_name, :first_name, :gender, :favorite_color, :birth_date
|
5
|
+
|
6
|
+
@@all = []
|
7
|
+
|
8
|
+
def self.all
|
9
|
+
@@all
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(last_name, first_name, gender, favorite_color, birth_date)
|
13
|
+
@last_name = last_name
|
14
|
+
@first_name = first_name
|
15
|
+
@gender = gender
|
16
|
+
@favorite_color = favorite_color
|
17
|
+
@birth_date = Date.strptime(birth_date, '%m/%d/%Y')
|
18
|
+
@@all << self
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'mail'
|
2
|
+
|
3
|
+
class EmailSender
|
4
|
+
attr_reader :outputs, :receiver
|
5
|
+
|
6
|
+
def initialize(outputs, receiver)
|
7
|
+
@outputs = outputs
|
8
|
+
@receiver = receiver
|
9
|
+
end
|
10
|
+
|
11
|
+
def formatted_email
|
12
|
+
email_message = ""
|
13
|
+
outputs.each_with_index do |output, i|
|
14
|
+
email_message << "<br>Output #{i+1}:<br>"
|
15
|
+
output.each do |contact_info|
|
16
|
+
email_message << contact_info + "<br>"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
email_message
|
20
|
+
end
|
21
|
+
|
22
|
+
def send_email(content = formatted_email, receiver = @receiver)
|
23
|
+
options = {
|
24
|
+
:address => "smtp.gmail.com",
|
25
|
+
:port => 587,
|
26
|
+
:domain => 'gmail.com',
|
27
|
+
:user_name => 'brennenawana108ny@gmail.com',
|
28
|
+
:password => ENV['PASSWORD'],
|
29
|
+
:authentication => 'plain',
|
30
|
+
:enable_starttls_auto => true
|
31
|
+
}
|
32
|
+
|
33
|
+
Mail.defaults do
|
34
|
+
delivery_method :smtp, options
|
35
|
+
end
|
36
|
+
|
37
|
+
Mail.deliver do
|
38
|
+
to "#{receiver}"
|
39
|
+
from 'brennenawana108ny@gmail.com'
|
40
|
+
subject 'Cyrus Code Challenge: Solution'
|
41
|
+
html_part do
|
42
|
+
content_type 'text/html; charset=UTF-8'
|
43
|
+
body "<p>#{content}</p>"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Formatter
|
2
|
+
|
3
|
+
def normalize(content)
|
4
|
+
dashed = content.gsub(/[-]/, "/")
|
5
|
+
contact = dashed.gsub(/[,]|[|]/, "").split(" ")
|
6
|
+
delete_middle_name(contact)
|
7
|
+
switch_dates(contact)
|
8
|
+
spell_gender(contact)
|
9
|
+
contact
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def delete_middle_name(content)
|
15
|
+
if content.length == 6
|
16
|
+
content.delete_at(2)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def switch_dates(content)
|
21
|
+
if content[3].include?("/")
|
22
|
+
content[3], content[4] = content[4], content[3]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def spell_gender(contact)
|
27
|
+
if contact[2] == "M"
|
28
|
+
contact[2] = "Male"
|
29
|
+
elsif contact[2] == "F"
|
30
|
+
contact[2] = "Female"
|
31
|
+
else
|
32
|
+
contact
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Parser
|
2
|
+
include Formatter
|
3
|
+
|
4
|
+
def initialize(file_path)
|
5
|
+
@file_path = file_path
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse
|
9
|
+
file = File.open(@file_path)
|
10
|
+
contents = file.read
|
11
|
+
array = contents.split("\n").map do |content|
|
12
|
+
normalize(content)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'pry'
|
2
|
+
class Printer
|
3
|
+
include Sorter
|
4
|
+
|
5
|
+
def print_all
|
6
|
+
output_1; output_2; output_3
|
7
|
+
end
|
8
|
+
|
9
|
+
def output_1
|
10
|
+
puts "", "Output 1:"
|
11
|
+
contacts = sorted_by_ascending_gender_and_last_name
|
12
|
+
contacts.each do |contact|
|
13
|
+
puts "#{contact.last_name} #{contact.first_name} #{contact.gender} #{contact.birth_date.strftime("%-m/%-d/%Y")} #{contact.favorite_color}"
|
14
|
+
end; puts""
|
15
|
+
end
|
16
|
+
|
17
|
+
def output_2
|
18
|
+
puts "Output 2:"
|
19
|
+
contacts = sorted_by_ascending_birthdate_and_last_name
|
20
|
+
contacts.each do |contact|
|
21
|
+
puts "#{contact.last_name} #{contact.first_name} #{contact.gender} #{contact.birth_date.strftime("%-m/%-d/%Y")} #{contact.favorite_color}"
|
22
|
+
end; puts""
|
23
|
+
end
|
24
|
+
|
25
|
+
def output_3
|
26
|
+
puts "Output 3:"
|
27
|
+
contacts = sorted_by_last_name_descending
|
28
|
+
contacts.each do |contact|
|
29
|
+
puts "#{contact.last_name} #{contact.first_name} #{contact.gender} #{contact.birth_date.strftime("%-m/%-d/%Y")} #{contact.favorite_color}"
|
30
|
+
end; puts""
|
31
|
+
end
|
32
|
+
|
33
|
+
def email_output_1
|
34
|
+
contacts = sorted_by_ascending_gender_and_last_name
|
35
|
+
contacts.map do |contact|
|
36
|
+
"#{contact.last_name} #{contact.first_name} #{contact.gender} #{contact.birth_date.strftime("%-m/%-d/%Y")} #{contact.favorite_color}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def email_output_2
|
41
|
+
contacts = sorted_by_ascending_birthdate_and_last_name
|
42
|
+
contacts.map do |contact|
|
43
|
+
"#{contact.last_name} #{contact.first_name} #{contact.gender} #{contact.birth_date.strftime("%-m/%-d/%Y")} #{contact.favorite_color}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def email_output_3
|
48
|
+
contacts = sorted_by_last_name_descending
|
49
|
+
contacts.map do |contact|
|
50
|
+
"#{contact.last_name} #{contact.first_name} #{contact.gender} #{contact.birth_date.strftime("%-m/%-d/%Y")} #{contact.favorite_color}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def email_all
|
55
|
+
[email_output_1, email_output_2, email_output_3]
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Sorter
|
2
|
+
|
3
|
+
def sorted_by_ascending_gender_and_last_name
|
4
|
+
Contacts.all.sort_by{|contact| [contact.gender, contact.last_name]}
|
5
|
+
end
|
6
|
+
|
7
|
+
def sorted_by_ascending_birthdate_and_last_name
|
8
|
+
Contacts.all.sort_by{|contact| [contact.birth_date, contact.last_name]}
|
9
|
+
end
|
10
|
+
|
11
|
+
def sorted_by_last_name_descending
|
12
|
+
Contacts.all.sort{|a,b| b.last_name <=> a.last_name}
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cyrus-code-challenge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brennen Awana
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-04 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email: brennenawana108ny@gmail.com
|
15
|
+
executables:
|
16
|
+
- cyrus-code-challenge
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/console
|
21
|
+
- bin/cyrus-code-challenge
|
22
|
+
- bin/test-output
|
23
|
+
- data/comma.txt
|
24
|
+
- data/pipe.txt
|
25
|
+
- data/space.txt
|
26
|
+
- env.rb
|
27
|
+
- lib/cyrus-code-challenge.rb
|
28
|
+
- lib/cyrus-code-challenge/cli-helpers.rb
|
29
|
+
- lib/cyrus-code-challenge/cli.rb
|
30
|
+
- lib/cyrus-code-challenge/contacts-creator.rb
|
31
|
+
- lib/cyrus-code-challenge/contacts.rb
|
32
|
+
- lib/cyrus-code-challenge/email-sender.rb
|
33
|
+
- lib/cyrus-code-challenge/formatter.rb
|
34
|
+
- lib/cyrus-code-challenge/parser.rb
|
35
|
+
- lib/cyrus-code-challenge/printer.rb
|
36
|
+
- lib/cyrus-code-challenge/sorter.rb
|
37
|
+
- lib/cyrus-code-challenge/version.rb
|
38
|
+
homepage: https://github.com/the-widget/code-challenge
|
39
|
+
licenses:
|
40
|
+
- MIT
|
41
|
+
metadata: {}
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
- data/input_files
|
47
|
+
- lib/cyrus-code-challenge
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 2.5.1
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: My solution for the cyrus-code-challenge, packaged into a CLI gem.
|
64
|
+
test_files: []
|