Skip to content

Instantly share code, notes, and snippets.

View atomkirk's full-sized avatar

Adam Kirk atomkirk

View GitHub Profile
@atomkirk
atomkirk / download-zoom-recording.md
Last active January 13, 2026 17:04
Force download a zoom recording
  1. Open dev tools
  2. Search for the <video… tag.
  3. Copy the source URL
  4. Right click on the body tag and click Edit as HTML
  5. Add an a link with the src right inside the body tag like:
<body>
  <a href="url-you-copied">download</a>
  ...
@atomkirk
atomkirk / gist:6d1a38a1636f7faa70de
Last active January 1, 2026 19:50
The Ecstasy and Disappointment of App Store Rankings

In 2010, Rob Foster and I released our first app, Calvetica, to the app store. It was one of the first two or three, if not the first, third-party calendar apps to use the new Event Kit that was released with iOS 4. The first day we sold around 20 copies, which wasn't bad I guess, but we're pie-in-the-sky dreamers, so we were a little disappointed. The next day, I woke to see we had sold 700 copies, and it got better and stayed that way for a while. It was the most excitement I'd felt since Christmas as a kid, watching our app climb the app store rankings. We made a lot of money.

Then, to our confusion and great disappointment, the rankings started to slip. Then, John Gruber linked to it on Daring Fireball and we sold about 2000 a day for a while and go to the #2 spot in productively and the #50 spot in the whole App Store. Thank you John! But, that was also just a spike. We began to watch our app sink again and wondered if and when it would stop. I bet if any app developers are reading this, they are shakin

@atomkirk
atomkirk / stop-all-docker.md
Created February 9, 2021 14:25
Stop all Docker containers

I will often run this command to make sure all my docker containers are stopped and removed before running docker-compose up. Sometimes when you restart your system, old containers will start back up automatically in the background.

docker stop $(docker ps -aq) && docker rm $(docker ps -aq)
defmodule Integrator.Scheduler do
use Oban.Worker, queue: :events, max_attempts: 5
require Logger
import Ecto.Query
require Logger
alias Integrator.Intercom
alias Integrator.Notion
alias Integrator.UserMatcher
alias Integrator.Slack
alias Integrator.TicketGenerator
@atomkirk
atomkirk / hungarian.ex
Last active August 1, 2025 19:14
Hungarian/Munkres algorithm in Elixir
defmodule Hungarian do
@moduledoc """
Written by Adam Kirk – Jan 18, 2020
Most helpful resources used:
https://www.youtube.com/watch?v=dQDZNHwuuOY
https://www.youtube.com/watch?v=cQ5MsiGaDY8
https://www.geeksforgeeks.org/hungarian-algorithm-assignment-problem-set-1-introduction/
@atomkirk
atomkirk / cloud-files.md
Last active April 8, 2025 12:15
Storing files on S3 with Elixir

I have this abstraction in my application code called a "CloudFile". This is where I store in the database information about files on S3 and it gives me a resource for other resources to own. For example, a user would have an avatar_cloud_file_id. On the front-end, I would load this relationship and display the avatar with user.avatar_cloud_file.download_url

defmodule RL.CloudFile do
  use Ecto.Schema
  import Ecto.Changeset

  @timestamps_opts type: :utc_datetime_usec
@atomkirk
atomkirk / ios-camera.html
Created March 13, 2020 04:49
iOS Safari Camera API
<video id="player" autoplay muted playsinline> </video>
<button id="capture">Capture</button>
<canvas id="canvas" width=320 height=240></canvas>
<script>
const player = document.getElementById('player');
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const captureButton = document.getElementById('capture');
const constraints = {
@atomkirk
atomkirk / hide-all-annotations.js
Last active December 28, 2024 15:40
hide all github annotations on a PR
javascript:(function() {document.querySelectorAll('.js-inline-annotations').forEach(function(annotation) {if (annotation.innerText.includes('coverbot')) {annotation.remove();}});})();
@atomkirk
atomkirk / soc2-by-myself.md
Last active August 6, 2024 20:50
I got SOC 2 certified by myself

I got SOC 2 certified by myself

From April 10 to May 2, 2024, I did all the work myself to get SOC 2 Type II certified. I'm now half way through the observation period to get Type II. The observation period is easy, you just have to babysit the controls. Getting to Type I is much harder. It took me somewhere around 100 hours.

image

SOC 2 is a security framework that, for many customers, eliminates the need to have you, as a vendor, fill out a lengthy security questionnaire. The SOC 2 controls and audits ask pretty much all the questions you'd get from a customer's security team. In fact, that is a great way to think about SOC 2. It's essentially a very thorough questionnaire you fill out once, an independent auditor forms an opinion of it in a report, and you share with all your customers.

There are two parts to SOC 2. The initial audit, where an auditor writes a Type I report sharing their opinion of your current setup. Then there's a 3 month observ