67 lines
2.4 KiB
JavaScript
67 lines
2.4 KiB
JavaScript
// @ts-check
|
|||
|
|
/**
|
||
|
|
* Files outside the notebooks: image files to put on a page, and the place
|
||
|
|
* a picture of a page is exported to. A web page cannot look through the
|
||
|
|
* user's directories or write where the user chooses, so it asks the local
|
||
|
|
* program (kokkoja.py), as it does for the notebooks.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { askLocalProgram } from './notebook.js';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @typedef {object} DirectoryListing
|
||
|
|
* @property {string} directory Its full path.
|
||
|
|
* @property {string | null} parent Null at the top of the file system.
|
||
|
|
* @property {{name: string, path: string}[]} directories
|
||
|
|
* @property {{name: string, path: string, size: number}[]} files Image files only.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param {Response} response
|
||
|
|
* @returns {Promise<string>} What the local program says went wrong.
|
||
|
|
*/
|
||
|
|
async function reason(response) {
|
||
|
|
try {
|
||
|
|
return String((await response.json()).error);
|
||
|
|
} catch {
|
||
|
|
return `error ${response.status}`;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param {string} [directory] A full path; without one, where the notebooks are.
|
||
|
|
* @returns {Promise<DirectoryListing>}
|
||
|
|
*/
|
||
|
|
export async function listFiles(directory = '') {
|
||
|
|
const response = await askLocalProgram(`api/files?directory=${encodeURIComponent(directory)}`);
|
||
|
|
if (!response.ok) throw new Error(`${directory}: ${await reason(response)}`);
|
||
|
|
return response.json();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @param {string} path The full path of an image file, from a listing.
|
||
|
|
* @returns {Promise<Blob>}
|
||
|
|
*/
|
||
|
|
export async function readFile(path) {
|
||
|
|
const response = await askLocalProgram(`api/file?path=${encodeURIComponent(path)}`);
|
||
|
|
if (!response.ok) throw new Error(`${path}: ${await reason(response)}`);
|
||
|
|
return response.blob();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Write a PNG picture into a directory.
|
||
|
|
* @param {string} directory Its full path.
|
||
|
|
* @param {string} name Ending in .png.
|
||
|
|
* @param {Blob} picture
|
||
|
|
* @param {boolean} replace Whether a file of that name may be replaced.
|
||
|
|
* @returns {Promise<string | null>} The full path written, or null if a
|
||
|
|
* file of that name exists and may not be replaced.
|
||
|
|
*/
|
||
|
|
export async function writePicture(directory, name, picture, replace) {
|
||
|
|
const query = `directory=${encodeURIComponent(directory)}&name=${encodeURIComponent(name)}` +
|
||
|
|
(replace ? '&replace=1' : '');
|
||
|
|
const response = await askLocalProgram(`api/file?${query}`, 'PUT', picture);
|
||
|
|
if (response.status === 409) return null;
|
||
|
|
if (!response.ok) throw new Error(await reason(response));
|
||
|
|
return (await response.json()).saved;
|
||
|
|
}
|