Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: python
python:
- "3.6"
- "3.7"

install:
- "pip install -r requirements.txt"
Expand Down
20 changes: 11 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
FROM python:3.6-stretch
FROM python:3.7-slim-buster
MAINTAINER Devin Matte <matted@csh.rit.edu>

RUN mkdir /opt/packet
RUN apt-get -yq update && \
apt-get -yq --no-install-recommends install gcc curl libsasl2-dev libldap2-dev libssl-dev && \
apt-get -yq clean all

ADD requirements.txt /opt/packet
RUN mkdir /opt/packet

WORKDIR /opt/packet

RUN apt-get -yq update && \
apt-get -yq --allow-unauthenticated install libsasl2-dev libldap2-dev libssl-dev && \
pip install -r requirements.txt && \
apt-get -yq clean all
COPY requirements.txt /opt/packet

RUN pip install -r requirements.txt

ADD . /opt/packet
COPY . /opt/packet

RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get -yq update && \
apt-get -yq install nodejs npm yarn && \
apt-get -yq --no-install-recommends install nodejs yarn && \
yarn install && \
npm install -g gulp && \
gulp production && \
rm -rf node_modules && \
apt-get -yq remove nodejs npm yarn && \
apt-get -yq autoremove && \
apt-get -yq clean all

RUN ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# CSH Web Packet

