Skip to content

Instantly share code, notes, and snippets.

View battis's full-sized avatar

Seth Battis battis

View GitHub Profile
@battis
battis / README.md
Created March 27, 2025 15:45
Publish a Blackbaud SKY API App

Publish a Blackbaud SKY API app

  1. Create an account on the SKY API developer portal if you don't already have one. This will need to be provisioned through your school.
  2. Create a new application under your account in My applications
  3. While you don't have to have your app deployed yet, you will need to know where it will be deployed, as you need a few URLs:
  • The URL to the app itself
  • A redirect URI for OAuth 2.0 authentication (use a PHP or TypeScript library for this!)
  1. Make a note of the Application ID (OAuth client_id) and Primary application secret (OAuth client_secret) (Blackbaud recommends rotating your secrets every 90 days, and provides a primary and secondary to facilitate doing this without a break in service).
  2. Make a note of your subscription key under [My subscriptions](h
@battis
battis / manageLearningProfiles.js
Created August 21, 2024 17:11
Parse the web view of Blackbaud's "Manage Learning Profiles" into a TSV list
/*
* Parse the list of learning profiles under
* Academics > Grades > Grades Management > Manage Learning Profiles
*
* The output is essentially a TSV.
*
* There is a known bug in Blackbaud were past students' (not alums) names are
* not shown (Case 019825709). The names have to be deduced by actually viewing
* the learning profile. All of these names are at the start of the list.
*/
@battis
battis / getUserRevision.js
Created April 11, 2024 18:13
Get content of user-attributed revision to a Google Sheet
/*
* Seth Battis
* Google Apps Script
* No external dependencies
*/
/**
* @param fileId: string - Google Sheets document ID
* @param tileIndex: number - index of "combined revisions" shown in versions UI
*/
@battis
battis / fileHistory.js
Last active February 9, 2025 11:47
List revisions for a Google Drive file
/*
* Seth Battis
* Google Apps Script
* No external dependencies
*/
function fileHistory(fileId) {
const response = JSON.parse(UrlFetchApp.fetch(`https://www.googleapis.com/drive/v3/files/${fileId}/revisions`, {
headers: {
Authorization: `Bearer ${ScriptApp.getOAuthToken()}`
}
@battis
battis / Calendar.ts
Last active September 29, 2023 13:40
import g from '@battis/gas-lighter';
const colors = {
'Pale Blue': '1',
'Pale Green': '2',
Mauve: '3',
'Pale Red': '4',
Yellow: '5',
Orange: '6',
Cyan: '7',
@battis
battis / README.md
Last active August 20, 2024 14:28
Publish a Google Workspace add-on written in TypeScript using @google/clasp

Publish a Google Workspace Add-on

Based on Google documentation

I have attached my draft version of a setup script for these projects (including my frequent need to connect to the Blackbaud SKY API), but not being able to script a number of key publishing steps makes it not really worthwhile. This assumes that you already have node installed on your computer to build the project.

In the browser

  1. Create a new Google Cloud project in the console.
  2. Under APIs & Services, configure OAuth Consent. I usually publish with Internal users (no need for Google review). Add the OAuth Scopes listed in the projects appscripts.json file to the OAuth Consent.
  3. Enable the Google Workspace Markplace SDK API.
@battis
battis / Secrets.php
Created November 22, 2022 16:14
Accessing Google Cloud Secrets API
<?php
use Google\Cloud\SecretManager\V1\SecretManagerServiceClient;
class Secrets {
private static ?SecretManagerServiceClient $client = null;
private function __construct()
{}
@battis
battis / README.md
Last active May 27, 2022 13:42
Generate "realistic" nested folders of (random-content) files on macOS
Usage: mkdummy [-f files] [-n bytes] [-x bytes] [-s bytes] [-d depth] [-r [0..99)] [path]
  -d: [D]epth of recursive folder nesting
  -f: maximum number of [F]iles
  -n: mi[N]imum file size (in bytes)
  -r: probabilty of [R]ecursive folder nesting [0..100), default 10
  -s: approximate amount of disk[S]pace to consume (in bytes)
  -x: ma[X]imum file size (in bytes)
@battis
battis / input.scss
Created July 18, 2021 21:17
Generated by SassMeister.com.
@use "sass:color";
@use "sass:meta";
/* base colors */
$white: white;
$gray: hsl(0, 0%, 75%);
$black: black;
$focus: hsl(205, 100%, 50%);
$danger: hsl(7, 80%, 50%);
@battis
battis / OrientationTracker.java
Created April 22, 2021 13:03
OrientationTracker
package org.firstinspires.ftc.teamcode;
import com.qualcomm.hardware.bosch.BNO055IMU;
import com.qualcomm.hardware.bosch.JustLoggingAccelerationIntegrator;
import org.firstinspires.ftc.robotcore.external.Func;
import org.firstinspires.ftc.robotcore.external.navigation.Acceleration;
import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
import org.firstinspires.ftc.robotcore.external.navigation.AxesOrder;
import org.firstinspires.ftc.robotcore.external.navigation.AxesReference;