Example #1
0
File: env.py Project: t2y/trac
    def upgrade(self, backup=False, backup_dest=None):
        """Upgrade database.

        :param backup: whether or not to backup before upgrading
        :param backup_dest: name of the backup file
        :return: whether the upgrade was performed
        """
        upgraders = []
        for participant in self.setup_participants:
            args = ()
            with self.db_query as db:
                if arity(participant.environment_needs_upgrade) == 1:
                    args = (db,)
                if participant.environment_needs_upgrade(*args):
                    upgraders.append(participant)
        if not upgraders:
            return

        if backup:
            try:
                self.backup(backup_dest)
            except Exception as e:
                raise BackupError(e)

        for participant in upgraders:
            self.log.info("%s.%s upgrading...", participant.__module__,
                          participant.__class__.__name__)
            args = ()
            with self.db_transaction as db:
                if arity(participant.upgrade_environment) == 1:
                    args = (db,)
                participant.upgrade_environment(*args)
            # Database schema may have changed, so close all connections
            DatabaseManager(self).shutdown()
        return True
Example #2
0
    def upgrade(self, backup=False, backup_dest=None):
        """Upgrade database.

        :param backup: whether or not to backup before upgrading
        :param backup_dest: name of the backup file
        :return: whether the upgrade was performed
        """
        upgraders = []
        for participant in self.setup_participants:
            args = ()
            with self.db_query as db:
                if arity(participant.environment_needs_upgrade) == 1:
                    args = (db,)
                if participant.environment_needs_upgrade(*args):
                    upgraders.append(participant)
        if not upgraders:
            return

        if backup:
            try:
                self.backup(backup_dest)
            except Exception as e:
                raise BackupError(e)

        for participant in upgraders:
            self.log.info("%s.%s upgrading...", participant.__module__, participant.__class__.__name__)
            args = ()
            with self.db_transaction as db:
                if arity(participant.upgrade_environment) == 1:
                    args = (db,)
                participant.upgrade_environment(*args)
            # Database schema may have changed, so close all connections
            DatabaseManager(self).shutdown()
        del self.database_version
        return True
Example #3
0
    def validate_test_case(self, req, postname, version, fields):
        if 'testcase-preview' in req.args:
            return []

        qa_res = Resource('qa', postname, version)

        if req.perm(qa_res).has_permission('QA_ADMIN'):
            return []

        if version > 1:
            bp = BlogPost(self.env, postname, version)
            last_post_fields = bp._fetch_fields(version=version - 1)
        else:
            last_post_fields = {}

        field_names = set(fields).union(last_post_fields)
        changes = []

        for field in field_names:
            old = to_unicode(last_post_fields.get(field, ''))
            new = to_unicode(fields.get(field, ''))
            if new and old != new:
                changes.append((old, new))
        author = fields.get('author', '')

        if arity(FilterSystem.test) == 4:
            # 0.11 compatible method signature
            FilterSystem(self.env).test(req, author, changes)
        else:
            # 0.12+ compatible that adds an 'ip' argument
            FilterSystem(self.env).test(req, author, changes, req.remote_addr)
        return []
    def validate_blog_post(self, req, postname, version, fields):
        if 'blog-preview' in req.args:
            return []

        blog_res = Resource('blog', postname, version)
        if req.perm(blog_res).has_permission('BLOG_ADMIN'):
            return []

        if version > 1:
            bp = BlogPost(self.env, postname, version)
            last_post_fields = bp._fetch_fields(version=version-1)
        else:
            last_post_fields = {}

        field_names = set(fields).union(last_post_fields)
        changes = []
        for field in field_names:
            old = to_unicode(last_post_fields.get(field, ''))
            new = to_unicode(fields.get(field, ''))
            if new and old != new:
                changes.append((old, new))
        author = fields.get('author', '')
        if arity(FilterSystem.test) == 4:
            # 0.11 compatible method signature
            FilterSystem(self.env).test(req, author, changes)
        else:
            # 0.12+ compatible that adds an 'ip' argument
            FilterSystem(self.env).test(req, author, changes, req.remote_addr)
        return []
Example #5
0
 def _post_process_request(self, req, *args):
     resp = args
     # `metadata` and the backward compatibility `method` are
     # optional in IRequestHandler's response. If not specified,
     # the default value is appended to response.
     metadata = {}
     method = None
     if len(resp) == 2:
         resp += (metadata, None)
     elif len(resp) == 3:
         metadata = resp[2]
         resp += (None, )
     elif len(resp) == 4:
         metadata = resp[2]
         method = resp[3]
     if method and isinstance(metadata, dict):
         metadata['method'] = method
     nbargs = len(resp)
     for f in reversed(self.filters):
         # As the arity of `post_process_request` has changed since
         # Trac 0.10, only filters with same arity gets passed real values.
         # Errors will call all filters with None arguments,
         # and results will not be not saved.
         extra_arg_count = arity(f.post_process_request) - 1
         if extra_arg_count == nbargs:
             resp = f.post_process_request(req, *resp)
         elif extra_arg_count == nbargs - 1:
             # IRequestFilters may modify the `method`, but the `method`
             # is forwarded when not accepted by the IRequestFilter.
             method = resp[-1]
             resp = f.post_process_request(req, *resp[:-1])
             resp += (method, )
         elif nbargs == 0:
             f.post_process_request(req, *(None, ) * extra_arg_count)
     return resp
Example #6
0
 def sanitize_attrib(env, element):
     if not WikiSystem(env).render_unsafe_content:
         if arity(sanitizer.sanitize_attrs) == 1:
             sanitized = sanitizer.sanitize_attrs(element.attrib)
         else:  # Trac 1.3.2+
             sanitized = sanitizer.sanitize_attrs(element.tag,
                                                  element.attrib)
         element = Element(element.tag, **sanitized)
     return element
Example #7
0
 def needs_upgrade(self):
     """Return whether the environment needs to be upgraded."""
     for participant in self.setup_participants:
         args = ()
         with self.db_query as db:
             if arity(participant.environment_needs_upgrade) == 1:
                 args = (db,)
             if participant.environment_needs_upgrade(*args):
                 self.log.warn("Component %s requires environment upgrade", participant)
                 return True
     return False
Example #8
0
File: env.py Project: t2y/trac
 def needs_upgrade(self):
     """Return whether the environment needs to be upgraded."""
     for participant in self.setup_participants:
         args = ()
         with self.db_query as db:
             if arity(participant.environment_needs_upgrade) == 1:
                 args = (db,)
             if participant.environment_needs_upgrade(*args):
                 self.log.warn("Component %s requires environment upgrade",
                               participant)
                 return True
     return False
Example #9
0
 def get_history(self, limit=None):
     repo = self.repos.repo
     pats = []
     if self.path:
         pats.append('path:' + self.path)
     opts = {'rev': ['%s:0' % hex(self.n)]}
     if self.isfile:
         opts['follow'] = True
     if arity(cmdutil.walkchangerevs) == 4:
         return self._get_history_1_4(repo, pats, opts, limit)
     else:
         return self._get_history_1_3(repo, pats, opts, limit)
Example #10
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
Example #11
0
 def _post_process_request(self, req, *args):
     nbargs = len(args)
     resp = args
     for f in reversed(self.filters):
         # As the arity of `post_process_request` has changed since
         # Trac 0.10, only filters with same arity gets passed real values.
         # Errors will call all filters with None arguments,
         # and results will not be not saved.
         extra_arg_count = arity(f.post_process_request) - 1
         if extra_arg_count == nbargs:
             resp = f.post_process_request(req, *resp)
         elif nbargs == 0:
             f.post_process_request(req, *(None, ) * extra_arg_count)
     return resp
