mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-23 23:16:58 +08:00
### What problem does this PR solve? ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: jinhai <haijin.chn@gmail.com> Signed-off-by: Jin Hai <haijin.chn@gmail.com> Co-authored-by: Lynn <lynn_inf@hotmail.com> Co-authored-by: chanx <1243304602@qq.com> Co-authored-by: balibabu <cike8899@users.noreply.github.com> Co-authored-by: 纷繁下的无奈 <zhileihuang@126.com> Co-authored-by: huangzl <huangzl@shinemo.com> Co-authored-by: writinwaters <93570324+writinwaters@users.noreply.github.com> Co-authored-by: Wilmer <33392318@qq.com> Co-authored-by: Adrian Weidig <adrianweidig@gmx.net> Co-authored-by: Zhichang Yu <yuzhichang@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Yongteng Lei <yongtengrey@outlook.com> Co-authored-by: Liu An <asiro@qq.com> Co-authored-by: buua436 <66937541+buua436@users.noreply.github.com> Co-authored-by: BadwomanCraZY <511528396@qq.com> Co-authored-by: cucusenok <31804608+cucusenok@users.noreply.github.com> Co-authored-by: Russell Valentine <russ@coldstonelabs.org> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Billy Bao <newyorkupperbay@gmail.com> Co-authored-by: Zhedong Cen <cenzhedong2@126.com> Co-authored-by: TensorNull <129579691+TensorNull@users.noreply.github.com> Co-authored-by: TensorNull <tensor.null@gmail.com> Co-authored-by: Ajay <160579663+aybanda@users.noreply.github.com> Co-authored-by: AB <aj@Ajays-MacBook-Air.local> Co-authored-by: 天海蒼灆 <huangaoqin@tecpie.com> Co-authored-by: He Wang <wanghechn@qq.com> Co-authored-by: Atsushi Hatakeyama <atu729@icloud.com> Co-authored-by: Jin Hai <haijin.chn@gmail.com> Co-authored-by: Mohamed Mathari <155896313+melmathari@users.noreply.github.com> Co-authored-by: Mohamed Mathari <nocodeventure@Mac-mini-van-Mohamed.fritz.box> Co-authored-by: Stephen Hu <stephenhu@seismic.com> Co-authored-by: Shaun Zhang <zhangwfjh@users.noreply.github.com> Co-authored-by: zhimeng123 <60221886+zhimeng123@users.noreply.github.com> Co-authored-by: mxc <mxc@example.com> Co-authored-by: Dominik Novotný <50611433+SgtMarmite@users.noreply.github.com> Co-authored-by: EVGENY M <168018528+rjohny55@users.noreply.github.com> Co-authored-by: mcoder6425 <mcoder64@gmail.com> Co-authored-by: TeslaZY <TeslaZY@outlook.com> Co-authored-by: lemsn <lemsn@msn.com> Co-authored-by: lemsn <lemsn@126.com> Co-authored-by: Adrian Gora <47756404+adagora@users.noreply.github.com> Co-authored-by: Womsxd <45663319+Womsxd@users.noreply.github.com> Co-authored-by: FatMii <39074672+FatMii@users.noreply.github.com>
100 lines
3.1 KiB
Python
100 lines
3.1 KiB
Python
#
|
|
# Copyright 2024 The InfiniFlow Authors. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
import re
|
|
from pathlib import PurePath
|
|
|
|
from .user_service import UserService as UserService
|
|
|
|
|
|
def _split_name_counter(filename: str) -> tuple[str, int | None]:
|
|
"""
|
|
Splits a filename into main part and counter (if present in parentheses).
|
|
|
|
Args:
|
|
filename: Input filename string to be parsed
|
|
|
|
Returns:
|
|
A tuple containing:
|
|
- The main filename part (string)
|
|
- The counter from parentheses (integer) or None if no counter exists
|
|
"""
|
|
pattern = re.compile(r"^(.*?)\((\d+)\)$")
|
|
|
|
match = pattern.search(filename)
|
|
if match:
|
|
main_part = match.group(1).rstrip()
|
|
bracket_part = match.group(2)
|
|
return main_part, int(bracket_part)
|
|
|
|
return filename, None
|
|
|
|
|
|
def duplicate_name(query_func, **kwargs) -> str:
|
|
"""
|
|
Generates a unique filename by appending/incrementing a counter when duplicates exist.
|
|
|
|
Continuously checks for name availability using the provided query function,
|
|
automatically appending (1), (2), etc. until finding an available name or
|
|
reaching maximum retries.
|
|
|
|
Args:
|
|
query_func: Callable that accepts keyword arguments and returns:
|
|
- True if name exists (should be modified)
|
|
- False if name is available
|
|
**kwargs: Must contain 'name' key with original filename to check
|
|
|
|
Returns:
|
|
str: Available filename, either:
|
|
- Original name (if available)
|
|
- Modified name with counter (e.g., "file(1).txt")
|
|
|
|
Raises:
|
|
KeyError: If 'name' key not provided in kwargs
|
|
RuntimeError: If unable to generate unique name after maximum retries
|
|
|
|
Example:
|
|
>>> def name_exists(name): return name in existing_files
|
|
>>> duplicate_name(name_exists, name="document.pdf")
|
|
'document(1).pdf' # If original exists
|
|
"""
|
|
MAX_RETRIES = 1000
|
|
|
|
if "name" not in kwargs:
|
|
raise KeyError("Arguments must contain 'name' key")
|
|
|
|
original_name = kwargs["name"]
|
|
current_name = original_name
|
|
retries = 0
|
|
|
|
while retries < MAX_RETRIES:
|
|
if not query_func(**kwargs):
|
|
return current_name
|
|
|
|
path = PurePath(current_name)
|
|
stem = path.stem
|
|
suffix = path.suffix
|
|
|
|
main_part, counter = _split_name_counter(stem)
|
|
counter = counter + 1 if counter else 1
|
|
|
|
new_name = f"{main_part}({counter}){suffix}"
|
|
|
|
kwargs["name"] = new_name
|
|
current_name = new_name
|
|
retries += 1
|
|
|
|
raise RuntimeError(f"Failed to generate unique name within {MAX_RETRIES} attempts. Original: {original_name}")
|