hailinator 0.0.2
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.
- data/hailinator_test.rb +266 -0
- data/hailinator_test_helper.rb +109 -0
- metadata +46 -0
data/hailinator_test.rb
ADDED
@@ -0,0 +1,266 @@
|
|
1
|
+
require './hailinator_test_helper'
|
2
|
+
|
3
|
+
|
4
|
+
unless File.exist?('hailinator.rb')
|
5
|
+
puts <<-WELCOME
|
6
|
+
|
7
|
+
__ __ _______ ___ d ___ ___ __ _ _______ _______ _______ ______
|
8
|
+
| | | || _ || | | | | | | | | || _ || || || _ |
|
9
|
+
| |_| || |_| || | | | | | | |_| || |_| ||_ _|| _ || | ||
|
10
|
+
| || || | | | | | | || | | | | | | || |_||_
|
11
|
+
| || || | | |___ | | | _ || | | | | |_| || __ |
|
12
|
+
| _ || _ || | | || | | | | || _ | | | | || | | |
|
13
|
+
|__| |__||__| |__||___| |_______||___| |_| |__||__| |__| |___| |_______||___| |_|
|
14
|
+
|
15
|
+
|
16
|
+
We're going to create a Ruby application! Hailinator will:
|
17
|
+
|
18
|
+
* search Twitter for certain hashtags, like #hail and #damage,
|
19
|
+
* export the tweet details to a CSV file for our sales reps
|
20
|
+
|
21
|
+
The sales reps need leads for people who have likely suffered from hail damage,
|
22
|
+
because they can try to sell them on their bodyshop's repair services. Amazingly,
|
23
|
+
some sales reps will pay up to $10 per lead! With just a few lines of code,
|
24
|
+
we'll be able to print some fun beer money.
|
25
|
+
|
26
|
+
This wizard will guide you through each step to build the working application.
|
27
|
+
Pass the current step to see the next step.
|
28
|
+
|
29
|
+
NOTE: If you break something, this wizard might jump back a few steps. That's OK,
|
30
|
+
just figure out what you broke and un-do it. You didn't lose any work.
|
31
|
+
|
32
|
+
READY?
|
33
|
+
|
34
|
+
To continue, create a file called 'hailinator.rb'. Once you're done, please
|
35
|
+
run this script again.
|
36
|
+
|
37
|
+
IF YOU STILL SEE THE SAME MESSAGE, check:
|
38
|
+
* to be sure you named your file correctly
|
39
|
+
* that you created it in the same directory
|
40
|
+
* HINT: you can see all files in the directory by typing 'ls'
|
41
|
+
|
42
|
+
|
43
|
+
WELCOME
|
44
|
+
|
45
|
+
# TODO:
|
46
|
+
# Add levenshtein check for incorrect filenames
|
47
|
+
|
48
|
+
|
49
|
+
exit
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
## STEP TWO
|
55
|
+
|
56
|
+
unless twitter_gem_installed?
|
57
|
+
step 2
|
58
|
+
|
59
|
+
puts <<-TWITTER
|
60
|
+
|
61
|
+
OK, we're going to search Twitter, right? So we need a way to talk to Twitter.
|
62
|
+
|
63
|
+
Ruby has different "libraries" or "gems" that add on to Ruby's abilities.
|
64
|
+
There are gems for talking to Facebook, gems for creating Excel spreadsheets, gems for sending email, and tens of thousands of other things.
|
65
|
+
|
66
|
+
Let's add the gem for twitter.
|
67
|
+
|
68
|
+
Run: 'gem install twitter' in Terminal
|
69
|
+
|
70
|
+
TWITTER
|
71
|
+
|
72
|
+
exit
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
unless twitter_gem_loaded?
|
78
|
+
step 3
|
79
|
+
|
80
|
+
puts <<-TWITTER
|
81
|
+
|
82
|
+
Cool, now we have the Twitter gem installed. But our hailinator script doesn't know about it.
|
83
|
+
|
84
|
+
We have to ask Ruby to "require" it. This is kinda like 'load', but pulls in a whole gem instead of
|
85
|
+
just a file. Also, the gem doesn't have to be in the current directory that our script is in.
|
86
|
+
|
87
|
+
It just needs to be installed on the machine.
|
88
|
+
|
89
|
+
Add 'require "twitter"' to 'hailinator.rb'
|
90
|
+
|
91
|
+
TWITTER
|
92
|
+
|
93
|
+
exit
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
unless Twitter.client?
|
99
|
+
step 4
|
100
|
+
|
101
|
+
puts <<-AUTHENTICATED
|
102
|
+
|
103
|
+
Awesome, we've loaded in the Twitter gem. Next we need to authenticate with Twitter.
|
104
|
+
|
105
|
+
Follow the quick-start guide to get that going:
|
106
|
+
https://github.com/sferik/twitter#quick-start-guide
|
107
|
+
|
108
|
+
AUTHENTICATED
|
109
|
+
|
110
|
+
exit
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
unless searching_twitter?
|
116
|
+
step 5
|
117
|
+
|
118
|
+
puts <<-AUTHENTICATED
|
119
|
+
|
120
|
+
Cool, we're authenticated! Hello, Twitter. Now we need to search for those tweets!
|
121
|
+
|
122
|
+
The documentation should help you get started.
|
123
|
+
|
124
|
+
AUTHENTICATED
|
125
|
+
|
126
|
+
exit
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
unless inspected_tweets?
|
131
|
+
|
132
|
+
step 6
|
133
|
+
|
134
|
+
puts <<-INSPECTED
|
135
|
+
|
136
|
+
Great, we're searching for stuff... Loop over the results and `puts` them to the screen.
|
137
|
+
|
138
|
+
Hint: `.inspect` is your friend
|
139
|
+
|
140
|
+
INSPECTED
|
141
|
+
|
142
|
+
exit
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
unless csv_file_exists?
|
148
|
+
step 7
|
149
|
+
|
150
|
+
puts <<-CSV
|
151
|
+
So we've done several things:
|
152
|
+
* 'gem install twitter'
|
153
|
+
* `require 'twitter'` in our script
|
154
|
+
* Authenticated with Twitter
|
155
|
+
* Searched for tweets
|
156
|
+
|
157
|
+
Alright, that's a lot of stuff going on. We want to spit the tweets out into a CSV, though.
|
158
|
+
|
159
|
+
Google for how to generate a CSV file in Ruby. To pass this step,
|
160
|
+
we should be creating a file with a ".csv" extension in this directory.
|
161
|
+
|
162
|
+
|
163
|
+
CSV
|
164
|
+
|
165
|
+
exit
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
unless csv_has_headers?
|
171
|
+
step 7
|
172
|
+
|
173
|
+
puts <<-CSV
|
174
|
+
|
175
|
+
RIGHT ON! OK, we have a CSV file named '#{Dir['*.csv'].first}'. Now we need some data in it.
|
176
|
+
|
177
|
+
Our client is using a propietary format and needs the file to be in this format EXACTLY:
|
178
|
+
|
179
|
+
handle,text,url
|
180
|
+
|
181
|
+
Let's add those as the CSV file headers.
|
182
|
+
|
183
|
+
HINT: run `cat {filename}.csv` to see what your actual file output is
|
184
|
+
|
185
|
+
CSV
|
186
|
+
|
187
|
+
|
188
|
+
|
189
|
+
exit
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
unless csv_has_rows?
|
194
|
+
step 8
|
195
|
+
|
196
|
+
puts <<-CSV
|
197
|
+
|
198
|
+
Cool, we have our headers. Let's display the tweet information on each row now.
|
199
|
+
|
200
|
+
CSV
|
201
|
+
|
202
|
+
|
203
|
+
exit
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
puts "SHIP IT"
|
210
|
+
puts <<-SQUIRREL
|
211
|
+
|
212
|
+
|
213
|
+
SHIP IT
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
..\|||||/',//
|
218
|
+
`\\`\ ///
|
219
|
+
`\` | / '/'
|
220
|
+
-.`\ \ | // //
|
221
|
+
_- -. \ | / /.
|
222
|
+
- | / .'.'
|
223
|
+
-- - `. \ / .'.'
|
224
|
+
-_ - ` \ \ / / / .'-'
|
225
|
+
-_ _ -` |\ | ' ' -'-''
|
226
|
+
-___ '`/ ` \ / / _-- -'_
|
227
|
+
_ _/ '` \ | /| _ -
|
228
|
+
_.__ / `. //| _ - _ -_
|
229
|
+
_ '| \._ \ __.--// | - __
|
230
|
+
_- ' ` \`. .' (/ | - _ -
|
231
|
+
' '| \ \ `' |\ _ _-_
|
232
|
+
'/ \ | ` _ `. _ _
|
233
|
+
\ | ` ` >/ ' `-.
|
234
|
+
\| .-' |_ db `.
|
235
|
+
\ .' d| MP \ ___ _.-
|
236
|
+
` ` | .' Vb ' |' \ .-' `----'
|
237
|
+
`\ .' / \ .-' | _\.'
|
238
|
+
\ .' | ---.___ .' `
|
239
|
+
/ - \._mm) `-._ / .' _.-
|
240
|
+
`\ / . `"Y" --.' .--------'
|
241
|
+
\\ / `. `-._____ .' .-'
|
242
|
+
/ \ `-. / .'
|
243
|
+
) / '. .-' .'
|
244
|
+
` / ' -._.- .' .'
|
245
|
+
) ' ' `..' .'
|
246
|
+
. ' ' ` .' .'`
|
247
|
+
` ' .' .' `
|
248
|
+
` ' '.-' .' `
|
249
|
+
` _ .' .' .`
|
250
|
+
' _`.' .' .`
|
251
|
+
'. .-'_ `_' .' `
|
252
|
+
- .' _ `_` .-' .`
|
253
|
+
) `-._` .' `
|
254
|
+
'__ _.-_ ` .' .` VK
|
255
|
+
'.' `' /__. `
|
256
|
+
/ /_.-'
|
257
|
+
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
SQUIRREL
|
264
|
+
|
265
|
+
|
266
|
+
|
@@ -0,0 +1,109 @@
|
|
1
|
+
def require filename
|
2
|
+
response = super filename
|
3
|
+
|
4
|
+
if defined?(Twitter) && !defined?(LOADED_TWITTER)
|
5
|
+
Kernel.const_set(:LOADED_TWITTER, true)
|
6
|
+
|
7
|
+
Twitter.module_eval do
|
8
|
+
def self.search(*args)
|
9
|
+
Kernel.const_set(:SEARCHED_TWITTER, true)
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
response
|
17
|
+
end
|
18
|
+
|
19
|
+
def puts *args
|
20
|
+
@inspected ||= args.any? do |arg|
|
21
|
+
arg.inspect.include?('Twitter::Tweet')
|
22
|
+
end
|
23
|
+
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
at_exit do
|
28
|
+
if @error_message
|
29
|
+
e = @error_message
|
30
|
+
puts "\n" * 4, "*" * 40, "\n" * 2
|
31
|
+
puts " ERROR TYPE: #{e.class.name}"
|
32
|
+
puts " MESSAGE: #{e.message}"
|
33
|
+
puts " FILE NAME: #{e.backtrace.first.split(':').first}"
|
34
|
+
puts " LINE NUMBER: #{e.backtrace.first.split(':')[1]}"
|
35
|
+
puts "\n" * 3
|
36
|
+
puts [e.class.name, e.message, *e.backtrace].join "\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# set_trace_func proc { |event, file, line, id, binding, classname|
|
41
|
+
# if classname =~ /Module/
|
42
|
+
# printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
|
43
|
+
# end
|
44
|
+
# }
|
45
|
+
|
46
|
+
begin
|
47
|
+
Dir['*.csv'].each do |file|
|
48
|
+
File.delete(file)
|
49
|
+
end
|
50
|
+
|
51
|
+
puts "*" * 40
|
52
|
+
puts "SCRIPT OUTPUT"
|
53
|
+
puts "*" * 40
|
54
|
+
|
55
|
+
load 'hailinator.rb'
|
56
|
+
rescue LoadError, Exception => e
|
57
|
+
@error_message = e
|
58
|
+
ensure
|
59
|
+
puts "\n" * 5, "*" * 40
|
60
|
+
puts "//SCRIPT OUTPUT"
|
61
|
+
puts "*" * 40, "\n" * 5
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def step number
|
66
|
+
total = 8
|
67
|
+
|
68
|
+
puts "#" * (total + 2)
|
69
|
+
puts ["[", "*" * number, " " * (total - number), "]"].join
|
70
|
+
puts "STEP #{number} OF #{total}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def twitter_gem_installed?
|
74
|
+
@twitter_gem_response = require 'twitter'
|
75
|
+
|
76
|
+
true
|
77
|
+
rescue LoadError
|
78
|
+
false
|
79
|
+
end
|
80
|
+
|
81
|
+
def twitter_gem_loaded?
|
82
|
+
# If require returns false, our script loaded it
|
83
|
+
!@twitter_gem_response
|
84
|
+
end
|
85
|
+
|
86
|
+
def searching_twitter?
|
87
|
+
defined?(SEARCHED_TWITTER)
|
88
|
+
end
|
89
|
+
|
90
|
+
def inspected_tweets?
|
91
|
+
@inspected
|
92
|
+
end
|
93
|
+
|
94
|
+
def csv_file_exists?
|
95
|
+
Dir['*.csv'].any?
|
96
|
+
end
|
97
|
+
|
98
|
+
def csv_has_headers?
|
99
|
+
Dir['*.csv'].any? do |file|
|
100
|
+
File.read(file).include?('handle,text,url')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def csv_has_rows?
|
105
|
+
Dir['*.csv'].any? do |file|
|
106
|
+
File.read(file).split("\n").length > 2
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hailinator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nathaniel Jones
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-13 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: yay!
|
15
|
+
email: hello@nthj.me
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- hailinator_test.rb
|
21
|
+
- hailinator_test_helper.rb
|
22
|
+
homepage: http://rubygems.org/gems/hailinator
|
23
|
+
licenses: []
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 1.8.25
|
43
|
+
signing_key:
|
44
|
+
specification_version: 3
|
45
|
+
summary: Hailinator!
|
46
|
+
test_files: []
|