👈🏼 🕸💍 👉🏼
Skip to main content

PGP: C756 2813 F881 06E2 6F1F 547B 003F 530D 3859 B702

Learn more about me. Email me at

cleverdevil

cleverdevil

cleverdevil

cleverdevil

cleverdevil

micro.blog/cleverdevil

www.npmjs.com/~cleverdevil

cleverca.st

 

Indiepaper for macOS

1 min read

Indiepaper LogoIndieWeb Summit 2018 took place a few weeks ago in Portland, OR, and my project on day two was to create a service called Indiepaper, which is a "read it later" service for the IndieWeb. Indiepaper makes use of Mercury by Postlight Labs under the hood to extract article content and then publish it to a Micropub destination for later reading. Indiepaper is open source and is deployed on AWS Lambda using the Zappa framework. The Indiepaper website includes a tool to create a Bookmarklet for your web browser, and a Workflow for iOS that adds system-wide support for sending links to Indiepaper.

In order to make Indiepaper even easier to use, I created Indiepaper for macOS, which adds system-wide sharing support for Indiepaper to macOS. Here is a quick video demo of Indiepaper for macOS in action. Indiepaper for macOS is also open source, so feel free to poke around in the source code, and submit pull requests if you have improvements!

 

Add native support for Indiepaper

1 min read

Regarding Together

Now that I've launched Indiepaper, I'd love to see Together add native support for sending articles to Indiepaper with the click of a button. This would require a few configuration settings, including the configuration of a bearer token and a target micropub destination.

 

Going Serverless with Python WSGI Apps

1 min read

I've been writing web applications and services in Python since the late 1990s, and enjoy it so much that I created the Pecan web application framework way back in 2010. Configuring and deploying Python web applications, especially WSGI compliant applications, is fairly straightforward, with great WSGI servers like Gunicorn and uWSGI, and excellent Apache integration via mod_wsgi. But, for many use cases, creating and maintaining one or more cloud servers creates unnecessary cost and complexity. Security patches, kernel upgrades, SSL certificate management, and more, can be a real burden.

Since the creation of AWS Lambda, "serverless" has become a pretty popular buzzword. Could Lambda provide a way to deploy Python WSGI applications that helps reduce cost, complexity, and management overhead?

It was a fun topic to explore, and I've published a blog post over at Reliam.com about running Python WSGI apps on Lambda!

 
 

Freeing Myself from Facebook

5 min read

Ever since my discovery of the IndieWeb movement, I've wanted to free myself from Facebook (and Instagram) and their brand of surveillance capitalism. I want to own my own data, and be in control of how it is shared, and I don't want it to be used for advertising.

I've had this incarnation of a personal website for a few years, and have mostly been following the POSSE publishing model, publishing most forms of content on my website, and then automatically (or manually) syndicating that content to silos like Facebook and Twitter. But, much of my content still remains trapped inside of Facebook and Instagram.

Until now.

As of March 4, 2018, I've pulled the vast majority of my Facebook content into my website, and all of my Instagram photos into my website, paving the way for me to delete myself from Facebook (and potentially Instagram) by the end of 2018. What follows is a high-level overview of how I made the move.

Facebook

Exporting Data from Facebook

While Facebook does offer an export feature, its extremely limited, only includes very low resolution versions of your photos, and is generally very difficult to process programmatically. After some research, I discovered the excellent fb-export project on GitHub. Once installed, this tool will dump a huge amount (though, not quite all) of your Facebook data into machine-readable JSON files.

Since my website is compatible with the Micropub publishing standard, I then needed to convert this Facebook-native JSON data into microformats2 formatted JSON. Enter granary, an amazing swiss-army knife of IndieWeb by Ryan Barrett. Using granary, I whipped up a quick script that transforms the exported data into native microformats2 formatted JSON:

https://gist.github.com/cleverdevil/f33530706d6e8dacd13a8bd8e8c15dba

Publishing Liberated Data

At this point, I had a directory full of data ready to publish. Sort of. Unfortunately, not all of the data is easily translatable, or even desirable, to publish to my website. As a result, I created another script that let me, on a case by case basis, publish a piece of content, choose to skip it entirely, or save it to deal with later.

https://gist.github.com/cleverdevil/c857695bb2de1e46686d720cad9d124c

