Beispiel #1
0
 def setUp(self):
     wiki = WikiPage(self.env)
     wiki.name = 'WikiStart'
     wiki.text = '--'
     wiki.save('joe', 'Entry page', '::1', datetime.now(utc))
     if self._setup:
         self._setup(self)
Beispiel #2
0
    def set_password(self, user, password):
        import re

        if len(user) < 3:
            raise TracError("user name must be at least 3 characters long")
        if not re.match(r"^\w+$", user):
            raise TracError("user name must consist only of alpha-numeric characters")
        if user not in self.get_users():
            from trac.wiki.model import WikiPage

            db = self.env.get_db_cnx()
            page = WikiPage(self.env, user, db=db)
            # User creation with existing page
            if page.exists:
                raise TracError('wiki page "%s" already exists' % user)
            else:
                from tractags.api import TagEngine

                tagspace = TagEngine(self.env).tagspace.wiki

                tagspace.add_tags(None, user, ["user"])
                page.text = """= %(user)s =\n\n[[ListTagged(%(user)s)]]\n\n[[TagIt(user)]]""" % {"user": user}
                page.save(user, "New user %s registered" % user, None)
                self.env.log.debug("New user %s registered" % user)
        HtPasswdStore.set_password(self, user, password)
Beispiel #3
0
 def getPageInfo(self, req, pagename, version=None):
     """ Returns information about the given page. """
     page = WikiPage(self.env, pagename, version)
     if page.exists:
         last_update = page.get_history().next()
         return self._page_info(page.name, last_update[1], last_update[2],
                                page.version)
Beispiel #4
0
 def getPageInfo(self, req, pagename, version=None):
     """ Returns information about the given page. """
     page = WikiPage(self.env, pagename, version)
     req.perm(page.resource).require("WIKI_VIEW")
     if page.exists:
         last_update = page.get_history().next()
         return self._page_info(page.name, last_update[1], last_update[2], page.version, page.comment)
Beispiel #5
0
 def _get_interwiki_map(self):
     from trac.wiki.model import WikiPage
     if self._interwiki_map is None:
         self._interwiki_lock.acquire()
         try:
             if self._interwiki_map is None:
                 self._interwiki_map = {}
                 content = WikiPage(self.env, InterWikiMap._page_name).text
                 in_map = False
                 for line in content.split('\n'):
                     if in_map:
                         if line.startswith('----'):
                             in_map = False
                         else:
                             m = re.match(InterWikiMap._interwiki_re, line)
                             if m:
                                 prefix, url, title = m.groups()
                                 url = url.strip()
                                 title = title and title.strip() or prefix
                                 self[prefix] = (prefix, url, title)
                     elif line.startswith('----'):
                         in_map = True
         finally:
             self._interwiki_lock.release()
     return self._interwiki_map
Beispiel #6
0
def add_pages(tc, names):
    now = datetime.now(utc)
    for name in names:
        w = WikiPage(tc.env)
        w.name = name
        w.text = '--'
        w.save('joe', 'the page ' + name, '::1', now)
Beispiel #7
0
 def interwiki_map(self):
     """Map from upper-cased namespaces to (namespace, prefix, title)
     values.
     """
     from trac.wiki.model import WikiPage
     map = {}
     content = WikiPage(self.env, InterWikiMap._page_name).text
     in_map = False
     for line in content.split('\n'):
         if in_map:
             if line.startswith('----'):
                 in_map = False
             else:
                 m = re.match(InterWikiMap._interwiki_re, line)
                 if m:
                     prefix, url, title = m.groups()
                     url = url.strip()
                     title = title.strip() if title else prefix
                     map[prefix.upper()] = (prefix, url, title)
         elif line.startswith('----'):
             in_map = True
     for prefix, value in self.interwiki_section.options():
         value = value.split(None, 1)
         if value:
             url = value[0].strip()
             title = value[1].strip() if len(value) > 1 else prefix
             map[prefix.upper()] = (prefix, url, title)
     return map
Beispiel #8
0
def main():
    names = sorted(name for name in resource_listdir('trac.wiki',
                                                     'default-pages')
                        if not name.startswith('.'))

    env = EnvironmentStub()
    load_components(env)
    with env.db_transaction:
        for name in names:
            wiki = WikiPage(env, name)
            wiki.text = resource_string('trac.wiki', 'default-pages/' +
                                        name).decode('utf-8')
            if wiki.text:
                wiki.save('trac', '')
            else:
                printout('%s: Skipped empty page' % name)

    req = Mock(href=Href('/'), abs_href=Href('http://trac.edgewall.org/'),
               perm=MockPerm(), chrome={})
    for name in sys.argv[1:]:
        name = os.path.basename(name)
        wiki = WikiPage(env, name)
        if not wiki.exists:
            continue
        context = web_context(req, wiki.resource, absurls=True)
        rst = wiki2rest(env, context, wiki)
        sys.stdout.write(rst)
 def initialize_agilo(self, project_name, db_url, svn_repo, demo=False):
     try:
         self.do_initenv('%s %s %s %s' % (project_name,
                                          db_url, 'svn', 
                                          svn_repo or 'somewhere'))
         # Now add agilo and the template path
         env = Environment(self.envname)
         ac = AgiloConfig(env)
         if not svn_repo:
             # remove the fake from the config
             ac.change_option('repository_dir', '', 'trac')
         # sets the restric_owner option
         ac.change_option('restrict_owner',
                          'true',
                          'ticket')
         # this is also saving the config
         ac.enable_agilo()
         # update wiki
         wiki = WikiPage(env, name='WikiStart')
         wiki.text = agilo_wiki
         wiki.save('admin', 'Updated to Agilo', '127.0.0.1')
         # reset the env
         self.env_set(envname=self.envname, env=env)
         # Now initialize Agilo
         self.do_upgrade('upgrade --no-backup')
         # Now create the demo if needed
         if demo:
             try:
                 from create_demo_data import _create_demo_data
                 _create_demo_data(env)
             except ImportError, e:
                 env.log.error(exception_to_unicode(e))
     except:
         pass
Beispiel #10
0
    def get_default_version(self, name):
        """Return default viewable version number for the named page.
        Called when the wiki UI is rendering a page with no 'version='
        in the HTTP request arguments.

        In this method, you'd normally do db lookups and so on to
        determine what the default viewable version of the named page
        is, and then return it; for this example, we're just going to
        pick a random page version instead.
        """
        db = self.env.get_db_cnx()
        page = WikiPage(self.env, name, 1)
        history = page.get_history(all_versions=1)
        try:
            # get highest version number
            (version,time,author,comment,ipnr) = history.next()
            # here's a twist; we can enable Wikipedia-style talk
            # pages which are *not* under workflow control 
            if name.endswith("/Talk"):
                return version
            # make some debug noise
            import random, sys
            print >>sys.stderr, "highest version", version
            # randomize the version number
            version = random.randint(1,version)
            print >>sys.stderr, "random version", version
            return version
        except:
            # returning None means that the default wiki "last edit
            # wins" behavior will be used instead
            return None
Beispiel #11
0
def main():
    options, args = parse_args()
    names = sorted(name for name in resource_listdir('trac.wiki',
                                                     'default-pages')
                        if not name.startswith('.'))
    if args:
        args = sorted(set(names) & set(map(os.path.basename, args)))
    else:
        args = names

    if options.download:
        download_default_pages(args, options.prefix)

    env = EnvironmentStub()
    load_components(env)
    with env.db_transaction:
        for name in names:
            wiki = WikiPage(env, name)
            wiki.text = resource_string('trac.wiki', 'default-pages/' +
                                        name).decode('utf-8')
            if wiki.text:
                wiki.save('trac', '')
            else:
                printout('%s: Skipped empty page' % name)

    req = Mock(href=Href('/'), abs_href=Href('http://localhost/'),
               perm=MockPerm())
    for name in args:
        wiki = WikiPage(env, name)
        if not wiki.exists:
            continue
        context = web_context(req, wiki.resource)
        out = DummyIO()
        DefaultWikiChecker(env, context, name).format(wiki.text, out)
Beispiel #12
0
def add_pages(tc, names):
    now = datetime.now(utc)
    for name in names:
        w = WikiPage(tc.env)
        w.name = name
        w.text = "--"
        w.save("joe", "the page " + name, "::1", now)
Beispiel #13
0
def copy_wiki_page(source_env, dest_env, name, dest_db=None):
    # In case a string gets passed in
    if not isinstance(source_env, Environment):
        source_env = _open_environment(source_env)
    if not isinstance(dest_env, Environment):
        dest_env = _open_environment(dest_env)
        
    # Log message
    source_env.log.info('DatamoverPlugin: Moving page %s to the environment at %s', name, dest_env.path)
    dest_env.log.info('DatamoverPlugin: Moving page %s from the environment at %s', name, source_env.path)
        
    # Open databases
    source_db = source_env.get_db_cnx()
    source_cursor = source_db.cursor()
    handle_commit = True
    if not dest_db:
        dest_db, handle_commit = dest_env.get_db_cnx(), False
    dest_cursor = dest_db.cursor()
    
    # Remove the page from the destination
    dest_page = WikiPage(dest_env, name, db=dest_db)
    if dest_page.exists:
        dest_page.delete(db=dest_db)

    # Copy each entry in the wiki table
    source_cursor.execute('SELECT * FROM wiki WHERE name=%s',(name,))
    for row in source_cursor:
        wiki_data = dict(zip([d[0] for d in source_cursor.description], row))
        q = make_query(wiki_data, 'wiki')
        dest_cursor.execute(*q)
       
    if handle_commit:
        dest_db.commit()
    def save_wiki_data(self, req):
        page = WikiPage(self.env, self.name)
        if not page.exists:
            self.log.error('Wiki page "%s" doesn\'t exist' % self.name)
            return None

        lines = page.text.split('\n')
        first = -1
        last = -1
        new_lines = []

        for index, line in enumerate(lines):
            if first < 0:
                new_lines.append(line)
                if self.data_start_regexp.match(line):
                    first = index + 1
                    new_lines.append(self.get_json(False, True))
            elif last < 0:
                if self.data_end_regexp.match(line):
                    last = index - 1
                    new_lines.append(line)
            else:
                new_lines.append(line)

        if last > 0:
            page.text = '\n'.join(new_lines)
            try:
                page.save(req.authname, 'Kanban board data changed', req.remote_addr)
            except TracError as e:
                self.log.error('TracError: "%s"' % e.message)
    def import_wiki_pages(self, template_path):
        """Creates wiki pages from wiki.xml template file.

        Creates wiki pages inside the project using data extracted from
        an wiki.ml file. We don't set the author or version as that wouldn't 
        be applicable to a new project.
        """

        # open the wiki XML file, parse the data and create wiki pages
        full_path = os.path.join(template_path, 'wiki.xml')
        try:
            tree = ET.ElementTree(file=full_path)
            for page in tree.getroot():
                if page.text:
                    wikipage = WikiPage(self.env, page.attrib['name'])
                    wikipage.readonly = int(page.attrib['readonly']) # we store as a string in xml
                    wikipage.text = page.text
                    wikipage.save(None, None, None)
                    self.log.info("Wiki page %s created", page.attrib['name'])
                else:
                    self.log.debug("Cannot create wiki pages with no text. "
                                   "Unable to import %s", wikipage)
        except IOError as exception:
            if exception.errno == errno.ENOENT:
                self.log.info("Path to wiki.xml file %s does not exist. Unable "
                              "to import wiki pages from template.", full_path)
Beispiel #16
0
 def _do_wiki_upgrade(self):
     """Move all wiki pages starting with Trac prefix to unbranded user
     guide pages.
     """
     wiki_admin = WikiAdmin(self.env)
     pages = wiki_admin.get_wiki_list()
     for old_name in pages:
         if old_name.startswith('Trac'):
             new_name = wiki.new_name(old_name)
             if not new_name:
                 continue
             if new_name in pages:
                 printout(_('Ignoring %(page)s : '
                            'The page %(new_page)s already exists',
                            page=old_name, new_page=new_name))
                 continue
             try:
                 wiki_admin._do_rename(old_name, new_name)
             except AdminCommandError, exc:
                 printout(_('Error moving %(page)s : %(message)s',
                            page=old_name, message=unicode(exc)))
             else:
                 # On success, rename links in other pages
                 self._do_wiki_rename_links(old_name, new_name)
                 # On success, insert redirection page
                 redirection = WikiPage(self.env, old_name)
                 redirection.text = _('See [wiki:"%(name)s"].', name=new_name)
                 comment = 'Bloodhound guide update'
                 redirection.save('bloodhound', comment, '0.0.0.0')
