Path: blob/master/src/packages/project/browser-websocket/api.ts
1447 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6* License7*/89// Websocket based request/response api.10//11// All functionality here is of the form:12//13// -- one request14// -- one response1516import { getClient } from "@cocalc/project/client";17import { get_configuration } from "../configuration";18import { run_formatter, run_formatter_string } from "../formatters";19import { nbconvert as jupyter_nbconvert } from "../jupyter/convert";20import { jupyter_strip_notebook } from "@cocalc/jupyter/nbgrader/jupyter-parse";21import { jupyter_run_notebook } from "@cocalc/jupyter/nbgrader/jupyter-run";22import { x11_channel } from "../x11/server";23import { canonical_paths } from "./canonical-path";24import { delete_files } from "@cocalc/backend/files/delete-files";25import { eval_code } from "./eval-code";26import computeFilesystemCache from "./compute-filesystem-cache";27import { move_files } from "@cocalc/backend/files/move-files";28import { rename_file } from "@cocalc/backend/files/rename-file";29import { realpath } from "./realpath";30import query from "./query";31import type { Mesg } from "@cocalc/comm/websocket/types";32import handleSyncFsApiCall, {33handleSyncFsRequestCall,34handleComputeServerSyncRegister,35handleCopy,36handleSyncFsGetListing,37handleComputeServerDeleteFiles,38handleComputeServerMoveFiles,39handleComputeServerRenameFile,40handleComputeServerComputeRegister,41} from "@cocalc/sync-fs/lib/handle-api-call";42import { version } from "@cocalc/util/smc-version";43import { getLogger } from "@cocalc/project/logger";44import execCode from "./exec-code";4546const log = getLogger("websocket-api");4748let primus: any = undefined;49export function init_websocket_api(_primus: any): void {50primus = _primus;5152primus.on("connection", function (spark) {53// Now handle the connection, which can be either from a web browser, or54// from a compute server.55log.debug(`new connection from ${spark.address.ip} -- ${spark.id}`);5657spark.on("request", async (data, done) => {58log.debug("primus-api", "request", data, "REQUEST");59const t0 = Date.now();60try {61const resp = await handleApiCall({ data, spark, primus });62//log.debug("primus-api", "response", resp);63done(resp);64} catch (err) {65// put this in for debugging...66// It's normal to sometimes get errors, e.g., when a Jupyter kernel67// isn't yet available.68// console.trace(); log.debug("primus-api error stacktrack", err.stack, err);69done({ error: err.toString(), status: "error" });70}71log.debug(72"primus-api",73"request",74data,75`FINISHED: time=${Date.now() - t0}ms`,76);77});78});7980primus.on("disconnection", function (spark) {81log.debug(82"primus-api",83`end connection from ${spark.address.ip} -- ${spark.id}`,84);85});86}8788export async function handleApiCall({89data,90spark,91primus,92}: {93data: Mesg;94spark;95primus;96}): Promise<any> {97const client = getClient();98switch (data.cmd) {99case "version":100return version;101case "listing":102return await listing(data.path, data.hidden, data.compute_server_id);103case "delete_files":104const { compute_server_id, paths } = data;105if (compute_server_id) {106return await handleComputeServerDeleteFiles({107paths,108compute_server_id,109});110} else {111return await delete_files(data.paths);112}113case "move_files":114if (data.compute_server_id) {115return await handleComputeServerMoveFiles(data);116} else {117return await move_files(data.paths, data.dest, (path) =>118client.set_deleted(path),119);120}121case "rename_file":122if (data.compute_server_id) {123return await handleComputeServerRenameFile(data);124} else {125return await rename_file(data.src, data.dest, (path) =>126client.set_deleted(path),127);128}129case "canonical_paths":130return await canonical_paths(data.paths);131case "configuration":132return await get_configuration(data.aspect, data.no_cache);133case "prettier": // deprecated134case "formatter":135return await run_formatter(data);136case "prettier_string": // deprecated137case "formatter_string":138return await run_formatter_string(data);139case "exec":140if (data.opts == null) {141throw Error("opts must not be null");142}143return await execCode(data.opts);144case "realpath":145return realpath(data.path);146147// todo: why?148case "query":149return await query(client, data.opts);150// todo: why?151case "eval_code":152return await eval_code(data.code);153154case "jupyter_strip_notebook":155return await jupyter_strip_notebook(data.ipynb_path);156case "jupyter_nbconvert":157return await jupyter_nbconvert(data.opts);158case "jupyter_run_notebook":159return await jupyter_run_notebook(data.opts);160161case "x11_channel":162return await x11_channel(client, primus, log, data.path, data.display);163164// compute server165166case "compute_filesystem_cache":167return await computeFilesystemCache(data.opts);168case "sync_fs":169return await handleSyncFsApiCall(data.opts);170171case "compute_server_sync_register":172// register filesystem container173return await handleComputeServerSyncRegister(data.opts, spark);174175case "compute_server_compute_register":176// register compute container177return await handleComputeServerComputeRegister(data.opts, spark);178case "compute_server_sync_request":179return await handleSyncFsRequestCall(data.opts);180case "copy_from_project_to_compute_server":181case "copy_from_compute_server_to_project":182return await handleCopy({ event: data.cmd, ...data.opts });183default:184throw Error(185`command "${186(data as any).cmd187}" not implemented -- restart your project (in Project --> Settings)`,188);189}190}191/* implementation of the api calls */192193import { DirectoryListingEntry } from "@cocalc/util/types";194import getListing from "@cocalc/backend/get-listing";195async function listing(196path: string,197hidden: boolean,198compute_server_id?: number,199): Promise<DirectoryListingEntry[]> {200if (!compute_server_id) {201return await getListing(path, hidden);202} else {203return await handleSyncFsGetListing({ path, hidden, compute_server_id });204}205}206207208