Switch to unified view

a/Allura/allura/lib/macro.py b/Allura/allura/lib/macro.py
...
...
16
#       under the License.
16
#       under the License.
17
17
18
import cgi
18
import cgi
19
import random
19
import random
20
import shlex
20
import shlex
21
import string
22
import logging
21
import logging
23
import traceback
22
import traceback
24
from operator import attrgetter
23
from operator import attrgetter
25
24
26
import pymongo
25
import pymongo
27
import jinja2
28
from pylons import tmpl_context as c, app_globals as g
26
from pylons import tmpl_context as c, app_globals as g
29
from pylons import request
27
from pylons import request
30
from paste.deploy.converters import asint
28
from paste.deploy.converters import asint
31
from urlparse import urljoin
32
29
33
from . import helpers as h
30
from . import helpers as h
34
from . import security
31
from . import security
35
32
36
log = logging.getLogger(__name__)
33
log = logging.getLogger(__name__)
...
...
80
        if context is None or context == self._context:
77
        if context is None or context == self._context:
81
            return macro
78
            return macro
82
        else:
79
        else:
83
            return None
80
            return None
84
81
85
template_neighborhood_feeds = string.Template('''
86
<div class="neighborhood_feed_entry">
87
<h3><a href="$href">$title</a></h3>
88
<p>
89
by <em>$author</em>
90
<small>$ago</small>
91
</p>
92
<p>$description</p>
93
</div>
94
''')
95
@macro('neighborhood-wiki')
82
@macro('neighborhood-wiki')
96
def neighborhood_feeds(tool_name, max_number=5, sort='pubdate'):
83
def neighborhood_feeds(tool_name, max_number=5, sort='pubdate'):
97
    from allura import model as M
84
    from allura import model as M
85
    from allura.lib.widgets.macros import NeighborhoodFeeds
98
    feed = M.Feed.query.find(
86
    feed = M.Feed.query.find(
99
        dict(
87
        dict(
100
            tool_name=tool_name,
88
            tool_name=tool_name,
101
            neighborhood_id=c.project.neighborhood._id))
89
            neighborhood_id=c.project.neighborhood._id))
102
    feed = feed.sort(sort, pymongo.DESCENDING).limit(int(max_number)).all()
90
    feed = feed.sort(sort, pymongo.DESCENDING).limit(int(max_number)).all()
103
    output = '\n'.join(
91
    output = ((dict(
104
        template_neighborhood_feeds.substitute(dict(
105
                href=item.link,
92
                href=item.link,
106
                title=item.title,
93
                title=item.title,
107
                author=item.author_name,
94
                author=item.author_name,
108
                ago=h.ago(item.pubdate),
95
                ago=h.ago(item.pubdate),
109
                description=item.description))
96
                description=g.markdown.convert(item.description)))
110
        for item in feed)
97
        for item in feed)
111
    return output
98
    feeds = NeighborhoodFeeds(feeds=output)
99
    g.resource_manager.register(feeds)
100
    response = feeds.display(feeds=output)
101
    return response
112
102
113
template_neighborhood_blog_posts = string.Template('''
114
<div class="neighborhood_feed_entry">
115
<h3><a href="$href">$title</a></h3>
116
<p>
117
by <em>$author</em>
118
<small>$ago</small>
119
</p>
120
$description
121
</div>
122
''')
123
@macro('neighborhood-wiki')
103
@macro('neighborhood-wiki')
124
def neighborhood_blog_posts(max_number=5, sort='timestamp', summary=False):
104
def neighborhood_blog_posts(max_number=5, sort='timestamp', summary=False):
125
    from forgeblog import model as BM
105
    from forgeblog import model as BM
106
    from allura.lib.widgets.macros import BlogPosts
126
    posts = BM.BlogPost.query.find(dict(
107
    posts = BM.BlogPost.query.find(dict(
127
        neighborhood_id=c.project.neighborhood._id,
108
        neighborhood_id=c.project.neighborhood._id,
128
        state='published'))
109
        state='published'))
129
    posts = posts.sort(sort, pymongo.DESCENDING).limit(int(max_number)).all()
110
    posts = posts.sort(sort, pymongo.DESCENDING).limit(int(max_number)).all()
130
    output = '\n'.join(
111
    output = ((dict(
131
        template_neighborhood_blog_posts.substitute(dict(
132
                href=post.url(),
112
                href=post.url(),
133
                title=post.title,
113
                title=post.title,
134
                author=post.author().display_name,
114
                author=post.author().display_name,
135
                ago=h.ago(post.timestamp),
115
                ago=h.ago(post.timestamp),
136
                description=summary and '&nbsp;' or g.markdown.convert(post.text)))
116
                description=summary and '&nbsp;' or g.markdown.convert(post.text)))
137
        for post in posts if post.app and
117
        for post in posts if post.app and
138
                             security.has_access(post, 'read', project=post.app.project)() and
118
                             security.has_access(post, 'read', project=post.app.project)() and
139
                             security.has_access(post.app.project, 'read', project=post.app.project)())
119
                             security.has_access(post.app.project, 'read', project=post.app.project)())
140
    return output
120
121
    posts = BlogPosts(posts=output)
122
    g.resource_manager.register(posts)
123
    response = posts.display(posts=output)
124
    return response
141
125
142
@macro()
126
@macro()
143
def project_blog_posts(max_number=5, sort='timestamp', summary=False, mount_point=None):
127
def project_blog_posts(max_number=5, sort='timestamp', summary=False, mount_point=None):
144
    from forgeblog import model as BM
