How to Block Distracting Websites on Your Laptop

"What exactly did I do the last 30 minutes?"

I'm sure you've been there, asking that same question, staring blankly into your computer screen.

I've written about how I'm working to minimized distraction. For me, a big component of that is blocking distraction on the device I spend the most time: my laptop.

Here's what I'm looking to do:

Automatically block distracting websites, but allow an easy way to temporarily unblock them. Example: I want to block Amazon by default, but sometimes I want to jump on and buy something quickly. I don't want to have to manage a schedule. Creating exceptions to schedules and then remembering to re-enable the schedule never works well. I don't want crappy software that is going to slow down my computer or cause weird networking issues. I want it to be hard, but not impossible, to disable. One or two clicks to disable is too easy. The Easy Way

For most folks, you'll want to use one of the couple apps out there that do this for you. Here are some that I've tried:

RescueTime Focus Freedom Cold Turkey

Focus is the best option I've found. It's a simple and nicely designed app. Check it out!

The Hard Way

If you like tinkering with your system setup, read on.

The pre-built applications always seemed to do strange things to the networking stack on my computer or hog lots of resources (GBs of memory in some cases). This is probably due to how much I customize my computer.

Also, I found that if I disabled my "blocking schedule" it didn't automatically re-enable. I would then find myself down the Twitter rabbit-hole with 20m wasted. That was a big issue for me.

Eventually, I got frustrated and built a solution which works surprisingly well:

Maintain a simple file listing every host is distracting. Run a script every time the computer wakes up. I used sleepwatcher for this. The script consumes a list of distracting hosts and adds them to /etc/hosts with a reference to a non-existent server. After trying a couple of tools, a node package hostile worked best. 1. Build a List of Distracting Websites

First, create a simple text file. Back it up on Gist or somewhere where it won't be lost. Version tracking the file allows you to view a history of what websites are distracting over time.

I keep this file in my dotfiles repo. Here's what it looks like:

facebook.com twitter.com smile.amazon.com

