Add Gmail table bookmarklet generation
authorJakob Cornell <jakob@jcornell.net>
Sat, 4 Jan 2020 07:23:12 +0000 (01:23 -0600)
committerJakob Cornell <jakob@jcornell.net>
Sat, 4 Jan 2020 07:23:12 +0000 (01:23 -0600)
main.py

diff --git a/main.py b/main.py
index e63d62322c466cbd45ab9573b7b832f564066e0c..577a6333e13f2a7e9a66a85d6de3cfb10f4dcb2c 100644 (file)
--- 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 = (
+               '<table style="border:1px solid black;">'
+               + '<thead>'
+               + ''.join('<th>' + html.escape(h) + '</th>' for h in DataEditModel.Record.DISPLAY_NAMES)
+               + '</thead>'
+               + '<tbody>'
+               + ''.join(
+                       '<tr>'
+                       + ''.join('<td>' + v + '</td>' for v in row)
+                       + '</tr>'
+                       for row in rows
+               )
+               + '</tbody>'
+               + '</table>'
+       )
+       assert "'" not in table_html
+       js_table_literal = "'{}'".format(table_html)
+       return (
+               'javascript:function(){document.querySelector(\'[contenteditable=\\\'true\\\']\')'
+               + '.innerHTML+=\'<br/>\'+' + js_table_literal + '+\'<br/>\';}()'
+       )
+
+
 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()