mirror of
https://github.com/woodchen-ink/obsidian-publish-to-discourse.git
synced 2025-07-17 13:23:33 +08:00
throwing this up for brevity
This commit is contained in:
parent
c2c8111f88
commit
8d732e64d7
102
package-lock.json
generated
102
package-lock.json
generated
@ -8,6 +8,9 @@
|
||||
"name": "obsidian-sample-plugin",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.6",
|
||||
"@typescript-eslint/eslint-plugin": "5.29.0",
|
||||
@ -887,6 +890,23 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
|
||||
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@ -984,6 +1004,18 @@
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@ -1034,6 +1066,15 @@
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
@ -1476,6 +1517,40 @@
|
||||
"license": "ISC",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
@ -1810,6 +1885,27 @@
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
@ -2009,6 +2105,12 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
|
@ -20,5 +20,8 @@
|
||||
"obsidian": "latest",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.2"
|
||||
}
|
||||
}
|
||||
|
181
src/main.ts
181
src/main.ts
@ -1,5 +1,7 @@
|
||||
import { App, Menu, MenuItem, Plugin, Modal, requestUrl, TFile } from 'obsidian';
|
||||
import { DEFAULT_SETTINGS, DiscourseSyncSettings, DiscourseSyncSettingsTab } from './config';
|
||||
import Axios from "axios";
|
||||
//import fs from "fs";
|
||||
//import * as crypto from "crypto";
|
||||
|
||||
export default class DiscourseSyncPlugin extends Plugin {
|
||||
@ -43,6 +45,132 @@ export default class DiscourseSyncPlugin extends Plugin {
|
||||
return matches;
|
||||
}
|
||||
|
||||
// CORS Error
|
||||
async uploadFetchImages(imageReferences: string[]): Promise<string[]> {
|
||||
const imageUrls: string[] = [];
|
||||
for (const ref of imageReferences) {
|
||||
const filePath = this.app.metadataCache.getFirstLinkpathDest(ref, this.activeFile.name)?.path;
|
||||
if (filePath) {
|
||||
const file = this.app.vault.getAbstractFileByPath(filePath) as TFile;
|
||||
if (file) {
|
||||
try {
|
||||
const imgFile = await this.app.vault.readBinary(file);
|
||||
const blob = new Blob([imgFile]);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("type", "composer");
|
||||
formData.append("synchronous", "true");
|
||||
formData.append("files[]", blob, file.name);
|
||||
|
||||
const url = `${this.settings.baseUrl}/uploads.json`;
|
||||
const headers = {
|
||||
"Api-Key": this.settings.apiKey,
|
||||
"Api-Username": this.settings.disUser,
|
||||
};
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
headers: headers,
|
||||
mode: 'cors',
|
||||
referrerPolicy: 'no-referrer',
|
||||
});
|
||||
console.log(response.json());
|
||||
} catch (error) {
|
||||
console.log('Fetch error: ' + error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Gather error: ' + error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return imageUrls;
|
||||
}
|
||||
|
||||
|
||||
// CORS Error
|
||||
async uploadAxiosImages(imageReferences: string[]): Promise<string[]> {
|
||||
const imageUrls: string[] = [];
|
||||
for (const ref of imageReferences) {
|
||||
const filePath = this.app.metadataCache.getFirstLinkpathDest(ref, this.activeFile.name)?.path;
|
||||
if (filePath) {
|
||||
const file = this.app.vault.getAbstractFileByPath(filePath) as TFile;
|
||||
if (file) {
|
||||
try {
|
||||
const imgFile = await this.app.vault.readBinary(file);
|
||||
const blob = new Blob([imgFile]);
|
||||
const url = `${this.settings.baseUrl}/uploads.json`;
|
||||
const form = new FormData();
|
||||
form.append("type", "composer");
|
||||
form.append("synchronous", "true");
|
||||
form.append("files[]", blob, file.name);
|
||||
const headers = {
|
||||
"Api-Key": this.settings.apiKey,
|
||||
"Api-Username": this.settings.disUser,
|
||||
"Content-Type": "multipart/form-data",
|
||||
};
|
||||
|
||||
const response = await Axios.post(url, form, { headers });
|
||||
console.log(JSON.stringify(response.data));
|
||||
imageUrls.push("empty");
|
||||
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error: " + error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return imageUrls;
|
||||
}
|
||||
|
||||
// URL not found error
|
||||
async uploadExternalImage(imageReferences: string[]): Promise<string[]> {
|
||||
const imageUrls: string[] = [];
|
||||
for (const ref of imageReferences) {
|
||||
const filePath = this.app.metadataCache.getFirstLinkpathDest(ref, this.activeFile.name)?.path;
|
||||
if (filePath) {
|
||||
const file = this.app.vault.getAbstractFileByPath(filePath) as TFile;
|
||||
if (file) {
|
||||
try {
|
||||
const url = `${this.settings.baseUrl}/uploads/generate-presigned-put.json`;
|
||||
//const imgfile = await this.app.vault.readBinary(file);
|
||||
const img = {
|
||||
type: "composer",
|
||||
file_name: file.name,
|
||||
file_size: file.stat.size,
|
||||
}
|
||||
console.log(JSON.stringify(img));
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Api-Key": this.settings.apiKey,
|
||||
"Api-Username": this.settings.disUser,
|
||||
};
|
||||
const response = await requestUrl({
|
||||
url: url,
|
||||
method: "POST",
|
||||
body: JSON.stringify(img),
|
||||
throw: false,
|
||||
headers: headers
|
||||
})
|
||||
console.log(response.json)
|
||||
} catch (error) {
|
||||
console.error(`Error uploading: ${error}`);
|
||||
//console.log(response.json)
|
||||
}
|
||||
} else {
|
||||
console.error('error')
|
||||
}
|
||||
} else {
|
||||
console.error('error')
|
||||
}
|
||||
}
|
||||
return imageUrls;
|
||||
}
|
||||
|
||||
// Incorrect params error
|
||||
async uploadImages(imageReferences: string[]): Promise<string[]> {
|
||||
const imageUrls = [];
|
||||
for (const ref of imageReferences) {
|
||||
@ -57,8 +185,7 @@ export default class DiscourseSyncPlugin extends Plugin {
|
||||
let body = '';
|
||||
body += `${sBoundary}Content-Disposition: form-data; name="type"\r\n\r\ncomposer\r\n`;
|
||||
body += `${sBoundary}Content-Disposition: form-data; name="synchronous"\r\n\r\ntrue\r\n`;
|
||||
body += `${sBoundary}Content-Disposition: form-data; name="files[]"; filename="${file.name}"\r\nContent-Type: image/jpg`;
|
||||
console.log(body);
|
||||
body += `${sBoundary}Content-Disposition: form-data; name="files[]"; filename="${file.name}"\r\nContent-Type: image/jpg\r\n`;
|
||||
|
||||
const eBoundary = '\r\n--' + boundary + '--\r\n';
|
||||
const bodyArray = new TextEncoder().encode(body);
|
||||
@ -79,12 +206,11 @@ export default class DiscourseSyncPlugin extends Plugin {
|
||||
const response = await requestUrl({
|
||||
url: url,
|
||||
method: "POST",
|
||||
body: formDataArray.buffer,
|
||||
body: formDataArray,
|
||||
throw: false,
|
||||
headers: headers,
|
||||
});
|
||||
|
||||
console.log(`Upload Image response: ${response.status}`);
|
||||
if (response.status == 200) {
|
||||
const jsonResponse = response.json();
|
||||
console.log(`Upload Image jsonResponse: ${JSON.stringify(jsonResponse)}`);
|
||||
@ -118,7 +244,10 @@ export default class DiscourseSyncPlugin extends Plugin {
|
||||
}
|
||||
let content = this.activeFile.content;
|
||||
const imageReferences = this.extractImageReferences(content);
|
||||
const imageUrls = await this.uploadImages(imageReferences);
|
||||
const imageUrls = await this.uploadFetchImages(imageReferences);
|
||||
//const imageUrls = await this.uploadAxiosImages(imageReferences);
|
||||
//const imageUrls = await this.uploadExternalImage(imageReferences);
|
||||
//const imageUrls = await this.uploadImages(imageReferences);
|
||||
|
||||
imageReferences.forEach((ref, index) => {
|
||||
const obsRef = `![[${ref}]]`;
|
||||
@ -133,27 +262,24 @@ export default class DiscourseSyncPlugin extends Plugin {
|
||||
});
|
||||
console.log("POST Body:", body);
|
||||
|
||||
const response = await requestUrl({
|
||||
url: url,
|
||||
method: "POST",
|
||||
contentType: "application/json",
|
||||
body,
|
||||
headers,
|
||||
});
|
||||
//const response = await requestUrl({
|
||||
// url: url,
|
||||
// method: "POST",
|
||||
// contentType: "application/json",
|
||||
// body,
|
||||
// headers,
|
||||
//});
|
||||
|
||||
if (response.status !== 200) {
|
||||
console.error("Error publishing to Discourse:", response.status);
|
||||
console.error("Response body:", response.text);
|
||||
if (response.status == 422) {
|
||||
new NotifyUser(this.app, `There's an error with this post, could be a duplicate or the title is too short: ${response.status}`).open();
|
||||
//if (response.status !== 200) {
|
||||
// console.error("Error publishing to Discourse:", response.status);
|
||||
// console.error("Response body:", response.text);
|
||||
// if (response.status == 422) {
|
||||
// new NotifyUser(this.app, `There's an error with this post, could be a duplicate or the title is too short: ${response.status}`).open();
|
||||
|
||||
console.error("there's an error with this post, try making a longer title");
|
||||
}
|
||||
return { message: "Error publishing to Discourse" };
|
||||
}
|
||||
|
||||
//const jsonResponse = response.json;
|
||||
//console.log(`jsonResponse: ${JSON.stringify(jsonResponse, null, 2)}`);
|
||||
// console.error("there's an error with this post, try making a longer title");
|
||||
// }
|
||||
// return { message: "Error publishing to Discourse" };
|
||||
//}
|
||||
return { message: "Success" };
|
||||
}
|
||||
|
||||
@ -235,9 +361,14 @@ interface Category {
|
||||
subcategory_list?: Subcategory[];
|
||||
}
|
||||
|
||||
interface PresignedImage {
|
||||
type: string;
|
||||
file_name: string;
|
||||
file_size: number;
|
||||
}
|
||||
|
||||
const genBoundary = (): string => {
|
||||
return '----WebKitFormBoundary' + Math.random().toString(36).substring(2, 15);
|
||||
//return crypto.randomBytes(16).toString("hex");
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user