From 4845d2ecccb76afd1bb1711f21b044f4773b63ab Mon Sep 17 00:00:00 2001 From: Andi Chang Date: Mon, 4 May 2026 15:14:16 -0700 Subject: [PATCH 01/16] Font change to IBM Plex Sans --- ocfweb/static/scss/pages/_home.scss | 2 +- ocfweb/static/scss/site.scss | 2 +- ocfweb/templates/partials/head.html | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ocfweb/static/scss/pages/_home.scss b/ocfweb/static/scss/pages/_home.scss index f1882675d..024ff7bb9 100644 --- a/ocfweb/static/scss/pages/_home.scss +++ b/ocfweb/static/scss/pages/_home.scss @@ -142,7 +142,7 @@ } @media (min-width: $screen-md-min) { - font-size: 40px; + font-size: 39px; } // we want the text to wrap after 'Open' diff --git a/ocfweb/static/scss/site.scss b/ocfweb/static/scss/site.scss index 458c4d0d9..295032fd6 100644 --- a/ocfweb/static/scss/site.scss +++ b/ocfweb/static/scss/site.scss @@ -45,7 +45,7 @@ html { body { padding-top: $navbar-height; - font-family: Roboto, Helvetica, Arial, sans-serif; + font-family: 'IBM Plex Sans', Roboto, Helvetica, Arial, sans-serif; font-size: 16px; background-color: #f5f5f5; display: flex; diff --git a/ocfweb/templates/partials/head.html b/ocfweb/templates/partials/head.html index cf431c481..26d18e3d3 100644 --- a/ocfweb/templates/partials/head.html +++ b/ocfweb/templates/partials/head.html @@ -30,7 +30,8 @@ - + + From e876b6aa99a33596e50801cc10458d159680adc1 Mon Sep 17 00:00:00 2001 From: Andi Chang Date: Mon, 4 May 2026 04:29:53 -0700 Subject: [PATCH 02/16] Reformat staff hours --- ocfweb/main/templates/main/home.html | 43 +++++++++------ ocfweb/main/templates/main/staff-hours.html | 2 +- ocfweb/static/scss/pages/_home.scss | 58 +++++++++------------ 3 files changed, 54 insertions(+), 49 deletions(-) diff --git a/ocfweb/main/templates/main/home.html b/ocfweb/main/templates/main/home.html index b1825b7a6..f08b7257c 100644 --- a/ocfweb/main/templates/main/home.html +++ b/ocfweb/main/templates/main/home.html @@ -104,24 +104,37 @@

