def view_all_chunks(request, viewtype, submission_id): user = request.user submission = Submission.objects.get(id = submission_id) semester = Semester.objects.get(assignments__milestones__submitmilestone__submissions=submission) authors = User.objects.filter(submissions=submission) # block a user who's crawling if user.username=="dekehu": raise Http404 try: user_membership = Member.objects.get(user=user, semester=semester) # you get a 404 page ifchrome # # you weren't a teacher during the semester # # and # # you aren't django staff # # and # # you aren't an author of the submission if not user_membership.is_teacher() and not user.is_staff and not (user in authors): raise PermissionDenied except Member.MultipleObjectsReturned: raise Http404 # you can't be multiple members for a class so this should never get called except Member.DoesNotExist: if not user.is_staff: raise PermissionDenied # you get a 401 page if you aren't a member of the semester files = File.objects.filter(submission=submission_id).select_related('chunks') if not files: raise Http404 milestone = files[0].submission.milestone milestone_name = milestone.full_name() paths = [] user_stats = [] static_stats = [] all_highlighted_lines = [] for afile in files: paths.append(afile.path) common_prefix = "" if len(paths) > 1: common_prefix = os.path.commonprefix(paths) #get a list of only the relative paths paths = [] for afile in files: paths.append(os.path.relpath(afile.path, common_prefix)) formatter = HtmlFormatter(cssclass='syntax', nowrap=True) for afile in files: staff_lines = StaffMarker.objects.filter(chunk__file=afile).order_by('start_line', 'end_line') lexer = get_lexer_for_filename(afile.path) #prepare the file - get the lines that are part of chunk and the ones that aren't highlighted_lines_for_file = [] numbers, lines = zip(*afile.lines) highlighted = zip(numbers, highlight(afile.data, lexer, formatter).splitlines()) highlighted_lines = [] staff_line_index = 0 for number, line in highlighted: if staff_line_index < len(staff_lines) and number >= staff_lines[staff_line_index].start_line and number <= staff_lines[staff_line_index].end_line: while staff_line_index < len(staff_lines) and number == staff_lines[staff_line_index].end_line: staff_line_index += 1 highlighted_lines.append((number, line, True)) else: highlighted_lines.append((number, line, False)) chunks = afile.chunks.order_by('start') total_lines = len(afile.lines) offset = numbers[0] start = offset end = offset user_comments = 0 static_comments = 0 for chunk in chunks: if len(chunk.lines)==0: continue numbers, lines = zip(*chunk.lines) chunk_start = numbers[0] chunk_end = chunk_start + len(numbers) if end != chunk_start and chunk_start > end: #some lines between chunks #non chunk part start = end end = chunk_start #True means it's a chunk, False it's not a chunk highlighted_lines_for_file.append((highlighted_lines[start-offset:end - offset], False, None, None)) if end == chunk_start: #get comments and count them def get_comment_data(comment): snippet = chunk.generate_snippet(comment.start, comment.end) return (comment, snippet) comments = chunk.comments.select_related('chunk', 'author__profile') comment_data = map(get_comment_data, comments) user_comments += comments.filter(type='U').count() static_comments += comments.filter(type='S').count() #now for the chunk part start = chunk_start end = chunk_end #True means it's a chunk, False it's not a chunk highlighted_lines_for_file.append((highlighted_lines[start-offset:end-offset], True, chunk, comment_data)) #see if there is anything else to grab highlighted_lines_for_file.append((highlighted_lines[end-offset:], False, None, None)) user_stats.append(user_comments) static_stats.append(static_comments) all_highlighted_lines.append(highlighted_lines_for_file) file_data = zip(paths, all_highlighted_lines, files) code_only = False comment_view = True if viewtype == "code": code_only = True comment_view = False path_and_stats = zip(paths, user_stats, static_stats) return render(request, 'chunks/view_all_chunks.html', { 'milestone_name': milestone_name, 'path_and_stats': path_and_stats, 'file_data': file_data, 'code_only': code_only, 'read_only': False, 'comment_view': comment_view, 'full_view': True, 'articles': [x for x in Article.objects.all() if not x == Article.get_root()], })
def view_chunk(request, chunk_id): user = request.user chunk = get_object_or_404(Chunk, pk=chunk_id) semester = chunk.file.submission.milestone.assignment.semester is_reviewer = Task.objects.filter(chunk=chunk, reviewer=user).exists() # you get a 404 page if # # you weren't a teacher during the semester # # and # # you didn't write the code # # and # # you weren't assigned to review the code # # and # # you aren't a django admin # # and # # this isn't a personal code upload chunk try: if not semester.semester == "Lifetime" and not semester.subject.name == "Life": #give permission if personal code upload user_membership = Member.objects.get(user=user, semester=semester) if not user_membership.is_teacher() and not chunk.file.submission.has_author(user) and not is_reviewer and not user.is_staff: raise PermissionDenied except Member.MultipleObjectsReturned: raise Http404 # you can't be multiple members for a class so this should never get called except Member.DoesNotExist: if not user.is_staff: raise PermissionDenied # you get a 401 page if you aren't a member of the semester user_votes = dict((vote.comment_id, vote.value) \ for vote in user.votes.filter(comment__chunk=chunk_id)) staff_lines = StaffMarker.objects.filter(chunk=chunk).order_by('start_line', 'end_line') def get_comment_data(comment): vote = user_votes.get(comment.id, None) snippet = chunk.generate_snippet(comment.start, comment.end) return (comment, vote, snippet) comment_data = map(get_comment_data, chunk.comments.select_related('author__profile')) lexer = get_lexer_for_filename(chunk.file.path) formatter = HtmlFormatter(cssclass='syntax', nowrap=True) numbers, lines = zip(*chunk.lines) # highlight the code this way to correctly identify multi-line constructs # TODO implement a custom formatter to do this instead highlighted = zip(numbers, highlight(chunk.data, lexer, formatter).splitlines()) highlighted_lines = [] staff_line_index = 0 for number, line in highlighted: if staff_line_index < len(staff_lines) and number >= staff_lines[staff_line_index].start_line and number <= staff_lines[staff_line_index].end_line: while staff_line_index < len(staff_lines) and number == staff_lines[staff_line_index].end_line: staff_line_index += 1 highlighted_lines.append((number, line, True)) else: highlighted_lines.append((number, line, False)) task_count = Task.objects.filter(reviewer=user) \ .exclude(status='C').exclude(status='U').count() remaining_task_count = task_count # get the associated task if it exists try: task = Task.objects.get(chunk=chunk, reviewer=user) last_task = task_count==1 and not (task.status == 'U' or task.status == 'C') if task.status == 'N': task.mark_as('O') if not (task.status=='U' or task.status=='C'): remaining_task_count -= 1 except Task.DoesNotExist: task = None if user.is_staff: # this is super hacky and it's only here to allow admins to view chunks like a student try: task = Task.objects.filter(chunk=chunk)[0] except IndexError: # having a task = None doesn't break the view_chunk.html page. pass last_task = False return render(request, 'chunks/view_chunk.html', { 'chunk': chunk, 'similar_chunks': chunk.get_similar_chunks(), 'highlighted_lines': highlighted_lines, 'comment_data': comment_data, 'task': task, 'task_count': task_count, 'full_view': True, 'file': chunk.file, 'articles': [x for x in Article.objects.all() if not x == Article.get_root()], 'last_task': last_task, 'remaining_task_count': remaining_task_count, })
def all_activity(request, review_milestone_id, username): user = request.user try: participant = User.objects.get(username__exact=username) #get all assignments review_milestone = ReviewMilestone.objects.select_related('submit_milestone', 'assignment__semester').get(id__exact=review_milestone_id) user_membership = Member.objects.get(user=user, semester=review_milestone.assignment.semester) if not user_membership.is_teacher() and not user==participant and not user.is_staff: raise Http404 except Member.DoesNotExist: if not user.is_staff: raise Http404 #get all relevant chunks chunks = Chunk.objects \ .filter(file__submission__milestone= review_milestone.submit_milestone) \ .filter(Q(comments__author=participant) | Q(comments__votes__author=participant)) \ .select_related('comments__votes', 'comments__author_profile') chunk_set = set() review_milestone_data = [] # lexer = JavaLexer() formatter = HtmlFormatter(cssclass='syntax', nowrap=True) for chunk in chunks: if chunk in chunk_set: continue else: chunk_set.add(chunk) lexer = get_lexer_for_filename(chunk.file.path) participant_votes = dict((vote.comment.id, vote.value) \ for vote in participant.votes.filter(comment__chunk=chunk.id)) numbers, lines = zip(*chunk.lines) staff_lines = StaffMarker.objects.filter(chunk=chunk).order_by('start_line', 'end_line') highlighted = zip(numbers, highlight(chunk.data, lexer, formatter).splitlines()) highlighted_lines = [] staff_line_index = 0 for number, line in highlighted: if staff_line_index < len(staff_lines) and number >= staff_lines[staff_line_index].start_line and number <= staff_lines[staff_line_index].end_line: while staff_line_index < len(staff_lines) and number == staff_lines[staff_line_index].end_line: staff_line_index += 1 highlighted_lines.append((number, line, True)) else: highlighted_lines.append((number, line, False)) comments = chunk.comments.prefetch_related('votes', 'author__profile', 'author__membership__semester') highlighted_comments = [] highlighted_votes = [] for comment in comments: if comment.id in participant_votes: highlighted_votes.append(participant_votes[comment.id]) else: highlighted_votes.append(None) if comment.author == participant: highlighted_comments.append(comment) else: highlighted_comments.append(None) comment_data = zip(comments, highlighted_comments, highlighted_votes) review_milestone_data.append((chunk, highlighted_lines, comment_data, chunk.file)) return render(request, 'review/all_activity.html', { 'review_milestone_data': review_milestone_data, 'participant': participant, 'activity_view': True, 'full_view': True, 'articles': [x for x in Article.objects.all() if not x == Article.get_root()], })
def view_chunk(request, chunk_id): user = request.user chunk = get_object_or_404(Chunk, pk=chunk_id) semester = chunk.file.submission.milestone.assignment.semester is_reviewer = Task.objects.filter(chunk=chunk, reviewer=user).exists() # you get a 404 page if # # you weren't a teacher during the semester # # and # # you didn't write the code # # and # # you weren't assigned to review the code # # and # # you aren't a django admin try: user_membership = Member.objects.get(user=user, semester=semester) if not user_membership.is_teacher( ) and not chunk.file.submission.has_author( user) and not is_reviewer and not user.is_staff: raise PermissionDenied except Member.MultipleObjectsReturned: raise Http404 # you can't be multiple members for a class so this should never get called except Member.DoesNotExist: if not user.is_staff: raise PermissionDenied # you get a 401 page if you aren't a member of the semester user_votes = dict((vote.comment_id, vote.value) \ for vote in user.votes.filter(comment__chunk=chunk_id)) staff_lines = StaffMarker.objects.filter(chunk=chunk).order_by( 'start_line', 'end_line') def get_comment_data(comment): vote = user_votes.get(comment.id, None) snippet = chunk.generate_snippet(comment.start, comment.end) return (comment, vote, snippet) comment_data = map( get_comment_data, chunk.comments.prefetch_related('author__profile', 'author__membership__semester')) lexer = get_lexer_for_filename(chunk.file.path) formatter = HtmlFormatter(cssclass='syntax', nowrap=True) highlighted_lines = highlight_chunk_lines(lexer, formatter, staff_lines, chunk) task_count = Task.objects.filter(reviewer=user) \ .exclude(status='C').exclude(status='U').count() remaining_task_count = task_count # get the associated task if it exists try: task = Task.objects.get(chunk=chunk, reviewer=user) last_task = task_count == 1 and not (task.status == 'U' or task.status == 'C') if task.status == 'N': task.mark_as('O') if not (task.status == 'U' or task.status == 'C'): remaining_task_count -= 1 except Task.DoesNotExist: task = None if user.is_staff: # this is super hacky and it's only here to allow admins to view chunks like a student task = Task.objects.filter(chunk=chunk)[0] last_task = False context = { 'chunk': chunk, 'similar_chunks': chunk.get_similar_chunks(), 'highlighted_lines': highlighted_lines, 'comment_data': comment_data, 'task': task, 'task_count': task_count, 'full_view': True, 'file': chunk.file, 'articles': [x for x in Article.objects.all() if not x == Article.get_root()], 'last_task': last_task, 'remaining_task_count': remaining_task_count, } return render(request, 'chunks/view_chunk.html', context)
def view_all_chunks(request, viewtype, submission_id): user = request.user submission = Submission.objects.get(id=submission_id) semester = Semester.objects.get( assignments__milestones__submitmilestone__submissions=submission) authors = User.objects.filter(submissions=submission) is_reviewer = Task.objects.filter(submission=submission, reviewer=user).exists() try: user_membership = Member.objects.get(user=user, semester=semester) # you get a 404 page ifchrome # # you weren't a teacher during the semester # # and # # you aren't django staff # # and # # you aren't an author of the submission if not user_membership.is_teacher() and not user.is_staff and not ( user in authors) and not is_reviewer: raise PermissionDenied except Member.MultipleObjectsReturned: raise Http404 # you can't be multiple members for a class so this should never get called except Member.DoesNotExist: if not user.is_staff: raise PermissionDenied # you get a 401 page if you aren't a member of the semester files = File.objects.filter( submission=submission_id).select_related('chunks') if not files: raise Http404 milestone = files[0].submission.milestone milestone_name = milestone.full_name() paths = [] user_stats = [] static_stats = [] all_highlighted_lines = [] for afile in files: paths.append(afile.path) common_prefix = "" if len(paths) > 1: common_prefix = os.path.commonprefix(paths) #get a list of only the relative paths paths = [] for afile in files: paths.append(os.path.relpath(afile.path, common_prefix)) formatter = HtmlFormatter(cssclass='syntax', nowrap=True) for afile in files: staff_lines = StaffMarker.objects.filter(chunk__file=afile).order_by( 'start_line', 'end_line') lexer = get_lexer_for_filename(afile.path) #prepare the file - get the lines that are part of chunk and the ones that aren't highlighted_lines_for_file = [] numbers, lines = zip(*afile.lines) highlighted = zip(numbers, highlight(afile.data, lexer, formatter).splitlines()) highlighted_lines = [] staff_line_index = 0 for number, line in highlighted: if staff_line_index < len(staff_lines) and number >= staff_lines[ staff_line_index].start_line and number <= staff_lines[ staff_line_index].end_line: while staff_line_index < len( staff_lines ) and number == staff_lines[staff_line_index].end_line: staff_line_index += 1 highlighted_lines.append((number, line, True)) else: highlighted_lines.append((number, line, False)) chunks = afile.chunks.order_by('start') total_lines = len(afile.lines) offset = numbers[0] start = offset end = offset user_comments = 0 static_comments = 0 for chunk in chunks: if len(chunk.lines) == 0: continue numbers, lines = zip(*chunk.lines) chunk_start = numbers[0] chunk_end = chunk_start + len(numbers) if end != chunk_start and chunk_start > end: #some lines between chunks #non chunk part start = end end = chunk_start #True means it's a chunk, False it's not a chunk highlighted_lines_for_file.append( (highlighted_lines[start - offset:end - offset], False, None, None)) if end == chunk_start: #get comments and count them def get_comment_data(comment): snippet = chunk.generate_snippet(comment.start, comment.end) return (comment, snippet) comments = chunk.comments.prefetch_related( 'chunk', 'author__profile', 'author__membership__semester') comment_data = map(get_comment_data, comments) user_comments += comments.filter(type='U').count() static_comments += comments.filter(type='S').count() #now for the chunk part start = chunk_start end = chunk_end #True means it's a chunk, False it's not a chunk highlighted_lines_for_file.append( (highlighted_lines[start - offset:end - offset], True, chunk, comment_data)) #see if there is anything else to grab highlighted_lines_for_file.append( (highlighted_lines[end - offset:], False, None, None)) user_stats.append(user_comments) static_stats.append(static_comments) all_highlighted_lines.append(highlighted_lines_for_file) file_data = zip(paths, all_highlighted_lines, files) code_only = False comment_view = True if viewtype == "code": code_only = True comment_view = False path_and_stats = zip(paths, user_stats, static_stats) return render( request, 'chunks/view_all_chunks.html', { 'milestone_name': milestone_name, 'path_and_stats': path_and_stats, 'file_data': file_data, 'code_only': code_only, 'read_only': False, 'comment_view': comment_view, 'full_view': True, 'articles': [x for x in Article.objects.all() if not x == Article.get_root()], })
def view_chunk(request, chunk_id): user = request.user chunk = get_object_or_404(Chunk, pk=chunk_id) semester = chunk.file.submission.milestone.assignment.semester is_reviewer = Task.objects.filter(chunk=chunk, reviewer=user).exists() # you get a 404 page if # # you weren't a teacher during the semester # # and # # you didn't write the code # # and # # you weren't assigned to review the code # # and # # you aren't a django admin try: user_membership = Member.objects.get(user=user, semester=semester) if not user_membership.is_teacher() and not chunk.file.submission.has_author(user) and not is_reviewer and not user.is_staff: raise PermissionDenied except Member.MultipleObjectsReturned: raise Http404 # you can't be multiple members for a class so this should never get called except Member.DoesNotExist: if not user.is_staff: raise PermissionDenied # you get a 401 page if you aren't a member of the semester user_votes = dict((vote.comment_id, vote.value) \ for vote in user.votes.filter(comment__chunk=chunk_id)) staff_lines = StaffMarker.objects.filter(chunk=chunk).order_by('start_line', 'end_line') def get_comment_data(comment): vote = user_votes.get(comment.id, None) snippet = chunk.generate_snippet(comment.start, comment.end) return (comment, vote, snippet) comment_data = map(get_comment_data, chunk.comments.prefetch_related('author__profile', 'author__membership__semester')) lexer = get_lexer_for_filename(chunk.file.path) formatter = HtmlFormatter(cssclass='syntax', nowrap=True) highlighted_lines = highlight_chunk_lines(lexer, formatter, staff_lines, chunk) task_count = Task.objects.filter(reviewer=user) \ .exclude(status='C').exclude(status='U').count() remaining_task_count = task_count # get the associated task if it exists try: task = Task.objects.get(chunk=chunk, reviewer=user) last_task = task_count==1 and not (task.status == 'U' or task.status == 'C') if task.status == 'N': task.mark_as('O') if not (task.status=='U' or task.status=='C'): remaining_task_count -= 1 except Task.DoesNotExist: task = None if user.is_staff: # this is super hacky and it's only here to allow admins to view chunks like a student task = Task.objects.filter(chunk=chunk)[0] last_task = False context = { 'chunk': chunk, 'similar_chunks': chunk.get_similar_chunks(), 'highlighted_lines': highlighted_lines, 'comment_data': comment_data, 'task': task, 'task_count': task_count, 'full_view': True, 'file': chunk.file, 'articles': [x for x in Article.objects.all() if not x == Article.get_root()], 'last_task': last_task, 'remaining_task_count': remaining_task_count, } return render(request, 'chunks/view_chunk.html', context)