|
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
|