Switch to unified view

a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
1
import os, re
1
import os, re
2
import logging
2
import logging
3
import json
3
import json
4
5
from bson import ObjectId
4
from urllib import unquote, quote
6
from urllib import unquote, quote
5
from urllib2 import urlopen
7
from urllib2 import urlopen
6
from itertools import chain, islice
8
from itertools import chain, islice
7
from cStringIO import StringIO
9
from cStringIO import StringIO
8
10
...
...
444
class NeighborhoodAdminController(object):
446
class NeighborhoodAdminController(object):
445
    def __init__(self, neighborhood):
447
    def __init__(self, neighborhood):
446
        self.neighborhood = neighborhood
448
        self.neighborhood = neighborhood
447
        self.awards = NeighborhoodAwardsController(self.neighborhood)
449
        self.awards = NeighborhoodAwardsController(self.neighborhood)
448
450
449
    def _check_security(self):
450
        require_access(self.neighborhood, 'admin')
451
452
    @with_trailing_slash
451
    @with_trailing_slash
453
    @expose()
452
    @expose()
454
    def index(self, **kw):
453
    def index(self, **kw):
454
        require_access(self.neighborhood, 'admin')
455
        utils.permanent_redirect('overview')
455
        utils.permanent_redirect('overview')
456
456
457
    @without_trailing_slash
457
    @without_trailing_slash
458
    @expose('jinja:allura:templates/neighborhood_admin_overview.html')
458
    @expose('jinja:allura:templates/neighborhood_admin_overview.html')
459
    def overview(self):
459
    def overview(self):
460
        require_access(self.neighborhood, 'admin')
460
        set_nav(self.neighborhood)
461
        set_nav(self.neighborhood)
461
        c.resize_editor = W.resize_editor
462
        c.resize_editor = W.resize_editor
462
        return dict(neighborhood=self.neighborhood)
463
        return dict(neighborhood=self.neighborhood)
463
464
464
    @without_trailing_slash
465
    @without_trailing_slash
465
    @expose('jinja:allura:templates/neighborhood_admin_permissions.html')
466
    @expose('jinja:allura:templates/neighborhood_admin_permissions.html')
466
    def permissions(self):
467
    def permissions(self):
468
        require_access(self.neighborhood, 'admin')
467
        set_nav(self.neighborhood)
469
        set_nav(self.neighborhood)
468
        return dict(neighborhood=self.neighborhood)
470
        return dict(neighborhood=self.neighborhood)
469
471
470
    @expose('json:')
472
    @expose('json:')
471
    def project_search(self, term=''):
473
    def project_search(self, term=''):
474
        require_access(self.neighborhood, 'admin')
472
        if len(term) < 3:
475
        if len(term) < 3:
473
            raise exc.HTTPBadRequest('"term" param must be at least length 3')
476
            raise exc.HTTPBadRequest('"term" param must be at least length 3')
474
        project_regex = re.compile('(?i)%s' % re.escape(term))
477
        project_regex = re.compile('(?i)%s' % re.escape(term))
475
        projects = M.Project.query.find(dict(
478
        projects = M.Project.query.find(dict(
476
            neighborhood_id=self.neighborhood._id, deleted=False,
479
            neighborhood_id=self.neighborhood._id, deleted=False,
...
...
484
                for p in projects])
487
                for p in projects])
485
488
486
    @without_trailing_slash
489
    @without_trailing_slash
487
    @expose('jinja:allura:templates/neighborhood_admin_accolades.html')
490
    @expose('jinja:allura:templates/neighborhood_admin_accolades.html')
488
    def accolades(self):
491
    def accolades(self):
492
        require_access(self.neighborhood, 'admin')
489
        set_nav(self.neighborhood)
493
        set_nav(self.neighborhood)
490
        awards = M.Award.query.find(dict(created_by_neighborhood_id=self.neighborhood._id)).all()
494
        awards = M.Award.query.find(dict(created_by_neighborhood_id=self.neighborhood._id)).all()
491
        awards_count = len(awards)
495
        awards_count = len(awards)
492
        grants = M.AwardGrant.query.find(dict(granted_by_neighborhood_id=self.neighborhood._id))
496
        grants = M.AwardGrant.query.find(dict(granted_by_neighborhood_id=self.neighborhood._id))
493
        grants_count = len(grants)
497
        grants_count = len(grants)
...
...
500
            neighborhood=self.neighborhood)
504
            neighborhood=self.neighborhood)
501
505
502
    @expose()
506
    @expose()
503
    @require_post()
507
    @require_post()
504
    def update(self, name=None, css=None, homepage=None, project_template=None, icon=None, **kw):
508
    def update(self, name=None, css=None, homepage=None, project_template=None, icon=None, **kw):
509
        require_access(self.neighborhood, 'admin')
505
        self.neighborhood.name = name
510
        self.neighborhood.name = name
506
        self.neighborhood.redirect = kw.pop('redirect', '')
511
        self.neighborhood.redirect = kw.pop('redirect', '')
507
        self.neighborhood.homepage = homepage
512
        self.neighborhood.homepage = homepage
508
        self.neighborhood.css = css
