Skip to content

Commit df69dda

Browse files
authored
Merge pull request #73 from tlkh/master
[WIP] Fix tests and add edit project page
2 parents 558c557 + 3409b56 commit df69dda

File tree

15 files changed

+147
-42
lines changed

15 files changed

+147
-42
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.coverage
12
gh_token
23

34
.DS_Store

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ before_install:
55
- docker pull opensutd/web-platform:latest-dev
66

77
script:
8-
- docker run --rm -e TRAVIS_JOB_ID="$TRAVIS_JOB_ID" -e TRAVIS_BRANCH="$TRAVIS_BRANCH" -e GH_ACCESS_TOKEN="$GH_ACCESS_TOKEN" -v ${PWD}:/app opensutd/web-platform:latest-dev bash -c './refresh_db.sh && coverage run --source=. manage.py test && COVERALLS_REPO_TOKEN=bggyt3TanEFVG5twpdpfhPntAJEkc8Uik coveralls'
8+
- docker run --rm -e TRAVIS_JOB_ID="$TRAVIS_JOB_ID" -e TRAVIS_BRANCH="$TRAVIS_BRANCH" -e GH_ACCESS_TOKEN="$GH_ACCESS_TOKEN" -v ${PWD}:/app opensutd/web-platform:latest-dev bash -c './refresh_db.sh && python3 manage.py collectstatic --noinput && coverage run --source=. manage.py test && COVERALLS_REPO_TOKEN=bggyt3TanEFVG5twpdpfhPntAJEkc8Uik coveralls'
99

Dockerfile

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,30 @@ RUN apt-get update && \
1919
&& apt-get clean && \
2020
rm -rf /var/lib/apt/lists/*
2121

22+
ENV SHELL=/bin/bash \
23+
NB_UID=1000 \
24+
NB_GID=100 \
25+
LC_ALL=en_US.UTF-8 \
26+
LANG=en_US.UTF-8 \
27+
LANGUAGE=en_US.UTF-8
28+
2229
WORKDIR /app
23-
COPY . /app
30+
31+
RUN groupadd wheel -g 11 && \
32+
echo "auth required pam_wheel.so use_uid" >> /etc/pam.d/su && \
33+
useradd -m -s /bin/bash -N -u 1000 opensutd && \
34+
chown opensutd:$NB_GID /app && \
35+
chmod g+w /etc/passwd
2436

2537
# install Python dependencies
2638

39+
COPY . /app
40+
2741
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
2842
python get-pip.py && \
2943
pip install --upgrade --no-cache-dir -r requirements.txt && \
3044
rm -rf get-pip.py ~/.cache
3145

46+
USER root
47+
3248
EXPOSE 8000

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ docker run --rm \
3838
--env GH_ACCESS_TOKEN=${GH_ACCESS_TOKEN} \
3939
-v ${PWD}:/app \
4040
opensutd/web-platform:${TAG} \
41-
python3 manage.py runserver 0:8000
41+
./refresh_db.sh && \
42+
python3 manage.py collectstatic --noinput && \
43+
python3 manage.py runserver 0:8000
4244
```
4345

4446
## Getting GitHub login working

projects/forms.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,18 @@ def save(self, user=None):
3737
user_profile.save()
3838
return user_profile
3939

40+
class ProjectEditForm(forms.ModelForm):
41+
class Meta:
42+
model = models.Project
43+
fields = ["title",
44+
"caption",
45+
"featured_image",
46+
"url",
47+
"poster_url"]
48+
49+
def save(self, project=None):
50+
project_edit = super(ProjectEditForm, self).save(commit=False)
51+
if project:
52+
project_edit.project = project
53+
project_edit.save()
54+
return project_edit

projects/migrations/__init__.py

100644100755
File mode changed.

projects/static/css/custom.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ body {
291291
border: 1px solid black;
292292
}
293293

294-
/*
294+
295295
.poster-thumbnail img {
296296
box-shadow: 0 0 5px 1px rgba(232, 232, 232, 1);
297297
border-radius: 4px;
@@ -310,7 +310,7 @@ body {
310310
.poster-thumbnail img:hover {
311311
box-shadow: 0 0 10px 1px rgba(189, 195, 199, 1);
312312
}
313-
*/
313+
314314

