/// /// /// /// import * as _ from 'lodash'; import * as Request from 'request'; import { Observable } from 'rx'; import { Course } from './models/course'; import { User, userFactory } from './models/user'; import { Person } from './models/person'; import { cacher } from './helpers/cacher'; import { caller } from './helpers/caller'; import { fetcher } from './helpers/fetcher'; import { seeker } from './helpers/seeker'; export interface ISearchCoursesOption { name?: string, department?: string, instructor?: string, grade?: string, type?: string } export interface ISearchPeopleOption { term?: string } /** * @description Represents an portal of SDK library. */ export class Application { /** * @description The user instance for application global operations. */ private currentUser: User = null; /** * @description The constructor of Application class. */ constructor () { this.currentUser = _.find(cacher.users, (user) => user.isConfirmed) || null; } /** * @description Get the exact user of given student id which has been registered before. * @param id The student id of the student. * @returns The student instance if exist, null if not. */ one (id: string): User { return cacher.users[id] || null; } /** * @description Register a student entity with student id and password. * @param id The student id of the student. * @param password The password of the UESTC Portal site. * @returns The student instance of the given student id. */ register (id: string, password: string): User { var user: User; cacher.users[id] = user = userFactory.$new(id, password); if(!this.isUserExist()) { user.confirm().subscribe((res) => res && (this.currentUser = user)); } return user; } /** * @description Search for courses that satisfy the given option online. * @param option The option of the search. * @param callback The callback function to be called with an error or the result of courses if don't want to use the Observable operations. It's deprecated. * @returns The Observable instance of the search result. */ searchForCourses (option: ISearchCoursesOption, callback?: { (error: Error, courses: Course[]): void; }): Observable { var observable: Observable = Observable.just(this.isUserExist()) .flatMap((x) => x? fetcher.searchForCourses(option, this.currentUser.jar): Observable.throw(new Error('401: Application#searchForCourses must be called with a current user.'))); caller.nodifyObservable(observable, callback); return observable; } /** * @description Search for courses that satisfy the given option offline. * @param option The option of the search. * @param callback The callback function to be called with an error or the result of courses ifor users unfamiliar with Rx. It's deprecated. * @returns The Observable instance of the search result. */ searchForCoursesInCache (option: ISearchCoursesOption, callback?: { (error: Error, courses: Course[]): void; }): Observable { var observable = seeker.searchForCourses(option); caller.nodifyObservable(observable, callback); return observable; } /** * @description Search for courses that satisfy the given option online when possible, offline when necessary. * @param option The option of the search. * @param callback The callback function to be called with an error or the result of courses for users unfamiliar with Rx. It's deprecated. * @returns The Observable instance of the search result. */ searchForCoursesWithCache (option: ISearchCoursesOption, callback?: { (error: Error, courses: Course[]): void; }): Observable { var observable = this.searchForCourses(option) .catch(this.searchForCoursesInCache(option)); caller.nodifyObservable(observable, callback); return observable; } /** * @description Search for people that satisfy the given option online. * @param option The option of the search. * @param callback The callback function to be called with an error or the result of people for users unfamiliar with Rx. It's deprecated. * @returns The Observable instance of the search result. */ searchForPeople (option: ISearchPeopleOption, callback?: { (error: Error, people: Person[]): void; }): Observable { var observable: Observable = Observable.just(this.isUserExist()) .flatMap((x) => x? fetcher.searchForPeople(option, this.currentUser.jar): Observable.throw(new Error('401: Application#searchForCourses must be called with a current user.'))); caller.nodifyObservable(observable, callback); return observable; } /** * @description Search for people that satisfy the given option offline. * @param option The option of the search. * @param callback The callback function to be called with an error or the result of people for users unfamiliar with Rx. It's deprecated. * @returns The Observable instance of the search result. */ searchForPeopleInCache (option: ISearchPeopleOption, callback?: { (error: Error, people: Person[]): void; }): Observable { var observable = seeker.searchForPeople(option); caller.nodifyObservable(observable, callback); return observable; } /** * @description Search for people that satisfy the given option online when possible, offline when necessary. * @param option The option of the search. * @param callback The callback function to be called with an error or the result of people for users unfamiliar with Rx. It's deprecated. * @returns The Observable instance of the search result. */ searchForPeopleWithCache (option: ISearchPeopleOption, callback?: { (error: Error, people: Person[]): void; }): Observable { var observable = this.searchForPeople(option) .catch(this.searchForPeopleInCache(option)); caller.nodifyObservable(observable, callback); return observable; } /** * @description Verify whether the given student id and password is valid. * @notice If some other accident occurs (i.e. No network), the result would be null, please do check whether the error exists or not. * @param id The student id of the student. * @param password The password of the student. * @param callback The callback function to be called with an error or the result of verify for users unfamiliar with Rx. It's deprecated. * @returns The boolean result of valid or not. */ verify (id: string, password: string, callback?: { (error: Error, result: boolean): void; }): Observable { var user = new User(id, password); var observable = user.confirm(); caller.nodifyObservable(observable, callback); return observable; } /** * @description Check whether there is a user to deal with global operation. * @returns The boolean result of exist or not. */ private isUserExist (): boolean { return !!this.currentUser; } } /** * @description The Application instance for access. */ export const app: Application = new Application();