Skip to content

Instantly share code, notes, and snippets.

View ianfoo's full-sized avatar
💭
staring into the sun ☀️

Ian Molee ianfoo

💭
staring into the sun ☀️
  • Seattle WA
View GitHub Profile
@ianfoo
ianfoo / INSTRUCTIONS.md
Created February 27, 2025 02:16
Bulk download Kindle books from Amazon

Bulk download all your Kindle books, while you can

Today, Feb 26 2025, is the last day that Amazon will allow you to download your Kindle books. Unfortunately, Amazon has no provision for downloading books in bulk. However, some kind individuals have created tools to help with this. I've tried a few, and will share the one that actually worked for me, and step-by-step instructions do use it yourself. This is intended for an audience that are not power users.

What you will need

  • Google Chrome
  • You can possibly use another browser, but Chrome is the one where it worked for me.
@ianfoo
ianfoo / jempradio-nowplaying.30s.sh
Created May 24, 2023 01:17
xbar action to show current playing selection on JEMP radio, with help from https://github.com/ianfoo/ph and jq
#!/usr/bin/env bash
PATH=$HOME/bin:/opt/homebrew/bin:$PATH
output_vars () {
ph --format json | jq -r '"TITLE=\"\(.title)\"\nARTIST=\"\(.artist)\"\nDATE=\"\(.performance_time)\""'
}
eval $(output_vars)
@ianfoo
ianfoo / serializable_decimal.py
Created March 29, 2023 00:11
Prototype for a serializable decimal field for Marshmallow
from decimal import Decimal
from marshmallow import Schema, ValidationError, fields, post_load
class SerializableDecimal(fields.Field):
def _serialize(self, value, attr, obj, **kwargs):
if value is None:
return None
if not isinstance(value, Decimal):
raise ValidationError("must be a Decimal value")
@ianfoo
ianfoo / test_different_json_dumps.py
Created March 28, 2023 22:17
Python's stdlib json.dumps and Flask's jsonify render JSON slightly differently
import json
import flask
from hamcrest import assert_that, is_
"""
json.dumps, by default, will include a bit of whitespace, using default
separators (', ', ': ') for item_separator and key_separator, respectively.
Flask defaults to a slightly more compact representation, using (',', ':')
@ianfoo
ianfoo / golang-get
Last active January 21, 2024 02:58
Install/switch version of Go on a Linux host
#! /usr/bin/env bash
#
# This script downloads and installs Go from http://go.dev. If no version is
# provided, it will install the latest released version as shown by
# https://go.dev/VERSION. If there is already a Go installed, the script will
# replace that installation with the new one (though it will not delete the old
# installation). If a directory exists in BASE_DIR indicating that the
# requested version is already present, the download will be skipped.
#
# Requirements: curl, GNU stow
@ianfoo
ianfoo / shell-log.txt
Created February 10, 2023 01:17
MySQL insert transaction with Python
➜ ~ python /tmp/tx.py
(3, 'from python, at 2023-02-10 01:11:07.107806')
(4, 'from python, at 2023-02-10 01:11:07.108763')
(5, 'from python, at 2023-02-10 01:11:07.109734')
(6, 'from python, at 2023-02-10 01:11:07.110544')
(7, 'from python, at 2023-02-10 01:11:07.111276')
➜ ~ mysql -P 33306 -h 127.0.0.1 -u root -e "select * from test.foo;"
+----+--------------------------------------------+
| id | mapping |
+----+--------------------------------------------+
@ianfoo
ianfoo / window-product.py
Created January 26, 2023 03:29
Calculate the product of a sliding window of integers in a list (Python)
from functools import reduce
def window_product(input: list[int], current_pos: int, window_size: int) -> int:
window_bound = max(current_pos + 1 - window_size, 0)
window = input[window_bound : current_pos + 1]
product = reduce(lambda a, b: a*b, window)
return product
def window_products(input: list[int], window_size: int) -> list[int]:
@ianfoo
ianfoo / mkgif
Created July 18, 2022 20:37
Make a reasonable-quality GIF from a video clip
#!/usr/bin/env bash
set -Eeuo pipefail
if [[ $# == 0 ]]; then
echo >&2 "movie filename and output filename is required"
exit 1
fi
input_file="$1"
// Generate a test input for rmchar.go.
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
@ianfoo
ianfoo / all-files.txt
Last active June 9, 2021 04:43
Cheap-ass filepath.WalkDir example
.
./all-files.txt
./sub1
./sub1/foo.toml
./sub1/foo.json
./sub1/bar.json
./sub1/foo.yaml
./sub1/sub2
./sub1/sub2/foo.blarg
./sub1/sub2/blarg.yamllllll