(yes, that's Amazon Smile since I have a browser extension to redirect me there)

Then you'll want to clean the file, add www variants of each host, and point them to 127.0.0.1:

sed '/^$/d' ./distracting_websites.txt | sed $'s/\(.*\)/127.0.0.1 \\1\\\n127.0.0.1 www.\\1/' > ~/distracting_sites.txt

I put this script in the setup process of my dotfiles for easy ad-hoc execution (you'll want to continually update your distracting_websites.txt as new things distract you).

2. Block all Distracting Websites with a Script

Below is a script that is run every time I wake my computer. Here's what it does:

Updates /etc/hosts using hostile and the distracting_sites.txt file Clears system DNS cache Clears Safari cache, which seems to have its own DNS cache. Chrome does not. # asdf is a node version management tool I use. Your exact execution paths will probably be different /Users/mike/.asdf/installs/nodejs/12.14.1/bin/node \ /Users/mike/.asdf/installs/nodejs/12.14.1/.npm/bin/hostile \ load /Users/mike/distracting_sites.txt # clear system cache # https://apple.stackexchange.com/questions/303110/flush-cache-of-dns-on-macos-sierra-high-sierra/303119#303119 sudo killall -HUP mDNSResponder # clear safari cache osascript << EOF tell application "Safari" activate end tell tell application "System Events" tell process "Safari" tell menu bar 1 to tell menu bar item "Develop" to tell menu 1 to tell menu item "Empty Caches" to click end tell end tell EOF

You can test this script by running it with sudo:

sudo /usr/local/sbin/sleepwatcher --verbose --wakeup .wakeup 3. Run Website Blocking Script When your Computer Wakes from Sleep

First, install sleepwatcher:

brew install sleepwatcher

Then, you'll want to find the location of the plist file which starts up sleepwatcher as a daemon process:

$ brew services Name Status User Plist sleepwatcher started root /Library/LaunchDaemons/homebrew.mxcl.sleepwatcher.plist

You'll want to edit this plist:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>homebrew.mxcl.sleepwatcher</string> <key>ProgramArguments</key> <array> <string>/usr/local/sbin/sleepwatcher</string> <string>-V</string> <string>-w /Users/mike/.wakeup</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/usr/local/var/log/sleepwatcher.log</string> <key>StandardErrorPath</key> <string>/usr/local/var/log/sleepwatcher.log</string> </dict> </plist>

Then, you'll want to ensure the process runs as root and the script you created is executable:

chmod + /Users/mike/.wakeup brew services stop sleepwatcher sudo brew services start sleepwatcher

And... you're done! Depending on your OS configuration you may need to grant some permissions on first run.

Was this overkill? Definitely. Does it prevent me from wasting any time on distracting websites? Absolutely.

Continue Reading

How I Broke My Phone Addiction

The launch of Neuralink started a conversation across the web about the "merge". The day when you can plug your brain into a computer and communicate with it through your thoughts. No keyboard, mouse, or touch screen. Something out of a sci-fi film.

I think Sam Altman has an interesting take:

I believe the merge has already started, and we are a few years in. Our phones control us and tell us what to do when; social media feeds determine how we feel; search engines decide what we think.

This resonated very strongly with me. My phone does control me to a certain extent and I feel uncomfortable if I hop in the car without it.

I've been on a kick this year of being intentional about how I use technology. A big part of that is my phone. It's the most distracting—and the most useful—thing I own.

"What's wrong with your phone? Is it broken?" has been a common refrain when I show a friend a photo or map on my phone. Friends often complain about how slow I am to respond to texts. My phone isn't broken and I know how to use the messages app, but I have taken some "extreme" measures to disconnect from my phone.

Below is the list of things I've done to disconnect from my phone. They work. Not that I'm close to perfect, but I can easily leave my phone in another room now and forget to check it for nearly a day. That's huge.

If they seem extreme, I encourage you try one or two and see what happens.

Turn off Text Notifications

Turn off all your text notifications. Settings > Notifications > Messages > Allow Notifications.

Yes, it's hard and annoying for a week. But man, it is amazing not to hear or see that ding from incoming messages. Once you get over the week or two of withdrawal you'll love it and never be able to go back. I've had my text notifications disabled for months at this point and it is the single biggest change you can make on your phone.

"Communication for work comes through text and I'm expected to respond instantly!"

You win. This won't work for you. Here are two ideas for you:

Can you block texts from non-work numbers? If your work will pay for a separate phone, you could setup that phone with text notifications and disable them on your device.

"What if you are meeting someone i person and need to communicate in real-time?"

This happens to me often. Just open up your message app.

"What if you miss an emergency text from your spouse/friend/whatever?"

Tell your spouse and close friends you've disabled text notifications. If they need you right away, they can call you.

1. Setup an Incoming Call Whitelist

The idea here is only allowing calls from people you know. Any other calls can go to voicemail. If it's important, they'll leave a message and you can listen to it later.

Here's how to setup this whitelist:

Navigate to Settings > Do Not Disturb. Setup a schedule and make it nearly the whole day. Allow Calls From: Favorites (or whatever list includes the people you need to be responsive to). This is your whitelist of people you want to hear from. Install Hiya. I've found this to be a helpful tool for identifying spam callers when reviewing my missed calls and voicemail.

"I may receive a callback from a customer service department or other unknown numbers"

Just disable do not disturb. Because you've setup a schedule, it'll automatically be enabled the next day.

2. Enable Grayscale Mode

This was a trick I pulled from Make Time. Makes your phone less addicting, but no less functional:

Settings > General > Accessibility >Display Accommodations >Color Filters. Switch Color Filters on and select Grayscale. 3. Remove Distracting Applications

Remove any apps which you find yourself pull-to-refresh'ing. Some examples:

Social: Twitter, Facebook, Pinterest, whatever Dedicated news apps Email. Truth be told, I still have this on my phone for work communication. Move any apps that you need to keep, but are distracting, off the home screen. 4. Block Nearly All Notifications

Go through every app on your phone (Settings > Notifications) and turn off notifications. Think hard about the couple apps you really need notifications from and enable them.

Here's my list:

Google Calendar FaceTime Phone Airline apps Google Maps Scooter apps, Lyft, Uber DMs on Slack within working hours Todoist 5. Block Distracting Websites

It's not intuitive but you can block distracting websites on chrome/safari on your phone.

Navigate to 'Screen Time > Content & Privacy Restrictions > Content Restrictions > Web Content > Limit Adult Websites' and enter in all distracting sites under "Never allow".

For example, here's some of my list:

facebook.com twitter.com news.ycombinator.com recode.net theverge.com techcrunch.com producthunt.com quora.com reddit.con

Setup a monthly reminder on your todo list to add any new distracting news sites that you've started looking at on your phone.

Other Tips & Tricks

If you've made it this far, I challenge you to stick with the setting changes for two weeks. That's about how long it took for me to stop being annoyed by the changes.

Below are some other configuration tips & tricks I've written down over the years for when I get a new iPhone.

Other Misc Tips & Tricks Move mail off of the home screen General > Display & Brightness > Night Shift. Enable, 9am-7pm General > Accessibility > Home Button > Reset Finger to Open Delete default apps I'll never use: Home, Books, iTunes Store, Watch, Tips, TV, Apple Mail, News, Stocks. Messages: Enable send as SMS, disable send read receipts, enable text message forwarding. iCloud: disable photos (use Amazon photos instead), enable contacts, disable calendar, enable Messages, disable Stocks, enable iCloud backup, disable Keychain (use 1Password instead) Phone > Call Blocking & Identification: Hiya Spam & Block Enable password autofill for 1Password. Password & Accounts > Autofill Passwords > 1Password. Disable keychain passwords. Amazon Music: download some music you like, enable automatic downloads of offline music, and disable cellular streaming. Download offline google maps for your local area. Automatic Backup Configuration If you have Amazon Prime. Install Prime Photos and use it to backup all of your photos. Settings > iCloud > Storage > Manage Storage > Backups > Disable Photo Backup . 5gb is not enough room for anything, and Amazon gives you unlimited photo storage for free. Plus, there additional storage tiers (if you take a lot of videos on your iphone) is really cheap. Settings > iCloud > Photos > Disable Photo Stream. Manually initiate a backup to ensure everything goes smoothly. Without photos + videos, your iPhone backup should be able to fit into the 5gb default iCloud storage. Warranty & Documentation

Some notes on warranty replacement:

An IMIE number is a unique identifier for your phone. Document this number in a 1Password note. Settings > General > About > IMIE Your ICC number is the unique identifier for your SIM card. Document this as well. If something is going wrong with your iPhone, try backing up the phone to iTunes and then doing a fresh restore. If that doesn't work it's a hardware issue. Try this before wasting your time with Apple/your cell provider. If you get an "Invalid SIM" error when switching cell phone providers or phones your IMIE and ICC numbers may not be "paired'. You can often pair these numbers yourself through the settings area of your cell provider. The support reps often do not check this or understand it fully.

Continue Reading

Learning Clojure by Automating an RSS Reader

I've been working on revamping how I consume information. Most of my information consumption has been moved to RSS feeds, but I can't keep up with the number of articles in my feeds. When I take a look at my reader I tend to get overwhelmed and spend more time than I'd like to trying to "catch up" on information I generally was consuming out of curiosity.

Not good.

I want articles to be automatically marked as read after they are a month old to eliminate the feeling of being "behind". This is a perfect little project to learn a programming language that's looked interesting for a while!

Building a small project in a new language or technology is the best way to learn. While I was building this tool, I documented what questions I was asking, answers to these questions, and what articles and resources I found helpful.

Posts like this have been interesting to me, hopefully this is a fun read for others!

What do I want to build?

I want to build a Clojure script for FeedBin that will:

Inspect all unread articles If the publish date is more than two weeks in the past, mark the article as unread Automatically run every day

Let's get started!

Resources

Here are some helpful blogs & tutorials I used while learning:

http://slipset.github.io/posts/Why-Clojure-is-my-favourite-language https://ltriant.github.io/2019/08/13/clojure-learning-functional-design.html https://learnxinyminutes.com/docs/clojure/ https://eli.thegreenplace.net/2017/notes-on-debugging-clojure-code/ https://clojure.org/guides/getting_started

Also, I always try to grab a couple of large open-source repos to look at when I'm learning a new language. Here are some places I searched:

https://github.com/trending/clojure https://clojars.org http://open-source.braveclojure.com

Some repos I found interesting:

https://github.com/metabase/metabase This is probably the largest full-blown open-source Clojure application out there. Most other projects I found were libraries, not applications. https://github.com/LightTable/LightTable https://github.com/clojars/clojars-web https://github.com/dakrone/clj-http Syntax & Structure

Now that I have some browser tabs open with documentation, let's start learning!

How do I install this thing? https://clojure.org/guides/getting_started => brew install clojure/tools/clojure Going through the "Learn X in Y" guide, some interesting takeaways: Clojure is built on the JVM and uses Java classes for things like arrays. Code in Clojure is essentially a list-of-lists. A list is how you execute code: the first element is the method name, and then arguments separated by spaces. This feels very weird at first, but it's a really powerful concept. Simple made Easy explains the philosophy behind this a bit. "Quoting" (prefacing a list with a single quote) prevents the list from executing. This is helpful for defining a list, passing code as a data structure that can be mutated later on. Sequences (Arrays/Lists) seem to have some important different properties from vectors. I need to understand this a bit more. When you define a function it doesn't get a name. You need to assign it (def) to a variable to give it a name. The [] in a function definition is the list of arguments. There are lots of ways to create functions: fn, defn, def ... #() multi-variadic function is a new word for me! It's a function with a variable number of arguments. Looks like you can define different execution paths depending on the arguments, kind-of like Elixir's pattern matching. [& args] is equivalent to (*args) in ruby The beginner (me!) can treat ArrayMap and HashMap as the same. Keywords == ruby symbols The language looks to execute from the inside out, and the composition of functions is done via spaces not commas, parens, etc. Looks like everything is immutable in Clojure. Everything is a function. So much so, that even basic control flow is managed the same way as a standard function. Looks like "STM" is an escape hatch if you need to store state. Similar to Elixir's process state. The Clojure community is big on "repl driven development", but what exactly do they mean? How is that different from binding.pry in a ruby process to play around with code? Looks like it's not that different. Some nice editor integrations make things a bit more clean, but more or less the same as opening up rails console with pry enabled. I've always disliked the ability to alias a module or function to a custom name. It makes it much harder for newcomers to the codebase to navigate what is going on. Looks like this is a pretty common pattern in Clojure, the require at the top of a file can setup custom aliases for all functions. "forms" have been mentioned a couple of times, but I still don't get it. What is a form? I've heard that Clojure is a Lisp. What is a "lisp"? https://en.wikipedia.org/wiki/Lisp_(programming_language) There was an original LISP programming language, but "a lisp" is a language patterned after the original LISP Seems like the unique property of a lisp-style language is code is essentially is a linked list data structure. Since all code is a data structure, you can define really interesting macros to modify your source code. Another property is the parentheses-based syntax. It's interesting to look at the different lisp styles available. I feel like the only language that is popular today is Clojure. Sounds like immutability is unique to Clojure and isn't a core structure other lisps.

I think I know just enough to start coding.

Coding in Clojure

Here's the learning process which generated the final source code:

Let's define the namespace and get a "Hello World" to make sure I have the runtime executing locally without an issue. 184408626bb41b87d53f9b0bb5485a8e9201d8d5 Ok, now let's outline the logic we'll need to implement. 7e018b05ff8ad925ef2bfe9c56c4a702dce4c3d0 Now, let's pick a HTTP library and figure out how to add it as a dependency. https://clojars.org looks like the most popular package repository. It doesn't seem like there's any download/popularity indicator that you can sort by. Bummer. Hard to figure out what sort of HTTP library I should use. Looks like project.clj is a gemspec type definition file. Metabase's http library is clj-http. Let's use that. We'll also need to figure out how to setup this dependency file. https://github.com/metabase/metabase/blob/master/project.clj#L63 https://github.com/technomancy/leiningen is linked in the project.clj files I've seen. It's listed as a dependency manager on the clj-http library: https://clojars.org/clj-http. Let's install it via brew install leiningen. lein new feedbin and mv ./feedbin./ ./ to setup the project structure. Looks like lein will help us with dependencies and deployment. b0b4022618abac840af6679f900584d04de510c1 There's this skip-aot thing in the main: definition which I don't understand. In any case, if I stuff a defn -main in the file for the namespace defined in main lein run works! 764d7a1e2a537d61b036df4229a2c96671725dd8 It looks like this ^: syntax is used often. What is it? Ok, let's copy our logic outline from the other file we were working on over to the src/feedbin/core.clj and try to add our HTTP dependency. Added [clj-http "3.10.0"] to the dependency list in project.clj, lein run seemed to pull down a bunch of files and run successfully. Now, let's pull the FeedBin variable from the ENV and store it to a var. Looks like you have to wrap let in parens, and include commands that rely on the var within the scope of the parens. I could see how this would force you to keep methods relatively short. 6f1f8099ffd0ed5f997be93685d18d1c574efb6b Let's hit the API and get all unread entries and store them in a var. Looks like cheshire is a popular JSON decoder, let's use that. It looks like let is only when you want temporary bindings within a specific scope. Otherwise, you should use def to setup a variable. 5b63cd289052d9fcebec2cb2965d598927b0616a Convention is - for word separation, not _ or camel case. Let's refactor the getenv to use def. Much better! a6a95a1e4703c07e76ecce32b56b6b0f1903acca Time to select entries that are two months old. A debugger is going to be helpful here to poke at the API responses. Looks like debugger is the pry equivalent. I had trouble getting this to work and deep-dived on this a bit: (pst) displays the stacktrace associated with the last exception. This is not dependent on clj-debugger Looking closer at clj-debugger it has ~no documentation and hasn't been updated in nearly two years. Is there a better option? Doesn't look like it (require 'feedbin.core :reload-all) seems like the best way to hot reload the code in a repl. Then you can rerun (feedbin.core/-main) Ah, figured it out! (break) on it's own won't do anything. It needs an input to debug. (break true) works. You need to run this in lien repl for it to work. As a side note, I've found the REPL/debugging aspect of learning a new programming language to be really important. Languages that don't have great tooling and accessible documentation around this make it much harder for newcomers to come up to speed. The REPL feedback loop is just so much faster and in developer tooling speed matters. I was able to extract the published date, now I just need to do some date comparison to figure out which entries are over a month old. ca16f54f66a39753933168c3f8deac636144ca47 Now to mark the entries as "read" (in feedbin this is deleting the entries). Should be able to just iterate through the ID list and POST to the delete endpoint. I started running into rate limiting errors as I was testing this. # turns a string into a regex, but appears to do much more. Looks like it's a shorthand for creating lambda. https://clojure.org/guides/weird_characters macroexpansion is an interesting command to help with debugging. With the rate limit errors gone, I can finally get this working for good. I tried passing in the article IDs as a comma-separated list as a query string and it didn't work. I need to send this data in as a JSON blob. 166ea49439ed690ff08c8fd987530b170b9bb80e Got the delete call working. You can pass a hash directly to clj-http and it'll convert it into JSON. Nice. 63ac8bf1d4fd969326fffa9ad7b50ad1f0a4b56d

Great! We have the script working. Now, let's deploy it.

Clojure Deployment Using AWS Serverless

I have a friend who is constantly talking about how awesome serverless is (i.e. AWS Lambda). I also remember hearing that you can setup cron-like jobs in AWS that hit a lambda. Let's see if that's the case and if we can get this script working on lambda.

Some things we'll need to figure out:

How/where do I specify that an endpoint should be hit every X hours? How do I specify where the entrypoint is for the lambda function? How do we specify environment variables?

Notes

I jumped into AWS lambda dashboard and created a function named "Mark-Feedbin-Entries-As-Read" with Java 11. It looks like the crazy AWS permission structure is generated for me. I added the com.amazonaws/aws-lambda-java-core package and it looks like I need to run gen-class to expose my handler. What is gen-class? It generates a .class file when compiling, which I vaguely remember is a file which is bundled into the .jar executable. Looks like aot compilation needs to be enabled as well. Still need to understand what aot is. I ran lein uberjar and specified feedbin.core::handler as my handler. Created a test event with "testing" as the input. Used the -standalone jar version that was generated. Looks like environment variables can be setup directly in the Lambda GUI. "Cron jobs" are setup via CloudWatch events. What is CloudWatch? It's AWS's monitoring stack. Strange that this is the recommended way to setup cron jobs. I would have thought there was a dedicated service for recurring job schedules. "Serverless" (looks like a CDK-like YML configuration syntax for AWS serverless) makes it look easy to deploy a lambda which executes on a schedule, but doesn't indicate how it's actually managed in AWS in the blog post. Aside: It's interesting the more you dig into AWS, the more it feels like a programming language. Each of the services is a library and the interface to configure them in yaml. It looks like "Amazon EventBridge" is the new "CloudWatch Events". Looks like we can setup a rule which triggers a lambda function at a particular rate. Neat, you can setup a rule directly with the AWS Lambda GUI. Use a EventBridge trigger with rate(1 day) to trigger the function every day. Really easy! I checked on it the next day and it's failing. How can we inspect the request? It's probably failing due to the input data being some sort of JSON object vs a simple string that I tested with. Here's what I found: you can inspect the logs, use CloudTrail to view an event, enable X-Ray tracing, and send failed events to a dead letter queue. I enabled all of this stuff: my end goal to inspect the event JSON passed the lambda to determine how to fix it. Ah! After a bit more digging, if you find the event in CloudTrail there's a "View event" button that will give you the JSON output. I can then copy the JSON into the test event in the configuration for the lambda and run it there to get helpful debugging information. Feels a bit primitive, but it works. I wonder how you would run the function and locally and write integration tests using example AWS JSON? Looks like the function signature for my handler is incorrect. When handling events, the handler accepts two arguments [Object com.amazonaws.services.lambda.runtime.Context]. This fixed the issue! 8520e8a319bd5d41a67a01f9517ce4cf559ab381

Resources:

https://bernhardwenzel.com/articles/using-clojure-with-aws-lambda/ https://aws.amazon.com/blogs/compute/clojure/ https://thenewstack.io/move-your-cron-jobs-to-serverless-in-3-steps/ https://serverless.com/blog/cron-jobs-on-aws/ https://docs.aws.amazon.com/lambda/latest/dg/with-scheduledevents-example-use-app-spec.html https://lumigo.io/blog/eventbridge-vs-cloudwatch-events-kinesis-and-sns/ https://docs.aws.amazon.com/eventbridge/latest/userguide/run-lambda-schedule.html https://d0nkrs.com/post/building-aws-lambda-functions-with-clojure https://github.com/aws/aws-cdk https://github.com/jebberjeb/lambda-sample Open Questions

Here's a list of questions that I wasn't able to answer during my learning process:

How can you parallelize operations in Clojure? How easy is deployment? How does interop with Java work? Is there a rails-like web stack? Is there a style guide?

Continue Reading

Reclaiming Your Mind: Creating an Information Diet

There's been a lot of areas of my life that I've been 'auditing' and attempting to tweak the habits that have intentionally or accidentally fallen into place. One of these is my information diet: how I find, consume, and process information.I've been tracking my time spent on reading/time on the internet and I'm not liking the trend. I've felt more addicted to information this year and I want to eliminate that feeling. Revamping my information intake is one way I'm going to do that. It's worth thinking about why it's worth spending time consuming information, how I consume information, and how I want to change my information consumption.

Categories Stories. I've been almost exclusively consuming non-fiction for the last decade and rarely read any non-fiction. At the suggestion of my ever-wise wife and the promptings of a great podcast on story I've reprioritized non-fiction as something worth spending time on. Great stories can change our perspective on our life and increase our creative thinking.Curiosity & Exploration. Investing in discovering new and interesting ideas has always paid off for me. For me, this generally looks like browsing community sites like hacker news, reading a random newsletter, of following interesting people on Twitter. Learning about random, interesting topics has always been really enjoyable for me—it sparks creativity (and joy) and is useful later Work. Learning specific to a work-related problem. Entertainment & Social. Twitter, Facebook, news, etc. When you look back at your time spent here you always feel like it was a waste. I've been convinced that keeping up with news is largely a waste of time (you'll hear anything worth knowing about through friends), and time spend communicating with friends over social is better spent with friends in person. This doesn't mean that there isn't a place for this category, but for me it means I need to bias towards eliminating any time spent on this category. Infrequent Personal-ish Updates. There's a group of organizations or people I follow that I want to keep tabs on, but don't send emails often. A friend running a non-profit, bands announcing a new album, etc. Deals/Promotions. Transaction/Service Emails. Mediums Podcasts.BooksBlogs.Community News. Hacker News, Lobsters, Reddit, Product Hunt.News Sites. Google News, Bloomberg, TechCrunch, etc. Social. Twitter, FaceBook.Movies. NetFlix, Amazon Prime, YouTube.Email.Personal communication. Texts, voicemails, etc.

Thoughts on Consumption.

Continually improve the system. Set aside time every month to quickly audit what I'm consuming and what tools I'm using. Make consumption a choice rather than a reaction. Right now, I randomly visit Hacker News or see an article come through my email. Instead I want to centralize information in one category into a single place that I can go. Optimize for pull vs push consumption. A great example here is email newsletters. They are push, not pull, and are often messy to read and pile up in my inbox. I want to separate "conversations with people" over "updates from companies/interesting news".Categorizing information is critical. Email newsletters can't be categorized easily. I want to put feeds into separate buckets that I can prioritize and triage separately. I should use RSS again. Way back when I read everything via NetNewsWire. Email newsletters took over seemingly overnight and I forgot that RSS existed. Most sites I care about still support RSS (even if it's not advertised explicitly).Use a RSS Reader. Specifically, one supported by paid subscriptions. Free is great, but most free things (without a huge market) die or have negative externalities over time. I don't want to have to mess with this part of my toolkit much and deal with a killed product. Paid subscriptions mean it's a real business that will continue to improve over time. Limit consumption. I want to enforce a limit on the numbers of things I'm consuming. I wonder if there is a way to automatically reset the read count of various feeds so it doesn't look like there are too many articles to read when I use a reader.Prefer books over articles. For most business/technology problems, blogs and Q&A sites are the main source of data, but work aside, books are generally higher-quality information compared to blogs. The time it took someone to create the content is a good indicator of the quality. Books > Blogs > Twitter. (this gets a bit tricky with low-cost kindle books: skip these). Optimize for highest impact & quality information at the beginning of the day. This means reading books and long-form articles at the beginning of the day while my mind is clear, instead of consuming blogs, tweets, texts, etc. Treat books like a blog archive. I really like this concept, can't remember where I first heard it. Reading books from cover to cover doesn't make a ton of sense, although it's definitely how I'm trained to read books. Skimming through a chapter (or skipping it entirely) if you find it boring or too verbose shouldn't feel 'wrong'. If the writer can't keep your attention, that's their fault. Additionally, books are generally longer than they need to be in order to hit page quotas.Don't switch contexts. If you are reading a book, don't stop and read a blog article. Cultivating sustained laser-focus attention on a single thing is critically important. I've found this to be more challenging as the years go by, and it's something I need to be even more intentional about.Focus on managing written internet media. I don't over-consume podcasts or books. I struggle most with interesting, distracting news sources like Hacker News or What I'm going to change Limit number of news feeds to 30. I suspect this number will change as I continue to slowly improve how I'm processing information, but this is a good start.Convert email newsletters to RSS. Most newsletters (like Ruby Weekly) have an RSS feed. For those that don't, FeedBin has a service to convert email newsletters into a feed, and I imagine there are standalone services that will do this for you automatically.Mass-unsubscribe from email newsletters. I've been using unroll.me for years (I don't love the privacy component, but it's a useful tool). It looks like their unsubscribe option will actually click through the unsubscribe links for me. I should go through my daily Unroll.me summary and remove newsletters I'm not interested in, and convert the others into a feed.Setup two aliases email+updates@gmail.com and email+promotions@gmail.com. Forward all updates to FeedBin and auto-archive. Auto-archive & tag all promotions.Subscribe to weekly summaries on community news site. Mass unfollow everyone on Twitter, and limit the people I follow to 50.Update my website blocking strategy, including blocking of all news & social sites. More on this in a separate post.Stop using Apple Podcasts. I find it hard to keep things organized and Apple seems to randomly reverse the listing of certain podcasts. I should trim which Podcasts I subscribe to and find another Podcast application. Categories: engineering, techReview all gmail filtersReview and trim all YouTube subscriptions. Review all Twitter app connectionsReview any compromised passwords via 1Password

