Ticket #6466: 6466-float-timestamps-2-r8770.patch
| File 6466-float-timestamps-2-r8770.patch, 34.0 KB (added by rblank, 3 years ago) |
|---|
-
contrib/sourceforge2trac.py
diff --git a/contrib/sourceforge2trac.py b/contrib/sourceforge2trac.py
a b 19 19 def __init__(self, e): 20 20 for field in e: 21 21 if field.get('name').endswith('date'): 22 setattr(self, field.get('name'), datetime.fromtimestamp( int(field.text)))22 setattr(self, field.get('name'), datetime.fromtimestamp(float(field.text))) 23 23 else: 24 24 setattr(self, field.get('name'), field.text) 25 25 -
trac/attachment.py
diff --git a/trac/attachment.py b/trac/attachment.py
a b 150 150 self.filename = row[0] 151 151 self.description = row[1] 152 152 self.size = row[2] and int(row[2]) or 0 153 time = row[3] and int(row[3]) or0153 time = row[3] or 0.0 154 154 self.date = datetime.fromtimestamp(time, utc) 155 155 self.author = row[4] 156 156 self.ipnr = row[5] … … 207 207 handle_ta = False 208 208 209 209 self.size = size and int(size) or 0 210 timestamp = int(t or time.time())210 timestamp = float(t or time.time()) 211 211 self.date = datetime.fromtimestamp(timestamp, utc) 212 212 213 213 # Make sure the path to the attachment is inside the environment … … 265 265 attachment.filename = filename 266 266 attachment.description = description 267 267 attachment.size = size and int(size) or 0 268 time = time and int(time) or0268 time = time or 0.0 269 269 attachment.date = datetime.fromtimestamp(time, utc) 270 270 attachment.author = author 271 271 attachment.ipnr = ipnr -
trac/db/mysql_backend.py
diff --git a/trac/db/mysql_backend.py b/trac/db/mysql_backend.py
a b 133 133 coldefs = [] 134 134 for column in table.columns: 135 135 ctype = column.type 136 if ctype == 'real': 137 ctype = 'double precision' 136 138 if column.auto_increment: 137 139 ctype = 'INT UNSIGNED NOT NULL AUTO_INCREMENT' 138 140 # Override the column type, as a text field cannot -
trac/db/postgres_backend.py
diff --git a/trac/db/postgres_backend.py b/trac/db/postgres_backend.py
a b 38 38 register_type(UNICODE) 39 39 register_adapter(Markup, lambda markup: QuotedString(unicode(markup))) 40 40 register_adapter(Empty, lambda empty: AsIs("''")) 41 # Work around a loss of precision for float values in psycopg 42 # See http://trac.edgewall.org/ticket/6466#comment:17 43 register_adapter(float, lambda value: AsIs(repr(value))) 41 44 42 45 has_psycopg = True 43 46 except ImportError: … … 92 95 coldefs = [] 93 96 for column in table.columns: 94 97 ctype = column.type 98 if ctype == 'real': 99 ctype = 'double precision' 95 100 if column.auto_increment: 96 101 ctype = 'SERIAL' 97 102 if len(table.key) == 1 and column.name in table.key: … … 173 178 dsn.append('port=' + str(port)) 174 179 cnx = psycopg.connect(' '.join(dsn)) 175 180 cnx.set_client_encoding('UNICODE') 181 cursor = cnx.cursor() 182 cursor.execute("SET extra_float_digits TO 2") 183 cnx.commit() 176 184 try: 177 185 self.schema = None 178 186 if 'schema' in params: 179 187 self.schema = params['schema'] 180 c nx.cursor().execute('SET search_path TO %s', (self.schema,))188 cursor.execute('SET search_path TO %s', (self.schema,)) 181 189 cnx.commit() 182 190 except PGSchemaError: 183 191 cnx.rollback() -
trac/db/tests/api.py
diff --git a/trac/db/tests/api.py b/trac/db/tests/api.py
a b 1 1 # -*- coding: utf-8 -*- 2 2 3 from datetime import datetime, timedelta 3 4 import os 4 5 import unittest 5 6 6 7 from trac.db.api import _parse_db_str 8 from trac.util.datefmt import to_timestamp, utc 7 9 from trac.test import EnvironmentStub 8 10 9 11 … … 108 110 self.assertEqual([(u'<em>märkup</em>',)], cursor.fetchall()) 109 111 110 112 113 class RealsTestCase(unittest.TestCase): 114 115 def setUp(self): 116 self.env = EnvironmentStub() 117 self.id = 0 118 119 def assertRoundTrips(self, db, when): 120 """Check that a time stored as a timestamp makes a perfect round-trip 121 through the database.""" 122 cursor = db.cursor() 123 self.id += 1 124 when_ts = to_timestamp(when) 125 cursor.execute("INSERT INTO ticket_change (ticket,time,field) " 126 "VALUES (%s,%s,'field')", (self.id, when_ts)) 127 db.commit() 128 cursor.execute("SELECT time FROM ticket_change " 129 "WHERE ticket=%s AND field='field'", (self.id,)) 130 rows = cursor.fetchall() 131 self.assertEqual([(when_ts,)], rows) 132 self.assertEqual(when, datetime.fromtimestamp(rows[0][0], utc)) 133 cursor.execute("SELECT ticket FROM ticket_change " 134 "WHERE time=%s AND field='field'", (when_ts,)) 135 self.assertEqual([(self.id,)], cursor.fetchall()) 136 137 def test_time_round_trip(self): 138 """Vary each digit in the microseconds field of a time and check a 139 round-trip through the database.""" 140 db = self.env.get_db_cnx() 141 base = datetime(2037, 2, 3, 4, 5, 6, 123456, utc) 142 self.assertRoundTrips(db, base) 143 for digit in range(7): 144 for i in range(1, 10): 145 when = base + timedelta(0, 0, i * 10 ** digit) 146 self.assertRoundTrips(db, when) 147 148 111 149 def suite(): 112 150 suite = unittest.TestSuite() 113 151 suite.addTest(unittest.makeSuite(ParseConnectionStringTestCase, 'test')) 114 152 suite.addTest(unittest.makeSuite(StringsTestCase, 'test')) 153 suite.addTest(unittest.makeSuite(RealsTestCase, 'test')) 115 154 return suite 116 155 117 156 if __name__ == '__main__': -
trac/db_default.py
diff --git a/trac/db_default.py b/trac/db_default.py
a b 17 17 from trac.db import Table, Column, Index 18 18 19 19 # Database version identifier. Used for automatic upgrades. 20 db_version = 2 220 db_version = 23 21 21 22 22 def __mkreports(reports): 23 23 """Utility function used to create report data in same syntax as the … … 45 45 Column('cookie'), 46 46 Column('name'), 47 47 Column('ipnr'), 48 Column('time', type=' int')],48 Column('time', type='real')], 49 49 Table('session', key=('sid', 'authenticated'))[ 50 50 Column('sid'), 51 51 Column('authenticated', type='int'), 52 Column('last_visit', type=' int'),52 Column('last_visit', type='real'), 53 53 Index(['last_visit']), 54 54 Index(['authenticated'])], 55 55 Table('session_attribute', key=('sid', 'authenticated', 'name'))[ … … 67 67 Column('id'), 68 68 Column('filename'), 69 69 Column('size', type='int'), 70 Column('time', type=' int'),70 Column('time', type='real'), 71 71 Column('description'), 72 72 Column('author'), 73 73 Column('ipnr')], … … 76 76 Table('wiki', key=('name', 'version'))[ 77 77 Column('name'), 78 78 Column('version', type='int'), 79 Column('time', type=' int'),79 Column('time', type='real'), 80 80 Column('author'), 81 81 Column('ipnr'), 82 82 Column('text'), … … 87 87 # Version control cache 88 88 Table('revision', key='rev')[ 89 89 Column('rev'), 90 Column('time', type=' int'),90 Column('time', type='real'), 91 91 Column('author'), 92 92 Column('message'), 93 93 Index(['time'])], … … 104 104 Table('ticket', key='id')[ 105 105 Column('id', auto_increment=True), 106 106 Column('type'), 107 Column('time', type=' int'),108 Column('changetime', type=' int'),107 Column('time', type='real'), 108 Column('changetime', type='real'), 109 109 Column('component'), 110 110 Column('severity'), 111 111 Column('priority'), … … 123 123 Index(['status'])], 124 124 Table('ticket_change', key=('ticket', 'time', 'field'))[ 125 125 Column('ticket', type='int'), 126 Column('time', type=' int'),126 Column('time', type='real'), 127 127 Column('author'), 128 128 Column('field'), 129 129 Column('oldvalue'), … … 144 144 Column('description')], 145 145 Table('milestone', key='name')[ 146 146 Column('name'), 147 Column('due', type=' int'),148 Column('completed', type=' int'),147 Column('due', type='real'), 148 Column('completed', type='real'), 149 149 Column('description')], 150 150 Table('version', key='name')[ 151 151 Column('name'), 152 Column('time', type=' int'),152 Column('time', type='real'), 153 153 Column('description')], 154 154 155 155 # Report system -
trac/ticket/model.py
diff --git a/trac/ticket/model.py b/trac/ticket/model.py
a b 328 328 db = self._get_db(db) 329 329 cursor = db.cursor() 330 330 sid = str(self.id) 331 when_ts = when and to_timestamp(when) or 0331 when_ts = to_timestamp(when) 332 332 if when_ts: 333 333 cursor.execute("SELECT time,author,field,oldvalue,newvalue," 334 334 "1 AS permanent FROM ticket_change " … … 356 356 (self.id, sid, sid)) 357 357 log = [] 358 358 for t, author, field, oldvalue, newvalue, permanent in cursor: 359 log.append((datetime.fromtimestamp( int(t), utc), author, field,359 log.append((datetime.fromtimestamp(t, utc), author, field, 360 360 oldvalue or '', newvalue or '', permanent)) 361 361 return log 362 362 … … 389 389 "WHERE ticket=%s AND time=%s", 390 390 (self.id, ts)) 391 391 fields = {} 392 change = {'date': datetime.fromtimestamp( int(ts), utc),392 change = {'date': datetime.fromtimestamp(ts, utc), 393 393 'author': author, 'fields': fields} 394 394 for field, author, old, new in cursor: 395 395 fields[field] = {'author': author, 'old': old, 'new': new} … … 445 445 (self.id, ts0, db.like_escape('_comment') + '%')) 446 446 for field, author, comment, ts in cursor: 447 447 rev = int(field[8:]) 448 history.append((rev, datetime.fromtimestamp( int(ts0), utc),448 history.append((rev, datetime.fromtimestamp(ts0, utc), 449 449 author0, comment)) 450 450 ts0, author0 = ts, author 451 451 history.sort() 452 452 rev = history and (history[-1][0] + 1) or 0 453 history.append((rev, datetime.fromtimestamp( int(ts), utc),453 history.append((rev, datetime.fromtimestamp(ts, utc), 454 454 author, last_comment)) 455 455 return history 456 456 … … 758 758 def _from_database(self, row): 759 759 name, due, completed, description = row 760 760 self.name = self._old_name = name 761 self.due = due and datetime.fromtimestamp( int(due), utc) or None761 self.due = due and datetime.fromtimestamp(due, utc) or None 762 762 self.completed = completed and \ 763 datetime.fromtimestamp( int(completed), utc) or None763 datetime.fromtimestamp(completed, utc) or None 764 764 self.description = description or '' 765 765 766 766 def delete(self, retarget_to=None, author=None, db=None): … … 890 890 raise ResourceNotFound(_('Version %(name)s does not exist.', 891 891 name=name)) 892 892 self.name = self._old_name = name 893 self.time = row[0] and datetime.fromtimestamp( int(row[0]), utc) or None893 self.time = row[0] and datetime.fromtimestamp(row[0], utc) or None 894 894 self.description = row[1] or '' 895 895 else: 896 896 self.name = self._old_name = None … … 975 975 for name, time, description in cursor: 976 976 version = cls(env) 977 977 version.name = version._old_name = name 978 version.time = time and datetime.fromtimestamp( int(time), utc) or None978 version.time = time and datetime.fromtimestamp(time, utc) or None 979 979 version.description = description or '' 980 980 versions.append(version) 981 981 def version_order(v): -
trac/ticket/query.py
diff --git a/trac/ticket/query.py b/trac/ticket/query.py
a b 331 331 elif val is None: 332 332 val = '--' 333 333 elif name in self.time_fields: 334 val = datetime.fromtimestamp( int(val or 0), utc)334 val = datetime.fromtimestamp(float(val or 0), utc) 335 335 elif field and field['type'] == 'checkbox': 336 336 try: 337 337 val = bool(int(val)) … … 1020 1020 # The most recent query is stored in the user session; 1021 1021 orig_list = None 1022 1022 orig_time = datetime.now(utc) 1023 query_time = int(req.session.get('query_time', 0))1023 query_time = float(req.session.get('query_time', 0)) 1024 1024 query_time = datetime.fromtimestamp(query_time, utc) 1025 1025 query_constraints = unicode(query.constraints) 1026 1026 try: -
trac/ticket/templates/report.rss
diff --git a/trac/ticket/templates/report.rss b/trac/ticket/templates/report.rss
a b 26 26 </py:when> 27 27 <py:when test="col in ('time', 'changetime', 'created', 'modified')"> 28 28 <!-- FIXME: we end up with multiple pubDate --> 29 <pubDate py:if="cell.value != 'None'">${http_date(fromtimestamp( int(cell.value)))}</pubDate>29 <pubDate py:if="cell.value != 'None'">${http_date(fromtimestamp(float(cell.value)))}</pubDate> 30 30 </py:when> 31 31 <py:when test="col == 'summary'"> 32 32 <title>#$row.id: $cell.value</title> -
trac/ticket/templates/report_view.html
diff --git a/trac/ticket/templates/report_view.html b/trac/ticket/templates/report_view.html
a b 144 144 145 145 <!--! generic fields --> 146 146 <py:when test="col == 'time'"> 147 <td class="date" py:attrs="td_attrs">${cell.value != '' and format_time( int(cell.value)) or '--'}147 <td class="date" py:attrs="td_attrs">${cell.value != '' and format_time(float(cell.value)) or '--'} 148 148 <hr py:if="fullrow"/> 149 149 </td> 150 150 </py:when> 151 151 152 152 <py:when test="col in ('date', 'created', 'modified')"> 153 <td class="date" py:attrs="td_attrs">${cell.value != '' and format_date( int(cell.value)) or '--'}153 <td class="date" py:attrs="td_attrs">${cell.value != '' and format_date(float(cell.value)) or '--'} 154 154 <hr py:if="fullrow"/> 155 155 </td> 156 156 </py:when> 157 157 158 158 <py:when test="col == 'datetime'"> 159 <td class="date" py:attrs="td_attrs">${cell.value != '' and format_datetime( int(cell.value)) or '--'}159 <td class="date" py:attrs="td_attrs">${cell.value != '' and format_datetime(float(cell.value)) or '--'} 160 160 <hr py:if="fullrow"/> 161 161 </td> 162 162 </py:when> -
trac/ticket/tests/model.py
diff --git a/trac/ticket/tests/model.py b/trac/ticket/tests/model.py
a b 312 312 sorted(log[1:3])) 313 313 self.assertEqual((t3, 'jim', 'comment', '', 'Other', True), log[3]) 314 314 315 def test_subsecond_change(self): 316 """Perform two ticket changes within a second.""" 317 tkt_id = self._insert_ticket('Test', reporter='joe', component='foo') 318 ticket = Ticket(self.env, tkt_id) 319 t1 = datetime(2001, 1, 1, 1, 1, 1, 123456, utc) 320 ticket.save_changes('jane', 'Testing', t1) 321 t2 = datetime(2001, 1, 1, 1, 1, 1, 789012, utc) 322 ticket.save_changes('jim', 'Other', t2) 323 log = ticket.get_changelog() 324 self.assertEqual(2, len(log)) 325 self.assertEqual((t1, 'jane', 'comment', '', 'Testing', True), log[0]) 326 self.assertEqual((t2, 'jim', 'comment', '', 'Other', True), log[1]) 327 315 328 def test_changelog_with_reverted_change(self): 316 329 tkt_id = self._insert_ticket('Test', reporter='joe', component='foo') 317 330 ticket = Ticket(self.env, tkt_id) -
trac/ticket/web_ui.py
diff --git a/trac/ticket/web_ui.py b/trac/ticket/web_ui.py
a b 1649 1649 comment_history.setdefault(rev, {}).update({'comment': old}) 1650 1650 comment_history.setdefault(rev + 1, {}).update( 1651 1651 {'author': author, 1652 'date': datetime.fromtimestamp( int(new), utc)})1652 'date': datetime.fromtimestamp(float(new), utc)}) 1653 1653 elif old or new: 1654 1654 current['fields'][field] = {'old': old, 'new': new} 1655 1655 if current: -
new file trac/upgrades/db23.py
diff --git a/trac/upgrades/db23.py b/trac/upgrades/db23.py new file mode 100644
- + 1 from trac.db import Table, Column, Index, DatabaseManager 2 3 def do_upgrade(env, ver, cursor): 4 # Convert time values from int to real 5 tables = [ 6 Table('auth_cookie', key=('cookie', 'ipnr', 'name'))[ 7 Column('cookie'), 8 Column('name'), 9 Column('ipnr'), 10 Column('time', type='real')], 11 Table('session', key=('sid', 'authenticated'))[ 12 Column('sid'), 13 Column('authenticated', type='int'), 14 Column('last_visit', type='real'), 15 Index(['last_visit']), 16 Index(['authenticated'])], 17 Table('attachment', key=('type', 'id', 'filename'))[ 18 Column('type'), 19 Column('id'), 20 Column('filename'), 21 Column('size', type='int'), 22 Column('time', type='real'), 23 Column('description'), 24 Column('author'), 25 Column('ipnr')], 26 Table('wiki', key=('name', 'version'))[ 27 Column('name'), 28 Column('version', type='int'), 29 Column('time', type='real'), 30 Column('author'), 31 Column('ipnr'), 32 Column('text'), 33 Column('comment'), 34 Column('readonly', type='int'), 35 Index(['time'])], 36 Table('revision', key='rev')[ 37 Column('rev'), 38 Column('time', type='real'), 39 Column('author'), 40 Column('message'), 41 Index(['time'])], 42 Table('ticket', key='id')[ 43 Column('id', auto_increment=True), 44 Column('type'), 45 Column('time', type='real'), 46 Column('changetime', type='real'), 47 Column('component'), 48 Column('severity'), 49 Column('priority'), 50 Column('owner'), 51 Column('reporter'), 52 Column('cc'), 53 Column('version'), 54 Column('milestone'), 55 Column('status'), 56 Column('resolution'), 57 Column('summary'), 58 Column('description'), 59 Column('keywords'), 60 Index(['time']), 61 Index(['status'])], 62 Table('ticket_change', key=('ticket', 'time', 'field'))[ 63 Column('ticket', type='int'), 64 Column('time', type='real'), 65 Column('author'), 66 Column('field'), 67 Column('oldvalue'), 68 Column('newvalue'), 69 Index(['ticket']), 70 Index(['time'])], 71 Table('milestone', key='name')[ 72 Column('name'), 73 Column('due', type='real'), 74 Column('completed', type='real'), 75 Column('description')], 76 Table('version', key='name')[ 77 Column('name'), 78 Column('time', type='real'), 79 Column('description')], 80 ] 81 82 for table in tables: 83 cursor.execute("CREATE TEMPORARY TABLE %s_old " 84 "AS SELECT * FROM %s" % (table.name, table.name)) 85 cursor.execute("DROP TABLE %s" % table.name) 86 87 db_connector, _ = DatabaseManager(env)._get_connector() 88 for table in tables: 89 for stmt in db_connector.to_sql(table): 90 cursor.execute(stmt) 91 92 for table in tables: 93 cursor.execute("INSERT INTO %s SELECT * FROM %s_old" 94 % (table.name, table.name)) 95 cursor.execute("DROP TABLE %s_old" % table.name) -
trac/util/datefmt.py
diff --git a/trac/util/datefmt.py b/trac/util/datefmt.py
a b 57 57 """Return the corresponding POSIX timestamp""" 58 58 if dt: 59 59 diff = dt - _epoc 60 return diff.days * 86400 + diff.seconds 60 return diff.days * 86400 + diff.seconds + diff.microseconds * 1e-6 61 61 else: 62 return 0 62 return 0.0 63 63 64 64 65 65 # -- formatting -
trac/util/tests/datefmt.py
diff --git a/trac/util/tests/datefmt.py b/trac/util/tests/datefmt.py
a b 42 42 tz.utcoffset(None)) 43 43 self.assertEqual('GMT +4:00', tz.zone) 44 44 45 45 46 class DateFormatTestCase(unittest.TestCase): 46 47 47 48 def test_to_datetime(self): … … 94 95 self.assertEqual('2009-08-20', 95 96 datefmt.format_date(a_date, format='%Y-%m-%d')) 96 97 98 99 class ToTimestampTestCase(unittest.TestCase): 100 101 def test_sub_second(self): 102 t = datetime.datetime(2001, 2, 3, 4, 5, 6, 123456, datefmt.utc) 103 ts = datefmt.to_timestamp(t) 104 self.assertNotEqual(ts, int(ts)) 105 self.assertEqual(t, datetime.datetime.fromtimestamp(ts, datefmt.utc)) 106 107 97 108 def suite(): 98 109 suite = unittest.TestSuite() 99 110 if PytzTestCase: … … 101 112 else: 102 113 print "SKIP: utils/tests/datefmt.py (no pytz installed)" 103 114 suite.addTest(unittest.makeSuite(DateFormatTestCase)) 115 suite.addTest(unittest.makeSuite(ToTimestampTestCase)) 104 116 return suite 105 117 106 118 if __name__ == '__main__': -
trac/versioncontrol/svn_fs.py
diff --git a/trac/versioncontrol/svn_fs.py b/trac/versioncontrol/svn_fs.py
a b 781 781 core.SVN_PROP_REVISION_DATE, self.pool()) 782 782 if not _date: 783 783 return None 784 ts = core.svn_time_from_cstring(_date, self.pool()) / 1000000 784 ts = core.svn_time_from_cstring(_date, self.pool()) / 1000000.0 785 785 return datetime.fromtimestamp(ts, utc) 786 786 787 787 def _get_prop(self, name): … … 847 847 author = author and to_unicode(author, 'utf-8') 848 848 _date = self._get_prop(core.SVN_PROP_REVISION_DATE) 849 849 if _date: 850 ts = core.svn_time_from_cstring(_date, self.pool()) / 1000000 850 ts = core.svn_time_from_cstring(_date, self.pool()) / 1000000.0 851 851 date = datetime.fromtimestamp(ts, utc) 852 852 else: 853 853 date = None -
trac/versioncontrol/tests/svn_fs.py
diff --git a/trac/versioncontrol/tests/svn_fs.py b/trac/versioncontrol/tests/svn_fs.py
a b 145 145 self.assertEqual(u'/tête', node.path) 146 146 self.assertEqual(Node.DIRECTORY, node.kind) 147 147 self.assertEqual(HEAD, node.rev) 148 self.assertEqual(datetime(2007, 4, 30, 17, 45, 26, 0, utc),148 self.assertEqual(datetime(2007, 4, 30, 17, 45, 26, 234375, utc), 149 149 node.last_modified) 150 150 node = self.repos.get_node(u'/tête/README.txt') 151 151 self.assertEqual('README.txt', node.name) 152 152 self.assertEqual(u'/tête/README.txt', node.path) 153 153 self.assertEqual(Node.FILE, node.kind) 154 154 self.assertEqual(3, node.rev) 155 self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 0, utc), node.last_modified)155 self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc), node.last_modified) 156 156 157 157 def test_get_node_specific_rev(self): 158 158 node = self.repos.get_node(u'/tête', 1) … … 160 160 self.assertEqual(u'/tête', node.path) 161 161 self.assertEqual(Node.DIRECTORY, node.kind) 162 162 self.assertEqual(1, node.rev) 163 self.assertEqual(datetime(2005, 4, 1, 10, 0, 52, 0, utc), node.last_modified)163 self.assertEqual(datetime(2005, 4, 1, 10, 0, 52, 353248, utc), node.last_modified) 164 164 node = self.repos.get_node(u'/tête/README.txt', 2) 165 165 self.assertEqual('README.txt', node.name) 166 166 self.assertEqual(u'/tête/README.txt', node.path) 167 167 self.assertEqual(Node.FILE, node.kind) 168 168 self.assertEqual(2, node.rev) 169 self.assertEqual(datetime(2005, 4, 1, 13, 12, 18, 0, utc), node.last_modified)169 self.assertEqual(datetime(2005, 4, 1, 13, 12, 18, 216267, utc), node.last_modified) 170 170 171 171 def test_get_dir_entries(self): 172 172 node = self.repos.get_node(u'/tête') … … 383 383 self.assertEqual(0, chgset.rev) 384 384 self.assertEqual('', chgset.message) 385 385 self.assertEqual('', chgset.author) 386 self.assertEqual(datetime(2005, 4, 1, 9, 57, 41, 0, utc), chgset.date)386 self.assertEqual(datetime(2005, 4, 1, 9, 57, 41, 312767, utc), chgset.date) 387 387 self.assertRaises(StopIteration, chgset.get_changes().next) 388 388 389 389 def test_changeset_added_dirs(self): … … 391 391 self.assertEqual(1, chgset.rev) 392 392 self.assertEqual('Initial directory layout.', chgset.message) 393 393 self.assertEqual('john', chgset.author) 394 self.assertEqual(datetime(2005, 4, 1, 10, 0, 52, 0, utc), chgset.date)394 self.assertEqual(datetime(2005, 4, 1, 10, 0, 52, 353248, utc), chgset.date) 395 395 396 396 changes = chgset.get_changes() 397 397 self.assertEqual(('branches', Node.DIRECTORY, Changeset.ADD, None, -1), … … 407 407 self.assertEqual(3, chgset.rev) 408 408 self.assertEqual('Fixed README.\n', chgset.message) 409 409 self.assertEqual('kate', chgset.author) 410 self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 0, utc), chgset.date)410 self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc), chgset.date) 411 411 412 412 changes = chgset.get_changes() 413 413 self.assertEqual((u'tête/README.txt', Node.FILE, Changeset.EDIT, … … 419 419 self.assertEqual(5, chgset.rev) 420 420 self.assertEqual('Moved directories.', chgset.message) 421 421 self.assertEqual('kate', chgset.author) 422 self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 0, utc), chgset.date)422 self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 658099, utc), chgset.date) 423 423 424 424 changes = chgset.get_changes() 425 425 self.assertEqual((u'tête/dir1/dir2', Node.DIRECTORY, Changeset.MOVE, … … 433 433 self.assertEqual(6, chgset.rev) 434 434 self.assertEqual('More things to read', chgset.message) 435 435 self.assertEqual('john', chgset.author) 436 self.assertEqual(datetime(2005, 4, 1, 18, 56, 46, 0, utc), chgset.date)436 self.assertEqual(datetime(2005, 4, 1, 18, 56, 46, 985846, utc), chgset.date) 437 437 438 438 changes = chgset.get_changes() 439 439 self.assertEqual((u'tête/README2.txt', Node.FILE, Changeset.COPY, … … 550 550 self.assertEqual('/dir1', node.path) 551 551 self.assertEqual(Node.DIRECTORY, node.kind) 552 552 self.assertEqual(5, node.rev) 553 self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 0, utc), node.last_modified)553 self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 658099, utc), node.last_modified) 554 554 node = self.repos.get_node('/README.txt') 555 555 self.assertEqual('README.txt', node.name) 556 556 self.assertEqual('/README.txt', node.path) 557 557 self.assertEqual(Node.FILE, node.kind) 558 558 self.assertEqual(3, node.rev) 559 self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 0, utc), node.last_modified)559 self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc), node.last_modified) 560 560 561 561 def test_get_node_specific_rev(self): 562 562 node = self.repos.get_node('/dir1', 4) … … 564 564 self.assertEqual('/dir1', node.path) 565 565 self.assertEqual(Node.DIRECTORY, node.kind) 566 566 self.assertEqual(4, node.rev) 567 self.assertEqual(datetime(2005, 4, 1, 15, 42, 35, 0, utc), node.last_modified)567 self.assertEqual(datetime(2005, 4, 1, 15, 42, 35, 450595, utc), node.last_modified) 568 568 node = self.repos.get_node('/README.txt', 2) 569 569 self.assertEqual('README.txt', node.name) 570 570 self.assertEqual('/README.txt', node.path) 571 571 self.assertEqual(Node.FILE, node.kind) 572 572 self.assertEqual(2, node.rev) 573 self.assertEqual(datetime(2005, 4, 1, 13, 12, 18, 0, utc), node.last_modified)573 self.assertEqual(datetime(2005, 4, 1, 13, 12, 18, 216267, utc), node.last_modified) 574 574 575 575 def test_get_dir_entries(self): 576 576 node = self.repos.get_node('/') … … 675 675 self.assertEqual(0, chgset.rev) 676 676 self.assertEqual('', chgset.message) 677 677 self.assertEqual('', chgset.author) 678 self.assertEqual(datetime(2005, 4, 1, 9, 57, 41, 0, utc), chgset.date)678 self.assertEqual(datetime(2005, 4, 1, 9, 57, 41, 312767, utc), chgset.date) 679 679 self.assertRaises(StopIteration, chgset.get_changes().next) 680 680 681 681 def test_changeset_added_dirs(self): … … 683 683 self.assertEqual(4, chgset.rev) 684 684 self.assertEqual('More directories.', chgset.message) 685 685 self.assertEqual('john', chgset.author) 686 self.assertEqual(datetime(2005, 4, 1, 15, 42, 35, 0, utc), chgset.date)686 self.assertEqual(datetime(2005, 4, 1, 15, 42, 35, 450595, utc), chgset.date) 687 687 688 688 changes = chgset.get_changes() 689 689 self.assertEqual(('dir1', Node.DIRECTORY, 'add', None, -1), … … 699 699 self.assertEqual(3, chgset.rev) 700 700 self.assertEqual('Fixed README.\n', chgset.message) 701 701 self.assertEqual('kate', chgset.author) 702 self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 0, utc), chgset.date)702 self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc), chgset.date) 703 703 704 704 changes = chgset.get_changes() 705 705 self.assertEqual(('README.txt', Node.FILE, Changeset.EDIT, … … 711 711 self.assertEqual(5, chgset.rev) 712 712 self.assertEqual('Moved directories.', chgset.message) 713 713 self.assertEqual('kate', chgset.author) 714 self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 0, utc), chgset.date)714 self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 658099, utc), chgset.date) 715 715 716 716 changes = chgset.get_changes() 717 717 self.assertEqual(('dir1/dir2', Node.DIRECTORY, Changeset.MOVE, … … 725 725 self.assertEqual(6, chgset.rev) 726 726 self.assertEqual('More things to read', chgset.message) 727 727 self.assertEqual('john', chgset.author) 728 self.assertEqual(datetime(2005, 4, 1, 18, 56, 46, 0, utc), chgset.date)728 self.assertEqual(datetime(2005, 4, 1, 18, 56, 46, 985846, utc), chgset.date) 729 729 730 730 changes = chgset.get_changes() 731 731 self.assertEqual(('README2.txt', Node.FILE, Changeset.COPY, -
trac/web/auth.py
diff --git a/trac/web/auth.py b/trac/web/auth.py
a b 148 148 cursor = db.cursor() 149 149 cursor.execute("INSERT INTO auth_cookie (cookie,name,ipnr,time) " 150 150 "VALUES (%s, %s, %s, %s)", (cookie, remote_user, 151 req.remote_addr, int(time.time())))151 req.remote_addr, time.time())) 152 152 db.commit() 153 153 154 154 req.authname = remote_user … … 173 173 db = self.env.get_db_cnx() 174 174 cursor = db.cursor() 175 175 cursor.execute("DELETE FROM auth_cookie WHERE name=%s OR time < %s", 176 (req.authname, int(time.time()) - 86400 * 10))176 (req.authname, time.time() - 86400 * 10)) 177 177 db.commit() 178 178 self._expire_cookie(req) 179 179 custom_redirect = self.config['metanav'].get('logout.redirect') -
trac/web/session.py
diff --git a/trac/web/session.py b/trac/web/session.py
a b 61 61 if not row: 62 62 return 63 63 self._new = False 64 self.last_visit = int(row[0] or 0)64 self.last_visit = float(row[0] or 0) 65 65 66 66 cursor.execute("SELECT name,value FROM session_attribute " 67 67 "WHERE sid=%s and authenticated=%s", … … 77 77 return 78 78 79 79 authenticated = int(self.authenticated) 80 now = int(time.time())80 now = time.time() 81 81 db = self.env.get_db_cnx() 82 82 cursor = db.cursor() 83 83 … … 241 241 # we didn't have an anonymous session for this sid 242 242 cursor.execute("INSERT INTO session (sid,last_visit,authenticated)" 243 243 " VALUES(%s,%s,1)", 244 (self.req.authname, int(time.time())))244 (self.req.authname, time.time())) 245 245 self._new = False 246 246 db.commit() 247 247 -
trac/web/tests/session.py
diff --git a/trac/web/tests/session.py b/trac/web/tests/session.py
a b 194 194 cursor = self.db.cursor() 195 195 cursor.execute("INSERT INTO session " 196 196 "VALUES ('123456', 0, %s)", 197 ( int(now - UPDATE_INTERVAL - 3600),))197 (now - UPDATE_INTERVAL - 3600,)) 198 198 cursor.execute("INSERT INTO session_attribute VALUES " 199 199 "('123456', 0, 'foo', 'bar')") 200 200 … … 287 287 288 288 cursor.execute("SELECT last_visit FROM session WHERE sid='123456' AND " 289 289 "authenticated=0") 290 self.assertAlmostEqual(now, int(cursor.fetchone()[0]), -1)290 self.assertAlmostEqual(now, float(cursor.fetchone()[0]), -6) 291 291 292 292 def test_modify_detached_session(self): 293 293 """ -
trac/wiki/admin.py
diff --git a/trac/wiki/admin.py b/trac/wiki/admin.py
a b 116 116 " SELECT 1+COALESCE(max(version),0),%s,%s," 117 117 " 'trac','127.0.0.1',%s FROM wiki " 118 118 " WHERE name=%s", 119 (title, int(time.time()), data, title))119 (title, time.time(), data, title)) 120 120 if not old: 121 121 WikiSystem(self.env).pages.invalidate(db) 122 122 if handle_ta:
