Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
157d2a6
no files available fix
bbearce Jul 27, 2023
aa602c2
Merge pull request #1041 from codalab/Issue_764_No_Files_Available_Yet
Didayolo Jul 27, 2023
2a32153
Do not hide back/next buttons in public competitions list
Didayolo Jul 28, 2023
cea7223
Merge pull request #1042 from codalab/fix-public-list
Didayolo Jul 28, 2023
f16340e
don't show user's email in collaborators
ihsaan-ullah Jul 30, 2023
40ff4dd
participants list protected
ihsaan-ullah Jul 30, 2023
d0bf0ef
by default show no phases
ihsaan-ullah Jul 30, 2023
bf72fdb
/api/phases/ restricted while others allowed to access phases
ihsaan-ullah Jul 30, 2023
fe1d994
extra code removed, extra print removed, comments changed
ihsaan-ullah Jul 30, 2023
8afebce
forum ui style updated
ihsaan-ullah Aug 1, 2023
ac4b0d3
do not allow in active users to login with email
ihsaan-ullah Aug 2, 2023
85d510a
bold text rendering fixed on chrome
ihsaan-ullah Aug 2, 2023
0a6d553
allow to delete an organization with members
ihsaan-ullah Aug 3, 2023
0c609a5
organizatio page: social icons added
ihsaan-ullah Aug 3, 2023
bababc6
Merge pull request #1045 from codalab/api_security_phases
Didayolo Aug 9, 2023
662ba1b
Merge pull request #1044 from codalab/api_security_competition_collab…
Didayolo Aug 9, 2023
4dae947
Merge pull request #1051 from codalab/bold
Didayolo Aug 9, 2023
fd1e795
Merge pull request #1057 from codalab/organization_delete_button
Didayolo Aug 9, 2023
82b03a4
Merge pull request #1059 from codalab/organization_social_icons
Didayolo Aug 9, 2023
209b19d
Merge pull request #1049 from codalab/user_login
Didayolo Aug 9, 2023
41fd803
Merge pull request #1048 from codalab/forum_ui_style
Didayolo Aug 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 53 additions & 8 deletions src/apps/api/views/competitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,9 +508,26 @@ def perform_update(self, serializer):


class PhaseViewSet(ModelViewSet):
queryset = Phase.objects.all()
serializer_class = PhaseSerializer

def get_queryset(self):
qs = Phase.objects.all()
return qs

def list(self, request, *args, **kwargs):
# Check if it's a direct request to /api/phases/
# i.e without a pk
direct_request = 'pk' not in kwargs or kwargs['pk'] == 'list'

if direct_request:
# return empty response in direct request
return Response([], status=status.HTTP_200_OK)

# Otherwise, allow other functions to use the list functionality as usual
queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

# TODO! Security, who can access/delete/etc this?

@action(detail=True, methods=('POST',), url_name='manually_migrate')
Expand Down Expand Up @@ -619,7 +636,6 @@ def get_leaderboard(self, request, pk):
# put detailed results in its submission
for k, v in submissions_keys.items():
response['submissions'][v]['detailed_results'] = submission_detailed_results[k]
print(f"\n{response['submissions']}\n")

for task in query['tasks']:
# This can be used to rendered variable columns on each task
Expand All @@ -643,12 +659,41 @@ class CompetitionParticipantViewSet(ModelViewSet):
search_fields = ('user__username', 'user__email',)

def get_queryset(self):
qs = super().get_queryset()
user = self.request.user
if not user.is_superuser:
qs = qs.filter(competition__in=user.competitions.all() | user.collaborations.all())
qs = qs.select_related('user').order_by('user__username')
return qs

# a boolean set to true if the request is considered valid
# i.e. it is either GET request with `competition``
# or patch request with `status`
# or post request with `message`
is_valid_request = False

if self.request.method == "PATCH":
# PATCH request is considered valid if it has `status`
if 'status' in self.request.data:
is_valid_request = True

if self.request.method == "POST":
# POST request is considered valid if it has `message`
if 'message' in self.request.data:
is_valid_request = True

if self.request.method == "GET":
# GET request is considered valid if it has `competition``
# if there is no competition then it si called from /api/participants/
# URL which is not considered valid
if 'competition' in self.request.GET:
is_valid_request = True

if is_valid_request:
# API to act normally i.e return participants
qs = super().get_queryset()
user = self.request.user
if not user.is_superuser:
qs = qs.filter(competition__in=user.competitions.all() | user.collaborations.all())
qs = qs.select_related('user').order_by('user__username')
return qs
else:
# API will work but will return empty participants list
return CompetitionParticipant.objects.none()