Example #12
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
Example #13
0
 def _post_process_request(self, req, *args):
     nbargs = len(args)
     resp = args
     for f in reversed(self.filters):
         # As the arity of `post_process_request` has changed since
         # Trac 0.10, only filters with same arity gets passed real values.
         # Errors will call all filters with None arguments,
         # and results will not be not saved.
         extra_arg_count = arity(f.post_process_request) - 1
         if extra_arg_count == nbargs:
             resp = f.post_process_request(req, *resp)
         elif nbargs == 0:
             f.post_process_request(req, *(None,)*extra_arg_count)
     return resp
Example #14
0
 def filter_topic(self, context, topic):
     # Test topic for spam.
     try:
         if arity(FilterSystem.test) == 4: #SpamFilter < 0.3.2 or >= 0.7.0
             FilterSystem(self.env).test(context.req, topic['author'],
                 [(None, topic['author']), (None, topic['subject']),
                  (None, topic['body'])])
         else: #SpamFilter >= 0.3.2 or < 0.7.0
             FilterSystem(self.env).test(context.req, topic['author'],
                 [(None, topic['author']), (None, topic['subject']),
                  (None, topic['body'])], context.req.remote_addr)
     except RejectContent, error:
         # Topic contains spam.
         return False, error.message
    def validate_blog_comment(self, req, postname, fields):
        if 'previewcomment' in req.args:
            return []

        blog_res = Resource('blog', postname)
        if req.perm(blog_res).has_permission('BLOG_ADMIN'):
            return []

        author = fields.get('author', '')
        changes = [(None, fields.get('comment', '')), (None, author)]
        if arity(FilterSystem.test) == 4:
            # 0.11 compatible method signature
            FilterSystem(self.env).test(req, author, changes)
        else:
            # 0.12+ compatible that adds an 'ip' argument
            FilterSystem(self.env).test(req, author, changes, req.remote_addr)
        return []
Example #16
0
 def filter_topic(self, context, topic):
     # Test topic for spam.
     try:
         if arity(FilterSystem.test) == 4:  #SpamFilter < 0.3.2 or >= 0.7.0
             FilterSystem(self.env).test(context.req, topic['author'],
                                         [(None, topic['author']),
                                          (None, topic['subject']),
                                          (None, topic['body'])])
         else:  #SpamFilter >= 0.3.2 or < 0.7.0
             FilterSystem(self.env).test(context.req, topic['author'],
                                         [(None, topic['author']),
                                          (None, topic['subject']),
                                          (None, topic['body'])],
                                         context.req.remote_addr)
     except RejectContent, error:
         # Topic contains spam.
         return False, error.message
Example #17
0
    def validate_blog_comment(self, req, postname, fields):
        if 'previewcomment' in req.args:
            return []

        blog_res = Resource('blog', postname)
        if req.perm(blog_res).has_permission('BLOG_ADMIN'):
            return []

        author = fields.get('author', '')
        changes = [(None, fields.get('comment', '')),
                   (None, author)]
        if arity(FilterSystem.test) == 4:
            # 0.11 compatible method signature
            FilterSystem(self.env).test(req, author, changes)
        else:
            # 0.12+ compatible that adds an 'ip' argument
            FilterSystem(self.env).test(req, author, changes, req.remote_addr)
        return []
Example #18
0
 def _post_process_request(self, req, *args):
     resp = args
     # `method` is optional in IRequestHandler's response. If not
     # specified, the default value is appended to response.
     if len(resp) == 3:
         resp += (None, )
     nbargs = len(resp)
     for f in reversed(self.filters):
         # As the arity of `post_process_request` has changed since
         # Trac 0.10, only filters with same arity gets passed real values.
         # Errors will call all filters with None arguments,
         # and results will not be not saved.
         extra_arg_count = arity(f.post_process_request) - 1
         if extra_arg_count == nbargs:
             resp = f.post_process_request(req, *resp)
         elif extra_arg_count == nbargs - 1:
             # IRequestFilters may modify the `method`, but the `method`
             # is forwarded when not accepted by the IRequestFilter.
             method = resp[-1]
             resp = f.post_process_request(req, *resp[:-1])
             resp += (method, )
         elif nbargs == 0:
             f.post_process_request(req, *(None, ) * extra_arg_count)
     return resp
Example #19
0
 def _post_process_request(self, req, *args):
     resp = args
     # `method` is optional in IRequestHandler's response. If not
     # specified, the default value is appended to response.
     if len(resp) == 3:
         resp += (None,)
     nbargs = len(resp)
     for f in reversed(self.filters):
         # As the arity of `post_process_request` has changed since
         # Trac 0.10, only filters with same arity gets passed real values.
         # Errors will call all filters with None arguments,
         # and results will not be not saved.
         extra_arg_count = arity(f.post_process_request) - 1
         if extra_arg_count == nbargs:
             resp = f.post_process_request(req, *resp)
         elif extra_arg_count == nbargs - 1:
             # IRequestFilters may modify the `method`, but the `method`
             # is forwarded when not accepted by the IRequestFilter.
             method = resp[-1]
             resp = f.post_process_request(req, *resp[:-1])
             resp += (method,)
         elif nbargs == 0:
             f.post_process_request(req, *(None,)*extra_arg_count)
     return resp
Example #20
0
                        FloatOption, ChoiceOption
from trac.env import IEnvironmentSetupParticipant
from trac.perm import PermissionSystem
from trac.util import arity
from trac.util.compat import md5, any
from trac.util.text import to_unicode, exception_to_unicode
from trac.util.translation import dgettext, domain_functions
from trac.web.chrome import ITemplateProvider, add_stylesheet, add_script, \
                            add_script_data


_, N_, add_domain = domain_functions('tracworkflowadmin',
                                     '_', 'N_', 'add_domain')


if arity(Option.__init__) <= 5:
    def _option_with_tx(Base): # Trac 0.12.x
        class Option(Base):
            def __getattribute__(self, name):
                val = Base.__getattribute__(self, name)
                if name == '__doc__':
                    val = dgettext('tracworkflowadmin', val)
                return val
        return Option
else:
    def _option_with_tx(Base): # Trac 1.0 or later
        class Option(Base):
            def __init__(self, *args, **kwargs):
                kwargs['doc_domain'] = 'tracworkflowadmin'
                Base.__init__(self, *args, **kwargs)
        return Option
