Flutter Initial Installation Experience

Installing Flutter on MacOS and using IntelliJ

https://flutter.io/setup-macos/
From there, just iterate on brew doctor until it stops warning you about things not being installed.
In IntelliJ, I also got the following warning about the Dart SDK
Dart SDF not configured
Of course, when you click on the “Download Dart SDK” link, it points you to install Flutter, which I have done.
Recommendations for Dart Installation
After checking the flutter/bin directory, I confirmed that there was nothing that looked like "dart" in there.
After a bit of searing on “Dart SDK is not configured”, I found that Android Studio users were running into the same thing:
In "Dart SDK path" click in "..." and navigate to flutter bin directory. Under that directory you'll find "cache/dart-sdk". This is the dart sdk path you should use.

Sure enough, in ".../flutter/bin/cache/dart-sdk/bin" were all the dart* binaries and alias scripts.

After that (I was already set up in Xcode for iPhone development), it was trivial to build and deploy a basic test app to the iPhone X Simulator.

Flutter Demo Counter App
Flutter Demo Counter App in iPhone X Simulator

Making Your zsh Return You to a Non-Production Setting

I have my prompt in zsh setup to display what Kubernetes context I am pointing to, so that I will notice if I'm somehow pointed at production environments, but I'm still wary of being asked to check things in production and then forgetting to point back to a "safe" environment before doing something else.

So I set up a preexec and precmd hook to store state for the session that I'm in. In the preexec, I save off whatever command was run.

In the precmd, I check to see that command matches "switching over to production", mark the time, and clear the command out (otherwise, pressing <return> on the shell will keep the same command).

If I have marked the time I switched to production (PROD_TIME is not an empty string), then I check the current time and if it's past a threshold (15 seconds in the current case), then I run the command to switch back.

The last few lines clear the prexec and precmd function hooks and set them to the "safety" functions.

Tracking HipChat Activity with AppleScript

The Problem

Chat tools are great for being able to work remotely, at least until you get bombarded by one chat after another. I've often wondered if I could come up with a way to track who my chats are with and how much time was spent chatting with each person. My initial attempts involved trying to connect the HipChat API, but I would get rate-limited before I even got through the full set of contacts, much less the rooms themselves. And as far as I could tell, I had to cycle through all public and/or subscribed rooms and not just the rooms that I subscribed to.

(You might be familiar with RescueTime doing similar for webpages, but it doesn't appear to do that for HipChat or Microsoft Teams as far as I've been able to tell.)

A Simpler Algorithm

What if I could just log periodically when I'm chatting with a specific person or on a specific topic? I started playing with the Accessibility Inspector to try and figure out if I could get a specific path to the name display so that I could track who I was chatting with/what room I was in.

Name in HipChat
Name display in HipChat

I could an incredibly long tree down to the name display, so I went directly into Script Editor with some AppleScript to dump the UI elements of HipChat (commented out below), but found that the display was too generic... so I switched to grabbing the entire contents:

For HipChat, the above produces a long list of element hierarchies, but static text is mentioned in the hierarchy (I used somebody else's name because your own name appears in more windows in the view, but there may be multiple hierarchies that display the name you're looking for):

static text "Thomas Powell" of group 1 of group 13 of group 4 of UI element 1 of scroll area 1 of group 1 of group 1 of group 1 of group 1 of window "HipChat" of application process "HipChat" of application "System Events",

So I would remove the last bit of the hierarchies, and ask for the "name of" or "value of" the remainder of the hierarchy.

name of UI element of group 2 of group 1 of group 3 of UI element 1 of scroll area 1 of group 1 of group 1 of group 1 of group 1 of window "HipChat" of application process "HipChat" of application "System Events"

Ultimately, "name of" was the key to getting the display value I was looking for, but the chat rooms had a slightly different hierarchy, and both required trial and error to find the correct hierarchy. Ultimately, the value I was looking for was in a list within the "name of" the UI element at the bottom of the hierarchy, so I continued the inspection in Script Editor until I got to the correct value.

Solution:

(Disclaimer: I am barely able to write AppleScript that parses, much less AppleScript that looks good.)

I ended up creating an application the allows me to select a log file for output. Then I created a giant loop that checks if HipChat (or Microsoft Teams or RubyMine) or the front applications and then logs a usage with name or project in a log file + timestamp separated by a semicolon. (I used Ruby to generate the statistics based on this... sorry.)

I don't wait for any period if none of the applications I'm looking for are currently in front. If one of them is, I delay 15 seconds.

Observations:

HipChat had *by far* the hardest hierarchy to find the name / chat room info in. For RubyMine, the file path and file name are in the window title and the git project are in one of the static texts near the top level. Microsoft Teams was similarly friendly in that the title of the window reflected the context it was being used in.

Future plans:

Hammerspoon looks a little more promising for doing anything more complex and/or DRYing this up, but there's something to be said for being able to quickly hack your way to the data you want vs. actually having to plan things out.

Removing a Broken Headphone Plug from an iPhone

Broken Headphone Plug and iPhone. 😱

The headphone jack is a pretty key port for anyone not on an iPhone 7 or later, so a broken headphone plug shoved in the jack renders a phone pretty much useless. It's also too small a space for needle nose pliers.

So what do you do if something breaks off in it? Well, searching around on iFixit lead me to the existence of a headphone plug extraction tool (for $50!!!) Unfortunately, my daughter actually uses her phone for school, so the wait (plus $50) was unacceptable if we could find another solution.

Other solutions?

  • Crazy glue the broken headphones to its counterpart (and risk sealing it up for good?!)
  • Small drill bit.
  • Bamboo toothpick.
  • Soda straw cut to squeeze around the broken plug.

Ok, the soda straw sounded reasonable and, if nothing else, low risk. So I tried with some IKEA straws and got close to extracting a piece out, but no further. The problem was that there was too much in the plug. (The headphone plug is concentric cylinders that had been shoved all the way in.)

Solution!

So I kept reading... CUTICLE SCISSORS! My wife had a small pair that worked well to extract one of the pieces. Grab what you can with the scissors, push the straw around the remainder and tug to extract. The plug tip slid far enough out in this process to grab with my fingernails.

Below is the final carnage with extraction tools.

Cuticle scissors, straw, headphone plug pieces

Dyson DC 40 Shuts Down from Overheating

This is the second time in about a month that my Dyson DC 40 has shut down from overheating. The symptoms start with loss of suction from the head assembly (leaving dust bunny trails, etc.) while the hose end still had good suction.

I started out by disassembling the head unit and cleaning out the long dog hairs there, but there wasn't any change in the amount of suction when vacuuming carpet and dust bunnies were still being left behind.

I also made sure to empty the canister of all of the collected dog hair, but there was no change in suction. Finally, I decided to remove the cover on the HEPA filter to let it cool down.

HEPA filter cover

Once disconnected, I more clearly saw the hose connection that clogged the last time, and sure enough, a combo of dog hair and something perfectly sized to get wedged and stuck had completely blocked off the flow of air.

Dyson Hose connection that clogs

Unfortunately, now the vacuum cleaner has shut down until it resets and cools down. Maybe Dyson would like to study the special properties of our dog's hair?

Update: Leaving the cover open and the vacuum unplugged for about 30-45 minutes brought it back to life.

Update (February 25, 2018, one week after this post): The DC 40 stopped working. We checked all the clog points, cleared the filters, unplugged, let things cool down, and replugged... It never came back. We ended up buying the Shark Rotator NV650 at our local Walmart instead. The price was only $20 more than my refurbished DC 40 cost, and is much quieter and more portable.

rspec-rails tricks: Hacking Your Routes for a Spec

I don't know that this is so much a reminder of "What can be done with rspec-rails" as a note that, "If you do this will rspec-rails, you will also need to undo it."

Today's note: If you hack the application routes for a controller test, you have to reload routes.

The original problem

This all came down to a spec that was attempting to test a method in ApplicationController. In our Rails 3 setup (rspec-core and rspec-rails 3.7.0), the tests only needed a monkey patched ApplicationController to happen prior to the test:

before do
  class ApplicationController
    def dummy_action
      dummy_method_actually_under_test
    end
  end
end
 
it 'example do test' do
  get :dummy_action #etc...
  # validate dummy_method_actually_under_test did the thing
end

The fix

In Rails 4 with the same gem versions, we'd end up with the "No route matches..." which could be remedied by redefining the routes.

before do
  class ApplicationController
    def dummy_action
      dummy_method_actually_under_test
    end
  end
  Rails.application.routes.draw do
    get 'application/dummy_action/:id', to: 'application#dummy_action'
  end
end

Great! The test passes now! (Insert philosophical argument about whether the person writing the test should have tested a method in this way.)

Or not...

..until you run the rest of the suite, of course. Now *every* subsequent controller test has a "No route matches" issue. (Insert philosophical argument about whether you should be writing controller tests.)

This should serve as a periodic reminder to clean up after your tests, which in this case is:

after do
  Rails.application.reload_routes!
end

Apache Crashing with PHP 7 Enabled after High Sierra Upgrade

Upgrading (partially) for a System PHP 7

I finally got around to upgrading to High Sierra, which has PHP 7 as a system PHP instead of PHP 5.6. As part of that upgrade, my quick hacks of httpd-vhosts.conf for a couple of small projects had disappeared, since bringing up those virtual hosts would bring up the default site.

In the process of restoring these changes, I checked the main /private/etc/apache2/httpd.conf and noticed that
LoadModule php7_module libexec/apache2/libphp7.so
was commented out. So I uncommented it, much like I seem to recall doing for prior Apache setup.

Problems and Debugging

Strangely, after sudo /usr/sbin/apachectl restart, I was getting a connection refused. I checked for instances of httpd processes running:
ps aux | grep httpd
I found none.

Eventually, I figured out that I could do a -k option on apachectl:


sudo /usr/sbin/apachectl -k restart
httpd not running, trying to start
/usr/sbin/apachectl: line 92: 37326 Segmentation fault $HTTPD "$@"

Searching around on StackOverflow, I found that conflicting PHP versions were potentially the problem. So I commented out the php7 module again, restarted, and loaded a page with phpinfo(); on it. Sure enough, PHP 5.6 was running.

Resolution

Searching in /private/etc/apache2 for other php module mentions, I found /private/etc/apache2/other/+php-osx.conf and commented out the following line:


LoadModule php5_module /usr/local/php5/libphp5.so

Restoring the php7_module in httpd.conf, I restarted Apache, and magically phpinfo(); displayed the 7.1.7 PHP version.

2017 Year in Review

January

  • Pigeon Forge field trip as chaperone
  • Pinewood Derby

February

  • Double Bridge Run
  • Manatees
  • Mardi Gras Parade in Pensacola

March

  • New Pergola
  • New Patio
  • New Piano
  • Trip to Louisville to meet Poland team
  • New beds

April

  • Mad Violin
  • Blueberry Festival

May

  • Wife quit job
  • Savannah to OBX

June

  • Lighthouses
  • Sea Catchers
  • Dan TDM in Jacksonville

July

  • Palafox Application
  • Etsy shop
  • Wife got a new job

August

  • 41
  • Traveled to Clayton, GA to see total eclipse
  • Sang with bishop installation choir

September

  • Palafox Market
  • Solar install
  • Hurricane Irma panic
  • Baby Musical accompaniment

October

  • Solar up and running
  • Hurricane prep and Tropical Storm hit

November

  • Webelos weekend
  • Pow-Wow for Thanksgiving
  • RubyConf NOLA
  • Blue Angels Homecoming

December

  • New treadmill
  • Trip back to Louisville

IntelliJ Spring MVC @RequestMapping Not Registering

I've been trying to reintroduce myself to Spring MVC @RequestMapping and working with Java in IntelliJ after 5 years away from Java and having primarily used Netbeans for any development. My last experience with Java was with Netbeans helping manage a Maven build.

I had my @RequestMapping annotations set up, and IntelliJ is launching Tomcat directly (vs. deploying to an already running instance). I created my *-servlet.xml configurations, and had my .jsp files placed properly. Everything seemed to be in good shape and compiling fine, but the routes I specified we not showing up with the project was run.

Eventually, I went to Build -> Build Artifacts -> ...:war:exploded -> Edit... and went the Project Settings -> Artifacts tab and noticed "Library 'org.springframework:spring-web:4.3.13-RELEASE' required for module '...' is missing from the artifact". Upon clicking "Fix" and adding the dependency. Some combination of that dependency and 'org.springframework:spring-webmvc:4.3.13-RELEASE' missing prevented the org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping.registerHandler from processing my @RequestMapping annotations.

Multiple Postgres Schemas and Rails db:test:prepare

In our Rails databases, we use multiple Postgres schemas. This is partly for partitioning archive data from fresh data. On a new Rails 5 project, I started having tests fail once the models had the "archivable" concern added, which depended on an archive schema existing.

Ultimately, the problem is that the archive schema wasn't being created in the test database, because rake db:test:prepare performs a db:test:load which was loading the db/schema.rb, which is completely ignorant of the Postgres-specific schema concept.

In order to fix this without attempting ugly hacks, the simplest solution was just to switch to using structure.sql for the Rails schema dump.

In config/application.rb, insert the following in your Application class definition:


config.active_record.schema_format = :sql

If you haven't already added the additional schema(s) to your schema_search_path in your config/database.yml.


database: whatever_db
schema_search_path: 'main,main_archive,public'

You'll need to run rake db:migrate to force structure.sql generation before running tests again. Also, be sure to switch from schema.rb to structure.sql if you're committing this file.