After running this script, I had a significant amount of my data copied from Facebook to my website. Huzzah!

Dealing with Photo Albums

Facebook has a "photo albums" feature, and I definitely wanted to get those memories onto my website. Again, I wrote a script that processes the exported data, and selectively allows me to upload all of the photos in an album to my website via Micropub, and then drops microformats2 JSON out that I could publish later.

https://gist.github.com/cleverdevil/d9c08ddc6eb2da0d060a5f6fe87ddf64

Once I finished processing and uploading all of the photos for the albums I wished to copy over, I ran a simple utility script I keep around to publish all of the albums as new posts to my website.

Here are some of the results:

Notice, one of these comes all the way back from 2009!

Almost There

There are still quite a few photos and other types of posts that I haven't yet been able to figure out how to migrate. Notably, Facebook has strange special albums such as "iOS Uploads," "Mobile Uploads," and "iPhoto Uploads" that represent how the photos were uploaded, not so much a group of related photos. Unfortunately, the data contained in the export produced by fb-export isn't quite adequate to deal with these yet.

Still, I am quite pleased with my progress so far. Time to move on to Instagram!

Instagram

Instagram has been slowly deteriorating as a service for years, so much so that I decided to completely stop publishing to Instagram earlier this year. It turns out, dealing with Instagram is a lot easier than Facebook when it comes to liberating your data.

Downloading My Data

