Switch to unified view

a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
...
...
95
        pq = M.Project.query.find(dict(
95
        pq = M.Project.query.find(dict(
96
                neighborhood_id=self.neighborhood._id,
96
                neighborhood_id=self.neighborhood._id,
97
                deleted=False,
97
                deleted=False,
98
                shortname={'$ne':'--init--'}
98
                shortname={'$ne':'--init--'}
99
                ))
99
                ))
100
        if sort=='alpha':
100
        if sort == 'alpha':
101
            pq.sort('name')
101
            pq.sort('name')
102
        else:
102
        else:
103
            pq.sort('last_updated', pymongo.DESCENDING)
103
            pq.sort('last_updated', pymongo.DESCENDING)
104
        count = pq.count()
104
        count = pq.count()
105
        nb_max_projects = self.neighborhood.get_max_projects()
105
        nb_max_projects = self.neighborhood.get_max_projects()
106
        projects = pq.skip(start).limit(int(limit)).all()
106
        projects = pq.skip(start).limit(int(limit)).all()
107
        categories = M.ProjectCategory.query.find({'parent_id':None}).sort('name').all()
107
        categories = M.ProjectCategory.query.find({'parent_id':None}).sort('name').all()
108
        c.custom_sidebar_menu = []
108
        c.custom_sidebar_menu = []
109
        if h.has_access(self.neighborhood, 'register')() and (nb_max_projects is None or count < nb_max_projects):
109
        if h.has_access(self.neighborhood, 'register')() and (nb_max_projects is None or count < nb_max_projects):
110
            c.custom_sidebar_menu += [
110
            c.custom_sidebar_menu += [
111
                SitemapEntry('Add a Project', self.neighborhood.url()+'add_project', ui_icon=g.icons['plus']),
111
                SitemapEntry('Add a Project', self.neighborhood.url() + 'add_project', ui_icon=g.icons['plus']),
112
                SitemapEntry('')
112
                SitemapEntry('')
113
            ]
113
            ]
114
        c.custom_sidebar_menu = c.custom_sidebar_menu + [
114
        c.custom_sidebar_menu = c.custom_sidebar_menu + [
115
            SitemapEntry(cat.label, self.neighborhood.url()+'browse/'+cat.name) for cat in categories
115
            SitemapEntry(cat.label, self.neighborhood.url() + 'browse/' + cat.name) for cat in categories
116
        ]
116
        ]
117
        return dict(neighborhood=self.neighborhood,
117
        return dict(neighborhood=self.neighborhood,
118
                    title="Welcome to "+self.neighborhood.name,
118
                    title="Welcome to " + self.neighborhood.name,
119
                    text=g.markdown.convert(self.neighborhood.homepage),
119
                    text=g.markdown.convert(self.neighborhood.homepage),
120
                    projects=projects,
120
                    projects=projects,
121
                    sort=sort,
121
                    sort=sort,
122
                    limit=limit, page=page, count=count)
122
                    limit=limit, page=page, count=count)
123
123
...
...
125
    @without_trailing_slash
125
    @without_trailing_slash
126
    def add_project(self, **form_data):
126
    def add_project(self, **form_data):
127
        c.project = self.neighborhood.neighborhood_project
127
        c.project = self.neighborhood.neighborhood_project
128
        require_access(self.neighborhood, 'register')
128
        require_access(self.neighborhood, 'register')
129
        c.add_project = W.add_project
129
        c.add_project = W.add_project
130
        form_data['tools'] = ['Wiki','Git','Tickets','Downloads','Discussion']
130
        form_data['tools'] = ['Wiki', 'Git', 'Tickets', 'Downloads', 'Discussion']
131
        form_data['neighborhood'] = self.neighborhood.name
131
        form_data['neighborhood'] = self.neighborhood.name
132
        return dict(neighborhood=self.neighborhood, form_data=form_data)
132
        return dict(neighborhood=self.neighborhood, form_data=form_data)
133
133
134
    @expose('json:')
134
    @expose('json:')
135
    def suggest_name(self, project_name=None):
135
    def suggest_name(self, project_name=None):
...
...
171
        if project_description:
171
        if project_description:
172
            c.project.short_description = project_description
172
            c.project.short_description = project_description
173
        offset = c.project.next_mount_point(include_search=True)
173
        offset = c.project.next_mount_point(include_search=True)
174
        if tools and not neighborhood.project_template:
174
        if tools and not neighborhood.project_template:
175
            for i, tool in enumerate(tools):
175
            for i, tool in enumerate(tools):
176
                c.project.install_app(tool, ordinal=i+offset)
176
                c.project.install_app(tool, ordinal=i + offset)
177
        flash('Welcome to the SourceForge Project System! '
177
        flash('Welcome to the SourceForge Project System! '
178
              'To get started, fill out some information about your project.')
178
              'To get started, fill out some information about your project.')
179
        redirect(c.project.script_name + 'admin/overview')
179
        redirect(c.project.script_name + 'admin/overview')
180
180
181
    @expose()
181
    @expose()
...
...
193
        self.additional_filters = {'neighborhood_id':self.neighborhood._id}
193
        self.additional_filters = {'neighborhood_id':self.neighborhood._id}
194
194
195
    @expose()
195
    @expose()
196
    def _lookup(self, category_name, *remainder):
196
    def _lookup(self, category_name, *remainder):
197
        c.project = self.neighborhood.neighborhood_project
197
        c.project = self.neighborhood.neighborhood_project
198
        category_name=unquote(category_name)
198
        category_name = unquote(category_name)
199
        return NeighborhoodProjectBrowseController(neighborhood=self.neighborhood, category_name=category_name, parent_category=self.category), remainder
199
        return NeighborhoodProjectBrowseController(neighborhood=self.neighborhood, category_name=category_name, parent_category=self.category), remainder
200
200
201
    @expose('jinja:allura:templates/neighborhood_project_list.html')
201
    @expose('jinja:allura:templates/neighborhood_project_list.html')
202
    @without_trailing_slash
202
    @without_trailing_slash
203
    def index(self, sort='alpha', limit=25, page=0, **kw):
203
    def index(self, sort='alpha', limit=25, page=0, **kw):
204
        c.project_summary = W.project_summary
204
        c.project_summary = W.project_summary
205
        c.page_list = W.page_list
205
        c.page_list = W.page_list
206
        limit, page, start = g.handle_paging(limit, page)
206
        limit, page, start = g.handle_paging(limit, page)
207
        projects, count = self._find_projects(sort=sort, limit=limit, start=start)
207
        projects, count = self._find_projects(sort=sort, limit=limit, start=start)
208
        title=self._build_title()
208
        title = self._build_title()
209
        c.custom_sidebar_menu = self._build_nav()
209
        c.custom_sidebar_menu = self._build_nav()
210
        return dict(projects=projects,
210
        return dict(projects=projects,
211
                    title=title,
211
                    title=title,
212
                    text=None,
212
                    text=None,
213
                    neighborhood=self.neighborhood,
213
                    neighborhood=self.neighborhood,
...
...
238
                dict(name=s.label, url=s.url, icon=s.ui_icon)
238
                dict(name=s.label, url=s.url, icon=s.ui_icon)
239
                for s in c.project.sitemap() ])
239
                for s in c.project.sitemap() ])
240
240
241
    @expose()
241
    @expose()
242
    def _lookup(self, name, *remainder):
242
    def _lookup(self, name, *remainder):
243
        name=unquote(name)
243
        name = unquote(name)
244
        if not h.re_path_portion.match(name):
244
        if not h.re_path_portion.match(name):
245
            raise exc.HTTPNotFound, name
245
            raise exc.HTTPNotFound, name
246
        subproject = M.Project.query.get(shortname=c.project.shortname + '/' + name,
246
        subproject = M.Project.query.get(shortname=c.project.shortname + '/' + name,
247
                                         neighborhood_id=c.project.neighborhood_id)
247
                                         neighborhood_id=c.project.neighborhood_id)
248
        if subproject:
248
        if subproject:
...
...
317
            return self.icon()
317
            return self.icon()
318
        except exc.HTTPNotFound:
318
        except exc.HTTPNotFound:
319
            redirect(g.forge_static('images/user.png'))
319
            redirect(g.forge_static('images/user.png'))
320
320
321
    @expose('json:')
321
    @expose('json:')
322
    def user_search(self,term=''):
322
    def user_search(self, term=''):
323
        if len(term) < 3:
323
        if len(term) < 3:
324
            raise exc.HTTPBadRequest('"term" param must be at least length 3')
324
            raise exc.HTTPBadRequest('"term" param must be at least length 3')
325
        users = M.User.by_display_name(term)
325
        users = M.User.by_display_name(term)