Example #21
0
    def process_request(self, req):
        """ Processing the request. """

        req.perm('blog').assert_permission('BLOG_VIEW')

        blog_core = FullBlogCore(self.env)
        format = req.args.get('format', '').lower()

        command, pagename, path_items, listing_data = self._parse_path(req)
        action = req.args.get('action', 'view').lower()
        try:
            version = int(req.args.get('version', 0))
        except:
            version = 0

        data = {}
        template = 'fullblog_view.html'
        data['blog_about'] = BlogPost(self.env, 'about')
        data['blog_infotext'] = blog_core.get_bloginfotext()
        blog_month_names = map_month_names(
            self.env.config.getlist('fullblog', 'month_names'))
        data['blog_month_names'] = blog_month_names
        self.env.log.debug(
            "Blog debug: command=%r, pagename=%r, path_items=%r" %
            (command, pagename, path_items))

        if not command:
            # Request for just root (display latest)
            data['blog_post_list'] = []
            count = 0
            maxcount = self.num_items
            blog_posts = get_blog_posts(self.env)
            for post in blog_posts:
                bp = BlogPost(self.env, post[0], post[1])
                if 'BLOG_VIEW' in req.perm(bp.resource):
                    data['blog_post_list'].append(bp)
                    count += 1
                if maxcount and count == maxcount:
                    # Only display a certain number on front page (from config)
                    break
            data['blog_list_title'] = "Recent posts" + \
                    (len(blog_posts) > maxcount and \
                        " (max %d) - Browse or Archive for more" % (maxcount,) \
                    or '')
            add_link(req, 'alternate', req.href.blog(format='rss'), 'RSS Feed',
                     'application/rss+xml', 'rss')

        elif command == 'archive':
            # Requesting the archive page
            template = 'fullblog_archive.html'
            data['blog_archive'] = []
            for period, period_posts in group_posts_by_month(
                    get_blog_posts(self.env)):
                allowed_posts = []
                for post in period_posts:
                    bp = BlogPost(self.env, post[0], post[1])
                    if 'BLOG_VIEW' in req.perm(bp.resource):
                        allowed_posts.append(post)
                if allowed_posts:
                    data['blog_archive'].append((period, allowed_posts))
            add_link(req, 'alternate', req.href.blog(format='rss'), 'RSS Feed',
                     'application/rss+xml', 'rss')

        elif command == 'view' and pagename:
            # Requesting a specific blog post
            the_post = BlogPost(self.env, pagename, version)
            req.perm(the_post.resource).require('BLOG_VIEW')
            if not the_post.version:
                raise HTTPNotFound("No blog post named '%s'." % pagename)
            if req.method == 'POST':  # Adding/Previewing a comment
                # Permission?
                req.perm(the_post.resource).require('BLOG_COMMENT')
                comment = BlogComment(self.env, pagename)
                comment.comment = req.args.get('comment', '')
                comment.author = (req.authname != 'anonymous' and req.authname) \
                            or req.args.get('author')
                comment.time = datetime.datetime.now(utc)
                warnings = []
                if 'cancelcomment' in req.args:
                    req.redirect(req.href.blog(pagename))
                elif 'previewcomment' in req.args:
                    warnings.extend(
                        blog_core.create_comment(req,
                                                 comment,
                                                 verify_only=True))
                elif 'submitcomment' in req.args and not warnings:
                    warnings.extend(blog_core.create_comment(req, comment))
                    if not warnings:
                        req.redirect(
                            req.href.blog(pagename) + '#comment-' +
                            str(comment.number))
                data['blog_comment'] = comment
                # Push all warnings out to the user.
                for field, reason in warnings:
                    if field:
                        add_warning(req, "Field '%s': %s" % (field, reason))
                    else:
                        add_warning(req, reason)
            data['blog_post'] = the_post
            context = web_context(req,
                                  the_post.resource,
                                  absurls=format == 'rss' and True or False)
            data['context'] = context
            if format == 'rss':
                return 'fullblog_post.rss', data, 'application/rss+xml'
            # Regular web response
            context = web_context(req, the_post.resource)

            data['blog_attachments'] = AttachmentModule(
                self.env).attachment_data(context)
            # Previous and Next ctxtnav
            prev, next = blog_core.get_prev_next_posts(req.perm, the_post.name)
            if prev:
                add_link(req, 'prev', req.href.blog(prev), prev)
            if next:
                add_link(req, 'next', req.href.blog(next), next)
            if arity(prevnext_nav) == 4:
                # 0.12 compat following trac:changeset:8597
                prevnext_nav(req, 'Previous Post', 'Next Post')
            else:
                prevnext_nav(req, 'Post')
            # RSS feed for post and comments
            add_link(req, 'alternate', req.href.blog(pagename, format='rss'),
                     'RSS Feed', 'application/rss+xml', 'rss')

        elif command in ['create', 'edit']:
            template = 'fullblog_edit.html'
            default_pagename = blog_core._get_default_postname(req.authname)
            the_post = BlogPost(self.env, pagename or default_pagename)
            warnings = []

            if command == 'create' and req.method == 'GET' and not the_post.version:
                # Support appending query arguments for populating intial fields
                the_post.update_fields(req.args)
            if command == 'create' and the_post.version:
                # Post with name or suggested name already exists
                if 'BLOG_CREATE' in req.perm and the_post.name == default_pagename \
                                    and not req.method == 'POST':
                    if default_pagename:
                        add_notice(
                            req, "Suggestion for new name already exists "
                            "('%s'). Please make a new name." % the_post.name)
                elif pagename:
                    warnings.append(
                        ('',
                         "A post named '%s' already exists. Enter new name." %
                         the_post.name))
                the_post = BlogPost(self.env, '')
            if command == 'edit':
                req.perm(the_post.resource).require(
                    'BLOG_VIEW')  # Starting point
            if req.method == 'POST':
                # Create or edit a blog post
                if 'blog-cancel' in req.args:
                    if req.args.get('action', '') == 'edit':
                        req.redirect(req.href.blog(pagename))
                    else:
                        req.redirect(req.href.blog())
                # Assert permissions
                if command == 'create':
                    req.perm(Resource('blog', None)).require('BLOG_CREATE')
                elif command == 'edit':
                    if the_post.author == req.authname:
                        req.perm(the_post.resource).require('BLOG_MODIFY_OWN')
                    else:
                        req.perm(the_post.resource).require('BLOG_MODIFY_ALL')

                # Check input
                orig_author = the_post.author
                if not the_post.update_fields(req.args):
                    warnings.append(('', "None of the fields have changed."))
                version_comment = req.args.get('new_version_comment', '')
                if 'blog-preview' in req.args:
                    warnings.extend(
                        blog_core.create_post(req,
                                              the_post,
                                              req.authname,
                                              version_comment,
                                              verify_only=True))
                elif 'blog-save' in req.args and not warnings:
                    warnings.extend(
                        blog_core.create_post(req, the_post, req.authname,
                                              version_comment))
                    if not warnings:
                        req.redirect(req.href.blog(the_post.name))
                context = web_context(req, the_post.resource)
                data['context'] = context
                data['blog_attachments'] = AttachmentModule(
                    self.env).attachment_data(context)
                data['blog_action'] = 'preview'
                data['blog_version_comment'] = version_comment
                if (orig_author and orig_author != the_post.author) and (
                        not 'BLOG_MODIFY_ALL' in req.perm(the_post.resource)):
                    add_notice(req, "If you change the author you cannot " \
                        "edit the post again due to restricted permissions.")
                    data['blog_orig_author'] = orig_author
            for field, reason in warnings:
                if field:
                    add_warning(req, "Field '%s': %s" % (field, reason))
                else:
                    add_warning(req, reason)
            data['blog_edit'] = the_post

        elif command == 'delete':
            bp = BlogPost(self.env, pagename)
            req.perm(bp.resource).require('BLOG_DELETE')
            if 'blog-cancel' in req.args:
                req.redirect(req.href.blog(pagename))
            comment = int(req.args.get('comment', '0'))
            warnings = []
            if comment:
                # Deleting a specific comment
                bc = BlogComment(self.env, pagename, comment)
                if not bc.number:
                    raise TracError(
                        "Cannot delete. Blog post name and/or comment number missing."
                    )
                if req.method == 'POST' and comment and pagename:
                    warnings.extend(blog_core.delete_comment(bc))
                    if not warnings:
                        add_notice(req, "Blog comment %d deleted." % comment)
                        req.redirect(req.href.blog(pagename))
                template = 'fullblog_delete.html'
                data['blog_comment'] = bc
            else:
                # Delete a version of a blog post or all versions
                # with comments and attachments if only version.
                if not bp.version:
                    raise TracError(
                        "Cannot delete. Blog post '%s' does not exist." %
                        (bp.name))
                version = int(req.args.get('version', '0'))
                if req.method == 'POST':
                    if 'blog-version-delete' in req.args:
                        if bp.version != version:
                            raise TracError(
                                "Cannot delete. Can only delete most recent version."
                            )
                        warnings.extend(
                            blog_core.delete_post(bp, version=bp.versions[-1]))
                    elif 'blog-delete' in req.args:
                        version = 0
                        warnings.extend(
                            blog_core.delete_post(bp, version=version))
                    if not warnings:
                        if version > 1:
                            add_notice(
                                req, "Blog post '%s' version %d deleted." %
                                (pagename, version))
                            req.redirect(req.href.blog(pagename))
                        else:
                            add_notice(req,
                                       "Blog post '%s' deleted." % pagename)
                            req.redirect(req.href.blog())
                template = 'fullblog_delete.html'
                data['blog_post'] = bp
            for field, reason in warnings:
                if field:
                    add_warning(req, "Field '%s': %s" % (field, reason))
                else:
                    add_warning(req, reason)

        elif command.startswith('listing-'):
            # 2007/10 or category/something or author/theuser
            title = category = author = ''
            from_dt = to_dt = None
            if command == 'listing-month':
                from_dt = listing_data['from_dt']
                to_dt = listing_data['to_dt']
                title = "Posts for the month of %s %d" % (
                    blog_month_names[from_dt.month - 1], from_dt.year)
                add_link(req, 'alternate', req.href.blog(format='rss'),
                         'RSS Feed', 'application/rss+xml', 'rss')

            elif command == 'listing-category':
                category = listing_data['category']
                if category:
                    title = "Posts in category %s" % category
                    add_link(req, 'alternate',
                             req.href.blog('category', category, format='rss'),
                             'RSS Feed', 'application/rss+xml', 'rss')
            elif command == 'listing-author':
                author = listing_data['author']
                if author:
                    title = "Posts by author %s" % author
                    add_link(req, 'alternate',
                             req.href.blog('author', author, format='rss'),
                             'RSS Feed', 'application/rss+xml', 'rss')
            if not (author or category or (from_dt and to_dt)):
                raise HTTPNotFound("Not a valid path for viewing blog posts.")
            blog_posts = []
            for post in get_blog_posts(self.env,
                                       category=category,
                                       author=author,
                                       from_dt=from_dt,
                                       to_dt=to_dt):
                bp = BlogPost(self.env, post[0], post[1])
                if 'BLOG_VIEW' in req.perm(bp.resource):
                    blog_posts.append(bp)
            data['blog_post_list'] = blog_posts
            data['blog_list_title'] = title
        else:
            raise HTTPNotFound("Not a valid blog path.")

        if (not command or command.startswith('listing-')) and format == 'rss':
            data['context'] = web_context(req, absurls=True)
            data['blog_num_items'] = self.num_items
            return 'fullblog.rss', data, 'application/rss+xml'

        data['blog_months'], data['blog_authors'], data['blog_categories'], \
                data['blog_total'] = \
                    blog_core.get_months_authors_categories(
                        user=req.authname, perm=req.perm)
        if 'BLOG_CREATE' in req.perm('blog'):
            add_ctxtnav(req,
                        'New Post',
                        href=req.href.blog('create'),
                        title="Create new Blog Post")
        add_stylesheet(req, 'tracfullblog/css/fullblog.css')
        add_stylesheet(req, 'common/css/code.css')
        data['blog_personal_blog'] = self.env.config.getbool(
            'fullblog', 'personal_blog')
        data['blog_archive_rss_icon'] = self.all_rss_icons \
                                        or self.archive_rss_icon
        data['blog_all_rss_icons'] = self.all_rss_icons
        return (template, data, None)
