comcigan-parser

Parse timetable data from comcigan.com

Usage no npm install needed!

<script type="module">
  import comciganParser from 'https://cdn.skypack.dev/comcigan-parser';
</script>

README

comcigan-parser

πŸ“˜πŸ•˜ λ³Έ λΌμ΄λΈŒλŸ¬λ¦¬λŠ” Node.js ν™˜κ²½μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” μ»΄μ‹œκ°„ μ•Œλ¦¬λ―Έ μ‹œκ°„ν‘œ νŒŒμ‹± 라이브러리 μž…λ‹ˆλ‹€.
λ³Έ λΌμ΄λΈŒλŸ¬λ¦¬λŠ” μ»΄μ‹œκ°„ ν™ˆνŽ˜μ΄μ§€μ—μ„œ λ“±λ‘λœ ν•™κ΅μ˜ μ‹œκ°„ν‘œ 데이터λ₯Ό νŒŒμ‹±ν•˜μ—¬ μ œκ³΅ν•©λ‹ˆλ‹€.

health npm version npm npm license

맀주 μ›”μš”μΌ 09μ‹œμ— λ³Έ 라이브러리 λ™μž‘ μ—¬λΆ€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€. μœ„ health의 μƒνƒœκ°€ passing이 μ•„λ‹ˆλΌλ©΄ μ»΄μ‹œκ°„ μ‚¬μ΄νŠΈ λ³€κ²½, μ†ŒμŠ€μ½”λ“œ λ³€κ²½ λ“±μ˜ λ¬Έμ œκ°€ λ°œμƒν–ˆλ‹€λŠ” μ˜λ―Έμ΄λ‹ˆ 이슈 전달 λΆ€νƒλ“œλ¦½λ‹ˆλ‹€.

κΈ°λŠ₯

  • 학ꡐλͺ… μž…λ ₯ ν›„ λ°”λ‘œ μ‚¬μš© κ°€λŠ₯
  • ν•™κΈ‰ μ‹œκ°„ν‘œ 데이터 제곡

정보

μ•„λž˜ 두 μ±—λ΄‡μ—μ„œ μ‚¬μš©ν•˜λ˜ μ‹œκ°„ν‘œ νŒŒμ‹± κΈ°λŠ₯을 라이브러리둜 κ°œλ°œν•˜μ˜€μŠ΅λ‹ˆλ‹€.

μ„€μΉ˜ν•˜κΈ°

μ»΄μ‹œκ°„ μ„œλΉ„μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” ν•™κ΅μ˜ μ‹œκ°„ν‘œ 데이터λ₯Ό μ‰½κ²Œ μˆ˜μ§‘ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ»΄μ‹œκ°„μΈ‘μ˜ μ†ŒμŠ€μ½”λ“œ λ³€κ²½μœΌλ‘œ 인해 μ‹œκ°„ν‘œ 데이터 νŒŒμ‹±μ΄ λΆˆκ°€λŠ₯ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ¬Έμ œκ°€ λ°œμƒν•  경우 μ—¬κΈ°λ₯Ό μ°Έκ³ ν•΄μ£Όμ„Έμš”

(주의!) λ³Έ λΌμ΄λΈŒλŸ¬λ¦¬λŠ” λΉ„κ³΅μ‹μ μœΌλ‘œ μ»΄μ‹œκ°„ μ„œλΉ„μŠ€μ˜ 데이터λ₯Ό νŒŒμ‹±ν•˜λ©°, 상업적인 μš©λ„λ‘œ μ‚¬μš©ν•˜λ‹€ λ¬Έμ œκ°€ λ°œμƒν•  경우 λ³Έ 라이브러리 κ°œλ°œμžλŠ” μ±…μž„μ„ 지지 μ•ŠμŠ΅λ‹ˆλ‹€.

npm i comcigan-parser

개발 λ¬Έμ„œ

Timetable

Timetable 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ—¬ μ‚¬μš©ν•©λ‹ˆλ‹€.

λͺ¨λ“ˆμ„ 뢈러였면 Timetable 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.

const Timetable = require('comcigan-parser');
const timetable = new Timetable();

Timetable.init()

