Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fetcher): implement vaksinasi.id db fetcher #806

Merged
merged 17 commits into from Oct 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
c84e78c
feat(fetcher): implement vaksinasi.id db fetcher
togetherwithasteria Oct 9, 2021
5984d61
style(fetcher): sort union type members in fetch-vaccine-database.ts
togetherwithasteria Oct 9, 2021
ebbbaa0
refactor(fetcher): move types of vaksinid fetcher to lib
togetherwithasteria Oct 9, 2021
03c7baf
refactor(fetcher): move the vaksin.id url to the top
togetherwithasteria Oct 9, 2021
fa2c55f
feat(fetcher): fetch vaksinasi.id db in fetch-wbw.ts
togetherwithasteria Oct 10, 2021
d0c21b7
refactor(fetcher): reduce repetition in vaccination types
togetherwithasteria Oct 10, 2021
8b80b67
fix(fetcher): fix program stuck caused by spinner
togetherwithasteria Oct 10, 2021
ccb05a7
refactor(fetcher): transform vaksinid output data to be Contact-compa…
togetherwithasteria Oct 11, 2021
d4d8379
refactor(fetcher): change vaksin.id output to PartialVaccinationProvi…
togetherwithasteria Oct 11, 2021
f35f99b
refactor(fetcher): change vaksin.id output to an object
togetherwithasteria Oct 12, 2021
a7532dd
chore: switch netlify export to yarn fetch-wbw
togetherwithasteria Oct 14, 2021
b56e628
Merge branch 'main' into feat/fetch-vaccination-database
togetherwithasteria Oct 14, 2021
6620521
feat(fetcher): log some info from vaccination db
togetherwithasteria Oct 15, 2021
3f43140
feat(fetcher): log the output text of vaccine.db fetcher
togetherwithasteria Oct 15, 2021
67c64d4
Merge branch 'main' of https://github.com/kawalcovid19/wargabantuwarg…
togetherwithasteria Oct 15, 2021
e94dbfb
fix(fetcher): fix vaksinasi.id fetcher only fetching 4 provinces
togetherwithasteria Oct 15, 2021
d5de61b
refactor(fetcher): remove console.log()s from vaccination fetcher
togetherwithasteria Oct 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions etc/fetchers/__mocks__/vaksinid-locations-aceh.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"data": [
{
"province": "Aceh",
"city": "Kota Banda Aceh",
"title": "UPTD PUSKESMAS KOPELMA DARUSSALAM",
"datestart": "2021-06-24",
"dateend": "2022-03-31",
"timestart": "08:00:00",
"timeend": "12:00:00",
"registration": "Walk-in",
"agerange": [
"Dewasa (18-59 Tahun)",
"Lansia (60-)"
],
"description": "-Senin dan Sabtu (bisa berubah sewaktu-waktu)\n-Dibeikan bagi warga dengan kriteria:\n1.petugas pelayanan publik\n2. Pra lansia &lansia\n3. Masyarakat Banda Aceh di utamakan yang berdomisili di wilayah Puskesmas Kopelma Darussalam,Rukoh,ie masen kayee adang,Lamgugob & Deah raya\n-Membawa KTP\n-informasi tambahan bisa dilihat di akun Instagram https://instagram.com/puskesmaskopelmadarussalam?utm_medium=copy_link",
"link": "https://www.instagram.com/p/CQgFAepnZkQ/?utm_medium=copy_link",
"address": "Jalan Inong Balee No.38 Darussalam Banda Aceh",
"map": "https://goo.gl/maps/9hViESZJ9rYwGypb9",
"isfree": true,
"isvalid": true,
"code": "",
"dateadded": "2021-07-30"
}
]
}
15 changes: 15 additions & 0 deletions etc/fetchers/__mocks__/vaksinid-regions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"data": [
{
"province": "Aceh",
"city": [
"Kota Banda Aceh",
"Kota Sabang",
"Kota Lhokseumawe",
"Kota Langsa",
"Kota Subulussalam",
"Kab. Aceh Selatan"
]
}
]
}
22 changes: 22 additions & 0 deletions etc/fetchers/__mocks__/wbw-vaccination-db.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"Aceh": [
{
"alamat": "Jalan Inong Balee No.38 Darussalam Banda Aceh",
"lokasi": "Kota Banda Aceh",
"buka_waktu": "08:00:00",
"id": "0",
"informasi_2": "-Senin dan Sabtu (bisa berubah sewaktu-waktu)\n-Dibeikan bagi warga dengan kriteria:\n1.petugas pelayanan publik\n2. Pra lansia &lansia\n3. Masyarakat Banda Aceh di utamakan yang berdomisili di wilayah Puskesmas Kopelma Darussalam,Rukoh,ie masen kayee adang,Lamgugob & Deah raya\n-Membawa KTP\n-informasi tambahan bisa dilihat di akun Instagram https://instagram.com/puskesmaskopelmadarussalam?utm_medium=copy_link",
"keterangan": "Lokasi Vaksinasi COVID-19",
"link": "https://www.instagram.com/p/CQgFAepnZkQ/?utm_medium=copy_link",
"map": "https://goo.gl/maps/9hViESZJ9rYwGypb9",
"mulai_tanggal": "2021-06-24",
"penyedia": "UPTD PUSKESMAS KOPELMA DARUSSALAM",
"rentang_umur": ["Dewasa (18-59 Tahun)", "Lansia (60-)"],
"selesai_tanggal": "2022-03-31",
"slug": "uptd-puskesmas-kopelma-darussalam",
"terakhir_update": "2021-07-30",
"tutup_waktu": "12:00:00",
"verifikasi": 1
}
]
}
53 changes: 53 additions & 0 deletions etc/fetchers/__tests__/fetch-vaccination-database.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import fs from "fs";
import path from "path";
import fetchMock from "jest-fetch-mock";
import { fetchVaccinationDatabase } from "../fetch-vaccination-database";

