Showing
9 changed files
with
130 additions
and
21 deletions
1 | -import * as selenium from 'selenium-webdriver'; | 1 | +const selenium = require('selenium-webdriver') |
2 | -import * as firefox from 'selenium-webdriver/firefox.js' | 2 | +const firefox = require('selenium-webdriver/firefox') |
3 | 3 | ||
4 | /* | 4 | /* |
5 | 5 | ||
... | @@ -39,7 +39,7 @@ ex) | ... | @@ -39,7 +39,7 @@ ex) |
39 | ] | 39 | ] |
40 | */ | 40 | */ |
41 | 41 | ||
42 | -export async function get_schedule(id, pw, target_date) { | 42 | +async function get_schedule(id, pw, target_date) { |
43 | return await using_selenium( async (driver) => { | 43 | return await using_selenium( async (driver) => { |
44 | return await login(driver, id, pw) | 44 | return await login(driver, id, pw) |
45 | .then(async () => { | 45 | .then(async () => { |
... | @@ -53,7 +53,7 @@ export async function get_schedule(id, pw, target_date) { | ... | @@ -53,7 +53,7 @@ export async function get_schedule(id, pw, target_date) { |
53 | }) | 53 | }) |
54 | } | 54 | } |
55 | 55 | ||
56 | -export async function using_selenium(next) { | 56 | +async function using_selenium(next) { |
57 | const option = new firefox.Options() | 57 | const option = new firefox.Options() |
58 | option.addArguments("-headless"); | 58 | option.addArguments("-headless"); |
59 | 59 | ||
... | @@ -67,7 +67,7 @@ export async function using_selenium(next) { | ... | @@ -67,7 +67,7 @@ export async function using_selenium(next) { |
67 | }) | 67 | }) |
68 | } | 68 | } |
69 | 69 | ||
70 | -export async function login(driver, id, pw) { | 70 | +async function login(driver, id, pw) { |
71 | 71 | ||
72 | await driver.get("https://khcanvas.khu.ac.kr/") | 72 | await driver.get("https://khcanvas.khu.ac.kr/") |
73 | 73 | ||
... | @@ -82,7 +82,7 @@ export async function login(driver, id, pw) { | ... | @@ -82,7 +82,7 @@ export async function login(driver, id, pw) { |
82 | return driver | 82 | return driver |
83 | } | 83 | } |
84 | 84 | ||
85 | -export async function load(driver, until) { | 85 | +async function load(driver, until) { |
86 | const start_date = until.toISOString() | 86 | const start_date = until.toISOString() |
87 | 87 | ||
88 | await driver.get(`https://khcanvas.khu.ac.kr/api/v1/planner/items?start_date=${start_date}`); | 88 | await driver.get(`https://khcanvas.khu.ac.kr/api/v1/planner/items?start_date=${start_date}`); |
... | @@ -96,7 +96,7 @@ export async function load(driver, until) { | ... | @@ -96,7 +96,7 @@ export async function load(driver, until) { |
96 | !it.submissions.submitted && it.plannable_type === "assignment").map(it => new Map([['course_name', it.context_name], ['due_date', it.plannable.due_at], ['assignment_name', it.plannable.title], ['points', it.plannable.points_possible]])) | 96 | !it.submissions.submitted && it.plannable_type === "assignment").map(it => new Map([['course_name', it.context_name], ['due_date', it.plannable.due_at], ['assignment_name', it.plannable.title], ['points', it.plannable.points_possible]])) |
97 | } | 97 | } |
98 | 98 | ||
99 | -export async function logout(driver) { | 99 | +async function logout(driver) { |
100 | await driver.get("https://khcanvas.khu.ac.kr/") | 100 | await driver.get("https://khcanvas.khu.ac.kr/") |
101 | 101 | ||
102 | await driver.findElement(selenium.By.xpath('html/body/div[2]/header[2]/div[1]/ul/li[1]/button/div[1]')).click(); | 102 | await driver.findElement(selenium.By.xpath('html/body/div[2]/header[2]/div[1]/ul/li[1]/button/div[1]')).click(); |
... | @@ -110,4 +110,10 @@ export async function logout(driver) { | ... | @@ -110,4 +110,10 @@ export async function logout(driver) { |
110 | 110 | ||
111 | function sleep(ms) { | 111 | function sleep(ms) { |
112 | return new Promise((r) => setTimeout(r, ms)); | 112 | return new Promise((r) => setTimeout(r, ms)); |
113 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
113 | +} | ||
114 | + | ||
115 | +module.exports.get_schedule = get_schedule | ||
116 | +module.exports.using_selenium = using_selenium | ||
117 | +module.exports.login = login | ||
118 | +module.exports.load = load | ||
119 | +module.exports.logout = logout | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | +var express = require('express'); | ||
2 | +const request = require('request'); | ||
3 | +const TARGET_URL = 'https://api.line.me/v2/bot/message/reply' | ||
4 | +const TOKEN = '채널 토큰으로 변경' | ||
5 | +const fs = require('fs'); | ||
6 | +const path = require('path'); | ||
7 | +const HTTPS = require('https'); | ||
8 | +const domain = "도메인 변경" | ||
9 | +const sslport = 23023; | ||
10 | + | ||
11 | +const bodyParser = require('body-parser'); | ||
12 | +var app = express(); | ||
13 | +app.use(bodyParser.json()); | ||
14 | +app.post('/hook', function (req, res) { | ||
15 | + | ||
16 | + var eventObj = req.body.events[0]; | ||
17 | + var source = eventObj.source; | ||
18 | + var message = eventObj.message; | ||
19 | + | ||
20 | + // request log | ||
21 | + console.log('======================', new Date() ,'======================'); | ||
22 | + console.log('[request]', req.body); | ||
23 | + console.log('[request source] ', eventObj.source); | ||
24 | + console.log('[request message]', eventObj.message); | ||
25 | + | ||
26 | + request.post( | ||
27 | + { | ||
28 | + url: TARGET_URL, | ||
29 | + headers: { | ||
30 | + 'Authorization': `Bearer ${TOKEN}` | ||
31 | + }, | ||
32 | + json: { | ||
33 | + "replyToken":eventObj.replyToken, | ||
34 | + "messages":[ | ||
35 | + { | ||
36 | + "type":"text", | ||
37 | + "text":"Hello, user" | ||
38 | + }, | ||
39 | + { | ||
40 | + "type":"text", | ||
41 | + "text":"May I help you?" | ||
42 | + } | ||
43 | + ] | ||
44 | + } | ||
45 | + },(error, response, body) => { | ||
46 | + console.log(body) | ||
47 | + }); | ||
48 | + | ||
49 | + | ||
50 | + res.sendStatus(200); | ||
51 | +}); | ||
52 | + | ||
53 | +try { | ||
54 | + const option = { | ||
55 | + ca: fs.readFileSync('/etc/letsencrypt/live/' + domain +'/fullchain.pem'), | ||
56 | + key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain +'/privkey.pem'), 'utf8').toString(), | ||
57 | + cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain +'/cert.pem'), 'utf8').toString(), | ||
58 | + }; | ||
59 | + | ||
60 | + HTTPS.createServer(option, app).listen(sslport, () => { | ||
61 | + console.log(`[HTTPS] Server is started on port ${sslport}`); | ||
62 | + }); | ||
63 | + } catch (error) { | ||
64 | + console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.'); | ||
65 | + console.log(error); | ||
66 | + } | ||
67 | + | ... | ... |
... | @@ -19,7 +19,7 @@ | ... | @@ -19,7 +19,7 @@ |
19 | "mocha":"^10.0.0", | 19 | "mocha":"^10.0.0", |
20 | "selenium-webdriver":"^4.1.2" | 20 | "selenium-webdriver":"^4.1.2" |
21 | }, | 21 | }, |
22 | - "type":"module", | 22 | + "type":"commonjs", |
23 | "devDependencies":{ | 23 | "devDependencies":{ |
24 | "@types/node":"^17.0.35", | 24 | "@types/node":"^17.0.35", |
25 | "eslint":"^8.16.0" | 25 | "eslint":"^8.16.0" | ... | ... |
schedule_selector.js
0 → 100644
1 | +//@ts-check | ||
2 | +/* eslint-disable no-unused-vars */ | ||
3 | +/* | ||
4 | +[ | ||
5 | + { | ||
6 | + 'course_name': 'name' | ||
7 | + 'due_date': '2022-05-15T14:59:59Z' | ||
8 | + 'assignment_name': '과제이름' | ||
9 | + 'points': 10.0 | ||
10 | + } | ||
11 | +] | ||
12 | +*/ | ||
13 | + | ||
14 | +const ADayForMS = 1000 * 60 * 60 * 24 | ||
15 | + | ||
16 | +export async function is_possible_schedule(date, assignments) { | ||
17 | + const assignments_dates = assignments.map(it => new Date(it.due_date)) | ||
18 | + const is_disqualified = assignments_dates.filter(it => { | ||
19 | + const current_timestamp = date.getTime() | ||
20 | + const target_timestamp = it.getTime() | ||
21 | + | ||
22 | + return current_timestamp > (target_timestamp - ADayForMS) | ||
23 | + }) | ||
24 | + | ||
25 | + if(is_disqualified) { | ||
26 | + return is_disqualified.at(0) | ||
27 | + } else { | ||
28 | + return null | ||
29 | + } | ||
30 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
talk.js
0 → 100644
1 | //@ts-check | 1 | //@ts-check |
2 | //https://github.com/gatoona/AWS-Selenium | 2 | //https://github.com/gatoona/AWS-Selenium |
3 | -import * as canvas from '../khcanvas.js' | ||
4 | -import * as rd from 'readline' | ||
5 | -import * as mocha from 'mocha' | ||
6 | -import process from 'node:process'; | ||
7 | -import util from 'util' | ||
8 | -import { rejects } from 'assert'; | ||
9 | 3 | ||
4 | +const canvas = require('../khcanvas') | ||
5 | +const rd = require('readline') | ||
6 | +const mocha = require('mocha') | ||
7 | +const process = require('node:process') | ||
8 | +const util = require('util') | ||
9 | +const assert = require('assert') | ||
10 | 10 | ||
11 | mocha.describe('khcanvas', () => { | 11 | mocha.describe('khcanvas', () => { |
12 | mocha.it('opening selenium', async () => { | 12 | mocha.it('opening selenium', async () => { |
... | @@ -36,7 +36,7 @@ mocha.describe('khcanvas', () => { | ... | @@ -36,7 +36,7 @@ mocha.describe('khcanvas', () => { |
36 | .then(it => console.log(it)) | 36 | .then(it => console.log(it)) |
37 | .catch(it => { | 37 | .catch(it => { |
38 | console.log(it) | 38 | console.log(it) |
39 | - rejects(it) | 39 | + assert.rejects(it) |
40 | }) | 40 | }) |
41 | }) | 41 | }) |
42 | }); | 42 | }); |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | -import * as mocha from 'mocha' | 1 | +const mocha = require('mocha') |
2 | -import * as weater from '../weather.js' | 2 | +const weater = require('../weather') |
3 | 3 | ||
4 | mocha.describe('weather', () => { | 4 | mocha.describe('weather', () => { |
5 | mocha.it('get tomorrow weather', async () => { | 5 | mocha.it('get tomorrow weather', async () => { | ... | ... |
1 | //@ts-check | 1 | //@ts-check |
2 | /* eslint-disable no-unused-vars */ | 2 | /* eslint-disable no-unused-vars */ |
3 | -import * as axios from 'axios'; | 3 | +const axios = require('axios') |
4 | 4 | ||
5 | 5 | ||
6 | // 최대 7 일간 예보를 반환합니다. 경희대 국제캠퍼스 정문 앞 삼거리 기준으로 호출됩니다. | 6 | // 최대 7 일간 예보를 반환합니다. 경희대 국제캠퍼스 정문 앞 삼거리 기준으로 호출됩니다. |
... | @@ -52,7 +52,7 @@ import * as axios from 'axios'; | ... | @@ -52,7 +52,7 @@ import * as axios from 'axios'; |
52 | "uvi": 7.71 //The maximum value of UV index for the day | 52 | "uvi": 7.71 //The maximum value of UV index for the day |
53 | 53 | ||
54 | */ | 54 | */ |
55 | -export async function get_weather_forecast(date) { | 55 | +async function get_weather_forecast(date) { |
56 | const lat = 37.24764302276268 //위도 | 56 | const lat = 37.24764302276268 //위도 |
57 | const lon = 127.0783992268606 //경도 | 57 | const lon = 127.0783992268606 //경도 |
58 | const api_key = "336ddd01d3d6f78782eed90d3921bc7e" | 58 | const api_key = "336ddd01d3d6f78782eed90d3921bc7e" |
... | @@ -79,4 +79,6 @@ function find_min_index(array) { | ... | @@ -79,4 +79,6 @@ function find_min_index(array) { |
79 | } | 79 | } |
80 | 80 | ||
81 | return lowest_index | 81 | return lowest_index |
82 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
82 | +} | ||
83 | + | ||
84 | +module.exports.get_weather_forecast = get_weather_forecast | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or login to post a comment