chainetv/chaineTV.py
2018-08-22 14:23:19 +02:00

282 lines
9.8 KiB
Python

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("<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)
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)
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("<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())
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()