All files cli.ts

96.15% Statements 50/52
88.89% Branches 16/18
100% Functions 7/7
95.74% Lines 45/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 1211x   1x 1x 1x 1x   1x     6x   6x                   5x 5x 5x 5x             1x 1x 1x 1x 1x 1x     1x       5x 5x 5x   5x 4x 3x   11x 5x 1x   4x     4x           1x       2x   2x 1x 1x   1x 1x       1x       1x   1x 1x   1x 1x           1x 1x                                              
import { CUSession, ICourse, ITerm } from 'cu-api-test';
import * as Conf from 'conf';
import moment from 'moment';
import { authorize } from './calendar';
import { google } from 'googleapis';
import { toDays } from './helper';
// for tests to spy on getCourses
import * as helper from './cli';
 
function getLogin(config: Conf): { username: string; password: string } {
  Iif (!config.has('username') || !config.has('password'))
    throw new TypeError('User is not loaded in to CU.');
  return {
    username: config.get('username'),
    password: config.get('password')
  };
}
 
/**
 * Creates a CU session with username and password from system keyring.
 */
async function createSession(config: Conf): Promise<CUSession> {
  const { username, password } = getLogin(config);
  const session = new CUSession();
  await session.init(username, password);
  return session;
}
 
/**
 * Returns the gpa as a number.
 * @param config the config for the application.
 */
export async function getGpa(config: Conf): Promise<number> {
  const { username, password } = await getLogin(config);
  const session = new CUSession();
  await session.init(username, password);
  const gpa = parseFloat((await session.GPA()).cum_GPA);
  return gpa;
}
 
export async function getCourses(
  config: Conf,
  term: 'current' | 'next' | 'next-next' | 'previous' = 'current'
): Promise<ICourse[]> {
  const session = await createSession(config);
  const terms = await session.termData();
  let wantedTerm: ITerm['attributeName'] = 'CURRENT_TERM';
 
  if (term === 'next') wantedTerm = 'NEXT_TERM';
  else if (term === 'next-next') wantedTerm = 'NEXT_NEXT_TERM';
  else if (term === 'previous') wantedTerm = 'PREVIOUS_TERM';
 
  const foundTerm = terms.find((term) => term.attributeName === wantedTerm);
  if (!foundTerm) {
    throw new Error('Could not find current term data.');
  }
  const courses = Array.from(
    (await session.classTermData(foundTerm.term4)).values()
  );
  return courses;
}
 
/**
 * Syncs classes from CU term to google calendar.
 */
export async function syncClassesCalendar(
  config: Conf,
  term: 'current' | 'next' | 'next-next' | 'previous' = 'current'
): Promise<void> {
  const courses = await helper.getCourses(config, term);
 
  if (!config.has('google')) throw new Error('Not logged in to google.');
  const auth = await authorize(config.get('google'));
  const calendar = google.calendar({ version: 'v3', auth });
 
  for (const course of courses) {
    const startTime = moment.utc(
      `${course.courseStartDate} ${course.courseStartTime}`,
      'YYYY-MM-DD k:m'
    );
    const endTime = moment.utc(
      `${course.courseStartDate} ${course.courseStopTime}`,
      'YYYY-MM-DD k:m'
    );
    const endDate = moment.utc(course.courseStopDate, 'YYYY-MM-DD');
    // const start = course.courseStartDate
    const days = toDays(course.days);
    const instructorText = course.instructors.reduce(
      (prev, instructor, index) => {
        Eif (index === 0) {
          return `\t${instructor.name} - ${instructor.email}`;
        }
        return prev + `\n\t${instructor.name} - ${instructor.email}`;
      },
      ''
    );
    console.log(`Creating "${course.courseTitle}" event.`);
    await calendar.events.insert({
      calendarId: 'primary',
      requestBody: {
        summary: course.courseTitle,
        description: `Course Id: ${course.courseId}\nSubject: ${course.courseSubject}${course.courseNumber}-${course.courseSection}\nCredits: ${course.credits}\nInstructors:\n${instructorText}`,
        start: {
          dateTime: startTime.toISOString(), // yyyy-mm-dd
          timeZone: 'America/Denver'
        },
        end: {
          dateTime: endTime.toISOString(), // yyyy-mm-dd
          timeZone: 'America/Denver'
        },
        recurrence: [
          `RRULE:FREQ=WEEKLY;UNTIL=${endDate
            .locale('en')
            .format('YYYYMMDD[T]000000[Z]')};WKST=SU;BYDAY=${days.join(',')}`
        ],
        location: course.descrLocation
      }
    });
  }
}