Skip to content

Instantly share code, notes, and snippets.

View rinogo's full-sized avatar

Rich Christiansen rinogo

  • Social5
  • Utah, USA
View GitHub Profile
@rinogo
rinogo / zoomMuteState.1s.scpt
Created February 3, 2023 16:15
Applescripts to use with Swiftbar for showing status of Zoom camera and microphone in the macOS menu bar. Paired with shortcuts in the Zoom app, this is an easy way to toggle Zoom's audio and video on and off.
#!/usr/bin/osascript
# <bitbar.title>zoomMuteState</bitbar.title>
# <bitbar.version>v1.0</bitbar.version>
# <bitbar.author>nickjvturner</bitbar.author>
# <bitbar.author.github>nickjvturner</bitbar.author.github>
# <bitbar.desc>Zoom Mute State</bitbar.desc>
# <bitbar.image>http://www.hosted-somewhere/pluginimage</bitbar.image>
# <bitbar.dependencies>Applescript</bitbar.dependencies>
# <bitbar.abouturl>http://url-to-about.com/</bitbar.abouturl>
@rinogo
rinogo / Heap.js
Last active September 14, 2022 18:53
Reliable and copy-pasteable JavaScript Heap/MinHeap/MaxHeap implementation
//Source: https://gist.github.com/rinogo/24940fe6d650ed8bd54d17528ffd3dae
//Originally from: https://github.com/datastructures-js/heap
/**
* @license MIT
* @copyright 2020 Eyas Ranjous <eyas.ranjous@gmail.com>
*
* @class
*/
class Heap {
@rinogo
rinogo / convert-facebook-exported-friends.js
Last active July 27, 2022 23:56
Convert exported/downloaded Facebook friends file into a simple list of names or links (e.g. LinkedIn search URLs)
/*
Instructions:
1. Download your contacts from Facebook's Settings area. When prompted to choose certain categories of data to export, you only need to select the "Friends" option.
2. You'll eventually be sent an email with a link to download your data.
3. Download the zip file and extract its contents. Within the `friends_and_followers` folder, open `friends.json`.
4. Copy the contents of that file into the line below marked, "Replace this line...".
5. In Chrome, type Cmd + Opt + J to open the Javascript Console or access View > Developer > Javascript Console.
6. Copy this entire file (with your data substituted at the appropriate line) into the Javascript Console and hit enter to execute the command.
7. The Console should generate a list of just the names of your friends which can be used however you like (e.g. for uploading to another service). There should be a small "Copy" button you can use to copy out the data.
*/
@rinogo
rinogo / convert-urls-to-origins.js
Created April 12, 2022 02:55
[Convert URLs to origins (domains)] Convert a list of full URLs into just origins (just the base domains with the protocols)
//Convert a list of full URLs into just origins (just the base domains with the protocols)
let s = '';
['https://www.whatever.com/narf',
'https://beta.something.co.uk/?3920#fjfjf'].map((u) => {
let url = new URL(u);
s += url.origin + '\n';
});
console.log(s);
@rinogo
rinogo / job.service.spec.ts
Last active December 3, 2023 14:52
Integration Testing a NestJS Service that leverages Prisma
import { Test, TestingModule } from '@nestjs/testing';
import { PrismaService } from '../prisma.service';
import { JobService } from './job.service';
import * as crypto from 'crypto';
describe('JobService', () => {
let service: JobService;
let prisma: PrismaService;
beforeEach(async () => {
@rinogo
rinogo / simple-email-debug.php
Created April 28, 2021 16:01
[Simple email debug] Instead of a bunch of `var_dump()` or `echo` statements (which can break AJAX responses, etc.), use these simple `mail()` lines.
//String
mail("me@example.com", __FILE__ . ":" . __LINE__, "Example");
//Export variable
mail("me@example.com", __FILE__ . ":" . __LINE__, var_export($alternative_image, true));
@rinogo
rinogo / test-brisk.py
Created April 14, 2021 19:01
BRISK keypoint detection and brute force matching using OpenCV (Source: https://stackoverflow.com/a/65863713/114558)
# Imports
import cv2 as cv
import matplotlib.pyplot as plt
import sys
# Open and convert the input and training-set image from BGR to GRAYSCALE
image1 = cv.imread(filename = sys.argv[1],
flags = cv.IMREAD_GRAYSCALE)
image2 = cv.imread(filename = sys.argv[2],
@rinogo
rinogo / call-with-trackbars.py
Last active April 30, 2021 23:21
An OpenCV utility function for displaying a set of easily-configurable trackbars and providing their results to an arbitrary callback - useful for quick prototyping and testing
#Usage: `python call-with-trackbars.py example.jpg`
import sys
import cv2
#### Example usage ####
def edge_detect(p):
edged = cv2.Canny(p["img"], p["low"] * 15, p["high"] * 15, apertureSize = (p["aperture"] * 2) + 3)
cv2.imshow("Edged", edged)
@rinogo
rinogo / optimal-resize.py
Created March 31, 2021 18:50
Optimally resize an image so that its line height is approximately 32 pixels (Keywords: OpenCV, Tesseract, OCR)
#Optimally resize `img` according to the bounding boxes specified in `boxes` (which is simply the (pruned) results from `pytesseract.image_to_data()`).
#Tesseract performs optimally when capital letters are ~32px tall (https://groups.google.com/g/tesseract-ocr/c/Wdh_JJwnw94/m/24JHDYQbBQAJ). Smaller text obviously can't be OCR'd as accurately, but weirdly enough, larger text causes problems as well. So, this function uses the bounding boxes we've found and resizes the image so that the median line height should be ~32px.
def optimal_resize(img, boxes):
median_height = np.median(boxes["height"])
target_height = 32 #See https://groups.google.com/g/tesseract-ocr/c/Wdh_JJwnw94/m/24JHDYQbBQAJ
scale_factor = target_height / median_height
print("Scale factor: " + str(scale_factor))
#If the image is already within `skip_percentage` percent of the target size, just return the original image (it's better to skip resizing if we can)
skip_percentage = 0.07
@rinogo
rinogo / playwright-wait-for-mutation-to-stop.js
Last active July 29, 2022 21:45
Wait for an element to remain unchanged for a period of time. Useful for waiting for asynchronous (AJAX) updates. Playwright, ES6, Promise, Mutation, MutationObserver
///////
//To test this code, execute it locally or copy/paste it at https://try.playwright.tech/
//Usage example: `await waitForMutationToStop(await page.$("#container"));`
///////
// @ts-check
const playwright = require("playwright");
//Wait for `elem` to have no mutations for a period of `noMutationDuration` ms. If `timeout` ms elapse without a "no mutation" period of sufficient length, throw an error. If `waitForFirstMutation` is true, wait until the first mutation before starting to wait for the `noMutationDuration` period.
const waitForMutationToStop = async (elem, noMutationDuration = 3000, timeout = 60000, waitForFirstMutation = true) => {