Skip to content

Commit 1ea0613

Browse files
author
YieldRay
committed
new API, support node.js
1 parent 8e5fdd4 commit 1ea0613

6 files changed

Lines changed: 220 additions & 273 deletions

File tree

README.md

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,57 @@
11
# Random-Picture
22

3-
通过随机发送`url.csv`文件中给出的图床链接来实现一个随机图片 API
3+
通过随机发送`url.csv`文件中给出的图床链接来实现一个随机图片 API
4+
本仓库含 php(vercel), node.js(vercel), deno(deno.dev) 版本,API 一致
45

5-
## 演示地址:
6+
## 演示
67

7-
<https://miku.x10.mx/> _(无稳定性保证)_
8-
<https://random-picture.vercel.app/> _(部署到 vercel,访问此地址查看使用说明)_
8+
- <https://random-picture.vercel.app/> _(vercel 演示)_
9+
- <https://random-picture.vercel.app/api/> _(vercel, php 版本)_
10+
- <https://random-picture.vercel.app/random.jpg>
11+
- <https://random-picture.vercel.app/api/?json>
12+
- <https://random-picture.vercel.app/api/node/> _(vercel, nodejs 版本)_
13+
- <https://random-picture.vercel.app/api/node/?json>
14+
15+
- <https://rand.deno.dev/> (deno 版本)
16+
- <https://rand.deno.dev/?json>
17+
- <https://rand.deno.dev/?raw>
18+
- <https://rand.deno.dev/?id=3>
19+
- <https://rand.deno.dev/3.jpg>
20+
- <https://rand.deno.dev/random.png?raw>
921

1022
> 演示图片来自<https://www.pixiv.net/users/8236670>
1123
12-
## 部署到 Vercel
24+
## php 部署到 Vercel
1325

