Commits

Anonymous committed 5d476ee

[svn r12168] XmlRpcPlugin: Trac 0.13+/1.0+ changes timestamps for ticket updates. Added compat code. Fixes #9921.

Comments (0)

Files changed (2)

trunk/tracrpc/tests/ticket.py

     def test_update_time_changed(self):
         # Update with collision check
         import datetime
-        from tracrpc.xml_rpc import from_xmlrpc_datetime, to_xmlrpc_datetime
+        from tracrpc.util import to_utimestamp
+        from tracrpc.xml_rpc import from_xmlrpc_datetime
         tid = self.admin.ticket.create('test_update_time_changed', '...', {})
         tid, created, modified, attrs = self.admin.ticket.get(tid)
         then = from_xmlrpc_datetime(modified) - datetime.timedelta(minutes=1)
         # Unrestricted old-style update (to be removed soon)
         try:
             self.admin.ticket.update(tid, "comment1",
-                    {'_ts': to_xmlrpc_datetime(then)})
+                    {'_ts': str(to_utimestamp(then))})
         except Exception, e:
             self.assertTrue("Ticket has been updated since last get" in str(e))
         # Update with 'action' to test new-style update.
         try:
             self.admin.ticket.update(tid, "comment1",
-                    {'_ts': to_xmlrpc_datetime(then),
+                    {'_ts': str(to_utimestamp(then)),
                      'action': 'leave'})
         except Exception, e:
             self.assertTrue("modified by someone else" in str(e))
         self.admin.ticket.delete(tid)
 
     def test_update_time_same(self):
-        # Update with collision check
-        import datetime
-        from tracrpc.xml_rpc import from_xmlrpc_datetime, to_xmlrpc_datetime
-
         # Unrestricted old-style update (to be removed soon)
         tid = self.admin.ticket.create('test_update_time_same', '...', {})
         tid, created, modified, attrs = self.admin.ticket.get(tid)

trunk/tracrpc/ticket.py

 from trac.util.datefmt import to_datetime, utc
 
 from tracrpc.api import IXMLRPCHandler, expose_rpc, Binary
-from tracrpc.util import StringIO, to_utimestamp
+from tracrpc.util import StringIO, to_utimestamp, from_utimestamp
 
 __all__ = ['TicketRPC']
 
         """ Fetch a ticket. Returns [id, time_created, time_changed, attributes]. """
         t = model.Ticket(self.env, id)
         req.perm(t.resource).require('TICKET_VIEW')
-        t['_ts'] = str(t.time_changed)
+        t['_ts'] = str(to_utimestamp(t.time_changed))
         return (t.id, t.time_created, t.time_changed, t.values)
 
     def create(self, req, summary, description, attributes={}, notify=False, when=None):
                     "has no workflow 'action'." % (id, req.authname))
             req.perm(t.resource).require('TICKET_MODIFY')
             time_changed = attributes.pop('_ts', None)
-            if time_changed and str(time_changed) != str(t.time_changed):
+            if time_changed and \
+                    str(time_changed) != str(to_utimestamp(t.time_changed)):
                 raise TracError("Ticket has been updated since last get().")
             for k, v in attributes.iteritems():
                 t[k] = v
             ts = TicketSystem(self.env)
             tm = TicketModule(self.env)
             # TODO: Deprecate update without time_changed timestamp
-            time_changed = str(attributes.pop('_ts', t.time_changed))
+            time_changed = attributes.pop('_ts', to_utimestamp(t.time_changed))
+            try:
+                time_changed = int(time_changed)
+            except ValueError:
+                raise TracError("RPC ticket.update: Wrong '_ts' token " \
+                                "in attributes (%r)." % time_changed)
             action = attributes.get('action')
             avail_actions = ts.get_available_actions(req, t)
             if not action in avail_actions:
             # TicketModule reads req.args - need to move things there...
             req.args.update(attributes)
             req.args['comment'] = comment
-            req.args['ts'] = time_changed
+            # Collision detection: 0.11+0.12 timestamp
+            req.args['ts'] = str(from_utimestamp(time_changed))
+            # Collision detection: 0.13/1.0+ timestamp
+            req.args['view_time'] = str(time_changed)
             changes, problems = tm.get_ticket_changes(req, t, action)
             for warning in problems:
                 add_warning(req, "Rpc ticket.update: %s" % warning)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.