parse from yml and stick into db

This commit is contained in:
Michael Zhang 2021-08-28 13:03:38 -05:00
parent 053973dd41
commit 74660120bb
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
8 changed files with 86 additions and 55 deletions

28
'
View file

@ -1,28 +0,0 @@
{ writeTextFile, nsjail }:
let
inner = writeTextFile {
name = "ocamlStudentModuleInner";
executable = true;
text = ''
INTERFACE_FILE=$1
STUDENT_FILE=$2
DRIVER_FILE=$3
ocamlc -o student.cmi $INTERFACE_FILE
ocamlc -o student.cmo $STUDENT_FILE
ocaml student.cmo $DRIVER_FILE
'';
};
in
writeTextFile {
name = "ocamlStudentModule";
executable = true;
text = ''
JAIL=$(mktemp -d)
${nsjail}/bin/nsjail \
-Mo \ # launch a single process using clone/execve
--chroot $JAIL
${inner}
'';
}

1
.ignore Normal file
View file

@ -0,0 +1 @@
/package-lock.json

View file

@ -1,14 +1,23 @@
import { Sequelize, Model, DataTypes } from "sequelize"; import { PrimaryKey, Sequelize, Column, Table, Model } from "sequelize-typescript";
class Page extends Model {} @Table
export class Page extends Model {
@PrimaryKey
@Column
public slug: string;
export async function init(path: string) { @Column
let sequelize = new Sequelize(`sqlite:${path}`); public title: string;
}
Page.init({ @Table
export class Exercise extends Model {
}
}, { sequelize, modelName: "page" }); export async function init(path: string): Promise<Sequelize> {
let sequelize = new Sequelize(`sqlite:${path}`, {
await sequelize.sync(); models: [Page, Exercise],
});
await sequelize.sync({ force: true });
return sequelize; return sequelize;
} }

View file

@ -1,26 +1,44 @@
import { readdir, readFile } from "fs/promises"; import { readdir, readFile } from "fs/promises";
import { join } from "path"; import { join } from "path";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import { plainToClass } from "class-transformer";
import { validate } from "class-validator";
import { init } from "./db"; import { init, Page } from "./db";
import { Page as PageConfig } from "./page";
// TODO: configure this thru cmdline or something later
let materials_dir = "../material";
let db_file = "test.db";
let db;
async function loadPageIntoDb(name: string): Promise<void> {
// check if this slug has already been loaded into the database
let path = join(materials_dir, name);
let rawData = await readFile(path, { encoding: "utf8" });
let parsedData = yaml.load(rawData);
let page_config = plainToClass(PageConfig, parsedData);
await validate(page_config);
console.log("Validated!", page_config);
let page = new Page({
slug: page_config.slug,
title: page_config.title,
});
await page.save();
}
async function main() { async function main() {
// TODO: configure this thru cmdline or something later db = await init(db_file);
let materials_dir = "../material";
let db_file = "test.db";
let db = await init(db_file);
// TODO: streaming version of readdir when the folder gets big
let names = await readdir(materials_dir); let names = await readdir(materials_dir);
await Promise.all(names await Promise.all(names
.filter(name => name.toLowerCase().endsWith(".yml")) .filter(name => name.toLowerCase().endsWith(".yml"))
.map(async name => { .map(loadPageIntoDb)
let path = join(materials_dir, name);
let rawData = await readFile(path, { encoding: "utf8" });
let parsedData = yaml.load(rawData);
console.log("data", parsedData);
})
); );
} }

View file

@ -4,11 +4,18 @@
"start": "ts-node index.ts" "start": "ts-node index.ts"
}, },
"devDependencies": { "devDependencies": {
"@types/js-yaml": "^4.0.3",
"@types/node": "^16.7.4",
"@types/validator": "^13.6.3",
"ts-node": "^10.2.1" "ts-node": "^10.2.1"
}, },
"dependencies": { "dependencies": {
"class-transformer": "^0.4.0",
"class-validator": "^0.13.1",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"reflect-metadata": "^0.1.13",
"sequelize": "^6.6.5", "sequelize": "^6.6.5",
"sqlite3": "^5.0.2" "sequelize-typescript": "^2.1.0",
"sqlite3": "^4.2.0"
} }
} }

24
compile-database/page.ts Normal file
View file

@ -0,0 +1,24 @@
export class Page {
public slug: string;
public title: string;
public type: string;
public summary?: string;
public content?: string;
public exercises?: Exercise[];
};
export class Exercise {
public slug: string;
public description: string;
public graders: Grader[];
};
export class Grader {
public language: string;
public style: string;
public props: any;
};

View file

@ -1,5 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es6",
"module": "commonjs",
"emitDecoratorMetadata": true,
"experimentalDecorators": true "experimentalDecorators": true
} }
} }

View file

@ -12,14 +12,11 @@ content: |
exercises: exercises:
- description: | - name: doubleIt
description: |
Write a function called `doubleIt` that takes an integer and doubles it. Write a function called `doubleIt` that takes an integer and doubles it.
examples: graders:
ocaml:
- |
grader:
ocaml: ocaml:
style: studentModule style: studentModule
props: props: