Skip to content

Commit

Permalink
added menu.matildaplatform.com as data provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaptensanders committed May 31, 2023
1 parent 9654f38 commit 3e01f02
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 15 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Skolmat custom component for the food menu in Swedish schools

## Description
This component is only valid in Sweden. It leverages data from skolmaten.se, webmenu.foodit.se or Matilda to create a sensor entity from a configured data source (url).
This component is only valid in Sweden. It leverages data from skolmaten.se, webmenu.foodit.se or menu.matildaplatform.com to create a sensor entity from a configured data source (url).
The sensor state will be todays available course(es) and the attributes will contain the full menu for the next two weeks.

You can use the sensor as you please or install the lovelace custom card to display the menu for today or for the week (https://github.com/Kaptensanders/skolmat-card)
Expand Down Expand Up @@ -38,3 +38,7 @@ sensor:
2. When you arrive at the page with this weeks menu, copy the url\
Like: `https://webmenu.foodit.se/?r=6&m=617&p=883&c=10023&w=0&v=Week&l=undefined`

#### menu.matildaplatform.com ####
1. Open https://menu.matildaplatform.com/ and find your school by using the search box
2. When you arrive at the page with this weeks menu, copy the url\
Like: `https://menu.matildaplatform.com/meals/week/63fc93fcccb95f5ce5711276_indianberget`
4 changes: 2 additions & 2 deletions custom_components/skolmat/manifest.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"version": "1.2.0",
"version": "1.3.0",
"domain": "skolmat",
"name": "Skolmat",
"issue_tracker": "https://github.com/Kaptensanders/skolmat/issues",
"documentation": "https://github.com/Kaptensanders/skolmat",
"dependencies": [],
"codeowners": ["@kaptensanders"],
"requirements": ["feedparser>=6.0.0"],
"requirements": ["feedparser>=6.0.0", "beautifulsoup4>=4.12.2"],
"iot_class": "cloud_polling"
}

55 changes: 43 additions & 12 deletions custom_components/skolmat/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@
from datetime import datetime, date
from logging import getLogger

import asyncio
import aiohttp
import asyncio, aiohttp
from bs4 import BeautifulSoup
import json


log = getLogger(__name__)

class Menu(ABC):

@staticmethod
def createMenu (url:str):

url = url.rstrip(" /")

if "skolmaten.se" in url:
if SkolmatenMenu.provider in url:
return SkolmatenMenu(url)
elif "foodit.se" in url:
elif FoodItMenu.provider in url:
return FoodItMenu(url)
elif "matildaplatform.com" in url:
elif MatildaMenu.provider in url:
return MatildaMenu(url)
else:
raise Exception("URL not recognized as skolmaten.se, webmenu.foodit.se or matildaplatform.com")
raise Exception(f"URL not recognized as {SkolmatenMenu.provider}, {FoodItMenu.provider} or {MatildaMenu.provider}")


def __init__(self, url:str):
Expand All @@ -39,7 +40,6 @@ async def _loadMenu (self, aiohttp_session):
return

async def loadMenu(self, aiohttp_session):

cur_menu = self.menu
cur_menuToday = self.menuToday

Expand All @@ -54,7 +54,7 @@ async def loadMenu(self, aiohttp_session):
except Exception as err:
self.menu = cur_menu
self.menuToday = cur_menuToday
log.Exception(f"Failed to load {self.provider} menu from {self.url}")
log.exception(f"Failed to load {self.provider} menu from {self.url}")
return False

def appendEntry(self, entryDate:date, courses:list):
Expand Down Expand Up @@ -129,19 +129,50 @@ async def _getFeed(self, aiohttp_session):

async with aiohttp_session.get(f"{self.url}?limit={self._weeks}") as response:
raw_feed = await response.text()
return feedparser.parse(raw_feed)
return feedparser.parse(raw_feed)


async def _loadMenu(self, aiohttp_session):

menuFeed = await self._getFeed(aiohttp_session)
for day in menuFeed["entries"]:

entryDate = datetime(day['published_parsed'][0], day['published_parsed'][1], day['published_parsed'][2]).date()
courses = day['summary'].split('<br />')
self.appendEntry(entryDate, courses)



class MatildaMenu (Menu):
pass
provider = "matildaplatform.com"

def __init__(self, url:str):
# https://menu.matildaplatform.com/meals/week/63fc93fcccb95f5ce5711276_indianberget
super().__init__(url)
self.headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36"}

async def _getWeek(self, aiohttp_session, url):

try:
async with aiohttp_session.get(url, headers=self.headers, raise_for_status=True) as response:
html = await response.text()
soup = BeautifulSoup(html, 'html.parser')
jsonData = soup.select("#__NEXT_DATA__")[0].string
return json.loads(jsonData)["props"]["pageProps"]
except Exception as err:
log.exception(f"Failed to retrieve {url}")
raise


async def _loadMenu(self, aiohttp_session):

w1 = await self._getWeek(aiohttp_session, self.url)
w2 = await self._getWeek(aiohttp_session, "https://menu.matildaplatform.com" + w1["nextURL"])

dayEntries = [*w1["meals"], *w2["meals"]]

for day in dayEntries:
entryDate = datetime.strptime(day["date"], "%Y-%m-%dT%H:%M:%S").date() # 2023-06-02T00:00:00
courses = []
for course in day["courses"]:
courses.append(course["name"])
self.appendEntry(entryDate, courses)

0 comments on commit 3e01f02

Please sign in to comment.