├── .gitignore
├── storage
├── app
│ └── .gitignore
├── images
│ └── .gitignore
└── logs
│ └── .gitignore
├── .test
├── pic.jpg
└── test_image_hosting.php
├── app
├── Controllers
│ ├── Controller.php
│ ├── IndexController.php
│ └── ApiController.php
├── autoload.php
├── Factory.php
├── Jobs
│ ├── Job.php
│ ├── ClearLog.php
│ └── Refresh.php
├── ImageHosting
│ ├── ImageHosting.php
│ ├── Local.php
│ ├── Catbox.php
│ ├── Chkaja.php
│ ├── Tietuku.php
│ ├── FiftyEight.php
│ ├── Smms.php
│ └── Riyugo.php
├── Libs
│ ├── Response.php
│ ├── Log.php
│ ├── Str.php
│ ├── Lock.php
│ ├── Env.php
│ ├── Request.php
│ ├── Config.php
│ ├── Curl.php
│ ├── Storage.php
│ └── Pixiv.php
├── Views
│ ├── loading.php
│ └── index.php
└── App.php
├── .docker
├── crontab
├── Dockerfile
├── start.sh
├── nginx-site.conf
└── config.php
├── index.php
├── demo.html
├── doc
├── advance-usage.md
├── deploy.md
├── docker.md
├── advance-usage.en.md
├── docker.en.md
├── deploy.en.md
├── log.md
└── log.en.md
├── LICENSE
├── .github
└── workflows
│ ├── develop.yml
│ └── docker-image.yml
├── README.md
├── README.en.md
└── config.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/storage/app/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/storage/images/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/storage/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/.test/pic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mokeyjay/Pixiv-daily-ranking-widget/HEAD/.test/pic.jpg
--------------------------------------------------------------------------------
/app/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 | "
15 | LABEL Version="2023.11.20"
16 | LABEL Description="Pixiv 每日排行榜小挂件"
17 |
18 | CMD cron && \
19 | chmod +x /root/start.sh && \
20 | /root/start.sh
21 |
--------------------------------------------------------------------------------
/app/Factory.php:
--------------------------------------------------------------------------------
1 | errorMsg;
35 | }
36 | }
--------------------------------------------------------------------------------
/app/Jobs/Job.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Pixiv 每日排行榜小挂件
8 |
9 |
10 |
11 |
12 |
13 |
14 | 鼠标移动到挂件上可控制图片滚动、查看作品信息;点击图片可访问作品详情页
15 |
16 | Mouse hover the image to control the image scrolling, view the work information; click the image to visit the work details page
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/ImageHosting/ImageHosting.php:
--------------------------------------------------------------------------------
1 | /etc/nginx/sites-enabled/default
4 |
5 | cd /var/www/html
6 | # 将环境变量保存起来,免得 crontab 读不到
7 | env=("URL" "BACKGROUND_COLOR" "LIMIT" "SERVICE" "LOG_LEVEL" "PROXY" "CLEAR_OVERDUE" "COMPRESS" "IMAGE_HOSTING" "IMAGE_HOSTING_EXTEND_TIETUKU_TOKEN" "IMAGE_HOSTING_EXTEND_SMMS_TOKEN" "IMAGE_HOSTING_EXTEND_RIYUGO_URL" "IMAGE_HOSTING_EXTEND_RIYUGO_UPLOAD_PATH" "IMAGE_HOSTING_EXTEND_RIYUGO_UNIQUE_ID" "IMAGE_HOSTING_EXTEND_RIYUGO_TOKEN" "DISABLE_WEB_JOB" "HEADER_SCRIPT" "RANKING_TYPE")
8 | file=".env"
9 | > $file
10 | for var in "${env[@]}"
11 | do
12 | # 部分环境变量值含有空格、换行,得用双引号包起来,不然 source 时会报错
13 | value="${!var}"
14 | value="${value//\"/\\\"}"
15 | echo "$var=\"$value\"" >> $file
16 | done
17 |
18 | chown -R www-data:www-data /var/www/html
19 |
20 | php-fpm -D
21 | nginx -g 'daemon off;'
--------------------------------------------------------------------------------
/.docker/nginx-site.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | listen [::]:80;
4 | server_name _;
5 | root /var/www/html;
6 | index index.php;
7 |
8 | error_page 500 502 503 504 /50x.html;
9 | location = /50x.html {
10 | root /usr/share/nginx/html;
11 | }
12 |
13 | location ~ /\. {
14 | deny all;
15 | }
16 |
17 | location / {
18 | try_files $uri $uri/ /index.php?$query_string;
19 | }
20 |
21 | location ~ \.php$ {
22 | fastcgi_pass 127.0.0.1:9000;
23 | fastcgi_index index.php;
24 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
25 | fastcgi_param PATH_INFO $fastcgi_path_info;
26 | fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
27 | include fastcgi_params;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/Controllers/IndexController.php:
--------------------------------------------------------------------------------
1 | 'fileupload',
20 | 'userhash' => '',
21 | 'fileToUpload' => Curl::getCurlFile($path),
22 | ];
23 | $result = Curl::post('https://catbox.moe/user/api.php', $data);
24 |
25 | Log::write('[猫盒图床]上传:' . json_encode($data));
26 | Log::write('[猫盒图床]返回:' . $result);
27 |
28 | if (stripos($result, 'files.catbox.moe') !== false) {
29 | return $result;
30 | }
31 |
32 | Log::write('[猫盒图床]上传失败', 'ERROR');
33 | return false;
34 | }
35 | }
--------------------------------------------------------------------------------
/doc/advance-usage.md:
--------------------------------------------------------------------------------
1 | # 高级用法
2 | ```html
3 |
4 | ```
5 |
6 | ## 自定义宽度或高度
7 | 此挂件支持自适应宽高,你只需要修改代码中的 `width` 或者 `height` 的值即可
8 | 例如你想要宽 300、高 500,则需要将上述代码中的
9 | `width:240px; height:380px;` 修改为 `width:300px; height:500px;`
10 |
11 | > 因为大多数 pixiv 画作的预览图都是 240*380 左右的分辨率,因此一般并不需要修改宽高度
12 |
13 | ## 自定义背景色
14 | 默认背景色为透明,如需修改背景色,可以添加 url 参数 `color`
15 | 例如你想要红色背景,则将上述代码中的
16 | `/pixiv` 修改为 `/pixiv?color=f00`
17 |
18 | 其中 `f00` 即表示红色,支持 3 或 6 位 [十六进制颜色值](https://baike.baidu.com/item/%E5%8D%81%E5%85%AD%E8%BF%9B%E5%88%B6%E9%A2%9C%E8%89%B2%E7%A0%81/10894232) ,无需 # 号
19 |
20 | ## 自定义数量
21 | 默认只显示排行前 50 的作品。你可以通过 url 参数 `limit` 来修改
22 | > limit 最大值为 500,因为排行榜最多就只有 500 名
23 |
24 | 例如你只想要前 10,则将上述代码中的
25 | `/pixiv` 修改为 `/pixiv?limit=10`
26 |
27 | > ⚠️ 该值无法超过 `config.php` 中的 limit 配置
28 |
29 | > 🌟 如需同时使用多个 url 参数,你可以用 `&` 来连接它们。例如 `?color=f00&limit=10`
--------------------------------------------------------------------------------
/app/Libs/Log.php:
--------------------------------------------------------------------------------
1 | {$message}\n";
28 | if (IS_CLI) {
29 | echo $content . "\n";
30 | }
31 |
32 | $file = STORAGE_PATH . 'logs/' . date('Ymd') . (IS_CLI ? '-cli' : '') . '.log';
33 |
34 | return file_put_contents($file, $content, FILE_APPEND) !== false;
35 | }
36 | }
--------------------------------------------------------------------------------
/.test/test_image_hosting.php:
--------------------------------------------------------------------------------
1 | upload(TEST_PATH . 'pic.jpg')) {
26 | var_dump($className . '成功: ' . $url);
27 | } else {
28 | var_dump($className . '失败: ' . $url);
29 | }
30 | }
--------------------------------------------------------------------------------
/app/Libs/Str.php:
--------------------------------------------------------------------------------
1 | 0 && is_numeric($opt['n'])) ? intval($opt['n']) : 7;
19 |
20 | $time = strtotime("-{$n} days");
21 | $path = STORAGE_PATH . 'logs/';
22 | $deleteNum = 0;
23 |
24 | if ($dh = opendir($path)) {
25 | while (($file = readdir($dh)) !== false) {
26 | if (in_array($file, ['.', '..', '.gitignore'])) {
27 | continue;
28 | }
29 |
30 | $file = $path . $file;
31 | if (filemtime($file) < $time) {
32 | $deleteNum++;
33 | Storage::deleteFile($file);
34 | }
35 | }
36 | }
37 |
38 | Log::write("共计清除日志文件 {$deleteNum} 个");
39 |
40 | return true;
41 | }
42 | }
--------------------------------------------------------------------------------
/app/ImageHosting/Chkaja.php:
--------------------------------------------------------------------------------
1 | Curl::getCurlFile($path),
20 | 'viewpassword' => '',
21 | 'viewtips' => '',
22 | 'Timelimit' => '',
23 | 'Countlimit' => '',
24 | 'submit' => 'submit',
25 | 'MAX_FILE_SIZE' => '8388608',
26 | ];
27 | $result = Curl::post('https://img.chkaja.com/ajaximg.php', $data);
28 |
29 | Log::write('[愛上傳图床]上传:' . json_encode($data));
30 | Log::write('[愛上傳图床]返回:' . $result);
31 |
32 | $url = preg_match('|https://img.chkaja.com/(.*?)\.jpg|', $result, $matches) ? $matches[0] : false;
33 |
34 | if (!empty($url)) {
35 | return $url;
36 | }
37 |
38 | Log::write('[愛上傳图床]上传失败', 'ERROR');
39 | return false;
40 | }
41 | }
--------------------------------------------------------------------------------
/app/Controllers/ApiController.php:
--------------------------------------------------------------------------------
1 | setAutoCorsHeader();
17 | }
18 |
19 | /**
20 | * 自动设置跨域头
21 | * @return void
22 | */
23 | private function setAutoCorsHeader()
24 | {
25 | if (!isset($_SERVER['HTTP_ORIGIN']) && !isset($_SERVER['HTTP_REFERER'])) {
26 | return;
27 | }
28 |
29 | $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : $_SERVER['HTTP_REFERER'];
30 |
31 | header('Access-Control-Allow-Origin: ' . $origin);
32 | }
33 |
34 | /**
35 | * 源数据(未使用图床)
36 | * @return void
37 | */
38 | public function sourceJson()
39 | {
40 | echo json_encode(Storage::getJson('source') ?: []);
41 | }
42 |
43 | /**
44 | * 处理后的数据(已使用图床)
45 | * @return void
46 | */
47 | public function pixivJson()
48 | {
49 | echo json_encode(Storage::getJson('pixiv') ?: []);
50 | }
51 | }
--------------------------------------------------------------------------------
/app/ImageHosting/Tietuku.php:
--------------------------------------------------------------------------------
1 | Config::$image_hosting_extend['tietuku']['token'],
27 | 'file' => Curl::getCurlFile($path),
28 | ];
29 | $result = Curl::post('http://up.imgapi.com/', $data);
30 |
31 | Log::write('[Tietuku图床]上传:' . json_encode($data));
32 | Log::write('[Tietuku图床]返回:' . $result);
33 | $result = json_decode($result, true);
34 |
35 | if (isset($result['code'])) {
36 | Log::write('[Tietuku图床]上传失败:' . $result['info'], 'ERROR');
37 | return false;
38 | }
39 | return $result['linkurl'];
40 | }
41 | }
--------------------------------------------------------------------------------
/app/ImageHosting/FiftyEight.php:
--------------------------------------------------------------------------------
1 | '0*0',
20 | 'Pic-Encoding' => 'base64',
21 | 'Pic-Path' => '/nowater/webim/big/',
22 | 'Pic-Data' => base64_encode(file_get_contents($path)),
23 | ];
24 | $result = Curl::post('https://upload.58cdn.com.cn/json', json_encode($data), [
25 | CURLOPT_HTTPHEADER => [
26 | 'Origin: https://ai.58.com',
27 | 'Referer: https://ai.58.com/pc/'
28 | ],
29 | ]);
30 |
31 | $data['Pic-Data'] = '(数据长度:' . strlen($data['Pic-Data']) . ')';
32 | Log::write('[58图床]上传:' . json_encode($data));
33 | Log::write('[58图床]返回:' . $result);
34 |
35 | if (empty($result) || stripos($result, 'n_v2') !== 0) {
36 | Log::write('[58图床]上传失败', 'ERROR');
37 | return false;
38 | }
39 |
40 | return 'https://pic3.58cdn.com.cn/nowater/webim/big/' . $result;
41 | }
42 | }
--------------------------------------------------------------------------------
/doc/deploy.md:
--------------------------------------------------------------------------------
1 | # 部署
2 | ## Docker
3 | ```shell
4 | docker run -d -p 80:80 --name=pixiv -e URL=http://localhost/ ghcr.io/mokeyjay/pixiv-daily-ranking-widget
5 | ```
6 | 详见 [Docker](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/docker.md)
7 | ## 本地部署
8 | - [下载源代码](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/releases/latest)
9 | - 解压缩到 web 目录下
10 | - 使用专业编辑器(例如 `Visual Studio Code`、`Sublime` 等,禁止使用记事本)编辑 `config.php`,根据实际情况修改相应配置
11 | > 由于 Pixiv 已经被墙,如果你想要将此项目部署在中国大陆境内,可能需要配置 `proxy` 配置项
12 |
13 | - 给予 `storage` 目录写入权限
14 |
15 | ## 主动触发更新
16 | 默认情况下,此挂件每次被访问都会检查排行榜数据是否已过期,并在需要时额外发起一次请求来触发自动更新。通常不需要干预
17 |
18 | 但在有些情况下(例如 PHP 超时时间设的不够长、服务器性能较低),这种通过 web 方式触发的更新还没执行完就被中断,不仅导致更新始终无法完成,还会一直浪费性能及带宽
19 | 如果你遇到同样的问题,可以关闭 web 方式触发更新(将 `config.php` 中的 `disable_web_job` 设为 `false`)
20 | 然后通过 cli 方式主动触发,例如 `php index.php -j=refresh`
21 |
22 | > 你可以使用 `crontab` 之类的工具来定时自动触发更新。例如 `*/30 * * * * php /path/to/pixiv/index.php -j=refresh`
23 | > 表示每 30 分钟执行一次更新。程序会自动判断是否真的需要更新,不会浪费性能
24 |
25 | ## 清除日志
26 | 打开日志(`config.php` 中的 `log_level` 设为 `['DEBUG', 'ERROR']`)可以将此挂件的运行信息记录下来
27 | 向我反馈问题时,通常也建议将日志和配置文件打包发送给我(请勿将配置文件发布到公开场合)
28 | 如果你准备长期打开日志又担心它占用过多的硬盘,可以通过 `php index.php -j=clear-log` 来删除 7 天前的日志
29 | > 添加参数 `-n=3` 即删除 3 天前的日志
30 |
31 | > 你可以使用 `crontab` 之类的工具来定时自动删除。例如 `30 1 * * * php /path/to/pixiv/index.php -j=clear-log`
--------------------------------------------------------------------------------
/doc/docker.md:
--------------------------------------------------------------------------------
1 | # Docker
2 | > 如需启用多个容器,请通过挂载目录的方式在它们之间共享 `/var/www/html/storage` 目录,避免每个容器各自更新排行榜数据,造成性能浪费
3 |
4 | ## 部署
5 | ### 命令行
6 | ```shell
7 | docker run -d -p 80:80 --name=pixiv -e URL=http://localhost/ ghcr.io/mokeyjay/pixiv-daily-ranking-widget
8 | ```
9 |
10 | ### Docker compose
11 | ```yaml
12 | version: '3.1'
13 |
14 | services:
15 | pixiv:
16 | image: ghcr.io/mokeyjay/pixiv-daily-ranking-widget
17 | container_name: pixiv
18 | restart: always
19 | environment:
20 | URL: http://localhost/
21 | ports:
22 | - "80:80"
23 | ```
24 |
25 | > `URL` 是指向这个容器的访问地址,支持路径,必须以 `/` 结尾
26 |
27 | ## 配置
28 | 通过 [环境变量](https://docs.docker.com/compose/compose-file/#environment) 进行配置。所有配置项见 [config.docker.php](../.docker/config.php)
29 |
30 | > 默认只启用了 `local` 图床(即图片存储在容器本地)。使用它时,必须配置 `URL` 项
31 | >
32 | > 与本地部署不同,Docker 镜像内置了自动更新排行榜数据的定时任务,因此 `DISABLE_WEB_JOB` 默认为 `true`,即不通过 web 访问触发更新
33 |
34 | > 日志路径:`/var/www/html/storage/logs`
35 |
36 | ## 任务
37 | ### 主动触发更新
38 | > 通常情况下,排行榜数据会每半小时检测一次更新,无需主动触发
39 | > 首次部署时,可以手动触发一次更新,或等待半小时自动更新
40 |
41 | ```shell
42 | docker exec pixiv php index.php -j=refresh
43 | ```
44 | 详见 [主动触发更新](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/deploy.md)
45 |
46 | ### 清除日志
47 | ```shell
48 | docker exec pixiv php index.php -j=clear-log
49 | ```
50 | 详见 [清除日志](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/deploy.md)
--------------------------------------------------------------------------------
/app/Libs/Lock.php:
--------------------------------------------------------------------------------
1 | time() || $lock == 0);
25 | }
26 |
27 | /**
28 | * 创建锁
29 | * @param string $name
30 | * @param int $expire 自动过期时间(秒)
31 | * @return bool 创建失败或锁已存在时返回 false
32 | */
33 | public static function create($name, $expire = 0)
34 | {
35 | if (self::check($name) === false) {
36 | return Storage::save("app/{$name}.lock", ($expire ? (time() + $expire) : 0));
37 | }
38 | return false;
39 | }
40 |
41 | /**
42 | * 移除锁
43 | * @param string $name
44 | * @return bool
45 | */
46 | public static function remove($name)
47 | {
48 | return Storage::remove("app/{$name}.lock");
49 | }
50 |
51 | /**
52 | * 强制创建锁
53 | * @param string $name 锁名称
54 | * @param int $expire 自动过期时间(秒)
55 | * @return bool
56 | */
57 | public static function forceCreate($name, $expire)
58 | {
59 | return Storage::save("app/{$name}.lock", ($expire ? (time() + $expire) : 0));
60 | }
61 | }
--------------------------------------------------------------------------------
/app/ImageHosting/Smms.php:
--------------------------------------------------------------------------------
1 | Curl::getCurlFile($path)];
26 | $header = [
27 | CURLOPT_HTTPHEADER => [
28 | 'Authorization' => Config::$image_hosting_extend['smms']['token'],
29 | ],
30 | ];
31 | $result = Curl::post('https://sm.ms/api/v2/upload', $data, $header);
32 |
33 | Log::write('[Smms图床]上传:' . json_encode($data));
34 | Log::write('[Smms图床]返回:' . $result);
35 | $result = json_decode($result, true);
36 |
37 | if (isset($result['code'])) {
38 | if ($result['code'] == 'success') {
39 | return $result['data']['url'];
40 | } elseif ($result['code'] == 'image_repeated') {
41 | return $result['images'];
42 | }
43 | }
44 |
45 | Log::write('[Smms图床]上传失败:' . $result['msg'], 'ERROR');
46 | return false;
47 | }
48 | }
--------------------------------------------------------------------------------
/doc/advance-usage.en.md:
--------------------------------------------------------------------------------
1 | # Advanced usage
2 | ```html
3 |
4 | ```
5 |
6 | ## Custom width or height
7 | This widget supports adaptive width and height. You only need to change the value of `width` or `height` in the code
8 | For example, if you want a width of 300px and height of 500px , then change the code above from
9 | `width:240px; height:380px;`
10 |
11 | to `width:300px; height:500px;`
12 |
13 | > Since most pixiv images are previewed at a resolution of about 240*380, there is usually no need to modify the width and height.
14 |
15 | ## Custom background color
16 | The default background color is transparent. If you want to change the background color, you can add a parameter `color` to the URL.
17 | For example, if you want a red background, then change the above code from
18 | `/pixiv`
19 |
20 | to `/pixiv?color=f00`
21 |
22 | `f00` means red, supports 3- or 6-digit [HTML Color Codes](https://htmlcolorcodes.com/), **without the # sign**
23 |
24 | ## Customize the returned pic number
25 | By default, only the top 50 entries are displayed. You can change this with the URL parameter `limit`.
26 | > the limit has a maximum of 500 since the maximum order of Pixiv Ranking is 500.
27 |
28 | For example, if you only want the first 10, then change the above code from
29 | `/pixiv` to `/pixiv?limit=10`
30 |
31 | > ⚠️ This value cannot exceed the limit configuration in `config.php`
32 |
33 | > 🌟 To use more than one URL argument at a time, you can connect them with `&`. Such as `?color=f00&limit=10`
--------------------------------------------------------------------------------
/.github/workflows/develop.yml:
--------------------------------------------------------------------------------
1 | name: 推送开发用的 docker 镜像
2 | on:
3 | push:
4 | branches:
5 | - 'develop'
6 |
7 | env:
8 | REGISTRY: ghcr.io
9 | IMAGE_NAME: ${{ github.repository }}
10 |
11 | jobs:
12 | push_to_registry:
13 | name: 构建并推送
14 | runs-on: ubuntu-latest
15 |
16 | permissions:
17 | contents: read
18 | packages: write
19 |
20 | steps:
21 | # https://github.com/actions/checkout
22 | - name: 拉取代码
23 | uses: actions/checkout@v4
24 | with:
25 | ref: develop
26 |
27 | # https://github.com/docker/login-action
28 | - name: 登录到 ghcr
29 | uses: docker/login-action@v3
30 | with:
31 | registry: ${{ env.REGISTRY }}
32 | username: ${{ github.actor }}
33 | password: ${{ secrets.GITHUB_TOKEN }}
34 |
35 | # https://github.com/docker/metadata-action
36 | - name: 提取事件元数据
37 | id: meta
38 | uses: docker/metadata-action@v5
39 | with:
40 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
41 |
42 | # https://github.com/docker/setup-buildx-action
43 | - name: 使用 buildx 作为构建器
44 | uses: docker/setup-buildx-action@v3
45 |
46 | # https://github.com/docker/build-push-action
47 | - name: 构建并推送
48 | uses: docker/build-push-action@v5
49 | with:
50 | context: .
51 | file: .docker/Dockerfile
52 | push: true
53 | tags: ${{ steps.meta.outputs.tags }}
54 | platforms: linux/amd64,linux/arm64
55 | cache-from: type=gha
56 | cache-to: type=gha,mode=max
--------------------------------------------------------------------------------
/.docker/config.php:
--------------------------------------------------------------------------------
1 | Env::getStr('URL'),
16 |
17 | 'background_color' => Env::getStr('BACKGROUND_COLOR', 'transparent'),
18 |
19 | 'limit' => Env::getStr('LIMIT', 50),
20 |
21 | 'service' => Env::getBool('SERVICE', true),
22 |
23 | 'log_level' => Env::getArray('LOG_LEVEL', ['DEBUG', 'ERROR']),
24 |
25 | 'proxy' => Env::getStr('PROXY'),
26 |
27 | 'clear_overdue' => Env::getBool('CLEAR_OVERDUE', true),
28 |
29 | 'compress' => Env::getBool('COMPRESS', true),
30 |
31 | 'image_hosting' => Env::getArray('IMAGE_HOSTING', ['local']),
32 |
33 | 'image_hosting_extend' => [
34 | 'tietuku' => [
35 | 'token' => Env::getStr('IMAGE_HOSTING_EXTEND_TIETUKU_TOKEN'),
36 | ],
37 | 'smms' => [
38 | 'token' => Env::getStr('IMAGE_HOSTING_EXTEND_SMMS_TOKEN'),
39 | ],
40 | 'riyugo' => [
41 | 'url' => Env::getStr('IMAGE_HOSTING_EXTEND_RIYUGO_URL'),
42 | 'upload_path' => Env::getStr('IMAGE_HOSTING_EXTEND_RIYUGO_UPLOAD_PATH'),
43 | 'unique_id' => Env::getStr('IMAGE_HOSTING_EXTEND_RIYUGO_UNIQUE_ID'),
44 | 'token' => Env::getStr('IMAGE_HOSTING_EXTEND_RIYUGO_TOKEN'),
45 | ],
46 | ],
47 |
48 | 'disable_web_job' => Env::getBool('DISABLE_WEB_JOB', true),
49 |
50 | 'header_script' => Env::getStr('HEADER_SCRIPT', ''),
51 |
52 | 'ranking_type' => Env::getStr('RANKING_TYPE', ''),
53 | ];
--------------------------------------------------------------------------------
/app/Libs/Env.php:
--------------------------------------------------------------------------------
1 | pathinfo($path, PATHINFO_BASENAME),
30 | 'uuid' => 'o_1g' . Str::random(27),
31 | 'uploadPath' => $config['upload_path'],
32 | 'mode' => 1,
33 | 'file' => Curl::getCurlFile($path),
34 | ];
35 | $result = Curl::post(rtrim($config['url']) . '/file.php', $data, [
36 | CURLOPT_HTTPHEADER => [
37 | 'accept: */*',
38 | 'referer: ' . $config['url'],
39 | 'origin: ' . $config['url'],
40 | ],
41 | CURLOPT_COOKIE => sprintf('frontendlogin=y; name-mode=_isRenameMode; filemanager%s=%s', $config['unique_id'], $config['token']),
42 | ]);
43 |
44 | Log::write('[薄荷图床]上传:' . json_encode($data));
45 | Log::write('[薄荷图床]返回:' . $result);
46 |
47 | $json = json_decode($result, true);
48 | if (isset($json['result']) && $json['result'] == 'success' && !empty($json['url'])) {
49 | return $json['url'];
50 | }
51 |
52 | Log::write('[薄荷图床]上传失败', 'ERROR');
53 | return false;
54 | }
55 | }
--------------------------------------------------------------------------------
/app/Libs/Request.php:
--------------------------------------------------------------------------------
1 | 1,
65 | ]);
66 | }
67 | }
--------------------------------------------------------------------------------
/.github/workflows/docker-image.yml:
--------------------------------------------------------------------------------
1 | # action 的名称
2 | name: 推送 Docker 镜像
3 | # 触发 action 的事件
4 | on:
5 | push:
6 | # master 分支有推送时触发
7 | branches:
8 | - 'master'
9 | # tag 新建时触发
10 | tags:
11 | - '*'
12 |
13 | env:
14 | REGISTRY: ghcr.io
15 | IMAGE_NAME: ${{ github.repository }}
16 |
17 | jobs:
18 | push_to_registry:
19 | name: 构建并推送
20 | # 基于指定平台构建。有 win、ubuntu、mac 可选
21 | # 消耗的分钟倍数:linux 1x、win 2x、mac 10x
22 | runs-on: ubuntu-latest
23 |
24 | permissions:
25 | contents: read
26 | packages: write
27 |
28 | steps:
29 | # https://github.com/actions/checkout
30 | - name: 拉取代码
31 | uses: actions/checkout@v4
32 |
33 | # https://github.com/docker/login-action
34 | - name: 登录到 ghcr
35 | uses: docker/login-action@v3
36 | with:
37 | registry: ${{ env.REGISTRY }}
38 | username: ${{ github.actor }}
39 | password: ${{ secrets.GITHUB_TOKEN }}
40 |
41 | # 从触发此次 action 的事件中提取源数据(tag、label 什么的)
42 | # https://github.com/docker/metadata-action
43 | - name: 提取事件元数据
44 | id: meta
45 | uses: docker/metadata-action@v5
46 | with:
47 | # 提取出来的源数据用于这个镜像
48 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
49 |
50 | # 使用 buildx 作为构建器,以支持多平台构建之类的能力
51 | # https://github.com/docker/setup-buildx-action
52 | - name: 使用 buildx 作为构建器
53 | uses: docker/setup-buildx-action@v3
54 |
55 | # https://github.com/docker/build-push-action
56 | - name: 构建并推送
57 | uses: docker/build-push-action@v5
58 | with:
59 | context: .
60 | file: .docker/Dockerfile
61 | push: true
62 | tags: ${{ steps.meta.outputs.tags }}
63 | labels: ${{ steps.meta.outputs.labels }}
64 | platforms: linux/amd64,linux/arm64
65 | cache-from: type=gha
66 | cache-to: type=gha,mode=max
--------------------------------------------------------------------------------
/app/Views/loading.php:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Pixiv 每日排行榜 Top=Config::$limit?> 小挂件
14 |
49 |
54 |
55 |
56 |
60 |
61 |
68 |
--------------------------------------------------------------------------------
/doc/docker.en.md:
--------------------------------------------------------------------------------
1 | # Docker
2 | > If you need to enable multiple containers, share the `/var/www/html/storage` directory between them by mounting it to avoid each container updating the ranking data separately and causing performance waste
3 |
4 | ## Deployment
5 | ### Command
6 | ```shell
7 | docker run -d -p 80:80 --name=pixiv -e URL=http://localhost/ ghcr.io/mokeyjay/pixiv-daily-ranking-widget
8 | ```
9 |
10 | ### Docker compose
11 | ```yaml
12 | version: '3.1'
13 |
14 | services:
15 | pixiv:
16 | image: ghcr.io/mokeyjay/pixiv-daily-ranking-widget
17 | container_name: pixiv
18 | restart: always
19 | environment:
20 | URL: http://localhost/
21 | ports:
22 | - "80:80"
23 | ```
24 |
25 | > `URL` is the access url to the container, supports path, and must end with `/`
26 |
27 | ## Configure
28 | By [environment](https://docs.docker.com/compose/compose-file/#environment) . all config items see [config.docker.php](../.docker/config.php)
29 |
30 | > Only the `local` image hosting is enabled by default (images are stored locally to the container). To use it, you must configure the `URL` item
31 | >
32 | > Different from local deployment, Docker image has built-in scheduling tasks that automatically update ranking data. Therefore, the default value of `DISABLE_WEB_JOB` is `true`, which means that updates are not triggered through web access
33 |
34 | > logs path: `/var/www/html/storage/logs`
35 |
36 | ## Jobs
37 | ### Trigger updates proactively
38 | > In general, ranking data is detected for updates every half hour without being actively triggered
39 | > When you deploy for the first time, you can trigger an update manually or wait for half an hour to update automatically
40 |
41 | ```shell
42 | docker exec pixiv php index.php -j=refresh
43 | ```
44 | See [Trigger updates proactively](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/deploy.en.md)
45 |
46 | ### Clear the logs
47 | ```shell
48 | docker exec pixiv php index.php -j=clear-log
49 | ```
50 | See [Clear the logs](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/deploy.en.md)
--------------------------------------------------------------------------------
/doc/deploy.en.md:
--------------------------------------------------------------------------------
1 | # Deployment
2 | ## Docker
3 | ```shell
4 | docker run -d -p 80:80 --name=pixiv -e URL=http://localhost/ ghcr.io/mokeyjay/pixiv-daily-ranking-widget
5 | ```
6 | See [Docker](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/docker.en.md)
7 | ## Local
8 | - [Download source code](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/releases/latest)
9 | - Unzip under your the web directory
10 | - Edit `config.php` with a **professional** editor (e.g. `Visual Studio Code`, `Sublime`, etc., notepad is not allowed) and modify the configuration according to your own needs
11 | - Grant write permission to `storage` directory
12 |
13 | ## Trigger updates proactively
14 | By default, this widget will check if the ranking data is out of date every time it is accessed and make an additional request to trigger an automatic update if needed. In most cases, this operation is not required.
15 |
16 | However, in some cases (e.g. PHP timeouts are not long enough, server performance is too poor), this web-triggered update will be interrupted before it finishes. This will interrupt the update and never let it finish, and also keeps consuming unnecessary performance and bandwidth.
17 | If you encounter the problem above, you can turn off web-triggered updates (set `disable_web_job` to `false` in `config.php`)
18 | Then trigger update proactively via cli, e.g. `php index.php -j=refresh`
19 |
20 | > You can use a tool like `crontab` to automatically trigger updates on a regular basis. For example `*/30 * * * * php /path/to/pixiv/index.php -j=refresh`
21 | > It means run update every 30 minutes. The program will automatically determine whether it really needs to be updated, and it won't waste performance
22 |
23 | ## Clear the logs
24 | Opening the log (set `log_level` to `['DEBUG', 'ERROR']` in `config.php`) will log this widget's running info.
25 | When giving me feedback on a problem, it is usually recommended to send me the logs and configuration file as a zip package (please do not post the configuration file to the public)
26 | If you are going to keep the log enabled for a long time and are worried about it taking up too much hard drive, you can delete the logs over 7 days with `php index.php -j=clear-log`
27 |
28 | > Add the parameter `-n=3` to delete logs that are 3 days old
29 |
30 | > You can use a tool like `crontab` to delete automatically on a regular basis. For example `30 1 * * * php /path/to/pixiv/index.php -j=clear-log`
--------------------------------------------------------------------------------
/app/Libs/Config.php:
--------------------------------------------------------------------------------
1 | $value) {
35 | self::$$key = $value;
36 | }
37 |
38 | // 获取本项目 url
39 | if (self::$url == '' && !IS_CLI) {
40 | self::$url = Request::getCurrentUrl();
41 | }
42 |
43 | // 是否对外提供服务,是则获取 url 参数
44 | if (self::$service) {
45 | if (isset($_GET['color'])) {
46 | self::$background_color = '#' . $_GET['color'];
47 | }
48 | if (isset($_GET['limit'])) {
49 | self::$limit = (int)$_GET['limit'];
50 | }
51 | }
52 |
53 | try {
54 | if (!is_writable(STORAGE_PATH)) {
55 | throw new \Exception(STORAGE_PATH . ' 目录无法写入');
56 | }
57 |
58 | if (!is_array(Config::$image_hosting) || count(Config::$image_hosting) < 1) {
59 | throw new \Exception('image_hosting 配置项至少要有一个值');
60 | }
61 |
62 | if (self::$limit < 1) {
63 | throw new \Exception('limit 配置项不得小于1');
64 | }
65 |
66 | if (IS_CLI && self::$url == '' && in_array('local', self::$image_hosting)) {
67 | throw new \Exception('在 cli 模式下使用 local 本地图床时,必须配置 url 项,否则可能会生成错误的缩略图 url');
68 | }
69 |
70 | if (!in_array(Config::$ranking_type, ['', 'illust', 'manga'])) {
71 | throw new \Exception('ranking_type 配置项必须为空、illust 或 manga');
72 | }
73 |
74 | } catch (\Exception $e) {
75 | Log::write($e->getMessage(), Log::LEVEL_ERROR);
76 | echo '错误:' . $e->getMessage();
77 |
78 | die;
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/app/App.php:
--------------------------------------------------------------------------------
1 | getMessage(), 'ERROR');
22 | http_response_code(500);
23 | die;
24 | });
25 | }
26 |
27 | public static function run()
28 | {
29 | self::init();
30 |
31 | self::job();
32 |
33 | self::route();
34 | }
35 |
36 | /**
37 | * 运行任务
38 | * @throws \Exception
39 | */
40 | protected static function job()
41 | {
42 | $opt = getopt('j:');
43 | if (empty($_GET['job']) && empty($opt['j'])) {
44 | return;
45 | }
46 |
47 | $jobName = !empty($_GET['job']) ? $_GET['job'] : $opt['j'];
48 | $job = Job::make($jobName);
49 |
50 | if (!empty($_GET['job']) && $job->onlyActivateByCli) {
51 | throw new \Exception("任务 {$jobName} 只能通过 cli 触发");
52 | }
53 |
54 | if (!$job) {
55 | throw new \Exception("任务 {$jobName} 加载失败");
56 | }
57 |
58 | set_time_limit(0);
59 | if ($job->run()) {
60 | Log::write("任务 {$jobName} 执行完毕");
61 | echo "任务 {$jobName} 执行完毕";
62 | } else {
63 | throw new \Exception("任务 {$jobName} 执行失败:{$job->getErrorMsg()}");
64 | }
65 |
66 | exit;
67 | }
68 |
69 | /**
70 | * 路由
71 | */
72 | protected static function route()
73 | {
74 | $route = isset($_GET['r']) ? $_GET['r'] : 'index';
75 | $route = explode('/', $route);
76 |
77 | $controller = Str::studly(array_shift($route) ?: 'index');
78 | $method = lcfirst(Str::studly(array_pop($route) ?: 'index'));
79 |
80 | $class = "app\\Controllers\\{$controller}Controller";
81 | if (!class_exists($class)) {
82 | Log::write("控制器不存在:{$class}", Log::LEVEL_ERROR);
83 |
84 | http_response_code(404);
85 | die;
86 | }
87 |
88 | $controller = new $class;
89 | if (!is_callable([$controller, $method])) {
90 | Log::write("无法调用此方法:{$class}->{$method}()", Log::LEVEL_ERROR);
91 |
92 | http_response_code(404);
93 | die;
94 | }
95 |
96 | $controller->$method();
97 | }
98 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 🖼️ Pixiv 每日排行榜小挂件
2 |
3 | English
4 |
5 | 想要在你的网站页面中添加一个 Pixiv 每日排行榜 的展示功能吗?现在,只需要一行代码即可实现!
6 | 在线预览
7 |
8 |
9 | ## ✨ 特色
10 | - 一行 `HTML` 代码即可调用,方便快捷
11 | - 自适应宽高。推荐宽度 `240px`、高度 `380px` 或以上
12 | - 点击图片可跳转到对应作品详情页
13 | - 每日自动更新,无需人工干预
14 | - 内置多图床支持、按需加载图片,极低资源消耗
15 | - 提供 API 服务,含有排行榜更新日期、缩略图 url 及详情页 url 等
16 |
17 | ## 🤔 如何使用
18 | 将这行代码添加到网页上即可
19 | ```html
20 |
21 | ```
22 |
23 | 以 `Wordpress` 为例。首先进入后台,点击 外观 -> 小工具
24 | 向右边适当的位置添加一个 **文本** 或 **自定义HTML** 小工具,内容填写上述代码即可
25 |
26 | [高级用法](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/advance-usage.md)
27 |
28 | ## 🛠️ 如何部署
29 | 想要自己定制代码?嫌我提供的服务太慢?
30 | 你也可以轻松拥有完全属于自己的小挂件!
31 | > 需要 Docker 或 PHP 版本 >= 5.6
32 |
33 | [部署文档](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/deploy.md)
34 |
35 | ## 🔌 API
36 | [排行榜数据(已上传至图床)](https://pixiv.mokeyjay.com/?r=api/pixiv-json)(推荐)
37 | [排行榜数据(pixiv url)](https://pixiv.mokeyjay.com/?r=api/source-json)
38 |
39 | 其中 `data` 为排行榜数据;`date` 为排行榜日期(可能是昨天或者前天,因为官方更新时间不一定)
40 | 这两个接口都会自动根据请求头的 `Origin` 或者 `Referer` 返回对应跨域头。可供前端直接调用
41 |
42 | > `image` 和 `url` 两个键是为了兼容 4.x 及之前版本的用户,无需理会
43 |
44 | ## 🆙 升级指南
45 | ### 从 5.2 升级到 6.0
46 | 1. [下载源代码](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/releases/latest)
47 | 2. 解压缩,将其中的 `app` 和 `index.php` 覆盖到线上环境
48 | > **⚠️ 对于 Docker 方式部署的用户**
49 | > - 请将环境变量名中所有 `-` 替换为 `_`
50 | > - 镜像从 docker hub 迁移至 [ghcr.io](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/pkgs/container/pixiv-daily-ranking-widget)
51 |
52 | ## 🌟 更新日志
53 | ### 新增
54 | - `ranking_type` 配置项,现在可以选择拉取综合还是插画、漫画日榜啦~
55 | - 图片预加载,优化网络环境较差时的体验
56 | ### 优化
57 | - 完全重写了前端,更优雅的缓动效果
58 | - 不再依赖 bootstrap,加载更快啦
59 | - 改为使用官方 php、nginx 包
60 | - 从本地存储获取图片时不再重复检查完整性
61 | - `background_color` 配置项现在支持[更多种颜色](https://developer.mozilla.org/zh-CN/docs/Web/CSS/background-color)了
62 | ### 修复
63 | - 部分环境变量在一些情况下无法被正常获取的问题
64 | - 定时任务实际上是一小时执行一次,而非文档说的半小时一次
65 | ### 其他
66 | - 由于不再依赖 bs,去除 `static_cdn` 配置项
67 | - 删除已经失效的 `Pngcm`、`Tsesze` 图床
68 | - Docker 镜像迁移至 [ghcr.io](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/pkgs/container/pixiv-daily-ranking-widget)
69 | - Docker 镜像时区默认为上海
70 |
71 | [历史更新日志](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/log.md)
72 |
73 | ## 👨💻 关于作者
74 | 常用 ID [mokeyjay](https://www.mokeyjay.com),热爱 IT 与 ACG 的学渣
--------------------------------------------------------------------------------
/app/Libs/Curl.php:
--------------------------------------------------------------------------------
1 | '', 'html' => ''] 数组
18 | */
19 | public static function get($url, $opt = [], $includeCookie = false)
20 | {
21 | $ch = curl_init($url);
22 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
23 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
24 | curl_setopt($ch, CURLOPT_TIMEOUT, 30);
25 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
26 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
27 | curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.52');
28 |
29 | Config::$proxy && curl_setopt($ch, CURLOPT_PROXY, Config::$proxy);
30 | $includeCookie && curl_setopt($ch, CURLOPT_HEADER, true);
31 |
32 | if (count($opt)) {
33 | curl_setopt_array($ch, $opt);
34 | }
35 |
36 | $data = curl_exec($ch);
37 | curl_close($ch);
38 |
39 | if ($includeCookie) {
40 | $data = explode("\r\n\r\n", $data);
41 |
42 | $header = array_shift($data);
43 | $html = implode("\r\n\r\n", $data);
44 |
45 | preg_match_all("/set-cookie:([^\r\n]*)/i", $header, $matches);
46 |
47 | $cookie = '';
48 | if (!empty($matches[1])) {
49 | $cookieItem = [];
50 | foreach ($matches[1] as $item) {
51 | $cookieItem[] = explode(';', trim($item))[0];
52 | }
53 | $cookie = implode('; ', $cookieItem);
54 | }
55 |
56 | return compact('cookie', 'html');
57 | }
58 |
59 | return $data;
60 | }
61 |
62 | /**
63 | * post请求
64 | * @param string $url
65 | * @param array|string $postData
66 | * @param array $opt
67 | * @return bool|string
68 | */
69 | public static function post($url, $postData, $opt = [])
70 | {
71 | $opt[CURLOPT_POST] = true;
72 | $opt[CURLOPT_POSTFIELDS] = $postData;
73 |
74 | return self::get($url, $opt);
75 | }
76 |
77 | /**
78 | * 获取curl file实例
79 | * @param string $path 文件路径
80 | * @return \CURLFile|string
81 | */
82 | public static function getCurlFile($path)
83 | {
84 | return class_exists('CURLFile') ? (new \CURLFile(realpath($path))) : ('@' . realpath($path));
85 | }
86 | }
--------------------------------------------------------------------------------
/app/Libs/Storage.php:
--------------------------------------------------------------------------------
1 | 碎碎念:原本这个项目只是随便搞搞,没想到后面功能越堆越多,代码也越来越丑。作为本辣鸡github上最高star的项目实在是丢人。好在我花了几天时间撸了这个4.0,总算是不那么丢人了
84 | > 还有就是添加了多图床的支持,每个月能节省几百G的流量了嘤
85 |
86 | ## 3.0
87 | - 添加`$download_proxy`配置项
88 | - 由于Pixiv的图片url添加了防盗链无法被直接显示,因此`$download`配置项默认开启
89 | 为了更好的显示效果,自行部署的用户建议配置一个定时任务,每天0点触发`download.php`
90 |
91 | ## 2.9
92 | - 修复因Pixiv改动导致挂掉的问题
93 |
94 | ## 2.8
95 | - 尝试优化更新锁,防止高并发下重复更新
96 | - 从 Conf::$download 中独立出配置项 Conf::$url_cache,现在可以仅缓存图片url而不缓存缩略图了
97 | - 添加贴图库图床支持
98 |
99 | > 贴图库免费版并不是很好用且不支持https,建议优先使用sm.ms,贴图库仅作为备用
100 | > 由于之前更新锁在高并发下有些问题无法很好的发挥作用,导致我的服务器IP因重复上传被sm.ms图床封了。而我个人也无力支撑高昂的CDN费用。因此即日起**方案一**不再提供CDN加速,改为直接从P站获取图片
101 | > 方案一目前由360网站卫士提供CDN支持
102 |
103 | ## 2.7
104 | - 添加图片压缩功能,降低服务器带宽压力(需要GD库)
105 | - 修复sm.ms图床支持,降低失败概率
106 | - 添加sm.ms图床上传日志
107 |
108 | > 如果开启`$enable_smms`出现问题,反馈时请带上日志文件
109 |
110 | ## 2.6
111 | - 添加sm.ms图床支持。一键启用即可大幅降低服务器带宽压力、节省流量。感谢[@Showfom](https://sb.sb/)提供图床
112 |
113 | > 我才不告诉你是因为方案一每天跑掉我几G流量,心疼不已才加的这个功能呢
114 | > 如果连续3次上传失败,则从服务器本地读取图片,确保访问正常
115 |
116 | ## 2.5
117 | - 修复因Pixiv改版导致挂掉的问题
118 | - Pixiv原生支持https啦!可喜可贺
119 |
120 | ## 2.4
121 | - 修复特定情况下URL的`limit`参数无效的问题
122 | - 修复**方案一**缓存问题
123 | - 修复上面效果图SSL证书问题
124 |
125 | ## 2.3
126 | - 更换了前端库引用地址,修复移动宽带下加载慢的问题
127 | - 添加协议自适应,修复在关闭缓存或缓存还没全部完成时影响小绿锁的问题
128 | - 以上更新来自@灵乌路空 的友情PR,我们一起对她PRPR以示感激吧
129 | - 超能小紫的方案一服务现已支持HTTPS。咬牙忍痛上了收费CDN,请大家且用且珍惜
130 | - 要是被滥用到我吃不消费用的话可能会暂停服务噢~
131 | - 如果访问量较高的话建议还是自行搭建服务,谢谢各位的支持与谅解
132 |
133 | ## 2.2
134 | - 优化下载线程以支持自行部署HTTPS
135 |
136 | ## 2.1
137 | - 规划2.0时脑子抽了,非要把所有逻辑都局限在一个文件里。虽然各方面确实有所提升,但在一些情况下照样会出现那些老问题。例如缩略图下载失败啊、PHP超时导致下载中断之类。因此在我测试并意识到这一点时,赶紧开始了新版本的开发 光速打脸
138 | - 去除自动更新锁机制,缩略图已存在并且有效时不再重复下载。防止因网络波动或超时导致的缩略图下载失败
139 |
140 | ## 2.0
141 | - 整体重构,各机制大幅优化
142 | - 添加自动更新锁机制,避免高访问量时并发更新浪费资源
143 | - 全新的伪多线程自动更新机制,后台更新不影响使用
144 | - 更新失败重试,避免因为网络问题导致的部分图片获取失败
145 |
146 | # 初衷
147 | 前几天跟朋友聊天,朋友说希望能在自己博客侧边栏中显示[Pixiv](http://www.pixiv.net/)的每日排行榜。我自己也是个`ACG`爱好者,被他这么一说也想弄一个。昨晚终于有空,花了半个多小时写完。[自己博客](https://www.mokeyjay.com)用上了感觉不错,完善了一下加了点功能开源出来福利各位
--------------------------------------------------------------------------------
/README.en.md:
--------------------------------------------------------------------------------
1 | 🖼️ Pixiv Daily Ranking Widget
2 |
3 | 中文
4 |
5 | Want to add a Pixiv Daily Ranking Widget to your website? It's a matter of one line of code!
6 | DEMO
7 |
8 |
9 | ## ✨ Features
10 | - Easy to use with one line of `HTML` code
11 | - Adaptive width and height. A minimum size of `240px * 380px` (width \* height) or more is recommanded
12 | - Redirect to artwork page by clicking on the widget
13 | - Automatic daily update
14 | - Low system resource utilisation with supports for multiple image hosting platforms and on-demand image loading
15 | - Offering an API that includes ranking update date, thumbnail URL and detail page URL etc.
16 |
17 | ## 🤔 How to use
18 | Just add the below code to your page
19 | ```html
20 |
21 | ```
22 |
23 | Taking `WordPress` as an example. On `wp-admin`, click on **Appearance** -> **Widgets**
24 | Then add a **Text** or **Custom HTML** widget as deemed appropriate on the right and fill the code above in
25 |
26 | [Advance Usage](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/advance-usage.en.md)
27 |
28 | ## 🛠️ How to deploy
29 | Wanted to customize the code yourself? Thought the service I provided is slow in speed?
30 |
31 | You can also easily deploy your own widget!
32 | > Requires Docker or PHP version >= 5.6
33 |
34 | [Deployment Documentation](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/deploy.en.md)
35 |
36 | ## 🔌 APIs
37 | [Ranking data (images hosted privately)](https://pixiv.mokeyjay.com/?r=api/pixiv-json) (recommended)
38 | [Ranking data (pixiv url)](https://pixiv.mokeyjay.com/?r=api/source-json)
39 |
40 | In which `data` is the data of the ranking table; `date` is the date of ranking (could be yesterday or the day before, as the time of refresh on Pixiv is not certain)
41 |
42 | Both APIs automatically return the respective cross-domain header according to `Origin` or `Referer` within the request header. The APIs are front-end ready.
43 |
44 | > The `image` and `url` keys are for compatibility purposes for users of 4.x or earlier versions, they can be ignored
45 |
46 | ## 🆙 Upgrading Guide
47 | ### Upgrading From 5.2 to 6.0
48 | 1. [Download the Source Code](https://github.com/mokeyjay/pixiv-daily-ranking-widget/releases/latest)
49 | 2. Unzip and overwrite the `app` and `index.php` to your server
50 | > **⚠️ For Docker User**
51 | > - Please replace all `-` in the environment variable name with `_`
52 | > - Docker Image migration from Docker Hub to [ghcr.io](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/pkgs/container/pixiv-daily-ranking-widget)
53 |
54 | ## 🌟 Changelog
55 | ### New Features
56 | - Added `ranking_type` configuration option, which now allows you to select whether to fetch the overall or illustration/manga daily rankings.
57 | - Added image preloading to improve the experience in poor network environments.
58 | ### Optimizations
59 | - Completely rewritten the frontend with more elegant animation effects.
60 | - Removed the dependency on Bootstrap for faster loading.
61 | - Switched to using the official PHP and Nginx packages.
62 | - No longer repeatedly check integrity when retrieving images from local storage.
63 | - The `background_color` configuration now supports [more colors](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color)
64 | ### Fixes
65 | - Some environment variables cannot be obtained normally in some cases
66 | - The scheduled task actually runs once every hour, not every half hour as stated in the documentation
67 | ### Other
68 | - Removed the `static_cdn` configuration option due to the removal of the dependency on Bootstrap.
69 | - Removed the invalid `Pngcm` and `Tsesze` image-hosting
70 | - Docker image migration to [ghcr.io](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/pkgs/container/pixiv-daily-ranking-widget)
71 | - Docker image timezone defaults to Shanghai
72 |
73 | [History](https://github.com/mokeyjay/Pixiv-daily-ranking-widget/blob/master/doc/log.en.md)
74 |
75 | ## 👨💻 About author
76 | [mokeyjay](https://www.mokeyjay.com), IT and ACG lover
77 |
--------------------------------------------------------------------------------
/config.php:
--------------------------------------------------------------------------------
1 | '',
18 |
19 | /**
20 | * 背景颜色。默认值为 transparent (透明)。你也可以通过 url 参数 color 来设置
21 | * Background color. The default value is transparent. You can also set the background color by url parameter 'color'
22 | */
23 | 'background_color' => 'transparent',
24 |
25 | /**
26 | * 显示和缓存的图片最大数量(范围1-500)
27 | * 例如将此值设为 10 则可以做出 Top10 的效果
28 | * 也可防止部分辣鸡主机在缓存图片时占用过多资源导致卡死或报警
29 | * 一般情况下默认的 50 就行
30 | *
31 | * Maximum number of images to display and cache (range 1-500)
32 | * For example, if you set this value to 10, you can make a Top10 effect
33 | * It also prevents some low-performance hosts from using too many resources when caching images, which can lead to jamming or alarms
34 | * Usually the default 50 is fine
35 | */
36 | 'limit' => 50,
37 |
38 | /**
39 | * 是否对外提供服务
40 | * 为 true 时,任何人都可通过 url 的 get 参数来临时修改 background_color 和 limit 的值
41 | *
42 | * Whether to provide external services
43 | * When true, anyone can temporarily change the values of background_color and limit by the url parameter
44 | */
45 | 'service' => true,
46 |
47 | /**
48 | * 日志级别。可多选:DEBUG、ERROR 或留空不记录任何日志
49 | * Logging level. Multiple options: DEBUG, ERROR or leave blank to not record any logs
50 | */
51 | 'log_level' => [],
52 |
53 | /**
54 | * 代理服务器配置。例如 127.0.0.1:1080
55 | * 留空为不使用代理
56 | *
57 | * Proxy server configuration. For example 127.0.0.1:1080
58 | * Leave blank to not use proxy
59 | */
60 | 'proxy' => '',
61 |
62 | /**
63 | * 每次更新排行榜数据后,自动删除过期的本地缓存缩略图
64 | * Automatically delete expired local cache thumbnails after each ranking data update
65 | */
66 | 'clear_overdue' => true,
67 |
68 | /**
69 | * 压缩缩略图,在几乎不损失画质的前提下减小 50% 左右的体积,降低服务器带宽压力
70 | * 需要启用 PHP 的 GD 扩展
71 | *
72 | * Compress thumbnails to reduce the size by about 50% with almost no loss of image quality, reducing server bandwidth pressure
73 | * Need the GD extension for PHP
74 | */
75 | 'compress' => true,
76 |
77 | /**
78 | * 图床名称
79 | * (推荐度按照顺序从高到低)
80 | *
81 | * 推荐填写多个图床,如果其中一个图床上传失败,则将按照顺序继续尝试其他图床
82 | *
83 | * Image-Hosting
84 | * (Recommendation is ranked from highest to lowest)
85 | *
86 | * It is recommended to fill in more than one image-hosting, if one of them fails to upload, it will continue to try other image-hosting in order
87 | */
88 | 'image_hosting' => ['fifty-eight', 'chkaja', 'catbox', 'local'],
89 |
90 | /**
91 | * 图床扩展配置信息
92 | * Extend Configuration information for the image-hosting
93 | */
94 | 'image_hosting_extend' => [
95 | 'tietuku' => [
96 | 'token' => ''
97 | ],
98 | 'smms' => [
99 | 'token' => '',
100 | ],
101 | // 薄荷图床
102 | 'riyugo' => [
103 | // 客服提供的会员专属网址。例如 https://r789.com/1234,必须以 / 结尾
104 | 'url' => '',
105 | // 要上传到的文件夹。通常可以留空
106 | 'upload_path' => '',
107 | // 管理后台-设置 中的 唯一用户ID
108 | 'unique_id' => '',
109 | // 登录管理后台后,filemanagerXXXXXXXXX 这个 cookie 的值
110 | // (XXXXXXXX 是你的唯一用户 ID)
111 | 'token' => '',
112 | ],
113 | ],
114 |
115 | /**
116 | * 禁用 web 访问的方式触发 job 更新,仅限 cli 方式触发
117 | * 由于部分环境 web 超时时间不够,会导致更新操作不断被触发但又无法完成整个更新流程
118 | * 因此添加一个开关,避免 web 触发更新,节约服务器资源
119 | *
120 | * Disable web-trigger update job, cli-trigger only
121 | * See doc/deploy.en.md
122 | */
123 | 'disable_web_job' => false,
124 |
125 | /**
126 | * 放置在页面 标签下的 js 脚本内容,通常用来放置统计代码
127 | * 无需
176 |
177 |
178 |
179 |
180 | $data): ?>
181 |
191 |
192 |
193 |
201 |
202 |
203 |
326 |
327 |