feat:tkinter
This commit is contained in:
parent
af0fd78c09
commit
e8a33f28e4
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@ -8,6 +8,7 @@ on:
|
||||
- master
|
||||
- dev
|
||||
- gd
|
||||
- gd-test
|
||||
jobs:
|
||||
push:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
|
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
@ -26,13 +26,13 @@ jobs:
|
||||
run: pipenv install pyinstaller
|
||||
|
||||
- name: Build the application
|
||||
run: pipenv run pyinstaller --onefile --windowed --add-data demo.txt:. --add-data config.py:. --add-data fofa_map.py:. --add-data main.py:. --add-data utils.py:. --name update-tool tkinter_ui.py
|
||||
run: pipenv run pyinstaller tkinter_ui.spec
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: update-tool
|
||||
path: dist/tkinter_ui
|
||||
path: dist/update-tool.exe
|
||||
|
||||
- name: Install jq
|
||||
run: sudo apt-get install jq
|
||||
@ -59,3 +59,13 @@ jobs:
|
||||
body: ${{ fromJSON(env.changelog) }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: Upload Release Asset
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./dist/update-tool.exe
|
||||
asset_name: update-tool.exe
|
||||
asset_content_type: application/octet-stream
|
||||
|
1
Pipfile
1
Pipfile
@ -19,6 +19,7 @@ aiohttp = ">=3.9.4"
|
||||
bs4 = ">=0.0.2"
|
||||
tqdm = ">=4.66.3"
|
||||
async-timeout = ">=4.0.3"
|
||||
pyinstaller = "*"
|
||||
|
||||
[requires]
|
||||
python_version = ">=3.11"
|
||||
|
76
Pipfile.lock
generated
76
Pipfile.lock
generated
@ -1,11 +1,11 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "8bcaa60bc11c1b7a2f0403744cfa8cf993bcbc3edb74caa34cb8b4446d96b36d"
|
||||
"sha256": "1d2e1a0c3c519496b2182c0a06934b3805decf830897194c0987ad52521c472d"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": ">=3.11"
|
||||
"python_version": ">=3.6"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
@ -107,6 +107,13 @@
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.3.1"
|
||||
},
|
||||
"altgraph": {
|
||||
"hashes": [
|
||||
"sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406",
|
||||
"sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"
|
||||
],
|
||||
"version": "==0.17.4"
|
||||
},
|
||||
"async-timeout": {
|
||||
"hashes": [
|
||||
"sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f",
|
||||
@ -522,6 +529,22 @@
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.3.0.post0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
|
||||
"sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==24.0"
|
||||
},
|
||||
"pefile": {
|
||||
"hashes": [
|
||||
"sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc",
|
||||
"sha256:da185cd2af68c08a6cd4481f7325ed600a88f6a813bad9dea07ab3ef73d8d8d6"
|
||||
],
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==2023.2.7"
|
||||
},
|
||||
"pycparser": {
|
||||
"hashes": [
|
||||
"sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6",
|
||||
@ -530,6 +553,33 @@
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==2.22"
|
||||
},
|
||||
"pyinstaller": {
|
||||
"hashes": [
|
||||
"sha256:000c36b13fe4cd8d0d8c2bc855b1ddcf39867b5adf389e6b5ca45b25fa3e619d",
|
||||
"sha256:1c3060a263758cf7f0144ab4c016097b20451b2469d468763414665db1bb743d",
|
||||
"sha256:2b71509468c811968c0b5decb5bbe85b6292ea52d7b1f26313d2aabb673fa9a5",
|
||||
"sha256:355832a3acc7de90a255ecacd4b9f9e166a547a79c8905d49f14e3a75c1acdb9",
|
||||
"sha256:39ac424d2ee2457d2ab11a5091436e75a0cccae207d460d180aa1fcbbafdd528",
|
||||
"sha256:3f4b6520f4423fe19bcc2fd63ab7238851ae2bdcbc98f25bc5d2f97cc62012e9",
|
||||
"sha256:5ff6bc2784c1026f8e2f04aa3760cbed41408e108a9d4cf1dd52ee8351a3f6e1",
|
||||
"sha256:6303c7a009f47e6a96ef65aed49f41e36ece8d079b9193ca92fe807403e5fe80",
|
||||
"sha256:81cccfa9b16699b457f4788c5cc119b50f3cd4d0db924955f15c33f2ad27a50d",
|
||||
"sha256:d257f6645c7334cbd66f38a4fac62c3ad614cc46302b2b5d9f8cc48c563bce0e",
|
||||
"sha256:fe0af018d7d5077180e3144ada89a4da5df8d07716eb7e9482834a56dc57a4e8",
|
||||
"sha256:ff31c5b99e05a4384bbe2071df67ec8b2b347640a375eae9b40218be2f1754c6"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version < '3.13' and python_version >= '3.8'",
|
||||
"version": "==6.8.0"
|
||||
},
|
||||
"pyinstaller-hooks-contrib": {
|
||||
"hashes": [
|
||||
"sha256:8bf0775771fbaf96bcd2f4dfd6f7ae6c1dd1b1efe254c7e50477b3c08e7841d8",
|
||||
"sha256:fd5f37dcf99bece184e40642af88be16a9b89613ecb958a8bd1136634fc9fac5"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2024.7"
|
||||
},
|
||||
"pysocks": {
|
||||
"hashes": [
|
||||
"sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299",
|
||||
@ -546,6 +596,14 @@
|
||||
"index": "pypi",
|
||||
"version": "==2024.1"
|
||||
},
|
||||
"pywin32-ctypes": {
|
||||
"hashes": [
|
||||
"sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60",
|
||||
"sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"
|
||||
],
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==0.2.2"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760",
|
||||
@ -572,6 +630,14 @@
|
||||
"markers": "python_version >= '3' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==1.0.6"
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4",
|
||||
"sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==70.0.0"
|
||||
},
|
||||
"sgmllib3k": {
|
||||
"hashes": [
|
||||
"sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9"
|
||||
@ -628,11 +694,11 @@
|
||||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a",
|
||||
"sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"
|
||||
"sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
|
||||
"sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.12.1"
|
||||
"version": "==4.12.2"
|
||||
},
|
||||
"urllib3": {
|
||||
"extras": [
|
||||
|
27
main.py
27
main.py
@ -146,15 +146,8 @@ class UpdateSource:
|
||||
)
|
||||
|
||||
def write_channel_to_file(self):
|
||||
total = len(
|
||||
[
|
||||
name
|
||||
for channel_obj in self.channel_data.values()
|
||||
for name in channel_obj.keys()
|
||||
]
|
||||
)
|
||||
self.pbar = tqdm(total=total)
|
||||
self.pbar.set_description(f"Writing, {total} channels remaining")
|
||||
self.pbar = tqdm(total=self.total)
|
||||
self.pbar.set_description(f"Writing, {self.total} channels remaining")
|
||||
self.start_time = time()
|
||||
for cate, channel_obj in self.channel_items.items():
|
||||
for name in channel_obj.keys():
|
||||
@ -243,6 +236,7 @@ class UpdateSource:
|
||||
update_file(user_log_file, "result_new.log")
|
||||
print(f"Update completed! Please check the {user_final_file} file!")
|
||||
self.update_progress(f"更新完成, 请检查{user_final_file}文件", 100, True)
|
||||
self.stop()
|
||||
except asyncio.exceptions.CancelledError:
|
||||
print("Update cancelled!")
|
||||
|
||||
@ -258,11 +252,16 @@ class UpdateSource:
|
||||
format="%(message)s",
|
||||
level=logging.INFO,
|
||||
)
|
||||
loop = asyncio.get_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
self.thread = threading.Thread(
|
||||
target=loop.run_until_complete, args=(self.main(),)
|
||||
)
|
||||
|
||||
def run_loop():
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
try:
|
||||
loop.run_until_complete(self.main())
|
||||
finally:
|
||||
loop.close()
|
||||
|
||||
self.thread = threading.Thread(target=run_loop, daemon=True)
|
||||
self.thread.start()
|
||||
if not self.run_ui:
|
||||
self.thread.join()
|
||||
|
128
tkinter_ui.py
128
tkinter_ui.py
@ -23,6 +23,31 @@ class TkinterUI:
|
||||
self.root.title("直播源接口更新工具")
|
||||
self.update_source = UpdateSource()
|
||||
self.update_running = False
|
||||
self.config_entrys = [
|
||||
"source_file_entry",
|
||||
"source_file_button",
|
||||
"final_file_entry",
|
||||
"final_file_button",
|
||||
"open_subscribe_checkbutton",
|
||||
"open_multicast_checkbutton",
|
||||
"open_online_search_checkbutton",
|
||||
"open_sort_checkbutton",
|
||||
"favorite_list_text",
|
||||
"favorite_page_num_entry",
|
||||
"default_page_num_entry",
|
||||
"urls_limit_entry",
|
||||
"response_time_weight_entry",
|
||||
"resolution_weight_entry",
|
||||
"ipv_type_combo",
|
||||
"recent_days_entry",
|
||||
"domain_blacklist_text",
|
||||
"url_keywords_blacklist_text",
|
||||
"subscribe_urls_text",
|
||||
"region_list_text",
|
||||
]
|
||||
|
||||
def format_list(self, text):
|
||||
return [f"{item.strip()}" for item in text.split(",") if item.strip()]
|
||||
|
||||
def select_source_file(self):
|
||||
filepath = filedialog.askopenfilename(
|
||||
@ -31,7 +56,7 @@ class TkinterUI:
|
||||
if filepath:
|
||||
self.source_file_entry.delete(0, tk.END)
|
||||
self.source_file_entry.insert(0, filepath)
|
||||
self.save_config(False)
|
||||
config.source_file = f'"{filepath}"'
|
||||
|
||||
def select_final_file(self):
|
||||
filepath = filedialog.askopenfilename(
|
||||
@ -40,12 +65,70 @@ class TkinterUI:
|
||||
if filepath:
|
||||
self.final_file_entry.delete(0, tk.END)
|
||||
self.final_file_entry.insert(0, filepath)
|
||||
self.save_config(False)
|
||||
config.final_file = f'"{filepath}"'
|
||||
|
||||
def format_list(self, text):
|
||||
return [f"{item.strip()}" for item in text.split(",") if item.strip()]
|
||||
def update_open_subscribe(self):
|
||||
config.open_subscribe = self.open_subscribe_var.get()
|
||||
|
||||
def save_config(self, tip=True):
|
||||
def update_open_multicast(self):
|
||||
config.open_multicast = self.open_multicast_var.get()
|
||||
|
||||
def update_open_online_search(self):
|
||||
config.open_online_search = self.open_online_search_var.get()
|
||||
|
||||
def update_open_sort(self):
|
||||
config.open_sort = self.open_sort_var.get()
|
||||
|
||||
def update_favorite_list(self, event):
|
||||
config.favorite_list = self.format_list(
|
||||
self.favorite_list_text.get(1.0, tk.END)
|
||||
)
|
||||
|
||||
def update_favorite_page_num(self, event):
|
||||
config.favorite_page_num = self.favorite_page_num_entry.get()
|
||||
|
||||
def update_default_page_num(self, event):
|
||||
config.default_page_num = self.default_page_num_entry.get()
|
||||
|
||||
def update_urls_limit(self, event):
|
||||
config.urls_limit = self.urls_limit_entry.get()
|
||||
|
||||
def update_response_time_weight(self, event):
|
||||
config.response_time_weight = self.response_time_weight_entry.get()
|
||||
|
||||
def update_resolution_weight(self, event):
|
||||
config.resolution_weight = self.resolution_weight_entry.get()
|
||||
|
||||
def update_ipv_type(self, event):
|
||||
config.ipv_type = f'"{self.ipv_type_combo.get()}"'
|
||||
|
||||
def update_recent_days(self, event):
|
||||
config.recent_days = self.recent_days_entry.get()
|
||||
|
||||
def update_url_keywords_blacklist(self, event):
|
||||
config.url_keywords_blacklist = self.format_list(
|
||||
self.url_keywords_blacklist_text.get(1.0, tk.END)
|
||||
)
|
||||
|
||||
def update_domain_blacklist(self, event):
|
||||
config.domain_blacklist = self.format_list(
|
||||
self.domain_blacklist_text.get(1.0, tk.END)
|
||||
)
|
||||
|
||||
def update_url_keywords_blacklist(self, event):
|
||||
config.url_keywords_blacklist = self.format_list(
|
||||
self.url_keywords_blacklist_text.get(1.0, tk.END)
|
||||
)
|
||||
|
||||
def update_subscribe_urls(self, event):
|
||||
config.subscribe_urls = self.format_list(
|
||||
self.subscribe_urls_text.get(1.0, tk.END)
|
||||
)
|
||||
|
||||
def update_region_list(self, event):
|
||||
config.region_list = self.format_list(self.region_list_text.get(1.0, tk.END))
|
||||
|
||||
def save_config(self):
|
||||
config_values = {
|
||||
"source_file": f'"{self.source_file_entry.get()}"',
|
||||
"final_file": f'"{self.final_file_entry.get()}"',
|
||||
@ -78,16 +161,19 @@ class TkinterUI:
|
||||
user_config_file = (
|
||||
"user_config.py" if os.path.exists("user_config.py") else "config.py"
|
||||
)
|
||||
with open(resource_path(user_config_file, True), "w", encoding="utf-8") as f:
|
||||
with open(
|
||||
resource_path(user_config_file, persistent=True), "w", encoding="utf-8"
|
||||
) as f:
|
||||
for key, value in config_values.items():
|
||||
f.write(f"{key} = {value}\n")
|
||||
if tip:
|
||||
messagebox.showinfo("提示", "保存成功")
|
||||
messagebox.showinfo("提示", "保存成功")
|
||||
|
||||
def run_update(self):
|
||||
self.update_running = not self.update_running
|
||||
if self.update_running:
|
||||
self.run_button.config(text="取消更新", state="normal")
|
||||
for entry in self.config_entrys:
|
||||
getattr(self, entry).config(state="disabled")
|
||||
self.progress_bar["value"] = 0
|
||||
self.progress_label.pack()
|
||||
self.progress_bar.pack()
|
||||
@ -95,6 +181,8 @@ class TkinterUI:
|
||||
else:
|
||||
self.update_source.stop()
|
||||
self.run_button.config(text="开始更新", state="normal")
|
||||
for entry in self.config_entrys:
|
||||
getattr(self, entry).config(state="normal")
|
||||
self.progress_bar.pack_forget()
|
||||
self.progress_label.pack_forget()
|
||||
|
||||
@ -104,6 +192,9 @@ class TkinterUI:
|
||||
self.root.update()
|
||||
if finished:
|
||||
self.run_button.config(text="开始更新", state="normal")
|
||||
self.update_running = False
|
||||
for entry in self.config_entrys:
|
||||
getattr(self, entry).config(state="normal")
|
||||
|
||||
def init_UI(self):
|
||||
|
||||
@ -123,6 +214,7 @@ class TkinterUI:
|
||||
variable=self.open_subscribe_var,
|
||||
onvalue=True,
|
||||
offvalue=False,
|
||||
command=self.update_open_subscribe,
|
||||
)
|
||||
self.open_subscribe_checkbutton.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
|
||||
@ -135,6 +227,7 @@ class TkinterUI:
|
||||
variable=self.open_multicast_var,
|
||||
onvalue=True,
|
||||
offvalue=False,
|
||||
command=self.update_open_multicast,
|
||||
)
|
||||
self.open_multicast_checkbutton.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
|
||||
@ -156,6 +249,7 @@ class TkinterUI:
|
||||
variable=self.open_online_search_var,
|
||||
onvalue=True,
|
||||
offvalue=False,
|
||||
command=self.update_open_online_search,
|
||||
)
|
||||
self.open_online_search_checkbutton.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
|
||||
@ -168,6 +262,7 @@ class TkinterUI:
|
||||
variable=self.open_sort_var,
|
||||
onvalue=True,
|
||||
offvalue=False,
|
||||
command=self.update_open_sort,
|
||||
)
|
||||
self.open_sort_checkbutton.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
|
||||
@ -210,6 +305,7 @@ class TkinterUI:
|
||||
side=tk.LEFT, padx=4, pady=4, expand=True, fill=tk.BOTH
|
||||
)
|
||||
self.favorite_list_text.insert(tk.END, ",".join(config.favorite_list))
|
||||
self.favorite_list_text.bind("<KeyRelease>", self.update_favorite_list)
|
||||
|
||||
row5 = tk.Frame(self.root)
|
||||
row5.pack(fill=tk.X)
|
||||
@ -225,6 +321,7 @@ class TkinterUI:
|
||||
self.favorite_page_num_entry = tk.Entry(row5_column1)
|
||||
self.favorite_page_num_entry.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
self.favorite_page_num_entry.insert(0, config.favorite_page_num)
|
||||
self.favorite_page_num_entry.bind("<KeyRelease>", self.update_favorite_page_num)
|
||||
|
||||
self.default_page_num_label = tk.Label(
|
||||
row5_column2, text="默认获取页数:", width=14
|
||||
@ -233,6 +330,7 @@ class TkinterUI:
|
||||
self.default_page_num_entry = tk.Entry(row5_column2)
|
||||
self.default_page_num_entry.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
self.default_page_num_entry.insert(0, config.default_page_num)
|
||||
self.default_page_num_entry.bind("<KeyRelease>", self.update_default_page_num)
|
||||
|
||||
row6 = tk.Frame(self.root)
|
||||
row6.pack(fill=tk.X)
|
||||
@ -248,6 +346,7 @@ class TkinterUI:
|
||||
self.urls_limit_entry = tk.Entry(row6_column1)
|
||||
self.urls_limit_entry.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
self.urls_limit_entry.insert(15, config.urls_limit)
|
||||
self.urls_limit_entry.bind("<KeyRelease>", self.update_urls_limit)
|
||||
|
||||
self.ipv_type_label = tk.Label(row6_column2, text="接口协议类型:", width=14)
|
||||
self.ipv_type_label.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
@ -255,7 +354,7 @@ class TkinterUI:
|
||||
self.ipv_type_combo.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
self.ipv_type_combo["values"] = ("ipv4", "ipv6", "all")
|
||||
self.ipv_type_combo.current(0)
|
||||
self.ipv_type_combo.bind("<<ComboboxSelected>>", lambda event: config.ipv_type)
|
||||
self.ipv_type_combo.bind("<<ComboboxSelected>>", self.update_ipv_type)
|
||||
|
||||
row7 = tk.Frame(self.root)
|
||||
row7.pack(fill=tk.X)
|
||||
@ -271,6 +370,9 @@ class TkinterUI:
|
||||
self.response_time_weight_entry = tk.Entry(row7_column1)
|
||||
self.response_time_weight_entry.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
self.response_time_weight_entry.insert(0, config.response_time_weight)
|
||||
self.response_time_weight_entry.bind(
|
||||
"<KeyRelease>", self.update_response_time_weight
|
||||
)
|
||||
|
||||
self.resolution_weight_label = tk.Label(
|
||||
row7_column2, text="分辨率权重:", width=14
|
||||
@ -279,6 +381,7 @@ class TkinterUI:
|
||||
self.resolution_weight_entry = tk.Entry(row7_column2)
|
||||
self.resolution_weight_entry.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
self.resolution_weight_entry.insert(0, config.resolution_weight)
|
||||
self.resolution_weight_entry.bind("<KeyRelease>", self.update_resolution_weight)
|
||||
|
||||
row8 = tk.Frame(self.root)
|
||||
row8.pack(fill=tk.X)
|
||||
@ -288,6 +391,7 @@ class TkinterUI:
|
||||
self.recent_days_entry = tk.Entry(row8)
|
||||
self.recent_days_entry.pack(side=tk.LEFT, padx=4, pady=4)
|
||||
self.recent_days_entry.insert(30, config.recent_days)
|
||||
self.recent_days_entry.bind("<KeyRelease>", self.update_recent_days)
|
||||
|
||||
row9 = tk.Frame(self.root)
|
||||
row9.pack(fill=tk.X)
|
||||
@ -299,6 +403,7 @@ class TkinterUI:
|
||||
side=tk.LEFT, padx=4, pady=4, expand=True, fill=tk.BOTH
|
||||
)
|
||||
self.domain_blacklist_text.insert(tk.END, ",".join(config.domain_blacklist))
|
||||
self.domain_blacklist_text.bind("<KeyRelease>", self.update_domain_blacklist)
|
||||
|
||||
row10 = tk.Frame(self.root)
|
||||
row10.pack(fill=tk.X)
|
||||
@ -314,6 +419,9 @@ class TkinterUI:
|
||||
self.url_keywords_blacklist_text.insert(
|
||||
tk.END, ",".join(config.url_keywords_blacklist)
|
||||
)
|
||||
self.url_keywords_blacklist_text.bind(
|
||||
"<KeyRelease>", self.update_url_keywords_blacklist
|
||||
)
|
||||
|
||||
row11 = tk.Frame(self.root)
|
||||
row11.pack(fill=tk.X)
|
||||
@ -325,6 +433,7 @@ class TkinterUI:
|
||||
side=tk.LEFT, padx=4, pady=4, expand=True, fill=tk.BOTH
|
||||
)
|
||||
self.subscribe_urls_text.insert(tk.END, ",".join(config.subscribe_urls))
|
||||
self.subscribe_urls_text.bind("<KeyRelease>", self.update_subscribe_urls)
|
||||
|
||||
row12 = tk.Frame(self.root)
|
||||
row12.pack(fill=tk.X)
|
||||
@ -336,6 +445,7 @@ class TkinterUI:
|
||||
side=tk.LEFT, padx=4, pady=4, expand=True, fill=tk.BOTH
|
||||
)
|
||||
self.region_list_text.insert(tk.END, ",".join(config.region_list))
|
||||
self.region_list_text.bind("<KeyRelease>", self.update_region_list)
|
||||
|
||||
row13 = tk.Frame(self.root)
|
||||
row13.pack(fill=tk.X, pady=10, padx=120)
|
||||
|
38
tkinter_ui.spec
Normal file
38
tkinter_ui.spec
Normal file
@ -0,0 +1,38 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['tkinter_ui.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[('demo.txt', '.')],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='update-tool',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
61
utils.py
61
utils.py
@ -1,7 +1,3 @@
|
||||
try:
|
||||
import user_config as config
|
||||
except ImportError:
|
||||
import config
|
||||
from selenium import webdriver
|
||||
import aiohttp
|
||||
import asyncio
|
||||
@ -23,6 +19,53 @@ from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
import concurrent.futures
|
||||
import sys
|
||||
import importlib.util
|
||||
|
||||
|
||||
def resource_path(relative_path, persistent=False):
|
||||
"""
|
||||
Get the resource path
|
||||
"""
|
||||
base_path = os.path.abspath(".")
|
||||
total_path = os.path.join(base_path, relative_path)
|
||||
if persistent:
|
||||
return total_path
|
||||
if os.path.exists(total_path):
|
||||
return total_path
|
||||
else:
|
||||
try:
|
||||
base_path = sys._MEIPASS
|
||||
return os.path.join(base_path, relative_path)
|
||||
except Exception:
|
||||
return total_path
|
||||
|
||||
|
||||
def load_external_config(name):
|
||||
"""
|
||||
Load the external config file
|
||||
"""
|
||||
config = None
|
||||
config_path = name
|
||||
config_filename = os.path.join(os.path.dirname(sys.executable), config_path)
|
||||
|
||||
if os.path.exists(config_filename):
|
||||
spec = importlib.util.spec_from_file_location(name, config_filename)
|
||||
config = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(config)
|
||||
else:
|
||||
import config
|
||||
|
||||
return config
|
||||
|
||||
|
||||
config_path = resource_path("user_config.py")
|
||||
default_config_path = resource_path("config.py")
|
||||
config = (
|
||||
load_external_config("user_config.py")
|
||||
if os.path.exists(config_path)
|
||||
else load_external_config("config.py")
|
||||
)
|
||||
|
||||
|
||||
def setup_driver():
|
||||
@ -101,7 +144,7 @@ def get_channel_items():
|
||||
current_category = ""
|
||||
pattern = r"^(.*?),(?!#genre#)(.*?)$"
|
||||
|
||||
with open(user_source_file, "r", encoding="utf-8") as f:
|
||||
with open(resource_path(user_source_file), "r", encoding="utf-8") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if "#genre#" in line:
|
||||
@ -269,8 +312,10 @@ def update_file(final_file, old_file):
|
||||
"""
|
||||
Update the file
|
||||
"""
|
||||
if os.path.exists(old_file):
|
||||
os.replace(old_file, final_file)
|
||||
old_file_path = resource_path(old_file, persistent=True)
|
||||
final_file_path = resource_path(final_file, persistent=True)
|
||||
if os.path.exists(old_file_path):
|
||||
os.replace(old_file_path, final_file_path)
|
||||
|
||||
|
||||
def get_channel_url(element):
|
||||
@ -423,7 +468,7 @@ def get_total_urls_from_info_list(infoList):
|
||||
Get the total urls from info list
|
||||
"""
|
||||
total_urls = [url for url, _, _ in infoList]
|
||||
return list(dict.fromkeys(total_urls))[: config.urls_limit]
|
||||
return list(dict.fromkeys(total_urls))[: int(config.urls_limit)]
|
||||
|
||||
|
||||
def get_total_urls_from_sorted_data(data):
|
||||
|
Loading…
x
Reference in New Issue
Block a user