Beispiel #17
0
        def do_upgrade_environment(db):
            for realm in self.SCHEMA:
                realm_schema = self.SCHEMA[realm]

                if need_db_create_for_realm(self.env, realm, realm_schema, db):
                    create_db_for_realm(self.env, realm, realm_schema, db)

                elif need_db_upgrade_for_realm(self.env, realm, realm_schema, db):
                    upgrade_db_for_realm(self.env, 'testmanager.upgrades', realm, realm_schema, db)
                    
            # Create default values for configuration properties and initialize counters
            db_insert_or_ignore(self.env, 'testconfig', 'NEXT_CATALOG_ID', '0', db)
            db_insert_or_ignore(self.env, 'testconfig', 'NEXT_TESTCASE_ID', '0', db)
            db_insert_or_ignore(self.env, 'testconfig', 'NEXT_PLAN_ID', '0', db)
            
            db.commit()

            # Fix templates with a blank id
            if self._check_blank_id_templates(db):
                self._fix_blank_id_templates(db)
                db.commit()
                self.env.log.info(_("""
    Test Manager templates with blank IDs have been fixed.\n
    Please go to the Administration panel, in the Test Manager Templates
    section, and check the associations between templates and Test Cases 
    and Test Catalogs.\n
    You will have to manually fix any misconfiguration you should find.
                    """))
          
            # Create the basic "TC" Wiki page, used as the root test catalog
            tc_page = WikiPage(self.env, 'TC')
            if not tc_page.exists:
                tc_page.text = ' '
                tc_page.save('System', '', '127.0.0.1')
            
                db.commit()
            
            if self._need_upgrade(db):
                # Set custom ticket field to hold related test case
                custom = self.config['ticket-custom']
                config_dirty = False
                if 'testcaseid' not in custom:
                    custom.set('testcaseid', 'text')
                    custom.set('testcaseid.label', _("Test Case"))
                    config_dirty = True
                if 'planid' not in custom:
                    custom.set('planid', 'text')
                    custom.set('planid.label', _("Test Plan"))
                    config_dirty = True

                # Set config section for test case outcomes
                if 'test-outcomes' not in self.config:
                    self.config.set('test-outcomes', 'green.SUCCESSFUL', _("Successful"))
                    self.config.set('test-outcomes', 'yellow.TO_BE_TESTED', _("Untested"))
                    self.config.set('test-outcomes', 'red.FAILED', _("Failed"))
                    self.config.set('test-outcomes', 'default', 'TO_BE_TESTED')
                    config_dirty = True

                if config_dirty:
                    self.config.save()
Beispiel #18
0
 def delete_wiki_page_in_trac(self, filename):
     page = WikiPage(self.env, filename)
     page.delete()
     conn = self.env.get_db_cnx()
     c = conn.cursor()
     c.execute("DELETE FROM wiki_local WHERE name = '%s'" % filename)
     conn.commit()
     conn.close()
Beispiel #19
0
    def process_request(self, req):
        action = req.args.get("action", "view")
        pagename = req.args.get("page", "WikiStart")
        version = req.args.get("version")

        db = self.env.get_db_cnx()
        page = WikiPage(self.env, pagename, version, db)
        ##########
        # readonly hack. if user created page originally, user can edit readonly
        # page.readonly = 0 allows wiki.css to show edit buttons
        if page.readonly == 1 and action == "view" and not req.perm.has_permission("WIKI_ADMIN"):
            cursor = db.cursor()
            # cursor.execute("SELECT * FROM wiki WHERE author=%s AND name=%s ORDER BY version ASC LIMIT 1", (req.authname,pagename) )
            cursor.execute("SELECT * FROM wiki WHERE author=%s AND name=%s AND version=1", (req.authname, pagename))
            if cursor.fetchone():
                page.readonly = 0
        ##########
        add_stylesheet(req, "common/css/wiki.css")

        if req.method == "POST":
            if action == "edit":
                latest_version = WikiPage(self.env, pagename, None, db).version
                if req.args.has_key("cancel"):
                    req.redirect(self.env.href.wiki(page.name))
                elif int(version) != latest_version:
                    action = "collision"
                    self._render_editor(req, db, page)
                elif req.args.has_key("preview"):
                    action = "preview"
                    self._render_editor(req, db, page, preview=True)
                else:
                    self._do_save(req, db, page)
            elif action == "delete":
                self._do_delete(req, db, page)
            elif action == "diff":
                get_diff_options(req)
                req.redirect(self.env.href.wiki(page.name, version=page.version, action="diff"))
        elif action == "delete":
            self._render_confirm(req, db, page)
        elif action == "edit":
            self._render_editor(req, db, page)
        elif action == "diff":
            self._render_diff(req, db, page)
        elif action == "history":
            self._render_history(req, db, page)
        else:
            if req.args.get("format") == "txt":
                req.send_response(200)
                req.send_header("Content-Type", "text/plain;charset=utf-8")
                req.end_headers()
                req.write(page.text)
                return
            self._render_view(req, db, page)

        req.hdf["wiki.action"] = action
        req.hdf["wiki.page_name"] = page.name
        req.hdf["wiki.current_href"] = self.env.href.wiki(page.name)
        return "wiki.cs", None
Beispiel #20
0
 def _process_page(self, page, author = None, comment = None, ipnr = None):
   
   if self.boilerplate_start_re.search( page.text ) != None:
     
     # If the audit info isn't available, grab it from the boilerplate page.
     if author == None or comment == None:
       page = WikiPage( self.env, page.name )
     if author == None:
       author = page.author
     if comment == None:
       comment = page.comment
     if ipnr == None:
       ipnr = '127.0.0.1' # I don't know what else to do here.
     
     # Extract the boilerplate text and the wanted pages.
     buf = StringIO()
     page_list = {}
     inboilerplate = False
     for line in page.text.splitlines():
       if inboilerplate:
         if self.boilerplate_end_re.search( line ) != None:
           inboilerplate = False
         else:
           buf.write( line )
           buf.write( '\n' )
       else:
         if self.boilerplate_start_re.search( line ) != None:
           inboilerplate = True
         else:
           if line.startswith('||') and line.endswith('||') and line[3] != "'":
             try:
               descriptor = ([i.strip() for i in line.strip('||').split('||')])
               name = descriptor[0]
               arguments = descriptor[1:]
               m = self.extractpagename_re.search( name )
               if m != None:
                 name = m.string[m.start(1):m.end(1)]
                 self.env.log.warning("extracted name = " + name )
               page_list[ name ] = arguments
             except Exception, e:
               self.env.log.warning("Invalid page line: %s (%s)", line, e)
     
     # Generate the derived pages as instructed.
     page_names = page_list.keys()
     page_names.sort()
     for name in page_names:
       text = buf.getvalue()
       args = page_list[ name ]
       text = text.replace( '{{0}}', name )
       i = 0
       for arg in args:
         text = text.replace('{{%d}}' % (i+1), args[i])
         i += 1
       newpage = WikiPage( self.env, name )
       if newpage.text != text:
         newpage.text = text
         newpage.save( author, comment, ipnr )
Beispiel #21
0
 def do_rename(db):
     page.rename(new_name)
     if redirect:
         redirection = WikiPage(self.env, old_name, db=db)
         redirection.text = _('See [wiki:"%(name)s"].', name=new_name)
         author = get_reporter_id(req)
         comment = u'[wiki:"%s@%d" %s] \u2192 [wiki:"%s"].' % (
                   new_name, old_version, old_name, new_name)
         redirection.save(author, comment, req.remote_addr)
Beispiel #22
0
 def deletePage(self, req, name, version=None):
     """Delete a Wiki page (all versions) or a specific version by
     including an optional version number. Attachments will also be
     deleted if page no longer exists. Returns True for success."""
     wp = WikiPage(self.env, name, version)
     req.perm(wp.resource).require("WIKI_DELETE")
     try:
         wp.delete(version)
         return True
     except:
         return False
Beispiel #23
0
    def user_created(self, user, password):
        req = FakeRequest(self.env, user)
        resource = Resource('wiki', user)
        tag_system = TagSystem(self.env)
        tag_system.add_tags(req, resource, ['user',])

        page = WikiPage(self.env, user)
        page.text = '''= %(user)s =\n\n[[ListTagged(%(user)s)]]\n''' % {'user' : user}
        page.save(user, 'New user %s registered' % user, None)

        self.env.log.debug("New user %s registered" % user)
Beispiel #24
0
    def _render_editor(self, req, page, action='edit', has_collision=False):
        if has_collision:
            if action == 'merge':
                page = WikiPage(self.env, page.name, version=None)
                req.perm(page.resource).require('WIKI_VIEW')
            else:
                action = 'collision'

        if page.readonly:
            req.perm(page.resource).require('WIKI_ADMIN')
        else:
            req.perm(page.resource).require('WIKI_MODIFY')
        original_text = page.text
        if 'text' in req.args:
            page.text = req.args.get('text')
        elif 'template' in req.args:
            template = self.PAGE_TEMPLATES_PREFIX + req.args.get('template')
            template_page = WikiPage(self.env, template)
            if template_page and template_page.exists and \
                   'WIKI_VIEW' in req.perm(template_page.resource):
                page.text = template_page.text
        if action == 'preview':
            page.readonly = 'readonly' in req.args

        author = get_reporter_id(req, 'author')
        comment = req.args.get('comment', '')
        editrows = req.args.get('editrows')
        
        if editrows:
            pref = req.session.get('wiki_editrows', '20')
            if editrows != pref:
                req.session['wiki_editrows'] = editrows
        else:
            editrows = req.session.get('wiki_editrows', '20')

        data = self._page_data(req, page, action)
        data.update({
            'author': author,
            'comment': comment,
            'edit_rows': editrows,
            'scroll_bar_pos': req.args.get('scroll_bar_pos', ''),
            'diff': None,
        })
        if action in ('diff', 'merge'):
            old_text = original_text and original_text.splitlines() or []
            new_text = page.text and page.text.splitlines() or []
            diff_data, changes = self._prepare_diff(
                req, page, old_text, new_text, page.version, '')
            data.update({'diff': diff_data, 'changes': changes,
                         'action': 'preview', 'merge': action == 'merge',
                         'longcol': 'Version', 'shortcol': 'v'})
        
        self._wiki_ctxtnav(req, page)
        return 'wiki_edit.html', data, None
Beispiel #25
0
    def setUp(self):
        self.env = EnvironmentStub(enable=[AutoWikify])
        self.req = Mock(
            authname='anonymous', perm=MockPerm(), tz=None, args={},
            href=Href('/'), abs_href=Href('http://www.example.com/'))
        self.autowikify = AutoWikify(self.env)

        for name in (u'autowikify', u'あいうName', u'Nameあいう',
                     u'かきくけこ'):
            page = WikiPage(self.env, name)
            page.text = name
            page.save('admin', '', '::1')
        self.context = Context.from_request(self.req, WikiPage(self.env, name))
Beispiel #26
0
    def upgrade_environment(self, db):
        # Create or update db
        for realm in self.SCHEMA:
            realm_metadata = self.SCHEMA[realm]

            if need_db_create_for_realm(self.env, realm, realm_metadata, db):
                create_db_for_realm(self.env, realm, realm_metadata, db)

            elif need_db_upgrade_for_realm(self.env, realm, realm_metadata, db):
                upgrade_db_for_realm(self.env, 'testmanager.upgrades', realm, realm_metadata, db)

        # Create default values for configuration properties and initialize counters
        db_insert_or_ignore(self.env, 'testconfig', 'NEXT_CATALOG_ID', '0')
        db_insert_or_ignore(self.env, 'testconfig', 'NEXT_TESTCASE_ID', '0')
        db_insert_or_ignore(self.env, 'testconfig', 'NEXT_PLAN_ID', '0')
        
        # Create the basic "TC" Wiki page, used as the root test catalog
        tc_page = WikiPage(self.env, 'TC')
        if not tc_page.exists:
            tc_page.text = ' '
            tc_page.save('System', '', '127.0.0.1')
        
        if self._need_upgrade(db):
            # Set custom ticket field to hold related test case
            custom = self.config['ticket-custom']
            config_dirty = False
            if 'testcaseid' not in custom:
                custom.set('testcaseid', 'text')
                custom.set('testcaseid.label', _("Test Case"))
                config_dirty = True
            if 'planid' not in custom:
                custom.set('planid', 'text')
                custom.set('planid.label', _("Test Plan"))
                config_dirty = True

            # Set config section for test case outcomes
            if 'test-outcomes' not in self.config:
                self.config.set('test-outcomes', 'green.SUCCESSFUL', _("Successful"))
                self.config.set('test-outcomes', 'yellow.TO_BE_TESTED', _("Untested"))
                self.config.set('test-outcomes', 'red.FAILED', _("Failed"))
                self.config.set('test-outcomes', 'default', 'TO_BE_TESTED')
                config_dirty = True

            # Set config section for default visible columns in tabular view
            if self.config.get('testmanager', 'testcatalog.visible_description') == '':
                self.config.set('testmanager', 'testcatalog.visible_description', 'False')
                config_dirty = True
                
            if config_dirty:
                self.config.save()
