Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
x1jumping committed Sep 20, 2023
1 parent 96a340e commit 679e02e
Show file tree
Hide file tree
Showing 9 changed files with 414 additions and 150 deletions.
95 changes: 65 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,103 @@
# picture-bed-use-freecdn

freecdn-js能提高网站稳定性,如果其中一个链接不可用则启用另一个链接。cdn.jsdelivr.net不太稳定需要备用链接,所以用到了freecdn-js。但是freecdn-js对本身就在服务器端的文件不太友好(因为需要`sha256`),例如我把github作为图床而上传的图片,故写了一个python脚本处理hash和生成freecdn-js所需要的配置文件。
freecdn-js能提高网站稳定性,如果其中一个cdn链接不可用则启用另一个链接。博客图床使用到的cdn.jsdelivr.net不太稳定需要备用链接,所以用到了freecdn-js。但是freecdn-js对本身就在服务器端的文件不太友好(因为需要`sha256`),例如我把github作为图床而上传的图片(图片不在本地),故写了一个python脚本处理hash和生成freecdn-js所需要的配置文件。

需要使用安装[freecdn-js](https://github.com/EtherDream/freecdn)。本脚本为python脚本(因为不会写gulp),需要安装python。报错或许需要1.25.11版本的`urllib3`
需要使用安装[freecdn-js](https://github.com/EtherDream/freecdn)。本脚本为python脚本(因为不会写gulp),需要安装python。若报错或许需要1.25.11版本的`urllib3`

经过验证,nodejs16.10.0能运行freecdn-js,如果有需要安装旧版本nodejs请使用nvm工具安装
经过验证,nodejs16.10.0能运行freecdn-js,如果有安装旧版本nodejs的需要请使用nvm工具安装


## 使用方法

只需要把放在github的图片url(以.xxx结尾,如.png、.css、.js)放在`urls.txt`,每行放一个url,并在同一个文件夹内运行`generate_custom.conf.py`,即可生成`custom.conf`
只需要把放在github的图片的url(以.xxx结尾,如.png、.css、.js)放在`urls.txt`,每行放一个url,并在同一个文件夹内运行`generate_custom_conf.py`,即可生成`custom.conf`(可以用`freecdn manifest --merge path_to_custom.conf`合并到`freecdn-manifest.txt`),`custom.conf`由几个内置的cdn模板生成

或者你也用hexo博客,那么可以使用`generate_pic.conf_without_urls.txt.py`根据`.md`(博客写作使用markdown)文件直接生成`pic.conf`,无需手动把url添加到`urls.txt``.md`放在`source\_posts`,或根据需要自行修改。`.py`文件中的正则表达需要根据自己的需求更改。如果你也使用[hexo-volantis](https://github.com/volantis-x/community)可以试着直接运行
`urls`的格式为`http(s)://cdn/user/repo/xxx`。脚本会分离为`user/repo/xxx``http(s)://website/`

如果你像我一样把文件(图片和某些js)放在github,需要在`.py`文件头部设置`user`变量为你的github id(用于定位你的github图床)。例如我就是xingpingcn
其中`cdn`可以是`cdn.jsdelivr.net/gh/`这种免费cdn。

`.py`文件头部可以设置是否使用代理(v2ray),需要自行设置。
示例
> https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo (2).ln5ua8psy9s.webp
`urls.txt`的格式为http(s)://website/user/repo/xxx
<font color=#808080 >*注:脚本未支持其他url格式和生成其他图床url。如果需要根据raw.githubusercontent.com生成cdn链接,请自行使用re.sub()将`/master`替换成`@master`*</font>

其中website可以是raw.githubusercontent.com或者cdn.jsdelivr.net这种免费cdn。
最终`.conf`会类似这样。[示例](https://github.com/xingpingcn/picture-bed-use-freecdn/blob/main/pic.conf)

示例
> https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://raw.githubusercontent.com/xingpingcn/picx-images-hosting/master/20230420/image.1anm5qwvdhnk.png
```typescript
@global
open_timeout=0
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://jsd.cdn.zzko.cn/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.us/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.ren/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
hash=53vmPtDi0FDFXfMGWxx4vfPICcg1nY8rLgmQh7wjZow=
```
<font color=#808080 >*注:脚本会自动urlencode,将不是url元字符的字符转义以兼容freecdn-js。脚本会生成`.bak.conf`,可以删除。*</font>

或者你也用hexo博客(如果你也使用hexo博客,需要把三个`.py`文件放在博客根目录),那么可以使用`generate_pic.conf_without_urls_txt.py`根据`.md`(博客写作使用markdown)文件直接生成`pic.conf`(作用和`custom.conf`一样,可以用`--merge`合并到`freecdn-manifest.txt`),无需手动把url添加到`urls.txt``.md`放在`source\_posts`,或根据需要自行修改。`.py`文件中的正则表达需要根据自己的需求更改。如果你也使用[hexo-volantis](https://github.com/volantis-x/community)可以试着直接运行。

如果你像我一样把文件(图片和某些js)放在github(我使用[picx.xpoet.cn](https://picx.xpoet.cn/)作为管理工具,上传图片的同时能够自动生成cdn链接),需要在`.py`文件头部设置`user`变量为你的github id(用于定位你的github图床)。例如我就是xingpingcn。

`.py`文件头部可以设置是否使用代理(v2ray),需要自行设置。

脚本未支持其他url格式和生成其他图床url。
`generate_external_manifest_file.py`用于生成`freecdn-manifest.txt``.txt`储存用于加速`manifest-full.txt`的cdn链接。详见[这里](https://github.com/EtherDream/freecdn/tree/master/examples/ext-manifest)

生成的`freecdn-manifest.txt`[示例](https://github.com/xingpingcn/picture-bed-use-freecdn/blob/main/freecdn-manifest.txt)如下

```python
@include
/manifest-full.txt
@global
open_timeout=0
/manifest-full.txt
https://jsd.cdn.zzko.cn/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://cdn.jsdelivr.us/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://cdn.jsdelivr.ren/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://cdn.jsdelivr.net/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
hash=izgWMFIdMtd29Zy7kWt3rWohTm7WQsZ9003qUATHdFo=
```

## 脚本运行逻辑

脚本会先判断`urls.txt`(或`.md`文件)中的url是否在`custom.conf`(或`pic.conf`)中,如果已经存在则直接写入到新的`.conf`,从而节省流量和时间。

如果url不在`.conf`中,则判断本地是否存储`urls.txt``generate_pic.conf_without_urls.txt.py`无需`urls.txt`,脚本内自动处理)中的文件,如果没有则下载文件。如果有则计算hash并写入`.conf`
如果url不在`.conf`中,则判断本地是否存储`urls.txt``generate_pic.conf_without_urls_txt.py`无需`urls.txt`,脚本内自动处理)中的文件,如果没有则下载文件。如果有则计算hash并写入`.conf`

下载文件储存在`dir_for_custom_conf`文件夹中,生成`.conf`后可以删除,下次生成`.conf`会根据该`.bak.conf`查询。
下载文件储存在`dir_for_custom_conf`文件夹中,在生成`.conf`后可以删除,下次生成`.conf`会根据`.bak.conf`查询。

内置了几个`类cdn.jsdelivr.net`的cdn。其中jsd.cdn.zzko.cn的GitHub地址是[这里](https://github.com/54ayao/Chinajsdelivr)

最终`.conf`会类似这样

```typescript
@global
open_timeout=0
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://jsd.cdn.zzko.cn/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.us/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.ren/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
hash=53vmPtDi0FDFXfMGWxx4vfPICcg1nY8rLgmQh7wjZow=
```
脚本会生成`.bak.conf`,可以删除。
## 和hexo配合
## 和hexo配合使用

我的博客用的hexo,因而可以使用以下命令行生成对应文件。

```powershell
cd f:/blog
hexo clean && hexo g
python ./generate_custom.conf.py
python ./generate_pic.conf_without_urls.txt.py #如果是hexo博客
python ./generate_custom_conf.py
python ./generate_pic.conf_without_urls_txt.py #如果是hexo博客
cd f:/blog/public
freecdn find --save
freecdn manifest --merge ../custom.conf
freecdn manifest --merge ../pic.conf #如果是hexo博客
freecdn js --make
gulp && hexo d
```

如果你也使用hexo,同时也希望通过`cdn`加速`freecdn-manifest.txt`,使用以下命令行。

```powershell
f:
cd f:/blog
hexo clean && hexo g
python ./generate_custom_conf.py
python ./generate_pic.conf_without_urls_txt.py #如果是hexo博客
cd f:/blog/public
freecdn find --save
freecdn manifest --merge ../custom.conf
freecdn manifest --merge ../pic.conf -o manifest-full.txt #用于生成外置的freecdn-manifest.txt
python ../generate_external_manifest_file.py
freecdn js --make --cdn "unpkg jsdelivr elemecdn https://jsd.cdn.zzko.cn/gh/xingpingcn/xingpingcn.github.io@main/freecdn-loader.min.js" #此命令为配置cdn链接用于加速.min.js文件,详细请查看freecdn项目的GitHub
gulp && hexo d
```
16 changes: 14 additions & 2 deletions custom.conf
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
@global
open_timeout=0
https://cdn.jsdelivr.net/gh/xingpingcn/website.comments/app.js
https://jsd.cdn.zzko.cn/gh/xingpingcn/website.comments/app.js
https://jsd.cdn.zzko.cn/gh/xingpingcn/website.comments/app.js
https://cdn.jsdelivr.us/gh/xingpingcn/website.comments/app.js
https://cdn.jsdelivr.ren/gh/xingpingcn/website.comments/app.js
https://cdn.jsdelivr.net/gh/xingpingcn/website.comments/app.js
hash=skOqpeqLCT5lUTj8auCbpcgSyWdMCKpIOZuJcIT+rug=
https://cdn.jsdelivr.net/gh/xingpingcn/website.comments/style4.css
https://jsd.cdn.zzko.cn/gh/xingpingcn/website.comments/style4.css
https://jsd.cdn.zzko.cn/gh/xingpingcn/website.comments/style4.css
https://cdn.jsdelivr.us/gh/xingpingcn/website.comments/style4.css
https://cdn.jsdelivr.ren/gh/xingpingcn/website.comments/style4.css
https://cdn.jsdelivr.net/gh/xingpingcn/website.comments/style4.css
hash=F839ZhZyJswxpRuWJtQQWyshcKKoITKrCMfTgmLJdBw=
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230419/%E8%87%AD%E5%8D%B7%E5%8C%85%E5%9C%86%E5%BD%A2.2rx79tqffvu0.png
https://jsd.cdn.zzko.cn/gh/xingpingcn/picx-images-hosting@master/20230419/%E8%87%AD%E5%8D%B7%E5%8C%85%E5%9C%86%E5%BD%A2.2rx79tqffvu0.png
https://cdn.jsdelivr.us/gh/xingpingcn/picx-images-hosting@master/20230419/%E8%87%AD%E5%8D%B7%E5%8C%85%E5%9C%86%E5%BD%A2.2rx79tqffvu0.png
https://cdn.jsdelivr.ren/gh/xingpingcn/picx-images-hosting@master/20230419/%E8%87%AD%E5%8D%B7%E5%8C%85%E5%9C%86%E5%BD%A2.2rx79tqffvu0.png
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230419/%E8%87%AD%E5%8D%B7%E5%8C%85%E5%9C%86%E5%BD%A2.2rx79tqffvu0.png
hash=xWPhZXLUcZFkPltRZW5UXuzEnLlNlkcIx55vlu5SB7M=
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://jsd.cdn.zzko.cn/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.us/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.ren/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
https://cdn.jsdelivr.net/gh/xingpingcn/picx-images-hosting@master/20230525/logo%20(2).ln5ua8psy9s.webp
hash=53vmPtDi0FDFXfMGWxx4vfPICcg1nY8rLgmQh7wjZow=
10 changes: 10 additions & 0 deletions freecdn-manifest.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@include
/manifest-full.txt
@global
open_timeout=0
/manifest-full.txt
https://jsd.cdn.zzko.cn/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://cdn.jsdelivr.us/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://cdn.jsdelivr.ren/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
https://cdn.jsdelivr.net/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt
hash=izgWMFIdMtd29Zy7kWt3rWohTm7WQsZ9003qUATHdFo=
70 changes: 37 additions & 33 deletions generate_custom.conf.py → generate_custom_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
freecdn 0.3.1
requests
'''
# 写到后面发现把多线程写成class会方便很多,但是快写完了就懒得改了,,,,

import re
import sys
Expand Down Expand Up @@ -68,7 +69,7 @@ def download_file_return_hash(line: str, headers=headers):
return hash256, res_url


def write_file(bak_file, line: str, file_to_w, cdn_list=cdn_list):
def write_file(bak_file, line: str, file_to_w, lock,cdn_list=cdn_list):
if bak_file: # 如果存在bak_conf文件
line_formated = re.escape(line) # 格式化url
re_obj = re.compile(f'{line_formated}.*?\thash=(.*?)\n', flags=re.S)
Expand All @@ -88,38 +89,41 @@ def write_file(bak_file, line: str, file_to_w, cdn_list=cdn_list):
file_to_w.write('\t'+cdn+res_url+'\n') # 写入cdn列表
file_to_w.write('\t'+'hash='+str(hash256)+'\n') # 写入hash

def main():

try:
os.remove('./custom.bak.conf')
except:
pass
try:
os.rename('./custom.conf', './custom.bak.conf')
except:
pass
lock = threading.Lock()
pool = ThreadPoolExecutor(16)
if not os.path.exists(f'{dir_for_custom_conf}'):
os.makedirs(f'{dir_for_custom_conf}')
with open('./custom.conf', 'w', encoding='utf8') as file_to_w:
file_to_w.write('@global\n\topen_timeout=0\n') # 通用文件
bak_file = None
if os.path.isfile('./custom.bak.conf'):
# 备份文件储存上一个custom.conf的信息,如果存在hash就不下载
with open('./custom.bak.conf', 'r') as custom_bak_conf:
bak_file = custom_bak_conf.read()
with open('./urls.txt', 'r', encoding='utf8') as file_of_urls:
try:
os.remove('./custom.bak.conf')
except:
pass
try:
os.rename('./custom.conf', './custom.bak.conf')
except:
pass
lock = threading.Lock()
pool = ThreadPoolExecutor(16)
if not os.path.exists(f'{dir_for_custom_conf}'):
os.makedirs(f'{dir_for_custom_conf}')
with open('./custom.conf', 'w', encoding='utf8') as file_to_w:
file_to_w.write('@global\n\topen_timeout=0\n') # 通用文件
bak_file = None
if os.path.isfile('./custom.bak.conf'):
# 备份文件储存上一个custom.conf的信息,如果存在hash就不下载
with open('./custom.bak.conf', 'r') as custom_bak_conf:
bak_file = custom_bak_conf.read()
with open('./urls.txt', 'r', encoding='utf8') as file_of_urls:

for line in file_of_urls.readlines(): # 读取需要处理的url
line = line.replace('\n', '')
# 验证是否是合法url
if not re.match(r'(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]', line):
print('非法url!如果是urls.txt文件结尾或开头的空白符请忽略这条警告。')
print(line)
continue
else:
for line in file_of_urls.readlines(): # 读取需要处理的url
line = line.replace('\n', '')
# 验证是否是合法url
if not re.match(r'(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]', line):
print('非法url!如果是urls.txt文件结尾或开头的空白符请忽略这条警告。')
print(line)
continue
else:

pool.submit(write_file, bak_file, url_encode(line),
file_to_w, cdn_list=cdn_list)
pool.shutdown()
print('done!')
pool.submit(write_file, bak_file, url_encode(line),
file_to_w, cdn_list=cdn_list,lock=lock)
pool.shutdown()
print('done!')
if __name__ == '__main__':
main()
13 changes: 13 additions & 0 deletions generate_external_manifest_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import os
import sys
from generate_custom_conf import CalcFileSha256_with_base64

def main():
os.chdir(sys.path[0]) # os.chdir(sys.path[0])把当前py文件所在路径设置为当前运行路径.
with open(os.path.join('./public', 'freecdn-manifest.txt'), 'w', encoding='utf8') as f:
hash256 = CalcFileSha256_with_base64(
os.path.join('./public', 'manifest-full.txt'))
f.write(f'''@include\n\t/manifest-full.txt\n@global\n\topen_timeout=0\n/manifest-full.txt\n\thttps://jsd.cdn.zzko.cn/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt\n\thttps://cdn.jsdelivr.us/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt\n\thttps://cdn.jsdelivr.ren/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt\n\thttps://cdn.jsdelivr.net/gh/xingpingcn/xingpingcn.github.io@main/manifest-full.txt\n\thash={hash256}''')

if __name__ == '__main__':
main()
Loading

0 comments on commit 679e02e

Please sign in to comment.