Skip to content

Commit

Permalink
Improved error handling + calendar, staff info, report card list, doc…
Browse files Browse the repository at this point in the history
…ument list, mail inbox count
  • Loading branch information
Ziggydave1 committed Dec 16, 2023
1 parent 2edd109 commit f833a5d
Show file tree
Hide file tree
Showing 21 changed files with 830 additions and 84 deletions.
7 changes: 6 additions & 1 deletion Sources/SwiftVue/Attendance/AttendanceParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public class AttendanceParser: NSObject, XMLParserDelegate {

public func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
self.parser.abortParsing()
self.error = parseError
if self.error == nil {
self.error = parseError
}
}

public func parser(_ parser: XMLParser, validationErrorOccurred validationError: Error) {
Expand Down Expand Up @@ -64,6 +66,9 @@ public class AttendanceParser: NSObject, XMLParserDelegate {
}

self.periodTotals.append(periodTotal)
case "RT_ERROR":
self.parser.abortParsing()
self.error = SwiftVueError.error(from: attributeDict["ERROR_MESSAGE"])
default:
return
}
Expand Down
40 changes: 40 additions & 0 deletions Sources/SwiftVue/Calendar/EventInfo.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// EventInfo.swift
//
//
// Created by Evan Kaneshige on 12/14/23.
//

import Foundation

public struct EventInfo: Hashable, Codable, Identifiable {
public var id: UUID
public var date: Date
public var title: String
public var dayType: String

public init(id: UUID = UUID(), date: Date, title: String, dayType: String) {
self.id = id
self.date = date
self.title = title
self.dayType = dayType
}

internal init?(attributes: [String: String]) {
guard let dateAttribute = attributes["Date"],
let titleAttribute = attributes["Title"],
let dayTypeAttribute = attributes["DayType"] else {
return nil
}

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "MM/dd/y"

guard let date = dateFormatter.date(from: dateAttribute) else {
return nil
}

self.init(date: date, title: titleAttribute, dayType: dayTypeAttribute)
}
}
48 changes: 48 additions & 0 deletions Sources/SwiftVue/Calendar/StudentCalendar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// StudentCalendar.swift
//
//
// Created by Evan Kaneshige on 12/14/23.
//

import Foundation

public struct StudentCalendar: Hashable, Codable, Identifiable {
public var id: UUID
public var schoolBeginDate: Date
public var schoolEndDate: Date
public var monthBeginDate: Date
public var monthEndDate: Date
public var events: [EventInfo]

public init(id: UUID = UUID(), schoolBeginDate: Date, schoolEndDate: Date, monthBeginDate: Date, monthEndDate: Date, events: [EventInfo]) {
self.id = id
self.schoolBeginDate = schoolBeginDate
self.schoolEndDate = schoolEndDate
self.monthBeginDate = monthBeginDate
self.monthEndDate = monthEndDate
self.events = events
}

internal init?(attributes: [String: String]) {
guard let schoolBeginDateAttribute = attributes["SchoolBegDate"],
let schoolEndDateAttribute = attributes["SchoolEndDate"],
let monthBeginDateAttribute = attributes["MonthBegDate"],
let monthEndDateAttribute = attributes["MonthEndDate"] else {
return nil
}

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "MM/dd/y"

guard let schoolBeginDate = dateFormatter.date(from: schoolBeginDateAttribute),
let schoolEndDate = dateFormatter.date(from: schoolEndDateAttribute),
let monthBeginDate = dateFormatter.date(from: monthBeginDateAttribute),
let monthEndDate = dateFormatter.date(from: monthEndDateAttribute) else {
return nil
}

self.init(schoolBeginDate: schoolBeginDate, schoolEndDate: schoolEndDate, monthBeginDate: monthBeginDate, monthEndDate: monthEndDate, events: [])
}
}
75 changes: 75 additions & 0 deletions Sources/SwiftVue/Calendar/StudentCalendarParser.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// StudentCalendarParser.swift
//
//
// Created by Evan Kaneshige on 12/14/23.
//

import Foundation