Beispiel #27
0
	def _controller_import(self, req, cat, page, component):
		""" Performs import. """

		# Data to be passed to view
		data = {'operations': {}}

		# User selected pages
		selected_pages = req.args.get('wikiimport_selected_pages')

		# User has selected some pages
		if selected_pages:

			# Choose between preconfigured and raw instance
			if req.args.get('wikiimport_instance_path'):
				data['instance_path'] = req.args.get('wikiimport_instance_path')
				source_env = Environment(data['instance_path'])
				instance_identifier = data['instance_path']
			else:
				data['instance_id'] = req.args.get('wikiimport_instance_id')
				source_env = self._get_instance_env(data['instance_id'])
				instance_identifier = data['instance_id']

			# Get operations to be performed
			data['operations'] = self._get_page_operations(source_env, self.env)

			# This is required in order to display pages list alphabetically
			data['sorted_pages'] = data['operations'].keys()
			data['sorted_pages'].sort()

			# Discard operation for pages that were unchecked on the preview page
			for page in data['sorted_pages']:
				if page not in selected_pages: 
					del data['operations'][page]

			# Update local wiki
			for page, operation in data['operations'].items():
				source_page = WikiPage(source_env, page)
				local_page = WikiPage(self.env, page)
				local_page.text = source_page.text
				local_page.save(
					get_reporter_id(req, 'author'), 
					'Importing pages from "%s" using [http://trac-hacks.org/wiki/WikiImportPlugin WikiImport plugin].' % instance_identifier,
					req.remote_addr
				)

		# Add stylesheet to view
		add_stylesheet(req, 'wikiimport/css/wikiimport.css');

		return 'admin_wikiimport_import.html', data
Beispiel #28
0
    def _do_rename(self, req, page):
        if page.readonly:
            req.perm(page.resource).require('WIKI_ADMIN')
        else:
            req.perm(page.resource).require('WIKI_RENAME')

        if 'cancel' in req.args:
            req.redirect(get_resource_url(self.env, page.resource, req.href))

        old_name, old_version = page.name, page.version
        new_name = req.args.get('new_name', '')
        new_name = re.sub(r'/{2,}', '/', new_name.strip('/'))
        redirect = req.args.get('redirect')

        # verify input parameters
        warn = None
        if not new_name:
            warn = _("A new name is mandatory for a rename.")
        elif not validate_page_name(new_name):
            warn = _("The new name is invalid (a name which is separated "
                     "with slashes cannot be '.' or '..').")
        elif new_name == old_name:
            warn = _("The new name must be different from the old name.")
        elif WikiPage(self.env, new_name).exists:
            warn = _("The page %(name)s already exists.", name=new_name)
        if warn:
            add_warning(req, warn)
            return self._render_confirm_rename(req, page, new_name)

        with self.env.db_transaction as db:
            page.rename(new_name)
            if redirect:
                redirection = WikiPage(self.env, old_name, db=db)
                redirection.text = _('See [wiki:"%(name)s"].', name=new_name)
                author = get_reporter_id(req)
                comment = u'[wiki:"%s@%d" %s] \u2192 [wiki:"%s"].' % (
                          new_name, old_version, old_name, new_name)
                redirection.save(author, comment, req.remote_addr)

        add_notice(req, _("The page %(old_name)s has been renamed to "
                          "%(new_name)s.", old_name=old_name,
                          new_name=new_name))
        if redirect:
            add_notice(req, _("The page %(old_name)s has been recreated "
                              "with a redirect to %(new_name)s.",
                              old_name=old_name, new_name=new_name))

        req.redirect(req.href.wiki(old_name if redirect else new_name))
Beispiel #29
0
    def putPage(self, req, pagename, content, attributes):
        """ writes the content of the page. """
        page = WikiPage(self.env, pagename)
        if page.readonly:
            req.perm(page.resource).require("WIKI_ADMIN")
        elif not page.exists:
            req.perm(page.resource).require("WIKI_CREATE")
        else:
            req.perm(page.resource).require("WIKI_MODIFY")

        page.text = content
        if req.perm(page.resource).has_permission("WIKI_ADMIN"):
            page.readonly = attributes.get("readonly") and 1 or 0

        page.save(attributes.get("author", req.authname), attributes.get("comment"), req.remote_addr)
        return True
def Main(opts):
    """ Cross your fingers and pray """
    env = Environment(opts.envpath)
    from tractags.api import TagSystem

    tlist = opts.tags or split_tags(env.config.get('blog', 'default_tag', 
                                                   'blog'))
    tags = TagSystem(env)
    req = Mock(perm=MockPerm())
    blog = tags.query(req, ' '.join(tlist + ['realm:wiki']))
                   
    cnx = env.get_db_cnx()
    for resource, page_tags in list(blog):
        try:
            page = WikiPage(env, version=1, name=resource.id)
            _, publish_time, author, _, _ =  page.get_history().next()
            if opts.deleteonly:
                page.delete()
                continue
            categories = ' '.join([t for t in page_tags if t not in tlist])
            page = WikiPage(env, name=resource.id)
            for version, version_time, version_author, version_comment, \
                _ in page.get_history():
                # Currently the basename of the post url is used due to 
                # http://trac-hacks.org/ticket/2956
                #name = resource.id.replace('/', '_')
                name = resource.id
                # extract title from text:
                fulltext = page.text
                match = _title_split_match(fulltext)
                if match:
                    title = match.group(1)
                    fulltext = match.group(2)
                else: 
                    title = name
                body = fulltext
                print "Adding post %s, v%s: %s" % (name, version, title)
                insert_blog_post(cnx, name, version, title, body,
                                 publish_time, version_time, 
                                 version_comment, version_author, author,
                                 categories)
                reparent_blog_attachments(env, resource.id, name)
                continue
            cnx.commit()
            if opts.delete:
                page.delete()
                continue
        except:
            env.log.debug("Error loading wiki page %s" % resource.id, 
                          exc_info=True)
            print "Failed to add post %s, v%s: %s" % (name, version, title)
            cnx.rollback()
            cnx.close()
            return 1
    cnx.close()
    return 0
Beispiel #31
0
    def process_request(self, req):
        req.perm.assert_permission('PHPDOC_VIEW')

        # Get request arguments
        path = req.args.get('path')
        action = req.args.get('action')
        link = req.args.get('link')

        self.log.debug('Performing %s(%s,%s)"' %
                       (action or 'default', path, link))

        # Redirect search requests.
        if action == 'search':
            req.redirect(req.href.search(q=req.args.get('query'), phpdoc='on'))
        if action == 'redirect':
            if link:  # we need to really redirect if there is a link
                if path:
                    req.redirect(req.href.phpdoc(path=path) + link)
                else:
                    req.redirect(req.href.phpdoc(link))
            else:
                self.log.warn("redirect without link")

        if req.path_info == '/phpdoc':
            req.redirect(req.href.phpdoc('/'))

        # Handle /phpdoc request
        if action == 'index':
            wiki = self.wiki_index
            if wiki:
                if WikiSystem(self.env).has_page(wiki):
                    text = WikiPage(self.env, wiki).text
                else:
                    text = 'PHPDoc index page [wiki:%s] does not exist.' % \
                           wiki
                data = {'phpdoc_text': wiki_to_html(text, self.env, req)}
                add_ctxtnav(req, "View %s page" % wiki, req.href.wiki(wiki))
                return 'phpdoc.html', data, 'text/html'
            # use configured PHPDoc index
            path = os.path.join(self.base_path, self.default_doc,
                                self.html_output, self.index)

        self.log.debug('path: %s' % (path, ))

        # security check
        path = os.path.abspath(path)
        if not path.startswith(self.base_path):
            raise TracError("Can't access paths outside of " + self.base_path)

        # view
        mimetype = mimetypes.guess_type(path)[0]
        if mimetype == 'text/html':
            add_stylesheet(req, 'phpdoc/css/phpdoc.css')
            # Genshi can't include an unparsed file
            # data = {'phpdoc': path}
            try:
                charset = (self.encoding
                           or self.env.config['trac'].get('default_charset'))
                content = Markup(to_unicode(file(path).read(), charset))
                data = {'phpdoc_content': content}
                return 'phpdoc.html', data, 'text/html'
            except OSError, e:
                raise TracError("Can't read phpdoc content: %s" % e)
Beispiel #32
0
    def setUp(self):
        ProductResourceTestCase.setUp(self)

        page = WikiPage(self.global_env)
        page.name = 'TestPage'
        page.text = 'Bla bla'
        t = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
        page.save('joe', 'Testing global', '::1', t)
        page.text = 'Bla bla bla'
        t = datetime(2002, 2, 2, 2, 2, 2, 0, utc)
        page.save('joe', 'Testing global 2', '::1', t)

        page = WikiPage(self.env1)
        page.name = 'TestPage'
        page.text = 'alb alB'
        t = datetime(2011, 1, 1, 1, 1, 1, 0, utc)
        page.save('mary', 'Testing product', '::1', t)
        page.text = 'Bla bla bla'
        t = datetime(2012, 2, 2, 2, 2, 2, 0, utc)
        page.save('mary', 'Testing product 2', '::1', t)
    def expand_macro(self, formatter, name, content):
        req = formatter.req
        args, kwargs = parse_args(content)
        args += [None, None]
        path, limit = args[:2]
        limit = kwargs.pop('limit', limit)
        package = kwargs.pop('package', None)

        if 'CHANGESET_VIEW' not in req.perm:
            return Markup('<i>Releases not available</i>')

        rm = RepositoryManager(self.env)
        reponame, repo, path = rm.get_repository_by_path(path)

        rev = repo.get_youngest_rev()
        rev = repo.normalize_rev(rev)
        path = repo.normalize_path(path)
        if limit is None:
            limit = 20
        else:
            limit = int(limit)

        releases = self.get_releases(repo, path, rev)

        # limit the releases after they have been sorted
        releases = releases[:1 + limit]
        items = []
        releases = [None] + releases + [None]

        # some extra checks to avoid using double-slashes
        if reponame == '':
            if path == '/':
                path = ''
            else:
                path = '/' + path
        elif path == '/':
            path = '/' + reponame.rstrip('/')
        else:
            path = '/' + reponame.rstrip('/') + '/' + path.lstrip('/')

        if not package:
            package = path.split("/")[-1]

        for i in xrange(len(releases) - 2):
            prev, cur, next = releases[i:i + 3]

            if prev == None and next == None:
                # no releases yet, just show trunk
                items.append(" * "
                             " [/browser%(path)s/trunk trunk]"
                             " @[changeset:%(rev)s/%(reponame)s %(rev)s]"
                             " ("
                             "[/log%(path)s/trunk changes]"
                             " [/changeset?new_path=%(path)s/trunk diffs]"
                             ")" % {
                                 'reponame': reponame,
                                 'path': path,
                                 'rev': cur['rev'],
                             })
            elif prev == None:
                # first entry = trunk
                items.append(
                    " * "
                    " [/browser%(path)s/trunk trunk]"
                    " @[changeset:%(rev)s/%(reponame)s %(rev)s]"
                    " ("
                    "[/log%(path)s/trunk?revs=%(stop_rev)s-%(rev)s changes]"
                    " [/changeset?old_path=%(path)s/tags/%(old_tag)s&new_path=%(path)s/trunk diffs]"
                    ")" % {
                        'reponame': reponame,
                        'path': path,
                        'rev': cur['rev'],
                        'old_tag': next['version'],
                        'stop_rev': next['rev'],
                    })
            elif next != None:
                # regular releases
                release_page = 'release/%s-%s' % (package, cur['version'])
                page = WikiPage(self.env, release_page)
                if page.exists:
                    release_link = " [wiki:%s release notes]" % (release_page)
                else:
                    release_link = ""

                items.append(
                    " * '''%(date)s'''"
                    " [/log%(path)s/tags/%(new_tag)s %(new_tag)s] "
                    " @[changeset:%(rev)s/%(reponame)s %(rev)s]"
                    " by %(author)s"
                    " ("
                    "[/log%(path)s/trunk?revs=%(stop_rev)s-%(rev)s changes]"
                    " [/changeset?old_path=%(path)s/tags/%(old_tag)s&new_path=%(path)s/tags/%(new_tag)s diffs]"
                    "%(release_link)s"
                    ")" % {
                        'reponame': reponame,
                        'path': path,
                        'date': cur['time'].strftime('%Y-%m-%d'),
                        'rev': cur['rev'],
                        'stop_rev': next['rev'],
                        'old_tag': next['version'],
                        'new_tag': cur['version'],
                        'author': cur['author'],
                        'release_link': release_link,
                    })
                url = self.specurl_annotate(cur)
                if url != None:
                    annotate = " spec: [%s annotate]" % url
                    items.append(annotate)
                    # check also diff link
                    url = self.specurl_diff(cur, next)
                    if url != None:
                        annotate = " [%s diff]" % url
                        items.append(annotate)
            else:
                # last release
                items.append(
                    " * '''%(date)s'''"
                    " [/log%(path)s/tags/%(new_tag)s?rev=%(rev)s&mode=follow_copy %(new_tag)s]"
                    " @[changeset:%(rev)s/%(reponame)s %(rev)s]"
                    " by %(author)s" % {
                        'reponame': reponame,
                        'path': path,
                        'date': cur['time'].strftime('%Y-%m-%d'),
                        'rev': cur['rev'],
                        'new_tag': cur['version'],
                        'author': cur['author'],
                    })

        return '<div class="releases">\n' + to_unicode(
            wiki_to_html("\n".join(items), self.env, req)) + '</div>\n'
Beispiel #34
0
    def _render_diff(self, req, page):
        if not page.exists:
            raise TracError(
                _('Version %(num)s of page "%(name)s" does not '
                  'exist',
                  num=req.args.get('version'),
                  name=page.name))

        old_version = req.args.get('old_version')
        if old_version:
            old_version = int(old_version)
            if old_version == page.version:
                old_version = None
            elif old_version > page.version:
                # FIXME: what about reverse diffs?
                old_version = page.resource.version
                page = WikiPage(self.env, page.name, version=old_version)
                req.perm(page.resource).require('WIKI_VIEW')
        latest_page = WikiPage(self.env, page.name, version=None)
        req.perm(latest_page.resource).require('WIKI_VIEW')
        new_version = int(page.version)

        date = author = comment = ipnr = None
        num_changes = 0
        prev_version = next_version = None
        for version, t, a, c, i in latest_page.get_history():
            if version == new_version:
                date = t
                author = a or 'anonymous'
                comment = c or '--'
                ipnr = i or ''
            else:
                if version < new_version:
                    num_changes += 1
                    if not prev_version:
                        prev_version = version
                    if old_version is None or version == old_version:
                        old_version = version
                        break
                else:
                    next_version = version
        if not old_version:
            old_version = 0
        old_page = WikiPage(self.env, page.name, old_version)
        req.perm(old_page.resource).require('WIKI_VIEW')

        # -- text diffs
        old_text = old_page.text.splitlines()
        new_text = page.text.splitlines()
        diff_data, changes = self._prepare_diff(req, page, old_text, new_text,
                                                old_version, new_version)

        # -- prev/up/next links
        if prev_version:
            add_link(
                req, 'prev',
                req.href.wiki(page.name, action='diff', version=prev_version),
                _('Version %(num)s', num=prev_version))
        add_link(req, 'up', req.href.wiki(page.name, action='history'),
                 _('Page history'))
        if next_version:
            add_link(
                req, 'next',
                req.href.wiki(page.name, action='diff', version=next_version),
                _('Version %(num)s', num=next_version))

        data = self._page_data(req, page, 'diff')
        data.update({
            'change': {
                'date': date,
                'author': author,
                'ipnr': ipnr,
                'comment': comment
            },
            'new_version': new_version,
            'old_version': old_version,
            'latest_version': latest_page.version,
            'num_changes': num_changes,
            'longcol': 'Version',
            'shortcol': 'v',
            'changes': changes,
            'diff': diff_data,
        })
        prevnext_nav(req, _('Previous Change'), _('Next Change'),
                     _('Wiki History'))
        return 'wiki_diff.html', data, None
Beispiel #35
0
    def create_hack(self, req, data, vars):
        import fcntl

        messages = []
        created = False
        have_lock = False
        lockfile = open(self.lockfile, "w")
        try:
            rv = fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
            if rv:
                raise TracError('Failed to acquire lock, error: %i' % rv)
            have_lock = True
        except IOError:
            messages.append(
                'A hack is currently being created by another user. '
                'Please wait a few seconds, then click the "Create hack" '
                'button again.'
            )

        if have_lock:
            steps_done = []
            try:
                # Step 1: create repository paths
                from os import popen

                svn_path = 'file://%s' % \
                    self.env.config.get('trac', 'repository_dir')
                svn_path = svn_path.rstrip('/')
                page_name = vars['WIKINAME']
                hack_path = vars['LCNAME']
                paths = [ '%s/%s' % (svn_path, hack_path) ]
                selected_releases = data['selected_releases']
                if isinstance(selected_releases, (basestring, unicode)):
                    selected_releases = [ selected_releases, ]
                for release in selected_releases:
                    if release == 'anyrelease': continue
                    paths.append("%s/%s/%s" % \
                        (svn_path, hack_path, release))

                cmd  = '/usr/bin/op create-hack %s ' % req.authname
                cmd += '"New hack %s, created by %s" ' % \
                        (page_name, req.authname)
                cmd += '%s 2>&1' % ' '.join(paths)
                output = popen(cmd).readlines()
                if output:
                    raise Exception(
                        "Failed to create Subversion paths:\n%s" % \
                            '\n'.join(output)
                        )
                steps_done.append('repository')

                # Step 2: Add permissions
                from svnauthz.model import User, Path, PathAcl

                authz_file = self.env.config.get('trac', 'authz_file')
                authz = AuthzFileReader().read(authz_file)

                svn_path_acl = PathAcl(User(req.authname), r=True, w=True)
                authz.add_path(Path("/%s" % hack_path, acls = [svn_path_acl,]))
                AuthzFileWriter().write(authz_file, authz)
                steps_done.append('permissions')

                # Step 3: Add component
                component = TicketComponent(self.env)
                component.name = page_name
                component.owner = req.authname
                component.insert()
                steps_done.append('component')

                # Step 4: Create wiki page
                template_page = WikiPage(self.env, self.template)
                page = WikiPage(self.env, page_name)
                page.text = Template(template_page.text).substitute(vars)
                page.save(req.authname, 'New hack %s, created by %s' % \
                          (page_name, req.authname), '0.0.0.0')
                steps_done.append('wiki')

                # Step 5: Tag the new wiki page
                res = Resource('wiki', page_name)
                tags = data['tags'].split() + selected_releases + [data['type']]
                TagSystem(self.env).set_tags(req, res, tags)
                steps_done.append('tags')

                rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                created = True
            except Exception, e:
                try:
                    if 'tags' in steps_done:
                        res = Resource('wiki', page_name)
                        tags = data['tags'].split() + selected_releases
                        TagSystem(self.env).delete_tags(req, res, tags)
                    if 'wiki' in steps_done:
                        WikiPage(self.env, page_name).delete()
                    if 'component' in steps_done:
                        TicketComponent(self.env, page_name).delete()
                    if 'permissions' in steps_done:
                        authz_file = self.env.config.get('trac', 'authz_file')
                        authz = AuthzFileReader().read(authz_file)
                        authz.del_path(Path("/%s" % hack_path))
                        AuthzFileWriter().write(authz_file, authz)
                    # TODO: rollback subversion path creation
                    rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                except:
                    self.env.log.error("Rollback failed")
                    rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                self.env.log.error(e, exc_info=True)
                raise TracError(str(e))
Beispiel #36
0
def wiki_setup(tc):
    tc.env.config.set('wiki', 'render_unsafe_content', True) # for #9712
    now = datetime.now(utc)
    wiki0 = WikiPage(tc.env)
    wiki0.name = 'Main/Sub'
    wiki0.text = '--'
    wiki0.save('joe', 'subpage', '::1', now)

    wiki1 = WikiPage(tc.env)
    wiki1.name = 'TestPage'
    wiki1.text = '--'
    wiki1.save('joe', 'normal WikiPageNames', '::1', now)

    wiki2 = WikiPage(tc.env)
    wiki2.name = 'Space 1 23'
    wiki2.text = '--'
    wiki2.save('joe', 'not a WikiPageNames', '::1', now)

    wiki3 = WikiPage(tc.env)
    wiki3.name = u"C'est l'\xe9t\xe9"
    wiki3.text = '--'
    wiki3.save('joe', 'unicode WikiPageNames', '::1', now)

    imt = WikiPage(tc.env)
    imt.name = u"InterMapTxt"
    imt.text = """
This is the InterMapTxt
----
{{{
MeatBall 	http://www.usemod.com/cgi-bin/mb.pl? # $1 in MeatBall...
tsvn            tsvn:
complex         http://server/$1/page/$2?format=txt  # resource $2 in $1
over        http://unused/? # Overridden in trac.ini
}}}
----
{{{
nolink          http://noweb
}}}
""" 
    imt.save('joe', 'test InterWiki links', '::1', now)
    tc.env.config.set('interwiki', 'inter',
                      'http://inter/$1/page/$2 Resource $2 in $1')
    tc.env.config.set('interwiki', 'over',
                      'http://over/$1/page/$2')

    w = WikiPage(tc.env)
    w.name = 'FirstLevel'
    w.text = '--'
    w.save('joe', 'first level of hierarchy', '::1', now)
    
    w = WikiPage(tc.env)
    w.name = 'FirstLevel/SecondLevel'
    w.text = '--'
    w.save('joe', 'second level of hierarchy', '::1', now)
    
    w = WikiPage(tc.env)
    w.name = 'FirstLevel/SecondLevel/ThirdLevel'
    w.text = '--'
    w.save('joe', 'third level of hierarchy', '::1', now)
    
    w = WikiPage(tc.env)
    w.name = 'FirstLevel/SecondLevel/OtherThirdLevel'
    w.text = '--'
    w.save('joe', 'other third level of hierarchy', '::1', now)
Beispiel #37
0
    def fetch_hacks(self, req, data, types, releases):
        """Return a list of hacks in the form

        [votes, rank, resource, tags, title]
        """
        tag_system = TagSystem(self.env)
        vote_system = VoteSystem(self.env)

        query = 'realm:wiki (%s) (%s)' % \
                (' or '.join(releases), ' or '.join(types))
        self.env.log.debug(query)
        tagged = tag_system.query(req, query)

        # Limit
        try:
            limit = int(req.args.get('limit', self.limit))
            data['limit_message'] = 'top %s' % limit
        except ValueError:
            data['limit_message'] = 'all'
            limit = 9999
        data['limit'] = limit

        # Query
        q = req.args.get('q', '')
        data['query'] = q
        query = Query(q.lower())

        # Build hacks list
        hacks = []
        for resource, tags in tagged:
            page = WikiPage(self.env, resource.id)
            if q:
                text = page.name.lower() + page.text.lower() + ' '.join(tags)
                if not query(text):
                    continue
            _, count, _ = vote_system.get_vote_counts(resource)
            match = self.title_extract.search(page.text)
            count_string = pluralise(count, 'vote')
            if match:
                title = '%s (%s)' % (match.group(1).strip(), count_string)
            else:
                title = '%s' % count_string
            hacks.append([count, None, resource, tags, title])

        # Rank
        total_hack_count = len(hacks)
        hacks = sorted(hacks, key=lambda i: -i[0])
        remainder = hacks[limit:]
        hacks = hacks[:limit] + random.sample(remainder,
                                              min(limit, len(remainder)))

        # Navigation
        #if len(hacks) >= limit:
        #    add_ctxtnav(req, builder.a('More', href='?action=more'))
        #    limit = len(hacks)
        #    data['limit'] = data['limit_message'] = limit
        #else:
        #    add_ctxtnav(req, 'More')
        #if q or limit != self.limit:
        #    add_ctxtnav(req, builder.a('Default', href='?action=default'))
        #else:
        #    add_ctxtnav(req, 'Default')
        #if total_hack_count > limit:
        #    add_ctxtnav(req, builder.a('All', href='?action=all'))
        #else:
        #    add_ctxtnav(req, 'All')
        #if limit > 10:
        #    limit = min(limit, len(hacks))
        #    add_ctxtnav(req, builder.a('Less', href='?action=less'))
        #else:
        #    add_ctxtnav(req, 'Less')
        #for i, hack in enumerate(hacks):
        #    hack[1] = i
        return hacks
