willkessler / jupytergraffiti Goto Github PK
View Code? Open in Web Editor NEWCreate interactive screencasts inside Jupyter Notebook that anybody can play back
License: Other
Create interactive screencasts inside Jupyter Notebook that anybody can play back
License: Other
Found that the control panel will cover on the cell content by default, and it's affected by the commit "align control panel with right edge of cells, not sitePanel".
Could you help explain the reason for this setting?
Getting approval to use Open Sourced tools, (even excellent ones), can be hard in many companies and involve the legal people - unfortunately expecting them to:
is a bit too much to ask.
The convention of an explicit LICENCE.txt at the top level of the repository is a valuable one to follow - I think that GitHub actually parses it as well.
Hi Will,
Thanks for this useful tool! I noticed the following bug when deploying jupytergraffiti
on my computer and then checked that it also occurs on the Binder version of the general demo.
Steps to reproduce:
X
.What happens:
The recording continues to play and there is no way out of it without waiting for it to end or refreshing the window.
Expected response:
The graffiti recording stops playing when the recording is closed.
Many thanks,
Achintya
If there are cells with previously existing output, not all cell outputs may get restored during playback. This is due to a logic bug in graffiti.js:
updateContents: (index, currentScrollTop) => {
const contentsRecord = state.getHistoryItem('contents', index);
const cells = Jupyter.notebook.get_cells();
let cellId, contents, outputs, frameContents, frameOutputs, renderedFrameOutput = false;
graffiti.applyCellListToNotebook(contentsRecord);
for (let cell of cells) {
if (cell.cell_type === 'code') {
cellId = utils.getMetadataCellId(cell.metadata);
if (state.graffitiShouldUpdateCellContents(cellId)) {
const contents = cell.get_text();
if (contentsRecord.cellsContent.hasOwnProperty(cellId)) {
frameContents = state.extractDataFromContentRecord(contentsRecord.cellsContent[cellId].contentsRecord, cellId);
if (frameContents !== undefined && frameContents !== contents) {
//console.log('Setting text on cellid:', utils.getMetadataCellId(cell.metadata));
cell.set_text(frameContents);
}
frameOutputs = state.extractDataFromContentRecord(contentsRecord.cellsContent[cellId].outputsRecord, cellId);
renderedFrameOutput = renderedFrameOutput || didRestoreFrameOutput;
}
}
}
}
The problem is that if renderedFrameOutput
becomes true for one cell then subsequent cells won't get output rendered. That is, this line:
renderedFrameOutput = renderedFrameOutput || renderedFrameOutput || didRestoreFrameOutput;
The fix is pending and will look like this:
didRestoreFrameOutput = state.restoreCellOutputs(cell, frameOutputs);
renderedFrameOutput = renderedFrameOutput || didRestoreFrameOutput;
This guarantees that state.restoreCellOutputs()
is always called regardless of whether it was called previously.
Using the docker image installation method works fine. But, when I try to do using the 3rd method of installation (in order to avoid docker), I get the above error on running jupyter nbextension enable graffiti_extension/main --user
. The previous steps of the installation went perfectly without any errors.
The error reads as follows :
Enabling notebook extension graffiti_extension/main...
- Validating: problems found:
- require? X graffiti_extension/main
I do not know how to fix this, as I am a complete beginner. I would really appreciate any help if possible.
After I use import on Jetson, the interface appears garbled code, is it because Jetson is an ARM architecture instead of x86
When determining whether the server operating system is Windows or Linux, you should confirm it during the plug-in installation process, rather than relying on the operating system of the client browser.
Dear @willkessler,
we have encountered a problem with the show/hide solution buttons in JupyterGraffiti (1.0.1.18).
It seems like the feature to create a solution box doesn't write a new file. If we want to display the solution, we obtain:
Note that the used kernel is "Python 3" (also visible in the figure). Interestingly, we are able to record and play voice recordings in the same setup.
We experienced the problem on various Windows machines and have also worked with Docker. Even with Docker the problem persists. On MacOSX everything works fine for some reason.
We currently work around the problem by using the "old" method of manually creating files and linking them to the solution button.
When converting a cell to a show/hide solution button jupytergraffiti writes the cells content to an external file that is loaded upon pressing the newly created show/hide button.
As far as I can see, it is not possible to update the content of this solution file directly from the jupyter notebook.
Instead the auto-generated files need to be opened and the content adapted in an external editor.
Especially, when many proposed solutions are present in the notebook it is very hard to find the corresponding file (since the names are autogenerated and not descriptive).
Of course it needs to be ensured, that the students working with the jupyter notebook can not easily change the content of the proposed solution (could happen by accident).
This extension is awesome using in jupyter notebook.
But i offen use jupyter lab, and want to intall in it.
So, i am not sure jupytergraffiti can do it or not.
If it can, please tell me how to do it?
Thank you very much.
Any chance to make this pip (and/or conda)-installable?
Hi
On a Mac (10.13.6), when using the terminal+code cell combination, the terminal's pwd
is set to the directory in which the Jupyter server is running.
Clicking the Jump to Notebook's Dir
link has no effect. For example, I can manually change directory in the terminal and run a pwd
to check that I have changed directory (which works). Whatever directory I manually change to, clicking the Jump to Notebook's Dir
link has no effect: the pwd
returns the same thing before and after clicking the button.
A side effect of this is that clicking the Run Code
button doesn't work in the general case - it will only work if the notebook (and hence the saved file) is in the same directory as the directory in which the notebook server was started.
Hi, I created a graffiti and recorded, but nothing is created in the jupytergraffiti_data
folder. When I clicked Play Movie
, I got 'Movie is not available'.
This is a bit of weird issue that we have encountered on multiple machines using firefox:
Recording works fine and on playback everything seems to work at first. After 3-4 seconds the sound stops, however.
Movement of the cursor and other interactions continue playing until the end of the recording.
Current workaround: Chrome works as expected.
The new feature to show/hide the currently selected cell creates a file with the cells content in the directory of the jupyter notebook.
This can seriously clutter the main directory. It would be great if these files could either end up in the jupytergraffiti_data directory or any user defined directory.
I notice that you're using a hardwired path to jupytergraffiti_data
here.
It would be useful if this path could be set by the jupytergraffiti screencast creator (eg they might want to specify a hidden directory or a common directory referenced from several directories containing their own graffitied notebooks), perhaps via a metadata editor / panel reached from / on the graffiti control panel?
A guard to check the existence of, and create otherwise, the directory would probably also make sense?
Occasionally it happens that a recording becomes corrupted and cannot be played back. The user is prompted to refer to the author of the notebook.
I cannot quite recreate the circumstances under which this happens. But even very short recordings in newly created notebooks with little content are sometimes affected. I estimate that this happens after every 10th recording on average.
The terminal in which the kernel is running displays such a message, whenever a corrupted recording is played:
[W 12:14:19.864 NotebookApp] 404 GET /notebooks/Desktop/Untitled%20Folder/jupytergraffiti_data/notebooks/id_ly85cbk/authors/dev/cells/id_54j2cgx/graffitis/id_4ngbmrt/takes/id_wr1j07o/history.txt (::1) 1.620000ms referer=http://localhost:8888/notebooks/Desktop/Untitled%20Folder/Untitled.ipynb?kernel_name=python3
If this problem arises, no further uncorrupted recordings can be added to the notebook: Existing recordings are still available but new recordings will throw a similar error.
To add further recordings the kernel needs to be restarted.
While this solves the problem for new recordings, all presently corrupted recordings stay corrupted.
Hello all !
I am trying to record a 6+ minutes codecast. It keeps displaying "Saving Graffiti Recordind. Please wait...", and nothing else happens.
I am working with Ubuntu 20.04.1 LTS, and graffiti 0.1.2 installed via pip (python 3.8). I tried on firefox (82.0) and chromium.
jupyter core : 4.6.3
jupyter-notebook : 6.0.3
qtconsole : 4.7.4
ipython : 7.15.0
ipykernel : 5.3.0
jupyter client : 6.1.3
jupyter lab : not installed
nbconvert : 5.6.1
ipywidgets : 7.5.1
nbformat : 5.0.6
traitlets : 4.3.3
I am not sure how to debug or correct this problem, do you have any suggestion ?
The codecast contains images displayed with matplotlib, it makes use of numpy and skimage, but nothing computationnaly expensive. Thank you in advance.
If you add a cell during a recording after the last cell, then on playback it will not insert the new cell after the last cell, but instead before the last cell.
Dear Will,
thank you for your great tool. We are using it a lot for teaching with Jupyter Notebooks and are very satisfied with the results.
We noticed a minor limitation however: Jupyter Notebooks with Widgets are a great tool for education but unfortunately it seems that Graffiti cannot capture our interactions with the widgets. This would be very beneficial because it allows to explain and interact at the same time.
I have attached a very simple Jupyter notebook (recording_with_widget.ipynb.zip) that show this behavior.
Best,
4flixt
Hi,
Fantastic work! This extension really helps a lot when teaching code.
I wonder is there a way to export recorded video as raw html and javascript (without Jupyter's python kernel)
Thanks
./jupytergraffiti/build_and_run.sh
(Re)Building docker image.
Sending build context to Docker daemon 1.324MB
Step 1/14 : FROM jupyter/datascience-notebook
latest: Pulling from jupyter/datascience-notebook
423ae2b273f4: Pull complete
de83a2304fa1: Pull complete
f9a83bce3af0: Pull complete
b6b53be908de: Pull complete
eac80289c2c5: Pull complete
b770752562e4: Pull complete
f9794a341066: Pull complete
157147dea6d0: Pull complete
a9cc9783b8fb: Pull complete
81c84a76cf52: Pull complete
7384c14c5b8f: Pull complete
96e5dd8ec1dd: Pull complete
54ff1acfdce5: Pull complete
9e8ff2458372: Pull complete
d281f5d9be70: Pull complete
4e3bcc2e9b25: Pull complete
37dd16c123a0: Pull complete
7512a97e9059: Pull complete
7e65510f9c51: Pull complete
199d2d12a4f0: Pull complete
87e795f2ae07: Pull complete
1ebe410b718e: Pull complete
28b79d334c41: Pull complete
6ea486a7cf22: Pull complete
fc2901daa1a3: Pull complete
0dccbd613972: Pull complete
21bba711623e: Pull complete
Digest: sha256:b672f926e0f2ddb4b68172d33c0fea64f8f66651e86e233dc12894ddf7299b98
Status: Downloaded newer image for jupyter/datascience-notebook:latest
---> ce97927bafa2
Step 2/14 : USER root
---> Running in 09374e988f97
Removing intermediate container 09374e988f97
---> 89a83cea4188
Step 3/14 : RUN curl -sL https://deb.nodesource.com/setup_11.x | sudo bash - && apt-get install -y nodejs
---> Running in 6d177fc7f9cc
================================================================================
================================================================================
DEPRECATION WARNING
Node.js 11.x is no longer actively supported!
You will not receive security or critical stability updates for this version.
You should migrate to a supported version of Node.js as soon as possible.
Use the installation script that corresponds to the version of Node.js you
wish to install. e.g.
* https://deb.nodesource.com/setup_10.x — Node.js 10 LTS "Dubnium" (recommended)
* https://deb.nodesource.com/setup_12.x — Node.js 12 LTS "Erbium"
Please see https://github.com/nodejs/Release for details about which
version may be appropriate for you.
The NodeSource Node.js distributions repository contains
information both about supported versions of Node.js and supported Linux
distributions. To learn more about usage, see the repository:
https://github.com/nodesource/distributions
================================================================================
================================================================================
Continuing in 20 seconds ...
## Installing the NodeSource Node.js 11.x repo...
## Populating apt-get cache...
+ apt-get update
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:3 http://security.ubuntu.com/ubuntu bionic-security/multiverse amd64 Packages [7,904 B]
Get:4 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [832 kB]
Get:5 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [861 kB]
Get:6 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:7 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
Get:8 http://archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1,344 kB]
Get:9 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages [35.2 kB]
Get:10 http://archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages [13.5 kB]
Get:11 http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages [11.3 MB]
Get:12 http://archive.ubuntu.com/ubuntu bionic/multiverse amd64 Packages [186 kB]
Get:13 http://archive.ubuntu.com/ubuntu bionic-updates/multiverse amd64 Packages [11.9 kB]
Get:14 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [48.7 kB]
Get:15 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [1,362 kB]
Get:16 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [1,155 kB]
Get:17 http://archive.ubuntu.com/ubuntu bionic-backports/main amd64 Packages [2,496 B]
Get:18 http://archive.ubuntu.com/ubuntu bionic-backports/universe amd64 Packages [4,247 B]
Fetched 17.7 MB in 8s (2,103 kB/s)
Reading package lists...
## Installing packages required for setup: lsb-release gnupg...
+ apt-get install -y lsb-release gnupg > /dev/null 2>&1
## Confirming "bionic" is supported...
+ wget -qO /dev/null -o /dev/null 'https://deb.nodesource.com/node_11.x/dists/bionic/Release'
## Adding the NodeSource signing key to your keyring...
+ wget -qO- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add -
Warning: apt-key output should not be parsed (stdout is not a terminal)
OK
## Creating apt sources list file for the NodeSource Node.js 11.x repo...
+ echo 'deb https://deb.nodesource.com/node_11.x bionic main' > /etc/apt/sources.list.d/nodesource.list
+ echo 'deb-src https://deb.nodesource.com/node_11.x bionic main' >> /etc/apt/sources.list.d/nodesource.list
## Running `apt-get update` for you...
+ apt-get update
Hit:1 http://security.ubuntu.com/ubuntu bionic-security InRelease
Get:2 https://deb.nodesource.com/node_11.x bionic InRelease [4,584 B]
Hit:3 http://archive.ubuntu.com/ubuntu bionic InRelease
Hit:4 http://archive.ubuntu.com/ubuntu bionic-updates InRelease
Hit:5 http://archive.ubuntu.com/ubuntu bionic-backports InRelease
Get:6 https://deb.nodesource.com/node_11.x bionic/main amd64 Packages [768 B]
Fetched 5,352 B in 1s (6,432 B/s)
Reading package lists...
## Run `sudo apt-get install -y nodejs` to install Node.js 11.x and npm
## You may also need development tools to build native addons:
sudo apt-get install gcc g++ make
## To install the Yarn package manager, run:
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get install yarn
Reading package lists...
Building dependency tree...
Reading state information...
The following NEW packages will be installed:
nodejs
0 upgraded, 1 newly installed, 0 to remove and 12 not upgraded.
Need to get 16.2 MB of archives.
After this operation, 77.9 MB of additional disk space will be used.
Get:1 https://deb.nodesource.com/node_11.x bionic/main amd64 nodejs amd64 11.15.0-1nodesource1 [16.2 MB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 16.2 MB in 2s (9,432 kB/s)
Selecting previously unselected package nodejs.
(Reading database ... 120073 files and directories currently installed.)
Preparing to unpack .../nodejs_11.15.0-1nodesource1_amd64.deb ...
Unpacking nodejs (11.15.0-1nodesource1) ...
Setting up nodejs (11.15.0-1nodesource1) ...
Removing intermediate container 6d177fc7f9cc
---> fcb26a88663f
Step 4/14 : RUN mkdir -p /opt/jupytergraffiti
---> Running in e34ecab1c85c
Removing intermediate container e34ecab1c85c
---> 89e23992ed0d
Step 5/14 : COPY . /opt/jupytergraffiti
---> 9f6070af249d
Step 6/14 : WORKDIR /opt/jupytergraffiti
---> Running in 369d58b0d429
Removing intermediate container 369d58b0d429
---> 7630b902da01
Step 7/14 : RUN cd /opt/jupytergraffiti && npm install && npm run build && jupyter nbextension install graffiti-dist && jupyter nbextension enable graffiti-dist/graffiti
---> Running in f3412255b6f7
npm WARN [email protected] No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
added 570 packages from 353 contributors and audited 10108 packages in 14.77s
found 288 vulnerabilities (287 low, 1 moderate)
run `npm audit fix` to fix them, or `npm audit` for details
> [email protected] build /opt/jupytergraffiti
> rm -rf graffiti-dist build ../build_for_pip/code-prep && node_modules/gulp/bin/gulp.js prebuild && node node_modules/.bin/r.js -o build.js && node_modules/gulp/bin/gulp.js moveStyles && node node_modules/.bin/r.js -o ../build_for_pip/buildPip.js && node_modules/gulp/bin/gulp.js pipMoveStyles
[17:14:22] Requiring external module @babel/register
Browserslist: caniuse-lite is outdated. Please run next command `npm update`
[17:14:22] Using gulpfile /opt/jupytergraffiti/gulpfile.babel.js
[17:14:22] Starting 'prebuild'...
[17:14:22] Starting 'main'...
[17:14:22] Starting 'jsFiles'...
[17:14:22] Starting 'pipMain'...
[17:14:22] Starting 'pipJsFiles'...
[17:14:23] Finished 'main' after 533 ms
[17:14:23] Finished 'pipMain' after 589 ms
[17:14:30] Finished 'jsFiles' after 7.64 s
[17:14:30] Finished 'pipJsFiles' after 7.64 s
[17:14:30] Finished 'prebuild' after 7.64 s
Tracing dependencies for: main
Uglify file: /opt/jupytergraffiti/graffiti-dist/graffiti.js
/opt/jupytergraffiti/graffiti-dist/graffiti.js
----------------
/opt/jupytergraffiti/build/js/LZString.js
/opt/jupytergraffiti/build/js/utils.js
/opt/jupytergraffiti/build/js/localizer.js
/opt/jupytergraffiti/build/js/xterm/xterm.js
/opt/jupytergraffiti/build/js/xterm/addons/fit/fit.js
/opt/jupytergraffiti/build/js/terminals.js
/opt/jupytergraffiti/build/js/state.js
/opt/jupytergraffiti/build/js/hark.js
/opt/jupytergraffiti/build/js/audio.js
/opt/jupytergraffiti/build/js/batchRunner.js
/opt/jupytergraffiti/build/js/storage.js
/opt/jupytergraffiti/build/js/sticker.js
/opt/jupytergraffiti/build/js/selectionSerializer.js
/opt/jupytergraffiti/build/js/workspace.js
/opt/jupytergraffiti/build/js/graffiti.js
/opt/jupytergraffiti/build/js/loader.js
/opt/jupytergraffiti/build/js/initExtension.js
/opt/jupytergraffiti/build/main.js
[17:14:35] Requiring external module @babel/register
Browserslist: caniuse-lite is outdated. Please run next command `npm update`
[17:14:36] Using gulpfile /opt/jupytergraffiti/gulpfile.babel.js
[17:14:36] Starting 'moveStyles'...
[17:14:36] Finished 'moveStyles' after 49 ms
Error: Error: ENOENT: no such file or directory, lstat '/opt/build_for_pip/buildPip.js'
at Object.realpathSync (fs.js:1566:7)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `rm -rf graffiti-dist build ../build_for_pip/code-prep && node_modules/gulp/bin/gulp.js prebuild && node node_modules/.bin/r.js -o build.js && node_modules/gulp/bin/gulp.js moveStyles && node node_modules/.bin/r.js -o ../build_for_pip/buildPip.js && node_modules/gulp/bin/gulp.js pipMoveStyles`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/jovyan/.npm/_logs/2020-03-26T17_14_36_425Z-debug.log
The command '/bin/sh -c cd /opt/jupytergraffiti && npm install && npm run build && jupyter nbextension install graffiti-dist && jupyter nbextension enable graffiti-dist/graffiti' returned a non-zero code: 1
Starting Jupyter Server container with Graffiti Extension...
Unable to find image 'jupytergraffiti:latest' locally
docker: Error response from daemon: pull access denied for jupytergraffiti, repository does not exist or may require 'docker login'.
See 'docker run --help'.
Is it possible to easily separate out the inline terminal into its own package?
I get the feeling it could be a handy thing to be able to drop into a non-graffiti notebook to provide an inline terminal. (It's possible to have a terminal and a notebook in view in JupyterLab, but to access a terminal when working in a traditional notebook requires opening the Jupyter terminal in another browser tab.)
Also, is there a way of resizing the inline terminal, eg making it draggable, or at least passing in a value that allows the height to be set manually?
Hello, first of all thank you for providing this great tool. But there seems to be a problem with notebook > 6.4.12. Once a newer version of notebook is installed, the interactive text no longer works. We have now seen this problem with many of our students and the only way to solve it seems to be to reinstall notebook == 6.4.12.
If I open jupyter notebook with notebook == 6.5.0 installed I get the following console output
[IPKernelApp] ERROR | No such comm target registered: jupyter.widget.control
[IPKernelApp] WARNING | No such comm: b8cfeda6-d1d5-48b2-8e9d-235c25888db0
Thank you
Felix
I visited the binder demo of graffiti on my iPad but the Drawing gesture will be recognise as scrolling.
The browser i used is Chrome.
I had run the following command before starting jupyter notebook,
pip3 install jupytergraffiti
jupyter nbextension install graffiti_extension --symlink --user jupyter nbextension enable graffiti_extension/main --user jupyter notebook
I was trying to save my notebook run using jupytergraffiti on chrome browser, Refer the screenshot,
OS: Ubuntu 18.04 (Google VM)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.