μΈμŠ€ν„΄μŠ€ 정보λ₯Ό μ΄ˆκΈ°ν™” ν•©λ‹ˆλ‹€.
μ˜΅μ…˜μ„ μΆ”κ°€ν•˜μ—¬ μ‚¬μš©μž 섀정을 진행할 수 μžˆμŠ΅λ‹ˆλ‹€.

timetable.init(options);
Parameter Type Required
option object X

μ˜΅μ…˜ μ •λ³΄λŠ” μ•„λž˜ ν‘œ μ°Έκ³ 

Option Value default Required
maxGrade number 3 X
cache number 0 X
  • maxGrade: μ΅œλŒ€ 학년을 μ§€μ •ν•©λ‹ˆλ‹€. (μ΄ˆλ“±: 6, 쀑/κ³ λ“±: 3)
  • cache: μ‹œκ°„ν‘œ 데이터 캐싱 μ‹œκ°„(ms)을 μ§€μ •ν•©λ‹ˆλ‹€ (κΈ°λ³Έκ°’: 0 - λΉ„ν™œμ„±)
    • μ‹œκ°„μ„ μ§€μ •ν•˜λ©΄, 데이터 쑰회 μ‹œ μ§€μ •ν•œ μ‹œκ°„λ§ŒνΌ μž„μ‹œλ‘œ λ³΄κ΄€ν•˜κ³  μžˆλ‹€κ°€, 이후 μƒˆλ‘œμš΄ μ‘°νšŒν•  λ•Œ λ³΄κ΄€ν•˜λ˜ κ²°κ³Ό 데이터λ₯Ό μ¦‰μ‹œ λ°˜ν™˜ν•©λ‹ˆλ‹€.
    • μ§€μ •ν•œ 캐싱 μ‹œκ°„μ΄ μ§€λ‚˜λ©΄ μƒˆλ‘œ μˆ˜μ§‘ν•˜λ©°, λ‹€μ‹œ 캐싱 μ‹œκ°„λ§ŒνΌ λ³΄κ΄€ν•©λ‹ˆλ‹€.

Return - Promise<void>


Timetable.search()

학ꡐ 정보λ₯Ό κ²€μƒ‰ν•©λ‹ˆλ‹€.

μ»΄μ‹œκ°„μ— λ“±λ‘λœ 학ꡐ가 아닐 경우 κ²€μƒ‰λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

timetable.search(keyword);
Parameter Type Required
keyword string O

Return - Promise<학ꡐ데이터[]>

학ꡐ λ°μ΄ν„°λŠ” μ—¬κΈ° μ°Έκ³ 


Timetable.setSchool()

μ‹œκ°„ν‘œλ₯Ό 뢈러올 학ꡐλ₯Ό μ§€μ •ν•©λ‹ˆλ‹€. 학ꡐ μ½”λ“œλŠ” 학ꡐ 검색을 톡해 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

timetable.setSchool(schoolCode);
Parameter Type Required
keyword number O

Return - Promise<void>


Timetable.getTimetable()

μ§€μ •ν•œ ν•™κ΅μ˜ μ‹œκ°„ν‘œ 데이터λ₯Ό λΆˆλŸ¬μ˜΅λ‹ˆλ‹€.

timetable.getTimetable();

Return - Promise<μ‹œκ°„ν‘œ>


Timetable.getClassTime()

각 κ΅μ‹œλ³„ μˆ˜μ—… μ‹œμž‘/μ’…λ£Œ μ‹œκ°„μ •λ³΄λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

timetable.getClassTime();

Return - string[]


μ‚¬μš© 방법

Timetable μΈμŠ€ν„΄μŠ€ 생성

comcigan-parser λͺ¨λ“ˆμ„ 뢈러온 ν›„ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
생성 ν›„ λ°˜λ“œμ‹œ init(option)λ₯Ό ν˜ΈμΆœν•˜μ—¬ μ΄ˆκΈ°ν™” ν•©λ‹ˆλ‹€.

const Timetable = require('comcigan-parser');
const timetable = new Timetable();

timetable.init().then(() => {
  // μ΄ˆκΈ°ν™” μ™„λ£Œ..
});

학ꡐ 검색

μ»΄μ‹œκ°„μ— λ“±λ‘λ˜μ–΄μžˆλŠ” 학ꡐλ₯Ό κ²€μƒ‰ν•˜μ—¬ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