Beispiel #38
0
    def _render_view(self, req, page):
        version = page.resource.version

        # Add registered converters
        if page.exists:
            for conversion in Mimeview(
                    self.env).get_supported_conversions('text/x-trac-wiki'):
                conversion_href = req.href.wiki(page.name,
                                                version=version,
                                                format=conversion[0])
                # or...
                conversion_href = get_resource_url(self.env,
                                                   page.resource,
                                                   req.href,
                                                   format=conversion[0])
                add_link(req, 'alternate', conversion_href, conversion[1],
                         conversion[3])

        data = self._page_data(req, page)
        if page.name == 'WikiStart':
            data['title'] = ''

        ws = WikiSystem(self.env)
        context = web_context(req, page.resource)
        higher, related = [], []
        if not page.exists:
            if 'WIKI_CREATE' not in req.perm(page.resource):
                raise ResourceNotFound(
                    _('Page %(name)s not found', name=page.name))
            formatter = OneLinerFormatter(self.env, context)
            if '/' in page.name:
                parts = page.name.split('/')
                for i in range(len(parts) - 2, -1, -1):
                    name = '/'.join(parts[:i] + [parts[-1]])
                    if not ws.has_page(name):
                        higher.append(
                            ws._format_link(formatter, 'wiki', '/' + name,
                                            name, False))
            else:
                name = page.name
            name = name.lower()
            related = [
                each for each in ws.pages if name in each.lower()
                and 'WIKI_VIEW' in req.perm('wiki', each)
            ]
            related.sort()
            related = [
                ws._format_link(formatter, 'wiki', '/' + each, each, False)
                for each in related
            ]

        latest_page = WikiPage(self.env, page.name, version=None)

        prev_version = next_version = None
        if version:
            try:
                version = int(version)
                for hist in latest_page.get_history():
                    v = hist[0]
                    if v != version:
                        if v < version:
                            if not prev_version:
                                prev_version = v
                                break
                        else:
                            next_version = v
            except ValueError:
                version = None

        prefix = self.PAGE_TEMPLATES_PREFIX
        templates = [
            template[len(prefix):] for template in ws.get_pages(prefix)
            if 'WIKI_VIEW' in req.perm('wiki', template)
        ]

        # -- prev/up/next links
        if prev_version:
            add_link(req, 'prev', req.href.wiki(page.name,
                                                version=prev_version),
                     _('Version %(num)s', num=prev_version))

        parent = None
        if version:
            add_link(req, 'up', req.href.wiki(page.name, version=None),
                     _('View latest version'))
        elif '/' in page.name:
            parent = page.name[:page.name.rindex('/')]
            add_link(req, 'up', req.href.wiki(parent, version=None),
                     _("View parent page"))

        if next_version:
            add_link(req, 'next', req.href.wiki(page.name,
                                                version=next_version),
                     _('Version %(num)s', num=next_version))

        # Add ctxtnav entries
        if version:
            prevnext_nav(req, _('Previous Version'), _('Next Version'),
                         _('View Latest Version'))
        else:
            if parent:
                add_ctxtnav(req, _('Up'), req.href.wiki(parent))
            self._wiki_ctxtnav(req, page)

        # Plugin content validation
        fields = {'text': page.text}
        for manipulator in self.page_manipulators:
            manipulator.prepare_wiki_page(req, page, fields)
        text = fields.get('text', '')

        data.update({
            'context':
            context,
            'text':
            text,
            'latest_version':
            latest_page.version,
            'attachments':
            AttachmentModule(self.env).attachment_data(context),
            'default_template':
            self.DEFAULT_PAGE_TEMPLATE,
            'templates':
            templates,
            'version':
            version,
            'higher':
            higher,
            'related':
            related,
            'resourcepath_template':
            'wiki_page_path.html',
        })
        add_script(req, 'common/js/folding.js')
        return 'wiki_view.html', data, None
Beispiel #39
0
    def process_request(self, req):
        req.perm.require('WIKIMETA_VIEW')
        
        data = {}
        self.log.debug(" +++ in process_request")
        self.log.debug(dir(req.args))
        self.log.debug(req.args)
        # first process reordering:
        for key in req.args.keys():
            if key.startswith('reorder_'):
                self.log.debug(" +++ found reorder: %s" % key)
                reorder_args = key.split('_')
                self._priority_reorder(int(reorder_args[1]), int(reorder_args[2]))

        # data for state filter
        data['state_label'] = 'State:'
        data['state_options'] = ['all (non-obsolete)'] + STATES
        data['selected_state'] = 'all (non-obsolete)'
        if req.args.get('state_name') is not None:
            data['selected_state'] = req.args.get('state_name')
        # data for owner filter
        data['owner_label'] = 'Owner:'
        owner_tuples = self.env.get_known_users()
        data['owner_options'] = ['all'] + [item[0] for item in owner_tuples]
        data['selected_owner'] = 'all'
        if req.args.get('owner_name') is not None:
            data['selected_owner'] = req.args.get('owner_name')

        # data for tag filters
        combined_title = ""
        categorized_tags = self._get_categorized_tags()
        tag_states = []
        tag_list = []

        for category in categorized_tags.keys():
            tag_states.append([category, 'category'])
            for tag in categorized_tags[category]:
                if req.args.get('tagfilter_%s' % tag) is not None:
                    tag_states.append([tag, 'checked'])
                    tag_list.append(tag)
                    combined_title = '%s %s' % (tag, combined_title)
                else:
                    tag_states.append([tag, 'unchecked'])
        data['tags'] = tag_states
        data['tags_label'] = 'Tag Filter'
        if len(combined_title) == 0:
            data['combined_title'] = 'all'
        else:
            data['combined_title'] = combined_title

        # check if the user requested to add a new page:
        newpagename = req.args.get('newpagename')
        if newpagename is not None and len(newpagename) > 0:
            newpage = WikiPage(self.env, newpagename)
            currently_logged_in_user = get_reporter_id(req, 'author')
            if data['selected_owner'] == 'all':
                new_owner = currently_logged_in_user
            else:
                new_owner = data['selected_owner']
            if newpage.exists == False:
                newpage.text = 'page content goes here'
                newpage.save(author=currently_logged_in_user, comment='', remote_addr='127.0.0.1')
            # add tags and meta
            if data['selected_state'] == 'all (non-obsolete)':
                new_state = 'planned'
            else:
                new_state = data['selected_state']
            new_page_meta = PageMeta(newpagename, new_owner, new_state, 0, time.time(), currently_logged_in_user)
            new_page_meta.insert(self.env)
            tag_resource(self.env, newpage.resource, old_id=None, author=currently_logged_in_user, tags=tag_list)

        # get a top context to render the wiki data:
        context = Context.from_request(req, 'wiki')
        self.log.debug(" +++ context: ")
        self.log.debug(dir(context))
        self.log.debug(" +++ child: ")
        self.log.debug(context.child)
        self.log.debug(" +++ href: ")
        self.log.debug(context.href)
        self.log.debug(" +++ parent: ")
        self.log.debug(context.parent)

        # get the wiki pages:
        wiki_data = self._get_wiki_data(context, data['selected_state'], data['selected_owner'], tag_list)
        #self.log.debug(" +++ wiki_data:")
        #self.log.debug(wiki_data)
        data['wiki_data'] = wiki_data

        add_stylesheet(req, 'wm/css/wikimeta.css')
        # This tuple is for Genshi (template_name, data, content_type)
        # Without data the trac layout will not appear.
        return 'wikimeta.html', data, None
Beispiel #40
0
    def expand_macro(self, formatter, name, args):
        """
        Return a list of translated pages with the native language names.
        The list of languages supported can be configured by adding new
        entries to TracLanguages page. Refer to ISO 639-1 for more information.
        """

        args, kw = parse_args(args)

        # first handle special cases
        show = u""
        lang = None
        silent = u'silent' in args
        outdated = u""
        if u'lang' in kw:
            lang = kw[u'lang']
        if u'outdated' in kw:
            outdated = self.outdated_tx % kw[u'outdated']
        if u'showproblems' in args:
            show += self._get_problems(silent)
        if u'showstatus' in args:
            show += self._get_status(lang)
        if u'showoutdated' in args:
            label = None
            if u'label_outdated' in kw:
                label = kw[u'label_outdated']
            show += self._get_outdated(lang, label)
        if u'showmissing' in args:
            show += self._get_missing(lang)
        if u'showuntranslated' in args:
            show += self._get_untranslated(silent)
        if len(show):
            outshow = StringIO()
            Formatter(self.env, formatter.context).format(show, outshow)
            val = outshow.getvalue()
            val = re.sub('>\$\$\$([a-z]+?)\$\$\$<a class=".*?"', \
                ' style="background-color:\\1"><a style="color:#151B8D"', val)
            # try again more secure in case previous fails due to Wiki engine changes
            val = re.sub('>\$\$\$([a-z]+?)\$\$\$', \
                ' style="background-color:\\1">', val)
            return val

        page_name = formatter.context.resource.id
        prefix, base_page_name, lang_code = self._get_page_info(page_name)

        lang_link_list = []
        for translation in self._get_translations(prefix, base_page_name):
            if translation != lang_code:
                page_name = self._get_translated_page(prefix, base_page_name,
                                                      translation)
                lang_link_list.append(u"  * [[wiki:/%s|%s]]" % (page_name, \
                    self._get_language_name(translation)))
            else:
                lang_link_list.append(u"  * '''%s'''" %
                                      self._get_language_name(translation))

        baselink = ""
        if lang_code != self.base_lang and u'revision' in kw:
            basepage = self._get_translated_page(prefix, base_page_name,
                                                 self.base_lang)
            newver = WikiPage(self.env, basepage).version
            oldver = abs(int(kw[u'revision']))
            if oldver < newver:
                baselink = u"\n  * [[wiki:/%s?action=diff&old_version=%s|@%s - @%s]]" \
                    % (basepage, oldver, oldver, newver)

        if len(lang_link_list) <= 1:
            return outdated
        out = StringIO()
        Formatter(self.env, formatter.context).format(u'\n'.join(lang_link_list) \
            +baselink, out)

        desc = u"Languages"
        if self.description.has_key(lang_code):
            desc = self.description[lang_code]
        return outdated + u"""
<div class="wiki-toc trac-nav" style="clear:both">
<h4>%s:</h4>
%s
</div>""" % (desc, out.getvalue())
Beispiel #41
0
    def process_request(self, req):
        req.perm.require('TAGS_VIEW')

        match = re.match(r'/tags/?(.*)', req.path_info)
        tag_id = match.group(1) and match.group(1) or None
        query = req.args.get('q', '')

        # Consider only providers, that are permitted for display.
        tag_system = TagSystem(self.env)
        all_realms = tag_system.get_taggable_realms(req.perm)
        if not (tag_id or query) or [r for r in all_realms
                                     if r in req.args] == []:
            for realm in all_realms:
                if realm not in self.exclude_realms:
                    req.args[realm] = 'on'
        checked_realms = [r for r in all_realms if r in req.args]
        if query:
            # Add permitted realms from query expression.
            checked_realms.extend(query_realms(query, all_realms))
        realm_args = dict(zip([r for r in checked_realms],
                              ['on' for r in checked_realms]))
        # Switch between single tag and tag query expression mode.
        if tag_id and not re.match(r"""(['"]?)(\S+)\1$""", tag_id, re.UNICODE):
            # Convert complex, invalid tag ID's --> query expression.
            req.redirect(req.href.tags(realm_args, q=tag_id))
        elif query:
            single_page = re.match(r"""(['"]?)(\S+)\1$""", query, re.UNICODE)
            if single_page:
                # Convert simple query --> single tag.
                req.redirect(req.href.tags(single_page.group(2), realm_args))

        data = dict(page_title=_("Tags"), checked_realms=checked_realms)
        # Populate the TagsQuery form field.
        data['tag_query'] = tag_id and tag_id or query
        data['tag_realms'] = list(dict(name=realm,
                                       checked=realm in checked_realms)
                                  for realm in all_realms)
        if tag_id:
            data['tag_page'] = WikiPage(self.env,
                                        tag_system.wiki_page_prefix + tag_id)
        if query or tag_id:
            macro = 'ListTagged'
            # TRANSLATOR: The meta-nav link label.
            add_ctxtnav(req, _("Back to Cloud"), req.href.tags())
            args = "%s,format=%s,cols=%s" % \
                   (tag_id and tag_id or query, self.default_format,
                    self.default_cols)
            data['mincount'] = 0
        else:
            macro = 'TagCloud'
            mincount = as_int(req.args.get('mincount', 0),
                              self.cloud_mincount)
            args = mincount and "mincount=%s" % mincount or None
            data['mincount'] = mincount

        # When using the given req the page isn't rendered properly. The call
        # to expand_macro() leads to Chrome().render_template(req, ...).
        # The function render_template() breaks something in the request handling.
        # That used to work with Genshi.
        #
        # With this mocked req everything is just fine.
        mock_req = MockRequest(self.env, path_info=req.path_info,
                           authname=req.authname, script_name=req.href())
        formatter = Formatter(self.env, web_context(mock_req, Resource('tag')))
        self.env.log.debug("%s macro arguments: %s", macro,
                           args and args or '(none)')
        macros = TagWikiMacros(self.env)
        try:
            # Query string without realm throws 'NotImplementedError'.
            data['tag_body'] = checked_realms and \
                               macros.expand_macro(formatter, macro, args,
                                                   realms=checked_realms) \
                               or ''
            data['tag_body'] = Markup(to_unicode(data['tag_body']))
        except InvalidQuery as e:
            data['tag_query_error'] = to_unicode(e)
            data['tag_body'] = macros.expand_macro(formatter, 'TagCloud', '')

        data['realm_args'] = realm_args
        add_stylesheet(req, 'tags/css/tractags.css')
        return 'tag_view.html', data, {'domain': 'tractags'}
