def fetch_members(self, board, trello_board): trello_members = trello_board.all_members() # For each member, check if he/she doesn't exist. In that case, create him/her for trello_member in trello_members: # If the member does not exist, create it with empty Trello credentials try: member = Member.objects.get( trello_member_profile__trello_id=trello_member.id) if self.debug: print(u"Member {0} already existed ".format( member.external_username)) except Member.DoesNotExist: member = Member(creator=self.member) member.save() trello_member_profile = TrelloMemberProfile( trello_id=trello_member.id, member=member, username=trello_member.username, initials=trello_member.initials) trello_member_profile.save() if self.debug: print(u"Member {0} created".format( member.external_username)) # Only add the board to the member if he/she has not it yet if not member.boards.filter(uuid=board.uuid).exists(): member.boards.add(board) if self.debug: print(u"Member {0} has role {1}".format( member.external_username, trello_member.member_type)) # If this member has no role in this board, add the role to the member if not member.roles.filter(board=board).exists(): if self.debug: print("Creating role {0} for {1}".format( trello_member.member_type, board.name)) member_role, created = MemberRole.objects.get_or_create( board=board, type=trello_member.member_type) member_role.members.add(member) # If this member has a role but is different from the role he/she has in Trello, # update his/her role elif member.roles.get( board=board).type != trello_member.member_type: if self.debug: print("Updating {0}'s role from {1} to {2} in {3}".format( member.external_username, member.roles.get(board=board).type, trello_member.member_type, board.name)) member.roles.clear() member_role, created = MemberRole.objects.get_or_create( board=board, type=trello_member.member_type) member_role.members.add(member)
def handle(self, *args, **options): if 'username' not in options or not options['username'] or len( options['username']) != 1: self.stdout.write(self.style.ERROR("username is mandatory")) return False if 'password' not in options or not options['password'] or len( options['password']) != 1: self.stdout.write(self.style.ERROR("password is mandatory")) return False username = options['username'][0] if User.objects.filter(username=username).exists(): self.stdout.write(self.style.ERROR("This username already exists")) return False password = options['password'][0] try: with transaction.atomic(): # Creation of user user = User(username=username, is_superuser=True, is_active=True) user.set_password(password) user.save() # Assignment of member member = Member(user=user) member.save() # Assignment of user to group administrators administrators = Group.objects.get( name=settings.ADMINISTRATOR_GROUP) administrators.user_set.add(user) except Exception as e: self.stdout.write( self.style.ERROR( "Supermember couldn't be created successfully because of exception {0}" .format(e))) # Everything went well self.stdout.write( self.style.SUCCESS( "Supermember with username {0} has been created successfully". format(username)))
def task_movements_by_member(request, movement_type="forward", board=None): if movement_type != "forward" and movement_type != "backward": raise ValueError( "{0} is not recognized as a valid movement type".format( movement_type)) # Caching chart_uuid = "members.task_movements_by_member-{0}-{1}".format( movement_type, board.id if board else "user-{0}".format(request.user.id)) chart = CachedChart.get(board=board, uuid=chart_uuid) if chart: return chart chart_title = u"Task {0} movements as of {1}".format( movement_type, timezone.now()) if board: chart_title += u" for board {0}".format(board.name) member_chart = pygal.HorizontalBar(title=chart_title, legend_at_bottom=True, print_values=True, print_zeroes=False, human_readable=True) card_movement_filter = {"type": movement_type} if board: card_movement_filter["board_id"] = board.id # If this user is a member, include it in the developers list at the front if user_is_member(request.user): members = [request.user.member] + list( Member.get_user_team_mates(request.user)) else: members = Member.get_user_team_mates(request.user) for member_i in members: member_name = member_i.external_username num_card_movements = member_i.card_movements.filter( **card_movement_filter).count() if num_card_movements > 0: member_chart.add(u"{0}".format(member_name), num_card_movements) chart = CachedChart.make(board=board, uuid=chart_uuid, svg=member_chart.render(is_unicode=True)) return chart.render_django_response()
def noise_level_per_weekday(current_user): # Caching chart_uuid = "noise_measurements.noise_level_per_weekday-{0}".format( current_user.id) chart = CachedChart.get(board=None, uuid=chart_uuid) if chart: return chart chart_title = u"Noise levels per weekday in db as of {0}".format( timezone.now()) noise_measurement_filter = { "member__in": Member.get_user_team_members(current_user) } noise_measurements = NoiseMeasurement.objects.filter( **noise_measurement_filter).order_by("datetime") noise_chart = pygal.Line(title=chart_title, legend_at_bottom=True, print_values=True, print_zeroes=False, x_label_rotation=0, human_readable=True) noise_values = {"avg": [], "min": [], "max": []} weekday_dict = { 1: "Sunday", 2: "Monday", 3: "Tuesday", 4: "Wednesday", 5: "Thursday", 6: "Friday", 7: "Saturday" } weekdays = [] weekday_i = 1 while weekday_i < 7: noise_level_in_hour_i = noise_measurements. \ filter(datetime__week_day=weekday_i). \ aggregate(avg=Avg("noise_level"), max=Max("noise_level"), min=Min("noise_level")) if noise_level_in_hour_i["avg"] is not None: noise_values["avg"].append(noise_level_in_hour_i["avg"]) noise_values["min"].append(noise_level_in_hour_i["min"]) noise_values["max"].append(noise_level_in_hour_i["max"]) weekdays.append(weekday_dict[weekday_i]) weekday_i += 1 noise_chart.add("Avg noise level", noise_values["avg"]) noise_chart.add("Min noise level", noise_values["min"]) noise_chart.add("Max noise level", noise_values["max"]) noise_chart.x_labels = weekdays chart = CachedChart.make(board=None, uuid=chart_uuid, svg=noise_chart.render(is_unicode=True)) return chart.render_django_response()
def get_all_from_member(member): user = member.user boards = get_user_boards(user) teammates = Member.get_user_team_members(user) forecasters = Forecaster.objects.filter( Q(last_updater=member) | Q(board__in=boards) | Q(member__in=list(teammates) + [member])) return forecasters
def noise_level(current_user): # Caching chart_uuid = "noise_measurements.noise_level-{0}".format(current_user.id) chart = CachedChart.get(board=None, uuid=chart_uuid) if chart: return chart chart_title = u"Average noise levels per day in db as of {0}".format( timezone.now()) noise_measurement_filter = { "member__in": Member.get_user_team_members(current_user) } noise_measurements = NoiseMeasurement.objects.filter( **noise_measurement_filter).order_by("datetime") noise_chart = pygal.Line(title=chart_title, legend_at_bottom=True, print_values=True, print_zeroes=False, x_label_rotation=65, human_readable=True) start_datetime = noise_measurements.aggregate( min_date=Min("datetime"))["min_date"] end_datetime = noise_measurements.aggregate( max_date=Max("datetime"))["max_date"] if start_datetime is None or end_datetime is None: return noise_chart.render_django_response() end_date = end_datetime.date() noise_values = [] days = [] date_i = copy.deepcopy(start_datetime).date() while date_i <= end_date: date_noise_measurements = noise_measurements.filter( datetime__date=date_i) if date_noise_measurements.exists(): noise_values.append( numpy.mean([ noise_measurement.noise_level for noise_measurement in date_noise_measurements ])) days.append(date_i.strftime("%Y-%m-%d")) date_i += timedelta(days=1) noise_chart.add("Average noise level by day", noise_values) noise_chart.x_labels = days chart = CachedChart.make(board=None, uuid=chart_uuid, svg=noise_chart.render(is_unicode=True)) return chart.render_django_response()
def noise_level_per_hour(current_user): # Caching chart_uuid = "noise_measurements.noise_level_per_hour-{0}".format( current_user.id) chart = CachedChart.get(board=None, uuid=chart_uuid) if chart: return chart chart_title = u"Noise levels per hour in db as of {0}".format( timezone.now()) noise_measurement_filter = { "member__in": Member.get_user_team_members(current_user) } noise_measurements = NoiseMeasurement.objects.filter( **noise_measurement_filter).order_by("datetime") noise_chart = pygal.Line(title=chart_title, legend_at_bottom=True, print_values=True, print_zeroes=False, x_label_rotation=0, human_readable=True) noise_values = {"avg": [], "min": [], "max": []} hours = [] hour_i = 0 while hour_i < 24: noise_level_in_hour_i = noise_measurements.\ filter(datetime__hour=hour_i).\ aggregate(avg=Avg("noise_level"), max=Max("noise_level"), min=Min("noise_level")) if noise_level_in_hour_i["avg"] is not None: noise_values["avg"].append(noise_level_in_hour_i["avg"]) noise_values["min"].append(noise_level_in_hour_i["min"]) noise_values["max"].append(noise_level_in_hour_i["max"]) hours.append(hour_i) hour_i += 1 noise_chart.add("Avg noise level", noise_values["avg"]) noise_chart.add("Min noise level", noise_values["min"]) noise_chart.add("Max noise level", noise_values["max"]) noise_chart.x_labels = hours chart = CachedChart.make(board=None, uuid=chart_uuid, svg=noise_chart.render(is_unicode=True)) return chart.render_django_response()
def __init__(self, *args, **kwarsg): super(FilterForecastersForm, self).__init__(*args, **kwarsg) # Regression model choices self.fields["model"].choices = REGRESSION_MODELS # Board and members current_request = CrequestMiddleware.get_request() current_user = current_request.user boards = get_user_boards(current_user) members = Member.get_user_team_members(current_user) self.fields["board"].choices = [("", "All")] + [(board.id, board.name) for board in boards] self.fields["member"].choices = [("", "None")] + [ (member.id, member.external_username) for member in members ]
def new(request): user = request.user current_member = user.member member = Member(creator=current_member, is_public=False) if request.method == "POST": form = NewMemberForm(request.POST, instance=member) if form.is_valid(): with transaction.atomic(): form.save(commit=True) member_password = form.cleaned_data.get("password") send_new_member_email(member, member_password) return HttpResponseRedirect(reverse("members:view_members")) else: form = NewMemberForm(instance=member) replacements = {"member": member, "form": form} return render(request, "members/new.html", replacements)
def subjective_noise_level(current_user, month=None, year=None): # Caching chart_uuid = "noise_measurements.subjective_noise_level-{0}-{1}-{2}".format( current_user.id, month if month else "None", year if year else "None") chart = CachedChart.get(board=None, uuid=chart_uuid) if chart: return chart chart_title = u"Subjective noise levels as of {0}".format(timezone.now()) noise_measurement_filter = { "member__in": Member.get_user_team_members(current_user) } noise_measurements = NoiseMeasurement.objects.filter( **noise_measurement_filter).order_by("datetime") if month and year and 1 <= month <= 12: noise_measurements = noise_measurements.filter(datetime__month=month, datetime__year=year) noise_chart = pygal.Bar(title=chart_title, legend_at_bottom=True, print_values=True, print_zeroes=False, human_readable=True, x_label_rotation=45) subjective_noise_levels = dict(NoiseMeasurement.SUBJECTIVE_NOISE_LEVELS) for level_key, level_name in subjective_noise_levels.items(): noise_chart.add( u"{0}".format(level_name), noise_measurements.filter( subjective_noise_level=level_key).count()) chart = CachedChart.make(board=None, uuid=chart_uuid, svg=noise_chart.render(is_unicode=True)) return chart.render_django_response()
def save(self, commit=False): member = Member() user = User( first_name=self.cleaned_data.get("first_name"), last_name=self.cleaned_data.get("last_name"), username=self.cleaned_data.get("username"), email=self.cleaned_data.get("email"), ) user.set_password(self.cleaned_data["password1"]) if commit: user.save() member.user = user member.max_number_of_boards = Member.DEFAULT_MAX_NUMBER_OF_BOARDS member.save() return member
def _number_of_interruptions(current_user, board, chart_title, interruption_measurement, incremental=False): # Caching chart_uuid = "interruptions.{0}".format( hashlib.sha256("_number_of_interruptions-{0}-{1}-{2}-{3}-{4}".format( current_user.id, board.id if board else "user-{0}".format(current_user.id), inspect.getsource(interruption_measurement), "incremental" if incremental else "absolute", chart_title)).hexdigest()) chart = CachedChart.get(board=board, uuid=chart_uuid) if chart: return chart if board: chart_title += u" for board {0} as of {1}".format( board.name, board.get_human_fetch_datetime()) interruptions_chart = pygal.Line(title=chart_title, legend_at_bottom=True, print_values=True, print_zeroes=False, x_label_rotation=65, human_readable=True) if incremental: datetime_filter = "datetime__date__lte" interruptions_chart.print_values = False else: datetime_filter = "datetime__date" interruptions_filter = {} if board: interruptions_filter["board"] = board boards = [board] else: boards = get_user_boards(current_user) interruptions_filter["member__in"] = Member.get_user_team_members( current_user) board_values = {board.id: [] for board in boards} interruptions = Interruption.objects.filter( **interruptions_filter).order_by("datetime") if not interruptions.exists(): return interruptions_chart.render_django_response() min_datetime = interruptions.aggregate( min_datetime=Min("datetime"))["min_datetime"] max_datetime = interruptions.aggregate( max_datetime=Max("datetime"))["max_datetime"] date_i = copy.deepcopy(min_datetime.date()) max_date = max_datetime.date() + timedelta(days=2) days = [] num_interruptions = [] while date_i <= max_date: interruptions_filter = {datetime_filter: date_i} interruptions_on_date = interruptions.filter(**interruptions_filter) interruptions_on_date_value = interruption_measurement( interruptions_on_date) # Add only values when there is some interruption in any project if interruptions_on_date_value > 0: days.append(date_i.strftime("%Y-%m-%d")) num_interruptions.append(interruptions_on_date_value) if board is None: for board_i in boards: board_i_interruptions_value = interruption_measurement( interruptions_on_date.filter(board=board_i)) board_values[board_i.id].append( board_i_interruptions_value) date_i += timedelta(days=1) interruptions_chart.add(u"All interruptions", num_interruptions) for board_i in boards: if sum(board_values[board_i.id]) > 0: interruptions_chart.add(board_i.name, board_values[board_i.id]) interruptions_chart.x_labels = days chart = CachedChart.make(board=None, uuid=chart_uuid, svg=interruptions_chart.render(is_unicode=True)) return chart.render_django_response()
def _interruption_measurement_by_month(current_user, chart_title, interruption_measurement, board=None): chart_uuid = "interruptions.{0}".format( hashlib.sha256("_interruption_measurement_by_month-{0}-{1}-{2}".format( current_user.id, inspect.getsource(interruption_measurement), board.id if board else "username-{0}".format(current_user.id))).hexdigest()) chart = CachedChart.get(board=board, uuid=chart_uuid) if chart: return chart if board: chart_title += u" for board {0} as of {1}".format( board.name, board.get_human_fetch_datetime()) interruptions_filter = {} if board: interruptions_filter["board"] = board else: interruptions_filter["member__in"] = Member.get_user_team_members( current_user) interruptions = Interruption.objects.filter( **interruptions_filter).order_by("datetime") interruptions_chart = pygal.Line(title=chart_title, legend_at_bottom=True, print_values=True, print_zeroes=False, human_readable=True) min_datetime = interruptions.aggregate( min_datetime=Min("datetime"))["min_datetime"] max_datetime = interruptions.aggregate( max_datetime=Min("datetime"))["max_datetime"] if min_datetime is None or max_datetime is None: return interruptions_chart.render_django_response() datetime_i = copy.deepcopy(min_datetime) date_i = datetime_i.date() month_i = date_i.month year_i = date_i.year last_month = max_datetime.month last_year = max_datetime.year if board is None: boards = get_user_boards(current_user) else: boards = [board] months = [] values = [] board_values = {board.id: [] for board in boards} has_board_values = {board.id: False for board in boards} while year_i < last_year or year_i == last_year and month_i <= last_month: monthly_interruptions = interruptions.filter(datetime__month=month_i, datetime__year=year_i) monthly_measurement = interruption_measurement(monthly_interruptions) # For each month that have some data, add it to the chart if monthly_measurement > 0: months.append(u"{0}-{1}".format(year_i, month_i)) values.append(monthly_measurement) for board in boards: monthly_interruption_measurement = interruption_measurement( monthly_interruptions.filter(board=board)) board_values[board.id].append(monthly_interruption_measurement) if monthly_interruption_measurement > 0: has_board_values[board.id] = True month_i += 1 if month_i > 12: month_i = 1 year_i += 1 interruptions_chart.x_labels = months interruptions_chart.add(u"All interruptions", values) for board in boards: if has_board_values[board.id]: interruptions_chart.add(board.name, board_values[board.id]) chart = CachedChart.make(board=None, uuid=chart_uuid, svg=interruptions_chart.render(is_unicode=True)) return chart.render_django_response()
def index(request): member = None boards = [] member_multiboards = [] team_mates = [] current_user = request.user if user_is_member(current_user): member = current_user.member member_multiboards = member.multiboards. \ filter(show_in_index=True, is_archived=False). \ order_by("order", "name") lists = [] if current_user.is_authenticated(): team_mates = Member.get_user_team_mates(request.user) boards = get_user_boards(current_user).filter( is_archived=False).order_by("name") now = timezone.now() today = now.date() week_of_year = get_week_of_year(today) weeks_of_year = get_weeks_of_year_since_one_year_ago() replacements = { "any_card_has_value": Card.objects.filter(board__in=boards, value__isnull=False).exists(), "has_noise_measurements": NoiseMeasurement.objects.filter( Q(member__in=team_mates) | Q(member=member)).exists(), "weeks_of_year": weeks_of_year, "lists": lists, "boards": boards, "week_of_year": week_of_year, "member": member, "multiboards": member_multiboards, "developers": [member] + (list(member.team_mates.filter( is_developer=True)) if member else list(team_mates)), "downtime_developers": ([ dev for dev in member.team_members.filter(is_developer=True) if dev.is_in_downtime ]) if member else [], "pending_red_cards": Card.objects.filter(board__in=boards, list__type="ready_to_develop", is_closed=False, labels__color="red").order_by( "board__name", "name"), "pending_orange_cards": Card.objects.filter(board__in=boards, list__type="ready_to_develop", is_closed=False, labels__color="orange").order_by( "board__name", "name"), "pending_yellow_cards": Card.objects.filter(board__in=boards, list__type="ready_to_develop", is_closed=False, labels__color="yellow").order_by( "board__name", "name") } return render(request, "index/index.html", replacements)
def _create_comments(card): card_comments = [] # {u'type': u'commentCard', u'idMemberCreator': u'56e2ac8e14e4eda06ac6b8fd', # u'memberCreator': {u'username': u'diegoj5', u'fullName': u'Diego J.', u'initials': u'DJ', # u'id': u'56e2ac8e14e4eda06ac6b8fd', u'avatarHash': u'a3086f12908905354b15972cd67b64f8'}, # u'date': u'2016-04-20T23:06:38.279Z', # u'data': {u'text': u'Un comentario', u'list': {u'name': u'En desarrollo', u'id': u'5717fb3fde6bdaed40201667'}, # u'board': {u'id': u'5717fb368199521a139712f0', u'name': u'Test', u'shortLink': u'2CGPEnM2'}, # u'card': {u'idShort': 6, u'id': u'57180ae1ed24b1cff7f8da7c', u'name': u'Por todas', # u'shortLink': u'bnK3c1jF'}}, u'id': u'57180b7e25abc60313461aaf'} member_dict = {} local_timezone = pytz.timezone(settings.TIME_ZONE) card_deleted_comments = { comment.uuid: comment for comment in card.comments.all() } # Create each one of the comments for comment in card.trello_card.comments: # Author of the comment loaded using memoization trello_member_id = comment["idMemberCreator"] if trello_member_id not in member_dict: try: member_dict[trello_member_id] = Member.objects.get( trello_member_profile__trello_id=comment[ "idMemberCreator"]) # If the member doesn't exist, create it except Member.DoesNotExist as e: deleted_member = Member() deleted_member.save() try: trello_member_profile = TrelloMemberProfile.objects.get( trello_id=comment["idMemberCreator"], username=comment["memberCreator"]["username"], initials=comment["memberCreator"]["initials"]) except TrelloMemberProfile.DoesNotExist: trello_member_profile = TrelloMemberProfile( member=deleted_member, trello_id=comment["idMemberCreator"], username=comment["memberCreator"]["username"], initials=comment["memberCreator"]["initials"]) trello_member_profile.member = deleted_member trello_member_profile.save() member_dict[trello_member_id] = deleted_member author = member_dict[trello_member_id] # Comment uuid uuid = comment["id"] # Comment content content = comment["data"]["text"] # Comment creation datetime comment_naive_creation_datetime = datetime.strptime( comment["date"], '%Y-%m-%dT%H:%M:%S.%fZ') comment_creation_datetime = local_timezone.localize( comment_naive_creation_datetime) # Creation of the card comment try: card_comment = card.comments.get(uuid=uuid) card_comment.content = content card_comment.blocking_card = None del card_deleted_comments[uuid] except CardComment.DoesNotExist: card_comment = CardComment( uuid=uuid, card=card, board=card.board, author=author, creation_datetime=comment_creation_datetime, content=content) #print "{0} {1} {2}".format(card.name, card_comment.content, card_comment.creation_datetime) # Check if comment has a blocking card blocking_card = card_comment.blocking_card_from_content if blocking_card: card_comment.blocking_card = blocking_card card_comment.save() # Create card comment list card_comments.append(card_comment) # Delete all card comments that are not present in trello.com for comment_uuid, comment in card_deleted_comments.items(): comment.delete() for trello_member_id, member in member_dict.items(): if not card.members.filter( trello_member_profile__trello_id=trello_member_id).exists( ): card.members.add(member) return card_comments