blob: 61942578c83715df9ce5a6308b749b2454deb0d2 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from tg import expose, validate, redirect
from tg.decorators import with_trailing_slash
from datetime import datetime
from allura.controllers import BaseController
import allura.model as M
from forgeuserstats.model.stats import UserStats
from pylons import tmpl_context as c
from allura.lib.security import require_access
from forgeuserstats.widgets.forms import StatsPreferencesForm
from allura.lib.decorators import require_post
stats_preferences_form = StatsPreferencesForm()
class ForgeUserStatsCatController(BaseController):
@expose()
def _lookup(self, category, *remainder):
cat = M.TroveCategory.query.get(shortname=category)
return ForgeUserStatsCatController(category=cat), remainder
def __init__(self, category=None):
self.category = category
super(ForgeUserStatsCatController, self).__init__()
@expose('jinja:forgeuserstats:templates/index.html')
@with_trailing_slash
def index(self, **kw):
self.user = c.project.user_project_of
if not self.user:
return None
stats = self.user.stats
if (not stats.visible) and (c.user != self.user):
return dict(user=self.user)
cat_id = None
if self.category:
cat_id = self.category._id
ret_dict = _getDataForCategory(cat_id, stats)
ret_dict['user'] = self.user
ret_dict['registration_date'] = stats.registration_date
ret_dict['category'] = self.category
return ret_dict
class ForgeUserStatsController(BaseController):
category = ForgeUserStatsCatController()
@expose('jinja:forgeuserstats:templates/settings.html')
@with_trailing_slash
def settings(self, **kw):
require_access(c.project, 'admin')
self.user = c.project.user_project_of
if not self.user:
return dict(user=None)
if not self.user.stats:
UserStats.create(self.user)
return dict(
user=self.user,
form=StatsPreferencesForm(
action=c.project.url() + 'userstats/change_settings'))
@expose()
@require_post()
@validate(stats_preferences_form, error_handler=settings)
def change_settings(self, **kw):
require_access(c.project, 'admin')
self.user = c.project.user_project_of
if not self.user:
return dict(user=None)
if not self.user.stats:
UserStats.create(self.user)
visible = kw.get('visible')
self.user.stats.visible = visible
redirect(c.project.url() + 'userstats/settings')
@expose('jinja:forgeuserstats:templates/index.html')
@with_trailing_slash
def index(self, **kw):
self.user = c.project.user_project_of
if not self.user:
return dict(user=None)
if not self.user.stats:
UserStats.create(self.user)
stats = self.user.stats
if (not stats.visible) and (c.user != self.user):
return dict(user=self.user)
ret_dict = _getDataForCategory(None, stats)
ret_dict['user'] = self.user
ret_dict['registration_date'] = stats.registration_date
ret_dict['totlogins'] = stats.tot_logins_count
ret_dict['last_login'] = stats.last_login
if stats.last_login:
ret_dict['last_login_days'] = \
(datetime.utcnow() - stats.last_login).days
categories = {}
for p in self.user.my_projects():
for cat in p.trove_topic:
cat = M.TroveCategory.query.get(_id=cat)
if categories.get(cat):
categories[cat] += 1
else:
categories[cat] = 1
categories = sorted(categories.items(),
key=lambda (x, y): y, reverse=True)
ret_dict['lastmonth_logins'] = stats.getLastMonthLogins()
ret_dict['categories'] = categories
days = ret_dict['days']
if days >= 30:
ret_dict['permonthlogins'] = \
round(stats.tot_logins_count * 30.0 / days, 2)
else:
ret_dict['permonthlogins'] = 'n/a'
return ret_dict
@expose('jinja:forgeuserstats:templates/commits.html')
@with_trailing_slash
def commits(self, **kw):
self.user = c.project.user_project_of
if not self.user:
return dict(user=None)
if not self.user.stats:
UserStats.create(self.user)
stats = self.user.stats
if (not stats.visible) and (c.user != self.user):
return dict(user=self.user)
commits = stats.getCommitsByCategory()
return dict(
user=self.user,
data=commits)
@expose('jinja:forgeuserstats:templates/artifacts.html')
@with_trailing_slash
def artifacts(self, **kw):
self.user = c.project.user_project_of
if not self.user:
return dict(user=None)
if not self.user.stats:
UserStats.create(self.user)
stats = self.user.stats
if (not stats.visible) and (c.user != self.user):
return dict(user=self.user)
stats = self.user.stats
artifacts = stats.getArtifactsByCategory(detailed=True)
return dict(
user=self.user,
data=artifacts)
@expose('jinja:forgeuserstats:templates/tickets.html')
@with_trailing_slash
def tickets(self, **kw):
self.user = c.project.user_project_of
if not self.user:
return dict(user=None)
if not self.user.stats:
UserStats.create(self.user)
stats = self.user.stats
if (not stats.visible) and (c.user != self.user):
return dict(user=self.user)
artifacts = self.user.stats.getTicketsByCategory()
return dict(
user=self.user,
data=artifacts)
def _getDataForCategory(category, stats):
totcommits = stats.getCommits(category)
tottickets = stats.getTickets(category)
artifacts_by_type = stats.getArtifactsByType(category)
totartifacts = artifacts_by_type.get(None)
if totartifacts:
del artifacts_by_type[None]
else:
totartifacts = dict(created=0, modified=0)
lmcommits = stats.getLastMonthCommits(category)
lm_artifacts_by_type = stats.getLastMonthArtifactsByType(category)
lm_totartifacts = stats.getLastMonthArtifacts(category)
lm_tickets = stats.getLastMonthTickets(category)
days = (datetime.utcnow() - stats.start_date).days
if days >= 30:
pmartifacts = dict(
created=round(totartifacts['created'] * 30.0 / days, 2),
modified=round(totartifacts['modified'] * 30.0 / days, 2))
pmcommits = dict(
number=round(totcommits['number'] * 30.0 / days, 2),
lines=round(totcommits['lines'] * 30.0 / days, 2))
pmtickets = dict(
assigned=round(tottickets['assigned'] * 30.0 / days, 2),
revoked=round(tottickets['revoked'] * 30.0 / days, 2),
solved=round(tottickets['solved'] * 30.0 / days, 2),
averagesolvingtime='n/a')
for key in artifacts_by_type:
value = artifacts_by_type[key]
artifacts_by_type[key]['pmcreated'] = \
round(value['created'] * 30.0 / days, 2)
artifacts_by_type[key]['pmmodified'] = \
round(value['modified'] * 30.0 / days, 2)
else:
pmartifacts = dict(created='n/a', modified='n/a')
pmcommits = dict(number='n/a', lines='n/a')
pmtickets = dict(
assigned='n/a',
revoked='n/a',
solved='n/a',
averagesolvingtime='n/a')
for key in artifacts_by_type:
artifacts_by_type[key]['pmcreated'] = 'n/a'
artifacts_by_type[key]['pmmodified'] = 'n/a'
return dict(
days=days,
totcommits=totcommits,
lastmonthcommits=lmcommits,
lastmonthtickets=lm_tickets,
tottickets=tottickets,
permonthcommits=pmcommits,
totartifacts=totartifacts,
lastmonthartifacts=lm_totartifacts,
permonthartifacts=pmartifacts,
artifacts_by_type=artifacts_by_type,
lastmonth_artifacts_by_type=lm_artifacts_by_type,
permonthtickets=pmtickets)