1777 lines
72 KiB
Python
Executable File
1777 lines
72 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Application de gestion de cave à cigares
|
|
WTFPL @ Jérôme LAUNAY
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import locale
|
|
import ntpath
|
|
import sqlite3
|
|
import configparser
|
|
|
|
import gi
|
|
gi.require_version('Gtk', '3.0')
|
|
try:
|
|
from gi.repository import Gtk as gtk, GdkPixbuf
|
|
except ImportError:
|
|
print("GTK (PyGI) n'est pas installé")
|
|
sys.exit(1)
|
|
|
|
__BDD__ = "bdd/main.db"
|
|
__CONFDIR__ = os.path.dirname(os.path.realpath("MesCigares.py"))
|
|
__CONFIGFILE__ = "conf/mescigares.conf"
|
|
|
|
"""
|
|
Class MesCigares
|
|
"""
|
|
class MesCigares(object):
|
|
|
|
@classmethod
|
|
def on_window_main_destroy(cls, widget, data=None):
|
|
del widget, data
|
|
db.close()
|
|
gtk.main_quit()
|
|
|
|
@classmethod
|
|
def on_gtk_quit_activate(cls, menuitem, data=None):
|
|
del menuitem, data
|
|
db.close()
|
|
gtk.main_quit()
|
|
|
|
def on_gtk_about_activate(self, menuitem, data=None):
|
|
del menuitem, data
|
|
self.aboutdialog.run()
|
|
self.aboutdialog.hide()
|
|
|
|
# Mise à jour de la quantité en fonction du cigare choisi dans la liste
|
|
# déroulante
|
|
def on_cbchoixcigqte_changed(self, objt, data=None):
|
|
del objt, data
|
|
item = self.cbchoixcigqte.get_active()
|
|
|
|
# Si aucune séléction, pas besoin de traitement.
|
|
if item == -1:
|
|
return
|
|
|
|
model = self.cbchoixcigqte.get_model()
|
|
idc = model[item]
|
|
|
|
cursor = db.cursor()
|
|
qte = cursor.execute("Select quantite from stocks " +
|
|
"where id_cigare = '{0}'"
|
|
.format(idc[0])).fetchone()[0]
|
|
cursor.close()
|
|
|
|
self.scaleqte.set_value(int(qte))
|
|
|
|
# Permet d'alimenter la treeview avec la liste des cigares
|
|
def loadtreeview(self):
|
|
if len(self.table) != 0:
|
|
self.table.clear()
|
|
|
|
cursor = db.cursor()
|
|
cursor.execute('Select c.designation, m.libelle, ' +
|
|
'mo.module,m.provenance,s.quantite,' +
|
|
'c.id from cigares c inner join modules mo on ' +
|
|
'mo.id = c.module inner join marques m on m.id = ' +
|
|
'c.marque inner join stocks s on s.id_cigare = c.id')
|
|
rs = cursor.fetchall()
|
|
|
|
cursor.execute("select avg(d.note), max(d.note),id_cigare " +
|
|
"from degustation d group by id_cigare")
|
|
rs2 = cursor.fetchall()
|
|
# top = 5 premier items de la liste par meilleure note [2] pour la note
|
|
# seulement
|
|
top = sorted(rs2, reverse=True)[0:5]
|
|
print(top)
|
|
# top5 = juste les id
|
|
top5 = list()
|
|
for i in top:
|
|
top5.append(i[2])
|
|
|
|
cursor.execute("select min(prix),id_cigare from achats " +
|
|
"group by id_cigare")
|
|
rs3 = cursor.fetchall()
|
|
|
|
cursor.execute("select commentaires, id_cigare from degustation " +
|
|
"group by id_cigare")
|
|
rs4 = cursor.fetchall()
|
|
|
|
for item in rs:
|
|
itr = self.table.append()
|
|
# Si le nombre de cigares est = 0 on affiche la ligne en rouge
|
|
# clair
|
|
if item[4] == 0:
|
|
color = '#F3B9B9' # rouge clair
|
|
else:
|
|
color = '#FFFFFF' # blanc
|
|
|
|
# On regarde si l'enregistrement est dans le top 5
|
|
try:
|
|
index = top5.index(item[5])
|
|
except Exception:
|
|
index = 9
|
|
# Et on affecte la couleur (dégradé de vert)
|
|
if index == 0:
|
|
topcolor = '#8FFF80'
|
|
if index == 1:
|
|
topcolor = '#A4FF97'
|
|
if index == 2:
|
|
topcolor = '#BFFFB7'
|
|
if index == 3:
|
|
topcolor = '#CDFFC7'
|
|
if index == 4:
|
|
topcolor = '#DBFFD7'
|
|
if index == 9:
|
|
topcolor = color
|
|
|
|
self.table.set(itr, 0, item[0], 1, item[1], 2, item[2].title(), 3,
|
|
item[3].title(), 4, item[4], 5, item[5], 11,
|
|
color, 12, topcolor)
|
|
# Il n'y a pas de outer join en sqlite du coup je suis obligé
|
|
# d'alimenter les notes à part
|
|
for item2 in rs2:
|
|
itr = self.table.get_iter_first()
|
|
while itr is not None:
|
|
# itr, 5 = id de la table cigare (colonne 4 invisible),
|
|
# item2[2] = id_cigare table degustation
|
|
if self.table.get_value(itr, 5) == item2[2]:
|
|
self.table.set(itr, 6, item2[1], 7, item2[0])
|
|
itr = self.table.iter_next(itr)
|
|
for item3 in rs3:
|
|
itr = self.table.get_iter_first()
|
|
while itr is not None:
|
|
# itr, 5 = id de la table cigare (colonne 4 invisible),
|
|
# item3[1] = id_cigare table achats
|
|
if self.table.get_value(itr, 5) == item3[1]:
|
|
# .2f pour 2 decimales
|
|
it = '%.2f' % item3[0]
|
|
self.table.set(itr, 8, it + " €", 10, float(item3[0]))
|
|
itr = self.table.iter_next(itr)
|
|
for item4 in rs4:
|
|
itr = self.table.get_iter_first()
|
|
while itr is not None:
|
|
# itr, 4 = id de la table cigare (colonne 4 invisible),
|
|
# item4[1] = id_cigare table achats
|
|
if self.table.get_value(itr, 5) == item4[1]:
|
|
self.table.set(itr, 9, item4[0])
|
|
itr = self.table.iter_next(itr)
|
|
|
|
# On calcule le nombre de cigares et le prix
|
|
nbcigares = 0
|
|
montant = 0
|
|
itr = self.table.get_iter_first()
|
|
while itr is not None:
|
|
nbcigares += int(self.table.get_value(itr, 4))
|
|
if self.table.get_value(itr, 8) is not None:
|
|
montant += float(self.table.get_value(itr, 10)) * \
|
|
int(self.table.get_value(itr, 4))
|
|
itr = self.table.iter_next(itr)
|
|
montant = float('%.2f' % montant)
|
|
|
|
# On calcule le prix total
|
|
montant_total = 0
|
|
cursor.execute("select prix, quantite from achats")
|
|
rs = cursor.fetchall()
|
|
|
|
for item in rs:
|
|
montant_total += (item[0] * item[1])
|
|
montant_total = float('%.2f' % montant_total)
|
|
|
|
cursor.close()
|
|
# On affiche le nombre de résultats trouvés sur la barre de statut
|
|
if nbcigares == 0:
|
|
self.statusbar.push(self.context_id, "Aucun cigare dans la base")
|
|
else:
|
|
self.statusbar.push(
|
|
self.context_id,
|
|
str(nbcigares) +
|
|
" cigares dans la base pour un montant de " +
|
|
str(montant) +
|
|
"€ - (" +
|
|
str(montant_total) +
|
|
"€ depuis le début)")
|
|
|
|
# Permet l'affichage de la photo du cigare séléctionné dans la zone
|
|
# rétractable
|
|
def affiche_preview(self):
|
|
|
|
cursor = db.cursor()
|
|
photo = cursor.execute(
|
|
"select photo from photos where id_cigare = '{0}'".format(
|
|
self.treeview_selection[5]))
|
|
|
|
try:
|
|
photo = cursor.fetchone()[0]
|
|
except TypeError:
|
|
photo = None
|
|
cursor.close()
|
|
# Si aucune photo n'existe pour ce cigare
|
|
if photo is None:
|
|
photo = __CONFDIR__ + "/images/no_photo.jpg"
|
|
self.image_preview.set_from_file(photo)
|
|
else:
|
|
if os.path.exists(photo):
|
|
pixbuf = GdkPixbuf.Pixbuf().new_from_file(photo)
|
|
# Si l'image est plus grande que la fenêtre on re-dimensionne
|
|
new_size = self.window.get_size()[0] - 20
|
|
if pixbuf.get_width() > new_size:
|
|
w, h = pixbuf.get_width(), pixbuf.get_height()
|
|
pixbuf = pixbuf.scale_simple(
|
|
new_size, new_size * h / w, GdkPixbuf.InterpType.HYPER)
|
|
# Si la largeur de l'image est plus petite que la hauteur on
|
|
# fait pivoter
|
|
if pixbuf.get_width() < pixbuf.get_height():
|
|
pixbuf = pixbuf.rotate_simple(270)
|
|
# Si la hauteur est dépasse la moitié de la fenêtre principale,
|
|
# on re-dimensionne
|
|
if pixbuf.get_height() > self.window.get_size()[1] / 2:
|
|
w, h = pixbuf.get_width(), pixbuf.get_height()
|
|
pixbuf = pixbuf.scale_simple(
|
|
(w * self.window.get_size()[1] / 2) / h,
|
|
self.window.get_size()[1] / 2,
|
|
GdkPixbuf.InterpType.HYPER)
|
|
self.image_preview.set_from_pixbuf(pixbuf)
|
|
else:
|
|
# Si la photo n'existe plus ou a été renommée
|
|
photo = __CONFDIR__ + "/images/bad_photo.jpg"
|
|
self.image_preview.set_from_file(photo)
|
|
self.imgpath = photo
|
|
|
|
# Si la fenêtre principale change de taille on re-dimensionne le preview
|
|
# aussi
|
|
def on_window_main_check_resize(self, widget):
|
|
# print(self.window.get_size()[1],self.window_last_h)
|
|
if abs(self.window_last_h - self.window.get_size()[1] > 40) | \
|
|
abs(self.window_last_w - self.window.get_size()[0]) > 5:
|
|
self.window_last_h = self.window.get_size()[1]
|
|
self.window_last_w = self.window.get_size()[0]
|
|
|
|
if not os.path.exists(self.imgpath):
|
|
return
|
|
pixbuf = GdkPixbuf.Pixbuf().new_from_file(self.imgpath)
|
|
# Si l'image est plus grande que la fenêtre on re-dimensionne
|
|
new_size = self.window.get_size()[0] - 20
|
|
if pixbuf.get_width() > new_size:
|
|
w, h = pixbuf.get_width(), pixbuf.get_height()
|
|
pixbuf = pixbuf.scale_simple(
|
|
new_size, new_size * h / w, GdkPixbuf.InterpType.HYPER)
|
|
# Si la largeur de l'image est plus petite que la hauteur on fait
|
|
# pivoter
|
|
if pixbuf.get_width() < pixbuf.get_height():
|
|
pixbuf = pixbuf.rotate_simple(270)
|
|
# Si la hauteur est dépasse la moitié de la fenêtre principale, on
|
|
# re-dimensionne
|
|
if pixbuf.get_height() > self.window.get_size()[1] / 2:
|
|
w, h = pixbuf.get_width(), pixbuf.get_height()
|
|
pixbuf = pixbuf.scale_simple(
|
|
(w * self.window.get_size()[1] / 2) / h,
|
|
self.window.get_size()[1] / 2,
|
|
GdkPixbuf.InterpType.HYPER)
|
|
self.image_preview.set_from_pixbuf(pixbuf)
|
|
|
|
# Dès qu'une ligne est séléctionnée sur la treeview on enregistre les
|
|
# valeurs
|
|
def on_treeview_cigares_row_activated(self, widget):
|
|
selection = self.tree.get_selection()
|
|
(model, itr) = selection.get_selected()
|
|
if itr is not None:
|
|
self.treeview_selection.clear()
|
|
self.treeview_selection.append(model.get_value(itr, 0))
|
|
self.treeview_selection.append(model.get_value(itr, 1))
|
|
self.treeview_selection.append(model.get_value(itr, 2))
|
|
self.treeview_selection.append(model.get_value(itr, 3))
|
|
self.treeview_selection.append(model.get_value(itr, 4))
|
|
self.treeview_selection.append(model.get_value(itr, 5))
|
|
self.treeview_selection.append(model.get_value(itr, 6))
|
|
self.treeview_selection.append(model.get_value(itr, 7))
|
|
# for i in range(0,6):
|
|
# print(model.get_value(iter, i))
|
|
# print("\n")
|
|
# Et on met à jour l'affichage du preview
|
|
self.affiche_preview()
|
|
|
|
def get_libelle_quantite(self):
|
|
selection = self.tree.get_selection()
|
|
(model, itr) = selection.get_selected()
|
|
if itr is not None:
|
|
lib = model.get_value(itr, 0)
|
|
qtee = model.get_value(itr, 5)
|
|
return lib, qtee
|
|
|
|
# Changer de base de données
|
|
def on_bdd_change_activate(self, widget):
|
|
filter = gtk.FileFilter()
|
|
filter.set_name("Bases sqlite")
|
|
filter.add_mime_type("application/octet-stream")
|
|
filter.add_pattern("*.db")
|
|
self.filechooser_bdd.add_filter(filter)
|
|
self.filechooser_bdd.set_current_folder(__CONFDIR__ + "/bdd/")
|
|
self.filechooser_bdd.run()
|
|
self.loadtreeview()
|
|
self.filechooser_bdd.hide()
|
|
|
|
# Double clic sur le sélécteur de fichiers pour choisir la bdd
|
|
def on_filechooser_bdd_file_activated(self, widget):
|
|
if not os.path.exists(self.filechooser_bdd.get_filename()):
|
|
createdb(self.filechooser_bdd.get_filename())
|
|
setconfig(self.filechooser_bdd.get_filename())
|
|
global db
|
|
db.close()
|
|
db = sqlite3.connect(self.filechooser_bdd.get_filename())
|
|
# On met à jour le titre de la fenêtre
|
|
self.window.set_title("MesCigares - base : {0}".format(
|
|
ntpath.basename(self.filechooser_bdd.get_filename().replace(
|
|
'.db', ''))))
|
|
self.loadtreeview()
|
|
self.filechooser_bdd.hide()
|
|
|
|
# Clic sur le bouton OK du sélécteur de fichiers pour choisir l'image
|
|
def on_btchooseokbdd_clicked(self, widget):
|
|
if not os.path.exists(self.filechooser_bdd.get_filename()):
|
|
createdb(self.filechooser_bdd.get_filename())
|
|
# changer la conf
|
|
setconfig(self.filechooser_bdd.get_filename())
|
|
global db
|
|
db.close()
|
|
db = sqlite3.connect(self.filechooser_bdd.get_filename())
|
|
self.loadtreeview()
|
|
|
|
# Ajouter une image pour un cigare
|
|
def on_inserer_image_activate(self, widget):
|
|
self.filechooser_image.run()
|
|
self.filechooser_image.hide()
|
|
|
|
# Modifier/Supprimer une note de degustation
|
|
def on_modsupp_degustation_activate(self, widget):
|
|
# On commence par vider la liststore_date_modif_degustation (2ème
|
|
# utilisation)
|
|
if len(self.lstore_dmodif_degust) != 0:
|
|
self.lstore_dmodif_degust.clear()
|
|
|
|
cursor = db.cursor()
|
|
# On regarde récupère le commentaire
|
|
cursor.execute("select date,q1,q2,q3,q4,q5,q6,q7,q8,q9,q10," +
|
|
"q11,q12,q13,id,commentaires from degustation " +
|
|
"where id_cigare = " +
|
|
"'{0}'".format(self.treeview_selection[5]))
|
|
rs = cursor.fetchall()
|
|
# si nb = 0 on insère sinon on update la table photos
|
|
db.commit()
|
|
cursor.close()
|
|
|
|
if len(rs) == 0:
|
|
# Afficher un message d'infos pour alerter qu'il faut d'abord faire
|
|
# une dégustation
|
|
self.msgdialog.format_secondary_text(
|
|
"Il n'y a aucune dégustation pour ce cigare")
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
return
|
|
|
|
for item in rs:
|
|
date = item[0]
|
|
q1 = item[1]
|
|
q2 = item[2]
|
|
q3 = item[3]
|
|
q4 = item[4]
|
|
q5 = item[5]
|
|
q6 = item[6]
|
|
q7 = item[7]
|
|
q8 = item[8]
|
|
q9 = item[9]
|
|
q10 = item[10]
|
|
q11 = item[11]
|
|
q12 = item[12]
|
|
q13 = item[13]
|
|
idcomm = item[14]
|
|
commentaire = item[15]
|
|
itr = self.lstore_dmodif_degust.append()
|
|
self.lstore_dmodif_degust.set(
|
|
itr, 0, date, 1, q1, 2, q2, 3, q3, 4, q4, 5, q5, 6,
|
|
q6, 7, q7, 8, q8, 9, q9, 10, q10, 11, q11, 12, q12,
|
|
13, q13, 14, idcomm, 15, commentaire)
|
|
|
|
# On affiche la fenêtre de modification du commentaire
|
|
self.window_modif_degustation.run()
|
|
self.window_modif_degustation.hide()
|
|
# On recharge la treeview
|
|
self.loadtreeview()
|
|
|
|
# Changement sur la liste déroulante de choix de la note de dégustation à
|
|
# modifier/supprimer
|
|
def on_cbchoix_date_modif_degustation_changed(self, widget):
|
|
index = self.cbchoix_date_modif_degustation.get_active()
|
|
q = list()
|
|
try:
|
|
for i in range(1, 14):
|
|
q.append(self.lstore_dmodif_degust[index][i])
|
|
# idcomm = self.lstore_dmodif_degust[index][14]
|
|
|
|
except IndexError:
|
|
pass
|
|
|
|
try:
|
|
commentaire = self.lstore_dmodif_degust[index][15]
|
|
self.txtview_commentaire_modif.get_buffer().set_text(commentaire)
|
|
except IndexError:
|
|
self.txtview_commentaire_modif.get_buffer().set_text("")
|
|
|
|
# On met la bonne valeur sur les scales
|
|
try:
|
|
self.scaleq1m.set_value(q[0])
|
|
self.scaleq2m.set_value(q[1])
|
|
self.scaleq3m.set_value(q[2])
|
|
self.scaleq4m.set_value(q[3])
|
|
self.scaleq5m.set_value(q[4])
|
|
self.scaleq6m.set_value(q[5])
|
|
self.scaleq7m.set_value(q[6])
|
|
self.scaleq8m.set_value(q[7])
|
|
self.scaleq9m.set_value(q[8])
|
|
self.scaleq10m.set_value(q[9])
|
|
self.scaleq11m.set_value(q[10])
|
|
self.scaleq12m.set_value(q[11])
|
|
self.scaleq13m.set_value(q[12])
|
|
except IndexError:
|
|
self.scaleq1m.set_value(1)
|
|
self.scaleq2m.set_value(1)
|
|
self.scaleq3m.set_value(1)
|
|
self.scaleq4m.set_value(5)
|
|
self.scaleq5m.set_value(2)
|
|
self.scaleq6m.set_value(2)
|
|
self.scaleq7m.set_value(2)
|
|
self.scaleq8m.set_value(1)
|
|
self.scaleq9m.set_value(1)
|
|
self.scaleq10m.set_value(1)
|
|
self.scaleq11m.set_value(1)
|
|
self.scaleq12m.set_value(1)
|
|
self.scaleq13m.set_value(1)
|
|
|
|
# Calcul de la note globale pour modification d'une note de dégustation
|
|
def on_scaleqm_change_value(self, scale, enum, new_value):
|
|
# On récupère les notes
|
|
|
|
note = []
|
|
note.append(int(self.scaleq1m.get_value()))
|
|
note.append(int(self.scaleq2m.get_value()))
|
|
note.append(int(self.scaleq3m.get_value()))
|
|
note.append(int(self.scaleq4m.get_value()))
|
|
note.append(int(self.scaleq5m.get_value()))
|
|
note.append(int(self.scaleq6m.get_value()))
|
|
note.append(int(self.scaleq7m.get_value()))
|
|
note.append(int(self.scaleq8m.get_value()))
|
|
note.append(int(self.scaleq9m.get_value()))
|
|
note.append(int(self.scaleq10m.get_value()))
|
|
note.append(int(self.scaleq11m.get_value()))
|
|
note.append(int(self.scaleq12m.get_value()))
|
|
note.append(int(self.scaleq13m.get_value()))
|
|
|
|
# On affiche la note / 100 temporaire
|
|
self.lbl_note_totale.set_text(
|
|
"Nouvelle note: {0}/100".format(sum(note)))
|
|
|
|
# Validation de la modification d'une dégustation
|
|
def on_btvalid_degustation_clicked(self, widget):
|
|
# modifier
|
|
index = self.cbchoix_date_modif_degustation.get_active()
|
|
textbuffer = self.txtview_commentaire_modif.get_buffer()
|
|
start = textbuffer.get_start_iter()
|
|
end = textbuffer.get_end_iter()
|
|
# On récupère le commentaire et on échape les quote pour l'insert SQL
|
|
commentaire = textbuffer.get_text(
|
|
start, end, include_hidden_chars=False).replace("'", "''")
|
|
# On récupère les notes
|
|
note = []
|
|
note.append(int(self.scaleq1m.get_value()))
|
|
note.append(int(self.scaleq2m.get_value()))
|
|
note.append(int(self.scaleq3m.get_value()))
|
|
note.append(int(self.scaleq4m.get_value()))
|
|
note.append(int(self.scaleq5m.get_value()))
|
|
note.append(int(self.scaleq6m.get_value()))
|
|
note.append(int(self.scaleq7m.get_value()))
|
|
note.append(int(self.scaleq8m.get_value()))
|
|
note.append(int(self.scaleq9m.get_value()))
|
|
note.append(int(self.scaleq10m.get_value()))
|
|
note.append(int(self.scaleq11m.get_value()))
|
|
note.append(int(self.scaleq12m.get_value()))
|
|
note.append(int(self.scaleq13m.get_value()))
|
|
|
|
# Le commentaire et l'id
|
|
idcomm = self.lstore_dmodif_degust[index][14]
|
|
id_cigare = self.treeview_selection[5]
|
|
|
|
# On met à jour la base de données
|
|
cursor = db.cursor()
|
|
|
|
req = ("update degustation set commentaires ='{0}',q1='{1}'," +
|
|
"q2='{2}',q3='{3}',q4 ='{4}',q5='{5}',q7='{7}'" +
|
|
",q8='{8}',q9='{9}',q10='{10}',q11='{11}',q12=" +
|
|
"'{12}',q13='{13}',note='{14}' where id_cigare='{15}' " +
|
|
"and id='{16}'")
|
|
|
|
sql = (req.format(commentaire, note[0], note[1], note[2],
|
|
note[3], note[4], note[5], note[6],
|
|
note[7], note[8], note[9], note[10],
|
|
note[11], note[12], sum(note),
|
|
id_cigare, idcomm))
|
|
cursor.execute(sql)
|
|
db.commit()
|
|
cursor.close()
|
|
# Afficher un message d'infos pour confirmer
|
|
self.msgdialog.format_secondary_text(
|
|
"Modification de la dégustation pour " +
|
|
"{0}.\nNouvelle note: {1}".format(
|
|
self.treeview_selection[1], sum(note)))
|
|
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
|
|
# On recharge la liste des cigares
|
|
self.loadtreeview()
|
|
|
|
# Double clic sur le sélécteur de fichiers pour choisir l'image
|
|
def on_filechooser_image_file_activated(self, widget):
|
|
self.addimage(self.filechooser_image.get_filename())
|
|
self.filechooser_image.hide()
|
|
|
|
# Clic sur le bouton OK du sélécteur de fichiers pour choisir l'image
|
|
def on_btchooseok_clicked(self, widget):
|
|
self.addimage(self.filechooser_image.get_filename())
|
|
|
|
# Mettre à jour la BDD avec le chemin de l'image choisie
|
|
def addimage(self, path):
|
|
|
|
cursor = db.cursor()
|
|
# On regarde s'il y a déjà une photo pour le cigare séléctionné
|
|
req = ("select count(*) from photos where id_cigare ='{0}'"
|
|
.format(self.treeview_selection[5]))
|
|
nb = cursor.execute(req).fetchone()[0]
|
|
# si nb = 0 on insère sinon on update la table photos
|
|
if nb == 0:
|
|
cursor.execute("insert into photos " +
|
|
"(id_cigare, photo) " +
|
|
"values('{0}','{1}')".format(
|
|
self.treeview_selection[5], path))
|
|
else:
|
|
cursor.execute(
|
|
"update photos set photo = '{0}' where id_cigare='{1}'".format(
|
|
path, self.treeview_selection[5]))
|
|
db.commit()
|
|
cursor.close()
|
|
|
|
# Clic droit sur un cigare dans la treeview
|
|
def on_treeview_cigares_button_press_event(self, treeview, event):
|
|
x = int(event.x)
|
|
y = int(event.y)
|
|
if event.button == 3: # Clic droit
|
|
pthinfo = self.tree.get_path_at_pos(x, y)
|
|
if pthinfo is not None:
|
|
path, col, cellx, celly = pthinfo
|
|
self.tree.grab_focus()
|
|
self.tree.set_cursor(path, col, 0)
|
|
# On affiche le popup
|
|
self.popup.show_all()
|
|
self.popup.popup(None, None, None, None, event.button, event.time)
|
|
|
|
def text_edited(self, widget, path, text):
|
|
self.liststore[path][1] = text
|
|
|
|
# Mise à jour du listestore si édition d'une cellule
|
|
def cell_edited_callback(self, cellule, path, new_text, col, data=None):
|
|
iter = self.table.get_iter(path)
|
|
if col == 4:
|
|
try:
|
|
self.table.set_value(iter, col, int(new_text))
|
|
self.update_db("id", new_text, tuple(
|
|
self.treeview_selection)[5])
|
|
except ValueError: # Si la quantité saisie n'est pas un entier
|
|
pass
|
|
else:
|
|
self.table.set_value(iter, col, new_text)
|
|
self.update_db("nom", new_text, tuple(self.treeview_selection)[5])
|
|
|
|
# Mise à jour de la BDD si changement dans un cellule
|
|
def update_db(self, operation, new_text, indice):
|
|
cursor = db.cursor()
|
|
# update cigares.designation
|
|
if operation == 'nom':
|
|
sql = (
|
|
"update cigares set designation =" +
|
|
"'{0}' where id = '{1}'".format(
|
|
new_text.replace("'", "''"), str(indice)))
|
|
# print(sql)
|
|
cursor.execute(sql)
|
|
db.commit()
|
|
|
|
# update quantité dans table stock
|
|
if operation == 'id':
|
|
sql = (
|
|
"update stocks set quantite = " +
|
|
"'{0}' where id_cigare='{1}'".format(
|
|
new_text, str(indice)))
|
|
# print(sql)
|
|
cursor.execute(sql)
|
|
db.commit()
|
|
|
|
cursor.close()
|
|
# recharger la treeview
|
|
self.loadtreeview()
|
|
|
|
# Affichage de la fenêtre d'ajout d'un cigare
|
|
def on_gtk_new_activate(self, widget):
|
|
# On commence par vider le liststore_marques (2è recherche)
|
|
if len(self.tablemarques) != 0:
|
|
self.tablemarques.clear()
|
|
if len(self.tablemodules) != 0:
|
|
self.tablemodules.clear()
|
|
|
|
cursor = db.cursor()
|
|
|
|
sql = ('Select id,libelle,provenance '
|
|
'from marques order by lower(libelle)')
|
|
|
|
cursor.execute(sql)
|
|
rs = cursor.fetchall()
|
|
# On alimente la combobox des marques
|
|
for item in rs:
|
|
iter = self.tablemarques.append()
|
|
self.tablemarques.set(iter, 0, item[0], 1,
|
|
item[1].title(), 2, item[2].title())
|
|
|
|
sql = ('Select id, module, longueur, diametre, calibre '
|
|
'from modules order by lower(module)')
|
|
|
|
cursor.execute(sql)
|
|
|
|
rs = cursor.fetchall()
|
|
# Et celle des modules
|
|
for item in rs:
|
|
itr = self.tablemodules.append()
|
|
self.tablemodules.set(itr,
|
|
0, item[0],
|
|
1, item[1].title(),
|
|
2, item[2],
|
|
3, item[3],
|
|
4, item[4])
|
|
|
|
cursor.close()
|
|
self.dialog_add_cigare.run()
|
|
self.dialog_add_cigare.hide()
|
|
|
|
# Changement dans la liste déroulante des marques
|
|
def on_cbmarques_changed(self, widget):
|
|
index = self.cbmarques.get_active()
|
|
try:
|
|
provenance = self.tablemarques[index][2].title()
|
|
self.lbl_marque.set_text("Terroir: " + provenance)
|
|
except IndexError:
|
|
self.lbl_marque.set_text("")
|
|
|
|
# Changement dans la liste déroulante des modules
|
|
def on_cbmodules_changed(self, widget):
|
|
try:
|
|
index = self.cbmodules.get_active()
|
|
longueur = self.tablemodules[index][2]
|
|
diametre = self.tablemodules[index][3]
|
|
calibre = self.tablemodules[index][4]
|
|
self.lbl_module.set_text(
|
|
"{0} mm, diamètre {1}, calibre(cepo) {2}".format(
|
|
longueur, diametre, calibre))
|
|
except IndexError:
|
|
self.lbl_module.set_text("")
|
|
|
|
# Validation de l'ajout d'un nouveau cigare
|
|
def on_btadd_clicked(self, widget):
|
|
index = self.cbmarques.get_active()
|
|
model = self.cbmarques.get_model()
|
|
itemmarque = model[index]
|
|
# item[0] = id à insérer dans champ marque de la table cigares
|
|
# print (str(itemmarque[0]), str(itemmarque[1]))
|
|
|
|
index = self.cbmodules.get_active()
|
|
model = self.cbmodules.get_model()
|
|
itemmodel = model[index]
|
|
# item[0] = id à insérer dans champ marque de la table cigares
|
|
# print (str(itemmodel[0]), str(itemmodel[1]))
|
|
# Il faudra faire une requete sur cigares pour obtenir le dernier id
|
|
# et faire + 1 : Select max(id) from cigares
|
|
# table stocks : id_cigare = max id + 1
|
|
# print (str(self.entry_nom_cigare.get_text()))
|
|
|
|
cursor = db.cursor()
|
|
cursor.execute('Select max(id) from cigares')
|
|
try:
|
|
maxid = cursor.fetchone()[0] + 1
|
|
except TypeError:
|
|
maxid = 1
|
|
cursor.execute("insert into stocks (id_cigare, quantite) " +
|
|
"values ('{0}','{1}')".format(int(maxid), 0))
|
|
cursor.execute("insert into cigares (designation, marque, module) " +
|
|
"values ('{0}','{1}','{2}')".format(
|
|
str(self.entry_nom_cigare.get_text()),
|
|
int(itemmarque[0]), int(itemmodel[0])))
|
|
db.commit()
|
|
cursor.close()
|
|
|
|
# On recharge le treeview
|
|
self.loadtreeview()
|
|
|
|
# Affichage de la fenêtre de gestion des achats
|
|
def on_gtk_achats_activate(self, widget):
|
|
# On remet les selections à zero
|
|
self.scale_qte_achats.set_value(1)
|
|
self.scale_typeboite.set_value(25)
|
|
self.entry_prix_achats.set_text("")
|
|
self.entry_code_boite.set_text("")
|
|
self.entry_prix_boite.set_text("")
|
|
self.notebook_achats.set_current_page(0)
|
|
# On vide le listestore_liste_cigares (2è recherche)
|
|
if len(self.tablechoixcig) != 0:
|
|
self.tablechoixcig.clear()
|
|
|
|
cursor = db.cursor()
|
|
cursor.execute('Select c.id, c.designation from cigares c ' +
|
|
'order by c.designation asc')
|
|
rs = cursor.fetchall()
|
|
for item in rs:
|
|
iter = self.tablechoixcig.append()
|
|
self.tablechoixcig.set(iter, 0, item[0], 1, item[1])
|
|
cursor.close()
|
|
# On affiche la fenêtre de gestion des achats
|
|
self.dialog_achats.run()
|
|
|
|
# Cancel sur l'ajout d'un achat
|
|
def on_bt_cancel_achats_clicked(self, widget):
|
|
self.dialog_achats.hide()
|
|
|
|
# Validation des achats
|
|
def on_bt_valid_achats_clicked(self, widget):
|
|
# On récupère le cigare choisi dans la liste déroulante
|
|
# [0] id_cigare ~ [1] libelle
|
|
index = self.cb_liste_cigares_achats.get_active()
|
|
itemchoixcig = self.tablechoixcig[index]
|
|
|
|
id_cigare = itemchoixcig[0]
|
|
|
|
# On vérifie les saisies
|
|
if index == -1: # Aucun cigare choisi
|
|
self.msgdialog.format_secondary_text(
|
|
"Vous devez d'abord choisir un cigare dans la liste")
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
return
|
|
# Mauvais prix unité
|
|
if self.notebook_achats.get_current_page() == 0 \
|
|
and not is_number(self.entry_prix_achats.get_text()):
|
|
self.msgdialog.format_secondary_text(
|
|
"Saisie erronée pour le prix du cigare.")
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
return
|
|
# Mauvais prix boite
|
|
if self.notebook_achats.get_current_page() == 1 \
|
|
and not is_number(self.entry_prix_boite.get_text()):
|
|
self.msgdialog.format_secondary_text(
|
|
"Saisie erronée pour le prix de la boite.")
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
return
|
|
if self.notebook_achats.get_current_page() == 0: # Choix à l'unité
|
|
qte_achat = int(self.scale_qte_achats.get_value())
|
|
prix_achat = self.entry_prix_achats.get_text().replace(",", ".")
|
|
prix_achat = '%.2f' % float(prix_achat)
|
|
code_boite = ""
|
|
else: # = 1 choix par boites
|
|
qte_achat = int(self.scale_typeboite.get_value())
|
|
prix_achat = float(self.entry_prix_boite.get_text()) / qte_achat
|
|
prix_achat = '%.2f' % prix_achat
|
|
code_boite = self.entry_code_boite.get_text()
|
|
print(qte_achat)
|
|
print(prix_achat)
|
|
print(code_boite)
|
|
|
|
# On formate la date (ajout d'un 0 si besoin)
|
|
j = str(self.calendar_date_achats.get_date()[2])
|
|
if len(str(self.calendar_date_achats.get_date()[1] + 1)) == 1:
|
|
m = "0" + str(self.calendar_date_achats.get_date()[1] + 1)
|
|
else:
|
|
m = str(self.calendar_date_achats.get_date()[1] + 1)
|
|
a = self.calendar_date_achats.get_date()[0]
|
|
|
|
date_achat = "{0}/{1}/{2}".format(j, m, a)
|
|
|
|
# Insert des achats en base de données
|
|
cursor = db.cursor()
|
|
cursor.execute(
|
|
"insert into achats (id_cigare, date, prix, quantite, " +
|
|
"code_boite) values ('{0}','{1}','{2}','{3}', '{4}')".format(
|
|
id_cigare,
|
|
date_achat,
|
|
prix_achat,
|
|
qte_achat,
|
|
code_boite))
|
|
# ajout dans le stock
|
|
cursor.execute("update stocks set quantite = " +
|
|
"quantite + {1} where id = {0}"
|
|
.format(id_cigare, qte_achat))
|
|
|
|
db.commit()
|
|
cursor.close()
|
|
|
|
# Afficher un message d'infos pour confirmer
|
|
self.msgdialog.format_secondary_text(
|
|
"Achats ajoutés avec succés " +
|
|
"pour {0}".format(itemchoixcig[1]))
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
|
|
# On recharge la liste des cigares
|
|
self.loadtreeview()
|
|
|
|
self.dialog_achats.hide()
|
|
|
|
# Affiche du prix d'un cigare pour les achats par boite
|
|
def on_scale_typeboite_change_value(self, scale, enum, new_value):
|
|
if is_number(self.entry_prix_boite.get_text()):
|
|
prix_unite = float(self.entry_prix_boite.get_text()) / \
|
|
int(self.scale_typeboite.get_value())
|
|
prix_unite = '%.2f' % prix_unite
|
|
# on met à jour le label
|
|
self.lbl_prix_unite_boite.set_text(
|
|
" Soit {0}€ le cigare".format(prix_unite))
|
|
|
|
def on_entry_prix_boite_changed(self, widget):
|
|
self.on_scale_typeboite_change_value(None, None, None)
|
|
|
|
# Affichage de la fenêtre d'ajout d'une marque
|
|
def on_gtk_add_marque_activate(self, menuitem, data=None):
|
|
del menuitem, data
|
|
self.dialog_add_marque.run()
|
|
self.dialog_add_marque.hide()
|
|
|
|
# Validation de l'ajout d'une marque
|
|
def on_bt_add_marque_clicked(self, widget):
|
|
print("todo")
|
|
e_marque = self.entry_marque.get_text().title()
|
|
e_provenance = self.entry_provenance.get_text().title()
|
|
|
|
# Insert de la nouvelle marque en base de données
|
|
cursor = db.cursor()
|
|
cursor.execute("insert into marques (libelle, provenance) " +
|
|
"values ('{0}','{1}')".format(e_marque, e_provenance))
|
|
|
|
db.commit()
|
|
cursor.close()
|
|
|
|
# Afficher un message d'infos pour confirmer
|
|
self.msgdialog.format_secondary_text(
|
|
"Marque {0} ajoutée.".format(e_marque))
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
|
|
# Affichage de la fenêtre de gestion des stocks
|
|
def on_gtk_stocks_activate(self, menuitem, data=None):
|
|
del menuitem, data
|
|
# On commence par vider le listestore_liste_cigares (2è recherche)
|
|
if len(self.tablechoixcig) != 0:
|
|
self.tablechoixcig.clear()
|
|
|
|
cursor = db.cursor()
|
|
|
|
sql = ('Select c.id, c.designation '
|
|
'from cigares c order by c.designation asc')
|
|
|
|
cursor.execute(sql)
|
|
|
|
rs = cursor.fetchall()
|
|
for item in rs:
|
|
iter = self.tablechoixcig.append()
|
|
self.tablechoixcig.set(iter, 0, item[0], 1, item[1])
|
|
cursor.close()
|
|
|
|
self.dialog_stocks.run()
|
|
self.dialog_stocks.hide()
|
|
|
|
# Validation des stocks
|
|
def on_btstockvalid_clicked(self, value):
|
|
item = self.cbchoixcigqte.get_active()
|
|
model = self.cbchoixcigqte.get_model()
|
|
idc = model[item]
|
|
|
|
cursor = db.cursor()
|
|
cursor.execute(
|
|
"Update stocks set quantite='{0}' where id_cigare='{1}'".format(
|
|
int(self.scaleqte.get_value()), idc[0]))
|
|
|
|
db.commit()
|
|
cursor.close()
|
|
# affichage message maj ok pour qte
|
|
self.msgdialog.format_secondary_text(
|
|
"Quantité mise à jour pour " +
|
|
"{0}.\nVous avez maintenant {1} exemplaire(s)"
|
|
.format(idc[1], int(self.scaleqte.get_value())))
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
# On recharge la treeview principale
|
|
self.loadtreeview()
|
|
|
|
# Affichage de la fenêtre de dégustation
|
|
def on_gtk_degustation_activate(self, menuitem, data=None):
|
|
del menuitem, data
|
|
if len(self.tablechoixcigare) != 0:
|
|
self.tablechoixcigare.clear()
|
|
|
|
cursor = db.cursor()
|
|
cursor.execute(
|
|
'Select c.id, c.designation from cigares c where c.id not in ' +
|
|
'(select s.id_cigare from stocks s where s.quantite = 0) ' +
|
|
'order by c.designation asc')
|
|
rs = cursor.fetchall()
|
|
for item in rs:
|
|
iter = self.tablechoixcigare.append()
|
|
self.tablechoixcigare.set(iter, 0, item[0], 1, item[1])
|
|
|
|
cursor.close()
|
|
self.window_degustation.run()
|
|
self.window_degustation.hide()
|
|
|
|
# Validation d'une dégusation
|
|
def on_btvalid_clicked(self, widget):
|
|
|
|
# On formate la date (ajout d'un 0 si besoin)
|
|
j = str(self.degustationdate.get_date()[2])
|
|
if len(str(self.degustationdate.get_date()[1] + 1)) == 1:
|
|
m = "0" + str(self.degustationdate.get_date()[1] + 1)
|
|
else:
|
|
m = str(self.degustationdate.get_date()[1] + 1)
|
|
a = self.degustationdate.get_date()[0]
|
|
|
|
# Formatage de la date du calendar au format %d/%m/%Y
|
|
DateDegustation = "{0}/{1}/{2}".format(j, m, a)
|
|
|
|
textbuffer = self.txtview_commentaire.get_buffer()
|
|
start = textbuffer.get_start_iter()
|
|
end = textbuffer.get_end_iter()
|
|
# On récupère le commentaire et on échape les quote pour l'insert SQL
|
|
textlines = textbuffer.get_text(
|
|
start, end, include_hidden_chars=False).replace("'", "''")
|
|
|
|
index = self.cbchoixcigare.get_active()
|
|
itemchoixcig = self.tablechoixcigare[index]
|
|
|
|
note = int(self.scaleq1.get_value()) + int(self.scaleq2.get_value()) \
|
|
+ int(self.scaleq3.get_value()) + int(self.scaleq4.get_value()) \
|
|
+ int(self.scaleq5.get_value()) + int(self.scaleq6.get_value()) \
|
|
+ int(self.scaleq7.get_value()) + int(self.scaleq8.get_value()) \
|
|
+ int(self.scaleq9.get_value()) + int(self.scaleq10.get_value()) \
|
|
+ int(self.scaleq11.get_value()) + int(self.scaleq12.get_value()) \
|
|
+ int(self.scaleq13.get_value())
|
|
|
|
cursor = db.cursor()
|
|
req = ("insert into degustation (id_cigare,date,commentaires," +
|
|
"q1,q2,q3,q4,q5,q6,q7,q8,q9,q10,q11,q12,q13,note) " +
|
|
"values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}'" +
|
|
",'{7}','{8}','{9}','{10}','{11}','{12}','{13}'," +
|
|
"'{14}','{15}','{16}')")
|
|
cursor.execute(req.format(itemchoixcig[0], DateDegustation, textlines,
|
|
int(self.scaleq1.get_value()),
|
|
int(self.scaleq2.get_value()),
|
|
int(self.scaleq3.get_value()),
|
|
int(self.scaleq4.get_value()),
|
|
int(self.scaleq5.get_value()),
|
|
int(self.scaleq6.get_value()),
|
|
int(self.scaleq7.get_value()),
|
|
int(self.scaleq8.get_value()),
|
|
int(self.scaleq9.get_value()),
|
|
int(self.scaleq10.get_value()),
|
|
int(self.scaleq11.get_value()),
|
|
int(self.scaleq12.get_value()),
|
|
int(self.scaleq13.get_value()), note))
|
|
# - 1 sur le stock
|
|
cursor.execute("update stocks set quantite = quantite - 1 " +
|
|
"where id = {0}".format(itemchoixcig[0]))
|
|
db.commit()
|
|
cursor.close()
|
|
|
|
# TODO(jlaunay) ajouter une checkbox sur le formulaire
|
|
# pour choisir si retirer 1 du stock ou non
|
|
self.msgdialog.format_secondary_text(
|
|
"Note de dégustation ajoutée avec succès pour : " +
|
|
"{0}.\n1 cigare retiré du stock.".format(itemchoixcig[1]))
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
|
|
# On recharge la treeview
|
|
self.loadtreeview()
|
|
|
|
# Affichage de la fenêtre des cigares à tester
|
|
def on_gtk_wish_activate(self, menuitem, data=None):
|
|
del menuitem, data
|
|
# On commence par vider le listestore_wishes (2è recherche)
|
|
if len(self.liststore_wishes) != 0:
|
|
self.liststore_wishes.clear()
|
|
|
|
cursor = db.cursor()
|
|
cursor.execute(
|
|
'select nom, provenance,raison,source,id from tester order by id')
|
|
rs = cursor.fetchall()
|
|
for item in rs:
|
|
iter = self.liststore_wishes.append()
|
|
self.liststore_wishes.set(iter, 0, item[0], 1, item[1],
|
|
2, item[2], 3, item[3], 4, item[4])
|
|
cursor.close()
|
|
|
|
self.window_wishes.resize(self.window.get_size()[0],
|
|
self.window.get_size()[1])
|
|
|
|
self.window_wishes.show()
|
|
|
|
# Quitter la fenêtre des cigares à tester
|
|
def on_window_wishes_delete_event(self, widget, data=None):
|
|
self.window_wishes.hide()
|
|
return True
|
|
|
|
# Affichage de l'assistant d'aide pour la documentation
|
|
def on_gtk_how_to_activate(self, widget):
|
|
self.doc.show()
|
|
# self.doc.hide()
|
|
|
|
def on_lbl_intro_activate_link(self, widget):
|
|
self.doc.set_forward_page_func(page_func=None, data=None)
|
|
|
|
# Quitter la fenêtre d'assistant
|
|
def on_assistant_delete_event(self, widget, data=None):
|
|
self.doc.hide()
|
|
return True
|
|
|
|
# Affichage de la fenêtre d'ajout d'un cigare à tester
|
|
def on_bt_add_wish_clicked(self, widget):
|
|
self.dialog_add_wish.run()
|
|
self.dialog_add_wish.hide()
|
|
|
|
# Valider l'ajout d'un cigare à tester
|
|
def on_bt_valid_add_wish_clicked(self, widget):
|
|
textbuffer = self.txtview_test_raison.get_buffer()
|
|
start = textbuffer.get_start_iter()
|
|
end = textbuffer.get_end_iter()
|
|
# On récupère le commentaire et on échape les quote pour l'insert SQL
|
|
textlines = textbuffer.get_text(
|
|
start, end, include_hidden_chars=False).replace("'", "''")
|
|
|
|
# On ajoute en base de données
|
|
cursor = db.cursor()
|
|
sql = ("insert into tester (nom, provenance, source, raison) " +
|
|
"values ('{0}','{1}','{2}','{3}')"
|
|
.format(self.entry_test_nom.get_text(),
|
|
self.entry_test_origine.get_text(),
|
|
self.entry_test_source.get_text(), textlines))
|
|
cursor.execute(sql)
|
|
db.commit()
|
|
cursor.close()
|
|
|
|
# On recharge la treeview des cigares à tester
|
|
self.on_gtk_wish_activate(self)
|
|
|
|
# Clic droit sur un cigare à tester dans la treeview
|
|
def on_treeview_wishes_button_press_event(self, treeview, event):
|
|
x = int(event.x)
|
|
y = int(event.y)
|
|
if event.button == 3: # Clic droit
|
|
pthinfo = self.treeview_wishes.get_path_at_pos(x, y)
|
|
if pthinfo is not None:
|
|
path, col, cellx, celly = pthinfo
|
|
self.treeview_wishes.grab_focus()
|
|
self.treeview_wishes.set_cursor(path, col, 0)
|
|
# On affiche le popup
|
|
self.popup_test.show_all()
|
|
self.popup_test.popup(None, None, None, None,
|
|
event.button, event.time)
|
|
|
|
# Ouvrir l'url dans le navigateur au clic droit sur une ligne de la
|
|
# treeview des cigares à tester
|
|
def on_gtk_copier_test_activate(self, widget):
|
|
try:
|
|
import webbrowser
|
|
from urllib.parse import urlparse
|
|
except ImportError:
|
|
print('webbrowser not available')
|
|
return False
|
|
|
|
selection = self.treeview_wishes.get_selection()
|
|
(model, iter) = selection.get_selected()
|
|
if iter is not None:
|
|
url = model.get_value(iter, 3)
|
|
if not urlparse(url).scheme:
|
|
url = "http://" + url
|
|
# On copie dans le presse papier
|
|
webbrowser.open(url)
|
|
|
|
# Pour supprimer au clic droit
|
|
def on_gtk_supprimer_activate(self, widget):
|
|
id_supp = self.treeview_selection[5]
|
|
cursor = db.cursor()
|
|
sql = "delete from cigares where id = {0}".format(id_supp)
|
|
cursor.execute(sql)
|
|
sql = "delete from achats where id_cigare = {0}".format(id_supp)
|
|
cursor.execute(sql)
|
|
sql = "delete from stocks where id_cigare = {0}".format(id_supp)
|
|
cursor.execute(sql)
|
|
sql = "delete from degustation where id_cigare = {0}".format(id_supp)
|
|
cursor.execute(sql)
|
|
sql = "delete from photos where id_cigare = {0}".format(id_supp)
|
|
cursor.execute(sql)
|
|
|
|
db.commit()
|
|
cursor.close()
|
|
|
|
# On recharge la treeview
|
|
self.loadtreeview()
|
|
|
|
# Pour supprimer un cigare à tester au clic droit
|
|
def on_gtk_supprimer_test_activate(self, widget):
|
|
selection = self.treeview_wishes.get_selection()
|
|
(model, iter) = selection.get_selected()
|
|
if iter is not None:
|
|
cursor = db.cursor()
|
|
sql = ("delete from tester where nom = '{0}' and provenance = " +
|
|
"'{1}' and raison = '{2}' and source = '{3}'"
|
|
.format(model.get_value(iter, 0),
|
|
model.get_value(iter, 1),
|
|
model.get_value(iter, 2),
|
|
model.get_value(iter, 3)))
|
|
cursor.execute(sql)
|
|
|
|
db.commit()
|
|
cursor.close()
|
|
|
|
# Afficher un message d'infos pour alerter que c'est bien supprimé
|
|
self.msgdialog.format_secondary_text(
|
|
"Cigare à tester correctement supprimé")
|
|
self.msgdialog.run()
|
|
self.msgdialog.hide()
|
|
|
|
# On recharge la treeview
|
|
self.on_gtk_wish_activate(self)
|
|
|
|
# Permet le filtrage de la treeview de cigares
|
|
def filter_func(self, model, iterr, data=None):
|
|
query = self.entry_search.get_buffer().get_text()
|
|
value = self.table.get_value(iterr, 0)
|
|
|
|
try:
|
|
if query == "":
|
|
return True
|
|
elif query in value.lower():
|
|
return True
|
|
except AttributeError:
|
|
pass
|
|
return False
|
|
# Filtrer au changement sur entry_search
|
|
|
|
def on_entry_search_changed(self, data=None):
|
|
self.tree_filter.refilter()
|
|
|
|
def __init__(self):
|
|
self.gladefile = "ui/ui.glade"
|
|
self.builder = gtk.Builder()
|
|
self.builder.add_from_file(self.gladefile)
|
|
self.builder.connect_signals(self)
|
|
self.window = self.builder.get_object("window_main")
|
|
self.aboutdialog = self.builder.get_object("aboutdialog")
|
|
self.statusbar = self.builder.get_object("window_main_statusbar")
|
|
self.context_id = self.statusbar.get_context_id("exemple")
|
|
self.table = self.builder.get_object("liststore_treeview_cigares")
|
|
self.dialog_add_cigare = self.builder.get_object("dialog_add_cigare")
|
|
self.dialog_add_marque = self.builder.get_object("dialog_add_marque")
|
|
self.dialog_add_module = self.builder.get_object("dialog_add_module")
|
|
|
|
# Modification/Suppression d'une note de dégustation
|
|
self.window_modif_degustation = self.builder.get_object(
|
|
"window_modif_degustation")
|
|
self.lstore_dmodif_degust = self.builder.get_object(
|
|
"liststore_date_modif_degustation")
|
|
self.cbchoix_date_modif_degustation = self.builder.get_object(
|
|
"cbchoix_date_modif_degustation")
|
|
self.scaleq1m = self.builder.get_object("scaleq1m")
|
|
self.scaleq2m = self.builder.get_object("scaleq2m")
|
|
self.scaleq3m = self.builder.get_object("scaleq3m")
|
|
self.scaleq4m = self.builder.get_object("scaleq4m")
|
|
self.scaleq5m = self.builder.get_object("scaleq5m")
|
|
self.scaleq6m = self.builder.get_object("scaleq6m")
|
|
self.scaleq7m = self.builder.get_object("scaleq7m")
|
|
self.scaleq8m = self.builder.get_object("scaleq8m")
|
|
self.scaleq9m = self.builder.get_object("scaleq9m")
|
|
self.scaleq10m = self.builder.get_object("scaleq10m")
|
|
self.scaleq11m = self.builder.get_object("scaleq11m")
|
|
self.scaleq12m = self.builder.get_object("scaleq12m")
|
|
self.scaleq13m = self.builder.get_object("scaleq13m")
|
|
self.lbl_note_totale = self.builder.get_object("lbl_note_totale")
|
|
self.txtview_commentaire_modif = self.builder.get_object(
|
|
"txtview_commentaire_modif")
|
|
|
|
self.cbmarques = self.builder.get_object("cbmarques")
|
|
self.cbchoixcigare = self.builder.get_object("cbchoixcigare")
|
|
self.tablechoixcigare = self.builder.get_object(
|
|
"liststore_cigares_a_noter")
|
|
self.scaleq1 = self.builder.get_object("scaleq1")
|
|
self.scaleq2 = self.builder.get_object("scaleq2")
|
|
self.scaleq3 = self.builder.get_object("scaleq3")
|
|
self.scaleq4 = self.builder.get_object("scaleq4")
|
|
self.scaleq5 = self.builder.get_object("scaleq5")
|
|
self.scaleq6 = self.builder.get_object("scaleq6")
|
|
self.scaleq7 = self.builder.get_object("scaleq7")
|
|
self.scaleq8 = self.builder.get_object("scaleq8")
|
|
self.scaleq9 = self.builder.get_object("scaleq9")
|
|
self.scaleq10 = self.builder.get_object("scaleq10")
|
|
self.scaleq11 = self.builder.get_object("scaleq11")
|
|
self.scaleq12 = self.builder.get_object("scaleq12")
|
|
self.scaleq13 = self.builder.get_object("scaleq13")
|
|
self.tablemarques = self.builder.get_object("liststore_marques")
|
|
self.cbmodules = self.builder.get_object("cbmodules")
|
|
self.tablemodules = self.builder.get_object("liststore_modules")
|
|
self.entry_nom_cigare = self.builder.get_object("entry_nom_cigare")
|
|
self.window_degustation = self.builder.get_object("window_degustation")
|
|
self.txtview_commentaire = self.builder.get_object(
|
|
"txtview_commentaire")
|
|
self.popup = self.builder.get_object("popup")
|
|
self.popup_test = self.builder.get_object("popup_test")
|
|
self.filechooser_image = self.builder.get_object("filechooser_image")
|
|
self.filechooser_bdd = self.builder.get_object("filechooser_bdd")
|
|
|
|
# Fenêtre d'ajout d'une marque
|
|
self.entry_marque = self.builder.get_object("entry_marque")
|
|
self.entry_provenance = self.builder.get_object("entry_provenance")
|
|
|
|
# Fenêtre des cigares à tester
|
|
self.txtview_test_raison = self.builder.get_object(
|
|
"txtview_test_raison")
|
|
self.entry_test_nom = self.builder.get_object("entry_test_nom")
|
|
self.entry_test_source = self.builder.get_object("entry_test_source")
|
|
self.entry_test_origine = self.builder.get_object("entry_test_origine")
|
|
|
|
self.lbl_marque = self.builder.get_object("lbl_marque")
|
|
self.lbl_module = self.builder.get_object("lbl_module")
|
|
|
|
self.msgdialog = self.builder.get_object("msgdialog")
|
|
|
|
self.tablechoixcig = self.builder.get_object(
|
|
"listestore_liste_cigares")
|
|
self.cbchoixcigqte = self.builder.get_object("cbchoixcigqte")
|
|
self.lblqte = self.builder.get_object("lblqte")
|
|
self.dialog_stocks = self.builder.get_object("dialog_stocks")
|
|
self.scaleqte = self.builder.get_object("scaleqte")
|
|
self.adjqte = self.builder.get_object("adjqte")
|
|
# Assistant pour la documentation de l'appli
|
|
self.doc = self.builder.get_object("assistant")
|
|
# Image pour afficher le preview dans la zone rétractable
|
|
self.image_preview = self.builder.get_object("image_preview")
|
|
# Date pour la dégustation
|
|
self.degustationdate = self.builder.get_object("calendar_degustation")
|
|
|
|
# Fenêtre de gestion des achats
|
|
self.dialog_achats = self.builder.get_object("dialog_achats")
|
|
# Combo pour la liste des cigares (achats) - utilise aussi
|
|
# listestore_choix_cigare_qte
|
|
self.cb_liste_cigares_achats = self.builder.get_object(
|
|
"cb_liste_cigares_achats")
|
|
# Scale pour la quantité achetée
|
|
self.scale_qte_achats = self.builder.get_object("scale_qte_achats")
|
|
# Entry pour le prix d'achat
|
|
self.entry_prix_achats = self.builder.get_object("entry_prix_achats")
|
|
# Notebook (tabs) pour les achats
|
|
self.notebook_achats = self.builder.get_object("notebook_achats")
|
|
self.scale_typeboite = self.builder.get_object("scale_typeboite")
|
|
self.entry_prix_boite = self.builder.get_object("entry_prix_boite")
|
|
self.entry_code_boite = self.builder.get_object("entry_code_boite")
|
|
self.lbl_prix_unite_boite = self.builder.get_object(
|
|
"lbl_prix_unite_boite")
|
|
|
|
# Calendar pour la date d'achat
|
|
self.calendar_date_achats = self.builder.get_object(
|
|
"calendar_date_achats")
|
|
# Fenêtre pour la liste des cigares à tester
|
|
self.window_wishes = self.builder.get_object("window_wishes")
|
|
# Fenêtre d'ajout d'un cigare à tester
|
|
self.dialog_add_wish = self.builder.get_object("dialog_add_wish")
|
|
# Treeview wishes
|
|
self.treeview_wishes = self.builder.get_object("treeview_wishes")
|
|
# Liststore associé à treeview wishes
|
|
self.liststore_wishes = self.builder.get_object("liststore_wishes")
|
|
|
|
# Ligne séléctionnée au changement sur la treeview
|
|
self.treeview_selection = []
|
|
# Chemin de l'image preview
|
|
self.imgpath = ""
|
|
self.window_last_h = self.window.get_size()[1]
|
|
self.window_last_w = self.window.get_size()[0]
|
|
|
|
# Recherche et filrage d'un cigare
|
|
self.entry_search = self.builder.get_object("entry_search")
|
|
|
|
# Filter la treeview des cigares
|
|
self.tree_filter = self.table.filter_new()
|
|
self.tree_filter.set_visible_func(self.filter_func)
|
|
self.filtered_model = gtk.TreeModelSort(model=self.tree_filter)
|
|
|
|
# Treeview de la liste des cigares
|
|
self.tree = self.builder.get_object("treeview_cigares")
|
|
|
|
# On défini le modèle pour la treeview qui permet le filtrage
|
|
self.tree.set_model(self.filtered_model)
|
|
|
|
# Constuire l'entête du treeview
|
|
self.editable_cell_nom = gtk.CellRendererText()
|
|
self.no_editable_cell = gtk.CellRendererText()
|
|
self.editable_cell_qte = gtk.CellRendererText()
|
|
self.invisible_cell = gtk.CellRendererText()
|
|
|
|
self.editable_cell_nom.connect('edited', self.cell_edited_callback, 0)
|
|
self.editable_cell_nom.set_property('editable', True)
|
|
|
|
self.col_nom = gtk.TreeViewColumn(
|
|
'Nom', self.editable_cell_nom, text=0, background=11)
|
|
self.col_nom.set_sort_column_id(0)
|
|
self.tree.append_column(self.col_nom)
|
|
|
|
# Recherche d'un cigare
|
|
self.tree.set_search_column(0)
|
|
self.tree.set_search_entry(self.entry_search)
|
|
|
|
self.no_editable_cell.set_property('editable', False)
|
|
|
|
self.col_marque = gtk.TreeViewColumn(
|
|
'Marque', self.no_editable_cell, text=1, background=11)
|
|
self.col_marque.set_sort_column_id(1)
|
|
self.tree.append_column(self.col_marque)
|
|
|
|
self.col_module = gtk.TreeViewColumn(
|
|
'Module', self.no_editable_cell, text=2, background=11)
|
|
self.col_module.set_sort_column_id(2)
|
|
self.tree.append_column(self.col_module)
|
|
|
|
self.col_provenance = gtk.TreeViewColumn(
|
|
'Terroir', self.no_editable_cell, text=3, background=11)
|
|
self.col_provenance.set_sort_column_id(3)
|
|
self.tree.append_column(self.col_provenance)
|
|
|
|
self.editable_cell_qte.connect('edited', self.cell_edited_callback, 4)
|
|
self.editable_cell_qte.set_property('editable', True)
|
|
self.col_qte = gtk.TreeViewColumn(
|
|
'Quantité', self.editable_cell_qte, text=4, background=11)
|
|
self.col_qte.set_sort_column_id(4)
|
|
self.tree.append_column(self.col_qte)
|
|
|
|
# colonne invisible pour l'id_cigare
|
|
self.invisible_cell.set_property('visible', False)
|
|
self.col_id = gtk.TreeViewColumn(
|
|
'id', self.invisible_cell, text=5, background=11)
|
|
self.col_id.set_sort_column_id(5)
|
|
|
|
self.col_best_note = gtk.TreeViewColumn(
|
|
'Meilleure note', self.no_editable_cell, text=6, background=11)
|
|
self.col_best_note.set_sort_column_id(6)
|
|
self.tree.append_column(self.col_best_note)
|
|
|
|
self.col_mid_note = gtk.TreeViewColumn(
|
|
'Note moyenne', self.no_editable_cell, text=7, background=12)
|
|
self.col_mid_note.set_sort_column_id(7)
|
|
self.tree.append_column(self.col_mid_note)
|
|
|
|
self.col_prix = gtk.TreeViewColumn(
|
|
'Prix', self.no_editable_cell, text=8, background=11)
|
|
# On utilise l'id de la col_tri (id = 10) qui contient le prix en float
|
|
# pour le tri
|
|
self.col_prix.set_sort_column_id(10)
|
|
self.tree.append_column(self.col_prix)
|
|
|
|
# colonne invisible pour le commentaire de dégustation
|
|
self.col_comment = gtk.TreeViewColumn(
|
|
'commentaire', self.invisible_cell, text=9)
|
|
self.col_comment.set_sort_column_id(9)
|
|
# On défini cette colonne comme colonne d'infobulle
|
|
self.tree.set_tooltip_column(9)
|
|
|
|
# colonne invisible pour le tri des prix
|
|
self.col_tri = gtk.TreeViewColumn('tri', self.invisible_cell, text=10)
|
|
|
|
# colonne invisible pour la couleur d'une ligne
|
|
self.col_couleur = gtk.TreeViewColumn(
|
|
'couleur', self.invisible_cell, text=11)
|
|
|
|
# colonne invisible pour la couleur du top 5
|
|
self.col_couleurtop5 = gtk.TreeViewColumn(
|
|
'couleurtop5', self.invisible_cell, text=12)
|
|
|
|
# Utiliser gtkspellcheck dans la txtview des commentaires
|
|
# http://koehlma.github.io/projects/pygtkspellcheck.html
|
|
try:
|
|
from gtkspellcheck import SpellChecker
|
|
SpellChecker(self.txtview_commentaire,
|
|
locale.getdefaultlocale()[0])
|
|
SpellChecker(self.txtview_commentaire_modif,
|
|
locale.getdefaultlocale()[0])
|
|
SpellChecker(self.txtview_test_raison,
|
|
locale.getdefaultlocale()[0])
|
|
except Exception:
|
|
print("gtkspellcheck n'est pas installé " +
|
|
"http://koehlma.github.io/projects/" +
|
|
"pygtkspellcheck.html")
|
|
pass
|
|
|
|
self.window.show_all()
|
|
# On charge la liste des cigares
|
|
self.loadtreeview()
|
|
|
|
|
|
# Vérifier qu'il s'agit d'un nombre
|
|
def is_number(s):
|
|
try:
|
|
float(s)
|
|
return True
|
|
except ValueError:
|
|
return False
|
|
|
|
|
|
def createdb(new_bdd):
|
|
db = sqlite3.connect(new_bdd)
|
|
cursor = db.cursor()
|
|
sql = ('create table achats(id INTEGER PRIMARY KEY, id_cigare '
|
|
'INTEGER, date TEXT, code_boite TEXT, prix FLOAT, '
|
|
'quantite INTEGER)')
|
|
cursor.execute(sql)
|
|
sql = ('create table cigares(id INTEGER PRIMARY KEY, designation '
|
|
'TEXT, marque INTEGER, module INTEGER)')
|
|
cursor.execute(sql)
|
|
sql = ('create table degustation'
|
|
'(id INTEGER PRIMARY KEY, id_cigare INTEGER, date TEXT, '
|
|
'note NUMERIC, commentaires TEXT, q1 INTEGER, q2 INTEGER, '
|
|
'q3 INTEGER, q4 INTEGER, q5 INTEGER, q6 INTEGER, q7 INTEGER, '
|
|
'q8 INTEGER, q9 INTEGER, q10 INTEGER, q11 INTEGER, q12 INTEGER, '
|
|
'q13 INTEGER)')
|
|
cursor.execute(sql)
|
|
sql = ('create table marques'
|
|
'(id INTEGER PRIMARY KEY, libelle TEXT, provenance TEXT)')
|
|
cursor.execute(sql)
|
|
sql = ('create table modules'
|
|
'(id INTEGER PRIMARY KEY, module TEXT, calibre TEXT, '
|
|
'diametre TEXT, longueur TEXT)')
|
|
cursor.execute(sql)
|
|
sql = ('create table photos'
|
|
'(id INTEGER PRIMARY KEY, id_cigare INTEGER, photo TEXT)')
|
|
cursor.execute(sql)
|
|
sql = ('create table stocks'
|
|
'(id INTEGER PRIMARY KEY, id_cigare INTEGER, quantite INTEGER)')
|
|
cursor.execute(sql)
|
|
sql = ('create table tester'
|
|
'(id INTEGER PRIMARY KEY, nom TEXT, provenance TEXT, '
|
|
'raison TEXT, source TEXT)')
|
|
cursor.execute(sql)
|
|
|
|
# INSERT à mettre dans un fichier à part
|
|
sql = "INSERT INTO modules VALUES(1, 'Laguito N °3', '26', '10.32', '115')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(2, 'Carolina', '26', '10.32', '121')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(3, 'Panetela Larga', '28', "
|
|
"'11.11', '175')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(4, 'Chico', '29', '11.51', '106')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(5, 'Entreacto', '30', '11.91', '100')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(6, 'Palmita', '32', '12.70', '152')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(7, 'Delicioso', '33', '13.10', '159')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(8, 'Palma', '33', '13.10', '170')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(9, 'Ninfa', '33', '13.10', '178')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(10, 'Panetela', '34', '13.49', '117')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(11, 'Placera', '34', '13.49', '125')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(12, 'Epicure', '35', '13.89', '110')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(13, 'Sport', '35', '13.89', '117')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(14, 'Conchita', '35', '13.89', '127')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(15, 'Carlota', '35', '13.89', '143')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(16, 'Cadete', '36', '14.29', '115')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(17, 'Seoane', '36', '14.29', '125')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(18, 'Veguerito', '36', '14.29', '127')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(19, 'Delicado Extra', "
|
|
"'36', '14.29', '185')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(20, 'Trabuco', '38', '15.08', '110')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(21, 'Laguito N ° 2', '38', "
|
|
"'15.08', '152')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(22, 'Parejo', '38', '15.08', '166')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(23, 'Delicado', '38', '15.08', '192')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(24, 'Laguito N ° 1', '38', "
|
|
"'15.08', '192')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(25, 'Belvedere', '39', '15.48', '125')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(26, 'Perla', '40', '15.87', '102')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(27, 'Franciscano', '40', '15.87', '116')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(28, 'Coronita', '40', '15.87', '117')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(29, 'Standard', '40', '15.87', '123')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(30, 'Londres', '40', '15.87', '126')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(31, 'Petit Cetro', '40', '15.87', '129')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(32, 'Almuerzo', '40', '15.87', '130')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(33, 'Crema', '40', '15.87', '140')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(34, 'Laguito No.1', '40', '15.87', "
|
|
"'192')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(35, 'Minuto', '42', '16.67', '110')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(36, 'Mareva', '42', '16.67', '129')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(37, 'Petit Corona', '42', '16.67', "
|
|
"'127')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(38, 'Eminente', '42', '16.67', '132')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(39, 'Nacional', '42', '15.87', '134')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(40, 'Cosaco', '42', '16.67', '135')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(41, 'Corona', '42', '16.67', '140')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(42, 'Corona Grande', '42', "
|
|
"'16.67', '155')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(43, 'Cervante', '42', '16.67', '165')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(44, 'Conserva', '43', '17.07', '145')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(45, 'Cazadore', '43', '17.07', '162')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(46, 'Dalia', '43', '17.07', '170')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(47, 'Francisco', '44', '17.46', '143')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(48, 'Corona Gorda', '46', "
|
|
"'18.26', '143')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(49, 'Taco', '47', '18.65', '158')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(50, 'Julieta / Churchill', "
|
|
"'47', '18.65', '178')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(51, 'Gran Corona', '47', '18.65', '235')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(52, 'Hermoso N ° 4', '49', "
|
|
"'19.05', '127')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(53, 'Paco', '49', '19.45', '180')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(54, 'Double corona', '49', "
|
|
"'19.45', '194')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(55, 'Robusto', '50', '19.84', '127')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(56, 'Gordito', '50', '19.84', '141')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(57, 'Campana', '52', '20.64', '140')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(58, 'Panetelas Extra', '37', "
|
|
"'13.49', '127')")
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(59, 'Oficios (Corona)', '43', "
|
|
"'17.07', '135')")
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(60, 'Majestic (Petit Corona)', "
|
|
"'39', '15.87', '140')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(61, 'Figurados', '60', '20+', '150+')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(62, 'Torpedo', '52', '20.8', '125')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(63, 'short robusto', '60', '24', '102')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(64, 'Mini Panetella', '20', '8', '125')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(65, 'Indéfini', '0', '0', '0')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO modules VALUES(66, 'Très petit corona', '40', "
|
|
"'15.88', '102')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(67, 'Toro', '52', '20.8', '152')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO modules VALUES(68, 'Prominente', '49', '19.45', '194')"
|
|
cursor.execute(sql)
|
|
|
|
# MARQUES
|
|
sql = "INSERT INTO marques VALUES(1, 'Cohiba', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(2, 'Trinidad', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(3, 'Vegas Robaina', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(4, 'Montecristo', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(5, 'Cuaba', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(6, 'Romeo y Julieta', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(7, 'Partagas', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(8, 'San Cristobal de la Habana', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(9, 'Punch', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(10, 'Hoyo de Monterrey', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(11, 'Bolivar', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(12, 'La Gloria Cubana', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(13, 'H.Upmann', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(14, 'Fonseca', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(15, 'La Flor de Cano', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(16, 'Troya', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(17, 'Quintero', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(18, 'Los Statos de Luxe', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(19, 'Caney', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(20, 'Belinda', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(21, 'Cabanas', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(22, 'La Corona', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(23, 'José L.Piedra', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(24, 'Cumpay', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(25, 'CAO', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(26, 'Dunhill', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(27, 'Nicarao', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(28, 'Oliva', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(29, 'Padron', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(30, 'Flor de Copan', 'Honduras')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(31, 'Flor de Selva', 'Honduras')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(32, 'J. Cortès', 'Honduras')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(33, 'Zino', 'Honduras')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(34, 'Villa Zamorano', 'Honduras')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO marques VALUES(35, "
|
|
"'Flor de Rafaël Gonzáles Márquez', 'cuba')")
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO marques VALUES(36, 'Macanudo', "
|
|
"'République Dominicaine')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(37, 'Pléiades', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(38, 'Toscano', 'Italie')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(39, 'Davidoff', 'cuba')"
|
|
cursor.execute(sql)
|
|
sql = ("INSERT INTO marques VALUES(40, 'Avo Uvezian', "
|
|
"'République Dominicaine')")
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(41, 'Don Pepin Garcia', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(42, 'O Line', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
sql = "INSERT INTO marques VALUES(43, 'Plasencia', 'Nicaragua')"
|
|
cursor.execute(sql)
|
|
|
|
db.commit()
|
|
|
|
|
|
def checkconfig():
|
|
"""Récupérer la configuration ou la créer"""
|
|
# Fichier de configuration
|
|
# configfile = os.path.expanduser("~/.config/cltwit.conf")
|
|
# On ouvre le fichier de conf
|
|
config = configparser.RawConfigParser()
|
|
try:
|
|
config.read(__CONFIGFILE__)
|
|
if config.has_option('MesCigares', 'bdd'):
|
|
bdd = config.get('MesCigares', 'bdd')
|
|
except Exception:
|
|
pass
|
|
|
|
if not os.path.exists(bdd):
|
|
createdb(bdd)
|
|
|
|
# Si aucune conf
|
|
if not config.has_option('MesCigares', 'bdd'):
|
|
bdd = __CONFDIR__ + "/bdd/main.db"
|
|
# écrire le fichier de conf avec les informations par defaut
|
|
try:
|
|
cfgfile = open(__CONFIGFILE__, 'w')
|
|
if not config.has_section('MesCigares'):
|
|
config.add_section('MesCigares')
|
|
config.set('MesCigares', 'bdd', bdd)
|
|
config.write(cfgfile)
|
|
except IOError:
|
|
pass
|
|
finally:
|
|
cfgfile.close
|
|
createdb(bdd)
|
|
return bdd
|
|
|
|
|
|
def setconfig(new_bdd):
|
|
"""Mettre à jour la configuration"""
|
|
config = configparser.RawConfigParser()
|
|
try:
|
|
cfgfile = open(__CONFIGFILE__, 'w')
|
|
if not config.has_section('MesCigares'):
|
|
config.add_section('MesCigares')
|
|
config.set('MesCigares', 'bdd', new_bdd)
|
|
config.write(cfgfile)
|
|
except IOError:
|
|
pass
|
|
finally:
|
|
cfgfile.close
|
|
|
|
|
|
if __name__ == "__main__":
|
|
dbconf = checkconfig()
|
|
db = sqlite3.connect(dbconf)
|
|
main = MesCigares()
|
|
main.window.set_title(
|
|
"MesCigares - base : {0}".format(ntpath.basename(dbconf))
|
|
.replace('.db', ''))
|
|
gtk.main()
|