Tuesday, May 26, 2020

Switching Java Versions

Believe it or not, I was unfamiliar with this way of switching Java versions:

$ export JAVA_HOME="$(/usr/libexec/java_home --version 1.8.0_251)"

Hope this helps somebody!

(because I know that someday that somebody will be me!!)

Sunday, May 17, 2020

30-Day Song Challenge

I keep seeing the "30-Day Song Challenge" on Instagram Stories. I'm terrible at Instagram, so I probably won't be posting my own selections. But when I googled what all the 30 days were, I kept seeing post after post on these nothing-but-ads sites. Well here they are, and I'll upload the graphic, too - tap it to get it full sized.

1. A song you like with a color in the title
2. A song you like with a number in the title
3. A song that reminds you of summertime
4. A song that reminds you of someone you'd rather forget
5. A song that needs to be played loud
6. A song that makes you want to dance
7. A song to drive to
8. A song about drugs or alcohol
9. A song that makes you happy
10. A song that makes you sad
11. A song you never get tired of
12. A song from your preteen years
13. A song you like from the 70s
14. A song you'd love to be played at your wedding
15. A song you like that's a cover by another artist
16. A song that's a classic favorite
17. A song you'd sing a duet with on karaoke
18. A song from the year you were born
19. A song that makes you think about life
20. A song that has many meanings to you
21. A song you like with a person's name in the title
22. A song that moves you forward
23. A song you think everybody should listen to
24. A song by a band you wish were still together
25. A song you like by an artist no longer living
26. A song that makes you want to fall in love
27. A song that breaks your heart
28. A song from an artist whose voice to love
29. A song you remember from your childhood
30. A song that reminds you of yourself

Saturday, May 16, 2020

iOS Edit Menu

I use the three finger double tap accessibility gesture to put my iPhone in zoom mode, handy for reading fine print and drawing tiny pictures. You then use three fingers to pan the zoomed view around the screen.

But recently I discovered that if you're not zoomed in, there are three finger gestures that do other things.

  • swipe left: undo
  • swipe right: redo
  • tap shows an Edit menu of undo/redo, cut/copy/paste

The best thing about this is that note I can turn off Shake to Undo, which I'm constantly having to cancel while grocery shopping. Problem solved!

Plus, iOS text editing isn't great about offering the Paste function when you drag the cursor to a new location. When that happens, just three-finger-tap and then choose Paste from the menu. Another problem solved!

Tuesday, April 21, 2020

Stacked Enchiladas

   Ingredients:
     * 1 package, corn or flour tortillas
     * 1 pint, sour cream
     * 2 cups, chopped turkey or chicken, cooked
     * 1 or 2 cans, enchilada sauce
     * 1/2 cup, chopped green onions
     * one or two little cans, chopped green chiles
     * 1/2 to 2/3 pounds, shredded cheddar or Monterey Jack cheese

   mix sour cream, green onions, chiles, meat and 3 teaspoons of enchilada
   sauce. in a round casserole dish, spread enchilada sauce to cover the
   bottom. place a tortilla that has been dipped in enchilada sauce in the
   bottom of the casserole dish then layer with approximately 1/4 cup of
   meat mixture and 1/4 cup of shredded cheese. repeat layers ending with
   tortilla and cheese. bake covered in 350 degree oven for 45 minutes.
   remove the cover for the last 15 minutes of baking.

   Muy delicioso!!

   (Makes 8 servings.  Calories per serving: about 550, 300 from fat)

     Copyright 1999, Dave Diamond. Last  updated on February 26, 2000.

Another recipe rescued from an old hard drive. Enjoy!

Thursday, March 26, 2020

Apple Watch Workout Sync

I have an Apple Watch problem. I'm obsessed. I can't not close my rings. Every challenge, accepted.

So the March Challenge is 31 workouts - no problem. I double up a couple days just to be sure.

Then it's the 26th and I look at my progress - wait, 13? It's not counting all my workouts!!

But when I look at the Workouts tab on the iPhone Activity app, sure enough, they're all there.

Googled around, nothing jumped out at me, so I started a chat with Apple.

To make a long story short, they had me unpair and re-pair my watch and my phone, which was kind of time consuming but not a big deal.

And the problem was fixed! March Challenge completed!!

Now if this happens to you - even if you just have to unpair/re-pair your watch and phone for any reason - here are some things to keep in mind:

