file support in progress

This commit is contained in:
2025-01-24 09:20:07 -07:00
parent b2514bb356
commit a60008c6d7
5 changed files with 69 additions and 43 deletions

View File

@@ -15,6 +15,18 @@ Development command: `dotnet watch --project Management.Web/`
<https://nowucca.com/2020/07/04/working-around-canvas-limitations.html> <https://nowucca.com/2020/07/04/working-around-canvas-limitations.html>
## Getting Started and Usage
<!-- draft -->
### Enable Image Support
You must set the `ENABLE_FILE_SYNC` environment variable to true. Image paths will be relative to the `/app/image_storage` directory in the container.
When an image is detected by canvas manager, it will upload the image to the canvas course and keep a lookup table of the original path/url of the image to the canvas course URL.
# ideas # ideas
matching questions matching questions

View File

@@ -1,5 +1,6 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = {}; const nextConfig = {
};
export default nextConfig; export default nextConfig;

3
run.sh
View File

@@ -4,6 +4,7 @@ docker run -it --rm \
--name canvas-manager-2 \ --name canvas-manager-2 \
-e TZ=America/Denver \ -e TZ=America/Denver \
-e NODE_ENV=development \ -e NODE_ENV=development \
-e NEXT_PUBLIC_ENABLE_FILE_SYNC=true \
-u 1000:1000 \ -u 1000:1000 \
-p 3000:3000 \ -p 3000:3000 \
-w /app \ -w /app \
@@ -12,8 +13,10 @@ docker run -it --rm \
-v ~/projects/faculty/4850_AdvancedFE/2024-fall-alex/modules:/app/storage/advanced_frontend \ -v ~/projects/faculty/4850_AdvancedFE/2024-fall-alex/modules:/app/storage/advanced_frontend \
-v ~/projects/faculty/1810/2025-spring-alex/online:/app/storage/intro_to_web_online \ -v ~/projects/faculty/1810/2025-spring-alex/online:/app/storage/intro_to_web_online \
-v ~/projects/faculty/1400/2025_spring_alex/modules:/app/storage/1400 \ -v ~/projects/faculty/1400/2025_spring_alex/modules:/app/storage/1400 \
-v ~/projects/faculty/1405/2025_spring_alex:/app/storage/1405 \
-v ~/projects/faculty/3840_Telemetry/2025_spring_alex/modules:/app/storage/telemetry \ -v ~/projects/faculty/3840_Telemetry/2025_spring_alex/modules:/app/storage/telemetry \
-v ~/projects/faculty/4620_Distributed/2025Spring/modules:/app/storage/distributed \ -v ~/projects/faculty/4620_Distributed/2025Spring/modules:/app/storage/distributed \
-v ~/projects/facultyFiles:/app/public/images/facultyFiles \
node \ node \
sh -c " sh -c "
mkdir -p ~/.npm-global && \ mkdir -p ~/.npm-global && \

View File

@@ -23,6 +23,8 @@ export const useAssignmentQuery = (
}); });
}; };
const enable_images = process.env.NEXT_PUBLIC_ENABLE_FILE_SYNC === "true";
export const useUpdateImageSettingsForAssignment = ({ export const useUpdateImageSettingsForAssignment = ({
moduleName, moduleName,
assignmentName, assignmentName,
@@ -37,50 +39,56 @@ export const useUpdateImageSettingsForAssignment = ({
const createCanvasUrlMutation = const createCanvasUrlMutation =
trpc.canvasFile.getCanvasFileUrl.useMutation(); trpc.canvasFile.getCanvasFileUrl.useMutation();
// useEffect(() => { useEffect(() => {
// if (isUpdatingSettings) { if (!enable_images) {
// console.log("not updating image assets, still loading"); console.log("not uploading images, FILE_POLLING is not set to true");
// return; return;
// } }
// setIsUpdatingSettings(true);
// const assignmentMarkdown = markdownToHtmlNoImages(assignment.description);
// const imageSources = extractImageSources(assignmentMarkdown); if (isUpdatingSettings) {
// const imagesToUpdate = imageSources.filter((source) => console.log("not updating image assets, still loading");
// settings.assets.every((a) => a.sourceUrl !== source) return;
// ); }
// console.log("images to update", imagesToUpdate); setIsUpdatingSettings(true);
const assignmentMarkdown = markdownToHtmlNoImages(assignment.description);
// if (imagesToUpdate.length) { const imageSources = extractImageSources(assignmentMarkdown);
// Promise.all( const imagesToUpdate = imageSources.filter((source) =>
// imagesToUpdate.map(async (source) => { settings.assets.every((a) => a.sourceUrl !== source)
// // todo: get canvas url );
// // const canvasUrl = ""; console.log("images to update", imagesToUpdate);
// const canvasUrl = await createCanvasUrlMutation.mutateAsync({
// sourceUrl: source, if (imagesToUpdate.length) {
// canvasCourseId: settings.canvasId, Promise.all(
// }); imagesToUpdate.map(async (source) => {
// console.log("got canvas url", source, canvasUrl); // todo: get canvas url
// return { sourceUrl: source, canvasUrl }; // const canvasUrl = "";
// }) console.log(source);
// ).then(async (newAssets) => { const canvasUrl = await createCanvasUrlMutation.mutateAsync({
// await updateSettings.mutateAsync({ sourceUrl: source,
// settings: { canvasCourseId: settings.canvasId,
// ...settings, });
// assets: [...settings.assets, ...newAssets], console.log("got canvas url", source, canvasUrl);
// }, return { sourceUrl: source, canvasUrl };
// }); })
// setIsUpdatingSettings(false); ).then(async (newAssets) => {
// }); await updateSettings.mutateAsync({
// } settings: {
// }, [ ...settings,
// assignment.description, assets: [...settings.assets, ...newAssets],
// createCanvasUrlMutation, },
// isUpdatingSettings, });
// settings, setIsUpdatingSettings(false);
// settings.assets, });
// updateSettings, }
// ]); }, [
assignment.description,
createCanvasUrlMutation,
isUpdatingSettings,
settings,
settings.assets,
updateSettings,
]);
}; };
export const useAssignmentNamesQuery = (moduleName: string) => { export const useAssignmentNamesQuery = (moduleName: string) => {

View File

@@ -17,7 +17,9 @@ const handler = app.getRequestHandler();
const folderToWatch = path.join(process.cwd(), "./storage", "/"); const folderToWatch = path.join(process.cwd(), "./storage", "/");
console.log("watching folder", folderToWatch); console.log("watching folder", folderToWatch);
const usePolling = process.env.FILE_POLLING === "true"; const usePolling = process.env.FILE_POLLING === "true";
const enable_images = process.env.NEXT_PUBLIC_ENABLE_FILE_SYNC === "true";
console.log("FILE_POLLING:", usePolling); console.log("FILE_POLLING:", usePolling);
console.log("NEXT_PUBLIC_ENABLE_FILE_SYNC:", enable_images);
const watcher = chokidar.watch(folderToWatch, { const watcher = chokidar.watch(folderToWatch, {
persistent: true, persistent: true,