Skip to content

Commit 3fd6a5a

Browse files
committed
core: add support for standard notes' export files
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
1 parent 9fc832d commit 3fd6a5a

File tree

2 files changed

+119
-45
lines changed

2 files changed

+119
-45
lines changed

packages/core/src/providers/provider-factory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
1717
along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
*/
1919

20-
// import { StandardNotes } from "./standard-notes";
20+
import { StandardNotes } from "./standard-notes";
2121
import { Evernote } from "./evernote";
2222
import { Markdown } from "./md";
2323
import { HTML } from "./html";
@@ -40,7 +40,7 @@ const providerMap = {
4040
keep: GoogleKeep,
4141
simplenote: Simplenote,
4242
// onenote: OneNote,
43-
// standardnotes: StandardNotes,
43+
standardnotes: StandardNotes,
4444
zohonotebook: ZohoNotebook,
4545
joplin: Joplin,
4646
textbundle: TextBundle,

packages/core/src/providers/standard-notes/index.ts

Lines changed: 117 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ import {
3838
import { buildTable, Cell, Row } from "../../utils/dom-utils";
3939
import { markdowntoHTML, textToHTML } from "../../utils/to-html";
4040
import { Providers } from "../provider-factory";
41+
import { HTML } from "../html";
42+
import { Markdown } from "../md";
43+
import { Text } from "../txt";
4144

4245
const defaultEditorDescription = (item: SNNote): EditorDescription => {
4346
const isHtml =
@@ -58,6 +61,7 @@ export class StandardNotes implements IFileProvider {
5861
examples = ["Standard Notes Backup - Fri Jan 14 2022 10_31_29 GMT+0500.zip"];
5962
helpLink =
6063
"https://help.notesnook.com/importing-notes/import-notes-from-standardnotes";
64+
standardNotesBackupAndImportFileName = "Standard Notes Backup and Import File.txt";
6165

6266
filter(file: File) {
6367
return [".txt"].includes(file.extension);
@@ -68,7 +72,68 @@ export class StandardNotes implements IFileProvider {
6872
_settings: ProviderSettings,
6973
_files: File[]
7074
): AsyncGenerator<ProviderMessage, void, unknown> {
71-
if (file.name !== "Standard Notes Backup and Import File.txt") return;
75+
if (file.extension === ".txt" && file.name !== this.standardNotesBackupAndImportFileName) {
76+
const text = new Text();
77+
yield* text.process(file, _settings, _files);
78+
}
79+
80+
if (file.extension === ".html") {
81+
const html = new HTML();
82+
yield* html.process(file, _settings, _files);
83+
}
84+
85+
if (file.extension === ".md") {
86+
const md = new Markdown();
87+
yield* md.process(file, _settings, _files)
88+
}
89+
90+
if (file.extension === ".json") {
91+
const text = await file.text();
92+
const data = JSON.parse(text);
93+
94+
let type: NoteType.Authentication | NoteType.Spreadsheet | null = null;
95+
if (Array.isArray(data)) {
96+
type = NoteType.Authentication;
97+
} else if ('sheets' in (data)) {
98+
type = NoteType.Spreadsheet;
99+
} else {
100+
type = null;
101+
}
102+
103+
if (type === NoteType.Authentication) {
104+
const html = this.parseAuthenticationContent(text);
105+
const content = {
106+
data: html,
107+
type: ContentType.HTML
108+
};
109+
const note: Note = {
110+
title: file.name,
111+
dateCreated: file.createdAt,
112+
dateEdited: file.modifiedAt,
113+
content
114+
};
115+
116+
yield { type: "note", note };
117+
}
118+
119+
if (type === NoteType.Spreadsheet) {
120+
const html = this.parseSpreadsheetContent(text);
121+
const content: Content = {
122+
type: ContentType.HTML,
123+
data: html
124+
};
125+
const note: Note = {
126+
title: file.name,
127+
dateCreated: file.createdAt,
128+
dateEdited: file.modifiedAt,
129+
content
130+
};
131+
132+
yield { type: "note", note };
133+
}
134+
}
135+
136+
if (file.name !== this.standardNotesBackupAndImportFileName) return;
72137

73138
const data: SNBackup = <SNBackup>JSON.parse(await file.text());
74139
if (!data.items) {
@@ -190,54 +255,14 @@ export class StandardNotes implements IFileProvider {
190255
};
191256
}
192257
case NoteType.Spreadsheet: {
193-
const spreadsheet = <Spreadsheet>JSON.parse(data);
194-
let html = ``;
195-
196-
for (const sheet of spreadsheet.sheets) {
197-
if (!sheet.rows || sheet.rows.length === 0) continue;
198-
199-
const lastCell = this.maxIndexItem(
200-
sheet.rows.map((row) => this.maxIndexItem(row.cells || []))
201-
);
202-
const lastRow = this.maxIndexItem(sheet.rows);
203-
const [maxColumns, maxRows] = [
204-
lastCell.index || 0,
205-
lastRow.index || 0
206-
];
207-
208-
const rows: Row[] = [];
209-
for (let i = 0; i <= maxRows; i++) {
210-
const row = sheet.rows.find(({ index }) => index === i);
211-
const cells: Cell[] = [];
212-
213-
for (let col = 0; col <= maxColumns; col++) {
214-
const cell = row?.cells?.find(({ index }) => index === col);
215-
cells.push({ type: "td", value: cell?.value?.toString() || "" });
216-
}
217-
rows.push({ cells });
218-
}
219-
220-
html += buildTable(rows);
221-
}
258+
const html = this.parseSpreadsheetContent(data);
222259
return {
223260
type: ContentType.HTML,
224261
data: html
225262
};
226263
}
227264
case NoteType.Authentication: {
228-
const tokens = <any[]>JSON.parse(data);
229-
const html = tokens
230-
.map((token) =>
231-
buildTable(
232-
Object.keys(token).map((key) => ({
233-
cells: [
234-
{ type: "th", value: key },
235-
{ type: "td", value: token[key] }
236-
]
237-
}))
238-
)
239-
)
240-
.join("\n");
265+
const html = this.parseAuthenticationContent(data);
241266
return {
242267
data: html,
243268
type: ContentType.HTML
@@ -276,4 +301,53 @@ export class StandardNotes implements IFileProvider {
276301
if (createdAt === 0) createdAt = undefined;
277302
return { createdAt, updatedAt };
278303
}
304+
305+
private parseAuthenticationContent(data: string): string {
306+
const tokens = <any[]>JSON.parse(data);
307+
return tokens
308+
.map((token) =>
309+
buildTable(
310+
Object.keys(token).map((key) => ({
311+
cells: [
312+
{ type: "th", value: key },
313+
{ type: "td", value: token[key] }
314+
]
315+
}))
316+
)
317+
)
318+
.join("\n");
319+
}
320+
321+
private parseSpreadsheetContent(data: string): string {
322+
const spreadsheet = <Spreadsheet>JSON.parse(data);
323+
let html = ``;
324+
325+
for (const sheet of spreadsheet.sheets) {
326+
if (!sheet.rows || sheet.rows.length === 0) continue;
327+
328+
const lastCell = this.maxIndexItem(
329+
sheet.rows.map((row) => this.maxIndexItem(row.cells || []))
330+
);
331+
const lastRow = this.maxIndexItem(sheet.rows);
332+
const [maxColumns, maxRows] = [
333+
lastCell.index || 0,
334+
lastRow.index || 0
335+
];
336+
337+
const rows: Row[] = [];
338+
for (let i = 0; i <= maxRows; i++) {
339+
const row = sheet.rows.find(({ index }) => index === i);
340+
const cells: Cell[] = [];
341+
342+
for (let col = 0; col <= maxColumns; col++) {
343+
const cell = row?.cells?.find(({ index }) => index === col);
344+
cells.push({ type: "td", value: cell?.value?.toString() || "" });
345+
}
346+
rows.push({ cells });
347+
}
348+
349+
html += buildTable(rows);
350+
}
351+
return html;
352+
}
279353
}

0 commit comments

Comments
 (0)