검색 κ²°κ³Όκ°€ μ—†λŠ” 경우 μ˜ˆμ™Έκ°€ λ°œμƒν•©λ‹ˆλ‹€.

timetable.search('κ΄‘λͺ…').then((schoolList) => {
  // schoolList
  // [
  //   { _: 24966, region: 'κ²½κΈ°', name: 'κ΄‘λͺ…뢁쀑학ꡐ', code: 74350 },
  //   { _: 24966, region: 'κ²½κΈ°', name: 'κ΄‘λͺ…κ²½μ˜νšŒκ³„κ³ λ“±ν•™κ΅', code: 13209 },
  //   { _: 24966, region: 'κ²½κΈ°', name: 'κ΄‘λͺ…뢁고등학ꡐ', code: 36854 },
  //   { _: 24966, region: 'κ²½κΈ°', name: 'κ΄‘λͺ…고등학ꡐ', code: 31443 },
  //   { _: 24966, region: 'κ²½κΈ°', name: 'κ΄‘λͺ…쀑학ꡐ', code: 31098 }
  // ]
});

학ꡐ μ„€μ •

μ»΄μ‹œκ°„μ— λ“±λ‘λ˜μ–΄μžˆλŠ” 학ꡐλ₯Ό κ²€μƒ‰ν•˜κ³  μΈμŠ€ν„΄μŠ€μ— λ“±λ‘ν•©λ‹ˆλ‹€.

학ꡐ가 μ—¬λŸ¬κ°œ μ‘°νšŒλ˜κ±°λ‚˜ 검색 κ²°κ³Όκ°€ μ—†λŠ” 경우 μ˜ˆμ™Έκ°€ λ°œμƒν•©λ‹ˆλ‹€.

const mySchool = schoolList.find((school) => {
  return school.region === 'κ²½κΈ°' && school.name === 'κ΄‘λͺ…κ²½μ˜νšŒκ³„κ³ λ“±ν•™κ΅';
});

timetable.setSchool(mySchool.code).then(() => {
  // 학ꡐ μ„€μ • μ™„λ£Œ..
});

μ‹œκ°„ν‘œ 쑰회

λ“±λ‘ν•œ ν•™κ΅μ˜ μ‹œκ°„ν‘œ 데이터λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.

timetable.getTimetable().then((result) => {
  console.log(result);

  // result[ν•™λ…„][반][μš”μΌ][κ΅μ‹œ]
  // μš”μΌ: (μ›”: 0 ~ 금: 4)
  // κ΅μ‹œ: 1κ΅μ‹œ(0), 2κ΅μ‹œ(1), 3κ΅μ‹œ(2)..
  // 3ν•™λ…„ 8반 ν™”μš”μΌ 2κ΅μ‹œ μ‹œκ°„ν‘œ
  console.log(result[3][8][1][1]);
});

μˆ˜μ—…μ‹œκ°„ 정보 쑰회

μˆ˜μ—… μ‹œκ°„ 정보λ₯Ό λ°˜ν™˜νž™λ‹ˆλ‹€.

timetable.getClassTime();

ν™œμš© μ˜ˆμ‹œ

const Timetable = require('comcigan-parser');
const timetable = new Timetable();

const schoolFinder = (schoolName, region) => (schoolList) => {
  const targetSchool = schoolList.find((school) => {
    return school.region === region && school.name.includes(schoolName);
  });
  return targetSchool;
};

timetable
  .init({ cache: 1000 * 60 * 60 }) // μΊμ‹œ 1μ‹œκ°„λ™μ•ˆ 보관
  .then(() => timetable.search('κ΄‘λͺ…'))
  .then(schoolFinder('κ΄‘λͺ…κ²½μ˜νšŒκ³„κ³ λ“±ν•™κ΅', 'κ²½κΈ°'))
  .then((school) => timetable.setSchool(school.code))
  .then(() => {
    Promise.all([timetable.getClassTime(), timetable.getTimetable()]).then((res) => {
      console.log(res[0]); // μ‹œκ°„ν‘œ
      console.log(res[1]); // μˆ˜μ—…μ‹œκ°„μ •λ³΄
    });
  });
const Timetable = require('comcigan-parser');
const timetable = new Timetable();

