Skip to content

Commit

Permalink
Merge pull request #83 from tmayoff/recipe-rs
Browse files Browse the repository at this point in the history
  • Loading branch information
tmayoff authored Jul 6, 2024
2 parents b6a4cbb + 9d59ae6 commit 7367da5
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 45 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "test_vault/.obsidian/plugins/hot-reload"]
path = test_vault/.obsidian/plugins/hot-reload
url = https://github.com/pjeby/hot-reload.git
[submodule "recipe-rs"]
path = recipe-rs
url = git@github.com:tmayoff/recipe-rs.git
Binary file modified bun.lockb
Binary file not shown.
22 changes: 22 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@
system: let
overlays = [
(final: prev: {
wasm-pack = prev.rustPlatform.buildRustPackage rec {
pname = "wasm-pack";
version = "0.13.0";

src = prev.fetchFromGitHub {
owner = "rustwasm";
repo = "wasm-pack";
rev = "refs/tags/v${version}";
hash = "sha256-NEujk4ZPQ2xHWBCVjBCD7H6f58P4KrwCNoDHKa0d5JE=";
};

cargoHash = "sha256-pFKGQcWW1/GaIIWMyWBzts4w1hMu27hTG/uUMjkfDMo=";
nativeBuildInputs = with prev; [cmake];

buildInputs = prev.lib.optional prev.stdenv.isDarwin prev.darwin.apple_sdk.frameworks.Security;

# Most tests rely on external resources and build artifacts.
# Disabling check here to work with build sandboxing.
doCheck = false;
};

biome = prev.rustPlatform.buildRustPackage rec {
pname = "biome";
version = "1.8.1";
Expand Down Expand Up @@ -82,6 +103,7 @@
biome
act
just
wasm-pack
];
};
}
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"scripts": {
"dev": "vite build --mode development --watch",
"build": "vite build --mode production",
"check": "svelte-check --tsconfig ./tsconfig.json"
"check": "svelte-check --tsconfig ./tsconfig.json",
"wasm": "wasm-pack build ./recipe-rs --target web"
},
"keywords": [],
"author": "",
Expand All @@ -17,7 +18,7 @@
"@popperjs/core": "^2.11.8",
"@sveltejs/vite-plugin-svelte": "^3.1.1",
"@tsconfig/svelte": "^5.0.4",
"@types/node": "^20.14.9",
"@types/node": "^20.14.10",
"@types/pluralize": "^0.0.33",
"autoprefixer": "^10.4.19",
"builtin-modules": "^4.0.0",
Expand All @@ -30,12 +31,14 @@
"tailwindcss": "^3.4.4",
"tslib": "^2.6.3",
"typescript": "^5.5.3",
"vite": "^5.3.3"
"vite": "^5.3.3",
"vite-plugin-wasm-pack": "^0.1.12"
},
"dependencies": {
"@unocss/extractor-svelte": "^0.61.2",
"moment": "^2.30.1",
"pluralize": "^8.0.0",
"recipe-rs": "^0.1.5",
"unocss": "^0.61.2"
}
}
1 change: 1 addition & 0 deletions recipe-rs
Submodule recipe-rs added at a77482
17 changes: 17 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { AddFileToShoppingList, AddMealPlanToShoppingList, ClearCheckedIngredien
import SearchRecipe from './recipe/SearchRecipe.svelte';
import { MealSettings, RecipeFormat } from './settings';
import 'virtual:uno.css';
import init from 'recipe-rs';
import { DownloadRecipeCommand } from './recipe/downloader';

// biome-ignore lint/style/noDefaultExport: <explanation>
export default class MealPlugin extends Plugin {
Expand All @@ -14,6 +16,11 @@ export default class MealPlugin extends Plugin {
async onload() {
await this.loadSettings();

const wasmPath = this.app.vault.adapter.getResourcePath(
`${this.app.vault.configDir}/plugins/${this.manifest.id}/assets/recipe_rs_bg.wasm`,
);
await init(wasmPath);

this.ctx.loadRecipes(undefined);

this.registerEvent(
Expand Down Expand Up @@ -62,6 +69,14 @@ export default class MealPlugin extends Plugin {
},
});

this.addCommand({
id: 'download-url',
name: 'Download recipe from url',
callback: async () => {
await DownloadRecipeCommand(this.ctx);
},
});

this.registerEvent(
this.app.workspace.on('file-menu', (e, t) => {
if (t instanceof TFile && t.path.contains(get(this.ctx.settings).recipeDirectory)) {
Expand All @@ -76,6 +91,8 @@ export default class MealPlugin extends Plugin {
}
}),
);

console.info('obisidan-meals plugin loaded');
}

async loadSettings() {
Expand Down
88 changes: 88 additions & 0 deletions src/recipe/downloader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { type App, Modal, SuggestModal, requestUrl } from 'obsidian';
import { type Recipe, format, scrape } from 'recipe-rs';
import { get } from 'svelte/store';
import type { Context } from '../context';
import { AppendMarkdownExt, NoteExists, OpenNotePath } from '../utils/filesystem';

class DownloadRecipeModal extends SuggestModal<string> {
query = '';
context: Context;

constructor(ctx: Context) {
super(ctx.app);
this.context = ctx;
}

getSuggestions(query: string): string[] | Promise<string[]> {
this.query = query;
return ['download'];
}

renderSuggestion(value: string, el: HTMLElement) {
el.createEl('div', { text: value });
}

async onChooseSuggestion(item: string, _evt: MouseEvent | KeyboardEvent) {
if (item === 'download') {
await DownloadRecipe(this.context, this.query);
}
}
}

class ErrorDialog extends Modal {
message = 'unknown error';

constructor(app: App, message: string) {
super(app);
this.message = message;
}

onOpen() {
this.contentEl.createEl('h4', { text: 'An error occured' });
this.contentEl.createEl('p', { text: this.message });
this.contentEl.createEl('a', {
href: 'https://github.com/tmayoff/recipe-rs/issues/new',
text: 'Please make an issue here so I can help resolve the issue',
});
}

onClose() {
this.contentEl.empty();
}
}

export function DownloadRecipeCommand(ctx: Context) {
new DownloadRecipeModal(ctx).open();
}

async function DownloadRecipe(ctx: Context, url: string) {
const dom = await requestUrl(url).text;

let recipe: Recipe | null = null;
let formatted = '';
try {
recipe = scrape(url, dom);
formatted = format(recipe);
} catch (exception) {
new ErrorDialog(ctx.app, `${exception}`).open();
return;
}

const newRecipeNotePath = AppendMarkdownExt(`${get(ctx.settings).recipeDirectory}/${recipe.name}`);
if (NoteExists(ctx.app, newRecipeNotePath)) {
new ErrorDialog(ctx.app, 'Recipe with that name already exists').open();
await OpenNotePath(ctx.app, newRecipeNotePath);
return;
}

let content = '---\n';
content += `source: ${url}\n`;
content += '---\n';

content += '\n';
content += formatted;

await ctx.app.vault.create(newRecipeNotePath, content);

await OpenNotePath(ctx.app, newRecipeNotePath);
}
88 changes: 46 additions & 42 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { svelte, vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import builtins from 'builtin-modules';
import UnoCSS from 'unocss/vite';
import { PluginOption, defineConfig } from 'vite';
import { type PluginOption, defineConfig } from 'vite';
import wasmPack from 'vite-plugin-wasm-pack';

const setOutDir = (mode: string) => {
switch (mode) {
Expand All @@ -12,47 +13,50 @@ const setOutDir = (mode: string) => {
}
};

// biome-ignore lint/style/noDefaultExport: <explanation>
export default defineConfig(({ mode }) => {
return {
plugins: [
UnoCSS(),
svelte({
preprocess: vitePreprocess(),
compilerOptions: {
customElement: true,
},
}) as PluginOption,
],
build: {
lib: {
entry: 'src/main',
formats: ['cjs'],
},
rollupOptions: {
output: {
entryFileNames: 'main.js',
assetFileNames: 'styles.css',
},
external: [
'obsidian',
'electron',
'@codemirror/autocomplete',
'@codemirror/collab',
'@codemirror/commands',
'@codemirror/language',
'@codemirror/lint',
'@codemirror/search',
'@codemirror/state',
'@codemirror/view',
'@lezer/common',
'@lezer/highlight',
'@lezer/lr',
...builtins,
return {
plugins: [
wasmPack([], ['recipe-rs']),
UnoCSS(),
svelte({
preprocess: vitePreprocess(),
compilerOptions: {
customElement: true,
},
}) as PluginOption,
],
},
outDir: setOutDir(mode),
emptyOutDir: false,
sourcemap: mode === 'production' ? false : 'inline',
},
};
build: {
ssrEmitAssets: true,
lib: {
entry: 'src/main',
formats: ['cjs'],
},
rollupOptions: {
output: {
entryFileNames: 'main.js',
assetFileNames: 'styles.css',
},
external: [
'obsidian',
'electron',
'@codemirror/autocomplete',
'@codemirror/collab',
'@codemirror/commands',
'@codemirror/language',
'@codemirror/lint',
'@codemirror/search',
'@codemirror/state',
'@codemirror/view',
'@lezer/common',
'@lezer/highlight',
'@lezer/lr',
...builtins,
],
},
outDir: setOutDir(mode),
emptyOutDir: false,
sourcemap: mode === 'production' ? false : 'inline',
},
};
});

0 comments on commit 7367da5

Please sign in to comment.