Merge pull request 'dev' (#52) from dev into main

Reviewed-on: #52
This commit is contained in:
fanxb 2024-11-17 20:05:06 +08:00
commit 51c6ec9986
11 changed files with 5315 additions and 4332 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "electron", "name": "renamer",
"version": "1.1.0", "version": "1.8.0",
"description": "", "description": "",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

View File

@ -1,4 +1,5 @@
import RuleInterface from "./RuleInterface"; import RuleInterface from "./RuleInterface";
import {dealFileName} from "./RuleInterface";
import FileObj from "../../vo/FileObj"; import FileObj from "../../vo/FileObj";
import path from 'path'; import path from 'path';
@ -20,43 +21,35 @@ export default class DeleteRule implements RuleInterface {
* true:false * true:false
*/ */
ignorePostfix: boolean; ignorePostfix: boolean;
/*
*
*/
regI: boolean;
constructor(data: any) { constructor(data: any) {
this.type = data.type; this.type = data.type;
this.start = new DeleteRuleItem(data.start); this.regI = data.regI != undefined && data.regI;
this.end = new DeleteRuleItem(data.end); this.start = new DeleteRuleItem(data.start, this.regI);
this.end = new DeleteRuleItem(data.end, this.regI);
this.ignorePostfix = data.ignorePostfix; this.ignorePostfix = data.ignorePostfix;
} }
deal(file: FileObj): void { deal(file: FileObj): void {
let target = "";
if (this.type === 'deleteAll') { if (this.type === 'deleteAll') {
file.realName = ""; target = "";
if (!this.ignorePostfix) {
file.expandName = "";
}
} else { } else {
let str = file.realName + (this.ignorePostfix ? "" : file.expandName); let str = file.realName + (this.ignorePostfix ? "" : file.expandName);
let startIndex = this.start.calIndex(str); let startIndex = this.start.calIndex(str, false);
let endIndex = this.end.calIndex(str); let endIndex = this.end.calIndex(str, true);
if (startIndex < 0 || endIndex < 0) { if (startIndex < 0 || endIndex < 0 || startIndex > endIndex) {
return; return;
} }
str = str.substring(0, startIndex) + str.substring(endIndex + 1); str = str.substring(0, startIndex) + str.substring(endIndex + 1);
if (this.ignorePostfix) { target = str;
file.realName = str;
} else {
file.expandName = path.extname(str);
if (file.expandName.length > 0) {
file.realName = str.substring(0, str.lastIndexOf("."));
} else {
file.realName = str;
} }
} dealFileName(file, target, this.ignorePostfix);
}
file.name = file.realName + file.expandName;
} }
} }
@ -70,22 +63,36 @@ class DeleteRuleItem {
* *
*/ */
value: string; value: string;
/**
*
*/
reg: RegExp;
constructor(data: any) { constructor(data: any, regI: boolean) {
this.type = data.type; this.type = data.type;
this.value = data.value; this.value = data.value;
if (this.type === 'reg') {
this.reg = regI ? new RegExp(this.value) : new RegExp(this.value, 'i');
}
} }
/** /**
* *
* @param str
* @param end
*/ */
calIndex(str: string): number { calIndex(str: string, end: boolean): number {
if (this.type === 'location') { if (this.type === 'location') {
return parseInt(this.value) - 1; let val = parseInt(this.value);
return val > 0 ? val - 1 : str.length + val;
} else if (this.type === 'text') { } else if (this.type === 'text') {
return str.indexOf(this.value); let index = str.indexOf(this.value);
return index + (end ? this.value.length - 1 : 0);
} else if (this.type === 'end') { } else if (this.type === 'end') {
return str.length - 1; return str.length - 1;
} else if (this.type === 'reg') {
let res = this.reg.exec(str);
return res == null ? -1 : (res.index + (end ? res[0].length - 1 : 0));
} }
return -1; return -1;
} }

View File

@ -1,5 +1,7 @@
import RuleInterface from "./RuleInterface"; import RuleInterface from "./RuleInterface";
import * as ValUtil from "../../../util/ValUtil";
import FileObj from "../../vo/FileObj"; import FileObj from "../../vo/FileObj";
import {dealFileName} from './RuleInterface';
import path from 'path'; import path from 'path';
@ -10,45 +12,101 @@ export default class ReplaceRule implements RuleInterface {
*/ */
type: number; type: number;
/** /**
* *
*/ */
source: string; source: string;
/** /**
* *
*/ */
target: string; target: string;
/**
*
*/
regFlag: boolean;
/**
*
*/
regI: boolean;
/**
*
*/
ignorePostfix: boolean;
constructor(data: any) { constructor(data: any) {
this.type = data.type; this.type = data.type;
this.source = data.source; this.source = data.source;
this.target = data.target; this.target = data.target;
this.regFlag = ValUtil.nullToDefault(data.regFlag, false);
this.regI = ValUtil.nullToDefault(data.regI, false);
this.ignorePostfix = ValUtil.nullToDefault(data.ignorePostfix, false);
} }
deal(file: FileObj): void { deal(file: FileObj): void {
let targetStr = this.ignorePostfix ? file.realName : file.name;
let res = this.regFlag ? this.dealReg(targetStr) : this.dealNoReg(targetStr);
dealFileName(file, res, this.ignorePostfix);
}
private dealNoReg(targetStr: string): string {
let start = 0; let start = 0;
let changed = false; let arr: number[] = [];
for (; ;) { for (let i = 0; i < (this.type == 1 ? 1 : 1000); i++) {
let index = this.type == 1 || this.type == 3 ? file.name.indexOf(this.source, start) : file.name.lastIndexOf(this.source); let one = targetStr.indexOf(this.source, start);
if (index > -1) { if (one == -1) {
file.name = file.name.substring(0, index) + this.target + file.name.substring(index + this.source.length);
start = index + this.target.length;
changed = true;
if (this.type != 3) {
break; break;
} }
} else { arr.push(one);
start = one + this.source.length;
}
if (arr.length == 0) {
return targetStr;
}
let res = "";
let needDealArr: number[] = this.type === 1 ? [arr[0]] : this.type === 2 ? [arr[arr.length - 1]] : arr;
let lastIndex = 0;
for (let i = 0; i < needDealArr.length; i++) {
res += targetStr.substring(lastIndex, needDealArr[i]) + this.target;
lastIndex = needDealArr[i] + this.source.length;
}
res += targetStr.substring(lastIndex);
return res;
}
private dealReg(targetStr: string): string {
let templateReg = new RegExp("#\{group(\\d+\)}", "g");
let templateArr: string[][] = [];
while (true) {
let one = templateReg.exec(this.target);
if (one == null) {
break; break;
} }
templateArr.push([one[0], one[1]]);
} }
if (changed) {
file.originName = file.name; let reg = new RegExp(this.source, this.regI ? "g" : "ig");
file.expandName = path.extname(file.name); let arr: RegExpExecArray[] = [];
if (file.expandName && file.expandName.length > 0) { for (let i = 0; i < (this.type == 1 ? 1 : 1000); i++) {
file.realName = file.name.substring(0, file.name.lastIndexOf(".")); let one = reg.exec(targetStr);
} else { if (one == null) {
file.realName = file.name; break;
} }
} arr.push(one);
}
if (arr.length == 0) {
return targetStr;
}
let res = "";
let needDealReg: RegExpExecArray[] = this.type === 1 ? [arr[0]] : this.type === 2 ? [arr[arr.length - 1]] : arr;
let lastIndex = 0;
for (let i = 0; i < needDealReg.length; i++) {
let reg = needDealReg[i];
let target = this.target;
templateArr.forEach(item => target = target.replace(item[0], ValUtil.nullToDefault(reg[parseInt(item[1])], '')));
res += targetStr.substring(lastIndex, reg.index) + target;
lastIndex = reg.index + reg[0].length;
}
res += targetStr.substring(lastIndex);
return res;
} }
} }

