Skip to content

Commit

Permalink
Merge pull request #183 from vidartf/omni2
Browse files Browse the repository at this point in the history
Omnibus 2
  • Loading branch information
vidartf committed Nov 8, 2023
2 parents 0889331 + 4839b85 commit b1110bd
Show file tree
Hide file tree
Showing 32 changed files with 2,645 additions and 493 deletions.
2 changes: 2 additions & 0 deletions js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@
"jszip": "^3.7.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"semver": "^7.5.4",
"tree-finder": "^0.0.13"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/preset-env": "^7.20.2",
"@jupyterlab/builder": "^4.0.0",
"@rjsf/utils": "^5.13.2",
"@types/file-saver": "^2.0.1",
"@types/jest": "^29.5.1",
"@types/jszip": "^3.4.1",
Expand Down
104 changes: 101 additions & 3 deletions js/schema/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"jupyter.lab.setting-icon": "jfs:drive",
"jupyter.lab.setting-icon-label": "jupyter-fs",
"type": "object",
"additionalProperties": false,

"jupyter.lab.shortcuts": [
{
Expand Down Expand Up @@ -39,14 +38,18 @@
"resource": {
"description": "Specification for an fs resource",
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"description": "Display name of resource",
"type": "string"
},
"url": {
"description": "A url pointing to an fs resource, as per the PyFilesystem fsurl specification",
"type": "string",
"pattern": "^.+?:\/\/([^:]*:.*@.*|[^@]*)$"
},
"preferred_dir": {
"description": "Directory to be first opened (e.g., myDir/mySubdir)",
"type": "string"
},
"auth": {
Expand All @@ -61,6 +64,30 @@
"default": true
}
}
},
"snippet": {
"description": "Per entry snippets for how to use it, e.g. a snippet for how to open a file from a given resource",
"type": "object",
"properties": {
"label": {
"description": "The designator to show to users",
"type": "string"
},
"caption": {
"description": "An optional, longer description to show to users",
"type": "string",
"default": ""
},
"pattern": {
"description": "A regular expression to match against the full URL of the entry, indicating if this snippet is valid for it",
"type": "string",
"default": ""
},
"template": {
"description": "A template string to build up the snippet",
"type": "string"
}
}
}
},