[![Python 3.6](https://img.shields.io/badge/python-3.6-blue.svg)](https://www.python.org/downloads/release/python-360/)
[![Python 3.7](https://img.shields.io/badge/python-3.7-blue.svg)](https://www.python.org/downloads/release/python-370/)
[![Build Status](https://travis-ci.com/ComputerScienceHouse/packet.svg?branch=develop)](https://travis-ci.com/ComputerScienceHouse/packet)

Packet is used by CSH to facilitate the freshmen packet portion of our introductory member evaluation process. This is
the second major iteration of packet on the web. The first version was
[Tal packet](https://github.com/TalCohen/CSHWebPacket).

## Setup
**Requires Python 3.6 or newer.**
**Requires Python 3.7 or newer.**

To get the server working you'll just need the Python dependencies and some secrets. There will be some UI issues due
to missing assets though. To solve that you'll want to set up the front end dependencies or download a copy of the
Expand Down
3 changes: 3 additions & 0 deletions config.env.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
ONESIGNAL_INTRO_APP_AUTH_KEY = environ.get("PACKET_ONESIGNAL_INTRO_APP_AUTH_KEY", None)
ONESIGNAL_INTRO_APP_ID = environ.get("PACKET_ONESIGNAL_INTRO_APP_ID", "6eff123a-0852-4027-804e-723044756f00")

# Sentry Config
SENTRY_DSN = environ.get("PACKET_SENTRY_DSN", "")

# Slack URL for pushing to #general
SLACK_WEBHOOK_URL = environ.get("PACKET_SLACK_URL", None)

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"title": "CSH Packet",
"name": "csh-packet",
"version": "3.3.3",
"version": "3.4.0",
"description": "A web app implementation of the CSH introductory packet.",
"bugs": {
"url": "https://github.com/ComputerScienceHouse/packet/issues",
Expand All @@ -10,7 +10,8 @@
"license": "MIT",
"contributors": [
"Devin Matte (https://devinmatte.com/)",
"Joel Eager (https://github.com/JoelEager)"
"Joel Eager (https://github.com/JoelEager)",
"Max Meinhold (https://github.com/mxmeinhold)"
],
"repository": {
"type": "git",
Expand Down
14 changes: 12 additions & 2 deletions packet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
The application setup and initialization code lives here
"""

import os
import logging
import json
import logging
import os

import csh_ldap
import onesignal
Expand All @@ -15,6 +15,10 @@
from flask_pyoidc.provider_configuration import ProviderConfiguration, ClientMetadata
from flask_sqlalchemy import SQLAlchemy

import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration

app = Flask(__name__)
gzip = Gzip(app)

Expand Down Expand Up @@ -60,6 +64,12 @@
# LDAP
_ldap = csh_ldap.CSHLDAP(app.config['LDAP_BIND_DN'], app.config['LDAP_BIND_PASS'])

# Sentry
sentry_sdk.init(
dsn=app.config['SENTRY_DSN'],
integrations=[FlaskIntegration(), SqlalchemyIntegration()]
)

app.logger.info('OIDCAuth and LDAP configured')

# pylint: disable=wrong-import-position
Expand Down
66 changes: 48 additions & 18 deletions packet/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Defines command-line utilities for use with packet
"""

import sys

from secrets import token_hex
from datetime import datetime, time, timedelta
import csv
Expand Down Expand Up @@ -31,9 +33,9 @@ def create_secret():

class CSVFreshman:
def __init__(self, row):
self.name = row[0]
self.rit_username = row[3]
self.onfloor = row[1] == 'TRUE'
self.name = row[0].strip()
self.rit_username = row[3].strip()
self.onfloor = row[1].strip() == 'TRUE'


def parse_csv(freshmen_csv):
Expand Down Expand Up @@ -219,31 +221,59 @@ def ldap_sync():


@app.cli.command('fetch-results')
def fetch_results():
@click.option('-f', '--file', 'file_path', required=False, type=click.Path(exists=False, writable=True),
help='The file to write to. If no file provided, output is sent to stdout.')
@click.option('--csv/--no-csv', 'use_csv', required=False, default=False, help='Format output as comma separated list.')
@click.option('--date', 'date_str', required=False, default='', help='Packet end date in the format MM/DD/YYYY.')
def fetch_results(file_path, use_csv, date_str):
"""
Fetches and prints the results from a given packet season.
"""
end_date = datetime.combine(input_date("Enter the last day of the packet season you'd like to retrieve results "
end_date = None
try:
end_date = datetime.combine(datetime.strptime(date_str, '%m/%d/%Y').date(), packet_end_time)
except ValueError:
end_date = datetime.combine(input_date("Enter the last day of the packet season you'd like to retrieve results "
'from'), packet_end_time)

for packet in Packet.query.filter_by(end=end_date).all():
print()

print('{} ({}):'.format(packet.freshman.name, packet.freshman.rit_username))
file_handle = open(file_path, 'w', newline='') if file_path else sys.stdout

column_titles = ['Name (RIT Username)', 'Upperclassmen Score', 'Total Score', 'Upperclassmen', 'Freshmen',
'Miscellaneous', 'Total Missed']
data = list()
for packet in Packet.query.filter_by(end=end_date).all():
received = packet.signatures_received()
required = packet.signatures_required()

print('\tUpperclassmen score: {:0.2f}%'.format(received.member_total / required.member_total * 100))
print('\tTotal score: {:0.2f}%'.format(received.total / required.total * 100))
print()

print('\tUpperclassmen: {}/{}'.format(received.upper, required.upper))
print('\tFreshmen: {}/{}'.format(received.fresh, required.fresh))
print('\tMiscellaneous: {}/{}'.format(received.misc, required.misc))
print()

print('\tTotal missed:', required.total - received.total)
row = [
'{} ({}):'.format(packet.freshman.name, packet.freshman.rit_username),
'{:0.2f}%'.format(received.member_total / required.member_total * 100),
'{:0.2f}%'.format(received.total / required.total * 100),
'{}/{}'.format(received.upper, required.upper),
'{}/{}'.format(received.fresh, required.fresh),
'{}/{}'.format(received.misc, required.misc),
required.total - received.total,
]
data.append(row)

if use_csv:
writer = csv.writer(file_handle)
writer.writerow(column_titles)
writer.writerows(data)
else:
for row in data:
file_handle.write(f'''

{row[0]}
\t{column_titles[1]}: {row[1]}
\t{column_titles[2]}: {row[2]}
\t{column_titles[3]}: {row[3]}
\t{column_titles[4]}: {row[4]}
\t{column_titles[5]}: {row[5]}

\t{column_titles[6]}: {row[6]}
''')


@app.cli.command('extend-packet')
Expand Down
Loading