Skip to content
This repository has been archived by the owner on Jan 15, 2019. It is now read-only.

Commit

Permalink
Merge pull request #35 from ColoradoSchoolOfMines/project-page
Browse files Browse the repository at this point in the history
Project Listing Page
  • Loading branch information
samsartor authored Mar 17, 2018
2 parents 700dfb6 + 4421d7a commit 5d8bab2
Show file tree
Hide file tree
Showing 13 changed files with 255 additions and 70 deletions.
14 changes: 14 additions & 0 deletions acmwebsite/controllers/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Project controller module."""

from tg import expose

from acmwebsite.lib.base import BaseController
from acmwebsite.model import DBSession, Project


class ProjectsController(BaseController):
"""Root controller for listing all projects"""

@expose('acmwebsite.templates.projects')
def index(self):
return dict(page='projects', projects=DBSession.query(Project).all())
2 changes: 2 additions & 0 deletions acmwebsite/controllers/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from acmwebsite.controllers.meeting import MeetingsController
from acmwebsite.controllers.schedule import ScheduleController
from acmwebsite.controllers.survey import SurveysController
from acmwebsite.controllers.project import ProjectsController

from sqlalchemy.sql import functions

Expand Down Expand Up @@ -51,6 +52,7 @@ class RootController(BaseController):
schedule = ScheduleController()
error = ErrorController()
contact = ContactController()
projects = ProjectsController()

def _before(self, *args, **kw):
tmpl_context.project_name = "acmwebsite"
Expand Down
6 changes: 5 additions & 1 deletion acmwebsite/lib/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ def markdown(*args, strip_par=False, **kwargs):


def icon(icon_name):
return Markup('<i class="glyphicon glyphicon-%s"></i>' % icon_name)
return Markup('<i class="glyphicon glyphicon-{}"></i>'.format(icon_name))


def fa_icon(icon_name):
return Markup('<i class="fa fa-{}"></i>'.format(icon_name))


def fa_icon(icon_name):
Expand Down
16 changes: 15 additions & 1 deletion acmwebsite/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ def init_model(engine):
from acmwebsite.model.meeting import Meeting
from acmwebsite.model.mailmessage import MailMessage
from acmwebsite.model.survey import Survey, SurveyField, SurveyResponse, SurveyData
from acmwebsite.model.project import Project, team_table
from acmwebsite.model.banner import Banner

__all__ = ('User', 'Group', 'Permission', 'Meeting', 'MailMessage', 'Survey', 'SurveyField', 'SurveyResponse', 'SurveyData', 'Banner')
__all__ = (
'User',
'Group',
'Permission',
'Meeting',
'MailMessage',
'Survey',
'SurveyField',
'SurveyResponse',
'SurveyData',
'Banner',
'Project',
'team_table',
)
1 change: 1 addition & 0 deletions acmwebsite/model/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ class User(DeclarativeBase):
created = Column(DateTime, default=datetime.now)
officer_title = Column(Unicode(255), nullable=True)
profile_pic = Column(UploadedFileField)
projects = relation('Project', secondary='team', back_populates='team_members')

def __repr__(self):
return '<User: name=%s, display=%s>' % (
Expand Down
32 changes: 32 additions & 0 deletions acmwebsite/model/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Project model module."""

from sqlalchemy.orm import relationship
from sqlalchemy import Table, ForeignKey, Column, UniqueConstraint
from sqlalchemy.types import Integer, Unicode

from depot.fields.sqlalchemy import UploadedFileField
from depot.fields.specialized.image import UploadedImageWithThumb

from acmwebsite.model import DeclarativeBase, metadata, User

team_table = Table(
'team',
metadata,
Column('user_id', Integer(), ForeignKey('tg_user.user_id'), nullable=False),
Column('project_id', Integer(), ForeignKey('projects.id'), nullable=False),
UniqueConstraint('user_id', 'project_id'),
)


class Project(DeclarativeBase):
__tablename__ = 'projects'

# Fields
id = Column(Integer, autoincrement=True, primary_key=True)
team_members = relationship(User, secondary=team_table, back_populates='projects')
name = Column(Unicode(1024), unique=True, nullable=False)
description = Column(Unicode(4096))
website = Column(Unicode(512))
repository = Column(Unicode(512))
video_url = Column(Unicode(512))
image = Column(UploadedFileField(upload_type=UploadedImageWithThumb))
69 changes: 45 additions & 24 deletions acmwebsite/public/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,31 @@

/* Footer styling */
.footer {
margin-top: 45px;
padding: 35px 30px 36px;
border-top: 1px solid #e5e5e5;
margin-top: 45px;
padding: 35px 30px 36px;
border-top: 1px solid #e5e5e5;
}

.footer p {
margin-bottom: 0;
color: #555;
margin-bottom: 0;
color: #555;
}

/* Mailing List Stuff */
.ml-fullname-warn {
display: none;
display: none;
}

.emailtext {
padding: 0;
color: inherit;
background-color: inherit;
border: none;
border-radius: inherit;
padding: 0;
color: inherit;
background-color: inherit;
border: none;
border-radius: inherit;
}

.navbar-right {
margin-right: 0px;
margin-right: 0;
}

/* Logo */
Expand All @@ -67,40 +67,40 @@

/* Contact Page */
.acm-officer-info {
margin-bottom: 15px;
margin-bottom: 15px;
}

.acm-officer-position {
font-style: italic;
font-style: italic;
}

.acm-officer-img {
width: 100%;
border-radius: 8px;
width: 100%;
border-radius: 8px;
}

/* Homepage */
.home-banner {
margin: 35px 0 30px;
width: 100%;
margin: 35px 0 30px;
width: 100%;
}

.home-banner-img {
width: 100%;
height: auto;
border-radius: 8px;
width: 100%;
height: auto;
border-radius: 8px;
}

.homepage-panels {
margin-top: 35px;
margin-top: 35px;
}

.checkbox.single-checkbox label {
font-weight: bold;
font-weight: bold;
}

.on-first-time {
display: none;
display: none;
}

/* Survey Page */
Expand All @@ -114,6 +114,27 @@
font-weight: bold;
}

/* Project Page */
.project-list-item .project-image {
border-radius: 8px;
width: 100%;
max-width: 350px;
max-height: 350px;
margin-bottom: 10px;
}

.project-list-item .project-title,
.project-links li {
font-weight: bold;
}

/* Add a dot between every project link */
.project-links li:not(:last-child)::after {
content: '\00B7';
font-size: 20px;
margin-left: 10px;
}

