def __setupDB(self, name): # Set the path and filename to the sqlite3 database sqlite = os.path.join(self.db_dir, "%s.sqlite3" % name) sql = SqLite(sqlite) sql.connect() sql.curs.execute(""" CREATE TABLE IF NOT EXISTS Users ( Id INTEGER PRIMARY KEY ,UrlId INTEGER NOT NULL ,Phone TEXT NOT NULL ,SentCount SIGNED INT DEFAULT 0 ,Active NUMERIC DEFAULT 1 ,Created DATETIME DEFAULT current_timestamp ); CREATE TABLE IF NOT EXISTS Sites ( Id INTEGER PRIMARY KEY ,Url TEXT NOT NULL ,Active NUMERIC DEFAULT 1 ,Created DATETIME DEFAULT current_timestamp ); CREATE TABLE IF NOT EXISTS Subscribed ( Id INTEGER PRIMARY KEY ,UserId INTEGER NOT NULL ,SiteId INTEGER NOT NULL ,DOW TEXT NOT NULL # The DOW field format is as follows: weekday (0-6, 0 = Sunday, * = Everyday). # Ranges can be used as: 1-5 = Monday through Friday ,Time NUMERIC DEFAULT 800 # Time field is numeric (no alpha characters allowed). # Time format is in 24 hr format, no colon: e.g. 800 = 8:00 AM, 2300 = 11:00 PM ,Created DATETIME DEFAULT current_timestamp ); CREATE TABLE IF NOT EXISTS Quotes ( Id INTEGER PRIMARY KEY ,UrlId INTEGER NOT NULL ,Quote TEXT NOT NULL ,Created DATETIME DEFAULT current_timestamp ); """)
def __init__(self, tabControl, win, language): # Instantiate the objects self.i18n = I18N(language) self.fonts = Fonts() self.functions = Functions(self) self.win = win self.sql = SqLite() # Creating the tab, adding it to the tabControl tabD = ttk.Frame(tabControl) tabControl.add(tabD, text=self.i18n.tabD) # Creating labelframes for the tab myPlanner_label = ttk.Label(text=self.i18n.myPlanner, font=self.fonts.FontHeader) self.myPlanner = ttk.LabelFrame(tabD, labelwidget=myPlanner_label) self.myPlanner.grid(column=0, row=0, pady=10) self.search_label = ttk.Label(text=self.i18n.search, font=self.fonts.FontHeader2) self.search = ttk.LabelFrame(self.myPlanner, labelwidget=self.search_label) self.search.grid(column=0, row=1, sticky="W") def handle_focus_in(_): recipies = self.sql.select_recipes() try: self.selectDay = OptionMenu(self.search, self.recipe_list, *recipies) self.selectDay.grid(column=0, row=2, sticky="W", padx=8, pady=4) except: pass # Get a list of recipes from the db recipies = self.sql.select_recipes() tabD.bind("<FocusIn>", handle_focus_in) # Searchbox self.recipe_list = StringVar(self.win) # On change dropdown value def change_dropdown(*args): self.recipe_list.get() recipies = self.sql.select_recipes() # link function to change dropdown self.recipe_list.trace('w', change_dropdown) self.recipe_list.set(self.i18n.selectrecipe) # This function formats the "JSON" recipe and shows the data def show_selected_recipe(): try: selected_recipe_list = self.sql.show_recipe( self.recipe_list.get()) selected_recipe_list = selected_recipe_list[0] RecipeName = selected_recipe_list[1] RecipeInstructions = selected_recipe_list[2] RecipePicture = selected_recipe_list[3] RecipeIngrediences = selected_recipe_list[4] RecipeMeasurements = selected_recipe_list[5] self.RecipeServings = selected_recipe_list[6] # The ast import is used to change a string formattet as a list to a list. import ast import re RecipeIngrediences = ast.literal_eval(RecipeIngrediences) RecipeMeasurements = ast.literal_eval(RecipeMeasurements) # The recipe ingrediences needs to be formattet into two lists, one for the volumes, # and one for the measurements. This is because the api for the recipes has strange # formats. vol = [] mea = [] # Going through the list of measurements checking for a number, else append 1 for x in range(0, len(RecipeIngrediences)): try: x = re.search("\d*\.\d+|\d+", RecipeMeasurements[x]) vol.append(x.group()) except: vol.append(1) # Going through the list of measurements for g,kg,oz.. for x in range(0, len(RecipeMeasurements)): try: y = re.search("[a-zA-Z ]+", RecipeMeasurements[x]) mea.append(y.group()) except: pass # Setup the canvas for the image image = Image.open(RecipePicture) \ .resize((pHeight+10,pWidth+10),Image.ANTIALIAS) self.img = ImageTk.PhotoImage(image) self.canvas.create_image(0, 0, anchor='nw', image=self.img) self.RecipeMeasurements = [ x.strip(' ') for x in RecipeMeasurements ] self.RecipeMeasurements = list(filter(None, RecipeMeasurements)) list_dict = list(zip(vol, mea)) self.dict = dict(zip(RecipeIngrediences, list_dict)) #print(self.diict) # Pandas creates a two dimentional datastructure. from pandas import DataFrame as df data = df.from_dict( self.dict, orient='index', columns=[self.i18n.number, self.i18n.value]) self.myIngrediences.delete('1.0', tk.END) self.myIngrediences.insert(tk.END, data) self.myRecipe.delete('1.0', tk.END) self.myRecipe.insert(tk.END, RecipeInstructions) self.recipe_name.config(text=self.i18n.recipeName + ": " + RecipeName) except: pass self.search_button = tk.Button(self.search, text=self.i18n.search, command=show_selected_recipe) self.search_button.grid(column=1, row=2, sticky='W', padx=8, pady=4) # Label for the recipe name self.recipe_name = ttk.Label(self.myPlanner, font=self.fonts.FontHeader) self.recipe_name.grid(column=0, row=5, padx=8, pady=4, sticky="W") # Ingrediences self.myIngrediences_label = ttk.Label(self.myPlanner, text=self.i18n.ingrediences, font=self.fonts.FontHeader2) self.myIngrediences_label.grid(column=0, row=6, sticky="NW", padx=8) self.myIngrediences = scrolledtext.ScrolledText(self.myPlanner, width=60, height=20, wrap=tk.WORD) self.myIngrediences.grid(column=0, row=7, padx=8, pady=4, sticky="W") # Recipe self.recipe_label = ttk.Label(self.myPlanner, text=self.i18n.recipe, font=self.fonts.FontHeader2) self.recipe_label.grid(column=1, row=6, sticky="NW", padx=8) self.myRecipe = scrolledtext.ScrolledText(self.myPlanner, width=60, height=20, wrap=tk.WORD) self.myRecipe.grid(column=1, row=7, sticky="NW", padx=8, pady=4) # Recipe picture pHeight = 322 pWidth = 322 self.recipepic_label = ttk.Label(self.myPlanner, text=self.i18n.recipePicture, font=self.fonts.FontHeader2) self.pictureFrame = ttk.LabelFrame(self.myPlanner, labelwidget=self.recipepic_label) self.pictureFrame.grid(column=3, row=6, sticky="NW", rowspan=10) self.canvas = Canvas(self.pictureFrame) self.canvas.config(width=pWidth, height=pHeight, highlightthickness=0) self.canvas.grid(column=0, row=0, padx=8, pady=4) # Dropdown menu self.add_recipe = ttk.Label(self.myPlanner, text=self.i18n.addrecipe, font=self.fonts.FontHeader2) self.addRecipes = ttk.LabelFrame(self.myPlanner, labelwidget=self.add_recipe) self.addRecipes.grid(column=0, row=8, sticky="w", columnspan=5) self.tkvar = StringVar(self.win) self.tkvar.set(self.i18n.selectDay) # on change dropdown value def change_dropdown(*args): self.tkvar.get() # link function to change dropdown self.tkvar.trace('w', change_dropdown) # Dictionary with options choices = (self.i18n.monday, self.i18n.tuesday, self.i18n.wednesday, self.i18n.thursday, self.i18n.friday, self.i18n.saturday, self.i18n.sunday) # Get planned recipe self.plan = self.sql.get_planned_meals() self.selectDay = OptionMenu(self.addRecipes, self.tkvar, *choices) self.selectDay.grid(column=0, row=0, padx=8, pady=4, sticky="W") # This function adds the recipe to the selected day def add_recipe_function(): selected_recipe = self.recipe_list.get() selected_day = self.tkvar.get() #print(selected_day,selected_recipe) self.functions.add_day(selected_recipe, selected_day, language) self.sql.add_recipe_to_meal_plan(selected_recipe, selected_day) # This function removes the recipe for the selected day def remove_recipe_function(): selected_day = self.tkvar.get() self.functions.add_day("None", selected_day, language) self.sql.add_recipe_to_meal_plan("None", selected_day) # Add and delete button self.addButton = tk.Button(self.addRecipes, text=self.i18n.add, command=add_recipe_function) self.addButton.grid(column=1, row=0) self.delButton = tk.Button(self.addRecipes, text=self.i18n.remove, command=remove_recipe_function) self.delButton.grid(column=2, row=0) # Labelframe for the planned recipes # This could be reworked to create the labels in a loop self.recipe_overview = tk.LabelFrame(self.addRecipes) self.recipe_overview.grid(column=0, row=1, padx=8, pady=4, columnspan=30, sticky="W") for x in range(len(choices)): self.test = ttk.Label(self.recipe_overview, text=choices[x], font=self.fonts.FontHeader) self.test.grid(column=x, row=1, padx=49, pady=4, sticky="W") word_len = 200 self.monday_recipe = ttk.Label(self.recipe_overview, text=self.plan[0], font=self.fonts.FontHeader2, wraplength=word_len) self.monday_recipe.grid(column=0, row=4) self.tuesday_recipe = ttk.Label(self.recipe_overview, text=self.plan[1], font=self.fonts.FontHeader2, wraplength=word_len) self.tuesday_recipe.grid(column=1, row=4) self.wednsday_recipe = ttk.Label(self.recipe_overview, text=self.plan[2], font=self.fonts.FontHeader2, wraplength=word_len) self.wednsday_recipe.grid(column=2, row=4) self.thursday_recipe = ttk.Label(self.recipe_overview, text=self.plan[3], font=self.fonts.FontHeader2, wraplength=word_len) self.thursday_recipe.grid(column=3, row=4) self.friday_recipe = ttk.Label(self.recipe_overview, text=self.plan[4], font=self.fonts.FontHeader2, wraplength=word_len) self.friday_recipe.grid(column=4, row=4) self.saturday_recipe = ttk.Label(self.recipe_overview, text=self.plan[5], font=self.fonts.FontHeader2, wraplength=word_len) self.saturday_recipe.grid(column=5, row=4) self.sunday_recipe = ttk.Label(self.recipe_overview, text=self.plan[6], font=self.fonts.FontHeader2, wraplength=word_len) self.sunday_recipe.grid(column=6, row=4)
def __init__(self, tabControl, win, language): # Instantiate the objects self.i18n = I18N(language) self.functions = Functions(self) self.fonts = Fonts() self.win = win self.sql = SqLite() # Creating the tab, adding it to the tabControl tabA = ttk.Frame(tabControl) tabControl.add(tabA, text=self.i18n.tabA) # Creating the labelframe for the tab myDay_label = ttk.Label(text=self.i18n.myDay, font = self.fonts.FontHeader) self.myDay = ttk.LabelFrame(tabA, labelwidget=myDay_label) self.myDay.grid(column=0, row=0, pady=10) # This function is run when tabA is in focus. # It collects the planned recipe for the current day, if any exists. # Else we do nothing. def handle_focus_in(_): self.recipename = self.sql.get_planned_meal(datetime.today().strftime('%A'))[0][0] try: self.recipe = self.sql.show_recipe(self.recipename)[0] self.recipeinstructions = self.recipe[2] self.recipepicture = self.recipe[3] self.recipeingrediences = self.recipe[4] self.recipemeasurements = self.recipe[5] if self.recipename != "None": show_recipe(self.recipename, self.recipe, self.recipeinstructions, self.recipepicture, self.recipeingrediences, self.recipemeasurements) if self.recipename == "None": self.ingredienceT.delete('1.0',tk.END) self.recipeT.delete('1.0',tk.END) myDay_label.config(text = self.i18n.myDay+": ") self.canvas.delete('all') except: pass tabA.bind("<FocusIn>", handle_focus_in) # This function formats the "JSON" recipe and shows the data def show_recipe(recipename, recipe, recipeinstructions, recipepicture, recipeingrediences, recipemeasurements): # The ast import is used to change a string formattet as a list to a list. import ast import re self.recipeingrediences = ast.literal_eval(self.recipeingrediences) self.recipemeasurements = ast.literal_eval(self.recipemeasurements) # The recipe ingrediences needs to be formattet into two lists, one for the volumes, # and one for the measurements. This is because the api for the recipes has strange # formats. vol = []; mea = [] # Going through the list of measurements checking for a number, else append 1 for x in range(0,len(self.recipeingrediences)): try: x = re.search("\d*\.\d+|\d+", self.recipemeasurements[x]) vol.append(x.group()) except: vol.append(1) # Going through the list of measurements for g,kg,oz.. for x in range(0,len(self.recipemeasurements)): try: y = re.search("[a-zA-Z ]+", self.recipemeasurements[x]) mea.append(y.group()) except: pass # Setup the canvas for the image pHeight = 340; pWidth = 340 image = Image.open(self.recipepicture) \ .resize((pHeight+10,pWidth+10),Image.ANTIALIAS) self.img = ImageTk.PhotoImage(image) self.canvas.create_image(0,0,anchor='nw',image=self.img) # Create a dictionary for the volumes and measurements list_dict = list(zip(vol,mea)) self.dict = dict(zip(self.recipeingrediences, list_dict)) #print(self.diict) # Pandas creates a two dimentional datastructure. from pandas import DataFrame as df data = df.from_dict(self.dict, orient='index', columns = [self.i18n.number, self.i18n.value]) #Insert the data in the ingredienceT scrolled text self.ingredienceT.delete('1.0',tk.END) self.ingredienceT.insert(tk.END, data) #Insert the recipe instructions into recipeT scrolled text self.recipeT.delete('1.0',tk.END) self.recipeT.insert(tk.END, self.recipeinstructions) myDay_label.config(text = self.i18n.myDay+": "+self.recipename) # Making the Ingrediences textbox, first with a labelframe ingredienceF_label = ttk.Label(text=self.i18n.ingrediences, font = self.fonts.FontHeader2) ingredienceF = ttk.LabelFrame(self.myDay, labelwidget = ingredienceF_label) ingredienceF.grid(column=0, row=1, padx=10, sticky="NW") # The ingredienceT contains the ingrediences self.ingredienceT = scrolledtext.ScrolledText(ingredienceF, width=60, height=20, wrap=tk.WORD) self.ingredienceT.grid(column=0, row=1, sticky="NW") # Making the recipe textbox recipeF_label = ttk.Label(text=self.i18n.recipe, font = self.fonts.FontHeader2) self.recipeF = ttk.LabelFrame(self.myDay, labelwidget=recipeF_label) self.recipeF.grid(column=0, row=2, padx=10, sticky="NW") # The recipeT contains the instructions self.recipeT = scrolledtext.ScrolledText(self.recipeF, width=60, height=20, wrap=tk.WORD) self.recipeT.grid(column=0, row=1, sticky="NW") # Making the Recipe picture canvas pHeight = 340; pWidth = 340 label = ttk.Label(text=self.i18n.recipePicture, font = self.fonts.FontHeader2) self.pictureFrame = ttk.LabelFrame(self.myDay,labelwidget=label) self.pictureFrame.grid(column=1, row=1, padx=8, pady=4, sticky="NW",rowspan=10) self.canvas = Canvas(self.pictureFrame) self.canvas.config( width = pWidth, height = pHeight, highlightthickness =0) self.canvas.grid(column=0,row=0) # Show the recipe for the day, this is only used when the program is initiated try: self.recipename = self.sql.get_planned_meal(datetime.today().strftime('%A'))[0][0] self.recipe = self.sql.show_recipe(self.recipename)[0] self.recipeinstructions = self.recipe[2] self.recipepicture = self.recipe[3] self.recipeingrediences = self.recipe[4] self.recipemeasurements = self.recipe[5] show_recipe(self.recipename, self.recipe, self.recipeinstructions, self.recipepicture, self.recipeingrediences, self.recipemeasurements) except: pass # This function sends the shopping list to the user. # Right now, it only shows a message box, but could be improved with an email or other. def send_shopping_list(): shoppinglist=[] try: for i in range(0,len(self.recipeingrediences)): shoppinglist.append(self.recipeingrediences[i]+" "+self.recipemeasurements[i]) message = "\n".join(shoppinglist) mBox.showinfo(self.i18n.shoppinglist, message) except: mBox.showinfo(self.i18n.shoppinglist, self.i18n.emptymessage) #print(*shoppinglist, sep='\n') # This function opens a dialog box to help the user add shoppings to the inventory. def add_shopping_to_db(): #self.sql.add_inventory("Pasta","1000","g","") try: self.functions.add_shopping_to_db(language,self.recipeingrediences) except: mBox.showinfo(self.i18n.shoppinglist, self.i18n.emptymessage) # Button to send the shopping list self.send_shopping_list_button = tk.Button(self.myDay,text=self.i18n.sendshopping, command=send_shopping_list) self.send_shopping_list_button.grid(column=0, row=3, sticky="W", padx=8, pady=4) # Button to add the shopping to the db self.add_shopping_to_db_button = tk.Button(self.myDay, text= self.i18n.addshopping, command=add_shopping_to_db) self.add_shopping_to_db_button.grid(column=0, row=4, sticky="W", padx=8, pady=4) # Initiate the calnderFrame by providing the tab name and the language. from calendarFrame import CalendarFrame self.calendar = CalendarFrame(self.myDay, language)
def __init__(self, tabControl, win, language): # Instantiate the objects self.i18n = I18N(language) self.functions = Functions(self) self.fonts = Fonts() self.win = win self.sql = SqLite() # Creating the tab, adding it to the tabControl tabB = ttk.Frame(tabControl) tabControl.add(tabB, text=self.i18n.tabB) # Creating the labelframe for the tab myWeek_label = ttk.Label(text=self.i18n.myWeek, font = self.fonts.FontHeader) self.myWeek = ttk.LabelFrame(tabB, labelwidget=myWeek_label) self.myWeek.grid(column=0, row=0, pady=10) # This function collect the planned meals from the db when the tab gets focus # We also populate the textboxes with the data. def handle_focus_in(_): self.planned_meals = self.sql.get_planned_meals() self.planned_meals = [f'{e}' for e in self.planned_meals] for child in self.myWeek.winfo_children(): if isinstance(child, tk.Text): child.config(state="normal") child.delete('1.0', tk.END) child.insert('1.0', self.planned_meals[0]) self.planned_meals.pop(0) tabB.bind("<FocusIn>", handle_focus_in) # Setup the label and textbox for the planned week # This could be refactored later. self.monday = ttk.Label(self.myWeek, text = self.i18n.monday, font = self.fonts.FontHeader2) self.monday.grid(column=0, row=2) self.monday_recipe = tk.Text(self.myWeek, height=1, width=50) self.monday_recipe.grid(row = 3) self.tuesday = ttk.Label(self.myWeek, text = self.i18n.tuesday, font = self.fonts.FontHeader2) self.tuesday.grid(column=0, row=4) self.tuesday_recipe = tk.Text(self.myWeek, height=1, width=50) self.tuesday_recipe.grid(row = 5) self.wednsday = ttk.Label(self.myWeek, text = self.i18n.wednesday, font = self.fonts.FontHeader2) self.wednsday.grid(column=0, row=6) self.wednsday_recipe = tk.Text(self.myWeek, height=1, width=50) self.wednsday_recipe.grid(row = 7) self.thursday = ttk.Label(self.myWeek, text = self.i18n.thursday, font = self.fonts.FontHeader2) self.thursday.grid(column=0, row=8) self.thursday_recipe = tk.Text(self.myWeek, height=1, width=50) self.thursday_recipe.grid(row = 9) self.friday = ttk.Label(self.myWeek, text = self.i18n.friday, font = self.fonts.FontHeader2) self.friday.grid(column=0, row=10) self.friday_recipe = tk.Text(self.myWeek, height=1, width=50) self.friday_recipe.grid(row = 11) self.saturday = ttk.Label(self.myWeek, text = self.i18n.saturday, font = self.fonts.FontHeader2) self.saturday.grid(column=0, row=12) self.saturday_recipe = tk.Text(self.myWeek, height=1, width=50) self.saturday_recipe.grid(row = 13) self.sunday = ttk.Label(self.myWeek, text = self.i18n.sunday, font = self.fonts.FontHeader2) self.sunday.grid(column=0, row=14) self.sunday_recipe = tk.Text(self.myWeek, height=1, width=50) self.sunday_recipe.grid(row = 15) for child in self.myWeek.winfo_children(): child.grid_configure(sticky = "W", padx=8, pady=4) child.config(state="disabled") from calendarFrame import CalendarFrame self.calendar = CalendarFrame(tabB, language)
def api_search(self, language): # This function calls the mealdb and adds the json object to the recipe database import requests from Resources import Fonts, I18N from PIL import Image, ImageTk self.fonts = Fonts() self.i18n = I18N(language) popup = tk.Toplevel() popup.winfo_class() popup.resizable(0, 0) popup.geometry("1050x520+200+200") popup.wm_title(self.i18n.recipeAPI) label = ttk.Label(popup, text=self.i18n.recipeAPIresult) response = requests.get("https://www.themealdb.com/api/json/v1/1/search.php?s="\ +str(self.sp.search)) recipe = response.json() recipe_dict = recipe["meals"][0] frame = ttk.LabelFrame(popup) frame.grid(column=0, row=0) label = ttk.Label(frame) label.grid(column=0, row=1) label.configure(text=recipe_dict["strMeal"], font=self.fonts.FontHeader2) self.recipe_ingredience = [] self.recipe_measurement = [] for x in range(1, 20): if (recipe_dict["strMeasure"+str(x)] == "None" \ or recipe_dict["strMeasure"+str(x)] == None \ or recipe_dict["strMeasure"+str(x)] == "" \ or recipe_dict["strMeasure"+str(x)] == " "): pass else: self.recipe_ingredience.append(recipe_dict["strIngredient" + str(x)]) self.recipe_measurement.append(recipe_dict["strMeasure" + str(x)]) self.recipe_ingredience = list(filter(None, self.recipe_ingredience)) self.recipe_measurement = list(filter(None, self.recipe_measurement)) self.recipe_picture = recipe_dict["strMealThumb"] self.recipe_instructions = recipe_dict["strInstructions"] self.ingrediences = scrolledtext.ScrolledText(frame, width=40) self.ingrediences.grid(column=0, row=2) dictst = { self.i18n.ing: self.recipe_ingredience, self.i18n.vol: self.recipe_measurement } from pandas import DataFrame as df data = df.from_dict(dictst) self.ingrediences.insert(tk.END, data) self.instructions = scrolledtext.ScrolledText(frame, width=40) self.instructions.grid(column=1, row=2) self.instructions.insert(tk.END, self.recipe_instructions) # RECIPE PICTURE pHeight = 322 pWidth = 322 import urllib.request from os import path url = self.recipe_picture fDir = path.dirname(__file__) urllib.request.urlretrieve( url, fDir + "/pictures/" + recipe_dict["strMeal"] + ".jpg") self.canvas = Canvas(frame) self.canvas.config(width=pWidth, height=pHeight, highlightthickness=0) self.canvas.grid(column=2, row=2, padx=8, pady=4) image = Image.open(fDir+"/pictures/"+recipe_dict["strMeal"]+".jpg") \ .resize((pHeight+10,pWidth+10),Image.ANTIALIAS) self.img = ImageTk.PhotoImage(image) self.canvas.create_image(0, 0, anchor='nw', image=self.img) def save_to_db(): self.sql.insert_recipe(recipename, str(ingrediences), str(measurements), instructions, picture) popup.destroy() B1 = tk.Button(frame, text=self.i18n.cancel, command=popup.destroy) B1.grid(column=0, row=4) B2 = tk.Button(frame, text=self.i18n.addtoDB, command=save_to_db) B2.grid(column=0, row=3) B2.config(font=self.fonts.FontHeader2) for child in frame.winfo_children(): child.grid_configure(sticky="w", padx=8, pady=4) from SqLite import SqLite self.sql = SqLite() recipename = recipe_dict["strMeal"] ingrediences = self.recipe_ingredience measurements = self.recipe_measurement instructions = self.recipe_instructions picture = fDir + "/pictures/" + recipe_dict["strMeal"] + ".jpg" B1.after(1, lambda: B1.focus_force()) popup.mainloop()
def add_shopping_to_db(self, language, shoppinglist): from Resources import Fonts, I18N from SqLite import SqLite self.sql = SqLite() self.fonts = Fonts() self.i18n = I18N(language) addshopping = tk.Toplevel() addshopping.resizable(0, 0) #addshopping.geometry("550x520+200+200") addshopping.wm_title("Add shopping to db") frame = ttk.LabelFrame(addshopping) frame.grid(column=0, row=0) shoppinglist_frame = ttk.LabelFrame(addshopping) shoppinglist_frame.grid(column=0, row=0) item_label = ttk.Label(shoppinglist_frame, text=self.i18n.treeName) item_label.grid(column=0, row=0) volume_label = ttk.Label(shoppinglist_frame, text=self.i18n.treeVolume) volume_label.grid(column=1, row=0) measurement_label = ttk.Label(shoppinglist_frame, text=self.i18n.treeUnit) measurement_label.grid(column=2, row=0) expiration_label = ttk.Label(shoppinglist_frame, text=self.i18n.treeExpiration + "\n(DD-MM-YYYY)") expiration_label.grid(column=3, row=0) volumes = [] measurements = [] expirations = [] for n in shoppinglist: item = ttk.Label(shoppinglist_frame, text=str(n), font=self.fonts.FontHeader2) item.grid(column=0, row=shoppinglist.index(n) + 1, sticky="w") volume = ttk.Entry(shoppinglist_frame, width=20, font=self.fonts.FontHeader2) volume.grid(column=1, row=shoppinglist.index(n) + 1, sticky="w") volumes.append(volume) measurement = ttk.Entry(shoppinglist_frame, width=5, font=self.fonts.FontHeader2) measurement.grid(column=2, row=shoppinglist.index(n) + 1, sticky="w") measurements.append(measurement) expiration = ttk.Entry(shoppinglist_frame, width=10, font=self.fonts.FontHeader2) expiration.grid(column=3, row=shoppinglist.index(n) + 1, sticky="w") expirations.append(expiration) def show_shoppings(): db_shoppinglist = [] def check_list(): #This function checks if every item on shopping list is filled correctly #If not, then we can't send to inventory db r = True for n in range(0, len(shoppinglist)): if volumes[n].get() == "" or volumes[n].get() == "!!": volumes[n].delete(0, tk.END) volumes[n].insert(0, "!!") r = False if measurements[n].get() == "" or measurements[n].get( ) == "!!": measurements[n].delete(0, tk.END) measurements[n].insert(0, "!!") r = False if expirations[n].get() == "" or expirations[n].get( ) == "!!": expirations[n].delete(0, tk.END) expirations[n].insert(0, "!!") r = False return r test = check_list() if test == True: for n in range(0, len(shoppinglist)): self.sql.add_inventory(shoppinglist[n], volumes[n].get(), measurements[n].get(), expirations[n].get()) addbutton = tk.Button(addshopping, text=self.i18n.addshopping, command=show_shoppings) addbutton.grid(column=0, row=1) addbutton.after(1, lambda: addbutton.focus_force()) addshopping.mainloop()
class Functions(): def __init__(self, SP): self.sp = SP def _quit(self): #Function to nicely quit the program self.sp.win.quit() self.sp.win.destroy() exit() def get_time(self): #Function that gets the date global currentdate currentdate = '' currentnewdate = datetime.now() if currentnewdate.day != currentdate: currentdate = currentnewdate.day self.sp.date.config(text=str(currentnewdate.day) + "/" + str(currentnewdate.month)) self.sp.date.after(5000, self.get_time) def tick(self): # this function enables the clock to be updated global time1 time1 = '' time2 = time.strftime('%H:%M:%S') if time2 != time1: time1 = time2 self.sp.clock.config(text=time2) self.sp.clock.after(200, self.tick) def add_day(self, selected_recipe, selected_day, language): #this function adds the recipe to the selected day in the database from Resources import I18N self.i18n = I18N(language) days = (self.i18n.monday, self.i18n.tuesday, self.i18n.wednesday, self.i18n.thursday, self.i18n.friday, self.i18n.saturday, self.i18n.sunday) a = int(days.index(selected_day)) if (a == 0): self.sp.monday_recipe.config(text=selected_recipe) if (a == 1): self.sp.tuesday_recipe.config(text=selected_recipe) if (a == 2): self.sp.wednsday_recipe.config(text=selected_recipe) if (a == 3): self.sp.thursday_recipe.config(text=selected_recipe) if (a == 4): self.sp.friday_recipe.config(text=selected_recipe) if (a == 5): self.sp.saturday_recipe.config(text=selected_recipe) if (a == 6): self.sp.sunday_recipe.config(text=selected_recipe) def api_search(self, language): # This function calls the mealdb and adds the json object to the recipe database import requests from Resources import Fonts, I18N from PIL import Image, ImageTk self.fonts = Fonts() self.i18n = I18N(language) popup = tk.Toplevel() popup.winfo_class() popup.resizable(0, 0) popup.geometry("1050x520+200+200") popup.wm_title(self.i18n.recipeAPI) label = ttk.Label(popup, text=self.i18n.recipeAPIresult) response = requests.get("https://www.themealdb.com/api/json/v1/1/search.php?s="\ +str(self.sp.search)) recipe = response.json() recipe_dict = recipe["meals"][0] frame = ttk.LabelFrame(popup) frame.grid(column=0, row=0) label = ttk.Label(frame) label.grid(column=0, row=1) label.configure(text=recipe_dict["strMeal"], font=self.fonts.FontHeader2) self.recipe_ingredience = [] self.recipe_measurement = [] for x in range(1, 20): if (recipe_dict["strMeasure"+str(x)] == "None" \ or recipe_dict["strMeasure"+str(x)] == None \ or recipe_dict["strMeasure"+str(x)] == "" \ or recipe_dict["strMeasure"+str(x)] == " "): pass else: self.recipe_ingredience.append(recipe_dict["strIngredient" + str(x)]) self.recipe_measurement.append(recipe_dict["strMeasure" + str(x)]) self.recipe_ingredience = list(filter(None, self.recipe_ingredience)) self.recipe_measurement = list(filter(None, self.recipe_measurement)) self.recipe_picture = recipe_dict["strMealThumb"] self.recipe_instructions = recipe_dict["strInstructions"] self.ingrediences = scrolledtext.ScrolledText(frame, width=40) self.ingrediences.grid(column=0, row=2) dictst = { self.i18n.ing: self.recipe_ingredience, self.i18n.vol: self.recipe_measurement } from pandas import DataFrame as df data = df.from_dict(dictst) self.ingrediences.insert(tk.END, data) self.instructions = scrolledtext.ScrolledText(frame, width=40) self.instructions.grid(column=1, row=2) self.instructions.insert(tk.END, self.recipe_instructions) # RECIPE PICTURE pHeight = 322 pWidth = 322 import urllib.request from os import path url = self.recipe_picture fDir = path.dirname(__file__) urllib.request.urlretrieve( url, fDir + "/pictures/" + recipe_dict["strMeal"] + ".jpg") self.canvas = Canvas(frame) self.canvas.config(width=pWidth, height=pHeight, highlightthickness=0) self.canvas.grid(column=2, row=2, padx=8, pady=4) image = Image.open(fDir+"/pictures/"+recipe_dict["strMeal"]+".jpg") \ .resize((pHeight+10,pWidth+10),Image.ANTIALIAS) self.img = ImageTk.PhotoImage(image) self.canvas.create_image(0, 0, anchor='nw', image=self.img) def save_to_db(): self.sql.insert_recipe(recipename, str(ingrediences), str(measurements), instructions, picture) popup.destroy() B1 = tk.Button(frame, text=self.i18n.cancel, command=popup.destroy) B1.grid(column=0, row=4) B2 = tk.Button(frame, text=self.i18n.addtoDB, command=save_to_db) B2.grid(column=0, row=3) B2.config(font=self.fonts.FontHeader2) for child in frame.winfo_children(): child.grid_configure(sticky="w", padx=8, pady=4) from SqLite import SqLite self.sql = SqLite() recipename = recipe_dict["strMeal"] ingrediences = self.recipe_ingredience measurements = self.recipe_measurement instructions = self.recipe_instructions picture = fDir + "/pictures/" + recipe_dict["strMeal"] + ".jpg" B1.after(1, lambda: B1.focus_force()) popup.mainloop() def getFileName(self): from os import path from tkinter import filedialog as fd fDir = path.dirname(__file__) + "/pictures/" fName = fd.askopenfilename(initialdir=fDir) return fName def add_shopping_to_db(self, language, shoppinglist): from Resources import Fonts, I18N from SqLite import SqLite self.sql = SqLite() self.fonts = Fonts() self.i18n = I18N(language) addshopping = tk.Toplevel() addshopping.resizable(0, 0) #addshopping.geometry("550x520+200+200") addshopping.wm_title("Add shopping to db") frame = ttk.LabelFrame(addshopping) frame.grid(column=0, row=0) shoppinglist_frame = ttk.LabelFrame(addshopping) shoppinglist_frame.grid(column=0, row=0) item_label = ttk.Label(shoppinglist_frame, text=self.i18n.treeName) item_label.grid(column=0, row=0) volume_label = ttk.Label(shoppinglist_frame, text=self.i18n.treeVolume) volume_label.grid(column=1, row=0) measurement_label = ttk.Label(shoppinglist_frame, text=self.i18n.treeUnit) measurement_label.grid(column=2, row=0) expiration_label = ttk.Label(shoppinglist_frame, text=self.i18n.treeExpiration + "\n(DD-MM-YYYY)") expiration_label.grid(column=3, row=0) volumes = [] measurements = [] expirations = [] for n in shoppinglist: item = ttk.Label(shoppinglist_frame, text=str(n), font=self.fonts.FontHeader2) item.grid(column=0, row=shoppinglist.index(n) + 1, sticky="w") volume = ttk.Entry(shoppinglist_frame, width=20, font=self.fonts.FontHeader2) volume.grid(column=1, row=shoppinglist.index(n) + 1, sticky="w") volumes.append(volume) measurement = ttk.Entry(shoppinglist_frame, width=5, font=self.fonts.FontHeader2) measurement.grid(column=2, row=shoppinglist.index(n) + 1, sticky="w") measurements.append(measurement) expiration = ttk.Entry(shoppinglist_frame, width=10, font=self.fonts.FontHeader2) expiration.grid(column=3, row=shoppinglist.index(n) + 1, sticky="w") expirations.append(expiration) def show_shoppings(): db_shoppinglist = [] def check_list(): #This function checks if every item on shopping list is filled correctly #If not, then we can't send to inventory db r = True for n in range(0, len(shoppinglist)): if volumes[n].get() == "" or volumes[n].get() == "!!": volumes[n].delete(0, tk.END) volumes[n].insert(0, "!!") r = False if measurements[n].get() == "" or measurements[n].get( ) == "!!": measurements[n].delete(0, tk.END) measurements[n].insert(0, "!!") r = False if expirations[n].get() == "" or expirations[n].get( ) == "!!": expirations[n].delete(0, tk.END) expirations[n].insert(0, "!!") r = False return r test = check_list() if test == True: for n in range(0, len(shoppinglist)): self.sql.add_inventory(shoppinglist[n], volumes[n].get(), measurements[n].get(), expirations[n].get()) addbutton = tk.Button(addshopping, text=self.i18n.addshopping, command=show_shoppings) addbutton.grid(column=0, row=1) addbutton.after(1, lambda: addbutton.focus_force()) addshopping.mainloop() def get_temperature(self): # Get I2C bus bus = smbus.SMBus(1) time.sleep(0.3) try: bus.write_byte(0x40, 0xF3) except OSError: pass time.sleep(0.3) # SI7021 address, 0x40 Read data 2 bytes, Temperature data0 = bus.read_byte(0x40) data1 = bus.read_byte(0x40) # Convert the data and output it global celsTemp celsTemp = ((data0 * 256 + data1) * 175.72 / 65536.0) - 46.85 self.sp.temperature.config(text=str(int(celsTemp)) + "°C") self.sp.temperature.after( 200, lambda: threading.Thread(target=self.get_temperature, daemon=True).start()) #print("Temperature in Celsius is : %.2f C" %celsTemp) def swap_language(self): from Resources import I18N import configparser from tkinter import messagebox as mBox config = configparser.ConfigParser() config.read('config.ini') language = config['language']['language'] self.i18n = I18N(language) if language == "en": config['language']['language'] = "da" if language == "da": config['language']['language'] = "en" with open('config.ini', 'w') as configfile: config.write(configfile) mBox.showinfo(self.i18n.warning, self.i18n.reloadprogram)
def __init__(self, tabControl, win, language): # Instantiate the objects self.i18n = I18N(language) self.functions = Functions(self) self.fonts = Fonts() self.win = win self.sql = SqLite() # Creating the tab, adding it to the tabControl tabS = ttk.Frame(tabControl) tabControl.add(tabS, text=self.i18n.tabS) # Create the recpie_name for the dropdown menu self.recipe_name = StringVar(self.win) self.recipe_name.set(self.i18n.selectrecipe) def handle_focus_in(_): recipe_list = self.sql.select_recipes() # DROPDOWN MENU ADD select_recipe = OptionMenu(recipe_list_frame, self.recipe_name, *recipe_list) select_recipe.grid(column=0, row=0, padx=8, pady=4, sticky="W") # on change dropdown value def change_dropdown(*args): self.recipe_name.get() recipe_list = self.sql.select_recipes() # link function to change dropdown self.recipe_name.trace('w', change_dropdown) def get_recipe_name(): self.selected_recipe = self.recipe_name.get() show_selected_recipe(self.selected_recipe) def show_selected_recipe(recipe_name): #Create treeview for recipe import ast import re recipe = self.sql.show_recipe(recipe_name) recipe_ingredient_name = ast.literal_eval(recipe[0][4]) recipe_ingredient_vol = ast.literal_eval(recipe[0][5]) # The recipe ingrediences needs to be formattet into two lists, one for the volumes, # and one for the measurements. This is because the api for the recipes has strange # formats. vol = [] mea = [] # Going through the list of measurements checking for a number, else append 1 for x in range(0, len(recipe_ingredient_vol)): try: a = re.search("\d*\.\d+|\d+", recipe_ingredient_vol[x]) a = a.group() vol.append(a) except AttributeError: a = 1 vol.append(a) try: b = re.search("[a-zA-Z ]+", recipe_ingredient_vol[x]) b = b.group() mea.append(b) except: b = "stk" mea.append(b) # Create a treeview for the recipe ingrediences tree = ttk.Treeview(recipe_list_frame, height=15) tree.grid(column=0, row=1, rowspan=30, columnspan=3, padx=10, sticky="n") tree.config(selectmode='browse') # Setup treeframe columns tree["columns"] = ("one", "two") tree.column("#0", width=200, stretch=False) tree.heading("#0", text=self.i18n.treeName, anchor="w") tree.column("one", width=50, stretch=False) tree.heading("one", text=self.i18n.treeVolume, anchor="w") tree.column("two", width=150, stretch=False) tree.heading("two", text=self.i18n.treeUnit, anchor="w") # Insert data into treeframe for n in range(0, len(recipe_ingredient_name)): tree.insert("", 0, n, text= recipe_ingredient_name[n],\ values = (vol[n],mea[n])) # Enable treeview to be edited def set_cell_value(event): # Double click to enter the edit state try: for item in tree.selection(): item_text = tree.item(item, "values") #print(item_text[0:2]) # Output the value of the selected row column = tree.identify_column(event.x) # column row = tree.identify_row(event.y) #row #Placing the textbox cn = int(str(column).replace('#', '')) rn = tree.index(tree.selection()) if cn == 1: x_pos = 200 if cn == 2: x_pos = 250 if cn == 3: x_pos = 290 entryedit = Text(recipe_list_frame, width=10, height=1) entryedit.config(wrap='none') entryedit.place(x=x_pos, y=65 + rn * 20) entryedit.insert(0.0, item_text[cn - 1:cn]) entryedit.focus_force() # The new value will be saved when the Return button is pressed def saveedit(event): newvalue = entryedit.get(0.0, "end").strip() tree.set(item, column=column, value=newvalue) #set value in db names = tree.get_children() #Build list to be sent to db ingrediences = [] for n in names: values = tree.item(n, "values") ingrediences.append(values[0] + " " + values[1]) #Update the recipe measurements in db self.sql.update_recipe_measurement( recipe_name, ingrediences) entryedit.destroy() entryedit.bind('<Return>', saveedit) except UnboundLocalError: pass recipe_instructions = scrolledtext.ScrolledText(recipe_list_frame, width=60, height=20, wrap=tk.WORD) recipe_instructions.grid(column=4, row=1) recipe_instructions.delete('1.0', tk.END) recipe_instructions.insert(tk.END, recipe[0][2]) def save_instructions(): instructions = recipe_instructions.get(0.0, tk.END) self.sql.update_recipe_instructions(recipe_name, instructions) recipe_instructions_save = tk.Button(recipe_list_frame, text=self.i18n.save, command=save_instructions) recipe_instructions_save.grid(column=4, row=0, sticky="w") def browse_file(): pHeight = 322 pWidth = 322 self.recipepic = self.functions.getFileName() image = Image.open(self.recipepic).resize( (pHeight + 10, pWidth + 10), Image.ANTIALIAS) self.img = ImageTk.PhotoImage(image) canvas.create_image(0, 0, anchor='nw', image=self.img) def save_picture(): try: self.sql.update_recipe_picture(recipe_name, self.recipepic) except AttributeError: pass #Browse to a new picture browse_new_pic = tk.Button(recipe_list_frame, text=self.i18n.findPicture, command=browse_file) browse_new_pic.grid(column=5, row=0, sticky="w") save_new_pic = tk.Button(recipe_list_frame, text=self.i18n.savePic, command=save_picture) save_new_pic.grid(column=6, row=0, sticky="e") pHeight = 322 pWidth = 322 canvas = Canvas(recipe_list_frame) canvas.config(width=pWidth, height=pHeight, highlightthickness=0) canvas.grid(column=5, row=1, columnspan=2) image = Image.open(recipe[0][3]) \ .resize((pWidth+10,pHeight+10),Image.ANTIALIAS) self.img = ImageTk.PhotoImage(image) canvas.create_image(0, 0, anchor='nw', image=self.img) tree.bind('<Double-1>', set_cell_value) recipe_list_label = ttk.Label(tabS, text=self.i18n.tabS, font=self.fonts.FontHeader2) recipe_list_frame = ttk.LabelFrame(tabS, labelwidget=recipe_list_label) recipe_list_frame.grid(column=0, row=0, sticky="w", columnspan=5) get_recipe_button = tk.Button(recipe_list_frame, text=self.i18n.search, command=get_recipe_name) get_recipe_button.grid(column=1, row=0, sticky='W', padx=8, pady=4) tabS.bind("<FocusIn>", handle_focus_in)
def __init__(self, tabControl, win, language): # Instantiate the objects self.i18n = I18N(language) self.functions = Functions(self) self.fonts = Fonts() self.win = win self.sql = SqLite() # Creating the tab, adding it to the tabControl tabC = ttk.Frame(tabControl) tabControl.add(tabC, text=self.i18n.tabC) # Creating the labelframe for the tab self.myFridge_label = ttk.Label(tabC, text=self.i18n.myFridge, font=self.fonts.FontHeader) self.myFridge = ttk.LabelFrame(tabC, labelwidget=self.myFridge_label) self.myFridge.grid(column=0, row=0) # Makeing a treeview for the fridge inventory. tree = ttk.Treeview(self.myFridge, height=40) tree.grid(column=0, row=0, rowspan=50, padx=10, columnspan=2) tree.config(selectmode='browse') tree["columns"] = ("one", "two", "three") tree.column("#0", width=200, stretch=False) tree.heading("#0", text=self.i18n.treeName, anchor="w") tree.column("one", width=50, stretch=False) tree.heading("one", text=self.i18n.treeVolume, anchor="w") tree.column("two", width=40, stretch=False) tree.heading("two", text=self.i18n.treeUnit, anchor="w") tree.column("three", width=80, stretch=False) tree.heading("three", text=self.i18n.treeExpiration, anchor="w") def handle_focus_in(_): # Collect what we have in the inventory try: inventory = self.sql.select_inventory() for n in inventory: tree.insert("", 0, n[0], text=n[0], values=((n)[1], n[2], n[3])) except IndexError: pass # This function enables the tree to be edited. # But this is only for the values, not the name def set_cell_value(event): # Double click to enter the edit state try: for item in tree.selection(): item_text = tree.item(item, "values") #print(item_text[0:2]) # Output the value of the selected row column = tree.identify_column(event.x) # column row = tree.identify_row(event.y) #row #Placing the textbox cn = int(str(column).replace('#', '')) rn = tree.index(tree.selection()) if cn == 1: x_pos = 200 if cn == 2: x_pos = 250 if cn == 3: x_pos = 290 entryedit = Text(self.myFridge, width=10, height=1) entryedit.config(wrap='none') entryedit.place(x=x_pos, y=20 + rn * 20) entryedit.insert(0.0, item_text[cn - 1:cn]) entryedit.focus_force() # The new value will be saved when the Return button is pressed def saveedit(event): newvalue = entryedit.get(0.0, "end").strip() tree.set(item, column=column, value=newvalue) #set value in db name = tree.item(item, "text") values = tree.item(item, "values") self.sql.update_inventory(name, values[0], values[1], values[2]) entryedit.destroy() entryedit.bind('<Return>', saveedit) except UnboundLocalError: pass def selectItem(event): curItem = tree.focus() selected_item = tree.item(curItem, "text") # Bind the function to a double click on a cell tree.bind('<Double-1>', set_cell_value) tree.bind('<ButtonRelease-1>', selectItem) # This function deletes the desired item from the database and treeview def del_from_db(): try: curItem = tree.focus() selected_item = tree.item(curItem, "text") self.sql.delete_inventory(selected_item) tree.delete(selected_item) except: pass # This function adds the item to the database and treeview def add_to_db(): try: new_item = entry_name.get(0.0, "end").strip() tree.insert("", 'end', new_item, text=new_item, values=(0, 0, 0)) self.sql.add_inventory(new_item, 0, 0, 0) except: pass tabC.bind("<FocusIn>", handle_focus_in) # Label and text box to add or delete item in database. entry_label = ttk.Label(self.myFridge, text=self.i18n.addNewItem) entry_label.grid(column=2, row=0, sticky="w") entry_name = Text(self.myFridge, width=20, height=1) entry_name.config(wrap='none') entry_name.grid(column=2, row=1, sticky="w") add_button = tk.Button(self.myFridge, text=self.i18n.addNewItem, command=add_to_db) add_button.grid(column=2, row=2, sticky="w") del_button = tk.Button(self.myFridge, text=self.i18n.deleteItem, command=del_from_db) del_button.grid(column=2, row=3, sticky="w") # Initiate the calnderFrame by providing the tab name and the language. from calendarFrame import CalendarFrame self.calendar = CalendarFrame(tabC, language)