cineclub-script/cineclubBlogSQ.py
Alice 05d20ec695 better one-by-one adding actors
new functionality : calendar from current film
clear exit with Ctrl-D
easier input mode thanks to readline
stay into program after adding a film and selecting it
BUGFIX : modify actors or idN
init BDD OK
TODO: add auto-completion
2019-03-09 03:43:35 +01:00

381 lines
17 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 1 22:49:56 2018
@author: alice
TODO :
* simplifier l'input autant que possible
* remplir
* débug
* documenter
* publication FB
"""
import sqlite3
import datetime
from datetime import date
import locale
locale.setlocale(locale.LC_ALL, 'fr_FR.utf8')
#def adapt_datetime(ts):
# return time.mktime(ts.timetuple())
#sqlite3.register_adapter(datetime.date, adapt_datetime)
class filmSQ():
def __init__(self, dic):
"""ceci est une aide"""
if type(dic) == type(""):
self.idN = dic
conn = sqlite3.connect("baseFilms.db")
conn.row_factory = sqlite3.Row
c = conn.cursor()
try:
c.execute("""SELECT i FROM films WHERE idN = ?""",(dic,))
r = c.fetchone()
self.i = r[0]
conn.commit()
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
elif type(dic) == type(1):
self.i = dic
conn = sqlite3.connect("baseFilms.db")
conn.row_factory = sqlite3.Row
c = conn.cursor()
try:
c.execute("""SELECT idN FROM films WHERE i = ?""",(dic,))
r = c.fetchone()
self.idN = r[0]
conn.commit()
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
else:
conn = sqlite3.connect("baseFilms.db")
conn.row_factory = sqlite3.Row
c = conn.cursor()
try:
c.execute('INSERT INTO films VALUES (:i, :idN, :date, :nom, :realisateur, :duree, :synopsis, :pays, :annee, :youtube, :couleur, :image, :formatCopie, :langST)', dic)
acteursToSq = [{'idFilm' : dic['i'], 'acteur' : a} for a in dic['acteurs']]
c.executemany('INSERT INTO acteurs VALUES (NULL, :idFilm, :acteur)', acteursToSq)
conn.commit()
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
#id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT [PRIMARY KEY]
self.__setattr__('idN', dic['idN'])
def __setattr__(self, nom_attr, val_attr):
if nom_attr == 'idN':
object.__setattr__(self, 'idN', val_attr)
else:
try:
conn = sqlite3.connect("baseFilms.db")
conn.row_factory = sqlite3.Row
c = conn.cursor()
if nom_attr == 'acteurs':
c.execute("""DELETE FROM acteurs WHERE iFilm =?""", (self.i,))
acteursToSq = [{'iFilm' : self.i, 'acteur' : a} for a in val_attr]
c.executemany('INSERT INTO acteurs VALUES (NULL, :iFilm, :acteur)', acteursToSq)
else:
c.execute('UPDATE films SET %s = ? WHERE idN = ?' % nom_attr, (val_attr, self.idN))
conn.commit()
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
def __getattr__(self, nom):
conn = sqlite3.connect("baseFilms.db", detect_types=sqlite3.PARSE_DECLTYPES)
conn.row_factory = sqlite3.Row
c = conn.cursor()
try:
if nom == 'acteurs':
c.execute("""SELECT name FROM acteurs WHERE iFilm=?""", (self.i,))
r = c.fetchall()
res = [a[0] for a in r]
else:
c.execute("""SELECT %s FROM films WHERE idN=:idN""" % nom, {"idN":self.idN})
r = c.fetchone()
res = r[0]
conn.commit()
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
return res
def __str__(self):
try:
conn = sqlite3.connect("baseFilms.db")
#conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('SELECT idN, nom, date FROM films WHERE idN = ?', (self.idN))
r = c.fetchone()
s = r[0] + ' : ' + r[1] + ' le ' + r[2]
conn.commit()
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
return s
def blog(self):
res = u'<div class="entry-trailer"><iframe src="'
res += self.youtube
res += u'" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></div><br />'
res += u'<!-- Commentaire pertinent quelconque vis-à-vis du film --> <div class="entry-mainblock"> \
<div class="entry-separator"><img class="alignnone wp-image-1873 size-medium" src="'+self.image+'" alt="" width="300" height="300" /></a></div> \
<div class="entry-text-info"><b> Durée </b>:'
res += str(self.duree) + " minutes"
if self.couleur:
res += u'<br /><b>Couleur</b>'
else:
res += u'<br /><b>Noir et blanc</b>'
res += u'<br /><b>Pays :</b>' + self.pays
res += u'<br /><b>' + self.formatCopie + ' . ' + self.langST +'</b>'
res += u'<br /><b>Année :</b>' + str(self.annee)
res += u'<br /><b>Avec :</b>' + strListe(self.acteurs)
res += u'<br /><div class="entry-text-info"><strong>Synopsis</strong> : ' + self.synopsis + '</div>'
res += u"<br /></div>"
res += u"Comme d'habitude, l'entrée coûte 4 euros, 3 pour les membres du COF et vous avez la possibilité d'acheter des cartes de 10 places pour respectivement 30 et 20 euros. L'entrée est gratuite pour les étudiant.e.s invité.e.s."
res += u'<div class="entry-resume"> Et pour résumer : <div class="resume-bloc"><span class="resume-date">Rendez-vous le ' + self.date.strftime("mardi %d %B %Y")
res += u', 20h30</span><br /><span class="resume-place">en salle Dussane, au 45 rue ' + "d'Ulm</span><br />" + '<span class="resume-see">pour voir et revoir</span> <br /><span class="resume-title">'
res += self.nom + u'</span><br /><span class="resume-director"> de ' + self.realisateur
res += u"</span><br /></div></div><!-- Balise de commentaire à retirer lors de l'insertion de l'analyse" + u'<div class="entry-analyse">'
res += u"<h2>Proposition d'analyse</h2>Bientôt…</div>-->"
return res
def calendrier(self):
res = '<!-- Film #' + str(self.i) + ' --> \n \n <div class="entry-mainblock"> <div class="entry-separator">'
res += '<img class="alignnone size-full wp-image-1963" src="'+self.image+'" alt="" width="150" height="150"/></div>'
res += '<div class="entry-text-info"><br /><br /><b>' + self.date.strftime("mardi %d %B %Y") +', 20h30 <br /><i>'
res += self.nom + '</i> de ' + self.realisateur +' (' +str(self.annee) + ')</b><br /><br />'
res += str(self.duree) + ' minutes . '
if self.couleur:
res += "Couleurs"
else:
res += "Noir & Blanc"
res += " . " + self.pays + ". <br /> Avec : " + strListe(self.acteurs) + ".<br/>"
res += self.langST + ' . ' + self.formatCopie + ".<br/><br/>"
res += '<span class="entry-synopsis">' + self.synopsis + '</span><br/><br/></div>'
res += '<div class="entry-break"></div>'
res += '</div><br/><a style="float: right;" href="#haut">Retour en haut de page</a>'
res += "<br/>\n \n<!-- END OF POST --><br/>"
return res
def allCalendars(self):
conn = sqlite3.connect("baseFilms.db", detect_types=sqlite3.PARSE_DECLTYPES)
conn.row_factory = sqlite3.Row
c = conn.cursor()
res = ""
try:
conn = sqlite3.connect("baseFilms.db")
#conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('SELECT idN FROM films WHERE date>=? ', (self.date,))
#c.executemany('INSERT INTO acteurs VALUES (NULL, :iFilm, :acteur)', acteursToSq)
r = c.fetchall()
listFilms = [filmSQ(a[0]) for a in r]
conn.commit()
for film in listFilms:
res += film.calendrier() + "\n\n"
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
return res
def bocal(self):
res = "\centerline{\date{" + self.date.strftime("mardi %d %B %Y") + ", 20h30}} \n"
res += "\centerline{Salle Dussane} \n"
res += "\centerline{\emph{\Large " + self.nom + "}} \n"
res += "\centerline{" + self.realisateur + " (" + str(self.annee) + ") } \n"
res += "\medskip \n"
if len(self.acteurs) == 1 :
res += "\centerline{" + self.acteurs[0] + "}\n"
if len(self.acteurs) >= 2 :
res += "\centerline{" + self.acteurs[0]+ ', ' + self.acteurs[1] + "}\n"
if len(self.acteurs) > 2 :
res += "\centerline{" + self.acteurs[2] + "}\n"
res += "\medskip \n"
res += "\centerline{" + self.langST + ' . ' + self.formatCopie + "}\n"
res += "\medskip \n"
res += "\centerline{\\textit{" + str(self.duree) + " minutes}}\n \n"
res += "\medskip\n"
res += "\medskip \n \centerline{4~€~/~3~€ COF} \n \medskip \n \n "
res += "\centerline{\includegraphics[width=5cm]{cine}}\n \n"
res += "\medskip\n"
res += self.synopsis
return res
def mail(self):
res = '<html> \n \t <head> \n \n <meta http-equiv="content-type" content="text/html; charset=utf-8"> \n \t \t'
res += '<style type="text/css">p { margin: 0; }</style> \n \t \t'
res += '<title>[cine-info] ' + self.nom + ' de ' + self.realisateur + ' (' + self.date.strftime("mardi %d %B %Y") + ', 20h30)</title> \n \t'
res += '</head> \n \t <body text="#000000" bgcolor="#FFFFFF"> \n \t \t <div style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000">'
res += '\n \t \t \t<style>p { margin: 0; }</style> \n \t\t\t'
res += '<div style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000"> \n <style>p { margin: 0; }</style> \n <div style="font-family: arial,helvetica,sans-serif; font-size: 12pt; color: #000000">'
res += '\n \t\t\t\t\t <style>p { margin: 0; }</style> \n\t\t\t\t <div style="font-family: arial,helvetica,sans-serif;font-size: 12pt; color: #000000"> \n'
res += '<p>Bonjour à toutes et à tous,</p> \n <p><i>Ce mail contient du HTML. Si vous ne pouvez pas le lire, allez sur notre site : <a class="moz-txt-link-freetext" href="http://www.cineclub.ens.fr" target="_blank">http://www.cineclub.ens.fr</a></i></p>'
res += '\n <p style="text-align:justify">Retrouvez-nous en salle Dussane <b>' + self.date.strftime("mardi %d %B %Y") + ", 20h30</b> ! Comme d'habitude, l'entrée coûte <b>4€, 3€</b> pour les membres du COF et vous avez la possibilité d'acheter des cartes de 10 places pour respectivement 30€ et 20€. L'entrée est gratuite pour les étudiants invités.<br>"
res += '</p> <div style="border:grey 1px solid; padding:5px; text-align:justify;">'
res += '<center><b><i>'+ self.nom +'</i></b> \n de <b>' + self.realisateur + '<br>\n </b></center>\n <br>'
res += '<b>Durée </b>: '+ str(self.duree) + ' minutes.<br> \n'
if self.couleur:
res +'<b>Couleur</b>. <br> \n'
else:
res += '<b>Noir et blanc</b> <br> \n'
res += '<b>Pays :</b> ' + self.pays + '<br> \n'
res += '<b> ' + self.formatCopie + ' . ' + self.langST + '</b> <br> \n'
res += '<b>Année :</b> ' + str(self.annee) + '<br> \n'
res += '<b>Avec :</b> ' + strListe(self.acteurs) + '...<br> \n'
res += '<b>Rapide synopsis :</b> ' + self.synopsis + '<br> <br>'
res += '<span class="entry-synopsis"> </span> <br> <center><a href="http://cineclub.ens.fr" title="Plus d\'informations (bande-annonce, synopsis, etc.) sur notre blog !" target="_blank">Plus d\'informations (bande-annonce, etc.) sur notre blog !</a></center>'
res += '</div> <p style="text-align:justify">Vous ne pouvez pas venir à cette séance mais vous aimeriez aller au ciné-club une prochaine fois ?<br>'
res += '<a href="http://cineclub.ens.fr/calendrier" title="Découvrez le calendrier de nos prochaines séances." target="_blank">Découvrez le calendrier de nos prochaines séances.</a></p>'
res += '<p>À très bientôt en salle Dussane !<br> L\'équipe du ciné-club<br> <a href="http://cineclub.ens.fr" title="http://cineclub.ens.fr" target="_blank">http://cineclub.ens.fr</a></p>'
res += '<p>Toutes les séances du ciné-club se déroulent en salle Dussane, au 45 rue d\'Ulm, Paris. <br> Métro : Luxembourg, Place Monge. Bus: Feuillantine.</p>'
res += '<p style="text-align:center"><small>Vous ne souhaitez plus recevoir notre newsletter ? <a href="http://www.cineclub.ens.fr/newsletter-desinscription/" target="_blank"> Désinscrivez-vous</a></small></p>'
res += '</div> </div> </body> </html>'
return res
def facebook(self):
res = self.nom + " - " + self.realisateur
res += " \n \n"
res += self.synopsis
res += " \n \n"
res += "Durée : " + str(self.duree) + " minutes \n"
if self.couleur:
res += 'Couleur \n'
else:
res += 'Noir et blanc\n'
res += "Pays : " + self.pays + "\n"
res += self.formatCopie + " . " + self.langST + "\n"
res += "Année : " + str(self.annee) + "\n"
res += 'Avec : ' + strListe(self.acteurs) + '...\n'
res += "Plus d'informations sur notre site Internet http://www.cineclub.ens.fr/category/seances/ \n"
res += "\n Comme dhabitude, lentrée coûte 4€, 3€ pour les membres du COF (association d'élèves de l'ENS). Lentrée est gratuite pour les membres du Programme Étudiant⋅e⋅s Invité⋅e⋅s."
res += " \n L'accès est ouvert à tous ; pas besoin d'être à l'ENS !"
return res
def maxId():
try:
conn = sqlite3.connect("baseFilms.db")
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('SELECT MAX(i) FROM films')
r = c.fetchone()
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
return r[0]
def printAll():
try:
conn = sqlite3.connect("baseFilms.db")
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('SELECT idN, nom, date, i FROM films ORDER BY i ASC')
r = c.fetchall()
for movie in r:
print(movie[3], ' - ', movie[0], ' : ', movie[1], ' le ', movie[2])
except Exception as e:
conn.rollback()
raise e
finally:
conn.close()
pass
def makeListActors():
l = []
new = input("Entrez le nom des acteurs en appuyant sur Entrée entre chaque.gccPour terminer, appuyer sur Entrée avec une ligne vide.\n")
if (new == -1):
return -1
while(new != ""):
l += [new]
new = input()
pass
return l
def newFilm():
"""Interface d'ajout d'un nouveau film"""
dic = {}
i = filmSQ.maxId()
dic['i'] = i+1
dic['idN'] = input("identifiant du film ? ")
d = input("date de la séance (format JJ/MM/AAAA ) ")
d = d.split("/")
dic['date'] = date(int(d[2]), int(d[1]), int(d[0]))
dic['nom'] = input("titre ? ")
dic['acteurs'] = filmSQ.makeListActors()
#eval(input("acteurs (format [acteur1, acteur2, ..]) ? "))
dic['realisateur'] = input("realisateur ? ")
dic['duree'] = eval(input("durée du film (en minutes)? "))
dic['synopsis'] = input("Donnez ici un synopsis rapide du film ")
dic['pays'] = input("pays de diffusion du film ? ")
dic['annee'] = input("année de sortie du film (format AAAA) ? ")
dic['youtube'] = input("adresse youtube de la bande-annonce ? ")
dic['image'] = input("url d'une affiche du film ? ")
dic['couleur'] = eval(input("le film est-il en couleur (format True/False) ? "))
dic['formatCopie'] = input("format de la copie ? ")
dic['langST'] = input("langue et sous-titre : VF/VOSTFR ? ")
seance = filmSQ(dic)
return seance
def strListe(liste):
res = ""
for l in liste[:-1]:
res += l +', '
if liste != []:
res += liste[-1]
return res