Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Suggestion: Bulk Upload of Local Images #9

Open
xaya1001 opened this issue May 25, 2023 · 4 comments
Open

Feature Suggestion: Bulk Upload of Local Images #9

xaya1001 opened this issue May 25, 2023 · 4 comments
Labels
enhancement New feature or request

Comments

@xaya1001
Copy link

xaya1001 commented May 25, 2023

Hello,

I'm a user of your Image Uploader plugin for Obsidian, and I've found it to be a very useful tool. However, I found myself needing to upload a large number of local images (over 2000) to my self-hosted image server.

With some assistance from GPT-4, I've written some code to add this bulk image upload functionality to the plugin. It allowed me to successfully upload all my local images to my server, and I thought that this feature might be beneficial to other users of your plugin who are in a similar situation.

Here is the code that I've written:

  async uploadLocalImages(): Promise<void> {
    // Get the current active MarkdownView
    const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView);
    if (!markdownView) return;
    // Get Editor
    const editor = markdownView.editor;
    // Get all the text
    const lines = editor.getValue().split("\n");

    for (let i = 0; i < lines.length; i++) {
      const line = lines[i];
      const matches = line.match(/!\[\[.*?\]\]/gm);

      if (!matches) continue;

      for (let match of matches) {
        try {
          await this.uploadImage(match, i, line, editor, markdownView);
          await new Promise(resolve => setTimeout(resolve, 300));  // Wait for 0.3 second before the next upload
        } catch (error) {
          console.error("Stopping function due to error: ", error);
          return;
        }
      }
    }
  }

  async uploadImage(match: string, i: number, line: string, editor: any, markdownView: any): Promise<void> {

    let imagePath = match.substring(match.lastIndexOf("[[") + 2, match.lastIndexOf("]]"));
    console.log('Uploading: ', imagePath);

    // Read image file
    const data = await this.app.vault.adapter.readBinary(imagePath);
    // Convert data to Blob
    const blob = new Blob([data], { type: 'image/png' });
    // Convert Blob to File
    const file = new File([blob], imagePath.split("/").pop(), { type: 'image/png' });

    // Use your pasteHandler function to upload the image
    const clipboardData = new DataTransfer();
    clipboardData.items.add(file);

    const fakeEvent = new ClipboardEvent("paste", { clipboardData: clipboardData });

    // Remove original link
    const newLine = line.replace(match, "");
    editor.replaceRange(newLine, { line: i, ch: 0 }, { line: i, ch: line.length + 1 });

    // Set the cursor to the start of the line
    editor.setCursor({ line: i, ch: 0 });

    await this.pasteHandler(fakeEvent, editor, markdownView);
  }
  
  async onload(): Promise<void> {
    console.log("loading Image Uploader");
    await this.loadSettings();
    // this.setupPasteHandler()
    this.addSettingTab(new ImageUploaderSettingTab(this.app, this));

    this.pasteFunction = this.pasteHandler.bind(this);

    this.registerEvent(
      this.app.workspace.on('editor-paste', this.pasteFunction)
    );

    this.addCommand({
      id: 'upload-local-images',
      name: 'Upload Local Images of This Page',
      callback: this.uploadLocalImages.bind(this),
    });
  }

Please feel free to use this code as you see fit. If you find it useful and believe it could be beneficial for other users (especially new users), consider incorporating it into the plugin as a new feature. I am not a programmer, and although I have tested the code and it works for my use case, it may not be perfect. As such, I'm providing it here for your reference rather than submitting a pull request.

@xaya1001
Copy link
Author

xaya1001 commented May 25, 2023

by the way, I'm using lsky-pro as self-hosted image server.
https://github.com/lsky-org/lsky-pro

here are my settings:

api endpoint:https://img.domain.com/api/v1/upload
upload header: 
{
  "Authorization": "Bearer xxxx",
  "Accept": "application/json",
  "Content-Type": "multipart/form-data"
}
upload body: 
{
  "file": "$FILE"
}
Image Url Path: data.links.url

@africa1207
Copy link

Yes, I also have the need to upload local images. Although the "Image Auto Upload Plugin" can achieve this functionality, it requires the installation of an additional tool called PicGo. It would be perfect if the ability to batch upload local existing images could be added without the need for PicGo.

@Creling
Copy link
Owner

Creling commented Aug 13, 2023

@xaya1001 Good jobs. I implement this feature by referencing your code. A new version will be released soon. Please refer 5cd9743 for more details.

@Creling
Copy link
Owner

Creling commented Aug 13, 2023

@africa1207 Yes, I also don't want to install extra tools, which is why I developed this plugin.

@Creling Creling added feature request enhancement New feature or request and removed feature request labels Aug 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants