def distribute(handler, sprint): handler.title("Distribute Tasks") sprintid = int(sprint) sprint = Sprint.load(sprintid) if not sprint or sprint.isHidden(handler.session["user"]): ErrorBox.die("Invalid Sprint", "No sprint with ID <b>%d</b>" % id) handler.title(sprint.safe.name) print sprintTabs(sprint, "distribute") requirePriv(handler, "Write") if not (sprint.isActive() or sprint.isPlanning()): ErrorBox.die("Sprint Closed", "Unable to modify inactive sprint") if not sprint.canEdit(handler.session["user"]): ErrorBox.die("Permission Denied", "You don't have permission to modify this sprint") print '<script type="text/javascript" src="/static/highcharts/js/highcharts.js"></script>' print '<script type="text/javascript" src="/static/highcharts/js/highcharts-more.js"></script>' print '<script type="text/javascript">' print "var sprintid = %d;" % sprint.id print "</script>" print InfoBox("Loading...", id="post-status", close=True) print '<div id="distribution-range">' print "Acceptable commitment: <span></span>" print "</div>" print '<div id="distribution-range-slider"></div>' print '<div class="clear"></div>' print '<div id="distribution-chart"></div>' for col in ("left", "right"): print '<div class="distribution %s">' % col for user in sorted(sprint.members): print '<img class="user-gravatar" src="%s" userid="%d" title="%s">' % ( user.getAvatar(64), user.id, user.safe.username, ) if col == "right": print '<img class="user-gravatar" src="/static/images/revision-deferred.svg" userid="deferred" title="Deferred tasks">' print "<br><br>" print '<div class="selected">' print '<img style="visibility: hidden" class="user-gravatar" src="%s">' % User.getBlankAvatar(64) print '<div class="info">' print '<div class="username"></div>' print '<div class="hours"></div>' print '<div class="task-progress-total"><div class="progress-current" style="visibility: hidden;"></div></div>' print "</div>" print "</div>" print '<div class="clear"></div>' print '<div class="tasks"></div>' print "</div>" print '<div class="clear"></div><br><br>'
def userAvatarShow(handler, username, size = 80): def die(msg): print msg done() handler.wrappers = False size = to_int(size, 'size', die) user = User.load(username = username) if not user or not Image: # If Image is None, PIL is not installed redirect(User.getBlankAvatar()) if user.avatar is None: redirect(user.getAvatar()) data = b64decode(user.avatar) image = Image.open(StringIO(data)) image = image.resize((size, size), Image.ANTIALIAS) out = StringIO() image.save(out, 'png') print out.getvalue() handler.contentType = 'image/png'
def adminLog(handler, page = 1, users = None, types = None): PAGE_LEN = 100 PAGINATION_BOXES = 12 handler.title('Log') requirePriv(handler, 'Admin') LogEntry.cacheAll() entries = LogEntry.loadAll(orderby = '-timestamp') filtered = (users is not None) or (types is not None) users = set(User.load(int(id)) for id in users) if users else (User.loadAll(orderby = 'username') + [None]) # if not all(users): # ErrorBox.die("Unrecognized user ID(s)") types = [str(type) for type in types] if types else LogEntry.getTypes() if 'error' in types: errorCounter.reset() if filtered: entries = filter(lambda entry: entry.user in users and entry.type in types, entries) page = int(page) pages = max(len(entries) / PAGE_LEN, 1) if page < 1: page = 1 if page > pages: page = pages print "<form method=\"get\" action=\"/admin/log\">" print "<select name=\"users[]\" multiple size=\"10\">" for user in User.loadAll(orderby = 'username'): print "<option value=\"%d\"%s>%s</option>" % (user.id, ' selected' if user in users else '', user.safe.username) print "<option value=\"0\"%s>(anonymous)</option>" % (' selected' if None in users else '') print "</select>" print "<select name=\"types[]\" multiple size=\"10\">" for type in LogEntry.getTypes(): print "<option value=\"%s\"%s>%s</option>" % (type, ' selected' if type in types else '', type) print "</select>" print "<br>" print Button('Update', type = 'submit') print "</form>" firstPage, lastPage = max(1, page - (PAGINATION_BOXES - 1)), min(pages, page + (PAGINATION_BOXES - 1)) while lastPage - firstPage > ((PAGINATION_BOXES - 1) - sum([firstPage > 1, firstPage > 2, lastPage < pages, lastPage < pages - 1])): if abs(firstPage - page) >= abs(lastPage - page): firstPage += 1 else: lastPage -= 1 link = "/admin/log?page=%d" + ''.join("&users[]=%d" % (user.id if user else 0) for user in users) + ''.join("&types[]=%s" % type for type in types) print "<div class=\"pagination\">" print "<ul>" if page == 1: print "<li class=\"disabled\"><a href=\"#\">«</a></li>" else: print "<li><a href=\"%s\">«</a></li>" % (link % (page - 1)) if firstPage > 1: print "<li><a href=\"%s\">1</a></li>" % (link % 1) if firstPage > 2: print "<li class=\"disabled\"><a href=\"#\">...</a></li>" for i in range(firstPage, lastPage + 1): print "<li%s><a href=\"%s\">%d</a></li>" % (' class="active"' if i == page else '', link % i, i) if lastPage < pages: if lastPage < pages - 1: print "<li class=\"disabled\"><a href=\"#\">...</a></li>" print "<li><a href=\"%s\">%d</a></li>" % (link % pages, pages) if page == pages: print "<li class=\"disabled\"><a href=\"#\">»</a></li>" else: print "<li><a href=\"%s\">»</a></li>" % (link % (page + 1)) print "</ul>" print "</div>" print "<br>" for entry in entries[((page - 1) * PAGE_LEN):(page * PAGE_LEN)]: print "<div class=\"logentry\">" print "<div class=\"gravatar\">" print "<img class=\"gravatar\" src=\"%s\">" % (entry.user.getAvatar() if entry.user else User.getBlankAvatar()) print "</div>" print "<div>" print "<b><span class=\"label logtype-%s\">%s</span> at %s</b><br>" % (entry.type.split('.')[0], entry.type, entry.location) print "%s by %s<br>" % (tsToDate(entry.timestamp), "%s (%s)" % (entry.user.username, entry.ip) if entry.user else entry.ip) print "<pre>%s</pre>" % (entry.text or ' ') print "</div>" print "</div>" print "<div class=\"clear\"></div>"