#!/usr/bin/python3 from tkinter import * from tkinter import ttk from tkinter.ttk import * from tkinter import messagebox from tkinter.font import Font import subprocess import time import re import os # simul.py.20220608 # --- default set --- st = 'Simul moOde Radio' # default programs dir bin_dir = "/home/pi/bin/" # default radio_dir radio_dir = "/home/pi/radio/" # default favorite_dir favorite_dir = "/home/pi/radio/FAVORITE/" # default area t = favorite_dir+"favorite1" # label(on air station) std = ' ' * 150 # default player #player = "mpv" player = "'ffplay -nodisp'" # default pulse_vol pulse_vol = 20 # default mpg_vol vo = 10 # cfg_radio_csv command = ("test -e " + radio_dir + "cfg_radio.csv" + " ; " + "echo $?") proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') proc = proc.strip() if proc == str(1): subprocess.run("touch " + radio_dir + "cfg_radio.csv", shell=True) # --- run --- # play def play_click(): subprocess.run(bin_dir + "killall.sh", shell=True) play_selection() # vol_onair edit def vol_click(): onair_click() subprocess.run("xterm -geometry 70x50 -e vi +" + str(i) + " " + radio_dir + "vol.list &", shell=True) # area edit def area_click(): subprocess.run("xterm -geometry 130x40 -e vi " + t + " &", shell=True) # cfg_radio.csv def cfg_radio_click(): proc = messagebox.askokcancel('cfg_radio.csv', "cfg_radio.csv GET") if proc == True: subprocess.run("sqlite3 -csv /var/local/www/db/moode-sqlite3.db 'SELECT * from cfg_radio ;' > " + radio_dir + "cfg_radio.csv", shell=True) # cfg_radio.csv Empty def cfg_empty_click(): proc = messagebox.askyesno('cfg_radio.csv Empty', "cfg_radio.csv Empty ?") if proc == True: subprocess.run(": > " + radio_dir + "cfg_radio.csv", shell=True) # img_file def img_file_click(): subprocess.run("xterm -e less /tmp/moode_id &", shell=True) # favorite def favorite1_click(): global t; t=favorite_dir+"favorite1"; area_selection();x();y() def favorite2_click(): global t; t=favorite_dir+"favorite2"; area_selection();x();y() def favorite3_click(): global t; t=favorite_dir+"favorite3"; area_selection();x();y() def favorite4_click(): global t; t=favorite_dir+"favorite4"; area_selection();x();y() def moode_f2(): global t; t=radio_dir+"moode/moode_f2"; area_selection();x();y() def moode_f1(): global t; t=radio_dir+"moode/moode_f1"; area_selection();x();y() def vol1_click(): global vo vo = "-5"; vol_control() def vol2_click(): global vo vo = "-2"; vol_control() def vol3_click(): subprocess.run(bin_dir + "simul_vol.py", shell=True) def vol4_click(): global vo vo = "+2"; vol_control() def vol5_click(): global vo vo = "+5"; vol_control() def menu_click(): subprocess.run("~/bin/radio_menu.py &", shell=True) def vol_control(): command = ("ps ax | grep pulseaudio | grep -v grep | awk '{print $NF}'") pulse = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') pulse = pulse.strip() if pulse == "--start": subprocess.run("pactl set-sink-volume 0 " + str(vo) + "%", shell=True) else: subprocess.run("mpc volume " + str(vo), shell=True) # Button ON AIR def onair_click(): global i m = "" on_air_selection() # vol_onair edit vid = st[:6] with open(radio_dir+"vol.list", 'r') as f: for s in f: if re.search(vid, s): m = s[:6] m = m.strip() with open(radio_dir+"vol.list", 'r') as f: for i, line in enumerate(f): if m in line: if i == 0: break i = i + 1 break # stop def stop_click(): f = open('/tmp/moode_id','w') f.write(' \n') f.close() f = open('/tmp/test_id','w') f.write('1\n') f.close() global st; stp() subprocess.run(bin_dir + "killall.sh", shell=True) stp() # Exit def exit_click(): root.quit() # --- ListenRadio --- def csra1_click(): global t; t=radio_dir+"ListenRadio/csra1"; area_selection();x();y() def csra2_click(): global t; t=radio_dir+"ListenRadio/csra2"; area_selection();x();y() def csra3_click(): global t; t=radio_dir+"ListenRadio/csra3"; area_selection();x();y() def csra4_click(): global t; t=radio_dir+"ListenRadio/csra4"; area_selection();x();y() def csra5_click(): global t; t=radio_dir+"ListenRadio/csra5"; area_selection();x();y() def csra6_click(): global t; t=radio_dir+"ListenRadio/csra6"; area_selection();x();y() def csra7_click(): global t; t=radio_dir+"ListenRadio/csra7"; area_selection();x();y() def csra8_click(): global t; t=radio_dir+"ListenRadio/csra8"; area_selection();x();y() # --- radiko --- def radiko_click(): global t; t=radio_dir+"RADIKO/radiko.list"; area_selection();x();y() # --- NHK --- def nhk_click(): global t; t=radio_dir+"NHK/NHK.list"; area_selection();x();y() # --- moOde --- def moode1_click(): global t; t=radio_dir+"moode/moode1"; area_selection();x();y() def moode2_click(): global t; t=radio_dir+"moode/moode2"; area_selection();x();y() def moode3_click(): global t; t=radio_dir+"moode/moode3"; area_selection();x();y() def moode4_click(): global t; t=radio_dir+"moode/moode4"; area_selection();x();y() def moode5_click(): global t; t=radio_dir+"moode/moode5"; area_selection();x();y() def moode6_click(): global t; t=radio_dir+"moode/moode6"; area_selection();x();y() def moode7_click(): global t; t=radio_dir+"moode/moode7"; area_selection();x();y() def moode8_click(): global t; t=radio_dir+"moode/moode8"; area_selection();x();y() # Scrollbar x def x(): scrollbar = ttk.Scrollbar(frame1,orient=HORIZONTAL,command=lb.xview) lb['xscrollcommand'] = scrollbar.set scrollbar.grid(row=1,column=0,sticky=(E,W)) # Scrollbar y def y(): scrollbar = ttk.Scrollbar(frame1,orient=VERTICAL,command=lb.yview) lb['yscrollcommand'] = scrollbar.set scrollbar.grid(row=0,column=1,sticky=(N,S)) # --- selection --- # PLAY def play_selection(): global st,a,stname station = "" # pulseaudio command = ("ps ax | grep pulseaudio | grep -v grep | awk '{print $NF}'") pulse = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') pulse = pulse.strip() # ListBOX for i in lb.curselection(): a = (lb.get(i)); b = (lb.get(i)); command = ("echo " + a + " | awk '{print $NF}'") a = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') a = a.strip() command = ("echo " + b + " | grep radiko") b = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') b = b.strip() if a == ("---"): messagebox.showinfo('simul radio', 'No URL !') return radko = (b[0:6]) if radko == "radiko": if not pulse: subprocess.run("sudo runuser -l www-data -c 'pulseaudio --start'", shell=True) subprocess.run("streamlink -p " + player + " http://radiko.jp/#!/live/" + a + " best &", shell=True) subprocess.run("pactl set-sink-volume 0 " + str(pulse_vol) + "%", shell=True) time.sleep(5.5) vol3_click() on_air_selection() break elif (pulse) == "--start": subprocess.run("sudo killall pulseaudio", shell=True) time.sleep(3) csra = ("jp/30" in a) nhk = ("live/2023" in a) stname = "" cfg_moode = "" if csra == True or nhk == True: if (pulse) == "--start": subprocess.run("sudo killall pulseaudio", shell=True) if csra == True: command = ("echo " + a + " | grep -oP 'jp/30.{0,3}'") if nhk == True: command = ("echo " + a + " | grep -oP 'live/2023.{0,5}'") cfg_id = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') cfg_id = cfg_id.strip() with open(radio_dir+"cfg_radio.csv", 'r') as f: for id in f: if re.search(cfg_id, id): cfg_moode = id if len(cfg_moode) != 0: cfg_moode = cfg_moode.strip() command = ("echo " + cfg_moode + " | awk -F',' '{print $3}'") stname = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') stname = stname.strip() stname = ("'"+stname+"'" + ".pls") # cfg_radio_csv play subprocess.run("mpc load RADIO/" + stname, shell=True) subprocess.Popen("mpc play &", shell=True) # radio list url play else: subprocess.run("mpc add " + a, shell=True) subprocess.run("mpc play &", shell=True) # other if (pulse) == "--start": subprocess.run("sudo killall pulseaudio", shell=True) time.sleep(1) if csra == False and nhk == False: subprocess.run("mpc add " + a, shell=True) subprocess.run("mpc play &", shell=True) # On Station on_air_selection() # simul_vol.py subprocess.run(bin_dir + "simul_vol.py", shell=True) # ON AIR def on_air_selection(): global st,a,std # playlist command = ("mpc playlist") proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') proc = proc.strip() http = ("http" in proc) # http if http == True: csra = ("jp/30" in proc) nhk = ("live/2023" in proc) # ListenRadio if csra == True: command = ("mpc playlist | grep -oP 'jp/30.{0,3}' | cut -b 4-") proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') proc = proc.strip() st = std; sta() with open(radio_dir+"vol.list", 'r') as f: for id in f: if re.search(proc, id): id = (re.sub('http.*', '', id)) st=id; st=st.strip(); sta() # NHK if nhk == True: command = ("mpc playlist | grep -oP 'live.{0,8}' | awk '{print substr($0,6,7)}'") proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') proc = proc.strip() st = std; sta() with open(radio_dir+"vol.list", 'r') as f: for id in f: if re.search((proc), id): st=id; st=st.strip(); sta() # moOde if csra == False and nhk == False: csv_moode = "" with open(radio_dir+"cfg_radio.csv", 'r') as f: for csvid in f: if re.search(proc, csvid): csv_moode = csvid if len(csv_moode) != 0 and len(proc) != 0: st = std; stc() csv_moode = csv_moode.strip() command = ("echo " + csv_moode + " | awk -F',' '{print $3}'") st = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') st = st.strip() # pulse.php image data subprocess.run("echo " + "'" + st + "'" + " > /tmp/moode_id", shell=True) subprocess.run("test -e /var/www/html/img/'" + st + ".jpg' ; echo $? > /tmp/test_id", shell=True) stc() else: # pulse.php image data (1) f = open('/tmp/test_id','w') f.write('1\n') f.close() # OnAir cfg_radio_csv else: csv_moode = "" with open(radio_dir+"cfg_radio.csv", 'r') as f: for csvid in f: if re.search(proc, csvid): csv_moode = csvid if len(csv_moode) != 0 and len(proc) != 0: csv_moode = csv_moode.strip() command = ("echo " + csv_moode + " | awk -F',' '{print $2}'") url = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') url = url.strip() csra = ("jp/3" in url) nhk = ("live/2023" in url) # ListenRadio if csra == True: st = std; sta() with open(radio_dir+"vol.list", 'r') as f: for id in f: if re.search(proc, id): id = (re.sub('http.*', '', id)) st=id; st=st.strip(); sta() # NHK if nhk == True: st = std; sta() with open(radio_dir+"vol.list", 'r') as f: for id in f: if re.search(proc, id): st=id; st=st.strip(); sta() # pulse.php image data (ListenRadio,NHK) command = ("echo " + stname + " | head -n1 | cut -d. -f1") cara_st = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') cara_st = cara_st.strip() subprocess.run("echo " + "'" + cara_st + "'" + " > /tmp/moode_id", shell=True) subprocess.run("test -e /var/www/html/img/'" + cara_st + ".jpg' ; echo $? > /tmp/test_id", shell=True) # moOde (ON AIR Button) else: proc = (subprocess.Popen('cat /tmp/moode_id', stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') proc = proc.strip() command = ("mpc | head -n1 | cut -d: -f1") air = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') air = air.strip() if air == ("volume"): air = "" if proc != air: proc = air if not(proc): st = 'Simul moOde Radio' stp() else: st = std; stc() st = proc; stc() # on station radiko command = ("ps ax | grep radiko.jp | grep -v grep | awk '{print $(NF-1)}' | awk 'NR==1' | cut -c 8-13") proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') proc = proc.strip() if proc == 'radiko': st = std; stb() command = ("ps ax | grep radiko.jp | grep -v grep | awk '{print $(NF-1)}' | awk 'NR==1' | cut -c 26-") proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8') proc = proc.strip() st=std; stb() with open(radio_dir+"RADIKO/radiko.list", 'r') as f: for id in f: if re.search(proc, id): st=id; st=(st[1:-2]); stb() if not st: stz() st = 'Simul Radio' stp() # AREA def area_selection(): global v1,lb with open(t, 'r') as f: proc = f.read() currencies = (proc) v1 = StringVar(value=currencies) lb = Listbox(frame1, listvariable=v1, background=bg_color, foreground=fg_color,height=lb_h,width=lb_w) lb.grid(row=0, column=0) # Label ListenRadio NHK def sta(): label1 = ttk.Label( frame0, background='#BF538C', foreground='#ffffff', text=st) label1.grid(row=0,column=0) # Label RADIKO def stb(): label1 = ttk.Label( frame0, background='#06793C', foreground='#ffffff', text=st) label1.grid(row=0,column=0) # Label moOde def stc(): label1 = ttk.Label( frame0, background='#4489B7', foreground='#ffffff', text=st) label1.grid(row=0,column=0) # Label default def stz(): global st label1 = ttk.Label( frame0, text = ' ' * 150, background=label_bg, foreground=label_fg) label1.grid(row=0,column=0) def stp(): global st stz() label1 = ttk.Label( frame0, text = st, background=label_bg, foreground=label_fg) label1.grid(row=0,column=0) def moode_id(): subprocess.run("xterm -e less " + "/tmp/moode_id &", shell=True) # --- main ---- if __name__ == '__main__': root = Tk() root.title('Simul moOde Radio') root.configure(background='#333333') # Background color style = ttk.Style() style.theme_use('default') #('clam', 'alt', 'default', 'classic') style.configure('TButton', background='#D9D9D9') # Button color # Listbox(color high-width) # 1F4660(Blue) bg_color='#222222'; fg_color='#ffffff'; lb_h = 27; lb_w = 73 # Listbox Font listfont = Font(family="Helvetica",size=9) root.option_add("*Listbox*Font", listfont) # Frame frame0 = ttk.Frame(root, padding=1) frame0.grid() frame1 = ttk.Frame( root, relief='sunken', borderwidth=1) frame1.grid() frame2 = ttk.Frame(root, padding=7) frame2.grid() frame3 = ttk.Frame(root, padding=7) frame3.grid() # label label_bg='#333333' label_fg='#ffffff' label1 = ttk.Label( frame0, text = ' ' * 150, background=label_bg, foreground=label_fg) label1.grid(row=0,column=0) stp() # Listbox with open(t, 'r') as f: proc = f.read() currencies = (proc) v1 = StringVar(value=currencies) lb = Listbox(frame1, listvariable=v1,background='#222222',foreground='#ffffff', height=lb_h,width=lb_w) lb.grid(row=0, column=0) # Scrollbar y scrollbar = ttk.Scrollbar(frame1, orient=VERTICAL, command=lb.yview) lb['yscrollcommand'] = scrollbar.set scrollbar.grid(row=0,column=1,sticky=(N,S)) # Scrollbar x scrollbar = ttk.Scrollbar(frame1, orient=HORIZONTAL, command=lb.xview) lb['xscrollcommand'] = scrollbar.set scrollbar.grid(row=1,column=0,sticky=(E,W)) # Button color style = Style() style.configure('TButton', font=('Helvetica', 8), background='#E6C0D4') style.configure('R.TButton', font=('Helvetica', 8), background='#E6C0D4') style.configure('G.TButton', font=('Helvetica', 8), background='#A4DCBF') style.configure('B.TButton', font=('Helvetica', 8), background='#A2CCE7') style.configure('Y.TButton', font=('Helvetica', 8), background='#FFEFD5') style.configure('L.TButton', font=('Helvetica', 8), background='#C4CAD0') style.configure('P.TButton', font=('Helvetica', 9), background='#ffffff',foreground='#202020') # Button frame1 button = ttk.Button(frame1, text='----- PLAY SIMUL RADIO -----', width=42, style='Y.TButton', command=play_click) button.grid(row=2, column=0, columnspan=1) # Button frame2 button = ttk.Button(frame2, style='R.TButton', text='favorite1', command=favorite1_click) button.grid(row=0, column=0, columnspan=1) button = ttk.Button(frame2, style='G.TButton', text='favorite2', command=favorite2_click) button.grid(row=0, column=1, columnspan=1) button = ttk.Button(frame2, style='B.TButton', text='moOde(1)', command=moode_f1) button.grid(row=0, column=2, columnspan=1) button = ttk.Button(frame2, style='TButton', text='らじる', command=nhk_click) button.grid(row=0, column=3, columnspan=1) button = ttk.Button(frame2, style='G.TButton', text='radiko', command=radiko_click) button.grid(row=0, column=4, columnspan=1) button = ttk.Button(frame2, style='B.TButton', text='ON AIR', command=onair_click) button.grid(row=0, column=5, columnspan=1) button = ttk.Button(frame2, style='Y.TButton', text='STOP', command=stop_click) button.grid(row=0, column=6, columnspan=1) button = ttk.Button(frame2, style='L.TButton', text='EXIT', command=exit_click) button.grid(row=0, column=7, columnspan=1) button = ttk.Button(frame2, style='Y.TButton', text='favorite3', command=favorite3_click) button.grid(row=1, column=0, columnspan=1) button = ttk.Button(frame2, style='Y.TButton', text='favorite4', command=favorite4_click) button.grid(row=1, column=1, columnspan=1) button = ttk.Button(frame2, style='B.TButton', text='moOde(2)', command=moode_f2) button.grid(row=1, column=2, columnspan=1) button = ttk.Button(frame2, style='Y.TButton', text='--5%', command=vol1_click) button.grid(row=1, column=3, columnspan=1) button = ttk.Button(frame2, style='Y.TButton', text='--2%', command=vol2_click) button.grid(row=1, column=4, columnspan=1) button = ttk.Button(frame2, style='G.TButton', text='Simul Vol', command=vol3_click) button.grid(row=1, column=5, columnspan=1) button = ttk.Button(frame2, style='Y.TButton', text='+2%', command=vol4_click) button.grid(row=1, column=6, columnspan=1) button = ttk.Button(frame2, style='Y.TButton', text='+5%', command=vol5_click) button.grid(row=1, column=7, columnspan=1) # Button frame3 ListenRadio button = ttk.Button(frame3, style='B.TButton', text='0 - 9', command=moode1_click) button.grid(row=0, column=0, columnspan=1) button = ttk.Button(frame3, style='B.TButton', text='ABCDE', command=moode2_click) button.grid(row=0, column=1, columnspan=1) button = ttk.Button(frame3, style='B.TButton', text='F', command=moode3_click) button.grid(row=0, column=2, columnspan=1) button = ttk.Button(frame3, style='B.TButton', text='GHIJK', command=moode4_click) button.grid(row=0, column=3, columnspan=1) button = ttk.Button(frame3, style='B.TButton', text='LMNOPQ', command=moode5_click) button.grid(row=0, column=4, columnspan=1) button = ttk.Button(frame3, style='B.TButton', text='R', command=moode6_click) button.grid(row=0, column=5, columnspan=1) button = ttk.Button(frame3, style='B.TButton', text='S', command=moode7_click) button.grid(row=0, column=6, columnspan=1) button = ttk.Button(frame3, style='B.TButton', text='TUVWXYZ', command=moode8_click) button.grid(row=0, column=7, columnspan=1) #label2 = ttk.Label(frame3, text = "ListenRadio") #label2.grid(row=0,column=0) button = ttk.Button(frame3, text='北海道', command=csra1_click) button.grid(row=1, column=0, columnspan=1) button = ttk.Button(frame3, text='東北', command=csra2_click) button.grid(row=1, column=1, columnspan=1) button = ttk.Button(frame3, text='関東', command=csra3_click) button.grid(row=1, column=2, columnspan=1) button = ttk.Button(frame3, text='北陸', command=csra4_click) button.grid(row=1, column=3, columnspan=1) button = ttk.Button(frame3, text='東海', command=csra5_click) button.grid(row=1, column=4, columnspan=1) button = ttk.Button(frame3, text='近畿', command=csra6_click) button.grid(row=1, column=5, columnspan=1) button = ttk.Button(frame3, text='中国・四国', command=csra7_click) button.grid(row=1, column=6, columnspan=1) button = ttk.Button(frame3, text='九州・沖縄', command=csra8_click) button.grid(row=1, column=7, columnspan=1) # Button edit button = ttk.Button(frame3, style='L.TButton', text='img_file', command=img_file_click) button.grid(row=2, column=1, columnspan=1) button = ttk.Button(frame3, style='L.TButton', text='cfg_Empty', command=cfg_empty_click) button.grid(row=2, column=2, columnspan=1) button = ttk.Button(frame3, style='L.TButton', text='cfg_radio', command=cfg_radio_click) button.grid(row=2, column=3, columnspan=1) button = ttk.Button(frame3, style='L.TButton', text='Vol Edit', command=vol_click) button.grid(row=2, column=4, columnspan=1) button = ttk.Button(frame3, style='L.TButton', text='Area Edit', command=area_click) button.grid(row=2, column=5, columnspan=1) button = ttk.Button(frame3, style='Y.TButton', text='MENU', command=menu_click) button.grid(row=2, column=6, columnspan=1) root.mainloop()