OCF Computer Lab

  • Mail Virtual Hosting
  • -
    +

    Staff Hours

    +
    {% for staff_hour in staff_hours %} -

    Staff Hours {{staff_hour.day}}

    -
    -

    - {{staff_hour.time}} - {% if staff_hour.cancelled %} - cancelled this week - {% endif %} -

    -
    - {{staffer.user_name}} +
    +
    + {{staff_hour.day}}
    +
    +
    +

    + {{staff_hour.time}} + {% if staff_hour.cancelled %} + cancelled this week + {% endif %} +

    +
    +
    + {{staffer.user_name}} +
    +
    + {{staffer.real_name}} <{{staffer.user_name}}> +
    +
    + +
    +
    {% endfor %}

    See more staff hours »

    diff --git a/ocfweb/main/templates/main/staff-hours.html b/ocfweb/main/templates/main/staff-hours.html index 258440e0c..2f66cad72 100644 --- a/ocfweb/main/templates/main/staff-hours.html +++ b/ocfweb/main/templates/main/staff-hours.html @@ -23,7 +23,7 @@

    Have questions? Drop by for help from a friendly volunteer staffer!

    {% for staffer in staff_hour.staff %}
  • {{staffer.user_name}} -

    {{staffer.real_name}}

    +

    {{staffer.real_name}} <{{staffer.user_name}}>

    {{staffer.position}}
  • {% endfor %} diff --git a/ocfweb/static/scss/pages/_home.scss b/ocfweb/static/scss/pages/_home.scss index 024ff7bb9..5d2ea9cbf 100644 --- a/ocfweb/static/scss/pages/_home.scss +++ b/ocfweb/static/scss/pages/_home.scss @@ -28,6 +28,31 @@ .ocf-hour-hours { padding: 0 5px; + + .ocf-staffer { + padding-top: 4px; + + .ocf-staffer-face { + padding: 4px 0; + } + } + } + + p { + margin: 0; + } + + .cancelled p { + color: #999; + } + + .cancelled-text { + color: #b20000; + font-weight: bold; + } + + .cancelled .ocf-staffer { + opacity: 0.6; } } } @@ -57,39 +82,6 @@ font-size: 14px; } - .ocf-staffhours { - p { - margin: 0; - } - - h3 { - margin-bottom: 0; - } - - .cancelled p { - color: #999; - } - - .cancelled-text { - color: #b20000; - font-weight: bold; - } - - .ocf-staffhours-faces img { - margin-right: 10px; - margin-bottom: 10px; - - @media (max-width: $screen-sm-max) { - margin-right: 5px; - margin-bottom: 5px; - } - } - - .cancelled .ocf-staffhours-faces { - opacity: 0.6; - } - } - .ocf-penguin-swing { position: absolute; From 2fd3dbbae565239e383b819ca251cc8fd8529e75 Mon Sep 17 00:00:00 2001 From: Andi Chang Date: Mon, 4 May 2026 15:29:33 -0700 Subject: [PATCH 03/16] Make footer lighter for accessibility --- ocfweb/static/scss/site.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ocfweb/static/scss/site.scss b/ocfweb/static/scss/site.scss index 295032fd6..8310b682b 100644 --- a/ocfweb/static/scss/site.scss +++ b/ocfweb/static/scss/site.scss @@ -19,7 +19,7 @@ $color-blue-baby: #cbe1ea; $color-blue-light: #f8fcfc; $color-blue: #298399; $color-gray-light: #ccc; -$color-gray: #888; +$color-gray: #aaa; $color-green-light: #de9; $color-yellow-light: #ffc; $color-penguin-blue: #0f4d92; From ae9319e0adafd414e71a0de435b12b8d310b5d74 Mon Sep 17 00:00:00 2001 From: Andi Chang Date: Mon, 11 May 2026 12:13:20 -0700 Subject: [PATCH 04/16] Move lab info out of docs --- ocfweb/about/templates/about/staff.html | 8 +- .../templates/announcements/index.html | 2 +- ocfweb/main/lab.py | 43 ++++++ ocfweb/main/templates/main/home.html | 6 +- ocfweb/main/templates/main/lab.html | 141 ++++++++++++++++++ ocfweb/templates/base.html | 4 +- ocfweb/urls.py | 2 + 7 files changed, 196 insertions(+), 10 deletions(-) create mode 100644 ocfweb/main/lab.py create mode 100644 ocfweb/main/templates/main/lab.html diff --git a/ocfweb/about/templates/about/staff.html b/ocfweb/about/templates/about/staff.html index 11bdc3116..438846d83 100644 --- a/ocfweb/about/templates/about/staff.html +++ b/ocfweb/about/templates/about/staff.html @@ -13,7 +13,7 @@

    What is the Open Computing Facility?

    We're a student organization dedicated to providing free computing for all UC Berkeley students, faculty, and staff.

    -

    We run a computer lab on southside, have a wicked set of servers for staff to play on, and provide cool services to the Berkeley community.

    +

    We run a computer lab on southside, have a wicked set of servers for staff to play on, and provide cool services to the Berkeley community.

    @@ -60,7 +60,7 @@

    OCF Staff Meetings

    OCF Staff meet to discuss technology, learn from each other, and work on OCF projects.

    Drop-in visitors are always welcome, especially those interested in joining the staff team!

    When: Every Wednesday at 7:30pm

    -

    Where: OCF Computer lab (171 MLK)

    +

    Where: OCF Computer lab (171 MLK)

    @@ -104,7 +104,7 @@

    Computer Lab & Printing

    We have a spiffy computer lab on southside.

    Create an account and drop by!

    -

    Our computer lab, located in 171 MLK Student Union, features high-res scanners, free printing, and high-end desktops with mechanical keyboards and GTX graphics cards, all running Debian GNU/Linux.

    +

    Our computer lab, located in 171 MLK Student Union, features high-res scanners, free printing, and high-end desktops with mechanical keyboards and GTX graphics cards, all running Debian GNU/Linux.

    a photo of servers in the rack, 2019 Spring
    @@ -149,7 +149,7 @@

    We've got a perfect sandbox to poke around.

    -

    We meet every Wednesday at 7:30pm in the lab.

    +

    We meet every Wednesday at 7:30pm in the lab.

    We hope to see you there!

    diff --git a/ocfweb/announcements/templates/announcements/index.html b/ocfweb/announcements/templates/announcements/index.html index c91fcd48e..e20a683b9 100644 --- a/ocfweb/announcements/templates/announcements/index.html +++ b/ocfweb/announcements/templates/announcements/index.html @@ -53,7 +53,7 @@

    About the Open Computing Facility

    • - + A spiffy computer lab in 171 MLK
    • diff --git a/ocfweb/main/lab.py b/ocfweb/main/lab.py new file mode 100644 index 000000000..9da1f9761 --- /dev/null +++ b/ocfweb/main/lab.py @@ -0,0 +1,43 @@ +from datetime import date +from datetime import timedelta + +from django.http import HttpRequest +from django.http import HttpResponse +from django.shortcuts import render + +from ocfweb.api.hours import get_hours_listing + + +def lab(request: HttpRequest) -> HttpResponse: + hours_listing = get_hours_listing() + return render( + request, + 'main/lab.html', + { + 'title': 'Computer Lab', + 'description': ( + 'The Open Computing Facility computer lab is a ' + 'free and open-source computer lab located on the ' + 'UC Berkeley campus, maintained by OCF volunteers.' + ), + 'hours_this_week': [ + ( + date.today() + timedelta(days=i), + hours_listing.hours_on_date(date.today() + timedelta(days=i)), + ) + for i in range(7) + ], + 'regular_hours': hours_listing.regular, + # Format dates to look like "month day, year" but with non-breaking + # spaces (\xa0) instead of spaces so that the date does not get + # broken up across lines: + # https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#date + 'holiday_format': 'M\xa0j,\xa0o', + # Only select current and future holidays (any that have not finished fully) + 'holidays': [ + holiday + for holiday in hours_listing.holidays + if holiday.enddate >= date.today() + ], + }, + ) diff --git a/ocfweb/main/templates/main/home.html b/ocfweb/main/templates/main/home.html index f08b7257c..3fb1dae6d 100644 --- a/ocfweb/main/templates/main/home.html +++ b/ocfweb/main/templates/main/home.html @@ -32,7 +32,7 @@

      Welcome to the Open Computing Facility!

      OCF volunteers maintain services for the Berkeley community, including:

    -

    See more lab hours »

    +

    See more lab hours »

    Account Tools

    @@ -161,6 +162,7 @@
    About the OCF
    Account Tools
    From 1a860a00c492838e80d1a8a793387a1a02135cee Mon Sep 17 00:00:00 2001 From: Andi Chang Date: Sat, 30 May 2026 03:24:49 -0700 Subject: [PATCH 13/16] Update info.py Co-authored-by: sophie --- ocfweb/account/info.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ocfweb/account/info.py b/ocfweb/account/info.py index dc12bcdbd..d8a09cfbb 100644 --- a/ocfweb/account/info.py +++ b/ocfweb/account/info.py @@ -19,7 +19,6 @@ @login_required def account_info(request: HttpRequest) -> HttpResponse: user = logged_in_user(request) - # user = 'animage' # test with get_connection() as c: paper_quota = get_quota(c, user) bytes_used = None From 472cc12887d19a1e224c09e5f1badc86b52cfebe Mon Sep 17 00:00:00 2001 From: Andi Chang Date: Sat, 30 May 2026 03:24:56 -0700 Subject: [PATCH 14/16] Update home.html Co-authored-by: sophie --- ocfweb/main/templates/main/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ocfweb/main/templates/main/home.html b/ocfweb/main/templates/main/home.html index 9966ce99f..aaa374b81 100644 --- a/ocfweb/main/templates/main/home.html +++ b/ocfweb/main/templates/main/home.html @@ -43,7 +43,7 @@

    Welcome to the Open Computing Facility!

  • High-performance computing on our GPU server
  • ...and lots more!
  • -

    Check out upcoming events on the OCF calendar.

    +

    Check out upcoming events on the OCF Calendar.

    We hold weekly staff hours to provide assistance with account issues or with OCF services. Drop by to ask questions or just to hang out!


    From ca9e13fc2fd71bcbfb4d3ab15a972c229209a08d Mon Sep 17 00:00:00 2001 From: Andi Chang Date: Sat, 30 May 2026 03:34:53 -0700 Subject: [PATCH 15/16] Add vhost link (should i add webapp and mail too?) --- ocfweb/account/commands.py | 4 ++-- ocfweb/account/info.py | 2 +- ocfweb/account/templates/account/info/index.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ocfweb/account/commands.py b/ocfweb/account/commands.py index e87fb19dc..72ca6fb56 100644 --- a/ocfweb/account/commands.py +++ b/ocfweb/account/commands.py @@ -53,8 +53,8 @@ def commands(request: HttpRequest) -> HttpResponse: if not error: if command_to_run == 'paper': - command_to_run = f"/run/current-system/sw/bin/paper view {username} | sed 's/\x1B\\[[0-9;]*[a-zA-Z]//g'" # noqa - _, ssh_stdout, ssh_stderr = ssh.exec_command(command_to_run, get_pty=True) + command_to_run = f"/run/current-system/sw/bin/paper view {username}" # noqa + _, ssh_stdout, ssh_stderr = ssh.exec_command(command_to_run, get_pty=False) output = ssh_stdout.read().decode() error = ssh_stderr.read().decode() else: diff --git a/ocfweb/account/info.py b/ocfweb/account/info.py index d8a09cfbb..0a38c41e1 100644 --- a/ocfweb/account/info.py +++ b/ocfweb/account/info.py @@ -58,7 +58,7 @@ def account_info(request: HttpRequest) -> HttpResponse: if not error: quota_command = "/run/current-system/sw/bin/quota 2>/dev/null | awk 'NR==3 {print $2, $3}'" - _, ssh_stdout, _ = ssh.exec_command(quota_command, get_pty=True) + _, ssh_stdout, _ = ssh.exec_command(quota_command, get_pty=False) sizes = ssh_stdout.read().decode().split() if len(sizes) == 2: bytes_used, bytes_total = (int(size) * 1024 for size in sizes) diff --git a/ocfweb/account/templates/account/info/index.html b/ocfweb/account/templates/account/info/index.html index 7f5ba7d57..66449c836 100644 --- a/ocfweb/account/templates/account/info/index.html +++ b/ocfweb/account/templates/account/info/index.html @@ -37,7 +37,7 @@ {% endfor %} {% else %} -

    Your account is not yet set up for web virtual hosting.

    +

    Your account is not yet set up for web virtual hosting.

    {% endif %} {% if vhosts_app %}

    Your account has web application hosting at:

    From 4540e54f9d680633eed01996485f7236c212297a Mon Sep 17 00:00:00 2001 From: Andi Chang Date: Sun, 7 Jun 2026 00:29:00 -0700 Subject: [PATCH 16/16] Remove commands page --- ocfweb/account/commands.py | 113 ------------------ .../templates/account/commands/index.html | 48 -------- .../account/templates/account/info/index.html | 2 +- ocfweb/account/urls.py | 2 - 4 files changed, 1 insertion(+), 164 deletions(-) delete mode 100644 ocfweb/account/commands.py delete mode 100644 ocfweb/account/templates/account/commands/index.html diff --git a/ocfweb/account/commands.py b/ocfweb/account/commands.py deleted file mode 100644 index 72ca6fb56..000000000 --- a/ocfweb/account/commands.py +++ /dev/null @@ -1,113 +0,0 @@ -from django import forms -from django.forms import widgets -from django.http import HttpRequest -from django.http import HttpResponse -from django.shortcuts import render -from paramiko import AuthenticationException -from paramiko import SSHClient -from paramiko.hostkeys import HostKeyEntry - -from ocfweb.component.forms import Form - - -def commands(request: HttpRequest) -> HttpResponse: - command_to_run = '' - output = '' - error = '' - if request.method == 'POST': - form = CommandForm(request.POST) - if form.is_valid(): - username = form.cleaned_data['username'] - password = form.cleaned_data['password'] - - command_to_run = form.cleaned_data['command_to_run'] - - ssh = SSHClient() - - host_keys = ssh.get_host_keys() - entry_ed25519 = HostKeyEntry.from_line( - 'ssh.ocf.berkeley.edu ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPm+RlDujsxQyxFTEOCTeImSBDvr63cL8Kg+rNrH6NK8', # noqa - ) - entry_rsa = HostKeyEntry.from_line( - 'ssh.ocf.berkeley.edu ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqMkHVVoMl8md25iky7e2Xe3ARaC4H1PbIpv5Y+xT4KOT17gGvFSmfjGyW9P8ZTyqxq560iWdyELIn7efaGPbkUo9retcnT6WLmuh9nRIYwb6w7BGEEvlblBmH27Fkgt7JQ6+1sr5teuABfIMg22WTQAeDQe1jg0XsPu36OjbC7HjA3BXsiNBpxKDolYIXWzOD+r9FxZLP0lawh8dl//O5FW4ha1IbHklq2i9Mgl79wAH3jxf66kQJTvLmalKnQ0Dbp2+vYGGhIjVFXlGSzKsHAVhuVD6TBXZbxWOYoXanS7CC43MrEtBYYnc6zMn/k/rH0V+WeRhuzTnr/OZGJbBBw==', # noqa - ) - host_keys.add( - 'ssh.ocf.berkeley.edu', - 'ssh-ed25519', - entry_ed25519.key, - ) - host_keys.add( - 'ssh.ocf.berkeley.edu', - 'ssh-rsa', - entry_rsa.key, - ) - - try: - ssh.connect( - 'ssh.ocf.berkeley.edu', - username=username, - password=password, - ) - except AuthenticationException: - error = 'Authentication failed. Did you type the wrong username or password?' - - if not error: - if command_to_run == 'paper': - command_to_run = f"/run/current-system/sw/bin/paper view {username}" # noqa - _, ssh_stdout, ssh_stderr = ssh.exec_command(command_to_run, get_pty=False) - output = ssh_stdout.read().decode() - error = ssh_stderr.read().decode() - else: - form = CommandForm() - - return render( - request, - 'account/commands/index.html', { - 'title': 'Account commands', - 'form': form, - 'command': command_to_run, - 'output': output, - 'error': error, - }, - ) - - -class CommandForm(Form): - username = forms.CharField( - label='OCF username', - min_length=3, - max_length=16, - ) - password = forms.CharField( - widget=forms.PasswordInput, - label='Password', - min_length=8, - max_length=256, - ) - - COMMAND_CHOICES = ( - ( - 'paper', - 'paper quota -- how many pages you have remaining this semester', - ), - ( - '/usr/bin/quota -vQs', - 'disk quota -- how much disk space you have used and how much you ' + - 'have left', - ), - ( - '/opt/share/utils/bin/makehttp', - 'makehttp -- set up the web space for your OCF account', - ), - ( - 'echo yes | /opt/share/utils/bin/makemysql', - 'makemysql -- reset your MySQL database password, or create a new ' + - 'MySQL database (copy down the password somewhere secure)', - ), - ) - - command_to_run = forms.ChoiceField( - choices=COMMAND_CHOICES, - label='Command to run', - widget=widgets.RadioSelect, - ) diff --git a/ocfweb/account/templates/account/commands/index.html b/ocfweb/account/templates/account/commands/index.html deleted file mode 100644 index 47105be4b..000000000 --- a/ocfweb/account/templates/account/commands/index.html +++ /dev/null @@ -1,48 +0,0 @@ -{% extends "base.html" %} -{% load bootstrap %} - -{% block content %} -
    -
    -

    Run an account command over the web.

    -

    - The commands you see listed below are all available to run via - SSH. For convenience, we - also let you run them from the web. -

    - -
    - {% csrf_token %} - {{form | bootstrap}} - -
    - - {% if command %} -
    -

    Command being run:

    {{command}}

    - {% endif %} - - {% if output %} -
    - {{ output|linebreaks }} -
    - {% endif %} - - {% if error %} -

    {{ error|linebreaks }}

    - {% endif %} -
    - -
    -

    - Note: You may find that running these commands - via SSH is more convenient. SSH also allows you access to the - full range of account management tools and other services we - offer. -

    -

    - For more information, see our documentation.

    -

    -
    -
    -{% endblock %} diff --git a/ocfweb/account/templates/account/info/index.html b/ocfweb/account/templates/account/info/index.html index 66449c836..eebe3583c 100644 --- a/ocfweb/account/templates/account/info/index.html +++ b/ocfweb/account/templates/account/info/index.html @@ -62,7 +62,7 @@ {% else %}

    Only group, faculty, and staff accounts are eligible for virtual hosting. Sorry!

    {% endif %} -

    You can also check this information via SSH by running paper view {{user}}, quota -vs, and check {{user}}.

    +

    You can also check this information via SSH by running paper view {{user}}, quota -vs, and check {{user}}. SSH, including our web terminal, gives further access to actions such as editing web space files.

    For our policies on printing, file storage, and virtual hosting, refer to the relevant documentation:

    • Printing
    • diff --git a/ocfweb/account/urls.py b/ocfweb/account/urls.py index 2dd96e700..5c3b60cf6 100644 --- a/ocfweb/account/urls.py +++ b/ocfweb/account/urls.py @@ -1,7 +1,6 @@ from django.urls import re_path from ocfweb.account.chpass import change_password -from ocfweb.account.commands import commands from ocfweb.account.info import account_info from ocfweb.account.register import account_created from ocfweb.account.register import account_pending @@ -19,7 +18,6 @@ urlpatterns = [ re_path(r'^password/$', change_password, name='change_password'), - re_path(r'^commands/$', commands, name='commands'), re_path(r'^info/$', account_info, name='account_info'), # account creation