hulaki 0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,5 @@
1
+ require 'amatch'
2
+
1
3
  class Hulaki::SearchEngine
2
4
  include Amatch
3
5
 
@@ -15,27 +17,34 @@ class Hulaki::SearchEngine
15
17
  private
16
18
 
17
19
  def search(data)
18
- result = search_result(data).select { |x| x[1] > 0.3 }
20
+ result = search_result(data).select { |x| x[1] > 0.4 } # setting threshold
21
+ # Sort data keeping data with higer degree of similarity at the top
22
+ # i.e. having lowest value of percentage at the bottom
19
23
  result.sort { |x, y| y[1] <=> x[1] }
20
24
  end
21
25
 
22
26
  def search_result(data)
27
+ downcased_data = data.downcase.gsub(' ', '')
23
28
  @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
+ max_point = 0.0
30
+ row.each do |col_head, v|
31
+ keys_to_search.each do |key, weight|
32
+ if col_head.to_s.downcase == key
33
+ point = PairDistance.new(v.to_s.downcase).match(downcased_data)*weight
34
+ max_point = point if max_point < point
35
+ # puts "#{key} #{col_head} #{point} #{v} #{downcased_data}"
29
36
  end
30
37
  end
31
38
  end
32
- weight = pt / keys_to_search.count
33
- percentage = weight *100
34
- [row, percentage]
39
+
40
+ [row, max_point]
35
41
  end
36
42
  end
37
43
 
38
44
  def keys_to_search
39
- ['name', 'email', 'phone']
45
+ {
46
+ 'name' => 2, 'first_name' => 3, 'last_name' => 3, 'given_name' => 3,
47
+ 'family_name' => 3, 'email' => 0.6, 'phone_1___value'=> 0.5, 'phone_2___value' => 0.5
48
+ }
40
49
  end
41
50
  end
@@ -0,0 +1,21 @@
1
+ require 'nexmo'
2
+
3
+ class Hulaki::Nexmo
4
+ attr_reader :to, :from, :message, :client
5
+
6
+ def initialize(params = {})
7
+ @to = params[:to]
8
+ @message = params[:message]
9
+
10
+ @config = params[:config]
11
+ @from = params.fetch(:from, @config['from'])
12
+ return true if ENV['mode'] == 'test'
13
+ @client = Nexmo::Client.new(key: @config['API_KEY'], secret: @config['API_SECRET'])
14
+
15
+ end
16
+
17
+ def send
18
+ return true if ENV['mode'] == 'test'
19
+ client.send_message(from: from, to: to, text: message)
20
+ end
21
+ end
@@ -1,35 +1,24 @@
1
+ require 'twilio-ruby'
2
+
1
3
  class Hulaki::Twilio
2
4
  attr_reader :to, :from, :message
3
5
 
4
6
  def initialize(params = {})
5
- @to = params[:to]
7
+ @to = params[:to]
6
8
  @message = params[:message]
7
9
 
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']
10
+ @config = params[:config]
11
+ @from = @config['ACCOUNT_PHONE_NUMBER']
12
+ @client = Twilio::REST::Client.new @config['API_KEY'],
13
+ @config['API_SECRET']
12
14
  end
13
15
 
14
16
  def send
15
- return true if @@mode == 'test'
17
+ return true if ENV['mode'] == 'test'
16
18
  @client.messages.create(
17
19
  from: from,
18
20
  to: to,
19
21
  body: message
20
22
  )
21
23
  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
24
  end
@@ -1,13 +1,16 @@
1
1
  class Hulaki::SmsHandler
2
+ VALID_GATEWAY = ['twilio', 'nexmo', 'sparrow']
2
3
  attr_reader :gateway, :to, :from, :message
3
4
 
4
5
  def initialize(params = {})
5
- @to = params.fetch(:to, params[:recipient])
6
- @from = params.fetch(:from, params[:sender])
6
+ @to = params.fetch(:to, params[:recipient])
7
+ @from = params.fetch(:from, params[:sender])
7
8
  @message = params.fetch(:message, params[:msg])
8
9
 
9
- @gateway = get_gateway(params.fetch(:gateway, 'twilio'))
10
+ explicit_gateway = params[:gateway] && VALID_GATEWAY.include?(params[:gateway].downcase) && params[:gateway].downcase
10
11
 
