def write_missing_housenumbers( self) -> Tuple[int, int, int, str, List[List[yattag.doc.Doc]]]: """ Calculate a write stat for the house number coverage of a relation. Returns a tuple of: todo street count, todo count, done count, percent and table. """ ongoing_streets, done_streets = self.get_missing_housenumbers() todo_count = 0 table = [] table.append([ util.html_escape(_("Street name")), util.html_escape(_("Missing count")), util.html_escape(_("House numbers")) ]) rows = [] for result in ongoing_streets: # street, only_in_ref row = [] row.append(result[0].to_html()) number_ranges = util.get_housenumber_ranges(result[1]) row.append(util.html_escape(str(len(number_ranges)))) doc = yattag.doc.Doc() if not self.get_config().get_street_is_even_odd( result[0].get_osm_name()): for index, item in enumerate( sorted(number_ranges, key=util.split_house_number_range)): if index: doc.text(", ") doc.asis(util.color_house_number(item).getvalue()) else: util.format_even_odd(number_ranges, doc) row.append(doc) todo_count += len(number_ranges) rows.append(row) # It's possible that get_housenumber_ranges() reduces the # of house numbers, e.g. 2, 4 and # 6 may be turned into 2-6, which is just 1 item. Sort by the 2nd col, which is the new # number of items. table += sorted(rows, reverse=True, key=lambda cells: int(cells[1].getvalue())) done_count = 0 for result in done_streets: number_ranges = util.get_housenumber_ranges(result[1]) done_count += len(number_ranges) if done_count > 0 or todo_count > 0: percent = "%.2f" % (done_count / (done_count + todo_count) * 100) else: percent = "100.00" # Write the bottom line to a file, so the index page show it fast. with self.get_files().get_housenumbers_percent_stream("w") as stream: stream.write(percent) return len(ongoing_streets), todo_count, done_count, percent, table
def test_html_comment(self) -> None: """Tests HTML commenting.""" doc = yattag.doc.Doc() house_numbers = [ util.HouseNumberRange("2*", "foo"), util.HouseNumberRange("4", ""), ] util.format_even_odd(house_numbers, doc) self.assertEqual(doc.getvalue(), '<span style="color: blue;"><abbr title="foo" tabindex="0">2</abbr></span>, 4')
def write_missing_housenumbers( self) -> Tuple[int, int, int, str, List[List[yattag.doc.Doc]]]: """ Calculate a write stat for the house number coverage of a relation. Returns a tuple of: todo street count, todo count, done count, percent and table. """ ongoing_streets, done_streets = self.get_missing_housenumbers() todo_count = 0 table = [] table.append([ util.html_escape(_("Street name")), util.html_escape(_("Missing count")), util.html_escape(_("House numbers")) ]) for result in ongoing_streets: # street_name, only_in_ref row = [] row.append(util.html_escape(result[0])) number_ranges = util.get_housenumber_ranges(result[1]) row.append(util.html_escape(str(len(number_ranges)))) number_range_strings = [i.get_number() for i in number_ranges] doc = yattag.doc.Doc() if not self.get_config().get_street_is_even_odd(result[0]): for index, item in enumerate( sorted(number_range_strings, key=util.split_house_number)): if index: doc.text(", ") doc.asis(util.color_house_number(item).getvalue()) else: util.format_even_odd(number_ranges, doc) row.append(doc) todo_count += len(number_ranges) table.append(row) done_count = 0 for result in done_streets: number_ranges = util.get_housenumber_ranges(result[1]) done_count += len(number_ranges) if done_count > 0 or todo_count > 0: percent = "%.2f" % (done_count / (done_count + todo_count) * 100) else: percent = "100.00" # Write the bottom line to a file, so the index page show it fast. with self.get_files().get_housenumbers_percent_stream("w") as stream: stream.write(percent) return len(ongoing_streets), todo_count, done_count, percent, table
def missing_housenumbers_view_txt(relations: areas.Relations, request_uri: str) -> str: """Expected request_uri: e.g. /osm/missing-housenumbers/ormezo/view-result.txt.""" tokens = request_uri.split("/") relation_name = tokens[-2] relation = relations.get_relation(relation_name) relation.get_config().set_letter_suffix_style(util.LetterSuffixStyle.LOWER) output = "" if not os.path.exists(relation.get_files().get_osm_streets_path()): output += _("No existing streets") elif not os.path.exists(relation.get_files().get_osm_housenumbers_path()): output += _("No existing house numbers") elif not os.path.exists(relation.get_files().get_ref_housenumbers_path()): output += _("No reference house numbers") else: ongoing_streets, _ignore = relation.get_missing_housenumbers() table = [] for result in ongoing_streets: range_list = util.get_housenumber_ranges(result[1]) range_strings = [i.get_number() for i in range_list] # Street name, only_in_reference items. if not relation.get_config().get_street_is_even_odd(result[0]): result_sorted = sorted(range_strings, key=util.split_house_number) row = result[0] + "\t[" + ", ".join(result_sorted) + "]" else: elements = util.format_even_odd(range_list, doc=None) row = result[0] + "\t[" + "], [".join(elements) + "]" table.append(row) table.sort(key=locale.strxfrm) output += "\n".join(table) return output
def get_missing_housenumbers_txt(ctx: context.Context, relation: areas.Relation) -> str: """Gets the cached plain text of the missing housenumbers for a relation.""" output = "" if is_missing_housenumbers_txt_cached(ctx, relation): with relation.get_files().get_housenumbers_txtcache_stream( "rb") as stream: output = util.from_bytes(stream.read()) return output ongoing_streets, _ignore = relation.get_missing_housenumbers() table = [] for result in ongoing_streets: range_list = util.get_housenumber_ranges(result[1]) range_strings = [i.get_number() for i in range_list] # Street name, only_in_reference items. if not relation.get_config().get_street_is_even_odd( result[0].get_osm_name()): result_sorted = sorted(range_strings, key=util.split_house_number) row = result[0].get_osm_name() + "\t[" + ", ".join( result_sorted) + "]" else: elements = util.format_even_odd(range_list, doc=None) row = result[0].get_osm_name() + "\t[" + "], [".join( elements) + "]" table.append(row) table.sort(key=util.get_lexical_sort_key()) output += "\n".join(table) with relation.get_files().get_housenumbers_txtcache_stream("wb") as stream: stream.write(util.to_bytes(output)) return output
def numbered_streets_to_table( self, numbered_streets: util.NumberedStreets ) -> Tuple[List[List[yattag.doc.Doc]], int]: """Turns a list of numbered streets into a HTML table.""" todo_count = 0 table = [] table.append([ util.html_escape(tr("Street name")), util.html_escape(tr("Missing count")), util.html_escape(tr("House numbers")) ]) rows = [] for result in numbered_streets: # street, only_in_ref row = [] row.append(result[0].to_html()) number_ranges = util.get_housenumber_ranges(result[1]) row.append(util.html_escape(str(len(number_ranges)))) doc = yattag.doc.Doc() if not self.get_config().get_street_is_even_odd( result[0].get_osm_name()): for index, item in enumerate( sorted(number_ranges, key=util.split_house_number_range)): if index: doc.text(", ") doc.asis(util.color_house_number(item).getvalue()) else: util.format_even_odd(number_ranges, doc) row.append(doc) todo_count += len(number_ranges) rows.append(row) # It's possible that get_housenumber_ranges() reduces the # of house numbers, e.g. 2, 4 and # 6 may be turned into 2-6, which is just 1 item. Sort by the 2nd col, which is the new # number of items. table += sorted(rows, reverse=True, key=lambda cells: int(cells[1].getvalue())) return table, todo_count
def missing_housenumbers_view_chkl(ctx: context.Context, relations: areas.Relations, request_uri: str) -> Tuple[str, str]: """Expected request_uri: e.g. /osm/missing-housenumbers/ormezo/view-result.chkl.""" tokens = request_uri.split("/") relation_name = tokens[-2] relation = relations.get_relation(relation_name) relation.get_config().set_letter_suffix_style(util.LetterSuffixStyle.LOWER) output = "" if not ctx.get_file_system().path_exists( relation.get_files().get_osm_streets_path()): output += tr("No existing streets") elif not ctx.get_file_system().path_exists( relation.get_files().get_osm_housenumbers_path()): output += tr("No existing house numbers") elif not ctx.get_file_system().path_exists( relation.get_files().get_ref_housenumbers_path()): output += tr("No reference house numbers") else: ongoing_streets, _ignore = relation.get_missing_housenumbers() table = [] for result in ongoing_streets: range_list = util.get_housenumber_ranges(result[1]) # Street name, only_in_reference items. row = "[ ] " if not relation.get_config().get_street_is_even_odd( result[0].get_osm_name()): result_sorted = sorted([i.get_number() for i in range_list], key=util.split_house_number) row += result[0].get_osm_name() + " [" + ", ".join( result_sorted) + "]" table.append(row) else: elements = util.format_even_odd(range_list, doc=None) if len(elements) > 1 and len( range_list) > get_chkl_split_limit(): for element in elements: row = "[ ] " + result[0].get_osm_name( ) + " [" + element + "]" table.append(row) else: row += result[0].get_osm_name() + " [" + "], [".join( elements) + "]" table.append(row) table.sort(key=util.get_lexical_sort_key()) output += "\n".join(table) return output, relation_name
def test_html_multi_odd(self) -> None: """Tests HTML output with multiple odd numbers.""" doc = yattag.Doc() util.format_even_odd(["1", "3"], doc) self.assertEqual(doc.getvalue(), "1, 3")
def test_html(self) -> None: """Tests HTML coloring.""" doc = yattag.Doc() util.format_even_odd(["2*", "4"], doc) self.assertEqual(doc.getvalue(), '<span style="color: blue;">2</span>, 4')
def test_only_even(self) -> None: """Tests when we have even numbers only.""" self.assertEqual(util.format_even_odd(["2", "4"], doc=None), ["2, 4"])
def test_only_odd(self) -> None: """Tests when we have odd numbers only.""" self.assertEqual(util.format_even_odd(["1", "3"], doc=None), ["1, 3"])
def test_happy(self) -> None: """Tests the happy path.""" self.assertEqual(util.format_even_odd(["1", "2"], doc=None), ["1", "2"])