from Tkinter import * import urllib import time # Save the number of times the client has visited this page during the # current Grail session. We don't want to reveal the secret the first # time they view it. try: been_here = been_here + 0 except NameError: been_here = 0 visit_times = [] def cardinalize(n): suffixes = ['st', 'nd', 'rd'] tens = n % 100 if tens >= 10 and tens < 20: suffix = 'th' else: try: suffix = suffixes[n % 10] except IndexError: suffix = 'th' return "%d%s" % (n+1, suffix) def record_time(): t = time.time() s = time.ctime(t) c = cardinalize(been_here) msg = "You visited this page for the %s time at %s.\n" % (c, s) visit_times.append(msg) def inject_text(textwidget): global been_here global visit_times # This is a horrible and ugly hack. At this time in the Viewer's # lifecycle, the text widget is frozen and does not allow us to # insert text into it. We save the state, toggle it to normal # (i.e. unfreeze it) and insert the text. Then we revert the # state back to it's previous value (could have been unfrozen to # begin with). We really should use a higher level hook on the # Viewer object instead of doing it this way. savestate = textwidget['state'] textwidget['state'] = NORMAL # It would be great if we could inject HTML into the grail_parser # so that we could dynamically add new hypertext onto the viewed # page. E.g. I'd like people to be able to download the applet # source by clicking on a link, instead of using a button as I'm # currently forced to do. Injecting HTML into the current page # isn't defined yet. textwidget.insert('end', "\n\nHere's a record of the times at \ which you visited this page. Keep revisiting it by clicking on the \ `Reload' button under the `Go' menu, or by clicking on the `Revisit' \ button below.\n\n") for msg in visit_times: textwidget.insert('end', msg) # restore the text widget's state textwidget['state'] = savestate # Top level applet class class RevealSecret: def __init__(self, master): global been_here record_time() # remember some useful thingies self.master = master self.text = master.grail_viewer.text self.browser = master.grail_browser self.context = master.grail_context # create a subframe of the master frame = Frame(master) frame.pack(side=BOTTOM) # don't reveal the secret the first time if been_here > 0: inject_text(self.text) # I wish I didn't need to use a button to do this... revisitbtn = Button(frame, text="Revisit This Page", command=self.revisit) revisitbtn.pack(side=LEFT) viewbtn = Button(frame, text='View Applet Source', command=self.view) viewbtn.pack(side=LEFT) resetbtn = Button(frame, text="Reset Page Visit Counter", command=self.reset) resetbtn.pack(side=LEFT) ## label = Label(frame, text='been here %d times' % been_here) ## label.pack(side=LEFT) else: revealbtn = Button(frame, text="Revisit This Page and Reveal the Secret", command=self.revisit) revealbtn.pack(side=LEFT) frame.pack(side=BOTTOM) # increment global counter been_here = been_here + 1 def view(self): url = self.context.get_baseurl() self.context.load(urllib.basejoin(url, 'reveal.py')) def revisit(self): self.browser.reload_command() def reset(self): global been_here global visit_times # reset the state of these values and trigger a reload been_here = 0 visit_times = [] self.browser.reload_command()