Example #22
0
    def _render_config(self, req, config_name):
        db = self.env.get_db_cnx()

        config = BuildConfig.fetch(self.env, config_name, db=db)
        if not config:
            raise HTTPNotFound("Build configuration '%s' does not exist." \
                                % config_name)

        repos = self.env.get_repository(authname=req.authname)
        assert repos, 'No "(default)" Repository: Add a repository or alias ' \
                      'named "(default)" to Trac.'
        rev = config.max_rev or repos.youngest_rev
        try:
            _has_permission(req.perm,
                            repos,
                            config.path,
                            rev=rev,
                            raise_error=True)
        except NoSuchNode:
            raise TracError("Permission checking against repository path %s "
                            "at revision %s failed." % (config.path, rev))

        data = {'title': 'Build Configuration "%s"' \
                          % config.label or config.name,
                'page_mode': 'view_config'}
        add_link(req, 'up', req.href.build(), 'Build Status')
        description = config.description
        if description:
            description = wiki_to_html(description, self.env, req)

        pending_builds = list(
            Build.select(self.env, config=config.name, status=Build.PENDING))
        inprogress_builds = list(
            Build.select(self.env,
                         config=config.name,
                         status=Build.IN_PROGRESS))

        data['config'] = {
            'name': config.name,
            'label': config.label,
            'path': config.path,
            'min_rev': config.min_rev,
            'min_rev_href': req.href.changeset(config.min_rev),
            'max_rev': config.max_rev,
            'max_rev_href': req.href.changeset(config.max_rev),
            'active': config.active,
            'description': description,
            'browser_href': req.href.browser(config.path),
            'builds_pending': len(pending_builds),
            'builds_inprogress': len(inprogress_builds)
        }

        context = Context.from_request(req, config.resource)
        data['context'] = context
        data['config']['attachments'] = AttachmentModule(
            self.env).attachment_data(context)

        platforms = list(
            TargetPlatform.select(self.env, config=config_name, db=db))
        data['config']['platforms'] = [{
            'name':
            platform.name,
            'id':
            platform.id,
            'builds_pending':
            len(
                list(
                    Build.select(self.env,
                                 config=config.name,
                                 status=Build.PENDING,
                                 platform=platform.id))),
            'builds_inprogress':
            len(
                list(
                    Build.select(self.env,
                                 config=config.name,
                                 status=Build.IN_PROGRESS,
                                 platform=platform.id)))
        } for platform in platforms]

        has_reports = False
        for report in Report.select(self.env, config=config.name, db=db):
            has_reports = True
            break

        if has_reports:
            chart_generators = []
            report_categories = list(
                self._report_categories_for_config(config))
            for generator in ReportChartController(self.env).generators:
                for category in generator.get_supported_categories():
                    if category in report_categories:
                        chart_generators.append({
                            'href':
                            req.href.build(config.name, 'chart/' + category),
                            'category':
                            category,
                            'style':
                            self.config.get('bitten', 'chart_style'),
                        })
            data['config']['charts'] = chart_generators

        page = max(1, int(req.args.get('page', 1)))
        more = False
        data['page_number'] = page

        repos = self.env.get_repository(authname=req.authname)
        assert repos, 'No "(default)" Repository: Add a repository or alias ' \
                      'named "(default)" to Trac.'

        builds_per_page = 12 * len(platforms)
        idx = 0
        builds = {}
        revisions = []
        for platform, rev, build in collect_changes(repos, config):
            if idx >= page * builds_per_page:
                more = True
                break
            elif idx >= (page - 1) * builds_per_page:
                if rev not in builds:
                    revisions.append(rev)
                builds.setdefault(rev, {})
                builds[rev].setdefault('href', req.href.changeset(rev))
                builds[rev].setdefault('display_rev', repos.normalize_rev(rev))
                if build and build.status != Build.PENDING:
                    build_data = _get_build_data(self.env, req, build)
                    build_data['steps'] = []
                    for step in BuildStep.select(self.env,
                                                 build=build.id,
                                                 db=db):
                        build_data['steps'].append({
                            'name': step.name,
                            'description': step.description,
                            'duration': to_datetime(step.stopped or int(time.time()), utc) - \
                                        to_datetime(step.started, utc),
                            'status': _step_status_label[step.status],
                            'cls': _step_status_label[step.status].replace(' ', '-'),

                            'errors': step.errors,
                            'href': build_data['href'] + '#step_' + step.name
                        })
                    builds[rev][platform.id] = build_data
            idx += 1
        data['config']['builds'] = builds
        data['config']['revisions'] = revisions

        if page > 1:
            if page == 2:
                prev_href = req.href.build(config.name)
            else:
                prev_href = req.href.build(config.name, page=page - 1)
            add_link(req, 'prev', prev_href, 'Previous Page')
        if more:
            next_href = req.href.build(config.name, page=page + 1)
            add_link(req, 'next', next_href, 'Next Page')
        if arity(prevnext_nav) == 4:  # Trac 0.12 compat, see #450
            prevnext_nav(req, 'Previous Page', 'Next Page')
        else:
            prevnext_nav(req, 'Page')
        return data