After some research, I found instaLooter on GitHub, which allowed me to quickly export every single photo in its original resolution, along with nearly every bit of data I needed... except the photo captions. I ran instaLooter, and embedded the unique identifier in the filenames (which instaLooter refers to as the "code').

Getting Metadata and Publishing

I wrote a script that used granary to lookup the photo metadata and publish to my website via Micropub:

https://gist.github.com/cleverdevil/5bb767fd152de9b4c246d01086e91399

Note, I used the non-JSON form of Micropub in this case, because Known's Micropub implementation doesn't properly handle JSON for photos yet.

Conclusions

It turns out, that with a little knowhow, and a lot of persistence, you can liberate much of your data from Facebook and Instagram. I feel well on target to my goal of leaving Facebook (and maybe Instagram) entirely.

 

Kiddo Concentration

1 min read

William and Colette have been asking for “homework,” since they’ve heard about it from others. William is practicing his fine motor skills and Colette remains goofy.

 

Special Lunch With William

1 min read

Colette had rehearsal for a children’s musical, so Lacey and I took William to lunch at Playa Hermosa on the Hermosa Beach Pier. Good food and lots of smiles with my sweet boy.

 

Editing a post in Known can have destructive side effects on content

1 min read

There is a bug in Known which causes HTML posts published via Micropub to be changed (usually in bad ways) when "editing" the post, even when you don't actually make any changes to the post. I discovered this issue when publishing via Sunlit 2.0, which supports Micropub.

I published two stories:

Because Sunlit doesn't yet support syndication via Micropub, I clicked "edit" on one of the posts, and toggled on syndication to Twitter and Facebook, and then clicked "save." The result was that the post's content was changed (in a destructive way, resulting in visual regressions), even though I hadn't actually edited the content, or even clicked into the content editor.

Seems like this is a bug.

 

Car Museum with William

1 min read

Last week I took William to the car museum in El Segundo for a Hot Wheels event. The event was fine, but we had a lot more fun in the museum itself. William even had the chance to sit in a Deloreon.

 

San Diego with Lacey

1 min read

2018-01-20

Dinner and drinks before our second viewing of Hamilton at the San Diego Civic Theatre.

2018-01-21

Late brunch “the morning after.” The view was far better than the food.

 

1955 Jaguar XKSS

1 min read

Season two of Amazon’s The Grand Tour has been a huge improvement over the lackluster debut season. The latest episode featured the Jaguar XKSS, which was originally released in 1955, and is being rereleased this year by Jaguar. The XKSS is easily one of the best looking cars of all time.

 

Baptism and Political Resistance ✊

3 min read

In today's church service, our pastor delivered a message about the biblical sacrament of baptism. After the message, the congregation was invited to the front of the church to participate in what the United Methodist Church refers to as the "Congressional Reaffirmation of the Baptismal Covenant." Following the process outlined in the UMC Book of Worship, I reaffirmed my baptism in Christ today. Before approaching the baptismal font, I read the following:

Renunciation of Sin and Profession of Faith

On behalf of the whole church, I ask you: Do you renounce the spiritual forces of wickedness, reject the evil powers of this world, and repent of your sin?

I do.

Do you accept the freedom and power God gives you to resist evil, injustice, and oppression in whatever forms they present themselves?

I do.

Do you confess Jesus Christ as your Savior, put your whole trust in his grace, and promise to serve him as your Lord, in union with the church which Christ has opened to people of all ages, nations, and races?

I do.

According the to grace given to you, will you remain faithful members of Christ’s holy church and serve as Christ’s representatives to the world?

I will.

This past year has been extremely trying for me in my faith in the wake of the 2016 Presidential election. Each passing day, I watch as many evangelicals enable injustice and oppression, and fail to reject the evil powers of this world, as the President of the United States spouts overtly racist, isolationist, and sexist words. I watch as many churches and Christians say nothing as the President pushes policies that harm the poor and deepen racial and gender inequality. Evangelicals, especially white evangelicals, voted hugely in favor of this man, and are enabling him every step of the way. I'm personally sick of it.

As I walked through the process of reaffirming my baptism today, I also am renewing my commitment to resist this despicible administration. I have made a promise to God to serve as Christ’s representative, to reject the evil forces of this world, to resist evil, injustice, and oppression in whatever forms they present themselves, and to do it all together with the church, which is open to all ages, nations, and races. Therefore I choose to resist this President, his hateful and isolationist agenda, and all who support him. I wish to do this together with the church, just as I am called. I encourage you to join me.

Note: I am not advocating that the Church should be "democrat" or "republican," or even political. I'm advocating that Christians, as Christ's representatives in the world, are called to fight injustice, oppression, and evil, no matter what form it takes. Right now, one of the most pressing forms of oppression and injustice in the world is Donald Trump, and his administration. Resist.

 

Here's to what's next

1 min read

Last week, I shared that I have decided to move on from DreamHost, and its been a crazy week tying up loose ends, meeting with colleagues to remember our time together, and reflecting on the past. 

Now, its time to focus on what's next.

On January 16th, I start as Chief Technology Officer at Reliam, a managed cloud service provider based out of Los Angeles, CA. Reliam has just secured up to $75 Million of investment from Great Hill Partners to drive growth. Simon Anderson, former CEO of DreamHost, and my ex-boss, has joined Reliam as CEO. I am thrilled by the possibilities that are ahead of us!

Why does this opportunity excite me? Well, that requires some storytelling that will come later. Suffice it to say, the tectonic shift to public cloud is a huge opportunity, and I believe that this team and company have what it takes to help businesses of all shapes and sizes make the move.

Looking forward to an amazing 2018!

 

Micro Monday: Eddie Hinkle

1 min read

Its our first ever Micro Monday, people! Thanks to @manton and @macgenie for deciding to make this happen. I think its a great way to grow the community of Indie Bloggers and Micro.blog itself. My first recommendation for my followers is @eddiehinkle.

Eddie is a fellow IndieWeb developer that I've enjoyed getting to know over the past year or two. Eddie works on an iOS app called Indigenous:

Indigenous is an iOS app that is in development. It’s goal is to provide a native iOS interface to the indieweb movement.

Indigenous is open source, written in Apple's Swift programming language. If you're an IndieWeb-curious developer on Apple platforms, I'd encourage you to get involved with Eddie, and help him with Indigenous!

In addition to his work on the IndieWeb, I also appreciate following Eddie because he writes thoughtful posts about, you know, being a human. Its always refreshing to see someone share how their faith informs their life in an open and honest, accepting way.

Thanks for being awesome, Eddie!

 

Farewell, DreamHost

2 min read

Late in December, I tendered my resignation to the founders of DreamHost. My last day is Friday, January 12th. After over six years, it’s time to move on to my next adventure. But, before I do, I want to spend some time reflecting on my time at DreamHost.

DreamHost is the reason I moved my wife and infant daughter from Atlanta to Los Angeles. We spent our first year in the heart of Venice Beach, in a little condo on Abbot Kinney Blvd., the trendiest street in the trendiest neighborhood in LA. We now have settled into a lovely home in a great family neighborhood in South Redondo Beach, and couldn’t be happier.

In my six years at DreamHost, I’ve held five different positions, covering a huge variety of disciplines and responsibilities – software development, product management, operations, and even managing an entire business unit. I’ve had the pleasure of helping DreamHost become a company with disciplined engineering, product, and marketing teams. I’ve helped guide the company to embrace modern cloud infrastructure, and been part of releasing some of our fastest growing products on top of that infrastructure. We launched two spinoff companies based on open source technology we created, one of which became one of the greatest commercial open source successes ever.

In my six year run, DreamHost has also gone through a major reorganization, redefined our core values, and defined a Noble Cause, Vision, and Mission. We even stood up for the freedom of our customers in a landmark battle with the Department of Justice! We’ve become a company that knows who we are, what we stand for, and how we fit into the world. I’m immensely proud and gratified to have been a part of it.

Today’s DreamHost has an incredible culture, a caring leadership team, and a bright future. It’s been a joy. Keep on dreaming, DreamHost! I’ll miss you all!

 

What’s next for me? Well, that’s a different story...

 

Cord-Cutting Experiments: Part 2

4 min read

Earlier this month, I began experimenting with cutting the cord, starting by evaluating over-the-air options. Early indications had me optimistic that between a solid indoor antenna, an HDHomeRun Connect tuner, and Live TV and DVR functionality from Plex, I'd at least have my problems solved when it comes to the major networks. Sadly, that's turned out not to be true.

Plex + HDHomeRun: Not Ready for Prime Time

As I mentioned before, the HDHomeRun is great, and the antenna does pull in many channels, but its not nearly as reliable as I had hoped, with my local NBC and CBS affiliates being far too spotty. In addition, Plex's DVR and Live TV functionality is extremely unreliable, with recordings going hours over time, hanging completely, or causing my Plex Media Server to crash. I could certainly continue down the rabbit hole by investing in a more powerful outdoor antenna, but they're costly, and there's still the matter of Plex's buggy support for DVR and Live TV. At this point, I don't recommend this path for most people.

Evaluating Streaming Services

With OTA off the table, it was time to start investigating streaming services that offer live TV functionality and cloud DVR. My priorities were:

  1. Local affiliates for the major networks: NBC, ABC, CBS, and Fox.
  2. Full access to ESPN and its associated networks, including access to WatchESPN.
  3. Access to Disney networks for the kids.
  4. More cost effective than DirecTV, my current service provider.

First, I took a look at Sling TV, which provides a highly-recommended a-la-carte service that meets many of my criteria. Many, but not all, unfortunately, as Sling hasn't managed to strike a deal with every local affiliate in my area.

Next, I signed up for PlayStation Vue, which on the surface, ticked all of the boxes. However, my free trial of the service was a total disaster. It took days for my account to activate, and my attempts to contact support resulted in announced hold times measured in hours. When I finally was able to get things working, the quality was pretty low, and the app experience left a lot to be desired. Once my trial was up, moved on.

A New Contender Emerges

Enter Hulu with Live TV, a new offering now in beta from one of the oldest and most respected names in streaming entertainment. Hulu with Live TV met all of my requirements on paper, so I decided to dive right in and put it to the test. Hulu

At this point, I'd love to tell you that Hulu is a perfect solution. The truth is, it isn't. That said, it meets all of my requirements, and its shortcomings are tolerable enough that I've officially cut the cord, and cancelled my DirecTV service. Overall, Hulu is great, with an extensive streaming catalog that is, in essence, like a massive "on-demand" library from a traditional provider. The client app is available on every platform that I use, and works well enough.

My wishlist for Hulu, however, is long:

  • Client apps, as far as I can tell, don't support anything but stereo sound. Why no 5.1 audio, Hulu?
  • The DVR functionality is odd, and takes some getting used to. In addition, if you want to fast forward through the commercials of your recordings, you have to pay extra. This very nearly caused me to cancel and continue my search, but even with the additional charge, the service is a massive cost savings over traditional cable.
  • Weird content restrictions, especially with sports. Want to watch the NFL game that's on your local CBS affiliate? Well, I hope you want to watch it on your TV, because you're not allowed to watch the game on your phone, tablet, or computer. I know that, strictly speaking, this isn't Hulu's fault, but its still annoying as hell.
  • The client app, while very consistent from platform to platform, is a bit difficult to navigate.

The good news is that most of these problems are fixable with software updates, and even with these shortcomings, its still "good enough."

Next Steps

I'm going to keep my eye on Plex and its DVR functionality. If it ever manages to stabilize, I'll spend the time and money to set up a more powerful antenna, so I'll have the highest possible quality option for things like NFL and NCAA football games on the major broadcast networks. This would also give me a chance to re-evaluate Sling, and cut my costs even further. But, for now, I'm going to enjoy being free of AT&T/DirecTV.

 

 

Cord-Cutting Experiments: Part 1

3 min read

Giving hundreds of dollars a month to AT&T / DirecTV has been on my list of expenses to shave for years, now. The kids mostly watch shows from Netflix or my family Plex server, and occasionally will want to watch Disney Channel. Lacey doesn't watch much TV anymore, but when she does, its largely shows on the national broadcast networks. That's pretty true for me, as well, but I have two main vices that I can't shake: sports and HBO.

HDHomeRun Logo

I've decided to experiment with cutting the cord, starting with the option that has the lowest ongoing cost: over the air programming. Thankfully, my aforementioned Plex server supports Live TV and DVR functionality through the use of a network-connected tuner and an antenna. I purchased an inexpensive HDHomeRun Connect tuner off of eBay for about $75, and bought a $10 antenna from Amazon, the Channel Master Flatenna, which was the recommended "cheap" antenna from the Wirecutter. Here are my quick takeaways so far:

The HDHomeRun is great. It was easy to set up, is compact, and responsive. The client application for macOS is barebones, but works really well. I recommend it without hesitation, especially at the price. Just make sure to get a good antenna.

That brings me to the cheap antenna I bought. How'd it go? Well, you get what you pay for. It picked up some channels, but completely failed to pull in ABC and Fox. After spending far too much time moving the antenna around the house trying to get it to work, I broke down and did what I should have done from the beginning, and bought the more expensive, amplified antenna recommendation from the Wirecutter, the ClearStream Eclipse from Antennas Direct. Now, I pull in every available channel with a strong, reliable signal.

Plex Logo

Plex Live TV and DVR shows a lot of promise, but also needs a lot of work. Live TV and DVR are only supported in a few of their client apps right now. Sadly, support doesn't yet exist in Fire TV or Plex Media Player, both of which we use in our house. The Apple TV support is pretty good, as is the iOS client. The user experience is a mixed bag, as well, with Plex choosing to eschew the traditional "grid" approach to presenting live TV content, instead breaking things down to a more Netflix-like experience. I see what they're trying to do, and it sort of works, but frankly they need a grid guide in addition to the more Netflix-like experience. Overall, its fine, not amazing, but I'm optimistic that it will continue to evolve.

With the addition of an Apple TV or two, I think this solution will work well enough to cut the cord, at least for local broadcast content. Apple is rumored to be releasing an updated Apple TV with 4K support, which would work great for us in our great room, where we currently use a Fire TV for our 4K TV. Its entirely possible that Apple will also still offer a 1080p version for cheaper, which we could then place into our home theater, which uses a 1080p native projector.

I'm going to continue tinkering with this setup for the next week or two, and then I will be exploring a solutuion for the rest of our content – sports and HBO. I've chosen Sling TV as the first service to test. That'll be part two, so keep your eye out for my post on that in a few weeks.

 

 

Todoodoo list

0 min read

 

The New Colossus ❤️

1 min read

By Emma Lazarus, 1883

Not like the brazen giant of Greek fame,

With conquering limbs astride from land to land;

Here at our sea-washed, sunset gates shall stand

A mighty woman with a torch, whose flame

Is the imprisoned lightning, and her name

Mother of Exiles. From her beacon-hand

Glows world-wide welcome; her mild eyes command

The air-bridged harbor that twin cities frame.

"Keep, ancient lands, your storied pomp!" cries she

With silent lips. "Give me your tired, your poor,

Your huddled masses yearning to breathe free,

The wretched refuse of your teeming shore.

Send these, the homeless, tempest-tost to me,

I lift my lamp beside the golden door!"