513
        self.neighborhood.css = css
509
        self.neighborhood.project_template = project_template
514
        self.neighborhood.project_template = project_template
...
...
577
        if neighborhood is not None:
582
        if neighborhood is not None:
578
            self.neighborhood = neighborhood
583
            self.neighborhood = neighborhood
579
584
580
    @expose('jinja:allura:templates/awards.html')
585
    @expose('jinja:allura:templates/awards.html')
581
    def index(self, **kw):
586
    def index(self, **kw):
587
        require_access(self.neighborhood, 'admin')
582
        awards = M.Award.query.find(dict(created_by_neighborhood_id=self.neighborhood._id))
588
        awards = M.Award.query.find(dict(created_by_neighborhood_id=self.neighborhood._id))
583
        count = len(awards)
589
        count = len(awards)
584
        return dict(awards=awards or [], count=count)
590
        return dict(awards=awards or [], count=count)
585
591
586
    @expose('jinja:allura:templates/award_not_found.html')
592
    @expose('jinja:allura:templates/award_not_found.html')
587
    def not_found(self, **kw):
593
    def not_found(self, **kw):
588
        return dict()
594
        return dict()
589
595
590
    @expose('jinja:allura:templates/grants.html')
596
    @expose('jinja:allura:templates/grants.html')
591
    def grants(self, **kw):
597
    def grants(self, **kw):
598
        require_access(self.neighborhood, 'admin')
592
        grants = M.AwardGrant.query.find(dict(granted_by_neighborhood_id=self.neighborhood._id))
599
        grants = M.AwardGrant.query.find(dict(granted_by_neighborhood_id=self.neighborhood._id))
593
        count = len(grants)
600
        count = len(grants)
594
        return dict(grants=grants or [], count=count)
601
        return dict(grants=grants or [], count=count)
595
602
596
    @expose()
603
    @expose()
597
    def _lookup(self, short, *remainder):
604
    def _lookup(self, award_id, *remainder):
598
        short=unquote(short)
599
        return AwardController(self.neighborhood, short), remainder
605
        return AwardController(self.neighborhood, award_id), remainder
600
606
601
    @expose()
607
    @expose()
602
    @require_post()
608
    @require_post()
603
    def create(self, icon=None, short=None, full=None):
609
    def create(self, icon=None, short=None, full=None):
610
        require_access(self.neighborhood, 'admin')
604
        app_config_id = ObjectId()
611
        app_config_id = ObjectId()
605
        tool_version = {'neighborhood': '0'}
612
        tool_version = {'neighborhood': '0'}
606
        if short:
613
        if short:
607
            award = M.Award(app_config_id=app_config_id, tool_version=tool_version)
614
            award = M.Award(app_config_id=app_config_id, tool_version=tool_version)
608
            award.short = short
615
            award.short = short
...
...
616
        redirect(request.referer)
623
        redirect(request.referer)
617
624
618
    @expose()
625
    @expose()
619
    @require_post()
626
    @require_post()
620
    def grant(self, grant=None, recipient=None):
627
    def grant(self, grant=None, recipient=None):
628
        require_access(self.neighborhood, 'admin')
621
        grant_q = M.Award.query.find(dict(short=grant,
629
        grant_q = M.Award.query.find(dict(short=grant,
622
            created_by_neighborhood_id=self.neighborhood._id)).first()
630
            created_by_neighborhood_id=self.neighborhood._id)).first()
623
        recipient_q = M.Project.query.find(dict(
631
        recipient_q = M.Project.query.find(dict(
624
            neighborhood_id=self.neighborhood._id, shortname=recipient,
632
            neighborhood_id=self.neighborhood._id, shortname=recipient,
625
            deleted=False)).first()
633
            deleted=False)).first()
...
...
629
            award = M.AwardGrant(app_config_id=app_config_id,
637
            award = M.AwardGrant(app_config_id=app_config_id,
630
                                 tool_version=tool_version)
638
                                 tool_version=tool_version)
631
            award.award_id = grant_q._id
639
            award.award_id = grant_q._id
632
            award.granted_to_project_id = recipient_q._id
640
            award.granted_to_project_id = recipient_q._id
633
            award.granted_by_neighborhood_id = self.neighborhood._id
641
            award.granted_by_neighborhood_id = self.neighborhood._id
642
            with h.push_context(recipient_q._id):
643
                g.post_event('project_updated')
634
        redirect(request.referer)
644
        redirect(request.referer)
635
645
636
class AwardController(object):
646
class AwardController(object):
637
647
638
    def __init__(self, neighborhood=None, short=None):
648
    def __init__(self, neighborhood=None, award_id=None):
639
        self.neighborhood = neighborhood
649
        self.neighborhood = neighborhood
640
        if short is not None:
650
        if award_id:
641
            self.short = short
651
            self.award = M.Award.query.find(dict(_id=ObjectId(award_id),
642
            self.award = M.Award.query.find(dict(short=self.short,
643
                created_by_neighborhood_id=self.neighborhood._id)).first()
652
                created_by_neighborhood_id=self.neighborhood._id)).first()
644
653
645
    @with_trailing_slash