Beispiel #42
0
 def assertFileContentMatchesPage(self, names):
     for n in names:
         self.assertEqual(
             WikiPage(self.env, n).text,
             self._file_content(self.tempdir, n))
Beispiel #43
0
    def process_request(self, req):
        """Process the request
        """
        base = self.get_mypage_base(req.authname)
        tzinfo = getattr(req, 'tz', None)
        now = datetime.now(tzinfo or localtz)
        today = format_date(now, 'iso8601', tzinfo)
        today_page_name = base + today
        today_page = WikiPage(self.env, today_page_name)
        if today_page.exists:
            req.redirect(req.href.wiki(today_page_name, action='edit'))

        # create page of the day for today
        if 'WIKI_CREATE' not in req.perm(today_page.resource):
            raise ResourceNotFound(_("Can't create the page of the day."))
        ws = WikiSystem(self.env)

        def get_page_text(pagename):
            if ws.has_page(pagename):
                page = WikiPage(self.env, pagename)
                if 'WIKI_VIEW' in req.perm(page.resource):
                    self.log.debug("get_page_text(%s) -> %s", pagename,
                                   page.text)
                    return page.text
            self.log.debug("get_page_text(%s) -> None", pagename)

        # retrieve page template
        template_name = 'PageTemplates/MyPage'
        mytemplate_name = '/'.join([template_name, req.authname])
        template_text = get_page_text(mytemplate_name)
        if template_text is None:
            template_text = get_page_text(template_name)

        text = last_page_text = last_page_quoted = None
        if template_text is not None:
            # retrieve previous "page of the day", if any
            all_mypages = self.get_all_mypages(base)
            last = bisect(all_mypages, today_page_name) - 1
            self.log.debug("Pos of today %s in %r is %d", today_page_name,
                           all_mypages, last)
            last_page_name = all_mypages[last] if last >= 0 else None
            last_page_link = ''
            if last_page_name:
                last_page_link = '[[%s]]' % last_page_name
                last_page_text = get_page_text(last_page_name)
                if last_page_text is not None:
                    last_page_quoted = '\n'.join(
                        ['> ' + line for line in last_page_text.splitlines()])

            today_user = user_time(req, format_date, now, tzinfo=tzinfo)
            author = req.session.get('name') or get_reporter_id(req)

            text = template_text \
                .replace(self.tokens['date'][0], today_user) \
                .replace(self.tokens['isodate'][0], today) \
                .replace(self.tokens['user'][0], req.authname) \
                .replace(self.tokens['author'][0], author) \
                .replace(self.tokens['lp_link'][0], last_page_link) \
                .replace(self.tokens['lp_name'][0], last_page_name or '') \
                .replace(self.tokens['lp_text'][0], last_page_text or '') \
                .replace(self.tokens['lp_quoted'][0], last_page_quoted or '')
        req.redirect(req.href.wiki(today_page_name, action='edit', text=text))
Beispiel #44
0
    def _update_data(self, req):
        # Update narcissus_data table with info to be visualised
        db = self.env.get_db_cnx()
        cursor = db.cursor()

        cursor.execute('select max(dtime) from narcissus_data')
        start_rev = 1
        last_update = cursor.fetchone()[0]
        if not last_update:
            # no data yet, update data from the beginning
            cursor.execute('select min(time) from wiki')
            last_update = cursor.fetchone()[0]
        else:
            # update data from this change
            cursor.execute(
                'select eid from narcissus_data where resource = "svn"')
            for row in cursor:
                if int(row[0]) > start_rev:
                    start_rev = int(row[0])
            start_rev += 1
        members = self._settings.members

        # populate table with wiki activity
        cursor.execute(
            '''select name, min(version), count(version), min(time) from wiki
            where time > %f group by name order by min(time)''' % last_update)
        for page, start_version, versions, _ in cursor:
            versions += start_version
            # page has been added
            if start_version == 1:
                new_page = WikiPage(self.env, page, 1)
                add = len(new_page.text.splitlines())
                if (new_page.author in members) and (self._to_microseconds(
                        new_page.time) > last_update):
                    self._insert_data(new_page.author, new_page.time,
                                      new_page.name, 'wiki', 'add', add)
                start_version += 1
            for i in xrange(start_version, versions):
                # page has been edited
                old_page, edit_page = WikiPage(self.env, page,
                                               i - 1), WikiPage(
                                                   self.env, page, i)
                if (edit_page.author in members) and (self._to_microseconds(
                        edit_page.time) > last_update):
                    changes = self._my_diff(old_page.text, edit_page.text)
                    edit = self._edit_newlines(changes)
                    if edit:
                        self._insert_data(edit_page.author, edit_page.time,
                                          edit_page.name, 'wiki', 'edit', edit)

        # populate table with ticket activity
        credits = self._settings.credits
        cursor.execute('select id from ticket')
        for row in cursor:
            ticket = Ticket(self.env, row[0])
            # ticket has been opened
            if ticket['reporter'] in members and self._to_microseconds(
                    ticket.time_created) > last_update:
                self._insert_data(ticket['reporter'], ticket.time_created,
                                  ticket.id, 'ticket', 'open', 1)  # FIXME
            for dtime, author, field, _, newvalue, _ in ticket.get_changelog():
                if author in members and self._to_microseconds(
                        dtime) > last_update:
                    if field == 'comment':
                        # ticket has received comment
                        self._insert_data(author, dtime, ticket.id, 'ticket',
                                          'comment', credits['comment'])
                    elif newvalue == 'assigned':
                        # ticket has been accepted
                        self._insert_data(author, dtime, ticket.id, 'ticket',
                                          'accept', credits['accept'])
                    elif field == 'resolution':
                        # ticket has been closed, reopened closures only count as a change
                        reopened = False
                        for inner_time, _, _, _, _, _ in ticket.get_changelog(
                        ):
                            if inner_time > dtime and field == 'resolution':
                                reopened = True
                        if reopened:
                            self._insert_data(author, dtime, ticket.id,
                                              'ticket', 'update',
                                              credits['update'])
                        else:
                            if ticket['owner'] in members:
                                self._insert_data(ticket['owner'], dtime,
                                                  ticket.id, 'ticket', 'close',
                                                  credits['close'])
                            if author != ticket['owner']:
                                self._insert_data(author, dtime, ticket.id,
                                                  'ticket', 'proxy close',
                                                  credits['update'])
                    else:
                        # ticket has been changed
                        self._insert_data(author, dtime, ticket.id, 'ticket',
                                          'update', 1)  # FIXME

        # populate table with svn activity
        repos = self.env.get_repository()
        youngest_rev = str(repos.youngest_rev or 0).split(':')[0]

        try:
            youngest_rev = int(youngest_rev) + 1
        except:
            youngest_rev = 0

        for rev in xrange(start_rev, youngest_rev):
            cs = repos.get_changeset(rev)
            add, edit = 0, 0
            for path, _, change, base_path, base_rev in cs.get_changes():
                if change == 'add':
                    add += self._svn_add_newlines(repos, path, rev)
                elif change == 'edit':
                    diff_args = {
                        'old_path': base_path,
                        'old_rev': base_rev,
                        'new_path': path or '/',
                        'new_rev': rev
                    }
                    changes = self._my_svn_diff(repos, diff_args)
                    if changes:
                        edit += self._edit_newlines(changes)

            valid_user = cs.author in members
            if not valid_user:
                for u, n, e in self.env.get_known_users():
                    if e != None and e in cs.author:
                        valid_user = True

            if add and valid_user:
                self._insert_data(cs.author, cs.date, rev, 'svn', 'add', add)
            if edit and valid_user:
                self._insert_data(cs.author, cs.date, rev, 'svn', 'edit', edit)
        db.commit()
Beispiel #45
0
    def expand_macro(self, formatter, name, args):
        req = formatter.req
        tag_system = TagSystem(self.env)

        all_releases = natural_sort([r.id for r, _ in
                                     tag_system.query(req, 'realm:wiki release')])
        all_categories = sorted([r.id for r, _ in
                                 tag_system.query(req, 'realm:wiki type')])

        hide_release_picker = False
        hide_fieldset_legend = False
        hide_fieldset_description = False
        other = []
        if args:
            categories = []
            releases = []
            for arg in args.split():
                if arg in all_releases:
                    hide_release_picker = True
                    releases.append(arg)
                elif arg in all_categories:
                    categories.append(arg)
                else:
                    other.append(arg)

            if len(categories) or len(releases):
                hide_fieldset_description = True

            if not len(categories):
                categories = all_categories
            elif len(categories) == 1:
                hide_fieldset_legend = True

            if not len(releases):
                releases = all_releases
        else:
            categories = all_categories
            releases = all_releases

        if 'update_th_filter' in req.args:
            show_releases = req.args.get('release', ['0.11'])
            if isinstance(show_releases, basestring):
                show_releases = [show_releases]
            req.session['th_release_filter'] = ','.join(show_releases)
        else:
            show_releases = req.session.get('th_release_filter', '0.11').split(',')

        output = ""
        if not hide_release_picker:
            style = "text-align:right; padding-top:1em; margin-right:5em;"
            form = builder.form('\n', style=style, method="get")

            style = "font-size:xx-small;"
            span = builder.span("Show hacks for releases:", style=style)

            for version in releases:
                inp = builder.input(version, type_="checkbox", name="release",
                                    value=version)
                if version in show_releases:
                    inp(checked="checked")
                span(inp, '\n')

            style = "font-size:xx-small; padding:0; border:solid 1px black;"
            span(builder.input(name="update_th_filter", type_="submit",
                               style=style, value="Update"), '\n')
            form('\n', span, '\n')
            output = "%s%s\n" % (output, form)


        def link(resource):
            return render_resource_link(self.env, formatter.context,
                                        resource, 'compact')

        for category in categories:
            page = WikiPage(self.env, category)
            match = self.title_extract.search(page.text)
            if match:
                cat_title = '%s' % match.group(1).strip()
                cat_body = self.title_extract.sub('', page.text, 1)
            else:
                cat_title = '%s' % category
                cat_body = page.text
            cat_body = self.self_extract.sub('', cat_body).strip()

            style = "padding:1em; margin:0em 5em 2em 5em; border:1px solid #999;"
            fieldset = builder.fieldset('\n', style=style)
            if not hide_fieldset_legend:
                legend = builder.legend(style="color: #999;")
                legend(builder.a(cat_title, href=self.env.href.wiki(category)))
                fieldset(legend, '\n')
            if not hide_fieldset_description:
                fieldset(builder.p(wiki_to_html(cat_body, self.env, req)))

            ul = builder.ul('\n', class_="listtagged")
            query = 'realm:wiki (%s) %s %s' % \
                (' or '.join(show_releases), category, ' '.join(other))

            lines = 0
            for resource, tags in tag_system.query(req, query):
                # filter out the page used to make important tags
                # persistent
                if resource.id == "tags/persistent":
                    continue

                lines += 1
                li = builder.li(link(resource), ': ')

                page = WikiPage(self.env, resource)
                match = self.title_extract.search(page.text)
                description = "''no description available''"
                if match:
                    if match.group(1):
                        description = match.group(1).strip()

                li(wiki_to_oneliner(description, self.env, req=req))
                if tags:
                    if hide_fieldset_legend == False and category in tags:
                        tags.remove(category)
                        self.log.debug("hide %s: no legend" % category)
                    for o in other:
                        if o in tags: tags.remove(o)
                    rendered_tags = [ link(resource('tag', tag))
                                      for tag in natural_sort(tags) ]

                    span = builder.span(style="font-size:xx-small;")
                    span(' (tags: ', rendered_tags[0],
                       [(', ', tag) for tag in rendered_tags[1:]], ')')
                    li(span)
                ul(li, '\n')

            if lines:
                fieldset(ul, '\n')
            else:
                message = "No results for %s." % \
                    (hide_release_picker and "this version" or "your selection")
                fieldset(builder.p(builder.em(message)), '\n')
            output = "%s%s\n" % (output, fieldset)

        return output
