Wednesday, March 27, 2024

The Sad Trees of Columbia Pike

Someone spray-painted a frowning face on nearly 30 trees along Columbia Pike*. I have so many questions.

Is this street art? Graffiti? A gang sign? An angry arborist? A statement on global warming? A commentary on local environmental efforts? A protest against the Missing Middle? Were the trees angry all along, and some generous citizen just gave them a voice? Or is this what happens when a group of bored teens get their hands on some white spray paint?

While painting a single tree is low effort, when you count up the number of trees involved and the consistency of each face, it becomes a relatively significant undertaking. Each tree appears to have only one face, and the light poles and other nearby infrastructure were spared. This, combined with years of watching CSI, suggests organized behavior.

So while the obvious culprit is bored teens, it could be more profound. Or more likely, I just want it to be more profound. After all, I do have a habit of seeing street art where others see public defacement of property.

Here are more examples of the trees that now scowl at us from along the Pike. Sorry, trees, we'll try harder.

*Columbia Pike is a street in Arlington, Virginia, and has been since around 1810.

Monday, March 25, 2024

out-of-band is officially out-of-bounds | Reviving emacs oauth2 with Google APIs

For months, I happily edited blog posts in Emacs using a tiny Blogger client I wrote in Elisp called hbo-blogger.el. hbo-blogger.el was easy to write, thanks in part to oauth2.el, which simplifies authentication against Google's Blogger API.

Things all came crashing down one day when I needed to re-authenticate using Google's OAuth2 server. I executed the following Elisp code, expecting it to open a browser, ask me a few questions, and show me a code I could paste back into Emacs.

(oauth2-auth-and-store
       "https://accounts.google.com/o/oauth2/v2/auth"
       "https://oauth2.googleapis.com/token"
       hbo-blogger-oauth-scope
       hbo-blogger-client-id
       hbo-blogger-client-secret)

However, this time I got an error announcing "Access blocked: Blur's request is invalid." Digging deeper took me to this page: Access blocked: Third-party app is using an unsupported OAuth method.

The issue is that oauth2.el sets up authentication using the redirect URL urn:ietf:wg:oauth:2.0:oob. The 'out-of-band' (oob) redirect URL handler works great when you are performing OAuth in a command-line or, in this case, an Elisp context. However, Google now denies this type of redirect URL.

Without a way to authenticate against the Blogger API, hbo-blogger was useless, and I was forced to go back to editing posts over at blogger.com.

What I needed were two things: support for a redirect URL that Google would be happy with, and a way to call oauth2.el using that new URL.

Good news: I now have both of these components, and if you want, you can have them too.

Setting up a Kosher OAuth2 Redirect Handler

First off, I built out oauth2handler. This is a bit of PHP code that runs on a publicly exposed Linux box. It allows you to set up a 'real' redirect URL without having to write any custom code. It serves as a sort of universal OAuth2 redirect URL.

Annoyingly, setting up oauth2handler takes about 12 steps. However, none of the steps are very hard; you just need to be patient.

With oauth2handler, I had a redirect URL. However, I needed a way to integrate this URL into oauth2.el. You can find the code for doing this over at oauth2handler.el.

Like oauth2handler (and heck, all things OAuth2), there's a heap of things to set up. But, once you've got everything properly defined, performing OAuth authentication is easy. Here's a function I can call to initialize the OAuth process:

;; Grab these values from the Google developer console.
(defvar hbo-blogger-client-id nil)
(defvar hbo-blogger-client-secret nil)

;; These can remain set to their defaults for blogger
(defvar hbo-blogger-oauth-scope
  "https://www.googleapis.com/auth/blogger")
(defvar hbo-blogger-oauth-auth-url
  "https://accounts.google.com/o/oauth2/auth")
(defvar hbo-blogger-oauth-token-url
  "https://www.googleapis.com/oauth2/v3/token")

;; Point this to your oauth2handler URL. For me, this is:
;; (setq hbo-blogger-oauth-redirect-url
;;      "https://code.benjisimon.com/oauth2handler/emacs_hbo")
(defvar hbo-blogger-oauth-redirect-url nil)

(defun hbo-blogger-auth-start ()
  "Start the Oauth2 authentication process in the browser"
  (interactive)
  (oauth2handler-start-auth
   hbo-blogger-oauth-redirect-url
   hbo-blogger-oauth-auth-url
   hbo-blogger-oauth-token-url
   hbo-blogger-oauth-scope
   hbo-blogger-client-id
   hbo-blogger-client-secret))

Running M-x oauth2handler-start-auth opens up a new web browser, and just like the 'oob' style of authentication, it prompts me to grant permission. The final page of oauth2handler displays a blob of JSON, similar to the code that the oob URL produces. I copy that JSON into an Emacs buffer that's been opened for me and hit C-c C-c.

Hitting C-c C-c generates the oauth2.plstore file that oauth2.el expects. From there, oauth2 and by extension hbo-blogger.el work again as they should.

In my .emacs.d/init.el file, I have the following settings and function call:

