crm_formatter 1.0.5.pre.rc.1 → 1.0.6.pre.rc.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 +4 -4
- data/README.md +296 -0
- data/gem_notes_crm_formatter.txt +109 -0
- data/lib/crm_formatter/version.rb +1 -1
- data/lib/crm_formatter/web.rb +6 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '031873afa102ba537d240f6c86c828bd29c75d85bf5063af6f6f5b715398203f'
|
4
|
+
data.tar.gz: a4c08972f40519a94ac636b5c5f287c68bb485bb6ae3c1126ffcc80a61dd3b2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a37c47288003b2593422fc199d6875dfb47a0104d48d53b1bb2366a59c7038229082cb17d5b1adc14b14f4227d704c07cfd6672adb5678c7b7744a0c6fb8169
|
7
|
+
data.tar.gz: 4ca91da1f810d5d93451fd6d36d82878185fc33df5f32e7318537a4fa5367eb9cf91ac22c038261bbb38340cf2e207424ae9f68175ba7c80174a34e3f0662cbd
|
data/README.md
ADDED
@@ -0,0 +1,296 @@
|
|
1
|
+
# CRMFormatter
|
2
|
+
|
3
|
+
Reformat and Normalize CRM Contact Data, Addresses, Phones, Emails and URLs.
|
4
|
+
Please note, that this gem is a rapid work in process. It is from a collection of modules currently being used on a production app, but decided to open them up. The tests have not yet been written for the gem and there will still be changes in the near future. Documentation is limited, but is coming. Here are some basic points below to help you get started.
|
5
|
+
|
6
|
+
## Getting Started
|
7
|
+
|
8
|
+
In your Gemfile add:
|
9
|
+
|
10
|
+
```
|
11
|
+
gem 'crm_formatter', '~> 1.0.5.pre.rc.1'
|
12
|
+
```
|
13
|
+
|
14
|
+
Or to install locally:
|
15
|
+
|
16
|
+
```
|
17
|
+
gem install crm_formatter --pre
|
18
|
+
```
|
19
|
+
|
20
|
+
### Prerequisites
|
21
|
+
|
22
|
+
CRMFormatter is optimized for Rails 5.2 and Ruby 2.5, but has worked well in older versions too.
|
23
|
+
|
24
|
+
### Architecture
|
25
|
+
|
26
|
+
CRMFormatter is the top level Module wrapper comprising of 3 Classes, Address, Phone and Web. There is also a Helpers Module for shared tasks.
|
27
|
+
|
28
|
+
|
29
|
+
### Usage
|
30
|
+
|
31
|
+
CRMFormatter could be used anywhere in an app for various reasons. Most commonly from an app's helper methods, controllers or model. If you wanted to ensure all new data is properly formatted before saving, methods could be accessed from the model via before_save, callbacks, or validations. In addition to CRMFormatter formatting CRM data, it also provides detailed reports on what if anything has changed and it always preserves the original data submitted. Here are a few examples below of how it could be used.
|
32
|
+
|
33
|
+
The gem can be used both en mass to clean up an entire database, or fully-integrated into an app's regular environment.
|
34
|
+
They were however, designed for an app that Harvests business data for sales and marketing teams, so they work perfectly with NokoGiri and Mechanize!
|
35
|
+
|
36
|
+
** These are just examples below, not strict usage guides ...
|
37
|
+
|
38
|
+
### Usage by Class & Methods
|
39
|
+
* The examples at the bottom of the page are rather verbose, so first, here is a list of methods available to you.
|
40
|
+
|
41
|
+
# Address
|
42
|
+
|
43
|
+
* 'get_full_address' takes a hash of address parts then runs each through their respective formatters, then also adds an additional feature of combining them into a long full address string, and indicates if there were any changes from the original version and newly formatted.
|
44
|
+
|
45
|
+
```
|
46
|
+
addr_formatter = CRMFormatter::Address.new
|
47
|
+
|
48
|
+
addr_formatter.get_full_address(full_address_hsh)
|
49
|
+
full_address_hsh = {street: street, city: city, state: state, zip: zip}
|
50
|
+
|
51
|
+
addr_formatter.format_street(street)
|
52
|
+
|
53
|
+
addr_formatter.format_city(city)
|
54
|
+
|
55
|
+
addr_formatter.format_state(state)
|
56
|
+
|
57
|
+
addr_formatter.format_zip(zip)
|
58
|
+
|
59
|
+
addr_formatter.format_full_address(adr = {})
|
60
|
+
|
61
|
+
addr_formatter.compare_versions(original, formatted)
|
62
|
+
|
63
|
+
|
64
|
+
```
|
65
|
+
|
66
|
+
# Phone
|
67
|
+
|
68
|
+
* Subtle but important distinction between 'format_phone' which simply puts a phone in any format, like 555-123-4567 into normalized (555) 123-4567, and 'validate_phone' which also uses 'format_phone' to normalize its output, but is mainly tasked with determining if the phone number seem legitimate. If you know for sure that it is a phone number, but just want to normalize then first try format_phone. If you are doing web scraping or throwing in strings of text mixed with phones, then validate_phone might work better.
|
69
|
+
|
70
|
+
```
|
71
|
+
ph_formatter = CRMFormatter::Phone.new
|
72
|
+
|
73
|
+
ph_formatter.validate_phone(phone)
|
74
|
+
|
75
|
+
ph_formatter.format_phone(phone)
|
76
|
+
|
77
|
+
```
|
78
|
+
|
79
|
+
# Web
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
```
|
84
|
+
web_formatter = CRMFormatter::Web.new
|
85
|
+
|
86
|
+
web_formatter.format_url(url)
|
87
|
+
|
88
|
+
web_formatter.extract_link(url_path)
|
89
|
+
|
90
|
+
web_formatter.remove_invalid_links(link)
|
91
|
+
|
92
|
+
web_formatter.remove_invalid_hrefs(href)
|
93
|
+
|
94
|
+
web_formatter.convert_to_scheme_host(url)
|
95
|
+
|
96
|
+
```
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
* Data will always be returned as hashes, with your original, modified, and details about what has changed.
|
108
|
+
* You may pass optional arguments at initialization to provide lists of data to match against, for example a list of words that if in a URL, it would automatically report as junk (but still keeping your original in tact.)
|
109
|
+
|
110
|
+
Typically, you will want to create your own method as a wrapper for the Gem methods, like below...
|
111
|
+
|
112
|
+
## Address
|
113
|
+
** The examples below are rather verbose, so you can make them much more compact of course.
|
114
|
+
|
115
|
+
```
|
116
|
+
def self.run_adrs
|
117
|
+
|
118
|
+
crm_address_formatter = CRMFormatter::Address.new
|
119
|
+
|
120
|
+
contacts = Contact.where.not(full_address: nil)
|
121
|
+
|
122
|
+
contacts.each do |contact|
|
123
|
+
|
124
|
+
cont_adr_hsh = { street: contact.street, city: contact.city,
|
125
|
+
state: contact.state, zip: contact.zip }
|
126
|
+
|
127
|
+
formatted_address_hsh = crm_address_formatter.format_full_address(cont_adr_hsh)
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
```
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
## Phone
|
138
|
+
|
139
|
+
In the phone example, format_all_phone_in_my_db could be a custom wrapper method, which when called by Rails C or from a front end GUI process, could grab all phones in db meeting certain criteria to be scrubbed. The results will always be in hash format, such as below.... phone_hash
|
140
|
+
|
141
|
+
```
|
142
|
+
@crm_phone = CRMFormatter::Phone.new
|
143
|
+
|
144
|
+
def self.format_all_phone_in_my_db
|
145
|
+
phones_from_contacts = Contacts.where.not(phone: nil)
|
146
|
+
|
147
|
+
phones_from_contacts.each do |contact|
|
148
|
+
phone_hash = @crm_phone.validate_phone(contact.phone)
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
phone_hash = { phone: 555-123-4567, valid_phone: (555) 123-4567, phone_edit: true }
|
154
|
+
```
|
155
|
+
|
156
|
+
|
157
|
+
## Web
|
158
|
+
|
159
|
+
In the example below, you might write a wrapper method named anything you like, such as 'format_a_url' and 'clean_many_websites' to pass in urls to be formatted.
|
160
|
+
|
161
|
+
```
|
162
|
+
@web = CRMFormatter::Web.new
|
163
|
+
|
164
|
+
def format_a_url(url)
|
165
|
+
hsh = @web.format_url(url)
|
166
|
+
end
|
167
|
+
|
168
|
+
def clean_many_websites(array_of_urls)
|
169
|
+
|
170
|
+
hashes = array_of_urls.map do |url|
|
171
|
+
@web.format_url(url)
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
```
|
176
|
+
|
177
|
+
|
178
|
+
### Additional Usage Examples
|
179
|
+
|
180
|
+
### Webs
|
181
|
+
* Another example below.
|
182
|
+
|
183
|
+
```
|
184
|
+
def self.run_webs
|
185
|
+
|
186
|
+
url_flags = %w(approv avis budget business collis eat enterprise facebook financ food google gourmet hertz hotel hyatt insur invest loan lube mobility motel motorola parts quick rent repair restaur rv ryder service softwar travel twitter webhost yellowpages yelp youtube)
|
187
|
+
|
188
|
+
link_flags = %w(: .biz .co .edu .gov .jpg .net // anounc book business buy bye call cash cheap click collis cont distrib download drop event face feature feed financ find fleet form gas generat graphic hello home hospi hour hours http info insta)
|
189
|
+
|
190
|
+
href_flags = %w(? .com .jpg @ * after anounc apply approved blog book business buy call care career cash charit cheap check click)
|
191
|
+
|
192
|
+
extension_flags = %w(au ca edu es gov in ru uk us)
|
193
|
+
|
194
|
+
args = { url_flags: url_flags, link_flags: link_flags, href_flags: href_flags, extension_flags: extension_flags }
|
195
|
+
web = CRMFormatter::Web.new(args)
|
196
|
+
|
197
|
+
urls = Accounts.where.not(url: nil).pluck(:url)
|
198
|
+
|
199
|
+
validated_url_hashes = urls.map { |url| web.format_url(url) }
|
200
|
+
valid_urls = validated_url_hashes.map { |hsh| hsh[:valid_url] }.compact
|
201
|
+
extracted_link_hashes = urls.map { |url| web.extract_link(url) }
|
202
|
+
links = extracted_link_hashes.map { |hsh| hsh[:link] }.compact
|
203
|
+
validated_link_hashes = links.map { |link| web.remove_invalid_links(link) }
|
204
|
+
hrefs = ["Hot Inventory", "Join Our Sale!", "Don't Wait till Later", "Apply Today!", "No Cash Down!"]
|
205
|
+
validated_href_hashes = hrefs.map { |href| web.remove_invalid_hrefs(href) }
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
```
|
210
|
+
|
211
|
+
### Fully Integrated into an App Example
|
212
|
+
** The gem is currently being used within another app in the following way...
|
213
|
+
|
214
|
+
```
|
215
|
+
@web_formatter.convert_to_scheme_host(url)
|
216
|
+
@web_formatter.format_url(url)
|
217
|
+
```
|
218
|
+
The two methods above, which are many available to you in the gem are being used below.
|
219
|
+
```
|
220
|
+
curl_result[:response_code] = result&.response_code.to_s
|
221
|
+
web_hsh = @web_formatter.format_url(result&.last_effective_url)
|
222
|
+
|
223
|
+
if web_hsh[:formatted_url].present?
|
224
|
+
curl_result[:verified_url] = @web_formatter.convert_to_scheme_host(web_hsh[:formatted_url])
|
225
|
+
end
|
226
|
+
|
227
|
+
```
|
228
|
+
|
229
|
+
# Above is an isolated sliver of the larger environment shown below...
|
230
|
+
|
231
|
+
```
|
232
|
+
def start_curl(url, timeout)
|
233
|
+
|
234
|
+
curl_result = { verified_url: nil, response_code: nil, curl_err: nil }
|
235
|
+
if url.present?
|
236
|
+
result = nil
|
237
|
+
|
238
|
+
begin # Curl Exception Handling
|
239
|
+
begin # Timeout Exception Handling
|
240
|
+
Timeout.timeout(timeout) do
|
241
|
+
puts "\n\n=== WAITING FOR CURL RESPONSE ==="
|
242
|
+
result = Curl::Easy.perform(url) do |curl|
|
243
|
+
curl.follow_location = true
|
244
|
+
curl.useragent = "curb"
|
245
|
+
curl.connect_timeout = timeout
|
246
|
+
curl.enable_cookies = true
|
247
|
+
curl.head = true #testing - new
|
248
|
+
end # result
|
249
|
+
|
250
|
+
curl_result[:response_code] = result&.response_code.to_s
|
251
|
+
web_hsh = @web_formatter.format_url(result&.last_effective_url)
|
252
|
+
|
253
|
+
if web_hsh[:formatted_url].present?
|
254
|
+
curl_result[:verified_url] = @web_formatter.convert_to_scheme_host(web_hsh[:formatted_url])
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
rescue Timeout::Error # Timeout Exception Handling
|
259
|
+
curl_result[:curl_err] = "Error: Timeout"
|
260
|
+
end
|
261
|
+
|
262
|
+
rescue LoadError => e # Curl Exception Handling
|
263
|
+
curl_err = error_parser("Error: #{$!.message}")
|
264
|
+
# CheckInt.new.check_int if curl_err.include?('TCP')
|
265
|
+
curl_result[:curl_err] = curl_err
|
266
|
+
end
|
267
|
+
else ## If no url present?
|
268
|
+
curl_result[:curl_err] = 'URL Nil'
|
269
|
+
end
|
270
|
+
|
271
|
+
print_result(curl_result)
|
272
|
+
curl_result
|
273
|
+
end
|
274
|
+
```
|
275
|
+
|
276
|
+
|
277
|
+
### Another Example from a Production Environment...
|
278
|
+
|
279
|
+
```
|
280
|
+
def format_url(url)
|
281
|
+
url_hash = @web_formatter.format_url(url)
|
282
|
+
url_hash.merge!({ verified_url: nil, url_redirected: false, response_code: nil, url_sts: nil, url_date: Time.now, wx_date: nil, timeout: nil })
|
283
|
+
url_hash = evaluate_formatted_url(url_hash)
|
284
|
+
end
|
285
|
+
|
286
|
+
```
|
287
|
+
|
288
|
+
|
289
|
+
|
290
|
+
## Author
|
291
|
+
|
292
|
+
Adam J Booth - [4rlm](https://github.com/4rlm)
|
293
|
+
|
294
|
+
## License
|
295
|
+
|
296
|
+
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
|
@@ -0,0 +1,109 @@
|
|
1
|
+
==== FIRST CREATE APP TO TEST GEM ====
|
2
|
+
-----------------------------------
|
3
|
+
rails new gem_tester
|
4
|
+
cd gem_tester
|
5
|
+
rails g scaffold Article
|
6
|
+
rails g controller Home index
|
7
|
+
-----------------------------------
|
8
|
+
get 'home/index'
|
9
|
+
root 'home#index'
|
10
|
+
-----------------------------------
|
11
|
+
|
12
|
+
|
13
|
+
==== CREATE BASIC GEM ====
|
14
|
+
-----------------------------------
|
15
|
+
create crm_formatter.gemspec
|
16
|
+
-----------------------------------
|
17
|
+
mkdir bin lib test lib/crm_formatter
|
18
|
+
-----------------------------------
|
19
|
+
touch Rakefile
|
20
|
+
touch lib/crm_formatter.rb
|
21
|
+
touch lib/crm_formatter/version.rb
|
22
|
+
touch lib/crm_formatter/translator.rb
|
23
|
+
touch bin/crm_formatter
|
24
|
+
touch test/test_crm_formatter.rb
|
25
|
+
-----------------------------------
|
26
|
+
$ git init .
|
27
|
+
$ ls -la
|
28
|
+
$ rm .DS_Store
|
29
|
+
$ git status
|
30
|
+
$ git add .
|
31
|
+
$ git commit -m "Initial Commit"
|
32
|
+
$ git log
|
33
|
+
$ git status
|
34
|
+
$ git ls-files -z
|
35
|
+
---- Create Repo on GitHub, then push.
|
36
|
+
-----------------------------------
|
37
|
+
$ gem build crm_formatter.gemspec
|
38
|
+
Successfully built RubyGem
|
39
|
+
Name: crm_formatter
|
40
|
+
Version: 1.0.5.pre.rc.1
|
41
|
+
File: crm_formatter-1.0.5.pre.rc.1.gem
|
42
|
+
-----------------------------------
|
43
|
+
$ gem install crm_formatter-1.0.5.pre.rc.1.gem
|
44
|
+
Successfully installed crm_formatter-1.0.5.pre.rc.1
|
45
|
+
Parsing documentation for crm_formatter-1.0.5.pre.rc.1
|
46
|
+
Installing ri documentation for crm_formatter-1.0.5.pre.rc.1
|
47
|
+
Done installing documentation for crm_formatter after 0 seconds
|
48
|
+
1 gem installed
|
49
|
+
-----------------------------------
|
50
|
+
$ irb
|
51
|
+
>> require 'crm_formatter'
|
52
|
+
=> true
|
53
|
+
>> CRMFormatter.hi 'english'
|
54
|
+
=> "hello world"
|
55
|
+
-----------------------------------
|
56
|
+
$ curl -u adamjbooth https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
|
57
|
+
Enter host password for user 'adamjbooth': RG<usual>rg
|
58
|
+
-----------------------------------
|
59
|
+
$ gem push crm_formatter-1.0.5.pre.rc.1.gem
|
60
|
+
Pushing gem to https://rubygems.org...
|
61
|
+
Successfully registered gem: crm_formatter (1.0.4.pre.rc.1)
|
62
|
+
-----------------------------------
|
63
|
+
|
64
|
+
|
65
|
+
============= after each change: =======================
|
66
|
+
gem build crm_formatter.gemspec
|
67
|
+
gem install crm_formatter-1.0.3.pre.rc.1.gem
|
68
|
+
irb
|
69
|
+
require 'crm_formatter'
|
70
|
+
CRMFormatter.hi('english')
|
71
|
+
|
72
|
+
Translator.new.greeter
|
73
|
+
|
74
|
+
CRMFormatter
|
75
|
+
=========================
|
76
|
+
|
77
|
+
CRMFormatter::Address.new
|
78
|
+
CRMFormatter::Address.new.state
|
79
|
+
CRMFormatter::Address.self_state
|
80
|
+
|
81
|
+
/Users/Adam/Desktop/gems/crm_formatter/lib/crm_formatter.rb
|
82
|
+
====================================================================
|
83
|
+
|
84
|
+
|
85
|
+
require '/Users/Adam/Desktop/gems/crm_formatter/lib/crm_formatter/address.rb'
|
86
|
+
crm_phone = CRMFormatter::Phone.new
|
87
|
+
crm_phone.validate_phone("229-954-6172")
|
88
|
+
|
89
|
+
=> [{:phone=>"229-954-6172", :valid_phone=>"(229) 954-6172", :change=>true},
|
90
|
+
{:phone=>"4.142285305606521", :valid_phone=>nil, :change=>nil},
|
91
|
+
{:phone=>"23870 Addie Green", :valid_phone=>nil, :change=>nil},
|
92
|
+
{:phone=>"73408-0942", :valid_phone=>nil, :change=>nil},
|
93
|
+
{:phone=>"8853 Hank Course", :valid_phone=>nil, :change=>nil},
|
94
|
+
{:phone=>"910-202-3756 x827", :valid_phone=>"(910) 202-3756", :change=>true},
|
95
|
+
{:phone=>"119-305-4317", :valid_phone=>"119-305-4317", :change=>false},
|
96
|
+
{:phone=>"197-294-8073 x2164", :valid_phone=>"(972) 948-0732", :change=>true},
|
97
|
+
{:phone=>"53.866282605787006", :valid_phone=>nil, :change=>nil},
|
98
|
+
{:phone=>"91783", :valid_phone=>nil, :change=>nil}]
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
address = CRMFormatter::Address.new
|
106
|
+
address.state
|
107
|
+
|
108
|
+
address = CRMFormatter::Address.new.state
|
109
|
+
address.gh
|
data/lib/crm_formatter/web.rb
CHANGED
@@ -5,7 +5,7 @@ module CRMFormatter
|
|
5
5
|
@url_flags = args.fetch(:url_flags, [])
|
6
6
|
@link_flags = args.fetch(:link_flags, [])
|
7
7
|
@href_flags = args.fetch(:href_flags, [])
|
8
|
-
@extension_flags = args.fetch(:
|
8
|
+
@extension_flags = args.fetch(:extension_flags, [])
|
9
9
|
@length_min = args.fetch(:length_min, 2)
|
10
10
|
@length_max = args.fetch(:length_max, 100)
|
11
11
|
end
|
@@ -28,14 +28,15 @@ module CRMFormatter
|
|
28
28
|
url = url[0..-2] if url[-1] == '/'
|
29
29
|
|
30
30
|
symbs = ['(', ')', '[', ']', '{', '}', '*', '@', '^', '$', '+', '!', '<', '>', '~', ',', "'"]
|
31
|
+
|
31
32
|
return url_hsh if symbs.any? {|symb| url&.include?(symb) }
|
32
33
|
|
33
34
|
uri = URI(url)
|
34
35
|
if uri.present?
|
35
36
|
host_parts = uri.host&.split(".")
|
36
37
|
|
37
|
-
if @
|
38
|
-
bad_host_sts = host_parts&.map { |part| TRUE if @
|
38
|
+
if @extension_flags.any?
|
39
|
+
bad_host_sts = host_parts&.map { |part| TRUE if @extension_flags.any? {|ext| part == ext } }&.compact&.first
|
39
40
|
return url_hsh if bad_host_sts
|
40
41
|
end
|
41
42
|
|
@@ -44,7 +45,9 @@ module CRMFormatter
|
|
44
45
|
url = "#{scheme}://#{host}" if host.present? && scheme.present?
|
45
46
|
url = "http://#{url}" if url[0..3] != "http"
|
46
47
|
url = url.gsub("//", "//www.") if !url.include?("www.")
|
48
|
+
|
47
49
|
return url_hsh if @url_flags.any? { |bad_text| url&.include?(bad_text) }
|
50
|
+
|
48
51
|
url_hsh[:formatted_url] = convert_to_scheme_host(url) if url.present?
|
49
52
|
url_hsh[:url_edit] = url_hsh[:formatted_url] != url_hsh[:url_path]
|
50
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crm_formatter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6.pre.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Booth
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Reformat and Normalize CRM Contact Data, Addresses, Phones, Emails and
|
14
14
|
URLs. Originally developed for proprietary use in an enterprise software suite. Recently
|
@@ -23,9 +23,11 @@ extensions: []
|
|
23
23
|
extra_rdoc_files: []
|
24
24
|
files:
|
25
25
|
- ".gitignore"
|
26
|
+
- README.md
|
26
27
|
- Rakefile
|
27
28
|
- bin/crm_formatter
|
28
29
|
- crm_formatter.gemspec
|
30
|
+
- gem_notes_crm_formatter.txt
|
29
31
|
- lib/crm_formatter.rb
|
30
32
|
- lib/crm_formatter/address.rb
|
31
33
|
- lib/crm_formatter/helpers.rb
|