Add regex-based path preprocessing for playlist sync
This commit is contained in:
@@ -144,4 +144,78 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-4">
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-column flex-lg-row align-items-lg-center gap-3 mb-3">
|
||||
<div>
|
||||
<h5 class="card-title mb-0">路径正则替换</h5>
|
||||
<small class="text-body-secondary">同步前按顺序处理每一首歌曲的路径,解决不同挂载路径的差异</small>
|
||||
</div>
|
||||
</div>
|
||||
<form id="pathRuleForm" method="post" action="/path-rules">
|
||||
<input type="hidden" name="local_path" value="{{ local_path }}">
|
||||
<div id="ruleList" class="d-flex flex-column gap-2 mb-3"></div>
|
||||
<div class="d-flex align-items-center gap-3 mb-3">
|
||||
<button class="btn btn-outline-primary rounded-circle rule-add-btn" type="button" id="addRuleBtn"
|
||||
title="添加新的正则规则">
|
||||
<i class="bi bi-plus-lg"></i>
|
||||
</button>
|
||||
<div class="text-body-secondary small">从上到下依次匹配,左侧填写正则表达式,右侧填写替换结果。</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<button class="btn btn-success" type="submit">
|
||||
<i class="bi bi-save"></i>
|
||||
<span class="ms-1">保存规则</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template id="ruleRowTemplate">
|
||||
<div class="input-group rule-row">
|
||||
<span class="input-group-text">匹配</span>
|
||||
<input type="text" class="form-control" name="pattern" placeholder="正则表达式" required>
|
||||
<span class="input-group-text">替换为</span>
|
||||
<input type="text" class="form-control" name="replacement" placeholder="替换文本">
|
||||
<button class="btn btn-outline-danger" type="button" title="删除此规则">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const existingRules = {{ path_rules | tojson | safe }};
|
||||
const ruleList = document.getElementById('ruleList');
|
||||
const addRuleBtn = document.getElementById('addRuleBtn');
|
||||
const template = document.getElementById('ruleRowTemplate');
|
||||
|
||||
function bindRemoveButton(row) {
|
||||
const removeBtn = row.querySelector('button');
|
||||
removeBtn.addEventListener('click', () => {
|
||||
row.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function addRuleRow(pattern = '', replacement = '') {
|
||||
const clone = template.content.cloneNode(true);
|
||||
const row = clone.querySelector('.rule-row');
|
||||
const [patternInput, replacementInput] = row.querySelectorAll('input');
|
||||
patternInput.value = pattern;
|
||||
replacementInput.value = replacement;
|
||||
bindRemoveButton(row);
|
||||
ruleList.appendChild(clone);
|
||||
}
|
||||
|
||||
addRuleBtn.addEventListener('click', () => addRuleRow());
|
||||
|
||||
if (existingRules.length) {
|
||||
existingRules.forEach(rule => addRuleRow(rule.pattern || '', rule.replacement || ''));
|
||||
}
|
||||
|
||||
if (!ruleList.children.length) {
|
||||
addRuleRow();
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user