1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - Check the speed of page editing 4 5 Check to see how quickly the user wanted to edit a page after previous 6 actions. Prevent them from saving a page if they were too fast. 7 8 @copyright: 2016 Paul Boddie <paul@boddie.org.uk> 9 @license: GNU GPL, see COPYING for details. 10 """ 11 12 from MoinMoin.events import PagePreSaveEvent, Abort 13 from MoinMoin.logfile.eventlog import EventLog 14 from MoinMoin import wikiutil 15 import time 16 17 # The default editing delay where no configuration setting has been provided. 18 # Value expressed in seconds. 19 20 editing_delay_default = "10" 21 22 # Event handling. 23 24 def handle_presave(event): 25 request = event.request 26 _ = request.getText 27 28 # Obtain user details. If no user is identified, nothing can be done. 29 30 username = request.user.name 31 if not username: 32 return None 33 34 # Obtain the required delay between viewing and editing. This is expressed 35 # in seconds. 36 37 delay = float(getattr(request.cfg, "editing_delay", editing_delay_default)) 38 39 # Obtain the current time. 40 41 time_now = time.time() 42 43 # Check in the log for the last action by the user. This requires the 44 # recording of the username in the log. 45 46 log = EventLog(request) 47 log.set_filter(["VIEWPAGE", "SAVEPAGE", "SAVENEW"]) 48 49 pagename = event.page_editor.page_name 50 last_viewed = None 51 last_saved = None 52 53 for event in log.reverse(): 54 event_usecs, event_type, event_attr = event[:3] 55 56 # Convert to seconds and determine if the start of the delay period has 57 # been reached. 58 59 event_secs = wikiutil.version2timestamp(event_usecs) 60 if time_now - event_secs >= delay: 61 break 62 63 event_page = event_attr.get("pagename") 64 event_user = event_attr.get("username") 65 66 # Stop when encountering the latest event entry for this page and user. 67 68 if event_page == pagename and event_user == username: 69 if event_type == "VIEWPAGE": 70 last_viewed = event_secs 71 else: 72 last_saved = event_secs 73 break 74 75 # Any attempt to save occurring too soon after VIEWPAGE is possibly an 76 # automated edit. 77 78 if last_viewed: 79 return Abort(_("Page not changed: the page was saved too quickly after viewing.")) 80 81 # Any attempt to save without any previous VIEWPAGE, but after a SAVENEW or 82 # SAVEPAGE may also be an automated edit. 83 84 elif last_saved: 85 return Abort(_("Page not changed: the page was saved again too soon or saved without viewing the page.")) 86 87 return None 88 89 def handle(event): 90 if isinstance(event, PagePreSaveEvent): 91 return handle_presave(event) 92 93 # vim: tabstop=4 expandtab shiftwidth=4