1760 lines
73 KiB
Python
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()
|