public class StudentCalendarParser: NSObject, XMLParserDelegate {
private var studentCalendar: StudentCalendar?
private var eventInfos: [EventInfo] = []

private var parser: XMLParser
private var error: Error?

public init(string: String) {
self.parser = XMLParser(data: Data(string.utf8))
super.init()
self.parser.delegate = self
self.parser.shouldProcessNamespaces = false
self.parser.shouldReportNamespacePrefixes = false
self.parser.shouldResolveExternalEntities = false
}

public func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
self.parser.abortParsing()
if self.error == nil {
self.error = parseError
}
}

public func parser(_ parser: XMLParser, validationErrorOccurred validationError: Error) {
self.parser.abortParsing()
self.error = validationError
}

public func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
switch elementName {
case "CalendarListing":
guard let studentCalendar = StudentCalendar(attributes: attributeDict) else {
self.parser.abortParsing()
return
}

self.studentCalendar = studentCalendar
case "EventList":
guard let eventInfo = EventInfo(attributes: attributeDict) else {
self.parser.abortParsing()
return
}

self.studentCalendar?.events.append(eventInfo)
case "RT_ERROR":
self.parser.abortParsing()
self.error = SwiftVueError.error(from: attributeDict["ERROR_MESSAGE"])
default:
return
}
}

public func parse() throws -> StudentCalendar {
self.parser.parse()

if let error {
throw error
}

if let studentCalendar {
return studentCalendar
} else {
throw SwiftVueError.couldNotParseXML
}
}
}
10 changes: 5 additions & 5 deletions Sources/SwiftVue/DataProvider/DataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ import Foundation

