Added bulk import.

This commit is contained in:
Andrew Lalis 2024-12-28 12:28:07 -05:00
parent 65e61a9fbf
commit 2b9b207e2d
7 changed files with 104 additions and 1 deletions

View File

@ -1,13 +1,15 @@
import handy_httpd;
import handy_httpd.handlers.path_handler;
import std.stdio;
import d2sqlite3;
import std.process;
import db;
import api_modules.auth;
static import api_modules.classroom_compliance;
void main() {
string env = environment.get("TEACHER_TOOLS_API_ENV", "DEV");
// Initialize the database on startup.
auto db = getDb();
db.close();
@ -22,6 +24,11 @@ void main() {
config.defaultHeaders["Access-Control-Request-Method"] = "*";
config.defaultHeaders["Access-Control-Allow-Headers"] = "Authorization, Content-Length, Content-Type";
if (env == "PROD") {
config.port = 8107;
config.workerPoolSize = 5;
}
PathHandler handler = new PathHandler();
handler.addMapping(Method.OPTIONS, "/api/**", &optionsEndpoint);

1
app/.env.production Normal file
View File

@ -0,0 +1 @@
VITE_API_URL=https://teacher-tools.andrewlalis.com/api

View File

@ -37,6 +37,8 @@ async function deleteThisClass() {
<div class="button-bar" style="margin-bottom: 1em;">
<button type="button" @click="router.push(`/classroom-compliance/classes/${cls.id}/edit-student`)">Add
Student</button>
<button type="button" @click="router.push(`/classroom-compliance/classes/${cls.id}/import-students`)">Import
Students</button>
<button type="button" @click="deleteThisClass">Delete this Class</button>
</div>

View File

@ -0,0 +1,51 @@
<script setup lang="ts">
import { showAlert } from '@/alerts';
import { ClassroomComplianceAPIClient } from '@/api/classroom_compliance';
import { useAuthStore } from '@/stores/auth';
import { computed, ref } from 'vue';
import { useRouter } from 'vue-router';
const props = defineProps<{
classId: string
}>()
const authStore = useAuthStore()
const router = useRouter()
const apiClient = new ClassroomComplianceAPIClient(authStore)
const textContent = ref('')
const working = ref(false)
const lines = computed(() => textContent.value.trim().split('\n').filter(s => s.trim().length > 0))
const studentCount = computed(() => lines.value.length)
async function doImport() {
working.value = true
const classIdNumber = parseInt(props.classId, 10)
for (let i = 0; i < lines.value.length; i++) {
const line = lines.value[i]
const student = await apiClient.createStudent(classIdNumber, { name: line, deskNumber: 0, removed: false })
.handleErrorsWithAlert()
if (!student) break;
}
working.value = false
await showAlert('Created students!')
await router.replace(`/classroom-compliance/classes/${classIdNumber}`)
}
</script>
<template>
<div>
<h1>Import Students</h1>
<p>
Import a large number of students to a class at once by pasting their names in the text box below, with one
student per line.
</p>
<form @submit.prevent="doImport">
<textarea style="min-width: 300px; min-height: 500px;" v-model="textContent"></textarea>
<div>
<span>Detected <span>{{ studentCount }}</span> students in the above text.</span>
</div>
<div class="button-bar">
<button type="submit" :disabled="working">Submit</button>
</div>
</form>
</div>
</template>

View File

@ -54,6 +54,11 @@ const router = createRouter({
component: () => import('@/apps/classroom_compliance/EditStudentView.vue'),
props: true,
},
{
path: 'classes/:classId/import-students',
component: () => import('@/apps/classroom_compliance/ImportStudentsView.vue'),
props: true,
},
],
},
],

23
deploy.sh Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -e
set -o pipefail
# Script for deploying the application to teacher-tools.andrewlalis.com.
echo "Building app"
cd app
rm -rf dist
npm run build
cd ..
echo "Building API"
cd api
dub clean
dub build --build=release --compiler=/opt/ldc2/ldc2-1.36.0-linux-x86_64/bin/ldc2
cd ..
ssh -f root@andrewlalis.com 'systemctl stop teacher-tools-api.service'
scp api/teacher-tools-api root@andrewlalis.com:/opt/teacher-tools/
rsync -rav -e ssh --delete app/dist/* root@andrewlalis.com:/opt/teacher-tools/app-content
ssh -f root@andrewlalis.com 'systemctl start teacher-tools-api.service'

14
teacher-tools-api.service Normal file
View File

@ -0,0 +1,14 @@
[Unit]
Description=teacher-tools-api
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/teacher-tools
Environment="TEACHER_TOOLS_API_ENV=PROD"
ExecStart=/opt/teacher-tools/teacher-tools-api
Restart=always
[Install]
WantedBy=multi-user.target