Skip to content

Commit

Permalink
Add function to download and update data
Browse files Browse the repository at this point in the history
  • Loading branch information
ruchernchong committed Nov 5, 2023
1 parent 540839a commit 9a9ea4a
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 5 deletions.
Binary file modified bun.lockb
Binary file not shown.
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
},
"devDependencies": {
"@tsconfig/node18": "^18.2.2",
"@types/adm-zip": "^0.5.3",
"@types/d3": "^7.4.2",
"aws-cdk-lib": "2.101.1",
"constructs": "10.2.69",
"prettier": "^3.0.3",
Expand All @@ -21,5 +23,10 @@
},
"workspaces": [
"packages/*"
]
],
"dependencies": {
"adm-zip": "^0.5.10",
"d3": "^7.8.5",
"node-fetch": "^3.3.2"
}
}
8 changes: 8 additions & 0 deletions packages/functions/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const BASE_URL: string = `https://singapore-ev-trends.ruchern.xyz`;

export enum FUEL_TYPE {
DIESEL = "Diesel",
ELECTRIC = "Electric",
OTHERS = "Others",
PETROL = "Petrol",
}
81 changes: 77 additions & 4 deletions packages/functions/src/lambda.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,81 @@
import { ApiHandler } from "sst/node/api";
import fs from "fs";
import fetch from "node-fetch";
import * as d3 from "d3";
import AdmZip from "adm-zip";
import { FUEL_TYPE } from "./config";
import { sortByMake } from "./lib/sortByMake";
import type { Car } from "./types";

export const handler = ApiHandler(async (_evt) => {
return {
statusCode: 200,
body: `Hello world. The time is ${new Date().toISOString()}`,
};
const tempDir: string = "/tmp";
const zipFileName: string = `Monthly New Registration of Cars by Make.zip`;
const zipFilePath: string = `${tempDir}/${zipFileName}`;
const csvFileName: string = `M03-Car_Regn_by_make.csv`;
const csvFilePath: string = `${tempDir}/${csvFileName}`;
const zipUrl: string = `https://datamall.lta.gov.sg/content/dam/datamall/datasets/Facts_Figures/Vehicle Registration/${zipFileName}`;

try {
const response = await fetch(zipUrl)
.then((response) => {
if (!response.ok) {
throw new Error(
`Failed to download the ZIP file: ${response.statusText}`,
);
}
return response.buffer();
})
.then((data) => {
fs.writeFileSync(zipFilePath, data);
})
.catch((error) =>
console.error("Error while downloading the ZIP file:", error),
);

const zip = new AdmZip(zipFilePath);
zip.extractAllTo(`${tempDir}`, true);

const csvData = fs.readFileSync(csvFilePath, "utf-8");

const parsedData = d3.csvParse(csvData);

const electricCars: Car[] = parsedData
.filter(
({ fuel_type, number }) =>
fuel_type === FUEL_TYPE.ELECTRIC && +number !== 0,
)
.reduce((result: Car[], { month, make, fuel_type, number }) => {
const existingCar = result.find(
(car) => car.month === month && car.make === make,
);

if (existingCar) {
existingCar.number += Number(number);
} else {
result.push({
month,
make,
fuel_type,
number: Number(number),
});
}

return result;
}, [])
.map((car) => ({ ...car, number: +car.number }))
.sort(sortByMake);

console.table(electricCars);

return {
statusCode: 200,
body: JSON.stringify(electricCars),
};
} catch (error) {
console.error(error);
return {
statusCode: 500,
body: "Error occurred while processing the ZIP file.",
};
}
});
4 changes: 4 additions & 0 deletions packages/functions/src/lib/sortByMake.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import type { Car } from "../types";

export const sortByMake = (a: Pick<Car, "make">, b: Pick<Car, "make">) =>
a.make.localeCompare(b.make);
19 changes: 19 additions & 0 deletions packages/functions/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FUEL_TYPE } from "../config";

export interface Car {
month: string;
make: string;
fuel_type: FUEL_TYPE | string;
number: number;
selected?: boolean;
}

export type Dataset = {
label: string;
data: number[];
};

export interface ChartDataset extends Dataset {
borderColor: string;
checked: boolean;
}

0 comments on commit 9a9ea4a

Please sign in to comment.