#!/usr/bin/env python3

import sys
import re
import itertools
import urllib.parse

import lxml.etree as etree

import pyopenmensa.feed


def sub_whitespace(text):
    return re.sub("\s+", " ", text)


def meals_uri(mensa_name):
    base = 'http://www.studentenwerk-goettingen.de/speiseplan.html?'
    params = {
        'no_cache': 1,
        'day': 7,
        'selectmensa': mensa_name,
        'push': 0
    }
    this_week = base + urllib.parse.urlencode(params)
    params['push'] = 1
    next_week = base + urllib.parse.urlencode(params)
    return this_week, next_week


def get_prices(source, parser):
    """Returns a dict with meal type as key and list of prices as value."""
    tree = etree.parse(source, parser)
    table = tree.xpath("//table")[0]
    prices = {}
    for row in table.getchildren():
        cols = [sub_whitespace(x.text) for x in row if x.text is not None]
        if not cols:
            continue
        meal_type = cols.pop(0)
        if not meal_type.isspace() and cols and not cols[0].isspace():
            prices[meal_type] = cols
    return prices


def get_meals(uri, valid_categories, parser):
    tree = etree.parse(uri, parser)
    for day in tree.xpath("//div[@class='speise-tblhead']"):
        # fix for M&Atilde;&curren;rz ...
        date = re.sub('M..rz', 'März', day.text)
        date = pyopenmensa.feed.extractDate(date)

        table = day.getnext()
        for tr in table.iterchildren():
            price_cat = tr.xpath(".//span[@class='ext_sits_preis']")
            price_cat = price_cat[0].text

            if price_cat not in valid_categories:
                continue

            meal = tr.xpath(".//span[@class='ext_sits_essen']/strong")
            meal = meal[0].text + " " + meal[0].tail.strip()

            # remove notes about special ingreidents
            # e.g.
            #     "Curryfleischwurst (2,3,8) vom Schwein"
            #  -> "Curryfleischwurst vom Schwein"
            meal = re.sub(r' \(\d+(,\d+)*\)', '', meal)

            yield (date, price_cat, meal)


def mensa_feed(this_week_uri, next_week_uri, prices_uri,
               roles=('student', 'employee', 'other')):
    parser = etree.HTMLParser(encoding='utf-8', no_network=False)
    prices = get_prices(prices_uri, parser)
    builder = pyopenmensa.feed.LazyBuilder()
    meals = itertools.chain(get_meals(this_week_uri, prices.keys(), parser),
                            get_meals(next_week_uri, prices.keys(), parser))
    for date, cat, meal in meals:
        builder.addMeal(date, cat, meal, prices=prices[cat], roles=roles)

    return builder.toXMLFeed()


if __name__ == '__main__':
    mensae = {
        'z': ('Zentralmensa', 'preise_zm.html'),
        'n': ('Nordmensa', 'preise-nm.html'),
        't': ('Mensa am turm', 'preise-mat.html'),
        'i': ('Mensa Italia', 'preise-mi.html'),
        'h': ('Bistro HAWK', 'preise-hawk.html')
        }

    name, prices = mensae[sys.argv[1]]
    prices = 'http://studentenwerk-goettingen.de/' + prices
    this_week, next_week = meals_uri(name)
    print(mensa_feed(this_week, next_week, prices))

@@ -1101,29 +1101,18 @@
 als(
-uri, valid_categories
+mensa, uri
 , pa
@@ -1435,30 +1435,24 @@
             
-price_
 cat = tr.xpa
@@ -1506,185 +1506,697 @@
     
-price_cat = price_cat%5B0%5D.text%0A%0A            if price_cat not in valid_categories:%0A                continue%0A%0A            meal = tr.xpath(%22.//span%5B@class='ext_sits_essen'%5D/strong%22)
+if not cat:%0A                continue%0A            c = cat%5B0%5D.text%0A%0A            # fix %3Cbr%3E line break in first column%0A            for br in cat%5B0%5D.xpath(%22.//br%22):%0A                c += %22 %22 + br.tail%0A            cat = c%0A%0A            # fix nordmensa inconsistency between price list and menu%0A            if mensa == 'Nordmensa':%0A                if %221%22 in cat:%0A                    cat = %22Stamm I Vegetarisch%22%0A                elif %222%22 in cat:%0A                    cat = %22Stamm II%22%0A                elif %223%22 in cat:%0A                    cat = %22Stamm III%22%0A%0A            meal = tr.xpath(%22.//span%5B@class='ext_sits_essen'%5D/strong%22)%0A            if not meal or meal%5B0%5D.text is None:%0A                continue
 %0A   
@@ -2304,10 +2304,10 @@
 ngre
-i
 d
+i
 ents
@@ -2520,14 +2520,8 @@
 te, 
-price_
 cat,
@@ -2536,32 +2536,39 @@
 %0Adef mensa_feed(
+mensa, 
 this_week_uri, n
@@ -2842,16 +2842,23 @@
 t_meals(
+mensa, 
 this_wee
@@ -2859,39 +2859,24 @@
 is_week_uri,
- prices.keys(),
  parser),%0A  
@@ -2911,16 +2911,23 @@
 t_meals(
+mensa, 
 next_wee
@@ -2936,23 +2936,8 @@
 uri,
- prices.keys(),
  par
@@ -2972,24 +2972,52 @@
 l in meals:%0A
+        p = prices.get(cat)%0A
         buil
@@ -3057,18 +3057,8 @@
 es=p
-rices%5Bcat%5D
 , ro
@@ -3562,16 +3562,22 @@
 sa_feed(
+name, 
 this_wee

fix some issues with the Nordmensa