def findActiveSprint(handler, project = None, search = None): handler.title('Active Sprint') requirePriv(handler, 'User') if project: projectid = int(project) project = Project.load(projectid) if not project: ErrorBox.die('Load project', "No project with ID <b>%d</b>" % projectid) url = "/sprints/%d" if search: url += "?search=%s" % search sprints = Sprint.loadAllActive(handler.session['user'], project) sprints = filter(lambda sprint: sprint.canView(handler.session['user']), sprints) for case in switch(len(sprints)): if case(0): ErrorBox.die('Active sprint', 'No active sprints found') break if case(1): redirect(url % sprints[0].id) break if case(): print "You are active in multiple sprints%s:<br><br>" % (" in the %s project" % project.safe.name if project else '') for sprint in sprints: print "<a href=\"%s\">%s</a><br>" % (url % sprint.id, sprint.safe.name) break
def finger(context, username): user = nameLookup(User, username, key = 'username') if not user: fail("No user named %s" % username) print clr(user.username, bold = True) print "Last seen: %s" % clr(tsToDate(user.lastseen) if user.lastseen else 'Never') sprints = Sprint.loadAllActive(user) if sprints: print "Member of: %s" % ', '.join(link(sprint.name, "/sprints/%d" % sprint.id) for sprint in sprints) if context['handler'].session['user'].hasPrivilege('Admin'): if user.hotpKey: print "HOTP key: %s" % clr(user.hotpKey) if user.resetkey: print "Reset key: %s" % clr(user.resetkey)
def sprint(context): match = re.search('^/sprints/([0-9]+)/?', context['path']) if match: return sprintByID(context, int(match.group(1))) match = re.search('\\?sprint=([0-9]+)$', context['path']) if match: return sprintByID(context, int(match.group(1))) sprints = Sprint.loadAllActive(context['handler'].session['user']) for case in switch(len(sprints)): if case(0): fail("No active sprints") break if case(1): return sprintByID(context, sprints[0].id) if case(): fail("%d active sprints" % len(sprints)) break
def user(handler, username): user = User.load(username = username) if not user: ErrorBox.die('User', "No user named <b>%s</b>" % stripTags(username)) Markdown.head('form#message-form .body pre code') print "<script src=\"/static/jquery.typing-0.2.0.min.js\" type=\"text/javascript\"></script>" print "<script src=\"/static/users.js\" type=\"text/javascript\"></script>" Chart.include() undelay(handler) handler.title(user.safe.username) handler.replace('$bodytitle$', '', 1) print "<img src=\"%s\" class=\"gravatar\">" % user.getAvatar(64) print "<h1>%s</h1>" % user.safe.username if isDevMode(handler): print "<div class=\"debugtext\">User ID: %d</div>" % user.id print "<div class=\"clear\"></div>" if handler.session['user'] and handler.session['user'].hasPrivilege('Admin'): print "<h3>Admin</h3>" print "<form method=\"post\" action=\"/admin/users\">" print "<input type=\"hidden\" name=\"username\" value=\"%s\">" % user.username print "<button type=\"submit\" class=\"btn\" name=\"action\" value=\"resetpw\">Reset password</button>" print "<button type=\"submit\" class=\"btn\" name=\"action\" value=\"impersonate\">Impersonate</button>" print "<button type=\"submit\" class=\"btn\" name=\"action\" value=\"sessions\">Manage sessions</button>" print "<button type=\"submit\" class=\"btn\" name=\"action\" value=\"privileges\">Manage privileges</button>" print "</form>" if user == handler.session['user']: print "<h3>Avatar</h3>" if user.hasLocalAvatar(): print "Your avatar is currently <a href=\"/users/%s/avatar/set\">locally hosted</a>" % user.username else: print "Your avatar can be changed at <a href=\"http://gravatar.com/\" target=\"_new\">http://gravatar.com/</a>. It must be associated with the e-mail <b>%s</b>, and be rated PG. You can also host an avatar <a href=\"/users/%s/avatar/set\">locally</a>, if necessary" % (user.getEmail(), user.username) print "<h3>Authentication</h3>" print "Your sprint tool password can be changed <a href=\"/resetpw\">here</a>.", if settings.kerberosRealm: print "You can also use your %s kerberos password to login" % settings.kerberosRealm, print "<br><br>" if user.hotpKey == '': print "You also have the option to use two-factor authentication via <a href=\"http://en.wikipedia.org/wiki/HOTP\">HOTP</a>. You can use <a href=\"http://support.google.com/a/bin/answer.py?hl=en&answer=1037451\">Google Authenticator</a> to generate verification codes<br><br>" print "<form method=\"post\" action=\"/security/two-factor\">" print "<button type=\"submit\" class=\"btn danger\" name=\"action\" value=\"enable\">Enable two-factor authentication</button>" print "</form>" else: print "You are currently using two-factor authentication<br><br>" print "<form method=\"post\" action=\"/security/two-factor\">" print "<button type=\"submit\" class=\"btn danger\" name=\"action\" value=\"enable\">Reset HOTP key</button>" print "<button type=\"submit\" class=\"btn danger\" name=\"action\" value=\"disable\">Disable two-factor authentication</button>" print "</form>" print "<h3>Messages</h3>" print "Your inbox and sent messages can be viewed <a href=\"/messages/inbox\">here</a><br>" print "<h3>Last seen</h3>" if not user.lastseen: print "Never" elif dateToTs(getNow()) - user.lastseen < 60: print "Just now" else: print "%s ago" % timesince(tsToDate(user.lastseen)) if handler.session['user'] and handler.session['user'] != user: print "<h3>Message</h3>" print "<small>(Messages are formatted in <a target=\"_blank\" href=\"/help/markdown\">markdown</a>)</small>" print "<form id=\"message-form\" method=\"post\" action=\"/messages/send\">" print "<input type=\"hidden\" name=\"userid\" value=\"%d\">" % user.id print "<textarea name=\"body\" class=\"large\"></textarea>" print "<div class=\"body markdown\"><div id=\"preview\"></div></div>" print Button('Send').post().positive() print "</form>" print "<h3>Project distribution</h3>" sprints = filter(lambda s: user in s.members, Sprint.loadAllActive()) sprintHours = map(lambda s: (s, Availability(s).getAllForward(getNow(), user)), sprints) projectHours = map(lambda (p, g): (p, sum(hours for sprint, hours in g)), groupby(sprintHours, lambda (s, a): s.project)) # For now at least, don't show projects with no hours projectHours = filter(lambda (p, h): h > 0, projectHours) if len(projectHours) > 0: chart = Chart('chart') chart.title.text = '' chart.tooltip.formatter = "function() {return '<b>' + this.point.name + '</b>: ' + this.point.y + '%';}" chart.plotOptions.pie.allowPointSelect = True chart.plotOptions.pie.cursor = 'pointer' chart.plotOptions.pie.dataLabels.enabled = False chart.plotOptions.pie.showInLegend = True chart.credits.enabled = False chart.series = seriesList = [] series = { 'type': 'pie', 'name': '', 'data': [] } seriesList.append(series) total = sum(hours for project, hours in projectHours) for project, hours in projectHours: series['data'].append([project.name, float("%2.2f" % (100 * hours / total))]) chart.js() chart.placeholder() else: print "Not a member of any active sprints"