326
        named_roles = RoleCache(
326
        named_roles = RoleCache(
327
            g.credentials,
327
            g.credentials,
...
...
347
class ScreenshotsController(object):
347
class ScreenshotsController(object):
348
348
349
    @expose()
349
    @expose()
350
    def _lookup(self, filename, *args):
350
    def _lookup(self, filename, *args):
351
        if args:
351
        if args:
352
            filename=unquote(filename)
352
            filename = unquote(filename)
353
        else:
353
        else:
354
            filename = unquote(request.path.rsplit('/', 1)[-1])
354
            filename = unquote(request.path.rsplit('/', 1)[-1])
355
        return ScreenshotController(filename), args
355
        return ScreenshotController(filename), args
356
356
357
class ScreenshotController(object):
357
class ScreenshotController(object):
...
...
463
        self.neighborhood.redirect = kw.pop('redirect', '')
463
        self.neighborhood.redirect = kw.pop('redirect', '')
464
        self.neighborhood.homepage = homepage
464
        self.neighborhood.homepage = homepage
465
        self.neighborhood.css = css
465
        self.neighborhood.css = css
466
        self.neighborhood.project_template = project_template
466
        self.neighborhood.project_template = project_template
467
        self.neighborhood.allow_browse = kw.get('allow_browse', False)
467
        self.neighborhood.allow_browse = kw.get('allow_browse', False)
468
        self.neighborhood.show_title = kw.get('show_title', False)
468
        tracking_id = kw.get('tracking_id', '')
469
        tracking_id = kw.get('tracking_id', '')
469
        if tracking_id != self.neighborhood.tracking_id:
470
        if tracking_id != self.neighborhood.tracking_id:
470
            c.project = self.neighborhood.neighborhood_project
471
            c.project = self.neighborhood.neighborhood_project
471
            M.AuditLog.log('update neighborhood tracking_id')
472
            M.AuditLog.log('update neighborhood tracking_id')
472
            self.neighborhood.tracking_id = tracking_id
473
            self.neighborhood.tracking_id = tracking_id
473
        if icon is not None and icon != '':
474
        if icon is not None and icon != '':
474
            if self.neighborhood.icon:
475
            if self.neighborhood.icon:
475
                self.neighborhood.icon.delete()
476
                self.neighborhood.icon.delete()
476
            M.NeighborhoodFile.save_image(
477
            M.NeighborhoodFile.save_image(
477
                icon.filename, icon.file, content_type=icon.type,
478
                icon.filename, icon.file, content_type=icon.type,
478
                square=True, thumbnail_size=(48,48),
479
                square=True, thumbnail_size=(48, 48),
479
                thumbnail_meta=dict(neighborhood_id=self.neighborhood._id))
480
                thumbnail_meta=dict(neighborhood_id=self.neighborhood._id))
480
        redirect('overview')
481
        redirect('overview')
481
482
482
    @expose('jinja:allura:templates/neighborhood_help.html')
483
    @expose('jinja:allura:templates/neighborhood_help.html')
483
    @with_trailing_slash
484
    @with_trailing_slash
...
...
513
                        last_updated_30 = last_updated_30 + 1
514
                        last_updated_30 = last_updated_30 + 1
514
                    if today_date - p.last_updated < timedelta(days=60):
515
                    if today_date - p.last_updated < timedelta(days=60):
515
                        last_updated_60 = last_updated_60 + 1
516
                        last_updated_60 = last_updated_60 + 1
516
                    if today_date - p.last_updated < timedelta(days=90):
517
                    if today_date - p.last_updated < timedelta(days=90):
517
                        last_updated_90 = last_updated_90 + 1
518
                        last_updated_90 = last_updated_90 + 1
518
    
519
519
        set_nav(self.neighborhood)
520
        set_nav(self.neighborhood)
520
        return dict(
521
        return dict(
521
            delete_count = delete_count,
522
            delete_count=delete_count,
522
            public_count = public_count,
523
            public_count=public_count,
523
            private_count = private_count,
524
            private_count=private_count,
524
            last_updated_30 = last_updated_30,
525
            last_updated_30=last_updated_30,
525
            last_updated_60 = last_updated_60,
526
            last_updated_60=last_updated_60,
526
            last_updated_90 = last_updated_90,
527
            last_updated_90=last_updated_90,
527
            neighborhood = self.neighborhood,
528
            neighborhood=self.neighborhood,
528
        )
529
        )
529
530
530
    @without_trailing_slash
531
    @without_trailing_slash
531
    @expose('jinja:allura:templates/neighborhood_stats_adminlist.html')
532
    @expose('jinja:allura:templates/neighborhood_stats_adminlist.html')
532
    def adminlist(self, sort='alpha', limit=25, page=0, **kw):
533
    def adminlist(self, sort='alpha', limit=25, page=0, **kw):
533
        limit, page, start = g.handle_paging(limit, page)
534
        limit, page, start = g.handle_paging(limit, page)
534
535
535
        pq = M.Project.query.find(dict(neighborhood_id=self.neighborhood._id, deleted=False))
536
        pq = M.Project.query.find(dict(neighborhood_id=self.neighborhood._id, deleted=False))
536
        if sort=='alpha':
537
        if sort == 'alpha':
537
            pq.sort('name')
538
            pq.sort('name')
538
        else:
539
        else:
539
            pq.sort('last_updated', pymongo.DESCENDING)
540
            pq.sort('last_updated', pymongo.DESCENDING)
540
        count = pq.count()
541
        count = pq.count()
541
        projects = pq.skip(start).limit(int(limit)).all()
542
        projects = pq.skip(start).limit(int(limit)).all()
542
543
543
        entries = []
544
        entries = []
544
        for proj in projects:
545
        for proj in projects:
545
            admin_role = M.ProjectRole.query.get(project_id=proj.root_project._id,name='Admin')
546
            admin_role = M.ProjectRole.query.get(project_id=proj.root_project._id, name='Admin')
546
            if admin_role is None:
547
            if admin_role is None:
547
                continue
548
                continue
548
            user_role_list = M.ProjectRole.query.find(dict(project_id=proj.root_project._id, name=None)).all()
549
            user_role_list = M.ProjectRole.query.find(dict(project_id=proj.root_project._id, name=None)).all()
549
            for ur in user_role_list:
550
            for ur in user_role_list:
550
                if ur.user is not None and admin_role._id in ur.roles:
551
                if ur.user is not None and admin_role._id in ur.roles:
...
...
656
            award.full = full
657
            award.full = full
657
            award.created_by_neighborhood_id = self.neighborhood._id
658
            award.created_by_neighborhood_id = self.neighborhood._id
658
            if hasattr(icon, 'filename'):
659
            if hasattr(icon, 'filename'):
659
                M.AwardFile.save_image(
660
                M.AwardFile.save_image(
660
                    icon.filename, icon.file, content_type=icon.type,
661
                    icon.filename, icon.file, content_type=icon.type,
661
                    square=True, thumbnail_size=(48,48),
662
                    square=True, thumbnail_size=(48, 48),
662
                    thumbnail_meta=dict(award_id=award._id))
663
                    thumbnail_meta=dict(award_id=award._id))
663
        redirect(request.referer)
664
        redirect(request.referer)
664
665
665
    @expose()
666
    @expose()
666
    @require_post()
667
    @require_post()
...
...
705
    def not_found(self, **kw):
706
    def not_found(self, **kw):
706
        return dict()
707
        return dict()
707
708
708
    @expose()
709
    @expose()
709
    def _lookup(self, recipient, *remainder):
710
    def _lookup(self, recipient, *remainder):
710
        recipient=unquote(recipient)
711
        recipient = unquote(recipient)
711
        return GrantController(self.neighborhood, self.award, recipient), remainder
712
        return GrantController(self.neighborhood, self.award, recipient), remainder
712
713
713
    @expose()
714
    @expose()
714
    def icon(self):
715
    def icon(self):
715
        icon = self.award.icon
716
        icon = self.award.icon
...
...
726
        if hasattr(icon, 'filename'):
727
        if hasattr(icon, 'filename'):
727
            if self.award.icon:
728
            if self.award.icon:
728
                self.award.icon.delete()
729
                self.award.icon.delete()
729
            M.AwardFile.save_image(
730
            M.AwardFile.save_image(
730
                icon.filename, icon.file, content_type=icon.type,
731
                icon.filename, icon.file, content_type=icon.type,
731
                square=True, thumbnail_size=(48,48),
732
                square=True, thumbnail_size=(48, 48),
732
                thumbnail_meta=dict(award_id=self.award._id))
733
                thumbnail_meta=dict(award_id=self.award._id))
733
        for grant in M.AwardGrant.query.find(dict(award_id=self.award._id)):
734
        for grant in M.AwardGrant.query.find(dict(award_id=self.award._id)):
734
            with h.push_context(grant.granted_to_project_id):
735
            with h.push_context(grant.granted_to_project_id):
735
                g.post_event('project_updated')
736
                g.post_event('project_updated')
736
        flash('Award updated.')
737
        flash('Award updated.')