1. by the end of the day, my watch battery was super low. if you're going to unpair/re-pair, you might want to put it on the charger while you do so.

2. I got to the grocery store to discover that my credit cards weren't there anymore. you have to go into the Watch app on iPhone and re-add your cards, which is just a couple of clicks, BUT you do have to know your cards' PIN codes.

Wednesday, August 28, 2019

Homemade Taco Seasoning

I haven't made this yet, but I don't want to lose it

https://gimmedelicious.com/2018/03/16/the-best-homemade-taco-seasoning/


Wednesday, July 31, 2019

EXIF metadata with a Promise

I had occasion to use exiftool recently, but instead of a callback, I'd rather use promises.

This is what I came up with:

const exif = require('exiftool');
const util = require('util');

const exif_metadata = function (data) {
    return new Promise((resolve, reject) => {
        exif.metadata(data, (err, metadata) => {
            if (err) {
                reject(new Error(err));
            } else {
                resolve(metadata);
            }
        });
    });
};


Worked great!

const fs_readFile = util.promisify(fs.readFile);
 

Promise.resolve()
  .then(() => {
    return fs_readFile(path);
  })
  .then(data => {
    return exif_metadata(data);
  })
  .then(metadata => {
    console.log('metadata: %O', metadata);
  })
  .catch(error => {
    res.send(error.toString());
  });

Saturday, July 27, 2019

Add Port to UFW

I'm running UFW (uncomplicated firewall) to restrict traffic into my Linux system.

And while being super restrictive is generally a good thing, there are times when you have to poke a new hole and connect from another system inside the house.

Usually it's a new app running on a new port and since I never remember the command to allow this, here it is:

$ sudo ufw allow from 192.168.1.0/24 to any port 3100

You're welcome, future self!

Saturday, July 20, 2019

The DX-M04 Shelving System

My dad bought a DX-M04 shelfy thing and I was tasked with its assembly.


I don't think a nicer set of shelves can be had at any price. And do you see the little screwdriver pictured in the instructions? YES, the DX-M04 really does come with a screwdriver!! And the bottom panel (part #3) has feet. Yes, they really did think of everything.

If I could make one suggestion:

At step three, you might want to leave the bottom a little loose, so when, in step four, you insert the back, you can wiggle it into the groove in the bottom. Then after you've installed the top in step five, you can go back and tighten the bottom.

If you need some shelves, you can't go wrong with the DX-M04. No, no idea where you'd buy them, but for the right price, I can put my hands on a really well assembled set.

Friday, July 19, 2019

MySQL CRAZIES

Did you install a new MySQL and things just aren't working the way you're used to?

WHAT?? ME TOO!!

In this case, I'm inserting just a few columns, and there are non-specified columns without default values.

In my other database it just works - I know, not correct behavior, but it's what I'm used to.

In my new database I get this error:

ERROR 1364 (HY000): Field 'xxx' doesn't have a default value

So what's the difference?

STRICT MODE

Thanks, documentation!!

Before, strict mode. Giving me an error...

mysql> select @@GLOBAL.sql_mode;

+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@GLOBAL.sql_mode                                                                                                                         |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)


After, non-strict mode. Working like my other database!

mysql> SET GLOBAL sql_mode = '';
Query OK, 0 rows affected, 1 warning (0.00 sec)

Tuesday, May 14, 2019

MySQL Passwords

I'll never remember this unless I write it down here. And hey, maybe it will help somebody else.

Problem:

  • MySQL version 8+
  • github.com/go-sql-driver/mysql
  • db, err = sql.Open("mysql", "username:password@/database")
    (no error)
  • query, err := db.Query("SELECT * FROM TABLE")
    this authentication plugin is not supported

Solution:

mysql> alter user 'username'@'localhost' identified with mysql_native_password by 'password';

See also: https://github.com/go-sql-driver/mysql/issues/785

Friday, March 08, 2019

How to Cook Chicken

This one, too.

375 degrees for 20 minutes, was it?

WIP: I'll note more detail next time.

How to Cook Salmon

I'm going to forget if I don't write this down.

- 1 lb salmon
- couple TBS oil
- Fish seasoning (salt, etc)

425 deg, 25 min

WIP: I'll write down more about this when I get a chance

Wednesday, February 06, 2019

My Very Own Burrito Recipe

I believe it was Benjamin Franklin who first said, "eat a burrito a day."

His recipe has been lost to the fog of time, but here's one I think he would like:

