Exemplo n.º 1
0
    def rename(self, new_name):
        """Rename wiki page in-place, keeping the history intact.
        Renaming a page this way will eventually leave dangling references
        to the old page - which litterally doesn't exist anymore.
        """
        assert self.exists, "Cannot rename non-existent page"

        if not validate_page_name(new_name):
            raise TracError(_("Invalid Wiki page name '%(name)s'",
                              name=new_name))
        old_name = self.name
        
        with self.env.db_transaction as db:
            new_page = WikiPage(self.env, new_name)
            if new_page.exists:
                raise TracError(_("Can't rename to existing %(name)s page.",
                                  name=new_name))

            db("UPDATE wiki SET name=%s WHERE name=%s", (new_name, old_name))
            # Invalidate page name cache
            del WikiSystem(self.env).pages
            # Reparent attachments
            from trac.attachment import Attachment
            Attachment.reparent_all(self.env, 'wiki', old_name, 'wiki',
                                    new_name)

        self.name = new_name
        self.env.log.info('Renamed page %s to %s', old_name, new_name)
        
        for listener in WikiSystem(self.env).change_listeners:
            if hasattr(listener, 'wiki_page_renamed'):
                listener.wiki_page_renamed(self, old_name)
Exemplo n.º 2
0
    def rename(self, new_name):
        """Rename wiki page in-place, keeping the history intact.
        Renaming a page this way will eventually leave dangling references
        to the old page - which literally doesn't exist anymore.
        """
        if not self.exists:
            raise TracError(_("Cannot rename non-existent page"))

        if not validate_page_name(new_name):
            raise TracError(
                _("Invalid Wiki page name '%(name)s'", name=new_name))
        old_name = self.name

        with self.env.db_transaction as db:
            new_page = WikiPage(self.env, new_name)
            if new_page.exists:
                raise TracError(
                    _("Can't rename to existing %(name)s page.",
                      name=new_name))

            db("UPDATE wiki SET name=%s WHERE name=%s", (new_name, old_name))
            # Invalidate page name cache
            del WikiSystem(self.env).pages
            # Reparent attachments
            from trac.attachment import Attachment
            Attachment.reparent_all(self.env, self.realm, old_name, self.realm,
                                    new_name)

        self.name = new_name
        self.env.log.info("Renamed page %s to %s", old_name, new_name)

        for listener in WikiSystem(self.env).change_listeners:
            if hasattr(listener, 'wiki_page_renamed'):
                listener.wiki_page_renamed(self, old_name)
Exemplo n.º 3
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))
Exemplo n.º 4
0
    def save(self, author, comment, remote_addr=None, t=None, db=None):
        """Save a new version of a page.

        :since 1.0: the `db` parameter is no longer needed and will be removed
                    in version 1.1.1
        :since 1.0.3: `remote_addr` is optional and deprecated, and will be
                      removed in 1.3.1
        """
        if not validate_page_name(self.name):
            raise TracError(_("Invalid Wiki page name '%(name)s'",
                              name=self.name))

        new_text = self.text != self.old_text
        if not new_text and self.readonly == self.old_readonly:
            raise TracError(_("Page not modified"))
        t = t or datetime.now(utc)

        with self.env.db_transaction as db:
            if new_text:
                db("""INSERT INTO wiki (name, version, time, author, ipnr,
                                        text, comment, readonly)
                      VALUES (%s,%s,%s,%s,%s,%s,%s,%s)
                      """, (self.name, self.version + 1, to_utimestamp(t),
                            author, remote_addr, self.text, comment,
                            self.readonly))
                self.version += 1
                self.resource = self.resource(version=self.version)
            else:
                db("UPDATE wiki SET readonly=%s WHERE name=%s",
                   (self.readonly, self.name))
            if self.version == 1:
                # Invalidate page name cache
                del WikiSystem(self.env).pages

        self.author = author
        self.comment = comment
        self.time = t

        for listener in WikiSystem(self.env).change_listeners:
            if self.version == 1:
                listener.wiki_page_added(self)
            else:
                from trac.util import arity
                if arity(listener.wiki_page_changed) == 6:
                    listener.wiki_page_changed(self, self.version, t,
                                               comment, author, remote_addr)
                else:
                    listener.wiki_page_changed(self, self.version, t,
                                               comment, author)

        self.old_readonly = self.readonly
        self.old_text = self.text
Exemplo n.º 5
0
 def _do_rename(self, name, new_name):
     if new_name == name:
         return
     if not new_name:
         raise AdminCommandError(_("A new name is mandatory for a rename."))
     if not validate_page_name(new_name):
         raise AdminCommandError(_("The new name is invalid."))
     with self.env.db_transaction:
         if model.WikiPage(self.env, new_name).exists:
             raise AdminCommandError(_("The page %(name)s already exists.",
                                       name=new_name))
         page = model.WikiPage(self.env, name)
         page.rename(new_name)
Exemplo n.º 6
0
 def _do_rename(self, name, new_name):
     if new_name == name:
         return
     if not new_name:
         raise AdminCommandError(_("A new name is mandatory for a rename."))
     if not validate_page_name(new_name):
         raise AdminCommandError(_("The new name is invalid."))
     with self.env.db_transaction:
         if model.WikiPage(self.env, new_name).exists:
             raise AdminCommandError(
                 _("The page %(name)s already exists.", name=new_name))
         page = model.WikiPage(self.env, name)
         page.rename(new_name)
Exemplo n.º 7
0
    def save(self, author, comment, remote_addr=None, t=None):
        """Save a new version of a page.

        :since 1.0.3: `remote_addr` is optional and deprecated, and will be
                      removed in 1.3.1
        """
        if not validate_page_name(self.name):
            raise TracError(
                _("Invalid Wiki page name '%(name)s'", name=self.name))

        new_text = self.text != self.old_text
        if not new_text and self.readonly == self.old_readonly:
            raise TracError(_("Page not modified"))
        t = t or datetime_now(utc)

        with self.env.db_transaction as db:
            if new_text:
                db(
                    """INSERT INTO wiki (name, version, time, author, ipnr,
                                        text, comment, readonly)
                      VALUES (%s,%s,%s,%s,%s,%s,%s,%s)
                      """,
                    (self.name, self.version + 1, to_utimestamp(t), author,
                     remote_addr, self.text, comment, self.readonly))
                self.version += 1
            else:
                db("UPDATE wiki SET readonly=%s WHERE name=%s",
                   (self.readonly, self.name))
            if self.version == 1:
                # Invalidate page name cache
                del WikiSystem(self.env).pages

        self.author = author
        self.comment = comment
        self.time = t

        for listener in WikiSystem(self.env).change_listeners:
            if self.version == 1:
                listener.wiki_page_added(self)
            else:
                from trac.util import arity
                if arity(listener.wiki_page_changed) == 6:
                    listener.wiki_page_changed(self, self.version, t, comment,
                                               author, remote_addr)
                else:
                    listener.wiki_page_changed(self, self.version, t, comment,
                                               author)

        self.old_readonly = self.readonly
        self.old_text = self.text
Exemplo n.º 8
0
    def import_page(self, filename, title, create_only=[], replace=False):
        if not validate_page_name(title):
            raise AdminCommandError(
                _("Invalid Wiki page name '%(name)s'", name=title))
        if filename:
            if not os.path.isfile(filename):
                raise AdminCommandError(
                    _("'%(name)s' is not a file",
                      name=path_to_unicode(filename)))
            data = read_file(filename)
        else:
            data = sys.stdin.read()
        data = to_unicode(data, 'utf-8')

        with self.env.db_transaction as db:
            # Make sure we don't insert the exact same page twice
            old = db(
                """SELECT text FROM wiki WHERE name=%s
                        ORDER BY version DESC LIMIT 1
                        """, (title, ))
            if old and title in create_only:
                printout(_("  %(title)s already exists", title=title))
                return False
            if old and data == old[0][0]:
                printout(_("  %(title)s is already up to date", title=title))
                return False

            if replace and old:
                db(
                    """UPDATE wiki SET text=%s
                      WHERE name=%s
                        AND version=(SELECT max(version) FROM wiki
                                     WHERE name=%s)
                      """, (data, title, title))
            else:
                db(
                    """INSERT INTO wiki (version, readonly, name, time, author,
                                        text)
                      SELECT 1 + COALESCE(max(version), 0),
                             COALESCE(max(readonly), 0),
                             %s, %s, 'trac', %s FROM wiki
                      WHERE name=%s AND version=(SELECT max(version)
                                                 FROM wiki WHERE name=%s)
                      """, (title, to_utimestamp(
                        datetime_now(utc)), data, title, title))
            if not old:
                del WikiSystem(self.env).pages
        return True
Exemplo n.º 9
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))
Exemplo n.º 10
0
    def save(self, author, comment, t=None, replace=False):
        """Save a new version of a page."""
        if not validate_page_name(self.name):
            raise TracError(
                _("Invalid Wiki page name '%(name)s'", name=self.name))

        new_text = self.text != self.old_text
        if not new_text and self.readonly == self.old_readonly:
            raise TracError(_("Page not modified"))
        t = t or datetime_now(utc)

        with self.env.db_transaction as db:
            if new_text:
                if replace and self.version != 0:
                    db(
                        """
                        UPDATE wiki SET text=%s WHERE name=%s AND version=%s
                        """, (self.text, self.name, self.version))
                else:
                    self.version += 1
                    db(
                        """INSERT INTO wiki
                           (name,version,time,author,text,comment,readonly)
                          VALUES (%s,%s,%s,%s,%s,%s,%s)
                          """, (self.name, self.version, to_utimestamp(t),
                                author, self.text, comment, self.readonly))
            else:
                db("UPDATE wiki SET readonly=%s WHERE name=%s",
                   (self.readonly, self.name))
            if self.version == 1:
                # Invalidate page name cache
                del WikiSystem(self.env).pages

        self.author = author
        self.comment = comment
        self.time = t

        for listener in WikiSystem(self.env).change_listeners:
            with self.env.component_guard(listener):
                if self.version == 1:
                    listener.wiki_page_added(self)
                else:
                    listener.wiki_page_changed(self, self.version, t, comment,
                                               author)

        self.old_readonly = self.readonly
        self.old_text = self.text
Exemplo n.º 11
0
    def save(self, author, comment, remote_addr, t=None, db=None):
        """Save a new version of a page.

        :since 0.13: the `db` parameter is no longer needed and will be removed
        in version 0.14
        """
        if not validate_page_name(self.name):
            raise TracError(
                _("Invalid Wiki page name '%(name)s'", name=self.name))

        new_text = self.text != self.old_text
        if not new_text and self.readonly == self.old_readonly:
            raise TracError(_("Page not modified"))
        t = t or datetime.now(utc)

        with self.env.db_transaction as db:
            if new_text:
                db(
                    """INSERT INTO wiki (name, version, time, author, ipnr,
                                        text, comment, readonly)
                      VALUES (%s,%s,%s,%s,%s,%s,%s,%s)
                      """,
                    (self.name, self.version + 1, to_utimestamp(t), author,
                     remote_addr, self.text, comment, self.readonly))
                self.version += 1
                self.resource = self.resource(version=self.version)
            else:
                db("UPDATE wiki SET readonly=%s WHERE name=%s",
                   (self.readonly, self.name))
            if self.version == 1:
                # Invalidate page name cache
                del WikiSystem(self.env).pages

        self.author = author
        self.comment = comment
        self.time = t

        for listener in WikiSystem(self.env).change_listeners:
            if self.version == 1:
                listener.wiki_page_added(self)
            else:
                listener.wiki_page_changed(self, self.version, t, comment,
                                           author, remote_addr)

        self.old_readonly = self.readonly
        self.old_text = self.text
Exemplo n.º 12
0
    def import_page(self, filename, title, create_only=[],
                    replace=False):
        if not validate_page_name(title):
            raise AdminCommandError(_("Invalid Wiki page name '%(name)s'",
                                      name=title))
        if filename:
            if not os.path.isfile(filename):
                raise AdminCommandError(_("'%(name)s' is not a file",
                                          name=path_to_unicode(filename)))
            data = read_file(filename)
        else:
            data = sys.stdin.read()
        data = to_unicode(data, 'utf-8')

        with self.env.db_transaction as db:
            # Make sure we don't insert the exact same page twice
            old = db("""SELECT text FROM wiki WHERE name=%s
                        ORDER BY version DESC LIMIT 1
                        """, (title,))
            if old and title in create_only:
                printout(_("  %(title)s already exists", title=title))
                return False
            if old and data == old[0][0]:
                printout(_("  %(title)s is already up to date", title=title))
                return False

            if replace and old:
                db("""UPDATE wiki SET text=%s
                      WHERE name=%s
                        AND version=(SELECT max(version) FROM wiki
                                     WHERE name=%s)
                      """, (data, title, title))
            else:
                db("""INSERT INTO wiki(version, name, time, author, ipnr, text)
                      SELECT 1 + COALESCE(max(version), 0), %s, %s, 'trac',
                             '127.0.0.1', %s FROM wiki WHERE name=%s
                      """, (title, to_utimestamp(datetime.now(utc)), data,
                            title))
            if not old:
                del WikiSystem(self.env).pages
        return True
Exemplo n.º 13
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)
Exemplo n.º 14
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)
Exemplo n.º 15
0
    def save(self, author, comment, remote_addr=None, t=None, db=None):
        """Save a new version of a page.

        :since 1.0: the `db` parameter is no longer needed and will be removed
                    in version 1.1.1
        :since 1.0.3: `remote_addr` is optional and deprecated, and will be
                      removed in 1.3.1
        """
        if not validate_page_name(self.name):
            raise TracError(
                _("Invalid Wiki page name '%(name)s'", name=self.name))

        new_text = self.text != self.old_text
        if not new_text and self.readonly == self.old_readonly:
            raise TracError(_("Page not modified"))
        t = t or datetime_now(utc)

        with self.env.db_transaction as db:
            if new_text:
                db(
                    """INSERT INTO wiki (name, version, time, author, ipnr,
                                        text, comment, readonly)
                      VALUES (%s,%s,%s,%s,%s,%s,%s,%s)
                      """,
                    (self.name, self.version + 1, to_utimestamp(t), author,
                     remote_addr, self.text, comment, self.readonly))
                self.version += 1
                self.resource = self.resource(version=self.version)
            else:
                db("UPDATE wiki SET readonly=%s WHERE name=%s",
                   (self.readonly, self.name))
            if self.version == 1:
                # Invalidate page name cache
                del WikiSystem(self.env).pages

        self.author = author
        self.comment = comment
        self.time = t

        for listener in WikiSystem(self.env).change_listeners:
            if self.version == 1:
                listener.wiki_page_added(self)
            else:
                listener.wiki_page_changed(page=self,
                                           version=self.version,
                                           t=t,
                                           comment=comment,
                                           author=author,
                                           ipnr=remote_addr)

        context = dict(version=self.version,
                       comment=comment,
                       author=author,
                       remote_addr=remote_addr)
        if self.version == 1:
            ResourceSystem(self.env).resource_created(self, context)
        else:
            old_values = dict()
            if self.readonly != self.old_readonly:
                old_values["readonly"] = self.old_readonly
            if self.text != self.old_text:
                old_values["text"] = self.old_text
            ResourceSystem(self.env).resource_changed(self,
                                                      old_values,
                                                      context=context)

        self.old_readonly = self.readonly
        self.old_text = self.text