View File

@ -1,6 +1,27 @@
import FileObj from "../../vo/FileObj"; import FileObj from "../../vo/FileObj";
import * as path from 'path';
export default interface RuleInterface { export default interface RuleInterface {
deal(file: FileObj): void; deal(file: FileObj): void;
} }
/**
*
* @param file
* @param newFileName
* @param ignorePostfix
*/
export function dealFileName(file: FileObj, newFileName: string, ignorePostfix: boolean) {
if (ignorePostfix) {
file.realName = newFileName;
} else {
file.expandName = path.extname(newFileName);
if (file.expandName.length > 0) {
file.realName = newFileName.substring(0, newFileName.lastIndexOf("."));
} else {
file.realName = newFileName;
}
}
file.name = file.realName + file.expandName;
}

View File

@ -3,21 +3,22 @@ import {isVideo, isSub, isNfo} from "../../util/MediaUtil"
export default class FileObj { export default class FileObj {
/** /**
* * ()
*/ */
name: string; name: string;
/** /**
* ()
*/
realName: string;
/**
()
*/ */
originName: string; originName: string;
/** /**
* * ()
*/ */
expandName: string; expandName: string;
/**
*
*/
realName: string;
/** /**
* *
*/ */

View File

@ -0,0 +1,8 @@
/**
* null to default
* @param value
* @param defaultVal
*/
export function nullToDefault(value: any, defaultVal: any): any {
return value === undefined || value == null ? defaultVal : value;
}

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@ export default {
name: "Home", name: "Home",
data() { data() {
return { return {
version: "1.7.1", version: "1.8.0",
latestVersion: null, latestVersion: null,
activeIndex: location.pathname, activeIndex: location.pathname,
showNewVersion: false showNewVersion: false

View File

@ -12,6 +12,10 @@
<el-radio v-model="ruleObj.data.start.type" label="text" :disabled="deleteAll">文本:</el-radio> <el-radio v-model="ruleObj.data.start.type" label="text" :disabled="deleteAll">文本:</el-radio>
<el-input v-model="startText" size="small" :disabled="deleteAll"/> <el-input v-model="startText" size="small" :disabled="deleteAll"/>
</div> </div>
<div class="line">
<el-radio v-model="ruleObj.data.start.type" label="reg" :disabled="deleteAll">正则:</el-radio>
<el-input v-model="startReg" size="small" :disabled="deleteAll"/>
</div>
</div> </div>
<div style="margin-left: 4em"> <div style="margin-left: 4em">
<div>结束</div> <div>结束</div>
@ -23,12 +27,20 @@
<el-radio v-model="ruleObj.data.end.type" label="text" :disabled="deleteAll">文本:</el-radio> <el-radio v-model="ruleObj.data.end.type" label="text" :disabled="deleteAll">文本:</el-radio>
<el-input v-model="endText" size="small" :disabled="deleteAll"/> <el-input v-model="endText" size="small" :disabled="deleteAll"/>
</div> </div>
<div class="line">
<el-radio v-model="ruleObj.data.end.type" label="reg" :disabled="deleteAll">正则:</el-radio>
<el-input v-model="endReg" size="small" :disabled="deleteAll"/>
</div>
<div class="line"> <div class="line">
<el-radio v-model="ruleObj.data.end.type" label="end" :disabled="deleteAll">直到末尾</el-radio> <el-radio v-model="ruleObj.data.end.type" label="end" :disabled="deleteAll">直到末尾</el-radio>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div v-if="ruleObj.data.start.type==='reg' || ruleObj.data.end.type==='reg'" class="flex">
<div class="left">区分大小写:</div>
<el-switch v-model="ruleObj.data.regI"/>
</div>
<div class="flex"> <div class="flex">
<div class="left">全部删除:</div> <div class="left">全部删除:</div>
<el-switch v-model="deleteAll" @change="allDeleteChange"/> <el-switch v-model="deleteAll" @change="allDeleteChange"/>
@ -60,28 +72,36 @@ export default {
value: "", value: "",
}, },
ignorePostfix: true, ignorePostfix: true,
regI: false,//reg
}, },
}, },
startIndex: 1, startIndex: 1,
endIndex: 1, endIndex: 1,
startText: "", startText: "",
startReg: "",
endText: "", endText: "",
endReg: "",
deleteAll: false, deleteAll: false,
}; };
}, },
created() { created() {
if (this.editRule) { if (this.editRule) {
this.ruleObj = JSON.parse(JSON.stringify(this.editRule)); this.ruleObj = JSON.parse(JSON.stringify(this.editRule));
if (this.ruleObj.data.type == "deletePart") { if (this.ruleObj.data.type === "deletePart") {
if (this.ruleObj.data.start.type == "location") { if (this.ruleObj.data.start.type === "location") {
this.startIndex = parseInt(this.ruleObj.data.start.value); this.startIndex = parseInt(this.ruleObj.data.start.value);
} else { } else if (this.ruleObj.data.start.type === "text") {
this.startText = this.ruleObj.data.start.value; this.startText = this.ruleObj.data.start.value;
}
if (this.ruleObj.data.end.type == "location") {
this.endIndex = parseInt(this.ruleObj.data.end.value);
} else { } else {
this.startReg = this.ruleObj.data.start.value;
}
if (this.ruleObj.data.end.type === "location") {
this.endIndex = parseInt(this.ruleObj.data.end.value);
} else if (this.ruleObj.data.end.type === "text") {
this.endText = this.ruleObj.data.end.value; this.endText = this.ruleObj.data.end.value;
} else {
this.endReg = this.ruleObj.data.end.value;
} }
} else { } else {
this.deleteAll = true; this.deleteAll = true;
@ -94,10 +114,12 @@ export default {
this.$message({message: "请填写完整", type: "warning"}); this.$message({message: "请填写完整", type: "warning"});
return null; return null;
} }
if (this.ruleObj.data.type == "deletePart") { if (this.ruleObj.data.type === "deletePart") {
if ( if (
(this.ruleObj.data.start.type == "text" && this.startText.length == 0) || ('text' === this.ruleObj.data.start.type && this.startText.length === 0) ||
(this.ruleObj.data.start.type == "text" && this.startText.length == 0) ('text' === this.ruleObj.data.end.type && this.endText.length === 0) ||
('reg' === this.ruleObj.data.start.type && this.startReg.length === 0) ||
('reg' === this.ruleObj.data.end.type && this.endReg.length === 0)
) { ) {
this.$message({ this.$message({
message: "开始或者结束文本不能为空", message: "开始或者结束文本不能为空",
@ -106,19 +128,20 @@ export default {
return null; return null;
} }
} }
this.ruleObj.data.start.value = this.ruleObj.data.start.type == "location" ? this.startIndex.toString() : this.startText; let startType = this.ruleObj.data.start.type;
this.ruleObj.data.end.value = this.ruleObj.data.end.type == "location" ? this.endIndex.toString() : this.endText; this.ruleObj.data.start.value = startType === "location" ? this.startIndex.toString() : startType === 'text' ? this.startText : this.startReg;
let endType = this.ruleObj.data.end.type;
this.ruleObj.data.end.value = endType === "location" ? this.endIndex.toString() : endType === 'text' ? this.endText : this.endReg;
let message = `删除:`; let message = `删除:`;
if (this.deleteAll) { if (this.deleteAll) {
message += "全部删除"; message += "全部删除";
} else { } else {
message += `从"${this.ruleObj.data.start.value}"到"${this.ruleObj.data.end.type == "untilEnd" ? "末尾" : this.ruleObj.data.end.value}"`; message += `从"${this.ruleObj.data.start.value}"到"${this.ruleObj.data.end.type === "end" ? "末尾" : this.ruleObj.data.end.value}"`;
} }
this.ruleObj.message = message; this.ruleObj.message = message;
return this.ruleObj; return this.ruleObj;
}, },
allDeleteChange(val) { allDeleteChange(val) {
console.log(val);
this.deleteAll = val; this.deleteAll = val;
this.ruleObj.data.type = val ? "deleteAll" : "deletePart"; this.ruleObj.data.type = val ? "deleteAll" : "deletePart";
}, },

View File

@ -7,37 +7,57 @@
<span class="left">目标</span> <span class="left">目标</span>
<el-input style="width:20em" v-model="ruleObj.data.target" /> <el-input style="width:20em" v-model="ruleObj.data.target" />
</div> </div>
<div class="flex">
<div class="left">正则模式:</div>
<el-switch v-model="ruleObj.data.regFlag" />
<el-tooltip effect="dark" :content="regTip" placement="right">
<el-icon>
<InfoFilled />
</el-icon>
</el-tooltip>
</div>
<div class="flex">
<div class="left">区分大小写:</div>
<el-switch v-model="ruleObj.data.regI" />
</div>
<div class="flex"> <div class="flex">
<span class="left">替换选项</span> <span class="left">替换选项</span>
<div class="location"> <div class="location">
<el-radio v-for="item in radioList" :key="item.code" v-model="ruleObj.data.type" :label="item.code" <el-radio v-for="item in radioList" :key="item.code" v-model="ruleObj.data.type" :label="item.code"
>{{ item.label }} >{{ item.label }}
</el-radio> </el-radio>
</div> </div>
</div> </div>
<div class="flex">
<div class="left">忽略拓展名:</div>
<el-switch v-model="ruleObj.data.ignorePostfix"/>
</div>
</template> </template>
<script> <script>
import { InfoFilled } from "@element-plus/icons-vue";
import { nullToDefault } from "@/utils/ValUtil";
export default { export default {
name: "ReplaceRule", name: "ReplaceRule",
components: { InfoFilled },
props: ["editRule"], props: ["editRule"],
data() { data() {
return { return {
regTip: `开启支持js正则匹配支持分组匹配,目标字符串支持模板#{groupN},N表示匹配到的第几组。比如#{group1}将被替换为匹配到的第一组数据`,
radioList: [ radioList: [
{ {
label: "替换第一个", label: "替换第一个",
code: 1, code: 1
}, },
{ {
label: "替换最后一个", label: "替换最后一个",
code: 2, code: 2
}, },
{ {
label: "全部替换", label: "全部替换",
code: 3, code: 3
}, }
], ],
ruleObj: { ruleObj: {
type: "replace", type: "replace",
@ -46,14 +66,20 @@ export default {
source: "", source: "",
target: "", target: "",
type: 1, //1:23 type: 1, //1:23
}, ignorePostfix: true, //
}, regFlag: false, //
regI: false //
}
}
}; };
}, },
created() { created() {
if (this.editRule) { if (this.editRule) {
console.log(this.editRule); console.log(this.editRule);
this.ruleObj = JSON.parse(JSON.stringify(this.editRule)); this.ruleObj = JSON.parse(JSON.stringify(this.editRule));
//
this.ruleObj.data.ignorePostfix = nullToDefault(this.ruleObj.data.ignorePostfix, true);
this.ruleObj.data.regFlag = nullToDefault(this.ruleObj.data.regFlag, false);
} }
}, },
methods: { methods: {
@ -69,8 +95,8 @@ export default {
this.ruleObj.message = `替换:将${this.ruleObj.data.source}替换为${this.ruleObj.data.target};` this.ruleObj.message = `替换:将${this.ruleObj.data.source}替换为${this.ruleObj.data.target};`
+ this.radioList.filter(item => item.code === this.ruleObj.data.type)[0].label; + this.radioList.filter(item => item.code === this.ruleObj.data.type)[0].label;
return this.ruleObj; return this.ruleObj;
}, }
}, }
}; };
</script> </script>

View File

@ -0,0 +1,9 @@
/**
* 空转default
* @param val
* @param defaultVal
* @returns {*}
*/
export function nullToDefault(val, defaultVal) {
return val === undefined || val == null ? defaultVal : val;
}