def update(self, request, *args, **kwargs):
if request.method == 'PATCH':
Expand Down
4 changes: 1 addition & 3 deletions src/apps/forums/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ def delete(self, request, *args, **kwargs):
self.object = self.get_object()

if self.object.thread.forum.competition.created_by == request.user or \
request.user in self.object.thread.forum.competition.admins.all() or \
self.object.posted_by == request.user:

# If there are more posts in the thread, leave it around, otherwise delete it
Expand Down Expand Up @@ -129,7 +128,6 @@ def delete(self, request, *args, **kwargs):
self.object = self.get_object()

if self.object.forum.competition.created_by == request.user or \
request.user in self.object.forum.competition.admins.all() or \
self.object.started_by == request.user:

success_url = self.object.forum.get_absolute_url()
Expand Down Expand Up @@ -161,7 +159,7 @@ def pin_thread(request, thread_pk):
except Thread.DoesNotExist:
raise Http404()

if thread.forum.competition.created_by == request.user or request.user in thread.forum.competition.admins.all():
if thread.forum.competition.created_by == request.user or thread.started_by == request.user:
# Toggle pinned date on/off
thread.pinned_date = now() if thread.pinned_date is None else None
thread.save()
Expand Down
5 changes: 4 additions & 1 deletion src/apps/profiles/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(email=username)
if user.check_password(password):
return user
if user.is_active:
return user
else:
return None
else:
return None
except ObjectDoesNotExist:
Expand Down
2 changes: 1 addition & 1 deletion src/apps/profiles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get_full_name(self):
return self.name

def __str__(self):
return f'{self.username} | {self.email}'
return self.username

@property
def slug_url(self):
Expand Down
10 changes: 0 additions & 10 deletions src/static/css/forums.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@
.forum-panel .thread_title {
border-bottom: 1px solid #CCC;
}

.pin-button, .remove-button {
opacity: 0.5;
color: darkred;
}
.pin-button, .remove-button:hover {
opacity: 1;
cursor: pointer;
}

