mirror of
https://github.com/lenalebt/obsidian-pocketbook-cloud-highlight-importer.git
synced 2026-07-22 07:40:24 +00:00
improved login process, integrated some review comments
This commit is contained in:
parent
e0ba9f81d2
commit
c80bde0c92
13 changed files with 143 additions and 78 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "pocketbook-cloud-highlight-importer",
|
||||
"name": "Pocketbook Cloud Highlight Importer",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"minAppVersion": "1.1.16",
|
||||
"description": "Imports notes and highlights from your Pocketbook Cloud account.",
|
||||
"author": "Lena Brüder",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "obsidian-sample-plugin",
|
||||
"version": "1.0.0",
|
||||
"description": "This is a sample plugin for Obsidian (https://obsidian.md)",
|
||||
"name": "pocketbook-cloud-highlight-importer",
|
||||
"version": "0.1.3",
|
||||
"description": "Pocketbook Cloud Highlight Importer",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
|
|
|
|||
|
|
@ -61,6 +61,11 @@ export interface PocketbookCloudNote {
|
|||
uuid: string; //TODO: uuid type?
|
||||
}
|
||||
|
||||
interface PocketbookCloudShopInfo {
|
||||
name: string;
|
||||
shop_id: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main things to know about the API:
|
||||
*
|
||||
|
|
@ -144,7 +149,7 @@ export class PocketbookCloudLoginClient {
|
|||
) {}
|
||||
|
||||
async login() {
|
||||
const shop_id = await fetch(
|
||||
const shops: PocketbookCloudShopInfo[] = await fetch(
|
||||
'https://cloud.pocketbook.digital/api/v1.0/auth/login?' +
|
||||
new URLSearchParams({
|
||||
username: this.username,
|
||||
|
|
@ -156,51 +161,64 @@ export class PocketbookCloudLoginClient {
|
|||
.then(data => {
|
||||
return data;
|
||||
})
|
||||
.then(data => data.providers.filter((item: any) => item.name.includes(this.shop_name)))
|
||||
.then(data => data[0].shop_id);
|
||||
.then(data => data.providers.filter((item: PocketbookCloudShopInfo) => item.name.includes(this.shop_name)));
|
||||
|
||||
console.log(`shop_id: ${shop_id}`);
|
||||
const login_responses = await Promise.all(
|
||||
shops.map(async shop => {
|
||||
let result;
|
||||
try {
|
||||
if (this.refresh_token) {
|
||||
result = await requestUrl({
|
||||
url: 'https://cloud.pocketbook.digital/api/v1.0/auth/renew-token',
|
||||
method: 'POST',
|
||||
contentType: 'application/x-www-form-urlencoded',
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.access_token}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: this.refresh_token,
|
||||
}).toString(),
|
||||
}).then(response => response.json);
|
||||
} else if (this.password) {
|
||||
result = await requestUrl({
|
||||
url: 'https://cloud.pocketbook.digital/api/v1.0/auth/login/knv',
|
||||
method: 'POST',
|
||||
contentType: 'application/x-www-form-urlencoded',
|
||||
body: new URLSearchParams({
|
||||
shop_id: shop.shop_id,
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
client_id: this.client_id,
|
||||
client_secret: this.client_secret,
|
||||
grant_type: 'password',
|
||||
language: 'en',
|
||||
}).toString(),
|
||||
}).then(response => response.json);
|
||||
}
|
||||
} catch (error) {
|
||||
result = null;
|
||||
}
|
||||
return { shop, result };
|
||||
})
|
||||
);
|
||||
|
||||
let login_response;
|
||||
if (this.refresh_token) {
|
||||
login_response = await requestUrl({
|
||||
url: 'https://cloud.pocketbook.digital/api/v1.0/auth/renew-token',
|
||||
method: 'POST',
|
||||
contentType: 'application/x-www-form-urlencoded',
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.access_token}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: this.refresh_token,
|
||||
}).toString(),
|
||||
}).then(response => response.json);
|
||||
} else if (this.password) {
|
||||
login_response = await requestUrl({
|
||||
url: 'https://cloud.pocketbook.digital/api/v1.0/auth/login/knv',
|
||||
method: 'POST',
|
||||
contentType: 'application/x-www-form-urlencoded',
|
||||
body: new URLSearchParams({
|
||||
shop_id,
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
client_id: this.client_id,
|
||||
client_secret: this.client_secret,
|
||||
}).toString(),
|
||||
}).then(response => response.json);
|
||||
} else {
|
||||
throw new Error('No password or refresh token provided, one is necessary to login.');
|
||||
// use first defined response, if any
|
||||
const login_response = login_responses.filter(response => response.result).first();
|
||||
if (!login_response) {
|
||||
throw new Error('Could not log in to Pocketbook Cloud');
|
||||
}
|
||||
|
||||
this.access_token = login_response.access_token;
|
||||
this.refresh_token = login_response.refresh_token;
|
||||
this.access_token = login_response.result.access_token;
|
||||
this.refresh_token = login_response.result.refresh_token;
|
||||
|
||||
// sets the access token to expire 5 minutes before it actually does
|
||||
this.access_token_valid_until = new Date(Date.now() + login_response.expires_in * 1000 - 5 * 60 * 1000);
|
||||
this.access_token_valid_until = new Date(Date.now() + login_response.result.expires_in * 1000 - 5 * 60 * 1000);
|
||||
|
||||
this.plugin.settings.access_token = this.access_token!!;
|
||||
this.plugin.settings.refresh_token = this.refresh_token!!;
|
||||
this.plugin.settings.access_token_valid_until = this.access_token_valid_until;
|
||||
this.plugin.settings.shop_name = login_response.shop.name;
|
||||
await this.plugin.saveSettings();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,12 +123,14 @@ export class PocketbookCloudHighlightsImporter {
|
|||
}
|
||||
|
||||
private async writeFile(file_name: string, content: string) {
|
||||
let file = this.app.vault.getAbstractFileByPath(file_name) as TFile;
|
||||
const file = this.app.vault.getAbstractFileByPath(file_name);
|
||||
if (!file) {
|
||||
file = await this.app.vault.create(file_name, '');
|
||||
await this.app.vault.create(file_name, content);
|
||||
} else if (file instanceof TFile) {
|
||||
await this.app.vault.modify(file, content);
|
||||
} else {
|
||||
throw new Error(`File ${file_name} is not a TFile, can only write to files.`);
|
||||
}
|
||||
|
||||
this.app.vault.modify(file, content);
|
||||
}
|
||||
|
||||
private async writeFileBinary(file_name: string, content: ArrayBuffer) {
|
||||
|
|
|
|||
|
|
@ -33,5 +33,6 @@ export default class PocketbookCloudHighlightsImporterPlugin extends Plugin {
|
|||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
this.importer = new PocketbookCloudHighlightsImporter(this.app, this, this.settings);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { App, Modal, Notice, PluginSettingTab, Setting } from 'obsidian';
|
||||
import { App, Modal, Notice, PluginSettingTab, Setting, TextComponent } from 'obsidian';
|
||||
import { PocketbookCloudLoginClient } from './apiclient';
|
||||
import PocketbookCloudHighlightsImporterPlugin from './main';
|
||||
|
||||
|
|
@ -48,6 +48,7 @@ export class PocketbookCloudHighlightsImporterSettingTab extends PluginSettingTa
|
|||
})
|
||||
);
|
||||
|
||||
let shop_name_text_field: TextComponent;
|
||||
new Setting(containerEl)
|
||||
.setName('Credentials')
|
||||
.setDesc('Use this to log in')
|
||||
|
|
@ -70,6 +71,8 @@ export class PocketbookCloudHighlightsImporterSettingTab extends PluginSettingTa
|
|||
this.plugin.settings.refresh_token = await api_client.getRefreshToken();
|
||||
this.plugin.saveSettings();
|
||||
|
||||
shop_name_text_field.setValue(this.plugin.settings.shop_name);
|
||||
|
||||
new Notice('Logged in successfully');
|
||||
}).open();
|
||||
})
|
||||
|
|
@ -77,26 +80,31 @@ export class PocketbookCloudHighlightsImporterSettingTab extends PluginSettingTa
|
|||
|
||||
new Setting(containerEl)
|
||||
.setName('Shop name')
|
||||
.setDesc('The name of the shop you are logging in to. Leave empty if you only have one; you can use a substring of the shop name here.')
|
||||
.addText(text =>
|
||||
.setDesc(
|
||||
'The name of the shop you are logging in to. Will be auto-filled on login - only change if that does not work well and you know what you are doing.'
|
||||
)
|
||||
.addText(text => {
|
||||
shop_name_text_field = text;
|
||||
text
|
||||
.setPlaceholder('')
|
||||
.setValue(this.plugin.settings.shop_name)
|
||||
.onChange(async value => {
|
||||
this.plugin.settings.shop_name = value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
});
|
||||
return text;
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Import Folder')
|
||||
.setDesc('The folder the plugin will write to. Should be empty, do not store other data here.')
|
||||
.setDesc('The folder the plugin will write to. The folder should be empty, do not store other data here.')
|
||||
.addText(text =>
|
||||
text
|
||||
.setPlaceholder('Enter your folder path from vault root')
|
||||
.setValue(this.plugin.settings.import_folder)
|
||||
.onChange(async value => {
|
||||
this.plugin.settings.import_folder = value;
|
||||
// filter out leading slashes, they are not needed
|
||||
this.plugin.settings.import_folder = value.replace(/^\//, '');
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
|
|
|||
3
test-vault/.obsidian/community-plugins.json
vendored
3
test-vault/.obsidian/community-plugins.json
vendored
|
|
@ -1,4 +1,5 @@
|
|||
[
|
||||
"dataview",
|
||||
"obsidian-pocketbook-cloud-highlight-importer"
|
||||
"obsidian-pocketbook-cloud-highlight-importer",
|
||||
"pocketbook-cloud-highlight-importer"
|
||||
]
|
||||
|
|
@ -25,5 +25,6 @@
|
|||
"workspaces": false,
|
||||
"file-recovery": true,
|
||||
"publish": false,
|
||||
"sync": false
|
||||
"sync": false,
|
||||
"bookmarks": true
|
||||
}
|
||||
2
test-vault/.obsidian/core-plugins.json
vendored
2
test-vault/.obsidian/core-plugins.json
vendored
|
|
@ -13,7 +13,7 @@
|
|||
"note-composer",
|
||||
"command-palette",
|
||||
"editor-status",
|
||||
"starred",
|
||||
"bookmarks",
|
||||
"outline",
|
||||
"word-count",
|
||||
"file-recovery"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"id": "obsidian-pocketbook-cloud-highlight-importer",
|
||||
"id": "pocketbook-cloud-highlight-importer",
|
||||
"name": "Pocketbook Cloud Highlight Importer",
|
||||
"version": "0.1.0",
|
||||
"minAppVersion": "0.15.0",
|
||||
"version": "0.1.3",
|
||||
"minAppVersion": "1.1.16",
|
||||
"description": "Imports notes and highlights from your Pocketbook Cloud account.",
|
||||
"author": "Lena Brüder",
|
||||
"authorUrl": "https://github.com/lenalebt/obsidian-pocketbook-cloud-highlight-importer",
|
||||
"fundingUrl": "https://github.com/lenalebt/obsidian-pocketbook-cloud-highlight-importer",
|
||||
"authorUrl": "https://github.com/lenalebt",
|
||||
"fundingUrl": "https://www.buymeacoffee.com/lenalebt",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
|
|
|
|||
68
test-vault/.obsidian/workspace.json
vendored
68
test-vault/.obsidian/workspace.json
vendored
|
|
@ -4,16 +4,16 @@
|
|||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "26af0e6f685fa949",
|
||||
"id": "3bb92423da205a5b",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "cf61624d22560890",
|
||||
"id": "c8fff2d3392bc4b1",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "Highlights/Befriend Your Brain/metadata.md",
|
||||
"file": "Highlights/No Rules Rules/metadata.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
}
|
||||
|
|
@ -64,6 +64,14 @@
|
|||
"type": "starred",
|
||||
"state": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "fdd063849d8a79d3",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "bookmarks",
|
||||
"state": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -85,7 +93,7 @@
|
|||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"file": "Highlights/Befriend Your Brain/metadata.md",
|
||||
"file": "Highlights/No Rules Rules/metadata.md",
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
|
|
@ -102,7 +110,7 @@
|
|||
"state": {
|
||||
"type": "outgoing-link",
|
||||
"state": {
|
||||
"file": "Highlights/Befriend Your Brain/metadata.md",
|
||||
"file": "Highlights/No Rules Rules/metadata.md",
|
||||
"linksCollapsed": false,
|
||||
"unlinkedCollapsed": true
|
||||
}
|
||||
|
|
@ -125,7 +133,7 @@
|
|||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "Highlights/Befriend Your Brain/metadata.md"
|
||||
"file": "Highlights/No Rules Rules/metadata.md"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -146,17 +154,43 @@
|
|||
"command-palette:Open command palette": false
|
||||
}
|
||||
},
|
||||
"active": "cf61624d22560890",
|
||||
"active": "c8fff2d3392bc4b1",
|
||||
"lastOpenFiles": [
|
||||
"Pocketbook Cloud Highlights API.md",
|
||||
"Highlights/Datenintensive Anwendungen designen/metadata.md",
|
||||
"Highlights/Getting Things Done The Art of Stress-free Productivity/metadata.md",
|
||||
"Highlights/Getting Things Done The Art of Stress-free Productivity/highlights/BE1FCB97-B5F5-504A-B645-C37E32DAFD16.md",
|
||||
"Highlights/From Conflict to Community/metadata.md",
|
||||
"Highlights/Befriend Your Brain/metadata.md",
|
||||
"Highlights/From Conflict to Community/highlights/45cdb958-6059-48df-a76f-376046d03fe5.md",
|
||||
"Highlights/From Conflict to Community/highlights/218a7270-d3da-4eeb-ab10-019a80f46f8f.md",
|
||||
"Highlights/From Conflict to Community/highlights/4213c9e0-2f8d-46e0-8ae0-e2fdb45cd590.md",
|
||||
"Testnote.md"
|
||||
"Highlights/Atomic Habits/highlights/2E34170D-BB04-5844-9DEA-A94B69A2B592.md",
|
||||
"Highlights/Atomic Habits/highlights/4A74F38F-BF21-5F22-A855-34537094AF9D.md",
|
||||
"Highlights/Atomic Habits/highlights/2183F8BC-8032-538A-A2CC-03955C12949D.md",
|
||||
"Highlights/Atomic Habits/highlights/4DC17BD8-FD9F-534F-8C09-9E51B66B9CC6.md",
|
||||
"Highlights/Atomic Habits/highlights/6C41FEF3-405C-54CA-931D-47353EEB73C5.md",
|
||||
"Highlights/Atomic Habits/highlights/B5B439AB-F889-5592-A650-781729BDCE19.md",
|
||||
"Highlights/Atomic Habits/highlights/E5A3A756-23EA-5D47-8081-1450610F4AB0.md",
|
||||
"Highlights/Atomic Habits/highlights/FD400042-30F2-5AB9-8D46-9F6A833FCF3F.md",
|
||||
"Highlights/Atomic Habits/highlights/FD6933DE-AE47-5D7C-BFF4-BB094B02B337.md",
|
||||
"Highlights/Atomic Habits/metadata.md",
|
||||
"Highlights/Atomic Habits/highlights",
|
||||
"Highlights/Atomic Habits",
|
||||
"Highlights/Weltuntergang fllt aus/highlights/8B9EF265-A8FB-539E-B602-55D556B0C5D0.md",
|
||||
"Highlights/Weltuntergang fllt aus/highlights/5CFEB5D1-BCD3-5612-A63A-5D0C9992A087.md",
|
||||
"Highlights/Weltuntergang fllt aus/metadata.md",
|
||||
"Highlights/Weltuntergang fllt aus/highlights",
|
||||
"Highlights/Weltuntergang fllt aus",
|
||||
"Highlights/Befriend Your Brain/highlights/E2F7276E-CF96-54B0-9AFB-89404E91B82A.md",
|
||||
"Highlights/Befriend Your Brain/highlights/503D15D8-6BA6-5431-8EFB-6679E24601AD.md",
|
||||
"Highlights/Befriend Your Brain/highlights/34298097-44C7-5761-8566-73BDF3262280.md",
|
||||
"Highlights/Befriend Your Brain/highlights/1E68FFDA-DD19-568F-86A8-B1323F7E2F1D.md",
|
||||
"Highlights/Befriend Your Brain/highlights/D8065698-6AB9-5D74-AA55-38204C39F462.md",
|
||||
"Highlights/Befriend Your Brain/highlights/1F49719C-1A9C-5686-865E-D8E95EA5325C.md",
|
||||
"Highlights/Befriend Your Brain/highlights/A074A385-B7B6-55B7-A71E-112AE025ABDB.md",
|
||||
"Highlights/Befriend Your Brain/highlights/B198D0F5-02A5-5A6D-B8BD-C5E6FED1218D.md",
|
||||
"Highlights/Befriend Your Brain/highlights/85FEDB42-6211-508A-9765-C20403CC76F9.md",
|
||||
"Highlights/Befriend Your Brain/highlights/68298E91-FE12-542E-B892-3778C7207E2B.md",
|
||||
"Highlights/Befriend Your Brain/highlights/9B09EC97-863E-5CFB-A358-8861E5AEA0A4.md",
|
||||
"Highlights/Befriend Your Brain/highlights/70B7FF9D-51B1-57A3-9560-65B74CC4A879.md",
|
||||
"Highlights/Befriend Your Brain/highlights/997550C9-84A7-5DA2-BBA4-0E0870AEBF64.md",
|
||||
"Highlights/Befriend Your Brain/highlights",
|
||||
"Highlights/Befriend Your Brain",
|
||||
"Highlights/Good StrategyBad Strategy/highlights",
|
||||
"Highlights/Good StrategyBad Strategy",
|
||||
"Highlights/Escaping the Build Trap/highlights",
|
||||
"Highlights/Escaping the Build Trap"
|
||||
]
|
||||
}
|
||||
1
test-vault/Highlights/.gitignore
vendored
1
test-vault/Highlights/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
|||
*.md
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"0.1.1": "1.1.16",
|
||||
"0.1.2": "1.1.16"
|
||||
"0.1.2": "1.1.16",
|
||||
"0.1.3": "1.1.16"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue