Ticket #1106: rename_wikipages_base_functionality.diff
| File rename_wikipages_base_functionality.diff, 7.9 KB (added by shookie@…, 3 years ago) |
|---|
-
trac/attachment.py
299 299 filename=self.filename)) 300 300 return fd 301 301 302 @classmethod 303 def reparent_all(cls, env, old_realm, old_id, new_realm, new_id, db=None): 304 """Reparent all attachments of a given resource to another resource. 305 306 :param old_realm: old parent's realm 307 :param old_id: old parent's id 308 :param new_realm: new parent's realm 309 :param new_id: new parent's id 310 :param env: the environent 311 :param db: the database connection 312 """ 313 old_dir = os.path.join(os.path.normpath(env.path), 'attachments', old_realm, old_id) 314 if not os.path.exists(old_dir): 315 return 316 317 new_dir = os.path.join(os.path.normpath(env.path), 'attachments', new_realm, new_id) 302 318 319 if not db: 320 db = env.get_db_cnx() 321 handle_ta = True 322 else: 323 handle_ta = False 324 325 cursor = db.cursor() 326 cursor.execute("SELECT filename FROM attachment WHERE type=%s AND id=%s", 327 (old_realm, old_id)) 328 renames = [] 329 for filename, in cursor: 330 old_filename = os.path.join(old_dir, filename) 331 new_filename = os.path.join(new_dir, filename) 332 if os.path.exists(new_filename): 333 raise TracError(_("Can't reparent attachment '%(att)s' as " 334 "it already exists in %(realm)s:%(id)s", 335 att=new_filename, realm=new_realm, id=new_id)) 336 renames.append((old_filename, new_filename)) 337 338 try: 339 if not os.path.exists(new_dir): 340 os.makedirs(new_dir) 341 except OSError, e: 342 env.log.error("Can't create attachment directory '%s'", new_dir, exc_info=True) 343 raise TracError(_("Can't create attachment folder for %(realm)s:%(id)s: %(err)", 344 realm=new_realm, id=new_id, err=e)) 345 346 for old_filename, new_filename in renames: 347 try: 348 os.rename(old_filename, new_filename) 349 except OSError, e: 350 env.log.error("Can't move attachment from '%s' to '%s'", 351 old_filename, new_filename, exc_info=True) 352 raise TracError(_("Can't move attachment '%(att)s'", 353 att=os.path.basename(new_filename))) 354 355 #should the following be checked for exceptions, and the file move reverted in case? 356 #probably not, since then the preceding rename had to be reversed as well 357 #if soemthing really goes wrong here, it's all handywork to clean it up 358 cursor.execute("UPDATE attachment SET type=%s, id=%s WHERE type=%s AND id=%s", 359 (new_realm, new_id, old_realm, old_id)) 360 handle_ta and db.commit() 361 env.log.info('Attachments reparented to: %s:%s' % (new_realm, new_id)) 362 363 303 364 class AttachmentModule(Component): 304 365 305 366 implements(IEnvironmentSetupParticipant, IRequestHandler, -
trac/wiki/api.py
42 42 def wiki_page_changed(page, version, t, comment, author, ipnr): 43 43 """Called when a page has been modified.""" 44 44 45 def wiki_page_renamed(page,old_page_name): 46 """Called when a page has been renamed in-place.""" 47 45 48 def wiki_page_deleted(page): 46 49 """Called when a page has been deleted.""" 47 50 -
trac/wiki/tests/model.py
1 1 from datetime import datetime 2 2 import unittest 3 import tempfile 3 4 4 5 from trac.core import * 5 6 from trac.test import EnvironmentStub 6 7 from trac.util.datefmt import utc, to_timestamp 7 8 from trac.wiki import WikiPage, IWikiChangeListener 9 from trac.attachment import Attachment 8 10 9 11 10 12 class TestWikiChangeListener(Component): … … 14 16 self.changed = [] 15 17 self.deleted = [] 16 18 self.deleted_version = [] 19 self.renamed = {} 17 20 18 21 def wiki_page_added(self, page): 19 22 self.added.append(page) … … 26 29 27 30 def wiki_page_version_deleted(self, page): 28 31 self.deleted_version.append(page) 32 33 def wiki_page_renamed(self, page, old_page_name): 34 self.renamed[old_page_name] = page 29 35 30 31 36 class WikiPageTestCase(unittest.TestCase): 32 37 33 38 def setUp(self): … … 167 172 self.assertEqual(page, listener.deleted[0]) 168 173 169 174 175 176 def test_rename_page(self): 177 cursor = self.db.cursor() 178 data = (1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0) 179 cursor.execute("INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)", 180 ('TestPage',) + data) 181 182 page = WikiPage(self.env, 'TestPage') 183 184 attachment = Attachment(self.env, 'wiki', 'TestPage') 185 attachment.insert('foo.txt', tempfile.TemporaryFile(), 0, 1) 186 187 page.rename('PageRenamed') 188 189 cursor.execute("SELECT version,time,author,ipnr,text,comment," 190 "readonly FROM wiki WHERE name=%s", ('PageRenamed',)) 191 self.assertEqual(data, cursor.fetchone()) 192 self.assertEqual(None, cursor.fetchone()) 193 194 attachments = Attachment.select(self.env, 'wiki', 'PageRenamed') 195 self.assertEqual('foo.txt', attachments.next().filename) 196 self.assertRaises(StopIteration, attachments.next) 197 Attachment.delete_all(self.env, 'wiki', 'PageRenamed', self.db) 198 199 200 old_page = WikiPage(self.env, 'TestPage') 201 202 cursor.execute("SELECT version,time,author,ipnr,text,comment," 203 "readonly FROM wiki WHERE name=%s", ('TestPage',)) 204 self.assertEqual(None, cursor.fetchone()) 205 206 listener = TestWikiChangeListener(self.env) 207 self.assertEqual({'TestPage': page}, listener.renamed) 208 170 209 def suite(): 171 210 return unittest.makeSuite(WikiPageTestCase, 'test') 172 211 -
trac/wiki/model.py
175 175 for version,ts,author,comment,ipnr in cursor: 176 176 time = datetime.fromtimestamp(ts, utc) 177 177 yield version,time,author,comment,ipnr 178 179 def rename(self, new_name, db=None): 180 """Rename wiki page in-place, keeping the history intact. 181 Renaming a page this way will eventually leave dangling references 182 to the old page - which litterally doesn't exist anymore. 183 """ 184 assert self.exists, 'Cannot rename non-existent page' 185 if not db: 186 db = self.env.get_db_cnx() 187 handle_ta = True 188 else: 189 handle_ta = False 190 new_page = WikiPage(self.env, new_name, version=None, db=db) 191 if new_page.exists: 192 raise TracError(_("Can't rename to existing %(new_name)s page.", 193 new_name=new_name)) 194 195 old_name = self.name 196 cursor = db.cursor() 197 cursor.execute("UPDATE wiki SET name=%s WHERE name=%s", (new_name, old_name)) 198 199 handle_ta and db.commit() 200 201 self.env.log.info('Renamed page %s in-place to %s' % (old_name, new_name)) 202 203 self.name = new_name 204 self._fetch(self.name, None, db) 205 206 from trac.attachment import Attachment 207 # Also rename attachments 208 Attachment.reparent_all(self.env, 'wiki', old_name, 'wiki', self.name, db) 209 210 for listener in WikiSystem(self.env).change_listeners: 211 if hasattr(listener, 'wiki_page_renamed'): 212 listener.wiki_page_renamed(self, old_name) 213
