Skip to content

Commit

Permalink
Merge pull request 'dev' (#40) from dev into main
Browse files Browse the repository at this point in the history
  • Loading branch information
FleyX committed Mar 8, 2023
2 parents 5251b5f + 388765a commit 4e9dc0b
Show file tree
Hide file tree
Showing 38 changed files with 9,829 additions and 755 deletions.
51 changes: 2 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,7 @@

![预览图](https://s3.fleyx.com/picbed/2022/11/18386180128d01eb1a59b8eacf652895.png)

renamer 的开源实现版本,BS 应用,支持arm/x86部署使用
renamer 的开源实现版本,BS 应用,支持 arm/x86 部署使用
已打包镜像到 dockerhub 中:[hub.docker.com/r/fleyx/open-renamer](https://hub.docker.com/r/fleyx/open-renamer)

开源地址:[github.com/FleyX/open-renamer](https://github.com/FleyX/open-renamer)

已实现如下四种处理规则:

- 插入(支持季号识别,支持后缀过滤)
- 删除
- 序列化
- 自动识别(针对 nas 用户开发,自动获取季号,剧名/电影名)

特点:

- 不限制规则数量
- 支持将规则保存为模板,方便下次使用
- 全平台(arm,x86)支持,可直接部署在 nas 中,通过浏览器访问

## 运行方式:

推荐通过 docker 部署到 nas 中,即可管理 nas 媒体文件

- docker 命令运行:

```bash
# 管理/mnt/vdisk目录中的文件,通过8089端口访问服务
docker run -itd --name openRenamer -v /mnt/vdisk:/data -p 8089:8089 -e PORT="8089" -e TOKEN="123456" fleyx/open-renamer
```

- docker-compose 运行:

```yaml
version: "3.6"
openRenamer:
container_name: openRenamer
image: fleyx/open-renamer
# 当前用户的uid,gid,使用root可不配置此项
#user: "1000:1000"
environment:
# 指定启动端口
- PORT=11004
# 指定认证token,不设置此项无需认证
- TOKEN=123456
volumes:
# 关键,把想要管理的文件夹映射到容器的data目录中,即可在程序中选择data目录进行重命名操作
- /mnt/vdisk:/data
# 存储模板数据,可不映射此目录
- ./data/openRenamer:/app/data
# 使用宿主机网络.即可通过"宿主机ip:11004"访问程序
network_mode: host
```
[点击查看参考文档](https://blog.fleyx.com/blog/detail/20221130)
3 changes: 1 addition & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
base=$(cd "$(dirname "$0")";pwd)
cd $base
rm -rf openRenamerBackend/dist
docker run -it --rm --name buildOpenRenamer --user ${UID} -v $base/openRenamerFront:/opt/front node:lts-buster-slim bash -c "cd /opt/front && yarn --registry https://registry.npmmirror.com && yarn build"
docker run -it --rm --name buildOpenRenamer --user ${UID} -v $base/openRenamerBackend:/opt/app node:lts-buster-slim bash -c "cd /opt/app && npm config set registry https://registry.npmmirror.com && npm install -g typescript && npm install && tsc"
docker run -it --rm --name buildOpenRenamer --user ${UID} -v $base/openRenamerFront:/opt/front node:lts-slim bash -c "cd /opt/front && npm install -g pnpm --registry https://registry.npmmirror.com && pnpm install --registry https://registry.npmmirror.com && pnpm run build"

rm -rf openRenamerBackend/static/*
touch openRenamerBackend/static/.gitkeep
Expand Down
3 changes: 3 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"version":1.3
}
3 changes: 2 additions & 1 deletion openRenamerBackend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ log
sqls/history.json
static/*
!static/.gitkeep
database.db
database.db
.idea
8 changes: 8 additions & 0 deletions openRenamerBackend/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions openRenamerBackend/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions openRenamerBackend/.idea/openRenamerBackend.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions openRenamerBackend/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions openRenamerBackend/api/AutoPlanApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Context } from "koa";
import AutoPlanService from "../service/AutoPlanService";

const router = {};

/**
* 获取目录下的文件列表
*/
router["POST /autoPlan/save"] = async function (ctx: Context) {
ctx.body = await AutoPlanService.saveAutoConfig(ctx.request.body);
};


export default router;
30 changes: 26 additions & 4 deletions openRenamerBackend/api/FileApi.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
import { Context } from "koa";
import {Context} from "koa";
import FileService from "../service/FileService";
import config from "../config";

const router = {};

/**
* 获取目录下的文件列表
* 获取目录下的文件列表
*/
router["GET /file/query"] = async function (ctx: Context) {
ctx.body = await FileService.readPath(ctx.query.path as string, ctx.query.showHidden === '1');
};

/**
*是否windows
* 递归读取文件夹下所有的文件
*/
router["POST /file/recursionQuery"] = async function (ctx: Context) {
ctx.body = await FileService.readRecursion(ctx.request.body);
};

/**
*是否windows
*/
router['GET /file/isWindows'] = async function (ctx: Context) {
ctx.body = config.isWindows;
}

/**
* 检查路径是否存在
* 检查路径是否存在
*/
router["GET /file/path/exist"] = async function (ctx: Context) {
ctx.body = await FileService.checkExist(ctx.query.path as string);
Expand All @@ -46,4 +53,19 @@ router["DELETE /file/path/delete"] = async function (ctx: Context) {
ctx.body = await FileService.deleteOne(ctx.query.id);
};

/**
* delete file batch
*/
router["POST /file/deleteBatch"] = async function (ctx: Context) {
ctx.body = await FileService.deleteBatch(ctx.request.body);
};

/**
* rename file
*/
router["POST /file/rename"] = async function (ctx: Context) {
await FileService.rename(ctx.request.body.source, ctx.request.body.target);
ctx.body = "";
};

export default router;
7 changes: 7 additions & 0 deletions openRenamerBackend/api/GlobalConfigApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ router["POST /config/update"] = async function (ctx: Context) {
ctx.body = await service.updateVal(ctx.request.body.code, ctx.request.body.val);
};

/**
* 提交修改
*/
router["POST /config/insertOrUpdate"] = async function (ctx: Context) {
ctx.body = await service.insertOrReplace(ctx.request.body);
};



export default router;
151 changes: 77 additions & 74 deletions openRenamerBackend/entity/bo/rules/AutoRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,86 +4,89 @@ import path from 'path';


let pattern = new RegExp(/s(eason)?(\d+)/);
let eNumPatternArr = [new RegExp(/e[p]?(\d+)/), new RegExp(/[\(\[(](\d+)[\)\])]/), new RegExp(/[\.-](\d+)/), new RegExp(/(\d+)/)];
let eNumPatternArr = [new RegExp(/ep?(\d+)/), new RegExp(/[\(\[(](\d+)[\)\])]/), new RegExp(/[\.-](\d+)/), new RegExp(/(\d+)/)];
let resolutionPattern = new RegExp(/(\d{3,}[pP])/);
let resolutionArr = ['1k', '1K', '2k', '2K', '4k', '4K', '8k', '8K'];
let charSet = new Set([' ', '[', '.', '(', '(']);
export default class InsertRule implements RuleInterface {

/**
* 识别类型,season:季号,name:剧名/电影名识别
*/
type: string;
/**
* 前面追加
*/
frontAdd: string;
/**
* 后面追加
*/
endAdd: string;
eNumWidth: number;
/**
* 识别类型,season:季号,name:剧名/电影名识别
*/
type: string;
/**
* 前面追加
*/
frontAdd: string;
/**
* 后面追加
*/
endAdd: string;
eNumWidth: number;

constructor(data: any) {
this.type = data.type;
this.frontAdd = data.frontAdd;
this.endAdd = data.endAdd;
}
constructor(data: any) {
this.type = data.type;
this.frontAdd = data.frontAdd;
this.endAdd = data.endAdd;
this.eNumWidth = data.eNumWidth;
}


deal(file: FileObj): void {
//识别到的内容
let getStr = null;
let patternRes = path.basename(file.path).replace(/[ ]+/, "").toLocaleLowerCase().match(pattern);
if (this.type === 'season') {
if (patternRes && patternRes[2]) {
getStr = patternRes[2];
}
} else if (this.type === 'name') {
let originName = null;
if (patternRes && patternRes[2]) {
//说明是剧集,取父文件夹的父文件夹名称
originName = path.basename(path.resolve(file.path, '..'));
} else {
//说明是电影
originName = path.basename(file.path);
}
getStr = '';
for (let i = 0; i < originName.length; i++) {
let char = originName.charAt(i);
if (charSet.has(char)) {
break;
}
getStr += char;
}
} else if (this.type === 'eNum') {
let lowName = file.originName.toLocaleLowerCase().replace(/ /g, '');
for (let i in eNumPatternArr) {
let patternRes = lowName.match(eNumPatternArr[i]);
if (patternRes && patternRes.length > 1) {
getStr = patternRes[1];
for (let i = 0; i < this.eNumWidth - getStr.length; i++) {
getStr = '0' + getStr;
}
break;
}
}
} else if (this.type === 'resolution') {
let res = file.originName.match(resolutionPattern);
if (res && res.length > 1) {
getStr = res[1];
} else {
for (let i = 0; i < resolutionArr.length; i++) {
if (file.originName.indexOf(resolutionArr[i]) > -1) {
getStr = resolutionArr[i];
break;
}
}
}
}
if (getStr && getStr.length > 0) {
file.realName = file.realName + this.frontAdd + getStr + this.endAdd;
file.name = file.realName + file.expandName;
}
}
deal(file: FileObj): void {
//识别到的内容
let getStr = null;
let patternRes = path.basename(file.path).replace(/[ ]+/, "").toLocaleLowerCase().match(pattern);
if (this.type === 'season') {
if (patternRes && patternRes[2]) {
getStr = patternRes[2];
}
} else if (this.type === 'name') {
let originName = null;
if (patternRes && patternRes[2]) {
//说明是剧集,取父文件夹的父文件夹名称
originName = path.basename(path.resolve(file.path, '..'));
} else {
//说明是电影
originName = path.basename(file.path);
}
getStr = '';
for (let i = 0; i < originName.length; i++) {
let char = originName.charAt(i);
if (charSet.has(char)) {
break;
}
getStr += char;
}
} else if (this.type === 'eNum') {
let lowName = file.originName.toLocaleLowerCase().replace(/ /g, '')
.replace(/\d+[a-df-z]/g, '')//去除4k,1080p等
.replace(/[xh]\d+/g, '')//去除x264,h264等 ;
for (let i in eNumPatternArr) {
let patternRes = lowName.match(eNumPatternArr[i]);
if (patternRes && patternRes.length > 1) {
getStr = patternRes[1];
for (let i = 0; i < this.eNumWidth - getStr.length; i++) {
getStr = '0' + getStr;
}
break;
}
}
} else if (this.type === 'resolution') {
let res = file.originName.match(resolutionPattern);
if (res && res.length > 1) {
getStr = res[1];
} else {
for (let i = 0; i < resolutionArr.length; i++) {
if (file.originName.indexOf(resolutionArr[i]) > -1) {
getStr = resolutionArr[i];
break;
}
}
}
}
if (getStr && getStr.length > 0) {
file.realName = file.realName + this.frontAdd + getStr + this.endAdd;
file.name = file.realName + file.expandName;
}
}
}
Loading

0 comments on commit 4e9dc0b

Please sign in to comment.