Exemplo n.º 1
0
  it("calls FileSaver.saveAs with notebook and filename", () => {
    const filename = "/here/there/awesome.ipynb";
    const expectedData = bigDummyJSON;
    expect(FileSaver.saveAs).not.toHaveBeenCalled();
    downloadString(
      stringifyNotebook(bigDummyJSON),
      filename,
      "application/json"
    );
    expect(FileSaver.saveAs).toHaveBeenCalledTimes(1);
    const actualMockBlobResponse = FileSaver.saveAs.mock.calls[0][0];
    const actualFilename = FileSaver.saveAs.mock.calls[0][1];

    expect(actualMockBlobResponse).toEqual({
      content: [stringifyNotebook(expectedData)],
      options: { type: "application/json" }
    });

    expect(actualFilename).toBe("awesome.ipynb");
  });
Exemplo n.º 2
0
export const downloadNotebook = (
  immutableNotebook: ?ImmutableNotebook,
  path: ?string
) => {
  if (immutableNotebook) {
    const notebook = commutable.toJS(immutableNotebook);
    const filename = (path || DEFAULT_NOTEBOOK_FILENAME).split("/").pop();
    const data = commutable.stringifyNotebook(notebook);
    const blob = new Blob([data], { type: "text/json" });
    FileSaver.saveAs(blob, filename);
  }
};
Exemplo n.º 3
0
      (
        action: actionTypes.Save | actionTypes.DownloadContent
      ): ActionsObservable<Action> => {
        const state = store.getState();

        const host = selectors.currentHost(state);
        if (host.type !== "jupyter") {
          // Dismiss any usage that isn't targeting a jupyter server
          return empty();
        }
        const contentRef = action.payload.contentRef;
        const content = selectors.content(state, { contentRef });

        // NOTE: This could save by having selectors for each model type
        //       have toDisk() selectors
        //       It will need to be cased off when we have more than one type
        //       of content we actually save
        if (!content) {
          const errorPayload = {
            error: new Error("Content was not set."),
            contentRef: action.payload.contentRef
          };
          if (action.type === actionTypes.DownloadContent) {
            return of(actions.downloadContentFailed(errorPayload));
          }
          return of(actions.saveFailed(errorPayload));
        }

        let filepath = content.filepath;

        // TODO: this default version should probably not be here.
        const appVersion = selectors.appVersion(state) || "0.0.0-beta";

        // This could be object for notebook, or string for files
        let serializedData: Notebook | string;
        let saveModel = {};
        if (content.type === "notebook") {
          // contents API takes notebook as raw JSON whereas downloading takes
          // a string
          serializedData = toJS(
            content.model.notebook.setIn(
              ["metadata", "nteract", "version"],
              appVersion
            )
          );
          saveModel = {
            content: serializedData,
            type: content.type
          };
        } else if (content.type === "file") {
          serializedData = content.model.text;
          saveModel = {
            content: serializedData,
            type: content.type,
            format: "text"
          };
        } else {
          // This shouldn't happen, is here for safety
          return empty();
        }

        switch (action.type) {
          case actionTypes.DOWNLOAD_CONTENT: {
            // FIXME: Convert this to downloadString, so it works for both files & notebooks
            if (
              content.type === "notebook" &&
              typeof serializedData === "object"
            ) {
              downloadString(
                stringifyNotebook(serializedData),
                filepath || "notebook.ipynb",
                "application/json"
              );
            } else if (
              content.type === "file" &&
              typeof serializedData === "string"
            ) {
              downloadString(
                serializedData,
                filepath,
                content.mimetype || "application/octet-stream"
              );
            } else {
              // This shouldn't happen, is here for safety
              return empty();
            }
            return of(
              actions.downloadContentFulfilled({
                contentRef: action.payload.contentRef
              })
            );
          }
          case actionTypes.SAVE: {
            const serverConfig = selectors.serverConfig(host);

            // if (action.type === actionTypes.SAVE)
            return contents.save(serverConfig, filepath, saveModel).pipe(
              mapTo(
                actions.saveFulfilled({ contentRef: action.payload.contentRef })
              ),
              catchError((error: Error) =>
                of(
                  actions.saveFailed({
                    error,
                    contentRef: action.payload.contentRef
                  })
                )
              )
            );
          }
          default:
            // NOTE: Flow types and our ofType should prevent reaching here, this
            // is here merely as safety
            return empty();
        }
      }
Exemplo n.º 4
0
export const asString = createSelector([asJSON], notebookJS => {
  if (notebookJS) {
    return commutable.stringifyNotebook(notebookJS);
  }
  return "";
});