mirror of
https://github.com/iritmaximus/bort.git
synced 2026-10-12 19:13:45 +03:00
can do basic querys from digitransit
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
dist
|
||||
node_modules
|
||||
.env
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"dotenv": "^16.4.5",
|
||||
"nodemon": "^3.1.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.3.3"
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
export interface IResponseRoute {
|
||||
code: string;
|
||||
directionId: number;
|
||||
headsign: string;
|
||||
route: {
|
||||
gtfsId: string;
|
||||
shortName: string;
|
||||
longName: string;
|
||||
mode: string;
|
||||
}
|
||||
}
|
||||
|
||||
export interface IRoute {
|
||||
gtfsId: string;
|
||||
number: string;
|
||||
name: string;
|
||||
direction: number;
|
||||
headsign: string;
|
||||
mode: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const parseRoute = (obj: IResponseRoute): IRoute | undefined => {
|
||||
if (!("route" in obj)) {
|
||||
console.error("No route in parsed object");
|
||||
return;
|
||||
}
|
||||
|
||||
const routeObj = obj.route;
|
||||
const gtfsId = routeObj.gtfsId;
|
||||
const number = routeObj.shortName;
|
||||
const name = routeObj.longName;
|
||||
const direction = obj.directionId;
|
||||
const headsign = obj.headsign;
|
||||
const mode = routeObj.mode;
|
||||
|
||||
const route: IRoute = {
|
||||
gtfsId,
|
||||
number,
|
||||
name,
|
||||
direction,
|
||||
headsign,
|
||||
mode
|
||||
}
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
|
||||
export const isRoute = (obj: any): obj is IRoute => {
|
||||
if (
|
||||
"code" in obj &&
|
||||
"number" in obj &&
|
||||
"name" in obj &&
|
||||
"direction" in obj &&
|
||||
"headsign" in obj &&
|
||||
"mode" in obj
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export default {
|
||||
parseRoute,
|
||||
isRoute
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { IResponseRoute, IRoute, parseRoute } from "./route";
|
||||
|
||||
|
||||
export interface IStop {
|
||||
gtfsId: string;
|
||||
name: string;
|
||||
code: string;
|
||||
routes: IRoute[];
|
||||
}
|
||||
|
||||
export const isStop = (obj: any): obj is IStop => {
|
||||
if (
|
||||
"name" in obj &&
|
||||
"gtfsId" in obj &&
|
||||
"code" in obj &&
|
||||
"routes" in obj
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export const parseStop = (obj: any): IStop | undefined => {
|
||||
if (!obj.patterns) {
|
||||
console.error("Incorrect query response, no patterns", obj);
|
||||
return;
|
||||
}
|
||||
const patterns: IResponseRoute[] = obj.patterns;
|
||||
const routes: IRoute[] = patterns.map(route => {
|
||||
return parseRoute(route);
|
||||
}).filter((route): route is IRoute => route != null);
|
||||
|
||||
// TODO all values are not typechecked
|
||||
const stop: IStop = {
|
||||
gtfsId: obj.gtfsId,
|
||||
name: obj.name,
|
||||
code: obj.code,
|
||||
routes: routes
|
||||
}
|
||||
return stop;
|
||||
}
|
||||
|
||||
export default {
|
||||
isStop,
|
||||
parseStop
|
||||
}
|
||||
+19
-4
@@ -1,5 +1,5 @@
|
||||
import express from "express";
|
||||
import { queryStop, IStop } from "./query";
|
||||
import { queryStopById } from "./query";
|
||||
|
||||
|
||||
const PORT: Number = 5000;
|
||||
@@ -12,9 +12,24 @@ api.get("/", (_req: express.Request, res: express.Response) => {
|
||||
res.send("Moi");
|
||||
});
|
||||
|
||||
api.get("/stops", async (_req, res) => {
|
||||
const stop: IStop = await queryStop(10);
|
||||
res.send(stop);
|
||||
api.get("/bus", async (_req, res) => {
|
||||
const busStop = await queryStopById("HSL:1220106");
|
||||
if (busStop) {
|
||||
res.send(busStop);
|
||||
return;
|
||||
}
|
||||
res.send({"message": "No stops found"});
|
||||
return;
|
||||
});
|
||||
|
||||
api.get("/tram", async (_req, res) => {
|
||||
const tramStop = await queryStopById("HSL:1220419");
|
||||
if (tramStop) {
|
||||
res.send(tramStop);
|
||||
return;
|
||||
}
|
||||
res.send({"message": "No stops found"});
|
||||
return;
|
||||
});
|
||||
|
||||
api.listen(PORT, () => {
|
||||
|
||||
+48
-25
@@ -1,29 +1,14 @@
|
||||
import config from "./utils/config";
|
||||
import { IStop, parseStop } from "./controllers/stop";
|
||||
|
||||
|
||||
const API_KEY: string = "25e625c8546141aa83b21b9ba94d4847";
|
||||
const API_URL_BASE: string = "https://api.digitransit.fi/routing/v1/routers/hsl/index/graphql";
|
||||
const API_URL: string = `${API_URL_BASE}?digitransit-subscription-key=${API_KEY}`;
|
||||
|
||||
export interface IStop {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
const API_URL: string = `${API_URL_BASE}?digitransit-subscription-key=${config.API_KEY}`;
|
||||
|
||||
|
||||
export const queryStop = async (stopId: number): Promise<IStop> => {
|
||||
console.log("Querying the HSL-api for stop", stopId);
|
||||
console.log(API_URL);
|
||||
|
||||
const query: string = `
|
||||
{
|
||||
stops(name: "mäkelänrinne") {
|
||||
gtfsId
|
||||
name
|
||||
code
|
||||
lat
|
||||
lon
|
||||
}
|
||||
}`
|
||||
const queryDigitransit = async (query: string) => {
|
||||
console.log("Querying the HSL-api with query", query);
|
||||
|
||||
const response = await fetch(API_URL, {
|
||||
method: "post",
|
||||
@@ -32,15 +17,53 @@ export const queryStop = async (stopId: number): Promise<IStop> => {
|
||||
},
|
||||
body: JSON.stringify({ query })
|
||||
});
|
||||
|
||||
const parsed_res = await response.json();
|
||||
console.log(parsed_res);
|
||||
return parsed_res.data;
|
||||
}
|
||||
|
||||
|
||||
export const queryStopById = async (stopId: string): Promise<IStop | undefined> => {
|
||||
console.info("Querying the HSL-api for stop", stopId);
|
||||
console.debug(API_URL);
|
||||
|
||||
const query: string = `
|
||||
{
|
||||
stop(id: "${stopId}") {
|
||||
gtfsId
|
||||
name
|
||||
code
|
||||
patterns {
|
||||
code
|
||||
directionId
|
||||
headsign
|
||||
route {
|
||||
gtfsId
|
||||
shortName
|
||||
longName
|
||||
mode
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
const stop: IStop = {
|
||||
id: stopId,
|
||||
name: "TOOO"
|
||||
const response = await queryDigitransit(query);
|
||||
if (!response) {
|
||||
console.error("No response from API");
|
||||
return;
|
||||
}
|
||||
return stop;
|
||||
|
||||
if (!response.stop || !response.stop.patterns) {
|
||||
console.error("Incorrect response from API", response);
|
||||
return;
|
||||
}
|
||||
|
||||
const stop: IStop | undefined = parseStop(response.stop);
|
||||
if (stop) {
|
||||
console.debug("Parsed stop:", stop);
|
||||
return stop;
|
||||
}
|
||||
|
||||
console.error("Failed parsing stop", stop);
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import "dotenv/config";
|
||||
|
||||
|
||||
if (process.env.API_KEY == undefined) {
|
||||
console.error("FATAL ERROR: API_KEY not set");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
export const API_KEY = process.env.API_KEY;
|
||||
|
||||
|
||||
export default { API_KEY };
|
||||
@@ -316,6 +316,11 @@ diff@^4.0.1:
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||
|
||||
dotenv@^16.4.5:
|
||||
version "16.4.5"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
|
||||
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
|
||||
|
||||
ee-first@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
|
||||
Reference in New Issue
Block a user