attribution_report/main.py

226 lines
8.4 KiB
Python
Raw Normal View History

2015-07-17 20:17:15 +00:00
from attribution import AttributionReport
2015-07-17 18:18:20 +00:00
__author__ = 'tsouza'
import Tkinter as tk
2015-07-20 16:23:44 +00:00
from ttk import Progressbar
2015-07-17 18:18:20 +00:00
import tkFileDialog
2015-07-17 20:17:15 +00:00
import tkMessageBox
2015-07-20 16:23:44 +00:00
from utils import get_dropbox_dir, ThreadedTask
import Queue
2015-07-17 18:18:20 +00:00
class AttributeGUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
2015-07-17 20:17:15 +00:00
self.salesforce_filename = None
self.deposit_filename = None
self.output_directoryname = None
self.defaults = {
'sf_label': u"<SalesForce Export File...>",
'dp_label': u"<Deposit Export File...>",
'output_label': u"<Output directory...>"
}
2015-07-20 16:23:44 +00:00
self.initGUI()
2015-07-17 20:50:29 +00:00
self.reset()
2015-07-17 20:17:15 +00:00
2015-07-17 20:50:29 +00:00
def reset(self):
2015-07-17 20:17:15 +00:00
self.report = AttributionReport(months=6, footer_length=6) # TODO MAKE MONTHS A DROPDOWN
2015-07-20 16:23:44 +00:00
self.input_frame.sf_label_var.set(self.defaults['sf_label'])
self.input_frame.dp_label_var.set(self.defaults['dp_label'])
self.output_frame.output_label_var.set(self.defaults['output_label'])
self.run_frame.run_button.config(text="Run")
2015-07-17 20:50:29 +00:00
self._check_ready_to_run()
2015-07-17 18:18:20 +00:00
2015-07-17 20:17:15 +00:00
def initGUI(self):
2015-07-17 18:18:20 +00:00
self.title('Attribution Report')
self.grid()
2015-07-17 18:40:11 +00:00
self.minsize(width=300, height=200)
# Input
2015-07-17 18:18:20 +00:00
self.input_frame = self.setup_input_frame()
2015-07-17 18:40:11 +00:00
self.input_frame.grid(row=0, column=0)
self.rowconfigure(0, weight=0)
# Output
2015-07-17 18:18:20 +00:00
self.output_frame = self.setup_output_frame()
2015-07-17 18:40:11 +00:00
self.output_frame.grid(row=1, column=0)
self.rowconfigure(1, weight=0)
# Run
2015-07-17 18:18:20 +00:00
self.run_frame = self.setup_run_frame()
2015-07-17 18:40:11 +00:00
self.run_frame.grid(row=2, column=0)
self.rowconfigure(2, weight=0)
2015-07-17 18:18:20 +00:00
2015-07-20 16:23:44 +00:00
# Progress bar
self.progress_bar = Progressbar(self, mode="indeterminate")
self.progress_bar.grid(column=0, row=3)
2015-07-17 18:18:20 +00:00
self.update()
2015-07-17 18:40:11 +00:00
self.minsize(self.winfo_width(), self.winfo_height())
self.resizable(True, False)
2015-07-17 18:18:20 +00:00
2015-07-20 16:23:44 +00:00
# ___ ___ _ __ __ ___ ___
# | __| _ \ /_\ | \/ | __/ __|
# | _|| / / _ \| |\/| | _|\__ \
# |_| |_|_\/_/ \_\_| |_|___|___/
2015-07-17 18:18:20 +00:00
def setup_input_frame(self):
input_frame = tk.LabelFrame(text="Input Files")
input_frame.grid()
row = 0
2015-07-20 16:23:44 +00:00
input_frame.sf_button = tk.Button(input_frame, text=u"Browse", command=self.callback_sf_browse_click)
2015-07-17 18:18:20 +00:00
input_frame.sf_button.grid(column=0, row=row)
input_frame.sf_label_var = tk.StringVar()
input_frame.sf_label = tk.Label(input_frame,
textvariable=input_frame.sf_label_var,
anchor="w")
input_frame.sf_label.grid(column=1, row=row, sticky='nsew')
2015-07-17 20:17:15 +00:00
input_frame.sf_label_var.set(self.defaults['sf_label'])
2015-07-17 18:18:20 +00:00
row += 1
2015-07-20 16:23:44 +00:00
input_frame.dp_button = tk.Button(input_frame, text=u"Browse", command=self.callback_dp_browse_click)
2015-07-17 18:18:20 +00:00
input_frame.dp_button.grid(column=0, row=row)
input_frame.dp_label_var = tk.StringVar()
input_frame.dp_label = tk.Label(input_frame,
textvariable=input_frame.dp_label_var,
anchor="w")
input_frame.dp_label.grid(column=1, row=row, sticky='nsew')
2015-07-17 20:17:15 +00:00
input_frame.dp_label_var.set(self.defaults['dp_label'])
2015-07-17 18:18:20 +00:00
input_frame.grid_columnconfigure(1, weight=1)
return input_frame
def setup_output_frame(self):
output_frame = tk.LabelFrame(text="Output Directory")
output_frame.grid()
row = 0
2015-07-20 16:23:44 +00:00
output_frame.output_button = tk.Button(output_frame, text=u"Browse", command=self.callback_output_browse_click)
2015-07-17 18:18:20 +00:00
output_frame.output_button.grid(column=0, row=row)
output_frame.output_label_var = tk.StringVar()
output_frame.sf_label = tk.Label(output_frame,
textvariable=output_frame.output_label_var,
anchor="w")
output_frame.sf_label.grid(column=1, row=row, sticky='nsew')
2015-07-17 20:17:15 +00:00
output_frame.output_label_var.set(self.defaults['output_label'])
2015-07-17 18:18:20 +00:00
output_frame.grid_columnconfigure(0, weight=1)
return output_frame
def setup_run_frame(self):
run_frame = tk.LabelFrame(text="Output Directory")
run_frame.grid()
row = 0
2015-07-20 16:23:44 +00:00
run_frame.run_button = tk.Button(run_frame, text=u"Run", command=self.callback_run_click)
2015-07-17 18:18:20 +00:00
run_frame.run_button.grid(column=0, row=row)
2015-07-20 16:23:44 +00:00
2015-07-17 18:18:20 +00:00
run_frame.grid_columnconfigure(0, weight=1)
return run_frame
2015-07-20 16:23:44 +00:00
# ___ _ _ _ ___ _ ___ _ _____
# / __| /_\ | | | | | _ ) /_\ / __| |/ / __|
# | (__ / _ \| |__| |__| _ \/ _ \ (__| ' <\__ \
# \___/_/ \_\____|____|___/_/ \_\___|_|\_\___/
def callback_sf_browse_click(self):
2015-07-17 20:17:15 +00:00
self.salesforce_filename = tkFileDialog.askopenfilename(
title="Salesforce Export File",
initialdir=get_dropbox_dir(),
filetypes=(
2015-07-17 20:53:06 +00:00
("Excel", "*.csv"),
2015-07-17 20:17:15 +00:00
("Excel", "*.xls"),
("Excel", "*.xlsx"),
)
)
if self.salesforce_filename:
df_parse_successful = self.report.set_dataframe_sf(self.salesforce_filename)
if df_parse_successful:
self.input_frame.sf_label_var.set(self.salesforce_filename)
else:
self.input_frame.sf_label_var.set(self.defaults['sf_label'])
tkMessageBox.showerror(
"Column Mismatch",
("At a minimum, the Salesforce file must have the following columns:\n\n"
"{0}\n\n"
"Please re-run and select a proper file.".format(", ".join(self.report.REQUIRED_SF_COLUMNS))
)
)
self._check_ready_to_run()
2015-07-17 18:40:11 +00:00
2015-07-20 16:23:44 +00:00
def callback_dp_browse_click(self):
2015-07-17 20:17:15 +00:00
self.deposit_filename = tkFileDialog.askopenfilename(
title="Deposit Data Export File",
initialdir=get_dropbox_dir(),
filetypes=(
2015-07-17 20:53:06 +00:00
("Excel", "*.csv"),
2015-07-17 20:17:15 +00:00
("Excel", "*.xls"),
("Excel", "*.xlsx"),
)
)
if self.deposit_filename:
df_parse_successful = self.report.set_dataframe_deposit(self.deposit_filename)
if df_parse_successful:
self.input_frame.dp_label_var.set(self.deposit_filename)
else:
self.input_frame.dp_label_var.set(self.defaults['dp_label'])
tkMessageBox.showerror(
"Column Mismatch",
"At a minimum, the Deposit Data file must have the following columns:\n\n"
"{0}\n\n"
"Please re-run and select a proper file.".format(
",\n".join(self.report.REQUIRED_DP_COLUMNS)))
self._check_ready_to_run()
2015-07-17 18:40:11 +00:00
2015-07-20 16:23:44 +00:00
def callback_output_browse_click(self):
2015-07-17 20:17:15 +00:00
self.output_directoryname = tkFileDialog.askdirectory(
initialdir=get_dropbox_dir(),
)
if self.output_directoryname:
2015-07-17 20:50:29 +00:00
self.report.set_output_dir(self.output_directoryname)
2015-07-17 20:17:15 +00:00
self.output_frame.output_label_var.set(self.output_directoryname)
self._check_ready_to_run()
2015-07-20 16:23:44 +00:00
def callback_run_click(self):
"""
When you click run, the progress bar and button notify you that something is happening.
This then starts a thread that sets the report Running and report Saving.
"""
self.progress_bar.start()
self.run_frame.run_button.config(text="Running...")
self.queue = Queue.Queue()
ThreadedTask(self.queue, self.report).start()
self.after(100, self._process_queue)
2015-07-17 20:17:15 +00:00
def _check_ready_to_run(self):
2015-07-20 16:23:44 +00:00
"""
Disables and re-enables the Run button when criteria is met.
"""
if self.report.salesforce_df is not None \
and self.report.deposit_df is not None \
and self.report.output_dir:
2015-07-17 20:50:29 +00:00
self.run_frame.run_button.config(state=tk.NORMAL)
else:
self.run_frame.run_button.config(state=tk.DISABLED)
self.update()
2015-07-17 18:40:11 +00:00
2015-07-20 16:23:44 +00:00
def _process_queue(self):
"""
Multi-threading the running stuff so that the UI doesn't lock.
"""
2015-07-17 20:50:29 +00:00
try:
2015-07-20 16:23:44 +00:00
self.queue.get(0)
# Show result of the task if needed
self.progress_bar.stop()
self.reset()
except Queue.Empty:
self.after(100, self._process_queue)
2015-07-17 18:18:20 +00:00
def main():
app = AttributeGUI()
app.mainloop()
2015-07-17 18:40:11 +00:00
2015-07-17 18:18:20 +00:00
if __name__ == "__main__":
main()