diff --git a/.dockerignore b/.dockerignore index c2658d7d..6b325ceb 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,3 @@ node_modules/ +.env +.env.example diff --git a/.env.example b/.env.example index a479ace6..131ab2da 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,7 @@ PACKET_IP=0.0.0.0 -PACKET_SERVER_NAME=localhost.localdomain:8000 +PACKET_SERVER_NAME=localhost:8000 PACKET_DATABASE_URI=postgresql://postgres:mysecretpassword@postgres:5432/postgres +PACKET_OIDC_CLIENT_ID=develop PACKET_OIDC_CLIENT_SECRET= PACKET_LDAP_BIND_PASS= PACKET_LDAP_BIND_DN= diff --git a/Dockerfile b/Dockerfile index 78d9e796..7994cd61 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/python:3.9-slim-trixie +FROM docker.io/python:3.14-slim-trixie RUN ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime RUN apt-get -yq update && \ @@ -32,4 +32,4 @@ RUN gulp production && \ # Set version for apm RUN echo "export DD_VERSION=\"$(python3 packet/git.py)\"" >> /tmp/version -CMD ["/bin/bash", "-c", "source /tmp/version && ddtrace-run gunicorn packet:app --bind=0.0.0.0:8080 --access-logfile=- --timeout=600"] +CMD ["/bin/bash", "-c", "source /tmp/version && gunicorn packet:app --bind=0.0.0.0:8080 --access-logfile=- --timeout=600"] diff --git a/Dockerfile.dev b/Dockerfile.dev deleted file mode 100644 index 473c469d..00000000 --- a/Dockerfile.dev +++ /dev/null @@ -1,34 +0,0 @@ -FROM docker.io/python:3.9-slim-trixie - -RUN ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime -RUN apt-get -yq update && \ - apt-get -yq --no-install-recommends install gcc curl libsasl2-dev libldap2-dev libssl-dev gnupg2 git && \ - apt-get -yq clean all \ - curl -sL https://deb.nodesource.com/setup_20.x | bash - && \ - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor -o /usr/share/keyrings/yarn-archive-keyring.gpg && \ - echo "deb [signed-by=/usr/share/keyrings/yarn-archive-keyring.gpg] https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ - apt-get -yq update && \ - apt-get -yq --no-install-recommends install nodejs yarn - -RUN mkdir /opt/packet -WORKDIR /opt/packet - -COPY requirements.txt /opt/packet/ -RUN pip install -r requirements.txt - -COPY package.json /opt/packet/ -COPY yarn.lock /opt/packet/ - -RUN yarn install && \ - yarn global add gulp - -COPY . /opt/packet -RUN gulp production && \ - rm -rf node_modules && \ - apt-get -yq remove nodejs npm yarn && \ - apt-get -yq autoremove && \ - apt-get -yq clean all - -EXPOSE 8000 - -CMD ["/bin/bash", "-c", "python3 wsgi.py"] diff --git a/README.md b/README.md index 197f50c7..04cc310e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ the second major iteration of packet on the web. The first version was 2. Build the dev environment with `docker compose build` 3. Start the dev environment with `docker compose up` 4. Run the database migrations with `docker exec -it packet-packet-1 flask db upgrade` -5. Go check out the app at http://localhost.localdomain:8000 +5. Go check out the app at http://localhost:8080 > Useful Tip: use `docker compose up --watch` so that you don't need to rebuild the container every time you want to test a change diff --git a/config.env.py b/config.env.py index 7e7b8832..a36b06b1 100644 --- a/config.env.py +++ b/config.env.py @@ -24,7 +24,7 @@ OIDC_CLIENT_SECRET = environ.get("PACKET_OIDC_CLIENT_SECRET", "PLEASE_REPLACE_ME") # SQLAlchemy config -SQLALCHEMY_DATABASE_URI = environ.get("PACKET_DATABASE_URI", "postgresql://postgres:mysecretpassword@localhost:5432/postgres") +SQLALCHEMY_DATABASE_URI = environ.get("PACKET_DATABASE_URI", "postgresql://postgres:mysecretpassword@postgres:5432/postgres") SQLALCHEMY_TRACK_MODIFICATIONS = False # LDAP config diff --git a/docker-compose.yml b/docker-compose.yml index dc452c4d..4448bd03 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,12 +2,11 @@ services: packet: build: context: . - dockerfile: ./Dockerfile.dev env_file: - path: ".env" required: true ports: - - "8000:8000" + - "8080:8080" develop: watch: - action: sync+restart @@ -23,14 +22,15 @@ services: postgres: condition: service_healthy restart: true + postgres: - image: "docker.io/postgres:17" + image: docker.io/postgres networks: - packet-network-dev environment: - POSTGRES_USER: "postgres" - POSTGRES_DB: "postgres" - POSTGRES_PASSWORD: "mysecretpassword" + POSTGRES_USER: postgres + POSTGRES_DATABASE: postgres + POSTGRES_PASSWORD: mysecretpassword ports: - "5432:5432" healthcheck: diff --git a/frontend/scss/partials/_base.scss b/frontend/scss/partials/_base.scss index 0d1956f1..42369c10 100644 --- a/frontend/scss/partials/_base.scss +++ b/frontend/scss/partials/_base.scss @@ -1,6 +1,7 @@ @use "sass:meta"; body { padding-top: 40px; + background-color: #eee; } .main { diff --git a/frontend/scss/partials/_global.scss b/frontend/scss/partials/_global.scss index c37d0efa..a2372e78 100644 --- a/frontend/scss/partials/_global.scss +++ b/frontend/scss/partials/_global.scss @@ -1,10 +1,5 @@ $csh-pink: #b0197e; -.navbar-fixed-bottom, -.navbar-fixed-top { - z-index: 900; -} - .sub-header { border-bottom: 1px solid #eee; padding-bottom: 10px; @@ -110,3 +105,24 @@ tr { select.form-control:not([size]):not([multiple]) { height: calc(3rem + 2px); } + +.bg-signed td { + background-color: #4caf505e !important; + box-shadow: none !important; +} + +.invert-color { + filter: invert(100%); +} + +.underline-only-hover { + text-decoration: none; +} + +.underline-only-hover:hover { + text-decoration: underline; +} + +.text-bg-grey { + background-color: var(--bs-gray-500); +} \ No newline at end of file diff --git a/gulpfile.js/tasks/javascript.js b/gulpfile.js/tasks/javascript.js index 7841b8fa..33148648 100644 --- a/gulpfile.js/tasks/javascript.js +++ b/gulpfile.js/tasks/javascript.js @@ -3,8 +3,8 @@ const minify = require('gulp-minify'); gulp.task('js:minify', (done) => { gulp.src([ - 'packet/static/js/*.js', - '!packet/static/js/*.min.js' + 'packet/static/js/**/*.js', + '!packet/static/js/**/*.min.js' ]) .pipe(minify({ ext: { diff --git a/packet/__init__.py b/packet/__init__.py index 85102f50..8870ae10 100644 --- a/packet/__init__.py +++ b/packet/__init__.py @@ -44,7 +44,8 @@ # Initialize the extensions db = SQLAlchemy(app) migrate = Migrate(app, db) -app.logger.info('SQLAlchemy pointed at ' + repr(db.engine.url)) +with app.app_context(): + app.logger.info('SQLAlchemy pointed at ' + repr(db.engine.url)) APP_CONFIG = ProviderConfiguration(issuer=app.config['OIDC_ISSUER'], client_metadata=ClientMetadata(app.config['OIDC_CLIENT_ID'], diff --git a/packet/static/js/admin/freshmen.js b/packet/static/js/admin/freshmen.js new file mode 100644 index 00000000..e5b7efc4 --- /dev/null +++ b/packet/static/js/admin/freshmen.js @@ -0,0 +1,89 @@ +$(document).ready(function () { + + // let openPacketsTable = $('#open_packets_table'); + // openPacketsTable.DataTable({ + // "searching": true, + // "order": [], + // "scrollX": false, + // "paging": true, + // "info": false, + // "columnDefs": [ + // { + // "targets": 0, + // "max-width": "50%", + // }, + // { + // "type": "num-fmt", + // "targets": 1, + // "visible": true, + // "max-width": "15%", + // } + // ] + // }); + + $('#all_freshmen_table').dataTable({ + "searching": true, + "order": [], + "scrollX": false, + "paging": true, + "info": false, + }); + + // $("#create-packets").click(() => { + // makePackets(); + // }); + + $("#sync-freshmen").click(() => { + syncFreshmen(); + }) + + // $("#sync-ldap").click(() => { + // syncLdap(); + // }) + +}); + +let syncFreshmen = () => { + let freshmen = []; + let fileUpload = document.getElementById("currentFroshFile"); + let regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/; + if (regex.test(fileUpload.value.toLowerCase())) { + if (typeof (FileReader) != "undefined") { + let reader = new FileReader(); + reader.onload = (e) => { + let rows = e.target.result.split("\n"); + for (let i = 0; i < rows.length; i++) { + let cells = rows[i].split(","); + if (cells.length > 1) { + freshmen.push({ + rit_username: cells[3], + name: cells[0], + onfloor: cells[1] + }); + } + } + if (freshmen.length >= 1) { + $("#sync-freshmen").append(" "); + $("#sync-freshmen").attr('disabled', true); + fetch('/api/v1/freshmen', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(freshmen) + } + ).then(response => { + if (response.status < 300) { + $('#sync-freshmen-modal').modal('hide'); + location.reload(); + } else { + alert("There was an error syncing freshmen") + } + }) + } + } + reader.readAsText(fileUpload.files[0]); + } + } +} \ No newline at end of file diff --git a/packet/static/js/admin.js b/packet/static/js/admin/packets.js similarity index 58% rename from packet/static/js/admin.js rename to packet/static/js/admin/packets.js index 2cde58e4..de75bc6a 100644 --- a/packet/static/js/admin.js +++ b/packet/static/js/admin/packets.js @@ -21,22 +21,21 @@ $(document).ready(function () { ] }); - let allFreshmenTable = $('#all_freshmen_table'); - allFreshmenTable.DataTable({ - "searching": true, - "order": [], - "scrollX": false, - "paging": true, - "info": false, - }); + // $('#all_freshmen_table').dataTable({ + // "searching": true, + // "order": [], + // "scrollX": false, + // "paging": true, + // "info": false, + // }); $("#create-packets").click(() => { makePackets(); }); - $("#sync-freshmen").click(() => { - syncFreshmen(); - }) + // $("#sync-freshmen").click(() => { + // syncFreshmen(); + // }) $("#sync-ldap").click(() => { syncLdap(); @@ -93,50 +92,50 @@ let makePackets = () => { } -let syncFreshmen = () => { - let freshmen = []; - let fileUpload = document.getElementById("currentFroshFile"); - let regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/; - if (regex.test(fileUpload.value.toLowerCase())) { - if (typeof (FileReader) != "undefined") { - let reader = new FileReader(); - reader.onload = (e) => { - let rows = e.target.result.split("\n"); - for (let i = 0; i < rows.length; i++) { - let cells = rows[i].split(","); - if (cells.length > 1) { - freshmen.push({ - rit_username: cells[3], - name: cells[0], - onfloor: cells[1] - }); - } - } - if (freshmen.length >= 1) { - $("#sync-freshmen").append(" "); - $("#sync-freshmen").attr('disabled', true); - fetch('/api/v1/freshmen', - { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(freshmen) - } - ).then(response => { - if (response.status < 300) { - $('#sync-freshmen-modal').modal('hide'); - location.reload(); - } else { - alert("There was an error syncing freshmen") - } - }) - } - } - reader.readAsText(fileUpload.files[0]); - } - } -} +// let syncFreshmen = () => { +// let freshmen = []; +// let fileUpload = document.getElementById("currentFroshFile"); +// let regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/; +// if (regex.test(fileUpload.value.toLowerCase())) { +// if (typeof (FileReader) != "undefined") { +// let reader = new FileReader(); +// reader.onload = (e) => { +// let rows = e.target.result.split("\n"); +// for (let i = 0; i < rows.length; i++) { +// let cells = rows[i].split(","); +// if (cells.length > 1) { +// freshmen.push({ +// rit_username: cells[3], +// name: cells[0], +// onfloor: cells[1] +// }); +// } +// } +// if (freshmen.length >= 1) { +// $("#sync-freshmen").append(" "); +// $("#sync-freshmen").attr('disabled', true); +// fetch('/api/v1/freshmen', +// { +// method: 'POST', +// headers: { +// 'Content-Type': 'application/json' +// }, +// body: JSON.stringify(freshmen) +// } +// ).then(response => { +// if (response.status < 300) { +// $('#sync-freshmen-modal').modal('hide'); +// location.reload(); +// } else { +// alert("There was an error syncing freshmen") +// } +// }) +// } +// } +// reader.readAsText(fileUpload.files[0]); +// } +// } +// } let syncLdap = () => { $("#sync-ldap").append(" "); diff --git a/packet/static/js/pfp-zoom.js b/packet/static/js/pfp-zoom.js index 3e80b5ff..fe988bbe 100644 --- a/packet/static/js/pfp-zoom.js +++ b/packet/static/js/pfp-zoom.js @@ -21,7 +21,7 @@ $(document).ready(function () { other.remove() } photo.insertAdjacentHTML('afterend', ` -
|
{% if info.is_upper %}
-
+
{% endif %}
|
{% endif %}
- + | {% if not packet.did_sign_result and info.ritdn != packet.freshman_username %} |