initial scrapbook implementation
This commit is contained in:
@@ -2,7 +2,7 @@ var minisrv_service_file = true;
|
||||
|
||||
var files = session_data.pagestore.listScrapbook();
|
||||
var dir = session_data.pagestore.scrapbookDir()
|
||||
var start = 12;
|
||||
var start = 0;
|
||||
|
||||
headers = `200 OK
|
||||
Connection: Keep-Alive
|
||||
@@ -158,14 +158,21 @@ Choose one of your saved images to view it full size.
|
||||
<table cellspacing=24 cellpadding=1 width=372 background="/ROMCache/light_blue_tile.gif">
|
||||
<tr>
|
||||
`
|
||||
for (let i = 0; i < 12; i++) {
|
||||
if (files.length === 0) {
|
||||
data += `<td align=center valign=middle colspan=4>
|
||||
<font color=AEBFD1 size=+1><blackface> Your scrapbook is empty. </blackface></font>
|
||||
</td>`;
|
||||
} else {
|
||||
for (let i = start; i < Math.min(files.length, start + 12); i++) {
|
||||
data += `
|
||||
<td align=center valign=middle>
|
||||
<A href=
|
||||
"${dir + files.i}" transition=light>
|
||||
<img src="${dir + files.i}" width=90>
|
||||
"wtv-tricks:/view-scrapbook-image?id=${files[i]}" transition=light>
|
||||
<img src="wtv-tricks:/view-scrapbook-image?id=${files[i]}&width=90" width=90>
|
||||
</A>
|
||||
</td>`
|
||||
</td>
|
||||
${i % 4 === 1 ? '</tr><tr>' : ''}`
|
||||
}
|
||||
}
|
||||
data += `
|
||||
</table>
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
var minisrv_service_file = true;
|
||||
var request_is_async = true;
|
||||
|
||||
|
||||
function handleError(reason) {
|
||||
var errpage = wtvshared.doErrorPage(400, reason);
|
||||
sendToClient(socket, errpage[0], errpage[1]);
|
||||
}
|
||||
|
||||
if (!request_headers.query.url) {
|
||||
handleError('No URL provided');
|
||||
} else {
|
||||
var url = request_headers.query.url;
|
||||
function isValidImageType(contentType, url) {
|
||||
// Check content-type header or file extension
|
||||
if (contentType) {
|
||||
return contentType === 'image/jpeg' || contentType == 'image/jpg' || contentType === 'image/gif';
|
||||
}
|
||||
return url.endsWith('.jpg') || url.endsWith('.jpeg') || url.endsWith('.gif');
|
||||
}
|
||||
|
||||
try {
|
||||
const parsedUrl = new URL(url);
|
||||
const protocol = parsedUrl.protocol === 'https:' ? https : http;
|
||||
|
||||
protocol.get(url, (res) => {
|
||||
if (res.statusCode !== 200) {
|
||||
handleError('URL does not exist or returned status ' + res.statusCode);
|
||||
res.resume();
|
||||
return;
|
||||
}
|
||||
|
||||
const contentType = res.headers['content-type'];
|
||||
const contentLength = parseInt(res.headers['content-length'], 10);
|
||||
|
||||
if (!isValidImageType(contentType, url)) {
|
||||
handleError('URL is not a JPEG or GIF image');
|
||||
res.resume();
|
||||
return;
|
||||
}
|
||||
|
||||
if (contentLength && contentLength > 1024 * 1024) {
|
||||
handleError('Image is larger than 1MB');
|
||||
res.resume();
|
||||
return;
|
||||
}
|
||||
|
||||
let data = [];
|
||||
let totalLength = 0;
|
||||
res.on('data', (chunk) => {
|
||||
totalLength += chunk.length;
|
||||
if (totalLength > 1024 * 1024) {
|
||||
handleError('Image is larger than 1MB');
|
||||
res.destroy();
|
||||
return;
|
||||
}
|
||||
data.push(chunk);
|
||||
});
|
||||
|
||||
res.on('end', () => {
|
||||
if (totalLength > 1024 * 1024) return;
|
||||
data = Buffer.concat(data);
|
||||
var id = session_data.pagestore.getFreeScrapbookID();
|
||||
var result = session_data.pagestore.addToScrapbook(id, contentType, data);
|
||||
if (result) {
|
||||
var successScrapbook = new clientShowAlert({
|
||||
'image': minisrv_config.config.service_logo,
|
||||
'message': "The image has been added to your scrapbook. Would you like to view your scrapbook now?",
|
||||
'buttonlabel1': "No",
|
||||
'buttonaction1': "client:donothing",
|
||||
'buttonlabel2': "Yes",
|
||||
'buttonaction2': "wtv-author:/scrapbook",
|
||||
}).getURL();
|
||||
sendToClient(socket, {'Status': 302, 'Location': successScrapbook, 'wtv-visit': successScrapbook}, '');
|
||||
} else {
|
||||
handleError('Failed to add image to scrapbook');
|
||||
}
|
||||
});
|
||||
|
||||
res.on('error', (err) => {
|
||||
handleError('Error downloading image');
|
||||
});
|
||||
}).on('error', (err) => {
|
||||
handleError('Failed to fetch URL');
|
||||
});
|
||||
} catch (e) {
|
||||
handleError(e.message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
var minisrv_service_file = true;
|
||||
var request_is_async = true;
|
||||
|
||||
function handleError(reason) {
|
||||
var errpage = wtvshared.doErrorPage(400, reason);
|
||||
sendToClient(socket, errpage[0], errpage[1]);
|
||||
}
|
||||
|
||||
async function handleImage() {
|
||||
if (!request_headers.query.id) {
|
||||
handleError('No image ID specified');
|
||||
} else {
|
||||
data = session_data.pagestore.getScrapbookImage(request_headers.query.id);
|
||||
if (!data) {
|
||||
handleError('Image not found');
|
||||
} else {
|
||||
try {
|
||||
if (request_headers.query.width) {
|
||||
// Scale the image to the specified width without losing aspect ratio, without using wtvshared
|
||||
const width = parseInt(request_headers.query.width, 10);
|
||||
data = await sharp(data).resize({ width, withoutEnlargement: true }).toBuffer();
|
||||
}
|
||||
headers = `200 OK
|
||||
Content-Type: ${session_data.pagestore.getScrapbookImageType(request_headers.query.id)}
|
||||
Content-Length: ${data.length}`
|
||||
sendToClient(socket, headers, data);
|
||||
} catch (error) {
|
||||
handleError('Error processing image');
|
||||
console.error('Image processing error:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleImage();
|
||||
Reference in New Issue
Block a user