import json import sys import os import unicodedata import webbrowser import urllib.request import re import io from PIL import Image,ImageTk from bs4 import BeautifulSoup from tkinter import Label,Button,Frame,Tk,Entry,StringVar,LEFT,RIGHT,PhotoImage,Image,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("",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) 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_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_canvas) 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): self.datafilepath=os.path.dirname(os.path.realpath(__file__))+"/chaine.json" self.data = load_jsonfile(self.datafilepath) 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("", self.enter) self.fenetre.bind("", 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()) try: strlink=geturlprogrammetv(self.data[self.value.get()]) link= Labbelink(self.resultframe.interior,self.data[self.value.get()],strlink) link.pack() self.resultframe.update() print(self.data[self.value.get()]) 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): parsechaine(self.datafilepath) self.data = load_jsonfile(self.datafilepath) labelupdate = Label(self.resultframe, text="update chaine done"+"\r") labelupdate.pack() def _openlink(self,link): webbrowser.open_new(link) def load_jsonfile(file): try: with open(file, 'r', encoding='utf-8') as f: return json.load(f) except FileNotFoundError: parsechaine(file) with open(file, 'r', encoding='utf-8') as f: return json.load(f) def RepresentsInt(s): try: int(s) return True except ValueError: return False except TypeError: return False def parsechaine(file): 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[int(num)] = firstTD.find_next().find_next().text else: #print(firstTD.find_next().string) liste_chaine[int(num)] = firstTD.find_next().text print(json.dumps(liste_chaine, indent=4)) with open(file, 'w', encoding='utf-8') as f: json.dump(liste_chaine, f, indent=4) 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")) i=0 for actor in casting: casting[i]=actor.text i+=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): datafilepath=os.path.dirname(os.path.realpath(__file__))+"/chaine.json" data = load_jsonfile(datafilepath) 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("") if len(sys.argv) > 1: for i in sys.argv[1:]: if i =="update": parsechaine(os.path.dirname(os.path.realpath(__file__))+"/chaine.json") else: cli(i) else: Interface().mainloop()