Skip to content

Commit

Permalink
added features to ignore and replace urls
Browse files Browse the repository at this point in the history
  • Loading branch information
Bergiu committed Aug 17, 2023
1 parent e74aad2 commit 544f3f0
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 62 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This plugin archives links in your note so they're available to you even if the
Upon pressing the "Archive Links" button in the ribbon/left sidebar, the plugin:

1. looks up every external link in the current note,
2. sumbits each of them to https://archive.org,
2. submits each of them to https://archive.org,
3. as soon as they are saved, it embeds an `(Archived)` link after the regular link in your note.

The plugin will attempt not to recreate archive links for already-archived links (and the archive links themselves) - but this relies on not modifying the formatting of the archive links.
Expand Down Expand Up @@ -39,4 +39,4 @@ Initial release.

## Future plans

- Support for other archive providers
- Support for other archive providers
44 changes: 29 additions & 15 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { MarkdownView, Notice, Plugin, request } from "obsidian";
import { waybackSaveUrl, waybackUrl } from "./constants";
import { defaultSettings as DEFAULT_SETTINGS, LinkArchivePluginSettings as LinkArchivePluginSettings, LinkArchiveSettingTab } from "./settings";
import { defaultSettings as DEFAULT_SETTINGS, LinkArchivePluginSettings as LinkArchivePluginSettings, LinkArchiveSettingTab, LinkReplaceRule } from "./settings";

