Skip to content

Commit

Permalink
feat: recipe 目录解压
Browse files Browse the repository at this point in the history
  • Loading branch information
luke358 committed Jan 23, 2024
1 parent c96198c commit f35b886
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 45 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@
"normalize.css": "^8.0.1",
"pinia": "^2.1.3",
"pinia-plugin-persistedstate": "^3.1.0",
"tar": "^6.2.0",
"vue-router": "^4.2.0"
},
"devDependencies": {
"@antfu/eslint-config": "^2.6.2",
"@types/express": "^4.17.21",
"@types/lodash-es": "^4.17.7",
"@types/ms": "^0.7.31",
"@types/tar": "^6.1.10",
"@vitejs/plugin-vue": "^4.2.3",
"electron": "^28.1.0",
"electron-builder": "^24.6.3",
Expand Down
5 changes: 2 additions & 3 deletions src/helpers/asar-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { app } from '@electron/remote';
import { join } from 'path';

export function asarPath(dir: string = '') {
return dir.replace('app.asar', 'app.asar.unpacked');
}

// Replacing app.asar is not beautiful but unfortunately necessary
export function asarRecipesPath(...segments: string[]) {
console.log(__dirname, 'recipesDirectory')
return process.env.NODE_ENV === 'development' ? '' : join(asarPath(join(__dirname, '..', 'recipes')), ...[segments].flat());
return join(asarPath(join(app.getAppPath(), process.env.NODE_ENV === 'development' ? 'recipes/archives' : 'recipes')), ...[segments].flat());
}
4 changes: 4 additions & 0 deletions src/helpers/async-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default function sleep(ms: number = 0): Promise<void> {
// eslint-disable-next-line no-promise-executor-return
return new Promise(r => setTimeout(r, ms));
}
100 changes: 59 additions & 41 deletions src/store/recipes.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { join } from 'node:path';
// @ts-check
import { defineStore } from 'pinia'
import { Recipe, RecipeStore } from '@/types/recipe'
import { ref } from 'vue'
import { Service } from '@/types'
import { userDataRecipesPath } from '@/environment-remote'
import { asarRecipesPath } from '@/helpers/asar-helpers'
import { ensureDirSync, pathExistsSync, readJsonSync, removeSync, copySync, readdirSync, statSync } from 'fs-extra';
import sleep from '@/helpers/async-helpers';
import tar, { x } from 'tar';

export const useRecipeStore = defineStore('recipe',() => {
const allRecipes = ref<Recipe[]>([])
Expand All @@ -24,7 +28,7 @@ export const useRecipeStore = defineStore('recipe',() => {
}

const _bulkRecipeCheck = (unfilteredRecipes: string[]) => {
// filter duplicates
// filter duplicates 现在其实就一个
const recipes = unfilteredRecipes.filter(
(elem: string, pos: number, arr: string[]) =>
arr.indexOf(elem) === pos,
Expand All @@ -33,16 +37,14 @@ export const useRecipeStore = defineStore('recipe',() => {
return Promise.all(
recipes.map(async (recipeId: string) => {
let recipe = allRecipes.value.find(r => r.id === recipeId);
await getRecipePackage(recipeId);

if (!recipe) {
console.warn(
`Recipe '${recipeId}' not installed, trying to fetch from server`,
);

await getRecipePackage(recipeId);

// debug('Rerun ServerAPI::getInstalledRecipes');
// await this.getInstalledRecipes();
await getInstalledRecipes();

recipe = allRecipes.value.find(r => r.id === recipeId);

Expand All @@ -57,59 +59,75 @@ export const useRecipeStore = defineStore('recipe',() => {
).catch(error => console.error("Can't load recipe", error));
}

// 加载 recipe 文件
const getRecipePackage = async (recipeId: string) => {
const recipesDirectory = userDataRecipesPath();
// const recipeTempDirectory = join(recipesDirectory, 'temp', recipeId);
const recipeTempDirectory = join(recipesDirectory, 'temp', recipeId);
// const tempArchivePath = join(recipeTempDirectory, 'recipe.tar.gz');

const internalRecipeFile = asarRecipesPath(`${recipeId}.tar.gz`);

console.log(recipesDirectory, 'recipesDirectory', internalRecipeFile)

// console.log(internalRecipeFile, 'ddddccc')
// ensureDirSync(recipeTempDirectory);
ensureDirSync(recipeTempDirectory);

// let archivePath: PathOrFileDescriptor;
let archivePath: string;

// if (pathExistsSync(internalRecipeFile)) {
// debug('[ServerApi::getRecipePackage] Using internal recipe file');
// archivePath = internalRecipeFile;
// } else {
// debug('[ServerApi::getRecipePackage] Downloading recipe from server');
// archivePath = tempArchivePath;
if (pathExistsSync(internalRecipeFile)) {
// debug('[ServerApi::getRecipePackage] Using internal recipe file');
archivePath = internalRecipeFile;
} else {
// TODO: 先不考虑 recipe 不存在的情况
// debug('[ServerApi::getRecipePackage] Downloading recipe from server');
// archivePath = tempArchivePath;

// const packageUrl = `${apiBase()}/recipes/download/${recipeId}`;
// const packageUrl = `${apiBase()}/recipes/download/${recipeId}`;

// const res = await window.fetch(packageUrl);
// debug('Recipe downloaded', recipeId);
// const blob = await res.blob();
// const buffer = await blob.arrayBuffer();
// writeFileSync(tempArchivePath, Buffer.from(buffer));
// }
// const res = await window.fetch(packageUrl);
// debug('Recipe downloaded', recipeId);
// const blob = await res.blob();
// const buffer = await blob.arrayBuffer();
// writeFileSync(tempArchivePath, Buffer.from(buffer));
}
// debug(archivePath);

// await sleep(10);
await sleep(10);

// // @ts-expect-error No overload matches this call.
// await tar.x({
// file: archivePath,
// cwd: recipeTempDirectory,
// preservePaths: true,
// unlink: true,
// preserveOwner: false,
// onwarn: x => debug('warn', recipeId, x),
// });
await tar.x({
file: archivePath!,
cwd: recipeTempDirectory,
preserveOwner: false,
unlink: true,
onwarn: x => console.warn(recipeId, x),
});

// await sleep(10);
console.log(archivePath!, recipeTempDirectory)
await sleep(10);

// const { id } = readJsonSync(join(recipeTempDirectory, 'package.json'));
// const recipeDirectory = join(recipesDirectory, id);
// copySync(recipeTempDirectory, recipeDirectory);
// removeSync(recipeTempDirectory);
// removeSync(join(recipesDirectory, recipeId, 'recipe.tar.gz'));
const { id } = readJsonSync(join(recipeTempDirectory, 'package.json'));
const recipeDirectory = join(recipesDirectory, id);
copySync(recipeTempDirectory, recipeDirectory);
removeSync(recipeTempDirectory);
removeSync(join(recipesDirectory, recipeId, 'recipe.tar.gz'));

// return id;
return id;
}
// 通过 recipe 文件构造 recipe
const getInstalledRecipes = async () => {
const recipesDirectory = userDataRecipesPath();
const paths = readdirSync(recipesDirectory).filter(
file =>
statSync(join(recipesDirectory, file)).isDirectory() &&
file !== 'temp' &&
file !== 'dev',
);

paths.map(id => {
// const Recipe = require(id)(class RecipeModel {});

// console.log(new Recipe())
})

}

return {
allRecipes,
getRecipeByServiceId
Expand Down
8 changes: 7 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,13 @@ export default defineConfig(({ command }) => {
},
]),
// Use Node.js API in the Renderer-process
renderer(),
renderer({
// FIX: https://github.com/caoxiemeihao/nuxt-electron/issues/16#issuecomment-1487849598
resolve: process.env.NODE_ENV === 'development' ? {
'fs-extra': { type: 'esm' },
'tar': { type: 'esm' }
} : undefined
}),
],
resolve: {
alias: {
Expand Down

0 comments on commit f35b886

Please sign in to comment.