forked from coala/community
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gci/: Redesign the GCI Students web-page
The redesigned web-page displays the data in a better UI/UX form with some additional information to make it more interactive and attractive. Closes coala#257
- Loading branch information
Showing
7 changed files
with
251 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,91 @@ | ||
from django.http import HttpResponse | ||
from datetime import datetime | ||
from calendar import timegm | ||
|
||
import logging | ||
import requests | ||
|
||
from IGitt.GitHub.GitHubUser import GitHubToken, GitHubUser | ||
|
||
from django.views.generic import TemplateView | ||
|
||
from community.views import get_header_and_footer | ||
from community.config import get_api_key, TokenMissing | ||
from .students import get_linked_students | ||
from .gitorg import get_logo | ||
from .task import get_tasks | ||
|
||
STUDENT_URL = ( | ||
'https://codein.withgoogle.com/dashboard/task-instances/?' | ||
'sp-organization={org_id}&sp-claimed_by={student_id}' | ||
'&sp-order=-modified&sp-my_tasks=false&sp-page_size=20' | ||
) | ||
|
||
|
||
def index(request): | ||
logger = logging.getLogger(__name__ + '.index') | ||
try: | ||
get_tasks() | ||
except FileNotFoundError: | ||
logger.info('GCI data not available') | ||
s = ['GCI data not available'] | ||
else: | ||
s = gci_overview() | ||
|
||
return HttpResponse('\n'.join(s)) | ||
|
||
|
||
def gci_overview(): | ||
logger = logging.getLogger(__name__ + '.gci_overview') | ||
linked_students = list(get_linked_students()) | ||
if not linked_students: | ||
logger.info('No GCI students are linked') | ||
return ['No GCI students are linked'] | ||
|
||
org_id = linked_students[0]['organization_id'] | ||
org_name = linked_students[0]['organization_name'] | ||
s = [] | ||
s.append('<link rel="stylesheet" href="static/main.css">') | ||
|
||
favicon = get_logo(org_name, 16) | ||
with open('_site/favicon.png', 'wb') as favicon_file: | ||
favicon_file.write(favicon) | ||
|
||
org_logo = get_logo(org_name) | ||
with open('_site/org_logo.png', 'wb') as org_logo_file: | ||
org_logo_file.write(org_logo) | ||
|
||
s.append('<link rel="shortcut icon" type="image/png" ' | ||
'href="static/favicon.png"/>') | ||
s.append('<img src="static/org_logo.png" alt="'+org_name+'">') | ||
s.append('<h2>Welcome</h2>') | ||
s.append('Hello, world. You are at the {org_name} community GCI website.' | ||
.format(org_name=org_name)) | ||
s.append('Students linked to %s issues:<ul class="students">' % org_name) | ||
for student in linked_students: | ||
student_id = student['id'] | ||
username = student['username'] | ||
|
||
r = requests.get('https://api.github.com/users/{}'.format(username)) | ||
|
||
if r.status_code == 404: | ||
continue | ||
|
||
student_url = STUDENT_URL.format(org_id=org_id, | ||
student_id=student_id, | ||
) | ||
s.append('<li class="student">' | ||
'STUDENT ID: <a href="{student_url}">{student_id}</a><br />' | ||
'<div class="github-card" data-github="{username}" ' | ||
'data-width="400" data-theme="default"></div>' | ||
.format(student_url=student_url, student_id=student_id, | ||
username=username)) | ||
|
||
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') | ||
s.append('</ul><i id="time" class="timestamp" data-time="{unix}">' | ||
'Last updated: {timestamp} ' | ||
'(<span id="ago" class="timeago"></span>)</i>' | ||
.format(unix=timegm(datetime.utcnow().utctimetuple()), | ||
timestamp=timestamp)) | ||
|
||
s.append('<script src="//cdn.jsdelivr.net/gh/lepture/[email protected]' | ||
'/jsdelivr/widget.js"></script>') | ||
s.append('<script src="static/timeago.js"></script>') | ||
s.append('<script>loadTimeElements()</script>') | ||
|
||
return s | ||
try: | ||
GITHUB_API_KEY = get_api_key('GH') | ||
except TokenMissing: | ||
GITHUB_API_KEY = None | ||
|
||
|
||
class GCIStudentsList(TemplateView): | ||
template_name = 'gci_students.html' | ||
|
||
def get_all_students(self): | ||
logger = logging.getLogger(__name__ + '.gci_overview') | ||
linked_students = list(get_linked_students()) | ||
data = { | ||
'students': list(), | ||
'error': None | ||
} | ||
if not linked_students: | ||
error_message = 'No GCI students are linked' | ||
logger.info(error_message) | ||
data['error'] = error_message | ||
return data | ||
org_id = linked_students[0]['organization_id'] | ||
for student in linked_students: | ||
student_id = student['id'] | ||
username = student['username'] | ||
try: | ||
user = GitHubUser(GitHubToken(GITHUB_API_KEY), username).data | ||
except RuntimeError: | ||
logger.warning("GCI Student {} doesn't exists! Please check" | ||
' the username.'.format(username)) | ||
else: | ||
student['url'] = STUDENT_URL.format(org_id=org_id, | ||
student_id=student_id) | ||
student['name'] = user['name'] | ||
student['bio'] = user['bio'] | ||
student['public_repos'] = user['public_repos'] | ||
student['public_gists'] = user['public_gists'] | ||
student['followers'] = user['followers'] | ||
data['students'].append(student) | ||
return data | ||
|
||
def get_gci_tasks_and_students(self): | ||
logger = logging.getLogger(__name__ + '.index') | ||
gci_students = { | ||
'data': {}, | ||
'error': None | ||
} | ||
try: | ||
get_tasks() | ||
except FileNotFoundError: | ||
logger.info('GCI data not available') | ||
error_message = ('No GCI data is available. Please create a' | ||
' tasks.yaml file containing GCI tasks related' | ||
' data in it.') | ||
gci_students['error'] = error_message | ||
else: | ||
data = self.get_all_students() | ||
if data['error']: | ||
gci_students['error'] = data['error'] | ||
else: | ||
gci_students['data'] = data['students'] | ||
return gci_students | ||
|
||
def get_data_updated_time(self): | ||
return timegm(datetime.utcnow().utctimetuple()) | ||
|
||
def get_context_data(self, **kwargs): | ||
context = super().get_context_data(**kwargs) | ||
context = get_header_and_footer(context) | ||
context['gci_students'] = self.get_gci_tasks_and_students() | ||
context['updated_time'] = self.get_data_updated_time() | ||
return context |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
.data-fetch-error { | ||
padding: 20px 20px 0px 20px; | ||
} | ||
|
||
.gci-students { | ||
padding: 2% 2%; | ||
} | ||
|
||
.gci-students .student-card { | ||
box-shadow: 0px 0px 25px 2px black; | ||
background-color: #c7da99; | ||
font-size: large; | ||
border: 4px #6c9a55 solid; | ||
} | ||
|
||
|
||
.gci-students .student-image { | ||
align-items: normal; | ||
} | ||
|
||
.gci-students .student-details { | ||
width: 100%; | ||
} | ||
|
||
@media only screen and (min-width: 768px) { | ||
.gci-students .student-card { | ||
width: 45%; | ||
height: 300px; | ||
overflow-y: auto; | ||
} | ||
} | ||
|
||
.participated-year, | ||
.gci-student-id, | ||
.public-repos, | ||
.public-gists, | ||
.followers { | ||
color: #37474f; | ||
font-weight: bold; | ||
padding-right: 3px; | ||
} | ||
|
||
.web-page-details { | ||
width: 100%; | ||
} | ||
|
||
.web-page-description, | ||
.data-updated-time, | ||
.data-fetch-error { | ||
text-align: center; | ||
font-size: large; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
$(document).ready(function(){ | ||
function generateTimeString(timestamp) { | ||
var sec = ((new Date()).getTime() / 1000) - parseInt(timestamp); | ||
var min = sec / 60; | ||
var hour = min / 60; | ||
var day = hour / 24; | ||
|
||
var timeString = ''; | ||
if (day >= 1) { | ||
timeString = Math.round(day) + ' days ago'; | ||
} else if (hour >= 1) { | ||
timeString = Math.round(hour) + ' hours ago'; | ||
} else if (min >= 1) { | ||
timeString = Math.round(min) + ' minutes ago'; | ||
} else { | ||
timeString = Math.round(sec) + ' seconds ago'; | ||
} | ||
|
||
return timeString; | ||
} | ||
|
||
function updateTimeAgo(time) { | ||
time.text(" " + generateTimeString(time.attr('data-time'))); | ||
} | ||
|
||
function loadTimeElements() { | ||
updateTimeAgo($('#time')); | ||
} | ||
|
||
loadTimeElements(); | ||
}); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
{% extends 'base.html' %} | ||
{% load staticfiles %} | ||
{% block title %} | ||
Community | GCI Students | ||
{% endblock %} | ||
|
||
{% block add_css_files %} | ||
<link rel="stylesheet" href="{% static 'css/gci_students.css' %}"> | ||
{% endblock %} | ||
|
||
{% block add_js_files %} | ||
<script src="{% static 'js/timeago.js' %}"></script> | ||
{% endblock %} | ||
|
||
{% block main-content %} | ||
<div class="web-page-details apply-flex center-content"> | ||
<h3 style="padding-right: 15px">~</h3> | ||
<h3 class="page-name"> | ||
<img src="{{ org.logo_url }}" alt="{{ org.name }}"> | ||
GCI Students | ||
</h3> | ||
<h3 style="padding-left: 15px">~</h3> | ||
</div> | ||
|
||
<div class="apply-flex-center"> | ||
<p class="container web-page-description"> | ||
Hello, World! {{ org.name }} has been participating in GCI (Google Code-In) from last few years and will | ||
be participating in coming years too. Following are the GCI students who participated in GCI with {{ org.name }} | ||
organization. | ||
</p> | ||
</div> | ||
|
||
{% if gci_students.data %} | ||
<div class="gci-students apply-flex evenly-spread-content custom-green-color-font"> | ||
{% for student in gci_students.data %} | ||
<div class="student-card card horizontal"> | ||
<div class="student-image card-image apply-flex"> | ||
<img src="//github.com/{{ student.username }}.png/"> | ||
</div> | ||
<div class="student-details card-content"> | ||
<a class="user-name bold-text" href="//github.com/{{ student.username }}" target="_blank"> | ||
{% if student.display_name %} | ||
{{ student.display_name }} | ||
{% else %} | ||
{{ student.username }} | ||
{% endif %} | ||
</a><br> | ||
{% if student.bio %} | ||
<p>{{ student.bio }}</p> | ||
{% endif %}{# if student.bio #} | ||
<div class="inline-contents"> | ||
<p class="gci-student-id">ID:</p> | ||
<a href="{{ student.url }}" target="_blank"> {{ student.id }}</a> | ||
</div><br> | ||
<div class="inline-contents"> | ||
<p class="participated-year">Participation year: {{ student.program_year }}</p> | ||
</div><br> | ||
<div class="inline-contents"> | ||
<p class="public-repos">Repos:</p> | ||
<p> {{ student.public_repos }}</p> | ||
</div> | ||
<div class="inline-contents"> | ||
<p class="public-gists">Gists:</p> | ||
<p> {{ student.public_gists }}</p> | ||
</div> | ||
<div class="inline-contents"> | ||
<p class="followers">Followers:</p> | ||
<p> {{ student.followers }}</p> | ||
</div><br> | ||
</div> | ||
</div> | ||
{% endfor %} | ||
</div> | ||
{% else %} | ||
<div class="apply-flex center-content data-fetch-error"> | ||
<h5><b>ERROR:</b></h5> | ||
<h5>{{ gci_students.error }}</h5> | ||
</div> | ||
{% endif %}{# if gci_students.data #} | ||
|
||
<div class="apply-flex center-content data-updated-time"> | ||
<b>GCI Students data was updated:</b> | ||
<p id="time" data-time="{{ updated_time }}"></p> | ||
</div> | ||
|
||
{% endblock %} |