Skip to content

Commit

Permalink
New feature:
Browse files Browse the repository at this point in the history
- We can fetch files from the web.

Fixed:
- Binary files can be restored correctly now.
  • Loading branch information
vrtmrz committed Dec 23, 2022
1 parent 50a0c73 commit fa24b76
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 161 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The plugin for picking and putting hidden files.

![screenshot](https://user-images.githubusercontent.com/45774780/158567788-fbea41ba-d07d-4faf-bc09-ce241a0c9f67.gif)

You can dump your files which stored in the specified directory, or put dumped files into any path under your vault.
You can dump your files which are stored in the specified directory, or put dumped files into any path under your vault.

### How to use

Expand Down Expand Up @@ -44,6 +44,10 @@ All you have to do is pick the target directory.
# --- Select a directory to dump. ---
target: .obsidian/snippets

# --- Or, specify URLs to fetch.
urls:
# - https://gist.githubusercontent.com/vrtmrz/8b638347f56d1dad25414953bb95d7b6/raw/77f2965f79e9390b88dd17d5f23475b1f8b8085a/ninja-cursor-snippets.css

# --- Prefixes to ignore. ---
ignores:
- /node_modules
Expand Down
153 changes: 81 additions & 72 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { App, Editor, MarkdownView, Notice, parseYaml, Plugin } from "obsidian";
import { App, Editor, MarkdownView, Notice, parseYaml, Plugin, requestUrl, arrayBufferToBase64, base64ToArrayBuffer } from "obsidian";

// Util functions
async function getFiles(
Expand Down Expand Up @@ -50,44 +50,11 @@ function isPlainText(filename: string): boolean {
if (filename.endsWith(".json")) return true;
if (filename.endsWith(".xml")) return true;
if (filename.endsWith(".ts")) return true;
if (filename.endsWith(".canvas")) return true;

return false;
}

function arrayBufferToBase64(buffer: ArrayBuffer): Promise<string> {
return new Promise((res) => {
const blob = new Blob([buffer], { type: "application/octet-binary" });
const reader = new FileReader();
reader.onload = function (evt) {
const dataurl = evt.target.result.toString();
res(dataurl.substr(dataurl.indexOf(",") + 1));
};
reader.readAsDataURL(blob);
});
}

function base64ToArrayBuffer(base64: string): ArrayBuffer {
try {
const binary_string = window.atob(base64);
const len = binary_string.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
} catch (ex) {
try {
return new Uint16Array(
[].map.call(base64, function (c: string) {
return c.charCodeAt(0);
})
).buffer;
} catch (ex2) {
return null;
}
}
}

async function ensureDirectory(app: App, fullpath: string) {
const pathElements = fullpath.split("/");
pathElements.pop();
Expand Down Expand Up @@ -134,6 +101,10 @@ export default class ScrewDriverPlugin extends Plugin {
# --- Select a directory to dump. ---
${targets}
# --- Or, specify URLs to fetch.
urls:
# - https://gist.githubusercontent.com/vrtmrz/8b638347f56d1dad25414953bb95d7b6/raw/77f2965f79e9390b88dd17d5f23475b1f8b8085a/ninja-cursor-snippets.css
# --- Prefixes to ignore. ---
ignores:
- /node_modules
Expand All @@ -150,7 +121,7 @@ filters:
// This adds an editor command that can perform some operation on the current editor instance
this.addCommand({
id: "screwdriver-dump",
name: "Dump files",
name: "Dump or fetch files",
editorCallback: async (editor: Editor, view: MarkdownView) => {
const data = view.data;
const bodyStartIndex = data.indexOf("\n---");
Expand All @@ -170,42 +141,74 @@ filters:
const filters = !filterSrc
? null
: filterSrc.map((e: string) => new RegExp(e));
if (target.trim() == "") {
new Notice("Target folder not specified.");

const urls = (yamlData.urls ?? "");
if (target.trim() == "" && urls == "") {
new Notice("Target folders or urls are not specified.");
return;
}
const files = await getFiles(
this.app,
target,
ignores,
filters
);
for (const file of files) {
let fileDat = "";
const stat = await this.app.vault.adapter.stat(file);
if (isPlainText(file)) {
fileDat = await this.app.vault.adapter.read(file);
fileDat = fileDat.replace(/\\/g, "\\\\");
fileDat = fileDat.replace(/`/g, "\\`");
} else {
const dtSrc = await this.app.vault.adapter.readBinary(
file
);
fileDat = await arrayBufferToBase64(dtSrc);
for (const url of urls) {
try {
let fileDat = "";
let bin = false;
const w = await requestUrl(url);
const filename = new URL(url).pathname.split("/").last();
const dt = w.arrayBuffer;

try {
const text = new TextDecoder("utf-8", { fatal: true }).decode(dt);
fileDat = text;
fileDat = fileDat.replace(/\\/g, "\\\\");
fileDat = fileDat.replace(/`/g, "\\`");
} catch (ex2) {
fileDat = await arrayBufferToBase64(dt);
bin = true;
}
newData += "\n";
newData += `# ${url} \n`;
newData += `- Fetched :${new Date().toLocaleString()} \n`;
newData += "\n```" + filename + (bin ? ":bin" : "") + "\n";
newData += fileDat + "";
newData += "\n```";
} catch (ex) {
new Notice(`Error on fetching ${url}\n${ex}`);
}
newData += "\n";
newData += `# ${file} \n`;
newData += `- Created :${new Date(
stat.ctime
).toLocaleString()} \n`;
newData += `- Modified:${new Date(
stat.mtime
).toLocaleString()} \n`;
newData += "\n```" + file + "\n";
newData += fileDat + "";
newData += "\n```";

}
if (target != "") {
const files = await getFiles(
this.app,
target,
ignores,
filters
);
for (const file of files) {
let fileDat = "";
const stat = await this.app.vault.adapter.stat(file);
if (isPlainText(file)) {
fileDat = await this.app.vault.adapter.read(file);
fileDat = fileDat.replace(/\\/g, "\\\\");
fileDat = fileDat.replace(/`/g, "\\`");
} else {
const dtSrc = await this.app.vault.adapter.readBinary(
file
);
fileDat = await arrayBufferToBase64(dtSrc);
}
newData += "\n";
newData += `# ${file} \n`;
newData += `- Created :${new Date(
stat.ctime
).toLocaleString()} \n`;
newData += `- Modified:${new Date(
stat.mtime
).toLocaleString()} \n`;
newData += "\n```" + file + "\n";
newData += fileDat + "";
newData += "\n```";

}
}
editor.setValue(newData);
},
});
Expand All @@ -222,10 +225,12 @@ filters:
.substring(bodyStartIndex)
.matchAll(/^```([\s\S]*?)\n([\s\S]*?)^```/gm);
for (const preBlock of preBlocks) {
const [, filename, data] = preBlock;
const [, filenameSrc, data] = preBlock;
const [filename, isBin] = `${filenameSrc}:`.split(":");
console.dir(isBin);
let saveData = data;
try {
if (isPlainText(filename)) {
if (isPlainText(filename) && isBin != "bin") {
saveData = saveData.replace(/\\`/g, "`");
saveData = saveData.replace(/\\\\/g, "\\");
saveData = saveData.substring(
Expand All @@ -238,6 +243,10 @@ filters:
saveData
);
} else {
saveData = saveData.substring(
0,
saveData.lastIndexOf("\n")
);
const saveDataArrayBuffer =
base64ToArrayBuffer(saveData);
await ensureDirectory(this.app, filename);
Expand All @@ -262,9 +271,9 @@ filters:
});
}

onunload() {}
onunload() { }

async loadSettings() {}
async loadSettings() { }

async saveSettings() {}
async saveSettings() { }
}
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "obsidian-screwdriver",
"name": "Screwdriver",
"version": "0.0.3",
"version": "0.0.4",
"minAppVersion": "0.12.0",
"description": "Utility to put any files in and out under your vault.",
"author": "vorotamoroz",
Expand Down
Loading

0 comments on commit fa24b76

Please sign in to comment.