# HG changeset patch # User John W. Eaton # Date 1636733895 18000 # Fri Nov 12 11:18:15 2021 -0500 # Node ID be463f75a5eadfc59170b5e34aff2fc2d2c96e8f # Parent b7bce52e45002a232df6726f692e7f46af7f3f31 JupyterNotebook: don't hardwire tmp directory name (bug #61470) * JupyterNotebook.m (JupyterNotebook.tmpdir): New property. Use it instead of "__octave_jupyter_temp__". diff --git a/scripts/miscellaneous/JupyterNotebook.m b/scripts/miscellaneous/JupyterNotebook.m --- a/scripts/miscellaneous/JupyterNotebook.m +++ b/scripts/miscellaneous/JupyterNotebook.m @@ -124,6 +124,16 @@ classdef JupyterNotebook < handle context = struct("ans", "") + ## Note: This name needs to be stored in a property because it is + ## set in the constructor but used in some other methods. However, + ## we want to defer calling tempname() until immediately before + ## calling mkdir. The temporary directory currently created and + ## deleted in the constructor and the name is reset to the empty + ## string when the directory is deleted. Another possible + ## implementation might be to generate the name and create the + ## tmporary directory here, then delete it in the class destructor. + tmpdir = ""; + endproperties methods @@ -379,17 +389,19 @@ classdef JupyterNotebook < handle fig_ids_new = setdiff (findall (0, "type", "figure"), fig_ids); if (numel (fig_ids_new) > 0) - if (exist ("__octave_jupyter_temp__", "dir")) + if (! isempty (obj.tmpdir) && exist (obj.tmpdir, "dir")) ## Delete open figures before raising the error. for i = 1:numel (fig_ids_new) delete (fig_ids_new(i)); endfor - error (["JupyterNotebook: temporary directory ", ... - "__octave_jupyter_temp__ exists. Please remove it ", ... - "manually."]); + error (["JupyterNotebook: temporary directory %s exists. ", ... + "Please remove it manually."], obj.tmpdir); endif - [status, msg, msgid] = mkdir ("__octave_jupyter_temp__"); + if (isempty (obj.tmpdir)) + obj.tmpdir = tempname (); + endif + [status, msg, msgid] = mkdir (obj.tmpdir); if (status == 0) ## Delete open figures before raising the error. for i = 1 : numel (fig_ids_new) @@ -399,17 +411,22 @@ classdef JupyterNotebook < handle msg]); endif + ## FIXME: Maybe it would be better for these cleanup actions to + ## happen in an onCleanup object or unwind_protect block so that + ## they will be executed no matter how we exit this function? + for i = 1:numel (fig_ids_new) figure (fig_ids_new(i), "visible", "off"); obj.embedImage (cell_index, fig_ids_new (i), printOptions); delete (fig_ids_new(i)); endfor - [status, msg, msgid] = rmdir ("__octave_jupyter_temp__"); + [status, msg, msgid] = rmdir (obj.tmpdir); if (status == 0) error (["JupyterNotebook: Cannot delete the temporary ", ... "directory. ", msg]); endif + obj.tmpdir = ""; endif endfunction @@ -605,7 +622,7 @@ classdef JupyterNotebook < handle mime = "image/jpeg"; endif - image_path = fullfile ("__octave_jupyter_temp__", ["temp.", fmt]); + image_path = fullfile (obj.tmpdir, ["temp.", fmt]); print (figHandle, image_path, ["-d", fmt], ["-r" printOptions.resolution]); @@ -622,7 +639,7 @@ classdef JupyterNotebook < handle function dstruct = embed_svg_image (obj, figHandle, printOptions) - image_path = fullfile ("__octave_jupyter_temp__", "temp.svg"); + image_path = fullfile (obj.tmpdir, "temp.svg"); print (figHandle, image_path, "-dsvg", ["-r" printOptions.resolution]); dstruct.output_type = "display_data";