- 首次运行会生成一个json文件,保存磁盘中的文件信息
Last active
April 18, 2021 11:05
-
-
Save heLomaN/139d698ac8c87702bf6fb907c73e3992 to your computer and use it in GitHub Desktop.
A simple tool to view fusion folder content on windows with pyqt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QListWidget | |
from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QTextEdit, QPushButton, QLineEdit, QCheckBox, QComboBox, QLabel | |
from PyQt5 import QtGui, QtCore | |
from collections import OrderedDict | |
# list all folder with depth 2 then save | |
# gen app command : pyinstaller --noconsole -F PTBrowserSimple.py | |
import os, sys | |
import json, re | |
def is_target_folder(sub_path): | |
return "col_" in sub_path or "fstore" in sub_path | |
def get_folder_scan_depth(sub_path): | |
return 6 if "col_book" in sub_path else 3 | |
global_valid_entries = [] | |
def collect_path(sub_path, depth): | |
res = [] | |
if depth <= 0: | |
res.append(sub_path) | |
else: | |
for entry in os.scandir(sub_path): | |
if os.access(entry, os.R_OK) and os.path.isdir(entry): | |
res += collect_path(entry.path, depth - 1) | |
res.append(entry.path) | |
return res | |
def glob_folders(top_path): | |
if not os.access(top_path, os.R_OK): | |
return | |
for entry in os.scandir(top_path): | |
if os.access(entry, os.R_OK) and is_target_folder(entry.path): | |
scan_depth = get_folder_scan_depth(entry.path) | |
global global_valid_entries | |
global_valid_entries += collect_path(entry.path, scan_depth) | |
# only match first matched | |
category_mapping = OrderedDict ( | |
[ | |
("col_book", "Book"), | |
("col_atv", "Atv"), | |
("fstore", "Atv"), | |
("col_course", "Course"), | |
("col_movie", "Movie"), | |
("col_music", "Music"), | |
("col_game", "Game"), | |
("col_tv", "TV"), | |
("col_soft", "Software"), | |
("col_pic", "Picture"), | |
("col_", "Other") | |
]) | |
def split_categories(all_paths): | |
seperated_lists = {} | |
for kvp in category_mapping.values(): | |
seperated_lists[kvp] = [] | |
for sp in all_paths: | |
for kvp in category_mapping.items(): | |
if kvp[0] in sp: | |
seperated_lists[kvp[1]].append(sp) | |
break | |
return seperated_lists | |
class MainWindow(QMainWindow): | |
def __init__(self, data, parent=None): | |
super(MainWindow, self).__init__(parent) | |
self.data = data | |
self.category_data = split_categories(data) | |
self.setWindowTitle('PTBrowser') | |
toolbar = QHBoxLayout() | |
self.category_select = QComboBox() | |
self.category_select.addItems(self.category_data.keys()) | |
self.category_select.currentTextChanged.connect(self.on_switch_category) | |
search_text = QLineEdit("") | |
search_text.setPlaceholderText("pattern") | |
search_text.setMaximumSize(400, 30) | |
self.search_text = search_text | |
search_btn = QPushButton("Refresh Search") | |
search_btn.pressed.connect(self.on_search) | |
search_text.editingFinished.connect(self.on_search) | |
self.normal_or_re = QCheckBox("Regex") | |
self.search_info = QLabel(" ") | |
toolbar.addWidget(self.category_select) | |
toolbar.addWidget(self.normal_or_re) | |
toolbar.addWidget(search_text) | |
toolbar.addWidget(search_btn) | |
toolbar.addWidget(self.search_info) | |
toolbar.setAlignment(QtCore.Qt.AlignLeft) | |
path_list = QListWidget() | |
path_list.doubleClicked.connect(self.item_double_click) | |
path_list.setUniformItemSizes(True) | |
self.path_list = path_list | |
top_layout = QVBoxLayout() | |
top_layout.addLayout(toolbar, 0) | |
top_layout.addWidget(path_list, 10) | |
widget = QWidget() | |
widget.setLayout(top_layout) | |
self.setCentralWidget(widget) | |
self.category_select.setCurrentText("Book") | |
self.on_switch_category("Book") | |
def on_switch_category(self, text): | |
self.path_list.clear() | |
self.path_list.addItems(self.category_data[text]) | |
self.search_info.setText("Valid: {}".format(self.path_list.count())) | |
def on_search(self): | |
text = self.search_text.text().lower() | |
try: | |
re_obj = re.compile(".*" + text + ".*", re.UNICODE) | |
except Exception as e: | |
print(e) | |
return | |
valid_items_count = 0 | |
for idx in range(self.path_list.count()): | |
item = self.path_list.item(idx) | |
current = item.text().lower() | |
if self.normal_or_re.isChecked(): | |
not_visible = not re_obj.search(current) | |
else: | |
not_visible = not text in current | |
item.setHidden(not_visible) | |
if not not_visible: | |
valid_items_count += 1 | |
self.search_info.setText("Valid: {}".format(valid_items_count)) | |
def item_double_click(self, index): | |
item = self.path_list.itemFromIndex(index) | |
QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(item.text())) | |
def prepare_data(): | |
global global_valid_entries | |
try: | |
with open("data-cache.json", encoding="utf-8") as f: | |
data = f.read() | |
global_valid_entries = json.loads(data) | |
except Exception as e: | |
pass | |
if not global_valid_entries: | |
valid_disk_sections = 'FGHIJKLMNOPQRSTUVWXYZ' | |
for letter in valid_disk_sections: | |
glob_folders("{}:\\".format(letter)) | |
with open("PTBrowserSimple-data-cache.json", "w", encoding='utf-8') as jsonfile: | |
json.dump(global_valid_entries, jsonfile, ensure_ascii=False) | |
global_valid_entries.sort(key = lambda x : x[2:] if len(x) > 2 else "0") | |
if __name__ == "__main__": | |
prepare_data() | |
app = QApplication(sys.argv) | |
w = MainWindow(global_valid_entries) | |
w.showMaximized() | |
sys.exit(app.exec_()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A tool for which have a lot of disks, especially PT. With which we can view files without care of partitions.
For example:
Desc:
'GHIJKLMNOPQRSTUVWXYZ' : means disk partitions to fusion
"col_" in sub_path or "fstore" in sub_path: here I only want fusion top folders with name "col_". Modify it as your wish.