Skip to content

Commit

Permalink
fix: potential issues with new release in the community market based …
Browse files Browse the repository at this point in the history
…on the feedback from Obsidian team
  • Loading branch information
sywhb committed Feb 6, 2023
1 parent 6579dbd commit d987f21
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 67 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ This plugin imports your saved [Omnivore](https://omnivore.app/) articles and hi

## Usage

1. The plugin will automatically sync with Omnivore every time you open the plugin and every time you change the settings
2. You can also manually sync with Omnivore by clicking the Omnivore icon on the ribbon
3. You can also change the API key, the search filter, and how often the plugin syncs with Omnivore by updating the settings
4. The plugin creates a new page for each saved article including metadata, labels. Content you have highlighted in Omnivore, and any notes you added, will be nested in the article page
5. Clicking on the article will open the Omnivore article in a new tab
6. We also create an internal link to each label in the article so you can group articles by label
1. The plugin will sync with Omnivore when you click on Omnivore ribbon icon or use the palette command
2. You can also change the API key, the search filter, and how often the plugin syncs with Omnivore by updating the settings
3. The plugin creates a new page for each saved article including metadata, labels. Content you have highlighted in Omnivore, and any notes you added, will be nested in the article page
4. Clicking on the article will open the Omnivore article in a new tab
5. We also create an internal link to each label in the article so you can group articles by label

## Contacts

Expand Down
111 changes: 56 additions & 55 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
Plugin,
PluginSettingTab,
Setting,
TFile,
TFolder,
} from "obsidian";
import {
Article,
Expand All @@ -21,7 +23,6 @@ import {
} from "./util";
import { FolderSuggest } from "./settings/file-suggest";

// Remember to rename these classes and interfaces!
enum Filter {
ALL = "import all my articles",
HIGHLIGHTS = "import just highlights",
Expand Down Expand Up @@ -102,15 +103,15 @@ export default class OmnivorePlugin extends Plugin {
await this.loadSettings();

this.addCommand({
id: "omnivore-sync",
id: "sync",
name: "Sync",
callback: () => {
this.fetchOmnivore();
},
});

this.addCommand({
id: "omnivore-resync",
id: "resync",
name: "Resync all articles",
callback: () => {
this.settings.syncAt = "";
Expand Down Expand Up @@ -201,9 +202,10 @@ export default class OmnivorePlugin extends Plugin {
this.settings.dateFormat
);
const folderName = `${folder}/${dateSaved}`;
if (
!(await this.app.vault.adapter.exists(normalizePath(folderName)))
) {
const omnivoreFolder = app.vault.getAbstractFileByPath(
normalizePath(folderName)
);
if (!(omnivoreFolder instanceof TFolder)) {
await this.app.vault.createFolder(folderName);
}

Expand Down Expand Up @@ -245,16 +247,6 @@ export default class OmnivorePlugin extends Plugin {
};
});

// // use template from file if specified
// let templateToUse = template;
// if (templateFileLocation) {
// const templateFile =
// this.app.vault.getAbstractFileByPath(templateFileLocation);
// if (templateFile) {
// templateToUse = await this.app.vault.read(templateFile as TFile);
// }
// }

// Build content string based on template
const content = Mustache.render(template, {
title: article.title,
Expand All @@ -272,7 +264,16 @@ export default class OmnivorePlugin extends Plugin {
content: article.content,
});

await this.app.vault.adapter.write(normalizePath(pageName), content);
const normalizedPath = normalizePath(pageName);
const omnivoreFile = app.vault.getAbstractFileByPath(normalizedPath);
if (omnivoreFile instanceof TFile) {
const existingContent = await this.app.vault.read(omnivoreFile);
if (existingContent !== content) {
await this.app.vault.modify(omnivoreFile, content);
}
} else {
await this.app.vault.create(normalizedPath, content);
}
}
}

Expand Down Expand Up @@ -317,17 +318,12 @@ class OmnivoreSettingTab extends PluginSettingTab {
this.plugin = plugin;
}

private static createFragmentWithHTML = (html: string) =>
createFragment(
(documentFragment) => (documentFragment.createDiv().innerHTML = html)
);

display(): void {
const { containerEl } = this;

containerEl.empty();

containerEl.createEl("h2", { text: "Settings for omnivore plugin" });
containerEl.createEl("h2", { text: "Settings for Omnivore plugin" });

// create a group of general settings
containerEl.createEl("h3", {
Expand All @@ -342,16 +338,21 @@ class OmnivoreSettingTab extends PluginSettingTab {
new Setting(generalSettings)
.setName("API Key")
.setDesc(
OmnivoreSettingTab.createFragmentWithHTML(
"You can create an API key at <a href='https://omnivore.app/settings/api'>https://omnivore.app/settings/api</a>"
)
createFragment((fragment) => {
fragment.append(
"You can create an API key at ",
fragment.createEl("a", {
text: "https://omnivore.app/settings/api",
href: "https://omnivore.app/settings/api",
})
);
})
)
.addText((text) =>
text
.setPlaceholder("Enter your Omnivore Api Key")
.setValue(this.plugin.settings.apiKey)
.onChange(async (value) => {
console.log("apiKey: " + value);
this.plugin.settings.apiKey = value;
await this.plugin.saveSettings();
})
Expand All @@ -365,7 +366,6 @@ class OmnivoreSettingTab extends PluginSettingTab {
dropdown
.setValue(this.plugin.settings.filter)
.onChange(async (value) => {
console.log("filter: " + value);
this.plugin.settings.filter = value;
await this.plugin.saveSettings();
});
Expand All @@ -374,9 +374,16 @@ class OmnivoreSettingTab extends PluginSettingTab {
new Setting(generalSettings)
.setName("Custom query")
.setDesc(
OmnivoreSettingTab.createFragmentWithHTML(
"See <a href='https://omnivore.app/help/search'>https://omnivore.app/help/search</a> for more info on search query syntax"
)
createFragment((fragment) => {
fragment.append(
"See ",
fragment.createEl("a", {
text: "https://omnivore.app/help/search",
href: "https://omnivore.app/help/search",
}),
" for more info on search query syntax"
);
})
)
.addText((text) =>
text
Expand All @@ -385,7 +392,6 @@ class OmnivoreSettingTab extends PluginSettingTab {
)
.setValue(this.plugin.settings.customQuery)
.onChange(async (value) => {
console.log("query: " + value);
this.plugin.settings.customQuery = value;
await this.plugin.saveSettings();
})
Expand All @@ -400,7 +406,6 @@ class OmnivoreSettingTab extends PluginSettingTab {
.setValue(this.plugin.settings.syncAt)
.setDefaultFormat("yyyy-MM-dd'T'HH:mm:ss")
.onChange(async (value) => {
console.log("syncAt: " + value);
this.plugin.settings.syncAt = value;
await this.plugin.saveSettings();
})
Expand All @@ -414,7 +419,6 @@ class OmnivoreSettingTab extends PluginSettingTab {
dropdown
.setValue(this.plugin.settings.highlightOrder)
.onChange(async (value) => {
console.log("highlightOrder: " + value);
this.plugin.settings.highlightOrder = value;
await this.plugin.saveSettings();
});
Expand All @@ -423,35 +427,26 @@ class OmnivoreSettingTab extends PluginSettingTab {
new Setting(generalSettings)
.setName("Template")
.setDesc(
OmnivoreSettingTab.createFragmentWithHTML(
`Enter template to render articles with. <a href="https://github.com/janl/mustache.js/#templates">Reference</a>`
)
createFragment((fragment) => {
fragment.append(
"Enter template to render articles with ",
fragment.createEl("a", {
text: "Reference",
href: "https://github.com/janl/mustache.js/#templates",
})
);
})
)
.addTextArea((text) =>
text
.setPlaceholder("Enter the template")
.setValue(this.plugin.settings.template)
.onChange(async (value) => {
console.log("template: " + value);
this.plugin.settings.template = value;
await this.plugin.saveSettings();
})
);

// new Setting(generalSettings)
// .setName("Template file location")
// .setDesc("Choose the file to use as the template")
// .addSearch((search) => {
// new FileSuggest(this.app, search.inputEl);
// search
// .setPlaceholder("Enter the file path")
// .setValue(this.plugin.settings.templateFileLocation)
// .onChange(async (value) => {
// this.plugin.settings.templateFileLocation = value;
// await this.plugin.saveSettings();
// });
// });

new Setting(generalSettings)
.setName("Folder")
.setDesc("Enter the folder where the data will be stored")
Expand All @@ -478,9 +473,15 @@ class OmnivoreSettingTab extends PluginSettingTab {
new Setting(generalSettings)
.setName("Date Format")
.setDesc(
OmnivoreSettingTab.createFragmentWithHTML(
'Enter the format date for use in rendered template.\nFormat <a href="https://moment.github.io/luxon/#/formatting?id=table-of-tokens">reference</a>.'
)
createFragment((fragment) => {
fragment.append(
"Enter the format date for use in rendered template.\nFormat ",
fragment.createEl("a", {
text: "reference",
href: "https://moment.github.io/luxon/#/formatting?id=table-of-tokens",
})
);
})
)
.addText((text) =>
text
Expand Down
2 changes: 2 additions & 0 deletions src/settings/file-suggest.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes

import { TAbstractFile, TFile, TFolder } from "obsidian";

import { TextInputSuggest } from "./suggest";
Expand Down
2 changes: 2 additions & 0 deletions src/settings/suggest.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes

import { createPopper, type Instance as PopperInstance } from "@popperjs/core";
import { App, type ISuggestOwner, Scope } from "obsidian";
import { wrapAround } from "../util";
Expand Down
16 changes: 10 additions & 6 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { diff_match_patch } from "diff-match-patch";
import { DateTime } from "luxon";
import escape from "markdown-escape";
import { requestUrl } from "obsidian";

export const DATE_FORMAT_W_OUT_SECONDS = "yyyy-MM-dd'T'HH:mm";
export const DATE_FORMAT = `${DATE_FORMAT_W_OUT_SECONDS}:ss`;
Expand Down Expand Up @@ -94,12 +95,13 @@ export const loadArticle = async (
slug: string,
apiKey: string
): Promise<Article> => {
const res = await fetch(ENDPOINT, {
const res = await requestUrl({
url: ENDPOINT,
headers: requestHeaders(apiKey),
body: `{"query":"\\n query GetArticle(\\n $username: String!\\n $slug: String!\\n ) {\\n article(username: $username, slug: $slug) {\\n ... on ArticleSuccess {\\n article {\\n ...ArticleFields\\n highlights {\\n ...HighlightFields\\n }\\n labels {\\n ...LabelFields\\n }\\n }\\n }\\n ... on ArticleError {\\n errorCodes\\n }\\n }\\n }\\n \\n fragment ArticleFields on Article {\\n savedAt\\n }\\n\\n \\n fragment HighlightFields on Highlight {\\n id\\n quote\\n annotation\\n }\\n\\n \\n fragment LabelFields on Label {\\n name\\n }\\n\\n","variables":{"username":"me","slug":"${slug}"}}`,
method: "POST",
});
const response = (await res.json()) as GetArticleResponse;
const response = res.json as GetArticleResponse;

return response.data.article.article;
};
Expand All @@ -114,15 +116,16 @@ export const loadArticles = async (
includeContent = false,
format = "html"
): Promise<[Article[], boolean]> => {
const res = await fetch(endpoint, {
const res = await requestUrl({
url: endpoint,
headers: requestHeaders(apiKey),
body: `{"query":"\\n query Search($after: String, $first: Int, $query: String, $includeContent: Boolean, $format: String) {\\n search(first: $first, after: $after, query: $query, includeContent: $includeContent, format: $format) {\\n ... on SearchSuccess {\\n edges {\\n node {\\n title\\n slug\\n siteName\\n originalArticleUrl\\n url\\n author\\n updatedAt\\n description\\n savedAt\\n pageType\\n content\\n highlights {\\n id\\n quote\\n annotation\\n patch\\n updatedAt\\n }\\n labels {\\n name\\n }\\n }\\n }\\n pageInfo {\\n hasNextPage\\n }\\n }\\n ... on SearchError {\\n errorCodes\\n }\\n }\\n }\\n ","variables":{"after":"${after}","first":${first}, "query":"${
updatedAt ? "updated:" + updatedAt : ""
} sort:saved-asc ${query}", "includeContent": ${includeContent}, "format": "${format}"}}`,
method: "POST",
});

const jsonRes = (await res.json()) as SearchResponse;
const jsonRes = res.json as SearchResponse;
const articles = jsonRes.data.search.edges.map((e) => e.node);

return [articles, jsonRes.data.search.pageInfo.hasNextPage];
Expand All @@ -135,15 +138,16 @@ export const loadDeletedArticleSlugs = async (
first = 10,
updatedAt = ""
): Promise<[string[], boolean]> => {
const res = await fetch(endpoint, {
const res = await requestUrl({
url: endpoint,
headers: requestHeaders(apiKey),
body: `{"query":"\\n query UpdatesSince($after: String, $first: Int, $since: Date!) {\\n updatesSince(first: $first, after: $after, since: $since) {\\n ... on UpdatesSinceSuccess {\\n edges {\\n updateReason\\n node {\\n slug\\n }\\n }\\n pageInfo {\\n hasNextPage\\n }\\n }\\n ... on UpdatesSinceError {\\n errorCodes\\n }\\n }\\n }\\n ","variables":{"after":"${after}","first":${first}, "since":"${
updatedAt || "2021-01-01"
}"}}`,
method: "POST",
});

const jsonRes = (await res.json()) as UpdatesSinceResponse;
const jsonRes = res.json as UpdatesSinceResponse;
const deletedArticleSlugs = jsonRes.data.updatesSince.edges
.filter((edge) => edge.updateReason === UpdateReason.DELETED)
.map((edge) => edge.node.slug);
Expand Down

0 comments on commit d987f21

Please sign in to comment.