Compare commits
19 Commits
8fac3fedcc
..
proxy
| Author | SHA1 | Date | |
|---|---|---|---|
| 881ee4568d | |||
| 7ac32d6dff | |||
| 175a86b490 | |||
| 8f1c789c8e | |||
| c4d55ec6c7 | |||
| 3ab1623bed | |||
| 88a6e5e692 | |||
| 99f05ea2e0 | |||
| 3ef1d4bdcb | |||
| 091197e7c7 | |||
| 63a9916a03 | |||
| 0219cc7f83 | |||
| 47a05b243f | |||
| 93017002b9 | |||
| f5e734a9c9 | |||
| 42566713cf | |||
| 9d8d5c078e | |||
| 77221513b5 | |||
| 9ecdae240b |
@@ -1,25 +1,22 @@
|
||||
A simple, random Hatsune Miku image server using no HTML*: https://random-miku.owo39.me/
|
||||
A simple no-HTML random Hatsune Miku image server. Example: https://rms.owo69.me/
|
||||
|
||||
The `/` URL will 302-redirect you** to a random URL like this: https://random-miku.owo39.me/https://www.pixiv.net/en/artworks/92388757, which then proxies the first original-size image from that post. The url is such that you can select and delete the left half to easily get to the Pixiv post.
|
||||
- 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
|
||||
|
||||
Refresh the window and you'll get another random image***. To do this the server remembers the last URL your IP address requested.
|
||||
Here is an HTML site that makes use of it: https://lamp.tk/miku.html
|
||||
|
||||
There are also some other parameters you can change.
|
||||
### Prerequisites
|
||||
|
||||
To include pornographic results: https://random-miku.owo39.me/?allow_r18
|
||||
- Node.js
|
||||
- GraphicsMagick for ?drawsource option
|
||||
|
||||
Auto-refresh the page every 3 seconds using HTTP refresh header: https://random-miku.owo39.me/?auto=3 Note that this way the browser won't log them to history, but you can see your IPA's history at https://random-miku.owo39.me/log (*the only thing HTML is used for).
|
||||
### todo
|
||||
|
||||
Get different sizes (regular, small, or thumb_mini; default is original): https://random-miku.owo39.me/?size=small
|
||||
|
||||
**Use noredirect parameter to get served a random image directly: https://random-miku.owo39.me/?noredirect This enables it to be embedded in Discord, but makes it harder to find the source.
|
||||
|
||||
***Use noredirect parameter to disable: https://random-miku.owo39.me/noredirect/https://www.pixiv.net/en/artworks/72389090 That's right, querystring is relocated to the left of pixiv url.
|
||||
|
||||
Combining opts: https://random-miku.owo39.me/?auto=0&size=small&allow_r18 
|
||||
|
||||
To get just a random ID: https://random-miku.owo39.me/api. Useful for embedding into a website with JavaScript. There is also an `X-Pixiv-Id` header.
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Data set consists of the top 99,495 popular 初音ミク Pixiv illustrations (10,242 of which are r18), scraped in September 2021. Originally served data from a mongo db, but was changed to proxy from Pixiv when lost access to db and because it is faster and more flexible. The old mongodb version is available at http://hmbp.gq:39/, which you can use if you encounter a 404 with the primary one (because some pixiv posts are disappearing apparently).
|
||||
- Option to limit range to get more higher-ranked illustrations
|
||||
|
||||
@@ -2,28 +2,35 @@ var express = require("express");
|
||||
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();
|
||||
app.set("trust proxy", "127.0.0.1");
|
||||
app.listen(process.env.PORT || 39);
|
||||
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 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 = {};
|
||||
|
||||
|
||||
function getRandomId(allow_r18) {
|
||||
var i = list[Math.floor(Math.random() * list.length)];
|
||||
if (i[2] && !allow_r18) return getRandomId();
|
||||
return i[0];
|
||||
if (allow_r18?.toLowerCase() == "only") {
|
||||
return list[list_r18_indices[Math.floor(Math.random() * list_r18_indices.length)]][0];
|
||||
} 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!=null);
|
||||
var d = getRandomId(req?.query.allow_r18);
|
||||
return `${s}/https://www.pixiv.net/en/artworks/${d}`;
|
||||
}
|
||||
|
||||
@@ -44,24 +51,37 @@ async function serveId(id, req, res, next) {
|
||||
pages = data.body;
|
||||
}
|
||||
|
||||
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(', ')}`);
|
||||
|
||||
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`);
|
||||
//}
|
||||
|
||||
res.status(pxreq.status);
|
||||
res.type(pxreq.headers.get("Content-Type"));
|
||||
res.header("Content-Disposition", `filename=${url.split('/').pop()}`);
|
||||
res.header("X-Pixiv-Id", id);
|
||||
res.header("Cache-Control", "max-age=99999999999999");
|
||||
if (req.query.auto) res.header("Refresh", `${Number(req.query.auto)}; url=${getRandomUrl(req)}`);
|
||||
pxreq.body.pipe(res);
|
||||
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) {
|
||||
console.log(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 || '';
|
||||
@@ -72,27 +92,40 @@ app.get("(/:settings)?/https://www.pixiv.net/en/artworks/:id", function (req, re
|
||||
|
||||
if (req.params.settings) req.query = qs.parse(req.params.settings);
|
||||
|
||||
if (ipa_lastload_map[req.ip] == req.url && req.query.noredirect == null)
|
||||
return res.redirect(getRandomUrl(req));
|
||||
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);
|
||||
});
|
||||
|
||||
// initial randir
|
||||
app.get('/', (req, res) => {
|
||||
res.redirect((req.rawQuery ? `/${req.rawQuery}` : '') + getRandomUrl(req));
|
||||
});
|
||||
|
||||
app.get('/', (req, res, next) => {
|
||||
if (req.query.noredirect != null) {
|
||||
serveId(getRandomId(req.query.allow_r18!=null), req, res, next)
|
||||
} else {
|
||||
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);
|
||||
});
|
||||
|
||||
|
||||
app.get("/api", function (req, res) {
|
||||
res.type("text/plain").send(getRandomId(req.query.allow_r18!=null));
|
||||
});
|
||||
|
||||
// log site
|
||||
app.get("/log", function (req, res) {
|
||||
res.redirect(`/log/${req.ip}`);
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>view history for ip address <span id="ipa">???</span></h1>
|
||||
<h1>history for <span id="ipa">???</span></h1>
|
||||
<p>in reverse-chronological order. hover for dates</p>
|
||||
|
||||
<script>
|
||||
@@ -22,8 +22,8 @@
|
||||
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 = "/size=thumb_mini/" + pixiv_url;
|
||||
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>`);
|
||||
}
|
||||
|
||||
Generated
+585
-258
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"gm": "^1.23.1",
|
||||
"node-fetch": "^2.6.5",
|
||||
"serve-favicon": "^2.5.0"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user