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.
@@ -1,10 +1,12 @@
1
- = mensa
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
- == Copyright
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.2
1
+ 0.1.3
data/bin/mensa CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH << File.join(File.dirname(__FILE__), '../lib')
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&amp;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>&nbsp;</td><td><h2>Echt bio! Jeden Mittwoch<br /></h2>Unser Bio-Essen aus biozertifizierten Produkten:<br /><strong><br /></strong><strong class="color_essen">03.06.09</strong><br />2 Texas Beanburger*<br /> mit Tomatensauce** FL 2,50 &euro;<br /> f&uuml;r G&auml;ste und MitarbeiterInnen der TU Darmstadt 3,50 &euro;&nbsp; <br /><br /></td></tr><tr><td valign="top">&nbsp;</td><td>&nbsp;</td><td valign="top"><span class="color_essen">&nbsp; *</span> Bio-Komponente - DE-007-&Ouml;ko-Kontrollstelle <span class="color_essen"><br />**</span> Komponente aus konventionellem Anbau</td></tr></tbody></table>
64
+ <table border="0"><tbody><tr><td><a href="stwscripts/show_image.php?abteilung=essen&amp;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>&nbsp;</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 &quot;Vegetaria&quot;*<br /> mit Tomatensauce** FL 3,30 &euro;<br /> f&uuml;r G&auml;ste und MitarbeiterInnen der TU Darmstadt 4,30 &euro;&nbsp; <br /><br /></td></tr><tr><td valign="top">&nbsp;</td><td>&nbsp;</td><td valign="top"><span class="color_essen">&nbsp; *</span> Bio-Komponente - DE-007-&Ouml;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>&Auml;nderungen behalten wir uns vor.</p>
83
83
 
84
84
  <a href="http://www.studentenwerkdarmstadt.de/index.php?option=com_spk&amp;task=sch�fferstra�e&amp;view=week">Wochenansicht</a>
85
- <br />&nbsp;<br /><table border="1" class="spk_table"><tr><th></th><th class="hl_today">Donnerstag, den 28.05.2009</th></tr>
86
- <tr><td valign="top">Mensa</td><td valign="top"><img class="spk_img" src="components/com_spk/images/gefluegelpict_k.jpg" alt="gefluegel" width="50px" />H&auml;hnchen-Nuggets-im Knuspermantel dazu ein Kr&auml;uterdip G 1,90 �</td></tr>
87
- <tr><td valign="top">&nbsp;</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">&nbsp;</td><td valign="top"><img class="spk_img" src="components/com_spk/images/gefluegelpict_k.jpg" alt="gefluegel" width="50px" />Wokpfanne &quot;Hot-Asia-Style&quot; mit H&auml;hnchenbrust und Mie-Nudeln G 2,80 �</td></tr>
89
- <tr><td valign="top">&nbsp;</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&auml;nge ! </td></tr>
90
- <tr><td valign="top">&nbsp;</td><td valign="top"><img class="spk_img" src="components/com_spk/images/fleischlospict_k.jpg" alt="fleischlos" width="50px" />R&uuml;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&uuml;gel # (F) Fisch # (FL) Fleischlos
94
- </div>
95
- <div class="legende">
96
- (1) Farbstoff # (2) Konservierungsstoff # (3) Antioxidationsmittel # (4) Geschmacksverst&auml;rker # (5) geschwefelt # (6) geschw&auml;rzt # (7) gewachst # (8) Phosphat # (9) S&uuml;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
- <!-- 1243545358 -->
120
+ <!-- 1244894038 -->
data/fixtures/output.txt CHANGED
@@ -45,3 +45,10 @@
45
45
 
46
46
  Country Kartoffeln mit Quark 1,10 €
47
47
 
48
+
49
+
50
+ Mensa Schöfferstraße 13.06.
51
+ ============================================================================
52
+
53
+ geschlossen
54
+
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
- string = document.css('.spk_table th:last-child').first.text.strip
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
- if date = /(\d{2})\.(\d{2})\.(\d{4})/.match(string)[1..3].reverse
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
- nil
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(70)
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
- if (lines.last.length + word.length) < 64
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
- result = lines.shift.ljust(70)
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
@@ -4,6 +4,8 @@ require 'uri'
4
4
  require 'net/http'
5
5
  require 'iconv'
6
6
 
7
+ require 'jcode' if RUBY_VERSION < '1.9'
8
+
7
9
  require 'rubygems'
8
10
  require 'nokogiri'
9
11
 
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.2"
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-04}
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.rdoc"
15
+ "README.md"
16
16
  ]
17
17
  s.files = [
18
18
  ".document",
19
19
  ".gitignore",
20
20
  "LICENSE",
21
- "README.rdoc",
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.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",
@@ -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
- uri[:stadtmitte] = "http://www.studentenwerkdarmstadt.de/essen/mensa-stadtmitte.html"
8
- uri[:lichtwiese] = "http://www.studentenwerkdarmstadt.de/essen/mensa-lichtwiese.html"
9
- uri[:haardtring] = "http://www.studentenwerkdarmstadt.de/essen/mensa-haardtring.html"
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] = Time.local(2009, 5, 28)
34
- date[:lichtwiese] = Time.local(2009, 5, 29)
35
- date[:haardtring] = Time.local(2009, 6, 1)
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] = "Mensa Stadtmitte"
39
- name[:lichtwiese] = "Mensa Lichtwiese"
40
- name[:haardtring] = "Mensa 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 \"Mensa Stadtmitte\"" do
82
+ it "should be \"#{name[canteen]}\"" do
67
83
  subject.name.should == name[canteen]
68
84
  end
69
85
  end
@@ -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(3).canteens }
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.2
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-04 00:00:00 -07:00
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.rdoc
33
+ - README.md
34
34
  files:
35
35
  - .document
36
36
  - .gitignore
37
37
  - LICENSE
38
- - README.rdoc
38
+ - README.md
39
39
  - Rakefile
40
40
  - VERSION
41
41
  - bin/mensa