12
+ @gateway_name = explicit_gateway || get_default_gateway_name
13
+ @gateway = get_gateway
11
14
  end
12
15
 
13
16
  def send
@@ -17,19 +20,16 @@ class Hulaki::SmsHandler
17
20
 
18
21
  private
19
22
 
20
- def get_gateway(gateway_name = nil)
23
+ def get_gateway
21
24
  config = gateway_config
22
-
23
- gateway_name ||= config['name']
24
-
25
- klass = gateway_name.to_s.capitalize
25
+ klass = @gateway_name.to_s.capitalize
26
26
 
27
27
  eval("Hulaki::#{klass}").new(
28
28
  {
29
- config: config,
30
- to: to,
31
- from: from || gateway_config['keys']['TWILIO_PHONE_NUMBER'],
32
- message: message
29
+ :config => gateway_config,
30
+ :to => to,
31
+ :from => from || gateway_config['from'],
32
+ :message => message
33
33
  })
34
34
 
35
35
  rescue SyntaxError => e
@@ -38,11 +38,20 @@ class Hulaki::SmsHandler
38
38
 
39
39
  def verify_details
40
40
  Hulaki::SmsValidator.new(to: to,
41
- from: from || gateway_config['keys']['TWILIO_PHONE_NUMBER'],
41
+ from: from || gateway_config['ACCOUNT_PHONE_NUMBER'],
42
42
  message: message).validate
43
43
  end
44
44
 
45
+ def get_default_gateway_name
46
+ Hulaki::Config['sms'].each do|key, value|
47
+ return key if value['default'] == true
48
+ end
49
+
50
+ # If no default defined in the config; pick the last one
51
+ Hulaki::Config['sms'].keys.last
52
+ end
53
+
45
54
  def gateway_config
46
- Hulaki::Config.new.parse['sms']['gateway']
55
+ @gateway_config ||= Hulaki::Config['sms'][@gateway_name]
47
56
  end
48
57
  end
@@ -3,15 +3,13 @@ class Hulaki::SmsValidator
3
3
  RegexPhoneNumber = /(?:\+?|\b)[0-9]{10}\b/
4
4
 
5
5
  def initialize(params = {})
6
- @errors = {}
7
- @to = params.fetch(:to, params[:recipient])
8
- @from = params.fetch(:from, params[:sender])
6
+ @errors = {}
7
+ @to = params.fetch(:to, params[:recipient])
9
8
  @message = params.fetch(:message, params[:msg])
10
9
  end
11
10
 
12
11
  def validate
13
- to || (raise Hulaki::InvalidPhoneNumber, 'Recipient phone number should be present.')
14
- from || (raise Hulaki::InvalidPhoneNumber, 'Sender phone number should be present.')
12
+ to || (raise Hulaki::InvalidPhoneNumber, 'Recipient phone number should be present.')
15
13
  message || (raise Hulaki::InvalidMessageBody, 'Message body should be present.')
16
14
 
17
15
  check_if_number_invalid
@@ -29,9 +27,6 @@ class Hulaki::SmsValidator
29
27
  def check_if_number_invalid
30
28
  RegexPhoneNumber.match(to) || (raise Hulaki::InvalidPhoneNumber,
31
29
  "Phone number '#{to}' is invalid.")
32
-
33
- RegexPhoneNumber.match(from) || (raise Hulaki::InvalidPhoneNumber,
34
- "Phone number '#{from}' is invalid.")
35
30
  end
36
31
 
37
32
  end
@@ -2,7 +2,11 @@ class String
2
2
  def black; "\e[30m#{self}\e[0m" end
3
3
  def red; "\e[31m#{self}\e[0m" end
4
4
  def green; "\e[32m#{self}\e[0m" end
5
+ def brown; "\e[33m#{self}\e[0m" end
5
6
  def blue; "\e[34m#{self}\e[0m" end
7
+ def magenta; "\e[35m#{self}\e[0m" end
8
+ def cyan; "\e[36m#{self}\e[0m" end
9
+ def gray; "\e[37m#{self}\e[0m" end
6
10
 
7
11
  def bg_black; "\e[40m#{self}\e[0m" end
8
12
  def bg_red; "\e[41m#{self}\e[0m" end
