hulaki 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 23ae4598e465d968a7d6b347336b2f64480d9203
4
+ data.tar.gz: bd861ed5e5495fa44acb6e7686e6a86268710f63
5
+ SHA512:
6
+ metadata.gz: 7ef0fd5d590ee83caf83f5de5c4ea22d832648e6d8bf08c8497b7175670ac4a94386e5cc06b44b463d2a7a1612a9f3e4b2cf2d346dd3f641827495e7cf0bf2f9
7
+ data.tar.gz: 10ab76ee6143e4372b181d1b8684cc335e0e6e17e9639063c27aebdcb1482ff3556730c8811be1f28b057fa939bd68a6b1eea0c02014e2b60c17565ae126ebf1
data/.gitignore ADDED
@@ -0,0 +1,31 @@
1
+ # Rubymine project
2
+ .idea/
3
+ # Test and misc files
4
+ *.rbc
5
+ capybara-*.html
6
+ .rspec
7
+ /public/system
8
+ /coverage/
9
+ /spec/tmp
10
+ **.orig
11
+ rerun.txt
12
+ pickle-email-*.html
13
+ # Ignore bundler config.
14
+ /.bundle
15
+ # Ignore the default SQLite database and schema.
16
+ /db/*.sqlite3
17
+ /db/*.sqlite3-journal
18
+ /db/schema.rb
19
+ #Configs
20
+ /config/database.yml
21
+ # Ignore all logfiles and tempfiles.
22
+ /log/*.log
23
+ /tmp
24
+ # Ignore rmvrc
25
+ .rvmrc
26
+ # If using bower-rails ignore default bower_components path bower.json files
27
+ /vendor/assets/bower_components
28
+ *.bowerrc
29
+ bower.json
30
+ /lib/hulaki/config/config.yml
31
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
4
+ before_install: gem install bundler -v 1.10.6
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hulaki.gemspec
4
+ gemspec
5
+ gem 'pry'
6
+ gem 'mail'
data/Gemfile.lock ADDED
@@ -0,0 +1,61 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ hulaki (0.1)
5
+ amatch
6
+ smarter_csv
7
+ twilio-ruby (~> 4.11.1)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ amatch (0.3.0)
13
+ tins (~> 1.0)
14
+ builder (3.2.2)
15
+ coderay (1.1.1)
16
+ diff-lcs (1.2.5)
17
+ jwt (1.5.6)
18
+ mail (2.6.3)
19
+ mime-types (>= 1.16, < 3)
20
+ method_source (0.8.2)
21
+ mime-types (2.99)
22
+ multi_json (1.12.1)
23
+ pry (0.10.3)
24
+ coderay (~> 1.1.0)
25
+ method_source (~> 0.8.1)
26
+ slop (~> 3.4)
27
+ rake (10.5.0)
28
+ rspec (3.5.0)
29
+ rspec-core (~> 3.5.0)
30
+ rspec-expectations (~> 3.5.0)
31
+ rspec-mocks (~> 3.5.0)
32
+ rspec-core (3.5.3)
33
+ rspec-support (~> 3.5.0)
34
+ rspec-expectations (3.5.0)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.5.0)
37
+ rspec-mocks (3.5.0)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.5.0)
40
+ rspec-support (3.5.0)
41
+ slop (3.6.0)
42
+ smarter_csv (1.1.0)
43
+ tins (1.12.0)
44
+ twilio-ruby (4.11.1)
45
+ builder (>= 2.1.2)
46
+ jwt (~> 1.0)
47
+ multi_json (>= 1.3.0)
48
+
49
+ PLATFORMS
50
+ ruby
51
+
52
+ DEPENDENCIES
53
+ bundler (~> 1.10)
54
+ hulaki!
55
+ mail
56
+ pry
57
+ rake (~> 10.0)
58
+ rspec
59
+
60
+ BUNDLED WITH
61
+ 1.13.1
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 john
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Hulaki
2
+ [![Code Climate](https://codeclimate.com/github/shivabhusal/hulaki/badges/gpa.svg)](https://codeclimate.com/github/shivabhusal/hulaki)
3
+ [![Test Coverage](https://codeclimate.com/github/shivabhusal/hulaki/badges/coverage.svg)](https://codeclimate.com/github/shivabhusal/hulaki/coverage)
4
+ [![Issue Count](https://codeclimate.com/github/shivabhusal/hulaki/badges/issue_count.svg)](https://codeclimate.com/github/shivabhusal/hulaki)
5
+ [ ![Codeship Status for shivabhusal/hulaki](https://codeship.com/projects/49470f10-ba22-0133-af95-025ac38368ea/status?branch=master)](https://codeship.com/projects/135625)
6
+
7
+ #### Hulaki is a CLI tool to search contact details from your CSV file.
8
+
9
+ Hulaki makes communication easier by providing ability to search through the contact list. The CLI tool also allows sending direct SMS and/or email to desired person in contact list
10
+
11
+ ## Installation
12
+
13
+ Install this in your system using command.
14
+
15
+ $ gem install hulaki
16
+
17
+ >**Note:**
18
+ - Make sure to install this in your default ruby-version gemset. Other wise you may not be able to use the command from anywhere in your terminal emulator.
19
+ - Or install in every ruby-version gemset; to make the command `$ hulaki` accessible from anywhere.
20
+
21
+ ## Usage
22
+ Use the following command for help
23
+ ```bash
24
+ $ hulaki -h
25
+ $ hulaki --help
26
+ ```
27
+ ### Search phone number or other contact detail
28
+ ```bash
29
+ $ hulaki -s search-string
30
+ # Example: Hulaki features fuzzy search
31
+ # $ hulaki -s smithjohn
32
+ # $ hulaki -s johsmith
33
+ # $ hulaki -s smijohnth
34
+ ```
35
+
36
+ ### Sending SMS
37
+ > First search for contact number, copy it
38
+
39
+ ```
40
+ $ hulaki -t +977xxxxxxxxxx -m "Message to be sent"
41
+ ```
42
+
43
+ ## Configuration
44
+ - `Hulaki` requires the file `~/hulaki/contact.csv` to be present.
45
+ - The file must be a valid `CSV` file.
46
+ - When you install the gem, a sample config file is copied to `~/hulaki/config.yml`
47
+ - You need to update your `Twilio` creds
48
+ - `Hulaki` only supports `Twilio` at the moment.
49
+ - Also, update the SMTP settings accordingly
50
+
51
+ ---
52
+
53
+ ## Development
54
+
55
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
56
+
57
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
58
+
59
+ ## Contributing
60
+
61
+ Bug reports and pull requests are welcome on GitHub at https://github.com/shivabhusal/hulaki. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
62
+
63
+
64
+ ## License
65
+
66
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
67
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "hulaki"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/hulaki ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ # exe/hulaki
4
+ this_file = Pathname.new(__FILE__).realpath
5
+
6
+ $:.unshift File.expand_path("../../lib", this_file)
7
+
8
+ require 'hulaki'
9
+ config = Hulaki::OptionParser.new.parse(ARGV)
10
+ Hulaki::Core.new(config).perform
data/hulaki.gemspec ADDED
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hulaki/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'hulaki'
8
+ spec.version = Hulaki::VERSION
9
+ spec.authors = ['Shiva Bhusal', 'Shishir Sapkota', 'Neha Suwal', 'Prativa Devkota']
10
+ spec.email = ['hotline.shiva@gmail.com']
11
+
12
+ spec.summary = %q{Hulaki is basically a CLI tool to search contact details \
13
+ exported already in CSV format.}
14
+
15
+ spec.description = %Q{We developers don't have time to grab mobile phones, \
16
+ slide the screen, press pin numbers, open contact list \
17
+ and search the person you are looking for. Instead it would \
18
+ me much more easier if we could press some shortcut key \
19
+ to open terminal and enter a command to \
20
+ search the contact details and send message if we like.}
21
+
22
+ spec.homepage = 'https://github.com/shivabhusal/hulaki'
23
+ spec.license = 'MIT'
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = 'exe'
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ['lib']
29
+
30
+ spec.add_development_dependency 'bundler', '~> 1.10'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'pry'
33
+ spec.add_development_dependency 'rspec'
34
+ spec.add_runtime_dependency 'amatch'
35
+ spec.add_runtime_dependency 'twilio-ruby', '~> 4.11.1'
36
+ spec.add_runtime_dependency 'smarter_csv'
37
+ end
@@ -0,0 +1,35 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+ class Hulaki::Config
4
+ ConfigPath = '~/hulaki/config.yml'
5
+ SampleConfigPath = 'lib/hulaki/config/config_sample.yml'
6
+ @@config_file_path = ConfigPath
7
+ attr_accessor :file_path
8
+
9
+ def initialize(params = {})
10
+ @file_path = File.expand_path(params.fetch(:path, @@config_file_path))
11
+ end
12
+
13
+ def parse
14
+ read_file
15
+ end
16
+
17
+ private
18
+
19
+ def read_file
20
+ read_file = File.open(@file_path).read
21
+ YAML.load(ERB.new(read_file).result)
22
+ rescue Errno::ENOENT => e
23
+ raise Hulaki::InvalidFilePath, 'Invalid file.'
24
+ end
25
+
26
+ class << self
27
+ def config_file_path=(config_file_path)
28
+ @@config_file_path = config_file_path
29
+ end
30
+
31
+ def config_file_path
32
+ @@config_file_path
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ sms:
2
+ # The later config will override the former one
3
+ gateway:
4
+ name: twilio
5
+ keys:
6
+ TWILIO_ACCOUNT_SID: ACf43b1e6876as8d7a6sd27515ea49e418
7
+ TWILIO_AUTH_TOKEN: 75768435c30daeef519439kjhkjahsdk
8
+ TWILIO_PHONE_NUMBER: "+150447566666"
9
+
10
+ gateway:
11
+ name: twilio
12
+ keys:
13
+ TWILIO_ACCOUNT_SID: ACf43b1e6167987123jhkhkhkjjj49e418
14
+ TWILIO_AUTH_TOKEN: 75768435c30daeef519439c123123123f
15
+ TWILIO_PHONE_NUMBER: "+154444451701"
16
+
17
+ email:
18
+ delivery_method: smtp
19
+ address: "smtp.gmail.com"
20
+ port: 587
21
+ domain: 'gmail.com'
22
+ user_name: "jyaasaruby@gmail.com"
23
+ password: "p@ssword123"
24
+ authentication: "plain"
25
+ from: 'shishir'
@@ -0,0 +1,22 @@
1
+ class Hulaki::ContactParser
2
+
3
+ DefaultFilePath = '~/hulaki/contact.csv'
4
+
5
+ def perform
6
+ parse
7
+ end
8
+
9
+ private
10
+ def parse
11
+ options = {:strings_as_keys => true, :downcase_header => true}
12
+ SmarterCSV.process(contact_file, options)
13
+ rescue Errno::ENOENT
14
+ puts 'Contact file not found. Make sure there is file'
15
+ puts @file_path
16
+ nil
17
+ end
18
+
19
+ def contact_file
20
+ @file_path = File.expand_path(DefaultFilePath)
21
+ end
22
+ end
@@ -0,0 +1,46 @@
1
+ class Hulaki::EmailValidator
2
+ EmailRegex = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
3
+
4
+ def initialize(options = {})
5
+ @sender_email = options[:from]
6
+ @reciepient_email = options[:to]
7
+ @message = options[:message]
8
+ @errors = {}
9
+ end
10
+
11
+ def validates_presence
12
+ validate_sender_email
13
+ validate_recipient_email
14
+ validate_message
15
+ @errors
16
+ end
17
+
18
+ def validates_format
19
+ @errors.store("check_sender_email_format", "email format not valid") if EmailRegex.match(@sender_email).nil?
20
+ @errors.store("check_recipient_email_format", "email format not valid") if EmailRegex.match(@reciepient_email).nil?
21
+ @errors
22
+ end
23
+
24
+ class << self
25
+ def is_email?(email)
26
+ !is_not_email?(email)
27
+ end
28
+
29
+ def is_not_email?(email)
30
+ EmailRegex.match(email).nil?
31
+ end
32
+ end
33
+
34
+ private
35
+ def validate_sender_email
36
+ @errors.store("need_sender_email", "sender_email must be present") if @sender_email.nil? || @sender_email.empty?
37
+ end
38
+
39
+ def validate_recipient_email
40
+ @errors.store("need_reciepient_email", "reciepient_email must be present") if @reciepient_email.nil? || @reciepient_email.empty?
41
+ end
42
+
43
+ def validate_message
44
+ @errors.store("need_message", "Message cannot be blank") if @message.nil? || @message.empty?
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ module Hulaki
2
+ class InvalidPhoneNumber < StandardError
3
+ end
4
+
5
+ class InvalidEmail < StandardError
6
+ end
7
+
8
+ class InvalidSmsGateway < StandardError
9
+ end
10
+
11
+ class InvalidMessageBody < StandardError
12
+ end
13
+
14
+ class InvalidFilePath< StandardError
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ module Hulaki::Logger
2
+ def log(message, color = :green)
3
+ puts message.send(color)
4
+ end
5
+
6
+ module_function :log
7
+ end
@@ -0,0 +1,59 @@
1
+ class Hulaki::Mailer
2
+ def initialize(params={})
3
+ configure
4
+ @reciever = params[:to]
5
+ @sender = @env["from"]
6
+ sender_email = @env["user_name"]
7
+ @message = params[:body]
8
+ @sub = params[:sub]
9
+ validate(@reciever, sender_email, @message)
10
+ end
11
+
12
+ def deliver
13
+ @msg.deliver
14
+ "sent"
15
+ end
16
+
17
+ private
18
+ def configure
19
+ @env = Hulaki::Config.new.parse["email"]
20
+ address = @env["address"]
21
+ port = @env["port"]
22
+ domain=@env["domain"]
23
+ user_name = @env["user_name"]
24
+ password = @env["password"]
25
+ authentication = @env["authentication"]
26
+ Mail.defaults do
27
+ delivery_method :smtp,
28
+ {
29
+ :address => address,
30
+ :port => port,
31
+ :domain => domain,
32
+ :user_name => user_name,
33
+ :password => password,
34
+ :authentication => authentication,
35
+ :enable_starttls_auto => true
36
+ }
37
+ end
38
+ end
39
+
40
+ def create_mail
41
+ @msg = Mail.new({
42
+ :to => @reciever,
43
+ :from => @sender,
44
+ :subject => @sub,
45
+ :body => @message
46
+ })
47
+ self.deliver
48
+ end
49
+
50
+ def validate(reciever, sender, message)
51
+ validator = Hulaki::EmailValidator.new(from: reciever, to: sender, message: message)
52
+ errors = validator.validates_format && validator.validates_presence
53
+ if (errors.empty?)
54
+ create_mail
55
+ else
56
+ errors
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,116 @@
1
+ require_relative 'recursive_ostruct'
2
+ require 'fileutils'
3
+ require 'optparse'
4
+ require_relative 'presenter'
5
+ class Hulaki::OptionParser
6
+ def initialize
7
+ @config = RecursiveOstruct.ostruct(
8
+ {
9
+ to: [],
10
+ from: [],
11
+ subject: 'Mic testing',
12
+ message: 'sample message',
13
+ command: 'help'
14
+ })
15
+ end
16
+
17
+ def parse(args)
18
+ options.parse!(args)
19
+ @config
20
+ end
21
+
22
+ def options
23
+ OptionParser.new do |opts|
24
+ opts.banner = [
25
+ 'Usage: ',
26
+ '------- Search --------',
27
+ '$ hulaki -s search-string',
28
+ '# Example: Hulaki features fuzzy search',
29
+ '# $ hulaki -s smithjohn',
30
+ '# $ hulaki -s johsmith',
31
+ '# $ hulaki -s smijohnth',
32
+ '',
33
+ '------- SMS --------',
34
+ '$ hulaki -t +977xxxxxxxxxx -m "Message to be sent"',
35
+ '------- EMAIL --------',
36
+ ].join("\n")
37
+
38
+ opts.separator ''
39
+ opts.separator 'Specific options:'
40
+
41
+ opts.on('-t x,y,z', '--to x,y,z', Array, 'list of recipient, can be') do |list|
42
+ @config.to = list
43
+ end
44
+
45
+ opts.on('-m [Message]', '--message [Message]', String, 'Message to be sent to recipient') do |msg|
46
+ @config.message = msg
47
+ end
48
+
49
+ opts.on('-S [Subject]', '--subject [Subject]', String, 'Subject to email') do |sub|
50
+ @config.subject = sub
51
+ end
52
+
53
+ opts.on('-f x,y,z', '--from x,y,z', Array, 'Help / Examples') do |sender_list|
54
+ @config.to = sender_list
55
+ end
56
+
57
+ opts.on('-s [name/contact]', '--search [name/contact]', String, 'Search keyword') do |word|
58
+ response = Hulaki::SearchEngine.new.perform(word)
59
+ Hulaki::Presenter.new(response).display if response
60
+ exit
61
+ end
62
+
63
+ # ----------------------------------------------------------------------
64
+ opts.on('-h', '--help', 'Help / Examples') do
65
+ Hulaki::Logger.log opts.banner
66
+ exit
67
+ end
68
+
69
+ opts.on('-l', '--list', 'list all the options available') do
70
+ puts opts
71
+ exit
72
+ end
73
+
74
+ opts.on('-i', '--install', 'Creates ~/hulaki/config.yml') do
75
+ create_dir
76
+ start_copying_file
77
+ exit
78
+ end
79
+ end
80
+ end
81
+
82
+ def create_dir
83
+ FileUtils.mkdir(File.expand_path('~/hulaki'))
84
+ rescue Errno::EEXIST
85
+ puts 'Directory already exists.'
86
+ end
87
+
88
+ def start_copying_file
89
+ this_file = __FILE__
90
+ file_path = File.expand_path('../../lib/hulaki/config/config_sample.yml',
91
+ File.dirname(this_file))
92
+ desc_file = File.expand_path('~/hulaki/config.yml')
93
+ if File.exist?(desc_file)
94
+ puts "Looks like the file '#{desc_file}' already exists."
95
+ puts 'shall we forcefully override the file?(yes/no)'
96
+ handle_conflict(file_path, desc_file)
97
+ else
98
+ copy_file(file_path, desc_file)
99
+ end
100
+ end
101
+
102
+ def handle_conflict(file_path, desc_file)
103
+ input = gets().chomp()
104
+ if %w{yes y}.include?(input.downcase)
105
+ copy_file(file_path, desc_file)
106
+ else
107
+ puts 'You choose to leave it as it is.'
108
+ end
109
+ end
110
+
111
+ def copy_file(file_path, desc_file)
112
+ puts "Creating file '~/hulaki/config.yml' ..."
113
+ FileUtils.cp(file_path, desc_file)
114
+ puts "Created file '~/hulaki/config.yml' ..."
115
+ end
116
+ end
@@ -0,0 +1,17 @@
1
+ class Hulaki::Presenter
2
+ def initialize(data)
3
+ @data = [data].flatten
4
+ end
5
+
6
+ def display
7
+ puts '~' * 100
8
+ puts 'Search Results'
9
+ puts '~' * 100
10
+ @data[0..5].each do |row|
11
+ email = row.fetch('e_mail_1___value', 'N/A') rescue 'N/A'
12
+ phone_number = row.fetch('phone_1___value', 'N/A') rescue 'N/A'
13
+ puts "name: #{row['name']}, phone: #{phone_number}, email: #{email}" rescue nil
14
+ end
15
+ puts '~' * 100
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ require 'ostruct'
2
+ class RecursiveOstruct
3
+ def self.ostruct(object)
4
+ if object.is_a?(Hash)
5
+ object = object.clone
6
+ object.each do |key, value|
7
+ object[key] = ostruct(value)
8
+ end
9
+ OpenStruct.new(object)
10
+ else
11
+ object
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,41 @@
1
+ class Hulaki::SearchEngine
2
+ include Amatch
3
+
4
+ def initialize
5
+ contact_parser = Hulaki::ContactParser.new
6
+ @csv_data = contact_parser.perform
7
+ end
8
+
9
+ def perform(search_data)
10
+ unless @csv_data.nil?
11
+ search(search_data)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def search(data)
18
+ result = search_result(data).select { |x| x[1] > 0.3 }
19
+ result.sort { |x, y| y[1] <=> x[1] }
20
+ end
21
+
22
+ def search_result(data)
23
+ @csv_data.map do |row|
24
+ pt = 0.0
25
+ row.each do |k, v|
26
+ keys_to_search.each do |key|
27
+ if k.to_s.match(key.to_s)
28
+ pt += PairDistance.new(v.to_s).match(data.to_s)
29
+ end
30
+ end
31
+ end
32
+ weight = pt / keys_to_search.count
33
+ percentage = weight *100
34
+ [row, percentage]
35
+ end
36
+ end
37
+
38
+ def keys_to_search
39
+ ['name', 'email', 'phone']
40
+ end
41
+ end
@@ -0,0 +1,9 @@
1
+ class Hulaki::Sparrow
2
+ def initialize(params = {})
3
+
4
+ end
5
+
6
+ def send
7
+
8
+ end
9
+ end
@@ -0,0 +1,35 @@
1
+ class Hulaki::Twilio
2
+ attr_reader :to, :from, :message
3
+
4
+ def initialize(params = {})
5
+ @to = params[:to]
6
+ @message = params[:message]
7
+
8
+ @config = params[:config]['keys']
9
+ @from = params.fetch(:from, @config['TWILIO_PHONE_NUMBER'])
10
+ @client = Twilio::REST::Client.new @config['TWILIO_ACCOUNT_SID'],
11
+ @config['TWILIO_AUTH_TOKEN']
12
+ end
13
+
14
+ def send
15
+ return true if @@mode == 'test'
16
+ @client.messages.create(
17
+ from: from,
18
+ to: to,
19
+ body: message
20
+ )
21
+ end
22
+
23
+ class << self
24
+ @@mode = 'live'
25
+
26
+ def mode=(mode)
27
+ @@mode = mode
28
+ end
29
+
30
+ def mode
31
+ @@mode
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,48 @@
1
+ class Hulaki::SmsHandler
2
+ attr_reader :gateway, :to, :from, :message
3
+
4
+ def initialize(params = {})
5
+ @to = params.fetch(:to, params[:recipient])
6
+ @from = params.fetch(:from, params[:sender])
7
+ @message = params.fetch(:message, params[:msg])
8
+
9
+ @gateway = get_gateway(params.fetch(:gateway, 'twilio'))
10
+
11
+ end
12
+
13
+ def send
14
+ verify_details
15
+ @gateway.send
16
+ end
17
+
18
+ private
19
+
20
+ def get_gateway(gateway_name = nil)
21
+ config = gateway_config
22
+
23
+ gateway_name ||= config['name']
24
+
25
+ klass = gateway_name.to_s.capitalize
26
+
27
+ eval("Hulaki::#{klass}").new(
28
+ {
29
+ config: config,
30
+ to: to,
31
+ from: from || gateway_config['keys']['TWILIO_PHONE_NUMBER'],
32
+ message: message
33
+ })
34
+
35
+ rescue SyntaxError => e
36
+ raise Hulaki::InvalidSmsGateway, 'Please choose a valid sms gateway'
37
+ end
38
+
39
+ def verify_details
40
+ Hulaki::SmsValidator.new(to: to,
41
+ from: from || gateway_config['keys']['TWILIO_PHONE_NUMBER'],
42
+ message: message).validate
43
+ end
44
+
45
+ def gateway_config
46
+ Hulaki::Config.new.parse['sms']['gateway']
47
+ end
48
+ end
@@ -0,0 +1,37 @@
1
+ class Hulaki::SmsValidator
2
+ attr_reader :errors, :to, :from, :message, :gateway
3
+ RegexPhoneNumber = /(?:\+?|\b)[0-9]{10}\b/
4
+
5
+ def initialize(params = {})
6
+ @errors = {}
7
+ @to = params.fetch(:to, params[:recipient])
8
+ @from = params.fetch(:from, params[:sender])
9
+ @message = params.fetch(:message, params[:msg])
10
+ end
11
+
12
+ def validate
13
+ to || (raise Hulaki::InvalidPhoneNumber, 'Recipient phone number should be present.')
14
+ from || (raise Hulaki::InvalidPhoneNumber, 'Sender phone number should be present.')
15
+ message || (raise Hulaki::InvalidMessageBody, 'Message body should be present.')
16
+
17
+ check_if_number_invalid
18
+ end
19
+
20
+ def self.is_phone_number?(number)
21
+ !is_not_phone_number?(number)
22
+ end
23
+
24
+ def self.is_not_phone_number?(number)
25
+ number.match(RegexPhoneNumber).nil?
26
+ end
27
+
28
+ private
29
+ def check_if_number_invalid
30
+ RegexPhoneNumber.match(to) || (raise Hulaki::InvalidPhoneNumber,
31
+ "Phone number '#{to}' is invalid.")
32
+
33
+ RegexPhoneNumber.match(from) || (raise Hulaki::InvalidPhoneNumber,
34
+ "Phone number '#{from}' is invalid.")
35
+ end
36
+
37
+ end
@@ -0,0 +1,17 @@
1
+ class String
2
+ def black; "\e[30m#{self}\e[0m" end
3
+ def red; "\e[31m#{self}\e[0m" end
4
+ def green; "\e[32m#{self}\e[0m" end
5
+ def blue; "\e[34m#{self}\e[0m" end
6
+
7
+ def bg_black; "\e[40m#{self}\e[0m" end
8
+ def bg_red; "\e[41m#{self}\e[0m" end
9
+ def bg_green; "\e[42m#{self}\e[0m" end
10
+ def bg_blue; "\e[44m#{self}\e[0m" end
11
+
12
+ def bold; "\e[1m#{self}\e[22m" end
13
+ def italic; "\e[3m#{self}\e[23m" end
14
+ def underline; "\e[4m#{self}\e[24m" end
15
+ def blink; "\e[5m#{self}\e[25m" end
16
+ def reverse_color; "\e[7m#{self}\e[27m" end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Hulaki
2
+ VERSION = '0.1'
3
+ end
data/lib/hulaki.rb ADDED
@@ -0,0 +1,78 @@
1
+ require 'hulaki/version'
2
+ require 'hulaki/string_modifier'
3
+ require 'amatch'
4
+ require 'hulaki/search_engine'
5
+ require 'hulaki/version'
6
+ require 'hulaki/contact_parser'
7
+ require 'smarter_csv'
8
+ require 'twilio-ruby'
9
+ require 'pry'
10
+ require 'hulaki/option_parser'
11
+ require 'hulaki/sms_handler/sms_handler'
12
+ require 'hulaki/sms_handler/sms_validator'
13
+ require 'hulaki/sms_handler/gateway_adapters/twilio'
14
+ require 'hulaki/sms_handler/gateway_adapters/sparrow'
15
+ require 'hulaki/config/config'
16
+ require 'hulaki/exceptions'
17
+ require 'hulaki/email_validator'
18
+ require 'hulaki/mailer'
19
+ require 'hulaki/logger'
20
+ require 'mail'
21
+
22
+ class Hulaki::Core
23
+ def initialize(config)
24
+ @config = config
25
+ end
26
+
27
+ def perform
28
+ puts '~' * 100
29
+ puts 'Welcome to Hulaki : Your best companion! to make your day great.'
30
+ puts '~' * 100
31
+
32
+ @config.to.each do |recipient|
33
+ if is_phone?(recipient)
34
+ handle_sms(recipient)
35
+ elsif is_email?(recipient)
36
+ handle_email(recipient)
37
+ end
38
+ end
39
+
40
+ puts '~' * 100
41
+ puts @config.message
42
+ puts '~' * 100
43
+
44
+ end
45
+
46
+ private
47
+
48
+ def is_phone?(number)
49
+ Hulaki::SmsValidator.is_phone_number?(number)
50
+ end
51
+
52
+ def is_email?(email)
53
+ Hulaki::EmailValidator.is_email?(email)
54
+ end
55
+
56
+ def handle_email(recipient)
57
+ puts "Sending email to #{recipient}"
58
+ email_handler = Hulaki::Mailer.new(
59
+ {
60
+ to: recipient,
61
+ body: @config.message,
62
+ sub: @config.subject,
63
+ })
64
+ puts "Email sent to #{recipient}."
65
+ end
66
+
67
+ def handle_sms(recipient)
68
+ puts "Sending SMS to #{recipient}"
69
+ sms_handler = Hulaki::SmsHandler.new(
70
+ {
71
+ to: recipient,
72
+ message: @config.message
73
+ })
74
+ if sms_handler.send
75
+ puts "SMS sent successfully to #{recipient}"
76
+ end
77
+ end
78
+ end
metadata ADDED
@@ -0,0 +1,183 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hulaki
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Shiva Bhusal
8
+ - Shishir Sapkota
9
+ - Neha Suwal
10
+ - Prativa Devkota
11
+ autorequire:
12
+ bindir: exe
13
+ cert_chain: []
14
+ date: 2016-09-25 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: bundler
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.10'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.10'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - "~>"
35
+ - !ruby/object:Gem::Version
36
+ version: '10.0'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '10.0'
44
+ - !ruby/object:Gem::Dependency
45
+ name: pry
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ - !ruby/object:Gem::Dependency
73
+ name: amatch
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ - !ruby/object:Gem::Dependency
87
+ name: twilio-ruby
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - "~>"
91
+ - !ruby/object:Gem::Version
92
+ version: 4.11.1
93
+ type: :runtime
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: 4.11.1
100
+ - !ruby/object:Gem::Dependency
101
+ name: smarter_csv
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ type: :runtime
108
+ prerelease: false
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ description: We developers don't have time to grab mobile phones, slide
115
+ the screen, press pin numbers, open contact list and search
116
+ the person you are looking for. Instead it would me much
117
+ more easier if we could press some shortcut key to open
118
+ terminal and enter a command to search the contact details
119
+ and send message if we like.
120
+ email:
121
+ - hotline.shiva@gmail.com
122
+ executables:
123
+ - hulaki
124
+ extensions: []
125
+ extra_rdoc_files: []
126
+ files:
127
+ - ".gitignore"
128
+ - ".rspec"
129
+ - ".travis.yml"
130
+ - CODE_OF_CONDUCT.md
131
+ - Gemfile
132
+ - Gemfile.lock
133
+ - LICENSE.txt
134
+ - README.md
135
+ - Rakefile
136
+ - bin/console
137
+ - bin/setup
138
+ - exe/hulaki
139
+ - hulaki.gemspec
140
+ - lib/hulaki.rb
141
+ - lib/hulaki/config/config.rb
142
+ - lib/hulaki/config/config_sample.yml
143
+ - lib/hulaki/contact_parser.rb
144
+ - lib/hulaki/email_validator.rb
145
+ - lib/hulaki/exceptions.rb
146
+ - lib/hulaki/logger.rb
147
+ - lib/hulaki/mailer.rb
148
+ - lib/hulaki/option_parser.rb
149
+ - lib/hulaki/presenter.rb
150
+ - lib/hulaki/recursive_ostruct.rb
151
+ - lib/hulaki/search_engine.rb
152
+ - lib/hulaki/sms_handler/gateway_adapters/sparrow.rb
153
+ - lib/hulaki/sms_handler/gateway_adapters/twilio.rb
154
+ - lib/hulaki/sms_handler/sms_handler.rb
155
+ - lib/hulaki/sms_handler/sms_validator.rb
156
+ - lib/hulaki/string_modifier.rb
157
+ - lib/hulaki/version.rb
158
+ homepage: https://github.com/shivabhusal/hulaki
159
+ licenses:
160
+ - MIT
161
+ metadata: {}
162
+ post_install_message:
163
+ rdoc_options: []
164
+ require_paths:
165
+ - lib
166
+ required_ruby_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ required_rubygems_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ requirements: []
177
+ rubyforge_project:
178
+ rubygems_version: 2.5.1
179
+ signing_key:
180
+ specification_version: 4
181
+ summary: Hulaki is basically a CLI tool to search contact details \ exported already
182
+ in CSV format.
183
+ test_files: []