diff --git a/features/support/env.el b/features/support/env.el index 52ba29e..2e277ec 100644 --- a/features/support/env.el +++ b/features/support/env.el @@ -71,9 +71,14 @@ for path = (ein:$notebook-notebook-path nb) do (ein:log 'debug "Notebook %s still open" path) finally do (assert nil))) - (let ((stragglers (file-name-all-completions "Untitled" - ein:testing-jupyter-server-root))) - (should-not stragglers))) + (cl-loop repeat 5 + for stragglers = (file-name-all-completions "Untitled" + ein:testing-jupyter-server-root) + until (null stragglers) + do (message "ein:testing-after-scenario: fs stale handles: %s" + (mapconcat #'identity stragglers ", ")) + do (sleep-for 0 1000) + finally do (should-not stragglers))) (Setup (ein:dev-start-debug) diff --git a/lisp/ein-contents-api.el b/lisp/ein-contents-api.el index 8d02a68..843ddf3 100644 --- a/lisp/ein-contents-api.el +++ b/lisp/ein-contents-api.el @@ -63,26 +63,13 @@ global setting. For global setting and more information, see :type 'boolean :group 'ein) -(defun ein:content-url (content &rest params) - (apply #'ein:content-url* (ein:$content-url-or-port content) (ein:$content-path content) params)) - -(defun ein:content-url* (url-or-port path &rest params) - (let* ((which (if (< (ein:notebook-version-numeric url-or-port) 3) - "notebooks" "contents")) - (api-path (concat "api/" which))) - (url-encode-url (apply #'ein:url - url-or-port - api-path - path - params)))) - (defun ein:content-query-contents (url-or-port path callback errback &optional iteration) "Register CALLBACK of arity 1 for the contents at PATH from the URL-OR-PORT. ERRBACK of arity 1 for the contents." (unless iteration (setq iteration 0)) (ein:query-singleton-ajax - (ein:content-url* url-or-port path) + (ein:notebooklist-url url-or-port path) :type "GET" :timeout ein:content-query-timeout :parser #'ein:json-read @@ -276,7 +263,7 @@ ERRBACK of arity 1 for the contents." (when callback* (funcall callback* nil))))) url-or-port callback) callback)) - + ;;; Save Content (defun ein:content-save-legacy (content &optional callback cbargs errcb errcbargs) @@ -287,7 +274,13 @@ ERRBACK of arity 1 for the contents." :timeout ein:content-query-timeout :data (ein:content-to-json content) :success (apply-partially #'ein:content-save-success callback cbargs) - :error (apply-partially #'ein:content-save-error (ein:content-url content) errcb errcbargs))) + :error (apply-partially #'ein:content-save-error + (ein:content-url content) + errcb errcbargs))) + +(defsubst ein:content-url (content) + (ein:notebooklist-url (ein:$content-url-or-port content) + (ein:$content-path content))) (defun ein:content-save (content &optional callback cbargs errcb errcbargs) (if (>= (ein:$content-notebook-version content) 3) diff --git a/lisp/ein-notebook.el b/lisp/ein-notebook.el index ed88317..b8a7613 100644 --- a/lisp/ein-notebook.el +++ b/lisp/ein-notebook.el @@ -221,16 +221,9 @@ combo must match exactly these url/port you used format ;;; Open notebook -(defun ein:notebook-url (notebook) - (ein:notebook-url-from-url-and-id (ein:$notebook-url-or-port notebook) - (ein:$notebook-api-version notebook) - (ein:$notebook-notebook-path notebook))) - -(defun ein:notebook-url-from-url-and-id (url-or-port api-version path) - (cond ((= api-version 2) - (ein:url url-or-port "api/notebooks" path)) - ((>= api-version 3) - (ein:url url-or-port "api/contents" path)))) +(defsubst ein:notebook-url (notebook) + (ein:notebooklist-url (ein:$notebook-url-or-port notebook) + (ein:$notebook-notebook-path notebook))) (defun ein:notebook-open--decorate-callback (notebook existing pending-clear callback no-pop) "In addition to CALLBACK, @@ -1418,20 +1411,6 @@ watch the fireworks!" ;; permanent local. (put 'ein:notebook-mode 'permanent-local t) -(defun ein:notebook-open-in-browser (&optional print) - "Open current notebook in web browser. -When the prefix argument (``C-u``) is given, print page is opened. -Note that print page is not supported in IPython 0.12.1." - (interactive "P") - (let ((url (apply #'ein:url - (ein:$notebook-url-or-port ein:%notebook%) - (if (>= (ein:$notebook-api-version ein:%notebook%) 3) - "notebooks") - (ein:$notebook-notebook-path ein:%notebook%) - (if print (list "print"))))) - (message "Opening %s in browser" url) - (browse-url url))) - (defun ein:notebook-fetch-data (notebook callback &optional cbargs) "Fetch data in body tag of NOTEBOOK html page. CALLBACK is called with a plist with data in the body tag as diff --git a/lisp/ein-notebooklist.el b/lisp/ein-notebooklist.el index 91f5eb1..dec1af7 100644 --- a/lisp/ein-notebooklist.el +++ b/lisp/ein-notebooklist.el @@ -132,9 +132,10 @@ This function adds NBLIST to `ein:notebooklist-map'." "Get an instance of `ein:$notebooklist' by URL-OR-PORT as a key." (gethash url-or-port ein:notebooklist-map)) -(defun ein:notebooklist-url (url-or-port version &optional path) - (let ((base-path (cond ((= version 2) "api/notebooks") - ((>= version 3) "api/contents")))) +(defun ein:notebooklist-url (url-or-port path) + (let* ((version (ein:notebook-version-numeric url-or-port)) + (base-path (cond ((= version 2) "api/notebooks") + (t "api/contents")))) (ein:url url-or-port base-path path))) (defun ein:notebooklist-sentinel (url-or-port process event) @@ -280,8 +281,7 @@ This function is called via `ein:notebook-after-rename-hook'." nil t nil nil "default" nil))) (let* ((notebooklist (ein:notebooklist-list-get url-or-port)) (path (ein:$notebooklist-path notebooklist)) - (version (ein:$notebooklist-api-version notebooklist)) - (url (ein:notebooklist-url url-or-port version path))) + (url (ein:notebooklist-url url-or-port path))) (ein:query-singleton-ajax url :type "POST" @@ -364,8 +364,7 @@ This function is called via `ein:notebook-after-rename-hook'." (apply-partially (lambda (url* settings* _kernel) (apply #'ein:query-singleton-ajax url* settings*)) - (ein:notebook-url-from-url-and-id - url-or-port (ein:$notebooklist-api-version notebooklist) path) + (ein:notebooklist-url url-or-port path) (list :type "DELETE" :complete (apply-partially #'ein:notebooklist-delete-notebook--complete diff --git a/lisp/ein-process.el b/lisp/ein-process.el index 7b0fd4c..56f9404 100644 --- a/lisp/ein-process.el +++ b/lisp/ein-process.el @@ -181,10 +181,10 @@ (ein:process-suitable-notebook-dir filename))) (path (concat (if ein:jupyter-use-containers - (file-name-as-directory - (file-name-base ein:jupyter-docker-mount-point)) + (file-name-as-directory (file-name-base ein:jupyter-docker-mount-point)) "") - (cl-subseq filename (length (file-name-as-directory nbdir))))) + (cl-subseq (expand-file-name filename) + (length (file-name-as-directory (expand-file-name nbdir)))))) (callback2 (apply-partially (lambda (path* callback* buffer url-or-port) (pop-to-buffer buffer) (ein:notebook-open url-or-port diff --git a/lisp/ob-ein.el b/lisp/ob-ein.el index ef12c0c..3cc2f8f 100644 --- a/lisp/ob-ein.el +++ b/lisp/ob-ein.el @@ -333,8 +333,7 @@ if necessary. Install CALLBACK (i.e., cell execution) upon notebook retrieval." kernelspec) (cl-letf (((symbol-function 'y-or-n-p) #'ignore)) (ein:notebook-close notebook)) - (ein:query-singleton-ajax - (ein:notebook-url notebook) + (ein:query-singleton-ajax (ein:notebook-url notebook) :type "DELETE") (cl-loop repeat 8 with fullpath = (concat (file-name-as-directory nbpath) path)