Add python code
This commit is contained in:
		
							parent
							
								
									32e9302a10
								
							
						
					
					
						commit
						01d4a8b415
					
				
					 5 changed files with 212 additions and 0 deletions
				
			
		
							
								
								
									
										17
									
								
								app.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
from flask import Flask, abort
 | 
			
		||||
 | 
			
		||||
import parsers
 | 
			
		||||
import utils
 | 
			
		||||
 | 
			
		||||
app = Flask(__name__)
 | 
			
		||||
 | 
			
		||||
parsers.define_parsers()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route('/mensa/<parser_name>/<mensa_name>')
 | 
			
		||||
def mensa(parser_name, mensa_name):
 | 
			
		||||
    try:
 | 
			
		||||
        return utils.get_parser(parser_name).parse(mensa_name)
 | 
			
		||||
    except KeyError:
 | 
			
		||||
        abort(404)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								parsers/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								parsers/__init__.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
from parsers import tuebingen
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def define_parsers():
 | 
			
		||||
    tuebingen.define_parsers()
 | 
			
		||||
							
								
								
									
										76
									
								
								parsers/tuebingen.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								parsers/tuebingen.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
{
 | 
			
		||||
  "name": "tuebingen-hohenheim",
 | 
			
		||||
  "base_url": "https://www.my-stuwe.de/wp-json/mealplans/v1/canteens/",
 | 
			
		||||
  "canteens": [
 | 
			
		||||
    {
 | 
			
		||||
      "id": "mensa-shedhalle",
 | 
			
		||||
      "suffix": "611",
 | 
			
		||||
      "name": "Mensa Shedhalle",
 | 
			
		||||
      "street": "Schlachthausstraße 13",
 | 
			
		||||
      "city": "72074 Tübingen"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": "mensa-morgenstelle",
 | 
			
		||||
      "suffix": "621",
 | 
			
		||||
      "name": "Mensa Morgenstelle",
 | 
			
		||||
      "street": "Auf der Morgenstelle 26",
 | 
			
		||||
      "city": "72076 Tübingen"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": "mensa-prinz_karl",
 | 
			
		||||
      "suffix": "623",
 | 
			
		||||
      "name": "Mensa Prinz Karl",
 | 
			
		||||
      "street": "Hafengasse 6",
 | 
			
		||||
      "city": "72070 Tübingen"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": "mensa-hohenheim",
 | 
			
		||||
      "suffix": "661",
 | 
			
		||||
      "name": "Mensa Hohenheim",
 | 
			
		||||
      "street": "Garbenstraße 29",
 | 
			
		||||
      "city": "70599 Stuttgart"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": "mensa-reutlingen",
 | 
			
		||||
      "suffix": "631",
 | 
			
		||||
      "name": "Mensa Reutlingen",
 | 
			
		||||
      "street": "Alteburgstraße 150 Gebäude 7",
 | 
			
		||||
      "city": "72762 Reutlingen"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": "mensa-nuertingen",
 | 
			
		||||
      "suffix": "665",
 | 
			
		||||
      "name": "Mensa Nürtingen",
 | 
			
		||||
      "street": "Neckarsteige 6-10",
 | 
			
		||||
      "city": "72622 Nürtingen"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": "mensa-rottenburg",
 | 
			
		||||
      "suffix": "655",
 | 
			
		||||
      "name": "Mensa Rottenburg",
 | 
			
		||||
      "street": "Schadenweiler Hof 1",
 | 
			
		||||
      "city": "72108 Rottenburg"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": "mensa-albstadt",
 | 
			
		||||
      "suffix": "645",
 | 
			
		||||
      "name": "Mensa Albstadt",
 | 
			
		||||
      "street": "Jakobstraße 1",
 | 
			
		||||
      "city": "72458 Albstadt"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": "mensa-sigmaringen",
 | 
			
		||||
      "suffix": "640",
 | 
			
		||||
      "name": "Mensa Sigmaringen",
 | 
			
		||||
      "street": "Anton-Günther-Straße 51",
 | 
			
		||||
      "city": " 72488 Sigmaringen"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "id": "cafeteria-morgenstelle",
 | 
			
		||||
      "suffix": "724",
 | 
			
		||||
      "name": "Cafeteria Morgenstelle",
 | 
			
		||||
      "street": "Auf der Morgenstelle 26",
 | 
			
		||||
      "city": "72076 Tübingen"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										93
									
								
								parsers/tuebingen.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								parsers/tuebingen.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
import json
 | 
			
		||||
import re
 | 
			
		||||
from urllib.request import urlopen, Request
 | 
			
		||||
 | 
			
		||||
from pyopenmensa.feed import LazyBuilder
 | 
			
		||||
 | 
			
		||||
from utils import Parser
 | 
			
		||||
 | 
			
		||||
allergens = {
 | 
			
		||||
    'Gl-a': 'Weizen',
 | 
			
		||||
    'Gl-b': 'Roggen',
 | 
			
		||||
    'Gl-c': 'Gerste',
 | 
			
		||||
    'Gl-d': 'Hafer',
 | 
			
		||||
    'Gl-e': 'Dinkel',
 | 
			
		||||
    'Nu-a': 'Mandeln',
 | 
			
		||||
    'Ei': 'Eier',
 | 
			
		||||
    'Er': 'Erdnüsse',
 | 
			
		||||
    'So': 'Soja',
 | 
			
		||||
    'Sn': 'Senf',
 | 
			
		||||
    'Kr': 'Krebstiere (Krusten- und Schalentiere)',
 | 
			
		||||
    'Fi': 'Fisch',
 | 
			
		||||
    'ML': 'Milch/Laktose',
 | 
			
		||||
    'Se': 'Sellerie',
 | 
			
		||||
    'Sf': 'Schwefeldioxid und Sulfite',
 | 
			
		||||
    'Sa': 'Sesam',
 | 
			
		||||
    'Lu': 'Lupine',
 | 
			
		||||
    'We': 'Weichtiere',
 | 
			
		||||
    'ALK': 'Alkohol'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
additives = {
 | 
			
		||||
    '1': 'Farbstoff',
 | 
			
		||||
    '2': 'Konservierungsstoff',
 | 
			
		||||
    '3': 'Nitritpökelsalz',
 | 
			
		||||
    '4': 'Antioxidationsmittel',
 | 
			
		||||
    '5': 'Geschmacksverstärker',
 | 
			
		||||
    '6': 'geschwefelt',
 | 
			
		||||
    '7': 'geschwärzt',
 | 
			
		||||
    '8': 'gewachst',
 | 
			
		||||
    '9': 'Süßungsmittel',
 | 
			
		||||
    '10': 'enthält eine Phenylalaninquelle',
 | 
			
		||||
    '11': 'Phosphat'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
legend = {
 | 
			
		||||
    'F': 'Fisch', 'G': 'Geflügel', 'K': 'Kalb',
 | 
			
		||||
    'L': 'Lamm', 'R': 'Rind', 'S': 'Schwein',
 | 
			
		||||
    'W': 'Wild', 'top': 'Empfehlung',
 | 
			
		||||
    'V': 'vegetarisch', 'vegan': 'vegan',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
multiple_whitespaces_regex = re.compile('\\s{2,}')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def parse_url(url, today=False):
 | 
			
		||||
    canteen = LazyBuilder()
 | 
			
		||||
    with urlopen(Request(url, None, {'User-Agent': 'Mozilla/5.0'})) as response:
 | 
			
		||||
        data = json.loads(response.read())
 | 
			
		||||
    if len(data) == 0:
 | 
			
		||||
        return canteen.toXMLFeed()
 | 
			
		||||
    canteen_data = data[list(data)[0]]
 | 
			
		||||
    menus = canteen_data['menus']
 | 
			
		||||
    canteen.name = canteen_data['canteen']
 | 
			
		||||
    canteen.setLegendData(legend)
 | 
			
		||||
 | 
			
		||||
    for menu in menus:
 | 
			
		||||
        canteen.addMeal(menu['menuDate'], menu['menuLine'],
 | 
			
		||||
                        build_menu_name(menu['menu']) if len(menu['menu']) != 0 else menu['menuLine'],
 | 
			
		||||
                        build_allergens_additives(menu['allergens'], menu['additives']),
 | 
			
		||||
                        {'student': menu['studentPrice'], 'pupil': menu['pupilPrice'], 'other': menu['guestPrice']})
 | 
			
		||||
    return canteen.toXMLFeed()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_menu_name(menu):
 | 
			
		||||
    output = ', '.join(menu)
 | 
			
		||||
    output = multiple_whitespaces_regex.sub(' ', output)
 | 
			
		||||
    output = output.replace(' [', '(').replace(']', ')').replace('(vegan)', '')
 | 
			
		||||
    return output
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def build_allergens_additives(raw_allergens, raw_additives):
 | 
			
		||||
    output = [allergens.get(element, element) for element in raw_allergens] + \
 | 
			
		||||
             [additives.get(element, element) for element in raw_additives]
 | 
			
		||||
    return output
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def define_parsers():
 | 
			
		||||
    with open('parsers/tuebingen.json') as canteen_file:
 | 
			
		||||
        canteen_json = json.load(canteen_file)
 | 
			
		||||
 | 
			
		||||
    parser = Parser(canteen_json['name'], handler=parse_url, shared_prefix=canteen_json['base_url'])
 | 
			
		||||
    for canteen in canteen_json['canteens']:
 | 
			
		||||
        parser.define(canteen['id'], canteen['suffix'])
 | 
			
		||||
							
								
								
									
										21
									
								
								utils.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								utils.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
parser_list = {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Parser:
 | 
			
		||||
    sources = {}
 | 
			
		||||
 | 
			
		||||
    def __init__(self, name, handler, shared_prefix: str):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.handler = handler
 | 
			
		||||
        self.shared_prefix = shared_prefix
 | 
			
		||||
        parser_list[name] = self
 | 
			
		||||
 | 
			
		||||
    def define(self, name: str, suffix: str):
 | 
			
		||||
        self.sources[name] = suffix
 | 
			
		||||
 | 
			
		||||
    def parse(self, source: str):
 | 
			
		||||
        return self.handler(self.shared_prefix + self.sources[source])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_parser(parser_name: str) -> Parser:
 | 
			
		||||
    return parser_list[parser_name]
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue