From 0a27c6f63161e6378f7137c3f43251bc67ca27b1 Mon Sep 17 00:00:00 2001 From: Jakob Cornell Date: Sat, 4 Jan 2020 01:23:12 -0600 Subject: [PATCH] Add Gmail table bookmarklet generation --- main.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index e63d623..577a633 100644 --- a/main.py +++ b/main.py @@ -141,6 +141,35 @@ class MainModel(Model): self.view.set_student(name) +def get_table_bookmarklet(records): + import html + + rows = [ + ['' if v is None else str(v) for v in r] for r in records + ] + table_html = ( + '' + + '' + + ''.join('' for h in DataEditModel.Record.DISPLAY_NAMES) + + '' + + '' + + ''.join( + '' + + ''.join('' for v in row) + + '' + for row in rows + ) + + '' + + '
' + html.escape(h) + '
' + v + '
' + ) + assert "'" not in table_html + js_table_literal = "'{}'".format(table_html) + return ( + 'javascript:function(){document.querySelector(\'[contenteditable=\\\'true\\\']\')' + + '.innerHTML+=\'
\'+' + js_table_literal + '+\'
\';}()' + ) + + class MainView(View): @contextmanager def no_propagate(self, key): @@ -243,12 +272,26 @@ class MainView(View): center_on_parent(dialog, self.root) self.gen_plot_btn = ttk.Button(actions_frame, text = "Generate plot", command = on_gen_plot) + def on_gen_table(): + name = self.controller.state['student'] + command = get_table_bookmarklet(self.controller.data[name]) + self.root.clipboard_clear() + self.root.clipboard_append(command) + messagebox.showinfo( + "Table Command Copied", + "In Gmail, make sure you have a new message box open," + + " then paste the command into the address bar and press Enter." + , + ) + self.gen_table_btn = ttk.Button(actions_frame, text = "Generate Gmail table", command = on_gen_table) + self.student_sel.pack(**TK_PAD, side = tk.LEFT) add_student_btn.pack(**TK_PAD, side = tk.LEFT) self.del_student_btn.pack(**TK_PAD, side = tk.LEFT) self.student_frame.pack(**TK_PAD, fill = tk.X) self.edit_data_btn.pack(**TK_PAD, fill = tk.X) self.gen_plot_btn.pack(**TK_PAD, fill = tk.X) + self.gen_table_btn.pack(**TK_PAD, fill = tk.X) actions_frame.pack(**TK_PAD, fill = tk.X) self.editor_views = {} @@ -266,6 +309,7 @@ class MainView(View): self.del_student_btn, self.edit_data_btn, self.gen_plot_btn, + self.gen_table_btn, ] for control in students_only: control.configure(state = state) @@ -306,6 +350,12 @@ class DataEditModel(Model): 's_time', ]) class Record(_Record): + DISPLAY_NAMES = [ + "Comment", + "Score (E)", "Score (M)", "Score (R)", "Score (S)", + "Time (E)", "Time (M)", "Time (R)", "Time (S)", + ] + @classmethod def parse(class_, strings): if len(strings) != len(class_._fields): @@ -375,12 +425,8 @@ class DataEditView(View): cancel_btn.pack(side = 'left', **TK_PAD) buttons.pack() - col_names = [ - "Comment", - "Score (E)", "Score (M)", "Score (R)", "Score (S)", - "Time (E)", "Time (M)", "Time (R)", "Time (S)", - ] - labels = [tk.Label(self.grid, text = name, width = 10) for name in col_names] + label_for = lambda name: tk.Label(self.grid, text = name, width = 10) + labels = list(map(label_for, DataEditModel.Record.DISPLAY_NAMES)) for (col, label) in enumerate(labels): label.grid(row = 0, column = col) self.rows = OrderedDict() -- 2.30.2