After a bunch of investigation, I settled on using FeedBin.

https://reederapp.com/mac/#faq doesn't look like it is updated oftenhttps://github.com/mausba/rssheap went open source and hasn't been touched in over a yearhttps://github.com/getstream/winds podcast and RSS reader, open-source, commercially supported and recently updated.https://www.inoreader.com. Standalone paid product, has an API, doesn't look too complex. 64 feeds for free. Free and paid tiersFeedly.com is the most popular, but looks to be overdone. http://newsblur.com. Standalone paid product. Not updated frequently. Doesn't look like a great design. Free and paid tiers. I found this reader most commonly referenced by HN and Lobsters.https://readkitapp.com ties into various services to create a great reading experience. https://www.goldenhillsoftware.com/unread/ another macos reader.https://yoleoreader.com web-based reader with a low-cost paid subscription. https://feedbin.com well-designed feed reader. Supports podcasts and receiving email newsletters via a special email address. Also has a Twitter reader as well. Bootstrapped business. Also open source, very cool. https://github.com/feedbin/feedbinhttps://github.com/ViennaRSS/vienna-rss Pete Cooper is involved in this one. Open source. Looks like a zombie product.https://www.nooshub.com new reader from HN with some fancy "AI" grouping.https://ranchero.com/netnewswire/https://apps.apple.com/app/leaf/id576338668 Leaf. Looks dead. Hasn't been updated in two years.