128
    from forgeblog import model as BM
129
    from allura.lib.widgets.macros import BlogPosts
145
    app_config_ids = []
130
    app_config_ids = []
146
    for conf in c.project.app_configs:
131
    for conf in c.project.app_configs:
147
        if conf.tool_name.lower() == 'blog' and (mount_point is None or conf.options.mount_point==mount_point):
132
        if conf.tool_name.lower() == 'blog' and (mount_point is None or conf.options.mount_point==mount_point):
148
            app_config_ids.append(conf._id)
133
            app_config_ids.append(conf._id)
149
    posts = BM.BlogPost.query.find({'state':'published','app_config_id':{'$in':app_config_ids}})
134
    posts = BM.BlogPost.query.find({'state':'published','app_config_id':{'$in':app_config_ids}})
150
    posts = posts.sort(sort, pymongo.DESCENDING).limit(int(max_number)).all()
135
    posts = posts.sort(sort, pymongo.DESCENDING).limit(int(max_number)).all()
151
    output = '\n'.join(
136
    output = ((dict(
152
        template_neighborhood_blog_posts.substitute(dict(
153
                href=post.url(),
137
                href=post.url(),
154
                title=post.title,
138
                title=post.title,
155
                author=post.author().display_name,
139
                author=post.author().display_name,
156
                ago=h.ago(post.timestamp),
140
                ago=h.ago(post.timestamp),
157
                description=summary and '&nbsp;' or g.markdown.convert(post.text)))
141
                description=summary and '&nbsp;' or g.markdown.convert(post.text)))
158
        for post in posts if security.has_access(post, 'read', project=post.app.project)() and
142
        for post in posts if security.has_access(post, 'read', project=post.app.project)() and
159
                             security.has_access(post.app.project, 'read', project=post.app.project)())
143
                             security.has_access(post.app.project, 'read', project=post.app.project)())
160
    return output
144
    posts = BlogPosts(posts=output)
145
    g.resource_manager.register(posts)
146
    response = posts.display(posts=output)
147
    return response
161
148
162
def get_projects_for_macro(category=None, display_mode='grid', sort='last_updated',
149
def get_projects_for_macro(category=None, display_mode='grid', sort='last_updated',
163
        show_total=False, limit=100, labels='', award='', private=False,
150
        show_total=False, limit=100, labels='', award='', private=False,
164
        columns=1, show_proj_icon=True, show_download_button=True, show_awards_banner=True,
151
        columns=1, show_proj_icon=True, show_download_button=True, show_awards_banner=True,
165
        grid_view_tools='',
152
        grid_view_tools='',
...
...
350
    if '://' in src:
337
    if '://' in src:
351
        return '<img src="%s" %s/>' % (src, ' '.join(attrs))
338
        return '<img src="%s" %s/>' % (src, ' '.join(attrs))
352
    else:
339
    else:
353
        return '<img src="./attachment/%s" %s/>' % (src, ' '.join(attrs))
340
        return '<img src="./attachment/%s" %s/>' % (src, ' '.join(attrs))
354
341
355
356
template_project_admins = string.Template('<li><a href="$url">$name</a></li>')
357
@macro()
342
@macro()
358
def project_admins():
343
def project_admins():
359
    admins = c.project.users_with_role('Admin')
344
    admins = c.project.users_with_role('Admin')
360
    output = ''.join(
345
    from allura.lib.widgets.macros import ProjectAdmins
361
        template_project_admins.substitute(dict(
346
    output = ((dict(
362
            url=user.url(),
347
            url=user.url(),
363
            name=jinja2.escape(user.display_name)))
348
            name=user.display_name))
364
        for user in admins)
349
        for user in admins)
365
    return u'<h6>Project Admins:</h6><ul class="md-users-list">{0}</ul>'.format(output)
350
    users = ProjectAdmins(users=output)
351
    g.resource_manager.register(users)
352
    response = users.display(users=output)
353
    return response
366
354
367
template_members = string.Template('<li><a href="$url">$name</a>$admin</li>')
368
@macro()
355
@macro()
369
def members(limit=20):
356
def members(limit=20):
357
    from allura.lib.widgets.macros import Members
370
    limit = asint(limit)
358
    limit = asint(limit)
371
    admins = set(c.project.users_with_role('Admin'))
359
    admins = set(c.project.users_with_role('Admin'))
372
    members = sorted(c.project.users(), key=attrgetter('display_name'))
360
    members = sorted(c.project.users(), key=attrgetter('display_name'))
373
    output = ''.join(
361
    output = [dict(
374
        template_members.substitute(dict(
375
            url=user.url(),
362
            url=user.url(),
376
            name=jinja2.escape(user.display_name),
363
            name=user.display_name,
377
            admin=' (admin)' if user in admins else '',
364
            admin=' (admin)' if user in admins else '',
378
            ))
365
            )
379
        for user in members[:limit])
366
        for user in members[:limit]]
367
380
    if len(members) > limit:
368
    over_limit = len(members) > limit
381
        output = output + '<li class="md-users-list-more"><a href="%s_members">All Members</a></li>' % c.project.url()
369
    users = Members(users=output, over_limit=over_limit)
382
    return u'<h6>Project Members:</h6><ul class="md-users-list">{0}</ul>'.format(output)
370
    g.resource_manager.register(users)
371
    response = users.display(users=output, over_limit=over_limit)
372
    return response
373