From f4fcf71f305a6100243e059c5cb98a9090d090fc Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 6 May 2024 15:25:38 +0200 Subject: [PATCH] [breaking, api] Removed `/api/get/root` route (#1154) * made sure that `https://nav.tum.de/` does not need `/api/get/root` * removed the root response from the details api * removed the root-handling from the api * removed more stale parts * Fixed formatting mistakes * Fixed data export mistake --- data/compile.py | 4 + data/processors/export.py | 17 +- data/processors/sitemap.py | 5 - openapi.yaml | 285 ++++++++++++--------------------- server/main-api/src/details.rs | 1 - webclient/api_types/index.ts | 97 ++++------- webclient/pages/index.vue | 101 ++++++++++-- 7 files changed, 233 insertions(+), 277 deletions(-) diff --git a/data/compile.py b/data/compile.py index 8fa41def3..0b9ce7090 100644 --- a/data/compile.py +++ b/data/compile.py @@ -120,6 +120,10 @@ def main() -> None: search.add_ranking_combined(data) logging.info("-- 100 Export and generate Sitemap") + # the root entry is somewhat arbitrary + # leaving it here and thus having it delivered by the other apis leads to bad ergonomics + # => we construct the frontpage "manually" with the most popular buildings + data.pop("root") export.export_for_search(data, "output/search_data.json") export.export_for_api(data, "output/api_data.json") sitemap.generate_sitemap() # only for deployments diff --git a/data/processors/export.py b/data/processors/export.py index 76cdd79c6..376a32a66 100644 --- a/data/processors/export.py +++ b/data/processors/export.py @@ -5,6 +5,7 @@ from external.models.common import PydanticConfiguration from utils import TranslatableStr +from utils import TranslatableStr as _ OUTPUT_DIR = Path(__file__).parent.parent / "output" SLUGIFY_REGEX = re.compile(r"[^a-zA-Z0-9-äöüß.]+") @@ -42,21 +43,21 @@ def export_for_search(data: dict, path: str) -> None: """Export a subset of the data for the /search api""" export = [] for _id, entry in data.items(): - # Currently, the "root" entry is excluded from search - if _id == "root": - continue - building_parents_index = len(entry["parents"]) if entry["type"] in {"room", "virtual_room"}: for i, parent in enumerate(entry["parents"]): + if parent == "root": + continue if data[parent]["type"] in {"building", "joined_building"}: building_parents_index = i break # The 'campus name' is the campus of site of this building or room campus_name = None - if entry["type"] not in {"root", "campus", "site"}: + if entry["type"] not in {"campus", "site"}: for parent in entry["parents"]: + if parent == "root": + continue if data[parent]["type"] in {"campus", "site"}: campus = data[parent] campus_name = campus.get("short_name", campus["name"]) @@ -124,8 +125,7 @@ def export_for_api(data: dict, path: str) -> None: """Add some more information about parents to the data and export for the /get/:id api""" export_data = [] for _id, entry in data.items(): - if entry["type"] != "root": - entry.setdefault("maps", {})["default"] = "interactive" + entry.setdefault("maps", {})["default"] = "interactive" entry["aliases"] = [] if arch_name := extract_arch_name(entry): @@ -139,8 +139,9 @@ def export_for_api(data: dict, path: str) -> None: def extract_exported_item(data, entry): """Extract the item that will be finally exported to the api""" + parent_names = [data[p]["name"] if not p == "root" else _("Standorte", "Sites") for p in entry["parents"]] result = { - "parent_names": [data[p]["name"] for p in entry["parents"]], + "parent_names": parent_names, **entry, } if "children" in result: diff --git a/data/processors/sitemap.py b/data/processors/sitemap.py index dcd49049f..883491ae2 100644 --- a/data/processors/sitemap.py +++ b/data/processors/sitemap.py @@ -83,8 +83,6 @@ def _extract_sitemap_data(new_data: list, old_data: list, old_sitemaps: Simplifi # so it's unlikely that we'll hit this limit without adding a lot of # data. But for the case that a new type of entry is introduced, the # sitemap is split into one for rooms and one for the rest. - # Note that the root element is not included, because it just redirects - # to the main page. sitemaps: Sitemaps = { "room": [], "other": [], @@ -93,9 +91,6 @@ def _extract_sitemap_data(new_data: list, old_data: list, old_sitemaps: Simplifi new_data_dict = {entry["id"]: entry for entry in new_data} changed_count = 0 for _id, entry in new_data_dict.items(): - if entry["type"] == "root": - continue - sitemap_name: Literal["room"] | Literal["other"] = entry["type"] if entry["type"] in sitemaps else "other" # Just copied from the webclient. diff --git a/openapi.yaml b/openapi.yaml index 77823f08f..f4de50e74 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -305,9 +305,6 @@ paths: '5304': summary: A normal building value: '5304' - root: - summary: The root entry of the NavigaTUM-data - value: root garching: summary: The garching campus value: garching @@ -338,20 +335,7 @@ paths: content: application/json: schema: - discriminator: - propertyName: type - mapping: - root: RootResponse - room: DetailsResponse - building: DetailsResponse - joined_building: DetailsResponse - area: DetailsResponse - site: DetailsResponse - campus: DetailsResponse - poi: DetailsResponse - oneOf: - - $ref: '#/components/schemas/RootResponse' - - $ref: '#/components/schemas/DetailsResponse' + $ref: '#/components/schemas/DetailsResponse' examples: mi-hs-1: value: @@ -867,9 +851,6 @@ paths: '5304': summary: A normal building value: '5304' - root: - summary: The root entry of the NavigaTUM-data - value: root garching: summary: The garching campus value: garching @@ -1818,53 +1799,111 @@ components: - sections - time_ms DetailsResponse: - allOf: - - $ref: '#/components/schemas/BaseDetailsResponse' - - type: object + type: object + properties: + id: + description: 'The id, that was requested' + type: string + type: + description: The type of the entry + type: string + enum: + - room + - building + - joined_building + - area + - site + - campus + - poi + type_common_name: + description: The type of the entry in a human-readable form + type: string + name: + description: The name of the entry in a human-readable form + type: string + example: '5602.EG.001 (MI HS 1, Friedrich L. Bauer Hörsaal)' + aliases: + description: | + A list of alternative ids for this entry. + + Not to be confused with + - `id` which is the unique identifier or + - `visual-id` which is an alternative identifier for the entry (only displayed in the URL). + type: array + items: + type: string + example: 26503@5406 + parents: + type: array + items: + type: string + description: The ids of the parents. They are ordered as they would appear in a Breadcrumb menu. See parent_names for their actual ids. + examples: + - root + - garching + parent_names: + type: array + items: + type: string + description: The ids of the parents. They are ordered as they would appear in a Breadcrumb menu. See parents for their actual ids. + examples: + - Standorte + - Garching Forschungszentrum + minItems: 1 + uniqueItems: true + props: + $ref: '#/components/schemas/Props' + imgs: + type: array + items: + $ref: '#/components/schemas/ImageInfo' + ranking_factors: + $ref: '#/components/schemas/RankingFactors' + sources: + $ref: '#/components/schemas/DataSources' + redirect_url: + description: | + The url, this item should be displayed at. + Present on both redirects and normal entries, to allow for the common /view/:id path + type: string + example: /room/5602.EG.001 + coords: + $ref: '#/components/schemas/Coordinate' + maps: + $ref: '#/components/schemas/Maps' + sections: + type: object properties: - id: - description: 'The id, that was requested' - type: string - type: - description: The type of the entry - type: string - enum: - - room - - building - - joined_building - - area - - site - - campus - - poi - coords: - $ref: '#/components/schemas/Coordinate' - maps: - $ref: '#/components/schemas/Maps' - sections: - type: object - properties: - buildings_overview: - $ref: '#/components/schemas/BuildingsOverview' - rooms_overview: - $ref: '#/components/schemas/RoomsOverview' - featured_overview: - $ref: '#/components/schemas/FeaturedOverview' - poi: - type: object - properties: - mvg: - type: array - items: - $ref: '#/components/schemas/Station' - minItems: 1 - uniqueItems: true - required: - - mvg + buildings_overview: + $ref: '#/components/schemas/BuildingsOverview' + rooms_overview: + $ref: '#/components/schemas/RoomsOverview' + featured_overview: + $ref: '#/components/schemas/FeaturedOverview' + poi: + type: object + properties: + mvg: + type: array + items: + $ref: '#/components/schemas/Station' + minItems: 1 + uniqueItems: true required: - - id - - type - - coords - - maps + - mvg + required: + - id + - type + - coords + - maps + - type_common_name + - name + - parents + - parent_names + - props + - ranking_factors + - sources + - redirect_url BuildingsOverview: type: object properties: @@ -1960,122 +1999,6 @@ components: required: - id - name - SitesOverview: - description: | - This is a list of all sites, that are available in the system. - It is sorted by the number of rooms in the site, descending. - The first entry is the site with the most importance - type: array - items: - allOf: - - $ref: '#/components/schemas/ChildEntry' - - type: object - properties: - n_visible: - description: | - A recommendation how many of the entries should be displayed by default. - The number is usually from 0-5. - More results might be displayed when clicking "expand". - If this field is not present, then all entries are displayed. - type: integer - format: int64 - example: 6 - minimum: 0 - children: - description: | - A select list of buildings, that are in this site. - Derived from the areatree. - type: array - items: - $ref: '#/components/schemas/ChildEntry' - required: - - n_visible - - children - RootResponse: - allOf: - - $ref: '#/components/schemas/BaseDetailsResponse' - - type: object - properties: - id: - description: 'The id, that was requested' - type: string - enum: - - root - type: - description: The type of the entry - type: string - enum: - - root - sites_overview: - $ref: '#/components/schemas/SitesOverview' - required: - - id - - type - - sites_overview - BaseDetailsResponse: - type: object - properties: - type_common_name: - description: The type of the entry in a human-readable form - type: string - name: - description: The name of the entry in a human-readable form - type: string - example: '5602.EG.001 (MI HS 1, Friedrich L. Bauer Hörsaal)' - aliases: - description: | - A list of alternative ids for this entry. - - Not to be confused with - - `id` which is the unique identifier or - - `visual-id` which is an alternative identifier for the entry (only displayed in the URL). - type: array - items: - type: string - example: 26503@5406 - parents: - type: array - items: - type: string - description: The ids of the parents. They are ordered as they would appear in a Breadcrumb menu. See parent_names for their actual ids. - examples: - - root - - garching - parent_names: - type: array - items: - type: string - description: The ids of the parents. They are ordered as they would appear in a Breadcrumb menu. See parents for their actual ids. - examples: - - Standorte - - Garching Forschungszentrum - minItems: 1 - uniqueItems: true - props: - $ref: '#/components/schemas/Props' - imgs: - type: array - items: - $ref: '#/components/schemas/ImageInfo' - ranking_factors: - $ref: '#/components/schemas/RankingFactors' - sources: - $ref: '#/components/schemas/DataSources' - redirect_url: - description: | - The url, this item should be displayed at. - Present on both redirects and normal entries, to allow for the common /view/:id path - type: string - example: /room/5602.EG.001 - required: - - type_common_name - - name - - parents - - parent_names - - props - - ranking_factors - - sources - - redirect_url CalendarResponse: type: object properties: diff --git a/server/main-api/src/details.rs b/server/main-api/src/details.rs index 7168f0c0c..6f5911a69 100644 --- a/server/main-api/src/details.rs +++ b/server/main-api/src/details.rs @@ -85,7 +85,6 @@ async fn get_alias_and_redirect(conn: &PgPool, query: &str) -> Option<(String, S fn extract_redirect_exact_match(type_: &str, key: &str) -> String { match type_ { - "root" => String::new(), "campus" => format!("/campus/{key}"), "site" | "area" => format!("/site/{key}"), "building" | "joined_building" => format!("/building/{key}"), diff --git a/webclient/api_types/index.ts b/webclient/api_types/index.ts index 3af738f68..ed7a2f3c5 100644 --- a/webclient/api_types/index.ts +++ b/webclient/api_types/index.ts @@ -495,7 +495,7 @@ export type components = { */ readonly time_ms: number; }; - readonly DetailsResponse: components["schemas"]["BaseDetailsResponse"] & { + readonly DetailsResponse: { /** @description The id, that was requested */ readonly id: string; /** @@ -503,6 +503,34 @@ export type components = { * @enum {string} */ readonly type: "room" | "building" | "joined_building" | "area" | "site" | "campus" | "poi"; + /** @description The type of the entry in a human-readable form */ + readonly type_common_name: string; + /** + * @description The name of the entry in a human-readable form + * @example 5602.EG.001 (MI HS 1, Friedrich L. Bauer Hörsaal) + */ + readonly name: string; + /** + * @description A list of alternative ids for this entry. + * + * Not to be confused with + * - `id` which is the unique identifier or + * - `visual-id` which is an alternative identifier for the entry (only displayed in the URL). + */ + readonly aliases?: readonly string[]; + readonly parents: readonly string[]; + readonly parent_names: readonly [string, ...string[]]; + readonly props: components["schemas"]["Props"]; + readonly imgs?: readonly components["schemas"]["ImageInfo"][]; + readonly ranking_factors: components["schemas"]["RankingFactors"]; + readonly sources: components["schemas"]["DataSources"]; + /** + * @description The url, this item should be displayed at. + * Present on both redirects and normal entries, to allow for the common /view/:id path + * + * @example /room/5602.EG.001 + */ + readonly redirect_url: string; readonly coords: components["schemas"]["Coordinate"]; readonly maps: components["schemas"]["Maps"]; readonly sections?: { @@ -579,71 +607,6 @@ export type components = { */ readonly name: string; }; - /** - * @description This is a list of all sites, that are available in the system. - * It is sorted by the number of rooms in the site, descending. - * The first entry is the site with the most importance - */ - readonly SitesOverview: readonly (components["schemas"]["ChildEntry"] & { - /** - * Format: int64 - * @description A recommendation how many of the entries should be displayed by default. - * The number is usually from 0-5. - * More results might be displayed when clicking "expand". - * If this field is not present, then all entries are displayed. - * - * @example 6 - */ - readonly n_visible: number; - /** - * @description A select list of buildings, that are in this site. - * Derived from the areatree. - */ - readonly children: readonly components["schemas"]["ChildEntry"][]; - })[]; - readonly RootResponse: components["schemas"]["BaseDetailsResponse"] & { - /** - * @description The id, that was requested - * @enum {string} - */ - readonly id: "root"; - /** - * @description The type of the entry - * @enum {string} - */ - readonly type: "root"; - readonly sites_overview: components["schemas"]["SitesOverview"]; - }; - readonly BaseDetailsResponse: { - /** @description The type of the entry in a human-readable form */ - readonly type_common_name: string; - /** - * @description The name of the entry in a human-readable form - * @example 5602.EG.001 (MI HS 1, Friedrich L. Bauer Hörsaal) - */ - readonly name: string; - /** - * @description A list of alternative ids for this entry. - * - * Not to be confused with - * - `id` which is the unique identifier or - * - `visual-id` which is an alternative identifier for the entry (only displayed in the URL). - */ - readonly aliases?: readonly string[]; - readonly parents: readonly string[]; - readonly parent_names: readonly [string, ...string[]]; - readonly props: components["schemas"]["Props"]; - readonly imgs?: readonly components["schemas"]["ImageInfo"][]; - readonly ranking_factors: components["schemas"]["RankingFactors"]; - readonly sources: components["schemas"]["DataSources"]; - /** - * @description The url, this item should be displayed at. - * Present on both redirects and normal entries, to allow for the common /view/:id path - * - * @example /room/5602.EG.001 - */ - readonly redirect_url: string; - }; readonly CalendarResponse: { /** @description The entries of the requested */ readonly events: readonly components["schemas"]["CalendarEntry"][]; @@ -958,7 +921,7 @@ export type operations = { /** @description More data about the requested building/room */ 200: { content: { - readonly "application/json": components["schemas"]["RootResponse"] | components["schemas"]["DetailsResponse"]; + readonly "application/json": components["schemas"]["DetailsResponse"]; }; }; /** @description Invalid input */ diff --git a/webclient/pages/index.vue b/webclient/pages/index.vue index 037ab8f52..7ed437958 100644 --- a/webclient/pages/index.vue +++ b/webclient/pages/index.vue @@ -1,14 +1,87 @@