Skip to content

Commit 1672ecc

Browse files
authored
Merge Version 3.5.3 (#251)
2 parents e4d19a7 + 83f6548 commit 1672ecc

17 files changed

+277
-35
lines changed

.devcontainer/Dockerfile

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM mcr.microsoft.com/vscode/devcontainers/universal:1-linux
2+
3+
USER root
4+
5+
# Add LDAP and python dependency build deps
6+
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive && \
7+
apt-get -yq --no-install-recommends install gcc curl libsasl2-dev libldap2-dev libssl-dev python3-dev
8+
9+
USER codespace

.devcontainer/devcontainer.json

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Update the VARIANT arg in docker-compose.yml to pick a Python version: 3, 3.8, 3.7, 3.6
2+
{
3+
"name": "Packet Codespace (python and postgres)",
4+
"dockerComposeFile": "docker-compose.yaml",
5+
"service": "app",
6+
7+
// Set *default* container specific settings.json values on container create.
8+
"settings": {
9+
"sqltools.connections": [{
10+
"name": "Container database",
11+
"driver": "PostgreSQL",
12+
"previewLimit": 50,
13+
"server": "localhost",
14+
"port": 5432,
15+
"database": "postgres",
16+
"username": "postgres",
17+
"password": "mysecretpassword"
18+
}],
19+
"terminal.integrated.shell.linux": "/bin/bash",
20+
"python.pythonPath": "/opt/python/latest/bin/python",
21+
"python.linting.enabled": true,
22+
"python.linting.pylintEnabled": true,
23+
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
24+
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
25+
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
26+
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
27+
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
28+
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
29+
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
30+
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
31+
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
32+
"python.testing.pytestPath": "/usr/local/py-utils/bin/pytest"
33+
},
34+
"remoteUser": "codespace",
35+
"overrideCommand": false,
36+
"workspaceMount": "source=${localWorkspaceFolder},target=/home/codespace/workspace,type=bind,consistency=cached",
37+
"workspaceFolder": "/home/codespace/workspace",
38+
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined", "--privileged", "--init" ],
39+
40+
// Add the IDs of extensions you want installed when the container is created.
41+
"extensions": [
42+
"GitHub.vscode-pull-request-github",
43+
"ms-python.python",
44+
"mtxr.sqltools",
45+
"mtxr.sqltools-driver-pg"
46+
],
47+
48+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
49+
// "forwardPorts": [5000, 5432],
50+
51+
// Use 'postCreateCommand' to run commands after the container is created.
52+
// "oryx build" will automatically install your dependencies and attempt to build your project
53+
"postCreateCommand": [
54+
"pip install --progress-bar=off install -r requirements.txt;",
55+
"yarn install && `yarn bin gulp production`;",
56+
"/home/codespace/.local/bin/flask db upgrade;"
57+
]
58+
}

.devcontainer/docker-compose.yaml

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
version: '3'
2+
3+
services:
4+
app:
5+
build:
6+
context: ..
7+
dockerfile: .devcontainer/Dockerfile
8+
args:
9+
NODE_VERSION: "10"
10+
11+
volumes:
12+
- /var/run/docker.sock:/var/run/docker.sock
13+
- ..:/workspace:cached
14+
15+
# Overrides default command so things don't shut down after the process ends.
16+
command: sleep infinity
17+
18+
# Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
19+
network_mode: service:db
20+
21+
# Uncomment the next line to use a non-root user for all processes.
22+
user: codespace
23+
24+
# Use "forwardPorts" in **devcontainer.json** to forward an app port locally.
25+
# (Adding the "ports" property to this file will not forward from a Codespace.)
26+
27+
db:
28+
image: postgres:latest
29+
restart: unless-stopped
30+
volumes:
31+
- postgres-data:/var/lib/postgresql/data
32+
environment:
33+
POSTGRES_USER: postgres
34+
POSTGRES_DB: postgres
35+
POSTGRES_PASSWORD: mysecretpassword
36+
37+
# Add "forwardPorts": ["5432"] to **devcontainer.json** to forward MongoDB locally.
38+
# (Adding the "ports" property to this file will not forward from a Codespace.)
39+
40+
volumes:
41+
postgres-data:

.github/workflows/python-app.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ jobs:
1515

1616
strategy:
1717
matrix:
18-
python-version: [3.7, 3.8]
18+
python-version: [3.9]
1919

2020
steps:
2121
- name: Install ldap dependencies
22-
run: sudo apt-get install libldap2-dev libsasl2-dev
22+
run: sudo apt-get update && sudo apt-get install libldap2-dev libsasl2-dev
2323
- uses: actions/checkout@v2
2424
- name: Set up Python ${{ matrix.python-version }}
2525
uses: actions/setup-python@v2

.pylintrc

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[MASTER]
22
ignore = ,input
33
persistent = yes
4+
load-plugins = pylint_quotes
45

56
[MESSAGES CONTROL]
67
disable =

Dockerfile

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
FROM python:3.7-slim-buster
1+
FROM python:3.9-slim-buster
22
MAINTAINER Devin Matte <[email protected]>
33

4+
ENV DD_LOGS_INJECTION=true
5+
46
RUN apt-get -yq update && \
5-
apt-get -yq --no-install-recommends install gcc curl libsasl2-dev libldap2-dev libssl-dev gnupg2 && \
7+
apt-get -yq --no-install-recommends install gcc curl libsasl2-dev libldap2-dev libssl-dev gnupg2 git && \
68
apt-get -yq clean all
79

810
RUN mkdir /opt/packet
@@ -30,4 +32,7 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
3032

3133
RUN ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime
3234

33-
CMD ["gunicorn", "packet:app", "--bind=0.0.0.0:8080", "--access-logfile=-", "--timeout=600"]
35+
# Set version for apm
36+
RUN echo "export DD_VERSION=$(python3 packet/git.py)" >> /tmp/version
37+
38+
CMD ["/bin/bash", "-c", "source /tmp/version && ddtrace-run gunicorn packet:app --bind=0.0.0.0:8080 --access-logfile=- --timeout=600"]

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# CSH Web Packet
22

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

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

1010
## Setup
11-
**Requires Python 3.7 or newer.**
11+
**Requires Python 3.9 or newer.**
1212

1313
To get the server working you'll just need the Python dependencies and some secrets. There will be some UI issues due
1414
to missing assets though. To solve that you'll want to set up the front end dependencies or download a copy of the
@@ -115,12 +115,12 @@ All DB commands are from the `Flask-Migrate` library and are used to configure D
115115
docs [here](https://flask-migrate.readthedocs.io/en/latest/) for details.
116116

117117
## Code standards
118-
This project is configured to use Pylint. Commits will be pylinted by Travis CI and if the score drops your build will
118+
This project is configured to use Pylint. Commits will be pylinted by GitHub actions and if the score drops your build will
119119
fail blocking you from merging. To make your life easier just run it before making a PR.
120120

121121
To run pylint use this command:
122122
```bash
123-
pylint --load-plugins pylint_quotes packet/routes packet
123+
pylint packet/routes packet
124124
```
125125

126126
All python files should have a top-level docstring explaining the contents of the file and complex functions should

config.env.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
# Logging config
1717
LOG_LEVEL = environ.get("PACKET_LOG_LEVEL", "INFO")
18-
ANALYTICS_ID = environ.get("ANALYTICS_ID", "UA-420696-9")
1918

2019
# OpenID Connect SSO config
2120
REALM = environ.get("PACKET_REALM", "csh")
@@ -68,3 +67,8 @@
6867
# Packet Config
6968
PACKET_UPPER = environ.get("PACKET_UPPER", "packet.csh.rit.edu")
7069
PACKET_INTRO = environ.get("PACKET_INTRO", "freshmen-packet.csh.rit.edu")
70+
71+
# RUM
72+
RUM_APP_ID = environ.get("PACKET_RUM_APP_ID", "")
73+
RUM_CLIENT_TOKEN = environ.get("PACKET_RUM_CLIENT_TOKEN","")
74+
DD_ENV = environ.get("DD_ENV", "local-dev")

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"title": "CSH Packet",
33
"name": "csh-packet",
4-
"version": "3.5.2",
4+
"version": "3.5.3",
55
"description": "A web app implementation of the CSH introductory packet.",
66
"bugs": {
77
"url": "https://github.com/ComputerScienceHouse/packet/issues",

packet/__init__.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
from sentry_sdk.integrations.flask import FlaskIntegration
2020
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
2121

22+
from .git import get_version
23+
2224
app = Flask(__name__)
2325
gzip = Gzip(app)
2426

@@ -31,9 +33,8 @@
3133
if os.path.exists(_pyfile_config):
3234
app.config.from_pyfile(_pyfile_config)
3335

34-
# Fetch the version number from the npm package file
35-
with open(os.path.join(_root_dir, 'package.json')) as package_file:
36-
app.config['VERSION'] = json.load(package_file)['version']
36+
# Fetch the version number
37+
app.config['VERSION'] = get_version()
3738

3839
# Logger configuration
3940
logging.getLogger().setLevel(app.config['LOG_LEVEL'])

packet/git.py

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import json
2+
import os
3+
import subprocess
4+
5+
def get_short_sha(commit_ish: str = 'HEAD'):
6+
"""
7+
Get the short hash of a commit-ish
8+
Returns '' if unfound
9+
"""
10+
11+
try:
12+
rev_parse = subprocess.run(f'git rev-parse --short {commit_ish}'.split(), capture_output=True, check=True)
13+
return rev_parse.stdout.decode('utf-8').strip()
14+
except subprocess.CalledProcessError:
15+
return ''
16+
17+
def get_tag(commit_ish: str = 'HEAD'):
18+
"""
19+
Get the name of the tag at a given commit-ish
20+
Returns '' if untagged
21+
"""
22+
23+
try:
24+
describe = subprocess.run(f'git describe --exact-match {commit_ish}'.split(), capture_output=True, check=True)
25+
return describe.stdout.decode('utf-8').strip()
26+
except subprocess.CalledProcessError:
27+
return ''
28+
29+
def get_version(commit_ish: str = 'HEAD'):
30+
"""
31+
Get the version string of a commit-ish
32+
33+
If we have a commit and the commit is tagged, version is `tag (commit-sha)`
34+
If we have a commit but not a tag, version is `commit-sha`
35+
If we have neither, version is the version field of package.json
36+
"""
37+
38+
if sha := get_short_sha(commit_ish):
39+
if tag := get_tag(commit_ish):
40+
return f'{tag} ({sha})'
41+
else:
42+
return sha
43+
else:
44+
root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
45+
with open(os.path.join(root_dir, 'package.json')) as package_file:
46+
return json.load(package_file)['version']
47+
48+
if __name__ == '__main__':
49+
print(get_version())

packet/ldap.py

+18
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,24 @@ def _is_member_of_group(self, member, group):
6767
else:
6868
return group in member.groups
6969

70+
def get_groups(self, member):
71+
if self.ldap:
72+
return list(
73+
map(
74+
lambda g: g[0][3:],
75+
filter(
76+
lambda d: d[1] == 'cn=groups',
77+
map(
78+
lambda group_dn: group_dn.split(','),
79+
member.get('memberOf')
80+
)
81+
)
82+
)
83+
)
84+
else:
85+
return member.groups
86+
87+
7088

7189
# Getters
7290

packet/routes/upperclassmen.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
"""
44
import json
55

6-
from itertools import chain
76
from operator import itemgetter
87
from flask import redirect, render_template, url_for
98

109
from packet import app
11-
from packet.models import Packet, MiscSignature
10+
from packet.models import Packet
1211
from packet.utils import before_request, packet_auth
1312
from packet.log_utils import log_cache, log_time
1413
from packet.stats import packet_stats
@@ -51,18 +50,20 @@ def upperclassmen_total(info=None):
5150

5251
# Sum up the signed packets per upperclassman
5352
upperclassmen = dict()
53+
misc = dict()
5454
for packet in open_packets:
55-
for sig in chain(packet.upper_signatures, packet.misc_signatures):
55+
for sig in packet.upper_signatures:
5656
if sig.member not in upperclassmen:
5757
upperclassmen[sig.member] = 0
5858

59-
if isinstance(sig, MiscSignature):
60-
upperclassmen[sig.member] += 1
61-
elif sig.signed:
62-
upperclassmen[sig.member] += 1
59+
if sig.signed:
60+
upperclassmen[sig.member] += 1
61+
for sig in packet.misc_signatures:
62+
misc[sig.member] = 1 + misc.get(sig.member, 0)
6363

6464
return render_template('upperclassmen_totals.html', info=info, num_open_packets=len(open_packets),
65-
upperclassmen=sorted(upperclassmen.items(), key=itemgetter(1), reverse=True))
65+
upperclassmen=sorted(upperclassmen.items(), key=itemgetter(1), reverse=True),
66+
misc=sorted(misc.items(), key=itemgetter(1), reverse=True))
6667

6768

6869
@app.route('/stats/packet/<packet_id>')

0 commit comments

Comments
 (0)