Advertisement
Kaadem-85

agenda.py

Sep 11th, 2016
910
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 20.44 KB | None | 0 0
  1. #!/usr/bin/python3
  2. # -*- coding: utf8 -*-
  3.  
  4. # Copyright © 2016 Ordinosor <https://twitter.com/Ordinosor>
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program.  If not, see <http://www.gnu.org/licenses/>
  17.  
  18. #==== IMPORTATION DES MODULES =============================================================================
  19.  
  20. from tkinter import* # Importation du module tkinter
  21. from tkinter.messagebox import *
  22. from calendar import monthcalendar # Instancie un calendrier mensuel
  23. from calendar import Calendar # Instancie un calendrier annuel
  24. from time import localtime # Importation de la date et de l'heure locales
  25. from datetime import time, datetime # Module permettant de manipuler les dates et les durées.
  26. from os import chdir        # Importation du module OS pour effectuer le changement de répertoire
  27. import os
  28. import os.path
  29. from PIL import Image, ImageTk  # Module PIL (traitement des images importées)
  30. from contextlib import suppress
  31.                
  32. #==== CLASSE ==============================================================================================
  33.  
  34. class Agenda(object) :
  35.     "Instanciation de l'agenda"
  36.    
  37.     dico_iteration = {}
  38.    
  39.     def __init__(self, d, m, y) :
  40.         "Constructeur"     
  41.         self.d = d
  42.         self.m = m
  43.         self.y =
  44.  
  45. #----------------------------------------------------------------------------------------------------------
  46.  
  47.     def pages(self, destroy_date = int()) :
  48.         "Création des pages"
  49.         if destroy_date != int() : # Destruction éventuelle de la page précédemment consultée
  50.             destroy_date.destroy()
  51.         self.page = Tk()
  52.         self.page.title('Mon agenda')
  53.        
  54. #----------------------------------------------------------------------------------------------------------
  55.  
  56.         self.frame = Frame(self.page, bg='white')
  57.         self.frame.grid()
  58.    
  59. #----------------------------------------------------------------------------------------------------------
  60.  
  61.         self.buttons = Frame(self.frame, bg='white')
  62.         self.buttons.grid(row=0, column=0, sticky = 'w')
  63.  
  64. #----------------------------------------------------------------------------------------------------------
  65.    
  66.         # Widget Frame qui contient la date du jour et deux petits triangles de changement de date :
  67.         self.subframe = Frame(self.frame, bg='white', relief='groove', bd=1, padx= 170)
  68.         self.subframe.grid(row=1, column=0, columnspan=2, sticky = 'nsew')
  69.    
  70. #----------------------------------------------------------------------------------------------------------
  71.    
  72.         #Création de trois boutons d'en-tête. Les commandes sont configurées plus tard :
  73.         self.button_list = list()
  74.         self.textes = ['Enregistrer', 'Valider', 'Effacer']
  75.         for i in range(0, len(self.textes)):
  76.             self.button = Button(self.buttons, text = self.textes[i], bg='#357AB7', fg='white', activebackground='white', activeforeground='#357AB7')
  77.             self.button.grid(row=0, column=i)
  78.             self.button_list.append(self.button)
  79.  
  80.         # Création de l'onglet "rechercher" :
  81.         self.search_labelframe = LabelFrame(self.buttons, bd=1, highlightthickness=0, bg='white')
  82.         self.search_labelframe.grid(row=0, column = 4)
  83.  
  84.         # Importation de l'image de la loupe :
  85.         self.mon_image = "/home/benoit/Documents/agendrier/loupe.png" # Importation de l'image
  86.         self.image = Image.open(self.mon_image)
  87.         self.size = 32, 32 # Réduction de la taille de l'image
  88.         self.image.thumbnail(self.size)
  89.         self.photo = ImageTk.PhotoImage(self.image, master = self.page)
  90.  
  91.         # Fonction qui efface le mot "Rechercher" lorsque l'utilisateur clique dans le widget "Entry"
  92.         def delete(event):
  93.             if self.search_entry.get() == "Rechercher":
  94.                 self.search_entry.delete(0, 'end')
  95.  
  96.         # Création du widget "chercher":
  97.         self.search_entry = Entry(self.search_labelframe, fg='#357AB7', font='Times 12 bold', border=0, highlightthickness=0)
  98.         self.search_entry.grid(row=0, column=0)
  99.         self.search_entry.insert(0, "Rechercher")
  100.         self.search_entry.bind('<Button-1>', delete)
  101.  
  102.         # Création du bouton "loupe" :
  103.         self.find = Actions(self.d, self.m, self.y)
  104.         self.search = Button(self.search_labelframe, image=self.photo, bd=0, highlightthickness=0, command = lambda : self.find.search(self.search_entry))
  105.         self.search.grid(row=0, column=1)
  106.  
  107.  #----------------------------------------------------------------------------------------------------------
  108.        
  109.         # Création du triangle de changement de date (vers le futur):
  110.         self.next_day = Actions(int(self.d)+1, self.m, self.y) # Création de l'objet "Jour d'après" :
  111.         self.right_triangle=Button(self.subframe,bg='white',fg='#357AB7',text=u"\u25B6",bd=0,highlightthickness=0,padx=0,pady=0,activebackground='#357AB7',activeforeground='white')
  112.         self.right_triangle.grid(row = 0, column = 2, padx = 10, sticky = 'e')
  113.         self.right_triangle['command'] = lambda : self.next_day.next_day(self.page)
  114. #----------------------------------------------------------------------------------------------------------
  115.  
  116.         # Date sous la forme dd/mm/yyyy.
  117.         # Quatre possibilités différentes concernant l'adjonction d'un "0" supplémentaire :
  118.         if int(self.d) < 10 and self.m < 10 :
  119.             self.date = Label(self.subframe, bg = 'white', fg='#357AB7', bd=0, font = 'Times 18 bold',
  120.             text = '0' + str(self.d) + '/' + '0' + str(self.m) + '/' + str(self.y))
  121.         elif int(self.d) < 10 :
  122.             self.date = Label(self.subframe, bg = 'white', fg='#357AB7', bd=0, font = 'Times 18 bold',
  123.             text = '0' + str(self.d) + '/' + str(self.m) + '/' + str(self.y))
  124.         elif self.m < 10 :
  125.             self.date = Label(self.subframe, bg = 'white', fg='#357AB7', bd=0, font = 'Times 18 bold',
  126.             text = str(self.d) + '/' + '0' + str(self.m) + '/' + str(self.y))
  127.         else :
  128.             self.date = Label(self.subframe, bg = 'white', fg='#357AB7', bd=0, font = 'Times 18 bold', text = str(self.d) + '/' + str(self.m) + '/' + str(self.y))
  129.         self.date.grid(row = 0, column = 1, sticky = 'nsew')
  130.  
  131. #----------------------------------------------------------------------------------------------------------
  132.  
  133.         # Création du triangle de changement de date (vers le passé):
  134.         self.previous_day = Actions(int(self.d)-1, self.m, self.y) # Création de l'objet "Jour d'avant" :
  135.         self.left_triangle=Button(self.subframe, bg='white', fg='#357AB7', text=u"\u25C0", bd=0, highlightthickness=0, padx = 0, pady = 0, activebackground = '#357AB7', activeforeground = 'white')
  136.         self.left_triangle.grid(row = 0, column = 0, padx = 10, sticky = 'w')
  137.         self.left_triangle['command'] = lambda : self.previous_day.previous_day(self.page)
  138.    
  139. #----------------------------------------------------------------------------------------------------------
  140.  
  141.         # Jour en cours. Remplacement des slashes par des tirets bas :
  142.         self.current_date = self.date['text'].replace('/', '_')
  143.  
  144. #----------------------------------------------------------------------------------------------------------
  145.  
  146.         # Création des pages de l'agenda
  147.         self.subframe2_list = list() # Création de deux listes vides.
  148.         self.hour_list = []
  149.         for i in range(7,22): # pour chaque heure de la journée :
  150.             self.subframe2 = Frame(self.frame, bg='white') # Création d'un cadre
  151.             self.subframe2.grid(row=i-5, column=0, sticky='nsew')
  152.             self.subframe2_list.append(self.subframe2)
  153.             if i < 10 : # Création des étiquettes affichant les heures de la journée.
  154.                 self.label = Label(self.subframe2, fg = 'white', bg = '#357AB7', padx=5, pady=2,font = 'bold', text = '  ' + str(i) + u"\u2070\u2070")
  155.             else :
  156.                 self.label = Label(self.subframe2, fg = 'white', bg = '#357AB7', padx=5, pady=2,font = 'bold', text = str(i) + u"\u2070\u2070")
  157.             self.label.grid(row=0, column = 0, sticky='nsew')  
  158.             # Création des entrées pour chaque heure de la journée :
  159.             self.hour = Text(self.subframe2, bg ='white', fg = 'black', font ='Times 14', highlightthickness=0, bd=1, selectbackground='blue', selectforeground='white', wrap='word', width=50, height=1, padx=10, pady=2)
  160.             self.hour.grid(row=0, column=1, sticky='nsew')
  161.             self.hour_list.append(self.hour)
  162.  
  163.         self.action_affichage = Actions(self.d, self.m, self.y, self.current_date, self.hour_list)
  164.         self.action_affichage.entries(self.page) # Affichage les différentes entrées de la page appelée.
  165.        
  166.         self.save = Actions(self.d, self.m, self.y, self.current_date)
  167.         self.validation = Actions(self.d, self.m, self.y, self.current_date)
  168.         self.invalider = Actions(self.d, self.m, self.y, self.current_date)
  169.         self.erase = Actions(self.d, self.m, self.y, self.current_date)
  170.         self.button_list[0]['command'] = lambda : self.save.save(self.subframe2_list)
  171.         self.button_list[1]['command'] = lambda : self.validation.validation(self.subframe2_list, self.page)
  172.         self.button_list[2]['command'] = lambda : self.erase.erase(self.subframe2_list, self.page)
  173.    
  174.         # Message qui apparait sous la forme d'une fenêtre pop-up dans le cas où une entrée n'a pas été traitée ni validée. Le message contient la date et le texte de l'entrée :
  175.         self.validated = open('validated','r')
  176.         self.read_validated = self.validated.readlines()
  177.         self.validated.close()
  178.         for i in range (0, len(self.read_validated)):
  179.             self.read_validated[i] = self.read_validated[i][:-1]
  180.         self.filelist = open('entrylist', 'r')
  181.         self.readfilelist = self.filelist.readline()
  182.         self.filelist.close()
  183.         self.readfilelist = self.readfilelist.split(',')
  184.         self.readfilelist = self.readfilelist[:-1]
  185.         for i in range(0, len(self.readfilelist)) :
  186.             if self.readfilelist[i] not in Agenda.dico_iteration :
  187.                 Agenda.dico_iteration[self.readfilelist[i]] = 0
  188.                 index = Agenda.dico_iteration[self.readfilelist[i]]
  189.             else:
  190.                 Agenda.dico_iteration[self.readfilelist[i]] = 1
  191.                 index = Agenda.dico_iteration[self.readfilelist[i]]
  192.             self.readfilelist[i] = self.readfilelist[i].split('-')
  193.             for i2 in range(0, len(self.readfilelist[i])):
  194.                 self.readfilelist[i][i2] = self.readfilelist[i][i2].split('_')
  195.             if self.readfilelist[i][0] == '':
  196.                 self.readfilelist[i][0] = []
  197.             self.duration = datetime.now() - datetime(int(self.readfilelist[i][0][2]), int(self.readfilelist[i][0][1]), int(self.readfilelist[i][0][0]))
  198.             self.readfilelist[i][0] = '_'.join(self.readfilelist[i][0])
  199.             self.readfilelist[i][1] = ''.join(self.readfilelist[i][1])
  200.             self.readfilelist[i] = '-'.join(self.readfilelist[i])
  201.             if self.duration.days > 1 and self.readfilelist[i] not in self.read_validated :
  202.                 while index < 1 :
  203.                     self.file = open(self.readfilelist[i], 'r')
  204.                     self.readfile = self.file.readline()
  205.                     self.readfilelist[i] = self.readfilelist[i].replace("_", "/")
  206.                     self.readfilelist[i] = self.readfilelist[i][:-3]
  207.                     self.warning = showwarning(self.readfilelist[i], self.readfilelist[i] + '\n' + self.readfile)
  208.                     index += 1
  209.                     Agenda.dico_iteration[self.readfilelist[i]] = 1
  210.  
  211.         # Démarrage du réceptionnaire d'événements :
  212.         self.page.mainloop()
  213.                                
  214. #==== CLASSE ==============================================================================================    
  215.  
  216. class Actions(Agenda) :
  217.     "Actions enregister, effacer, valider..."
  218.    
  219.     def __init__(self, d, m, y, current_date = [], hour_list = []) :
  220.         "Constructeur"
  221.         Agenda.__init__(self, d, m, y)
  222.         self.current_date = current_date
  223.         self.hour_list = hour_list
  224.        
  225. #----------------------------------------------------------------------------------------------------------
  226.                        
  227.     def previous_day(self, page) :
  228.         "Conditions à remplir pour reculer d'un jour"
  229.         if self.d < 1 :
  230.             self.m -=1
  231.             if self.m == 0 :
  232.                 self.m = 12
  233.                 self.y -= 1
  234.             self.c = monthcalendar(self.y, self.m)
  235.             self.d = max(max(self.c))# "max(max" s'explique par le fait que self.c est une liste de listes.
  236.         self.pages(page)
  237.  
  238. #----------------------------------------------------------------------------------------------------------
  239.        
  240.     def next_day(self, page) :
  241.         "Conditions à remplir pour avancer d'un jour"
  242.         self.c = monthcalendar(self.y, self.m) # Mois en cours.
  243.         if self.d > max(max(self.c)): # Si le n° du jour est supérieur au n° du dernier jour du mois
  244.             self.d = '1' # N° du jour = 1
  245.             self.m += 1
  246.             if self.m > 12 :
  247.                 self.m = 1  # m = mois
  248.                 self.y += 1 # y = year(année)
  249.         self.pages(page)               
  250.  
  251. #----------------------------------------------------------------------------------------------------------
  252.  
  253.     def save(self, subframe2_list):
  254.         "Enregistrement des entrées"
  255.         self.subframe2_list = subframe2_list
  256.         self.file = None
  257.         for i in range(0, len(self.subframe2_list)) :
  258.             for child in self.subframe2_list[i].winfo_children():
  259.                 if child.winfo_class() == "Text":
  260.                     self.get_text = child.get(1.0, 'end')
  261.                     self.filename = str(self.current_date) + '-' + str(i)
  262.                     if len(self.get_text) > 1 :
  263.                         self.file = open(self.filename, 'w')
  264.                         self.file.write(self.get_text)
  265.                         self.file.close()
  266.                         self.filelist = open('entrylist', 'r')
  267.                         self.readfilelist = self.filelist.readline()
  268.                         self.filelist.close()
  269.                         self.readfilelist = self.readfilelist.strip() + self.filename + ','
  270.                         self.readfilelist.replace('\n','')
  271.                         self.filelist = open('entrylist', 'w')
  272.                         self.filelist.write(self.readfilelist)                     
  273.                         self.filelist.close()
  274.                         self.readfilelist = self.readfilelist.split(',')
  275.                         self.readfilelist2 = []
  276.                         for entry in self.readfilelist :
  277.                             if entry not in self.readfilelist2 :
  278.                                 self.readfilelist2.append(entry)
  279.                             if entry == '' :
  280.                                 del entry
  281.                         self.readfilelist2 = ",".join(self.readfilelist2)
  282.                         self.filelist = open('entrylist', 'w')
  283.                         self.filelist.write(self.readfilelist2)
  284.                         self.filelist.close()
  285.                 if child['bg'] == 'green' and child['fg'] == 'white' :
  286.                     self.green(i, self.filename)
  287.  
  288. #----------------------------------------------------------------------------------------------------------
  289.  
  290.     def entries(self, page) :
  291.         "Affichage des entrées de la page consultée"
  292.         self.page = page
  293.         self.filelist = open('entrylist', 'r')
  294.         self.readfilelist = self.filelist.readline()
  295.         self.readfilelist = self.readfilelist.split(',')
  296.         for i in range(0, len(self.readfilelist)):
  297.             self.readfilelist[i] = self.readfilelist[i].split('-')
  298.         self.readfilelist = self.readfilelist[:-1]
  299.         self.filelist.close()
  300.         for i in range (0, len(self.readfilelist)) :
  301.             self.filename = str(self.current_date) + '-' + self.readfilelist[i][1]
  302.             if '-'.join(self.readfilelist[i]) == self.filename :
  303.                 self.file = open(self.filename, 'r')
  304.                 self.readfile = self.file.readline()
  305.                 self.hour_list[int(self.readfilelist[i][1])].delete(1.0, 'end')
  306.                 self.readfile = self.readfile.strip()
  307.                 self.hour_list[int(self.readfilelist[i][1])].insert('end', self.readfile)
  308.                 self.file.close()
  309.         self.validated = open('validated', 'r')
  310.         self.read_validated = self.validated.readlines()
  311.         self.validated.close()
  312.         self.read_validated_2 = []
  313.         for entry in self.read_validated :
  314.             if entry not in self.read_validated_2 :
  315.                 self.read_validated_2.append(entry)
  316.         self.validated = open('validated', 'w')
  317.         for i in range (0, len(self.read_validated_2)):
  318.             self.validated.write(self.read_validated_2[i])
  319.         self.validated.close()
  320.         for i in range(0, len(self.read_validated_2)):
  321.             self.read_validated_2[i] = self.read_validated_2[i].split('-')
  322.             if self.read_validated_2[i][0] == self.current_date :
  323.                 self.hour_list[int(self.read_validated_2[i][1])].config(bg = 'green', fg = 'white')
  324.                
  325. #----------------------------------------------------------------------------------------------------------    
  326.  
  327.     def validation(self, subframe2_list, page):
  328.         "Validation des entrées traitées (Rendez-vous honorés etc...)"
  329.         self.page = page
  330.         self.subframe2_list = subframe2_list
  331.         self.validated_entry = self.page.focus_get()
  332.         self.validated_entry.config(bg = 'green', fg = 'white')
  333.         self.save(self.subframe2_list)
  334.                        
  335. #----------------------------------------------------------------------------------------------------------    
  336.  
  337.     def green(self, i, filename) :
  338.         "Stockage des pages validées dans un fichier"
  339.         self.validated = open('validated', 'a')
  340.         self.validated.write(filename + '\n')
  341.         self.validated.close()
  342.            
  343. #----------------------------------------------------------------------------------------------------------
  344.                    
  345.     def erase(self, subframe2_list, page):
  346.         "Effacement des entrées"
  347.         self.page = page
  348.         self.subframe2_list = subframe2_list
  349.         self.get_entry = self.page.focus_get()
  350.         self.get_entry.delete(1.0, 'end')
  351.         self.get_entry.config(bg='white', fg='black')
  352.         self.filename = ''
  353.         for i  in range(0, len(self.subframe2_list)) :
  354.             for child in self.subframe2_list[i].winfo_children():
  355.                 if child == self.get_entry:
  356.                     self.filename = str(self.current_date) + '-' + str(i)  
  357.         self.validated = open('validated', 'r')
  358.         self.read_validated = self.validated.readlines()
  359.         self.validated.close()
  360.         if self.filename + '\n' in self.read_validated :
  361.             self.read_validated.remove(self.filename + '\n')
  362.         self.validated = open('validated', 'w')
  363.         for i in range(0, len(self.read_validated)):
  364.             self.validated.write(self.read_validated[i])
  365.         self.validated.close()
  366.         self.filelist = open('entrylist', 'r')
  367.         self.readfilelist = self.filelist.readline()
  368.         self.readfilelist = self.readfilelist.split(',')
  369.         if self.filename in self.readfilelist :
  370.             self.readfilelist.remove(self.filename)
  371.         self.readfilelist = ','.join(self.readfilelist)
  372.         self.filelist.close()
  373.         self.filelist = open('entrylist', 'w')
  374.         self.filelist.write(self.readfilelist)
  375.         self.filelist.close()
  376.         os.remove('/home/benoit/' + self.filename)
  377.                    
  378. #----------------------------------------------------------------------------------------------------------
  379.    
  380.     def search(self, search_entry):
  381.         "Méthode qui cherche une chaîne de caractères dans les fichiers"
  382.         with suppress(Exception):
  383.             self.search_string = search_entry.get()
  384.             self.search_string = self.search_string.lower()
  385.             self.listdir = os.listdir('/home/benoit/Documents/agendrier')
  386.             self.list_all_files = list()
  387.             for i in range (0, len(self.listdir)) :
  388.                 if self.listdir[i]!='validated' and self.listdir[i]!='entrylist' and self.listdir[i]!='__pycache__' and os.path.splitext(self.listdir[i])[1]!='.py' and os.path.splitext(self.listdir[i])[1] != '.py~':
  389.                     self.list_all_files.append(self.listdir[i])
  390.             self.in_page = Toplevel(bg = 'white', padx=10, pady=10)
  391.             self.in_page.title('Votre recherche')
  392.             self.label = Label(self.in_page, bg = 'white', text = 'Les pages suivantes'+'\n'+'contiennent votre recherche', fg = 'black', font='Times 18 bold')
  393.             self.label.grid(row=0, column = 0, columnspan = 4, pady = 10)
  394.             i2 = 1 # variable d'incrémentation de la ligne dans le Toplevel
  395.             i3 = 0 # variable d'incrémentation de la colonne dans le Toplevel
  396.             for i in range(0, len(self.list_all_files)):
  397.                 self.file = open(self.list_all_files[i], 'r')
  398.                 self.readfile = self.file.readline()
  399.                 self.readfile = self.readfile.lower()
  400.                 self.file.close()
  401.                 if self.readfile.find(self.search_string) != -1 :
  402.                     self.filename = os.path.splitext(self.list_all_files[i])
  403.                     self.d = int(self.filename[0][:2])
  404.                     self.m = int(self.filename[0][3:5])
  405.                     self.y = int(self.filename[0][6:10])
  406.                     self.button_page = Button(self.in_page, bg='#357AB7', fg='white', text=self.filename[0][:10].replace('_','/'))
  407.                     self.button_page.grid(row=i2, column = i3, sticky = 'w')
  408.                     self.show_page = Agenda(self.d, self.m, self.y)
  409.                     self.show_page.pages
  410.                     self.button_page.config(command=self.show_page.pages)
  411.                     i3 += 1
  412.                     if i3 % 4 == 0:
  413.                         i2 += 1
  414.                         i3 = 0 
  415.         if len(self.in_page.winfo_children()) == 1 :
  416.             self.label.config(bg='red', fg='white', text='Aucun résultat', padx = 50)
  417.            
  418. # ##### MAIN PROGRAMM #####################################################################################
  419.  
  420. if __name__ == "__main__":
  421.  
  422.     rep = os.getcwd() # = /home/benoit
  423.     if rep != '/home/benoit' :
  424.         rep = '/home/benoit'
  425.     chdir(rep + "/Documents/agendrier") # Change directory, c'est-à dire changement du répertoire de travail courant.
  426.  
  427.     d = localtime()[2] # Current day
  428.     m = localtime()[1] # Current month 
  429.     y = localtime()[0] # Current year
  430.  
  431.     agenda = Agenda(d, m, y)
  432.     agenda.pages()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement