ICal.js 2.39 KB
const fs = require("fs");

function parseICal(text) {
  const schedules = [];
  let sche = {};
  let reading = false;
  for (const line of text.replace(/\r\n /g, "").split("\r\n")) {
    if (reading) {
      if (line === "END:VEVENT") {
        reading = false;
        schedules.push(sche);
        sche = {};
      } else {
        const i = line.indexOf(":");
        process(sche, line.slice(0, i), line.slice(i + 1));
      }
    } else if (line === "BEGIN:VEVENT") reading = true;
  }
  return schedules;
}

const errArr = [];
function process(sche, k, v) {
  switch (k) {
    case "DTSTART":
      sche.scheType = "time";
      sche.date = getDatestr(v);
      return;
    case "DTEND":
      k = "endTime";
      v = getTimestr_z(v);
      break;
    case "DTSTART;VALUE=DATE":
      sche.scheType = "date";
      k = "date";
      v = getDatestr(v);
      break;
    case "DTEND;VALUE=DATE":
      return;
    case "X-ALT-DESC;FMTTYPE=text/html":
      k = "detail";
      break;
    case "SUMMARY":
      k = "label";
      v = v.substring(0, v.indexOf(" ["));
      break;
    case "UID":
      k = "uid";
      v = v.split("-")[2];
      break;
    case "DTSTAMP":
    case "CLASS":
    case "SEQUENCE":
      return;
    case "DESCRIPTION":
      k = "description";
    case "URL":
      k = "url";
      sche.subjectID = v.substring(v.indexOf("se_") + 3, v.indexOf("&m"));
      break;
    default:
      errArr.push(k);
  }
  sche[k] = v;
}

function insert(str, idxs, char) {
  let nstr = str.substring(0, idxs[0]);
  for (let i = 0; i < idxs.length - 1; i++)
    nstr += char + str.substring(idxs[i], idxs[i + 1]);
  return nstr;
}

/**
 * parse DateString
 * @param {string} str "YYYYMMDDTHHMMSS"
 * @returns {string} "YYYY-MM-DD"
 */
function getDatestr(str) {
  const a = str.substring(0, str.indexOf("T"));
  return insert(a, [4, 6, 8], "-");
}

/**
 * parse ZDateString
 * @param {string} zstr "YYYYMMDDTHHMMSSZ" (UTC)
 * @returns {string} "HH:MM:SS" (UTC+9)
 */
function getTimestr_z(zstr) {
  const it = zstr.indexOf("T");
  const a = zstr.substring(0, it);
  const b = zstr.substring(it + 1, zstr.length - 1);
  const date = new Date(
    insert(a, [4, 6, 8], "-") + "T" + insert(b, [2, 4, 6], ":") + "+00:00"
  );
  return date.toTimeString().substring(0, 8);
}

// const fdata = fs.readFileSync("C:/Users/teddy/Downloads/data.ics", "utf8");
// const jcal = parseICal(fdata);
// console("done");

module.exports = parseICal;