describe("fetchVaksinasiDB", () => {
const writeFileSyncSpy = jest.spyOn(fs, "writeFileSync");

beforeEach(() => {
fetchMock.resetMocks();
writeFileSyncSpy.mockImplementation(() => {});
});

afterEach(() => {
writeFileSyncSpy.mockRestore();
});
it("fetches database from api.vaksinasi.id correctly", async () => {
const mockedResponses: { [url: string]: string } = {
"/regions": fs.readFileSync(
path.resolve(__dirname, "../__mocks__/vaksinid-regions.json"),
"utf-8",
),
"/locations/Aceh": fs.readFileSync(
path.resolve(__dirname, "../__mocks__/vaksinid-locations-aceh.json"),
"utf-8",
),
};

fetchMock.mockResponse(
async (req) =>
mockedResponses[new URL(req.url).pathname] ||
'{ "details":"Not Found" }',
);
await fetchVaccinationDatabase();

expect(fetchMock).toBeCalledTimes(2);

expect(fetchMock).toBeCalledWith("https://api.vaksinasi.id/regions");
expect(fetchMock).toHaveBeenCalledWith(
"https://api.vaksinasi.id/locations/Aceh",
);

expect(writeFileSyncSpy).toHaveBeenCalledTimes(1);
expect(JSON.parse(writeFileSyncSpy.mock.calls[0][1] as string)).toEqual(
JSON.parse(
fs.readFileSync(
path.resolve(__dirname, "../__mocks__/wbw-vaccination-db.json"),
"utf-8",
),
),
);
});
});
57 changes: 57 additions & 0 deletions etc/fetchers/fetch-vaccination-database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import fs from "fs";
import path from "path";
import fetch from "cross-fetch";
import {
VaccinationRegionsResponse,
VaccinationRegion,
VaccinationContact,
} from "../../lib/data/vaccination";
import { getKebabCase } from "../../lib/string-utils";

const vaksinId = "https://api.vaksinasi.id";

