Scala, Java, Unix, MacOS tutorials (page 1)

“I wish it need not have happened in my time,” said Frodo.

“So do I,” said Gandalf, “and so do all who live to see such times. But that is not for them to decide. All we have to decide is what to do with the time that is given us.”

“To be a programmer is to develop a carefully managed relationship with error. There’s no getting around it. You either make your accommodations with failure, or the work will become intolerable.”

~ Ellen Ullman (via this tweet)

This quote makes me think of all those years of exception-handling with Java. I never knew there was a better way to handle errors, so I developed a strategy of letting my exceptions bubble up to the controller level (as in model/view/controller), where I would deal with them. These days I know I can use Option/Some/None in Scala, as well as Try/Success/Failure.

I was writing some Scala code like this today:

val sb = new StringBuilder
for (b: Byte <- mdOut.digest) {
    val hexString: String = String.format("%02x", b)
    sb.append(hexString)
}
sb.toString

and encountered this error message:

Under Your Scars by Godsmack is today’s song of the day:

And everything feels broken
When you’re not next to me
Would you still be you
If we weren’t we

Remember all those people having a good time on the beach in Ft. Lauderdale a few weeks ago? According to their cellphones, this is where they went when they left the beach.

~ image comes from this video

Where the spring breakers went after Ft. Lauderdale (Coronavirus 2020)

I can’t find the original source of this image and product, but I have always liked the “Live Brave” saying, which I first heard on the excellent Eli Stone tv series (which stars Johnny Lee Miller, who may be more well known for the movie Hackers and of course, Elementary).

Live Brave bracelet

While this photo looks like a sunset, it was actually a sunrise. I took it in Virginia Beach on April 17, 2017.

Dark sunrise, Virginia Beach

Last week I finished writing some Scala code to convert this website from using Drupal 8 to using static web pages. Technically what happens is that I use Drupal at a different location, and then my Scala code reads the Drupal database and uses to the Twirl template system — that comes with the Play Framework — to convert that data into the static HTML pages you see here.

Along the way I learned a lot about the 2020 version of Twirl templates, so I thought I’d share some tips and examples about how to do things with Twirl. If you ever want to use Twirl in standalone mode like I did, or inside the Play Framework, I hope this is helpful.

If karma is defined as “cause and effect,” here’s a little karma of the last 4-5 months:

  • In early November, 2019, I suddenly started having severe chest pain.
  • I happened to be standing next to my computer, so I quickly disabled comments on alvinalexander.com. In case this was something I couldn’t come back from, I didn’t want other people to have to worry about dealing with those.
  • (At the hospital I would find out this was pericarditis, i.e., inflammation around the heart.)
  • Over time I realized that “no comments” meant less stress and less work, so I kept them turned off.
  • One day I realized that if I was going to keep comments turned off, there was no reason to serve pages dynamically with Drupal 8 any more.
  • I took a week to write some Scala scripts to convert Drupal 8 blog content to static web pages.
  • My server CPU use has dropped significantly, so I can reduce my server costs by about $400/year.

Dr. Foreman: The kid was just taking his calculus exam when all of a sudden he got nauseous and disoriented.

Dr. House: That’s the way calculus presents.

Our sunset on the evening of Thursday, March 26, 2020, had a pastel feel.

Pastel sunset

I think a lot of people in the United States will remember the New York Times front page for March 27, 2020, for a long time.

The New York Times front page, March 27, 2020

As a brief note, here’s a Scala function to get the Unix epoch time for X days ago:

/**
 * Returns a 10-digit Long (like 1585275929) representing the date/time.
 * Use it to get the time for 1 day ago, 2 days ago, etc. `0` will give
 * you the current time.
 */
def unixEpochTimeForNumberOfDaysAgo(numDaysAgo: Int): Long = {
    import java.time._
    val numDaysAgoDateTime: LocalDateTime = LocalDateTime.now().minusDays(numDaysAgo)
    val zdt: ZonedDateTime = numDaysAgoDateTime.atZone(ZoneId.of("America/Denver"))
    val numDaysAgoDateTimeInMillis = zdt.toInstant.toEpochMilli
    val unixEpochTime = numDaysAgoDateTimeInMillis / 1000L
    unixEpochTime
}

As shown in the comments, if you give it a 0 it will return the current epoch time.

Of course you can make the code shorter and better; I just wanted to show the steps in the approach using the Time classes in Java 8.

“As of last weekend, the nation had 17,000 confirmed cases, but the actual number was probably somewhere between 60,000 and 245,000. Numbers are now starting to rise exponentially: As of Wednesday morning, the official case count was 54,000, and the actual case count is unknown.”

I had a lot of chest pain last night, but if anything, these days that tends to keep me focused in the present moment, and make me grateful for each moment. And fortunately the universe has been giving us some amazing sunsets here lately in Colorado.

Another amazing Colorado sunset

In terms of being a nice person, Steve Jobs may have been the worst Buddhist in the history of the world, but he captures the Zen/Buddhist essence in this quote:

“Remembering that I’ll be dead soon is the most important tool I’ve ever encountered to help me make the big choices in life. Because almost everything — all external expectations, all pride, all fear of embarrassment or failure — these things just fall away in the face of death, leaving only what is truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are already naked. There is no reason not to follow your heart.”

Photo from forbes.com, words from Steve Jobs.

Steve Jobs - remembering that i will be dead soon

I’ll write more about this when I have some free time, but for the moment I’ll just say that if you ever need to emit raw HTML when using the Play Framework and Twirl template library, code like this will do the trick:

@play.twirl.api.HtmlFormat.raw(currentBookNode.bodyValue)

In this case the bodyValue field already contains HTML as a Scala String, and I don’t want Twirl to mess with that, so I use its HtmlFormat.raw method as shown.

As a brief “note to self,” this is the Bourne shell script I use to copy images from my Drupal 8 sites directory to the same directory on my new “Static Drupal” website:

tarFile=newImagesFromDrupalSitesDir.tar
drupalHtmlDir=/drupal8/html
staticHtmlDir=/staticDrupal/html

cd $drupalHtmlDir
rm $tarFile 2> /dev/null

# create a tar file containing all new images
find sites -type f \( -name "*.jpg" -o -name "*.jpeg"  -o -name "*.png" -o -name "*.gif"  \) -mtime -2 -print0 | xargs -0 tar rvf $tarFile

# TODO make sure the tar file exists
if [ -e $tarFile ]
then
    echo "tar file exists, moving it to $staticHtmlDir"
    mv $tarFile $staticHtmlDir
    cd $staticHtmlDir
    tar xvf $tarFile
    rm $tarFile
else
    echo "POSSIBLE ERROR: the tar file DOES NOT exist"
fi

I changed the three initial variable names, but the rest of the script shows one possible way to copy all of the images in the original sites directory into the new Static Drupal directory. If you wanted to see things such as how to use multiple filenames with the Linux find command, or how to use the find command to create a tar file, I hope this example is helpful.

All those places on Amazon Prime Video where there should be an image, but there isn’t, reminds me of WeakHashMap.

Amazon Prime Video reminds me of WeakHashMap

After switching from Drupal 8 to my Static Drupal app — which generates static HTML pages from a Drupal 8 database — the CPU use on this website has dropped from an average of 22% CPU use down to 9.2%. The max CPU use has also dropped from a whopping 59% down to 22.5%.

My Static Drupal app: CPU usage drops by more than 50%