Compare commits
No commits in common. "proxy" and "4dd589fdce1a6fe3bb8ee76032fe7771633de9a9" have entirely different histories.
proxy
...
4dd589fdce
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
.env
|
.env
|
||||||
output.log
|
|
||||||
logs
|
|
22
README.md
22
README.md
@ -1,22 +0,0 @@
|
|||||||
A simple no-HTML random Hatsune Miku image server. Example: https://rms.owo69.me/
|
|
||||||
|
|
||||||
- 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
|
|
||||||
|
|
||||||
Here is an HTML site that makes use of it: https://lamp.tk/miku.html
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
- Node.js
|
|
||||||
- GraphicsMagick for ?drawsource option
|
|
||||||
|
|
||||||
### todo
|
|
||||||
|
|
||||||
- Option to limit range to get more higher-ranked illustrations
|
|
1
idlist.json
Normal file
1
idlist.json
Normal file
File diff suppressed because one or more lines are too long
163
index.js
163
index.js
@ -1,138 +1,31 @@
|
|||||||
|
require("dotenv").config();
|
||||||
|
var {MongoClient, GridFSBucket} = require("mongodb");
|
||||||
var express = require("express");
|
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();
|
var app = express();
|
||||||
app.set("trust proxy", "127.0.0.1");
|
var dbclient = new MongoClient(process.env.DB_URI);
|
||||||
app.listen(process.env.PORT || 39, process.env.ADDRESS);
|
dbclient.connect().then(async () => {
|
||||||
app.use(serveFavicon("ミク.png"));
|
var db = dbclient.db("mikudb");
|
||||||
app.use((req,res,next)=>{req.rawQuery = req.url.includes('?') && req.url.substr(req.url.indexOf('?')+1);next();});
|
var collection = db.collection("illustration_collection");
|
||||||
|
var bucket = new GridFSBucket(db);
|
||||||
var list = require("./list.json");
|
var idlist = require("./idlist.json");
|
||||||
var list_r18_indices = [], list_safe_indices = [];
|
var ipa_lastload_map = {};
|
||||||
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);
|
let redirectRandom = (req, res) => {
|
||||||
var ipa_lastload_map = {};
|
let random_id = idlist[Math.floor(Math.random() * idlist.length)];
|
||||||
|
res.redirect(`/https://www.pixiv.net/en/artworks/${random_id}`);
|
||||||
|
};
|
||||||
function getRandomId(allow_r18) {
|
app.get('/', redirectRandom);
|
||||||
if (allow_r18?.toLowerCase() == "only") {
|
app.get("/https://www.pixiv.net/en/artworks/:id", async (req, res) => {
|
||||||
return list[list_r18_indices[Math.floor(Math.random() * list_r18_indices.length)]][0];
|
//if (req.headers["cache-control"] == "max-age=0") { // this indicates a reload in chrome
|
||||||
} else if (allow_r18 != null) {
|
// but chrome still sends it after redirect
|
||||||
return list[Math.floor(Math.random() * list.length)][0];
|
if (ipa_lastload_map[req.ip] == req.params.id) {
|
||||||
} else {
|
return redirectRandom(req, res);
|
||||||
return list[list_safe_indices[Math.floor(Math.random() * list_safe_indices.length)]][0];
|
} else ipa_lastload_map[req.ip] = req.params.id;
|
||||||
}
|
console.log(new Date().toLocaleString(), req.ip, req.params.id);
|
||||||
};
|
var asdf = await collection.findOne({_id: req.params.id}, {downloaded_images: 1});
|
||||||
|
if (!asdf) return res.sendStatus(404);
|
||||||
|
var gfsid = Object.values(asdf.downloaded_images)[0];
|
||||||
function getRandomUrl(req) {
|
bucket.openDownloadStream(gfsid).pipe(res);
|
||||||
var s = req?.params.settings ? `/${req?.params.settings}` : '';
|
});
|
||||||
var d = getRandomId(req?.query.allow_r18);
|
app.listen(8039);
|
||||||
return `${s}/https://www.pixiv.net/en/artworks/${d}`;
|
console.log("server ready");
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function serveId(id, req, res, next) {
|
|
||||||
try {
|
|
||||||
console.log(new Date().toLocaleString(), req.ip, req.url);
|
|
||||||
|
|
||||||
let pages = list.find(x => x[0] == id)?.[1];
|
|
||||||
if (!pages) {
|
|
||||||
let data = await (await fetch(`https://pixiv.net/ajax/illust/${id}/pages`, {
|
|
||||||
headers: { "Host": "www.pixiv.net" }
|
|
||||||
})).json();
|
|
||||||
if (data.error) {
|
|
||||||
res.status(502).type("text").send(data.message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pages = data.body;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
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) {
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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/"});
|
|
||||||
});
|
});
|
||||||
|
34
log.html
34
log.html
@ -1,34 +0,0 @@
|
|||||||
<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>
|
|
1220
package-lock.json
generated
1220
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"dotenv": "^10.0.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"gm": "^1.23.1",
|
"mongodb": "^4.1.2"
|
||||||
"node-fetch": "^2.6.5",
|
|
||||||
"serve-favicon": "^2.5.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user