(require 'hbo-blogger)
(setq hbo-blogger-client-id  "<from the google developer's console>")
(setq hbo-blogger-client-secret "<from the google developer's console>")
(setq hbo-blogger-oauth-redirect-url
      "https://code.benjisimon.com/oauth2handler/emacs_hbo")

(hbo-blogger-auth-setup)

hbo-blogger-auth-setup uses oauth2.el's oauth2-auth-and-store function to set up a valid OAuth2 token. This token is what hbo-blogger.el uses to communicate with Blogger's API.

This whole process has been frustrating and exceedingly delicate. However, now that I've got oauth2handler and the corresponding Elisp code, life is good again. It feels good to be back home (editing in Emacs).

Monday, March 11, 2024

The ABC's of Easy to Forget Hiking Essentials

When I find myself in the backcountry and I'm missing some essential item, it's not usually because I've forgotten it. I mean, sure, that happens. There was that notable time when I grabbed my backpack from the trunk and trudged off for a 3-day backpacking trip, only to realize shortly thereafter I'd never changed into the boots still in the car.

Typically, I remember the item but talk myself out of bringing it. Bug spray? There aren't any bugs at the trailhead, so we should be good. Sunscreen? We put it on at the car, so why would we need to re-apply? Trekking poles? The hike is so short, why bother?

Fast forward a few hours, and you'll find us being bombarded by bugs, scorched by the sun, and Shira hobbling because she rolled her ankle during a gnarly section of terrain. At this point, I'm kicking myself for intentionally leaving essentials behind.

The solution to both forgetting gear and being shortsighted is the same: a checklist. For the last year and a half, I've come to appreciate that not all checklists are equal. A written checklist or checklist on your phone is good. But even better is one that you can mentally tick off. This allows you to confirm your checklist when you're packing, have a moment of downtime as the trip approaches, as well as when you're about to step off for the adventure. It's also possible to make a quick written copy of the checklist for times when the stakes are especially high.

A mental checklist sounds like a recipe for disaster, especially for someone like myself who doesn't have a gift for memorization. And yet, I've found that if I structure the items around a series of alphabetically arranged words, I can remember the list with ease. Try it, you'll be amazed at your brain's ability.

Below is my list of easy to leave behind hiking items and the prompts I use to remember them. This list isn't exhaustive, for example, there's no mention of a map or navigation aids. Instead, it focuses on the items that I'm quick to forget or think I can do without.

This photo shows a minimal version of the checklist below*

Agua - Water.

Boots.

Camera.

Deet & Derm - Skin protection from bugs and the sun.

EDC.

Food.

Gloves & Gripping - Gloves for me, Trekking polls for Shira.

Hat.

InReach - Comms: Garmin inReach and if in a group, Rocky Talkies

Jacket - Extra layers.

Kleenex - Bathroom kit (TP, hand sanitizer and a ziplock bag for packing out used TP)

Light - Flashlight.

Mylar - SOL heatsheet and other surival essentials.

No-Blisters - KT Tape to treat blisters and hot spots.


*Wait, aren't items on the list missing from this photo? The camera is my cell phone, which is being used to capture the snapshot. The bathroom kit, flashlight, SOL heatsheet and KT tape are all part of my EDC. I include them in the list so that I can use this checklist for others.

Tuesday, March 05, 2024

A Little Los Angeles

[Composed 10/29/2023]

A handful of business meetings landed Shira and me some time in the colorful city of Los Angeles. While we didn't really have time to play tourist (next time, tar pits!), we did get a chance to explore downtown and a bit of Griffith Park. What we found in the city itself was a mishmash of contrasts: new construction a few blocks from run-down historic buildings; a diverse collection of architectural themes; a map that promised a mighty Los Angeles River, yet bridges that spanned a trickling spillway; and feelings of safety that ran the spectrum from family-friendly to "we're absolutely definitely getting mugged here" (spoiler alert: we were not mugged). And then there's the graffiti. Or, do they prefer to call it street art?

Either way, I kept raving to Shira about how impressive it was. Every surface seemed to be covered in colorful, detailed creations. Like, seriously, when you stop and think about it: how does one go about creating on an 8 x 12 foot canvas that's situated along the side of a freeway or positioned far out of reach? Factor in that the artist only had the resources he or she could fit into a backpack and the clock of discovery always ticking and it becomes all the more impressive. We stepped into The Broad for a proper art experience one evening, and it was nice and all. But I'd argue that with little effort you could find examples in the neighborhood that were superior.

Shira was not as taken by the graffiti scene. Where I saw renegade artistic genius, she saw the destruction of public property. As this article underscores, local street artists would be the first to agree that not all paint on a wall should be considered street art.

We were fortunate to get some nature time in Griffith Park. We started our walk at the base of the park and hiked up to the observatory. As our luck would have it, the observatory opened shortly after we arrived, so we got to see glimpses of the telescope as well as the exhibits within. I found the whole thing quite impressive. We even caught a Tesla Coil demonstration, which naturally I found, well, electrifying.

After touring the museum, we perused a number of trails in the area and took in the sights of downtown LA from a wide-angle vantage point. Between the trails, views, working observatory, historic architecture and free-to-enter world class astrononmy musuem, Griffith Park has to be among the nicest city parks we've ever visited.

We had a number of fine meals during our stay, including one from Green Leaves Vegan and one from Tulsi Indian Eatery, but the clear winner from a culinary perspective was Donut Friend. On impulse, we stepped in and ordered some fancy donuts and ice cream. It was delicious. And then we realized it was all plant based, or as they call it secretly vegan (OK, it's not really a secret). We returned multiple times, including before heading to LAX to pick up donuts for the road. Nothing eases the hassle of waiting around in an airport like yummy donuts. We worried that TSA might confiscate some of the cream-filled creations, but they let them through without incident.

Thinking of iconic cities we've visited: NY, Boston, Philly, Chicago I find myself wondering if LA really is as unique as it seemed in the moment. Was the graffiti really that much more extravagant? The architecture that much more varied? The vegan options that much more plentiful? Maybe. Or maybe LA was just great at delivering that feeling. Either way, it was a great place to visit and I'd relish the chance to explore the city further.