[ACTIVE] the capsule and home of figbert in geminispace
git clone git://
Log | Files | Refs | README

commit 074768ea2ab9bd101030d74c5d7becccbef7541d
parent 279997601060ca5ceec5ac39e5dd380b7bc0a9e5
Author: FIGBERT <>
Date:   Mon, 12 Apr 2021 23:27:23 -0700

Add gemtext version of main site content

Acontent/index.gmi | 42++++++++++++++++++++++++++++++++++++++++++
Acontent/log/2020-06-13-i-wrote-this-one.gmi | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/log/2020-06-27-i-wrote-this-two.gmi | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/log/2020-07-03-how-to-replace-keybase-in-three-easy-steps.gmi | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/log/2020-07-03-keybase-hidden-address.gmi | 8++++++++
Acontent/log/2020-07-04-i-wrote-this-three.gmi | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/log/2020-07-28-pebkac-txtodo-rewrite.gmi | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/log/2020-08-22-going-full-static.gmi | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/log/2020-10-07-mac-control-center-is-better.gmi | 9+++++++++
Acontent/log/2020-11-01-moving-to-hetzner-from-digitalocean.gmi | 48++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/log/2020-11-16-a-very-convincing-terraria-review.gmi | 8++++++++
Acontent/log/2020-12-31-how-to-mirror-your-iphone-to-your-mac.gmi | 16++++++++++++++++
Acontent/log/2021-01-02-sass-style-update.gmi | 25+++++++++++++++++++++++++
Acontent/log/2021-01-21-my-first-regex.gmi | 34++++++++++++++++++++++++++++++++++
Acontent/log/2021-01-22-remarkable-tablet.gmi | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/log/2021-02-10-some-quality-shitposting.gmi | 18++++++++++++++++++
Acontent/log/2021-03-19-package-in-the-bush.gmi | 22++++++++++++++++++++++
Acontent/projects/tofu.gmi | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontent/projects/txtodo.gmi | 16++++++++++++++++
Acontent/static/age.txt | 1+
Acontent/static/bitcoin.txt | 1+
Acontent/static/media/blender-doughnut.mp4 | 0
Acontent/static/media/ios-jailbreak-tour.mp4 | 0
Acontent/static/media/macos-control-center.mp4 | 0
Acontent/static/media/pebkac-txtodo/ascending-checkmarks-error.mp4 | 0
Acontent/static/media/pebkac-txtodo/randomized-test-values.mp4 | 0
Acontent/static/media/pebkac-txtodo/update-preview.mp4 | 0
Acontent/static/media/terraria-review.jpg | 0
Acontent/static/ | 2++
Acontent/static/monero.txt | 1+
Acontent/static/one-angry-wizard.gblorb | 0
Acontent/static/publickey-pgp.asc | 15+++++++++++++++
Acontent/static/zcash.txt | 1+
33 files changed, 931 insertions(+), 0 deletions(-)

diff --git a/content/index.gmi b/content/index.gmi @@ -0,0 +1,42 @@ +# Hello World + +I'm FIGBERT, an Israeli-American high school student with a passion for Computer Science and Engineering. I spend my time coding side-projects, doing schoolwork, and playing the occasional videogame. My current goal is to become a full-stack developer, proficient in everything from front-end design to cybersecurity. + +## My Work + +To see some of the things I do, you can: + +=> /log Read my gemlog on this capsule +=> /projects Check out all the projects I've worked on +=> Download txtodo from the App Store +=> Download Tofu on iOS, which I contributed heavily too +=> Take a look at the source code for this capsule +=> /one-angry-wizard.gblorb Check out my text adventure, One Angry Wizard + +I'm constantly working on more stuff, so continue checking back for more project highlights. + +## Web Presence + +You can find me on most platforms as FIGBERT: + +=> My self-hosted Gitea instance (FIGBERT) +=> Github (FIGBERT) +=> Twitter (@therealfigbert) +=> Mastodon ( +=> Reddit (@therealFIGBERT) +=> Hacker News (figbert) + +## Keys and Crypto + +You can contact me via email at using a variety of cryptographies: + +=> /publickey-pgp.asc This PGP key (old-skool) +=> /age.txt My age key (written in Go, ooh) +=> / My minisign key (is signing still crypto?) + +If for some reason you want to send me money, feel free to send it to one of my crypto address so I never notice: + +=> /bitcoin.txt Bitcoin +=> /monero.txt Monero +=> /zcash.txt ZCash + diff --git a/content/log/2020-06-13-i-wrote-this-one.gmi b/content/log/2020-06-13-i-wrote-this-one.gmi @@ -0,0 +1,55 @@ +# I Wrote This #1 + +So, I'm FIGBERT – I wrote this. Nailed that intro. I'm a highschooler working in the tech world, currently stuck at home like pretty much everybody else who's not trying to die. I plan on using this blog to writing mainly on my experiences in tech, either in focused articles centered around one topic or more summary-style roundups like this, the "I Wrote This" series. + +I've always found statements like that kind of funny in their generalness, and was thinking the other day that if I ever made a game studio I would name it "I Made This Game." Then, when I was trying to think of what to name this series (The Weekly Fig? Fig Talks?), I thought it would be funny to do something similar. I plan to release these once a week on Saturdays, if all goes to plan. Without further ado, here's a brief summary of interesting things that happened this week. + +## Releasing txtodo v2.0 + +Some people reading this may be familiar with my most recent project, txtodo – a full writeup is linked below this paragraph. The point of txtodo was to create a todo list application without any of the feature bloat I found in other competing solutions. In txtodo, every task deletes at midnight. This week I launched the MacOS companion app for txtodo, completing my long-term "cross-platform" goal for the app. I went from not knowing SwiftUI at all to having two published apps that talk to each other! Making computers talk to each other is, like, the hardest thing you can do with computers! Ok, technically a lot of it is just Apple APIs but still, let me have this. I think there is probably one more major change I could make to the app (moving the tasks from an @State variable to an @EnvironmentObject), but after that it's pretty much bugfixes and... the bank? I don't know. + +=> txtodo website +=> /projects/txtodo.gmi project writeup + +## Signing Git Commits + +I while back I saw that when I editing my project using the GitHub web app, it got a little green "verified" badge next to the commit message. I looked into it for a bit today, and found this GitHub help article. One GPG install and Protonmail-key-download later, now all my commits have a green badge! Neat! + +=> this GitHub help article + +## The Meh vimrc + +I made the switch from nano to vim a few months ago, but up until a few days ago I was using the barebones default `macvim`. Not anymore! I DuckDuckGo-ed "vim configuration," and downloaded what is supposedly "The ultimate Vim configuration." from amix. It's a pretty good configuration out-of-the-box: I'm using the Awesome version with the fantastic Jetbrains Mono font. I'm still not that good at actually using vim to its fullest potential but I'm confident that I'll improve with a little practice and ascend to elite vim status in no time. + +=> The Ultimate vimrc +=> Jetbrains Mono + +## Maybe Rust? + +Speaking of elite programmers: Rust! I've been thinking about learning the language for a while, and now that I have no main project (other than maintain my finished apps and sites), it's as good a time as any to learn a new language. It's idiomatic syntax combined with low-level abilities makes Rust seem a little bit like Python+ to me. It also helps that it's skyrocketing in popularity – maybe I'll do the cliche Rust developer thing and post about how much I love the language on the orange site once I learn it. + +## From Brave to Firefox + +I made the switch from Brave to Firefox Developer Edition this week, after accumulating around 50 USD in BAT. I started using Brave almost when it came out and loved it – the chromium feel with a powerful built in adblocker? It sounded too good to be true – and perhaps it was: over time the browsers performace began to slow down, they hijacked links, launched a weird Zoom competitor with no fanfare or announcement, and refuse to get rid of their required KYC. Anyways, I dropped it. Now my dock is all blue! + +=> Brave hijacking links +=> Brave's weird Zoom competitor +=> Their terrible required KYC + +## New Music + +On a non-tech-related note, a bunch of good new music came out recently. In no particular order, here are some good new songs (largely out of the Middle East): + +* Coronavirus by Mohamed Ramadan +* Zot Ani – Ela Li Lahv +* Million Dollar – Noah Kirel and Shachar Saul +* Naughty – Tzagay Boi +* TROLLZ – 6ix9ine & Nicki Minaj + +## Wrapup + +So, that's been this week's update. I've got some exciting ideas for my next posts, so I hope you stick around for what's to come. Until then, farewell! + +-- +FIGBERT + diff --git a/content/log/2020-06-27-i-wrote-this-two.gmi b/content/log/2020-06-27-i-wrote-this-two.gmi @@ -0,0 +1,89 @@ +# I Wrote This #2 + +Hi! So, I just started this series and I already missed a week. Oh well. This week was a crazy week for Apple and their operating systems, as they announced iOS 14 and macOS 11 Big Sur at this year's WWDC. I've also started working on a new game project, another little side project, and finding a good alternative to Keybase now that it's owned by Zoom. + +## Jailbreaking my iPhone + +When I was a kid – or at least, a younger child than I am now – I had a friend who jailbroke his phone. I thought it was super cool, and wanted to do the same. At around the same time I was watching TechSource, I got deep into those Top 10 Amazing Jailbreak Tweaks compilations. However, I wasn't allowed to jailbreak my phone because my parents said it wasn't allowed, and that was the end of that. + +Until last week, when I decided to jailbreak my iPhone 7 running iOS 13.5.1 using the checkra1n hardware exploit. To do this, I couldn't use my USB-C to Lightning cable due to a known issue and instead swapped to a USB-A to Lightning cable with a USB-A to USB-C adapter. After jailbreaking the phone, I began to install a host of tweaks. One of the most interesting things I learned about the jailbreaking community is that charging upfront for apps is quite common for premium and well-known tweaks, which stands in high contrast to the iOS App Store's ubiquitous freemium payment model (a free download followed by a monthly subscription) especially in the light of the controversy of recent weeks. + +=> checkra1n +=> checkra1n's known issues (including incompatibility with Apple's own USB-C to Lighting cables) +=> controversy + +All in all, I spent around USD$21 on tweaks, which is infinitely more than I have spent on the App Store – so maybe charging upfront does work. Huh. + +=> /static/media/ios-jailbreak-tour.mp4 A little tour of my jailbroken phone + +## Updating my iDevices to Developer Betas + +Soon after completing the jailbreak, WWDC happened and new developer betas were released. Never one to miss jumping on a hype train, I updated both of my main devices to the new software. These new betas come with a whole host of bugs, as is to be expected, which I plan to write about in a blog post coming soon. So far, however, I'm liking these updates – the PiP on iOS is *incredible*, and the new design on macOS is growing on me. + +Some interesting resources: + +=> An interview of Craig Federighi by MKBHD +=> This iTerm2 issue on GitLab +=> This Firefox bug +=> This Github issue for Homebrew users (so basically everybody) + +Interestingly, I was having a bunch of issues with brew (curl was broken?) after updating to Big Sur but now it seems to be working flawlessly. Very nice. + + +## Making a Doughnut in Blender + +For my next medium-large project, I'm going to need to make some 3D art and models. One problem: I don't know how to do that, or rather, I didn't. Thanks internet! I powered through the incredible Blender Beginner Tutorial Series by the Blender Guru. + +=> Blender Beginner Tutorial Series +=> Blender Guru +=> /static/media/blender-doughnut.mp4 My final animation + +## Replacing Keybase + +Now that Keybase is compromised, I thought it would be good to seek out an alternative. Initially, I thought that would be perfect – I thought it was a slightly-tweaked fork. However, this does not appear to be the case. Instead, it seems kinda like garbo – it doesn't have the budget Keybase had, and as a result, is majorly lacking in features. However, I've replaced it completely, and am happier with this setup than I ever was with Keybase. My new setup uses Matrix and Element for messaging, Jitsi for video chat, Syncthing for file storage, and an Indieweb h-card for identity verification. I plan on writing more about this at a later date, but I'm really pleased with the results so far. + +=> Keybase Joins Zoom +=> +=> Matrix +=> Element +=> Jitsi +=> Syncthing +=> Indieweb + +## Future Projects + +I've got a few interesting projects in the pipeline at the moment, not counting the few articles that I've already promised to write. My next major project is a dreidel game/simulator for mobile devices – I plan to code it with Godot, make the models with Blender, and do any music/sound stuff in FLStudio. Naturally, I'll keep you all updated on any progress there. + +=> Godot +=> Blender +=> FLStudio + +I'm also working on a much smaller project that should take around a day or two to complete. The working title is "" – essentially, it's a website that takes the size of the State of Israel, and compares it to the size of a given location and tells you how many times Israel could fit inside it. All I need to do is find a suitable mapping API (preferably not by Google) that will tell me the size of different locations and I can whip it into a static site! + +I'm also planning on revamping the txtodo macOS app with Mac Catalyst, which I feel I haven't properly explored. I've also discovered a bug in the app that causes issues when tasks are modified by CloudKit instead of the user, so I'm going to have to work on that as well. Shouldn't be hard! + +## Interesting Blog Tidbits + +I'm not sure what tense to write my headers in – I currently write them in present continuous tense but I am considering writing them like I do Git commits. Huh. I'm also committing to writing more non-update blog posts but we'll see how that goes. Writing is hard, and you shouldn't make false promises. I'm also working on implementing webmentions to the site, which is a little difficult with a static site but I'm going to give it a try. Lastly, I really need to learn how to use vim but it's so goddamn hard. I'm writing this blog post with it but I'm definitely not using it to its full potential at all. + +## New Music + +Wow, these have been a great two weeks for the Israeli music scene. In no particular order, here are some good new songs (basically in the order they appear on the trending tab): + +* Habib Albi – Static and Ben El +* Rak Banot – Itay Levi and Stephane Legar +* Shvuaim – Eden Hason +* Yom Huledet – Eliad +* Hatzi Madleket – Dudu Faruk +* Hayde – Peled +* Ze Mi She Ani – Peled + +I know music isn't tech, but I like it and now it's a recurring section. + +## Wrapup + +So, that's been this week's update. I'm really enjoying writing updates on this blog, and I hope you stick around. Until then, farewell! + +-- +FIGBERT + diff --git a/content/log/2020-07-03-how-to-replace-keybase-in-three-easy-steps.gmi b/content/log/2020-07-03-how-to-replace-keybase-in-three-easy-steps.gmi @@ -0,0 +1,82 @@ +# How to Replace Keybase in 3 Easy Steps + +Ever since Keybase was acquired by Zoom, a company with a very bad history with security/privacy, people wanted an alternative. There have been a few different alternatives proposed: this is (the best) mine. + +First, a catalog of very bad links from Keybase's new owners: + +=> An 0day in the macOS client! +=> Saying they use e2e when they don't! +=> Using installing tricks from your local malware dealers! +=> Protonmail has arrived to shit on them too! +=> Shutting down people who talk about Tianamen Square! +=> Not encrypting free calls so they can snitch to the cops! +=> Rolling their own crypto! +=> Remember the installer from earlier? Now it has ACE! +=> Monitoring all the apps you have open! + +## What is Keybase? + +Before we talk about replacing Keybase, we should have a good idea of what Keybase actually is. It's main features are as follows (ordered as on the website): + +=> Keybase + +* E2EE chats and messaging (people and teams). +* Cryptographic identity verification from around the net. +* KBFS (Public signed file hosting, private E2EE file storage w/ sharing, Static site hosting??) +* Git repositories? Crypto? An alternative to PGP called saltpack? + +## Previous Attempts to Replace Keybase + +I'm not the first person to try this, obviously. Some brave folks have tried to build Keybase alternatives, such as and the brand-new Keyoxide. I've tried both, but found that though they both are good in their own right, they are not the solutions that I am looking for. + +=> +=> Keyoxide + +## OK Time for the Steps + +### Step #1: Chat/Messaging + +There are a few great pre-existing options for encrypted messaging: Signal, ProtonMail if you want to go full email, Telegram, and WhatsApp. However, they all have their problems (though I use the first two on a daily basis). Signal requires a phone number, and is more of an iMessage/text replacement than a Slack-style chat app. Protonmail is literally not chat – it's email. Telegram is (debatably) not secure. If you use WhatsApp for security you might be crazy – I only use it because it's *the way* to communicate with people in the Middle East and Africa. + +Instead, I would recommend you use Matrix. Matrix is an "open network for secure, decentralized communication," and it's the perfect replacement for Keybase's chat. It utilizes E2E encrypted messaging, and can be self-hosted as well. + +=> Matrix + +In addition to a Matrix server, you also need a client. For this, I recommend Element – though Nio, once stable, will almost surely be my go-to. Element is a beautiful Matrix client with a bunch of awesome features, including Slack-like integrations, and apps for pretty much every major platform (Linux, MacOS, Windows, iOS, Android, and a web client). Plus it looks a lot like Discord. + +=> Element +=> Nio + +### Step #2: Identity verification + +Replacing Keybase's original function is probably the most difficult part of this tutorial: cryptographically verified identity proofs is a great and innovative idea. I would swap this out with an IndieWeb profile – one part of the larger microformats HTML structure. There are some pretty great tutorials out there, so I won't go into too much detail about exactly how to do that. However, it's important to note that though some tutorials recommend hiding your h-card with the display: none; property: don't do that. It's a documented anti-pattern. I just merged my about and contact pages onto my homepage, and added the microformats classes to my existing markup. + +=> The IndieWeb homepage +=> microformats homepage +=> An Indieweb profile tutorial by Kev Quirk +=> Another Indieweb tutorial by Brian Wisti +=> Invisible metadata antipattern + + +### Step #3: File Storage + +Replacing KBFS is easy to do, but hard to get right. Swapping to Google Drive is probably the move that most people would make, but that abandons the entire security/encryption aspect of Keybase. There's also Dropbox, but that has the same problems as above. ProtonDrive has potential, but it's not production ready. Enter Syncthing. Nikita Tonsky wrote one of my favorite posts of all time about Syncthing – go read it. One reason Syncthing is so great is that it's not the same thing as KBFS or any of the other "Drive" solutions. Instead of being a file hosting system, it's a "continuous file synchronization program" - aka p2p. You have no data limits other than your storage and no third-party to worry about. Plus, sharing folders is also incredibly easy. Just read the article. + +=> Syncthing +=> Nikita Tonsky amazing article + +### Bonus Step #4: Video Calling + +It would be a shame to talk about text chat, or really any form of communication, in this new pandemic age without talking about video chat. After all, the whole reason I'm writing this article is because the new videocalling giant Zoom. So, how have I replaced Zoom and how does that relate to replacing Keybase? Well, Matrix happens to have a fantastic Jitsi Meet integration. Plus, the folks over at Jitsi are working on E2E encryption for their calls. I've integrated Jitsi Meet into my self-hosted instance of Matrix, and now all my videocalls are just that – mine! + +## Summary + +* Swapped chat to Matrix and Riot. +* Swapped identity verification to Indieweb. +* Swapped file storage/sync to Syncthing. +* Added videocalling to chat program via Jitsi. + +## Conclusion + +Keybase is a great service, and the people who work there should be really proud of what they've built. However, given Zoom's aquisition of the company, the stability and security of the product have been called into question. So, ever one to hop on a hype train, I jumped ship. + diff --git a/content/log/2020-07-03-keybase-hidden-address.gmi b/content/log/2020-07-03-keybase-hidden-address.gmi @@ -0,0 +1,8 @@ +# Keybase Has an Onion Address + +Little known fact about Keybase: it has two onion addresses. Huh. + +=> Keybase (clearnet) +=> http://fncuwbiisyh6ak3i.onion/ fncuwbiisyh6ak3i.onion +=> http://keybase5wmilwokqirssclfnsqrjdsi7jdir5wy7y7iu3tanwmtp6oid.onion keybase5wmilwokqirssclfnsqrjdsi7jdir5wy7y7iu3tanwmtp6oid.onion + diff --git a/content/log/2020-07-04-i-wrote-this-three.gmi b/content/log/2020-07-04-i-wrote-this-three.gmi @@ -0,0 +1,126 @@ +# I Wrote This #3 + +It appears I'm not that great at keeping a weekly schedule. Right after I published my last post, I started a class on text adventures and have been living and breathing in Inform7 ever since. I've also spent some time working on this site – though I've got even bigger changes coming in the future – learning a few new languages, and listening to a whole lot of music. I think something happened in cybersec too? Oh also I learned how to drive. + +## Interactive Fiction + +These past few weeks, my main work has been on interactive fiction as part of a summer class for my school. The first week was spent learning the history of text adventures (as I will refer to them for the rest of the article, becuase calling them "interactive fiction" makes me sound like a dick). I gathered a collection of games to play in free time (if I ever have any more of that), from the very first of the genre – Adventure – to modern ones like Lost Pig. + +In the second week, we all made our own text adventures. It was a really interesting experience – drastically different than any other programming I've done. The main thing I struggled with was the semi-NLP style of Inform7. Rather than telling the computer what to do, I felt like I was making suggestions. I also struggled with the editor a bit. Inform7 isn't open source, which means there's only one IDE you can use to program in the language. That would be fine if the IDE was high quality, but I often found it really bad and draining. This was made a little better after I changed the editor colors to be much more vibrant (so I wouldn't fall asleep), but I still felt like it needed some work. Regardless of any struggles along the way, the payoff after the game was finished was huge. Watching my little sister play a text adventure for the first time, one I had made, was awesome. + + +Without further ado, I present to you: + +=> /static/one-angry-wizard.gblorb One Angry Wizard, or the Tentacular Adventures of our Brave Hero through a World Most Strange and Foreign +=> Inform7 (text adventure ide) +=> Gargoyle (text adventure player) + +## Site Work + +I made some changes that you guys can see, and some other ones behind the scenes. + +### Joining Webrings + +I first encountered webrings on Hacker News, where I find most of my interesting internet things. From there, I decided to join both the geekring and the Hotline Webring – you can find links to the webrings on the homepage. Joining the Hotline Webring was designed to be supremely easy, but the geekring was a little more complicated. I've never been a big IRC person (though not for lack of trying), and I ended up joining via the HTML form and getting my key via email (I may or may not have confused my number with my private-ish key, and had to use a little bit of bfg magic to fix that). + +=> geekring +=> Hotline Webring + +### Self-Hosting + +My site was previously hosted using a continuous deploy on Netlify. This was a pretty great system for me – all I had to do was commit my code to the GitHub repo, which I was already doing, and then they would take care of everything and serve a great site – here's the kicker – for free. + +This was working really well for me for a while, until I decided to add security headers to the site. I tried doing this in two different ways: using Helmet as described in the Sapper Docs and using Netlify _headers. The Helmet middleware didn't work with Netlify, and I'm honestly not sure why – possibly because of how they host the file server (I'm not sure what/how they server the site), or maybe I just f*cked up somewhere idk JavaScript is hard. Using the Netlify config didn't work either because I'm not a paying subscriber, which wasn't too clear at first. This would probably be solved if I just gave them money, but I'm not going to do that any time soon. + +I decided to move to DigitalOcean and host the site myself (or I guess not totally myself – I don't feel comfortable running it on a Pi from my house just yet) with Caddy. I went with DigitalOcean partially because of their dev-focused business model, but mostly because they're cheap (my droplet is USD$5/month and I get $50 credit with them from the GitHub Student Developer Pack – my first year of hosting for only $10). + +Unfortunately, I didn't quite run the transition too well. It definitely wasn't zero downtime – it was probably more like a-few-hours downtime. I doubt this really affected anyone because of my small audience, but I was still up late working on it. If it had happened a few days later, it might have gotten mixed up with the Cloudflare downtime (I don't use Cloudflare). + +=> Cloudflare downtime + +My current setup uses a custom CaddyServer configuration to serve my site, which I am absolutely loving so far: it is so much easier to run advanced setups with Caddy than Apache or Nginx. I wanted to move away from Javascript analytics (via GoatCounter) to log-based analytics (via GoAccess) but found that Caddy's structured logs are not supported natively. I'm hoping they'll add it soon though! + +=> Caddy support potentially coming to GoAccess... + +### Next Steps + +I've got two major todos for my site in the near future. The first thing I want to do is Dockerize. Using Docker will significantly clean up my current setup, and allow me to host more fun things on the same machine (for example, my own analytics and maybe git). With that said, I probably should get a little better at Docker first... For beginners, Flavio Copes' has a few pretty great posts on the subject. + +=> Flavio Copes' Docker series + +The second thing I want to do is a bit of a larger project, and one I'm not yet sure how I'm going to solve it. I've run into some problems with the frameworks I use to develop Sapper generates inline scripts and blobs, which tanks the security of my CSP. Their proposed solution is to inject nonces with JS middleware, but this doesn't work with CaddyServer. I would much rather Sapper avoid inline scripts altogether, but this doesn't seem likely. I really like the freedom that writing static sites in Svelte provides me versus other static site generators, but this could be a dealbreaker. I might talk a look at Routify and see if that's any better. + +I've also been reconsidering using TailwindCSS, however useful it is, after reading some articles on the subject. I attempted to replicate the current look of without TailwindCSS, and failed. So I'm probably going to rewrite the site again, though I'm not sure how. Through iteration, we will arrive at a stable version – this one, unfortunately, is not yet it. If I do leave Svelte, which is probably a 50/50 chance at this point, I would probably go either back to Hugo (with some variation of the incredible archie theme) or to Zola. + +=> Etcd, or, why modern software makes me sad +=> Why you'll probably regret using Tailwind +=> Hugo +=> archie theme +=> Zola + +## Real World Updates + +### CyberSec + +So, some pretty crazy things have happened. For one, Twitter got hacked by some people from OGUsers who got access to some internal managment tools. This hack, though not necessarily the most technical hack, was super high profile. There were a few really good articles written about the hack, but I also noticed a few people acting in ways that I thought were not appropriate. More specifically, Biran Krebs, who reacted to the hack by repeatedly doxxing the hackers, many of whom are still teenagers. He's received relatively little criticism for doing this, though it appears to be a pattern of behavior. + +=> Techcrunch on the Twitter hack +=> OGUsers +=> No, you couldn't have made more money than the Twitter hacker + +=> Biran Krebs +=> Dox #1 +=> Dox #2 +=> Little criticism +=> A pattern of behavior + +There was also a brief mention of a new macOS malware, but judging by the lack of further publicity it's probably not that common in the wild. That, or people don't care because it's spread mainly through torrenting sites and they don't want to protect people they perceived to be morally below them – which is wrong, obviously. + +=> Wired on macOS malware + +### Driving + +I learned how to drive! Or rather, I got kind-of licensed to drive a car in the US. I've been driving around a lot lately as something fun I can do to pass time in quarantine, and last week I finished my online driver's ed course and got my learner's permit. It was a surprisingly simple and COVID-friendly process! The most complicated/least COVID-friendly part was going to the DMV to take the written test, but I wore a mask and gloves and glared at anybody who got remotely close to me. The next steps are much more dangerous to do during a pandemic, but we have a year to complete them so we're going to delay them (some in-person driver's training and the driver's test) for a bit. For now though, I have a piece of paper that says I can learn to drive! + +### Better Platforms + +I've also taken some time to focus on decentralization. I've had a Mastodon account for a while, but I rarely used it. I didn't have a mobile client, and I almost never use social media on my computers. To help change my behaviour I downloaded Mast, a paid Mastodon client for the Apple ecosystem. I went with Mast mostly because it's gorgeous – and open source – which is something I value in the apps I use. Apps that look really nice are fantastic inspiration for my own apps' designs, and this one is no exception. + +=> Mastodon account +=> Mast on the App Store +=> Mast source on Github + +I've also started using three other apps much more heavily recently: Feedly, Octal, and Element. Feedly is a fantastic RSS reader, which helps me keep track of all the interesting blogs that I find online (I read somewhere about self-hosting an RSS reader, which sounds pretty cool, but I forget what it was called). Octal is a HN client for iOS, which is really handy for keeping up with my favorite tech news when I'm away from my computer. Element (previously Riot), is the first-party Matrix client that makes using a decentralized E2EE chat service feel better than Discord. I love it. In an ideal world where I could choose the tools I use to communicate with people, I would only use Signal and Element/Matrix (for replacing iMessage and Discord/Slack, respectively). + +=> Feedly +=> Octal +=> Element +=> Matrix + +### Music + +Oh my god there's so much new music. + +* Jonny by Bar Tsabari +* Kukuriku by Eden Ben Zaken and Omer Adam +* Ta'azri et Atzmech by Dekel Vaknin +* Sivuvim by Eden Hason +* Lecha Dodi by Moshe Peretz and others +* Haravot BaPita (Album) by Peled +* Magevet BaAvir by Noroz +* Nadav_15 by Shekel +* Moshe by Narkis and Miri Mesikah +* Tik Tok by Mohamed Ramadan and Super Sako +* Aliyato VeNiflato Shel Shem Tov Hevi by Tamir Bar +* Falafel Pop (Album) by Quarter to Africa +* Lama Kacha Atzuva by Idan Raichel and Stav Beger +* Kapara by Kevin Robin and Rotem Cohen +* Ehad HaAm by Aya Zahavi Fayglin + +## Wrapup + +I hope you enjoyed reading this update! I know it's much longer than usual, and I'll try and keep them shorter than this from now on. I plan on uploaded more short, topic-focused articles rather than just updates, but those will come soon. For now though, I need to focus on knocking out some of the larger projects that I'm working on. I keep finding cool and interesting things to do, and I need to work on finishing the ones that I've already started! + +Salamat, +FIGBERT + diff --git a/content/log/2020-07-28-pebkac-txtodo-rewrite.gmi b/content/log/2020-07-28-pebkac-txtodo-rewrite.gmi @@ -0,0 +1,118 @@ +# Problem Exists Between Keyboard and Chair: How I Spent 2 Days Chasing a Bug that Didn't Exist + +Post-WWDC2020, I decided to rewrite the backend of txtodo in SwiftUI using the new App and Scene structure. Rebuilding the app from scratch may have not been the best choice, but during that process I have massively simplified the app's data structure, despaghettified some messy UI code, and spent two full days trying to solve a problem that didn't exist. This is the story of that last bit. + +=> WWDC2020 +=> App and Scene structure + +## Structural Changes + +The new app, so far, was mostly the same as the old version but without the AppDelegate.swift or SceneDelegate.swift files (using the new XCode 12 multiplatform app template). I also combined the Core Data FloatingTask and DailyTask entities into one Task entity. By this point, everything was running well enough so I started to migrate more code into the new codebase starting with the fetch request: + +```swift +@FetchRequest( + entity: Task.entity(), + sortDescriptors: [ + NSSortDescriptor(keyPath: \Task.completed, ascending: true), + NSSortDescriptor(keyPath: \Task.priority, ascending: false), + NSSortDescriptor(keyPath: \, ascending: true) + ] +) var tasks: FetchedResults<Task> +``` + +## Breaking TaskView + +Tasks are displayed as TaskViews in a ForEach loop on the homescreen, which is simple enough. The TaskView struct, however, is relatively complicated. The purpose of TaskView is to represent and manipulate a single Task. In the previous version of the app (I'm going to call the original version 2.0 and the rewrite 3.0 from now on), this involved passing a number of attributes individually to be manipulated as the view's @State. When migrating the view, I reduced this to a single @ObservedObject. I also removed some of the text styling, which I planned to port over after I got the UI functional. + +I ran the app on my device, and this happened: + +=> /static/media/pebkac-txtodo/ascending-checkmarks-error.mp4 Bizarre ascending checkmarks error (video) + +Well that was unexpected. Instead of checking off the tasks I selected, tasks were checked off starting from the bottom and ascending – obviously not the intended behavior! My first thought was that it was caused by the use of @ObservedObject to declare the view's task property – I haven't seen it used to manipulate a Core Data entity before, but it's worked fine so far in txtodo – so I rewrote the variables to match version 2.0. + +```swift +// VERSION 3.0 +struct TaskView: View { + @Environment(\.managedObjectContext) var managedObjectContext + @ObservedObject var task: Task + @State var priority: Int + @State private var config = TaskConfig() + // UI... +} + +// VERSION 2.0 +struct floatingTaskView: View { + @Environment(\.managedObjectContext) var managedObjectContext + @ObservedObject var task: FloatingTask + @State var completed: Bool + @State var name: String + @State var priority: Int + @State var deleted: Bool = false + @State private var editingText: Bool = false + @State private var editingPriority: Bool = false + @State private var viewingNotes: Bool = false + @State private var confirmingDelete: Bool = false + // UI... +} +``` + +Still no change. It was getting pretty late at this point, but I decided to stick it out for just a bit longer. I rewrote the `TaskView` struct from scratch *two more times* to no avail. Something was wrong, but I had no idea where it was and there was no way I was going to figure it out at two in the morning by coding it again the exact same way. + +## Fantastic Bugs and Where to Find Them + +The next morning, I took a look at the code again. If the problem wasn't in `TaskView`, where was it? The only other thing in the UI was the button to make a new task, which looked something like this: + +```swift +Button(action: { + let newTask = Task(context: self.managedObjectContext) + = "test" + newTask.priority = 3 + newTask.notes = [String]() as NSObject + = UUID() + = Date.init() + newTask.daily = true + do { + try + } catch { + print(error.localizedDescription) + } +}) { + Text("Add") +} +``` + +Some of you may have figured it out by this point. At the time, I was still confused – this was the exact method I was using in my previous app, but with preset values – how could it be broken? I modified the generation slightly so I could tell the difference between tasks, and hopefully get to the bottom of the issue: + +```swift +let newTask = Task(context: self.managedObjectContext) = String(UUID().uuidString.prefix(Int.random(in: 5..<9))) +newTask.priority = Int16.random(in: 1..<4) +newTask.notes = [String]() as NSObject = UUID() = Date.init() +newTask.daily = Bool.random() +``` + +I ran the app again and saw this: + +=> /static/media/pebkac-txtodo/randomized-test-values.mp4 The same code, randomized variables (video) + +## Intentional Behavior + +The tasks weren't being marked off in ascending order. They were being moved to the bottom automatically when marked as complete, which I couldn't see because a) all the tasks were identical and b) there were no animations to indicate that was happening. They were sorted by the FetchRequest with a NSSortDescriptor, to make sure that the unfinished tasks are the first thing the user sees. The "glitch" I had spent two days chasing down was entirely by design, and I had just forgotten. + +There were two main things I learned from this experience. First, it's incredibly important to be able to take breaks. The difference between spending two days trying to fix a non-existent glitch and realizing it's a feature you implemented could be as simple as a nap – it was for me. Secondly, your test and placeholder data is more significant than you might think: garbage in, garbage out definitely applies here. If all your test data is the same, your tests are not good tests. + +=> GIGO (garbage in, garbage out) + +## Wrap-up + +To make the sorting more clear, I randomized the tasks' priority, name, and category (as seen above) and added an animation with `.animation(.easeIn(duration: 0.25))`. The current prototype looks something like this: + +=> /static/media/pebkac-txtodo/update-preview.mp4 A sneak peek + +This has been a really fun blog post to write! A got a big laugh out of this bug chase, and I hope you've enjoyed reading it. + +Till next time, +FIGBERT + diff --git a/content/log/2020-08-22-going-full-static.gmi b/content/log/2020-08-22-going-full-static.gmi @@ -0,0 +1,55 @@ +# Going Full Static with Zola + +Those of you who read my last "I Wrote This" post will know that I was having some trouble with my website. My site was coded using Sapper, a Svelte-based web-app framework I had been using for some time. I had chosen to use Sapper because it allowed me to stay as close to the web-metal as possible, while still letting me do some fancy things like use components, scoped CSS, and server routes. However, after diving deeper into website tests and statistics, I started noticing that my "static" site had a lot more moving parts than I thought. The HTML was crammed full of inline scripts and blobs, tanking performance, wreaking havoc on my CSP, and breaking the site for people with scripts disabled. I decided to move the site to Zola, a ludicrously simple static site generator made in Rust. + +=> Explore the site source here +=> Svelte (still my JS framework of choice, when I must touch the seething wound that is JS) +=> Zola <3 + +## NPM Hell + +I decided I was going to rewrite my site partially because I have a bad habit of rewriting everything all the time, but also because of Sapper's underwhelming response to this Github issue: + +=> An issue suggesting the creation of a "script export" mode + +The issue proposes a "strict export" for Sapper sites to remove inline scripts and use of eval(). I think this is a great idea, but it unfortunately has not received much attention. + +--- BEGIN EDIT --- +When I initially wrote this post, I saw that the issue had been added to a "Roadmap Triage" project board. Checking back now (2021-04-12), Sapper is being retired in favor of SvelteKit. However: + +=> It has the same issue. +-- END EDIT --- + +I started a new branch and began working to translate my site to Sapper's main competitor, Routify. Sapper and Routify are not the same thing, but for me they both would serve well enough. After around two days, I had a working MVP of my site in Routify. + +Then disaster struck: I got a bunch of emails from Github. A series of high priority security vulnerabilities had been found in dependencies used by basically all of my web projects. I spent a day force-updating all the dependencies of my web projects – a bit of a pain because npm refuses to natively upgrade breaking changes – and decided to stay as far away from the Javascript ecosystem as possible. I hate that when I install a JS framework, a fundamental tool of modern web development, I install a million other dependencies that could, and often do, have critical security vulnerabilities. I'm thankful that Dependabot caught these ones, but it really killed my enthusiasm for using any JS framework on my site – which means Routify was out of the picture. + +## The Last Dependency Standing + +I decided to use a static site generator. I'd heard of many of the big boys in the past, like Hugo, Jekyll, and Eleventy, but they all had their own problems when I looked at them in the past. Hugo has god-awful templating syntax, Jekyll is Ruby-based and I don't know Ruby, and Eleventy isn't even an escape from Javascript! So I decided to use Zola, a "one-stop static site engine.". Zola is made in Rust, so it's super fast, and it's designed to be dead simple. Seriously: the CLI has only five commands, everything is configured from one .toml file, and your content is all written in "Augmented Markdown." + +The interesting thing is that there's honestly not much more to the story because of how easy and simple Zola is to use. All of my posts and projects go into the content directory, my CSS, favicon, and miscellaneous files (non-content related stuff like emojis and public keys) go in the static directory, and templates and shortcodes go into the templates directory. If I was using a theme, it's files would go into a theme directory. + +### Benefits + +* My slow Python script to convert Markdown posts to Svelte (which was perfect at first but I then packed full excess tests and sandboxing) is gone. Zola handles that automatically. +* I got rid of TailwindCSS, and replaced it with custom styles. It's actually pretty fun to write simple custom CSS, especially with modern tools like variables. +* Writing new posts is ludicrously easy now. I write a post in Markdown, throw any images or videos used in the same directory, and publish. +* Zola comes with a whole bunch of features built-in that I didn't have before, like syntax highlighting and anchor links (the latter of which I have yet to set up). Other things are just handled automatically, like feed generation or i18n. +* Build times are much faster. Exporting with Sapper wasn't slow, but it didn't feel instant. Zola does. + +### Drawbacks + +* You sacrifice a certain amount of control by using a static site generator, like link properties. You could solve this with shortcodes, or by contributing to the project (which I plan to do). +* I mean that's really it to be honest. + +EDIT: This issue has been fixed in Zola – you can now add attributes like noreferrer to links automatically... so I guess no drawbacks? Yeah that feels right. + +## To Infinity and Beyond + +I'm really happy with using Zola, and I look forward to continuing to work with it in the future. I want to publish my blog's styles and templates as a Zola theme, but I have to iron out a few kinks (like anchor links, which are still a bit finicky on my end) before that. I also have yet to re-implement a bunch of the indie-web features and GoatCounter analytics of my old site into this version. Overall though, I think it's been a really fun and productive experiment using Zola, and I'd highly recommend using it for anybody looking for a great, no-nonsense static site generator. + +EDIT: Anchor links are working, and I decided to forgo analytics altogether. My site's better off without JS. + +Until next time, FIGBERT. + diff --git a/content/log/2020-10-07-mac-control-center-is-better.gmi b/content/log/2020-10-07-mac-control-center-is-better.gmi @@ -0,0 +1,9 @@ +# MacOS Control Center is Better + +I've been using the macOS Big Sur Beta for a couple of months now. So far it's pretty fantastic, and a surprisingly smooth experience over all. One brand new feature in this update is the introduction of the Control Center. + +Regardless of your opinion on the iOS-ifying in macOS Big Sur, the new Control Center has at least one leg up on that of iOS: Control Center on macOS actually turns off services. + +=> /static/media/macos-control-center.mp4 See the difference? + +Did you catch that? It's pretty subtle. When you try and turn off Bluetooth or Wifi on iOS, they aren't actually turned off: they're just temporarily disabled. The interface still broadcasts, it just doesn't accept new connections. It's one of my biggest pet peeves, and I'm glad Apple got it right with macOS. Now if they could just port it to iOS... diff --git a/content/log/2020-11-01-moving-to-hetzner-from-digitalocean.gmi b/content/log/2020-11-01-moving-to-hetzner-from-digitalocean.gmi @@ -0,0 +1,48 @@ +# Moving to Hetzner Cloud from DigitalOcean + +Since I began working on self-hosting, I've been using a DigitalOcean VPS running Debian 10. However, after investigating the alternatives in the space, I'll be moving to Hetzner Cloud when my DigitalOcean credits run out in six months. Here's why. + +=> DigitalOcean (affiliate link) +=> Hetzner Cloud + +I went with DigitalOcean as my hosting platform primarily because of the USD$50 credit included with Github Student. I've used USD$20 of that credit as of today, and the remaining money should run out around April 2020, giving me almost a year of VPS for free. Not a bad deal. + +=> Github Student + +With that said, as my credits hit the half-way point, I've begun to think about what's to come. Namely, the fact that my current server is running at a constant 80% memory usage – severely limiting what I can self-host. + +## Money talks... + +I currently use the cheapest DigitalOcean VPS available. I have 1 vCPU, 1GB of RAM, 25GB of SSD, and 1TB of data transfer. All that power is packed in a clean USD$5 per month. This is, as far as cloud hosts go, pretty good bang for your buck. Hetzner blows that out of the water. Take a look at this table: + +```table +┌─────────────┬──────────┬────────────┬─────────────┬─────────────┬────────────┐ +│ USD/Month │ vCPU │ Memory │ Storage │ Traffic │ Provider │ +╞═════════════╪══════════╪════════════╪═════════════╪═════════════╪════════════╡ +│ $3.41 │ 1 │ 2GB │ 20GB │ 20TB │ Hetzner │ +├─────────────┼──────────┼────────────┼─────────────┼─────────────┼────────────┤ +│ $4.77 │ 2 │ 2GB │ 40GB │ 20TB │ Hetzner │ +├─────────────┼──────────┼────────────┼─────────────┼─────────────┼────────────┤ +│ $5.00 │ 1 │ 1GB │ 25GB │ 1TB │ DO │ +├─────────────┼──────────┼────────────┼─────────────┼─────────────┼────────────┤ +│ $6.70 │ 2 │ 4GB │ 40GB │ 20TB │ Hetzner │ +├─────────────┼──────────┼────────────┼─────────────┼─────────────┼────────────┤ +│ $10.00 │ 1 │ 2GB │ 25GB │ 2TB │ DO │ +└─────────────┴──────────┴────────────┴─────────────┴─────────────┴────────────┘ +``` + +Check out the math on that, seriously. Hetzner's base tier offers 1 vCPU, 2GB of ram, 20GB of SSD, and 20TB of data transfer for USD$3.41 per month. That's double the ram and 20 times the transfer for almost half the price of my current DigitalOcean droplet. The fourth down in the table above, the one I plan on purchasing, costs USD$1.70 more than DigitalOcean and has quadruple the performace of my current VPS. That's more than even Docker could need. Ok that might be a slight exaggeration, but it's still a lot. + +## ...and it speaks for the trees. + +Hetzner is a green hosting provider, as certified by the Green Web Foundation. DigitalOcean is not. Obviously, climate change is important. If we look at it objectively, it's one of the only extinction-level threats to human existence at the moment. All that is to say that switching to a green hosting provider is the only thing I need to do according to a random online website carbon calculator, and you know I can't resist online website metrics. + +=> Green Hosting Provider Directory +=> Random online carbon calculator + +## So that's nice. + +Anyways, that's a pretty good summary of my thoughts on the move. I'm probably going to use the move to make a few other changes to my hosting setup (i.e. `docker-compose` to `k3s`, `umami` to `plausible`). I'll keep you all abreast of the latest updates to my hosting in future posts. + +Until then, this is FIGBERT signing off. I should make a more consistent outro. + diff --git a/content/log/2020-11-16-a-very-convincing-terraria-review.gmi b/content/log/2020-11-16-a-very-convincing-terraria-review.gmi @@ -0,0 +1,8 @@ +# A Very Convincing Review of Terraria + +=> /static/media/terraria-review.jpg A review of Terraria, on Steam + +> "I have never hated a game more in my life, i would rather get the skin on my nuts ripped off than play this game for another hour." – Dbama 57.028, played 2046.2 hrs at review time. + +If I wasn't certain I wanted this game before, I am now. + diff --git a/content/log/2020-12-31-how-to-mirror-your-iphone-to-your-mac.gmi b/content/log/2020-12-31-how-to-mirror-your-iphone-to-your-mac.gmi @@ -0,0 +1,16 @@ +# How to Mirror Your iDevice to your Mac + +I recently found myself debugging a mobile game I'm working on with a friend over Jitsi. I had no trouble sharing my Godot window, Xcode console, or IRC bouncer. But how were they going to view the output on my phone? + +Well turns out it's really easy, and requires no non-default software: + +1. Open Quicktime +2. Press File -> New Movie Recording (or ⌥ + ⌘ + N) +3. Plug in your iDevice (I've only tested with an iPhone) via USB +4. Click the down caret by the red record button +5. Select your device as the Camera + +That's it! I didn't even need to record anything, as I just used Jitsi's built-in Window Sharing feature to share the screen live. + +If you want to record your phone with something more powerful than Quicktime, you can use OBS and select your phone as a Video Capture Device. + diff --git a/content/log/2021-01-02-sass-style-update.gmi b/content/log/2021-01-02-sass-style-update.gmi @@ -0,0 +1,25 @@ +# SASS and Light Mode + +Obviously, this doesn't really apply to the capsule. Gemini doesn't have CSS (or an equivalent), which is something I'm largely appreciative of. It lets you focus on content, rather than how the text looks. Plus, you can still maintain a unique look through the use of emojis, ACII art, and other little personalizations. Regardless, I'm going to keep this post up on Gemini for consistencies sake, so if you want to read a little bit about my the HTTP version of, read on. + +I'm on a roll! A second blog post in less than a month! Crazy. Anyway, as you may have noticed – depending on whether or not you read this via RSS or on the main site – I changed the site styles. I got rid of dark mode, added styles for code and keyboard blocks, and changed the look of links to a new cool design. + +Update: I brought back dark mode. Light mode gave me anxiety. + +It all started the other day when I was cruising through cyberspace and noticed a rather unique looking link style. Instead of the traditional underline styling, hyperlinks were surrounded in square brackets (like Markdown). I thought it was a really cool change, and made the site stand out – so I stole the idea and implemented it here! Yay for stealing. + +However, when I went to add the new style to my site I noticed that my global.css file had gotten rather lengthy and disorganized. Given that Zola comes with built-in support for Sass, I thought I might try it out. I found it easy enough to pick up given that I already know CSS. I decided to use Sass' indented syntax, which required more work to convert from my existing CSS but – in my humble opinion – looks much cleaner. + +=> Sass indented syntax + +Given that I was already tinkering with site styles, I decided to implement a couple other changes. I abandoned the site's dark mode, as though I myself am an avid dark mode user, I couldn't find a way to implement it in a satisfying way. If I figure out a Sass-y way to do so, I may add it back. I added a border around inline code blocks, because I thought I already had done that. Lastly, I added StackExchange's amazing <kbd> styling. + +I'm pretty happy with the new styles, but I have no doubt I'll continue to tweak it as I find cool designs around the web. + +Thanks for dropping by: see you next time! + +-- +FIGBERT + +PS: It's interesting that Sass supports both of the two modern syntax paradigms, both the indents and linebreaks camp (Python, etc) and the brackets and semicolons camp (C, Rust, etc). I don't really prefer one over the other, but it's an interesting divide. + diff --git a/content/log/2021-01-21-my-first-regex.gmi b/content/log/2021-01-21-my-first-regex.gmi @@ -0,0 +1,34 @@ +# My First RegEx + +``` +(?<=\.\/IssuerIcons\/).*(?=\.png) +``` + +## What it does + +Let's break it apart piece by piece. It's meant to return the filename from a given path in a specific format. When given ./IssuerIcons/Example.png, the expression should return Example. + +The first section is a positive lookbehind: (?<=\.\/IssuerIcons\/). This asserts that the selected portion must by preceeded by ./IssuerIcons/. + +The section section is a pattern match: .*. This matches all characters, excluding newlines, of any length. + +The third and final section is a positive lookforward: (?=\.png). This asserts that the selected portion must be followed by .png. + +## Background + +Yesterday, I wrote my first regular expression. I've always regarded regex as an arcane art of true shell wizards – and for the most part, I still do. Now though, I've gotten a glimpse of their world. + +I wrote this expression for Tofu, an open-source 2FA app for iOS. I had been thinking of making more "issuer icons" for the app when I noticed that the icons were all designed in one Sketch file. This could become a problem if two people were to edit the file at one time, so I suggested a solution. + +The author got back to me with another idea: ditch Sketch altogether, and replace it with a shell script that generates icons from a directory of pngs. I wrote it. I've since refined it, with help from ThinkChaos, to make it independent of any preceding directories using sed: + +``` +sed -E 's:.+/(.+)\.png:\1:' +``` + +It was a really fun experience – I've never written bash before! It reminded me a lot of Drew DeVault's post Become shell literate. I work primarily from my terminal, and am slowly working my way up to true mastery – I'm nowhere near close, but this was a step in the right direction. + +=> Become shell literate by Drew DeVault +=> /projects/tofu.gmi Read more about my contributions to Tofu +=> Download Tofu on the App Store + diff --git a/content/log/2021-01-22-remarkable-tablet.gmi b/content/log/2021-01-22-remarkable-tablet.gmi @@ -0,0 +1,66 @@ +# Quite the reMarkable Device + +Lately, there's been renewed interest in clean, simple technology built to help us focus. Protocols like Gemini strip away the chaos of the web. Hardware hackers fit screens in mirrors and build beautiful minimalist displays to read the news, display data neatly in a picture frame, or provide a daily summary. + +=> gemini:// Gemini +=> Smarter Mirrors and How They're Made +=> This Super-Clean Smart Screen Puts a Newspaper on Your Wall +=> Let's Make More Calm Technology: Accent, the Smart Picture Frame +=> Hacking Together an E-ink Dashboard + +Hidden amongst these many awesome projects is the reMarkable 2. + +=> reMarkable 2 + +I've been using the reMarkable for the past month or so and it is a seriously solid device. I use it mainly to take notes, at which it excels. The e-ink display is the best I have ever seen, barely ever refreshing the entire screen and almost entirely without the temporary artifacts that plague similar devices. The pencil is comfortable to use – slightly fuzzy – and, interestingly, entirely passive: it never needs to charge. Given that it's meant to replace your paper, it shouldn't be too surprising that the tablet's also incredibly thin. + +## cornellNotes + +In one of my classes, I'm required to take Cornell notes. On what may be a related note, it's a terrible class. Regardless, I need to get an A and so notes I shall take. The reMarkable comes with a built-in Cornell notes template. It's slightly different than the format I'm used to, but it fits the bill well enough. + +It's hard to describe the experience of using the device. I would say that it feels shockingly natural. Using it to take notes feels like writing on a clipboard with none of the usual annoyances – the paper sliding, having finite pages; and all the benefits of a digital device – sending files via email, OCR, a select-and-drag tool, etc. It's convenient, feels nice, and performs well. Most importantly, it makes me *excited* to use it every time I turn it on. + +## workSheet + +In another class, the instructor distributes worksheets every once in a while to complete during class. Now that we're in distance learning due to COVID, these are pdfs – perfect for use with the reMarkable. + +I download them onto my laptop, upload them through the app, and voila. Look Mom, no scratch paper! I can write directly on the worksheet. I've only started doing it this week, and it's amazing. Sure, there are programs on the computer that allow you to write on a pdf, but doing math with a trackpad sounds like torture. With the reMarkable, it's enjoyable. + +That's the device's biggest impact. I used to hate writing by hand. I would beg my teachers to let me type assignments so I didn't have to use a pencil – what am I, a caveman? Now, my paper has superpowers. + +## notKindle + +It's also a suprisingly good reading device, with native support for epubs and pdfs. It doesn't have a backlight, but to be fair neither do actual books so I'm not too bothered. The default font size is quite large, and the UI is really minimal which makes for peaceful, undistracted reading. I own two Kindles already, but I've taken to using the reMarkable instead for a number of reasons: + +1. There's no ads or tracking. On Kindle there's an ad on the bottom of the homescreen, which expands to the whole screen when you turn it off – plus it sends every move you make to live forever with Big Papa Bezos. Not so with the reMarkable. +2. The screen on the reMarkable is physically larger. Though sometimes the compact size of my Kindle comes in handy, like when traveling, having a nice big display is definitely an advantage. My Kindle is closer to a large phone, and the reMarkable is definitely a tablet. +3. The reMarkable is a fairly open device. The Kindle, on the other hand, is locked down and dripping with DRM (fairly easy to break but still an encumberance). + +The developers have also made a browser extension for Chromium-based browsers called Read on reMarkable, which I would love to see the insides of but is unfortunately closed-source. Basically, it takes any webpage, turns it into an epub, and sends it off to your device. I love it and use it near constantly: whenever I run into anything on HN that is either really long, or I just want to save for later, I hit a button and it sends it to the tablet. Again, just incredibly convenient. + +=> Read on reMarkable extension + +EDIT: Dario Vladović has pointed out to me that extensions are unpackable, and thus though it's not open source it is, by nature, source available. + +## jailBreak + +This section is titled "jailbreak," which is actually a bit of misnomer because the reMarkable runs Linux and you can `ssh` into it with ease. It's also not too fitting because I'm not just going to talk about modifying the device, but also about official accessories. My device came with a Book Folio and Marker in the box, which is pretty good value. I did find out while writing this that they offer a "Marker Plus" that comes with a built-in eraser. It is, unfortunately, out of stock currently but I plan on buying it once it returns in "January 2021," so supposedly sometime in the next week or so. + +=> Markers for the reMarkable 2 + +Ok now time for the jailbreak-y stuff. There's an active community on Freenode, an unofficial wiki, and an Awesome list. All of these are really great resources for cool stuff you can do with your device, and I'm planning to begin experimenting with them in the coming weeks. My first goal is to get KOReader running so I can sync my extensive Calibre library to the device. I'm going to avoid adding any games so as not to add additional complexity to a device that aims to remove distractions, and proceed slowly so I don't brick my fancy new toy. Stick around to see how that goes. + +=> Unofficial wiki +=> Awesome list +=> KOReader + +## pS + +The recently published fairly viral Ditherpunk article by Surma gives a really interesting overview of image dithering. After reading the article, I noticed that the reMarkable itself uses dithering to "fade off" your writing and make it look like pencil. Neat. + +=> Ditherpunk article + +Also, comparing the reMarkable to the Kindle makes me want to jailbreak that too – I'll find some time to look into that soon. + +EDIT: I ended up jailbreaking one of my Kindles, which I now use daily as my primary book-reading device (as opposed to the reMarkable, which I think of as an article-reading device). I should write some stuff about that. + diff --git a/content/log/2021-02-10-some-quality-shitposting.gmi b/content/log/2021-02-10-some-quality-shitposting.gmi @@ -0,0 +1,18 @@ +# Some Quality Shitposting + +I was doing my daily HN and Lobster trawling, when I stumbled on a post by boringcactus which sounded somewhat familiar. About half way through I realized it was a truly epic shitpost and genuinely burst out laughing. + +The story begins on February 2, 2021, with a post on Drew Devault's blog: + +=> I'm tired of this anti-Wayland horseshit + +It's a good read – Drew's a smart guy (he makes Sourcehut). In it, he disparages detractors of Wayland and says that much of the people who criticize it haven't given it a close enough look and should think about what they're saying before they go shitting on maintainers of an all-together pretty dope project (which, by the way, I use). + +Seven days later he wrote another post: + +=> Rust: "Move fast and break things" as a moral imperative + +In this post, he criticizes the Rust Foundation's attitude toward stability and platform support. A fatal mistake. In one fell swoop, and one s/Wayland/Rust, boringcactus ended this man's career. Check it out: + +=> I'm tired of this anti-Rust horseshit + diff --git a/content/log/2021-03-19-package-in-the-bush.gmi b/content/log/2021-03-19-package-in-the-bush.gmi @@ -0,0 +1,22 @@ +# A Package in the Bush + +A little more than a month ago, I noticed that my computer charger had slightly yellowed at the ends. Though I'm unsure how, it seemed like it had sustained some sort of heat damage. I went over to Wirecutter to pick one out, ordered it off Amazon, and... it never came. + +Checking the app, the package was marked as delivered. Checking my front door said differently. I got a refund and ordered another, which I've been using ever since (pretty good, only downside is that it's only 1m long, but it makes up for that in speed). + +A couple days later – or maybe weeks, I'm not sure – I noticed an Amazon package tossed midway into a bush by my front door. It wasn't the full box kind, made of cardboard. More like an envelope, I suppose. + +> Huh, that's neat. + +> There's an Amazon package in the bush. + +> Wonder what it's doing there. + +After several weeks of thinking this every time I exited my front door (a fairly rare occurance, these days), I opened it. Wet from the rain, I figured it was time to bring it inside. + +It would appear as if the person who received my first charger order delivered it to me, but couldn't quite make it to the door. + +Now I've got two chargers, for the price of one. One from Amazon. + +One from the bush. + diff --git a/content/projects/tofu.gmi b/content/projects/tofu.gmi @@ -0,0 +1,73 @@ +# Tofu + +Tofu is an easy-to-use, open-source, two-factor authentication app designed specifically for iOS, made by Calle Luks. I adopted it after migrating from Authy, and ended up overhauling its icon system. It's a really well designed app: + +When I migrated to Tofu, it had a limited number of hand-designed icons in one big Sketch file. + +=> Ye olde Sketch file + +Each icon was created and exported manually: I set out to simplify the process. + +=> "Hello, good sir, may I simplify some processes?" + +Calle proposed we create a shell script to generate icons on-demand from a folder of pngs. I got my shell hat on and a week later, my pull request was commited to upstream with a brand new bash script. The script iterates over a given directory using `sed` and regex to grab the names of each png inside and add them to Xcode's assets folder. It uses a heredoc as a template for the new imageset's JSON, and the `sips` cli to generate properly sized icons for use in the app. + +=> My pull request + +Contributing to open source projects is incredibly fun. If you've got a free weekend, take some time to hack on your favorite codebase. Big thanks to Calle for creating such an awesome app – I look forward to collaborating more in the future. + +This was my first serious bash script, so I'm fairly proud: +```bash +#!/usr/bin/env bash +set -euo pipefail + +get_name() { + echo $1 | sed -E 's:.+/(.+)\.png:\1:' +} + +write_json() { + # JSON copied from Xcode output + cat << EOF > "$2" +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "${1}.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "${1}@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "${1}@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} +EOF +} + +cd "$(dirname "$0")" +for file in ./IssuerIcons/*.png; do + name="$(get_name $file)" + echo "Generating icon for ${name}" + imageset="./Tofu/Assets.xcassets/${name}.imageset/" + mkdir -p "$imageset" + sips --resampleWidth 192 "$file" --out "${imageset}${name}@3x.png" >/dev/null + sips --resampleWidth 128 "$file" --out "${imageset}${name}@2x.png" >/dev/null + sips --resampleWidth 64 "$file" --out "${imageset}${name}.png" >/dev/null + write_json "$name" "${imageset}Contents.json" +done +``` + +=> Download Tofu on the App Store +=> Explore the source on GitHub +=> Check out Calle Luks + diff --git a/content/projects/txtodo.gmi b/content/projects/txtodo.gmi @@ -0,0 +1,16 @@ +# txtodo + +txtodo is a minimalist open-source todo list app inspired by Jeff Huang's "One File to Rule Them All" and Mac-assed Mac apps like IINA, Sketch, and Safari. It's available for download on iOS and macOS via the App Store. + +=> One File to Rule Them All +=> Daring Fireball on "Mac-assed" Mac apps + +txtodo lists your immediate, short-term tasks to help you get things done without overthinking it. At midnight, all tasks are discarded so you can start fresh tomorrow. You can also create up to three long-term tasks that "float" with you from day-to-day. + +On 15 February 2020, I deleted my account with Trello. A solo developer, I know my projects inside and out. I know what features need work, and which graphics need a refresh. I don't need a massive crudware suite keep track of every little move. I need something small. + +A dead-simple UX and midnight expiration date prevents the overwhelming buildup of tasks we delay over and over again, and helps you deal only with tasks you can get done *that day*. + +=> Read more at +=> Download the app on the App Store +=> Explore the source on my Gitea diff --git a/content/static/age.txt b/content/static/age.txt @@ -0,0 +1 @@ +age1g5jj4u4zwfzask8gcq5uxx3unj3c73ch9kdhy24pca9vudtvsppqmul62w diff --git a/content/static/bitcoin.txt b/content/static/bitcoin.txt @@ -0,0 +1 @@ +bc1qu7m2dqhttm3lr74vm9fs54ywtlugr7gh2lnuz4 diff --git a/content/static/media/blender-doughnut.mp4 b/content/static/media/blender-doughnut.mp4 Binary files differ. diff --git a/content/static/media/ios-jailbreak-tour.mp4 b/content/static/media/ios-jailbreak-tour.mp4 Binary files differ. diff --git a/content/static/media/macos-control-center.mp4 b/content/static/media/macos-control-center.mp4 Binary files differ. diff --git a/content/static/media/pebkac-txtodo/ascending-checkmarks-error.mp4 b/content/static/media/pebkac-txtodo/ascending-checkmarks-error.mp4 Binary files differ. diff --git a/content/static/media/pebkac-txtodo/randomized-test-values.mp4 b/content/static/media/pebkac-txtodo/randomized-test-values.mp4 Binary files differ. diff --git a/content/static/media/pebkac-txtodo/update-preview.mp4 b/content/static/media/pebkac-txtodo/update-preview.mp4 Binary files differ. diff --git a/content/static/media/terraria-review.jpg b/content/static/media/terraria-review.jpg Binary files differ. diff --git a/content/static/ b/content/static/ @@ -0,0 +1,2 @@ +untrusted comment: minisign public key ACD1B48D748FDB1D +RWQd2490jbTRrA+QRkoXWmIpP7ew9wLYMxkrLwUA5noCE/i80Sb07FUU diff --git a/content/static/monero.txt b/content/static/monero.txt @@ -0,0 +1 @@ +44JZxbGg8F121EPCvNjHCRYRBKEdUhDiGNrgHWDt234eHc2X2ux8s78GAmJWyEaNh94WCHBJdA9pYDcaQHuyjZ1SCsb79ps diff --git a/content/static/one-angry-wizard.gblorb b/content/static/one-angry-wizard.gblorb Binary files differ. diff --git a/content/static/publickey-pgp.asc b/content/static/publickey-pgp.asc @@ -0,0 +1,15 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: OpenPGP.js v4.10.4 +Comment: + +xjMEXhQu2hYJKwYBBAHaRw8BAQdARwdzF9LBcu0OiKmurP3qL+d2AY7dusCc +hMW/8zteYhvNKWZpZ2JlcnRAZmlnYmVydC5jb20gPGZpZ2JlcnRAZmlnYmVy +dC5jb20+wngEEBYKACAFAl4ULtoGCwkHCAMCBBUICgIEFgIBAAIZAQIbAwIe +AQAKCRBn8VmNYHqES2MmAP9hl+y8F3NNgn6HefYXG9rRjry2HoycqHXgftbg +cyQEfAEAluNeLJK3SqNVHjF48zXYb6VQ/S2f60T0mEgXKsofiAHOOAReFC7a +EgorBgEEAZdVAQUBAQdAErfPyvRrxYAxvAXSBIrktILEb3QGUBxfIHtniR3B +nG8DAQgHwmEEGBYIAAkFAl4ULtoCGwwACgkQZ/FZjWB6hEu9LQD/YU3TkeDI +KwF0UQyO7skGVHks4YpGL7SczQKay52loGAA/0yBUpIwLm4CaeVaFBrxL9+s +U2vJ411ZiQPASGA3MSgF +=OIC2 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/content/static/zcash.txt b/content/static/zcash.txt @@ -0,0 +1 @@ +t1cVsTxoLZspKgf5BWiNpPLcA7RHzm8Pkwm