Example #23
0
    def _render_config(self, req, config_name):
        db = self.env.get_db_cnx()

        config = BuildConfig.fetch(self.env, config_name, db=db)
        if not config:
            raise HTTPNotFound("Build configuration '%s' does not exist." \
                                % config_name)

        repos = self.env.get_repository(authname=req.authname)
        assert repos, 'No "(default)" Repository: Add a repository or alias ' \
                      'named "(default)" to Trac.'
        rev = config.max_rev or repos.youngest_rev
        try:
            _has_permission(req.perm, repos, config.path, rev=rev,
                                                        raise_error=True)
        except NoSuchNode:
            raise TracError("Permission checking against repository path %s "
                "at revision %s failed." % (config.path, rev))

        data = {'title': 'Build Configuration "%s"' \
                          % config.label or config.name,
                'page_mode': 'view_config'}
        add_link(req, 'up', req.href.build(), 'Build Status')
        description = config.description
        if description:
            description = wiki_to_html(description, self.env, req)

        pending_builds = list(Build.select(self.env,
                                config=config.name, status=Build.PENDING))
        inprogress_builds = list(Build.select(self.env,
                                config=config.name, status=Build.IN_PROGRESS))

        data['config'] = {
            'name': config.name, 'label': config.label, 'path': config.path,
            'min_rev': config.min_rev,
            'min_rev_href': req.href.changeset(config.min_rev),
            'max_rev': config.max_rev,
            'max_rev_href': req.href.changeset(config.max_rev),
            'active': config.active, 'description': description,
            'browser_href': req.href.browser(config.path),
            'builds_pending' : len(pending_builds),
            'builds_inprogress' : len(inprogress_builds)
        }

        context = Context.from_request(req, config.resource)
        data['context'] = context
        data['config']['attachments'] = AttachmentModule(self.env).attachment_data(context)

        platforms = list(TargetPlatform.select(self.env, config=config_name,
                                               db=db))
        data['config']['platforms'] = [
            { 'name': platform.name,
              'id': platform.id,
              'builds_pending': len(list(Build.select(self.env,
                                                    config=config.name,
                                                    status=Build.PENDING,
                                                    platform=platform.id))),
              'builds_inprogress': len(list(Build.select(self.env,
                                                    config=config.name,
                                                    status=Build.IN_PROGRESS,
                                                    platform=platform.id)))
              }
            for platform in platforms
        ]

        has_reports = False
        for report in Report.select(self.env, config=config.name, db=db):
            has_reports = True
            break

        if has_reports:
            chart_generators = []
            report_categories = list(self._report_categories_for_config(config))
            for generator in ReportChartController(self.env).generators:
                for category in generator.get_supported_categories():
                    if category in report_categories:
                        chart_generators.append({
                            'href': req.href.build(config.name, 'chart/' + category),
                            'category': category,
                            'style': self.config.get('bitten', 'chart_style'),
                        })
            data['config']['charts'] = chart_generators

        page = max(1, int(req.args.get('page', 1)))
        more = False
        data['page_number'] = page

        repos = self.env.get_repository(authname=req.authname)
        assert repos, 'No "(default)" Repository: Add a repository or alias ' \
                      'named "(default)" to Trac.'

        builds_per_page = 12 * len(platforms)
        idx = 0
        builds = {}
        revisions = []
        for platform, rev, build in collect_changes(repos, config):
            if idx >= page * builds_per_page:
                more = True
                break
            elif idx >= (page - 1) * builds_per_page:
                if rev not in builds:
                    revisions.append(rev)
                builds.setdefault(rev, {})
                builds[rev].setdefault('href', req.href.changeset(rev))
                builds[rev].setdefault('display_rev', repos.normalize_rev(rev))
                if build and build.status != Build.PENDING:
                    build_data = _get_build_data(self.env, req, build)
                    build_data['steps'] = []
                    for step in BuildStep.select(self.env, build=build.id,
                                                 db=db):
                        build_data['steps'].append({
                            'name': step.name,
                            'description': step.description,
                            'duration': to_datetime(step.stopped or int(time.time()), utc) - \
                                        to_datetime(step.started, utc),
                            'status': _step_status_label[step.status],
                            'cls': _step_status_label[step.status].replace(' ', '-'),

                            'errors': step.errors,
                            'href': build_data['href'] + '#step_' + step.name
                        })
                    builds[rev][platform.id] = build_data
            idx += 1
        data['config']['builds'] = builds
        data['config']['revisions'] = revisions

        if page > 1:
            if page == 2:
                prev_href = req.href.build(config.name)
            else:
                prev_href = req.href.build(config.name, page=page - 1)
            add_link(req, 'prev', prev_href, 'Previous Page')
        if more:
            next_href = req.href.build(config.name, page=page + 1)
            add_link(req, 'next', next_href, 'Next Page')
        if arity(prevnext_nav) == 4: # Trac 0.12 compat, see #450
            prevnext_nav(req, 'Previous Page', 'Next Page')
        else:
            prevnext_nav (req, 'Page')
        return data
Example #24
0
    def process_request(self, req):
        """ Processing the request. """

        req.perm('blog').assert_permission('BLOG_VIEW')

        blog_core = FullBlogCore(self.env)
        format = req.args.get('format', '').lower()

        command, pagename, path_items, listing_data = self._parse_path(req)
        action = req.args.get('action', 'view').lower()
        try:
            version = int(req.args.get('version', 0))
        except:
            version = 0

        data = {}
        template = 'fullblog_view.html'
        data['blog_about'] = BlogPost(self.env, 'about')
        data['blog_infotext'] = blog_core.get_bloginfotext()
        blog_month_names = map_month_names(
                    self.env.config.getlist('fullblog', 'month_names'))
        data['blog_month_names'] = blog_month_names

        user_recent_post = get_blog_posts(self.env,author=req.authname, per_num='3' ,current_num='0') 
        if user_recent_post:   
            data['user_recent_post'] = user_recent_post

            # data['user_recent_post']['url']= user_recent_post[0][0]
            # data['user_recent_post']['title']= user_recent_post[0][4]

        self.env.log.debug(
            "Blog debug: command=%r, pagename=%r, path_items=%r" % (
                command, pagename, path_items))
        
        
        if not command:
            # Request for just root (display latest)
            try:
                page=req.args.get('page') 
                print page                                
            except:
                pass
            try:
                page=int(page)               
            except:
                page=1 
                
            if page>1:               
                data['page'] =  int(page)                
            else:
                page = 1
                data['page'] =  1
                
            
            if data['page'] > 1 :
                data['page_pre4'] = data['page'] - 1
                data['page_pre'] = data['page'] -1
            if data['page'] > 2 :
                data['page_pre3'] = data['page'] - 2                
            if data['page'] > 3 :
                data['page_pre2'] = data['page'] - 3                
            if data['page'] > 4 :
                data['page_pre1'] = data['page'] - 4

            data['page_next1'] = data['page'] + 1
            data['page_next2'] = data['page'] + 2
            data['page_next3'] = data['page'] + 3
            data['page_next4'] = data['page'] + 4
            data['page_next'] = data['page_next1']

                
            data['blog_post_list'] = []
            count = 0
            maxcount = self.num_items
            if page:  
                blog_posts = get_blog_posts(self.env,per_num=maxcount, current_num=(page-1))
            else:
                blog_posts = get_blog_posts(self.env,per_num=maxcount)
            if not blog_posts:
                del data['page_next1'],data['page_next2'],data['page_next3'],data['page_next4'],data['page_next']
#                data['page_next1'] = data['page_next2'] =  data['page_next3'] = data['page_next4'] = data['page_next'] = ''
                
            for post in blog_posts:
                bp = BlogPost(self.env, post[0], post[1])
                if 'BLOG_VIEW' in req.perm(bp.resource):
                    data['blog_post_list'].append(bp)
                    count += 1
                if maxcount and count == maxcount:
                    # Only display a certain number on front page (from config)
                    break
            data['blog_list_title'] = "Recent posts" + \
                    (len(blog_posts) > maxcount and \
                        " (max %d) - Browse or Archive for more" % (maxcount,) \
                    or '')
            add_link(req, 'alternate', req.href.blog(format='rss'), 'RSS Feed',
                     'application/rss+xml', 'rss')

        


        elif command == 'archive':
            # Requesting the archive page
            template = 'fullblog_archive.html'
            data['blog_archive'] = []
            for period, period_posts in group_posts_by_month(get_all_blog_posts(self.env)):
                allowed_posts = []
                for post in period_posts:
                    bp = BlogPost(self.env, post[0], post[1])
                    if 'BLOG_VIEW' in req.perm(bp.resource):
                        allowed_posts.append(post)
                if allowed_posts:
                    data['blog_archive'].append((period, allowed_posts))
            add_link(req, 'alternate', req.href.blog(format='rss'), 'RSS Feed',
                     'application/rss+xml', 'rss')

        elif command == 'view' and pagename:
            # Requesting a specific blog post
            the_post = BlogPost(self.env, pagename, version)
            req.perm(the_post.resource).require('BLOG_VIEW')
            if not the_post.version:
                raise HTTPNotFound("No blog post named '%s'." % pagename)
            if req.method == 'POST':   # Adding/Previewing a comment
                # Permission?
                req.perm(the_post.resource).require('BLOG_COMMENT')
                comment = BlogComment(self.env, pagename)
                comment.comment = req.args.get('comment', '')
                comment.author = (req.authname != 'anonymous' and req.authname) \
                            or req.args.get('author')
                comment.time = datetime.datetime.now(utc)
                warnings = []
                if 'cancelcomment' in req.args:
                    req.redirect(req.href.blog(pagename))
                elif 'previewcomment' in req.args:
                    warnings.extend(blog_core.create_comment(req, comment, verify_only=True))
                elif 'submitcomment' in req.args and not warnings:
                    warnings.extend(blog_core.create_comment(req, comment))
                    if not warnings:
                        req.redirect(req.href.blog(pagename
                                )+'#comment-'+str(comment.number))
                data['blog_comment'] = comment
                # Push all warnings out to the user.
                for field, reason in warnings:
                    if field:
                        add_warning(req, "Field '%s': %s" % (field, reason))
                    else:
                        add_warning(req, reason)
            data['blog_post'] = the_post
            context = Context.from_request(req, the_post.resource)
            data['context'] = context
            data['blog_attachments'] = AttachmentModule(self.env).attachment_data(context)
            # Previous and Next ctxtnav
            prev, next = blog_core.get_prev_next_posts(req.perm, the_post.name)
            if prev:
                add_link(req, 'prev', req.href.blog(prev), prev)
            if next:
                add_link(req, 'next', req.href.blog(next), next)
            if arity(prevnext_nav) == 4:
                # 0.12 compat following trac:changeset:8597
                prevnext_nav(req, 'Previous Post', 'Next Post')
            else:
                prevnext_nav(req, 'Post')

        elif command in ['create', 'edit']:
            template = 'fullblog_edit.html'
            default_pagename = blog_core._get_default_postname(req.authname)
            the_post = BlogPost(self.env, pagename or default_pagename)
            warnings = []

            if command == 'create' and req.method == 'GET' and not the_post.version:
                # Support appending query arguments for populating intial fields
                the_post.update_fields(req.args)
            if command == 'create' and the_post.version:
                # Post with name or suggested name already exists
                if 'BLOG_CREATE' in req.perm and the_post.name == default_pagename \
                                    and not req.method == 'POST':
                    if default_pagename:
                        add_notice(req, "Suggestion for new name already exists "
                            "('%s'). Please make a new name." % the_post.name)
                elif pagename:
                    warnings.append(
                        ('', "A post named '%s' already exists. Enter new name."
                                            % the_post.name))
                the_post = BlogPost(self.env, '')
            if command == 'edit':
                req.perm(the_post.resource).require('BLOG_VIEW') # Starting point
            if req.method == 'POST':
                # Create or edit a blog post
                if 'blog-cancel' in req.args:
                    if req.args.get('action','') == 'edit':
                        req.redirect(req.href.blog(pagename))
                    else:
                        req.redirect(req.href.blog())
                # Assert permissions
                if command == 'create':
                    req.perm(Resource('blog', None)).require('BLOG_CREATE')
                elif command == 'edit':
                    if the_post.author == req.authname:
                        req.perm(the_post.resource).require('BLOG_MODIFY_OWN')
                    else:
                        req.perm(the_post.resource).require('BLOG_MODIFY_ALL')

                # Check input
                orig_author = the_post.author
                if not the_post.update_fields(req.args):
                    warnings.append(('', "None of the fields have changed."))
                version_comment = req.args.get('new_version_comment', '')
                if 'blog-preview' in req.args:
                    warnings.extend(blog_core.create_post(
                            req, the_post, req.authname, version_comment, verify_only=True))
                elif 'blog-save' in req.args and not warnings:
                    warnings.extend(blog_core.create_post(
                            req, the_post, req.authname, version_comment))
                    if not warnings:
                        req.redirect(req.href.blog(the_post.name))
                context = Context.from_request(req, the_post.resource)
                data['context'] = context
                data['blog_attachments'] = AttachmentModule(self.env).attachment_data(context)
                data['blog_action'] = 'preview'
                data['blog_version_comment'] = version_comment
                if (orig_author and orig_author != the_post.author) and (
                        not 'BLOG_MODIFY_ALL' in req.perm(the_post.resource)):
                    add_notice(req, "If you change the author you cannot " \
                        "edit the post again due to restricted permissions.")
                    data['blog_orig_author'] = orig_author
            for field, reason in warnings:
                if field:
                    add_warning(req, "Field '%s': %s" % (field, reason))
                else:
                    add_warning(req, reason)
            data['blog_edit'] = the_post

        elif command == 'delete':
            bp = BlogPost(self.env, pagename)
            req.perm(bp.resource).require('BLOG_ADMIN')
            if 'blog-cancel' in req.args:
                req.redirect(req.href.blog(pagename))
            comment = int(req.args.get('comment', '0'))
            warnings = []
            if comment:
                # Deleting a specific comment
                bc = BlogComment(self.env, pagename, comment)
                if not bc.number:
                    raise TracError(
                            "Cannot delete. Blog post name and/or comment number missing.")
                if req.method == 'POST' and comment and pagename:
                    warnings.extend(blog_core.delete_comment(bc))
                    if not warnings:
                        add_notice(req, "Blog comment %d deleted." % comment)
                        req.redirect(req.href.blog(pagename))
                template = 'fullblog_delete.html'
                data['blog_comment'] = bc
            else:
                # Delete a version of a blog post or all versions
                # with comments and attachments if only version.
                if not bp.version:
                    raise TracError(
                            "Cannot delete. Blog post '%s' does not exist." % (
                                    bp.name))
                version = int(req.args.get('version', '0'))
                if req.method == 'POST':
                    if 'blog-version-delete' in req.args:
                        if bp.version != version:
                            raise TracError(
                                "Cannot delete. Can only delete most recent version.")
                        warnings.extend(blog_core.delete_post(bp, version=bp.versions[-1]))
                    elif 'blog-delete' in req.args:
                        version = 0
                        warnings.extend(blog_core.delete_post(bp, version=version))
                    if not warnings:
                        if version > 1:
                            add_notice(req, "Blog post '%s' version %d deleted." % (
                                                pagename, version))
                            req.redirect(req.href.blog(pagename))
                        else:
                            add_notice(req, "Blog post '%s' deleted." % pagename)
                            req.redirect(req.href.blog())
                template = 'fullblog_delete.html'
                data['blog_post'] = bp
            for field, reason in warnings:
                if field:
                    add_warning(req, "Field '%s': %s" % (field, reason))
                else:
                    add_warning(req, reason)                        

        elif command.startswith('listing-'):
            # 2007/10 or category/something or author/theuser
            title = category = author = ''
            from_dt = to_dt = None
            if command == 'listing-month':
                from_dt = listing_data['from_dt']
                to_dt = listing_data['to_dt']
                title = "Posts for the month of %s %d" % (
                        blog_month_names[from_dt.month -1], from_dt.year)
                add_link(req, 'alternate', req.href.blog(format='rss'), 'RSS Feed',
                        'application/rss+xml', 'rss')

            elif command == 'listing-category':
                category = listing_data['category']
                if category:
                    title = "Posts in category %s" % category
                    add_link(req, 'alternate', req.href.blog('category', category,
                        format='rss'), 'RSS Feed', 'application/rss+xml', 'rss')
            elif command == 'listing-author':
                author = listing_data['author']
                if author:
                    title = "Posts by author %s" % author
                    add_link(req, 'alternate', req.href.blog('author', author,
                        format='rss'), 'RSS Feed', 'application/rss+xml', 'rss')
            if not (author or category or (from_dt and to_dt)):
                raise HTTPNotFound("Not a valid path for viewing blog posts.")
            blog_posts = []
            for post in get_blog_posts(self.env, category=category,
                        author=author, from_dt=from_dt, to_dt=to_dt):
                bp = BlogPost(self.env, post[0], post[1])
                if 'BLOG_VIEW' in req.perm(bp.resource):
                    blog_posts.append(bp)
            data['blog_post_list'] = blog_posts
            data['blog_list_title'] = title
        else:
            raise HTTPNotFound("Not a valid blog path.")

        if (not command or command.startswith('listing-')) and format == 'rss':
            data['context'] = Context.from_request(req, absurls=True)
            data['blog_num_items'] = self.num_items
            return 'fullblog.rss', data, 'application/rss+xml'

        data['blog_months'], data['blog_authors'], data['blog_categories'], \
                data['blog_total'] = \
                    blog_core.get_months_authors_categories(
                        user=req.authname, perm=req.perm)
        if 'BLOG_CREATE' in req.perm('blog'):
            add_ctxtnav(req, 'New Post', href=req.href.blog('create'),
                    title="Create new Blog Post")
        add_stylesheet(req, 'tracfullblog/css/fullblog.css')
        add_stylesheet(req, 'common/css/code.css')
        data['blog_personal_blog'] = self.env.config.getbool('fullblog',
                                                'personal_blog')
        b=data['blog_categories']
        data['blog_categories']=sorted(b, key =lambda b:b[1],reverse=True)
        return (template, data, None)
