Skip to content

Instantly share code, notes, and snippets.

@natanlao
natanlao / contacts.md
Last active January 12, 2023 18:30
Importing birthdays and contact images from Google Contacts to Fastmail

Fastmail offers an automated Google Contacts [import feature][import], and also supports importing contacts by CSV and vCard. Unfortunately, I've noticed that all of these import features are lossy. Regardless of import method:

  • Contact profile pictures stored in Google Contacts are not imported. (Google exports profile photos by including a link to the photo in the CSV.)
  • Birthdays without associated years (i.e., just the month and day) are sometimes not imported at all.
  • Empty ('') phone numbers are sometimes added to contacts. (This issue may have been a result of me trying to fix the two issues above, and not Fastmail
@natanlao
natanlao / reminders.md
Created September 29, 2020 06:24
Tracking recurring reminders

I use my Fastmail calendar to track recurring reminders, like regular maintenance, or scheduling a doctor's appointment, or requesting a credit report, etc. I create each reminder as an all-day event on a calendar only for reminders, and configure each event to send me an email reminder on the day of the event.

This approach is simple and flexible:

  • Recurrence rules make it trivial to configure a task to repeat at any interval, whether it be on the nth day of the month every m months, or every other year, etc.
  • With an Inbox Zero approach, reminders stay out of the way until they're relevant, and can be
@natanlao
natanlao / perl-multistage.md
Created August 8, 2020 00:25
Multi-stage Dockerfiles with perl and perl-slim

The benefits of using multi-stage Docker builds is well-known. Using multi-stage builds with a pure Perl setup is trivial -- all it involves is copying the /usr/local/lib/perl5 directory:

FROM perl:5.28 as builder
COPY cpanfile cpanfile
RUN cpanm --installdeps .
@natanlao
natanlao / recovery-codes.md
Last active April 25, 2021 22:16
Managing multifactor authentication recovery codes

I store my multifactor authentication recovery codes in plaintext on a flash drive. The flash drive is stored in a safe place that can only realistically be accessed by me. I periodically generate a PDF from these codes and print it.

There's a good amount of reading on ways that other people manage this:

In choosing this approach, I considered not only the possibility that I would need to recover access to an MFA-protected account, but also the possibility

@natanlao
natanlao / github-global-node-id.md
Last active December 27, 2023 07:04
Translating GitHub resource IDs to global node IDs

GitHub associates a unique resource ID (or "database ID" or just "ID") with each API-accessible resource. For example, each [issue][issue-id], [repository][repository-id], and [user][user-id] has a global ID. In my limited experience with it, GitHub's REST API generally does not expose endpoints by which resources can be queried by ID (though it does have some [undocumented endpoints][repo-rest]). These resource IDs have been superseded by distinct [global node IDs][global-ids] (node_id). GitHub's GraphQL API allows retrieval of a node by its ID, called a "direct node lookup".

As you can tell, you likely don't have much reason to interact with the older

@natanlao
natanlao / candidates.tsv
Last active May 30, 2020 17:48
UC Santa Cruz Student Union Assembly elections history (1999-2020)
We can make this file beautiful and searchable if this error is corrected: It looks like row 7 should actually have 10 columns, instead of 9. in line 6.
Election Term Position Function Name Votes Proportion Winner Links Comments/Notes
1999 1999 - 2000 Campus Office Director Internal Affairs Eric Gonzalez 2046 100 TRUE https://deanofstudents.ucsc.edu/elections/pdf/ballots-results/1999-campus-elections-results.pdf
1999 1999 - 2000 Chair President Maria Catalina 720 28.1 FALSE https://deanofstudents.ucsc.edu/elections/pdf/ballots-results/1999-campus-elections-results.pdf
1999 1999 - 2000 Chair President Dylan Smith 881 34.4 FALSE https://deanofstudents.ucsc.edu/elections/pdf/ballots-results/1999-campus-elections-results.pdf
1999 1999 - 2000 Chair President Kirti Srivastava 957 37.4 TRUE https://deanofstudents.ucsc.edu/elections/pdf/ballots-results/1999-campus-elections-results.pdf
1999 1999 - 2000 Lobby Corps Director External Affairs Carolyn Boyd 655 30.4 FALSE https://deanofstudents.ucsc.edu/elections/pdf/ballots-results/1999-campus-elections-results.pdf
1999 1999 - 2000 Lobby Corps Director External Affairs Patrick McHugh 522 24.2 FALSE https://deanofstu
@natanlao
natanlao / volume.md
Last active August 9, 2021 19:46
docker-compose: no declaration was found in the volumes section

If, when doing something like docker-compose up, you run into an error like this:

ERROR: Named volume "server/db:/usr/share/nginx/html/db:rw" is used in service "web" but no declaration was found in the volumes section.

You're missing a leading ./, so, for example:

volumes:
 - 'server/db:/usr/share/nginx/html/db'
@natanlao
natanlao / ccpa.md
Last active April 14, 2021 18:14
CCPA wall of shame

Over the last few months, I've been cleaning up after myself and filing CCPA requests where I can. Here are some of the less-friendly companies that I've encountered in this process.

Sift

Signed me up for marketing emails using the email address I provided for my CCPA request.

Equifax

The worst one of them yet.

@natanlao
natanlao / data.tsv
Last active March 22, 2020 18:51
NearlyFreeSpeechNET deposit scraping
payment grossfee rebate netfee deposit
$0.50 -$4.00 +$3.58 -$0.42 $0.08
$0.51 -$4.00 +$3.58 -$0.42 $0.09
$0.52 -$4.00 +$3.58 -$0.42 $0.10
$0.53 -$4.00 +$3.58 -$0.42 $0.11
$0.54 -$4.00 +$3.58 -$0.42 $0.12
$0.55 -$4.00 +$3.58 -$0.42 $0.13
$0.56 -$4.00 +$3.58 -$0.42 $0.14
$0.57 -$4.00 +$3.58 -$0.42 $0.15
$0.58 -$4.00 +$3.58 -$0.42 $0.16
@natanlao
natanlao / caffeine.md
Created September 15, 2019 18:49
Caffeinating a process that is already running

bash-3.2$ caffeinate -d $(while true; do if ! kill -0 $PID; then sleep 5; exit; fi; done)