Compare commits
14 commits
401d21aed1
...
0e999284b9
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e999284b9 | |||
| d4f286d723 | |||
| 0939fc6847 | |||
| 49a28973ce | |||
| 9e54fb8216 | |||
| ca09a1372d | |||
| b8372626bf | |||
| 6f8987d393 | |||
| 342a4af782 | |||
| a5927fbc9a | |||
| 46ee9ff892 | |||
| 79674d4a07 | |||
| 00d710e00b | |||
| 5dae68f714 |
14 changed files with 282 additions and 51 deletions
|
|
@ -1,2 +1,3 @@
|
|||
blog: blog/:year/:month/:slug/
|
||||
photos: photos/:year/:month/:slug/
|
||||
twitter: twitter/:year/:month/:slug/
|
||||
|
|
|
|||
|
|
@ -1,8 +1,20 @@
|
|||
---
|
||||
title: Eryn Rachel Wells
|
||||
layout: single
|
||||
draft: true
|
||||
params:
|
||||
renderHeadingAnchors: false
|
||||
---
|
||||
|
||||
{{< nobreak >}}Ingeniera de software,{{< /nobreak >}}
|
||||
alfarera, música, y
|
||||
{{< nobreak >}}nerd en general.{{< /nobreak >}}
|
||||
¡Hola! Me llamo Eryn Wells. Este es mi sitio web. ¡Bienvenidos!
|
||||
|
||||
|
||||
## Personal
|
||||
|
||||
Soy mujer queer,
|
||||
|
||||
|
||||
## Profesional
|
||||
|
||||
Desde 2011, he trabajado como ingeniera de software en varios companías alrededor del área
|
||||
del Bahía de San Francisco. En 2016, me uní a [Apple][]. Hoy, trabajo en
|
||||
tecnologías que
|
||||
|
|
|
|||
|
|
@ -6,53 +6,61 @@ params:
|
|||
|
||||
Hi, I'm Eryn Wells. This is my website. Welcome!
|
||||
|
||||
|
||||
## Latest
|
||||
|
||||
Here are some of my most recent posts.
|
||||
|
||||
{{< home/latest >}}
|
||||
|
||||
|
||||
## Personal
|
||||
|
||||
I'm a queer trans woman, {{< tess >}}' partner, and mom of [two cats][cats]. I
|
||||
I'm a queer woman, {{< tess >}}' partner, and mom of [two cats][cats]. I
|
||||
was born in Seattle, {{< abbr Washington >}}WA{{< /abbr >}} and grew up in
|
||||
Phoenix, {{< abbr Arizona >}}AZ{{< /abbr >}}. I attended [Oberlin College][ob]
|
||||
Phoenix, {{< abbr Arizona >}}AZ{{< /abbr >}}. I attended [Oberlin College][]
|
||||
where I got a degree in Computer Science. My pronouns are [she/her][pronouns].
|
||||
|
||||
You can read more about me on my [about][ab] page, or [get in touch][where-am-i].
|
||||
|
||||
|
||||
## Professional
|
||||
|
||||
I've worked as a software engineer since 2011 for a variety of companies around
|
||||
the San Francisco Bay Area. I joined [Apple][a] in 2016, where I currently work
|
||||
the San Francisco Bay Area. I joined [Apple][] in 2016, where I currently work
|
||||
on password management and authentication technologies.
|
||||
|
||||
My [résumé][r] has all the details.
|
||||
|
||||
|
||||
## Hobbies
|
||||
|
||||
When I'm not working, you can reliably find me hacking on this website or [some
|
||||
coding other project][gh]. I'm also a musician, and play piano, Irish tin
|
||||
whistle, and modular synthesizer. Occasionally I [record][bc] [things][sc]. I
|
||||
love outer space and astronomy; I will always get excited to look at the moon
|
||||
with you, or check out anything through a telescope. I enjoy [photograhy][p],
|
||||
mostly as a travel hobby. And I've been practicing iaido, a traditional Japanese
|
||||
sword art, since early 2024. Other things I've been into include: bread baking,
|
||||
other coding project][src]. I'm also a musician: I play piano, Irish tin
|
||||
whistle, and modular synthesizer. Occasionally I [record things][sc] or offer
|
||||
them [for sale][sc]. I love outer space and astronomy; I will always get excited
|
||||
to look at the moon with you, or check out anything through a telescope. I enjoy
|
||||
[photograhy][p], mostly as a travel hobby. And I've been practicing
|
||||
[iaidō][mjer], a traditional Japanese sword art, at [Nishi Kaigan Iaidō
|
||||
Dōjō][nkid] since early 2024. Other things I've been into include: bread baking,
|
||||
bicycling, calligraphy, ceramics, and knitting.
|
||||
|
||||
[a]: https://apple.com
|
||||
|
||||
[Apple]: https://apple.com
|
||||
[ab]: {{< ref "/about" >}}
|
||||
[b]: {{< ref "/blog" >}}
|
||||
[bc]: https://erynwells.bandcamp.com/releases
|
||||
[cats]: {{< ref "/cats" >}}
|
||||
[eml]: mailto:Eryn%20Wells<eryn@erynwells.me>
|
||||
[gh]: https://github.com/erynofwales
|
||||
[src]: https://source.erynwells.me/eryn
|
||||
[ig]: https://www.instagram.com/erynofwales
|
||||
[m]: https://mastodon.social/@erynofwales
|
||||
[n]: {{< ref "/now" >}}
|
||||
[ob]: https://www.oberlin.edu
|
||||
[Oberlin College]: https://www.oberlin.edu
|
||||
[p]: {{< ref "/photos" >}}
|
||||
[pronouns]: http://pronoun.is/she
|
||||
[r]: {{< ref "/resume" >}}
|
||||
[sc]: https://soundcloud.com/purlsnbeeps
|
||||
[where-am-i]: {{< ref "/about/where-am-i" >}}
|
||||
[mjer]: https://en.wikipedia.org/wiki/Mus%C5%8D_Jikiden_Eishin-ry%C5%AB
|
||||
[nkid]: https://iaido.org
|
||||
|
|
|
|||
14
content/blog/2026/thirty-eight/index.md
Normal file
14
content/blog/2026/thirty-eight/index.md
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
title: "Thirty Eight"
|
||||
date: 2026-01-14
|
||||
draft: true
|
||||
tags:
|
||||
- Me
|
||||
- Birthdays
|
||||
---
|
||||
|
||||
I'm turning thirty eight today!
|
||||
|
||||
Neil Armstrong was 38 when he walked on the moon. (Buzz Aldrin was 39.) Jack
|
||||
Swigert was 38 when he timed the 14 second burn that brought Apollo 13 back into
|
||||
position for reentry to Earth.
|
||||
BIN
content/photos/2025/harvest-moon/harvest-moon.png
Normal file
BIN
content/photos/2025/harvest-moon/harvest-moon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 268 KiB |
23
content/photos/2025/harvest-moon/index.md
Normal file
23
content/photos/2025/harvest-moon/index.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
title: "Harvest Moon"
|
||||
date: 2025-10-06T22:00:00-07:00
|
||||
tags:
|
||||
- Space
|
||||
- Astrophotography
|
||||
- Moon
|
||||
---
|
||||
|
||||
Monday October 6 was the full moon. As the closest full moon to the [autumnal
|
||||
equinox][], it is the [Harvest Moon][]. It also happened to be a [supermoon][],
|
||||
making it slightly bigger in the night sky.
|
||||
|
||||
I shot this photo from my back deck with my Fujifilm X-T5 and a Canon 100mm
|
||||
macro prime[^1]. Amazingly, this is a handheld shot too. I couldn't find a
|
||||
necessary bit of my tripod to mount the camera, so I made do.
|
||||
|
||||
[^1]: Photography nerds will notice these are _not_ compatible components; I use
|
||||
a Fringer EF-FX mount adapter for this.
|
||||
|
||||
[autumnal equinox]: https://en.wikipedia.org/wiki/September_equinox
|
||||
[Harvest Moon]: https://en.wikipedia.org/wiki/Full_moon#Harvest_moon
|
||||
[supermoon]: https://science.nasa.gov/moon/supermoons/
|
||||
5
content/tags/eaoc/_index.md
Normal file
5
content/tags/eaoc/_index.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Erin Anne O'Connor
|
||||
linkTitle: EAOC
|
||||
slug: eaoc
|
||||
---
|
||||
138
content/uses/index.tok.md
Normal file
138
content/uses/index.tok.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
---
|
||||
title: "mi kepeken e ni"
|
||||
draft: true
|
||||
toc: open
|
||||
---
|
||||
|
||||
## Tech
|
||||
|
||||
### Hardware
|
||||
|
||||
[Apple M2 MacBook Air from 2022](https://www.apple.com/macbook-air-13-and-15-m2/)
|
||||
: mi olin e ilo sona ni. tenpo pini la mi olin e ilo sona ante. ilo sona ante en
|
||||
ilo sona ni li MacBook Air. tenpo ale la mi jo e ilo sona ante. kin la tenpo ale
|
||||
la mi jo e ilo sona ni.
|
||||
|
||||
[Apple Studio Display](https://www.apple.com/studio-display/)
|
||||
: I was on the fence about a Cinema Display for a long time. I ordered and
|
||||
canceled three times. Ultimately I gave in, and I'm quite happy with it. It's
|
||||
mounted on a VESA arm attached to my desktop.
|
||||
|
||||
### Software
|
||||
|
||||
#### Development
|
||||
|
||||
[Neovim](https://neovim.io/)
|
||||
: tenpo suli la, mi kepeken e `vim`. ona li ilo nanpa wan pi pali lipu mi.
|
||||
|
||||
[Visual Studio Code](https://code.visualstudio.com/)
|
||||
: tenpo sike mute la mi alasa e VSCode. ona li jo e ijo pona mute.
|
||||
|
||||
[Xcode](https://developer.apple.com/xcode/)
|
||||
: mi pali lon [kulupu kili][apple]. Xcode li ilo pi pali lipu tawa. lon kulupu
|
||||
kili la mi kepeken e Xcode. lon tomo mi, mi kepeken kin e Xcode. Xcode li pona.
|
||||
|
||||
[Fork](https://fork.dev)
|
||||
: A GUI client for `git`. I think Fork has totally changed how I use `git`. I
|
||||
still use the command line for many things, but working through diffs, staging
|
||||
changes, and even rebasing is so much easier in a GUI.
|
||||
|
||||
#### Terminal
|
||||
|
||||
[Terminal.app](https://support.apple.com/guide/terminal/welcome/mac)
|
||||
: macOS's built in terminal emulator is solid. The only thing I miss from it now
|
||||
and then is "true color" support, and that's only when I try to install a new
|
||||
color theme in Neovim and everything goes haywire.
|
||||
|
||||
[Zsh](https://www.zsh.org)
|
||||
: I've been using Zsh since before it was cool. My shell config is full of
|
||||
bespoke tweaks, including a prompt theme I'm rather proud of.
|
||||
|
||||
#### Hosting
|
||||
|
||||
[Digital Ocean](https://www.digitalocean.com)
|
||||
: DO has hosted my VPS for a number of years. I moved there from Linode because
|
||||
I wanted to run FreeBSD on my server.
|
||||
|
||||
[FreeBSD](https://www.freebsd.org)
|
||||
: My server OS of choice. It's secure, simple, and resilient, and I appreciate
|
||||
the less-encumbered BSD license.
|
||||
|
||||
[FastMail](https://www.fastmail.com/)
|
||||
: I've used FastMail for years now as my email host. Their annual fees are quite
|
||||
modest and they have a great feature set including a Sieve email filter editor,
|
||||
and Masked Email for genearating ad hoc email addresses. I've never had a
|
||||
problem with uptime, and the few times I've contacted support, they've been
|
||||
helpful.
|
||||
|
||||
[Hugo](https://gohugo.io)
|
||||
: This whole website is built with Hugo.
|
||||
|
||||
### Mobile
|
||||
|
||||
[Doppler](https://brushedtype.co/doppler/)
|
||||
: File-based music player.
|
||||
|
||||
[Ivory](https://tapbots.com/ivory/)
|
||||
: My Mastodon client of choice for macOS and iOS.
|
||||
|
||||
[Overcast](https://overcast.fm/podcasts)
|
||||
: My podcast player of choice.
|
||||
|
||||
[Reeder](https://www.reederapp.com)
|
||||
: RSS feed organizer and reader. I'm doing a lot more RSS these days.
|
||||
|
||||
[Transit](https://transitapp.com)
|
||||
: Helps me stay on top of bus schedules in San Francisco.
|
||||
|
||||
## Music
|
||||
|
||||
[Logic Pro](https://www.apple.com/logic-pro/)
|
||||
: Apple's DAW is full of features and plugins (far more than I could ever use)
|
||||
and it's hard to beat the corporate discount, much as I also love Ableton.
|
||||
|
||||
[Shure SM7B](https://www.shure.com/en-US/products/microphones/sm7b)
|
||||
: The SM7 is an iconic mic, and has been the go-to for voice actors, podcasters,
|
||||
and musicians for 50 years. The excellent podcast Twenty Thousand Hertz did a
|
||||
great [deep dive episode][20ksm7] on its history and place in the audio
|
||||
industry. I have one on my desk at home, and it makes me sound great on work
|
||||
video calls, and the occasional audio recording.
|
||||
|
||||
[Moog Matriarch](https://www.moogmusic.com/synthesizers?type=202)
|
||||
: I'm a bit of a Moog fangirl, and this might be my favorite of their synths.
|
||||
It's just hard to beat the sound of a Moog.
|
||||
|
||||
[Kawaii CA-65](https://kawaius.com/product/ca65/)
|
||||
: I've been playing piano since I was seven years old. A digital piano is
|
||||
perfect for the small apartments I've called home. This one has a fantastic
|
||||
realistic action and it sounds great.
|
||||
|
||||
## Coffee
|
||||
|
||||
[Baratza Encore](https://www.baratza.com/product/encoretm-zcg485)
|
||||
: It's affordable and does a pretty good job.
|
||||
|
||||
[Kalita Wave](https://kalitausa.com/products/kalita-wave-185-stainless-steel-coffee-dripper)
|
||||
: The Kalita is probably the easist single serve pour over dripper I've used.
|
||||
|
||||
[Chemex](https://www.chemexcoffeemaker.com/six-cup-classic-series-coffeemaker.html)
|
||||
: If I'm making coffee for more than just me, the Chemex is the biggest pour
|
||||
over vessel I have. Makes yummy coffee too.
|
||||
|
||||
## Gaming
|
||||
|
||||
[Nintendo Switch](https://www.nintendo.com/us/switch/)
|
||||
: Most of my gaming happens here. I play a lot of Mario Kart online with
|
||||
friends, and I'm a big fan of both of the major Legend of Zelda titles that have
|
||||
come out for it: Breath of the Wild and Tears of the Kingdom.
|
||||
|
||||
[PlayStation 5](https://www.playstation.com/en-us/ps5/)
|
||||
: I also have a PS5. I've played a ton of Horizon: Zero Dawn and the new Final
|
||||
Fantasy 7 games.
|
||||
|
||||
[Analogue Pocket](https://www.analogue.co/pocket)
|
||||
: When I want to play my stock of Game Boy games, this thing is great.
|
||||
|
||||
[apple]: https://www.apple.com
|
||||
[vscode-vim]: https://marketplace.visualstudio.com/items?itemName=vscodevim.vim
|
||||
[20ksm7]: https://www.20k.org/episodes/sm7
|
||||
14
deploy.sh
14
deploy.sh
|
|
@ -1,14 +0,0 @@
|
|||
#!/usr/bin/env zsh
|
||||
# Deploy erynwells.me to my web root
|
||||
# Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
print -P "%BFiltering .DS_Store files%b"
|
||||
find . -name '.DS_Store' -print -delete
|
||||
|
||||
print -P "%BGenerating site%b"
|
||||
hugo
|
||||
|
||||
echo
|
||||
print -P "%BRsyncing site to nutmeg.erynwells.me%b"
|
||||
rsync -avz --no-times --no-perms --delete public/ \
|
||||
eryn@nutmeg.erynwells.me:/srv/www/erynwells.me/html
|
||||
|
|
@ -1 +1 @@
|
|||
<abbr title="{{ .Get 0 }}">{{ .Inner }}</abbr>
|
||||
<abbr title="{{ .Get 0 }}">{{ .Inner }}</abbr>{{- "" -}}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,33 @@
|
|||
import os.path as osp
|
||||
|
||||
|
||||
def root_dir() -> str:
|
||||
'''Return the path to the root of the repository.'''
|
||||
return osp.normpath(osp.join(osp.dirname(__file__), '..', '..'))
|
||||
|
||||
|
||||
def assets_path() -> str:
|
||||
'''Return the path to the assets directory.'''
|
||||
path = osp.join(root_dir(), 'assets')
|
||||
return path
|
||||
|
||||
|
||||
def content_path() -> str:
|
||||
'''Return the path to the content directory.'''
|
||||
path = osp.abspath(osp.join(osp.dirname(__file__), '..', '..', 'content'))
|
||||
assert osp.isdir(path)
|
||||
path = osp.join(root_dir(), 'content')
|
||||
return path
|
||||
|
||||
|
||||
def blog_path() -> str:
|
||||
'''Return the path to the blog content directory.'''
|
||||
return osp.join(content_path(), 'blog')
|
||||
|
||||
|
||||
def photos_path() -> str:
|
||||
'''Return the path to the photos content directory.'''
|
||||
return osp.join(content_path(), 'photos')
|
||||
|
||||
|
||||
content_dir = content_path
|
||||
blog_dir = blog_path
|
||||
photos_dir = photos_path
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from .scripting import Command
|
|||
|
||||
class WeeknotesCommand(Command):
|
||||
@staticmethod
|
||||
def weeknotes_filename(year: str, week: str) -> str:
|
||||
def weeknotes_filename(year: str | int, week: str | int) -> str:
|
||||
return f'weeknotes-{year}w{week}.md'
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -26,7 +26,7 @@ class WeeknotesCommand(Command):
|
|||
week_number_str = next_sunday.strftime('%V')
|
||||
|
||||
return blog.post_path(WeeknotesCommand.weeknotes_filename(
|
||||
str(year),
|
||||
year,
|
||||
week_number_str
|
||||
))
|
||||
|
||||
|
|
|
|||
|
|
@ -14,12 +14,23 @@ from erynwells_me.metadata import slugify
|
|||
from erynwells_me.paths import photos_path
|
||||
|
||||
|
||||
def date_argument(value: str) -> datetime.datetime:
|
||||
parsed_date = datetime.datetime.fromisoformat(value)
|
||||
|
||||
if not parsed_date.tzinfo:
|
||||
local_timezone = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
|
||||
parsed_date = datetime.datetime.combine(parsed_date.date(), parsed_date.time(), local_timezone)
|
||||
|
||||
return parsed_date
|
||||
|
||||
|
||||
def parse_args(argv, *a, **kw):
|
||||
parser = argparse.ArgumentParser(*a, **kw)
|
||||
parser.add_argument('-e', '--edit', action='store_true')
|
||||
parser.add_argument('-n', '--dry-run', action='store_true')
|
||||
parser.add_argument('-t', '--title')
|
||||
parser.add_argument('-s', '--slug')
|
||||
parser.add_argument('-d', '--date', type=date_argument)
|
||||
parser.add_argument('--dump-exif', action='store_true')
|
||||
parser.add_argument('photos', nargs='+')
|
||||
args = parser.parse_args(argv)
|
||||
|
|
@ -29,7 +40,7 @@ def parse_args(argv, *a, **kw):
|
|||
def main(argv):
|
||||
args = parse_args(argv[1:], prog=argv[0])
|
||||
|
||||
earliest_exif_date: Optional[datetime.datetime] = None
|
||||
post_date: Optional[datetime.datetime] = args.date
|
||||
|
||||
for index, photo in enumerate(args.photos):
|
||||
print(f'image\t\t{photo}')
|
||||
|
|
@ -40,14 +51,20 @@ def main(argv):
|
|||
continue
|
||||
|
||||
raw_exif = image._getexif()
|
||||
friendly_exif = {}
|
||||
if raw_exif:
|
||||
friendly_exif = {TAGS[k]: v for k, v in raw_exif.items() if k in TAGS}
|
||||
|
||||
photo_date = None
|
||||
if not args.date:
|
||||
try:
|
||||
date_string = f'{friendly_exif["DateTime"]} {friendly_exif["OffsetTime"]}'
|
||||
exif_date = datetime.datetime.strptime(date_string, '%Y:%m:%d %H:%M:%S %z')
|
||||
photo_date = datetime.datetime.strptime(date_string, '%Y:%m:%d %H:%M:%S %z')
|
||||
except KeyError:
|
||||
exif_date = datetime.datetime.strptime(friendly_exif["DateTime"], '%Y:%m:%d %H:%M:%S')
|
||||
print(f'capture-time\t{exif_date.isoformat()}')
|
||||
photo_date = datetime.datetime.strptime(friendly_exif["DateTime"], '%Y:%m:%d %H:%M:%S')
|
||||
else:
|
||||
photo_date = args.date
|
||||
print(f'capture-time\t{photo_date.isoformat()}')
|
||||
|
||||
iso_rating = friendly_exif.get('ISOSpeedRatings')
|
||||
if iso_rating:
|
||||
|
|
@ -66,23 +83,24 @@ def main(argv):
|
|||
if exposure_time:
|
||||
print(f'exposure-time\t{exposure_time}')
|
||||
|
||||
if not earliest_exif_date or exif_date < earliest_exif_date:
|
||||
earliest_exif_date = exif_date
|
||||
if not post_date or photo_date < post_date:
|
||||
post_date = photo_date
|
||||
|
||||
if index < len(args.photos) - 1:
|
||||
print()
|
||||
|
||||
if not earliest_exif_date:
|
||||
earliest_exif_date = datetime.datetime.now()
|
||||
if not post_date:
|
||||
post_date = datetime.datetime.now()
|
||||
|
||||
year = earliest_exif_date.year
|
||||
month = earliest_exif_date.month
|
||||
year = post_date.year
|
||||
month = post_date.month
|
||||
|
||||
if args.slug:
|
||||
name = args.slug
|
||||
elif args.title:
|
||||
name = slugify(args.title)
|
||||
else:
|
||||
photo = args.photos[0]
|
||||
name = osp.splitext(osp.basename(photo))[0]
|
||||
|
||||
post_path_year = os.path.join(photos_path(), f'{year:04}', name)
|
||||
|
|
@ -100,7 +118,7 @@ def main(argv):
|
|||
post_path = post_path_year
|
||||
|
||||
try:
|
||||
hugo_command = ['hugo', 'new', '--clock', earliest_exif_date.isoformat(), post_path]
|
||||
hugo_command = ['hugo', 'new', '--clock', post_date.isoformat(), post_path]
|
||||
if not args.dry_run:
|
||||
result = subprocess.run(hugo_command)
|
||||
result.check_returncode()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ A Python interface to my personal website, Erynwells.me.
|
|||
'''
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import os.path as osp
|
||||
from typing import List
|
||||
from erynwells_me.scripting import Command
|
||||
from erynwells_me.weeknotes import WeeknotesCommand
|
||||
|
|
@ -31,7 +33,14 @@ def parse_args(commands: List[Command], argv, *a, **kw):
|
|||
|
||||
|
||||
def main(argv):
|
||||
args = parse_args(COMMANDS, argv[1:], prog=argv[0])
|
||||
program_name = osp.basename(argv[0])
|
||||
args = parse_args(COMMANDS, argv[1:], prog=program_name)
|
||||
|
||||
scripts_dir = osp.dirname(__file__)
|
||||
repo_root_dir = osp.normpath(osp.join(scripts_dir, '..'))
|
||||
if os.getcwd() != repo_root_dir:
|
||||
os.chdir(repo_root_dir)
|
||||
|
||||
return args.handler(args)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue