Roundup Tracker

Attachment 'msgfile.py'

Download

   1 from roundup.date import Interval, Date
   2 
   3 def join(lol):
   4     '''Flattens a list of lists into a list'''
   5     if lol == []:
   6         return []
   7     return reduce(lambda x,y: x+y, lol)
   8 
   9 def msgfile_reactor(db, cl, issue_id, oldvals):
  10     '''Ensure that each file is always connected to a message
  11     '''
  12 
  13 
  14     #
  15     # Figure out which files and messages have been added
  16     #
  17     messages = cl.get(issue_id, "messages")
  18     files = cl.get(issue_id, "files")
  19     if oldvals and oldvals.has_key("files"):
  20         added_files = [id for id in files if not id in oldvals["files"]]
  21     elif not oldvals:
  22         added_files = files
  23     else:
  24         added_files = []
  25 
  26     if oldvals and oldvals.has_key("messages"):
  27         added_msgs =   [id for id in messages if not id in oldvals["messages"]]
  28         removed_msgs = [id for id in oldvals["messages"] if not id in messages]
  29     elif not oldvals:
  30         added_msgs = messages
  31         removed_msgs = []
  32     else:
  33         added_msgs = []
  34         removed_msgs = []
  35 
  36 
  37     #
  38     # Make sure that each file is attached to a message
  39     #
  40 
  41     # Workaround for the web frontend (which allows only
  42     # one file per message):
  43     # If the user attaches only one file and no message and
  44     # the last message is from the same user and less than
  45     # 5 minutes old, we attach the new file to that message.
  46     if added_msgs == [] and messages != None and \
  47             len(messages) > 0 and len(added_files) == 1 and \
  48             (Date(".") - db.msg.get(messages[-1], "date")) < Interval("0:05"):
  49         db.msg.set(messages[-1], files=db.msg.get(messages[-1], "files")+added_files)
  50 
  51     # Otherwise we create a new message and attach all files
  52     # without message to that new message
  53     else:
  54         referenced = join([db.msg.get(id, "files") for id in added_msgs])
  55         to_add = [id for id in added_files if not id in referenced]
  56         if to_add:
  57             msg = db.msg.create(
  58                 author = db.file.get(to_add[0], "creator"),
  59                 date = db.file.get(to_add[0], "creation"),
  60                 content = "[attached files]",
  61                 files = to_add)
  62             messages.append(msg)
  63             cl.set(issue_id, messages=messages)
  64 
  65 
  66     #
  67     # If a message has been detached, detach its files as well
  68     #
  69     for msg_id in removed_msgs:
  70         for file_id in db.msg.get(msg_id, "files"):
  71             files.remove(file_id)
  72 
  73 
  74             # The following code physically removes the file,
  75             # if no other messages refer to it
  76             #if len(db.msg.find(files=file_id)) == 1:
  77             #    db.file.destroy(file_id)
  78 
  79         # Optionally we also physically remove the message,
  80         # if it is not attached to any other issue
  81         if not cl.find(messages=msg_id):
  82             pass
  83             #db.msg.destroy(msg_id)
  84 
  85     if files != cl.get(issue_id, "files"):
  86         cl.set(issue_id, files=files)
  87 
  88 
  89 
  90 def msgfile_auditor(db, cl, issue_id, newdata):
  91     '''Do not allow direct removal of a file without its message
  92     '''
  93 
  94     if newdata.has_key("files") and issue_id:
  95         if newdata.has_key("messages"):
  96             messages = newdata["messages"]
  97         else:
  98             messages = cl.get(issue_id, "messages")
  99 
 100         files = cl.get(issue_id, "files")
 101         if newdata["files"]:
 102             removed_files = [id for id in files if not id in newdata["files"]]
 103         else:
 104             removed_files = files
 105         referenced = join([db.msg.get(id, "files") for id in messages])
 106 
 107         for file_id in removed_files:
 108             if file_id in referenced:
 109                 raise ValueError, "Cannot remove file alone - remove message instead."
 110 
 111 
 112 
 113 def init(db):
 114     db.issue.react('set', msgfile_reactor)
 115     db.issue.react('create', msgfile_reactor)
 116     db.issue.audit('set', msgfile_auditor)
 117 
 118 # vim: set filetype=python ts=4 sw=4 et si

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2010-04-24 15:39:29, 8.0 KB) [[attachment:issue.item.html.diff]]
  • [get | view] (2010-04-24 15:34:13, 3.8 KB) [[attachment:msgfile.py]]
  • [get | view] (2010-04-24 15:34:23, 115.3 KB) [[attachment:msgfile_after.png]]
  • [get | view] (2010-04-24 15:34:35, 132.7 KB) [[attachment:msgfile_before.png]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.