Other interesting finds:

https://superfeedr.com RSS feed APIhttps://throttlehq.comhttps://news.ycombinator.com/item?id=20167143 and https://news.ycombinator.com/item?id=19909102

Continue Reading

2019 Goal Retrospective

I've been doing retrospective's on my yearly goals for a couple years now. Although it's a little late, I wouldn't want to break the habit (plus, I'm trying to open source my thinking).

Let's go!

What Worked Creating a distinction between habits and goals. I have a separate "habit document" where I document habits that are important to me. Setting a goal to kickstart a habit. Habit-goals shouldn't be all, or even most, of your goals for the year but having one or two habit-goals can be really effective at changing behavior. It was useful to commit to an action (like hiring a personal trainer) to force building momentum for a specific habit. If you've set a goal for the last couple years and haven't been able to make it happen, consider doing something drastic. How can you up the ante and put something on the line associated with the goal? Maybe it's hiring a coach, tying money to it, making a commitment that you can't back out of without causing issues for someone else, etc. Figuring out how to raise the stakes has been hugely helpful. Including a just-for-fun goal: vacation, hobbies, etc that you'll be really motivated to accomplish. This has helped me be excited about the year and maintain motivation for the important but not exciting goals. Setting aside project time as a married couple. It was fun to work on our goals together, and we got some important and run things done during this time. Looking forward to more of this. Joint goals or projects with my wife was really fun and motivating. For instance, we built a garden together this year. Zero-targets. Setting a non-action goal was a great way to break some behaviors I wanted to change. What Didn't Goals that weren't exciting or specific enough fell to wayside. We didn't do the quarterly review at all. This is the second year that this wasn't an effective practice. In the season of life that we are in (little kids), we just don't have the time to really set aside the time to do a proper quarterly review. We need to rethink this. This may be obvious, but having a kid is a goal in and of itself. We knew we were going to be growing our family, but I didn't account for this in my list of goals. Make sure to a in that year and you need to plan for that. We didn't create "project time" that often individually or as a couple. I wish we blocked off time for projects 2-3x more than we did. What Needs to Change? Remove the quarterly review. We haven't stuck to it for the last two years and with two young kids carving out that amount of time just isn't practical. Next iteration on this is adding reminders to our monthly review to ask a couple of the questions that we wanted to incorporate into the monthly review. More project time. This is super fun if you set goals at a couple and helps create focus around making progress on goals that are slipping.

Here are some other reflections I had about the year:

Many of the exciting life changes have come and gone (moving, buying a house, etc) and we are in a season where family (kids) take up the majority of our time. This means that most of our goals are less exciting, and that's ok. We have to remember that raising amazing kids and being present to them is our top priority. What that requires shifts and changes throughout the year. Some things in our life which need to change are hard to tie to a specific and measurable goal. Mostly because we don't know exactly what needs to change. With two young kids "improving our family balance" is a thing we need to improve, but what that exactly means isn't clear. What we decided to do was pick a specific thing that represented the best forcing function we could think of for improving on the vauge state that we are marching towards, and then adjust the specifics of that goal as we move through the year. Most of your goals shouldn't be actions that you naturally motivated to take. I tend towards this mode and need to think hard about what goals work against things I don't

Continue Reading

Life Categories for Your 2020 Goals

Each year my wife and I go through a review process where we set goals and habit targets. We've been doing it for five years and it's amazing to see the progress we've both made. It's also been powerful to set joint goals that we can work on together.

I've found it helpful to think over the "categories" of your life. A couple of years ago I wrote out my main life categories and it's time to update that list:

Spiritual Marriage Kids Health Intellectual Work Adventure, beauty, and fun. Intentionally pursuing outdoor adventure and just-for-fun activities with friends is a new thing for me. In the past the first thing to go with this sort of self-care, but I've found this to be more and more critical to achieving the life I want to have over the long-term. Financial Relationships

This list is stack ranked against what my long-term priorities are. For a season, one category will be more important than other aspects of my life but over the long term, I want to ensure I prioritize my life against this stack-ranked list.

It has served as a good gut check for me at the end of each year: is my time aligned against how I want my life to look?

 

Continue Reading

Archiving a QuickBooks Online Account to QuickBooks Desktop

If you run a small business, you probably use QuickBooks. I've been impressed with the product: the rate of improvement continues to stay constant over the last couple of years (one of the most important criteria in picking a software platform for your business!) and it's surprisingly pleasant to use.

If you close a company, you'll want to archive all of your QuickBooks data for at least a couple of years in case you get audited. However, QuickBooks Online does not have a low-cost "audit backup" option to access a read-only version of your data. If you cancel your subscription, you only have 90 days to reactivate your subscription and restore your data. There are some QuickBooks Online apps that claim to backup your data, but there are significant caveats with most of these cloud apps.

The best (and cheapest) option is to download a QuickBooks Desktop version of your data which can then be later used to create a new QuickBooks Online account if you ever need to. However, this is more complicated than it should be (most likely, by design).

Hopefully, this guide makes it a bit easier!

1. Get Access to Windows 7 with Internet Explorer 11

In order to actually export the QuickBooks Desktop file from QuickBooks Online, you need Windows + IE. User-agent spoofing won't work, there's some wacky ActiveX plugin you need to install in order to complete the export process.

Other versions of Windows and IE may work, but this is the 'official' version stated to work when you login to QuickBooks Online > Exports > "Moving to QuickBooks Desktop?" > "Download company data".

"How can I possibly get those exact versions, especially when I don't have a Microsoft computer anywhere in sight?!" you may ask. Great question.

Luckily, Microsoft has virtual machines with a bunch of different Microsoft and IE versions (designed to be used for website testing) you can download and use for 90 days for free. Download the virtual machine here.

2. Download VirtualBox

You'll need VirtualBox to run the virtual machine you downloaded from Microsoft. Download it here. You'll also want to set up a couple of configuration options by navigating to Machine > Settings once your virtual machine is running:

General > Advanced > Shared Clipboard > Bidirectional. Helpful for sharing passwords for QB. Shared Folder > Add New. Set up a folder and make sure to auto-mount it. General > Displays. Make sure video memory is at least 128mb. For some reason the default was 4mb. 3. Download QuickBooks Desktop Trial Version

In order to download the QuickBooks Desktop file, you'll need to have QuickBooks Desktop installed on your virtual machine. You can download a trial here.

4. Generate QuickBooks Desktop Download File

Follow these instructions to download your QuickBooks Online as a QuickBooks Desktop file. Here's another guide that's more simple (but won't be kept up to date).

5. Verify & Backup

After you generate the QuickBooks Download file you'll get a strange email with the subject "QuickBooks Online Simple Start: Company Data Ready for Download" asking you to "2. Click the task or to do item called 'Download the company file created on xx/yy/zzz'". This must be old email copy, because there is no such thing as a "task or to do item" in QuickBooks.

Here's what you need to do:

Navigate to QuickBooks Online > Exports > "Moving to QuickBooks Desktop?" > "Download company data". You'll be walked through a process to download the file and import it into QuickBooks Desktop. If things don't work, restart your computer and open up QuickBooks Desktop before opening up IE. After you've opened the file in QuickBooks desktop, run the P&L and Balance Sheet reports to ensure the numbers match up with QuickBooks Online. Create a backup from QuickBooks Desktop and store it in your shared folder Create a copy of the company for QuickBooks online. File > Utilities. Copy the backup to DropBox/Google Drive/whatever Recreate a new company in QuickBooks Desktop using your backup to ensure you can recreate it if you need it.

Continue Reading

Why You Should Open Source Your Thinking

Open source software (OSS) has transformed the technology landscape. I can't imagine any software company build without OSS at the core.

What makes OSS magical is the serendipity of how it's created. Someone throws an initial idea on the internet, and if others have the same problem, they join in and organically refine and improve the original idea. Others silently lurk into the project, start using it, and run into some bugs or edge cases which they report (and sometimes post a fix for). Before you know it, there's a robust piece of software that has been tested under a variety of circumstances by experts around the world.

Amazing.

Blogging has similar properties. Someone can post an idea, which is then improved upon or augmented by the community. Unlike software, the mechanics (i.e. GitHub) don't easily exist to collaboratively discuss a particular part of the idea or concept that is being written (what a cool product that would be! Holloway is doing something similar).

I think posts written as a breakdown of someone's thinking on a particular topic, without any hidden agenda, have the best chance of creating the OSS dynamic. For instance, by reading Stephen Wolfram's explanation of his productivity system, you'll probably end up tweaking your own working style or adopting some of his tricks. Reading how someone else learned a programming language may change how you approach learning. A packing list for a family with four kids may help augment your own travel strategy and inspire you to travel the world with your kids. Reading how someone manages their finances, consumes information, purchases insurance, will help you revise and improve your own processes.

I think of these posts as "open sourcing your thinking". Documenting how you approach a specific topic with enough detail and vulnerability helps you clarify your own ideas but more importantly allows your ideas to be critiqued and improved by the larger internet community (just like OSS).

I'm going to be doing more of this. And, selfishly, I hope you do the same so I can learn from you!

Continue Reading

Optimize Your Charitable Giving Using a Donor Advised Fund (DAF)

I've always been fascinated with the idea of recurring revenue. Building a business or a portfolio of investments which passively create recurring income has been interesting to me since I got my first paycheck.

Over the last year I've been thinking: why can't I (slowly) create a charitable asset that kicks off income each year which can go tax-free to charities? This way, instead of giving to an organization once, you can build a mix of assets that generate enough income to perpetually give to the organizations you carry about?

This idea, combined with the recent tax law changes that made it more challenging to get a deduction from charitable donations (10k SALT limitation makes it harder to itemize), got me researching. I ended up finding an interesting vechicle which I hadn't heard of before: the Donor Advised Fund (DAF).

Obviously, I'm not a financial advisor, lawyer, CPA, etc. Don't trust anything you read here, and always consult your own advisors. 

How a Donor Advised Fund Works

Here's the basics of how a DAF works:

You 'join' a DAF run by an independent organization. There's a minimum (~$5k) to opening up an account with DAFs (Fidelity, Vanguard, etc). These organizations charge a management fee (~0.5% of assets). You donate to the tax-deductible DAF. When you donate to the DAF, you are giving away any legal control over that money. The DAF can technically do whatever they'd like with it. However, you can 'advise' the fund where you'd like them to donate. Essentially, this means you control exactly where the money in the fund flows. You don't have to donate everything that you put into the fund within the same calendar year

Here's why it's powerful:

You only have one tax slip at the end of the year from the DAF. No more chasing down charities to properly document your charitable giving! You can 'batch' donations in a single year to the DAF get above the standard dedution, but distribute money to charities across a number of years. While the money is in the DAF and not distributed to a charity you can invest the cash in low-cost index funds. You could structure the DAF so you only distribute earnings from your invested cash. If you have a cash windfall, you can make a large donation in the same tax year to the DAF to get the deduction, but decide later exactly what charity you'd like to distribute the funds. It's easier to control the organizations you donate to: instead of organizations charging your card every month, you can setup monthly/quarterly/yearly donations which are sent to various organizations. You don't have to worry about organizations not canceling your recurring donation or contacting them to change your donation. You can manage all your donations from a central dashboard.

I've been using the Fidelity Charitable DAF for the last year and it's been awesome. The management fees and minimums made the most sense for my situation, plus it seemed like they had the best website. The Vanguard and Schwab options seemed about the same.

Some interesting threads/links I found along the way:

Reddit Analysis of DAFs Boglehead Thread Alliance for Good What's the Catch?

From what I can tell, there isn't any.

For some reason, the DAF hasn't been advertised heavily. Probably because the number of folks willing to donate about the minimums (~5k for the initial setup) isn't huge, and non-profits have an incentive to maintain a direct relationship with the donor and ping their card every month (with a DAF you control the fund outflow).

However, there are some limitations/downsides to be aware of:

You are legally removing control over the money. Theoritically, the organization managing the DAF could do whatever they'd like with it. There are some limitations to organizations beyond 501(c)(3) you can donate to. A ~0.5% management fee is charged on a yearly basis. What About Foundations? Or a 501(c)(3)?

I've heard differing opinions on if it makes sense to open up your own foundation.

Some folks have said that the legal and compliance overhead with foundations are not worth it unless you have 100s of thousands to give away. 5-10 This seems to align with what I've seen (through my wife who worked in non-profit development)—only very large donors seem to maintain a foundation in their name, and foundations seem to have a bunch more rules to follow and compliance to worry about.

I've also heard about some folks who open their own 501(c)(3) and park their charitable donations there. From my cursory research, non-profit organizations have the same or more overhead compared to a foundation.

In my analysis, the simplicity and relatively low management fees of the DAF make it the best choice for most folks.

A foundation or 501(c)(3) would make sense for very high net-worth individuals, or the unique person who has the time/savvy/interest to read through & file the paperwork and ensure there aren't any compliance issues. I'm more keen to keep things simple and eliminate overhead, even if it means reduced control or slightly higher costs. KISS, baby.

Why Everyone Should Give

You might ask why this matters, or why you should give at all. Here's my perspective.

I believe strongly that everyone, regardless of their income level, should give something to the community they are a part of. This doesn't always mean money, but it does mean something valuable (time, things, ideas, etc) that helps others around you.

It's easy to become very self-centered and giving counteracts the natural force that makes life all about us. For most of us, many other people have been given a set of circumstances that make life much harder than our own. Giving (especially when it's significant enough to 'hurt') makes us aware of those around us less fortunate and ensures we live a life for others, and not ourselves.

Continue Reading

Habits, Systems, and Scripts

I've been 'auditing' various areas of my life.

After being obsessively focused on work for a long time, it's been helpful to think deeply about the habits and pre-written scripts that I've developed across a bunch of areas of life. In most cases, the habits I've adopted over the years are a function of taking the path of least resistance than an intentional choice.

Here are some things I'm looking at:

Information Consumption (news, email, podcasts, reading, etc) Exercise Eating Prayer Marriage Friendship

Thinking through what I want from these categories, where I'm not satisfied, and asking 'why' multiple times until I get the root cause of the delta has been insightful. It's allowed me to rewrite the default scripts I operate out of and make meaningful change very quickly.

It takes intentional effort & dedicated time to create clarity in your thinking to focus in on what needs to change and to generate the excitement to do it.

Take some time and audit areas of your life that you've ignored because of laziness or busyness. It's worth it.

Continue Reading