mirror of
https://github.com/System-End/site.git
synced 2026-04-19 22:05:11 +00:00
Merge branch 'board-render-api-endpoint' into onboard_gallery
This commit is contained in:
commit
3fc1ff93b7
5 changed files with 116 additions and 97 deletions
|
|
@ -288,6 +288,13 @@ const nextConfig = {
|
|||
},
|
||||
{ key: 'Access-Control-Allow-Headers', value: 'Content-Type' }
|
||||
]
|
||||
},
|
||||
{
|
||||
source: '/api/board/svg/(.+)',
|
||||
headers: [{
|
||||
key: 'content-type',
|
||||
value: 'image/svg+xml'
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
17
pages/api/board/svg/[board_url]/bottom.js
Normal file
17
pages/api/board/svg/[board_url]/bottom.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// test me with: curl http://localhost:3000/api/board/svg/https%3A%2F%2Fgithub.com%2Fhackclub%2FOnBoard%2Fraw%2Fmain%2Fprojects%2F2_Switch_Keyboard%2Fgerber.zip/bottom
|
||||
|
||||
import { gerberToSvg } from "."
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { board_url } = req.query
|
||||
if (!board_url) {
|
||||
return res.status(404).json({ status: 404, error: 'Must provide file' })
|
||||
}
|
||||
// ensure valid file url is included
|
||||
const parsed_url = new URL(decodeURI(board_url))
|
||||
if (!parsed_url) {
|
||||
return res.status(404).json({ status: 404, error: 'Invalid file' })
|
||||
}
|
||||
const svg = await gerberToSvg(parsed_url)
|
||||
return res.status(200).send(svg.bottom)
|
||||
}
|
||||
75
pages/api/board/svg/[board_url]/index.js
Normal file
75
pages/api/board/svg/[board_url]/index.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import JSZip from "jszip";
|
||||
import { read, plot, renderLayers, renderBoard, stringifySvg } from '@tracespace/core'
|
||||
import fs from 'fs'
|
||||
|
||||
export const gerberToSvg = async (gerberURL) => {
|
||||
const data = await fetch(gerberURL).then((res) => res.arrayBuffer());
|
||||
const files = [];
|
||||
const zip = new JSZip();
|
||||
|
||||
const zippedData = await new Promise((resolve, _reject) => {
|
||||
zip.loadAsync(data).then(resolve)
|
||||
})
|
||||
|
||||
const allowedExtensions = [
|
||||
'gbr', // gerber
|
||||
'drl', // drillfile
|
||||
'gko', // gerber board outline
|
||||
'gbl', // gerber bottom layer
|
||||
'gbp', // gerber bottom paste
|
||||
'gbs', // gerber bottom solder mask
|
||||
'gbo', // gerber bottom silk
|
||||
'gtl', // gerber top layer
|
||||
'gto', // gerber top silk
|
||||
'gts' // gerber top soldermask
|
||||
]
|
||||
const unzipJobs = Object.entries(zippedData.files).map(async ([filename, file]) => {
|
||||
const extension = filename.split('.').pop().toLowerCase();
|
||||
if (allowedExtensions.includes(extension)) {
|
||||
const filePath = `/tmp/${filename}`
|
||||
await new Promise((resolve, _reject) => {
|
||||
file.async('uint8array').then(function (fileData) {
|
||||
fs.writeFileSync(filePath, fileData)
|
||||
files.push(filePath)
|
||||
resolve()
|
||||
}
|
||||
)})
|
||||
}
|
||||
})
|
||||
|
||||
await Promise.all(unzipJobs)
|
||||
|
||||
let readResult;
|
||||
try {
|
||||
readResult = await read(files)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return {}
|
||||
}
|
||||
const plotResult = plot(readResult)
|
||||
const renderLayersResult = renderLayers(plotResult)
|
||||
const renderBoardResult = renderBoard(renderLayersResult)
|
||||
return {
|
||||
top: stringifySvg(renderBoardResult.top),
|
||||
bottom: stringifySvg(renderBoardResult.bottom),
|
||||
// all: stringifySvg(renderLayersResult)
|
||||
}
|
||||
}
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { file, format } = req.query
|
||||
if (!file) {
|
||||
return res.status(400).json({ status: 400, error: 'Must provide file' })
|
||||
}
|
||||
// ensure valid file url is included
|
||||
const url = new URL(decodeURI(file))
|
||||
const svg = await GenerateSVG(url)
|
||||
if (format == 'top') {
|
||||
res.contentType('image/svg');
|
||||
return res.status(200).send(svg.top)
|
||||
}
|
||||
if (format == 'json') return res.status(200).json(svg)
|
||||
|
||||
return res.status(200).json(svg)
|
||||
}
|
||||
// test me with: curl http://localhost:3000/api/board/svg/https%3A%2F%2Fgithub.com%2Fhackclub%2FOnBoard%2Fraw%2Fmain%2Fprojects%2F2_Switch_Keyboard%2Fgerber.zip
|
||||
17
pages/api/board/svg/[board_url]/top.js
Normal file
17
pages/api/board/svg/[board_url]/top.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// test me with: curl http://localhost:3000/api/board/svg/https%3A%2F%2Fgithub.com%2Fhackclub%2FOnBoard%2Fraw%2Fmain%2Fprojects%2F2_Switch_Keyboard%2Fgerber.zip/top
|
||||
|
||||
import { gerberToSvg } from "."
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { board_url } = req.query
|
||||
if (!board_url) {
|
||||
return res.status(404).json({ status: 404, error: 'Must provide file' })
|
||||
}
|
||||
// ensure valid file url is included
|
||||
const parsed_url = new URL(decodeURI(board_url))
|
||||
if (!parsed_url) {
|
||||
return res.status(404).json({ status: 404, error: 'Invalid file' })
|
||||
}
|
||||
const svg = await gerberToSvg(parsed_url)
|
||||
return res.status(200).send(svg.top)
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
import JSZip from "jszip";
|
||||
import {read, plot, renderLayers, renderBoard, stringifySvg} from '@tracespace/core'
|
||||
import fs from 'fs'
|
||||
|
||||
async function asyncLoadZip(data) {
|
||||
return await new Promise((resolve, reject) => {
|
||||
JSZip.loadAsync(data).then(function (zip) {
|
||||
resolve(zip)
|
||||
}, function (e) {
|
||||
reject(e)
|
||||
});
|
||||
})
|
||||
}
|
||||
async function asyncUnzip (file) {
|
||||
const zip = new JSZip();
|
||||
return await new Promise((resolve, reject) => {
|
||||
zip.file(file).async("uint8array").then(function (data) {
|
||||
resolve(data)
|
||||
}, function (e) {
|
||||
reject(e)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
export const GenerateSVG = async (zipFile) => {
|
||||
//const zip = new JSZip();
|
||||
const data = await fetch(zipFile)
|
||||
.then((res) => res.arrayBuffer());
|
||||
let files = [];
|
||||
if(!fs.existsSync('gerber'))
|
||||
fs.mkdirSync('gerber');
|
||||
try {
|
||||
const zip = await asyncLoadZip(data)
|
||||
await new Promise(async (resolve, reject) => {
|
||||
for(let filename of Object.keys(zip.files)) {
|
||||
await (zip.files[filename].async('uint8array').then(function (fileData) {
|
||||
filename = filename.replace(/\//g, '_');
|
||||
const extension = filename.split('.').pop().toLowerCase();
|
||||
if (extension === 'gbr' || // gerber
|
||||
extension === 'drl' || // drillfile
|
||||
extension === 'gko' || // gerber board outline
|
||||
extension === 'gbl' || // gerber bottom layer
|
||||
extension === 'gbp' || // gerber bottom paste
|
||||
extension === 'gbs' || // gerber bottom solder mask
|
||||
extension === 'gbo' || // gerber bottom silk
|
||||
extension === 'gtl' || // gerber top layer
|
||||
extension === 'gto' || // gerber top silk
|
||||
extension === 'gts' // gerber top soldermask
|
||||
) {
|
||||
//console.log('gerber/' + filename)
|
||||
files.push('gerber/' + filename);
|
||||
if(!fs.existsSync('gerber/' + filename))
|
||||
fs.writeFileSync('gerber/' + filename, fileData);
|
||||
}
|
||||
}));
|
||||
//console.log(zip.files[filename])
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
if(fs.existsSync('gerber'))
|
||||
fs.rmdirSync('gerber', { recursive: true });
|
||||
return {}
|
||||
}
|
||||
|
||||
//console.log(files)
|
||||
|
||||
let readResult;
|
||||
try {
|
||||
readResult = await read(files)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
if(fs.existsSync('gerber'))
|
||||
fs.rmdirSync('gerber', { recursive: true });
|
||||
return {}
|
||||
}
|
||||
const plotResult = plot(readResult)
|
||||
const renderLayersResult = renderLayers(plotResult)
|
||||
const renderBoardResult = renderBoard(renderLayersResult)
|
||||
|
||||
if(fs.existsSync('gerber'))
|
||||
fs.rmdirSync('gerber', { recursive: true });
|
||||
return {
|
||||
top: stringifySvg(renderBoardResult.top),
|
||||
bottom: stringifySvg(renderBoardResult.bottom),
|
||||
}
|
||||
}
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const { file } = req.query
|
||||
if (!file) {
|
||||
return res.status(400).json({ status: 400, error: 'Must provide file' })
|
||||
}
|
||||
const svg = await GenerateSVG(file)
|
||||
return res.status(200).json(svg)
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue