generated from polymech/site-template
refactor models
This commit is contained in:
parent
8d4e880a3a
commit
b8d44fd215
@ -23,7 +23,7 @@
|
||||
"format": "unix-time"
|
||||
}
|
||||
],
|
||||
"default": "2025-03-31T18:28:08.800Z"
|
||||
"default": "2025-03-31T18:45:06.624Z"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
export default new Map([
|
||||
["src/content/infopages/contact.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Finfopages%2Fcontact.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/resources/workflow.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fresources%2Fworkflow.mdx&astroContentModuleFlag=true")]]);
|
||||
["src/content/resources/workflow.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Fresources%2Fworkflow.mdx&astroContentModuleFlag=true")],
|
||||
["src/content/infopages/contact.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=src%2Fcontent%2Finfopages%2Fcontact.mdx&astroContentModuleFlag=true")]]);
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -552,7 +552,7 @@
|
||||
},
|
||||
"https://github.com/%5Bfiltered%5D": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445732144
|
||||
"timestamp": 1743446744432
|
||||
},
|
||||
"https://github.com/darigovresearch": {
|
||||
"isValid": true,
|
||||
@ -670,7 +670,7 @@
|
||||
},
|
||||
"https://scholarworks.uni.edu/cgi/viewcontent.cgi?article=3680%5C&context=grp": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445690980
|
||||
"timestamp": 1743446708264
|
||||
},
|
||||
"https://pmc.ncbi.nlm.nih.gov/articles/PMC10489002/": {
|
||||
"isValid": true,
|
||||
@ -754,7 +754,7 @@
|
||||
},
|
||||
"https://journals.plos.org/plosone/article?id=10.1371%252Fjournal.pone.0288696": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445696843
|
||||
"timestamp": 1743446719043
|
||||
},
|
||||
"https://www.youtube.com/watch?v=_a7usMe_K38": {
|
||||
"isValid": true,
|
||||
@ -841,7 +841,7 @@
|
||||
},
|
||||
"https://www.toraytac.com/media/c3feb206-1398-4e0e-bca6-df7780f11745/tcCurg/TenCate%2520Advanced%2520Composites/Documents/Technical%2520papers/TenCate_chopped_fiber_thermoplastics_compression_molding_technical_paper.pdf": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445691831
|
||||
"timestamp": 1743446708939
|
||||
},
|
||||
"https://youtu.be/qtZv96cifIU": {
|
||||
"isValid": true,
|
||||
@ -1397,7 +1397,7 @@
|
||||
},
|
||||
"https://www.amazon.it/s?k=cnc+CNC%20Router": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445692320,
|
||||
"timestamp": 1743446709933,
|
||||
"meta": {
|
||||
"title": "Ci dispiace",
|
||||
"image": "https://images-eu.ssl-images-amazon.com/images/G/29/x-locale/communities/people/logo.gif",
|
||||
@ -1897,7 +1897,7 @@
|
||||
},
|
||||
"https://digitalcommons.calpoly.edu/cgi/viewcontent.cgi?article=1288%5C&context=eesp": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445693492
|
||||
"timestamp": 1743446711171
|
||||
},
|
||||
"*": {
|
||||
"isValid": false,
|
||||
@ -1905,7 +1905,7 @@
|
||||
},
|
||||
"https://partners.noplasticsunday.com/NPSblog/?bmode=view%5C&idx=11164797": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445694627,
|
||||
"timestamp": 1743446715113,
|
||||
"meta": {
|
||||
"title": "노플라스틱선데이",
|
||||
"description": "지속가능한 제조 서비스 NPS Partners",
|
||||
@ -2062,7 +2062,7 @@
|
||||
},
|
||||
"https://www.youtube.com/watch?v=Eq9IbetsLB4%5C&t=2s": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445695078,
|
||||
"timestamp": 1743446716528,
|
||||
"meta": {
|
||||
"title": "Injection molding machine for recycling plastic",
|
||||
"description": "Injection molding machine for recycling plastic (called \"Smart Injector\"). The design is low-cost and uses easy componentsIMPORTANT! The machine is still wor...",
|
||||
@ -2647,7 +2647,7 @@
|
||||
},
|
||||
"https://www.youtube.com/watch?time_continue=163%5C&v=95aPYlXShTY%5C&feature=emb_logo": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445695576,
|
||||
"timestamp": 1743446717894,
|
||||
"meta": {
|
||||
"title": "Hands-Free Door Opener: Technical Information",
|
||||
"description": "Discover our available models, printing and mounting instructions, and informational sticker for our 3D-printed hands-free door opener to avoid passing on CO...",
|
||||
@ -2895,7 +2895,7 @@
|
||||
},
|
||||
"https://crescent.education/wp-content/uploads/2019/02/MODULE-II-%25E2%2580%2593-FUNDAMENTALS-OF-EXTRUSION-MOULDING.pdf": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445696698
|
||||
"timestamp": 1743446718866
|
||||
},
|
||||
"https://rjginc.com/essential-injection-molding-safety-standards-and-practices/": {
|
||||
"isValid": true,
|
||||
@ -2920,7 +2920,7 @@
|
||||
},
|
||||
"https://www.oldergeeks.com/downloads/search.php?limit=100%5C&string=Power+Software+Ltd.%5C&sort=file_name%5C&order=asc%5C&id=0%5C&page=9": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445697371,
|
||||
"timestamp": 1743446720119,
|
||||
"meta": {
|
||||
"favicon": "https://www.oldergeeks.com/favicon.ico"
|
||||
}
|
||||
@ -3131,7 +3131,7 @@
|
||||
},
|
||||
"https://papers.ssrn.com/sol3/Delivery.cfm/733008ad-9620-43bf-896c-aa4a2e9931e5-MECA.pdf?abstractid=4611811%5C&mirid=1": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445698706,
|
||||
"timestamp": 1743446723798,
|
||||
"meta": {
|
||||
"title": "Page Cannot be Found",
|
||||
"favicon": "https://papers.ssrn.com/favicon.ico"
|
||||
@ -3231,7 +3231,7 @@
|
||||
},
|
||||
"https://en.wikipedia.org/wiki/Jigsaw_%5C(power_tool%5C": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445699826
|
||||
"timestamp": 1743446723984
|
||||
},
|
||||
"https://www.amazon.de/-/en/Stanley-10-099-Classic/dp/B001FWP58U": {
|
||||
"isValid": false,
|
||||
@ -3819,7 +3819,7 @@
|
||||
},
|
||||
"https://scibizsw.com/20_THE%2520OFFICIAL%2520RASPBERRY%2520PI%2520PROJECTS%2520BOOK%2520v3.pdf": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445730383
|
||||
"timestamp": 1743446742609
|
||||
},
|
||||
"https://archive.org/stream/MagPi/Projects_Book_v3_djvu.txt": {
|
||||
"isValid": true,
|
||||
@ -5834,7 +5834,7 @@
|
||||
},
|
||||
"https://www.rainbow-pkg.com/news/youpinzhiku%25E4%25B8%25A8hot-stamping-and-cold-stamping-technology-which-one-is-more-suitable-for-your-packaging-products/": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445703799
|
||||
"timestamp": 1743446726706
|
||||
},
|
||||
"https://ch-wauters.com/en/cold-foil-stamping-by-wauters/": {
|
||||
"isValid": true,
|
||||
@ -6091,7 +6091,7 @@
|
||||
},
|
||||
"https://%5Bfiltered%5D.github.io/academy/build/compression": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445704158
|
||||
"timestamp": 1743446727151
|
||||
},
|
||||
"https://davehakkens.nl/community/forums/topic/v4-sheet-press-mould-development/index.html": {
|
||||
"isValid": true,
|
||||
@ -7218,7 +7218,7 @@
|
||||
},
|
||||
"https://guides.lib.virginia.edu/c.php?g=1164312%5C&p=8718414": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445705612,
|
||||
"timestamp": 1743446729252,
|
||||
"meta": {
|
||||
"title": "LibGuides: COVID-19 Pandemic Children's Book Collection: Normalizing Face Masks",
|
||||
"description": "LibGuides: COVID-19 Pandemic Children's Book Collection: Normalizing Face Masks",
|
||||
@ -7462,7 +7462,7 @@
|
||||
},
|
||||
"https://forum.freecad.org/viewtopic.php?style=1%5C&t=62057": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445706338,
|
||||
"timestamp": 1743446729884,
|
||||
"meta": {
|
||||
"title": "Step by step tutorial on injection mold design - FreeCAD Forum",
|
||||
"image": "https://forum.freecad.org/styles/elegance/theme/images/logo.png",
|
||||
@ -7664,7 +7664,7 @@
|
||||
},
|
||||
"https://www.youtube.com/watch?v=YzjTm3FRLVY%5C&t=5s": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445706630,
|
||||
"timestamp": 1743446731175,
|
||||
"meta": {
|
||||
"title": "Recycling plastic waste on the beaches of Panama",
|
||||
"description": "Precious Plastic community submission! Thanks Thomas, check him out in our forums:https://davehakkens.nl/community/members/thomasthefirst/More information: h...",
|
||||
@ -7880,8 +7880,13 @@
|
||||
}
|
||||
},
|
||||
"https://seafood.media/fis/worldnEws/worldnews.asp?monthyear=9-2024%5C&day=18%5C&id=131886%5C&l=e%5C&country=%5C&special=%5C&ndb=1%5C&df=1": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445729274
|
||||
"isValid": true,
|
||||
"timestamp": 1743446741406,
|
||||
"meta": {
|
||||
"title": "Seafood Media Group - Worldnews",
|
||||
"image": "https://seafood.media/fis/gif/free/flags/ES.gif",
|
||||
"favicon": "https://seafood.media/favicon.ico"
|
||||
}
|
||||
},
|
||||
"https://theoceancleanup.com/oceans/": {
|
||||
"isValid": true,
|
||||
@ -8028,7 +8033,7 @@
|
||||
},
|
||||
"https://%5Bfiltered%5D.github.io/academy/build/sheetpressbuild": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445729461
|
||||
"timestamp": 1743446741634
|
||||
},
|
||||
"https://www.singhalglobal.com/blog/sheets-of-hdpe-manufacturing-processes-and-various-use": {
|
||||
"isValid": true,
|
||||
@ -8499,7 +8504,7 @@
|
||||
},
|
||||
"https://www.youtube.com/watch?v=gxkcffQD3eQ%5C&t=131s": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445730780,
|
||||
"timestamp": 1743446743571,
|
||||
"meta": {
|
||||
"title": "🎄⭐🎅Como hacer figuras de plástico- Figuras Navideñas de Plástico Reciclado🎄⭐🎅",
|
||||
"description": "En este tutorial reciclamos tapas de botellas y las convertimos en figuras navideñas usando la dremel motosaw y un horno de pizza",
|
||||
@ -9404,7 +9409,7 @@
|
||||
},
|
||||
"https://scholarworks.uark.edu/cgi/viewcontent.cgi?article=1066%5C&context=inquiry": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445733821
|
||||
"timestamp": 1743446745917
|
||||
},
|
||||
"https://www.youtube.com/watch?v=1OZVCOYlYy8": {
|
||||
"isValid": true,
|
||||
@ -9430,7 +9435,7 @@
|
||||
},
|
||||
"https://www.forum.linuxcnc.org/30-cnc-machines/53486-the-linuxcnc-rigid-CNC%20Router-an-open-source-dual-z-axis-gantry-machine": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445734477,
|
||||
"timestamp": 1743446747446,
|
||||
"meta": {
|
||||
"title": "The LinuxCNC "Rigid Router" an open-source dual z-axis gantry machine",
|
||||
"description": "Hi all, I recently designed an open-source CNC router. My goal was to make a rigid, medium-format CNC router that can self-manufacture new machines and not...",
|
||||
@ -9517,7 +9522,7 @@
|
||||
},
|
||||
"https://www.bunnings.com.au/search/products?q=fiber%2520cement": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445734754
|
||||
"timestamp": 1743446747639
|
||||
},
|
||||
"https://safeworkwear.com.au/electrical-gloves": {
|
||||
"isValid": false,
|
||||
@ -10094,7 +10099,7 @@
|
||||
},
|
||||
"https://citeseerx.ist.psu.edu/document?repid=rep1%5C&type=pdf%5C&doi=2d21d208bf921ec8278814cfbee00e60e54acfb4": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445735783
|
||||
"timestamp": 1743446748314
|
||||
},
|
||||
"https://www.youtube.com/watch?v=viwbxM6F7zc": {
|
||||
"isValid": true,
|
||||
@ -10299,7 +10304,7 @@
|
||||
},
|
||||
"https://dspace.mit.edu/bitstream/handle/1721.1/127868/1196826370-MIT.pdf?sequence=1%5C&isAllowed=y": {
|
||||
"isValid": true,
|
||||
"timestamp": 1743445737987,
|
||||
"timestamp": 1743446752351,
|
||||
"meta": {
|
||||
"favicon": "https://dspace.mit.edu/favicon.ico"
|
||||
}
|
||||
@ -10395,7 +10400,7 @@
|
||||
},
|
||||
"*No%20link%20provided%20in%20source%20text*": {
|
||||
"isValid": false,
|
||||
"timestamp": 1743445738440
|
||||
"timestamp": 1743446752449
|
||||
},
|
||||
"https://www.instructables.com/Bottle-Cap-Table-with-Poured-Resin-Surface/": {
|
||||
"isValid": true,
|
||||
|
||||
@ -1 +1,49 @@
|
||||
export const HOWTO_ROOT = () => '/howto';
|
||||
export const HOWTO_ROOT = () => '/howto';
|
||||
export const DIRECTORY_ROOT = () => '/directory';
|
||||
|
||||
export const HOWTO_FILES_WEB = () => '/howto';
|
||||
export const DIRECTORY_FILES_WEB = () => '/directory';
|
||||
|
||||
export const HOWTO_FILES_ABS = () => '/howto';
|
||||
export const DIRECTORY_FILES_ABS = () => '/directory';
|
||||
|
||||
export const HOWTO_FILTER_LLM = () => true;
|
||||
export const DIRECTORY_FILTER_LLM = () => true;
|
||||
|
||||
export const HOWTO_GLOB = () => '**/*.md';
|
||||
export const DIRECTORY_GLOB = () => '**/*.md';
|
||||
|
||||
export const HOWTO_MIGRATION = () => 'data/migration.json';
|
||||
export const DIRECTORY_MIGRATION = () => 'data/migration.json';
|
||||
|
||||
export const HOWTO_ANNOTATIONS = () => true;
|
||||
export const DIRECTORY_ANNOTATIONS = () => true;
|
||||
|
||||
export const HOWTO_COMPLETE_RESOURCES = () => true;
|
||||
export const DIRECTORY_COMPLETE_RESOURCES = () => true;
|
||||
|
||||
export const HOWTO_ADD_HARDWARE = () => true;
|
||||
export const DIRECTORY_ADD_HARDWARE = () => true;
|
||||
|
||||
export const HOWTO_COMPLETE_SKILLS = () => true;
|
||||
export const DIRECTORY_COMPLETE_SKILLS = () => true;
|
||||
|
||||
export const HOWTO_LOCAL_RESOURCES = () => true;
|
||||
export const DIRECTORY_LOCAL_RESOURCES = () => true;
|
||||
|
||||
export const HOWTO_ADD_RESOURCES = () => true;
|
||||
export const DIRECTORY_ADD_RESOURCES = () => true;
|
||||
|
||||
export const HOWTO_ADD_REFERENCES = () => true;
|
||||
export const DIRECTORY_ADD_REFERENCES = () => true;
|
||||
|
||||
export const HOWTO_SEO_LLM = () => true;
|
||||
export const DIRECTORY_SEO_LLM = () => true;
|
||||
|
||||
export const HOWTO_MAX_ITEMS = () => 1000;
|
||||
export const DIRECTORY_MAX_ITEMS = () => 1000;
|
||||
|
||||
export const default_image = () => ({
|
||||
src: '/images/default.png',
|
||||
alt: 'Default image'
|
||||
});
|
||||
@ -45,7 +45,8 @@ type LLMConfig = z.infer<typeof LLMConfigSchema>;
|
||||
export const enum TemplateContext {
|
||||
COMMONS = 'commons',
|
||||
HOWTO = 'howto',
|
||||
MARKETPLACE = 'marketplace'
|
||||
MARKETPLACE = 'marketplace',
|
||||
DIRECTORY = 'directory'
|
||||
}
|
||||
// Default configuration
|
||||
export const DEFAULT_CONFIG: LLMConfig = {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { decode } from "html-entities";
|
||||
import { IHowto, asset_local_rel } from "@/model/howto/howto.jswto.js";
|
||||
import { IHowto, asset_local_rel } from "@/model/howto/howto.js";
|
||||
import { Img } from "imagetools/components";
|
||||
import { i18n as Translate } from "@polymech/astro-base";
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
|
||||
@ -3,7 +3,7 @@ import { default_image, IMAGE_SETTINGS } from "config/config.js";
|
||||
import Translate from "@/components/polymech/i18n.astro";
|
||||
import { Img } from "imagetools/components";
|
||||
import Sidebar from "@/components/howtos/sidebar2.astro";
|
||||
import { asset_local_abs,asset_local_rel, IHowto } from "@/model/howto/howto.jswto.js";
|
||||
import { asset_local_abs,asset_local_rel, IHowto } from "@/model/howto/howto.js";
|
||||
const { title, url, model, selected = false } = Astro.props;
|
||||
const item: IHowto = model.item;
|
||||
const classes = `group relative bg-white overflow-hidden group rounded-xl ${selected ? "ring-2 ring-orange-500" : ""}`;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
// Import the required interfaces and utilities
|
||||
import { IHowto } from "@/model/howto/howto.jswto.js";
|
||||
import { IHowto } from "@/model/howto/howto.js";
|
||||
import { i18n as Translate } from "@polymech/astro-base";
|
||||
import { getCollection } from 'astro:content';
|
||||
const items = await getCollection('howtos');
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import { IHowto } from "@/model/howto/howto.jswto.js";
|
||||
import { IHowto } from "@/model/howto/howto.js";
|
||||
import { i18n as Translate } from "@polymech/astro-base";
|
||||
const locale = Astro.currentLocale;
|
||||
const items = await getCollection('howtos')
|
||||
|
||||
@ -20,7 +20,6 @@ export const I18N_CACHE = true
|
||||
export const I18N_ASSET_PATH = "${SRC_DIR}/${SRC_NAME}-${DST_LANG}${SRC_EXT}"
|
||||
|
||||
// Library - Howtos
|
||||
|
||||
export const HOWTO_GLOB = '**/config.json'
|
||||
export const FILES_WEB = 'https://files.polymech.io/files/machines/howtos/'
|
||||
export const HOWTO_EDIT_ROOT = 'https://git.polymech.io/osr-plastic/osr-machines/src/branch/master/howtos'
|
||||
@ -43,6 +42,29 @@ export const HOWTO_FILES_ABS = (id) => `${HOWTO_ROOT()}/${id}`
|
||||
export const HOWTO_FILES_WEB = (id: string) => `${FILES_WEB}/${id}`
|
||||
export const HOWTO_EDIT_URL = (id: string, lang: string) => `${HOWTO_EDIT_ROOT}/${id}`
|
||||
|
||||
// Library - Directory
|
||||
export const DIRECTORY_GLOB = '**/config.json'
|
||||
export const DIRECTORY_FILES_BASE = 'https://files.polymech.io/files/directory/'
|
||||
export const DIRECTORY_EDIT_ROOT = 'https://git.polymech.io/osr-plastic/osr-machines/src/branch/master/directory'
|
||||
export const DIRECTORY_FILTER_LLM = true
|
||||
export const DIRECTORY_ANNOTATIONS = false
|
||||
export const DIRECTORY_ANNOTATIONS_CACHE = false
|
||||
export const DIRECTORY_COMPLETE_RESOURCES = true
|
||||
export const DIRECTORY_ADD_HARDWARE = false
|
||||
export const DIRECTORY_ADD_RESOURCES = true
|
||||
export const DIRECTORY_ADD_REFERENCES = true
|
||||
export const DIRECTORY_COMPLETE_SKILLS = false
|
||||
export const DIRECTORY_LOCAL_RESOURCES = false
|
||||
export const DIRECTORY_SEO_LLM = true
|
||||
export const DIRECTORY_MAX_ITEMS = 200
|
||||
|
||||
export const DIRECTORY_MIGRATION = () => path.resolve(resolve("./data/last.json"))
|
||||
export const DIRECTORY_ROOT_INTERN = () => path.resolve(resolve("./public/resources/directory"))
|
||||
export const DIRECTORY_ROOT = () => path.resolve(resolve("${OSR_ROOT}/osr-machines/directory"))
|
||||
export const DIRECTORY_FILES_ABS = (id) => `${DIRECTORY_ROOT()}/${id}`
|
||||
export const DIRECTORY_FILES_WEB = (id: string) => `${DIRECTORY_FILES_BASE}/${id}`
|
||||
export const DIRECTORY_EDIT_URL = (id: string, lang: string) => `${DIRECTORY_EDIT_ROOT}/${id}`
|
||||
|
||||
// Products
|
||||
export const PRODUCT_ROOT = () => path.resolve(resolve("${OSR_ROOT}/products"))
|
||||
export const PRODUCT_BRANCHES = read(path.join(PRODUCT_ROOT(), 'config/machines.json'), 'json')
|
||||
|
||||
@ -18,7 +18,7 @@ import {
|
||||
IComponentConfigEx,
|
||||
group_by_path,
|
||||
group_path,
|
||||
} from "@/model/component/component.jsmponent.js";
|
||||
} from "@/model/component/component.js";
|
||||
|
||||
import "flowbite";
|
||||
|
||||
|
||||
@ -1,129 +0,0 @@
|
||||
import * as path from 'path'
|
||||
import { findUp } from 'find-up'
|
||||
import { sync as read } from '@polymech/fs/read'
|
||||
import { resolveConfig } from '@polymech/commons'
|
||||
import { DataEntry } from "astro:content"
|
||||
import type { Loader, LoaderContext } from 'astro/loaders'
|
||||
|
||||
import { logger } from '@/base/index.js'
|
||||
|
||||
import {
|
||||
PRODUCT_BRANCHES,
|
||||
PRODUCT_DIR, PRODUCT_GLOB,
|
||||
PRODUCT_ROOT
|
||||
} from 'config/config.js'
|
||||
|
||||
import { env } from '../../base/index.js'
|
||||
|
||||
import { gallery } from '../../base/media.js';
|
||||
import { get } from '@polymech/commons/component'
|
||||
import { PFilterValid } from '@polymech/commons/filter'
|
||||
import { translate } from "@/base/i18n.js"
|
||||
import { I18N_SOURCE_LANGUAGE } from "config/config.js"
|
||||
import { slugify } from "@/base/strings.js"
|
||||
|
||||
import { I_PC_USER } from 'site/types/types.js'
|
||||
|
||||
export interface I_User extends I_PC_USER {
|
||||
content: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
export interface IStoreItem extends DataEntry {
|
||||
data: I_User,
|
||||
}
|
||||
|
||||
|
||||
const filterBranch = (items: { rel: string, config, path }[], branch: string) => {
|
||||
if (!PRODUCT_BRANCHES) {
|
||||
return items
|
||||
}
|
||||
const branchItems = PRODUCT_BRANCHES[branch]
|
||||
if (!branchItems) {
|
||||
return items
|
||||
}
|
||||
return items.filter((item) => branchItems.includes(item.rel))
|
||||
}
|
||||
|
||||
export const items = (branch: string) =>
|
||||
filterBranch(get(`${PRODUCT_ROOT()}/${PRODUCT_GLOB}`,
|
||||
PRODUCT_ROOT(), PFilterValid.marketplace_component), branch)
|
||||
|
||||
|
||||
const onItem = async (item: IStoreItem, ctx: LoaderContext) => {
|
||||
if (!item || !item.data) {
|
||||
ctx.logger.error(`Error completing ${''}: no data`);
|
||||
return
|
||||
}
|
||||
|
||||
let data: I_User = item.data
|
||||
data = resolveConfig(data as Record<string, string>) as I_User
|
||||
}
|
||||
|
||||
export function loader(branch: string): Loader {
|
||||
const load = async ({
|
||||
config,
|
||||
logger,
|
||||
watcher,
|
||||
parseData,
|
||||
store,
|
||||
generateDigest }: LoaderContext) => {
|
||||
|
||||
store.clear();
|
||||
let products = items(branch)
|
||||
for (const item of products) {
|
||||
const product: any = item.config
|
||||
const id = product.slug;
|
||||
const data = {
|
||||
rel: item.rel,
|
||||
slug: id,
|
||||
id,
|
||||
title: product.name,
|
||||
type: 'directory',
|
||||
...product,
|
||||
}
|
||||
//const parsedData = await parseData({ id, data: data });
|
||||
const storeItem = {
|
||||
digest: await generateDigest(data),
|
||||
filePath: id,
|
||||
assetImports: [],
|
||||
id: `${item.rel}`,
|
||||
data: data
|
||||
}
|
||||
await onItem(storeItem, {
|
||||
logger,
|
||||
watcher,
|
||||
parseData,
|
||||
store,
|
||||
generateDigest
|
||||
} as any)
|
||||
|
||||
storeItem.data['config'] = JSON.stringify({
|
||||
...storeItem.data
|
||||
}, null, 2)
|
||||
|
||||
store.set(storeItem)
|
||||
}
|
||||
}
|
||||
return {
|
||||
name: "directory-loader",
|
||||
load
|
||||
};
|
||||
}
|
||||
|
||||
export const group_path = (item) => item.id.split("/")[1]
|
||||
const group_label = async (text: string, locale) => await translate(slugify(text), I18N_SOURCE_LANGUAGE, locale)
|
||||
const group = async (items, locale) => {
|
||||
return items.reduce(async (accPromise, item) => {
|
||||
const acc = await accPromise
|
||||
const id = group_path(item)
|
||||
let key: string = await group_label(id, locale)
|
||||
key = key.charAt(0).toUpperCase() + key.slice(1)
|
||||
if (!acc[key]) {
|
||||
acc[key] = []
|
||||
}
|
||||
acc[key].push(item)
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
export const group_by_path = async (items, locale): Promise<I_User[]> => await group(items, locale)
|
||||
207
src/model/directory/item.ts
Normal file
207
src/model/directory/item.ts
Normal file
@ -0,0 +1,207 @@
|
||||
import * as path from 'path'
|
||||
import { findUp } from 'find-up'
|
||||
import pMap from 'p-map'
|
||||
import { sanitizeFilename } from "@polymech/fs/utils"
|
||||
import { execFileSync, execFile } from "child_process";
|
||||
import { sync as read } from '@polymech/fs/read'
|
||||
import { sync as exists } from '@polymech/fs/exists'
|
||||
import { sync as mkdir } from '@polymech/fs/dir'
|
||||
import { sync as rm } from '@polymech/fs/remove'
|
||||
import { sync as write } from '@polymech/fs/write'
|
||||
import type { Loader, LoaderContext } from 'astro/loaders'
|
||||
import { resolveVariables } from "@polymech/commons/variables"
|
||||
import { IUser } from './types.js'
|
||||
import { blacklist, default_filters_markdown, validateLinks } from '../../base/filters.js'
|
||||
import { download } from '../download.js'
|
||||
import { filter } from "@/base/kbot.js"
|
||||
import { slugify } from "@/base/strings.js"
|
||||
import { urlCache } from '../../base/url-cache.js';
|
||||
|
||||
const expandUrls = true
|
||||
import {
|
||||
DIRECTORY_FILES_WEB,
|
||||
DIRECTORY_FILES_ABS,
|
||||
DIRECTORY_FILTER_LLM,
|
||||
default_image,
|
||||
DIRECTORY_ROOT,
|
||||
DIRECTORY_GLOB,
|
||||
DIRECTORY_MIGRATION,
|
||||
DIRECTORY_ANNOTATIONS,
|
||||
DIRECTORY_COMPLETE_RESOURCES,
|
||||
DIRECTORY_ADD_HARDWARE,
|
||||
DIRECTORY_COMPLETE_SKILLS,
|
||||
DIRECTORY_LOCAL_RESOURCES,
|
||||
DIRECTORY_ADD_RESOURCES,
|
||||
DIRECTORY_ADD_REFERENCES,
|
||||
DIRECTORY_SEO_LLM,
|
||||
DIRECTORY_MAX_ITEMS
|
||||
} from "config/config.js"
|
||||
|
||||
import { env, logger } from '@/base/index.js'
|
||||
import { applyFilters, default_filters_plain, FilterFunction } from '../../base/filters.js'
|
||||
import { TemplateContext, buildPrompt, LLMConfig, createTemplates } from '@/base/kbot-templates.js'
|
||||
import { template_filter } from '@/base/kbot.js'
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Assets
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
export const item_path = (item: IUser) => `${DIRECTORY_ROOT()}/${item._id}`
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Data
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
export const raw = async () => {
|
||||
const src = DIRECTORY_MIGRATION()
|
||||
const data = read(src, 'json') as any;
|
||||
let users = data.v3_mappins as any[]
|
||||
users = users.filter((u) => u.moderation == 'accepted' && !u._deleted);
|
||||
users = users.filter((u: IUser) => !blacklist.includes(u._id))
|
||||
users = users.slice(0, DIRECTORY_MAX_ITEMS)
|
||||
return users
|
||||
}
|
||||
|
||||
export const defaults = async (data: any, cwd: string, root: string) => {
|
||||
let defaultsJSON = await findUp('defaults.json', {
|
||||
stopAt: root,
|
||||
cwd: cwd
|
||||
});
|
||||
try {
|
||||
if (defaultsJSON) {
|
||||
data = {
|
||||
...read(defaultsJSON, 'json') as any,
|
||||
...data,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Content filters & conversions
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const commons = async (text: string): Promise<string> => {
|
||||
return await template_filter(text, 'simple', TemplateContext.COMMONS);
|
||||
}
|
||||
|
||||
const content = async (str: string, filters: FilterFunction[] = default_filters_plain) => await applyFilters(str, filters)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Store
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const complete = async (item: IUser) => {
|
||||
const configPath = path.join(item_path(item), 'config.json')
|
||||
const config = read(configPath, 'json') as IUser || {}
|
||||
// item = { ...item, ...config }
|
||||
|
||||
if (!DIRECTORY_ANNOTATIONS) {
|
||||
// return item
|
||||
}
|
||||
|
||||
// commons: language, tone, bullshit filter, and a piece of love, just a bit, at least :)
|
||||
if (DIRECTORY_FILTER_LLM) {
|
||||
item.detail = await commons(item.detail || '')
|
||||
}
|
||||
|
||||
item.detail = await applyFilters(item.detail || '', [validateLinks])
|
||||
|
||||
// Generate keywords using the keywords template
|
||||
if (DIRECTORY_ADD_RESOURCES) {
|
||||
item.data = await applyFilters(item.data, default_filters_markdown);
|
||||
write(path.join(item_path(item), 'resources.md'), item.data as string)
|
||||
}
|
||||
|
||||
if (DIRECTORY_SEO_LLM) {
|
||||
item.brief = await template_filter(item.detail, 'brief', TemplateContext.DIRECTORY);
|
||||
}
|
||||
|
||||
item.detail = await applyFilters(item.detail || '', [validateLinks])
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
const onStoreItem = async (store: any) => {
|
||||
let item = store.data.item as IUser
|
||||
|
||||
item = await complete(item)
|
||||
const configPath = path.join(item_path(item), 'config.json')
|
||||
write(configPath, JSON.stringify(item, null, 2))
|
||||
logger.info(`Stored item ${item._id} at ${configPath}`)
|
||||
store.data.item = item
|
||||
return store
|
||||
}
|
||||
|
||||
export function loader(): Loader {
|
||||
const load = async ({
|
||||
config,
|
||||
logger,
|
||||
watcher,
|
||||
parseData,
|
||||
store,
|
||||
generateDigest }: LoaderContext) => {
|
||||
|
||||
store.clear()
|
||||
if (expandUrls) {
|
||||
//await urlCache.expandUrls()
|
||||
}
|
||||
let items = await raw()
|
||||
for (const item of items) {
|
||||
const id = item._id
|
||||
const data = {
|
||||
slug: item._id,
|
||||
id,
|
||||
title: item.type,
|
||||
type: 'directory',
|
||||
components: [],
|
||||
item
|
||||
}
|
||||
|
||||
let storeItem = {
|
||||
digest: await generateDigest(data),
|
||||
filePath: id,
|
||||
id: `${item._id}`,
|
||||
data: data
|
||||
}
|
||||
|
||||
storeItem = await onStoreItem(storeItem)
|
||||
storeItem.data['config'] = JSON.stringify(storeItem.data, null, 2)
|
||||
store.set(storeItem)
|
||||
}
|
||||
}
|
||||
return {
|
||||
name: `astro:store:directory`,
|
||||
load
|
||||
};
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Taxonomy
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
export const group_by_type = (items: IUser[]) => {
|
||||
return items.reduce((acc: Record<string, IUser[]>, item: IUser) => {
|
||||
const type = item?.type || 'untyped'
|
||||
if (type === 'untyped') {
|
||||
return acc
|
||||
}
|
||||
if (!acc[type]) {
|
||||
acc[type] = []
|
||||
}
|
||||
acc[type].push(item)
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
38
src/model/directory/types.ts
Normal file
38
src/model/directory/types.ts
Normal file
@ -0,0 +1,38 @@
|
||||
export interface IUser {
|
||||
_modified: string
|
||||
_id: string
|
||||
subType: string
|
||||
moderation: string
|
||||
_deleted: boolean
|
||||
verified: boolean
|
||||
type: string
|
||||
location: ILocation
|
||||
_created: string
|
||||
geo: IGeo
|
||||
data: any
|
||||
detail: any
|
||||
brief?: string
|
||||
}
|
||||
|
||||
export interface ILocation {
|
||||
lat: number
|
||||
lng: number
|
||||
}
|
||||
|
||||
export interface IGeo {
|
||||
latitude: number
|
||||
lookupSource: string
|
||||
longitude: number
|
||||
localityLanguageRequested: string
|
||||
continent: string
|
||||
continentCode: string
|
||||
countryName: string
|
||||
countryCode: string
|
||||
principalSubdivision: string
|
||||
principalSubdivisionCode: string
|
||||
city: string
|
||||
locality: string
|
||||
postcode: string
|
||||
plusCode: string
|
||||
localityInfo: any
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
import { IUser } from '../directory/types.js'
|
||||
export const ITEM_TYPE = 'howto'
|
||||
|
||||
export interface ICoverImage {
|
||||
name: string
|
||||
downloadUrl: string
|
||||
@ -52,43 +54,6 @@ export interface ITag {
|
||||
_id: string
|
||||
}
|
||||
|
||||
export interface IUser {
|
||||
_modified: string
|
||||
_id: string
|
||||
subType: string
|
||||
moderation: string
|
||||
_deleted: boolean
|
||||
verified: boolean
|
||||
type: string
|
||||
location: ILocation
|
||||
_created: string
|
||||
geo: IGeo
|
||||
data: any
|
||||
detail: any
|
||||
}
|
||||
|
||||
export interface ILocation {
|
||||
lat: number
|
||||
lng: number
|
||||
}
|
||||
|
||||
export interface IGeo {
|
||||
latitude: number
|
||||
lookupSource: string
|
||||
longitude: number
|
||||
localityLanguageRequested: string
|
||||
continent: string
|
||||
continentCode: string
|
||||
countryName: string
|
||||
countryCode: string
|
||||
principalSubdivision: string
|
||||
principalSubdivisionCode: string
|
||||
city: string
|
||||
locality: string
|
||||
postcode: string
|
||||
plusCode: string
|
||||
localityInfo: any
|
||||
}
|
||||
|
||||
// Extended IHowto interface with version field
|
||||
export interface IHowto {
|
||||
|
||||
@ -7,7 +7,7 @@ import config from "config/config.json";
|
||||
import { getCollection } from "astro:content";
|
||||
import StoreEntries from "@/components/store/StoreEntries.astro";
|
||||
import CtaOne from "@/components/cta/CtaOne.astro";
|
||||
import { group_by_path } from "@/model/component/component.jsmponent.js";
|
||||
import { group_by_path } from "@/model/component/component.js";
|
||||
|
||||
const view = "store"
|
||||
const items = await getCollection(view)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
---
|
||||
import { IHowto } from "@/model/howto/howto.jswto.js";
|
||||
import { IHowto } from "@/model/howto/howto.js";
|
||||
import { getCollection } from "astro:content";
|
||||
import List from "@/components/howtos/List.astro";
|
||||
import { LANGUAGES_PROD as LANGUAGES } from "config/config.js";
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
---
|
||||
import { group_by_cat } from "@/model/howto/howto.jswto.js";
|
||||
import { group_by_cat } from "@/model/howto/howto.js";
|
||||
import { getCollection } from "astro:content";
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import Wrapper from "@/components/containers/Wrapper.astro";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user