Ejemplo n.º 1
0
    def process_request(self, req):
        action = req.args.get('action', 'view')
        pagename = req.args.get('page', 'WikiStart')
        version = req.args.get('version')
        old_version = req.args.get('old_version')

        if pagename.endswith('/'):
            req.redirect(req.href.wiki(pagename.strip('/')))

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

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

        if version and versioned_page.version == 0 and \
               page.version != 0:
            raise TracError(_('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 = int(version) != page.version
                for a in ('preview', 'diff', 'merge'):
                    if a in req.args:
                        action = a
                        break
                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 == 'delete':
                self._do_delete(req, versioned_page)
            elif action == 'diff':
                get_diff_options(req)
                req.redirect(req.href.wiki(versioned_page.name, action='diff',
                                           old_version=old_version))
        elif action == 'delete':
            return self._render_confirm(req, versioned_page)
        elif action == 'edit':
            return self._render_editor(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)
Ejemplo n.º 2
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
Ejemplo n.º 3
0
    def process_request(self, req):
        # req.args为一个字典:有'action'时返回action的值,没有时返回default值
        action = req.args.get('action', 'view')
        pagename = req.args.get('page', 'ZhWikiStart')
        version = req.args.get('version')

        if pagename.endswith('/'):
            req.redirect(req.href.wiki(pagename.strip('/')))

        db = self.env.get_db_cnx()
        # 使用Page对象,不用使用数据库相关东西
        page = WikiPage(self.env, pagename, version, db)

        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(req.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(req.href.wiki(
                    page.name, version=page.version,
                    old_version=req.args.get('old_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:
            req.perm.assert_permission('WIKI_VIEW')            
            format = req.args.get('format')
            if format:
                Mimeview(self.env).send_converted(req, 'text/x-trac-wiki',
                                                  page.text, format, page.name)
            self._render_view(req, db, page)

        req.hdf['wiki.action'] = action
        req.hdf['wiki.current_href'] = req.href.wiki(page.name)
        return 'wiki.cs', None
Ejemplo n.º 4
0
    def _prepare_diff(self, req, page, old_text, new_text,
                      old_version, new_version):
        diff_style, diff_options, diff_data = get_diff_options(req)
        diff_context = 3
        for option in diff_options:
            if option.startswith('-U'):
                diff_context = int(option[2:])
                break
        if diff_context < 0:
            diff_context = None
        diffs = diff_blocks(old_text, new_text, context=diff_context,
                            ignore_blank_lines='-B' in diff_options,
                            ignore_case='-i' in diff_options,
                            ignore_space_changes='-b' in diff_options)
        def version_info(v, last=0):
            return {'path': get_resource_name(self.env, page.resource),
                    # TRANSLATOR: wiki page
                    'rev': v or _('currently edited'),
                    'shortrev': v or last + 1,
                    'href': req.href.wiki(page.name, version=v) if v else None}
        changes = [{'diffs': diffs, 'props': [],
                    'new': version_info(new_version, old_version),
                    'old': version_info(old_version)}]

        add_stylesheet(req, 'common/css/diff.css')
        add_script(req, 'common/js/diff.js')
        return diff_data, changes
Ejemplo n.º 5
0
    def _prepare_diff(self, req, page, old_text, new_text,
                      old_version, new_version):
        diff_style, diff_options, diff_data = get_diff_options(req)
        diff_context = 3
        for option in diff_options:
            if option.startswith('-U'):
                diff_context = int(option[2:])
                break
        if diff_context < 0:
            diff_context = None
        diffs = diff_blocks(old_text, new_text, context=diff_context,
                            ignore_blank_lines='-B' in diff_options,
                            ignore_case='-i' in diff_options,
                            ignore_space_changes='-b' in diff_options)
        def version_info(v, last=0):
            return {'path': get_resource_name(self.env, page.resource),
                    # TRANSLATOR: wiki page
                    'rev': v or _("currently edited"),
                    'shortrev': v or last + 1,
                    'href': req.href.wiki(page.name, version=v)
                            if v else None}
        changes = [{'diffs': diffs, 'props': [],
                    'new': version_info(new_version, old_version),
                    'old': version_info(old_version)}]

        add_stylesheet(req, 'common/css/diff.css')
        add_script(req, 'common/js/diff.js')
        return diff_data, changes
Ejemplo n.º 6
0
def get_diffs(self, req, title, old_text, new_text):
    diff_style, diff_options, diff_data = get_diff_options(req)
    diff_context = 3
    for option in diff_options:
        if option.startswith('-U'):
            diff_context = int(option[2:])
            break
    if diff_context < 0:
        diff_context = None
    diffs = diff_blocks(old_text.splitlines(), new_text.splitlines(), context=diff_context,
                        tabwidth=2,
                        ignore_blank_lines=True,
                        ignore_case=True,
                        ignore_space_changes=True)
    
    chrome = Chrome(self.env)
    loader = TemplateLoader(chrome.get_all_templates_dirs())
    tmpl = loader.load('diff_div.html')
    
    changes=[{'diffs': diffs, 'props': [],
              'title': title,
              'new': {'path':"", 'rev':'', 'shortrev': '', 'href':''},
              'old': {'path':"", 'rev':'', 'shortrev': '', 'href': ''}}]

    data = chrome.populate_data(req,
                                { 'changes':changes , 'no_id':True, 'diff':diff_data,
                                  'longcol': '', 'shortcol': ''})
    diff_data['style']='sidebyside';
    data.update({ 'changes':changes , 'no_id':True, 'diff':diff_data,
                  'longcol': '', 'shortcol': ''})
    stream = tmpl.generate(**data)
    return stream.render()
Ejemplo n.º 7
0
def get_diffs(self, req, title, old_text, new_text):
    diff_style, diff_options, diff_data = get_diff_options(req)
    diff_context = 3
    for option in diff_options:
        if option.startswith('-U'):
            diff_context = int(option[2:])
            break
    if diff_context < 0:
        diff_context = None
    diffs = diff_blocks(old_text.splitlines(),
                        new_text.splitlines(),
                        context=diff_context,
                        tabwidth=2,
                        ignore_blank_lines=True,
                        ignore_case=True,
                        ignore_space_changes=True)

    chrome = Chrome(self.env)
    loader = TemplateLoader(chrome.get_all_templates_dirs())
    tmpl = loader.load('diff_div.html')

    changes = [{
        'diffs': diffs,
        'props': [],
        'title': title,
        'new': {
            'path': "",
            'rev': '',
            'shortrev': '',
            'href': ''
        },
        'old': {
            'path': "",
            'rev': '',
            'shortrev': '',
            'href': ''
        }
    }]

    data = chrome.populate_data(
        req, {
            'changes': changes,
            'no_id': True,
            'diff': diff_data,
            'longcol': '',
            'shortcol': ''
        })
    diff_data['style'] = 'sidebyside'
    data.update({
        'changes': changes,
        'no_id': True,
        'diff': diff_data,
        'longcol': '',
        'shortcol': ''
    })
    stream = tmpl.generate(**data)
    return stream.render()
Ejemplo n.º 8
0
    def process_request(self, req, db=None):
        req.perm.assert_permission('CHANGESET_VIEW')

        if not db:
            db = self.env.get_db_cnx()

        # Fetch the standard ticket fields
        cursor = db.cursor()

        ticket_id = req.args.get('ticket_id')
	req.hdf['ticket_id'] = ticket_id

        repos = self.env.get_repository(req.authname)
        authzperm = SubversionAuthorizer(self.env, req.authname)

        diff_options = get_diff_options(req)
        if req.args.has_key('update'):
            req.redirect(self.env.href.setchangeset(ticket_id))

	ticket = Ticket(self.env, ticket_id)

	ticket.setchangesets = self.get_setchangesets(ticket_id,db)

	ticket.values['setchangesets'] = ticket.setchangesets

	ticket.values['changesets'] = ""
	for changeset in ticket.setchangesets:
	    ticket.values['changesets'] +=  str(changeset)
	
	setchangesets = ticket.setchangesets
	req.hdf['ticket'] = ticket
	req.hdf['dbWarning'] = False

	# get the list of changesets for the ticket_id
	# then loop through and get the actual changesets like the following line
	chgset = []
	self.log.debug('PublishRevert: %s', ticket['ticketaction'])
	for rev in setchangesets:
	    authzperm.assert_permission_for_changeset(rev)
	    changeset = repos.get_changeset(rev)
            chgset.append(changeset)

        format = req.args.get('format')

        self._render_html(req, ticket, repos, chgset, diff_options)

        return 'setchangeset.cs', None
Ejemplo n.º 9
0
    def process_request(self, req, db=None):
        req.perm.assert_permission('CHANGESET_VIEW')

        if not db:
            db = self.env.get_db_cnx()

        # Fetch the standard ticket fields
        cursor = db.cursor()

        ticket_id = req.args.get('ticket_id')
        req.hdf['ticket_id'] = ticket_id

        repos = self.env.get_repository(req.authname)
        authzperm = SubversionAuthorizer(self.env, req.authname)

        diff_options = get_diff_options(req)
        if req.args.has_key('update'):
            req.redirect(self.env.href.setchangeset(ticket_id))

        ticket = Ticket(self.env, ticket_id)

        ticket.setchangesets = self.get_setchangesets(ticket_id, db)

        ticket.values['setchangesets'] = ticket.setchangesets

        ticket.values['changesets'] = ""
        for changeset in ticket.setchangesets:
            ticket.values['changesets'] += str(changeset)

        setchangesets = ticket.setchangesets
        req.hdf['ticket'] = ticket
        req.hdf['dbWarning'] = False

        # get the list of changesets for the ticket_id
        # then loop through and get the actual changesets like the following line
        chgset = []
        self.log.debug('PublishRevert: %s', ticket['ticketaction'])
        for rev in setchangesets:
            authzperm.assert_permission_for_changeset(rev)
            changeset = repos.get_changeset(rev)
            chgset.append(changeset)

        format = req.args.get('format')

        self._render_html(req, ticket, repos, chgset, diff_options)

        return 'setchangeset.cs', None
Ejemplo n.º 10
0
    def process_request(self, req, db=None):
        req.perm.assert_permission('TRAC_ADMIN')

        if not db:
            self.db = self.env.get_db_cnx()

        ticket_id = req.args.get('ticket_id')
        req.hdf['ticket_id'] = ticket_id
        req.hdf['message'] = ''

        repos = self.env.get_repository(req.authname)
        authzperm = SubversionAuthorizer(self.env, req.authname)

        diff_options = get_diff_options(req)
        if req.args.has_key('update'):
            req.redirect(self.env.href.svnpublish(ticket_id))

        ticket = Ticket(self.env, ticket_id)
        chgset = []

        if (ticket['ticketaction'] == "ClonePublish"):
            from publishrevert.setchangeset import SetChangesetModule
            setchangeset = SetChangesetModule(self.env)
            setchangesets = setchangeset.get_setchangesets(ticket_id)

            # get the list of changesets for the ticket_id
            # then loop through and get the actual changesets like the following line
            for rev in setchangesets:
                authzperm.assert_permission_for_changeset(rev)
                changeset = repos.get_changeset(rev)

                # now loop through the files in changeset to get all the paths
                # and for each path, find the current test/prod revision number and save that info
                chgset.append(changeset)

            format = req.args.get('format')
            self._render_html(req, ticket, repos, chgset, diff_options)
            req.hdf['setchangesets'] = setchangesets
            ticket['ticketaction'] = 'CloneTest'
            ticket.save_changes(req.authname, 'published to clone', 0, db)
            req.hdf['message'] += 'Successfully Published All Files'
            req.hdf['ticket'] = ticket.values
        else:
            req.hdf['error'] = 'Error: not in correct state to publish'

        return 'setchangeset.cs', None
Ejemplo n.º 11
0
    def process_request(self, req, db=None):
        req.perm.assert_permission('TRAC_ADMIN')

        if not db:
            self.db = self.env.get_db_cnx()

        ticket_id = req.args.get('ticket_id')
	req.hdf['ticket_id'] = ticket_id
	req.hdf['message'] = ''

        repos = self.env.get_repository(req.authname)
        authzperm = SubversionAuthorizer(self.env, req.authname)

        diff_options = get_diff_options(req)
        if req.args.has_key('update'):
            req.redirect(self.env.href.svnpublish(ticket_id))

	ticket = Ticket(self.env, ticket_id)
        chgset = []

	if(ticket['ticketaction'] == "ClonePublish"):
            from publishrevert.setchangeset import SetChangesetModule
  	    setchangeset = SetChangesetModule(self.env)
            setchangesets = setchangeset.get_setchangesets(ticket_id)

	    # get the list of changesets for the ticket_id
	    # then loop through and get the actual changesets like the following line
	    for rev in setchangesets:
	        authzperm.assert_permission_for_changeset(rev)
	        changeset = repos.get_changeset(rev)

	    # now loop through the files in changeset to get all the paths
	    # and for each path, find the current test/prod revision number and save that info
                chgset.append(changeset)

            format = req.args.get('format')
            self._render_html(req, ticket, repos, chgset, diff_options)
	    req.hdf['setchangesets'] = setchangesets
	    ticket['ticketaction'] = 'CloneTest'
	    ticket.save_changes(req.authname, 'published to clone', 0, db)
	    req.hdf['message'] += 'Successfully Published All Files'
            req.hdf['ticket'] = ticket.values
	else:
	    req.hdf['error'] = 'Error: not in correct state to publish'

        return 'setchangeset.cs', None
Ejemplo n.º 12
0
    def _render_diff_html(self, req, data):
        """Use Trac's rendering to show the changes in the pull request.
        
        To exploit Trac's built-in HTML rendering for diffs we must
        setup a fresh data dict and call the internal method
        `_render_html` of the `ChangesetModule`.

        Afterwards the `diff_data` must be added to the original data
        without replacing existing keys. An exception helps to find
        those keys that must be renamed. Remember to adapt the Genshi
        templates accordingly.

        XHR must be disabled even for automatic preview as Trac's
        rendering otherwise aborts request processing and immediately
        sends a result to the browser.
        """
        style, options, diff = get_diff_options(req)

        cm = ChangesetModule(self.env)
        diff_data = {}
        repo = data['pr_srcrepo'] or data['pr_dstrepo']

        if not (repo and repo.has_node('', data['pr_srcrev'])):
            return

        diff_data.update({
            'old_path': '',
            'old_rev': data['pr_dstrev'],
            'new_path': '',
            'new_rev': data['pr_srcrev'],
            'repos': repo,
            'reponame': repo.reponame,
            'diff': diff,
            'wiki_format_messages': cm.wiki_format_messages
        })

        cm._render_html(req, repo, False, True, False, diff_data)

        for key in diff_data:
            diff_key = key
            if key in ['changes']:
                diff_key = 'diff_' + key
            if diff_key in data:
                raise TracError("Key %(key)s collides in data", diff_key)
            data[diff_key] = diff_data[key]
Ejemplo n.º 13
0
    def _diff_cr(self, req):
        add_stylesheet(req, 'common/css/diff.css')
        cs_id = req.args.get('id')
        old_version = req.args.get('old_version', 1)
        version = req.args.get('version', 1)
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        try:
            version_author, version_status, newtext = self._get_version_record(
                cursor, cs_id, version)
            oldversion_author, oldversion_status, oldtext = self._get_version_record(
                cursor, cs_id, old_version)
        except ValueError:
            return pretty_err(req, 'Version Error')
        ctime = round(time.time(), 2)
        diff_style, diff_options = get_diff_options(req)
        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.splitlines(),
                           newtext.splitlines(),
                           context=context,
                           ignore_blank_lines='-B' in diff_options,
                           ignore_case='-i' in diff_options,
                           ignore_space_changes='-b' in diff_options)
        req.hdf['version.diff'] = changes

        req.hdf['version_author'] = version_author
        req.hdf['oldversion_author'] = oldversion_author
        req.hdf['version_status'] = status_str[version_status]
        req.hdf['oldversion_status'] = status_str[oldversion_status]
        req.hdf['ctime'] = time.ctime(ctime)
        req.hdf['old_version'] = old_version
        req.hdf['version'] = version
        req.hdf['rev'] = cs_id
        req.hdf['update.href'] = self.env.href.CodeReview(cs_id, action='diff')
        return 'codereviewdiff.cs', None
Ejemplo n.º 14
0
    def process_request(self, req):
        req.perm.assert_permission('CHANGESET_VIEW')

        ticket_id = req.args.get('ticket_id')
	req.hdf['ticket_id'] = ticket_id

        repos = self.env.get_repository(req.authname)
        authzperm = SubversionAuthorizer(self.env, req.authname)

        diff_options = get_diff_options(req)
        if req.args.has_key('update'):
            req.redirect(self.env.href.setchangeset(ticket_id))

	ticket = Ticket(self.env, ticket_id)
	setchangesets = ticket.setchangesets

	# get the list of changesets for the ticket_id
	# then loop through and get the actual changesets like the following line
	chgset = []
	for rev in setchangesets:
	    authzperm.assert_permission_for_changeset(rev)
	    changeset = repos.get_changeset(rev)
            chgset.append(changeset)
	    req.check_modified(changeset.date,
                      diff_options[0] + ''.join(diff_options[1]))

        format = req.args.get('format')

        self._render_html(req, ticket, repos, chgset, diff_options)
        add_link(req, 'alternate', '?format=diff', 'Unified Diff',
                 'text/plain', 'diff')
        add_link(req, 'alternate', '?format=zip', 'Zip Archive',
                 'application/zip', 'zip')
        add_stylesheet(req, 'common/css/changeset.css')
        add_stylesheet(req, 'common/css/diff.css')
        add_stylesheet(req, 'common/css/code.css')
        return 'setchangeset.cs', None
Ejemplo n.º 15
0
    def _diff_cr(self, req):
        add_stylesheet(req, 'common/css/diff.css')
        cs_id = req.args.get('id')
        old_version = req.args.get('old_version', 1)
        version = req.args.get('version', 1)
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        try:
            version_author, version_status, newtext = self._get_version_record(cursor, cs_id, version)
            oldversion_author, oldversion_status, oldtext = self._get_version_record(cursor, cs_id, old_version)
        except ValueError:
            return pretty_err(req, 'Version Error')
        ctime = round(time.time(), 2)
        diff_style, diff_options = get_diff_options(req)
        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.splitlines(), newtext.splitlines(), context=context,
                           ignore_blank_lines='-B' in diff_options,
                           ignore_case='-i' in diff_options,
                           ignore_space_changes='-b' in diff_options)
        req.hdf['version.diff'] = changes

        req.hdf['version_author'] = version_author
        req.hdf['oldversion_author'] = oldversion_author
        req.hdf['version_status'] = status_str[version_status]
        req.hdf['oldversion_status'] = status_str[oldversion_status]
        req.hdf['ctime'] = time.ctime(ctime)
        req.hdf['old_version'] = old_version
        req.hdf['version'] = version
        req.hdf['rev'] = cs_id
        req.hdf['update.href'] = self.env.href.CodeReview(cs_id, action='diff')
        return 'codereviewdiff.cs', None
Ejemplo n.º 16
0
    def process_request(self, req):
        """The appropriate mode of operation is inferred from the request
        parameters:

         * If `new_path` and `old_path` are equal (or `old_path` is omitted)
           and `new` and `old` are equal (or `old` is omitted),
           then we're about to view a revision Changeset: `chgset` is True.
           Furthermore, if the path is not the root, the changeset is
           ''restricted'' to that path (only the changes affecting that path,
           its children or its ancestor directories will be shown).
         * In any other case, the set of changes corresponds to arbitrary
           differences between path@rev pairs. If `new_path` and `old_path`
           are equal, the ''restricted'' flag will also be set, meaning in this
           case that the differences between two revisions are restricted to
           those occurring on that path.

        In any case, either path@rev pairs must exist.
        """
        req.perm.assert_permission('CHANGESET_VIEW')

        # -- retrieve arguments
        new_path = req.args.get('new_path')
        new = req.args.get('new')
        old_path = req.args.get('old_path')
        old = req.args.get('old')

        if old and '@' in old:
            old_path, old = unescape(old).split('@')
        if new and '@' in new:
            new_path, new = unescape(new).split('@')

        # -- normalize and check for special case
        repos = self.env.get_repository(req.authname)
        new_path = repos.normalize_path(new_path)
        new = repos.normalize_rev(new)

        repos.authz.assert_permission_for_changeset(new)

        old_path = repos.normalize_path(old_path or new_path)
        old = repos.normalize_rev(old or new)

        if old_path == new_path and old == new: # revert to Changeset
            old_path = old = None

        diff_options = get_diff_options(req)

        # -- setup the `chgset` and `restricted` flags, see docstring above.
        chgset = not old and not old_path
        if chgset:
            restricted = new_path not in ('', '/') # (subset or not)
        else:
            restricted = old_path == new_path # (same path or not)

        # -- redirect if changing the diff options
        if req.args.has_key('update'):
            if chgset:
                if restricted:
                    req.redirect(req.href.changeset(new, new_path))
                else:
                    req.redirect(req.href.changeset(new))
            else:
                req.redirect(req.href.changeset(new, new_path, old=old,
                                                old_path=old_path))

        # -- preparing the diff arguments
        if chgset:
            prev = repos.get_node(new_path, new).get_previous()
            if prev:
                prev_path, prev_rev = prev[:2]
            else:
                prev_path, prev_rev = new_path, repos.previous_rev(new)
            diff_args = DiffArgs(old_path=prev_path, old_rev=prev_rev,
                                 new_path=new_path, new_rev=new)
        else:
            if not new:
                new = repos.youngest_rev
            elif not old:
                old = repos.youngest_rev
            if not old_path:
                old_path = new_path
            diff_args = DiffArgs(old_path=old_path, old_rev=old,
                                 new_path=new_path, new_rev=new)
        if chgset:
            chgset = repos.get_changeset(new)
            message = chgset.message or '--'
            if self.wiki_format_messages:
                message = wiki_to_html(message, self.env, req,
                                              escape_newlines=True)
            else:
                message = html.PRE(message)
            req.check_modified(chgset.date, [
                diff_options[0],
                ''.join(diff_options[1]),
                repos.name,
                repos.rev_older_than(new, repos.youngest_rev),
                message,
                pretty_timedelta(chgset.date, None, 3600)])
        else:
            message = None # FIXME: what date should we choose for a diff?

        req.hdf['changeset'] = diff_args

        format = req.args.get('format')

        if format in ['diff', 'zip']:
            req.perm.assert_permission('FILE_VIEW')
            # choosing an appropriate filename
            rpath = new_path.replace('/','_')
            if chgset:
                if restricted:
                    filename = 'changeset_%s_r%s' % (rpath, new)
                else:
                    filename = 'changeset_r%s' % new
            else:
                if restricted:
                    filename = 'diff-%s-from-r%s-to-r%s' \
                                  % (rpath, old, new)
                elif old_path == '/': # special case for download (#238)
                    filename = '%s-r%s' % (rpath, old)
                else:
                    filename = 'diff-from-%s-r%s-to-%s-r%s' \
                               % (old_path.replace('/','_'), old, rpath, new)
            if format == 'diff':
                self._render_diff(req, filename, repos, diff_args,
                                  diff_options)
                return
            elif format == 'zip':
                self._render_zip(req, filename, repos, diff_args)
                return

        # -- HTML format
        self._render_html(req, repos, chgset, restricted, message,
                          diff_args, diff_options)
        if chgset:
            diff_params = 'new=%s' % new
        else:
            diff_params = unicode_urlencode({'new_path': new_path,
                                             'new': new,
                                             'old_path': old_path,
                                             'old': old})
        add_link(req, 'alternate', '?format=diff&'+diff_params, 'Unified Diff',
                 'text/plain', 'diff')
        add_link(req, 'alternate', '?format=zip&'+diff_params, 'Zip Archive',
                 'application/zip', 'zip')
        add_stylesheet(req, 'common/css/changeset.css')
        add_stylesheet(req, 'common/css/diff.css')
        add_stylesheet(req, 'common/css/code.css')
        return 'changeset.cs', None
Ejemplo n.º 17
0
    def process_request(self, req):
        """The appropriate mode of operation is inferred from the request
        parameters:

         * If `new_path` and `old_path` are equal (or `old_path` is omitted)
           and `new` and `old` are equal (or `old` is omitted),
           then we're about to view a revision Changeset: `chgset` is True.
           Furthermore, if the path is not the root, the changeset is
           ''restricted'' to that path (only the changes affecting that path,
           its children or its ancestor directories will be shown).
         * In any other case, the set of changes corresponds to arbitrary
           differences between path@rev pairs. If `new_path` and `old_path`
           are equal, the ''restricted'' flag will also be set, meaning in this
           case that the differences between two revisions are restricted to
           those occurring on that path.

        In any case, either path@rev pairs must exist.
        """
        req.perm.assert_permission('CHANGESET_VIEW')

        # -- retrieve arguments
        new_path = req.args.get('new_path')
        new = req.args.get('new')
        old_path = req.args.get('old_path')
        old = req.args.get('old')

        if old and '@' in old:
            old_path, old = unescape(old).split('@')
        if new and '@' in new:
            new_path, new = unescape(new).split('@')

        # -- normalize and check for special case
        repos = self.env.get_repository(req.authname)
        new_path = repos.normalize_path(new_path)
        new = repos.normalize_rev(new)

        repos.authz.assert_permission_for_changeset(new)

        old_path = repos.normalize_path(old_path or new_path)
        old = repos.normalize_rev(old or new)

        if old_path == new_path and old == new: # revert to Changeset
            old_path = old = None

        diff_options = get_diff_options(req)

        # -- setup the `chgset` and `restricted` flags, see docstring above.
        chgset = not old and not old_path
        if chgset:
            restricted = new_path not in ('', '/') # (subset or not)
        else:
            restricted = old_path == new_path # (same path or not)

        # -- redirect if changing the diff options
        if req.args.has_key('update'):
            if chgset:
                if restricted:
                    req.redirect(req.href.changeset(new, new_path))
                else:
                    req.redirect(req.href.changeset(new))
            else:
                req.redirect(req.href.changeset(new, new_path, old=old,
                                                old_path=old_path))

        # -- preparing the diff arguments
        if chgset:
            prev = repos.get_node(new_path, new).get_previous()
            if prev:
                prev_path, prev_rev = prev[:2]
            else:
                prev_path, prev_rev = new_path, repos.previous_rev(new)
            diff_args = DiffArgs(old_path=prev_path, old_rev=prev_rev,
                                 new_path=new_path, new_rev=new)
        else:
            if not new:
                new = repos.youngest_rev
            elif not old:
                old = repos.youngest_rev
            if not old_path:
                old_path = new_path
            diff_args = DiffArgs(old_path=old_path, old_rev=old,
                                 new_path=new_path, new_rev=new)
        if chgset:
            chgset = repos.get_changeset(new)
            message = chgset.message or '--'
            if self.wiki_format_messages:
                message = wiki_to_html(message, self.env, req,
                                              escape_newlines=True)
            else:
                message = html.PRE(message)
            req.check_modified(chgset.date, [
                diff_options[0],
                ''.join(diff_options[1]),
                repos.name,
                repos.rev_older_than(new, repos.youngest_rev),
                message,
                pretty_timedelta(chgset.date, None, 3600)])
        else:
            message = None # FIXME: what date should we choose for a diff?

        req.hdf['changeset'] = diff_args

        format = req.args.get('format')

        if format in ['diff', 'zip']:
            req.perm.assert_permission('FILE_VIEW')
            # choosing an appropriate filename
            rpath = new_path.replace('/','_')
            if chgset:
                if restricted:
                    filename = 'changeset_%s_r%s' % (rpath, new)
                else:
                    filename = 'changeset_r%s' % new
            else:
                if restricted:
                    filename = 'diff-%s-from-r%s-to-r%s' \
                                  % (rpath, old, new)
                elif old_path == '/': # special case for download (#238)
                    filename = '%s-r%s' % (rpath, old)
                else:
                    filename = 'diff-from-%s-r%s-to-%s-r%s' \
                               % (old_path.replace('/','_'), old, rpath, new)
            if format == 'diff':
                self._render_diff(req, filename, repos, diff_args,
                                  diff_options)
                return
            elif format == 'zip':
                self._render_zip(req, filename, repos, diff_args)
                return

        # -- HTML format
        self._render_html(req, repos, chgset, restricted, message,
                          diff_args, diff_options)
        if chgset:
            diff_params = 'new=%s' % new
        else:
            diff_params = unicode_urlencode({'new_path': new_path,
                                             'new': new,
                                             'old_path': old_path,
                                             'old': old})
        add_link(req, 'alternate', '?format=diff&'+diff_params, 'Unified Diff',
                 'text/plain', 'diff')
        add_link(req, 'alternate', '?format=zip&'+diff_params, 'Zip Archive',
                 'application/zip', 'zip')
        add_stylesheet(req, 'common/css/changeset.css')
        add_stylesheet(req, 'common/css/diff.css')
        add_stylesheet(req, 'common/css/code.css')
        return 'changeset.cs', None
Ejemplo n.º 18
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)
Ejemplo n.º 19
0
    def _get_userlog(self, req, db, user, sort):
        mimeview = Mimeview(self.env)
        repos = self.env.get_repository()
        diff_options = get_diff_options(req)
        cursor = db.cursor()
        cursor.execute("SELECT rev, time, message FROM revision "
                       "WHERE author='%s' ORDER BY time %s" % (user, sort))
                       # Have to sort by time because rev is a text field
                       # and sorts lexicographically rather than numerically
        changesets = []
        for rev, time, message in cursor:
            if self.wiki_format_messages:
                message = wiki_to_html(message, self.env, req,
                                              escape_newlines=True)
            else:
                message = html.PRE(message)
            prev = repos.get_node('/', rev).get_previous()
            if prev:
                prev_rev = prev[1]
            else:
                prev_rev = rev
            diffs = []
            changes = repos.get_changes(old_path='/', old_rev=prev_rev,
                                        new_path='/', new_rev=rev)
            for old_node, new_node, kind, change in changes:
                if kind == Node.DIRECTORY:
                    if change == Changeset.ADD:
                        diffs.append(('%s added' % new_node.path, ''))
                    elif change == Changeset.DELETE:
                        diffs.append(('%s deleted' % old_node.path, ''))
                    continue

                new_content = old_content = ''
                new_node_info = old_node_info = ('','')
                
                if old_node:
                    old_content = old_node.get_content().read()
                    if is_binary(old_content):
                        continue
                    old_node_info = (old_node.path, old_node.rev)
                    old_content = mimeview.to_unicode(old_content,
                                                      old_node.content_type)
                if new_node:
                    new_content = new_node.get_content().read()
                    if is_binary(new_content):
                        continue
                    new_node_info = (new_node.path, new_node.rev)
                    new_path = new_node.path
                    new_content = mimeview.to_unicode(new_content,
                                                      new_node.content_type)
                else:
                    old_node_path = repos.normalize_path(old_node.path)
                    diff_old_path = repos.normalize_path('/')
                    new_path = posixpath.join('/', old_node_path[len(diff_old_path)+1:])

                if old_content != new_content:
                    context = 3
                    options = diff_options[1]
                    for option in options:
                        if option.startswith('-U'):
                            context = int(option[2:])
                            break
                    if not old_node_info[0]:
                        old_node_info = new_node_info # support for 'A'dd changes
                    diff = 'Index: ' + new_path + CRLF
                    diff += '=' * 67 + CRLF
                    diff += '--- %s (revision %s)' % old_node_info + CRLF
                    diff += '+++ %s (revision %s)' % new_node_info + CRLF
                    for line in unified_diff(old_content.splitlines(),
                                             new_content.splitlines(), context,
                                             ignore_blank_lines='-B' in options,
                                             ignore_case='-i' in options,
                                             ignore_space_changes='-b' in options):
                        diff += line + CRLF
                    if change == Changeset.ADD:
                        diffs.append(('%s added' % (new_node.path,), diff))
                    elif change == Changeset.DELETE:
                        diffs.append(('%s deleted' % (old_node.path,), diff))
                    else:
                        diffs.append(('%s edited' % (new_node.path,), diff))
            changesets.append((int(rev), format_datetime(time), message, diffs))
        return changesets
Ejemplo n.º 20
0
    def process_request(self, req):
        action = req.args.get('action', 'view')
        pagename = req.args.get('page', 'WikiStart')
        version = req.args.get('version')
        old_version = req.args.get('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=version)

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

        if version and versioned_page.version != int(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 = int(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 == '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))
        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 == '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)
Ejemplo n.º 21
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
Ejemplo n.º 22
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')

        self._set_title(req, page, u'变化')

        # 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:  # FIXME: what about reverse diffs?
                old_version, page = page.version, \
                                    WikiPage(self.env, page.name, old_version)
        latest_page = WikiPage(self.env, page.name)
        new_version = int(page.version)
        info = {
            'version': new_version,
            'latest_version': latest_page.version,
            'history_href': req.href.wiki(page.name, action='history')
        }

        num_changes = 0
        old_page = None
        prev_version = next_version = None
        for version, t, author, comment, ipnr in latest_page.get_history():
            if version == new_version:
                if t:
                    info['time'] = format_datetime(t)
                    info['time_delta'] = pretty_timedelta(t)
                info['author'] = author or 'anonymous'
                info['comment'] = wiki_to_html(comment or '--', self.env, req,
                                               db)
                info['ipnr'] = ipnr or ''
            else:
                if version < new_version:
                    num_changes += 1
                    if not prev_version:
                        prev_version = 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
                else:
                    next_version = version
        req.hdf['wiki'] = info

        # -- prev/next links
        if prev_version:
            add_link(
                req, 'prev',
                req.href.wiki(page.name, action='diff', version=prev_version),
                'Version %d' % prev_version)
        if next_version:
            add_link(
                req, 'next',
                req.href.wiki(page.name, action='diff', version=next_version),
                'Version %d' % next_version)

        # -- text diffs
        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
Ejemplo n.º 23
0
    def process_request(self, req):
        action = req.args.get('action', 'view')
        pagename = req.args.get('page', 'WikiStart')
        version = req.args.get('version')
        old_version = req.args.get('old_version')

        if pagename.endswith('/'):
            req.redirect(req.href.wiki(pagename.strip('/')))

        page = WikiPage(self.env, pagename)
        versioned_page = WikiPage(self.env, pagename, version=version)
        page.permission_v=self._perm_v_list(pagename,req)
        page.permission_w=self._perm_w_list(pagename,req)
        versioned_page.permission_v=self._perm_v_list(pagename,req)
        versioned_page.permission_w=self._perm_w_list(pagename,req)
        req.perm(page.resource).require('WIKI_VIEW')
        req.perm(versioned_page.resource).require('WIKI_VIEW')
        page.admin_or_creator="TRAC_ADMIN" in req.perm or self._is_the_creator(pagename,req.authname,req)==True
        versioned_page.admin_or_creator="TRAC_ADMIN" in req.perm or self._is_the_creator(pagename,req.authname,req)==True
        page.edit_perm=self._has_edit_perm(page.name,req.authname,req)
        versioned_page.edit_perm=self._has_edit_perm(page.name,req.authname,req)
        page.page_exist=self._exist_in_wiki(pagename,req)
        versioned_page.page_exist=self._exist_in_wiki(pagename,req)


        if self._has_view_perm(page.name,req.authname,req)==False:
            raise ResourceNotFound(
                _('You are not authorized to view this page!'))

        if version and versioned_page.version != int(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))

                permission_v=req.args.get("permission_v","")
                permission_w=req.args.get("permission_w","")
                self._update_wikipermission_v(pagename,permission_v,req)
                self._update_wikipermission_w(pagename,permission_w,req)
                has_collision = int(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 == '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))
        elif action == 'delete':
            return self._render_confirm_delete(req, versioned_page)
        elif action == 'rename':
            return self._render_confirm_rename(req, page)
        elif action == 'edit':
            if self._has_edit_perm(page.name,req.authname,req)==False:
                raise ResourceNotFound(_('You are not authorized to edit this page!'))
            return self._render_editor(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)
Ejemplo n.º 24
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')

        self._set_title(req, page, u'变化')

        # 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: # FIXME: what about reverse diffs?
                old_version, page = page.version, \
                                    WikiPage(self.env, page.name, old_version)
        latest_page = WikiPage(self.env, page.name)
        new_version = int(page.version)
        info = {
            'version': new_version,
            'latest_version': latest_page.version,
            'history_href': req.href.wiki(page.name, action='history')
        }

        num_changes = 0
        old_page = None
        prev_version = next_version = None
        for version,t,author,comment,ipnr in latest_page.get_history():
            if version == new_version:
                if t:
                    info['time'] = format_datetime(t)
                    info['time_delta'] = pretty_timedelta(t)
                info['author'] = author or 'anonymous'
                info['comment'] = wiki_to_html(comment or '--',
                                               self.env, req, db)
                info['ipnr'] = ipnr or ''
            else:
                if version < new_version:
                    num_changes += 1
                    if not prev_version:
                        prev_version = 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
                else:
                    next_version = version
        req.hdf['wiki'] = info

        # -- prev/next links
        if prev_version:
            add_link(req, 'prev', req.href.wiki(page.name, action='diff',
                                                version=prev_version),
                     'Version %d' % prev_version)
        if next_version:
            add_link(req, 'next', req.href.wiki(page.name, action='diff',
                                                version=next_version),
                     'Version %d' % next_version)

        # -- text diffs
        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
Ejemplo n.º 25
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"] = 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": 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"] = author or "anonymous"
                info["comment"] = comment or "--"
                info["ipnr"] = 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