Edgewall Software

Ticket #8861: 8861-wiki-replace-r8952.patch

File 8861-wiki-replace-r8952.patch, 8.7 KB (added by rblank, 2 years ago)

Add trac-admin $ENV wiki replace and enhance wiki load on trunk.

  • trac/admin/tests/console-tests.txt

    diff --git a/trac/admin/tests/console-tests.txt b/trac/admin/tests/console-tests.txt
    a b  
    6060version time         Set version date 
    6161wiki dump            Export wiki pages to files named by title 
    6262wiki export          Export wiki page to file or stdout 
    63 wiki import          Import wiki page from file or stdin 
     63wiki import          Import wiki page from file or stdin (deprecated) 
    6464wiki list            List wiki pages 
    65 wiki load            Import all wiki pages from directory 
     65wiki load            Import wiki pages from files or stdin 
    6666wiki remove          Remove wiki page 
     67wiki replace         Replace the content of wiki pages from files or stdin 
    6768wiki upgrade         Upgrade default wiki pages to current version 
    6869===== test_attachment_list_empty ===== 
    6970 
  • trac/wiki/admin.py

    diff --git a/trac/wiki/admin.py b/trac/wiki/admin.py
    a b  
    2121from trac.core import * 
    2222from trac.wiki import model 
    2323from trac.wiki.api import WikiSystem 
     24from trac.util import read_file 
    2425from trac.util.compat import any 
    2526from trac.util.datefmt import format_datetime, utc 
    2627from trac.util.text import to_unicode, unicode_quote, unicode_unquote, \ 
    27                            print_table, printout 
     28                           print_table, printerr, printout 
    2829from trac.util.translation import _ 
    2930 
    3031 
     
    4647               'Export wiki page to file or stdout', 
    4748               self._complete_import_export, self._do_export) 
    4849        yield ('wiki import', '<page> [file]', 
    49                'Import wiki page from file or stdin', 
     50               'Import wiki page from file or stdin (deprecated)', 
    5051               self._complete_import_export, self._do_import) 
    5152        yield ('wiki dump', '<directory> [name] [...]', 
    5253               """Export wiki pages to files named by title 
     
    5657               that prefix should be dumped. If no name is specified, all wiki 
    5758               pages are dumped.""", 
    5859               self._complete_dump, self._do_dump) 
    59         yield ('wiki load', '<directory>', 
    60                'Import all wiki pages from directory', 
     60        yield ('wiki load', '(<page> [path] | <directory>)', 
     61               """Import wiki pages from files or stdin 
     62                
     63               When both arguments are given, the specified page is imported 
     64               from a file. When a single argument specifying an existing 
     65               directory is given, all files in that directory are imported 
     66               into pages corresponding to the file names. Otherwise, a single 
     67               page with the given name is imported from stdin.""", 
    6168               self._complete_load, self._do_load) 
     69        yield ('wiki replace', '(<page> [path] | <directory>)', 
     70               """Replace the content of wiki pages from files or stdin 
     71                
     72               This command replaces the content of the last version of one 
     73               or more wiki pages with new content. The previous content is 
     74               lost, and no new entry is created in the page history. The 
     75               metadata of the page (time, author) is not changed either. 
     76                
     77               When both arguments are given, the specified page is imported 
     78               from a file. When a single argument specifying an existing 
     79               directory is given, all files in that directory are imported 
     80               into pages corresponding to the file names. Otherwise, a single 
     81               page with the given name is imported from stdin.""", 
     82               self._complete_load, self._do_replace) 
    6283        yield ('wiki upgrade', '', 
    6384               'Upgrade default wiki pages to current version', 
    6485               None, self._do_upgrade) 
     
    85106            finally: 
    86107                f.close() 
    87108     
    88     def import_page(self, filename, title, db=None, create_only=[]): 
    89         if not os.path.isfile(filename): 
    90             raise AdminCommandError(_("'%(name)s' is not a file", 
    91                                       name=filename)) 
    92          
    93         f = open(filename, 'r') 
    94         try: 
    95             data = to_unicode(f.read(), 'utf-8') 
    96         finally: 
    97             f.close() 
     109    def import_page(self, filename, title, db=None, create_only=[], 
     110                    replace=False): 
     111        if filename: 
     112            if not os.path.isfile(filename): 
     113                raise AdminCommandError(_("'%(name)s' is not a file", 
     114                                          name=filename)) 
     115            data = to_unicode(read_file(filename)) 
     116        else: 
     117            data = sys.stdin.read() 
    98118         
    99119        # Make sure we don't insert the exact same page twice 
    100120        handle_ta = not db 
     
    111131        if old and data == old[0][0]: 
    112132            printout('  %s already up to date.' % title) 
    113133            return False 
     134        if replace and not old: 
     135            printout("  Replacing %s, but page doesn't exist." % title) 
     136            return False 
    114137         
    115         cursor.execute("INSERT INTO wiki(version,name,time,author,ipnr,text) " 
    116                        " SELECT 1+COALESCE(max(version),0),%s,%s," 
    117                        " 'trac','127.0.0.1',%s FROM wiki " 
    118                        " WHERE name=%s", 
    119                        (title, int(time.time()), data, title)) 
     138        if replace: 
     139            cursor.execute("UPDATE wiki SET text=%s WHERE name=%s " 
     140                           "  AND version=(SELECT max(version) FROM wiki " 
     141                           "               WHERE name=%s)", 
     142                           (data, title, title)) 
     143        else: 
     144            cursor.execute("INSERT INTO wiki(version,name,time,author,ipnr," 
     145                           "                 text) " 
     146                           "SELECT 1+COALESCE(max(version),0),%s,%s," 
     147                           "       'trac','127.0.0.1',%s FROM wiki " 
     148                           "WHERE name=%s", 
     149                           (title, int(time.time()), data, title)) 
    120150        if not old: 
    121151            WikiSystem(self.env).pages.invalidate(db) 
    122152        if handle_ta: 
    123153            db.commit() 
    124154        return True 
    125155 
    126     def load_pages(self, dir, db=None, ignore=[], create_only=[]): 
     156    def load_pages(self, dir, db=None, ignore=[], create_only=[], 
     157                   replace=False): 
    127158        cons_charset = getattr(sys.stdout, 'encoding', None) or 'utf-8' 
    128159        for page in os.listdir(dir): 
    129160            if page in ignore: 
     
    131162            filename = os.path.join(dir, page) 
    132163            page = unicode_unquote(page.encode('utf-8')) 
    133164            if os.path.isfile(filename): 
    134                 if self.import_page(filename, page, db, create_only): 
     165                if self.import_page(filename, page, db, create_only, replace): 
    135166                    printout(_("  %(page)s imported from %(filename)s", 
    136167                               filename=filename, page=page)) 
    137168     
     
    147178     
    148179    def _complete_dump(self, args): 
    149180        if len(args) == 1: 
    150             return get_dir_list(args[-1], True) 
     181            return get_dir_list(args[-1], dirs_only=True) 
    151182        elif len(args) == 2: 
    152183            return self.get_wiki_list() 
    153184     
    154185    def _complete_load(self, args): 
    155186        if len(args) == 1: 
    156             return get_dir_list(args[-1], True) 
     187            return (get_dir_list(args[-1], dirs_only=True) 
     188                    + self.get_wiki_list()) 
     189        elif len(args) == 2: 
     190            return get_dir_list(args[-1]) 
    157191     
    158192    def _do_list(self): 
    159193        db = self.env.get_db_cnx() 
     
    184218        self.export_page(page, filename) 
    185219     
    186220    def _do_import(self, page, filename=None): 
     221        printerr(_('trac-admin $ENV import is deprecated. Use load instead.')) 
    187222        self.import_page(filename, page) 
    188223     
    189224    def _do_dump(self, directory, *names): 
     
    206241                printout(' %s => %s' % (p, dst)) 
    207242                self.export_page(p, dst, cursor) 
    208243     
    209     def _do_load(self, directory): 
     244    def _load_or_replace(self, page_or_dir, path, replace): 
    210245        db = self.env.get_db_cnx() 
    211         self.load_pages(directory, db) 
     246        if path is not None: 
     247            self.import_page(path, page_or_dir, db, replace=replace) 
     248        elif os.path.isdir(page_or_dir): 
     249            self.load_pages(page_or_dir, db, replace=replace) 
     250        else: 
     251            self.import_page(None, page_or_dir, db, replace=replace) 
    212252        db.commit() 
    213253     
     254    def _do_load(self, page_or_dir, path=None): 
     255        self._load_or_replace(page_or_dir, path, replace=False) 
     256     
     257    def _do_replace(self, page_or_dir, path=None): 
     258        self._load_or_replace(page_or_dir, path, replace=True) 
     259     
    214260    def _do_upgrade(self): 
    215261        db = self.env.get_db_cnx() 
    216262        self.load_pages(pkg_resources.resource_filename('trac.wiki',