Switch to unified view

a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
1
import re
1
import re
2
import logging
2
import logging
3
3
from datetime import datetime, timedelta
4
from bson import ObjectId
5
from urllib import unquote
4
from urllib import unquote
6
from itertools import chain, islice
5
from itertools import chain, islice
7
6
7
from bson import ObjectId
8
from tg import expose, flash, redirect, validate, request, response
8
from tg import expose, flash, redirect, validate, request, response
9
from tg.decorators import with_trailing_slash, without_trailing_slash
9
from tg.decorators import with_trailing_slash, without_trailing_slash
10
from pylons import c, g
10
from pylons import c, g
11
from webob import exc
11
from webob import exc
12
import pymongo
12
import pymongo
...
...
398
398
399
class NeighborhoodAdminController(object):
399
class NeighborhoodAdminController(object):
400
    def __init__(self, neighborhood):
400
    def __init__(self, neighborhood):
401
        self.neighborhood = neighborhood
401
        self.neighborhood = neighborhood
402
        self.awards = NeighborhoodAwardsController(self.neighborhood)
402
        self.awards = NeighborhoodAwardsController(self.neighborhood)
403
        self.stats = NeighborhoodStatsController(self.neighborhood)
404
405
    def _check_security(self):
406
        require_access(self.neighborhood, 'admin')
403
407
404
    @with_trailing_slash
408
    @with_trailing_slash
405
    @expose()
409
    @expose()
406
    def index(self, **kw):
410
    def index(self, **kw):
407
        require_access(self.neighborhood, 'admin')
408
        utils.permanent_redirect('overview')
411
        utils.permanent_redirect('overview')
409
412
410
    @without_trailing_slash
413
    @without_trailing_slash
411
    @expose('jinja:allura:templates/neighborhood_admin_overview.html')
414
    @expose('jinja:allura:templates/neighborhood_admin_overview.html')
412
    def overview(self, **kw):
415
    def overview(self, **kw):
413
        require_access(self.neighborhood, 'admin')
414
        set_nav(self.neighborhood)
416
        set_nav(self.neighborhood)
415
        c.overview_form = W.neighborhood_overview_form
417
        c.overview_form = W.neighborhood_overview_form
416
        return dict(neighborhood=self.neighborhood)
418
        return dict(neighborhood=self.neighborhood)
417
419
418
    @without_trailing_slash
420
    @without_trailing_slash
419
    @expose('jinja:allura:templates/neighborhood_admin_permissions.html')
421
    @expose('jinja:allura:templates/neighborhood_admin_permissions.html')
420
    def permissions(self):
422
    def permissions(self):
421
        require_access(self.neighborhood, 'admin')
422
        set_nav(self.neighborhood)
423
        set_nav(self.neighborhood)
423
        return dict(neighborhood=self.neighborhood)
424
        return dict(neighborhood=self.neighborhood)
424
425
425
    @expose('json:')
426
    @expose('json:')
426
    def project_search(self, term=''):
427
    def project_search(self, term=''):
427
        require_access(self.neighborhood, 'admin')
428
        if len(term) < 3:
428
        if len(term) < 3:
429
            raise exc.HTTPBadRequest('"term" param must be at least length 3')
429
            raise exc.HTTPBadRequest('"term" param must be at least length 3')
430
        project_regex = re.compile('(?i)%s' % re.escape(term))
430
        project_regex = re.compile('(?i)%s' % re.escape(term))
431
        projects = M.Project.query.find(dict(
431
        projects = M.Project.query.find(dict(
432
            neighborhood_id=self.neighborhood._id, deleted=False,
432
            neighborhood_id=self.neighborhood._id, deleted=False,
...
...
440
                for p in projects])
440
                for p in projects])
441
441
442
    @without_trailing_slash
442
    @without_trailing_slash
443
    @expose('jinja:allura:templates/neighborhood_admin_accolades.html')
443
    @expose('jinja:allura:templates/neighborhood_admin_accolades.html')
444
    def accolades(self):
444
    def accolades(self):
445
        require_access(self.neighborhood, 'admin')
446
        set_nav(self.neighborhood)
445
        set_nav(self.neighborhood)
447
        awards = M.Award.query.find(dict(created_by_neighborhood_id=self.neighborhood._id)).all()
446
        awards = M.Award.query.find(dict(created_by_neighborhood_id=self.neighborhood._id)).all()
448
        awards_count = len(awards)
447
        awards_count = len(awards)
449
        grants = M.AwardGrant.query.find(dict(granted_by_neighborhood_id=self.neighborhood._id))
448
        grants = M.AwardGrant.query.find(dict(granted_by_neighborhood_id=self.neighborhood._id))
450
        grants_count = len(grants)