14-
fork 后,修改自己仓库的 `url.csv`,然后在 Vercel 平台上导入自己的项目
26+
fork 后,修改自己仓库的 `url.csv`,然后在 Vercel 平台上导入自己的项目
1527
你也可以直接修改<https://github.com/YieldRay/Random-Picture/blob/master/url.csv>来创建 fork
16-
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/git?s=https%3A%2F%2Fgithub.com%2FYieldRay%2FRandom-Picture)
28+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/git?s=https%3A%2F%2Fgithub.com%2FYieldRay%2FRandom-Picture)
29+
php 版本也可以直接上传到虚拟主机
30+
31+
## node.js 部署到 Vercel
32+
33+
![env.png](https://s2.loli.net/2022/03/25/ocECsXr2v1aKShG.png)
34+
部署到 vercel 后设置环境变量 `RECORD_URL` 为图片地址,或直接修改源码给定位置
35+
如果你已经 frok 了本项目,环境变量填入`https://raw.githubusercontents.com/YieldRay/Random-Picture/master/url.csv`即可
36+
**注意将用户名换为你自己的 Github 用户名**
37+
当然你也可以自行托管此文本,但是每次修改需要重新部署才能获取到更新后的地址
38+
如果出错请切换到 node.js >= 14
1739

18-
## 部署到虚拟主机
40+
nodejs 及 deno 版本每次部署时将图床地址读入内存,因此 API 不宜托管过多图床链接
1941

20-
上传至虚拟主机即可
42+
## deno 部署到 deno.dev
43+
44+
Deno 版本需要你能够托管一个文本文件,并获取这个文本文件的网址。下面托管在 Github
45+
46+
登录<https://dash.deno.com/>
47+
![deno.png](https://s2.loli.net/2022/03/20/tLITdUB4kWHe7VO.png)
48+
点击 `New Playground`
49+
![deno2.png](https://s2.loli.net/2022/03/20/h53uRYrnmQxwAz1.png)
50+
进入<https://github.com/YieldRay/Random-Picture/blob/master/test/deno.ts>
51+
或者复制<https://github.com/YieldRay/Random-Picture/raw/master/test/deno.ts>所有代码
52+
删除编辑器所有原有代码,再将复制的代码粘贴,最后点击 `✔ Saved & Deployed` 即可
2153

22-
## 伪静态
54+
## php 伪静态
2355

2456
伪静态是可选的。
2557
开启伪静态后支持以<https://example.net/:id.png>形式访问
@@ -34,16 +66,3 @@ location / {
3466
}
3567
}
3668
```
37-
38-
## Deno 版本
39-
40-
Deno 版本需要你能够托管一个文本文件,并获取这个文本文件的网址
41-
下面托管在 Github
42-
43-
登录<https://dash.deno.com/>
44-
![deno.png](https://s2.loli.net/2022/03/20/tLITdUB4kWHe7VO.png)
45-
点击 `New Playground`
46-
![deno2.png](https://s2.loli.net/2022/03/20/h53uRYrnmQxwAz1.png)
47-
进入<https://github.com/YieldRay/Random-Picture/blob/master/test/deno.ts>
48-
或者复制<https://github.com/YieldRay/Random-Picture/raw/master/test/deno.ts>所有代码
49-
删除编辑器所有原有代码,再将复制的代码粘贴,最后点击 `✔ Saved & Deployed` 即可

api/index.php

Lines changed: 35 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,54 @@
11
<?php
2-
const ALLOW_OUTPUT = false; // 修改以开启
3-
const ERROR_IMG = [
4-
404 => 'https://http.cat/404',
5-
503 => 'https://http.cat/503'
6-
];
72

3+
const ALLOW_RAW_OUTPUT = true;
4+
// 是否开启 ?raw 选项,可能会消耗服务器较多流量
5+
6+
function has_query($query)
7+
{
8+
return isset($_GET[$query]);
9+
}
810
if (file_exists('../url.csv')) {
9-
$url = file('../url.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
11+
$imgs_array = file('../url.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1012
} else {
11-
$url = file('http://' . $_SERVER['HTTP_HOST'] . '/url.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
13+
$imgs_array = file('http://' . $_SERVER['HTTP_HOST'] . '/url.csv', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
1214
}
13-
14-
if (empty($url[0])) {
15-
$code = 503;
16-
$target_url = ERROR_IMG[503];
15+
if (count($imgs_array) == 0) {
16+
$imgs_array = ['https://http.cat/503'];
1717
}
1818

1919

20-
$id = $_REQUEST['id'];
21-
$type = $_REQUEST['type'];
22-
$length = count($url);
23-
$final_id = array_rand($url);
24-
$is_idValid = false;
25-
26-
if (isset($id)) {
20+
$id = 0;
21+
if (is_numeric($_GET['id'])) {
2722
header('Cache-Control: public, max-age=86400');
28-
if (is_numeric($id)) {
29-
settype($id, 'integer');
30-
if ($is_idValid = is_int($id)) {
31-
$final_id = $id; // id是整数
32-
}
23+
global $id;
24+
$id = $_GET['id'];
25+
settype($id, 'int');
26+
$len = count($imgs_array);
27+
if ($id >= $len || $id < 0) {
28+
$id = array_rand($imgs_array);
3329
}
3430
} else {
3531
header('Cache-Control: no-cache');
32+
$id = array_rand($imgs_array);
3633
}
3734

3835

39-
40-
if (!$code && $is_idValid && $final_id > $length) {
41-
// 超过最大数
42-
$code = 404;
43-
$target_url = ERROR_IMG[404];
44-
} else {
45-
$code = 200;
46-
$target_url = $url[$final_id];
36+
if (has_query('json')) {
37+
header('Access-Control-Allow-Origin: *');
38+
header('Content-Type: application/json');
39+
echo json_encode(['id' => $id, 'url' => $imgs_array[$id]]);
40+
exit();
4741
}
4842

49-
/**
50-
* Variables for OUTPUT
51-
* $code
52-
* $target_url final url
53-
* $length amount of images
54-
*/
55-
header('Access-Control-Max-Age: 86400'); // 1day
56-
header('Access-Control-Allow-Origin: *');
5743

58-
switch ($type) {
59-
case 'length':
60-
echo $length;
61-
break;
62-
case 'json':
63-
$result = [
64-
'code' => $code,
65-
'url' => $target_url
66-
];
67-
header('Content-Type: text/json');
68-
echo json_encode($result);
69-
break;
70-
case 'JSON':
71-
$result = [
72-
'code' => $code,
73-
'url' => $target_url
74-
];
75-
$imageInfo = getimagesize($target_url);
76-
$imageSize = get_headers($target_url, 1)['Content-Length'];
77-
$result['width'] = $imageInfo[0];
78-
$result['height'] = $imageInfo[1];
79-
$result['mime'] = $imageInfo['mime'];
80-
$result['size'] = $imageSize;
81-
header('Content-Type: text/json');
82-
echo json_encode($result);
83-
break;
84-
case 'output':
85-
header($header);
86-
if (ALLOW_OUTPUT) {
87-
header('Content-Type: image/png');
88-
echo file_get_contents($target_url);
89-
} else {
90-
die('disabled');
91-
}
92-
break;
93-
default:
94-
header('Location: ' . $target_url);
44+
if (has_query('raw')) {
45+
if (!ALLOW_RAW_OUTPUT) {
46+
header('HTTP/1.1 403 Forbidden');
47+
exit();
48+
}
49+
header('Content-Type: image/png');
50+
echo file_get_contents($imgs_array[$id]);
51+
exit();
52+
} else {
53+
header('Location: ' . $imgs_array[$id]);
9554
}

test/node.mjs renamed to api/node.mjs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
11
import axios from 'axios';
22
// 填入环境变量,或者修改下面的地址,这个地址应该返回一个文本文件,每行一个图片地址
33
const recordURL = process.env.RECORD_URL || 'https://raw.githubusercontents.com/YieldRay/Random-Picture/master/url.csv';
4-
/**
5-
* 有?json则返回json,否则如有?raw直接输出图像否则302跳转
6-
* 优先获取123.jpg中的id,其次?id
7-
* example:
8-
* https://rand.deno.dev/?id=123
9-
* https://rand.deno.dev/3.jpg
10-
* https://rand.deno.dev/3.png?json
11-
* https://rand.deno.dev/3.jpeg?raw
12-
* https://rand.deno.dev/?raw
13-
*/
144

5+
/*
6+
* Program Start
7+
*/
158
const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
169
const imagesArray = ['https://http.cat/503'];
1710
(async () => {
1811
const text = await axios.get(recordURL).then(res => res.data);
19-
console.log(text);
20-
const imgs = text.split(/\r|\n|\r\n/);
12+
const imgs = text.split(/\r|\n|\r\n/).filter(item => item.length > 5);
2113
imagesArray.splice(0, 1, ...imgs);
2214
})();
2315

@@ -46,8 +38,12 @@ export default async function (req /*: http.IncomingMessage*/, res /*: http.Serv
4638
console.log(`send ${id} of ${imagesArray.length} with ${req.url}`);
4739
// 调整发送格式json/raw/302
4840
if (searchParams.has('json')) {
49-
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
50-
res.write(JSON.stringify({ url: remoteURL }));
41+
res.writeHead(200, {
42+
'Content-Type': 'application/json',
43+
'Access-Control-Allow-Origin': '*',
44+
'Cache-Control': 'no-cache',
45+
});
46+
res.write(JSON.stringify({ id, url: remoteURL }));
5147
res.end();
5248
} else if (searchParams.has('raw')) {
5349
console.log(`send raw ${remoteURL}`);
@@ -60,10 +56,16 @@ export default async function (req /*: http.IncomingMessage*/, res /*: http.Serv
6056
'User-Agent': 'PixivIOSApp/6.7.1 (iOS 10.3.1; iPhone8,1)',
6157
}, // 这个Header允许调用pixiv上面的图片
6258
});
59+
res.writeHead(200, {
60+
'Content-Type': response.headers['content-type'],
61+
'Access-Control-Allow-Origin': '*',
62+
'Cache-Control': 'no-cache',
63+
});
6364
response.data.pipe(res);
6465
} else {
6566
res.writeHead(302, {
6667
Location: remoteURL,
68+
'Cache-Control': 'no-cache',
6769
});
6870
res.end();
6971
}

0 commit comments

Comments
 (0)