Skip to content

Commit

Permalink
Merge pull request #2592 from mneunomne/#2591
Browse files Browse the repository at this point in the history
vault capture updates
  • Loading branch information
dhowe authored Jan 4, 2025
2 parents 4e762fa + 3b0f30f commit 0dce702
Show file tree
Hide file tree
Showing 8 changed files with 4,213 additions and 6 deletions.
1,460 changes: 1,460 additions & 0 deletions docs/capture/package-lock.json

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions docs/capture/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"dependencies": {
"cors": "^2.8.5",
"express": "^4.21.2",
"node-fetch": "^3.3.2",
"path": "^0.12.7",
"sharp": "^0.33.5"
},
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"type": "module"
}
134 changes: 134 additions & 0 deletions docs/capture/public/render-ads-capture-base64.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON to SVG Converter</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}

.container {
text-align: center;
}

#output {
margin-top: 20px;
border: 1px solid #ccc;
padding: 10px;
overflow: auto;
max-width: 100%;
max-height: 80vh;
}

svg {
width: 100%;
height: auto;
}

#downloadButton {
margin-top: 10px;
display: none;
}
</style>
</head>

<body>
<div class="container">
<h1>JSON to SVG Converter</h1>
<p>Upload a JSON file to generate an SVG:</p>
<input type="file" id="fileInput" accept=".json" />
<a id="downloadButton" download="generated.svg">Download SVG</a>
<!-- image loaded counter -->
<p id="imageCounter">
Images loaded: <span id="imageCounterValue">0</span> / <span id="imageCounterTotal">0</span>
</p>
<div id="output"></div>
</div>

<script>
const fileInput = document.getElementById('fileInput');
const output = document.getElementById('output');
const downloadButton = document.getElementById('downloadButton');

fileInput.addEventListener('change', async (event) => {
const file = event.target.files[0];

if (file) {
try {
const jsonText = await file.text();
const jsonData = JSON.parse(jsonText);
const svgContent = await generateSVG(jsonData);
output.innerHTML = svgContent;

// Make the SVG downloadable
const blob = new Blob([svgContent], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
downloadButton.href = url;
downloadButton.style.display = 'inline-block';
} catch (error) {
console.error('Error processing file:', error);
output.innerHTML = `<p style="color: red;">Invalid JSON file.</p>`;
downloadButton.style.display = 'none';
}
}
});

async function fetchBase64Image(url) {
const proxyUrl = `/proxy?url=${encodeURIComponent(url)}`;
const response = await fetch(proxyUrl);
if (!response.ok) {
throw new Error('Failed to fetch image via proxy');
}
return await response.text(); // The proxy already returns the Base64 string
}

// if its image/webp, convert to image/jpg
async function convertContentType(url) {
const convertUrl = `/convert?base64=${encodeURIComponent(url)}`;
const response = await fetch(convertUrl);
if (!response.ok) {
throw new Error('Failed to convert image', url);
}
return await response.text(); // The proxy already returns the Base64 string
}


async function generateSVG(json) {
if (!json.ads || !Array.isArray(json.ads)) {
throw new Error('Invalid JSON structure. Expected an "ads" array.');
}

const svgHeader = `<svg xmlns="http://www.w3.org/2000/svg" width="10000" height="10000" viewBox="-5000 -5000 10000 10000">\n`;
const svgFooter = `</svg>`;

document.getElementById('imageCounterTotal').textContent = json.ads.length;


// Fetch and encode all image URLs to Base64
const images = await Promise.all(
json.ads.map(async (ad) => {
let src = ad.src
if (src.startsWith('http')) {
src = await fetchBase64Image(src);
}
// if its image/webp, convert to image/jpg
if (src.startsWith('data:image/webp')) {
src = await convertContentType(src);
}
console.log("Parsed image", ad)
document.getElementById('imageCounterValue').textContent = parseInt(document.getElementById('imageCounterValue').textContent) + 1;

return `<image href="${src}" x="${ad.pos.x}" y="${ad.pos.y}" height="${ad.height}" width="${ad.width}" />`;
})
);

return `${svgHeader}${images.join('\n')}\n${svgFooter}`;
}
</script>
</body>

</html>
87 changes: 87 additions & 0 deletions docs/capture/public/render-ads-capture.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON to SVG Converter</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.container {
text-align: center;
}
#output {
margin-top: 20px;
border: 1px solid #ccc;
padding: 10px;
overflow: auto;
max-width: 100%;
max-height: 80vh;
}
svg {
width: 100%;
height: auto;
}
#downloadButton {
margin-top: 10px;
display: none;
}
</style>
</head>
<body>
<div class="container">
<h1>JSON to SVG Converter</h1>
<p>Upload a JSON file to generate an SVG:</p>
<input type="file" id="fileInput" accept=".json" />
<div id="output"></div>
<a id="downloadButton" download="generated.svg">Download SVG</a>
</div>

<script>
const fileInput = document.getElementById('fileInput');
const output = document.getElementById('output');
const downloadButton = document.getElementById('downloadButton');

fileInput.addEventListener('change', async (event) => {
const file = event.target.files[0];

if (file) {
try {
const jsonText = await file.text();
const jsonData = JSON.parse(jsonText);
const svgContent = generateSVG(jsonData);
output.innerHTML = svgContent;

// Make the SVG downloadable
const blob = new Blob([svgContent], { type: 'image/svg+xml' });
const url = URL.createObjectURL(blob);
downloadButton.href = url;
downloadButton.style.display = 'inline-block';
} catch (error) {
console.error('Error processing file:', error);
output.innerHTML = `<p style="color: red;">Invalid JSON file.</p>`;
downloadButton.style.display = 'none';
}
}
});

function generateSVG(json) {
if (!json.ads || !Array.isArray(json.ads)) {
throw new Error('Invalid JSON structure. Expected an "ads" array.');
}

const svgHeader = `<svg xmlns="http://www.w3.org/2000/svg" width="10000" height="10000" viewBox="-5000 -5000 10000 10000">\n`;
const svgFooter = `</svg>`;

const images = json.ads.map(ad => {
return `<image href="${encodeURI(ad.src)}" x="${ad.pos.x}" y="${ad.pos.y}" height="${ad.height}" width="${ad.width}" />`;
}).join('\n');

return `${svgHeader}${images}\n${svgFooter}`;
}
</script>
</body>
</html>
92 changes: 92 additions & 0 deletions docs/capture/server.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0dce702

Please sign in to comment.