.pinned-thread-icon {
opacity: 0.5;
color: darkred;
Expand Down
26 changes: 13 additions & 13 deletions src/static/riot/competitions/detail/_tabs.tag
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
</tr>
<!-- Conditional row if no files to show -->
<tr class="center aligned">
<td if = {competition.files}} colspan="100%">
<td if = {competition.files === undefined ||competition.files.length === 0} colspan="100%">
<em>No Files Available Yet</em>
</td>
</tr>
Expand Down Expand Up @@ -233,20 +233,20 @@
self.competition.files.push(scoring_program)
}
})
_.forEach(phase.tasks, task => {
_.forEach(task.solutions, solution => {
self.competition.files.push({
key: solution.data,
name: solution.name,
file_size: solution.size,
phase: phase.name,
task: task.name,
type: 'Solution'
})
})
})
// Need code for public_data and starting_kit at phase level
if(self.competition.participant_status === 'approved'){
_.forEach(phase.tasks, task => {
_.forEach(task.solutions, solution => {
self.competition.files.push({
key: solution.data,
name: solution.name,
file_size: solution.size,
phase: phase.name,
task: task.name,
type: 'Solution'
})
})
})
if (phase.starting_kit != null){
self.competition.files.push({
key: phase.starting_kit.key,
Expand Down
6 changes: 5 additions & 1 deletion src/static/riot/competitions/detail/participant_manager.tag
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,11 @@
self._update_status = (id, status) => {
CODALAB.api.update_participant_status(id, {status: status})
.done(() => {
toastr.success('success')
if(status === 'denied'){
toastr.success('Revoked successfully')
}else{
toastr.success('Approved successfully')
}
self.update_participants()
})
}
Expand Down
4 changes: 2 additions & 2 deletions src/static/riot/competitions/public-list.tag
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<public-list>
<h1>Public Competitions</h1>
<div class="pagination-nav" hide="{(get_array_length(competitions.results) === competitions.count) || (get_array_length(competitions.results) < 10)}">
<div class="pagination-nav" hide="{(competitions.count < 10)}">
<button show="{competitions.previous}" onclick="{handle_ajax_pages.bind(this, -1)}" class="float-left ui inline button active">Back</button>
<button hide="{competitions.previous}" disabled="disabled" class="float-left ui inline button disabled">Back</button>
{ current_page } of {Math.ceil(competitions.count/competitions.page_size)}
Expand Down Expand Up @@ -32,7 +32,7 @@
</div>
</a>
</div>
<div class="pagination-nav" hide="{(get_array_length(competitions.results) === competitions.count) || (get_array_length(competitions.results) < 10)}}">
<div class="pagination-nav" hide="{(competitions.count < 10)}">
<button show="{competitions.previous}" onclick="{handle_ajax_pages.bind(this, -1)}" class="float-left ui inline button active">Back</button>
<button hide="{competitions.previous}" disabled="disabled" class="float-left ui inline button disabled">Back</button>
{ current_page } of {Math.ceil(competitions.count/competitions.page_size)}
Expand Down
47 changes: 47 additions & 0 deletions src/static/stylus/forum.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.forum-post
background-color #fff
padding 10px
width 80%
border-radius: 5px
box-shadow 0.5px 0.5px 2px gray

.post-header
display flex
justify-content flex-start

.post-user
margin-right 10px

.post-user-img
width 50px
height 50px
border-radius 50%
border 1px solid #000

.post-user-name-date
display flex
flex-direction column
justify-content center

.poster-name
font-size 18px

.posted-date
font-size 14px
color #aba8a8
line-height 1
margin-top 5px

.post-actions
margin-left auto
cursor pointer

.post-content
margin-left 60px
margin-right 60px
padding 10px
background-color #F5F5F5
border-radius: 2px

.forum-pin-icon
color #017BFE
1 change: 1 addition & 0 deletions src/static/stylus/home.styl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ $textcolorlight = #f8f8f8
$textcolordark = #2e2e2e

body
-webkit-font-smoothing antialiased
font-family Roboto, sans-serif
background-color $backgroundlight
color $textcolordark !important
Expand Down
1 change: 1 addition & 0 deletions src/static/stylus/index.styl
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
@import "src/static/stylus/search.styl"
@import "src/static/stylus/simple_page.styl"
@import "src/static/stylus/toastr.styl"
@import "src/static/stylus/forum.styl"

2 changes: 2 additions & 0 deletions src/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Overpass+Mono&display=swap" rel="stylesheet">

<!-- Bootstrap -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">

<!-- Ours -->
<link rel="stylesheet" href="{% static "generated/output.css" %}">
Expand Down
12 changes: 2 additions & 10 deletions src/templates/forums/base_forum.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ <h1>{{ forum.competition.title }} Forum</h1>
</a>
{% elif 'new_post' not in request.path %}
<a href="{% url 'forums:forum_new_post' forum_pk=forum.pk thread_pk=thread.pk %}">
<button class="ui button primary">
Post in this thread
<button class="ui button green right floated">
<i class="icon plus"></i> Add new post
</button>
</a>
{% endif %}
Expand All @@ -47,14 +47,6 @@ <h1>{{ forum.competition.title }} Forum</h1>
{% block forum_content %}
{% endblock forum_content %}
</div>

{% if thread and 'new_post' not in request.path %}
<a href="{% url 'forums:forum_new_post' forum_pk=forum.pk thread_pk=thread.pk %}">
<button class="ui button primary">
Post in this thread
</button>
</a>
{% endif %}
</div>
</div>
</div>
Expand Down
32 changes: 29 additions & 3 deletions src/templates/forums/thread_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,36 @@
{% block forum_content %}

<div class="ui horizontal divider">{{ thread.title }}</div>
<div class="ui divided items form-content">
<div class="ui items form-content">
{% for post in ordered_posts %}
<div class="item">
<div class="content">
<div class="forum-post">
<!-- Header -->
<div class="post-header">
<div class="post-user">
{% if post.posted_by.photo %}
<img class="post-user-img" src="/static/img/user-avatar.png">
<!-- <img class="post-user-img" src="{{ post.posted_by.photo }}"> -->
{% else %}
<img class="post-user-img" src="/static/img/user-avatar.png">
{% endif %}
</div>
<div class="post-user-name-date">
<div class="poster-name">{{ post.posted_by }}</div>
<div class="posted-date">{{ post.date_created }}</div>
</div>
<div class="post-actions">
{% if thread.forum.competition.creator == request.user or post.posted_by == request.user %}
<i class="icon trash red remove-button" data-submission-pk="{{ post.pk }}"></i>
{% endif %}
</div>
</div>
<!-- Content -->
<div class="post-content">
<div class="markdown-content" data-content="{{ post.content }}"></div>
</div>
</div>
<!-- <div class="content">
{% if thread.forum.competition.creator == request.user or request.user in thread.forum.competition.admins.all or post.posted_by == request.user %}
<i class="remove-button glyphicon glyphicon-remove pull-right" data-submission-pk="{{ post.pk }}"></i>
{% endif %}
Expand All @@ -16,7 +42,7 @@
<div class="extra">
Posted by: <a href="{% url "profiles:user_profile" username=post.posted_by.slug %}">{{ post.posted_by }}</a> @ {{ post.date_created }}
</div>
</div>
</div> -->
</div>
{% endfor %}
</div>
Expand Down
Loading