public protocol DataProvider {
func getMessages() async throws -> String
func getCalendar() async throws -> String
func getCalendar() async throws -> StudentCalendar
func getAttendance() async throws -> Attendance
func getGradebook(reportPeriod: Int?) async throws -> Gradebook
func getClassNotes() async throws -> String
func getStudentInfo() async throws -> StudentInfo
func getSchedule(termIndex: Int?) async throws -> Schedule
func getSchoolInfo() async throws -> String
func listReportCards() async throws -> String
func getStaffInfo() async throws -> [StaffInfo]
func listReportCards() async throws -> [ReportCardInfo]
func getReportCard(documentGUID: String) async throws -> String
func listDocuments() async throws -> String
func listDocuments() async throws -> [DocumentInfo]
func getDocument(documentGUID: String) async throws -> String
func getMailInboxCount() async throws -> String
func getMailInboxCount() async throws -> MailInboxCount
func verifyCredentials() async throws -> Bool

init(credentials: Credentials)
Expand Down
10 changes: 5 additions & 5 deletions Sources/SwiftVue/DataProvider/PreviewDataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class PreviewDataProvider: DataProvider {
throw SwiftVueError.notImplemented("PreviewDataProvider.getMessages")
}

public func getCalendar() async throws -> String {
public func getCalendar() async throws -> StudentCalendar {
guard validCredentials else { throw SwiftVueError.invalidCredentials }
throw SwiftVueError.notImplemented("PreviewDataProvider.getCalendar")
}
Expand Down Expand Up @@ -65,12 +65,12 @@ public class PreviewDataProvider: DataProvider {
}
}

public func getSchoolInfo() async throws -> String {
public func getStaffInfo() async throws -> [StaffInfo] {
guard validCredentials else { throw SwiftVueError.invalidCredentials }
throw SwiftVueError.notImplemented("PreviewDataProvider.getSchoolInfo")
}

public func listReportCards() async throws -> String {
public func listReportCards() async throws -> [ReportCardInfo] {
guard validCredentials else { throw SwiftVueError.invalidCredentials }
throw SwiftVueError.notImplemented("PreviewDataProvider.listReportCards")
}
Expand All @@ -80,7 +80,7 @@ public class PreviewDataProvider: DataProvider {
throw SwiftVueError.notImplemented("PreviewDataProvider.getReportCard")
}

public func listDocuments() async throws -> String {
public func listDocuments() async throws -> [DocumentInfo] {
guard validCredentials else { throw SwiftVueError.invalidCredentials }
throw SwiftVueError.notImplemented("PreviewDataProvider.listDocuments")
}
Expand All @@ -90,7 +90,7 @@ public class PreviewDataProvider: DataProvider {
throw SwiftVueError.notImplemented("PreviewDataProvider.getDocument")
}

public func getMailInboxCount() async throws -> String {
public func getMailInboxCount() async throws -> MailInboxCount {
guard validCredentials else { throw SwiftVueError.invalidCredentials }
throw SwiftVueError.notImplemented("PreviewDataProvider.getMailInboxCount")
}
Expand Down
58 changes: 29 additions & 29 deletions Sources/SwiftVue/DataProvider/RealDataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,15 @@ public class RealDataProvider: DataProvider {
return try await makeRequest(method: "GetPXPMessages")
}

public func getCalendar() async throws -> String {
return try await makeRequest(method: "StudentCalendar")
public func getCalendar() async throws -> StudentCalendar {
let result = try await makeRequest(method: "StudentCalendar")

return try StudentCalendarParser(string: result).parse()
}

public func getAttendance() async throws -> Attendance {
let result = try await makeRequest(method: "Attendance")

if !result.contains("Attendance") {
throw SwiftVueError.invalidCredentials
}

return try AttendanceParser(string: result).parse()
}

Expand All @@ -145,10 +143,6 @@ public class RealDataProvider: DataProvider {
}
let result = try await makeRequest(method: "Gradebook", params: params)

if !result.contains("Gradebook") {
throw SwiftVueError.invalidCredentials
}

return try GradebookParser(string: result).parse()
}

Expand All @@ -158,9 +152,7 @@ public class RealDataProvider: DataProvider {

public func getStudentInfo() async throws -> StudentInfo {
let string = try await makeRequest(method: "StudentInfo")
if !string.contains("StudentInfo") {
throw SwiftVueError.invalidCredentials
}

return try StudentInfoParser(string: string).parse()
}

Expand All @@ -170,46 +162,54 @@ public class RealDataProvider: DataProvider {
params = ["TermIndex": "\(term)"]
}
let string = try await makeRequest(method: "StudentClassList", params: params)
if !string.contains("StudentClassSchedule") {
throw SwiftVueError.invalidCredentials
}

return try ScheduleParser(string: string).parse()
}

public func getSchoolInfo() async throws -> String {
return try await makeRequest(method: "StudentSchoolInfo")
public func getStaffInfo() async throws -> [StaffInfo] {
let result = try await makeRequest(method: "StudentSchoolInfo")

return try StaffInfoParser(string: result).parse()
}

public func listReportCards() async throws -> String {
return try await makeRequest(method: "GetReportCardInitialData")
public func listReportCards() async throws -> [ReportCardInfo] {
let result = try await makeRequest(method: "GetReportCardInitialData")

return try ReportCardInfoParser(string: result).parse()
}

public func getReportCard(documentGUID: String) async throws -> String {
return try await makeRequest(method: "GetReportCardDocumentData", params: ["DocumentGU": documentGUID])
}

public func listDocuments() async throws -> String {
return try await makeRequest(method: "GetStudentDocumentInitialData")
public func listDocuments() async throws -> [DocumentInfo] {
let result = try await makeRequest(method: "GetStudentDocumentInitialData")

return try DocumentInfoParser(string: result).parse()
}

public func getDocument(documentGUID: String) async throws -> String {
return try await makeRequest(method: "GetContentOfAttachedDoc", params: ["DocumentGU": documentGUID])
}

public func getMailInboxCount() async throws -> String {
return try await makeRequest(method: "SynergyMailGetInboxCount")
public func getMailInboxCount() async throws -> MailInboxCount {
let result = try await makeRequest(method: "SynergyMailGetInboxCount")

return try MailInboxCountParser(string: result).parse()
}

public func verifyCredentials() async throws -> Bool {
let string = try await getMailInboxCount()
return string.contains("SynergyMailInboxCountXML")
do {
let _ = try await getMailInboxCount()
return true
} catch SwiftVueError.invalidCredentials {
return false
}
}

public static func getDistrictList(zip: String) async throws -> [DistrictInfo] {
let string = try await makeRequest(method: "GetMatchingDistrictList", params: ["Key":"5E4B7859-B805-474B-A833-FDB15D205D40", "MatchToDistrictZipCode":"\(zip)"])
if !string.contains("DistrictList") {
throw SwiftVueError.invalidCredentials
}

return try DistrictInfoParser(string: string).parse()
}
}
Loading

0 comments on commit f833a5d

Please sign in to comment.