Ce l’ho fatta!!
async uploadImages(imageReferences: string[]): Promise<string[]> {
const imageUrls = [];
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 boundary = genBoundary();
const sBoundary = '--' + boundary + '\r\n';
const imgForm = `${sBoundary}Content-Disposition: form-data; name=\"file\"; filename=\"${file.name}\"\r\nContent-Type: image/${file.extension}\r\n\r\n`;
let body = '';
body += `\r\n${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`;
const eBoundary = '\r\n--' + boundary + '--\\r\n';
const imgFormArray = new TextEncoder().encode(imgForm);
const bodyArray = new TextEncoder().encode(body);
const endBoundaryArray = new TextEncoder().encode(eBoundary);
const formDataArray = new Uint8Array(imgFormArray.length + imgfile.byteLength + bodyArray.length + endBoundaryArray.length);
formDataArray.set(imgFormArray, 0);
formDataArray.set(new Uint8Array(imgfile), imgFormArray.length);
formDataArray.set(bodyArray, imgFormArray.length + imgfile.byteLength);
formDataArray.set(endBoundaryArray, imgFormArray.length + bodyArray.length + imgfile.byteLength);
const url = `${this.settings.baseUrl}/uploads.json`;
const headers = {
"Api-Key": this.settings.apiKey,
"Api-Username": this.settings.disUser,
"Content-Type": `multipart/form-data; boundary=${boundary}`,
};
const response = await requestUrl({
url: url,
method: "POST",
body: formDataArray.buffer,
throw: false,
headers: headers,
});
if (response.status == 200) {
const jsonResponse = response.json;
console.log(`Upload Image jsonResponse: ${JSON.stringify(jsonResponse)}`);
imageUrls.push(jsonResponse.url);
} else {
new NotifyUser(this.app, `Error uploading image: ${response.status}`).open();
console.error(`Error uploading image: ${JSON.stringify(response.json)}`);
}
} catch (error) {
new NotifyUser(this.app, `Exception while uploading image: ${error}`).open();
console.error("Exception while uploading image:", error);
}
} else {
new NotifyUser(this.app, `File not found in vault: ${ref}`).open();
console.error(`File not found in vault: ${ref}`);
}
} else {
new NotifyUser(this.app, `Unable to resolve file path for: ${ref}`).open();
console.error(`Unable to resolve file path for: ${ref}`);
}
}
return imageUrls;
}
Il problema era l’ordine in cui stavo costruendo il form-data. Doveva essere:
- parametri img
- binario img
- parametri
In precedenza mettevo i parametri prima dell’immagine.
Ho risolto analizzando un upload riuscito usando python:
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
from requests.models import PreparedRequest
class Discourse:
def __init__(self):
self.base_url = "CENSORED"
self.api_key = "CENSORED"
self.api_username = "CENSORED"
self.category = 2
def post_uploads(self, file_path):
headers = {
"Content-Type": "multipart/form-data",
"Api-Key": self.api_key,
"Api-Username": self.api_username
}
multi = MultipartEncoder(
fields = {
'file': ('filename', open(file_path, 'rb'), 'image/jpg'),
'type': 'composer',
'synchronous': 'true'
}
)
headers['Content-Type'] = multi.content_type
request = requests.Request(
method = "POST",
url = f"{self.base_url}/uploads.json",
headers = headers,
data = multi
)
prepared_request = request.prepare()
print("Headers:")
for k, v in prepared_request.headers.items():
print(f"{k}: {v}")
print(multi.to_string())
response = requests.post(
f"{self.base_url}/uploads.json",
headers=headers,
params=params,
data=m
)
return response.json()
if __name__ == "__main__":
ds = Discourse()
response = ds.post_uploads("/home/tfinley/Pictures/face2.jpg")
print(response)
Ora come faccio a eliminare gli upload orfani? ^_o