You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

260 lines
22 KiB

/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/
'use strict';
var obsidian = require('obsidian');
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
const DEFAULT_SETTINGS = {
termsAccepted: false,
isPremium: false
};
const BASE_URL = "https://ocr.taskbone.com";
const privacyPolicyURL = "https://www.taskbone.com/legal/privacy";
const contactURL = "http://www.taskbone.com/contact";
class TaskboneOCRPlugin extends obsidian.Plugin {
onload() {
return __awaiter(this, void 0, void 0, function* () {
console.log('Taskbone OCR: start loading plugin');
yield this.loadSettings();
this.addSettingTab(new TaskboneOCRSettingTab(this.app, this));
this.addCommand({
id: 'open-image-select-modal',
name: 'Create annotation page for image',
callback: () => __awaiter(this, void 0, void 0, function* () {
if (!this.settings.termsAccepted) {
const errorText = `Please go to the Taskbone OCR plugin settings and accept the privacy policy.`;
return new ErrorModal(this.app, errorText).open();
}
if (!this.settings.isPremium) {
if (!this.settings.standardToken) {
const tokenResponse = yield fetch(BASE_URL + '/get-new-token', {
method: 'post'
});
if (tokenResponse.status == 200) {
const jsonResponse = yield tokenResponse.json();
this.settings.standardToken = jsonResponse.token;
this.saveSettings();
}
else {
const errorText = `Taskbone OCR Error: ${tokenResponse.status}<br/>Please try again later.`;
return new ErrorModal(this.app, errorText).open();
}
}
}
else {
if (!this.settings.premiumToken) {
const errorText = `Your plugin configuration is incomplete. Check the plugin settings and either enter a token or disable the 'I have a personal token' setting.`;
return new ErrorModal(this.app, errorText).open();
}
}
const images = this.getNotAnnotatedImagePaths();
if (images.length > 0) {
new FileSelectorModal(this.app, this).open();
}
else {
new ErrorModal(this.app, "All supported image files already have an annotation file.").open();
}
})
});
});
}
onunload() {
console.log('Taskbone OCR: unloading plugin');
}
loadSettings() {
return __awaiter(this, void 0, void 0, function* () {
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
});
}
saveSettings() {
return __awaiter(this, void 0, void 0, function* () {
yield this.saveData(this.settings);
});
}
getTextForFile(path) {
return __awaiter(this, void 0, void 0, function* () {
const vault = this.app.vault;
const file = vault.getFiles().filter((file) => {
return file.path == path;
})[0];
const fileBuffer = yield this.app.vault.readBinary(file);
const formData = new FormData();
formData.append('image', new Blob([fileBuffer]));
const token = this.settings.isPremium ? this.settings.premiumToken : this.settings.standardToken;
try {
const response = yield fetch(BASE_URL + '/get-text', {
headers: {
'Authorization': 'Bearer ' + token
},
method: "post",
body: formData
});
if (response.status == 200) {
const jsonResponse = yield response.json();
const text = jsonResponse === null || jsonResponse === void 0 ? void 0 : jsonResponse.text;
return text || '';
}
else {
const errorText = `Could not read Text from ${path}:<br/> Error: ${response.status}`;
new ErrorModal(this.app, errorText).open();
}
}
catch (error) {
const errorText = `The OCR service seems unavailable right now. Please try again later.`;
new ErrorModal(this.app, errorText).open();
}
});
}
createAnnotationFileForFile(path) {
return __awaiter(this, void 0, void 0, function* () {
const imageText = yield this.getTextForFile(path);
if (!imageText)
return;
if (imageText.length == 0) {
new ErrorModal(this.app, `No text found in ${path}`).open();
}
else {
const annotationFileContent = `![[${path}]]\n\n${imageText}`;
const annotationFilePath = path + '.annotations.md';
this.app.vault.create(annotationFilePath, annotationFileContent);
}
});
}
getNotAnnotatedImagePaths() {
const files = this.app.vault.getFiles();
const markdownFilePaths = this.app.vault.getMarkdownFiles().map((file) => {
return file.path;
});
const images = files.filter((file) => {
const isImage = ['png', 'jpg', 'jpeg'].includes(file.extension);
if (!isImage)
return false;
const annotationFilePath = file.path + '.annotations.md';
const annotationFileAlreadyExist = markdownFilePaths.contains(annotationFilePath);
return !annotationFileAlreadyExist;
});
const imagePaths = images.map((file) => {
return file.path;
});
return imagePaths;
}
}
class FileSelectorModal extends obsidian.SuggestModal {
constructor(app, plugin) {
super(app);
this.app = app;
this.plugin = plugin;
}
getSuggestions(query) {
const imagePaths = this.plugin.getNotAnnotatedImagePaths();
if (query.length == 0) {
return imagePaths;
}
const filteredImageNames = imagePaths.filter((path, index, paths) => {
path.contains(query);
return path.contains(query);
});
return filteredImageNames;
}
renderSuggestion(value, el) {
el.setText(value);
}
onChooseSuggestion(item, evt) {
return __awaiter(this, void 0, void 0, function* () {
this.plugin.createAnnotationFileForFile(item);
});
}
}
class ErrorModal extends obsidian.Modal {
constructor(app, message) {
super(app);
this.message = message;
}
onOpen() {
this.titleEl.setText("Taskbone OCR Error");
this.contentEl.innerHTML = this.message;
}
onClose() {
this.containerEl.empty();
}
}
class TaskboneOCRSettingTab extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
let { containerEl } = this;
containerEl.empty();
containerEl.createEl('h2', { text: 'Taskbone OCR Settings' });
containerEl.createEl('p', { text: 'The Taskbone OCR service is provided for free (within reasonable limits).' });
const div = containerEl.createEl('div');
const premiumText = document.createElement('p');
premiumText.innerHTML = `<a href="${contactURL}">Get in touch</a> if you think you are outside of these limits or if you are interested in any of the following features:<ul><li>PDF support</li><li>bigger file size limit</li><li>bulk operations (e.g. process a whole directory with lots of images)</li><li>General image annotations (find relevant tags for images)</li></ul>`;
div.appendChild(premiumText);
const acceptTermsSetting = new obsidian.Setting(containerEl)
.setName('Accept Privacy Policy and Terms and Conditions')
.addToggle((toggle) => toggle
.setValue(this.plugin.settings.termsAccepted)
.onChange((value) => {
this.plugin.settings.termsAccepted = value;
this.plugin.saveData(this.plugin.settings);
this.display();
}));
acceptTermsSetting.descEl.innerHTML = `I accept the Taskbone <a href="${privacyPolicyURL}">Privacy Policy</a>`;
new obsidian.Setting(containerEl)
.setName('I have a personal token')
.setDesc('Switch on, if you received a custom authentication token')
.addToggle((toggle) => toggle
.setValue(this.plugin.settings.isPremium)
.onChange((value) => {
this.plugin.settings.isPremium = value;
this.plugin.saveData(this.plugin.settings);
this.display();
}));
if (this.plugin.settings.isPremium) {
new obsidian.Setting(containerEl)
.setName('Authentication Token')
.setDesc('Copy and paste the token you received from taskbone')
.addText(text => text
.setPlaceholder('Enter your token')
.setValue(this.plugin.settings.premiumToken)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
this.plugin.settings.premiumToken = value;
yield this.plugin.saveSettings();
})));
}
}
}
module.exports = TaskboneOCRPlugin;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOm51bGwsIm5hbWVzIjpbIlBsdWdpbiIsIlN1Z2dlc3RNb2RhbCIsIk1vZGFsIiwiUGx1Z2luU2V0dGluZ1RhYiIsIlNldHRpbmciXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF1REE7QUFDTyxTQUFTLFNBQVMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUU7QUFDN0QsSUFBSSxTQUFTLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEtBQUssWUFBWSxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLFVBQVUsT0FBTyxFQUFFLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDaEgsSUFBSSxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxVQUFVLE9BQU8sRUFBRSxNQUFNLEVBQUU7QUFDL0QsUUFBUSxTQUFTLFNBQVMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO0FBQ25HLFFBQVEsU0FBUyxRQUFRLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMs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