hkopendata
Version:
Access different Opendata API and data in Hong Kong
109 lines (100 loc) • 3.48 kB
JavaScript
// https://www.districtcouncils.gov.hk/datagovhk/dataspec/en/dataspec_Attendance_Record_en.pdf
const moment = require("../../moment");
const cmn = require("../../common");
const BASE_URL = "https://www.districtcouncils.gov.hk/datagovhk/psi/Attendance_record_of_DC_members/Attendance_record_of_DC_members_{year}_{lang}.csv";
const VALID = {
lang: /^(en|tc|sc)$/,
year: /^\d{4}$/,
};
const PARAMS = {
lang: "en",
year: "2019"
}
function parseSearchFields(params) {
if ("year" in params) {
let year = parseInt(params.year),
now = moment().year();
if (year < 2019) year = 2019;
if (year > now) year = now;
params.year = year;
}
return params;
}
function validateParameters(params) {
params = parseSearchFields(params);
let result = cmn.ValidateParameters(params, VALID);
if (!result.error) {
result.data = {
...params
}
}
return result;
}
function search(data, opts) {
return new Promise((resolve, reject) => {
let processed = validateParameters({
...PARAMS,
...data
});
if (processed.error) {
reject(processed);
} else {
cmn.CSVFetch(cmn.ReplaceURL(BASE_URL, processed.data))
.then((res) => {
resolve(processData(res))
})
.catch((err) => reject(err))
}
})
}
function processData(data) {
let body = data.body,
result = [],
header = ["district", "period", "meeting", "type", "name", "rate", "remarks"];
body.map(row => {
let item = {},
temp = {};
row.map((v, i) => item[header[i]] = v);
for (let key in item) {
if (key == "district") {
temp[key] = item[key].replace(" and ", " & ");
} else if (key == "period") {
let split = item[key].split("-"),
start = split[0],
end = split[1];
temp.startDate = moment(start, "D.M.YYYY").format("YYYY-MM-DD");
temp.endDate = moment(end, "D.M.YYYY").format("YYYY-MM-DD");
} else if (key == "rate") {
try {
let m = item[key].match(/^(\d+)\/(\d+) \((\d+)%\)$/),
attended = parseInt(m[0]),
total = parseInt(m[1]),
rate = 0;
if (total > 0) rate = attended / total * 100;
temp.attendance = {
attended: attended,
total: total,
rate: `${rate}%`,
};
} catch (e) {
temp.attendance = item[key];
}
} else {
let val = item[key].trim(),
m = val.match(/(\d{4}.\d{1,2}.\d{1,2}.|\d{1,2}.\d{1,2}.\d{2,4})/g);
if (m) {
m.map(v => {
let date = moment(v, ["D.M.YYYY", "YYYY.M.D", ]);
if (date.isValid()) {
val = val.replace(v, date.format("YYYY-MM-DD"));
}
})
}
temp[key] = val;
}
}
result.push(temp);
})
return result.filter(v => typeof v.attendance === "object" && v.attendance.total > 0);
}
module.exports = search;