diff --git a/zefie_wtvp_minisrv/includes/ServiceDeps/wtv-search/results.njk b/zefie_wtvp_minisrv/includes/ServiceDeps/wtv-search/results.njk new file mode 100644 index 00000000..36ccff41 --- /dev/null +++ b/zefie_wtvp_minisrv/includes/ServiceDeps/wtv-search/results.njk @@ -0,0 +1,36 @@ + + + Web Search Proxy + + +
+ + + + +
+

Search Results

+ {% if request_headers.query.categories == 'general' %} + {% for result in content %} +

{{ result.title }}
Direct - Proxy
{{ result.content }}


+ {% endfor %} + {% else %} + {% for result in content %} + + {% endfor %} + {% endif %} + + + \ No newline at end of file diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/imgproxy.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/imgproxy.js new file mode 100644 index 00000000..d2c42392 --- /dev/null +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/imgproxy.js @@ -0,0 +1,54 @@ +minisrv_service_file = true; +request_is_async = true; + + + +async function handleRequest(request_headers) { + const imageUrl = request_headers.query.url; + if (!imageUrl) { + var errpage = wtvshared.doErrorPage(400, "Missing url parameter"); + sendToClient(socket, errpage[0], errpage[1]); + return; + } + + try { + const urlObj = new URL(imageUrl); + const lib = urlObj.protocol === 'https:' ? https : http; + const fetch = (lib, options) => new Promise((resolve, reject) => { + const req = lib.request(imageUrl, options, (res) => { + let data = []; + res.on('data', chunk => data.push(chunk)); + res.on('end', () => { + res.buffer = async () => Buffer.concat(data); + res.ok = res.statusCode >= 200 && res.statusCode < 300; + resolve(res); + }); + }); + req.on('error', reject); + req.end(); + }); + const imgRes = await fetch(lib, { method: 'GET', headers: { 'User-Agent': 'Mozilla/4.0 WebTV/2.6 (compatible; MSIE 4.0)' } }); + if (!imgRes.ok) { + var errpage = wtvshared.doErrorPage(502, "Failed to fetch image"); + sendToClient(socket, errpage[0], errpage[1]); + return; + } + const imgBuffer = await imgRes.buffer(); + + const resized = await sharp(imgBuffer) + .resize(50, 50, { fit: 'inside' }) + .toBuffer(); + + headers = `200 OK +Content-Type: image/png`; + data = resized; + sendToClient(socket, headers, data); + } catch (err) { + var errpage = wtvshared.doErrorPage(500, "Error processing image: " + err.message); + sendToClient(socket, errpage[0], errpage[1]); + } +} + +handleRequest(request_headers); + +// Example usage: handleRequest(request_headers, response); \ No newline at end of file diff --git a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/search.js b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/search.js index 8213252d..7d3bbe64 100644 --- a/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/search.js +++ b/zefie_wtvp_minisrv/includes/ServiceVault/wtv-search/search.js @@ -9,8 +9,7 @@ searchUrl += 'search'; if (!request_headers.query.q) { const headers = `200 OK\nContent-Type: text/html`; - const data = ` - + const data = ` Web Search Proxy @@ -40,6 +39,7 @@ if (!request_headers.query.q) { } } params.append('format', 'json'); + params.append('limit', '10'); const urlObj = new URL(searchUrl); const lib = urlObj.protocol === 'https:' ? https : http; var post_data = params.toString(); @@ -63,7 +63,7 @@ if (!request_headers.query.q) { fetch(lib, options, post_data) .then(response => response.text()) .then(text => { process(text); }) - .catch(err => { finishPage(`Error fetching page: ${err.message}`); }); + .catch(err => { finishPage([`Error fetching page: ${err.message}`]); }); } function fetch(lib, options, post_data) { @@ -86,12 +86,20 @@ function process(data) { const results = JSON.parse(data).results || []; let content = ''; if (results.length === 0) { - content = '

No results found

'; + content = ['

No results found

']; } else { - content = '

Search Results

'; + content = []; results.forEach(result => { result.title = result.title.replace(/\/g, '>'); - content += `

${result.title}
Direct - Proxy
${result.content || `` || ''}


`; + if (result.description) { + result.description = result.description.replace(/\/g, '>'); + } + result.encodedurl = encodeURIComponent(result.url); + if (result.thumbnail_src) { + result.thumbnail_src = "wtv-search:/imgproxy?url=" + encodeURIComponent(result.thumbnail_src); + } + + content.push(result); }); } finishPage(content); @@ -101,23 +109,7 @@ function process(data) { function finishPage(content) { const headers = `200 OK\nContent-Type: text/html`; - const data = ` - - - Web Search Proxy - - -
- - - - -
- ${content} - -`; + nunjucks.configure({ autoescape: true }); + const data = nunjucks.render(wtvshared.getServiceDep('wtv-search/results.njk', true), { content, request_headers }); sendToClient(socket, headers, data); } \ No newline at end of file