export async function fetchVaccinationDatabase() {
togetherwithasteria marked this conversation as resolved.
Show resolved Hide resolved
const regions = (await (
await fetch(`${vaksinId}/regions`)
).json()) as VaccinationRegionsResponse;

const locations: { [province: string]: VaccinationContact[] } = {};

const promisedLocations = [];
for (const { province } of regions.data) {
promisedLocations.push(
fetch(`${vaksinId}/locations/${province}`)
.then((res) => res.json() as unknown as VaccinationRegion)
.then((region) => {
locations[region.data[0].province] = region.data.map((location) => ({
id: `${region.data.findIndex(
(index) => location.title === index.title,
)}`,
keterangan: "Lokasi Vaksinasi COVID-19",
lokasi: location.city,
verifikasi: location.isvalid ? 1 : 0,
penyedia: location.title,
alamat: location.address,
slug: getKebabCase(location.title),
informasi_2: location.description,
terakhir_update: location.dateadded,
rentang_umur: location.agerange,
buka_waktu: location.timestart,
tutup_waktu: location.timeend,
mulai_tanggal: location.datestart,
selesai_tanggal: location.dateend,
link: location.link,
map: location.map,
}));
}),
);
}

await Promise.all(promisedLocations);

const text = JSON.stringify(locations);
fs.writeFileSync(
path.resolve(__dirname, "../../data/wbw-vaccination-database.json"),
text,
);
}
14 changes: 14 additions & 0 deletions etc/fetchers/fetch-wbw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,25 @@ import { toSecond } from "../../lib/string-utils";
import { fetchDatabase } from "./fetch-database";
import { fetchFaqSheets } from "./fetch-faq-sheets";
import { fetchSheets } from "./fetch-sheets";
import { fetchVaccinationDatabase } from "./fetch-vaccination-database";

(function fetchWbw() {
const start = process.hrtime();
const spinner = ora(`${chalk.yellowBright("Fetching all data...")}`).start();

fetchVaccinationDatabase()
.then(() => {
zainfathoni marked this conversation as resolved.
Show resolved Hide resolved
const end = `${toSecond(process.hrtime(start))} seconds`;
spinner.succeed(
`Fetching vaccination database (vaksinasi.id) done in ${chalk.greenBright(
end,
)}`,
);
})
.catch((err) => {
chalk.red(err);
});

fetchFaqSheets()
.then(() => {
const end = `${toSecond(process.hrtime(start))} seconds`;
Expand Down
53 changes: 53 additions & 0 deletions lib/data/vaccination.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Contact } from "./provinces";

type City = `${"Kab." | "Kota"} ${string}`;
type DateString = `${number}-${number}-${number}`;
type TimeString = `${number}:${number}:${number}`;
type VaccinationAgeRange = Array<`${string} (${number}-${
| number
| null} Tahun)`>;

export interface VaccinationRegions {
province: string;
city: Array<City>;
}

export interface VaccinationRegionsResponse {
data: Array<VaccinationRegions>;
}
export interface VaccinationLocation {
province: string;
city: City;
title: string;
datestart: DateString;
dateend: DateString;
timestart: TimeString;
timeend: TimeString;
registration: string;
agerange: VaccinationAgeRange;
description: string;
link: string;
address: string;
map: string;
isFree: boolean;
isvalid: boolean;
code: string;
dateadded: DateString;
}

type _location = VaccinationLocation;
export interface VaccinationRegion {
data: Array<VaccinationLocation>;
}

export interface VaccinationContact extends Contact {
rentang_umur: _location["agerange"];
buka_waktu: _location["timestart"];
tutup_waktu: _location["timeend"];
mulai_tanggal: _location["datestart"];
selesai_tanggal: _location["dateend"];
kode?: _location["code"];
gratis?: _location["isFree"];
map: _location["map"];
link: _location["link"];
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"lint": "eslint \"**/*.{js,jsx,ts,tsx,yml,yaml}\"",
"lint:fix": "eslint --fix \"**/*.{js,jsx,ts,tsx,yml,yaml}\"",
"mirror-box": "ts-node etc/mirror-box.ts",
"netlify-export": "yarn mirror-box && yarn build && next export",
"netlify-export": "yarn fetch-wbw && yarn build && next export",
"prepare": "husky install",
"start": "next start",
"cypress:open": "cypress open",
Expand Down