@@ -0,0 +1,76 @@
1
+ module Utils
2
+ def create_dir
3
+ FileUtils.mkdir(File.expand_path('~/hulaki'))
4
+ rescue Errno::EEXIST
5
+ puts 'Looks like directory `~/hulaki` already exists.'.brown
6
+ end
7
+
8
+ def install_dependencies
9
+ if `which xclip`.match('not found')
10
+ puts "Looks like you don't `xclip` installed in your system. It is required to copy phone numbers to ClipBoard"
11
+ puts 'We are installing it right now ... '
12
+ puts 'It will ask you password: Be ready'
13
+ puts `sudo apt-get install xclip`.red
14
+ puts '`xclip` successfully installed!'.green
15
+ else
16
+ puts '`xclip` is already installed!'
17
+ end
18
+ end
19
+
20
+ def start_copying_file
21
+ # this line is for debugging purposes
22
+ this_file = __FILE__
23
+ files_to_be_copied = {
24
+ 'sample.contact.csv' => 'contact.csv',
25
+ 'sample.config.yml' => 'config.yml',
26
+ 'sample.template.html.erb' => 'template.html.erb'
27
+ }
28
+
29
+ # Start copying the files
30
+ files_to_be_copied.each do|source, dest|
31
+ file_path = File.expand_path("../../lib/hulaki/config/#{source}", File.dirname(this_file))
32
+ desc_file = File.expand_path("~/hulaki/#{dest}")
33
+ if File.exist?(desc_file)
34
+ puts "Looks like the file '#{desc_file}' already exists.".brown
35
+ print 'Shall we forcefully override the file?(yes/no)'.brown
36
+ handle_conflict(file_path, desc_file)
37
+ else
38
+ copy_file(file_path, desc_file)
39
+ end
40
+ end
41
+ Hulaki::Logger.log '~'*100
42
+ Hulaki::Logger.log 'Please make sure you have modified the files at `~/hulaki` a/c to your need.'
43
+ Hulaki::Logger.log '~'*100
44
+ end
45
+
46
+ def handle_conflict(file_path, desc_file)
47
+ input = gets().chomp()
48
+ if %w{yes y}.include?(input.downcase)
49
+ copy_file(file_path, desc_file)
50
+ else
51
+ Hulaki::Logger.log 'You choose to leave it as it is.'
52
+ end
53
+ end
54
+
55
+ def copy_file(file_path, desc_file)
56
+ puts "Creating file '#{desc_file}' ...".brown
57
+ FileUtils.cp(file_path, desc_file)
58
+ Hulaki::Logger.log "Created file '#{desc_file}' ..."
59
+ end
60
+
61
+ def present(object)
62
+ object.to_s.split("\n").map{|x|
63
+ if x[0] == '#'
64
+ x.gray
65
+ elsif x[0] == '$'
66
+ x.green
67
+ elsif x.match('---')
68
+ x.brown
69
+ else
70
+ x
71
+ end
72
+ }.join("\n")
73
+ end
74
+
75
+ module_function :create_dir, :start_copying_file, :handle_conflict, :copy_file, :install_dependencies, :present
76
+ end
@@ -1,3 +1,3 @@
1
1
  module Hulaki
2
- VERSION = '0.1'
2
+ VERSION = '1.0.2'
3
3
  end
metadata CHANGED
@@ -1,17 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hulaki
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shiva Bhusal
8
- - Shishir Sapkota
9
- - Neha Suwal
10
- - Prativa Devkota
11
8
  autorequire:
12
9
  bindir: exe
13
10
  cert_chain: []
14
- date: 2016-09-25 00:00:00.000000000 Z
11
+ date: 2017-06-01 00:00:00.000000000 Z
15
12
  dependencies:
16
13
  - !ruby/object:Gem::Dependency
17
14
  name: bundler
@@ -73,16 +70,16 @@ dependencies:
73
70
  name: amatch
74
71
  requirement: !ruby/object:Gem::Requirement
75
72
  requirements:
76
- - - ">="
73
+ - - "~>"
77
74
  - !ruby/object:Gem::Version
78
- version: '0'
75
+ version: 0.3.1
79
76
  type: :runtime
80
77
  prerelease: false
81
78
  version_requirements: !ruby/object:Gem::Requirement
82
79
  requirements:
83
- - - ">="
80
+ - - "~>"
84
81
  - !ruby/object:Gem::Version
