It’s not the tool I use around the house the most. That’s probably the Skeletool I keep on my hip or my drill. I actually look forward to seeing how fast I can assemble flatpack furniture with my drill.
But the Dremel makes little impossible things possible in a small apartment.
Like when the top for my daughter’s favorite water bottle broke.
It’s a very short task to use the carving attachments to cut the sharp bits off and then use a sander to round over the edges.
Little things become easy. Or if we need to cut off a section of our outdoor tiles or small metals sections. If you can’t fit it in tin snips, you can still use the metal cutting disks to cut through it or score things enough to snap.
I just came back from AWS:ReInvent 2023 and wanted to jot down some ideas I had about how to improve the experience next time.
First impressions – this conference was extremely well-run, very organized and FULL of helpful people eager to get you where you are going. Just like everything in Las Vegas, it felt like a thing designed to process you, a pipeline oriented around directing a sprayhose of humans to various areas. It’s people and crowd management at scale. That’s what it is and if you give up your individuality you can get whisked around and processed quickly. Swimming against the stream doesn’t work well.
Do’s and Don’ts:
Do register early and get flights and hotel rooms early. As a late registrant, I stayed in a non-conference hotel and had to do a lot of travel to get started where other attendees were.
Do try to keep most sessions within a venue. The transportation options are good, but walking in Las Vegas is a fool’s game. The conference centers are massive. The casinos are massive. It takes forever to get around. Even if you get on a shuttle, there is traffic. It’s difficult to move between venues.
Do reserve sessions seats early when they come out. Many sessions I wanted to attend were fully-reserved. This isn’t a big problem as there is plenty of space for walk-ins, but it means having to queue up for the walk-in space early, which limits your time and makes it hard to switch venues.
Do leave room for breakfast and lunch. It’s grueling focusing intently for long periods. Your brain needs energy for it. The AWS ReInvent folks provide meals for breakfast and lunch, but it’s easy to miss them if you have a session at that time. This isn’t such a big deal, except the venues are massive, so it takes a long time to get out and get to somewhere else that has decent food. The food at the venues was much healthier and better than a lot of the easy-to-get food in the casinos etc.
Don’t get too hyped about RePlay unless that’s really your jam. I’m sad I didn’t get there in time for the Linda Lindas, but conference wrap parties in general seem like getting on a bus, getting a few beverages, watching the band, getting back on a bus. Our bus got stuck behind tons of other busses on the road and we eventually walked to the venue. It’s a logistics nightmare to try to get 65K people in and out of a single concert in a reasonable timeframe. I had a lot more fun doing side events with my co-workers like checking out the Sphere and going to OmegaMart.
Don’t go to “Builder’s Sessions”. Your mileage may vary, but I found these uniformly unhelpful. The session is a very brief talk, then following a tutorial at a rapid pace. There is very little context. The session names seemed interesting, but generally they were not educational – they were just a way to step quickly through a pre-configured tutorial. There was no explanation of WHY to do anything – many of the instructions were “copy paste this text”. At the end of any of these sessions, there was no time to ask questions and I don’t think I got much from them. I don’t think anyone who attended one added any new skill.
Do go to big talks in big rooms. The best talks get the big rooms. Figure out capacity and try to attend these. The best talk I attended, “Building Observability to Increase Resiliency” was in a big room, and I loved it.
Do meet with product managers for products you use. You get a lot of information and they can speak about things that aren’t published or take your specific nuanced feedback about usage. I found this super useful. I got to talk about what would specifically impact my team and our way of working.
Do watch the keynotes via stream in your hotel room. They don’t hand out any special goodies. The hotel is comfy. The editing is good.
Do register for new sessions after they keynote. They unlock new sessions related to the just announced stuff. Most of the just announced stuff didn’t really thrill me, but there is a helpful filter in the catalog for “just launched” sessions.
Most of the sessions I attended really were laser focused on the AWS product, which, you know, fair enough. It’s not a generalist conference. But my favorite session took great lessons about a subject and then applied them to how to use AWS products.
Here is how platforms die: first, they are good to their users; then they abuse their users to make things better for their business customers; finally, they abuse those business customers to claw back all the value for themselves. Then, they die. I call this enshittification, and it is a seemingly inevitable consequence arising from the combination of the ease of changing how a platform allocates value, combined with the nature of a “two sided market,” where a platform sits between buyers and sellers, hold each hostage to the other, raking off an ever-larger share of the value that passes between them.
Lots of folks are known for one-shot takes, but this shows how Spielberg sneaks in gorgeous “oners” that do work without calling attention to themselves.
This essay on Fincher is great, but I love the little golden nugget about how spacing shows the evolving relationship between Mills and Somerset
That title always struck me. Every Frame a Painting. That’s gotta be a bar filmakers strive for. Some make it.
Some movies are just so damn beautiful. Just gorgeous.
Like the one that you like that isn’t my cup of tea.
Might be nice to see an image from it, right there behind all of your terminals and windows and such, set as your wallpaper. If every frame’s a painting, set a random one as your wallpaper whenever I like it.
So here’s the plan. I want it. So I made it for me. You can have it. But here’s the terms of the deal. I made it for me, so if it doesn’t work for you, you have to make it work for you. If it causes you problems, those are not my problems. If you don’t agree, this isn’t for you.
By default, it won’t use the first 5 or last 10 minutes since that’s often the credits. But you can override this.
We’ll find out how many frames are in that remaining part of the movie.
We’ll pick one randomly and extract it from the movie.
Then we’ll set it as your wallpaper. Nice!
Want to change this often? Set up a cron job!
Pulling a single frame out the middle of a movie is CPU intense, so you probably want to use nice in your cron job so it doesn’t interfere with the rest of your work.
Here’s the code, save this in a file called every_frame_a_wallpaper.zsh and then chmod u+x every_frame_wallpaper.zsh
#! /bin/zsh
# This is a pretty processor intensive set of tasks! You should probably nice this script
# as in call it with nice -n 10 "every_frame_a_wallpaper.zsh /path/to/video.mkv"
SCRIPT_NAME=$(basename "$0")
# I like a nice log file for my cron jobs
function LOG() {
echo -e "$(date --iso-8601=seconds): [$SCRIPT_NAME] : $1"
}
# set up some options
local begin_skip_minutes=5
local end_skip_minutes=10
local wallpaper="$HOME/Pictures/wallpaper.png"
local usage=(
"$SCRIPT_NAME [-h|--help]"
"$SCRIPT_NAME [-b|--begin_skip_minutes] [-e|--end_skip_minutes] [<video file path>]"
"Extract a single random frame from a movie and set it as wallpaper"
"By default, skips 5 minutes from the beginning and 10 from the end, but this is overridable"
)
# the docs suck on zparseopts so let this be a reference for next time
# -D pulls parsed flags out of $@
# -F fails if we find a flag that wasn't defined
# -K allows us to set default values without zparseopts overwriting them
# Remember that the first dash is automatically handled, so long options are -opt, not --opt
zparseopts -D -F -K -- \
{h,-help}=flag_help \
{b,-begin_skip_minutes}:=begin_skip_minutes \
{e,-end_skip_minutes}:=end_skip_minutes \
|| return 1
[[ -z "$flag_help" ]] || {print -l $usage && return }
if [[ -z "$@" ]] {
print -l "A video file path is required"
print -l $usage && return
} else {
MOVIE="$@"
}
if [[ $DISPLAY ]]
then
LOG "interactively running, not in cron"
else
LOG "Not running interactively, time to export the session's environment for cron"
export $(xargs -0 -a "/proc/$(pgrep gnome-session -n -U $UID)/environ") 2>/dev/null
fi
LOG "skipping $begin_skip_minutes[-1] minutes from the beginning"
LOG "skipping $end_skip_minutes[-1] minutes from the end"
LOG "outputting the wallpaper to $wallpaper"
LOG "using file $MOVIE"
LOG "Let's get a frame from ${MOVIE}";
LOG "What's the duration of the movie?"
DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 \
$MOVIE);
DURATION=$(printf '%.0f' $DURATION);
LOG "Duration looks like ${DURATION} seconds";
LOG "what's the frame rate?"
FRAMERATE=$(ffprobe -v error -select_streams v:0 \
-show_entries \
stream=r_frame_rate \
-print_format default=nokey=1:noprint_wrappers=1 $MOVIE)
FRAMERATE=$(bc -l <<< "$FRAMERATE");
FRAMERATE=$(printf "%.0f" $FRAMERATE);
LOG "Looks like it's roughly $FRAMERATE"
FRAMECOUNT=$(bc -l <<< "${FRAMERATE} * ${DURATION}");
FRAMECOUNT=$(printf '%.0f' $FRAMECOUNT)
LOG "So the frame count should be ${FRAMECOUNT}";
SKIP_MINUTES=$begin_skip_minutes[-1]
SKIP_CREDITS_MINUTES=$end_skip_minutes[-1]
LOG "We want to skip $SKIP_MINUTES from the beginning and $SKIP_CREDITS_MINUTES from the end".
SKIP_BEGINNING_FRAMES=$(bc -l <<< "${FRAMERATE} * $SKIP_MINUTES * 60");
LOG "So $SKIP_MINUTES * 60 seconds * $FRAMERATE frames per second = $SKIP_BEGINNING_FRAMES frames to skip from the beginning."
SKIP_ENDING_FRAMES=$(bc -l <<< "${FRAMERATE} * $SKIP_CREDITS_MINUTES * 60");
LOG "So $SKIP_CREDITS_MINUTES * 60 seconds * $FRAMERATE frames per second = $SKIP_ENDING_FRAMES frames to skip from the ending."
USEABLE_FRAMES=$(bc -l <<< "$FRAMECOUNT - $SKIP_BEGINNING_FRAMES - $SKIP_ENDING_FRAMES");
UPPER_FRAME=$(bc -l <<<"$FRAMECOUNT - $SKIP_ENDING_FRAMES")
LOG "That leaves us with ${USEABLE_FRAMES} usable frames between $SKIP_BEGINNING_FRAMES and $UPPER_FRAME";
FRAME_NUMBER=$(shuf -i $SKIP_BEGINNING_FRAMES-$UPPER_FRAME -n 1)
LOG "Extract the random frame ${FRAME_NUMBER} to ${wallpaper}";
LOG "This takes a few minutes for large files.";
ffmpeg \
-loglevel error \
-hide_banner \
-i $MOVIE \
-vf "select=eq(n\,${FRAME_NUMBER})" \
-vframes 1 \
-y \
$wallpaper
WALLPAPER_PATH="file://$(readlink -f $wallpaper)"
LOG "Set the out file as light and dark wallpaper - using ${WALLPAPER_PATH}";
gsettings set org.gnome.desktop.background picture-uri-dark "${WALLPAPER_PATH}";
gsettings set org.gnome.desktop.background picture-uri "${WALLPAPER_PATH}";
In my crontab I call it like this:
# generate a neat new background every morning
0 4 * * * nice -n 10 ~/crons/every_frame_a_wallpaper.zsh -b 5 -e 12 /home/mk/Videos/Movies/Spider-Man_Across_the_Spider-Verse.mkv >> ~/.logs/every_frame_a_wallpaper/`date +"\%F"`-run.log 2>&1
Apropos of nothing in particular, certainly nothing that’s going on right now, a video of found footage where lots of people died, where the cameras are all focused on one side as protagonists. Where bombs go off far away but we get close ups on the artillery being fired. Absolutely top notch song though.
I’m against young men dying. I’m against people starving each other and murdering each other and driving each other from their homes. I do not think death is the solution for much and stories don’t stop just because we think it’s a good conclusion.
I’m sure everything is more complex, I’m sure, I’m sure – but that’s where most of my reactions stem from.
Max rides with me on this to school. We got it from some parents who don’t need it anymore and we fixed a flat tire and replaced a stolen seat.
We don’t have a great private place to secure it. It’s all just locked up on the street. One day we came out and one of the handlebar grips was gone. Ah well. People can be jerks. Such is life. No big deal.
We just ride without the grips and make do. “It’s fine!” says Max.
Today we came out to take Max to Brooklyn Game Lab for Dungeons and Dragons club. This is what we found:
Someone bought new handlebar grips and installed them on the bike for Max. Those are good ones, too! Better than what we had by a lot.
We were blown away by this thoughtful kindness!
Maxwell’s reaction was that he wants to learn how to fix things for other people. We have no idea who did this for us. If I figure it out I’m gonna hug the hell out them and thank them so much.
I started tracking books a long time ago on LibraryThing, when LibraryThing was giving out a CueCat. I liked LibraryThing, but they never got as popular as GoodReads, and I had friends who actually used GoodReads. So I moved on to GoodReads to be with my friends, since community trumps technology. I really wish I could have used the functionality of LibraryThing but still kept tabs with my pals. Sadly, these folks want to have a walled garden and don’t value interoperability.
I don’t want to give my data directly to Amazon (the owners of GoodReads). I don’t want to lose APIs or access to all the data that I’ve been putting in. I also care about my friends, but not that they use the same website as me!
So I was incredibly excited to discover a great book tracker in the Fediverse!
BookWyrm is a social network for tracking your reading, talking about books, writing reviews, and discovering what to read next. Federation allows BookWyrm users to join small, trusted communities that can connect with one another, and with other ActivityPub services like Mastodon and Pleroma.
https://joinbookwyrm.com
BookWyrm is open source, decentralized and federated. It’s built on top of the ActivityPub protocol like Mastodon.
BookWyrm is decentralized. That means it isn’t just one website like Twitter, GoodReads, FaceBook, LibraryThing, etc. It is made up of many sites – there are 22 sites live as I write this. If you don’t like one of them, you can leave and move to another, you’re not locked in to the choices and beliefs of whoever owns a server.
And Federated means that all these sites speak about books to each other in a special set of ways called ActivityPub. Some of these sites are for folks who speak a certain language or live somewhere or are interested in a certain kind of book… But if you have a friend on a different site, you can still be friends! The sites all speak to each other in a federation of small common websites. Bookwyrm has good people on it – you can find a good like minded community or span across communities.
And because BookWyrm speaks ActivityPub, it means that people who left Twitter for Mastodon can be friends with you on BookWyrm – they can comment on your books safely from their own community! It’s as natural as sending emails from your work to someone else’s.
And when I want to just get the books that I marked to-read so I can search for them across multiple places, I don’t have to spend a ton of time faking my way to get my own data. BookWyrm is here for me, not as a place trying to find a business model to exploit me.
I’ve been doing a little project and took a moment to get a bit better at using tmux.
Every time I go into this project I set up some splits. A main window where I’ll edit files using vim, then I split a pane off to run the code or test suite on every save. Another split where I pip install after any changes to my requirements.txt file.
Since I do the same thing repeatedly I was pretty sure tmux has a way to set this up so I don’t need to do it by hand. I tried using tmux session saving plugins, but they are too much for what I need right now.
Turns out tmux is incredibly easy to script. This gist is very long and very informative on how to split windows in tmux and covered everything I needed.
#! /bin/sh
# split -h horizontally to take up 30% of the width to run my __main__.py file on every save of a python file
# this is -d detached so that focus remains on the main window
tmux splitw -d -h -p 30 'ls *.py | entr -c env/bin/python . ./goodreads_library_export.csv data.csv ~/books'
# split my second pane vertically with 20% for rerunning pip installs on save of requirements.txt
tmux splitw -d -t 2 -p 20 'ls requirements.txt | entr -c env/bin/pip install -r requirements.txt'
# create a little detached shell just in case I need to try something
tmux splitw -d -t 3
# open up the python files in tabs in my main pane
vim -p *.py
entr is a great little tool I like for monitoring for file changes and running a command in response.