Merge branch 'main' into pages
This commit is contained in:
@@ -118,15 +118,36 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"from bs4 import BeautifulSoup\n",
|
"from bs4 import BeautifulSoup\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"class HtmlTransformerUtil:\n",
|
||||||
|
" \n",
|
||||||
|
" def applySoupTransformerToFile(self, file, soupTransformer):\n",
|
||||||
|
" self._writeSoup(soupTransformer(self._readSoup(file)), file)\n",
|
||||||
|
"\n",
|
||||||
|
" def _readSoup(self, file):\n",
|
||||||
|
" with open(file) as fp:\n",
|
||||||
|
" soup = BeautifulSoup(fp, 'lxml')\n",
|
||||||
|
" return soup\n",
|
||||||
|
"\n",
|
||||||
|
" def _writeSoup(self, soup, file):\n",
|
||||||
|
" with open(file, \"w\") as fp:\n",
|
||||||
|
" fp.write(str(soup)) \n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "af101279",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
"def saveLastUpdatedIntensivstationen(lastUpdated):\n",
|
"def saveLastUpdatedIntensivstationen(lastUpdated):\n",
|
||||||
" file = \"../../docs/intensivstationen.html\"\n",
|
" def setLastUpdated(soup):\n",
|
||||||
" with open(file) as fp:\n",
|
" soup.find(id = \"Datenstand\").string.replace_with(lastUpdated.strftime(DateProvider.INTENSIVSTATIONEN_DATE_FORMAT))\n",
|
||||||
" soup = BeautifulSoup(fp, 'lxml')\n",
|
" return soup\n",
|
||||||
"\n",
|
"\n",
|
||||||
" soup.find(id = \"Datenstand\").string.replace_with(lastUpdated.strftime(DateProvider.INTENSIVSTATIONEN_DATE_FORMAT))\n",
|
" HtmlTransformerUtil().applySoupTransformerToFile(\n",
|
||||||
"\n",
|
" file = \"../../docs/intensivstationen.html\",\n",
|
||||||
" with open(file, \"w\") as fp:\n",
|
" soupTransformer = setLastUpdated)"
|
||||||
" fp.write(str(soup))"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -760,7 +781,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"kreisValues = timeSeries['Kreis'].drop_duplicates().values"
|
"kreisValues = sorted(timeSeries['Kreis'].drop_duplicates().values)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -770,18 +791,165 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"def printKreisOptions(kreisValues):\n",
|
"def getKreisOptions(kreisValues):\n",
|
||||||
" for kreis in kreisValues:\n",
|
" return [getKreisOption(kreis) for kreis in kreisValues]\n",
|
||||||
" printKreisOption(kreis)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"def printKreisOption(kreis):\n",
|
"def getKreisOption(kreis):\n",
|
||||||
" print('<option value=\"{kreis}\">{kreis}</option>'.format(kreis = kreis))"
|
" return '<option value=\"{kreis}\">{kreis}</option>'.format(kreis = kreis)\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 15,
|
"execution_count": null,
|
||||||
"id": "33a4b725",
|
"id": "9c38ca16",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"kreisOptions = ['<option selected=\"\" value=\"de\">Alle Landkreise</option>'] + getKreisOptions(kreisValues)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "9eb453d0",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from bs4 import BeautifulSoup\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"class KreisOptionsSetter:\n",
|
||||||
|
"\n",
|
||||||
|
" def setKreisOptions(self, html, options):\n",
|
||||||
|
" soup = self._setKreisOptions(self._parse(html), self._parseOptions(options))\n",
|
||||||
|
" return str(soup)\n",
|
||||||
|
"\n",
|
||||||
|
" def _setKreisOptions(self, soup, options):\n",
|
||||||
|
" kreisSelect = soup.find(id = \"kreisSelect\")\n",
|
||||||
|
" kreisSelect.clear()\n",
|
||||||
|
" for option in options:\n",
|
||||||
|
" kreisSelect.append(option)\n",
|
||||||
|
" return soup\n",
|
||||||
|
"\n",
|
||||||
|
" def _parseOptions(self, options):\n",
|
||||||
|
" return [self._parse(option).option for option in options]\n",
|
||||||
|
"\n",
|
||||||
|
" def _parse(self, html):\n",
|
||||||
|
" return BeautifulSoup(html, 'lxml')\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "e4f8fa80",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import unittest\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"class KreisOptionsSetterTest(unittest.TestCase):\n",
|
||||||
|
"\n",
|
||||||
|
" def test_setKreisOptions(self):\n",
|
||||||
|
" # Given\n",
|
||||||
|
" kreisOptionsSetter = KreisOptionsSetter()\n",
|
||||||
|
"\n",
|
||||||
|
" # When\n",
|
||||||
|
" htmlActual = kreisOptionsSetter.setKreisOptions(\n",
|
||||||
|
" html = '''\n",
|
||||||
|
" <html>\n",
|
||||||
|
" <body>\n",
|
||||||
|
" <p>Test<p/>\n",
|
||||||
|
" <select id=\"kreisSelect\" name=\"kreis\">\n",
|
||||||
|
" <option selected=\"\" value=\"de\">Alle Landkreise</option>\n",
|
||||||
|
" <option value=\"Ahrweiler\">Ahrweiler</option>\n",
|
||||||
|
" <option value=\"Wiesbaden, Landeshauptstadt\">Wiesbaden, Landeshauptstadt</option>\n",
|
||||||
|
" <option value=\"Aichach-Friedberg\">Aichach-Friedberg</option>\n",
|
||||||
|
" </select>\n",
|
||||||
|
" </body>\n",
|
||||||
|
" </html>\n",
|
||||||
|
" ''',\n",
|
||||||
|
" options = [\n",
|
||||||
|
" '<option selected=\"\" value=\"de\">Alle Landkreise</option>',\n",
|
||||||
|
" '<option value=\"Ahrweiler\">Ahrweiler</option>',\n",
|
||||||
|
" '<option value=\"Aichach-Friedberg\">Aichach-Friedberg</option>'])\n",
|
||||||
|
"\n",
|
||||||
|
" # Then\n",
|
||||||
|
" assertEqualHTML(\n",
|
||||||
|
" htmlActual,\n",
|
||||||
|
" '''\n",
|
||||||
|
" <html>\n",
|
||||||
|
" <body>\n",
|
||||||
|
" <p>Test<p/>\n",
|
||||||
|
" <select id=\"kreisSelect\" name=\"kreis\">\n",
|
||||||
|
" <option selected=\"\" value=\"de\">Alle Landkreise</option>\n",
|
||||||
|
" <option value=\"Ahrweiler\">Ahrweiler</option>\n",
|
||||||
|
" <option value=\"Aichach-Friedberg\">Aichach-Friedberg</option>\n",
|
||||||
|
" </select>\n",
|
||||||
|
" </body>\n",
|
||||||
|
" </html>\n",
|
||||||
|
" ''')\n",
|
||||||
|
"\n",
|
||||||
|
"# adapted from https://stackoverflow.com/questions/8006909/pretty-print-assertequal-for-html-strings\n",
|
||||||
|
"def assertEqualHTML(string1, string2, file1='', file2=''):\n",
|
||||||
|
" u'''\n",
|
||||||
|
" Compare two unicode strings containing HTML.\n",
|
||||||
|
" A human friendly diff goes to logging.error() if they\n",
|
||||||
|
" are not equal, and an exception gets raised.\n",
|
||||||
|
" '''\n",
|
||||||
|
" from bs4 import BeautifulSoup as bs\n",
|
||||||
|
" import difflib\n",
|
||||||
|
"\n",
|
||||||
|
" def short(mystr):\n",
|
||||||
|
" max = 20\n",
|
||||||
|
" if len(mystr) > max:\n",
|
||||||
|
" return mystr[:max]\n",
|
||||||
|
" return mystr\n",
|
||||||
|
" p = []\n",
|
||||||
|
" for mystr, file in [(string1, file1), (string2, file2)]:\n",
|
||||||
|
" if not isinstance(mystr, str):\n",
|
||||||
|
" raise Exception(u'string ist not unicode: %r %s' %\n",
|
||||||
|
" (short(mystr), file))\n",
|
||||||
|
" soup = bs(mystr)\n",
|
||||||
|
" pretty = soup.prettify()\n",
|
||||||
|
" p.append(pretty)\n",
|
||||||
|
" if p[0] != p[1]:\n",
|
||||||
|
" for line in difflib.unified_diff(p[0].splitlines(), p[1].splitlines(), fromfile=file1, tofile=file2):\n",
|
||||||
|
" display(line)\n",
|
||||||
|
" display(p[0], ' != ', p[1])\n",
|
||||||
|
" raise Exception('Not equal %s %s' % (file1, file2))\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "e80117e5",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"unittest.main(argv = [''], verbosity = 2, exit = False)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "403f8b7b",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from bs4 import BeautifulSoup\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def saveKreisOptions(kreisOptions):\n",
|
||||||
|
" HtmlTransformerUtil().applySoupTransformerToFile(\n",
|
||||||
|
" file = \"../../docs/intensivstationen.html\",\n",
|
||||||
|
" soupTransformer = lambda soup: BeautifulSoup(KreisOptionsSetter().setKreisOptions(html = str(soup), options = kreisOptions), 'lxml'))\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "5dd8d864",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
@@ -1176,9 +1344,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"kreisValues = sorted(kreisValues)\n",
|
"saveKreisOptions(kreisOptions)"
|
||||||
"# FK-TODO: die folgenden Optionen in der Datei intensivstationen.html in das select-Element nach \"Alle Landkreise\" einsetzen \n",
|
|
||||||
"printKreisOptions(kreisValues)"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user