Example #25
0
    def process_request(self, req):
        """ Processing the request. """

        req.perm("blog").assert_permission("BLOG_VIEW")

        blog_core = FullBlogCore(self.env)
        format = req.args.get("format", "").lower()

        command, pagename, path_items, listing_data = self._parse_path(req)
        action = req.args.get("action", "view").lower()
        try:
            version = int(req.args.get("version", 0))
        except:
            version = 0

        data = {}
        template = "fullblog_view.html"
        data["blog_about"] = BlogPost(self.env, "about")
        data["blog_infotext"] = blog_core.get_bloginfotext()
        blog_month_names = map_month_names(self.env.config.getlist("fullblog", "month_names"))
        data["blog_month_names"] = blog_month_names
        self.env.log.debug("Blog debug: command=%r, pagename=%r, path_items=%r" % (command, pagename, path_items))

        if has_UserPictureModule and self.avatar_size > 0:
            data["avatars"] = avatars = {}
        else:
            avatars = None

        page = int(req.args.get("page", 1))

        if not command:
            # Request for just root (display latest)
            data["blog_post_list"] = []
            count = 0
            mincount = (page - 1) * self.num_items
            maxcount = mincount + self.num_items
            blog_posts = get_blog_posts(self.env)
            for post in blog_posts:
                bp = BlogPost(self.env, post[0], post[1])
                if "BLOG_VIEW" in req.perm(bp.resource):
                    count += 1
                    if count <= mincount:
                        continue
                    data["blog_post_list"].append(bp)
                    if avatars != None and bp.author not in avatars:
                        avatars[bp.author] = self._get_avatar(req, bp.author)
                if maxcount and count == maxcount:
                    # Only display a certain number on front page (from config)
                    break
            data["blog_list_title"] = _("Recent posts")
            if len(blog_posts) > maxcount:
                data["blog_list_title"] += _(" (max %d) - Browse or Archive for") % (self.num_items,)
                data["blog_list_title_more"] = _("more")
                data["blog_list_title_href"] = req.href.blog(page=page + 1)
            add_link(req, "alternate", req.href.blog(format="rss"), "RSS Feed", "application/rss+xml", "rss")

        elif command == "archive":
            # Requesting the archive page
            template = "fullblog_archive.html"
            data["blog_archive"] = []
            for period, period_posts in group_posts_by_month(get_blog_posts(self.env)):
                allowed_posts = []
                for post in period_posts:
                    bp = BlogPost(self.env, post[0], post[1])
                    if "BLOG_VIEW" in req.perm(bp.resource):
                        allowed_posts.append(post)
                if allowed_posts:
                    data["blog_archive"].append((period, allowed_posts))
            add_link(req, "alternate", req.href.blog(format="rss"), "RSS Feed", "application/rss+xml", "rss")

        elif command == "view" and pagename:
            # Requesting a specific blog post
            the_post = BlogPost(self.env, pagename, version)
            req.perm(the_post.resource).require("BLOG_VIEW")
            if not the_post.version:
                raise HTTPNotFound("No blog post named '%s'." % pagename)
            if req.method == "POST":  # Adding/Previewing a comment
                # Permission?
                req.perm(the_post.resource).require("BLOG_COMMENT")
                comment = BlogComment(self.env, pagename)
                comment.comment = req.args.get("comment", "")
                comment.author = (req.authname != "anonymous" and req.authname) or req.args.get("author")
                comment.time = datetime.datetime.now(utc)
                warnings = []
                if "cancelcomment" in req.args:
                    req.redirect(req.href.blog(pagename))
                elif "previewcomment" in req.args:
                    warnings.extend(blog_core.create_comment(req, comment, verify_only=True))
                elif "submitcomment" in req.args and not warnings:
                    warnings.extend(blog_core.create_comment(req, comment))
                    if not warnings:
                        req.redirect(req.href.blog(pagename) + "#comment-" + str(comment.number))
                data["blog_comment"] = comment
                # Push all warnings out to the user.
                for field, reason in warnings:
                    if field:
                        add_warning(req, "Field '%s': %s" % (field, reason))
                    else:
                        add_warning(req, reason)
            data["blog_post"] = the_post
            if avatars != None:
                avatars[the_post.author] = self._get_avatar(req, the_post.author)
            context = Context.from_request(req, the_post.resource, absurls=format == "rss" and True or False)
            data["context"] = context
            if format == "rss":
                return "fullblog_post.rss", data, "application/rss+xml"
            # Regular web response
            context = Context.from_request(req, the_post.resource)

            data["blog_attachments"] = AttachmentModule(self.env).attachment_data(context)
            # Previous and Next ctxtnav
            prev, next = blog_core.get_prev_next_posts(req.perm, the_post.name)
            if prev:
                add_link(req, "prev", req.href.blog(prev), prev)
            if next:
                add_link(req, "next", req.href.blog(next), next)
            if arity(prevnext_nav) == 4:
                # 0.12 compat following trac:changeset:8597
                prevnext_nav(req, "Previous Post", "Next Post")
            else:
                prevnext_nav(req, "Post")
            # RSS feed for post and comments
            add_link(req, "alternate", req.href.blog(pagename, format="rss"), "RSS Feed", "application/rss+xml", "rss")

        elif command in ["create", "edit"]:
            template = "fullblog_edit.html"
            default_pagename = blog_core._get_default_postname(req.authname)
            the_post = BlogPost(self.env, pagename or default_pagename)
            warnings = []

            if command == "create" and req.method == "GET" and not the_post.version:
                # Support appending query arguments for populating intial fields
                the_post.update_fields(req.args)
                if self.use_authname:
                    the_post.update_fields({"author": req.authname})
            if command == "create" and the_post.version:
                # Post with name or suggested name already exists
                if "BLOG_CREATE" in req.perm and the_post.name == default_pagename and not req.method == "POST":
                    if default_pagename:
                        add_notice(
                            req,
                            "Suggestion for new name already exists " "('%s'). Please make a new name." % the_post.name,
                        )
                elif pagename:
                    warnings.append(("", "A post named '%s' already exists. Enter new name." % the_post.name))
                the_post = BlogPost(self.env, "")
                if self.use_authname:
                    the_post.update_fields({"author": req.authname})
            if command == "edit":
                req.perm(the_post.resource).require("BLOG_VIEW")  # Starting point
            if req.method == "POST":
                # Create or edit a blog post
                if "blog-cancel" in req.args:
                    if req.args.get("action", "") == "edit":
                        req.redirect(req.href.blog(pagename))
                    else:
                        req.redirect(req.href.blog())
                # Assert permissions
                if command == "create":
                    req.perm(Resource("blog", None)).require("BLOG_CREATE")
                elif command == "edit":
                    if the_post.author == req.authname:
                        req.perm(the_post.resource).require("BLOG_MODIFY_OWN")
                    else:
                        req.perm(the_post.resource).require("BLOG_MODIFY_ALL")

                # Check input
                orig_author = the_post.author
                if not the_post.update_fields(req.args):
                    warnings.append(("", "None of the fields have changed."))
                version_comment = req.args.get("new_version_comment", "")
                if "blog-preview" in req.args:
                    warnings.extend(
                        blog_core.create_post(req, the_post, req.authname, version_comment, verify_only=True)
                    )
                elif "blog-save" in req.args and not warnings:
                    warnings.extend(blog_core.create_post(req, the_post, req.authname, version_comment))
                    if not warnings:
                        req.redirect(req.href.blog(the_post.name))
                context = Context.from_request(req, the_post.resource)
                data["context"] = context
                data["blog_attachments"] = AttachmentModule(self.env).attachment_data(context)
                data["blog_action"] = "preview"
                data["blog_version_comment"] = version_comment
                if (orig_author and orig_author != the_post.author) and (
                    not "BLOG_MODIFY_ALL" in req.perm(the_post.resource)
                ):
                    add_notice(
                        req, "If you change the author you cannot " "edit the post again due to restricted permissions."
                    )
                    data["blog_orig_author"] = orig_author
            for field, reason in warnings:
                if field:
                    add_warning(req, "Field '%s': %s" % (field, reason))
                else:
                    add_warning(req, reason)
            data["blog_edit"] = the_post

        elif command == "delete":
            bp = BlogPost(self.env, pagename)
            req.perm(bp.resource).require("BLOG_DELETE")
            if "blog-cancel" in req.args:
                req.redirect(req.href.blog(pagename))
            comment = int(req.args.get("comment", "0"))
            warnings = []
            if comment:
                # Deleting a specific comment
                bc = BlogComment(self.env, pagename, comment)
                if not bc.number:
                    raise TracError("Cannot delete. Blog post name and/or comment number missing.")
                if req.method == "POST" and comment and pagename:
                    warnings.extend(blog_core.delete_comment(bc))
                    if not warnings:
                        add_notice(req, "Blog comment %d deleted." % comment)
                        req.redirect(req.href.blog(pagename))
                template = "fullblog_delete.html"
                data["blog_comment"] = bc
            else:
                # Delete a version of a blog post or all versions
                # with comments and attachments if only version.
                if not bp.version:
                    raise TracError("Cannot delete. Blog post '%s' does not exist." % (bp.name))
                version = int(req.args.get("version", "0"))
                if req.method == "POST":
                    if "blog-version-delete" in req.args:
                        if bp.version != version:
                            raise TracError("Cannot delete. Can only delete most recent version.")
                        warnings.extend(blog_core.delete_post(bp, version=bp.versions[-1]))
                    elif "blog-delete" in req.args:
                        version = 0
                        warnings.extend(blog_core.delete_post(bp, version=version))
                    if not warnings:
                        if version > 1:
                            add_notice(req, "Blog post '%s' version %d deleted." % (pagename, version))
                            req.redirect(req.href.blog(pagename))
                        else:
                            add_notice(req, "Blog post '%s' deleted." % pagename)
                            req.redirect(req.href.blog())
                template = "fullblog_delete.html"
                data["blog_post"] = bp
            for field, reason in warnings:
                if field:
                    add_warning(req, "Field '%s': %s" % (field, reason))
                else:
                    add_warning(req, reason)

        elif command.startswith("listing-"):
            # 2007/10 or category/something or author/theuser
            title = category = author = ""
            from_dt = to_dt = None
            mincount = maxcount = 0
            if command == "listing-month":
                from_dt = listing_data["from_dt"]
                to_dt = listing_data["to_dt"]
                title = _("Posts for the month of %s %d") % (blog_month_names[from_dt.month - 1], from_dt.year)
                add_link(req, "alternate", req.href.blog(format="rss"), "RSS Feed", "application/rss+xml", "rss")

            elif command == "listing-category":
                category = listing_data["category"]
                mincount = (page - 1) * self.num_items_category
                maxcount = mincount + self.num_items_category
                if category:
                    title = _("Posts in category %s") % category
                    add_link(
                        req,
                        "alternate",
                        req.href.blog("category", category, format="rss"),
                        "RSS Feed",
                        "application/rss+xml",
                        "rss",
                    )
            elif command == "listing-author":
                author = listing_data["author"]
                mincount = (page - 1) * self.num_items_category
                maxcount = mincount + self.num_items_author
                if author:
                    title = _("Posts by author %s") % author
                    add_link(
                        req,
                        "alternate",
                        req.href.blog("author", author, format="rss"),
                        "RSS Feed",
                        "application/rss+xml",
                        "rss",
                    )
            if not (author or category or (from_dt and to_dt)):
                raise HTTPNotFound("Not a valid path for viewing blog posts.")
            blog_posts = []
            count = 0
            for post in get_blog_posts(self.env, category=category, author=author, from_dt=from_dt, to_dt=to_dt):
                bp = BlogPost(self.env, post[0], post[1])
                if "BLOG_VIEW" in req.perm(bp.resource):
                    count += 1
                    if count <= mincount:
                        continue
                    blog_posts.append(bp)
                    if avatars != None and bp.author not in avatars:
                        avatars[bp.author] = self._get_avatar(req, bp.author)
                if maxcount and count == maxcount:
                    break

            if maxcount and count == maxcount:
                title += _(" (max %d) - Browse or Archive for") % (maxcount - mincount)
                data["blog_list_title_more"] = _("more")
                if category:
                    rs = u"category/" + category
                else:
                    rs = u"author/" + author
                data["blog_list_title_href"] = req.href.blog(rs, page=page + 1)

            data["blog_post_list"] = blog_posts
            data["blog_list_title"] = title
        else:
            raise HTTPNotFound("Not a valid blog path.")

        if (not command or command.startswith("listing-")) and format == "rss":
            data["context"] = Context.from_request(req, absurls=True)
            data["blog_num_items"] = self.num_items
            return "fullblog.rss", data, "application/rss+xml"

        data["blog_months"], data["blog_authors"], data["blog_categories"], data[
            "blog_total"
        ] = blog_core.get_months_authors_categories(user=req.authname, perm=req.perm)
        if "BLOG_CREATE" in req.perm("blog"):
            add_ctxtnav(req, _("New Post"), href=req.href.blog("create"), title=_("Create new Blog Post"))
        add_stylesheet(req, "tracfullblog/css/fullblog.css")
        add_stylesheet(req, "common/css/code.css")
        data["blog_personal_blog"] = self.env.config.getbool("fullblog", "personal_blog")
        data["blog_archive_rss_icon"] = self.all_rss_icons or self.archive_rss_icon
        data["blog_all_rss_icons"] = self.all_rss_icons
        return (template, data, None)