t6d-mensa 0.1.2 → 0.1.3
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/{README.rdoc → README.md} +4 -2
- data/Rakefile +7 -0
- data/VERSION +1 -1
- data/bin/mensa +4 -1
- data/fixtures/canteens.rb +1 -0
- data/fixtures/mensa-schofferstrase.html +4 -16
- data/fixtures/output.txt +7 -0
- data/lib/mensa/canteen.rb +34 -5
- data/lib/mensa/client.rb +10 -3
- data/lib/mensa.rb +2 -0
- data/mensa.gemspec +5 -5
- data/spec/mensa/canteen_spec.rb +29 -13
- data/spec/mensa/client_spec.rb +15 -1
- metadata +4 -4
data/{README.rdoc → README.md}
RENAMED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
1
|
+
mensa
|
2
|
+
=====
|
2
3
|
|
3
4
|
Fetches the daily bill of fare from the canteen page of Studentenwerk Darmstadt.
|
4
5
|
|
5
6
|
It is a little fun project to get familiar with TDD techniques, git and web
|
6
7
|
scraping.
|
7
8
|
|
8
|
-
|
9
|
+
Copyright
|
10
|
+
---------
|
9
11
|
|
10
12
|
Copyright (c) 2009 Konstantin Tennhard. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -35,6 +35,7 @@ end
|
|
35
35
|
task :default => :spec
|
36
36
|
|
37
37
|
require 'rake/rdoctask'
|
38
|
+
|
38
39
|
Rake::RDocTask.new do |rdoc|
|
39
40
|
if File.exist?('VERSION.yml')
|
40
41
|
config = YAML.load(File.read('VERSION.yml'))
|
@@ -49,3 +50,9 @@ Rake::RDocTask.new do |rdoc|
|
|
49
50
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
51
|
end
|
51
52
|
|
53
|
+
desc "Generates documentation with yard"
|
54
|
+
task :yardoc do
|
55
|
+
Dir.chdir(File.dirname(__FILE__)) do
|
56
|
+
`yardoc 'lib/**/*.rb'`
|
57
|
+
end
|
58
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/bin/mensa
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
$LOAD_PATH
|
3
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../lib')
|
4
|
+
|
5
|
+
# its important to set the kcode to use the jcode library
|
6
|
+
$KCODE = 'u' if RUBY_VERSION < '1.9'
|
4
7
|
|
5
8
|
require 'mensa'
|
6
9
|
|
data/fixtures/canteens.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
canteen "http://www.studentenwerkdarmstadt.de/essen/mensa-stadtmitte.html"
|
2
2
|
canteen "http://www.studentenwerkdarmstadt.de/essen/mensa-haardtring.html"
|
3
3
|
canteen "http://www.studentenwerkdarmstadt.de/essen/mensa-lichtwiese.html"
|
4
|
+
canteen "http://www.studentenwerkdarmstadt.de/essen/mensa-schofferstrase.html"
|
4
5
|
|
@@ -61,7 +61,7 @@
|
|
61
61
|
<table class="contentpaneopen">
|
62
62
|
<tr>
|
63
63
|
<td valign="top" colspan="2">
|
64
|
-
<table border="0"><tbody><tr><td><a href="stwscripts/show_image.php?abteilung=essen&bild=bio-siegel.jpg"><img class="mosimage_class" src="http://www.studentenwerkdarmstadt.de/images/stories/essen/bio-siegel_k.jpg" width="80" height="66" hspace="0" alt="Bio-Siegel" title="Bio-Siegel" border="0" /></a></td><td> </td><td><h2>Echt bio! Jeden Mittwoch<br /></h2>Unser Bio-Essen aus biozertifizierten Produkten:<br /><strong><br /></strong><strong class="color_essen">
|
64
|
+
<table border="0"><tbody><tr><td><a href="stwscripts/show_image.php?abteilung=essen&bild=bio-siegel.jpg"><img class="mosimage_class" src="http://www.studentenwerkdarmstadt.de/images/stories/essen/bio-siegel_k.jpg" width="80" height="66" hspace="0" alt="Bio-Siegel" title="Bio-Siegel" border="0" /></a></td><td> </td><td><h2>Echt bio! Jeden Mittwoch<br /></h2>Unser Bio-Essen aus biozertifizierten Produkten:<br /><strong><br /></strong><strong class="color_essen">10.06.09</strong><br />Lasagne "Vegetaria"*<br /> mit Tomatensauce** FL 3,30 €<br /> für Gäste und MitarbeiterInnen der TU Darmstadt 4,30 € <br /><br /></td></tr><tr><td valign="top"> </td><td> </td><td valign="top"><span class="color_essen"> *</span> Bio-Komponente - DE-007-Öko-Kontrollstelle <span class="color_essen"><br />**</span> Komponente aus konventionellem Anbau</td></tr></tbody></table>
|
65
65
|
</tr>
|
66
66
|
</table>
|
67
67
|
|
@@ -82,20 +82,8 @@
|
|
82
82
|
<p>Änderungen behalten wir uns vor.</p>
|
83
83
|
|
84
84
|
<a href="http://www.studentenwerkdarmstadt.de/index.php?option=com_spk&task=sch�fferstra�e&view=week">Wochenansicht</a>
|
85
|
-
<br
|
86
|
-
|
87
|
-
<tr><td valign="top"> </td><td valign="top"><img class="spk_img" src="components/com_spk/images/schweinpict_k.jpg" alt="schwein" width="50px" />Grillbraten vom Schweinenacken mit Thymianjus S 2,00 �</td></tr>
|
88
|
-
<tr><td valign="top"> </td><td valign="top"><img class="spk_img" src="components/com_spk/images/gefluegelpict_k.jpg" alt="gefluegel" width="50px" />Wokpfanne "Hot-Asia-Style" mit Hähnchenbrust und Mie-Nudeln G 2,80 �</td></tr>
|
89
|
-
<tr><td valign="top"> </td><td valign="top"><img class="spk_img" src="components/com_spk/images/pict_k.jpg" alt="" width="50px" />Spargelwoche !!! Bitte beachten Sie unsere Aushänge ! </td></tr>
|
90
|
-
<tr><td valign="top"> </td><td valign="top"><img class="spk_img" src="components/com_spk/images/fleischlospict_k.jpg" alt="fleischlos" width="50px" />Rühreier mit Rahmspinat FL 1,20 �</td></tr>
|
91
|
-
</table><br />
|
92
|
-
<div class="legende">
|
93
|
-
(S) Schweinefleisch # (R) Rindfleisch # (K) Kalbfleisch # (L) Lammfleisch # (G) Geflügel # (F) Fisch # (FL) Fleischlos
|
94
|
-
</div>
|
95
|
-
<div class="legende">
|
96
|
-
(1) Farbstoff # (2) Konservierungsstoff # (3) Antioxidationsmittel # (4) Geschmacksverstärker # (5) geschwefelt # (6) geschwärzt # (7) gewachst # (8) Phosphat # (9) Süssungsmittel # (11) Phenylalaninquelle
|
97
|
-
</div>
|
98
|
-
<br />
|
85
|
+
<p><br /><b>Am Samstag, den 13.06.2009 bleibt die Mensa geschlossen.</b></p>
|
86
|
+
|
99
87
|
<table class="contentpaneopen">
|
100
88
|
<tr><td>
|
101
89
|
</td></tr>
|
@@ -129,4 +117,4 @@ I</div><div id="footer2">
|
|
129
117
|
|
130
118
|
</body>
|
131
119
|
</html>
|
132
|
-
<!--
|
120
|
+
<!-- 1244894038 -->
|
data/fixtures/output.txt
CHANGED
data/lib/mensa/canteen.rb
CHANGED
@@ -4,10 +4,18 @@ module Mensa
|
|
4
4
|
class Canteen
|
5
5
|
attr_reader :document
|
6
6
|
|
7
|
+
##
|
8
|
+
# Creates a new canteen for a given uri
|
9
|
+
# @param [String]
|
10
|
+
# @return [Canteen]
|
7
11
|
def initialize(uri)
|
8
12
|
@document = Nokogiri::HTML(Document.new(uri).to_s)
|
9
13
|
end
|
10
14
|
|
15
|
+
##
|
16
|
+
# Extracts the bill of fare
|
17
|
+
#
|
18
|
+
# @return [Array]
|
11
19
|
def fares
|
12
20
|
if @fares.nil?
|
13
21
|
@fares = []
|
@@ -33,28 +41,49 @@ module Mensa
|
|
33
41
|
@fares
|
34
42
|
end
|
35
43
|
|
44
|
+
##
|
45
|
+
# A canteen is opened if it offers at least one fare
|
46
|
+
#
|
47
|
+
# @return [true | false]
|
36
48
|
def opened?
|
37
49
|
!fares.empty?
|
38
50
|
end
|
39
51
|
|
52
|
+
##
|
53
|
+
# A canteen is closed if it offers no fares
|
54
|
+
#
|
55
|
+
# @return [true | false]
|
40
56
|
def closed?
|
41
57
|
fares.empty?
|
42
58
|
end
|
43
59
|
|
60
|
+
##
|
61
|
+
# Extracts the date
|
62
|
+
#
|
63
|
+
# @return [Time]
|
44
64
|
def date
|
45
|
-
|
65
|
+
node = document.css('div.inside p b')
|
66
|
+
node = document.css('.spk_table th:last-child') if node.empty?
|
67
|
+
raise "Website does not contain a proper date" if node.empty?
|
46
68
|
|
47
|
-
|
48
|
-
return Time.local(*(date.map { |e| e.to_i }))
|
49
|
-
end
|
69
|
+
date = /(\d{2})\.(\d{2})\.(\d{4})/.match(node.first.text.strip)
|
50
70
|
|
51
|
-
|
71
|
+
Time.local(*(date.captures.reverse.map { |e| e.to_i }))
|
52
72
|
end
|
53
73
|
|
74
|
+
##
|
75
|
+
# Extracts the name
|
76
|
+
#
|
77
|
+
# @return [String]
|
54
78
|
def name
|
55
79
|
document.css('.contentheading').first.text.strip
|
56
80
|
end
|
57
81
|
|
82
|
+
##
|
83
|
+
# Compares two canteens based on their date, state and name
|
84
|
+
#
|
85
|
+
# @param [Canteen]
|
86
|
+
# @return [true | false]
|
58
87
|
def ==(other)
|
59
88
|
self.name == other.name && self.date == other.date &&
|
60
89
|
self.closed? == other.closed? && self.opened? == other.opened?
|
data/lib/mensa/client.rb
CHANGED
@@ -65,9 +65,11 @@ module Mensa
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def print_header(canteen)
|
68
|
+
pad = (RUBY_VERSION < '1.9' ? canteen.name.length - canteen.name.jlength : 0) + 70
|
69
|
+
|
68
70
|
result = "\n"
|
69
71
|
result += " "
|
70
|
-
result += canteen.name.ljust(
|
72
|
+
result += canteen.name.ljust(pad)
|
71
73
|
result += canteen.date.strftime('%d.%m.')
|
72
74
|
result += "\n"
|
73
75
|
result += " "
|
@@ -80,14 +82,19 @@ module Mensa
|
|
80
82
|
lines << ' '
|
81
83
|
|
82
84
|
fare.name.split(' ').each do |word|
|
83
|
-
|
85
|
+
word_length = RUBY_VERSION < '1.9' ? word.jlength : word.length
|
86
|
+
|
87
|
+
if (lines.last.length + word_length) < 64
|
84
88
|
lines.push(lines.pop + ' ' + word)
|
85
89
|
else
|
86
90
|
lines << " #{word}"
|
87
91
|
end
|
88
92
|
end
|
89
93
|
|
90
|
-
|
94
|
+
# calculates the right amount of space padding (ruby < 1.9 compatibility hack)
|
95
|
+
pad = (RUBY_VERSION < '1.9' ? lines.first.length - lines.first.jlength : 0) + 70
|
96
|
+
|
97
|
+
result = lines.shift.ljust(pad)
|
91
98
|
result += "%1d,%02d €" % [fare.price / 100, fare.price % 100]
|
92
99
|
result += "\n"
|
93
100
|
|
data/lib/mensa.rb
CHANGED
data/mensa.gemspec
CHANGED
@@ -2,23 +2,23 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{mensa}
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Konstantin Tennhard"]
|
9
|
-
s.date = %q{2009-06-
|
9
|
+
s.date = %q{2009-06-14}
|
10
10
|
s.default_executable = %q{mensa}
|
11
11
|
s.email = %q{development@tennhard.net}
|
12
12
|
s.executables = ["mensa"]
|
13
13
|
s.extra_rdoc_files = [
|
14
14
|
"LICENSE",
|
15
|
-
"README.
|
15
|
+
"README.md"
|
16
16
|
]
|
17
17
|
s.files = [
|
18
18
|
".document",
|
19
19
|
".gitignore",
|
20
20
|
"LICENSE",
|
21
|
-
"README.
|
21
|
+
"README.md",
|
22
22
|
"Rakefile",
|
23
23
|
"VERSION",
|
24
24
|
"bin/mensa",
|
@@ -47,7 +47,7 @@ Gem::Specification.new do |s|
|
|
47
47
|
s.homepage = %q{http://github.com/t6d/mensa}
|
48
48
|
s.rdoc_options = ["--charset=UTF-8"]
|
49
49
|
s.require_paths = ["lib"]
|
50
|
-
s.rubygems_version = %q{1.3.
|
50
|
+
s.rubygems_version = %q{1.3.4}
|
51
51
|
s.summary = %q{Fetches the daily bill of fare from the canteen page of Studentenwerk Darmstadt.}
|
52
52
|
s.test_files = [
|
53
53
|
"spec/mensa/canteen_spec.rb",
|
data/spec/mensa/canteen_spec.rb
CHANGED
@@ -3,10 +3,19 @@
|
|
3
3
|
require File.join(File.dirname(__FILE__), '../spec_helper')
|
4
4
|
|
5
5
|
module Mensa
|
6
|
+
##
|
7
|
+
# Setup
|
8
|
+
##
|
9
|
+
|
6
10
|
uri = {}
|
7
|
-
|
8
|
-
uri[:
|
9
|
-
|
11
|
+
# open - 6 fares offering
|
12
|
+
uri[:stadtmitte] = "http://www.studentenwerkdarmstadt.de/essen/mensa-stadtmitte.html"
|
13
|
+
# open - 8 fares offering
|
14
|
+
uri[:lichtwiese] = "http://www.studentenwerkdarmstadt.de/essen/mensa-lichtwiese.html"
|
15
|
+
# closed
|
16
|
+
uri[:haardtring] = "http://www.studentenwerkdarmstadt.de/essen/mensa-haardtring.html"
|
17
|
+
# closed (unexpected markup)
|
18
|
+
uri[:schoefferstrasse] = "http://www.studentenwerkdarmstadt.de/essen/mensa-schofferstrase.html"
|
10
19
|
|
11
20
|
fares = {}
|
12
21
|
fares[:stadtmitte] = [
|
@@ -27,20 +36,27 @@ module Mensa
|
|
27
36
|
Fare.new("Wokpfanne \"Thai 7 Spice\" mit Putenbrust und Basmatireis", :poultry, 280),
|
28
37
|
Fare.new("Country Kartoffeln mit Quark", :meatless, 110)
|
29
38
|
]
|
30
|
-
fares[:haardtring]
|
39
|
+
fares[:haardtring] = []
|
40
|
+
fares[:schoefferstrasse] = []
|
31
41
|
|
32
42
|
date = {}
|
33
|
-
date[:stadtmitte]
|
34
|
-
date[:lichtwiese]
|
35
|
-
date[:haardtring]
|
43
|
+
date[:stadtmitte] = Time.local(2009, 5, 28)
|
44
|
+
date[:lichtwiese] = Time.local(2009, 5, 29)
|
45
|
+
date[:haardtring] = Time.local(2009, 6, 1)
|
46
|
+
date[:schoefferstrasse] = Time.local(2009, 6, 13)
|
36
47
|
|
37
48
|
name = {}
|
38
|
-
name[:stadtmitte]
|
39
|
-
name[:lichtwiese]
|
40
|
-
name[:haardtring]
|
49
|
+
name[:stadtmitte] = "Mensa Stadtmitte"
|
50
|
+
name[:lichtwiese] = "Mensa Lichtwiese"
|
51
|
+
name[:haardtring] = "Mensa Haardtring"
|
52
|
+
name[:schoefferstrasse] = "Mensa Schöfferstraße"
|
53
|
+
|
54
|
+
##
|
55
|
+
# Specs
|
56
|
+
##
|
41
57
|
|
42
|
-
[:stadtmitte, :lichtwiese, :haardtring].each do |canteen|
|
43
|
-
describe "#{canteen.to_s.capitalize} am #{date[canteen].strftime('%d.%m.%Y')} Canteen" do
|
58
|
+
[:stadtmitte, :lichtwiese, :haardtring, :schoefferstrasse].each do |canteen|
|
59
|
+
describe "#{canteen.to_s.capitalize} am #{date[canteen].strftime('%d.%m.%Y')}: Canteen" do
|
44
60
|
subject { Canteen.new(uri[canteen]) }
|
45
61
|
|
46
62
|
it { should have(fares[canteen].length).fares }
|
@@ -63,7 +79,7 @@ module Mensa
|
|
63
79
|
end
|
64
80
|
|
65
81
|
describe "#name" do
|
66
|
-
it "should be \"
|
82
|
+
it "should be \"#{name[canteen]}\"" do
|
67
83
|
subject.name.should == name[canteen]
|
68
84
|
end
|
69
85
|
end
|
data/spec/mensa/client_spec.rb
CHANGED
@@ -4,9 +4,19 @@ require File.join(File.dirname(__FILE__), '../spec_helper')
|
|
4
4
|
|
5
5
|
module Mensa
|
6
6
|
describe Client do
|
7
|
+
##
|
8
|
+
# Setup
|
9
|
+
##
|
10
|
+
|
11
|
+
##
|
12
|
+
# Access to the configuration file is _mocked out_!
|
7
13
|
user_config_file = File.join(ENV['HOME'], ".mensarc")
|
8
14
|
global_config_file = File.join(MENSA_DIR, 'config/canteens.rb')
|
9
15
|
|
16
|
+
##
|
17
|
+
# used to check if canteens are displayed in the order of the user
|
18
|
+
# specific configuration file
|
19
|
+
# (see spec 'Client with user specific settings')
|
10
20
|
canteens = {}
|
11
21
|
canteens[:stadtmitte] = Canteen.new(
|
12
22
|
'http://www.studentenwerkdarmstadt.de/essen/mensa-stadtmitte.html'
|
@@ -15,6 +25,10 @@ module Mensa
|
|
15
25
|
'http://www.studentenwerkdarmstadt.de/essen/mensa-haardtring.html'
|
16
26
|
)
|
17
27
|
|
28
|
+
##
|
29
|
+
# Specs
|
30
|
+
##
|
31
|
+
|
18
32
|
subject { Client.new(StringIO.new) }
|
19
33
|
|
20
34
|
describe 'with global settings (config/canteens.rb)' do
|
@@ -36,7 +50,7 @@ module Mensa
|
|
36
50
|
File.should_receive(:read).with(user_config_file).and_return(config)
|
37
51
|
end
|
38
52
|
|
39
|
-
it { should have(
|
53
|
+
it { should have(4).canteens }
|
40
54
|
|
41
55
|
it 'should have "Mensa Stadtmitte" as first canteen' do
|
42
56
|
subject.canteens[0].should == canteens[:stadtmitte]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: t6d-mensa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Tennhard
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-06-
|
12
|
+
date: 2009-06-14 00:00:00 -07:00
|
13
13
|
default_executable: mensa
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -30,12 +30,12 @@ extensions: []
|
|
30
30
|
|
31
31
|
extra_rdoc_files:
|
32
32
|
- LICENSE
|
33
|
-
- README.
|
33
|
+
- README.md
|
34
34
|
files:
|
35
35
|
- .document
|
36
36
|
- .gitignore
|
37
37
|
- LICENSE
|
38
|
-
- README.
|
38
|
+
- README.md
|
39
39
|
- Rakefile
|
40
40
|
- VERSION
|
41
41
|
- bin/mensa
|