修改远程文件无法显示的问题(文件夹可以打开)
This commit is contained in:
parent
06a2ab71e6
commit
04499390f1
@ -83,29 +83,80 @@ class BaiduCloud(BaseCloud):
|
||||
return False
|
||||
|
||||
def list_files(self, remote_path: str) -> List[str]:
|
||||
"""
|
||||
获取远程目录的文件列表
|
||||
|
||||
返回格式:
|
||||
- 目录: "D folder_name"
|
||||
- 文件: "F file_name size"
|
||||
"""
|
||||
try:
|
||||
cmd = ["bypy", "list", remote_path]
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cmd,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=120,
|
||||
encoding='utf-8',
|
||||
errors='replace',
|
||||
env=self.utf8_env
|
||||
)
|
||||
|
||||
|
||||
if result.returncode == 0:
|
||||
files = []
|
||||
for line in result.stdout.split('\n'):
|
||||
line = line.strip()
|
||||
if line and not line.startswith('Quota'):
|
||||
files.append(line)
|
||||
output = result.stdout
|
||||
|
||||
# 记录原始输出用于调试
|
||||
self.logger.debug(f"Baidu list raw output:\n{output}")
|
||||
|
||||
# 解析bypy输出
|
||||
lines = output.split('\n')
|
||||
in_file_list = False
|
||||
|
||||
for line in lines:
|
||||
# 跳过空行
|
||||
if not line.strip():
|
||||
continue
|
||||
|
||||
# 跳过警告信息
|
||||
if '<W>' in line or 'WARNING' in line or 'WARN' in line:
|
||||
continue
|
||||
|
||||
# 跳过Quota信息
|
||||
if line.strip().startswith('Quota') or 'Loading quota' in line:
|
||||
continue
|
||||
|
||||
# 跳过表头和分隔符
|
||||
if '($t $f $s $m $d)' in line or line.strip().startswith('/apps/bypy'):
|
||||
in_file_list = True
|
||||
continue
|
||||
|
||||
# 跳过包含特殊字符的格式化行
|
||||
if any(x in line for x in ['<W>', '<P>', '<D>', '<T>', '!0!0!', '>"!!']):
|
||||
continue
|
||||
|
||||
# 如果已经进入文件列表区域,处理文件信息
|
||||
if in_file_list:
|
||||
line = line.strip()
|
||||
|
||||
# bypy的输出可能是多列格式,需要解析
|
||||
# 典型格式: "D folder_name" 或 "F file_name (size)"
|
||||
if line.startswith('D ') or line.startswith('F '):
|
||||
files.append(line)
|
||||
elif line and not line.startswith('-') and not line.startswith('='):
|
||||
# 尝试将行解析为文件信息
|
||||
# 如果行包含文件名,尝试识别类型
|
||||
# 简单判断:如果没有扩展名,可能是目录
|
||||
if '.' not in line or line.count(' ') > 0:
|
||||
# 可能需要更复杂的解析,暂时标记为文件
|
||||
files.append(f"F {line}")
|
||||
|
||||
self.logger.info(f"Parsed {len(files)} files from Baidu: {remote_path}")
|
||||
return files
|
||||
else:
|
||||
self.logger.error(f"Baidu list failed: {result.stderr}")
|
||||
return []
|
||||
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
self.logger.error(f"Baidu list timeout: {remote_path}")
|
||||
return []
|
||||
|
||||
@ -164,7 +164,13 @@ class SyncTab:
|
||||
remote_frame = ttk.LabelFrame(preview_paned, text="远程文件", padding="5")
|
||||
preview_paned.add(remote_frame, weight=1)
|
||||
|
||||
self.remote_tree = ttk.Treeview(remote_frame, show="tree")
|
||||
# 创建带隐藏列的Treeview用于存储元数据
|
||||
self.remote_tree = ttk.Treeview(remote_frame, show="tree", columns=("path", "type", "cloud"))
|
||||
# 隐藏columns(宽度设为0)
|
||||
self.remote_tree.column("path", width=0, stretch=False)
|
||||
self.remote_tree.column("type", width=0, stretch=False)
|
||||
self.remote_tree.column("cloud", width=0, stretch=False)
|
||||
|
||||
remote_scrollbar = ttk.Scrollbar(remote_frame, orient=tk.VERTICAL, command=self.remote_tree.yview)
|
||||
self.remote_tree.configure(yscrollcommand=remote_scrollbar.set)
|
||||
|
||||
@ -174,6 +180,12 @@ class SyncTab:
|
||||
remote_frame.columnconfigure(0, weight=1)
|
||||
remote_frame.rowconfigure(0, weight=1)
|
||||
|
||||
# 绑定双击事件以展开文件夹
|
||||
self.remote_tree.bind('<Double-1>', self._on_remote_item_double_click)
|
||||
|
||||
# 用于跟踪当前远程目录路径(用于导航)
|
||||
self.current_remote_path_stack = []
|
||||
|
||||
# 控制区域
|
||||
control_frame = ttk.Frame(main_frame)
|
||||
control_frame.grid(row=3, column=0, sticky=(tk.W, tk.E), pady=(10, 0))
|
||||
@ -402,6 +414,9 @@ class SyncTab:
|
||||
# 显示加载提示
|
||||
self.log_queue.put(f"🔄 正在加载远程文件: {remote_path}")
|
||||
|
||||
# 保存当前路径
|
||||
self.current_remote_path = remote_path
|
||||
|
||||
def load_worker():
|
||||
try:
|
||||
# 获取所有可用的云盘服务
|
||||
@ -424,6 +439,14 @@ class SyncTab:
|
||||
|
||||
# 在UI线程中更新树形视图
|
||||
def update_tree():
|
||||
# 如果不是根目录,添加"返回上级"选项
|
||||
if remote_path != self.remote_dir_var.get() and '/' in remote_path:
|
||||
parent_path = '/'.join(remote_path.rstrip('/').split('/')[:-1])
|
||||
if not parent_path:
|
||||
parent_path = self.remote_dir_var.get()
|
||||
back_item = self.remote_tree.insert("", "end", text="⬆️ 返回上级目录",
|
||||
values=(parent_path, 'back', ''))
|
||||
|
||||
if not all_files:
|
||||
# 显示"无文件"提示
|
||||
self.remote_tree.insert("", "end", text="📭 远程目录为空或不存在")
|
||||
@ -431,31 +454,57 @@ class SyncTab:
|
||||
|
||||
# 为每个云盘创建一个分类节点
|
||||
for cloud_name, files in all_files.items():
|
||||
cloud_node = self.remote_tree.insert("", "end", text=f"☁️ {cloud_name}", open=True)
|
||||
# 如果只有一个云盘且文件不多,可以不创建云盘节点
|
||||
if len(self.clouds) == 1 and len(files) < 50:
|
||||
parent_node = ""
|
||||
else:
|
||||
cloud_node = self.remote_tree.insert("", "end", text=f"☁️ {cloud_name}",
|
||||
values=('', 'cloud', cloud_name), open=True)
|
||||
parent_node = cloud_node
|
||||
|
||||
# 解析文件列表并添加到树中
|
||||
# 分类存储文件夹和文件
|
||||
folders = []
|
||||
regular_files = []
|
||||
|
||||
# 解析文件列表并分类
|
||||
for file_info in files:
|
||||
# bypy的输出格式可能是 "D 文件夹名" 或 "F 文件名 (大小)"
|
||||
file_info = file_info.strip()
|
||||
|
||||
if not file_info:
|
||||
continue
|
||||
|
||||
# 尝试解析文件类型和名称
|
||||
# 解析文件类型和名称
|
||||
if file_info.startswith('D '):
|
||||
# 目录
|
||||
name = file_info[2:].strip()
|
||||
self.remote_tree.insert(cloud_node, "end", text=f"📁 {name}")
|
||||
folders.append(name)
|
||||
elif file_info.startswith('F '):
|
||||
# 文件
|
||||
parts = file_info[2:].split('(')
|
||||
name = parts[0].strip()
|
||||
size = parts[1].rstrip(')').strip() if len(parts) > 1 else ""
|
||||
display_text = f"📄 {name}" + (f" ({size})" if size else "")
|
||||
self.remote_tree.insert(cloud_node, "end", text=display_text)
|
||||
regular_files.append((name, size))
|
||||
else:
|
||||
# 未知格式,直接显示
|
||||
self.remote_tree.insert(cloud_node, "end", text=f"📄 {file_info}")
|
||||
# 未知格式,尝试直接显示
|
||||
regular_files.append((file_info, ""))
|
||||
|
||||
# 先显示文件夹(按名称排序)
|
||||
for name in sorted(folders):
|
||||
full_path = f"{remote_path.rstrip('/')}/{name}"
|
||||
folder_item = self.remote_tree.insert(
|
||||
parent_node, "end",
|
||||
text=f"📁 {name}",
|
||||
values=(full_path, 'folder', cloud_name)
|
||||
)
|
||||
|
||||
# 再显示文件(按名称排序)
|
||||
for name, size in sorted(regular_files):
|
||||
display_text = f"📄 {name}" + (f" ({size})" if size else "")
|
||||
full_path = f"{remote_path.rstrip('/')}/{name}"
|
||||
file_item = self.remote_tree.insert(
|
||||
parent_node, "end",
|
||||
text=display_text,
|
||||
values=(full_path, 'file', cloud_name)
|
||||
)
|
||||
|
||||
self.log_queue.put("✅ 远程文件列表加载完成")
|
||||
|
||||
@ -473,6 +522,51 @@ class SyncTab:
|
||||
# 在后台线程中加载
|
||||
threading.Thread(target=load_worker, daemon=True).start()
|
||||
|
||||
def _on_remote_item_double_click(self, event):
|
||||
"""处理远程文件树的双击事件"""
|
||||
selection = self.remote_tree.selection()
|
||||
if not selection:
|
||||
return
|
||||
|
||||
item = selection[0]
|
||||
item_data = self.remote_tree.item(item)
|
||||
item_text = item_data.get('text', '')
|
||||
item_values = item_data.get('values', [])
|
||||
|
||||
# 从values中获取路径和类型 (path, type, cloud)
|
||||
if item_values and len(item_values) >= 2:
|
||||
item_path = item_values[0]
|
||||
item_type = item_values[1]
|
||||
else:
|
||||
# 如果没有设置values,尝试从文本判断
|
||||
if item_text.startswith('📁 '):
|
||||
# 这是一个文件夹
|
||||
folder_name = item_text[2:].strip()
|
||||
current_path = getattr(self, 'current_remote_path', self.remote_dir_var.get())
|
||||
item_path = f"{current_path.rstrip('/')}/{folder_name}"
|
||||
item_type = 'folder'
|
||||
elif item_text.startswith('⬆️'):
|
||||
# 返回上级
|
||||
item_type = 'back'
|
||||
current_path = getattr(self, 'current_remote_path', self.remote_dir_var.get())
|
||||
item_path = '/'.join(current_path.rstrip('/').split('/')[:-1]) or self.remote_dir_var.get()
|
||||
else:
|
||||
# 文件或其他,不处理
|
||||
self.log_queue.put(f"ℹ️ 点击的项目不可操作: {item_text}")
|
||||
return
|
||||
|
||||
# 如果是文件夹或返回上级,进入该目录
|
||||
if item_type == 'folder' or item_type == 'back':
|
||||
self.log_queue.put(f"📂 进入目录: {item_path}")
|
||||
self._refresh_remote_tree(item_path)
|
||||
elif item_type == 'file':
|
||||
# 文件双击暂不处理,可以在未来添加下载功能
|
||||
self.log_queue.put(f"ℹ️ 文件双击功能待实现: {item_path}")
|
||||
elif item_type == 'cloud':
|
||||
# 双击云盘节点,不做任何操作
|
||||
pass
|
||||
|
||||
|
||||
def _browse_directory(self):
|
||||
"""向后兼容的方法"""
|
||||
self._browse_and_add_folder()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user