449
        grants_count = len(grants)
...
...
458
457
459
    @expose()
458
    @expose()
460
    @require_post()
459
    @require_post()
461
    @validate(W.neighborhood_overview_form, error_handler=overview)
460
    @validate(W.neighborhood_overview_form, error_handler=overview)
462
    def update(self, name=None, css=None, homepage=None, project_template=None, icon=None, **kw):
461
    def update(self, name=None, css=None, homepage=None, project_template=None, icon=None, **kw):
463
        require_access(self.neighborhood, 'admin')
464
        self.neighborhood.name = name
462
        self.neighborhood.name = name
465
        self.neighborhood.redirect = kw.pop('redirect', '')
463
        self.neighborhood.redirect = kw.pop('redirect', '')
466
        self.neighborhood.homepage = homepage
464
        self.neighborhood.homepage = homepage
467
        self.neighborhood.css = css
465
        self.neighborhood.css = css
468
        self.neighborhood.project_template = project_template
466
        self.neighborhood.project_template = project_template
...
...
482
        require_access(self.neighborhood, 'admin')
480
        require_access(self.neighborhood, 'admin')
483
        set_nav(self.neighborhood)
481
        set_nav(self.neighborhood)
484
        return dict(
482
        return dict(
485
            neighborhood=self.neighborhood,
483
            neighborhood=self.neighborhood,
486
        )
484
        )
485
486
class NeighborhoodStatsController(object):
487
488
    def __init__(self, neighborhood):
489
        self.neighborhood = neighborhood
490
491
    @with_trailing_slash
492
    @expose('jinja:allura:templates/neighborhood_stats.html')
493
    def index(self, **kw):
494
        delete_count = M.Project.query.find(dict(neighborhood_id=self.neighborhood._id, deleted=True)).count()
495
        public_count = 0
496
        private_count = 0
497
        last_updated_30 = 0
498
        last_updated_60 = 0
499
        last_updated_90 = 0
500
        today_date = datetime.today()
501
        if M.Project.query.find(dict(neighborhood_id=self.neighborhood._id, deleted=False)).count() < 20000: # arbitrary limit for efficiency
502
            for p in M.Project.query.find(dict(neighborhood_id=self.neighborhood._id, deleted=False)):
503
                if p.private:
504
                    private_count = private_count + 1
505
                else:
506
                    public_count = public_count + 1
507
                    if today_date - p.last_updated < timedelta(days=30):
508
                        last_updated_30 = last_updated_30 + 1
509
                    if today_date - p.last_updated < timedelta(days=60):
510
                        last_updated_60 = last_updated_60 + 1
511
                    if today_date - p.last_updated < timedelta(days=90):
512
                        last_updated_90 = last_updated_90 + 1
513
    
514
        set_nav(self.neighborhood)
515
        return dict(
516
            delete_count = delete_count,
517
            public_count = public_count,
518
            private_count = private_count,
519
            last_updated_30 = last_updated_30,
520
            last_updated_60 = last_updated_60,
521
            last_updated_90 = last_updated_90,
522
            neighborhood = self.neighborhood,
523
        )
524
525
    @without_trailing_slash
526
    @expose('jinja:allura:templates/neighborhood_stats_adminlist.html')
527
    def adminlist(self, sort='alpha', limit=25, page=0, **kw):
528
        limit, page, start = g.handle_paging(limit, page)
529
530
        pq = M.Project.query.find(dict(neighborhood_id=self.neighborhood._id, deleted=False))
531
        if sort=='alpha':
532
            pq.sort('name')
533
        else:
534
            pq.sort('last_updated', pymongo.DESCENDING)
535
        count = pq.count()
536
        projects = pq.skip(start).limit(int(limit)).all()
537
538
        entries = []
539
        for proj in projects:
540
            admin_role = M.ProjectRole.query.get(project_id=proj.root_project._id,name='Admin')
541
            if admin_role is None:
542
                continue
543
            user_role_list = M.ProjectRole.query.find(dict(project_id=proj.root_project._id, name=None)).all()
544
            for ur in user_role_list:
545
                if ur.user is not None and admin_role._id in ur.roles:
546
                    entries.append({'project': proj, 'user': ur.user})
547
548
        set_nav(self.neighborhood)
549
        return dict(entries=entries,
550
                    sort=sort,
551
                    limit=limit, page=page, count=count,
552
                    page_list=W.page_list,
553
                    neighborhood=self.neighborhood,
554
                    )
555
487
556
488
class NeighborhoodModerateController(object):
557
class NeighborhoodModerateController(object):
489
558
490
    def __init__(self, neighborhood):
559
    def __init__(self, neighborhood):
491
        self.neighborhood = neighborhood
560
        self.neighborhood = neighborhood