const urlRegex =/(\b(https?|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;

function replaceLinks(link: string, replaceRules: LinkReplaceRule[]): string {
let modifiedLink = link;

for (const rule of replaceRules) {
const regex = new RegExp(rule.originalPattern, "g");
modifiedLink = modifiedLink.replace(regex, rule.replacementPattern);
}

return modifiedLink;
}

export default class ObsidianLinkArchivePlugin extends Plugin {
settings: LinkArchivePluginSettings;

Expand Down Expand Up @@ -31,22 +42,24 @@ export default class ObsidianLinkArchivePlugin extends Plugin {
while ((linkArray = urlRegex.exec(viewData)) !== null) {
console.log(`Found ${linkArray[0]}. Next starts at ${urlRegex.lastIndex}.`);

//if(linkArray[0].startsWith(waybackUrl)) continue;

//if(viewData.substring(urlRegex.lastIndex, urlRegex.lastIndex + 14).contains(archiveText)) continue;

// replace clean logic with
// IF next link is the same except with archiveorg in front of it, skip it

reverseArray.unshift([linkArray[0], urlRegex.lastIndex]);
}

console.log(reverseArray);
console.log(reverseArray);

// ReSharper marks the "some" call as an error, but it's actually correct...
const cleanedList = reverseArray.filter(x =>
!x[0].startsWith(waybackUrl)
&& !reverseArray.some(y => y[0].startsWith(waybackUrl) && y[0].endsWith(x[0])));
const cleanedList = reverseArray.filter(x =>
// Filtering out links that start with the archive URL
!x[0].startsWith(waybackUrl)
// Testing if a link does not have an archived version in the reverseArray
&& !reverseArray.some(y =>
y[0].startsWith(waybackUrl) && y[0].endsWith(x[0]) // Already archived links
|| y[0].startsWith(waybackUrl) && y[0].endsWith(replaceLinks(x[0], this.settings.linkReplaceRules)) // Already replaced and archived links
)
// Testing if the link is not already associated with the archive text in viewData
&& !viewData.substring(x[1]+2, x[1]+2 + archiveText.length).includes(archiveText)
// Testing if the link is not in the ignore list
&& !this.settings.ignoreUrlPatterns.some(pattern => new RegExp(pattern).test(x[0])));

console.log(cleanedList);

Expand All @@ -62,12 +75,13 @@ export default class ObsidianLinkArchivePlugin extends Plugin {

for (const tuple of cleanedList) {
const currentLink = tuple[0];
const replacedLink = replaceLinks(currentLink, this.settings.linkReplaceRules);
const saveLink = `${waybackSaveUrl}${currentLink}`;
const archiveLink = ` ${archiveText}(${waybackUrl}${dateLinkPart}/${currentLink})`;
const archiveLink = ` ${archiveText}(${waybackUrl}${dateLinkPart}/${replacedLink})`;
const extraOffset = viewData.charAt(tuple[1]) === ")" ? 1 : 0;
const offset = view.editor.offsetToPos(tuple[1] + extraOffset);
const message = `(${i}/${totalLinks}) Successfully archived ${currentLink}!`;
const failMessage = `(${i}/${totalLinks}) Failed to archive ${currentLink}!`;
const message = `(${i}/${totalLinks}) Successfully archived ${replacedLink}!`;
const failMessage = `(${i}/${totalLinks}) Failed to archive ${replacedLink}!`;
i += 1;

await this.delay(400);
Expand Down
163 changes: 118 additions & 45 deletions settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { App, PluginSettingTab, Setting } from "obsidian";
import ObsidianLinkArchivePlugin from "./main";
import { defaultArchiveText } from "./constants";

export interface LinkReplaceRule {
originalPattern: string;
replacementPattern: string;
}

export const enum ArchiveOptions {
Wayback,
Archiveis,
Expand All @@ -12,11 +17,15 @@ export const enum ArchiveOptions {
export interface LinkArchivePluginSettings {
archiveOption: ArchiveOptions;
archiveText: string;
linkReplaceRules: LinkReplaceRule[];
ignoreUrlPatterns: string[];
}

export const defaultSettings: LinkArchivePluginSettings = {
archiveOption: ArchiveOptions.Archiveis,
archiveText: defaultArchiveText
archiveText: defaultArchiveText,
linkReplaceRules: [],
ignoreUrlPatterns: []
}


Expand All @@ -30,54 +39,118 @@ export class LinkArchiveSettingTab extends PluginSettingTab {

display(): void {
const plugin: ObsidianLinkArchivePlugin = (this as any).plugin;

const { containerEl } = this;
const { containerEl } = this;

containerEl.empty();

// add archive link text customization option
const archiveSettingsSection = containerEl.createDiv();
archiveSettingsSection.createEl("h2", { text: "Archive Settings" });

new Setting(archiveSettingsSection)
.setName("Link text")
.setDesc("The text of the archive links")
.addText(text =>
text
.setValue(plugin.settings.archiveText)
.onChange(async value => {
console.log(`Link text: ${value}`);
plugin.settings.archiveText = value;
await plugin.saveSettings();
}));

// link ignore rules
const linkIgnoreSection = containerEl.createDiv();
linkIgnoreSection.createEl("h2", { text: "Link Ignore Rules" });

new Setting(linkIgnoreSection)
.setName("Ignore URL Patterns")
.setDesc("Enter regular expressions to match URLs that should be ignored by the plugin")
.addButton(button => {
button.setButtonText("Add Pattern").onClick(() => {
plugin.settings.ignoreUrlPatterns.push("");
this.display();
});
});

// add ignore url patterns
for (let i = 0; i < plugin.settings.ignoreUrlPatterns.length; i++) {
const pattern = plugin.settings.ignoreUrlPatterns[i];

const setting = new Setting(containerEl)
.setName(`Pattern ${i + 1}`)
.addText(text => text
.setPlaceholder("URL Pattern")
.setValue(pattern)
.onChange(async value => {
plugin.settings.ignoreUrlPatterns[i] = value;
await plugin.saveSettings();
}));

setting.addButton(button => {
button.setIcon("cross")
.onClick(async () => {
plugin.settings.ignoreUrlPatterns.splice(i, 1);
await plugin.saveSettings();
this.display();
});
});
}

// add link replacement rules
const linkReplacementSection = containerEl.createDiv();
linkReplacementSection.createEl("h2", { text: "Link Replacement Rules" });

new Setting(linkReplacementSection)
.setDesc("Configure rules to replace specific links before archiving.")
.addButton(button => {
button.setButtonText("Add Rule").onClick(() => {
plugin.settings.linkReplaceRules.push({
originalPattern: "",
replacementPattern: ""
});
this.display();
});
});

// add link replacement rules
for (let i = 0; i < plugin.settings.linkReplaceRules.length; i++) {
const rule = plugin.settings.linkReplaceRules[i];

const setting = new Setting(containerEl)
.setName(`Rule ${i + 1}`)
.addText(text => text
.setPlaceholder("Original Pattern")
.setValue(rule.originalPattern)
.onChange(async value => {
rule.originalPattern = value;
await plugin.saveSettings();
}))
.addText(text => text
.setPlaceholder("Replacement Pattern")
.setValue(rule.replacementPattern)
.onChange(async value => {
rule.replacementPattern = value;
await plugin.saveSettings();
}));

setting.addButton(button => {
button.setIcon("cross")
.onClick(async () => {
plugin.settings.linkReplaceRules.splice(i, 1);
await plugin.saveSettings();
this.display();
});
});
}

// add about section
const aboutSection = containerEl.createDiv();
aboutSection.createEl("h2", { text: "About Link Archive" });

aboutSection.createEl("p", {text: "This plugin archives links in your note so they're available to you even if the original site goes down or gets removed."});

aboutSection.createEl("a", {text: "Open GitHub repository", href: "https://github.com/tomzorz/obsidian-link-archive"});

containerEl.createEl("h2", {text: "Archive Settings"});

new Setting(containerEl)
.setName("Link text")
.setDesc("The text of the archive links")
.addText(text =>
text
.setValue(plugin.settings.archiveText)
.onChange(async value => {
console.log(`Link text: ${value}`);
plugin.settings.archiveText = value;
await plugin.saveSettings();
}));

// new Setting(containerEl)
// .setName('Archive Provider')
// .setDesc('Choose a provider for the link archive')
// .addDropdown((dropdown) => {
// const options: Record<ArchiveOptions, string> = {
// 0: "Internet Archive",
// 1: "archive.is",
// 2: "Both"
// };

// dropdown
// .addOptions(options)
// .setValue(plugin.settings.archiveOption.toString())
// .onChange(async (value) => {
// console.log('Archive option: ' + value);
// plugin.settings.archiveOption = +value;
// await plugin.saveSettings();
// this.display();
// })
// });

containerEl.createEl("h2", {text: "About Link Archive"});

containerEl.createEl("p", {text: "This plugin archives links in your note so they're available to you even if the original site goes down or gets removed."});

containerEl.createEl("a", {text: "Open GitHub repository", href: "https://github.com/tomzorz/obsidian-link-archive"});

// TODO github support and ko-fi
}
}

0 comments on commit 544f3f0

Please sign in to comment.