Compare commits

..

29 Commits

Author SHA1 Message Date
lamp 881ee4568d Update 'README.md' 2023-02-04 21:44:02 -06:00
lamp 7ac32d6dff update urls 2023-02-05 03:35:33 +00:00
lamp 175a86b490 Merge branch 'proxy' of gitea.moe:lamp/random-miku-server into proxy 2023-02-05 03:29:25 +00:00
lamp 8f1c789c8e remove backup origin 2023-02-05 03:28:29 +00:00
lamp c4d55ec6c7 update url 2022-10-14 02:13:53 -05:00
lamp 3ab1623bed multiple random id 2022-07-31 17:23:18 -07:00
lamp 88a6e5e692 rip 39 commits
update fallback uri
2021-12-08 15:02:21 -06:00
lamp 99f05ea2e0 39 2021-12-04 22:29:27 -08:00
lamp 3ef1d4bdcb draw only id on thumb_mini 2021-11-25 18:16:10 -08:00
lamp 091197e7c7 hmm 2021-11-25 20:08:30 -06:00
lamp 63a9916a03 add option to draw url 2021-11-25 17:56:00 -08:00
lamp 0219cc7f83 Merge branch 'proxy' of gitea.moe:lamp/random-miku-server into proxy 2021-11-25 17:02:05 -08:00
lamp 47a05b243f relocate cache-control 2021-11-25 17:02:02 -08:00
lamp 93017002b9 Update 'README.md' 2021-11-25 18:55:28 -06:00
lamp f5e734a9c9 Update 'README.md' 2021-11-25 18:38:55 -06:00
lamp 42566713cf add r18 only 2021-11-25 16:32:42 -08:00
lamp 9d8d5c078e rewrite readme 2021-11-25 16:12:55 -08:00
lamp 77221513b5 refactor api 2021-11-25 15:36:32 -08:00
lamp 9ecdae240b proxy alternative server if pximg not OK
use status 203
add content-disposition
fix error handler i forgot to un-debug
2021-11-25 14:58:39 -08:00
lamp 8fac3fedcc Merge branch 'proxy' of gitea.moe:lamp/random-miku-server into proxy 2021-11-21 23:31:27 -08:00
lamp 04cbf250b0 add history page and rewrite readme 2021-11-21 23:30:36 -08:00
lamp ebb2071a12 move querystring to left of pixiv url; add auto 2021-11-21 16:12:37 -08:00
lamp c018ca12de fix table 2021-11-18 23:06:06 -06:00
lamp 66ab01429a /?noredirect for direct 2021-11-18 21:00:27 -08:00
lamp 9fee2a7852 use the url data that I downloaded already
and now including r18
2021-11-18 18:23:19 -08:00
lamp 4c8ee7b20a asdfuhsdfg 2021-10-20 17:31:03 -05:00
lamp a75c37731f preserve params in redir 2021-10-20 17:20:45 -05:00
lamp ebf6a8ffc4 Merge branch 'aaaaaaaaa' of gitea.moe:lamp/random-miku-server into aaaaaaaaa 2021-10-20 17:03:18 -05:00
lamp 6ed02a4740 log query & ref 2021-10-20 17:03:16 -05:00
8 changed files with 794 additions and 290 deletions
+1
View File
@@ -1,3 +1,4 @@
node_modules node_modules
.env .env
output.log output.log
logs
+16 -13
View File
@@ -1,19 +1,22 @@
Simply go to https://random-miku.owo39.me/ and it will redirect to `https://random-miku.owo39.me/https://www.pixiv.net/en/artworks/<randomid>` which will serve the raw image directly, and the url as such allows you to delete the left half to get to the source. A simple no-HTML random Hatsune Miku image server. Example: https://rms.owo69.me/
Your address and last requested URL are remembered so that when you click reload in your browser, you're redirected to a different one. You can add `?noredirect` query param to disable this. - Click reload to get a different one. Delete left half of URL to get to source.
- Include pornographic results: https://rms.owo69.me/?allow_r18([=only](https://rms.owo69.me/?allow_r18=only))
- Get different sizes (original, regular, small, or thumb_mini): https://rms.owo69.me/?size=thumb_mini
- Auto-refresh using HTTP Refresh header: https://rms.owo69.me/?auto=3
- kek: https://rms.owo69.me/?allow_r18&size=thumb_mini&auto=0
- See your history: https://rms.owo69.me/log
- Load image by id without redirect thing: https://rms.owo69.me/img/51586149
- Load random image directly without redirect thing: https://rms.owo69.me/img/random
- Draw Pixiv URL onto upper left corner of image: https://rms.owo69.me/img/random?drawsource&size=regular
You can add the `size` query parameter with one of `original`, `regular`, `small`, or `thumb_mini` (or whatever pixiv api has) to get a different size. The default is `original`. Here is an HTML site that makes use of it: https://lamp.tk/miku.html
For programatic purposes you can GET `/api` which responds just a random ID in plain text. ### Prerequisites
<hr> - Node.js
- GraphicsMagick for ?drawsource option
The original version served already-downloaded images from a MongoDB database, containing ~90,000 of the top 初音ミク illustrations on pixiv, but the system went down so now it only has the list of ids from said database and it proxies the images from pixiv. (might revert later when I get back and resurrect said system...) ### todo
<hr> - Option to limit range to get more higher-ranked illustrations
here's an embedded example.
unfortunately there's no way to get source like this (browsers don't expose redirected urls of embedded resources).
![random miku image](https://random-miku.owo39.me/)
-1
View File
File diff suppressed because one or more lines are too long
+109 -22
View File
@@ -1,29 +1,47 @@
var express = require("express"); var express = require("express");
var fetch = require("node-fetch"); var fetch = require("node-fetch");
var qs = require("qs");
var serveFavicon = require("serve-favicon");
var gm = require("gm");
var fs = require("fs");
var app = express(); var app = express();
app.set("trust proxy", "127.0.0.1"); app.set("trust proxy", "127.0.0.1");
app.listen(process.env.PORT || 39, process.env.ADDRESS);
app.use(serveFavicon("ミク.png"));
app.use((req,res,next)=>{req.rawQuery = req.url.includes('?') && req.url.substr(req.url.indexOf('?')+1);next();});
var idlist = require("./idlist.json"); var list = require("./list.json");
var list_r18_indices = [], list_safe_indices = [];
for (let i = 0, h = list.length; i < h; i++) if (list[i][2]) list_r18_indices.push(i); else list_safe_indices.push(i);
var ipa_lastload_map = {}; var ipa_lastload_map = {};
var page_cache = {};
let randomId = () => idlist[Math.floor(Math.random() * idlist.length)];
let redirectRandom = (req, res) => res.redirect(`/https://www.pixiv.net/en/artworks/${randomId()}`);
app.get('/', redirectRandom); function getRandomId(allow_r18) {
app.get("/favicon.ico", (req, res) => res.sendFile(process.cwd() + "/ミク.png")); if (allow_r18?.toLowerCase() == "only") {
app.get("/api", (req, res) => res.type("text/plain").send(randomId())); return list[list_r18_indices[Math.floor(Math.random() * list_r18_indices.length)]][0];
app.get("/https://www.pixiv.net/en/artworks/:id", async function (req, res, next) { } else if (allow_r18 != null) {
return list[Math.floor(Math.random() * list.length)][0];
} else {
return list[list_safe_indices[Math.floor(Math.random() * list_safe_indices.length)]][0];
}
};
function getRandomUrl(req) {
var s = req?.params.settings ? `/${req?.params.settings}` : '';
var d = getRandomId(req?.query.allow_r18);
return `${s}/https://www.pixiv.net/en/artworks/${d}`;
}
async function serveId(id, req, res, next) {
try { try {
if (ipa_lastload_map[req.ip] == req.url && req.query.noredirect == null) console.log(new Date().toLocaleString(), req.ip, req.url);
return redirectRandom(req, res);
else ipa_lastload_map[req.ip] = req.url;
console.log(new Date().toLocaleString(), req.ip, req.params.id, req.query); let pages = list.find(x => x[0] == id)?.[1];
let pages = page_cache[req.params.id];
if (!pages) { if (!pages) {
let data = await (await fetch(`https://pixiv.net/ajax/illust/${req.params.id}/pages`, { let data = await (await fetch(`https://pixiv.net/ajax/illust/${id}/pages`, {
headers: { "Host": "www.pixiv.net" } headers: { "Host": "www.pixiv.net" }
})).json(); })).json();
if (data.error) { if (data.error) {
@@ -31,21 +49,90 @@ app.get("/https://www.pixiv.net/en/artworks/:id", async function (req, res, next
return; return;
} }
pages = data.body; pages = data.body;
page_cache[req.params.id] = pages;
} }
var url = pages[0].urls[req.query.size ?? "original"]; var size = req.query.size || "original";
var url = pages[0].urls[size];
if (!url) return res.status(400).type("text").send(`size must be one of the following: ${Object.keys(pages[0].urls).join(', ')}`); if (!url) return res.status(400).type("text").send(`size must be one of the following: ${Object.keys(pages[0].urls).join(', ')}`);
res.type(url.split('.').pop()); var pxreq = await fetch(url, { headers: {"Referer": "https://www.pixiv.net"} });
//if (pxreq.status != 200 && size == "original") {
// res.header("X-Using-Backup", '1');
// pxreq = await fetch(`https://39.hmbp.gq/https://www.pixiv.net/en/artworks/${id}?noredirect`);
//}
(await fetch(url, { res.status(pxreq.status);
headers: {"Referer": "https://www.pixiv.net"} res.type(pxreq.headers.get("Content-Type"));
})).body.pipe(res); res.header("Content-Disposition", `filename=${url.split('/').pop()}`);
res.header("X-Pixiv-Id", id);
if (req.query.auto) res.header("Refresh", `${Number(req.query.auto)}; url=${getRandomUrl(req)}`);
if (req.query.drawsource != null && pxreq.headers.get("Content-Type").startsWith("image")) {
gm(pxreq.body).drawText(2, 12, size == "thumb_mini" ? id : `https://www.pixiv.net/en/artworks/${id}`).stream().pipe(res);
}
else pxreq.body.pipe(res);
fs.appendFileSync(`logs/${req.ip.replace(/[:\/]/g, '-')}.csv`, `${new Date().toISOString()},${id}\n`);
} catch(error) { } catch(error) {
next(error); next(error);
} }
}
// original HTML-less site for humans via web browser.
// - click refresh to get different image
// - delete left half of url to get to source
// - hacked querystring so it's before source url
app.get("(/:settings)?/https://www.pixiv.net/en/artworks/:id", function (req, res, next) {
if (req.rawQuery) {
let settings = req.params.settings || '';
if (settings) settings += "&";
settings += req.rawQuery;
return res.redirect(`/${settings}/https://www.pixiv.net/en/artworks/${req.params.id}`);
}
if (req.params.settings) req.query = qs.parse(req.params.settings);
if (ipa_lastload_map[req.ip] == req.url) return res.redirect(getRandomUrl(req));
else ipa_lastload_map[req.ip] = req.url;
serveId(req.params.id, req, res, next);
}); });
app.listen(8039); // initial randir
app.get('/', (req, res) => {
res.redirect((req.rawQuery ? `/${req.rawQuery}` : '') + getRandomUrl(req));
});
// direct random image without redirects
app.get("/img/random", (req, res, next) => {
serveId(getRandomId(req.query.allow_r18), req, res, next);
});
// simple serve id without redirects
app.get("/img/:id", (req, res, next) => {
res.header("Cache-Control", "max-age=99999999999999");
serveId(req.params.id, req, res, next);
});
// plaintext random id(s) for scripts
app.get("/randomid", function (req, res) {
var count = Number(req.query.count) || 1;
count = Math.min(count, 100);
var ids = [];
for (let i = 0; i < count; i++) ids.push(getRandomId(req.query.allow_r18));
ids = ids.join(',');
res.type("text/plain").send(ids);
});
// log site
app.get("/log", function (req, res) {
res.redirect(`/log/${req.ip}`);
});
var log_html = fs.readFileSync("log.html", "utf8");
app.get("/log/:ipa", function (req, res) {
res.send(log_html);
});
app.get("/log/:ipa/csv", function (req, res) {
res.sendFile(req.params.ipa.replace(/[:\/]/g, '-') + '.csv', {root: process.cwd() + "/logs/"});
});
+1
View File
File diff suppressed because one or more lines are too long
+34
View File
@@ -0,0 +1,34 @@
<title>history</title>
<style>
.i {
width: 128px;
height: 128px;
display: inline-block;
}
</style>
<h1>history for <span id="ipa">???</span></h1>
<p>in reverse-chronological order. hover for dates</p>
<script>
let ipa = location.pathname.split("/").pop().trim();
document.getElementById("ipa").innerText = ipa;
fetch(location.pathname + "/csv").then(r => r.text()).then(csv => {
csv = csv.trim();
csv = csv.split("\n").map(x => x.split(','));
var imgs = [];
for (let row of csv) {
let date = new Date(row[0]).toLocaleString();
let pixiv_id = row[1];
let pixiv_url = `https://www.pixiv.net/en/artworks/${pixiv_id}`;
let thumb_url = `/img/${pixiv_id}?size=thumb_mini`;
//imgs.unshift(`<a href="${pixiv_url}"><img src="${thumb_url}" alt="${pixiv_id}" title="${date}" /></a>`);
imgs.unshift(`<a href="${pixiv_url}"><div class="i" style="background-image: url(${thumb_url})" title="${date}">${pixiv_id}</div></a>`);
}
document.body.innerHTML += imgs.join('');
});
</script>
+630 -253
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -1,6 +1,8 @@
{ {
"dependencies": { "dependencies": {
"express": "^4.17.1", "express": "^4.17.1",
"node-fetch": "^2.6.5" "gm": "^1.23.1",
"node-fetch": "^2.6.5",
"serve-favicon": "^2.5.0"
} }
} }