Files
NFLmusic/NFLmusic.py
NFL_jiancx 2ba7e62ef0 feat(WANGYIYUN): 添加音乐下载密钥并更新版本号
- 在请求网易云音乐时添加了特定的密钥参数
- 将软件版本号从 4.2.6 升级到 4.2.7
2025-06-09 15:41:35 +08:00

1760 lines
73 KiB
Python

import time
from functools import total_ordering
from tkinter import *
import threading
import pygame
import requests
from ttkbootstrap import *
import tkinter.messagebox
import tkinter.filedialog
import sys
import re
import os
import json
import subprocess
from random import randint
from random import choice as c
import math
import webbrowser
from pyperclip import copy
# 子代码
from nflmusic import language as lang, make_image, theme_language as tmla, logs, ifm_json as ij
from nflmusic.label_button import LabelButton as lb
from nflmusic import lyrics
from nflmusic.player import MusicPlayer
from nflmusic.load_gif import *
def opening_animation():
global loaded, appdata
while True:
try:
root0 = Frame(root, height=530, width=810)
break
except:
pass
time.sleep(0.05)
root.attributes("-topmost", True)
root.overrideredirect(True)
root0.place(x=0, y=0)
label_image = Label(root0, image=imagetk8)
label_image.place(relx=0.5, rely=0.5, anchor="center")
time.sleep(2)
root0.destroy()
root.attributes("-topmost", False)
root.overrideredirect(False)
homepage_frame.place(x=0, y=0)
root.config(menu=menubar)
loaded = True
run(update)
def make_jsondata():
appdata = os.getenv("APPDATA")
with open(appdata + "/.NFLmusic/NFLmusic.json", "w") as f:
jsondata = ij.usercache
f.write(json.dumps(jsondata))
def make_lang_json():
if not os.path.exists(appdata + "/.NFLmusic/language"):
os.mkdir(appdata + "/.NFLmusic/language")
with open(appdata + "/.NFLmusic/language/zh_cn.json", "w") as f:
f.write(json.dumps(ij.Language.zh_cn))
with open(appdata + "/.NFLmusic/language/en_us.json", "w") as f:
f.write(json.dumps(ij.Language.en_us))
def save_jsondata():
jsondata["language"] = var5.get()
jsondata["choice"] = repo_dict[var4.get()]
jsondata["auto_update"] = var3.get()
jsondata["auto_play"] = var6.get()
tm = var1.get()
style.theme = tmla.get(la)[tm]
jsondata["theme"] = tmla.get(la)[tm]
if not os.path.exists(var2.get()):
var2.set(path)
jsondata["path"] = var2.get()
with open(appdata + "/.NFLmusic/NFLmusic.json", "w") as f:
f.write(json.dumps(jsondata))
def detect_change():
global changed
if (
jsondata["language"] != var5.get() or
jsondata["choice"] != repo_dict[var4.get()] or
jsondata["auto_update"] != var3.get() or
jsondata["auto_play"] != var6.get() or
jsondata["theme"] != tmla.get(la)[var1.get()] or
jsondata["path"] != var2.get()
):
changed = True
def display(window, msg, ltime=3):
a = Label(window, text=msg)
a.place(relx=0.5, rely=0.9, anchor="center")
time.sleep(ltime)
a.destroy()
def get_treeview_index(tree, item):
parent_id = tree.parent(item)
if parent_id:
# 如果有父节点,获取父节点下所有子节点,并返回目标节点在其中的索引值
children = tree.get_children(parent_id)
return children.index(item)
else:
# 如果没有父节点,直接返回根节点下的索引值
root_children = tree.get_children()
return root_children.index(item)
def download_check(*value):
global downloading
time.sleep(0.2)
try:
if not downloading:
downloading = True
run(download_music, var0.get(), get_treeview_index(songlist, songlist.selection()[0]) + 1)
except:
downloading = False
def download_music(song_name, choose):
global progressbar, downloading
def update_progressbar():
while True:
progress = int((downloaded / total_length) * 100)
progressbar['value'] = progress
if downloaded == total_length:
break
time.sleep(0.05)
try:
progressbar = Progressbar(labelframe_download, mode='determinate', length=490,
style='success.Striped.Horizontal.TProgressbar')
progressbar.place(x=10, y=300)
br = br_dict[var.get()]
if choice == "KUWO":
resp = requests.get(f"{url}?msg={song_name}&n={choose}&br={br}&num=60&type=json")
resp.close()
id = resp.json()["link"].rsplit("/", 1)[1]
try:
resp_lrc = requests.get(f"http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId={id}")
resp_lrc.close()
lrc = ""
lrclist = resp_lrc.json()["data"]["lrclist"]
for i in lrclist:
total_time = i["time"]
min = float(total_time) // 60
sec = float(total_time) % 60
lrc += f'[{int(min)}:{sec}]{i["lineLyric"]}\n'
except Exception as e:
print(f"download_kw_lrc: {e}")
lrc = ""
music_name = resp.json()["song_name"]
singer = resp.json()["song_singer"]
music_url = resp.json()["flac_url"]
elif choice == "WANGYIYUN":
resp = requests.get(f"{url}?gm={song_name}&n={choose}&br={br}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3")
resp.close()
id = resp.json()["link"].rsplit("=", 1)[1]
try:
resp_lrc = requests.get(f"https://music.163.com/api/song/lyric?id={id}&lv=-1&kv=-1&tv=-1")
resp_lrc.close()
lrc = resp_lrc.json()["lrc"]["lyric"]
except Exception as e:
print(f"download_wyy_lrc: {e}")
lrc = ""
music_name = resp.json()["title"]
singer = resp.json()["singer"]
music_url = resp.json()["music_url"]
elif choice == "QQ":
resp = requests.get(f"{url}?msg={song_name}&n={choose}&num=60&type=json&br={br}")
resp.close()
try:
lrc = resp.json()["data"]["lyric"]
except Exception as e:
print(f"download_qq_lrc: {e}")
lrc = ""
music_name = resp.json()["data"]["song_name"]
singer = resp.json()["data"]["song_singer"]
music_url = resp.json()["data"]["music_url"]
elif choice == "KUGOU":
resp = requests.get(f"{url}?gm={song_name}&n={choose}&num=60&type=json&quality={br}")
resp.close()
try:
lrc = resp.json()["lyrics"]
except Exception as e:
print(f"download_kugou_lrc: {e}")
lrc = ""
music_name = resp.json()["title"]
singer = resp.json()["singer"]
music_url = resp.json()["music_url"]
elif choice == "DOUYIN":
resp = requests.get(f"{url}?msg={song_name}&n={choose}&num=50&type=json")
resp.close()
try:
lrc = resp.json()["data"]["lrc"]
except Exception as e:
print(f"download_qishui_lrc: {e}")
lrc = ""
music_name = resp.json()["data"]["title"]
singer = resp.json()["data"]["singer"]
music_url = resp.json()["data"]["url"]
elif choice == "XIAOFEN":
resp = requests.get(f"{url}?msg={song_name}&n={choose}&num=60&type=json&br={br}")
resp.close()
try:
lrc = resp.json()["lrc"]
except Exception as e:
print(f"download_xiaofen_lrc: {e}")
lrc = ""
music_name = resp.json()["title"]
singer = resp.json()["singer"]
music_url = resp.json()["music_url"]
else:
lrc = ""
lrc = lrc.replace("\\n", "\n")
print("请求api:", url)
response = requests.get(music_url, stream=True)
print("下载直链:", music_url)
formated = music_url.split("?")[0].rsplit(".", 1)[1]
if formated not in ["m4a", "mp3", "ogg", "flac"]:
formated = "mp3"
filename_without_endswith = f"{singer} - {music_name}"
filename_without_endswith = filename_without_endswith.replace("\\", "#").replace("/", "#")
filename_without_endswith = filename_without_endswith.replace(":", "#").replace("*", "#")
filename_without_endswith = filename_without_endswith.replace("?", "#").replace("\"", "#")
filename_without_endswith = filename_without_endswith.replace("<", "#").replace(">", "#").replace("|", "#")
filename = f"{filename_without_endswith}.{formated}"
temp_filename = f"{filename}.crdownload"
if path == "./music":
if os.path.exists("./music"):
pass
else:
os.makedirs("./music")
try:
if lrc:
with open(os.path.join(path, f"{filename_without_endswith}.lrc", ), "w", encoding="utf-8") as f:
f.write(lrc)
except:
pass
temp_filepath = os.path.join(path, temp_filename)
final_filepath = os.path.join(path, filename)
# 检查同名文件是否存在
if os.path.exists(final_filepath):
progressbar.destroy()
response.close()
if not lrc:
display(labelframe_download, lang.get(la, 'ui.download.text.file_exists', {"_filename_": filename}))
else:
display(labelframe_download, lang.get(la, 'ui.download.text.download_lyrics_success'))
downloading = False
return
with open(temp_filepath, "wb") as f:
total_length = int(response.headers.get('content-length'))
downloaded = 0
run(update_progressbar)
for data in response.iter_content(chunk_size=1024):
downloaded += len(data)
f.write(data)
os.rename(temp_filepath, final_filepath)
refresh()
time.sleep(0.1)
progressbar.destroy()
response.close()
display(labelframe_download, lang.get(la, 'ui.download.text.download_success',
{"_singer_": f"{singer}", "_music_": f"{music_name}"}))
downloading = False
except KeyError:
downloading = False
progressbar.destroy()
if song_name == "":
songlist.delete(0, "end")
display(labelframe_download, lang.get(la, "ui.download.text.download_fail_no_keys"))
else:
display(labelframe_download, lang.get(la, "ui.download.text.search_fail_not_found"))
except PermissionError:
downloading = False
progressbar.destroy()
response.close()
display(labelframe_download, lang.get(la, "ui.download.text.download_fail_no_permission"))
except requests.exceptions.ConnectionError:
downloading = False
progressbar.destroy()
response.close()
display(labelframe_download, lang.get(la, "ui.download.text.download_fail_no_network"))
except FileNotFoundError:
downloading = False
progressbar.destroy()
response.close()
display(labelframe_download, lang.get(la, "ui.download.text.download_fail_file_not_found"))
except FileExistsError:
downloading = False
progressbar.destroy()
response.close()
display(labelframe_download, lang.get(la, 'ui.download.text.download_success',
{"_singer_": f"{singer}", "_music_": f"{music_name}"}))
def run(task, *args):
t = threading.Thread(target=task, args=args, daemon=True)
t.start()
def get_data_without_blocking(song_name):
def search_and_update_list():
global last_search_target
if song_name != last_search_target:
try:
button0["state"] = "disabled"
songlist.delete(*songlist.get_children())
if choice == "KUWO":
url1 = f"{url}?msg={song_name}&num=60&type=json"
elif choice == "WANGYIYUN":
url1 = f"{url}?gm={song_name}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3"
elif choice == "QQ":
url1 = f"{url}?msg={song_name}&num=60&type=json"
elif choice == "KUGOU":
url1 = f"{url}?gm={song_name}&num=60&type=json"
elif choice == "DOUYIN":
url1 = f"{url}?msg={song_name}&num=50&type=json"
elif choice == "XIAOFEN":
url1 = f"{url}?msg={song_name}&num=60&type=json"
resp = requests.get(url1)
jsondata = resp.json()["data"]
resp.close()
last_search_target = song_name
for index in range(len(jsondata)):
if choice == "KUWO":
full_name = jsondata[index]["songname"]
artist = jsondata[index]["singer"]
album = jsondata[index]["song_rid"]
elif choice == "WANGYIYUN":
full_name = jsondata[index]["title"]
artist = jsondata[index]["singer"]
album = jsondata[index]["songid"]
elif choice == "QQ":
full_name = jsondata[index]["song_title"]
artist = jsondata[index]["song_singer"]
album = ""
elif choice == "KUGOU":
full_name = jsondata[index]["title"]
artist = jsondata[index]["singer"]
album = ""
elif choice == "DOUYIN":
full_name = jsondata[index]["title"]
artist = jsondata[index]["singer"]
album = ""
elif choice == "XIAOFEN":
full_name = jsondata[index]["title"]
artist = jsondata[index]["singer"]
album = ""
songlist.insert("", "end", values=(full_name, artist, album))
except requests.exceptions.JSONDecodeError:
resp_text = resp.text
songname_rule = '"songname": "(.*?)",'
name_rule = '"name": "(.*?)",'
songname_list = re.findall(songname_rule, resp_text)
name_list = re.findall(name_rule, resp_text)
for index in range(len(songname_list) - 1):
full_name = songname_list[index]
artist = name_list[index]
songlist.insert("", "end", values=(full_name, artist))
except TypeError:
pass
except:
tkinter.messagebox.showinfo(title=lang.get(la, "mbox.title.search_fail"),
message=lang.get(la, "mbox.text.search_fail", ))
pass
finally:
button0["state"] = "normal"
search_thread = threading.Thread(target=search_and_update_list)
search_thread.start()
def refresh():
global music_dir, music_dir_without_endswith
try:
listbox1.delete(0, "end")
music_dir_without_endswith = [os.path.splitext(file)[0] for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
music_dir = [file for file in os.listdir(path) if file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
if var7.get() in ["", lang.get(la, "ui.download.entry.song_name")]:
for musics in music_dir_without_endswith:
listbox1.insert(END, musics)
else:
for musics in music_dir_without_endswith:
if var7.get() in musics:
listbox1.insert(END, musics)
except:
pass
def delete():
global listbox1, filtered_list, music_dir, music_dir_without_endswith
try:
if tkinter.messagebox.askokcancel(lang.get(la, "mbox.title.delete"), lang.get(la, "mbox.text.delete", )):
abs_path = path + "/" + music_dir[listbox1.curselection()[0]]
abs_path_lrc = path + "/" + music_dir_without_endswith[listbox1.curselection()[0]] + ".lrc"
if var7.get() not in ["", lang.get(la, "ui.download.entry.song_name")]:
music_dir_filtered = []
for file in music_dir:
if var7.get() in os.path.splitext(file)[0]:
music_dir_filtered.append(file)
music_dir0 = music_dir_filtered
music_dir_without_endswith0 = [os.path.splitext(file)[0] for file in music_dir0 if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
abs_path = path + "/" + music_dir0[listbox1.curselection()[0]]
abs_path_lrc = path + "/" + music_dir_without_endswith0[listbox1.curselection()[0]] + ".lrc"
os.remove(abs_path)
try:
os.remove(abs_path_lrc)
except:
pass
music_dir_without_endswith.remove(listbox1.get(0, END)[listbox1.curselection()[0]])
music_dir.remove(music_dir[listbox1.curselection()[0]])
listbox1.delete(listbox1.curselection()[0])
except IndexError:
tkinter.messagebox.showwarning(title=lang.get(la, "mbox.title.delete_fail"),
message=lang.get(la, "mbox.text.delete_fail_no_target", ))
except PermissionError:
try:
stopmusic()
os.remove(abs_path)
try:
os.remove(abs_path_lrc)
except:
pass
music_dir_without_endswith.remove(filtered_list[listbox1.curselection()[0]])
music_dir.remove(music_dir[listbox1.curselection()[0]])
listbox1.delete(listbox1.curselection()[0])
except:
tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.delete_fail"),
message=lang.get(la, "mbox.text.delete_fail_no_permission", ))
except FileNotFoundError:
tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.delete_fail"),
message=lang.get(la, "mbox.text.delete_fail_not_found", ))
def pausesound():
global music_dir, player
try:
if not music_player.get_finished():
music_player.pause_music()
except IndexError:
tkinter.messagebox.showwarning(title=lang.get(la, "mbox.title.play_fail"),
message=lang.get(la, "mbox.text.play_fail_no_target", ))
except:
pass
tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.play_fail"),
message=lang.get(la, "mbox.text.play_fail_not_found", ))
def playsound(*event):
global music_playing, music_file_name, music_file_without_endswith, lyric, song_list, song_list_limit, music_dir
if not music_player.get_finished():
music_player.stop_music()
lyric = ""
music_dir_without_endswith = [os.path.splitext(file)[0] for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
music_dir = [file for file in os.listdir(path) if file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
if var7.get() not in ["", lang.get(la, "ui.download.entry.song_name")]:
music_dir_filtered = []
for file in music_dir:
if var7.get() in os.path.splitext(file)[0]:
music_dir_filtered.append(file)
music_dir = music_dir_filtered
music_dir_without_endswith = [os.path.splitext(file)[0] for file in music_dir if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
abs_path = path + "/" + music_dir[listbox1.curselection()[0]]
if abs_path not in song_list:
song_list.append(abs_path)
if len(song_list) > song_list_limit:
del song_list[0]
music_playing = abs_path
music_file_name = music_dir[listbox1.curselection()[0]]
music_file_without_endswith = music_dir_without_endswith[listbox1.curselection()[0]]
music_player.set_format_of_time(
lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
playmusic(abs_path)
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except:
pass
def playmusic(music_path):
music_name = music_path.split("/")[-1]
try:
music_player.stop_music()
except:
pass
try:
music_player.play_music(music_path)
except pygame.error:
tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.play_fail"),
message=lang.get(la, "mbox.text.play_fail_unrecognized_format",
{"_file_": music_name}))
except:
pass
def stopmusic():
global music_playing
music_playing = ""
music_player.stop_music()
def restart0():
root.destroy()
python = sys.executable
os.execl(python, python, *sys.argv)
def save_sth():
jsondata["br"][choice] = var.get()
jsondata["playing_mode"] = playingmode
save_jsondata()
root.destroy()
def display_sentences():
global poem, passage, label0
time.sleep(0.1)
poem = ""
try:
resp = requests.get("http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/random_quote")
poem = resp.text.replace("\r", "").split("\n")
resp.close()
resp0 = requests.get("http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/announcement")
announcement_text = resp0.text.replace("\\n", "")
resp0.close()
poem = c(poem)
poem_lines = [poem[i:i + 15] for i in range(0, len(poem), 15)]
passage = lang.get(la, "ui.about.text.information", {"_version_": version})
time.sleep(2)
random_quote["text"] = "\n".join(poem_lines)
announcement["text"] = lang.get(la, "ui.about.text.announcement", {"_announcement_": announcement_text})
label0["text"] = passage
except requests.exceptions.ConnectionError:
poem = c(lang.get(la, "ui.about.text.starting_poem", ))
poem_lines = [poem[i:i + 15] for i in range(0, len(poem), 15)]
passage = lang.get(la, "ui.about.text.information", {"_version_": version})
while True:
if loaded:
break
time.sleep(0.05)
tkinter.messagebox.showinfo(title=lang.get(la, "mbox.title.network_connection_fail"),
message=lang.get(la, "mbox.text.network_connection_fail", ))
random_quote["text"] = "\n".join(poem_lines)
label0["text"] = passage
def make_resource():
global resource_path
resource_path = os.getenv('APPDATA')
make_image.get(resource_path)
def open_file_dialog():
filepath = tkinter.filedialog.askdirectory()
if filepath:
var2.set(filepath)
def settings():
global page, changed
detect_change()
if changed:
response = tkinter.messagebox.askyesnocancel(lang.get(la, "mbox.title.save_settings"),
lang.get(la, "mbox.text.save_settings", ))
if response is not None:
if response:
if not os.path.exists(var2.get()):
tkinter.messagebox.showwarning(title=lang.get(la, "mbox.title.position_not_exist"),
message=lang.get(la, "mbox.text.position_not_exist", ))
else:
jsondata["br"][choice] = var.get()
jsondata["playing_mode"] = playingmode
save_jsondata()
tkinter.messagebox.showinfo(message=lang.get(la, "mbox.text.restart"),
title=lang.get(la, "mbox.title.restart", ))
restart0()
else:
page = will_page
if page == "homepage":
ExchangeGUI.home_page()
elif page == "about":
ExchangeGUI.about()
elif page == "versions":
ExchangeGUI.versions()
var1.set(tmla.catch(la, jsondata["theme"]))
var2.set(path)
var3.set(auto_update)
var4.set(repo_dict_reverse[choice])
var5.set(la)
var6.set(auto_play)
else:
pass
else:
page = will_page
if page == "homepage":
ExchangeGUI.home_page()
elif page == "about":
ExchangeGUI.about()
elif page == "versions":
ExchangeGUI.versions()
changed = False
class joke:
@staticmethod
def parabola_frame():
x = -400
while True:
y = pow(x / 10, 2)
root.geometry(f'+{x + 400}+{int(y)}')
time.sleep(0.01)
x += 1
if x == 400:
x = -400
@staticmethod
def jump_window():
while True:
for x in range(0, 20):
y = pow(x, 2)
root.geometry(f'+0+{int(y)}')
time.sleep(0.02)
for x in range(0, 20):
y = pow(19 - x, 2)
root.geometry(f'+0+{int(y)}')
time.sleep(0.02)
@staticmethod
def wave_window():
while True:
for x in range(-1080, 1440):
y = math.sin(x / 180 * math.pi)
root.geometry(f'+{int(x)}+{int(y * 300) + 300}')
time.sleep(0.01)
@staticmethod
def portal_window():
while True:
root.geometry(f'+{randint(0, 400)}+{randint(0, 400)}')
time.sleep(0.1)
@staticmethod
def repeat_window():
for i in range(10):
run(tkinter.messagebox.showinfo, lang.get(la, "mbox.title.joke0"), lang.get(la, "mbox.text.joke0", ))
@staticmethod
def circle_window():
while True:
for i in range(360):
x = math.cos(i / 180 * math.pi)
y = math.sin(i / 180 * math.pi)
root.geometry(f'{int(x * 300) + 400}x{int(y * 300) + 300}+{int(x * 300) + 400}+{int(y * 300) + 300}')
time.sleep(0.01)
def do_not_click():
global isJoking
if not isJoking:
tkinter.messagebox.showwarning(lang.get(la, "mbox.title.joke_warning"),
lang.get(la, "mbox.text.joke_warning", ))
joke_mode = randint(0, 5)
ExchangeGUI.home_page()
isJoking = True
if joke_mode == 0:
run(joke.wave_window)
elif joke_mode == 1:
run(joke.jump_window)
elif joke_mode == 2:
run(joke.parabola_frame)
elif joke_mode == 3:
run(joke.repeat_window)
isJoking = False
elif joke_mode == 4:
run(joke.portal_window)
elif joke_mode == 5:
run(joke.circle_window)
else:
tkinter.messagebox.showwarning(lang.get(la, "mbox.title.joke_fail"),
lang.get(la, "mbox.text.joke_fail", ))
def update():
global datalist, have_checked, screen_height, screen_width
def f_update_progressbar():
while True:
progress = int((downloaded / total_length) * 100)
update_progressbar['value'] = progress
if downloaded == total_length:
break
time.sleep(0.05)
def f_app_progressbar():
while True:
progress = int((downloaded / total_length) * 100)
app_progressbar['value'] = progress
if downloaded == total_length:
break
time.sleep(0.05)
def prevent_closing():
pass
def run_update():
subprocess.Popen(update_path + "update.exe")
appdata = os.getenv('APPDATA')
if not os.path.exists(appdata + "/.NFLmusic/update"):
os.mkdir(appdata + "/.NFLmusic/update")
if not have_checked:
data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/data"
data_resp = requests.get(data_url)
data_resp.close()
datalist = data_resp.text.replace("\r", "").split("\n")
update_path = appdata + "/.NFLmusic/update/"
data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/latest_update_log"
data_resp = requests.get(data_url).text
latest_version = datalist[0]
if latest_version != version:
if not jsondata["auto_update"]:
response = tkinter.messagebox.askquestion(
lang.get(la, "mbox.title.update_reminding", {"_version_": latest_version}),
lang.get(la, "mbox.text.update_reminding", {"_update_": data_resp}))
if response == "yes":
check_update_button["state"] = "disabled"
# 将root隐藏
root.withdraw()
download_page = Toplevel(root)
x_dl = (screen_width - 360) // 2
y_dl = (screen_height - 200) // 2
download_page.geometry(f"360x200+{x_dl}+{y_dl}")
download_page.title(lang.get(la, "mbox.title.update_start", {"_version_": latest_version}))
download_page.protocol("WM_DELETE_WINDOW", prevent_closing)
download_page.resizable(False, False)
download_page.iconbitmap(resource_path + "/.NFLmusic/resource/icon.ico")
update_progressbar = Progressbar(download_page, mode="determinate", length=320,
style="success.Striped.Horizontal.TProgressbar")
app_progressbar = Progressbar(download_page, mode="determinate", length=320,
style="info.Striped.Horizontal.TProgressbar")
Label(download_page, text=lang.get(la, "ui.update.text.download_update")).pack()
update_progressbar.pack()
Label(download_page, text=f"\n\n{lang.get(la, 'ui.update.text.download_app')}").pack()
app_progressbar.pack()
update_url = datalist[1]
app_url = datalist[2]
try:
update_resp = requests.get(update_url, stream=True)
app_resp = requests.get(app_url, stream=True)
with open(update_path + "file_path", "w") as f:
f.write(latest_version + "\n" + os.path.abspath(sys.executable))
with open(update_path + "update.exe", "wb") as f:
total_length = int(update_resp.headers.get('content-length'))
downloaded = 0
run(f_update_progressbar)
for data in update_resp.iter_content(chunk_size=1024):
downloaded += len(data)
f.write(data)
time.sleep(0.1)
with open(update_path + f"NFLmusicv{latest_version}.exe", "wb") as f:
total_length = int(app_resp.headers.get('content-length'))
downloaded = 0
run(f_app_progressbar)
for data in app_resp.iter_content(chunk_size=1024):
downloaded += len(data)
f.write(data)
run_update()
download_page.destroy()
root.destroy()
except Exception as e:
# 重新显示窗口
check_update_button["state"] = "normal"
root.deiconify()
print(e)
download_page.destroy()
tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.update_fail"),
message=lang.get(la, "mbox.text.update_fail", ))
else:
check_update_button["state"] = "normal"
else:
tkinter.messagebox.showinfo(lang.get(la, "mbox.title.update_start", {"_version_": latest_version}),
lang.get(la, "mbox.text.update_start_auto", {"_update_": data_resp}))
check_update_button["state"] = "disabled"
# 将root隐藏
root.withdraw()
download_page = Toplevel(root)
x_dl = (screen_width - 360) // 2
y_dl = (screen_height - 200) // 2
download_page.geometry(f"360x200+{x_dl}+{y_dl}")
download_page.title(lang.get(la, "mbox.title.update_start", {"_version_": latest_version}))
download_page.protocol("WM_DELETE_WINDOW", prevent_closing)
download_page.resizable(False, False)
download_page.iconbitmap(resource_path + "/.NFLmusic/resource/icon.ico")
update_progressbar = Progressbar(download_page, mode="determinate", length=320,
style="success.Striped.Horizontal.TProgressbar")
app_progressbar = Progressbar(download_page, mode="determinate", length=320,
style="info.Striped.Horizontal.TProgressbar")
Label(download_page, text=lang.get(la, "ui.update.text.download_update")).pack()
update_progressbar.pack()
Label(download_page, text=f"\n\n{lang.get(la, 'ui.update.text.download_app')}").pack()
app_progressbar.pack()
update_url = datalist[1]
app_url = datalist[2]
try:
update_resp = requests.get(update_url, stream=True)
app_resp = requests.get(app_url, stream=True)
with open(update_path + "file_path", "w") as f:
f.write(latest_version + "\n" + os.path.abspath(sys.executable))
with open(update_path + "update.exe", "wb") as f:
total_length = int(update_resp.headers.get('content-length'))
downloaded = 0
run(f_update_progressbar)
for data in update_resp.iter_content(chunk_size=1024):
downloaded += len(data)
f.write(data)
time.sleep(0.1)
with open(update_path + f"NFLmusicv{latest_version}.exe", "wb") as f:
total_length = int(app_resp.headers.get('content-length'))
downloaded = 0
run(f_app_progressbar)
for data in app_resp.iter_content(chunk_size=1024):
downloaded += len(data)
f.write(data)
run_update()
download_page.destroy()
root.destroy()
except Exception as e:
# 重新显示窗口
check_update_button["state"] = "normal"
root.deiconify()
print(e)
download_page.destroy()
tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.update_fail"),
message=lang.get(la, "mbox.text.update_fail", ))
def check_update():
global datalist, have_checked
check_update_button["state"] = "disabled"
try:
data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/data"
data_resp = requests.get(data_url)
datalist = data_resp.text.replace("\r", "").split("\n")
latest_version = datalist[0]
data_resp.close()
if version == latest_version:
tkinter.messagebox.showinfo(lang.get(la, "mbox.title.update_reminding", {"- v_version_": ""}),
lang.get(la, "mbox.text.update_latest"))
check_update_button["state"] = "normal"
else:
run(update)
except:
check_update_button["state"] = "normal"
have_checked = True
class ExchangeGUI:
exchanged = False
page_list = ["homepage", "settings", "about", "versions"]
@staticmethod
def close_other_page():
homepage_frame.place_forget()
setting_frame.place_forget()
about_frame.place_forget()
version_frame.place_forget()
@classmethod
def display_animation(cls, frame, current_page):
if not cls.exchanged:
global page
cls.exchanged = True
frame.place(x=0, y=1000)
def animation():
global page, former_page
if cls.page_list.index(page) > cls.page_list.index(former_page):
for i in range(40, 0, -1):
frame.place(x=pow(i, 2), y=0)
time.sleep(0.01)
elif cls.page_list.index(page) < cls.page_list.index(former_page):
for i in range(40, 0, -1):
frame.place(x=-pow(i, 2), y=0)
time.sleep(0.01)
elif cls.page_list.index(page) == cls.page_list.index(former_page):
for i in range(40, 0, -1):
frame.place(x=0, y=pow(i, 2))
time.sleep(0.01)
cls.exchanged = False
page = current_page
run(animation)
@staticmethod
def home_page():
global page, will_page, former_page
if page == "settings":
will_page = "homepage"
settings()
else:
ExchangeGUI.close_other_page()
page = "homepage"
ExchangeGUI.display_animation(homepage_frame, page)
former_page = "homepage"
@staticmethod
def window_settings():
global page, former_page
ExchangeGUI.close_other_page()
var2.set(path)
page = "settings"
ExchangeGUI.display_animation(setting_frame, page)
former_page = "settings"
@staticmethod
def about():
global page, will_page, former_page
will_page = "about"
if page == "settings":
will_page = "about"
settings()
else:
ExchangeGUI.close_other_page()
page = "about"
ExchangeGUI.display_animation(about_frame, page)
former_page = "about"
@staticmethod
def versions():
global page, will_page, former_page
will_page = "versions"
if page == "settings":
will_page = "versions"
settings()
else:
ExchangeGUI.close_other_page()
page = "versions"
ExchangeGUI.display_animation(version_frame, page)
former_page = "versions"
def tick():
def lrc_rolling(timestamp):
global next_showed
try:
lrc = lyrics.get_lyrics(lyric, music_player.get_progress())
try:
timestamp_list = list(lyric.keys())
next_timestamp = timestamp_list[timestamp_list.index(timestamp) + 1]
this_time = music_player.decode_format(timestamp)
next_time = music_player.decode_format(next_timestamp)
rolling_frequency = (next_time - this_time) / (len(lrc) - 30) / 1.5
except:
end_time = music_player.decode_format(music_player.get_length())
this_time = music_player.decode_format(timestamp)
rolling_frequency = (end_time - this_time) / (len(lrc) - 30) / 1.5
for i in range(0, len(lrc) - 30):
music_lrc["text"] = lrc[i:i + 31]
time.sleep(rolling_frequency)
if next_showed:
next_showed = False
break
except:
pass
global music_playing, playingmode, music_file_name, music_file_without_endswith, lyric, song_list
last_timestamp = "0"
while True:
try:
music_dir_with_path = [path + "/" + file for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
song_list = [song for song in song_list if song in music_dir_with_path]
if music_player.finish:
if auto_play:
playing_progress.state(["disabled"])
playsoundButton["image"] = imagetk1
try:
if playingmode == 0:
if music_playing:
refresh()
music_player.set_format_of_time(
lang.get(la, "ui.playing.text.time_format",
{"_music_": music_file_without_endswith}))
playmusic(music_playing)
if playingmode == 1:
if music_playing:
refresh()
music_dir_with_path = [path + "/" + file for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
if music_playing == song_list[-1]:
if len(song_list) >= len(music_dir_with_path):
del song_list[0]
elif len(song_list) > song_list_limit:
del song_list[0]
song_list_full = [song for song in music_dir_with_path if song not in song_list]
random_index = randint(0, len(song_list_full) - 1)
abs_path = song_list_full[random_index]
music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
song_list.append(abs_path)
music_playing = abs_path
else:
try:
current_index = song_list.index(music_playing)
except ValueError:
current_index = -1
abs_path = song_list[current_index + 1]
music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
music_playing = abs_path
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except Exception as e:
print("lyric: ", e)
lyric = {}
music_player.set_format_of_time(
lang.get(la, "ui.playing.text.time_format",
{"_music_": music_file_without_endswith}))
playmusic(abs_path)
if playingmode == 2:
if music_playing:
refresh()
music_dir = [file for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
music_dir_without_endswith = [os.path.splitext(file)[0] for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
try:
music_file_name = music_dir[music_dir.index(music_file_name) + 1]
music_file_without_endswith = music_dir_without_endswith[
music_dir_without_endswith.index(music_file_without_endswith) + 1]
abs_path = path + "/" + music_file_name
music_playing = abs_path
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except Exception as e:
print("lyric: ", e)
lyric = {}
except IndexError:
music_file_name = music_dir[0]
music_file_without_endswith = music_dir_without_endswith[0]
music_playing = path + "/" + music_file_name
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except:
lyric = {}
music_player.set_format_of_time(
lang.get(la, "ui.playing.text.time_format",
{"_music_": music_file_without_endswith}))
playmusic(music_playing)
except Exception as e:
print("External loop error: ", e)
pass
else:
playing_progress.state(["!disabled"])
try:
if lyric:
if len(lyrics.get_lyrics(lyric, music_player.get_progress())) >= 30:
if last_timestamp != music_player.get_progress():
run(lrc_rolling, music_player.get_progress())
last_timestamp = music_player.get_progress()
else:
next_showed = True
music_lrc["text"] = lyrics.get_lyrics(lyric, music_player.get_progress())
else:
music_lrc["text"] = ""
except:
pass
if music_player.get_busy():
playsoundButton["image"] = imagetk6
else:
playsoundButton["image"] = imagetk1
except:
pass
time.sleep(0.1)
def former_song():
global music_playing, lyric, music_file_name, song_list, song_list_limit, music_file_without_endswith
if playingmode == 1:
refresh()
music_dir_with_path = [path + "/" + file for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
if music_playing == song_list[0]:
if len(song_list) >= len(music_dir_with_path):
del song_list[-1]
elif len(song_list) > song_list_limit:
del song_list[-1]
song_list_full = [song for song in music_dir_with_path if song not in song_list]
random_index = randint(0, len(song_list_full) - 1)
abs_path = song_list_full[random_index]
music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
song_list.insert(0, abs_path)
music_playing = abs_path
else:
try:
current_index = song_list.index(music_playing)
except ValueError:
song_list.append(music_playing)
current_index = -1
abs_path = song_list[current_index - 1]
music_file_without_endswith = abs_path.rsplit("/")[-1].rsplit(".", 1)[0]
music_playing = abs_path
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except:
lyric = {}
music_player.set_format_of_time(
lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
playmusic(abs_path)
if playingmode in [0, 2]:
refresh()
music_dir = [file for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
try:
music_file_name = music_dir[music_dir.index(music_playing.split("/")[-1]) - 1]
music_file_without_endswith = music_file_name.split("/")[-1].rsplit(".", 1)[0]
abs_path = path + "/" + music_file_name
music_playing = abs_path
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except:
lyric = {}
except IndexError:
music_file_name = music_dir[0]
music_file_without_endswith = music_file_name.split("/")[-1].rsplit(".", 1)[0]
music_playing = path + "/" + music_file_name
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except:
lyric = {}
music_player.set_format_of_time(
lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
playmusic(music_playing)
def latter_song():
global music_playing, lyric, music_file_name, song_list, song_list_limit, music_file_without_endswith
if playingmode == 1:
refresh()
music_dir_with_path = [path + "/" + file for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
try:
last_song = song_list[-1]
except IndexError:
last_song = song_list[0]
if music_playing == last_song:
if len(song_list) >= len(music_dir_with_path):
del song_list[0]
elif len(song_list) > song_list_limit:
del song_list[0]
song_list_full = [song for song in music_dir_with_path if song not in song_list]
random_index = randint(0, len(song_list_full) - 1)
abs_path = song_list_full[random_index]
music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
song_list.append(abs_path)
music_playing = abs_path
else:
try:
current_index = song_list.index(music_playing)
except ValueError:
current_index = 0
song_list.insert(0, music_playing)
abs_path = song_list[current_index + 1]
music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
music_playing = abs_path
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except:
lyric = {}
music_player.set_format_of_time(
lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
playmusic(abs_path)
if playingmode in [0, 2]:
refresh()
music_dir = [file for file in os.listdir(path) if
file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
try:
music_file_name = music_dir[music_dir.index(music_playing.split("/")[-1]) + 1]
music_file_without_endswith = music_file_name.split("/")[-1].rsplit(".", 1)[0]
abs_path = path + "/" + music_file_name
music_playing = abs_path
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except:
lyric = {}
except IndexError:
music_file_name = music_dir[0]
music_file_without_endswith = music_file_name.split("/")[-1].rsplit(".", 1)[0]
music_playing = path + "/" + music_file_name
try:
lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
except:
lyric = {}
music_player.set_format_of_time(
lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
playmusic(music_playing)
def entry_focus(boolean):
global last_search_target
if boolean:
if entry.get() == lang.get(la, "ui.download.entry.song_name"):
var0.set("")
else:
if entry.get() == "":
var0.set(lang.get(la, "ui.download.entry.song_name"))
def entry1_focus(boolean):
global last_search_target1, focused
if boolean:
focused = True
if entry1.get() == lang.get(la, "ui.download.entry.song_name"):
var7.set("")
else:
focused = False
if entry1.get() == "":
var7.set(lang.get(la, "ui.download.entry.song_name"))
def change_playing_mode():
global playingmode
if playingmode == 0:
playingmodeButton["image"] = imagetk7["rand"]
playingmode += 1
elif playingmode == 1:
playingmodeButton["image"] = imagetk7["sequ"]
playingmode += 1
else:
playingmodeButton["image"] = imagetk7["loop"]
playingmode = 0
def load_versions():
global version_json
time.sleep(0.5)
try:
resp = requests.get("http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/version_list.json")
version_json = resp.json()
resp.close()
for version_item in version_json:
list_version = version_item["version"]
list_upload_time = version_item["upload_time"]
list_brief = version_item["brief"]
version_list.insert("", "end", values=(list_version, list_upload_time, list_brief))
except:
labelframe_update_log["text"] = lang.get(la, "frame.update_log", {"_version_": "NFLmusic"})
def version_choice(*event):
global version_download_choice
try:
version_download_choice = version_list.selection()[0]
choice_index = get_treeview_index(version_list, version_download_choice)
labelframe_update_log["text"] = lang.get(la, "frame.update_log",
{"_version_": version_json[choice_index]["version"]})
data["state"] = "normal"
data.delete(1.0, END)
data.insert("end", version_json[choice_index]["log"])
data["state"] = "disabled"
download_button.place(relx=0.5, rely=0.9, anchor="center")
except:
pass
def return_all_log(*event):
data["state"] = "normal"
text = logs.get(la)
data.delete("1.0", END)
data.insert('end', text)
data["state"] = "disabled"
download_button.place_forget()
labelframe_update_log["text"] = lang.get(la, "frame.update_log", {"_version_": "NFLmusic"})
def download_version():
version_web = version_json[get_treeview_index(version_list, version_download_choice)]["url"]
if tkinter.messagebox.askyesno(lang.get(la, "mbox.title.download_web"),
lang.get(la, "mbox.text.download_web", {"_url_": version_web})):
tkinter.messagebox.showinfo(lang.get(la, "mbox.title.copy_pwd"),
lang.get(la, "mbox.text.copy_pwd",
{"_pwd_": version_json[
get_treeview_index(version_list, version_download_choice)][
"password"]}))
webbrowser.open(version_web)
copy(version_json[get_treeview_index(version_list, version_download_choice)]["password"])
def search_local_song():
global search_words, filtered_list, music_dir_without_endswith
while True:
if focused:
former_words = var7.get()
time.sleep(1)
current_words = var7.get()
if former_words != current_words and entry1.get() != lang.get(la, "ui.download.entry.song_name"):
search_words = current_words
filtered_list = [song for song in music_dir_without_endswith if search_words in song]
if not filtered_list:
listbox1.unbind("<Double-1>")
else:
listbox1.bind("<Double-1>", playsound)
print(music_dir_without_endswith)
listbox1.delete(0, END)
for song in filtered_list:
listbox1.insert(END, song)
else:
time.sleep(1)
version = "4.2.7"
poem = ""
appdata = os.getenv("APPDATA")
make_resource()
make_lang_json()
if not os.path.exists(appdata + "/.NFLmusic/NFLmusic.json"):
make_jsondata()
try:
with open(appdata + '/.NFLmusic/NFLmusic.json', 'r') as file:
jsondata = json.loads(file.read())
la = jsondata["language"]
theme = tmla.catch(la, jsondata["theme"])
choice = jsondata["choice"]
url = ij.api_data[choice][0]
br_dict = ij.api_data[choice][1]
br_list = [br for br in br_dict]
path = jsondata["path"]
br = jsondata["br"][choice]
if br not in br_list:
br = ij.usercache["br"][choice]
auto_update = jsondata["auto_update"]
playingmode = jsondata["playing_mode"]
auto_play = jsondata["auto_play"]
except:
make_jsondata()
with open(appdata + '/.NFLmusic/NFLmusic.json', 'r') as file:
jsondata = json.loads(file.read())
la = jsondata["language"]
theme = tmla.catch(la, jsondata["theme"])
choice = jsondata["choice"]
url = ij.api_data[choice][0]
br_dict = ij.api_data[choice][1]
br_list = [br for br in br_dict]
path = jsondata["path"]
br = jsondata["br"][choice]
if br not in br_list:
br = ij.usercache["br"][choice]
auto_update = jsondata["auto_update"]
playingmode = jsondata["playing_mode"]
auto_play = jsondata["auto_play"]
theme0 = tmla.get(la)[theme]
style = Style(theme=theme0)
style.configure("Treeview", rowheight=40)
root = style.master
version_json = {}
version_download_choice = 0
song_list_limit = 20
music_player = MusicPlayer(root)
music_playing = ""
music_file_name = ""
music_dir_without_endswith = []
song_list = []
music_file_without_endswith = ""
lyric = ""
last_search_target = ""
last_search_target1 = ""
root.resizable(0, 0)
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# 计算窗口左上角的位置使窗口居中
x = (screen_width - 810) // 2
y = (screen_height - 530) // 2
root.geometry(f'810x530+{x}+{y}')
root.title(f"NFLmusic v{version}")
root.protocol('WM_DELETE_WINDOW', save_sth)
downloading = False
var = StringVar()
var0 = StringVar()
var0.set(lang.get(la, "ui.download.entry.song_name"))
var1 = StringVar()
var2 = StringVar()
var3 = BooleanVar()
var3.set(auto_update)
var4 = StringVar()
var5 = StringVar()
var5.set(la)
var6 = BooleanVar()
var6.set(auto_play)
var7 = StringVar()
var7.set(lang.get(la, "ui.download.entry.song_name"))
isJoking = False
changed = False
focused = False
player = None
OptionMenu = ttk.OptionMenu
Button = ttk.Button
Scrollbar = ttk.Scrollbar
Progressbar = ttk.Progressbar
Checkbutton = ttk.Checkbutton
Entry = ttk.Entry
showed = False
page = "homepage"
will_page = "homepage"
former_page = "homepage"
search_words = lang.get(la, "ui.download.entry.song_name")
next_showed = False
loaded = False
have_checked = False
playingmode_dict = {
0: "loop",
1: "rand",
2: "sequ"
}
if path == "./music":
if os.path.exists("./music"):
pass
else:
os.makedirs("./music")
image1 = Image.open(resource_path + "/.NFLmusic/resource/buttons/playsound.png")
imagetk1 = ImageTk.PhotoImage(image1.resize((20, 20)))
image2 = Image.open(resource_path + "/.NFLmusic/resource/buttons/download.png")
imagetk2 = ImageTk.PhotoImage(image2.resize((16, 16)))
image3 = Image.open(resource_path + "/.NFLmusic/resource/buttons/refresh.png")
imagetk3 = ImageTk.PhotoImage(image3.resize((16, 16)))
image4 = Image.open(resource_path + "/.NFLmusic/resource/buttons/delete.png")
imagetk4 = ImageTk.PhotoImage(image4.resize((16, 16)))
image5 = Image.open(resource_path + "/.NFLmusic/resource/buttons/browse.png")
imagetk5 = ImageTk.PhotoImage(image5.resize((16, 16)))
image6 = Image.open(resource_path + "/.NFLmusic/resource/buttons/pausesound.png")
imagetk6 = ImageTk.PhotoImage(image6.resize((20, 20)))
image7 = {"sequ": Image.open(resource_path + "/.NFLmusic/resource/buttons/playingmode_sequential.png"),
"rand": Image.open(resource_path + "/.NFLmusic/resource/buttons/playingmode_random.png"),
"loop": Image.open(resource_path + "/.NFLmusic/resource/buttons/playingmode_loop.png")}
imagetk7 = {"sequ": ImageTk.PhotoImage(image7["sequ"].resize((16, 16))),
"rand": ImageTk.PhotoImage(image7["rand"].resize((16, 16))),
"loop": ImageTk.PhotoImage(image7["loop"].resize((16, 16)))}
image8 = Image.open(resource_path + "/.NFLmusic/resource/images/logo.png")
imagetk8 = ImageTk.PhotoImage(image8.resize((256, 256)))
image9 = Image.open(resource_path + "/.NFLmusic/resource/buttons/former.png")
imagetk9 = ImageTk.PhotoImage(image9.resize((20, 20)))
image0 = Image.open(resource_path + "/.NFLmusic/resource/buttons/latter.png")
imagetk0 = ImageTk.PhotoImage(image0.resize((20, 20)))
run(opening_animation)
label_image = Label(root, image=imagetk8)
label_image.place(relx=0.5, rely=0.5, anchor="center")
# 主页
homepage_frame = ttk.Frame(root, width=1000, height=1000)
labelframe_playing_settings = ttk.Labelframe(homepage_frame, text=lang.get(la, "frame.playing_settings"), width=770,
height=120)
labelframe_playing_settings.place(x=20, y=380)
# 操控按钮
button_x = 15
button_y = 9
play_button_y = 7
formerButton = Button(labelframe_playing_settings, image=imagetk9, style="Link.TButton", command=former_song)
formerButton.place(x=button_x + 45, y=play_button_y)
latterButton = Button(labelframe_playing_settings, image=imagetk0, style="Link.TButton", command=latter_song)
latterButton.place(x=button_x + 135, y=play_button_y)
playsoundButton = Button(labelframe_playing_settings, command=pausesound, image=imagetk1, style="Link.TButton")
playsoundButton.place(x=button_x + 90, y=play_button_y)
playingmodeButton = Button(labelframe_playing_settings, command=change_playing_mode,
image=imagetk7[playingmode_dict[playingmode]], style="Link.TButton")
playingmodeButton.place(x=button_x + 180, y=button_y)
refreshButton = Button(labelframe_playing_settings, command=refresh, style="Link.TButton", image=imagetk3)
refreshButton.place(x=button_x, y=button_y)
deleteButton = Button(labelframe_playing_settings, command=delete, style="Link.TButton", image=imagetk4)
deleteButton.place(x=button_x + 225, y=button_y)
playing_time = ttk.Label(labelframe_playing_settings, text="")
playing_time.place(relx=0.03, rely=0.5)
music_lrc = ttk.Label(labelframe_playing_settings, text=lyric, style="Link.TLabel", font=("黑体", 15),
foreground="orange")
music_lrc.place(relx=0.65, rely=0.3, anchor="center")
playing_progress = ttk.Scale(labelframe_playing_settings, length=730, from_=0, to=1)
playing_progress.place(x=20, y=70)
labelframe_song_list = ttk.Labelframe(homepage_frame, text=lang.get(la, "frame.song_list"), width=250,
height=354)
labelframe_song_list.place(x=20, y=20)
scrollbar1 = Scrollbar(labelframe_song_list, orient=VERTICAL)
listbox1 = Listbox(labelframe_song_list, width=30, height=16, yscrollcommand=scrollbar1.set)
listbox1.place(x=10, y=0)
listbox1.bind("<Double-1>", playsound)
entry1 = Entry(labelframe_song_list, width=31, textvariable=var7)
entry1.bind("<FocusIn>", lambda event: entry1_focus(True))
entry1.bind("<FocusOut>", lambda event: entry1_focus(False))
entry1.place(x=10, y=295)
scrollbar1.config(command=listbox1.yview)
scrollbar1.place(x=227, y=0, height=292)
refresh()
filtered_list = music_dir_without_endswith
labelframe_download = ttk.Labelframe(homepage_frame, text=lang.get(la, "frame.download"), height=354, width=510)
labelframe_download.place(x=280, y=20)
scrollbar2 = Scrollbar(labelframe_download, orient=VERTICAL)
songlist = ttk.Treeview(labelframe_download, columns=("Song", "Artist", "Album"), height=5, show="headings",
yscrollcommand=scrollbar2.set)
songlist.heading("Song", text=lang.get(la, "ui.download.treeview.song"))
songlist.heading("Artist", text=lang.get(la, "ui.download.treeview.artist"))
songlist.heading("Album", text=lang.get(la, "ui.download.treeview.album"))
songlist.column("Song", width=160, minwidth=160)
songlist.column("Artist", width=160, minwidth=160)
songlist.column("Album", width=160, minwidth=160)
songlist.place(x=5, y=50)
songlist.bind("<Double-1>", download_check)
scrollbar2.config(command=songlist.yview)
scrollbar2.place(x=490, y=50, height=235)
button0 = Button(labelframe_download, text=lang.get(la, "ui.download.button.search"),
command=lambda: get_data_without_blocking(var0.get()), style="Outline.TButton")
button0.place(x=230, y=10)
Label(labelframe_download, text=lang.get(la, "ui.download.text.song_name")).place(x=10, y=14)
Label(labelframe_download, text=lang.get(la, "ui.download.text.sound_quality")).place(x=310, y=14)
entry = Entry(labelframe_download, textvariable=var0)
entry.place(x=70, y=10)
entry.bind("<Return>", lambda event: get_data_without_blocking(var0.get()))
entry.bind("<FocusIn>", lambda event: entry_focus(True))
entry.bind("<FocusOut>", lambda event: entry_focus(False))
menu0 = OptionMenu(labelframe_download, var, br, *br_list)
menu0.place(x=370, y=10)
# 设置页面
setting_frame = Frame(root, width=1000, height=1000)
labelframe_settings = ttk.Labelframe(setting_frame, text=lang.get(la, "frame.base_settings"),
height=480, width=500)
labelframe_settings.place(x=20, y=20)
# 关于页面
about_frame = Frame(root, width=1000, height=1000)
labelframe_treasure_chest = ttk.LabelFrame(about_frame, text=lang.get(la, "frame.treasure_chest"),
height=210, width=500)
labelframe_treasure_chest.place(x=20, y=20)
random_quote = Label(labelframe_treasure_chest, text="", font=("楷体", 18))
random_quote.place(relx=0.5, rely=0.2, anchor="center")
do_not_click_button = Button(labelframe_treasure_chest, text=lang.get(la, "ui.about.button.do_not_click"),
style="danger.Outline.TButton", width=30, command=do_not_click)
do_not_click_button.place(relx=0.5, rely=0.7, anchor="center")
labelframe_about = ttk.LabelFrame(about_frame, text=lang.get(la, "frame.about"),
height=261, width=500)
labelframe_about.place(x=20, y=240)
label0 = Label(labelframe_about, text="")
label0.place(x=30, y=10)
announcement = Label(labelframe_about, text="")
announcement.place(x=300, y=10)
run(display_sentences)
labelframe_thanks = LabelFrame(about_frame, text=lang.get(la, "frame.thanks"), height=480, width=250, )
labelframe_thanks.place(x=540, y=20)
# 鸣谢
oiapi = "https://oiapi.net/"
githook = "http://git.nanfengling.cn/"
nanfect = "http://pan.nanfengling.cn/"
skylark = "https://space.bilibili.com/1868716664"
sponsorship = "https://afdian.com/a/NFLstudio"
lb0 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.music_url'),
button=lang.get(la, 'ui.thanks.button.music_url'), command=lambda: webbrowser.open(oiapi))
lb0.place(button=(80, 15), label=(10, 20))
lb1 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.random_poem'),
button=lang.get(la, 'ui.thanks.button.random_poem'), command=lambda: webbrowser.open(githook))
lb1.place(button=(80, 55), label=(10, 60))
lb2 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.file_store'),
button=lang.get(la, 'ui.thanks.button.file_store'), command=lambda: webbrowser.open(nanfect))
lb2.place(button=(80, 95), label=(10, 100))
lb3 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.bug_fix'),
button=lang.get(la, 'ui.thanks.button.bug_fix'), command=lambda: webbrowser.open(skylark))
lb3.place(button=(80, 135), label=(10, 140))
lb4 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.sponsorship'),
button=lang.get(la, 'ui.thanks.button.sponsorship'), command=lambda: webbrowser.open(sponsorship))
lb4.place(button=(80, 175), label=(10, 180))
scrollbar3 = Scrollbar(labelframe_thanks, orient=VERTICAL)
sponsors_list = Listbox(labelframe_thanks, height=13, width=30, yscrollcommand=scrollbar3.set)
sponsors_list.place(x=10, y=210)
scrollbar3.config(command=sponsors_list.yview)
scrollbar3.place(x=227, y=210, height=240)
try:
data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/sponsors"
data_resp = requests.get(data_url)
data_list = data_resp.text.replace("\r", "").split("\n")
for sponsor in data_list:
sponsors_list.insert("end", sponsor)
data_resp.close()
except:
pass
# 开发版本页面
version_frame = Frame(root, width=1000, height=1000)
current_version = Label(version_frame, font=("微软雅黑", 10),
text=lang.get(la, "ui.versions.text.current_version", {"_version_": version}))
current_version.place(relx=0.4, rely=0.08, anchor="center")
labelframe_version_list = LabelFrame(version_frame, text=lang.get(la, "frame.version_list"),
height=350, width=500)
labelframe_version_list.place(x=20, y=140)
scrollbar4 = Scrollbar(labelframe_version_list, orient=VERTICAL)
version_list = ttk.Treeview(labelframe_version_list, style="success.Treeview",
columns=("Version", "UploadTime", "UpdateBrief"), height=6,
show="headings", yscrollcommand=scrollbar4.set)
version_list.heading("Version", text=lang.get(la, "ui.versions.treeview.version"))
version_list.heading("UploadTime", text=lang.get(la, "ui.versions.treeview.upload_time"))
version_list.heading("UpdateBrief", text=lang.get(la, "ui.versions.treeview.update_brief"))
version_list.column("Version", width=100, minwidth=100)
version_list.column("UploadTime", width=100, minwidth=100)
version_list.column("UpdateBrief", width=250, minwidth=250)
version_list.place(x=20, y=20)
version_list.bind("<Double-1>", version_choice)
version_list.bind("<Button-3>", return_all_log)
scrollbar4.config(command=version_list.yview)
scrollbar4.place(x=475, y=40, height=255)
labelframe_update_log = ttk.LabelFrame(version_frame, text=lang.get(la, "frame.update_log", {"_version_": "NFLmusic"}),
height=350,
width=250)
labelframe_update_log.place(x=540, y=140)
# 更新日志
scrollbar = Scrollbar(labelframe_update_log, orient=VERTICAL)
data = Text(labelframe_update_log, width=29, height=14, yscrollcommand=scrollbar.set)
data.place(x=10, y=16)
scrollbar.config(command=data.yview)
scrollbar.place(x=230, y=10, height=265)
download_button = Button(labelframe_update_log, image=imagetk2, style="warning.TButton",
command=lambda: download_version())
return_all_log()
run(load_versions)
# 菜单栏
menubar = Menu(root)
menubar.add_command(label=lang.get(la, "menu.homepage"), command=ExchangeGUI.home_page)
menubar.add_command(label=lang.get(la, "menu.settings"), command=ExchangeGUI.window_settings)
menubar.add_command(label=lang.get(la, "menu.about"), command=ExchangeGUI.about)
menubar.add_command(label=lang.get(la, "menu.versions"), command=ExchangeGUI.versions)
themeLabel = Label(labelframe_settings, text=lang.get(la, "ui.settings.text.theme", ))
themeLabel.place(x=10, y=25)
# 基本设置
repo_dict = {
"酷我音乐": "KUWO",
"网易云音乐": "WANGYIYUN",
"QQ音乐": "QQ",
"酷狗音乐": "KUGOU",
"汽水音乐": "DOUYIN",
"小粉音乐": "XIAOFEN"
}
repo_dict_reverse = {}
for repo in repo_dict:
repo_dict_reverse[repo_dict[repo]] = repo
repo_list = [repo for repo in repo_dict]
language_list = lang.list_languages()
label3 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.text.download_source', ))
label3.place(x=10, y=65)
if repo_dict_reverse.get(jsondata["choice"]) is None:
jsondata["choice"] = "KUWO"
menu0 = OptionMenu(labelframe_settings, var4, repo_dict_reverse[jsondata["choice"]],
*repo_list)
menu0.place(x=80, y=60)
label1 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.text.download_position', ))
label1.place(x=10, y=105)
entry0 = Entry(labelframe_settings, textvariable=var2, width=20)
entry0.place(x=80, y=100)
button1 = Button(labelframe_settings, image=imagetk5, command=open_file_dialog)
button1.place(x=240, y=100)
label2 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.text.auto_update', ))
label2.place(x=10, y=142)
check_button1 = Checkbutton(labelframe_settings, variable=var3, style="Squaretoggle.Toolbutton",
text=lang.get(la, "ui.settings.check_button.auto_update", ))
check_button1.place(x=80, y=140)
label3 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.text.language', ))
label3.place(x=10, y=175)
lang_optionmenu = OptionMenu(labelframe_settings, var5, jsondata["language"], *language_list)
lang_optionmenu.place(x=50, y=170)
label4 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.button.auto_play', ))
label4.place(x=10, y=212)
check_button2 = Checkbutton(labelframe_settings, variable=var6, style="Squaretoggle.Toolbutton",
text=lang.get(la, "ui.settings.check_button.auto_play", ))
check_button2.place(x=80, y=210)
check_update_button = Button(labelframe_settings, text=lang.get(la, 'ui.settings.button.check_update', ),
command=check_update, style="info.Outline.TButton")
check_update_button.place(x=10, y=240)
menu1 = OptionMenu(labelframe_settings, var1, theme, *list(tmla.get(la).keys()))
menu1.place(x=50, y=20)
root.iconbitmap(resource_path + "/.NFLmusic/resource/icon.ico")
run(search_local_song)
run(tick)
music_player.bind(cls_time=playing_time, cls_progress_bar=playing_progress)
playing_progress["command"] = lambda event: music_player.set_progress(playing_progress.get())
music_player.set_format_of_time(lang.get(la, "ui.playing.text.time_format", {"_music_": ""}))
root.mainloop()