diff --git a/modules/sachsen/__init__.py b/modules/sachsen/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc1061948d87da07adc69bc740eac679a555e2f9
--- /dev/null
+++ b/modules/sachsen/__init__.py
@@ -0,0 +1,3 @@
+from .backend import SachsenLevelBackend
+
+__all__ = ['SachsenLevelBackend']
diff --git a/modules/sachsen/backend.py b/modules/sachsen/backend.py
new file mode 100644
index 0000000000000000000000000000000000000000..9c99cd5accfc106983cb9cedb9e1f171a270447e
--- /dev/null
+++ b/modules/sachsen/backend.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2010,2011 Romain Bignon, Florent Fourcot
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, version 3 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+from __future__ import with_statement
+
+from .browser import SachsenBrowser
+from weboob.capabilities.gauge import ICapWaterLevel
+from weboob.tools.backend import BaseBackend
+
+
+__all__ = ['SachsenLevelBackend']
+
+
+class SachsenLevelBackend(BaseBackend, ICapWaterLevel):
+ NAME = 'sachsen'
+ MAINTAINER = 'Florent Fourcot'
+ EMAIL = ''
+ VERSION = '0.b'
+ LICENSE = 'GPLv3'
+ DESCRIPTION = u"Level of Sachsen river"
+ BROWSER = SachsenBrowser
+
+ def create_default_browser(self):
+ return self.create_browser()
+
+ def get_list(self):
+ return self.browser.get_rivers_list()
+
+ def get_history(self, id):
+ return self.browser.get_history(id)
+
+ def last(self, id):
+ return self.browser.last_seen(id)
+
+ def search(self, pattern):
+ return self.browser.search(pattern)
diff --git a/modules/sachsen/browser.py b/modules/sachsen/browser.py
new file mode 100644
index 0000000000000000000000000000000000000000..19932019a26ba3560db6cd5ba54e713b631801b5
--- /dev/null
+++ b/modules/sachsen/browser.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2010-2011 Romain Bignon, Florent Fourcot
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+
+from weboob.tools.browser import BaseBrowser
+
+
+from .pages import ListPage, HistoryPage
+
+
+__all__ = ['SachsenBrowser']
+
+
+class SachsenBrowser(BaseBrowser):
+ DOMAIN = u'www.umwelt.sachsen.de'
+ ENCODING = None
+ PAGES = {'.*inhalt_re.html.*': ListPage,
+ '.*hwz/MP/.*': HistoryPage
+ }
+
+ cache_list = None
+
+ def __init__(self, *args, **kwargs):
+ BaseBrowser.__init__(self, *args, **kwargs)
+
+ def home(self):
+ self.location('/de/wu/umwelt/lfug/lfug-internet/hwz/inhalt_re.html')
+
+ def get_rivers_list(self):
+ if self.cache_list == None:
+ if not self.is_on_page(ListPage):
+ self.location('/de/wu/umwelt/lfug/lfug-internet/hwz/inhalt_re.html')
+ self.cache_list = self.page.get_rivers_list()
+ return self.cache_list
+
+ def get_history(self, id):
+ self.location('/de/wu/umwelt/lfug/lfug-internet/hwz/MP/%d/index.html' %int(id))
+ return self.page.get_history()
+
+ def last_seen(self, id):
+ self.location('/de/wu/umwelt/lfug/lfug-internet/hwz/MP/%d/index.html' %int(id))
+ return self.page.last_seen()
+
+ def search(self, pattern):
+ if self.cache_list == None:
+ self.get_rivers_list()
+ l = []
+ for gauge in self.cache_list:
+ if gauge.name.__contains__(pattern) or gauge.river.__contains__(pattern):
+ l.append(gauge)
+
+ return l
diff --git a/modules/sachsen/pages.py b/modules/sachsen/pages.py
new file mode 100644
index 0000000000000000000000000000000000000000..9b7842373f18e5bc0a9ea0e8e5b2e7e47218cc81
--- /dev/null
+++ b/modules/sachsen/pages.py
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2010-2011 Romain Bignon, Florent Fourcot
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see .
+
+from datetime import datetime, date, time
+from weboob.tools.browser import BasePage
+
+from weboob.capabilities.gauge import Gauge, GaugeHistory
+from weboob.capabilities.base import NotAvailable
+
+__all__ = ['ListPage', 'HistoryPage']
+
+class ListPage(BasePage):
+ def get_rivers_list(self):
+ l = []
+ for pegel in self.document.getroot().xpath(".//a[@onmouseout='pegelaus()']"):
+ data = pegel.attrib['onmouseover'].strip('pegelein(').strip(')').replace(",'", ",").split("',")
+ gauge = Gauge(int(data[7]))
+ gauge.name = data[0].strip("'")
+ gauge.river = data[1]
+ try:
+ lastdate = date(*reversed([int(x) for x in data[2].split(' ')[0].split(".")]))
+ lasttime = time(*[int(x) for x in data[2].split(' ')[1].split(":")])
+ gauge.lastdate = datetime.combine(lastdate, lasttime)
+ except:
+ gauge.lastdate = NotAvailable
+ try:
+ gauge.level = float(data[3])
+ except:
+ gauge.level = NotAvailable
+ try:
+ gauge.flow = float(data[4])
+ except:
+ gauge.flow = NotAvailable
+ bildforecast = data[5]
+ if bildforecast.__eq__("pf_gerade.png"):
+ gauge.forecast = "stable"
+ elif bildforecast.__eq__("pf_unten.png"):
+ gauge.forecast = "Go down"
+ else:
+ gauge.forecast = NotAvailable
+
+ l.append(gauge)
+
+ return l
+
+class HistoryPage(BasePage):
+ def get_history(self):
+ l = []
+ table = self.document.getroot().cssselect('table[width="215"]')
+ first = True
+ for line in table[0].cssselect("tr"):
+ if first:
+ first = False
+ continue
+ history = GaugeHistory()
+ leveldate = date(*reversed([int(x) for x in line[0].text_content().split(' ')[0].split(".")]))
+ leveltime = time(*[int(x) for x in line[0].text_content().split(' ')[1].split(":")])
+ history.date = datetime.combine(leveldate, leveltime)
+
+ try:
+ history.level = float(line[1].text_content())
+ except:
+ history.level = NotAvailable
+ try:
+ history.flow = float(line[2].text_content())
+ except:
+ history.flow = NotAvailable
+ l.append(history)
+
+ return l
+
+ def first_value(self, table, index):
+ first = NotAvailable
+ for lignes in table[0].cssselect("tr"):
+ try:
+ valeur = float(lignes[index].text_content())
+ if (valeur > 1.0):
+ first = valeur
+ return first
+ except:
+ continue
+ return first
+
+ def last_seen(self):
+ tables = self.document.getroot().cssselect('table[width="215"]')
+ gauge = GaugeHistory()
+ gauge.level = self.first_value(tables, 1)
+ gauge.flow = self.first_value(tables, 2)
+
+ return gauge