Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/client/welcome-file.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/**6* Anonymous User Welcome File7*8* The goal is to present an anonymous user with a file/editor matching a specific intention.9* What exactly is open for experientation, but it is clear that if you want to run "latex",10* you're not interested in working with a "juypter notebook".11*/1213import { delay } from "awaiting";1415import { once } from "@cocalc/util/async-utils";16import { redux } from "@cocalc/frontend/app-framework";17import { QueryParams } from "../misc/query-params";18import { separate_file_extension } from "@cocalc/util/misc";19import type { JupyterActions } from "@cocalc/jupyter/redux/actions";2021type Kernel = "ir" | "python3" | "bash" | "octave";22type Cell = { type?: "markdown" | "code"; content: string };2324const ir_welcome = `# Welcome to R in CoCalc!2526Run a cell via \`Shift + Return\`. Learn more about [CoCalc Jupyter Notebooks](https://doc.cocalc.com/jupyter.html).`;2728const python3_welcome = `# Welcome to Python in CoCalc!2930Run a cell via \`Shift + Return\`. Learn more about [CoCalc Jupyter Notebooks](https://doc.cocalc.com/jupyter.html).`;3132const bash_welcome = `# Welcome to Bash in CoCalc!3334Run a cell via \`Shift + Return\`. Learn more about [CoCalc Jupyter Notebooks](https://doc.cocalc.com/jupyter.html).`;3536const octave_welcome = `# Welcome to Octave in CoCalc!3738Run a cell via \`Shift + Return\`. Learn more about [CoCalc Jupyter Notebooks](https://doc.cocalc.com/jupyter.html).`;3940const WelcomeSetups: Record<Kernel, Cell[]> = {41ir: [42{ type: "markdown", content: ir_welcome },43{ content: "data <- rnorm(100)\nsummary(data)" },44{ content: "hist(data)" },45],46python3: [47{ type: "markdown", content: python3_welcome },48{ content: "import sys\nsys.version" },49{ content: "import matplotlib.pyplot as plt\nimport numpy as np" },50{51content: `xx = np.linspace(0, 10 * np.pi, 1000)52yy = np.sin(xx) * np.exp(-xx / 10)53plt.grid()54plt.plot(xx, yy)`,55},56],57bash: [58{ type: "markdown", content: bash_welcome },59{ content: 'foo="World"\necho "Hello $foo!"' },60{ content: "date" },61{ content: "echo '2*20 + 2' | bc -l" },62],63octave: [64{ type: "markdown", content: octave_welcome },65{66content: `x = 1:10;67y = 1:10;68x' * y`,69},70{71content: `tx = ty = linspace (-8, 8, 41)';72[xx, yy] = meshgrid (tx, ty);73r = sqrt (xx .^ 2 + yy .^ 2) + eps;74tz = sin (r) ./ r;75mesh (tx, ty, tz);76xlabel ("tx");77ylabel ("ty");78zlabel ("tz");79title ("3-D Sombrero plot");`,80},81],82};8384export class WelcomeFile {85private readonly project_id: string;86private readonly param: string;87private readonly path: string | undefined;8889constructor(project_id: string) {90this.project_id = project_id;91const qparam = QueryParams.get("anonymous");92if (qparam != null) {93this.param = (Array.isArray(qparam) ? qparam[0] : qparam).toLowerCase();94}95if (this.param == null) return;96this.path = this.make_path();97}9899async open() {100if (this.path == null) return;101await this.create_file();102await this.extra_setup();103}104105private async extra_setup(): Promise<void> {106switch (this.param) {107case "python":108await this.setup_notebook("python3");109break;110case "jupyter-r":111case "r":112await this.setup_notebook("ir");113break;114case "jupyter-bash":115await this.setup_notebook("bash");116break;117case "octave":118case "jupyter-octave":119await this.setup_notebook("octave");120break;121}122}123124// For some jupyter notebook kernels, initialize them.125private async setup_notebook(kernel: Kernel) {126if (this.path == null)127throw new Error("WelcomeFile::setup_notebook path is not defined");128let editor_actions: any;129// inspired by nbgrader actions130while (true) {131editor_actions = redux.getEditorActions(this.project_id, this.path);132if (editor_actions != null) break;133await delay(200);134}135136const jactions = editor_actions.jupyter_actions as JupyterActions;137if (jactions.syncdb.get_state() == "init") {138await once(jactions.syncdb, "ready");139}140jactions.set_kernel(kernel);141await jactions.save(); // TODO how to make sure get_cell_list() has at least one cell?142let cell_id: string = jactions.store.get_cell_list().first();143144WelcomeSetups[kernel].forEach((cell) => {145jactions.set_cell_input(cell_id, cell.content);146if (cell.type == "markdown") {147jactions.set_cell_type(cell_id, "markdown");148} else {149jactions.run_code_cell(cell_id);150}151cell_id = jactions.insert_cell_adjacent(cell_id, +1);152});153}154155// Calling the "create file" action will properly initialize certain files,156// in particular .tex157private async create_file(): Promise<void> {158if (this.path == null)159throw new Error("WelcomeFile::create_file – path is not defined");160const project_actions = redux.getProjectActions(this.project_id);161const { name, ext } = separate_file_extension(this.path);162await project_actions.create_file({163name,164ext,165current_path: "",166switch_over: true,167});168}169170// Derive a file from the parameter value, which implies what to show.171private make_path(): string | undefined {172switch (this.param) {173case "ipynb":174case "jupyter":175case "python":176case "true":177// TODO expand this first notebook to be a bit more exciting…178return "Welcome to CoCalc.ipynb";179case "r":180case "jupyter-r":181case "jupyter-bash":182case "octave":183case "jupyter-octave":184// TODO: pre-select the R, bash or octave kernel185return "Welcome to CoCalc.ipynb";186case "linux":187case "terminal":188return "Welcome to CoCalc.term";189case "sagews":190case "sage":191return "Welcome to CoCalc.sagews";192case "latex":193return "Welcome-to-CoCalc.tex";194case "x11":195return "Welcome to CoCalc.x11";196default:197console.warn(`Got unknown param=${this.param}`);198return undefined;199}200}201}202203204