85
- version: '0'
82
+ version: 0.3.1
86
83
  - !ruby/object:Gem::Dependency
87
84
  name: twilio-ruby
88
85
  requirement: !ruby/object:Gem::Requirement
@@ -97,20 +94,76 @@ dependencies:
97
94
  - - "~>"
98
95
  - !ruby/object:Gem::Version
99
96
  version: 4.11.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: nexmo
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 4.6.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 4.6.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: mail
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 2.6.3
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 2.6.3
100
125
  - !ruby/object:Gem::Dependency
101
126
  name: smarter_csv
102
127
  requirement: !ruby/object:Gem::Requirement
103
128
  requirements:
104
- - - ">="
129
+ - - '='
105
130
  - !ruby/object:Gem::Version
106
- version: '0'
131
+ version: 1.1.0
107
132
  type: :runtime
108
133
  prerelease: false
109
134
  version_requirements: !ruby/object:Gem::Requirement
110
135
  requirements:
111
- - - ">="
136
+ - - '='
112
137
  - !ruby/object:Gem::Version
113
- version: '0'
138
+ version: 1.1.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: terminal-table
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '='
144
+ - !ruby/object:Gem::Version
145
+ version: 1.8.0
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '='
151
+ - !ruby/object:Gem::Version
152
+ version: 1.8.0
153
+ - !ruby/object:Gem::Dependency
154
+ name: clipboard
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '='
158
+ - !ruby/object:Gem::Version
159
+ version: 1.1.0
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '='
165
+ - !ruby/object:Gem::Version
166
+ version: 1.1.0
114
167
  description: We developers don't have time to grab mobile phones, slide
115
168
  the screen, press pin numbers, open contact list and search
116
169
  the person you are looking for. Instead it would me much
@@ -137,29 +190,36 @@ files:
137
190
  - bin/setup
138
191
  - exe/hulaki
139
192
  - hulaki.gemspec
193
+ - images/hulaki.png
140
194
  - lib/hulaki.rb
141
195
  - lib/hulaki/config/config.rb
142
- - lib/hulaki/config/config_sample.yml
196
+ - lib/hulaki/config/sample.config.yml
197
+ - lib/hulaki/config/sample.contact.csv
198
+ - lib/hulaki/config/sample.template.html.erb
143
199
  - lib/hulaki/contact_parser.rb
144
- - lib/hulaki/email_validator.rb
200
+ - lib/hulaki/core.rb
201
+ - lib/hulaki/email_handler/email_validator.rb
202
+ - lib/hulaki/email_handler/mailer.rb
145
203
  - lib/hulaki/exceptions.rb
146
204
  - lib/hulaki/logger.rb
147
- - lib/hulaki/mailer.rb
148
205
  - lib/hulaki/option_parser.rb
149
206
  - lib/hulaki/presenter.rb
150
207
  - lib/hulaki/recursive_ostruct.rb
151
208
  - lib/hulaki/search_engine.rb
209
+ - lib/hulaki/sms_handler/gateway_adapters/nexmo.rb
152
210
  - lib/hulaki/sms_handler/gateway_adapters/sparrow.rb
153
211
  - lib/hulaki/sms_handler/gateway_adapters/twilio.rb
154
212
  - lib/hulaki/sms_handler/sms_handler.rb
155
213
  - lib/hulaki/sms_handler/sms_validator.rb
156
214
  - lib/hulaki/string_modifier.rb
215
+ - lib/hulaki/utils.rb
157
216
  - lib/hulaki/version.rb
158
217
  homepage: https://github.com/shivabhusal/hulaki
159
218
  licenses:
160
219
  - MIT
161
220
  metadata: {}
162
- post_install_message:
221
+ post_install_message: Please run `$ hulaki -i` to install Configuration files so that
222
+ you can modify later
163
223
  rdoc_options: []
164
224
  require_paths:
165
225
  - lib
@@ -175,9 +235,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
235
  version: '0'
176
236
  requirements: []
177
237
  rubyforge_project:
178
- rubygems_version: 2.5.1
238
+ rubygems_version: 2.6.12
179
239
  signing_key:
180
240
  specification_version: 4
181
241
  summary: Hulaki is basically a CLI tool to search contact details \ exported already
182
- in CSV format.
242
+ in CSV format, send SMS and Emails in a single command.
183
243
  test_files: []