const test = async () => {
  await timetable.init();
  const school = await timetable.search('κ΄‘λͺ…κ²½μ˜νšŒκ³„κ³ λ“±ν•™κ΅');
  await timetable.setSchool(school[0].code);

  // 전ꡐ μ‹œκ°„ν‘œ 정보 쑰회
  const result = await timetable.getTimetable();
  console.log(result);

  // 각 κ΅μ‹œλ³„ μˆ˜μ—… μ‹œμž‘/μ’…λ£Œ μ‹œκ°„ 정보 쑰회
  const time = await timetable.getClassTime();
  console.log(time);
};

데이터 ν˜•μ‹

학ꡐ 데이터

{
  _: 24966, // μ•Œ 수 μ—†λŠ” μ½”λ“œ
  region:'κ²½κΈ°', // 지역
  name: 'κ΄‘λͺ…κ²½μ˜νšŒκ³„κ³ λ“±ν•™κ΅', // 학ꡐλͺ…
  code: 13209 // ν•™κ΅μ½”λ“œ
}

μ‹œκ°„ν‘œ 데이터

{
  "1": {
    // 1ν•™λ…„
    "1": [ // 1반
      [ // μ›”μš”μΌ μ‹œκ°„ν‘œ
        {
          grade: 1,                   // ν•™λ…„
          class: 1,                   // 반
          weekday: 1,                 // μš”μΌ (1: μ›” ~ 5: 금)
          weekdayString: 'μ›”',         // μš”μΌ λ¬Έμžμ—΄
          classTime: 1,              // κ΅μ‹œ
          teacher: '이희*',            // μ„ μƒλ‹˜ 성함
          subject: 'μ‹€μš©λΉ„μ¦ˆλ‹ˆμŠ€μ˜μ–΄'     // κ³Όλͺ©λͺ…
        },
        {
          grade: 1,
          class: 1,
          weekday: 1,
          weekdayString: 'μ›”',
          classTime: 2,
          code: '1606',
          teacher: 'κ°•μ—°*',
          subject: 'μ§„λ‘œν™œλ™'
        }
      ],
      [ν™”μš”μΌμ‹œκ°„ν‘œ],
      [μˆ˜μš”μΌμ‹œκ°„ν‘œ],
      [λͺ©μš”μΌμ‹œκ°„ν‘œ],
      [κΈˆμš”μΌμ‹œκ°„ν‘œ]
    ],
    "2": [ // 2반
      [μ›”μš”μΌμ‹œκ°„ν‘œ],
      [ν™”μš”μΌμ‹œκ°„ν‘œ],
      [μˆ˜μš”μΌμ‹œκ°„ν‘œ],
      [λͺ©μš”μΌμ‹œκ°„ν‘œ],
      [κΈˆμš”μΌμ‹œκ°„ν‘œ]
    ],
    "3": [
      [], [], [], [], []
    ],
    ...
  },
  "2": {
    // 2ν•™λ…„
  },
  "3": {
    // 3ν•™λ…„
  }
}

각 μ‹œκ°„ν‘œ 데이터 ν˜•μ‹

  • 각 μš”μΌ Array μ—λŠ” μ•„λž˜μ™€ 같은 ν˜•μ‹μ˜ 데이터가 ν¬ν•¨λ˜μ–΄μžˆμŒ
[
  {
    grade: 3,                   // ν•™λ…„
    class: 10,                  // 반
    weekday: 1,                 // μš”μΌ (1: μ›” ~ 5: 금)
    weekdayString: 'μ›”',        // μš”μΌ λ¬Έμžμ—΄
    classTime: 1,               // κ΅μ‹œ
    code: '5644',               // μˆ˜μ—… μ½”λ“œ
    teacher: '이희*',            // μ„ μƒλ‹˜ 성함
    subject: 'μ‹€μš©λΉ„μ¦ˆλ‹ˆμŠ€μ˜μ–΄'     // κ³Όλͺ©λͺ…
  },
  {
    grade: 3,
    class: 10,
    weekday: 1,
    weekdayString: 'μ›”',
    classTime: 2,
    teacher: 'κ°•μ—°*',
    subject: 'μ§„λ‘œν™œλ™'
  },
  ...
]

μˆ˜μ—…μ‹œκ°„ 정보

['1(09:10)', '2(10:10)', '3(11:10)', '4(12:10)', '5(13:50)', '6(14:50)', '7(15:50)', '8(16:50)'];

μ‘μš© 방법

timetable.getTimetable().then((result) => {
  // 3ν•™λ…„ 8반 μ‹œκ°„ν‘œ (μ›” ~ 금)
  console.log(result[3][8]);

  // 1ν•™λ…„ 1반 μ›”μš”μΌ μ‹œκ°„ν‘œ
  console.log(result[1][1][0]);

  // 2ν•™λ…„ 5반 κΈˆμš”μΌ 3κ΅μ‹œ μ‹œκ°„ν‘œ
  console.log(result[2][5][4][2]);
});
  • ν•™λ…„, 반의 경우 인덱슀 상관 없이 λ™μΌν•˜κ²Œ μ ‘κ·Ό
    • 예: 1ν•™λ…„ 3반(result[1][3]), 3ν•™λ…„ 9반(result[3][9])
  • μš”μΌ, κ΅μ‹œμ˜ 경우 μΈλ±μŠ€λŠ” 0λΆ€ν„° μ‹œμž‘ν•˜λ―€λ‘œ -1 값을 톡해 μ ‘κ·Ό
    • 예: μ›”μš”μΌ 3κ΅μ‹œ(result[..][..][0][2])

문제 μ‹ κ³ 

μ‹œκ°„ν‘œ νŒŒμ‹±μ΄ λ˜μ§€ μ•Šκ±°λ‚˜ λ¬Έμ œκ°€ λ°œμƒν•œ 경우 이슈λ₯Ό λ‚¨κ²¨μ£Όμ„Έμš”.

변경사항

  • 1.0.0
    • 학ꡐ 검색과 μ„€μ • κΈ°λŠ₯을 뢄리
    • 학ꡐ μ„€μ • 방식 λ³€κ²½ (μžμ„Έν•œ 사항은 μ—¬κΈ° μ°Έμ‘°)
    • 학ꡐ 검색 κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” search λ©”μ†Œλ“œ μΆ”κ°€
    • 검색 κΈ°λŠ₯ 뢄리에 λ”°λ₯Έ setSchool λ©”μ†Œλ“œ μˆ˜μ •
    • λ™μΌν•œ μ΄λ¦„μ˜ 학ꡐ가 μ‘°νšŒλ˜μ—ˆμ„ λ•Œ μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚€λ˜ 둜직 제거 (#12)
  • 0.3.0
    • μ»΄μ‹œκ°„ 변경사항 λŒ€μ‘ (도메인 λ³€κ²½)
    • 더 μ›ν™œν•œ 데이터 μˆ˜μ§‘μ„ μœ„ν•΄ μ½”μ–΄ 둜직 μˆ˜μ •
    • getClassTime() μ‚¬μš©λ²• λ³€κ²½ - 이제 ν”„λΌλ―ΈμŠ€λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€
    • firstNames μ˜΅μ…˜ 제거
    • cache μ˜΅μ…˜ μΆ”κ°€
    • μ‹œκ°„ν‘œ λ°μ΄ν„°μ˜ 속성λͺ… λ³€κ²½ (μ „: class_time, ν›„: classTime)
    • μ‹œκ°„ν‘œ λ°μ΄ν„°μ˜ code κ°’ 제거
  • 0.2.0
    • getClassTime λ©”μ†Œλ“œ μΆ”κ°€ (각 κ΅μ‹œλ³„ μˆ˜μ—… μ‹œμž‘/μ’…λ£Œ μ‹œκ°„ 정보) - μ°Έμ‘°
  • 0.1.1
    • tempSave μ˜΅μ…˜ 문제 μˆ˜μ •
  • 0.1.0
    • tempSave μ˜΅μ…˜ μ‚­μ œ
    • μ‹œκ°„ν‘œ μΆ”μΆœ 데이터 μž„κ³„κ°’ μ˜΅μ…˜ μΆ”κ°€ (μžμ„Έν•œ 사항은 μ—¬κΈ° μ°Έμ‘°)
  • 0.0.3
    • 데이터 νŒŒμ‹± 문제 μˆ˜μ •
  • 0.0.2
    • 개발 λ¬Έμ„œ μΆ”κ°€
    • init의 κΈ°λ³Έ μ˜΅μ…˜ 문제 μˆ˜μ •
  • 0.0.1 - 첫 번째 릴리즈!