Beispiel #46
0
    def render_new(self, req, data, hacks):
        req.perm.require('HACK_CREATE')

        tag_system = TagSystem(self.env)

        hacks = list(hacks)
        hack_names = set(r[2].id for r in hacks)
        users = set(u.id for u, _ in tag_system.query(req, 'realm:wiki user'))
        exclude = hack_names.union(users).union(data['types']).union(data['releases'])

        cloud = {}

        for votes, rank, resource, tags, title in hacks:
            for tag in tags:
                if tag in exclude:
                    continue
                try:
                    cloud[tag] += 1
                except KeyError:
                    cloud[tag] = 1

        # Pick the top 25 tags + a random sample of 10 from the rest.
        cloud = sorted(cloud.items(), key=lambda i: -i[1])
        remainder = cloud[25:]
        cloud = dict(cloud[:25] +
                     random.sample(remainder, min(10, len(remainder))))

        # Render the cloud
        min_px = 8
        max_px = 20

        def cloud_renderer(tag, count, percent):
            self.env.log.debug("cloud: %s = %2.2f%%" % (tag, percent * 100))
            return builder.a(tag, href='#', style='font-size: %ipx' %
                             int(min_px + percent * (max_px - min_px)))

        data['cloud'] = render_cloud(self.env, req, cloud, cloud_renderer)

        add_script(req, 'common/js/wikitoolbar.js')
        add_script(req, 'common/js/folding.js')

        data['focus'] = 'name'

        # Populate data with form submission
        if req.method == 'POST' and 'create' in req.args or 'preview' in req.args:
            data.update(req.args)

            context = self.form.validate(data)
            data['form_context'] = context

            vars = {}
            vars['OWNER'] = req.authname
            vars['WIKINAME'] = get_page_name(data['name'], data['type'])
            vars['TYPE'] = data.setdefault('type', 'plugin')
            vars['TITLE'] = data.setdefault('title', 'No title available')
            vars['LCNAME'] = vars['WIKINAME'].lower()
            vars['SOURCEURL'] = '%s/%s' % (self.svnbase, vars['LCNAME'])
            vars['DESCRIPTION'] = data.setdefault('description',
                                                  'No description available')
            vars['EXAMPLE'] = data.setdefault('example',
                                              'No example available')

            if 'create' in req.args and not context.errors:
                success, message = self.create_hack(req, data, vars)
                if success:
                    target = '%s?%s' % \
                        (req.href.wiki(vars['WIKINAME']), 'hack=created')
                    req.redirect(target)
                    raise RequestDone
                else:
                    add_warning(req, message)
            elif 'preview' in req.args and not context.errors:
                page = WikiPage(self.env, self.template)
                if not page.exists:
                    raise TracError('New hack template %s does not exist.' % \
                                    self.template)
                template = Template(page.text).substitute(vars)
                template = re.sub(r'\[\[ChangeLog[^\]]*\]\]',
                                  'No changes yet', template)
                data['page_preview'] = wiki_to_html(template, self.env, req)
        else:
            data['form_context'] = None
            data['type'] = 'plugin'
            data['release'] = ['0.11']

        self.env.log.debug('MUPPETS AHOY')
        return 'hacks_new.html', data, None
Beispiel #47
0
 def test_tracguide_is_readonly(self):
     from trac.wiki.model import WikiPage
     for name in ('TracGuide', 'TracInstall', 'TracUpgrade'):
         self.assertTrue(WikiPage(self.env, name).readonly)
     for name in ('SandBox', 'WikiStart', 'InterMapTxt'):
         self.assertFalse(WikiPage(self.env, name).readonly)
Beispiel #48
0
 def _insert_templates(self):
     page = WikiPage(self.env)
     page.name = 'PageTemplates/TheTemplate'
     page.text = 'The template below /PageTemplates'
     page.save('trac', 'create page')
     page = WikiPage(self.env)
     page.name = 'TheTemplate'
     page.text = 'The template below /'
     page.save('trac', 'create page')
Beispiel #49
0
    def process_request(self, req):
        req.perm.require('TAGS_VIEW')

        match = re.match(r'/tags/?(.*)', req.path_info)
        tag_id = match.group(1) and match.group(1) or None
        query = req.args.get('q', '')

        # Consider only providers, that are permitted for display.
        realms = [p.get_taggable_realm() for p in self.tag_providers
                  if (not hasattr(p, 'check_permission') or \
                      p.check_permission(req.perm, 'view'))]
        if not (tag_id or query) or [r for r in realms if r in req.args] == []:
            for realm in realms:
                if not realm in self.exclude_realms:
                    req.args[realm] = 'on'
        checked_realms = [r for r in realms if r in req.args]
        if query:
            # Add permitted realms from query expression.
            checked_realms.extend(query_realms(query, realms))
        realm_args = dict(
            zip([r for r in checked_realms], ['on' for r in checked_realms]))
        # Switch between single tag and tag query expression mode.
        if tag_id and not re.match(r"""(['"]?)(\S+)\1$""", tag_id, re.UNICODE):
            # Convert complex, invalid tag ID's --> query expression.
            req.redirect(req.href.tags(realm_args, q=tag_id))
        elif query:
            single_page = re.match(r"""(['"]?)(\S+)\1$""", query, re.UNICODE)
            if single_page:
                # Convert simple query --> single tag.
                req.redirect(req.href.tags(single_page.group(2), realm_args))

        data = dict(page_title=_("Tags"), checked_realms=checked_realms)
        # Populate the TagsQuery form field.
        data['tag_query'] = tag_id and tag_id or query
        data['tag_realms'] = list(
            dict(name=realm, checked=realm in checked_realms)
            for realm in realms)
        if tag_id:
            page_name = tag_id
            page = WikiPage(self.env, page_name)
            data['tag_page'] = page

        macros = TagWikiMacros(self.env)
        if query or tag_id:
            # TRANSLATOR: The meta-nav link label.
            add_ctxtnav(req, _("Back to Cloud"), req.href.tags())
            macro = 'ListTagged'
            args = "%s,format=%s,cols=%s" % \
                   (tag_id and tag_id or query, self.default_format,
                    self.default_cols)
            data['mincount'] = None
        else:
            macro = 'TagCloud'
            mincount = as_int(req.args.get('mincount', None),
                              self.cloud_mincount)
            args = mincount and "mincount=%s" % mincount or None
            data['mincount'] = mincount
        formatter = Formatter(self.env,
                              Context.from_request(req, Resource('tag')))
        self.env.log.debug("Tag macro arguments: %s", args and args
                           or '(none)')
        try:
            # Query string without realm throws 'NotImplementedError'.
            data['tag_body'] = checked_realms and \
                               macros.expand_macro(formatter, macro, args,
                                                   realms=checked_realms) \
                               or ''
        except InvalidQuery, e:
            data['tag_query_error'] = to_unicode(e)
            data['tag_body'] = macros.expand_macro(formatter, 'TagCloud', '')
Beispiel #50
0
    def process_request(self, req):
        page = req.args.get('page', None)
        location = req.args.get('location', None)
        theme = req.args.get('theme', 'default')

        if not page:
            raise TracError('Invalid S5 template')

        page = WikiPage(self.env, name=page)
        if not page.exists:
            raise TracError('Invalid S5 template "%s"' % page.name)

        page_text = self.fixup_images_re.sub(
            r'[[Image(wiki:%s:\1)]]' % page.name, page.text)

        in_section = -1
        text = ''
        title = ''
        html_title = ''
        title_page = ''
        handout = ''
        slides = []

        def htmlify(text):
            return wiki_to_html(text, self.env, req)

        for line in page_text.splitlines():
            match = self.heading_re.match(line)
            if match:
                # Insert accumulated text into appropiate location
                if in_section == 1:
                    title_page = htmlify(text)
                elif in_section == 2:
                    text = self.fixup_re.sub(r'\1', text)
                    slides.append({
                        'body': htmlify(text),
                        'handout': htmlify(handout)
                    })

                if match.lastgroup == 'title':
                    title = match.group(match.lastgroup)
                    html_title = htmlify(title)
                    title = html_title.plaintext()
                    in_section = 1
                else:
                    in_section = 2
                text = ''

            text += line + '\n'

        if in_section == 1:
            title_page = htmlify(text)
        elif in_section == 2:
            text = self.fixup_re.sub(r'\1', text)
            slides.append({'body': htmlify(text), 'handout': htmlify(handout)})

        req.hdf['theme'] = theme
        req.hdf['title'] = title
        req.hdf['html_title'] = html_title
        req.hdf['location'] = location
        req.hdf['title_page'] = title_page
        req.hdf['slides'] = slides

        return 's5.cs', None
Beispiel #51
0
    def _render_diff(self, req, db, page):
        req.perm.assert_permission('WIKI_VIEW')

        if not page.exists:
            raise TracError, "Version %s of page %s does not exist" \
                             % (req.args.get('version'), page.name)

        add_stylesheet(req, 'common/css/diff.css')

        req.hdf['title'] = escape(page.name) + ' (diff)'

        # Ask web spiders to not index old versions
        req.hdf['html.norobots'] = 1

        old_version = req.args.get('old_version')
        if old_version:
            old_version = int(old_version)
            if old_version == page.version:
                old_version = None
            elif old_version > page.version:
                old_version, page = page.version, \
                                    WikiPage(self.env, page.name, old_version)

        info = {
            'version': page.version,
            'history_href':
            escape(self.env.href.wiki(page.name, action='history'))
        }

        num_changes = 0
        old_page = None
        for version, t, author, comment, ipnr in page.get_history():
            if version == page.version:
                if t:
                    info['time'] = format_datetime(t)
                    info['time_delta'] = pretty_timedelta(t)
                info['author'] = escape(author or 'anonymous')
                info['comment'] = escape(comment or '--')
                info['ipnr'] = escape(ipnr or '')
            else:
                num_changes += 1
                if version < page.version:
                    if (old_version and version == old_version) or \
                            not old_version:
                        old_page = WikiPage(self.env, page.name, version)
                        info['num_changes'] = num_changes
                        info['old_version'] = version
                        break

        req.hdf['wiki'] = info

        diff_style, diff_options = get_diff_options(req)

        oldtext = old_page and old_page.text.splitlines() or []
        newtext = page.text.splitlines()
        context = 3
        for option in diff_options:
            if option.startswith('-U'):
                context = int(option[2:])
                break
        if context < 0:
            context = None
        changes = hdf_diff(oldtext,
                           newtext,
                           context=context,
                           ignore_blank_lines='-B' in diff_options,
                           ignore_case='-i' in diff_options,
                           ignore_space_changes='-b' in diff_options)
        req.hdf['wiki.diff'] = changes
Beispiel #52
0
def read_file(name):
    text[name] = file("wiki/" + name).read().decode('utf-8')
    page = WikiPage(env)
    page.name = name
    page.text = '--'
    page.save('', '', '::1', 0)
