From 657668dc7de898496ce0c40bb8ad35dbd2d9d8e1 Mon Sep 17 00:00:00 2001 From: ltctceplrm <14954927+ltctceplrm@users.noreply.github.com> Date: Sun, 11 May 2025 17:26:12 +0200 Subject: [PATCH] Added download option for image urls --- src/main.ts | 26 ++++++++++++++++++++++++++ src/models/MediaTypeModel.ts | 3 +++ src/settings/Settings.ts | 27 +++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/main.ts b/src/main.ts index c4f8562..8240617 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,5 @@ import { MarkdownView, Notice, parseYaml, Plugin, stringifyYaml, TFile, TFolder } from 'obsidian'; +import { requestUrl, normalizePath } from 'obsidian'; // Add requestUrl import import type { MediaType } from 'src/utils/MediaType'; import { APIManager } from './api/APIManager'; import { BoardGameGeekAPI } from './api/apis/BoardGameGeekAPI'; @@ -314,6 +315,31 @@ export default class MediaDbPlugin extends Plugin { options.openNote = this.settings.openNoteInNewTab; + if (mediaTypeModel.image && typeof mediaTypeModel.image === 'string' && mediaTypeModel.image.startsWith('http')) { + if (this.settings.imageDownload) { + try { + const imageurl = mediaTypeModel.image; + const imageext = imageurl.split('.').pop()?.split(/\#|\?/)[0] || 'jpg'; + const imagefileName = `${replaceIllegalFileNameCharactersInString(`${mediaTypeModel.type}_${mediaTypeModel.title} (${mediaTypeModel.year})`)}.${imageext}`; + const imagepath = normalizePath(`${this.settings.imageFolder}/${imagefileName}`); + + if (!this.app.vault.getAbstractFileByPath(this.settings.imageFolder)) { + await this.app.vault.createFolder(this.settings.imageFolder); + } + + const response = await requestUrl({ url: imageurl, method: 'GET' }); + await this.app.vault.createBinary(imagepath, response.arrayBuffer); + + // Update model to use local image path + mediaTypeModel.image = `[[${imagepath}]]`; + } catch (e) { + console.warn('MDB | Failed to download image:', e); + } + } else { + mediaTypeModel.image = mediaTypeModel.image; + } + } + const fileContent = await this.generateMediaDbNoteContents(mediaTypeModel, options); if (!options.folder) { diff --git a/src/models/MediaTypeModel.ts b/src/models/MediaTypeModel.ts index 51c6378..e4d03a0 100644 --- a/src/models/MediaTypeModel.ts +++ b/src/models/MediaTypeModel.ts @@ -9,6 +9,7 @@ export abstract class MediaTypeModel { dataSource: string; url: string; id: string; + image?: string; userData: object; @@ -21,6 +22,8 @@ export abstract class MediaTypeModel { this.dataSource = ''; this.url = ''; this.id = ''; + this.image = ''; + this.userData = {}; } diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 15c45af..b48b82c 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -69,6 +69,8 @@ export interface MediaDbPluginSettings { boardgameFolder: string; bookFolder: string; + imageDownload: boolean; + imageFolder: string; propertyMappingModels: PropertyMappingModel[]; } @@ -130,6 +132,8 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = { boardgameFolder: 'Media DB/boardgames', bookFolder: 'Media DB/books', + imageDownload: false, + imageFolder: 'Media DB/images', propertyMappingModels: [], }; @@ -298,6 +302,29 @@ export class MediaDbSettingTab extends PluginSettingTab { }); }); + new Setting(containerEl) + .setName('Download images') + .setDesc('Downloads images for new notes in the folder below') + .addToggle(cb => { + cb.setValue(this.plugin.settings.imageDownload).onChange(data => { + this.plugin.settings.imageDownload = data; + void this.plugin.saveSettings(); + }); + }); + + new Setting(containerEl) + .setName('Image folder') + .setDesc('Where downloaded images should be stored.') + .addSearch(cb => { + new FolderSuggest(this.app, cb.inputEl); + cb.setPlaceholder(DEFAULT_SETTINGS.imageFolder) + .setValue(this.plugin.settings.imageFolder) + .onChange(data => { + this.plugin.settings.imageFolder = data; + void this.plugin.saveSettings(); + }); + }); + // Create a map to store APIs for each media type const mediaTypeApiMap = new Map();