Semi-working signin and timetable
This commit is contained in:
commit
64745479c6
|
@ -0,0 +1,7 @@
|
|||
*
|
||||
!*.*
|
||||
!/**/
|
||||
*.swp
|
||||
*.un~
|
||||
.netrwhist
|
||||
*.json
|
|
@ -0,0 +1,169 @@
|
|||
import httpcore, httpclient, json, strformat, tables, times, uri
|
||||
import elvis
|
||||
|
||||
type
|
||||
Bakalari* = ref object
|
||||
website*: Uri
|
||||
accessToken*: string
|
||||
refreshToken*: string
|
||||
Homework* = object
|
||||
id*: string
|
||||
subject*: string
|
||||
teacher*: string
|
||||
content*: string
|
||||
startTime*: DateTime
|
||||
endTime*: DateTime
|
||||
Message* = object
|
||||
title*: string
|
||||
sender*: string
|
||||
text*: string
|
||||
sentTime*: DateTime
|
||||
Hour* = ref object
|
||||
number*: string
|
||||
beginTime*: string
|
||||
endTime*: string
|
||||
Room* = ref object
|
||||
name*: string
|
||||
abbrev*: string
|
||||
Subject* = ref object
|
||||
name*: string
|
||||
abbrev*: string
|
||||
Teacher* = ref object
|
||||
name*: string
|
||||
abbrev*: string
|
||||
Lesson* = object
|
||||
hour*: Hour
|
||||
room*: Room
|
||||
subject*: Subject
|
||||
teacher*: Teacher
|
||||
Day* = object
|
||||
lessons*: seq[Lesson]
|
||||
dayOfWeek*: int
|
||||
date*: DateTime
|
||||
Timetable* = object
|
||||
days*: seq[Day]
|
||||
|
||||
const
|
||||
iso8601 = initTimeFormat("yyyy-MM-dd'T'HH:mm:sszzz")
|
||||
|
||||
proc newBakalari*(website: Uri, username: string, password: string): Bakalari =
|
||||
new result
|
||||
result.website = website
|
||||
let
|
||||
api = website / "api/login"
|
||||
client = newHttpClient()
|
||||
response = client.post($api, body = &"client_id=ANDR&grant_type=password&username={username}&password={password}")
|
||||
root = response.body.parseJson
|
||||
result.accessToken = root{"access_token"}.getStr
|
||||
result.refreshToken = root{"refresh_token"}.getStr
|
||||
|
||||
proc newBakalari*(website: Uri, refreshToken: string): Bakalari =
|
||||
new result
|
||||
result.website = website
|
||||
let
|
||||
api = website / "api/login"
|
||||
client = newHttpClient()
|
||||
response = client.post($api, body = &"client_id=ANDR&grant_type=refresh_token&refresh_token={refreshToken}")
|
||||
root = response.body.parseJson
|
||||
result.accessToken = root{"access_token"}.getStr
|
||||
result.refreshToken = root{"refresh_token"}.getStr
|
||||
|
||||
func accessToken*(bakalari: Bakalari): string =
|
||||
bakalari.accessToken
|
||||
|
||||
func refreshToken*(bakalari: Bakalari): string =
|
||||
bakalari.refreshToken
|
||||
|
||||
proc renewTokens(bakalari: Bakalari) =
|
||||
let
|
||||
api = bakalari.website / "api/login"
|
||||
client = newHttpClient()
|
||||
response = client.post($api, body = &"client_id=ANDR&grant_type=refresh_token&refresh_token={bakalari.refreshToken}")
|
||||
body = response.body
|
||||
root = body.parseJson
|
||||
bakalari.accessToken = root{"access_token"}.getStr
|
||||
bakalari.refreshToken = root{"refresh_token"}.getStr
|
||||
|
||||
proc getEndpoint*(bakalari: Bakalari, endpoint: string): JsonNode =
|
||||
let
|
||||
api = bakalari.website / "api/3" / endpoint
|
||||
client = newHttpClient(headers = newHttpHeaders {
|
||||
"Authorization": "Bearer " & bakalari.accessToken,
|
||||
})
|
||||
response = client.get($api)
|
||||
body = response.body
|
||||
bakalari.renewTokens
|
||||
result = body.parseJson
|
||||
|
||||
proc postEndpoint*(bakalari: Bakalari, endpoint: string): JsonNode =
|
||||
let
|
||||
api = bakalari.website / "api/3" / endpoint
|
||||
client = newHttpClient(headers = newHttpHeaders {
|
||||
"Authorization": "Bearer " & bakalari.accessToken,
|
||||
})
|
||||
response = client.post($api)
|
||||
body = response.body
|
||||
bakalari.renewTokens
|
||||
result = body.parseJson
|
||||
|
||||
iterator homework*(bakalari: Bakalari): Homework =
|
||||
let root = bakalari.getEndpoint("homeworks")
|
||||
for node in root{"Homeworks"}.getElems:
|
||||
yield Homework(
|
||||
id: node{"ID"}.getStr,
|
||||
subject: node{"Subject"}{"Name"}.getStr,
|
||||
teacher: node{"Teacher"}.getStr,
|
||||
content: node{"Content"}.getStr,
|
||||
startTime: node{"DateStart"}.getStr.parse(iso8601),
|
||||
endTime: node{"DateEnd"}.getStr.parse(iso8601),
|
||||
)
|
||||
|
||||
iterator messages*(bakalari: Bakalari): Message =
|
||||
let root = bakalari.postEndpoint("komens/messages/received")
|
||||
for node in root{"Messages"}.getElems:
|
||||
yield Message(
|
||||
title: node{"Title"}.getStr,
|
||||
sender: node{"Sender"}{"Name"}.getStr,
|
||||
text: node{"Text"}.getStr,
|
||||
sentTime: node{"SentDate"}.getStr.parse(iso8601)
|
||||
)
|
||||
|
||||
proc timetable*(bakalari: Bakalari, permanent: bool): Timetable =
|
||||
let root = bakalari.getEndpoint(permanent ? "timetable/permanent" ! "timetable/actual")
|
||||
var hours: Table[int, Hour]
|
||||
for hourNode in root{"Hours"}:
|
||||
hours[hourNode{"Id"}.getInt] = Hour(
|
||||
number: hourNode{"Caption"}.getStr,
|
||||
beginTime: hourNode{"BeginTime"}.getStr,
|
||||
endTime: hourNode{"EndTime"}.getStr,
|
||||
)
|
||||
var rooms: Table[string, Room]
|
||||
for roomNode in root{"Rooms"}:
|
||||
rooms[roomNode{"Id"}.getStr] = Room(
|
||||
name: roomNode{"Name"}.getStr,
|
||||
abbrev: roomNode{"Abbrev"}.getStr,
|
||||
)
|
||||
var subjects: Table[string, Subject]
|
||||
for subjectNode in root{"Subjects"}:
|
||||
subjects[subjectNode{"Id"}.getStr] = Subject(
|
||||
name: subjectNode{"Name"}.getStr,
|
||||
abbrev: subjectNode{"Abbrev"}.getStr,
|
||||
)
|
||||
var teachers: Table[string, Teacher]
|
||||
for teacherNode in root{"Teachers"}:
|
||||
teachers[teacherNode{"Id"}.getStr] = Teacher(
|
||||
name: teacherNode{"Name"}.getStr,
|
||||
abbrev: teacherNode{"Abbrev"}.getStr,
|
||||
)
|
||||
for dayNode in root{"Days"}:
|
||||
var day: Day
|
||||
for lessonNode in dayNode{"Atoms"}:
|
||||
var lesson: Lesson
|
||||
lesson.hour = hours[lessonNode{"HourId"}.getInt]
|
||||
lesson.subject = subjects[lessonNode{"SubjectId"}.getStr]
|
||||
lesson.teacher = teachers[lessonNode{"TeacherId"}.getStr]
|
||||
lesson.room = rooms[lessonNode{"RoomId"}.getStr]
|
||||
day.lessons.add lesson
|
||||
day.dayOfWeek = dayNode{"DayOfWeek"}.getInt
|
||||
day.date = dayNode{"Date"}.getStr.parse(iso8601)
|
||||
result.days.add day
|
|
@ -0,0 +1,62 @@
|
|||
import json, os, times, unicode, uri
|
||||
import cligen
|
||||
import bakalari
|
||||
|
||||
type
|
||||
Config = object
|
||||
website: string
|
||||
username: string
|
||||
refreshToken: string
|
||||
|
||||
const
|
||||
defaultConfigFile = getConfigDir() / "bk.json"
|
||||
|
||||
proc loadConfig(configFile = defaultConfigFile): Config =
|
||||
defaultConfigFile.readFile.parseJson.to(Config)
|
||||
|
||||
proc saveConfig(configFile = defaultConfigFile, config: Config) =
|
||||
configFile.writeFile((%*config).pretty)
|
||||
|
||||
proc signin(
|
||||
website: string,
|
||||
username: string,
|
||||
password: string,
|
||||
configFile = defaultConfigFile,
|
||||
) =
|
||||
let
|
||||
bakalari = newBakalari(website.parseUri, username, password)
|
||||
config = Config(
|
||||
website: website,
|
||||
username: username,
|
||||
refreshToken: bakalari.refreshToken,
|
||||
)
|
||||
configFile.saveConfig(config)
|
||||
|
||||
proc rozvrh(
|
||||
configFile = defaultConfigFile,
|
||||
date = "",
|
||||
oneDay = false,
|
||||
permanent = false,
|
||||
) =
|
||||
var config = configFile.loadConfig
|
||||
let bakalari = newBakalari(config.website.parseUri, config.refreshToken)
|
||||
config.refreshToken = bakalari.refreshToken
|
||||
configFile.saveConfig(config)
|
||||
let timetable = bakalari.timetable(permanent)
|
||||
for day in timetable.days:
|
||||
stdout.writeLine day.date.format("yyyyMMdd")
|
||||
for lesson in day.lessons:
|
||||
var line = ""
|
||||
line &= lesson.hour.number
|
||||
line &= ". "
|
||||
line &= lesson.hour.beginTime.align(5, '0'.Rune)
|
||||
line &= "-"
|
||||
line &= lesson.hour.endTime.align(5, '0'.Rune)
|
||||
line &= " "
|
||||
line &= lesson.subject.abbrev.align(4)
|
||||
line &= " "
|
||||
line &= lesson.teacher.abbrev.align(4)
|
||||
line &= " "
|
||||
line &= lesson.room.abbrev.align(4)
|
||||
stdout.writeLine line
|
||||
dispatchMulti([signin], [rozvrh])
|
Loading…
Reference in New Issue