Makes two good-sized burritos

Ingredients

  • 1/4 lb., your choice of meat, cooked (alternatively 1/2 cup of cooked beans)
  • 1/2 cup, cooked rice
  • 1/2 cup, grated cheese - I used cheddar
  • 1/4 cup, salsa
  • two 10-inch flour (or gluten-free) tortillas

Steps

  • Mix it all up (everything but the tortillas, of course) in a microwave-safe dish (or fire-safe, if you're into that kind of thing).
  • Heat (microwave, fire, etc) the mixture until the cheese is melted
  • Give it all a good stir
  • Divide the melty mixture between the two tortillas, flattening and shaping it so as to create proper burrito-shaped innards
  • Fold the two sides toward the middle, then the near end over the center; finally flop the middle part onto the other end of the tortilla - please don't make me draw a diagram
Garnish the tortilla with a little more cheese, which then melt


Serve with a little more salsa, some Spanish rice, maybe some refried beans.

And enjoy!

Monday, December 31, 2018

Onion Dip Experiment #2

It's time to try the onion dip recipe again.

Here are my notes from last time.

Here's what I'm doing this time...

Ingredients
  • 2-3 small-medium onions (2 cups finely chopped)
  • 2 TBS unsalted butter
  • 3/4 tsp Kosher salt
  • 1/8 tsp pepper
  • 2 cups, plain yogurt
  • 2 TBS chives
Directions
Chop the onions finely. Try not to cry. They're just onions.

Melt the butter. Add the onions and 1/2 tsp salt. Cook until golden brown. You'll know they're golden brown when a spouse or other responsible adult tells you you're golden brown. It should take about 30-35 minutes.

Put the cooked onions in a tightly covered dish and refrigerate until cool. While you wait, you can tweet or write a blog post about the experience.

Once the onions are cool, mix them in a medium bowl with the yogurt, 1/4 tsp salt, the pepper, and the chives.

I know I said I was going to try adding cayenne pepper. We'll see about that, and I'll let you know. Nah, I think it's perfect as-is.

So as promised, the sodium content. The TOTAL sodium in the whole recipe is just about 1000 mg:
  • onions: 8 mg
  • unsalted butter: 0 mg
  • 3/4 tsp kosher salt: 840 mg
  • pepper: <1 mg
  • yogurt: 150 mg
  • chives: 0 mg
So one eighth of the recipe (about 1/4 cup) would have about 120 mg of sodium.

Let's compare this with Lipton's onion soup mix. The mix itself has 610 mg. The sour cream adds another 40-something.

This recipe reduces the sodium by more than 80%. That's quite a savings!!

Can we get that number up to 96%? Stay tuned, I'll try that in a couple weeks!

Tuesday, December 25, 2018

Sausage Bread

Originally from an old friend of the family.

Sausage Bread

  • 1 box of hot roll mix
  • 1/4 cup Parmesan cheese
  • 1/2 cup grated Swiss cheese
  • 2 eggs beaten
  • 1/4 tsp Tabasco
  • 1/2 tsp salt
  • 2 tbsp parsley
  • 1 onion chopped
  • 1 lb sausage, hot or sweet

Mix dough according to directions on box. Let rise 45 min. Roll out 1/4" thick oval. Cook onions wish sausage (not brown). Drain excess fat. Add all other ingredients. Stir until cheese has melted. Let cool. Don't spread to edges. Roll up and pinch ends together. Shape into crescent. Place on greased cookie sheet (with edges). Bake 20 min at 400 degrees until brown and toothpick comes out fairly clean.

I'm going to try and make this with gluten free bread dough sometime soon. I'll report back.

Sunday, December 23, 2018

Italian Wedding Soup

I found this great recipe for Italian Wedding Soup.

I used a one-pound box of baby spinach for the greens.

Instead of the three kinds of meat, I just used a pound of ground turkey.

Gillian's (unseasoned) gluten free bread crumbs worked very nicely.

I made the meatballs smaller - about 3/4 inch - which I find much nicer for soup.

And when you put them into the broth, it's a good idea to count them, so you know just how many you have if you're divvying them up for a large crowd. This batch served thirteen people as a soup course with a couple cups left over.

The spinach and puffed-up meatballs insisted on floating to the top, so swirling in the egg and cheese mixture was a bit difficult. I actually removed a bunch of it to perform this step!

Also worth noting: The meatball parsley should be chopped finely. And the recipe calls for a teaspoon of minced garlic - two cloves in the garlic press was just the right amount.

Garnish means "don't eat me" in Italian. Next time I'd use whole leaves of parsley and more coarsely grated cheese. (yes, eat the cheese)

Here's a pantry/fridge/freezer/shopping list for your convenience:

3 quarts homemade chicken stock (I might have used four? sorry, not sure)
1 lb. ground turkey
1 cup unseasoned (gluten free for my needs) bread crumbs
1/8 lb. Parmigiano-Reggiano (sorry, not sure how much I actually used)
3 large eggs
a medium onion
a bunch of fresh parsley
two cloves of garlic
kosher salt
black pepper grinder

Tuesday, December 11, 2018

Onion Dip Experiment #1

I love onion dip. Who doesn't? People on low-sodium diets, that's who. And besides, who wants all the crap that's in those processed soup packages? Not me, thanks!

So I went looking for an onion soup recipe to play with, and I found this one. My plan was to make it the first time exactly as written, but since I had some sour cream left over from Hanukkah, I combined that with some plain yogurt (Siggi's). And instead of unsalted butter and salt, I used the Land O' Lakes spread we had in the fridge. The rest of the salt I figured I would leave out.

The mixture is way too thick for my taste, so I think instead of the cream cheese, I'll stick with all yogurt next time - Greek or Icelandic.

My dip seemed a little bland, so I added some garlic powder. I guess I wish I'd read the original recipe's comments section, because somebody suggested adding a little cayenne pepper. That seems like a better idea.

Another commenter suggested getting a better texture by putting the cooked onions through a food processor.  That seems like a lot of work, so I think next time I'll chop the onions instead of just slicing them before cooking them.

Now as for the salt, the recipe calls for cooking with a half teaspoon of salt, which I left out, though I did use a buttery spread containing about 25 mg of sodium per serving of dip. The additional quarter teaspoon of salt the recipe calls for only adds another 30 mg of sodium per serving, so I think next time, I'll leave it in. The overall sodium savings compared with processed soup mix has to be at least 500 mg. Once I have the recipe perfected the way I like it, I'll do that math.

One more thing, I put a small container in the freezer. I'll thaw it out next week and see if it's any good. Update: I froze a 5 oz yogurt container of the original unsalted recipe. It was in there for about a week and then I put it in the refrigerator for about a day to thaw. The texture was just as it was, still too thick for my taste. And taste, just the same. I would have added some cayenne, but dang it, there wasn't any in the cupboard. That will have to wait for experiment #2.

UPDATE: read all about Onion Dip Experiment #2!

Monday, November 26, 2018

Soup: Split Pea with Turkey

Thanksgiving took place under my roof, so naturally I took custody of the turkey carcass - with an eye toward soup, of course! On the other hand, I've had a hankering for split pea soup, but preferring to avoid all the sodium that ham is full of.

Enter this recipe. I used turkey broth instead of chicken. And instead of ham, I used the turkey that boiled off the bones during the broth-making. And I left out the salt (and forgot about the pepper).

It's really good!

There's still plenty of broth left over, some of which will turn into Sherry Noodle Soup. But I also plan to make a batch (or half batch) of split pea with a cup of water swapped out for sherry. UPDATE: I swapped 1/2 cup water for sherry, which really helps when you cook without salt. It was a great addition!

Saturday, November 17, 2018

Apache Reverse Proxy for Microservice Subdomain

You've got Apache 2 running. What more does a plain-old simple HTML site need, after all?

Now you want to add a microservice, but you don't want to add more hosting. Can you add it to this existing host? Yes you can!

Here's how to add a subdomain - tictactoe.example.com - that will send requests to your microservice that's listening on port 8888.

Put the following in /etc/apache2/sites-available/tictactoe.com.conf

<VirtualHost *:80>
    ServerName tictactoe.example.com

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    ProxyPass "/"  "http://example.com:8888/"
    ProxyPassReverse "/"  "http://example.com:8888/"

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>


Then add your site:

sudo a2ensite tictactoe.com

The best part is your Go code (or Rust, Ruby, Python, whatever) can just handle HTTP. You can use Let's Encrypt/certbot to add the HTTPS virtual host that will proxy secure traffic to your microservice as well.

UPDATE: Nothing like getting an invalid command error trying to do this on an Apache without proxy enabled. So...

sudo a2enmod proxy_http