Expand All @@ -72,11 +99,78 @@
"type": "array",
"default": []
},
"snippets": {
"title": "Snippets",
"description": "A list of usage snippets",
"items": { "$ref": "#/definitions/snippet" },
"type": "array",
"default": [
{
"label": "Read CSV as dataframe",
"caption": "Read the contents of this CSV file as a pandas DataFrame",
"pattern": "\\.csv$",
"template": "# uses https://docs.pyfilesystem.org/en/latest/reference/base.html#fs.base.FS.openbin \nfrom jupyterfs import open_fs\nimport pandas\nwith open_fs(\"{{url}}\") as fs_instance:\n df = pandas.read_csv(fs_instance.openbin(\"{{path}}\"))"
},
{
"label": "Read contents",
"caption": "Read the contents of this file with PyFilesystem",
"pattern": "^(?!osfs://)(.*/)?[^/]+$",
"template": "# uses https://docs.pyfilesystem.org/en/latest/reference/base.html#fs.base.FS.readbytes \nfrom jupyterfs import open_fs\nwith open_fs(\"{{url}}\") as fs_instance:\n contents = fs_instance.readbytes(\"{{path}}\")"
},
{
"label": "Read contents (local)",
"caption": "Read the contents of this local file",
"pattern": "^(?=osfs://)(.*/)?[^/]+$",
"template": "import pathlib;\ncontents = pathlib.Path(\"{{path}}\").read_bytes()"
},
{
"label": "Read text",
"caption": "Read the contents of this file as text with PyFilesystem",
"pattern": "^(?!osfs://)(.*/)?[^/]+$",
"template": "# uses https://docs.pyfilesystem.org/en/latest/reference/base.html#fs.base.FS.readtext \nfrom jupyterfs import open_fs\nwith open_fs(\"{{url}}\") as fs_instance:\n contents = fs_instance.readtext(\"{{path}}\")"
},
{
"label": "List directory contents",
"caption": "List the entries of this directory with PyFilesystem",
"pattern": "^.*/$",
"template": "# uses https://docs.pyfilesystem.org/en/latest/reference/base.html#fs.base.FS.listdir \nfrom jupyterfs import open_fs\nwith open_fs(\"{{url}}\") as fs_instance:\n entries = fs_instance.listdir(\"{{path}}\")"
},
{
"label": "Read Excel as dataframe",
"caption": "Read the contents of this Excel file as a pandas DataFrame",
"pattern": "\\.(xls|xlsx|xlsm|xlsb)$",
"template": "# uses https://docs.pyfilesystem.org/en/latest/reference/base.html#fs.base.FS.open \nfrom jupyterfs import open_fs\nimport pandas\nwith open_fs(\"{{url}}\") as fs_instance:\n df = pandas.read_excel(fs_instance.open(\"{{path}}\", mode=\"rb\"))"
},
{
"label": "Write dataframe as CSV",
"caption": "Save a pandas DF from the session to the given CSV file with PyFilesystem",
"pattern": "\\.csv$",
"template": "# uses https://docs.pyfilesystem.org/en/latest/reference/base.html#fs.base.FS.writetext \nfrom jupyterfs import open_fs\nwith open_fs(\"{{url}}\") as fs_instance:\n fs_instance.writetext(\"{{path}}\", YOUR_DF_VARIABLE.to_csv())"
},
{
"label": "Write contents",
"caption": "Write the given contents (bytes) to the specified file with PyFilesystem",
"pattern": "^(?!osfs://)(.*/)?[^/]+$",
"template": "# uses https://docs.pyfilesystem.org/en/latest/reference/base.html#fs.base.FS.writebytes \nfrom jupyterfs import open_fs\nwith open_fs(\"{{url}}\") as fs_instance:\n fs_instance.writebytes(\"{{path}}\", YOUR_BYTES_CONTENT)"
},
{
"label": "Write contents (local)",
"caption": "Write the contents to this local file",
"pattern": "^(?=osfs://)(.*/)?[^/]+$",
"template": "import pathlib;\ncontents = pathlib.Path(\"{{path}}\").write_bytes(YOUR_BYTES_CONTENT)"
},
{
"label": "Write text",
"caption": "Write the given text to the specified file with PyFilesystem",
"pattern": "^(?!osfs://)(.*/)?[^/]+$",
"template": "# uses https://docs.pyfilesystem.org/en/latest/reference/base.html#fs.base.FS.writetext \nfrom jupyterfs import open_fs\nwith open_fs(\"{{url}}\") as fs_instance:\n fs_instance.writetext(\"{{path}}\", YOUR_TEXT_CONTENT)"
}
]
},
"options": {
"title": "Options",
"description": "Global options for jupyter-fs",
"type": "object",
"additionalProperties": false,
"properties": {
"cache": {
"description": "If true, only recreate the actual resources when necessary (ie on initial load or changes to 'resources')",
Expand All @@ -87,6 +181,10 @@
"description": "If true, jupyter-fs will output helpful info messages to the console",
"type": "boolean",
"default": false
},
"writtenVersion": {
"description": "The version of the schema these settings were written with (do not edit)",
"type": "string"
}
},
"default": {}
Expand Down
12 changes: 9 additions & 3 deletions js/src/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
TextField,
InputAdornment,
IconButton,
Tooltip,
} from "@material-ui/core";
import * as React from "react";

Expand Down Expand Up @@ -54,8 +55,8 @@ function tokensFromUrl(url: string): string[] {
return new DoubleBraceTemplate(url).tokens();
}

function _askRequired(spec: IFSResource) {
return spec.auth === "ask" && !spec.init;
function _askRequired(spec: IFSResource): boolean {
return spec.auth === "ask" && !spec.init && !!(spec.missingTokens?.length);
}

export function askRequired(specs: IFSResource[]) {
Expand Down Expand Up @@ -131,6 +132,7 @@ export class AskDialog<
protected _formInner() {
return this.props.resources.map(resource => {
// ask for credentials if needed, or state why not
const decodedUrl = decodeURIComponent(resource.url);
const askReq = _askRequired(resource);
const inputs = askReq ? this._inputs(resource.url) : [];
const tokens = tokensFromUrl(resource.url);
Expand All @@ -153,7 +155,11 @@ export class AskDialog<
>
<ExpansionPanelSummary className="jfs-ask jfs-ask-panel-summary">
<Typography>{summary}</Typography>
{!reason && <Typography>{resource.url}</Typography>}
{!reason &&
<Tooltip title={decodedUrl}>
<Typography noWrap={true}>{decodedUrl}</Typography>
</Tooltip>
}
</ExpansionPanelSummary>
<ExpansionPanelDetails className="jfs-ask jfs-ask-panel-details">
{inputs}
Expand Down
Loading

0 comments on commit b1110bd

Please sign in to comment.