315315
/*
316316
* User Profile Page

projects/templates/opensutd/home.html

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,6 @@ <h2><i class="far fa-clock"></i> Recent Projects</h2>
8787
{% else %}
8888
<p>Error! No projects are available.</p>
8989
{% endif %}
90-
<hr>
91-
<p>Here are the working pages for test purposes:</p>
92-
<ul>
93-
<li><a href="{% url 'projects:approval' %}">Projects Page</a></li>
94-
</ul>
9590
</div>
9691

9792
</div>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{% extends 'base.html' %}
2+
{% block content %}
3+
4+
{% load static %}
5+
{% load bootstrap %}
6+
7+
<div class="container">
8+
<br>
9+
<h1>Edit Project Information</h1>
10+
11+
{% if form.subject.errors %}
12+
<ol>
13+
{% for error in form.subject.errors %}
14+
<li><strong>{{ error|escape }}</strong></li>
15+
{% endfor %}
16+
</ol>
17+
{% endif %}
18+
19+
<form method="post">
20+
21+
{% csrf_token %}
22+
{{ form|bootstrap }}
23+
<input class="btn btn-primary" type="submit" value="Submit">
24+
25+
</form>
26+
27+
</div>
28+
{% endblock %}

projects/templates/opensutd/user.html

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ <h5 class="profile-faculty text-primary">{{ current_user.pillar }} - Class of
2525
{% if user.is_authenticated %}
2626
{% if user.username == current_user.username %}
2727
<a class="btn btn-outline-primary btn-block" href="{% url 'projects:submit_new' %}" role="button"><i
28-
class="far fa-edit"></i> Submit Project</a>
29-
<a class="btn btn-outline-primary btn-block" href="{% url 'projects:user_edit' current_user.username %}" role="button"><i class="far fa-edit"></i> Edit
30-
Profile</a>
28+
class="fas fa-file-upload"></i> Submit Project</a>
29+
<a class="btn btn-outline-primary btn-block" href="{% url 'projects:user_edit' current_user.username %}"
30+
role="button"><i class="far fa-edit"></i> Edit Profile</a>
31+
<a class="btn btn-outline-primary btn-block" href="{% url 'projects:approval' %}"
32+
role="button"><i class="fas fa-user-shield"></i> Admin Panel</a>
3133
<hr>
3234
{% endif %}
3335
{% endif %}

projects/templates/projects/showcase.html

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33

44
{% load static %}
55
<div class="container">
6-
<div class="card mb-3" style="margin: 0 auto; text-align: center; padding: 1.5rem 0rem 0rem 0rem" >
6+
<div class="card mb-3" style="margin: 0 auto; text-align: center; padding: 1.5rem 0rem 0rem 0rem">
77
<div class="project-card-header row">
88
<div class="col-sm-8" style="display: flex; align-items: center">
99
<h1 style="vertical-align: middle; font-size: 2.5rem">{{ current_project.title }}</h1>
1010
</div>
11-
<div class="col-sm-4">
12-
<button type="button" class="btn btn-outline-primary project-button-header">Share</button>
13-
<button type="button" class="btn btn-outline-primary project-button-header">Upvote</button>
11+
<div class="col-sm-4" style="text-align: center !important;">
12+
{% if user.is_authenticated %}
13+
<a class="btn btn-outline-primary project-button-header btn-block"
14+
href="{% url 'projects:project_edit' current_project.project_uid %}" role="button">
15+
<i class="far fa-edit"></i> Edit Project</a>
16+
{% endif %}
17+
<a class="btn btn-outline-primary project-button-header btn-block" href="#" role="button">
18+
<i class="fas fa-share-alt-square"></i> Share Project</a>
1419
</div>
1520
</div>
1621
</div>
@@ -19,7 +24,6 @@ <h1 style="vertical-align: middle; font-size: 2.5rem">{{ current_project.title }
1924
<div class="col-sm-9" style="flex-grow: 5">
2025
<div class="card readme">
2126
<div class="readme-card-body">
22-
<!-- <h3 style="color: #232b2b">PROJECT README </h3> -->
2327
<p class="card-text text-primary readme-content">
2428
{{ readme | safe }}
2529
</p>
@@ -29,18 +33,24 @@ <h1 style="vertical-align: middle; font-size: 2.5rem">{{ current_project.title }
2933
</div>
3034
</div>
3135
<br>
32-
<!-- <div class="card poster">
36+
{% if current_project.poster_url == "" %}
37+
<!-- No Poster URL -->
38+
{% else %}
39+
<div class="card poster">
3340
<h3>Poster</h3>
34-
<div class="poster-thumbnail">
35-
<a href='{{ current_project.poster_url }}'>
36-
<img src='{{ current_project.poster_url }}' alt="Poster">
37-
</a>
38-
<br>
39-
<a href='{{ current_project.poster_url }}' class="btn btn-sm poster-enlarge">Enlarge Poster <i
40-
class="fas fa-chevron-circle-right"></i></a>
41+
<div class="project-card-sm">
42+
<img src="{{ current_project.poster_url }}">
43+
<div class="card-body">
44+
<div class="row" style="display: flex; justify-content: space-around">
45+
<a href="{{ current_project.poster_url }}" class="card-link">
46+
Enlarge Poster <i class="fas fa-chevron-circle-right"></i></a>
47+
</div>
48+
</div>
4149
</div>
4250
</div>
43-
<br> -->
51+
<br>
52+
{% endif %}
53+
<!--
4454
<div class="card">
4555
<h3>Comments</h3>
4656
<div class="form-group">
@@ -49,11 +59,12 @@ <h3>Comments</h3>
4959
<input type="submit" class="btn btn-sm btn-primary" style="margin-top: 5px; float: right">
5060
</form>
5161
</div>
52-
</div>
62+
</div>-->
5363
</div>
5464

5565
<div class="col-sm-3">
5666
<div class="project-created-by">
67+
<h5> <i class="fas fa-star"></i> {{ stars }} </h5>
5768
<h5>Created by</h5>
5869
</div>
5970
<br>
@@ -75,7 +86,8 @@ <h5>Created by</h5>
7586
<p class="text-primary" style="margin:0; margin-top: 20px">Related Tags:</p>
7687
{% for tag in current_project.tags.all %}
7788
<div class="tag">
78-
<a href="{% url 'projects:projects_list' %}?title=&category=&tags__name={{ tag }}"><span class="badge badge-pill badge-secondary project-badge-tags">{{ tag }}</span></a>
89+
<a href="{% url 'projects:projects_list' %}?title=&category=&tags__name={{ tag }}"><span
90+
class="badge badge-pill badge-secondary project-badge-tags">{{ tag }}</span></a>
7991
</div>
8092
{% endfor %}
8193
</div>

projects/tests.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,9 @@ def test_project_leaders_not_empty(self):
6969
response = self.client.get(url)
7070
self.assertGreater(len(response.content), LEN_BASE)
7171

72-
73-
VERBOSE = True
74-
75-
72+
VERBOSE = False
7673
class TraverseLinksTest(TestCase):
74+
7775
def setUp(self):
7876
# By default, login as superuser
7977
um = OpenSUTDUserManager()
@@ -107,11 +105,22 @@ def setUpTestData(cls):
107105
display_picture="https://via.placeholder.com/150",
108106
graduation_year=2021, pillar="ESD")
109107

108+
pm.create_project(project_uid="ACAD_00002",
109+
title="RandomZZZZZ",
110+
caption="Sample project 2",
111+
category="ACAD",
112+
url="https://github.com/OpenSUTD/web-platform-prototype",
113+
poster_url="https://via.placeholder.com/150",
114+
featured_image="https://via.placeholder.com/150")
115+
110116
pm.set_project_status("ACAD_00001", "ACCEPT")
111117
pm.add_user_to_project("ACAD_00001", "dick")
112118
pm.add_user_to_project("ACAD_00001", "jane")
113119
pm.add_tag_to_project("ACAD_00001", "rand1,rand2,education,student,policy")
114120

121+
pm.add_user_to_project("ACAD_00002", "jane")
122+
pm.add_tag_to_project("ACAD_00002", "rand1,rand2,education,student,policy")
123+
115124
def test_traverse_urls(self):
116125
# Fill these lists as needed with your site specific URLs to check and to avoid
117126
to_traverse_list = ["/", "/projects/", "/students/", "/educators/", "/leaders/"]
@@ -160,7 +169,7 @@ def recurse_into_path(self, to_traverse_list, to_avoid_list, done_list, error_li
160169
url = to_traverse_list.pop()
161170

162171
if not match_any(url, to_avoid_list):
163-
print("Surfing to " + str(url) +
172+
print("\nSurfing to " + str(url) +
164173
", discovered in " + str(source_of_link[url]))
165174
response = self.client.get(url, follow=True)
166175

@@ -428,10 +437,13 @@ def test_add_del_user_project(self):
428437
self.assertEqual(len(proj.users.all()), 1)
429438

430439
def test_project_page_not_approved(self):
440+
pm = OpenSUTDProjectManager()
441+
pm.set_project_status("ACAD_00001", "REJECT")
431442
url = reverse("projects:project_page", args=("ACAD_00001",))
432443
response = self.client.get(url)
433-
self.assertEqual(response.status_code, 404)
434-
#self.assertGreater(len(response.content), LEN_BASE)
444+
self.assertEqual(response.status_code, 200)
445+
self.assertEqual("Error 404: Page Not Found!" in str(response.content), True)
446+
self.assertGreater(len(response.content), LEN_BASE)
435447

436448
def test_project_page_approved(self):
437449
pm = OpenSUTDProjectManager()

projects/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
path('users/edit/<user_id>/', views.user_edit_view.as_view(), name="user_edit"),
1414
path('projects/', views.project_list_view, name="projects_list"),
1515
path('projects/<project_uid>/', views.project_view, name="project_page"),
16+
path('projects/edit/<project_uid>/', views.project_edit_view.as_view(), name="project_edit"),
1617
path('projects/bypass/<project_uid>/', views.project_view_bypass, name="project_page_bypass"),
1718
path('admin/approval', views.approval_view, name='approval'),
1819
path('admin/submit', views.submit_new_project, name='submit_new'),

projects/views.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,22 @@ def get_success_url(self, *args, **kwargs):
8181
return reverse("projects:user", kwargs={'user_id': self.kwargs["user_id"]})
8282

8383

84-
def get_readme(current_project_url):
84+
@method_decorator(login_required, name="dispatch")
85+
class project_edit_view(UpdateView):
86+
model = models.Project
87+
form_class = ProjectEditForm
88+
template_name = "opensutd/project_edit.html"
89+
90+
def get_object(self, *args, **kwargs):
91+
project = get_object_or_404(
92+
models.Project, project_uid=self.kwargs["project_uid"])
93+
return project
94+
95+
def get_success_url(self, *args, **kwargs):
96+
return reverse("projects:project_page", kwargs={'project_uid': self.kwargs["project_uid"]})
97+
98+
99+
def get_readme_and_stars(current_project_url):
85100
repo_url = current_project_url.split("/")
86101
repo_name = repo_url[-2] + "/" + repo_url[-1]
87102
repo = gh.get_repo(repo_name)
@@ -98,19 +113,22 @@ def get_readme(current_project_url):
98113
'src="', 'src="https://raw.githubusercontent.com/' + repo_name + '/master/')
99114
readme = readme.replace('<|SPECIAL_TOKEN|>', 'src="http')
100115

101-
return readme
116+
return readme, str(int(repo.stargazers_count))
102117

103118

104119
def project_view(request, project_uid):
105120
current_project = models.Project.objects.get(project_uid=project_uid)
106121
if current_project.is_accepted():
107122
try:
108-
readme = get_readme(current_project.url)
123+
readme, stars = get_readme_and_stars(current_project.url)
109124
except Exception as e:
110125
readme = "Unable to retrieve README:\n"+str(e)
126+
stars = "0"
111127

112128
context = {"current_project": current_project,
129+
"stars": stars,
113130
"readme": readme}
131+
114132
return render(request, "projects/showcase.html", context)
115133
else:
116134
raise Http404("Project is not yet approved!")
@@ -119,12 +137,15 @@ def project_view(request, project_uid):
119137
def project_view_bypass(request, project_uid):
120138
current_project = models.Project.objects.get(project_uid=project_uid)
121139
try:
122-
readme = get_readme(current_project.url)
140+
readme, stars = get_readme_and_stars(current_project.url)
123141
except Exception as e:
124142
readme = "Unable to retrieve README:\n"+str(e)
143+
stars = "0"
125144

126145
context = {"current_project": current_project,
146+
"stars": stars,
127147
"readme": readme}
148+
128149
return render(request, "projects/showcase.html", context)
129150

130151

static/css/custom.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ body {
291291
border: 1px solid black;
292292
}
293293

294-
/*
294+
295295
.poster-thumbnail img {
296296
box-shadow: 0 0 5px 1px rgba(232, 232, 232, 1);
297297
border-radius: 4px;
@@ -310,7 +310,7 @@ body {
310310
.poster-thumbnail img:hover {
311311
box-shadow: 0 0 10px 1px rgba(189, 195, 199, 1);
312312
}
313-
*/
313+
314314

315315
/*
316316
* User Profile Page

0 commit comments

Comments
 (0)