materials-cli
Version:
CLI for Imperial Materials
161 lines (160 loc) • 7.86 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ora_1 = __importDefault(require("ora"));
const chalk_1 = __importDefault(require("chalk"));
const update_notifier_1 = __importDefault(require("update-notifier"));
const argparse_1 = require("argparse");
const inquirer_1 = require("./lib/inquirer");
const materials_api_1 = __importStar(require("./lib/materials-api"));
const keystore_1 = __importDefault(require("./lib/keystore"));
const configstore_1 = __importDefault(require("./lib/configstore"));
const concurrent_downloader_1 = __importDefault(require("./lib/concurrent-downloader"));
const startup_1 = require("./utils/startup");
const config_1 = require("./utils/config");
const path_1 = __importDefault(require("path"));
const open_1 = __importDefault(require("open"));
const pkg = require('../package.json');
const version = pkg.version;
const notifier = update_notifier_1.default({ pkg, updateCheckInterval: 0 });
const parser = new argparse_1.ArgumentParser({
description: 'Materials CLI Tool'
});
parser.add_argument('shortcut', { nargs: "?", help: "Shortcut to course" });
parser.add_argument('-v', '--version', { action: 'version', version });
parser.add_argument('-c', '--clean', { action: 'store_true', help: "Clean configurations" });
parser.add_argument('-o', '--open', { action: 'store_true', help: "Open folder based off shortcut or selection" });
parser.add_argument('-d', '--dir', { action: 'store_true', help: "Save folders in current directory instead" });
parser.add_argument('-a', '--all', { action: 'store_true', help: "Download all shortcut courses one go" });
const argv = parser.parse_args();
const run = () => __awaiter(void 0, void 0, void 0, function* () {
startup_1.startUp(pkg.version);
notifier.notify();
const keystore = new keystore_1.default();
const conf = new configstore_1.default(config_1.id);
if (argv.clean) {
yield keystore.deleteCredentials();
conf.clearConfig();
console.log(chalk_1.default.greenBright("Configuration cleared!"));
return;
}
let existingCredentials = yield keystore.getCredentials();
let tokenAndCredentials;
if (!existingCredentials) {
startup_1.intro();
tokenAndCredentials = yield inquirer_1.askCredentials();
yield keystore.setCredentials(tokenAndCredentials.credentials);
}
else {
const spinner = ora_1.default('Signing into Materials...').start();
const newToken = yield materials_api_1.testAuth(existingCredentials);
if (!newToken) {
tokenAndCredentials = yield inquirer_1.askCredentials();
yield keystore.setCredentials(tokenAndCredentials.credentials);
}
else {
tokenAndCredentials = { credentials: existingCredentials, token: newToken };
}
spinner.stop();
spinner.clear();
console.log(chalk_1.default.greenBright("✔ Successfully authenticated"));
}
if (!conf.getFolderPath()) {
const folderPath = yield inquirer_1.setFolder();
conf.setFolderPath(folderPath);
}
const materialsAPI = new materials_api_1.default(tokenAndCredentials.token);
// Successfully authenticated
const currentShortcuts = conf.getShortcuts();
let course;
const shortCutArg = argv.shortcut;
if (shortCutArg) {
course = currentShortcuts[shortCutArg];
}
if (argv.all) {
const shortcuts = Object.keys(currentShortcuts);
for (let i = 0; i < shortcuts.length; i++) {
let course = currentShortcuts[shortcuts[i]];
yield downloadCourse(course, materialsAPI, shortCutArg, conf, argv.open, false);
}
}
else {
yield downloadCourse(course, materialsAPI, shortCutArg, conf, argv.open);
}
});
function downloadCourse(course, materialsAPI, shortCutArg, conf, argvOpenFolder, openFolder = true) {
return __awaiter(this, void 0, void 0, function* () {
let folderPath = argv.dir ? process.cwd() : conf.getFolderPath();
if (!course) {
const spinner = ora_1.default('Fetching courses...').start();
const courses = yield materialsAPI.getCourses();
spinner.stop();
spinner.clear();
if (shortCutArg) {
console.log(chalk_1.default.yellow(`No course found for shortcut ${shortCutArg}, assign one below:`));
}
const courseNameChosen = yield inquirer_1.pickCourse(courses.data);
if (shortCutArg) {
console.log(chalk_1.default.yellow(`Shortcut ${shortCutArg}, assigned to ${courseNameChosen.course}!`));
}
course = courses.data.find(x => x.title === courseNameChosen.course);
if (shortCutArg) {
conf.setShortcuts(shortCutArg, course);
}
}
else {
console.log(chalk_1.default.blueBright(course.title));
}
if (argvOpenFolder) {
yield open_1.default(path_1.default.join(folderPath, course.title));
return;
}
const spinner2 = ora_1.default('Fetching course materials...').start();
const resourcesResult = yield materialsAPI.getCourseResources(course.code);
// .map is a hack to ensure the extension is always added
const nonLinkResources = resourcesResult.data.filter(x => x.type == 'file').map(x => {
x.title = path_1.default.parse(x.title).name + path_1.default.parse(x.path).ext;
return x;
});
const pdfLinkResources = resourcesResult.data.filter(x => x.type == 'link' && x.path.endsWith(".pdf"));
spinner2.stop();
spinner2.clear();
console.log(chalk_1.default.greenBright(`Found ${nonLinkResources.length + pdfLinkResources.length} resources!`));
const concurrentDownloader = new concurrent_downloader_1.default(materialsAPI, course.title, folderPath);
concurrentDownloader.scheduleDownloads(nonLinkResources);
concurrentDownloader.scheduleLinkDownloads(pdfLinkResources);
yield concurrentDownloader.executeDownloads(openFolder);
});
}
run();