Beispiel #53
0
    def _render_editor(self, req, page, action='edit', has_collision=False):
        if has_collision:
            if action == 'merge':
                page = WikiPage(self.env, page.name, version=None)
                req.perm(page.resource).require('WIKI_VIEW')
            else:
                action = 'collision'

        if not page.exists:
            req.perm(page.resource).require('WIKI_CREATE')
        else:
            req.perm(page.resource).require('WIKI_MODIFY')
        original_text = page.text
        comment = req.args.get('comment', '')
        if 'text' in req.args:
            page.text = req.args.get('text')
        elif 'template' in req.args:
            template = self.PAGE_TEMPLATES_PREFIX + req.args.get('template')
            template_page = WikiPage(self.env, template)
            if template_page and template_page.exists and \
                    'WIKI_VIEW' in req.perm(template_page.resource):
                page.text = template_page.text
        elif 'version' in req.args:
            old_page = WikiPage(self.env,
                                page.name,
                                version=int(req.args['version']))
            req.perm(page.resource).require('WIKI_VIEW')
            page.text = old_page.text
            comment = _("Reverted to version %(version)s.",
                        version=req.args['version'])
        if action in ('preview', 'diff'):
            page.readonly = 'readonly' in req.args

        author = get_reporter_id(req, 'author')
        defaults = {'editrows': 20}
        prefs = dict((key, req.session.get('wiki_%s' % key, defaults.get(key)))
                     for key in ('editrows', 'sidebyside'))

        if 'from_editor' in req.args:
            sidebyside = req.args.get('sidebyside') or None
            if sidebyside != prefs['sidebyside']:
                req.session.set('wiki_sidebyside', int(bool(sidebyside)), 0)
        else:
            sidebyside = prefs['sidebyside']

        if sidebyside:
            editrows = max(int(prefs['editrows']),
                           len(page.text.splitlines()) + 1)
        else:
            editrows = req.args.get('editrows')
            if editrows:
                if editrows != prefs['editrows']:
                    req.session.set('wiki_editrows', editrows,
                                    defaults['editrows'])
            else:
                editrows = prefs['editrows']

        data = self._page_data(req, page, action)
        context = web_context(req, page.resource)
        data.update({
            'context':
            context,
            'author':
            author,
            'comment':
            comment,
            'edit_rows':
            editrows,
            'sidebyside':
            sidebyside,
            'scroll_bar_pos':
            req.args.get('scroll_bar_pos', ''),
            'diff':
            None,
            'attachments':
            AttachmentModule(self.env).attachment_data(context),
            'show_readonly_checkbox':
            ReadonlyWikiPolicy.__name__
            in self.config.get('trac', 'permission_policies')
        })
        if action in ('diff', 'merge'):
            old_text = original_text.splitlines() if original_text else []
            new_text = page.text.splitlines() if page.text else []
            diff_data, changes = self._prepare_diff(req, page, old_text,
                                                    new_text, page.version, '')
            data.update({
                'diff': diff_data,
                'changes': changes,
                'action': 'preview',
                'merge': action == 'merge',
                'longcol': 'Version',
                'shortcol': 'v'
            })
        elif sidebyside and action != 'collision':
            data['action'] = 'preview'

        self._wiki_ctxtnav(req, page)
        Chrome(self.env).add_wiki_toolbars(req)
        Chrome(self.env).add_auto_preview(req)
        add_script(req, 'common/js/folding.js')
        return 'wiki_edit.html', data, None
Beispiel #54
0
 # 得到帮助文件名
 # 不应该使用wiki-default,应该使用zhwiki-default目录的listdir()
 # 因为有可以没有一些页面的中文版本
 help_zh = os.listdir(curdir + '/zhwiki-default')
 # \n 是后面安全去除添加内容的重要凭据
 headString = '\n\n[Zh%s 中文版本][[BR]]%s\n\n\n'
 headStringCN = '\n\n%s\n\n\n'
 for docName in help_zh:
     # 防止.svn目录
     if not os.path.isdir(curdir + '/zhwiki-default/' +
                          docName):
         print 'editing %s' % docName
         # 取英文文件名
         doc = docName[2:]
         # 英文文件
         page = WikiPage(myEnv, doc)
         if page.version == 0:
             print '%s no exist!'
             continue
         seealso = seeAlso.get(doc, [''])
         # %的两边要达到统一编码
         addString = headString % (doc,
                                   seealso[0].encode('utf8'))
         addString = addString.decode('utf8')
         page.text = addString + page.text
         page.save('Trac', '', '')
         # 中文文件
         page = WikiPage(myEnv, docName)
         if page.version == 0:
             print '%s no exist!'
             continue
Beispiel #55
0
 def check_permission(self, action, username, resource, perm):
     if resource and resource.realm == 'wiki' and \
             action in ('WIKI_DELETE', 'WIKI_MODIFY', 'WIKI_RENAME'):
         page = WikiPage(self.env, resource)
         if page.readonly and 'WIKI_ADMIN' not in perm(resource):
             return False
Beispiel #56
0
 def get_resource_url(self, resource, href, **kwargs):
     page = WikiPage(self.env, resource.id)
     if page.exists:
         return get_resource_url(self.env, page.resource, href, **kwargs)
     return href("tags/'%s'" % unicode(resource.id).replace("'", "\\'"))
Beispiel #57
0
 def setUp(self):
     self.env = EnvironmentStub(enable=[NewTitleIndexMacro])
     page = WikiPage(self.env)
     page.name = 'NewTitleIndexMacroDefinitions'
     page.save('admin', 'NewTitleIndexMacro definitions')
Beispiel #58
0
    def _generate_blog(self, req, args, kwargs):
        """Extract the blog pages and fill the HDF.

        *args is a list of tags to use to limit the blog scope
        **kwargs are any aditional keyword arguments that are needed
        """
        tallies = {}
        parms = self._get_display_params(req, kwargs)
        tagged_pages, tlist = self._initialize_tags(args, kwargs)
        poststart, postend, default_times = self._get_time_range(parms, req, 
                                                                 kwargs)

        # The blog can be displayed in various formats depending on the values
        # of the parameters.  The two main methods/displays are:
        #  * Fixed number of posts, ie. always show the last 5 posts.
        #  * All posts in a given date range, ie. all posts for a given month.
        # Issues with the first method is that all posts have to be read, and
        # then sorted by date before the selection can be made, as we are not
        # guaranteed any specific order from the tag retrieval.
        #
        # Issues with the second are likewise.  However, with the second, while
        # we still need to read in all of the posts, we can drop those that are
        # out of range in the process, so no extra sorting need be done. 
        #
        # An option for parsing would be:
        # for each tagged post:
        #   load post
        #   save post_time and page name in list
        # sort the list
        # Formatting
        # 
        # Create a dictionary of page names keyed by the post date.  Create a
        # sorted (decending) list of post date timestamps.
        for p in tagged_pages:
            page = WikiPage(self.env, version=1, name=p)
            version, post_time, author, comment, ipnr = page.get_history(
                                                        ).next()
            posts[post_time] = p
            # We also take time to update our tallies
            self._tally(tallies, post_time, p)
            continue
        post_times = posts.keys()
        post_times.sort()
        post_times.reverse()
        # Slice the list of post times down to those posts that fall in the
        # selected time frame and/or number of posts.
        if default_times and parms['num_posts']:
            post_times = post_times[:parms['num_posts']]
        else:
            i = 0 
            maxindex = len(post_times)
            while (i < maxindex) and (post_times[i] < poststart):
                i += 1
            start_index = i
            while (i < maxindex) and (post_times[i] <= postend):
                i += 1
            stop_index = i 
            post_times = post_times[start_index:stop_index]
            if parms['num_posts'] and (parms['num_posts'] <= len(post_times)):
                post_times = post_times[:parms['num_posts']]
        # Now that we have the list of pages that we are going to use, what now?

        # We need the following information:
        #- * formatted post time
        #- * truncated(?) version of page to display
        #  * list of tags to display in "tagged under"
        #    * link name (tag)
        #    * tag name (tag)
        #    * last tag indicator
        #- * page name
        #- * link to wiki page (read_post)
        #- * author
        #- * comment (?)
        #  * whether or not tags are present
        #  * whether or not more tags are available
        #- * whether or not the post has been updated
        #-   * update time 
        entries = {}
        for post in post_times:
            page = WikiPage(self.env, name=posts[post])
            version, modified, author, comment, ipnr = page.get_history().next()
            # Truncate the post text if necessary and format for display
            post_text = wiki_to_nofloat_html(self._trin_page(page.text), 
                                    self.env, req,
                                    macro_blacklist=parms['macro_blacklist'])
            # Format the page time for display
            post_time = format_datetime(post_time, format=parms['date_format']) 
            # Create the link to the full post text
            read_post_link = wiki_to_oneliner(parms['read_post'] % posts[post],
                                              self.env),
            # Set whether or not the page has been modified
            post_modified = ((modified != post) and parms['mark_updated'])
            # Create post modified string.  If {{{post_modified}}} is false,
            # this string is simply ignored.
            modified_notice = format_datetime(modified, 
                                              format=parms['date_format'])
            data = {
                    'name'      : posts[post],
                    'wiki_text' : post_text,
                    'time'      : post_time,
                    'author'    : author, # need to make sure this is the orig.
                    'comment'   : comment,
                    'modified'  : post_modified,
                    'mod_time'  : modified_notice,
                    'wiki_link' : read_post_link,
                    'tags'      : {
                                    'present' : tags_present,
                                    'tags'    : page_tags,
                                    'more'    : more_tags,
                                  },
                   }
            entries[post_time] = data
            
            
        for blog_entry in blog:
                pagetags = [x for x in self.tags.get_name_tags(blog_entry) 
                            if x not in tlist]
                tagtags = []
                for i, t in enumerate(pagetags[:3]):
                    d = { 'link' : t,
                          'name' : t,
                          'last' : i == 2,
                        }
                    tagtags.append(d)
                    continue
                data = {
                        'tags'      : {
                                        'present' : len(pagetags),
                                        'tags'    : tagtags,
                                        'more'    : len(pagetags) > 3 or 0,
                                      },
                       }
            continue
        # mark the last post so that we don't display a line after the last post
        if post_times:
            entries[post_times[-1]]['last'] = 1
        # fill the HDF with the blog entries
        req.hdf['blog.entries'] = [entries[x] for x in post_times]
        # set link name for blog posts
        bloglink = self.env.config.get('blog', 'new_blog_link', 'New Blog Post')
        req.hdf['blog.newblog'] = bloglink
        # generate calendar
        hidecal = self._choose_value('hidecal', req, kwargs)
        if not hidecal:
            self._generate_calendar(req, tallies)
        req.hdf['blog.hidecal'] = hidecal
        pass
Beispiel #59
0
    def process_request(self, req):
        action = req.args.get('action', 'view')
        pagename = req.args.get('page', self.START_PAGE)
        version = None
        if req.args.get('version'):  # Allow version to be empty
            version = req.args.getint('version')
        old_version = req.args.getint('old_version')

        if pagename.startswith('/') or pagename.endswith('/') or \
                '//' in pagename:
            pagename = re.sub(r'/{2,}', '/', pagename.strip('/'))
            req.redirect(req.href.wiki(pagename))
        if not validate_page_name(pagename):
            raise TracError(_("Invalid Wiki page name '%(name)s'",
                              name=pagename))

        page = WikiPage(self.env, pagename)
        versioned_page = WikiPage(self.env, pagename, version)

        req.perm(versioned_page.resource).require('WIKI_VIEW')

        if version and versioned_page.version != version:
            raise ResourceNotFound(
                _('No version "%(num)s" for Wiki page "%(name)s"',
                  num=version, name=page.name))

        add_stylesheet(req, 'common/css/wiki.css')

        if req.method == 'POST':
            if action == 'edit':
                if 'cancel' in req.args:
                    req.redirect(req.href.wiki(page.name))

                has_collision = version != page.version
                for a in ('preview', 'diff', 'merge'):
                    if a in req.args:
                        action = a
                        break
                versioned_page.text = req.args.get('text')
                valid = self._validate(req, versioned_page)
                if action == 'edit' and not has_collision and valid:
                    return self._do_save(req, versioned_page)
                else:
                    return self._render_editor(req, page, action,
                                               has_collision)
            elif action == 'edit_comment':
                self._do_edit_comment(req, versioned_page)
            elif action == 'delete':
                self._do_delete(req, versioned_page)
            elif action == 'rename':
                return self._do_rename(req, page)
            elif action == 'diff':
                style, options, diff_data = get_diff_options(req)
                contextall = diff_data['options']['contextall']
                req.redirect(req.href.wiki(versioned_page.name, action='diff',
                                           old_version=old_version,
                                           version=version,
                                           contextall=contextall or None))
            else:
                raise HTTPBadRequest(_("Invalid request arguments."))
        elif action == 'delete':
            return self._render_confirm_delete(req, page)
        elif action == 'rename':
            return self._render_confirm_rename(req, page)
        elif action == 'edit':
            return self._render_editor(req, page)
        elif action == 'edit_comment':
            return self._render_edit_comment(req, versioned_page)
        elif action == 'diff':
            return self._render_diff(req, versioned_page)
        elif action == 'history':
            return self._render_history(req, versioned_page)
        else:
            format = req.args.get('format')
            if format:
                Mimeview(self.env).send_converted(req, 'text/x-trac-wiki',
                                                  versioned_page.text,
                                                  format, versioned_page.name)
            return self._render_view(req, versioned_page)
Beispiel #60
0
 def _change_page(self, name):
     page = WikiPage(self.env, name)
     page.text = random_paragraph()
     page.save('user2', 'Page changed.')