stuffed 0.1.0
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/Gemfile +2 -0
- data/Rakefile +10 -0
- data/bin/stuffed +5 -0
- data/lib/stuffed.rb +6 -0
- data/lib/stuffed/cli.rb +105 -0
- data/lib/stuffed/stuff.rb +230 -0
- data/spec/cli_spec.rb +160 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/stuff_spec.rb +231 -0
- data/stuffed.gemspec +17 -0
- metadata +103 -0
data/Gemfile
ADDED
data/Rakefile
ADDED
data/bin/stuffed
ADDED
data/lib/stuffed.rb
ADDED
data/lib/stuffed/cli.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'stuffed'
|
2
|
+
|
3
|
+
module Stuffed
|
4
|
+
class CLI
|
5
|
+
|
6
|
+
attr_accessor :out, :args, :hosts_path
|
7
|
+
|
8
|
+
def initialize(out = STDOUT, hosts_path = "/etc/hosts")
|
9
|
+
@out = out
|
10
|
+
@hosts_path = hosts_path
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse(args = ARGV)
|
14
|
+
@args = args
|
15
|
+
command = @args[0]
|
16
|
+
case command
|
17
|
+
when "add"
|
18
|
+
add
|
19
|
+
when "remove"
|
20
|
+
remove
|
21
|
+
when "list"
|
22
|
+
list
|
23
|
+
when "on"
|
24
|
+
on
|
25
|
+
when "off"
|
26
|
+
off
|
27
|
+
else
|
28
|
+
out.puts <<-eos
|
29
|
+
USAGE: stuffed <task>
|
30
|
+
|
31
|
+
The stuffed tasks are:
|
32
|
+
add <site> Add a site to the block list
|
33
|
+
remove <site> Remove a site from the block list
|
34
|
+
list List all sites being blocked
|
35
|
+
on Toggle blocking on
|
36
|
+
off Toggle blocking off
|
37
|
+
eos
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def add
|
42
|
+
if @args[1]
|
43
|
+
|
44
|
+
begin
|
45
|
+
backup_hosts_file
|
46
|
+
Stuffed::Stuff.new(@hosts_path).add(@args[1])
|
47
|
+
out.puts "Successfully added #{@args[1]}"
|
48
|
+
rescue Errno::EACCES
|
49
|
+
out.puts "Use 'sudo stuffed <task>'"
|
50
|
+
rescue Exception => e
|
51
|
+
out.puts e.message
|
52
|
+
end
|
53
|
+
|
54
|
+
else
|
55
|
+
out.puts "Which site do you want to add to the blocked list"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def remove
|
60
|
+
if @args[1]
|
61
|
+
|
62
|
+
begin
|
63
|
+
backup_hosts_file
|
64
|
+
Stuffed::Stuff.new(@hosts_path).remove(@args[1])
|
65
|
+
out.puts "Successfully removed #{@args[1]}."
|
66
|
+
rescue Errno::EACCES
|
67
|
+
out.puts "Use 'sudo stuffed <task>'"
|
68
|
+
rescue Exception => e
|
69
|
+
out.puts e.message
|
70
|
+
end
|
71
|
+
|
72
|
+
else
|
73
|
+
out.puts "Which site do you want to remove from the blocked list"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def list
|
78
|
+
out.puts Stuffed::Stuff.new(@hosts_path).list
|
79
|
+
end
|
80
|
+
|
81
|
+
def on
|
82
|
+
backup_hosts_file
|
83
|
+
Stuffed::Stuff.new(@hosts_path).on
|
84
|
+
out.puts "Sites are now being stuffed."
|
85
|
+
rescue Errno::EACCES
|
86
|
+
out.puts "Use 'sudo stuffed <task>'"
|
87
|
+
end
|
88
|
+
|
89
|
+
def off
|
90
|
+
backup_hosts_file
|
91
|
+
Stuffed::Stuff.new(@hosts_path).off
|
92
|
+
out.puts "Blocking has been temporarily turned off."
|
93
|
+
rescue Errno::EACCES
|
94
|
+
out.puts "Use 'sudo stuffed <task>'"
|
95
|
+
end
|
96
|
+
|
97
|
+
def backup_hosts_file
|
98
|
+
backup_path = @hosts_path + ".backup"
|
99
|
+
if !File.exists?(backup_path)
|
100
|
+
hosts_data = File.read(@hosts_path)
|
101
|
+
File.open(backup_path, "w") {|file| file.write hosts_data}
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
module Stuffed
|
4
|
+
class Stuff
|
5
|
+
|
6
|
+
attr_accessor :hosts_path
|
7
|
+
|
8
|
+
def initialize(hosts_path = "/etc/hosts")
|
9
|
+
@hosts_path = hosts_path
|
10
|
+
@on_state = is_stuffed_on?
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(site)
|
14
|
+
|
15
|
+
raise "#{site} is already being blocked." if already_blocked site
|
16
|
+
|
17
|
+
s1, s2 = site_variations site
|
18
|
+
|
19
|
+
add_block_section if !has_block_list?
|
20
|
+
|
21
|
+
insert_sites_into_block_list s1, s2
|
22
|
+
|
23
|
+
flush
|
24
|
+
end
|
25
|
+
|
26
|
+
def remove(site)
|
27
|
+
|
28
|
+
raise "#{site} is not currently being blocked." if !already_blocked(site) || !has_block_list?
|
29
|
+
|
30
|
+
s1, s2 = site_variations(site)
|
31
|
+
|
32
|
+
remove_sites_from_block_list s1, s2
|
33
|
+
|
34
|
+
remove_block_section if stuffed_section_empty?
|
35
|
+
|
36
|
+
flush
|
37
|
+
end
|
38
|
+
|
39
|
+
def list
|
40
|
+
if stuffed_section_empty?
|
41
|
+
"You aren't currently blocking any sites."
|
42
|
+
else
|
43
|
+
sites = get_block_list.split("\n")
|
44
|
+
|
45
|
+
address = @on_state ? "# 127.0.0.1 " : "127.0.0.1 "
|
46
|
+
|
47
|
+
sites.map! do |site|
|
48
|
+
site.sub address, ""
|
49
|
+
end
|
50
|
+
|
51
|
+
"Blocked sites:\n" + sites.join("\n") + "\n"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def on
|
56
|
+
if !stuffed_section_empty?
|
57
|
+
block_list = get_block_list
|
58
|
+
block_list.gsub! /# /, ""
|
59
|
+
rewrite_block_list block_list
|
60
|
+
|
61
|
+
flush
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def off
|
66
|
+
if @on_state || !stuffed_section_empty?
|
67
|
+
block_list = get_block_list
|
68
|
+
sites = block_list.split "\n"
|
69
|
+
sites.map! do |site|
|
70
|
+
site.include?("#") ? site : "# " + site
|
71
|
+
end
|
72
|
+
|
73
|
+
rewrite_block_list(sites.join("\n") + "\n")
|
74
|
+
|
75
|
+
flush
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def flush
|
80
|
+
if os_is_mac?
|
81
|
+
if os_is_lion_or_greater?
|
82
|
+
system( "killall -HUP mDNSResponder" )
|
83
|
+
else
|
84
|
+
system( "dscacheutil -flushcache" )
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def already_blocked(site)
|
92
|
+
hosts_file_contains? site
|
93
|
+
end
|
94
|
+
|
95
|
+
def site_variations(site)
|
96
|
+
s1 = site
|
97
|
+
s2 = is_www(site) ? rm_www(site) : add_www(site)
|
98
|
+
[s1, s2]
|
99
|
+
end
|
100
|
+
|
101
|
+
def is_www(site)
|
102
|
+
site =~ /www./
|
103
|
+
end
|
104
|
+
|
105
|
+
def add_www(site)
|
106
|
+
"www." + site
|
107
|
+
end
|
108
|
+
|
109
|
+
def rm_www(site)
|
110
|
+
site.gsub "www.", ""
|
111
|
+
end
|
112
|
+
|
113
|
+
def has_block_list?
|
114
|
+
hosts_file_contains? "# Stuffed Section"
|
115
|
+
end
|
116
|
+
|
117
|
+
def hosts_file_contains?(string)
|
118
|
+
open(@hosts_path).grep(Regexp.new string).length > 0
|
119
|
+
end
|
120
|
+
|
121
|
+
def add_block_section
|
122
|
+
file = File.open(@hosts_path, "a")
|
123
|
+
file.puts ""
|
124
|
+
file.puts "# Stuffed Section"
|
125
|
+
file.puts "# End Stuffed Section"
|
126
|
+
file.close
|
127
|
+
end
|
128
|
+
|
129
|
+
def remove_block_section
|
130
|
+
top = get_top_text
|
131
|
+
top.sub! "# Stuffed Section\n", ""
|
132
|
+
bottom = get_bottom_text
|
133
|
+
bottom.sub! "# End Stuffed Section\n", ""
|
134
|
+
|
135
|
+
File.open(@hosts_path, "w") do |file|
|
136
|
+
file.write top
|
137
|
+
file.write bottom
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def insert_sites_into_block_list(s1, s2)
|
142
|
+
address = @on_state ? "# 127.0.0.1 " : "127.0.0.1 "
|
143
|
+
add_to_block_list(address + s1 + "\n")
|
144
|
+
add_to_block_list(address + s2 + "\n")
|
145
|
+
end
|
146
|
+
|
147
|
+
def is_stuffed_on?
|
148
|
+
if has_block_list?
|
149
|
+
get_block_list.include? "#"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def remove_sites_from_block_list(s1, s2)
|
154
|
+
block_list = get_block_list
|
155
|
+
address = @on_state ? "# 127.0.0.1 " : "127.0.0.1 "
|
156
|
+
remove_from_block_list(address + s1 + "\n")
|
157
|
+
remove_from_block_list(address + s2 + "\n")
|
158
|
+
end
|
159
|
+
|
160
|
+
def add_to_block_list(string)
|
161
|
+
block_list = get_block_list
|
162
|
+
block_list += string
|
163
|
+
rewrite_block_list block_list
|
164
|
+
end
|
165
|
+
|
166
|
+
def remove_from_block_list(string)
|
167
|
+
block_list = get_block_list
|
168
|
+
block_list.sub! string, ""
|
169
|
+
rewrite_block_list block_list
|
170
|
+
end
|
171
|
+
|
172
|
+
def get_top_text
|
173
|
+
text = File.read(@hosts_path)
|
174
|
+
if toptext = text.match(/.*# Stuffed Section\n/m)
|
175
|
+
toptext[0]
|
176
|
+
else
|
177
|
+
""
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def get_bottom_text
|
182
|
+
text = File.read(@hosts_path)
|
183
|
+
if toptext = text.match(/# End Stuffed Section\n.*/m)
|
184
|
+
toptext[0]
|
185
|
+
else
|
186
|
+
""
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def get_block_list
|
191
|
+
text = File.read(@hosts_path)
|
192
|
+
text.gsub! /.*# Stuffed Section\n/m, ""
|
193
|
+
text.gsub! /# End Stuffed Section\n.*/m, ""
|
194
|
+
text
|
195
|
+
end
|
196
|
+
|
197
|
+
def rewrite_block_list(string)
|
198
|
+
top_text = get_top_text
|
199
|
+
bottom_text = get_bottom_text
|
200
|
+
File.open(@hosts_path, "w") do |file|
|
201
|
+
file.write top_text
|
202
|
+
file.write string
|
203
|
+
file.write bottom_text
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def line_includes_sites?(line, *args)
|
208
|
+
args.each do |a|
|
209
|
+
return true if line.include? a
|
210
|
+
end
|
211
|
+
return false
|
212
|
+
end
|
213
|
+
|
214
|
+
def stuffed_section_empty?
|
215
|
+
block_list = get_block_list
|
216
|
+
block_list.strip!
|
217
|
+
block_list.empty?
|
218
|
+
end
|
219
|
+
|
220
|
+
def os_is_mac?
|
221
|
+
RUBY_PLATFORM.match(/darwin/) ? true : false
|
222
|
+
end
|
223
|
+
|
224
|
+
def os_is_lion_or_greater?
|
225
|
+
version = RUBY_PLATFORM.match(/darwin(.*)/)[1]
|
226
|
+
major_version = version.split(".")[0]
|
227
|
+
major_version.to_i >= 11
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'stuffed/cli'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Stuffed::CLI do
|
5
|
+
include StuffedSpecHelpers
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@tempfile = Tempfile.new('hosts')
|
9
|
+
@tempfile.close
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:each) do
|
13
|
+
@tempfile.unlink
|
14
|
+
end
|
15
|
+
|
16
|
+
it "displays usage info if no command is passed" do
|
17
|
+
|
18
|
+
stuffed("", @tempfile.path).should == <<-eos
|
19
|
+
USAGE: stuffed <task>
|
20
|
+
|
21
|
+
The stuffed tasks are:
|
22
|
+
add <site> Add a site to the block list
|
23
|
+
remove <site> Remove a site from the block list
|
24
|
+
list List all sites being blocked
|
25
|
+
on Toggle blocking on
|
26
|
+
off Toggle blocking off
|
27
|
+
eos
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#add" do
|
31
|
+
|
32
|
+
it "gives an error if no command is passed" do
|
33
|
+
|
34
|
+
stuffed("add", @tempfile.path).should == "Which site do you want to add to the blocked list\n"
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
it "tells you the site got added" do
|
39
|
+
|
40
|
+
stuffed("add alexmarchant.com", @tempfile.path).should == "Successfully added alexmarchant.com\n"
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
it "tells you if the site already added" do
|
45
|
+
|
46
|
+
stuffed("add alexmarchant.com", @tempfile.path)
|
47
|
+
stuffed("add alexmarchant.com", @tempfile.path).should == "alexmarchant.com is already being blocked.\n"
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
it "tells the user to use sudo if priveledges are insufficient to modify hosts" do
|
52
|
+
|
53
|
+
File.chmod 0007, @tempfile
|
54
|
+
|
55
|
+
stuffed("add alexmarchant.com", @tempfile.path).should == "Use 'sudo stuffed <task>'\n"
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#remove" do
|
61
|
+
|
62
|
+
it "gives an error if no command is passed" do
|
63
|
+
|
64
|
+
stuffed("remove", @tempfile.path).should == "Which site do you want to remove from the blocked list\n"
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
it "tells you the site got removed" do
|
69
|
+
|
70
|
+
stuffed("add alexmarchant.com", @tempfile.path)
|
71
|
+
stuffed("remove alexmarchant.com", @tempfile.path).should == "Successfully removed alexmarchant.com.\n"
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
it "tells you if the site is not available to remove" do
|
76
|
+
|
77
|
+
stuffed("remove alexmarchant.com", @tempfile.path).should == "alexmarchant.com is not currently being blocked.\n"
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
it "tells the user to use sudo if priveledges are insufficient to modify hosts" do
|
82
|
+
|
83
|
+
File.chmod 0007, @tempfile
|
84
|
+
|
85
|
+
stuffed("remove alexmarchant.com", @tempfile.path).should == "Use 'sudo stuffed <task>'\n"
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#list" do
|
91
|
+
|
92
|
+
it "lists all blocked sites" do
|
93
|
+
|
94
|
+
stuffed("add alexmarchant.com", @tempfile.path)
|
95
|
+
stuffed("list", @tempfile.path).should == "Blocked sites:\nalexmarchant.com\nwww.alexmarchant.com\n"
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when the list is empty" do
|
100
|
+
|
101
|
+
it "says the list is empty" do
|
102
|
+
|
103
|
+
stuffed("list", @tempfile.path).should == "You aren't currently blocking any sites.\n"
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "#on" do
|
110
|
+
|
111
|
+
it "gives feedback" do
|
112
|
+
|
113
|
+
stuffed("on", @tempfile.path).should == "Sites are now being stuffed.\n"
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
it "tells the user to use sudo if priveledges are insufficient to modify hosts" do
|
118
|
+
|
119
|
+
File.chmod 0007, @tempfile
|
120
|
+
|
121
|
+
stuffed("remove alexmarchant.com", @tempfile.path).should == "Use 'sudo stuffed <task>'\n"
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#off" do
|
127
|
+
|
128
|
+
it "gives a status message" do
|
129
|
+
|
130
|
+
stuffed("off", @tempfile.path).should == "Blocking has been temporarily turned off.\n"
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
it "tells the user to use sudo if priveledges are insufficient to modify hosts" do
|
135
|
+
|
136
|
+
File.chmod 0007, @tempfile
|
137
|
+
|
138
|
+
stuffed("remove alexmarchant.com", @tempfile.path).should == "Use 'sudo stuffed <task>'\n"
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "#backup_hosts_file" do
|
144
|
+
|
145
|
+
it "backs up the hosts file if a backup doesn't exist" do
|
146
|
+
|
147
|
+
|
148
|
+
@tempfile.open
|
149
|
+
@tempfile.puts "Orignial hosts file"
|
150
|
+
@tempfile.puts "test data"
|
151
|
+
@tempfile.close
|
152
|
+
hosts_data = File.read(@tempfile)
|
153
|
+
|
154
|
+
backup_path = @tempfile.path + ".backup"
|
155
|
+
stuffed("add alexmarchant.com", @tempfile.path)
|
156
|
+
File.read(backup_path).should == hosts_data
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib', )
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rspec'
|
5
|
+
require 'pry'
|
6
|
+
|
7
|
+
module StuffedSpecHelpers
|
8
|
+
def stuffed(args, hosts_path)
|
9
|
+
out = StringIO.new
|
10
|
+
Stuffed::CLI.new(out, hosts_path).parse(args.split(/\s+/))
|
11
|
+
out.rewind
|
12
|
+
out.read
|
13
|
+
rescue SystemExit
|
14
|
+
out.rewind
|
15
|
+
out.read
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Kernel
|
20
|
+
def system(cmd)
|
21
|
+
"call #{cmd}"
|
22
|
+
end
|
23
|
+
end
|
data/spec/stuff_spec.rb
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
require 'stuffed/stuff'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
describe Stuffed::Stuff do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@tempfile = Tempfile.new('hosts')
|
9
|
+
@tempfile.close
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:each) do
|
13
|
+
@tempfile.unlink
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#add" do
|
17
|
+
|
18
|
+
it "adds the site to the hosts file" do
|
19
|
+
|
20
|
+
Stuffed::Stuff.new(@tempfile.path).add("alexmarchant.com")
|
21
|
+
@tempfile.open.grep(/alexmarchant.com/).length.should > 0
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
it "adds the corresponding www/no-www site to the hosts file" do
|
26
|
+
|
27
|
+
Stuffed::Stuff.new(@tempfile.path).add("alexmarchant.com")
|
28
|
+
@tempfile.open.grep(/www.alexmarchant.com/).length.should > 0
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when this entry already exists" do
|
33
|
+
|
34
|
+
it "raises an exception" do
|
35
|
+
|
36
|
+
Stuffed::Stuff.new(@tempfile.path).add("alexmarchant.com")
|
37
|
+
lambda{Stuffed::Stuff.new(@tempfile.path).add("alexmarchant.com")}.should raise_error(RuntimeError, 'alexmarchant.com is already being blocked.')
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when the stuffed section does not exist" do
|
43
|
+
|
44
|
+
it "creates a stuffed section" do
|
45
|
+
|
46
|
+
Stuffed::Stuff.new(@tempfile.path).add("alexmarchant.com")
|
47
|
+
@tempfile.open.grep(/# Stuffed Section/).length.should > 0
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when stuffed is off" do
|
53
|
+
|
54
|
+
it "comments out sites before adding them" do
|
55
|
+
|
56
|
+
@tempfile.open
|
57
|
+
@tempfile.puts "# Stuffed Section"
|
58
|
+
@tempfile.puts "# 127.0.0.1 alexmarchant.com"
|
59
|
+
@tempfile.puts "# 127.0.0.1 www.alexmarchant.com"
|
60
|
+
@tempfile.puts "# End Stuffed Section"
|
61
|
+
@tempfile.close
|
62
|
+
|
63
|
+
Stuffed::Stuff.new(@tempfile.path).add("facebook.com")
|
64
|
+
@tempfile.open.grep(/facebook\.com/)[0].should == "# 127.0.0.1 facebook.com\n"
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
describe "#remove" do
|
72
|
+
|
73
|
+
it "removes the site from the hosts file" do
|
74
|
+
|
75
|
+
@tempfile.open
|
76
|
+
@tempfile.puts "# Stuffed Section"
|
77
|
+
@tempfile.puts "127.0.0.1 alexmarchant.com"
|
78
|
+
@tempfile.puts "127.0.0.1 www.alexmarchant.com"
|
79
|
+
@tempfile.puts "# End Stuffed Section"
|
80
|
+
@tempfile.close
|
81
|
+
|
82
|
+
Stuffed::Stuff.new(@tempfile.path).remove("alexmarchant.com")
|
83
|
+
open(@tempfile).grep(/alexmarchant.com/).length.should == 0
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
it "removes the corresponding www/no-www site to the hosts file" do
|
88
|
+
|
89
|
+
@tempfile.open
|
90
|
+
@tempfile.puts "# Stuffed Section"
|
91
|
+
@tempfile.puts "# 127.0.0.1 alexmarchant.com"
|
92
|
+
@tempfile.puts "# 127.0.0.1 www.alexmarchant.com"
|
93
|
+
@tempfile.puts "# End Stuffed Section"
|
94
|
+
@tempfile.close
|
95
|
+
|
96
|
+
Stuffed::Stuff.new(@tempfile.path).remove("alexmarchant.com")
|
97
|
+
open(@tempfile).grep(/www.alexmarchant.com/).length.should == 0
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
it "only removes the site from the stuffed section" do
|
102
|
+
|
103
|
+
@tempfile.open
|
104
|
+
@tempfile.puts "127.0.0.1 alexmarchant.com"
|
105
|
+
@tempfile.puts "127.0.0.1 www.alexmarchant.com"
|
106
|
+
@tempfile.close
|
107
|
+
|
108
|
+
lambda{Stuffed::Stuff.new(@tempfile.path).remove("alexmarchant.com")}.should raise_error(RuntimeError, 'alexmarchant.com is not currently being blocked.')
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when this entry does not exist" do
|
113
|
+
|
114
|
+
it "raises an exception" do
|
115
|
+
|
116
|
+
lambda{Stuffed::Stuff.new(@tempfile.path).remove("alexmarchant.com")}.should raise_error(RuntimeError, 'alexmarchant.com is not currently being blocked.')
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when the stuffed section exist and we removed the last entry" do
|
122
|
+
|
123
|
+
it "removes the stuffed section" do
|
124
|
+
|
125
|
+
@tempfile.open
|
126
|
+
@tempfile.puts "# Stuffed Section"
|
127
|
+
@tempfile.puts "127.0.0.1 alexmarchant.com"
|
128
|
+
@tempfile.puts "127.0.0.1 www.alexmarchant.com"
|
129
|
+
@tempfile.puts "# End Stuffed Section"
|
130
|
+
@tempfile.close
|
131
|
+
|
132
|
+
Stuffed::Stuff.new(@tempfile.path).remove("alexmarchant.com")
|
133
|
+
open(@tempfile).grep(/# Stuffed Section/).length.should == 0
|
134
|
+
open(@tempfile).grep(/# End Stuffed Section/).length.should == 0
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "#list" do
|
141
|
+
|
142
|
+
it "lists all blocked sites" do
|
143
|
+
|
144
|
+
@tempfile.open
|
145
|
+
@tempfile.puts "# Stuffed Section"
|
146
|
+
@tempfile.puts "127.0.0.1 alexmarchant.com"
|
147
|
+
@tempfile.puts "127.0.0.1 www.alexmarchant.com"
|
148
|
+
@tempfile.puts "# End Stuffed Section"
|
149
|
+
@tempfile.close
|
150
|
+
|
151
|
+
list = Stuffed::Stuff.new(@tempfile.path).list
|
152
|
+
list.should == "Blocked sites:\nalexmarchant.com\nwww.alexmarchant.com\n"
|
153
|
+
|
154
|
+
@tempfile.unlink
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "#on" do
|
159
|
+
|
160
|
+
it "uncomments blocked sites" do
|
161
|
+
|
162
|
+
@tempfile.open
|
163
|
+
@tempfile.puts "# Stuffed Section"
|
164
|
+
@tempfile.puts "# 127.0.0.1 alexmarchant.com"
|
165
|
+
@tempfile.puts "# 127.0.0.1 www.alexmarchant.com"
|
166
|
+
@tempfile.puts "# End Stuffed Section"
|
167
|
+
@tempfile.close
|
168
|
+
|
169
|
+
Stuffed::Stuff.new(@tempfile.path).on
|
170
|
+
open(@tempfile).read.should == "# Stuffed Section\n127.0.0.1 alexmarchant.com\n127.0.0.1 www.alexmarchant.com\n# End Stuffed Section\n"
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "#off" do
|
176
|
+
|
177
|
+
it "comments out blocked sites" do
|
178
|
+
|
179
|
+
@tempfile.open
|
180
|
+
@tempfile.puts "# Stuffed Section"
|
181
|
+
@tempfile.puts "127.0.0.1 alexmarchant.com"
|
182
|
+
@tempfile.puts "127.0.0.1 www.alexmarchant.com"
|
183
|
+
@tempfile.puts "# End Stuffed Section"
|
184
|
+
@tempfile.close
|
185
|
+
|
186
|
+
Stuffed::Stuff.new(@tempfile.path).off
|
187
|
+
open(@tempfile).read.should == "# Stuffed Section\n# 127.0.0.1 alexmarchant.com\n# 127.0.0.1 www.alexmarchant.com\n# End Stuffed Section\n"
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
it "doesn't comment out lines a second time" do
|
192
|
+
|
193
|
+
@tempfile.open
|
194
|
+
@tempfile.puts "# Stuffed Section"
|
195
|
+
@tempfile.puts "# 127.0.0.1 alexmarchant.com"
|
196
|
+
@tempfile.puts "# 127.0.0.1 www.alexmarchant.com"
|
197
|
+
@tempfile.puts "# End Stuffed Section"
|
198
|
+
@tempfile.close
|
199
|
+
|
200
|
+
Stuffed::Stuff.new(@tempfile.path).off
|
201
|
+
open(@tempfile).read.should == "# Stuffed Section\n# 127.0.0.1 alexmarchant.com\n# 127.0.0.1 www.alexmarchant.com\n# End Stuffed Section\n"
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe "#flush" do
|
207
|
+
|
208
|
+
context "on mac" do
|
209
|
+
|
210
|
+
context "on Lion and greater" do
|
211
|
+
|
212
|
+
it "calls 'killall -HUP mDNSResponder'" do
|
213
|
+
|
214
|
+
RUBY_PLATFORM = "x86_64-darwin12.2.1"
|
215
|
+
Stuffed::Stuff.new(@tempfile.path).flush.should == "call killall -HUP mDNSResponder"
|
216
|
+
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context "on Snow Leapard and lower" do
|
221
|
+
|
222
|
+
it "calls 'dscacheutil -flushcache'" do
|
223
|
+
|
224
|
+
RUBY_PLATFORM = "x86_64-darwin10.0.0"
|
225
|
+
Stuffed::Stuff.new(@tempfile.path).flush.should == "call dscacheutil -flushcache"
|
226
|
+
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
data/stuffed.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "stuffed"
|
3
|
+
s.version = "0.1.0"
|
4
|
+
s.date = "2013-05-07"
|
5
|
+
s.summary = "Stuffed blocks websites."
|
6
|
+
s.description = "A simple tool to temporarily block websites."
|
7
|
+
s.authors = ["Alex Marchant"]
|
8
|
+
s.email = "alexjmarchant@gmail.com"
|
9
|
+
s.files = ["bin", "bin/stuffed", "Gemfile", "lib", "lib/stuffed", "lib/stuffed/cli.rb", "lib/stuffed/stuff.rb", "lib/stuffed.rb", "Rakefile", "spec", "spec/cli_spec.rb", "spec/spec_helper.rb", "spec/stuff_spec.rb", "stuffed.gemspec"]
|
10
|
+
s.executables = ["stuffed"]
|
11
|
+
s.require_paths = ["lib"]
|
12
|
+
s.homepage = "http://www.github.com/alexmarchant/stuffed"
|
13
|
+
|
14
|
+
s.add_development_dependency "rake", "~> 0.9"
|
15
|
+
s.add_development_dependency "rspec", "~> 2.11"
|
16
|
+
s.add_development_dependency "pry", "~> 0.9"
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stuffed
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alex Marchant
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.9'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.9'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '2.11'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '2.11'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: pry
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.9'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.9'
|
62
|
+
description: A simple tool to temporarily block websites.
|
63
|
+
email: alexjmarchant@gmail.com
|
64
|
+
executables:
|
65
|
+
- stuffed
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- bin/stuffed
|
70
|
+
- Gemfile
|
71
|
+
- lib/stuffed/cli.rb
|
72
|
+
- lib/stuffed/stuff.rb
|
73
|
+
- lib/stuffed.rb
|
74
|
+
- Rakefile
|
75
|
+
- spec/cli_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
- spec/stuff_spec.rb
|
78
|
+
- stuffed.gemspec
|
79
|
+
homepage: http://www.github.com/alexmarchant/stuffed
|
80
|
+
licenses: []
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 1.8.25
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: Stuffed blocks websites.
|
103
|
+
test_files: []
|