cyrus-code-challenge 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|