200 lines
5.7 KiB
Python
200 lines
5.7 KiB
Python
import os
|
||
import sqlite3
|
||
|
||
from files_sort import GetFilesDBNodeInfo, sort_fragments_by_start_byte
|
||
|
||
|
||
def GetFolderID(
|
||
folder_path: str,
|
||
db_path: str = "../src/db_ntfs_info.db",
|
||
table_name: str = "db_path"
|
||
) -> int | None:
|
||
"""
|
||
根据文件夹路径,查询数据库中该文件夹对应的 ID。
|
||
|
||
:param folder_path: 文件夹路径(如 r"CloudMusic\\")
|
||
:param db_path: 数据库文件路径
|
||
:param table_name: 要查询的数据表名称,默认为 'db_path'
|
||
:return: 成功则返回 ID(int),失败返回 None
|
||
"""
|
||
|
||
conn = sqlite3.connect(db_path)
|
||
cursor = conn.cursor()
|
||
|
||
try:
|
||
# 使用 table_name 构建 SQL 查询
|
||
sql = f"SELECT ID FROM {table_name} WHERE Path = ?"
|
||
cursor.execute(sql, (folder_path,))
|
||
result = cursor.fetchone()
|
||
|
||
if result:
|
||
return result[0]
|
||
else:
|
||
print(f"未找到路径:{folder_path} 在表 {table_name} 中")
|
||
return None
|
||
|
||
except sqlite3.Error as e:
|
||
print(f"数据库操作失败:{e}")
|
||
return None
|
||
|
||
finally:
|
||
conn.close()
|
||
|
||
|
||
def GetSubPathsByParentID(
|
||
parent_id: int,
|
||
db_path: str = "../src/db_ntfs_info.db",
|
||
table_name: str = "db_path"
|
||
) -> list:
|
||
"""
|
||
根据 ParentID 查询 db_path 表中对应的子项(文件/文件夹)。
|
||
|
||
:param parent_id: 父节点 ID
|
||
:param db_path: 数据库文件路径
|
||
:param table_name: 数据表名称
|
||
:return: 包含 ID、Path、Name 的字典列表
|
||
"""
|
||
conn = sqlite3.connect(db_path)
|
||
cursor = conn.cursor()
|
||
|
||
sql = f"""
|
||
SELECT ID, Path, Name
|
||
FROM {table_name}
|
||
WHERE ParentID = ?
|
||
"""
|
||
|
||
try:
|
||
cursor.execute(sql, (parent_id,))
|
||
rows = cursor.fetchall()
|
||
except Exception as e:
|
||
print(f"数据库查询失败:{e}")
|
||
return []
|
||
|
||
results = []
|
||
for row in rows:
|
||
item = {
|
||
'id': row[0],
|
||
'absolute_path': row[1],
|
||
'name': row[2]
|
||
}
|
||
results.append(item)
|
||
|
||
conn.close()
|
||
return results
|
||
|
||
|
||
if __name__ == "__main__":
|
||
test_folder_path = "pictures/"
|
||
parent_id_test = GetFolderID(test_folder_path)
|
||
# node_data = GetNodeFragmentsByParentID(parent_id_test)
|
||
path_data = GetSubPathsByParentID(parent_id_test)
|
||
node_data = GetFilesDBNodeInfo(path_records=path_data)
|
||
for data in node_data:
|
||
print(data)
|
||
|
||
|
||
def GetSortFragmentsByFolderPath(db_path: str = "../src/db_ntfs_info.db", folder_path: str = None) -> list:
|
||
"""
|
||
根据文件夹路径,查询数据库中该文件夹下的所有文件的分片信息。
|
||
:param db_path: 要查询的数据库
|
||
:param folder_path: 文件夹的绝对路径
|
||
:return list: 文件夹下所有文件按片段顺序排列的列表
|
||
"""
|
||
parent_id = GetFolderID(folder_path=folder_path, db_path=db_path)
|
||
path_data = GetSubPathsByParentID(parent_id=parent_id, db_path=db_path)
|
||
node_data = GetFilesDBNodeInfo(path_records=path_data)
|
||
result = sort_fragments_by_start_byte(node_data)
|
||
|
||
return result
|
||
|
||
|
||
# if __name__ == "__main__":
|
||
# folder_path_test = "pictures/"
|
||
# data = GetSortFragmentsByFolderPath(db_path="../src/db_ntfs_info.db", folder_path=folder_path_test)
|
||
# for item in data:
|
||
# print(item)
|
||
|
||
|
||
def ScanDirectory(root_dir, skip_system=True):
|
||
"""
|
||
递归扫描指定目录,返回相对于盘符的路径列表(使用 '/' 分隔),不包含盘符。
|
||
|
||
:param root_dir: 要扫描的根目录路径
|
||
:param skip_system: 是否跳过系统目录(默认 True)
|
||
:return: 文件路径列表,格式为 relative/path/to/file.ext
|
||
"""
|
||
file_list = []
|
||
|
||
for root, dirs, files in os.walk(root_dir):
|
||
# 跳过系统目录
|
||
if skip_system:
|
||
dirs[:] = [d for d in dirs if not d.startswith('$') and d != "System Volume Information"]
|
||
|
||
for file in files:
|
||
full_path = os.path.join(root, file)
|
||
|
||
# 去掉盘符
|
||
_, relative_path = os.path.splitdrive(full_path)
|
||
|
||
# 替换 \ 为 /
|
||
relative_path = relative_path.lstrip("\\").replace("\\", "/")
|
||
|
||
file_list.append(relative_path)
|
||
|
||
return file_list
|
||
|
||
|
||
# if __name__ == "__main__":
|
||
# folder_path = r"Y:/folder1/"
|
||
# files_list = ScanDirectory(folder_path)
|
||
#
|
||
# print(f"共找到 {len(files_list)} 个文件:")
|
||
# for f in files_list:
|
||
# print(f)
|
||
|
||
|
||
def ScanMultiFolders(folder_paths, skip_system=True):
|
||
"""
|
||
扫描多个根目录,返回所有子目录中的文件路径列表。
|
||
|
||
:param folder_paths: 包含多个根目录的列表
|
||
:param skip_system: 是否跳过系统目录(默认 True)
|
||
:return: 所有文件的相对路径列表(格式为 folder/file.ext)
|
||
"""
|
||
all_files = []
|
||
|
||
for root_dir in folder_paths:
|
||
# 确保路径存在
|
||
if not os.path.exists(root_dir):
|
||
print(f"⚠️ 路径不存在:{root_dir}")
|
||
continue
|
||
|
||
for root, dirs, files in os.walk(root_dir):
|
||
# 跳过系统目录
|
||
if skip_system:
|
||
dirs[:] = [d for d in dirs if not d.startswith('$') and d != "System Volume Information"]
|
||
|
||
for file in files:
|
||
full_path = os.path.join(root, file)
|
||
|
||
# 去掉盘符
|
||
_, relative_path = os.path.splitdrive(full_path)
|
||
relative_path = relative_path.lstrip("\\").replace("\\", "/")
|
||
|
||
all_files.append(relative_path)
|
||
|
||
return all_files
|
||
|
||
|
||
if __name__ == "__main__":
|
||
folders = [
|
||
r"Y:\CloudMusic",
|
||
r"Y:\folder1"
|
||
]
|
||
|
||
files = ScanMultiFolders(folders)
|
||
|
||
print(f"共找到 {len(files)} 个文件:")
|
||
for f in files:
|
||
print(f)
|