geeklets 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +19 -0
- data/VERSION +1 -1
- data/bin/geeklets +2 -2
- data/lib/Next_Months_Calendar/next_months_calendar.rb +3 -2
- data/lib/OPM_Alerts/opm_alerts.rb +9 -23
- data/lib/Trash_Usage/trash_usage.rb +3 -2
- data/lib/VRE_Alerts/vre_alerts.rb +23 -43
- data/lib/WMATA_Alerts/wmata_alerts.rb +37 -58
- data/lib/configurable.rb +68 -0
- data/lib/configuration_required_error.rb +3 -0
- data/lib/geeklet.rb +39 -0
- data/lib/geeklets.rb +38 -28
- data/lib/unregistered_config_value_error.rb +3 -0
- data/spec/Next_Months_Calendar/next_months_calendar_spec.rb +41 -0
- data/spec/Trash_Usage/trash_usage_spec.rb +25 -0
- data/spec/configurable_spec.rb +72 -0
- data/spec/geeklet_spec.rb +65 -0
- data/spec/geeklets_spec.rb +191 -6
- data/spec/spec_helper.rb +0 -1
- metadata +15 -3
data/History.txt
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
=== 0.0.7
|
2
|
+
* updated WMATA_Alerts to use configurable values
|
3
|
+
* updated VRE_Alerts to use configurable values
|
4
|
+
* updated OPM_Alerts to use configurable values
|
5
|
+
* show_help fixed for some scripts
|
6
|
+
* show_help shows defaulted params and options
|
7
|
+
* added command line overrides of configuration values
|
8
|
+
* moved configuration into a module
|
9
|
+
* added basic configuration and tests.
|
10
|
+
* added tests for base class.
|
11
|
+
* added base class for all Geeklet scripts.
|
12
|
+
* added tests for the main geeklet engine
|
13
|
+
* added tests for Next_Months_Calendar script
|
14
|
+
* added tests for Trash_Usage script
|
15
|
+
|
16
|
+
=== 0.0.6 2010-04-10
|
17
|
+
|
18
|
+
* updated the dependencies in the gemspec
|
19
|
+
|
1
20
|
=== 0.0.2 2010-02-07
|
2
21
|
|
3
22
|
* Added weather script from Ted Wise.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.7
|
data/bin/geeklets
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
class Next_Months_Calendar
|
1
|
+
class Next_Months_Calendar < Geeklet
|
2
2
|
|
3
3
|
def run(params)
|
4
|
+
super(:Next_Months_Calendar, params)
|
4
5
|
today = Date.today
|
5
6
|
nextmonth = today >> 1
|
6
|
-
system("cal","#{nextmonth.month}","#{nextmonth.year}")
|
7
|
+
Kernel.system("cal","#{nextmonth.month}","#{nextmonth.year}")
|
7
8
|
end
|
8
9
|
|
9
10
|
end
|
@@ -3,33 +3,18 @@ require 'rubygems'
|
|
3
3
|
require 'open-uri'
|
4
4
|
require 'nokogiri'
|
5
5
|
|
6
|
-
class OPM_Alerts
|
7
|
-
URL
|
6
|
+
class OPM_Alerts < Geeklet
|
7
|
+
registerConfiguration :OPM_Alerts, :URL, :default => "http://www.opm.gov/status/index.aspx", :description => "OPM website URL", :type => :string
|
8
|
+
registerConfiguration :OPM_Alerts, :width, :default => 40, :description => "Word wrap width", :type => :int
|
8
9
|
|
9
|
-
def
|
10
|
-
|
11
|
-
opm-status
|
12
|
-
|
13
|
-
USAGE:
|
14
|
-
|
15
|
-
\topm-status [wrapping-width]
|
16
|
-
|
17
|
-
Returns U.S. Office of Personnel Management status Alerts.
|
18
|
-
|
19
|
-
[wrapping-width] is an integer to limit the width of the descriptions
|
20
|
-
Defaults to: 40
|
21
|
-
|
22
|
-
EOS
|
23
|
-
|
24
|
-
exit
|
10
|
+
def description
|
11
|
+
"Returns U.S. Office of Personnel Management status Alerts."
|
25
12
|
end
|
26
13
|
|
27
14
|
def run(params)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
doc = Nokogiri::HTML(open(URL))
|
15
|
+
super(:OPM_Alerts, params)
|
16
|
+
|
17
|
+
doc = Nokogiri::HTML(open(configurableValue(:OPM_Alerts, :URL)))
|
33
18
|
|
34
19
|
date_str = doc.css('#_ctl0__ctl0_DisplayDateSpan').text.strip
|
35
20
|
begin
|
@@ -52,6 +37,7 @@ EOS
|
|
52
37
|
status = "Not found" if status.length == 0
|
53
38
|
|
54
39
|
# display results
|
40
|
+
width = configurableValue(:OPM_Alerts, :width)
|
55
41
|
puts Utility.wrap_text("#{date_str} - #{title}", width, date_str.length + 3, :outdent)
|
56
42
|
puts "-" * width
|
57
43
|
puts Utility.wrap_text(status, width)
|
@@ -3,40 +3,25 @@ require 'rubygems'
|
|
3
3
|
require 'chronic'
|
4
4
|
require 'mechanize'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
USAGE:
|
16
|
-
|
17
|
-
\tvre-alert [rail_lines] [wrapping-width] [specific-date]
|
18
|
-
|
19
|
-
Returns Virgina Railway Express (VRE) Alerts.
|
20
|
-
|
21
|
-
[rail_lines] specifies which rail lines you want alerts for.
|
22
|
-
Can be:
|
23
|
-
\tfredericsburg - for the Fredericsburg line
|
24
|
-
\tmanassas - for the Manassas line
|
25
|
-
\tboth - for both lines.
|
26
|
-
Defaults to: both
|
6
|
+
class VRE_Alerts < Geeklet
|
7
|
+
registerConfiguration :VRE_Alerts, :URL, :default => "http://www.vre.org/service/daily-download.html", :description => "VRE website URL", :type => :string
|
8
|
+
registerConfiguration :VRE_Alerts, :lines, :default => "both", :description => "Which rail line. (manassas, fredericksburg, or both)", :type => :string
|
9
|
+
registerConfiguration :VRE_Alerts, :width, :default => 40, :description => "Wrapping width", :type => :int
|
10
|
+
registerConfiguration :VRE_Alerts, :date, :default => "today", :description => "A string parseable by Date::parse which is the date from the VRE daily download to display. NOTE: this does not access history, it only allows you to choose a specific entry from the Daily Download to render.", :type => :string
|
11
|
+
|
12
|
+
def name
|
13
|
+
"VRE_Alerts"
|
14
|
+
end
|
27
15
|
|
28
|
-
|
29
|
-
|
16
|
+
def description
|
17
|
+
"Returns Virgina Railway Express (VRE) Alerts."
|
18
|
+
end
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
EOS
|
38
|
-
|
39
|
-
exit
|
20
|
+
def line(cell_class)
|
21
|
+
case cell_class
|
22
|
+
when "fbg_delay" then :fredericksburg
|
23
|
+
when "mss_delay" then :manassas
|
24
|
+
end
|
40
25
|
end
|
41
26
|
|
42
27
|
# >> notice.search("tr")[2].search("td")[0].attributes["class"].value
|
@@ -68,7 +53,8 @@ class VRE_Alerts
|
|
68
53
|
end
|
69
54
|
|
70
55
|
cell_class = cells[0].attributes["class"].value unless cells[0].text.empty?
|
71
|
-
|
56
|
+
rail_lines = configurableValue(:VRE_Alerts, :lines).to_sym
|
57
|
+
detail[service] << {:line => line(cell_class), :train => cells[0].text, :description => cells[1].text} if rail_lines == :both || rail_lines == line(cell_class)
|
72
58
|
else
|
73
59
|
next
|
74
60
|
end
|
@@ -100,23 +86,17 @@ class VRE_Alerts
|
|
100
86
|
end
|
101
87
|
|
102
88
|
def run(params)
|
103
|
-
|
104
|
-
|
105
|
-
@rail_lines = (params[0] || "both").to_sym
|
106
|
-
width = (params[1] and params[1].to_i) || 40
|
107
|
-
alert_date = (params[2] and Date.parse(params[2])) || Date.today
|
108
|
-
|
109
|
-
#debug - set a date of interest, and rail line of interest
|
110
|
-
# alert_date = Date.civil(2010, 1, 13)
|
111
|
-
# @rail_lines = :fredericksburg
|
89
|
+
super(:VRE_Alerts, params)
|
112
90
|
|
113
91
|
agent = Mechanize.new
|
114
|
-
agent.get(
|
92
|
+
agent.get(configurableValue(:VRE_Alerts, :URL))
|
115
93
|
notices = agent.page.search(".format").map{ |notice| parse_notice(notice) }
|
116
94
|
|
117
95
|
#debug
|
118
96
|
#puts notices.to_yaml
|
119
97
|
|
98
|
+
width = configurableValue(:VRE_Alerts, :width)
|
99
|
+
alert_date = configurableValue(:VRE_Alerts, :date)
|
120
100
|
render_notice(notices.select{ |notice| notice[:date] == alert_date }.shift, width)
|
121
101
|
end
|
122
102
|
|
@@ -5,86 +5,65 @@ require 'open-uri'
|
|
5
5
|
require 'chronic'
|
6
6
|
require 'htmlentities'
|
7
7
|
|
8
|
-
class WMATA_Alerts
|
8
|
+
class WMATA_Alerts < Geeklet
|
9
|
+
registerConfiguration :WMATA_Alerts, :URL, :default => "http://www.wmata.com/rider_tools/metro_service_status/feeds/rail.xml", :description => "WMATA website URL", :type => :string
|
10
|
+
registerConfiguration :WMATA_Alerts, :width, :default => 40, :description => "Wrapping width", :type => :int
|
11
|
+
registerConfiguration :WMATA_Alerts, :history, :default => "7 days ago", :description => "how many days of feed history to display. Can be anything parseable by Chronic gem.", :type => :string
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
["p.m.", "pm"],
|
13
|
-
["a.m.", "am"]
|
14
|
-
]
|
15
|
-
|
16
|
-
FEED_URL = "http://www.wmata.com/rider_tools/metro_service_status/feeds/rail.xml"
|
17
|
-
|
18
|
-
def die
|
19
|
-
puts <<-EOS
|
20
|
-
metro-feed
|
21
|
-
|
22
|
-
USAGE:
|
23
|
-
|
24
|
-
\tmetro-feed [history] [wrapping-width]
|
25
|
-
|
26
|
-
Returns WMATA feed information for metro lines.
|
27
|
-
|
28
|
-
[history] is how many days of feed history to display.
|
29
|
-
\tdefaults to 7 days. Can be anything parseable by Chronic gem
|
30
|
-
|
31
|
-
[wrapping-width] is the limit to how wide the text can be
|
32
|
-
\tdefaults to 40 characters. should be a positive integer value.
|
33
|
-
|
34
|
-
Requires gems: chronic, htmlentities
|
35
|
-
|
36
|
-
|
37
|
-
EOS
|
38
|
-
|
39
|
-
exit
|
13
|
+
def name
|
14
|
+
"WMATA_Alerts"
|
40
15
|
end
|
41
|
-
|
16
|
+
|
17
|
+
def description
|
18
|
+
"Returns WMATA feed information for metro lines."
|
19
|
+
end
|
20
|
+
|
21
|
+
def translate(message)
|
22
|
+
[
|
23
|
+
["p.m.", "pm"],
|
24
|
+
["a.m.", "am"]
|
25
|
+
].each { |r| message.gsub!(r[0], r[1]) }
|
26
|
+
message
|
27
|
+
end
|
28
|
+
|
42
29
|
def run(params)
|
30
|
+
super(:WMATA_Alerts, params)
|
43
31
|
|
44
|
-
|
32
|
+
rss_content = ""
|
45
33
|
|
46
|
-
|
47
|
-
|
48
|
-
@width = @width.to_s.to_i
|
49
|
-
|
50
|
-
@cutoff = Chronic.parse(@cutoff_string)
|
51
|
-
|
52
|
-
@rss_content = ""
|
53
|
-
|
54
|
-
open(FEED_URL) do |f|
|
55
|
-
@rss_content = f.read
|
34
|
+
open(configurableValue(:WMATA_Alerts, :URL)) do |f|
|
35
|
+
rss_content = f.read
|
56
36
|
end
|
57
37
|
|
58
|
-
|
38
|
+
rss = RSS::Parser.parse(rss_content, false)
|
59
39
|
|
60
|
-
|
40
|
+
item_hash = {}
|
61
41
|
|
62
42
|
# filter down to the items we want.
|
63
|
-
|
64
|
-
|
43
|
+
rss.items.each do |item|
|
44
|
+
item_hash[item.pubDate] = item unless item.pubDate < Chronic.parse(configurableValue(:WMATA_Alerts, :history))
|
65
45
|
end
|
66
46
|
|
67
|
-
if
|
47
|
+
if item_hash.empty?
|
68
48
|
puts "No data from WMATA feed."
|
69
49
|
else
|
70
|
-
|
71
|
-
|
72
|
-
item =
|
50
|
+
coder = HTMLEntities.new
|
51
|
+
item_hash.keys.sort.reverse.each do |key|
|
52
|
+
item = item_hash[key]
|
73
53
|
|
74
54
|
title = "#{item.pubDate.strftime('%x')} - #{item.title}"
|
75
55
|
puts title
|
76
56
|
puts ("-" * title.length)
|
77
57
|
|
78
|
-
message =
|
79
|
-
|
80
|
-
message = message.gsub(r[0], r[1])
|
81
|
-
end
|
58
|
+
message = coder.decode(item.description)
|
59
|
+
message = translate(message)
|
82
60
|
subject, *body = message.split(".")
|
83
61
|
|
84
|
-
|
62
|
+
width = configurableValue(:WMATA_Alerts, :width)
|
63
|
+
puts Utility.wrap_text(subject + "...", width)
|
85
64
|
body.each do |sentence|
|
86
|
-
puts Utility.wrap_text(sentence+".",
|
87
|
-
end
|
65
|
+
puts Utility.wrap_text(sentence + ".", width, 3, :all)
|
66
|
+
end
|
88
67
|
|
89
68
|
puts
|
90
69
|
end
|
data/lib/configurable.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'unregistered_config_value_error'
|
2
|
+
require 'configuration_required_error'
|
3
|
+
require 'trollop'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
module Configurable
|
7
|
+
|
8
|
+
# configurations should be a hash of hashes, where the first key is the calculator type, and the second key is the tag
|
9
|
+
def configurations
|
10
|
+
@@configuration ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def isHelp?(param)
|
14
|
+
param.to_s.downcase == 'help'
|
15
|
+
end
|
16
|
+
|
17
|
+
def configurableValue(group, key)
|
18
|
+
raise UnregisteredConfigValueError unless configurations.include?(group)
|
19
|
+
raise UnregisteredConfigValueError unless configurations[group].include?(key)
|
20
|
+
value = configurations[group][key][:override] || configurations[group][key][:stored] || configurations[group][key][:default]
|
21
|
+
raise ConfigurationRequiredError unless value
|
22
|
+
value
|
23
|
+
end
|
24
|
+
|
25
|
+
def registerConfiguration(group, key, options = {})
|
26
|
+
configurations[group] ||= {}
|
27
|
+
configurations[group][key] = options
|
28
|
+
end
|
29
|
+
|
30
|
+
def command_parser(group)
|
31
|
+
groupConfigs = configurations[group]
|
32
|
+
return unless groupConfigs #if there are no configs defined, there is nothing to do.
|
33
|
+
|
34
|
+
parser = Trollop::Parser.new do
|
35
|
+
groupConfigs.each do |key, options|
|
36
|
+
# our concept of a default is different from trollop's, so remove any default key and value
|
37
|
+
defaultValue = options[:stored] || options[:default]
|
38
|
+
if defaultValue
|
39
|
+
opt key, options[:description], options.merge({ :default => defaultValue })
|
40
|
+
else
|
41
|
+
opt key, options[:description], options
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_overrides(group, params)
|
48
|
+
return if (params.nil? || params.empty?) # nothing to do in this case
|
49
|
+
raise Trollop::HelpNeeded if isHelp?(params[0])
|
50
|
+
|
51
|
+
groupConfigs = configurations[group]
|
52
|
+
trollop_opts = command_parser(group).parse(params)
|
53
|
+
trollop_opts.each do |key, value|
|
54
|
+
groupConfigs[key][:override] = value if groupConfigs.key?(key)
|
55
|
+
end
|
56
|
+
|
57
|
+
# puts "trollop opts:"
|
58
|
+
# puts trollop_opts.to_yaml
|
59
|
+
# puts
|
60
|
+
# puts "group configs:"
|
61
|
+
# puts groupConfigs.to_yaml
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.included(base)
|
65
|
+
base.extend(Configurable)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/lib/geeklet.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'configurable'
|
2
|
+
|
3
|
+
class Geeklet
|
4
|
+
include Configurable
|
5
|
+
|
6
|
+
|
7
|
+
def name
|
8
|
+
self.class.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
def description
|
12
|
+
"No description specified for this geeklet."
|
13
|
+
end
|
14
|
+
|
15
|
+
def show_help(group)
|
16
|
+
parser = command_parser(group)
|
17
|
+
Kernel.puts(
|
18
|
+
<<-EOS
|
19
|
+
Geeklet: #{name}
|
20
|
+
|
21
|
+
Description: #{description}
|
22
|
+
|
23
|
+
EOS
|
24
|
+
)
|
25
|
+
parser.educate
|
26
|
+
end
|
27
|
+
|
28
|
+
def run(group, params)
|
29
|
+
begin
|
30
|
+
add_overrides(group, params)
|
31
|
+
rescue => e
|
32
|
+
show_help(group)
|
33
|
+
# Kernel.puts e.inspect
|
34
|
+
Kernel.exit
|
35
|
+
end
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/lib/geeklets.rb
CHANGED
@@ -1,51 +1,61 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
-
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
4
|
require 'pathname'
|
5
5
|
require 'utility'
|
6
|
-
require '
|
6
|
+
require 'geeklet'
|
7
|
+
require 'yaml'
|
7
8
|
|
8
9
|
class Geeklets
|
9
10
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
11
|
+
def initialize(scripts = {})
|
12
|
+
@geeklet_scripts = scripts
|
13
|
+
if @geeklet_scripts.empty?
|
14
|
+
cwd = File.dirname(__FILE__)
|
15
|
+
children = Pathname.new(cwd).children
|
16
|
+
children.reject! { |child| !child.directory? }
|
17
|
+
children.each do |child_dir|
|
18
|
+
geeklet_name = child_dir.basename.to_s
|
19
|
+
geeklet_file = geeklet_name.downcase
|
20
|
+
begin
|
21
|
+
Kernel.require "#{geeklet_name}/#{geeklet_file}"
|
22
|
+
@geeklet_scripts[geeklet_name] = Kernel.eval("#{geeklet_name}.new")
|
23
|
+
rescue => e
|
24
|
+
Kernel.puts "Problem loading #{geeklet_name} geeklet."
|
25
|
+
# Kernel.puts e.inspect
|
26
|
+
# Kernel.puts e.backtrace
|
27
|
+
next
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
13
31
|
end
|
14
32
|
|
15
|
-
def
|
16
|
-
puts "
|
17
|
-
puts
|
18
|
-
script_inventory.each { |script| puts "\t#{script}"}
|
33
|
+
def show_usage
|
34
|
+
puts "Usage: geeklets <geeklet-script> [relevant-parameters-for-script]"
|
19
35
|
puts
|
20
36
|
end
|
21
|
-
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def self.run_geeklet(geeklet, params)
|
30
|
-
require "#{geeklet}/#{geeklet.downcase}"
|
31
|
-
obj = eval("#{geeklet}.new")
|
32
|
-
obj.run(params)
|
37
|
+
|
38
|
+
def show_known_scripts
|
39
|
+
Kernel.puts "These are the currently known geeklet scripts:"
|
40
|
+
Kernel.puts
|
41
|
+
Kernel.puts "There are no defined geeklet scripts." if @geeklet_scripts.empty?
|
42
|
+
@geeklet_scripts.keys.sort.each { |key| Kernel.puts "\t#{key}" }
|
43
|
+
Kernel.puts
|
33
44
|
end
|
34
45
|
|
35
|
-
def
|
36
|
-
if params.empty?
|
46
|
+
def run(params)
|
47
|
+
if params.nil? || params.empty?
|
37
48
|
show_usage
|
38
49
|
show_known_scripts
|
39
50
|
else
|
40
51
|
geeklet = params.shift
|
41
|
-
if
|
42
|
-
|
52
|
+
if @geeklet_scripts.include?(geeklet)
|
53
|
+
@geeklet_scripts[geeklet].run(params)
|
43
54
|
else
|
44
|
-
puts "I do not know how to run the #{geeklet} geeklet."
|
55
|
+
Kernel.puts "I do not know how to run the #{geeklet} geeklet."
|
45
56
|
show_known_scripts
|
46
57
|
end
|
47
58
|
end
|
48
|
-
|
49
59
|
end
|
50
60
|
|
51
|
-
end
|
61
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'Next_Months_Calendar/next_months_calendar'
|
3
|
+
|
4
|
+
describe Next_Months_Calendar do
|
5
|
+
|
6
|
+
before { @script = Next_Months_Calendar.new }
|
7
|
+
|
8
|
+
subject { @script }
|
9
|
+
|
10
|
+
describe "In general" do
|
11
|
+
it { should be_a_kind_of(Geeklet)}
|
12
|
+
end
|
13
|
+
|
14
|
+
describe :run do
|
15
|
+
|
16
|
+
context "when this month is April" do
|
17
|
+
it "should get the calendar for next month" do
|
18
|
+
Date.should_receive(:today).and_return(Date.civil(2010, 4, 26))
|
19
|
+
Kernel.should_receive(:system).with("cal","5","2010")
|
20
|
+
@script.run([])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when this month is December" do
|
25
|
+
it "should get the calendar for next month, in the next year" do
|
26
|
+
Date.should_receive(:today).and_return(Date.civil(2010, 12, 25))
|
27
|
+
Kernel.should_receive(:system).with("cal","1","2011")
|
28
|
+
@script.run([])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when the following month has fewer days" do
|
33
|
+
it "should get the calendar for next month, in the next year" do
|
34
|
+
Date.should_receive(:today).and_return(Date.civil(2010, 1, 31))
|
35
|
+
Kernel.should_receive(:system).with("cal","2","2010")
|
36
|
+
@script.run([])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
require 'Trash_Usage/trash_usage'
|
3
|
+
|
4
|
+
describe Trash_Usage do
|
5
|
+
|
6
|
+
before { @script = Trash_Usage.new }
|
7
|
+
|
8
|
+
subject { @script }
|
9
|
+
|
10
|
+
describe "in general" do
|
11
|
+
it { should be_a_kind_of(Geeklet) }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe :run do
|
15
|
+
|
16
|
+
it "should get the trash usage" do
|
17
|
+
|
18
|
+
Kernel.should_receive(:system).with("du -sh ~/.Trash/ | awk '{print \"Trash is using \"$1}'")
|
19
|
+
|
20
|
+
@script.run([])
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'configurable'
|
3
|
+
|
4
|
+
describe Configurable do
|
5
|
+
|
6
|
+
before do
|
7
|
+
klass = Class.new do
|
8
|
+
include Configurable
|
9
|
+
end
|
10
|
+
@configurable = klass.new
|
11
|
+
end
|
12
|
+
|
13
|
+
describe :configurableValue do
|
14
|
+
|
15
|
+
context "when group not registered" do
|
16
|
+
it "should throw an exception" do
|
17
|
+
lambda { @configurable.configurableValue("no_group", "someUnregisteredKey") }.should raise_exception(UnregisteredConfigValueError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when group is registered but configurable value not registered" do
|
22
|
+
it "should throw an exception" do
|
23
|
+
@configurable.registerConfiguration("group", "someRegisteredKey")
|
24
|
+
lambda { @configurable.configurableValue("group", "someUnregisteredKey") }.should raise_exception(UnregisteredConfigValueError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when configurable value is registered" do
|
29
|
+
|
30
|
+
context "with a default value" do
|
31
|
+
it "should return the default value" do
|
32
|
+
@configurable.registerConfiguration("group", "someRegisteredKey", :default => "some Default Value")
|
33
|
+
@configurable.configurableValue("group", "someRegisteredKey").should == "some Default Value"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "without a default value" do
|
38
|
+
it "should indicate that configuration is necessary" do
|
39
|
+
@configurable.registerConfiguration("group", "someRegisteredKey")
|
40
|
+
lambda { @configurable.configurableValue("group", "someRegisteredKey") }.should raise_exception(ConfigurationRequiredError)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when value is overridden" do
|
45
|
+
it "should return the overridden value" do
|
46
|
+
@configurable.registerConfiguration("group", "someRegisteredKey", :default => "default", :type => :string)
|
47
|
+
@configurable.add_overrides("group", ["-s", "override"])
|
48
|
+
@configurable.configurableValue("group", "someRegisteredKey").should == "override"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
describe :isHelp do
|
59
|
+
|
60
|
+
it "should return true when param is 'help'" do
|
61
|
+
help = ['Help', 'help', "HeLp"]
|
62
|
+
help.each { |param| @configurable.isHelp?(param).should be_true }
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should be false when the param is not 'help'" do
|
66
|
+
not_help = [2, nil, ""]
|
67
|
+
not_help.each { |param| @configurable.isHelp?(param).should be_false }
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'geeklet'
|
3
|
+
|
4
|
+
describe Geeklet do
|
5
|
+
|
6
|
+
before { @geeklet = Geeklet.new }
|
7
|
+
|
8
|
+
subject { @geeklet }
|
9
|
+
|
10
|
+
it { should respond_to :run }
|
11
|
+
|
12
|
+
describe :run do
|
13
|
+
|
14
|
+
context "When params is nil" do
|
15
|
+
subject { @geeklet.run("group", nil)}
|
16
|
+
it { should be_true }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "When params is empty" do
|
20
|
+
subject { @geeklet.run("group", [])}
|
21
|
+
it { should be_true }
|
22
|
+
end
|
23
|
+
|
24
|
+
context "When params has items" do
|
25
|
+
subject { @geeklet.run("group", ["one", 2, "three"])}
|
26
|
+
it { should be_true }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "When params has 'help' as first item" do
|
30
|
+
it "should show help and exit" do
|
31
|
+
@geeklet.should_receive(:show_help)
|
32
|
+
Kernel.should_receive(:exit)
|
33
|
+
|
34
|
+
@geeklet.run("group", ["Help", 2, "4.5"])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
describe :show_help do
|
43
|
+
|
44
|
+
it "should display usage information" do
|
45
|
+
parser = mock("command_parser")
|
46
|
+
@geeklet.should_receive(:command_parser).with("group").and_return(parser)
|
47
|
+
@geeklet.should_receive(:name).and_return("Script Name")
|
48
|
+
@geeklet.should_receive(:description).and_return("Some script description")
|
49
|
+
Kernel.should_receive(:puts).with(
|
50
|
+
<<-EOS
|
51
|
+
Geeklet: Script Name
|
52
|
+
|
53
|
+
Description: Some script description
|
54
|
+
|
55
|
+
EOS
|
56
|
+
)
|
57
|
+
parser.should_receive(:educate)
|
58
|
+
|
59
|
+
@geeklet.show_help("group")
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
data/spec/geeklets_spec.rb
CHANGED
@@ -1,15 +1,200 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'geeklets'
|
2
3
|
|
3
|
-
|
4
|
+
module GeekletExampleHelperMethods
|
5
|
+
def mock_no_scripts
|
6
|
+
mock_cwd = mock("cwd")
|
7
|
+
mock_cwd_pathname = mock("cwd Pathname")
|
8
|
+
mock_children = []
|
4
9
|
|
5
|
-
|
10
|
+
File.should_receive(:dirname).with(any_args()).and_return(mock_cwd)
|
11
|
+
Pathname.should_receive(:new).with(mock_cwd).and_return(mock_cwd_pathname)
|
12
|
+
mock_cwd_pathname.should_receive(:children).and_return(mock_children)
|
13
|
+
mock_children.should_receive(:reject!)
|
14
|
+
|
6
15
|
|
7
|
-
|
16
|
+
geeklets = Geeklets.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def mock_some_scripts_no_problems
|
20
|
+
mock_cwd = mock("cwd")
|
21
|
+
mock_cwd_pathname = mock("cwd Pathname")
|
22
|
+
mock_children = [ mock("Dir1"), mock("Dir2"), mock("Dir3")]
|
23
|
+
mock_children_basenames = ["Dir1.Basename", "Dir2.Basename", "Dir3.Basename"]
|
24
|
+
mock_script_1 = mock("script1")
|
25
|
+
mock_script_2 = mock("script2")
|
26
|
+
mock_script_3 = mock("script3")
|
27
|
+
|
28
|
+
File.should_receive(:dirname).with(any_args()).and_return(mock_cwd)
|
29
|
+
Pathname.should_receive(:new).with(mock_cwd).and_return(mock_cwd_pathname)
|
30
|
+
mock_cwd_pathname.should_receive(:children).and_return(mock_children)
|
31
|
+
mock_children[0].should_receive(:directory?).and_return(true)
|
32
|
+
mock_children[1].should_receive(:directory?).and_return(true)
|
33
|
+
mock_children[2].should_receive(:directory?).and_return(true)
|
34
|
+
|
35
|
+
mock_children[0].should_receive(:basename).and_return(mock_children_basenames[0])
|
36
|
+
Kernel.should_receive(:require).with("Dir1.Basename/dir1.basename")
|
37
|
+
Kernel.should_receive(:eval).with("Dir1.Basename.new").and_return(mock_script_1)
|
38
|
+
|
39
|
+
mock_children[1].should_receive(:basename).and_return(mock_children_basenames[1])
|
40
|
+
Kernel.should_receive(:require).with("Dir2.Basename/dir2.basename")
|
41
|
+
Kernel.should_receive(:eval).with("Dir2.Basename.new").and_return(mock_script_2)
|
42
|
+
|
43
|
+
mock_children[2].should_receive(:basename).and_return(mock_children_basenames[2])
|
44
|
+
Kernel.should_receive(:require).with("Dir3.Basename/dir3.basename")
|
45
|
+
Kernel.should_receive(:eval).with("Dir3.Basename.new").and_return(mock_script_3)
|
46
|
+
|
47
|
+
geeklets = Geeklets.new
|
48
|
+
end
|
49
|
+
|
50
|
+
def mock_some_scripts_with_problems
|
51
|
+
mock_cwd = mock("cwd")
|
52
|
+
mock_cwd_pathname = mock("cwd Pathname")
|
53
|
+
mock_children = [ mock("Dir1"), mock("Dir2"), mock("Dir3")]
|
54
|
+
mock_children_basenames = ["Dir1.Basename", "Dir2.Basename", "Dir3.Basename"]
|
55
|
+
mock_script_3 = mock("script3")
|
56
|
+
|
57
|
+
File.should_receive(:dirname).with(any_args()).and_return(mock_cwd)
|
58
|
+
Pathname.should_receive(:new).with(mock_cwd).and_return(mock_cwd_pathname)
|
59
|
+
mock_cwd_pathname.should_receive(:children).and_return(mock_children)
|
60
|
+
mock_children[0].should_receive(:directory?).and_return(true)
|
61
|
+
mock_children[1].should_receive(:directory?).and_return(true)
|
62
|
+
mock_children[2].should_receive(:directory?).and_return(true)
|
63
|
+
|
64
|
+
mock_children[0].should_receive(:basename).and_return(mock_children_basenames[0])
|
65
|
+
Kernel.should_receive(:require).with("Dir1.Basename/dir1.basename").and_raise("can't require")
|
66
|
+
|
67
|
+
mock_children[1].should_receive(:basename).and_return(mock_children_basenames[1])
|
68
|
+
Kernel.should_receive(:require).with("Dir2.Basename/dir2.basename")
|
69
|
+
Kernel.should_receive(:eval).with("Dir2.Basename.new").and_raise("can't create")
|
70
|
+
Kernel.should_receive(:puts).with("Problem loading Dir1.Basename geeklet.").ordered
|
71
|
+
|
72
|
+
mock_children[2].should_receive(:basename).and_return(mock_children_basenames[2])
|
73
|
+
Kernel.should_receive(:require).with("Dir3.Basename/dir3.basename")
|
74
|
+
Kernel.should_receive(:eval).with("Dir3.Basename.new").and_return(mock_script_3)
|
75
|
+
Kernel.should_receive(:puts).with("Problem loading Dir2.Basename geeklet.").ordered
|
76
|
+
|
77
|
+
geeklets = Geeklets.new
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
describe Geeklets do
|
83
|
+
|
84
|
+
before(:all) { @geeklets = Geeklets.new }
|
85
|
+
|
86
|
+
subject { @geeklets }
|
87
|
+
|
88
|
+
it { should respond_to :show_usage }
|
89
|
+
it { should respond_to :show_known_scripts }
|
90
|
+
it { should respond_to :run }
|
91
|
+
end
|
92
|
+
|
93
|
+
describe Geeklets do
|
94
|
+
|
95
|
+
context :initialize, "when there are no scripts" do
|
96
|
+
include GeekletExampleHelperMethods
|
8
97
|
|
9
|
-
|
98
|
+
before(:each) { @geeklets = mock_no_scripts }
|
10
99
|
|
11
|
-
|
100
|
+
it "should produce an empty list" do
|
101
|
+
Kernel.should_receive(:puts).with("These are the currently known geeklet scripts:").ordered
|
102
|
+
Kernel.should_receive(:puts).with(no_args()).ordered
|
103
|
+
Kernel.should_receive(:puts).with("There are no defined geeklet scripts.").ordered
|
104
|
+
Kernel.should_receive(:puts).with(no_args()).ordered
|
105
|
+
|
106
|
+
@geeklets.show_known_scripts
|
107
|
+
end
|
108
|
+
end
|
12
109
|
|
13
|
-
|
110
|
+
context :initialize, "when there are scripts with no problems" do
|
111
|
+
include GeekletExampleHelperMethods
|
112
|
+
|
113
|
+
before(:each) { @geeklets = mock_some_scripts_no_problems }
|
114
|
+
|
115
|
+
it "should not produce an empty list" do
|
116
|
+
Kernel.should_receive(:puts).with("These are the currently known geeklet scripts:").ordered
|
117
|
+
Kernel.should_receive(:puts).with(no_args()).ordered
|
118
|
+
Kernel.should_receive(:puts).with("\tDir1.Basename").ordered
|
119
|
+
Kernel.should_receive(:puts).with("\tDir2.Basename").ordered
|
120
|
+
Kernel.should_receive(:puts).with("\tDir3.Basename").ordered
|
121
|
+
Kernel.should_receive(:puts).with(no_args()).ordered
|
122
|
+
|
123
|
+
@geeklets.show_known_scripts
|
124
|
+
end
|
125
|
+
end
|
14
126
|
|
127
|
+
context :initialize, "when there are scripts with problems" do
|
128
|
+
include GeekletExampleHelperMethods
|
129
|
+
|
130
|
+
before(:each) { @geeklets = mock_some_scripts_with_problems }
|
131
|
+
|
132
|
+
it "should skip the scripts with problems and report them" do
|
133
|
+
Kernel.should_receive(:puts).with("These are the currently known geeklet scripts:").ordered
|
134
|
+
Kernel.should_receive(:puts).with(no_args()).ordered
|
135
|
+
Kernel.should_receive(:puts).with("\tDir3.Basename").ordered
|
136
|
+
Kernel.should_receive(:puts).with(no_args()).ordered
|
137
|
+
|
138
|
+
@geeklets.show_known_scripts
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
describe Geeklets do
|
145
|
+
|
146
|
+
before { @geeklets = Geeklets.new }
|
147
|
+
|
148
|
+
subject { @geeklets.run }
|
149
|
+
|
150
|
+
context "when given no parameters" do
|
151
|
+
|
152
|
+
it "should show usage and available scripts" do
|
153
|
+
@geeklets.should_receive(:show_usage)
|
154
|
+
@geeklets.should_receive(:show_known_scripts)
|
155
|
+
|
156
|
+
@geeklets.run(nil)
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when given empty parameters" do
|
162
|
+
|
163
|
+
it "should show usage and available scripts" do
|
164
|
+
@geeklets.should_receive(:show_usage)
|
165
|
+
@geeklets.should_receive(:show_known_scripts)
|
166
|
+
|
167
|
+
@geeklets.run([])
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
context "when given parmeters for a non existant script" do
|
173
|
+
|
174
|
+
it "should indicate that it doesn't understand, and show the available scripts" do
|
175
|
+
Kernel.should_receive(:puts).with("I do not know how to run the noscript geeklet.").ordered
|
176
|
+
@geeklets.should_receive(:show_known_scripts)
|
177
|
+
|
178
|
+
@geeklets.run(["noscript"])
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
context "when given parmeters for an existing script" do
|
184
|
+
|
185
|
+
before do
|
186
|
+
@script_hash = mock("script hash")
|
187
|
+
@script_hash.should_receive(:empty?).and_return(false)
|
188
|
+
@geeklets = Geeklets.new(@script_hash)
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should attempt to run that script" do
|
192
|
+
@script_hash.should_receive(:include?).with("some_script").and_return(true)
|
193
|
+
@script_hash.should_receive(:[]).with("some_script").and_return(mock_script = mock("some_script"))
|
194
|
+
mock_script.should_receive(:run).with(["some_params"])
|
195
|
+
|
196
|
+
@geeklets.run(["some_script", "some_params"])
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
15
200
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 7
|
9
|
+
version: 0.0.7
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- John F. Schank III
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-05-02 00:00:00 -04:00
|
18
18
|
default_executable: geeklets
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -124,8 +124,16 @@ files:
|
|
124
124
|
- lib/VRE_Alerts/vre_alerts.rb
|
125
125
|
- lib/WMATA_Alerts/wmata_alerts.rb
|
126
126
|
- lib/Weather/weather.rb
|
127
|
+
- lib/configurable.rb
|
128
|
+
- lib/configuration_required_error.rb
|
129
|
+
- lib/geeklet.rb
|
127
130
|
- lib/geeklets.rb
|
131
|
+
- lib/unregistered_config_value_error.rb
|
128
132
|
- lib/utility.rb
|
133
|
+
- spec/Next_Months_Calendar/next_months_calendar_spec.rb
|
134
|
+
- spec/Trash_Usage/trash_usage_spec.rb
|
135
|
+
- spec/configurable_spec.rb
|
136
|
+
- spec/geeklet_spec.rb
|
129
137
|
- spec/geeklets_spec.rb
|
130
138
|
- spec/spec.opts
|
131
139
|
- spec/spec_helper.rb
|
@@ -162,6 +170,10 @@ signing_key:
|
|
162
170
|
specification_version: 3
|
163
171
|
summary: Scripts for GeekTool
|
164
172
|
test_files:
|
173
|
+
- spec/configurable_spec.rb
|
174
|
+
- spec/geeklet_spec.rb
|
165
175
|
- spec/geeklets_spec.rb
|
176
|
+
- spec/Next_Months_Calendar/next_months_calendar_spec.rb
|
166
177
|
- spec/spec_helper.rb
|
178
|
+
- spec/Trash_Usage/trash_usage_spec.rb
|
167
179
|
- spec/utility_spec.rb
|