296 lines
10 KiB
Python
296 lines
10 KiB
Python
import json
|
|
import sys
|
|
import os
|
|
import unicodedata
|
|
import webbrowser
|
|
import urllib.request
|
|
import re
|
|
import io
|
|
from PIL import ImageTk
|
|
from bs4 import BeautifulSoup
|
|
from tkinter import Label,Button,Frame,Tk,Entry,StringVar,LEFT,RIGHT,Scrollbar,VERTICAL,Canvas,Y,BOTH,NW
|
|
|
|
|
|
|
|
class Labbelink (Label):
|
|
|
|
def __init__(self,parent,text,link):
|
|
Label.__init__(self,parent,text=text,fg="blue",cursor="hand2")
|
|
self.link=link
|
|
self.bind("<Button-1>",self._openlink)
|
|
|
|
def _openlink(self,evt):
|
|
webbrowser.open(self.link)
|
|
|
|
class LabelImage(Label):
|
|
|
|
def __init__(self,parent,url):
|
|
raw_data = urllib.request.urlopen(url).read()
|
|
imagetoinsert=ImageTk.PhotoImage(file=io.BytesIO(raw_data))
|
|
Label.__init__(self,parent,image=imagetoinsert)
|
|
self.image = imagetoinsert
|
|
|
|
|
|
class ScrollableCanvas(Frame):
|
|
def __init__(self, parent, *args, **kw):
|
|
Frame.__init__(self, parent, *args, **kw)
|
|
|
|
canvas=Canvas(self,width=300,height=300,scrollregion=(0,0,500,500))
|
|
|
|
vbar=Scrollbar(self,orient=VERTICAL)
|
|
vbar.pack(side=RIGHT, fill=Y)
|
|
vbar.config(command=canvas.yview)
|
|
|
|
canvas.config(width=200,height=200)
|
|
canvas.config(yscrollcommand=vbar.set)
|
|
canvas.pack(side=LEFT,expand=True,fill=BOTH)
|
|
|
|
# create a frame inside the canvas which will be scrolled with it
|
|
self.interior = interior = Frame(canvas)
|
|
interior_id = canvas.create_window(0, 0, window=interior, anchor=NW )
|
|
# track changes to the canvas and frame width and sync them,
|
|
# also updating the scrollbar
|
|
def _configure_interior(event):
|
|
# update the scrollbars to match the size of the inner frame
|
|
size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
|
|
canvas.config(scrollregion="0 0 %s %s" % size)
|
|
canvas.yview_moveto(1)
|
|
if interior.winfo_reqwidth() != canvas.winfo_width():
|
|
# update the canvas's width to fit the inner frame
|
|
canvas.config(width=interior.winfo_reqwidth())
|
|
interior.bind('<Configure>', _configure_interior)
|
|
|
|
def _configure_canvas(event):
|
|
if interior.winfo_reqwidth() != canvas.winfo_width():
|
|
# update the inner frame's width to fill the canvas
|
|
canvas.itemconfigure(interior_id, width=canvas.winfo_width())
|
|
canvas.bind('<Configure>', _configure_canvas)
|
|
|
|
def _MouseWhell(event):
|
|
canvas.yview_scroll(-1*(event.delta/120), "units")
|
|
self.bind_all("<MouseWheel>",_MouseWhell)
|
|
|
|
|
|
|
|
class emmisionGUI(Frame):
|
|
def __init__(self,parent,**kwarg):
|
|
Frame.__init__(self,parent)
|
|
self.image=LabelImage(self,kwarg['img'])
|
|
self.image.pack()
|
|
self.LabelTitle=Labbelink(self,("emmision ce soir: "+kwarg["title"]),kwarg['href'])
|
|
self.LabelTitle.pack()
|
|
if len(kwarg['casting']) > 0:
|
|
self.LabelReal=Label(self,text="réalisateur: "+kwarg['casting'][0])
|
|
self.LabelReal.pack()
|
|
self.labelCasting=Label(self,text="acteur: "+str(kwarg['casting'][1:]))
|
|
self.labelCasting.pack()
|
|
self.LabelSynopsys=Label(self,text="synopsys: " +kwarg['synopsis'],wraplength=350)
|
|
self.LabelSynopsys.pack()
|
|
|
|
|
|
class Interface:
|
|
|
|
def __init__(self,data):
|
|
self.data = data
|
|
self.fenetre = Tk()
|
|
self.fenetre.title("recherche de chaine")
|
|
self.value = StringVar()
|
|
self.label = Label(self.fenetre, text="entrer numero de chaine")
|
|
self.entree = Entry(self.fenetre, textvariable=self.value, width=30)
|
|
self.frame = Frame(self.fenetre)
|
|
self.resultframe = ScrollableCanvas(self.fenetre)
|
|
self.bouton_update_base = Button(self.fenetre, text="update la base de chaine", command=self.click_update)
|
|
self.bouton = Button(self.frame, text="OK", command=self.click)
|
|
self.reset = Button(self.frame, text="reset", command=self.click_reset)
|
|
self.label.pack()
|
|
self.entree.pack()
|
|
self.entree.focus_set()
|
|
self.resultframe.pack(expand=1,fill='both')
|
|
self.frame.pack()
|
|
self.bouton.pack(side=LEFT)
|
|
self.reset.pack(side=RIGHT)
|
|
self.bouton_update_base.pack()
|
|
self.fenetre.bind("<Key-Return>", self.enter)
|
|
self.fenetre.bind("<Key-Escape>", self.eventreset)
|
|
|
|
|
|
def enter(self,evt):
|
|
self.click()
|
|
|
|
def eventreset(self,evt):
|
|
self.click_reset()
|
|
|
|
def mainloop(self):
|
|
self.fenetre.mainloop()
|
|
|
|
def click(self):
|
|
print(self.value.get())
|
|
Arrayvalue=self.value.get().split(" ")
|
|
for value in Arrayvalue:
|
|
|
|
|
|
try:
|
|
strlink=geturlprogrammetv(self.data.get_chaine(value))
|
|
link= Labbelink(self.resultframe.interior,self.data.get_chaine(value),strlink)
|
|
link.pack()
|
|
self.resultframe.update()
|
|
print(self.data.get_chaine(value))
|
|
emision=parse_emmission(strlink)
|
|
if emision:
|
|
if emision == "can't find show":
|
|
Label(self.resultframe.interior,text="impssible de parser cette chaine").pack()
|
|
else:
|
|
emmisionGUI(self.resultframe.interior,**emision).pack()
|
|
else:
|
|
Label(self.resultframe.interior,text="pas de connection internet impossible de determiner l'émission du soir").pack()
|
|
|
|
|
|
except KeyError:
|
|
print("numero de chaine inconnue")
|
|
unknow=Label(self.resultframe.interior, text="numero de chaine inconnue")
|
|
unknow.pack()
|
|
|
|
self.value.set("")
|
|
|
|
def click_reset(self):
|
|
print("reset")
|
|
for child in self.resultframe.interior.winfo_children():
|
|
child.destroy()
|
|
|
|
|
|
def click_update(self):
|
|
self.data.parsechaine()
|
|
labelupdate = Label(self.resultframe.interior, text="update chaine done"+"\r")
|
|
labelupdate.pack()
|
|
|
|
def _openlink(self,link):
|
|
webbrowser.open_new(link)
|
|
|
|
|
|
class JSONfile:
|
|
|
|
def __init__(self,filename):
|
|
import os,json
|
|
self.datafilepath=os.path.dirname(os.path.realpath(__file__))+"/"+filename
|
|
try:
|
|
with open(self.datafilepath, 'r', encoding='utf-8') as f:
|
|
self.data=json.load(f)
|
|
except FileNotFoundError:
|
|
self.parsechaine()
|
|
|
|
def get_chaine(self,number):
|
|
return self.data[number]
|
|
def parsechaine(self):
|
|
|
|
URL = 'https://fr.wikipedia.org/wiki/Liste_des_cha%C3%AEnes_de_Canal'
|
|
liste_chaine = {}
|
|
response = urllib.request.urlopen(URL)
|
|
html = response.read()
|
|
parse = BeautifulSoup(html,"html.parser")
|
|
for item in parse.find_all('table'):
|
|
if (item.get("class") == ['wikitable'] or item.get("class") == ['wikitable', 'sortable']):
|
|
for tr in item.find_all('tr'):
|
|
|
|
firstTD = tr.find()
|
|
num = firstTD.text
|
|
#print(num)
|
|
if RepresentsInt(num):
|
|
|
|
if RepresentsInt(firstTD.find_next().string):
|
|
#print(firstTD.find_next().find_next().text)
|
|
liste_chaine[str(int(num))] = firstTD.find_next().find_next().text
|
|
else:
|
|
#print(firstTD.find_next().string)
|
|
liste_chaine[str(int(num))] = firstTD.find_next().text
|
|
print(json.dumps(liste_chaine, indent=4))
|
|
self.data=liste_chaine
|
|
with open(self.datafilepath, 'w', encoding='utf-8') as f:
|
|
json.dump(liste_chaine, f, indent=4)
|
|
def __repr__(self):
|
|
return str(self.data)
|
|
|
|
def RepresentsInt(s):
|
|
try:
|
|
int(s)
|
|
return True
|
|
except ValueError:
|
|
return False
|
|
except TypeError:
|
|
return False
|
|
|
|
def geturlprogrammetv(strsearch):
|
|
strsearch=unicodedata.normalize('NFD', strsearch).encode('ascii', 'ignore')
|
|
strsearch=strsearch.decode("utf-8")
|
|
strsearch=strsearch.replace(" ","+")
|
|
return "https://www.programme-tv.net/rechercher?q="+strsearch
|
|
|
|
|
|
def parse_emmission(URL):
|
|
try:
|
|
response = urllib.request.urlopen(URL)
|
|
except urllib.error.URLError:
|
|
return False
|
|
|
|
html = response.read()
|
|
parse=BeautifulSoup(html,"html.parser")
|
|
link=parse.select_one(".prog_name")
|
|
if link == None:
|
|
return "can't find show"
|
|
href="https://www.programme-tv.net"+link['href']
|
|
response = urllib.request.urlopen(href)
|
|
html = response.read()
|
|
parse=BeautifulSoup(html,"html.parser")
|
|
divcasting=parse.select_one(".descriptif")
|
|
casting=divcasting.find_all(href=re.compile("biographie"))
|
|
count=0
|
|
for actor in casting:
|
|
casting[count]=actor.text
|
|
count+=1
|
|
divsynopsis=parse.select_one(".episode-synopsis")
|
|
img=divsynopsis.find_next('img')['data-src']
|
|
synopsis=divsynopsis.select_one(".d-b").text
|
|
return {'title':link['title'],'href':href,'casting':casting,'synopsis':remove_first_space(synopsis),'img':img}
|
|
|
|
|
|
def remove_first_space (string):
|
|
space_number=0
|
|
for char in string:
|
|
if char.isspace():
|
|
space_number+=1
|
|
else:
|
|
break
|
|
return string[space_number:]
|
|
|
|
|
|
def cli(num,data):
|
|
print(num)
|
|
try:
|
|
print(data[num])
|
|
except KeyError:
|
|
print("numero de chaine inconnue")
|
|
return
|
|
emision=parse_emmission(geturlprogrammetv(data[num]))
|
|
if emision:
|
|
if emision == "can't find show":
|
|
print ("impssible de parser cette chaine")
|
|
else:
|
|
print("emmision ce soir: "+emision["title"])
|
|
if len(emision['casting']) > 0:
|
|
print("réalisateur: "+emision['casting'][0])
|
|
print("acteur: "+str(emision['casting'][1:]))
|
|
print("synopsys: " +emision['synopsis'])
|
|
print("lien: "+emision['href'])
|
|
|
|
else:
|
|
print("pas de connection internet impossible de determiner l'émission du soir")
|
|
print("")
|
|
|
|
data=JSONfile("chaine.json")
|
|
if len(sys.argv) > 1:
|
|
for arg in sys.argv[1:]:
|
|
if arg =="update":
|
|
data.parsechaine()
|
|
else:
|
|
cli(arg,data.data)
|
|
else:
|
|
Interface(data).mainloop() |