654
    @with_trailing_slash
646
    @expose('jinja:allura:templates/award.html')
655
    @expose('jinja:allura:templates/award.html')
647
    def index(self, **kw):
656
    def index(self, **kw):
657
        require_access(self.neighborhood, 'admin')
648
        set_nav(self.neighborhood)
658
        set_nav(self.neighborhood)
649
        if self.award is not None:
659
        if self.award is not None:
650
            return dict(award=self.award, neighborhood=self.neighborhood)
660
            return dict(award=self.award, neighborhood=self.neighborhood)
651
        else:
661
        else:
652
            redirect('not_found')
662
            redirect('not_found')
...
...
668
        return icon.serve()
678
        return icon.serve()
669
679
670
    @expose()
680
    @expose()
671
    @require_post()
681
    @require_post()
672
    def grant(self, recipient=None):
682
    def grant(self, recipient=None):
683
        require_access(self.neighborhood, 'admin')
673
        recipient_q = M.Project.query.find(dict(name=recipient, deleted=False,
684
        recipient_q = M.Project.query.find(dict(name=recipient, deleted=False,
674
            neighborhood_id=self.neighborhood._id)).first()
685
            neighborhood_id=self.neighborhood._id)).first()
675
        app_config_id = ObjectId()
686
        app_config_id = ObjectId()
676
        tool_version = {'neighborhood': '0'}
687
        tool_version = {'neighborhood': '0'}
677
        grant = M.AwardGrant(app_config_id=app_config_id, tool_version=tool_version)
688
        grant = M.AwardGrant(app_config_id=app_config_id, tool_version=tool_version)
...
...
681
        redirect(request.referer)
692
        redirect(request.referer)
682
693
683
    @expose()
694
    @expose()
684
    @require_post()
695
    @require_post()
685
    def update(self, icon=None, short=None, full=None):
696
    def update(self, icon=None, short=None, full=None):
697
        require_access(self.neighborhood, 'admin')
686
        self.award.short = short
698
        self.award.short = short
687
        self.award.full = full
699
        self.award.full = full
688
        if hasattr(icon, 'filename'):
700
        if hasattr(icon, 'filename'):
689
            if self.award.icon:
701
            if self.award.icon:
690
                self.award.icon.delete()
702
                self.award.icon.delete()
691
            M.AwardFile.save_image(
703
            M.AwardFile.save_image(
692
                icon.filename, icon.file, content_type=icon.type,
704
                icon.filename, icon.file, content_type=icon.type,
693
                square=True, thumbnail_size=(48,48),
705
                square=True, thumbnail_size=(48,48),
694
                thumbnail_meta=dict(award_id=self.award._id))
706
                thumbnail_meta=dict(award_id=self.award._id))
707
        for grant in M.AwardGrant.query.find(dict(award_id=self.award._id)):
708
            with h.push_context(grant.granted_to_project_id):
709
                g.post_event('project_updated')
695
        flash('Award updated.')
710
        flash('Award updated.')
696
        redirect(self.award.longurl())
711
        redirect(self.award.longurl())
697
712
698
    @expose()
713
    @expose()
699
    @require_post()
714
    @require_post()
700
    def delete(self):
715
    def delete(self):
716
        require_access(self.neighborhood, 'admin')
701
        if self.award:
717
        if self.award:
702
            grants = M.AwardGrant.query.find(dict(award_id=self.award._id))
718
            grants = M.AwardGrant.query.find(dict(award_id=self.award._id))
703
            for grant in grants:
719
            for grant in grants:
704
                grant.delete()
720
                grant.delete()
721
                with h.push_context(grant.granted_to_project_id):
722
                    g.post_event('project_updated')
705
            M.AwardFile.query.remove(dict(award_id=self.award._id))
723
            M.AwardFile.query.remove(dict(award_id=self.award._id))
706
            self.award.delete()
724
            self.award.delete()
707
        redirect(request.referer)
725
        redirect(request.referer)
708
726
709
class GrantController(object):
727
class GrantController(object):
...
...
719
                granted_to_project_id=self.project._id)
737
                granted_to_project_id=self.project._id)
720
738
721
    @with_trailing_slash
739
    @with_trailing_slash
722
    @expose('jinja:allura:templates/grant.html')
740
    @expose('jinja:allura:templates/grant.html')
723
    def index(self, **kw):
741
    def index(self, **kw):
742
        require_access(self.neighborhood, 'admin')
724
        if self.grant is not None:
743
        if self.grant is not None:
725
            return dict(grant=self.grant)
744
            return dict(grant=self.grant)
726
        else:
745
        else:
727
            redirect('not_found')
746
            redirect('not_found')
728
747
...
...
738
        return icon.serve()
757
        return icon.serve()
739
758
740
    @expose()
759
    @expose()
741
    @require_post()
760
    @require_post()
742
    def revoke(self):
761
    def revoke(self):
762
        require_access(self.neighborhood, 'admin')
743
        self.grant.delete()
763
        self.grant.delete()
764
        with h.push_context(self.project._id):
765
            g.post_event('project_updated')
744
        redirect(request.referer)
766
        redirect(request.referer)