/* Footer */
footer .social-links {
margin-top: 10px;
Expand Down
44 changes: 22 additions & 22 deletions acmwebsite/public/js/mailinglist.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
(function($){
var last_query = "";
$("#ml-username").on("change keyup paste", function(){
if ($("#ml-username").val().indexOf("@") >= 0) {
$("#ml-username").val($("#ml-username").val().replace(/\@.*$/g, ""));
alert("Only a Mines username is required, not a full email address.");
(function($) {
var last_query = "";
$("#ml-username").on("change keyup paste", function() {
if ($("#ml-username").val().indexOf("@") >= 0) {
$("#ml-username").val($("#ml-username").val().replace(/\@.*$/g, ""));
alert("Only a Mines username is required, not a full email address.");
}
if ($("#ml-username").val() != last_query && $("#ml-username").val().length > 1) {
last_query = $("#ml-username").val();
$.getJSON("https://mastergo.mines.edu/mpapi/uid/" + encodeURIComponent($("#ml-username").val()), function(data) {
if (data["result"] == "success") {
$("#ml-fullname").val(data["attributes"]["first"] + " " + data["attributes"]["sn"]);
$(".ml-fullname-warn").fadeIn();
}
if ($("#ml-username").val() != last_query && $("#ml-username").val().length > 1) {
last_query = $("#ml-username").val();
$.getJSON("https://mastergo.mines.edu/mpapi/uid/" + encodeURIComponent($("#ml-username").val()), function(data) {
if (data["result"] == "success") {
$("#ml-fullname").val(data["attributes"]["first"] + " " + data["attributes"]["sn"]);
$(".ml-fullname-warn").fadeIn();
}
else {
$("#ml-fullname").val("");
$(".ml-fullname-warn").fadeOut();
}
});
else {
$("#ml-fullname").val("");
$(".ml-fullname-warn").fadeOut();
}
});
});
}
});

$('#mailinglist-form').submit(function() {
$(this).find("button[type='submit']").prop('disabled',true);
});
$('#mailinglist-form').submit(function() {
$(this).find("button[type='submit']").prop('disabled',true);
});

})(jQuery);
32 changes: 16 additions & 16 deletions acmwebsite/public/js/site.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
$(document).ready(function() {
function change_theme(theme_name) {
$('#bs-css').attr('href', '/css/bootstrap.' + theme_name + '.min.css');
$('#toggle-theme').text('Too ' + theme_name + '?');
}
function change_theme(theme_name) {
$('#bs-css').attr('href', '/css/bootstrap.' + theme_name + '.min.css');
$('#toggle-theme').text('Too ' + theme_name + '?');
}

$('#toggle-theme').click(function (event) {
event.preventDefault();
$.get("/toggle_theme", change_theme, "text");
});
$('#toggle-theme').click(function (event) {
event.preventDefault();
$.get("/toggle_theme", change_theme, "text");
});

$(".vupdate").on("change keyup paste", function() {
$(this).attr("value", $(this).val());
});
$(".vupdate").on("change keyup paste", function() {
$(this).attr("value", $(this).val());
});

$('input[name="first_time"]').change(function() {
checked = this.checked;
$('.on-first-time').each(function() {
if (checked) { $(this).fadeIn() } else { $(this).fadeOut() }
});
$('input[name="first_time"]').change(function() {
checked = this.checked;
$('.on-first-time').each(function() {
if (checked) { $(this).fadeIn() } else { $(this).fadeOut() }
});
});
});
1 change: 1 addition & 0 deletions acmwebsite/templates/master.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<ul class="nav navbar-nav">
<li class="${('', 'active')[value_of('page') == 'index']}"><a href="${tg.url('/')}">Home</a></li>
<li class="${('', 'active')[value_of('page') == 'schedule']}"><a href="${tg.url('/schedule')}">Schedule</a></li>
<li class="${('', 'active')[value_of('page') == 'projects']}"><a href="${tg.url('/projects')}">Projects</a></li>
<li class="${('', 'active')[value_of('page') == 'mailinglist']}"><a href="${tg.url('/mailinglist')}">Mailing List</a></li>
<li class="${('', 'active')[value_of('page') == 'contact']}"><a href="${tg.url('/contact')}">Contact</a></li>
</ul>
Expand Down
50 changes: 50 additions & 0 deletions acmwebsite/templates/projects.xhtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<html py:strip=""
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude">

<py:extends href="master.xhtml" />

<head py:block="head" py:strip="True">
<title>Mines ACM - Projects</title>
</head>

<body py:block="body" py:strip="True">
<h1 class="page-header">Projects</h1>
<div py:for="project in projects" class="project-list-item panel panel-default">
<div class="panel-heading">
<h2 py:content="project.name" class="panel-title project-title" />
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-3">
<img py:if="project.image" src="${project.image.url}" class="project-image" />
</div>

<div class="col-md-9">
<ul py:if="project.repository or project.website or project.video"
class="list-inline project-links">
<li py:if="project.repository">
<a href="${project.repository}" target="_blank">${h.fa_icon('code-fork')} Repository</a>
</li>
<li py:if="project.website">
<a href="${project.website}" target="_blank">${h.fa_icon('globe')} Website</a>
</li>
<li py:if="project.video_url">
<a href="${project.video_url}" target="_blank">${h.fa_icon('video-camera')} Video</a>
</li>
</ul>
<p py:content="h.markdown(project.description)" />
<p>
<b>Contributors:</b>
<ul>
<li py:for="tm in project.team_members">
<a href="${tg.url('/u/{}'.format(tm.user_name))}" py:content="tm.display_name" />
</li>
</ul>
</p>
</div>
</div>
</div>
</div>
</body>
</html>
Loading

0 comments on commit 5d8bab2

Please sign in to comment.