Skip to content

Commit e13c243

Browse files
authored
Save data in a csv file (#4)
1 parent a7a6b58 commit e13c243

File tree

3 files changed

+113
-10
lines changed

3 files changed

+113
-10
lines changed

package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,18 @@
5656
"watch:labextension": "jupyter labextension watch ."
5757
},
5858
"dependencies": {
59+
"@json2csv/plainjs": "^7.0.0",
5960
"@jupyterlab/application": "^4.0.0",
61+
"@jupyterlab/apputils": "^4.0.0",
62+
"@jupyterlab/cells": "^4.0.0",
6063
"@jupyterlab/coreutils": "^6.0.0",
64+
"@jupyterlab/notebook": "^4.0.0",
6165
"@jupyterlab/services": "^7.0.0",
62-
"@jupyterlab/settingregistry": "^4.0.0"
66+
"@jupyterlab/settingregistry": "^4.0.0",
67+
"@jupyterlab/ui-components": "^4.0.0",
68+
"@lumino/commands": "^2.0.0",
69+
"@lumino/signaling": "^2.0.0",
70+
"react": "^18.2.0"
6371
},
6472
"devDependencies": {
6573
"@jupyterlab/builder": "^4.0.0",

src/index.ts

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import { Parser } from '@json2csv/plainjs';
12
import {
23
JupyterFrontEnd,
34
JupyterFrontEndPlugin
45
} from '@jupyterlab/application';
56
import { ICommandPalette, IToolbarWidgetRegistry } from '@jupyterlab/apputils';
67
import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook';
8+
import { Contents, ContentsManager } from '@jupyterlab/services';
79
import { ISettingRegistry } from '@jupyterlab/settingregistry';
810
import { runIcon } from '@jupyterlab/ui-components';
911

@@ -34,20 +36,24 @@ const plugin: JupyterFrontEndPlugin<void> = {
3436
label: 'Run SQL',
3537
caption: 'Run SQL',
3638
icon: runIcon,
37-
execute: () => {
39+
execute: async args => {
40+
const path = (args?.path || '_sql_output') as string;
41+
3842
const activeCell = tracker.activeCell;
3943

4044
if (!(activeCell?.model.type === 'raw')) {
4145
return;
4246
}
43-
47+
const date = new Date();
4448
const source = activeCell?.model.sharedModel.getSource();
4549
requestAPI<any>('execute', {
4650
method: 'POST',
4751
body: JSON.stringify({ query: source })
4852
})
4953
.then(data => {
50-
console.log(data);
54+
saveData(path, data.data, date)
55+
.then(dataPath => console.log(`Data saved ${dataPath}`))
56+
.catch(undefined);
5157
})
5258
.catch(reason => {
5359
console.error(
@@ -100,3 +106,52 @@ const plugin: JupyterFrontEndPlugin<void> = {
100106
};
101107

102108
export default plugin;
109+
110+
/**
111+
* Save data in a CSV file.
112+
*
113+
* @param path - the path to the directory where to save data.
114+
* @param data - the data to parse as CSV.
115+
* @param date - the query date.
116+
*/
117+
async function saveData(
118+
path: string,
119+
data: any,
120+
date: Date
121+
): Promise<string | undefined> {
122+
const contentsManager = new ContentsManager();
123+
const parser = new Parser();
124+
const csv = parser.parse(data);
125+
126+
const dateText = date
127+
.toLocaleString()
128+
.replace(/[/:]/g, '-')
129+
.replace(/\s/g, '')
130+
.replace(',', '_');
131+
132+
const filename = `${dateText}.csv`;
133+
const fileModel = {
134+
name: filename,
135+
path: `${path}/${filename}`,
136+
format: 'text' as Contents.FileFormat,
137+
content: csv
138+
};
139+
140+
let currentPath = '';
141+
for (const directory of path.split('/')) {
142+
currentPath = `${currentPath}${directory}/`;
143+
await contentsManager
144+
.get(currentPath, { content: false })
145+
.catch(() => contentsManager.save(currentPath, { type: 'directory' }));
146+
}
147+
148+
return contentsManager
149+
.save(fileModel.path, fileModel)
150+
.then(() => {
151+
return fileModel.path;
152+
})
153+
.catch(e => {
154+
console.error(e);
155+
return undefined;
156+
});
157+
}

yarn.lock

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,16 +2039,41 @@ __metadata:
20392039
languageName: node
20402040
linkType: hard
20412041

2042+
"@json2csv/formatters@npm:^7.0.3":
2043+
version: 7.0.3
2044+
resolution: "@json2csv/formatters@npm:7.0.3"
2045+
checksum: 283ae93eda527a25f0dedbfe3350f06a2c35c925da293e92a54b31fba979fa9afc39de2b3766012e52f8f8539bfa0468eb25081370d8728f93bf5cb8d08a9a8f
2046+
languageName: node
2047+
linkType: hard
2048+
2049+
"@json2csv/plainjs@npm:^7.0.0":
2050+
version: 7.0.3
2051+
resolution: "@json2csv/plainjs@npm:7.0.3"
2052+
dependencies:
2053+
"@json2csv/formatters": ^7.0.3
2054+
"@streamparser/json": ^0.0.17
2055+
lodash.get: ^4.4.2
2056+
checksum: 34d0d9558494f530938bf4a259c65413bb069bd4ab66f6c56e1e46e02c20d35f68b3c994e2784aeae81dc365e59b22be2d2d88a11a0777b168a76ebf68f350f7
2057+
languageName: node
2058+
linkType: hard
2059+
20422060
"@jupyter/sql-cell@workspace:.":
20432061
version: 0.0.0-use.local
20442062
resolution: "@jupyter/sql-cell@workspace:."
20452063
dependencies:
2064+
"@json2csv/plainjs": ^7.0.0
20462065
"@jupyterlab/application": ^4.0.0
2066+
"@jupyterlab/apputils": ^4.0.0
20472067
"@jupyterlab/builder": ^4.0.0
2068+
"@jupyterlab/cells": ^4.0.0
20482069
"@jupyterlab/coreutils": ^6.0.0
2070+
"@jupyterlab/notebook": ^4.0.0
20492071
"@jupyterlab/services": ^7.0.0
20502072
"@jupyterlab/settingregistry": ^4.0.0
20512073
"@jupyterlab/testutils": ^4.0.0
2074+
"@jupyterlab/ui-components": ^4.0.0
2075+
"@lumino/commands": ^2.0.0
2076+
"@lumino/signaling": ^2.0.0
20522077
"@types/jest": ^29.2.0
20532078
"@types/json-schema": ^7.0.11
20542079
"@types/react": ^18.0.26
@@ -2063,6 +2088,7 @@ __metadata:
20632088
mkdirp: ^1.0.3
20642089
npm-run-all: ^4.1.5
20652090
prettier: ^3.0.0
2091+
react: ^18.2.0
20662092
rimraf: ^5.0.1
20672093
source-map-loader: ^1.0.2
20682094
style-loader: ^3.3.1
@@ -2118,7 +2144,7 @@ __metadata:
21182144
languageName: node
21192145
linkType: hard
21202146

2121-
"@jupyterlab/apputils@npm:^4.1.6":
2147+
"@jupyterlab/apputils@npm:^4.0.0, @jupyterlab/apputils@npm:^4.1.6":
21222148
version: 4.1.6
21232149
resolution: "@jupyterlab/apputils@npm:4.1.6"
21242150
dependencies:
@@ -2202,7 +2228,7 @@ __metadata:
22022228
languageName: node
22032229
linkType: hard
22042230

2205-
"@jupyterlab/cells@npm:^4.0.6":
2231+
"@jupyterlab/cells@npm:^4.0.0, @jupyterlab/cells@npm:^4.0.6":
22062232
version: 4.0.6
22072233
resolution: "@jupyterlab/cells@npm:4.0.6"
22082234
dependencies:
@@ -2441,7 +2467,7 @@ __metadata:
24412467
languageName: node
24422468
linkType: hard
24432469

2444-
"@jupyterlab/notebook@npm:^4.0.6":
2470+
"@jupyterlab/notebook@npm:^4.0.0, @jupyterlab/notebook@npm:^4.0.6":
24452471
version: 4.0.6
24462472
resolution: "@jupyterlab/notebook@npm:4.0.6"
24472473
dependencies:
@@ -2681,7 +2707,7 @@ __metadata:
26812707
languageName: node
26822708
linkType: hard
26832709

2684-
"@jupyterlab/ui-components@npm:^4.0.6":
2710+
"@jupyterlab/ui-components@npm:^4.0.0, @jupyterlab/ui-components@npm:^4.0.6":
26852711
version: 4.0.6
26862712
resolution: "@jupyterlab/ui-components@npm:4.0.6"
26872713
dependencies:
@@ -2885,7 +2911,7 @@ __metadata:
28852911
languageName: node
28862912
linkType: hard
28872913

2888-
"@lumino/commands@npm:^2.1.3":
2914+
"@lumino/commands@npm:^2.0.0, @lumino/commands@npm:^2.1.3":
28892915
version: 2.1.3
28902916
resolution: "@lumino/commands@npm:2.1.3"
28912917
dependencies:
@@ -2968,7 +2994,7 @@ __metadata:
29682994
languageName: node
29692995
linkType: hard
29702996

2971-
"@lumino/signaling@npm:^1.10.0 || ^2.0.0, @lumino/signaling@npm:^2.1.2":
2997+
"@lumino/signaling@npm:^1.10.0 || ^2.0.0, @lumino/signaling@npm:^2.0.0, @lumino/signaling@npm:^2.1.2":
29722998
version: 2.1.2
29732999
resolution: "@lumino/signaling@npm:2.1.2"
29743000
dependencies:
@@ -3119,6 +3145,13 @@ __metadata:
31193145
languageName: node
31203146
linkType: hard
31213147

3148+
"@streamparser/json@npm:^0.0.17":
3149+
version: 0.0.17
3150+
resolution: "@streamparser/json@npm:0.0.17"
3151+
checksum: 5e1cb2113d3393b5858a2d32133ba9efed2ea732100f9967c50ec6104bc4d4948546d3263cbdb6b69185a49420dc216fb5f341b38eaad57293d6693357036c46
3152+
languageName: node
3153+
linkType: hard
3154+
31223155
"@tootallnate/once@npm:2":
31233156
version: 2.0.0
31243157
resolution: "@tootallnate/once@npm:2.0.0"
@@ -7357,6 +7390,13 @@ __metadata:
73577390
languageName: node
73587391
linkType: hard
73597392

7393+
"lodash.get@npm:^4.4.2":
7394+
version: 4.4.2
7395+
resolution: "lodash.get@npm:4.4.2"
7396+
checksum: e403047ddb03181c9d0e92df9556570e2b67e0f0a930fcbbbd779370972368f5568e914f913e93f3b08f6d492abc71e14d4e9b7a18916c31fa04bd2306efe545
7397+
languageName: node
7398+
linkType: hard
7399+
73607400
"lodash.memoize@npm:4.x":
73617401
version: 4.1.2
73627402
resolution: "lodash.memoize@npm:4.1.2"

0 commit comments

Comments
 (0)