Linux Server – Adding a New Domain and WordPress Site – Linode VPS – Ubuntu 18.04

I have a VPS server with Linode that I use to host about a dozen different websites. All but one of them run on WordPress. Occasionally, I get a request to add another domain and website to the server. It’s not terribly time consuming to do, but it does require a number of specific steps and I never remember all of them. To help me remember them (and perhaps to help someone else), I’m putting together this tutorial.

Step 1: Purchase the new domain. For this tutorial, I’m going to be adding a domain my brother-in-law requested: He’s a pilot but is getting certified as a yoga instructor and wanted to set up a simple website. I use Google Domains to purchase and manage all my domains. So, step 1, decide on what company you want to use to purchase your domains and purchase your domain.

My domains in Google Domains.

Step 2: Change the DNS settings on the new domain to point to Linode’s nameservers. If using Google domains, click on the domain then click on DNS:

Select “DNS” to change the nameservers.

Under Name servers, select “Use custom name servers” and enter “” for the first Name server then add a second and enter “” Hit Save.

Here are the custom name servers in Google Domains.

Step 3: You now need to add the domain and then add domain records to your Linode account. Login to your account and select Domains.

Click on “Create Domain”:

click “Create Domain” at the top right.

Enter the domain and the admin email address. Unless you need to do something special with the Records, select “Insert default records from one of my Linodes.” then select your Linode:

Basic domain creation information.

Assuming you don’t need anything special, the defaults should take care of this step and you’re done.

Step 4: Since I already have about a dozen websites running on the server, I’m not going to go into detail on how to install a LAMP stack – Apache, MySQL, and PHP. There are a number of tutorials for doing so. Instead, my next step is to SSH into my server (obviously replace “user” and the IP address with your own) and create the directories where the files for the new website will be hosted.

ssh user@

Whenever I log into my server, I use that as an opportunity to run updates.

sudo apt-get update
sudo apt-get upgrade

Next, navigate to the directory where you store your public-facing web files. On my server, it’s /var/www/

cd /var/www/

In that directory, I’m going to create a new folder for the domain:


I’m then going to navigate inside that folder and create two additional folders: (1) a “public” folder where the actual files go and (2) a “logs” folder for access and error logs.

mkdir logs public

Now, navigate back to the main directory where you store all your website files and change the ownership of the directories:

cd ..
sudo chown -R www-data:www-data

This allows Apache to access the information in the folders and since Apache is effectively the web server, that’s important. Don’t skip this step.

Step 5: Download the latest version of WordPress and untar it into the public folder. Where you download it and untar isn’t actually all that important as we’re going to move it to the public folder shortly.

sudo wget
tar -xvf latest.tar.gz
mv wordpress/* /var/www/
rmdir wordpress/
rm latest.tar.gz

Just to clarify the above commands. The first line downloads the latest version of wordpress. The second one unpacks wordpress into a folder called “wordpress.” The third line moves all of the files that were just unpacked into the newly created public folder for the domain. The fourth line deletes the now empty “wordpress” folder and the fifth line deletes the wordpress tar.gz download (nice and clean server).

Step 6: It would be nice if we were done, but we’ve got a ways to go yet. Next up, let’s create a MySQL user and database with a corresponding user. This can be done from the command line as well, but I prefer using phpmyadmin.

You’ll need to look up where to find phpMyAdmin on your server.

Navigate to “User accounts” and scroll down to “Add user account.” Click on that and you’ll get this screen:

Click “add user account” to set up a new database and user.

Obviously, choose an appropriate user name. I typically let phpMyAdmin generate a nice strong password. Just below the “Login Information” box is a box that says “Database for user account.” Check “Create database with same name and grant all privileges.” Don’t check below that where it says “Global privileges – Check all.” That would give this user access to all databases you have on the server. Not a good security choice. Write down or copy the username and password to a text file as you’ll need it later. When you’ve got all that done, scroll down to the bottom and select “Go.” That will create your database, the user, with the password you wrote down (you wrote it down or copied it to a text file, right?). You now have the database WordPress is going to use for your website.

Here’s where you can create a new user and database in PHPMyAdmin

Step 7: Next up is creating the website information for Apache. Back to the SSH shell. Navigate to where the Apache websites are stored on your server:

cd /etc/apache2/sites-available

In there, you should see the configuration files for all the websites on your server. Since I already have sites configured, I typically just copy one of the existing configuration files and then edit it according to the new domain:


Since I’m using SSL on all my domains, I have two configuration files per domain. The above commands copy existing configuration files and create new ones for my new domain. Here’s the contents for the first one:

<Directory /var/www/>
    Require all granted
<VirtualHost *:80>
        DocumentRoot /var/www/

        ErrorLog /var/www/
        CustomLog /var/www/ combined

RewriteEngine on
RewriteCond %{SERVER_NAME} [OR]
RewriteCond %{SERVER_NAME}
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

And the contents for the second one –

<IfModule mod_ssl.c>
<Directory /var/www/>
    Require all granted
<VirtualHost *:443>
        DocumentRoot /var/www/

        ErrorLog /var/www/
        CustomLog /var/www/ combined

Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/

Once you have these updated, you can then tell Apache to load the site:

sudo a2ensite
systemctl reload apache2

The first line tells Apache to enable the site. The second line restarts Apache. NOTE: You don’t have to load the ssl configuration file (i.e.,

Step 8: Since I have SSL encryption on all of my websites using LetsEncrypt, there is an extra step. This is always the one I forget. Since I’m adding a domain, I have to use the following commands to add a domain to my existing domains on the single SSL certificate that I use for all of my domains. First, let me find the name of my current certificate:

certbot certificates

That provides me the name of my current certificate as well as a list of all of my other domains. Next, I copy all of the existing domains so I can update the certificate and add the two new ones I need to add. The command to then get a new certificate with the added domains is:

certbot --expand -d,,,

Assuming everything works, this will expand the existing certificate with the new domain and issue a new SSL certificate with all the domains. (NOTE: no spaces between the domains.)

Step 9: Now you can test your server. I always do this by creating a simple html file with the classic “Hello World” in it and putting that into the public directory for the new website:

<!DOCTYPE html>
        <title>Test Page</title>
        <p>Hello World!</p>

Save that as “index.html” and put it in the public folder. Now, navigate to the new domain in your browser and, hopefully, you’ll see “Hello World!”

Yeah. Website is working!

If you saw “Hello World!” in your browser, everything is working. It’s always a good idea to check that the https redirect is working as well – so you know that your SSL certificate is good and working. The easiest way to do that is to click on the lock icon in your browser and then check the certificate information.

Step 10: Now, the final step to install WordPress – change the name of the index.html file to something else (e.g. “index.html-test”) then reload the page. You should now see the installation guide for WordPress that will ask for your database name, username, and password:

This is the last step to install WordPress on a new domain.

Enter the database information from Step 6 above. Assuming everything goes according to plan, WordPress will populate the database with the relevant fields and your site will be ready:

Here’s the backend of my new wordpress installation.

 203 total views,  1 views today

GPRENAME – removing text up to a space using regular expressions

For a recent project, I came into possession of hundreds of photos, each of which was named according to the settings the person who take the photo with their phone had in place but ended with ” – FirstName LastName.jpg.”

The photos have varied characters before the names. That required some creative thinking on how to batch rename them.

I wanted to keep the users’ names, but everything before that could go. With hundreds of photos, I realized that it would be way too time-consuming to edit each file name by hand. Enter “gprename,” an app for bulk renaming files in Linux, and regular expressions.

Regular expressions are strings of characters that can be used to search for patterns. I’m no expert, but I’m familiar with them and realized that this could be a solution to my problem. A quick google search brought up this Stack Overflow post with the answer. I then applied it using gprename and, a 2 hour task was cut down to 5 minutes.

Here’s how I did it…

Open gprename and navigate to the folder where the files are located.

This is one of about 14 folders I needed to clean up.

On the “Replace / Remove” tab, in the “Replace” box, enter: “^.*?\s+”. In the “with” box that follows, you can just leave that blank. Make sure you check the box next to “Regular expression.”

Here’s where you enter the regular expression.

Here’s what the expression means:
^: Match from the beginning of the line
.*?\s+: Match anything until a space is encountered

Hit “Preview” and you should see the result:

A preview of the changes.

When you’re ready, click “Rename” and all of the characters prior to the first space will be wiped out:

The cleaned up files.

In my case, I then did some additional renaming (removing the ” – ” before the names and adding dates after), but this should get you close to your goal.

 1,028 total views,  1 views today

ZFS Snapshot Management

With my new fileserver/NAS, I am using a ZFS raid array for my file storage. One aspect of the ZFS file system that I didn’t really investigate all that closely before I installed it was the snapshot feature. ZFS snapshots basically store a “picture” or “image” of all the files on the system at a specific point in time. The logic behind snapshots is that you can then roll the filesystem back to that point in time, in case there was a problem.

This is, of course, a great feature for a variety of reasons. If you accidentally deleted a file, you could recover it this way. If someone hacked your server and encrypted your files, you could recover them this way (assuming the snapshots aren’t also encrypted).

However, there is a small issue here. In order for the snapshots to work, they basically have to store all of the files that were in existence when the snapshot was made. In other words, so long as you retain a snapshot, you will also have to retain all of the files associated with that snapshot, which will take up all the corresponding space as well. Technically, once you delete a file, it won’t show up in your file directory, but the file system has to retain a copy of it as part of the snapshot.

It was this issue that finally got me to look more closely at snapshot management. My fileserver has four 4TB hard drives in it, which gives me roughly 8TB of storage. I can always upgrade the drives to bigger drives if needed, but I don’t have 8TB of files at this point. I have around 4TB, but my fileserver was reporting less and less available space, even after I deleted some files I didn’t want/need. I was confused until I realized that I had set up some automatic snapshots when I first set up the fileserver. Those snapshots included many of the files I had deleted, so no space was freed up when I deleted those files. I had to delete the snapshots in order to free up the space. It took some doing, but I finally figured out how to manage snapshots a bit better.

First, here’s how to list your existing snapshots:

zfs list -t snapshot -r [ZFSpoolnamehere]

If you have any snapshots, you should see a list like this:

This shows the snapshots I have created on my fileserver.

To create a snapshot, you can use this code:

sudo zfs snapshot -r [ZFSpoolnamehere]@[nameofsnapshot]

The above command puts you in root (sudo) and calls zfs, telling it to create a snapshot. The “-r” part of the command tells zfs to make a recursive snapshot, which means it will create snapshots of each of your top directories in your ZFS pool. You then have to invoke the ZFS pool followed by the “@” symbol and then the name of your snapshot. Here’s my actual command:

sudo zfs snapshot -r ZFSNAS@2021_01_02

This command creates a snapshot of my entire ZFS pool and names it with the date it was created – January 2nd, 2021.

Once I’ve created my snapshot, I can see it in the list of snapshots I have created with the command above.

Of course, there is also the issue of deleting snapshots. This was the issue I needed to address that got me started on ZFS snapshots – I had some very old snapshots that were taking up terabytes of space on my fileserver. To delete a snapshot, you can use the following code:

sudo zfs destroy [ZFSpoolname]/[directoryname]@[nameofsnapshot]

Here’s an example of my actual code used to delete an old snapshot:

sudo zfs destroy ZFSNAS/files@2020_12_25

This command tells zfs to delete my snapshot in the ZFSNAS pool that was made of the “files” directory on December 25, 2020 (@2020_12_25). When I check the list of snapshots after deleting that one, it’s no longer there and the space that was reserved for that snapshot is freed up.

Luckily, I haven’t needed to roll back to a snapshot at this point. However, it is nice knowing that my filesystem on my NAS has that capability.

For more information on working with ZFS snapshots, see here.

Finally, there is the issue of how many snapshots to keep and when to make them. Given my use case – a fileserver/NAS that stores my music, my video collection, my old photos (not the current year’s photos), and my old files, I actually don’t need particularly frequent snapshots. I decided that one snapshot per month would be sufficient. You can automate this by putting it into a crontab job. However, I simply added this to my calendar to create a snapshot once a month. That way, I can also delete the corresponding snapshot from 12 months prior. Basically, I am keeping one year’s worth of snapshots with one snapshot per month. This gives me a year’s worth of backups to which I can roll back should I need to but also regularly frees up any space that might be taken up by particularly old backups.

I can imagine that other use scenarios would require different frequencies of snapshots for a zfs system (e.g., a production server or someone who uses a zfs raid as their primary file storage). Since my server is primarily used for storing old files and relatively unchanging collections, once a month snapshots are sufficient.

 2,026 total views,  1 views today

PVC paintball gun holder

I play paintball frequently enough that I finally broke down and made myself a paintball gun holder. Is it a requirement for paintball? Of course not! Is it a convenient place to put your gun between games while you fill the hopper and work on it? Yes!

I initially tried a different design but didn’t like it. This was my second attempt and I’m quite pleased with it. I found several youtube videos showing how to make PVC paintball gun holders. They showed what I needed to see, but in almost all of them, the people creating the videos didn’t measure anything – they were just winging it. I’m not one for winging it. So, after successfully building my own, here are detailed instructions.

First, supplies. You’ll need:

  • PVC cutting tool (you can use a hacksaw if needed)
  • dry erase marker
  • ruler or tape measure
  • PVC fittings – all in 3/4 inch PVC (unless otherwise indicated):
    • 4 – 90 degree elbows
    • 4 – 45 degree elbows
    • 3 – tees
    • 1 – 3/4″ to 1″ tee
  • 3/4 PVC pipe cut to the following lengths:
    • 1 – 24 centimeter piece (9 1/2 inches)
    • 4 – 22 centimeter pieces (8 2/3 inches)
    • 1 – 16 centimeter piece (6 1/3 inches)
    • 2 – 11 centimeter pieces (4 1/3 inches)
    • 4 – 10 centimeter pieces (4 inches)
    • 1 – 5.5 centimeter pieces (2 1/4 inches)
    • 2 – 4.5 centimeter pieces (1 3/4 inches)

Here’s a photo of all the pieces labeled:

Once you cut all of the pieces of PVC, then it’s just a matter of assembling them in the right way. Here are the pieces assembled and labeled:

The hardest part of this build was cutting the 3/4″ x 1″ tee in half. That isn’t actually required. You could also just use another 3/4″ tee and turn it sideways, placing it under the barrel. If you do, the length of PVC that holds it up will need to be slightly shorter.

 1,934 total views,  1 views today

Long Term Storage of Gmail/Email using Mozilla’s Thunderbird (on Linux)

I have email going back to 2003. There have been times when I have actually benefited from my email archive. Several times, I have gone back 5 or more years to look for a specific email and my archive has saved me. However, my current approach to backing up my email is, let’s say, a borderline violation of Google’s Terms of Service. Basically, I created a second email account that I use almost exclusively (not exclusively – I use it for a couple of other things) for storing the email from my primary Gmail account. However, Google has recently changed its storage policies for their email accounts, which has made me a little nervous. And, of course, I’m always wary about storing my data with Google or other large software companies.

Since I have already worked out a storage solution for old files that is quite reliable, moving my old email to that storage solution makes sense. (FYI, my storage solution is to run a local file server in my house with a RAID array so I have plenty of space and local backups. Certain folders on the file server are backed up in real-time to an online service so I also have a real-time offsite backup of all my important files. In other words, I have local and offsite redundancy for all my important files.)

I’m also a fan of Open Source Software (OSS) and would prefer an OSS solution to any software needs I have. Enter Mozilla’s Thunderbird email client. I have used Thunderbird for various tasks in the past and like its interface. I was wondering if there was a way to have Mozilla archive my email in a way that I can easily retrieve the email should I need to. Easily might be a bit of a stretch here, but it is retrievable using this solution. And, it’s free, doesn’t violate any terms of service, and works with my existing data backup approach.

So, how does it work? And how did I set it up?

First, install Thunderbird and set up whatever online email account you want to backup. I’m not going to go through those steps as there are plenty of tutorials for both of them. I’m using a Gmail account for this.

Once you have your email account set up in Thunderbird, click on the All Mail folder (assuming it’s a Gmail account) and let Thunderbird take the time it needs to synchronize all of your email locally. With the over one hundred thousand emails I had in my online archive, it took the better part of a day to do all the synchronizing.

I had over 167,000 emails in my online archive account.

Once you’ve got your email synchronized, right-click on “Local Folders” and select “New Folder.” I called my new folder “Archive.”

Technically, you could store whatever emails you want to store in that folder. However, you’ll probably want to create a subfolder in that folder with a memorable name (e.g., “2015 Work”). Trust me, it will be beneficial later. I like to organize things by year. So, I created subfolders under the Archive folder for each year of emails I wanted to back up. You can see that I have a folder in the above image for the year 2003, which is the oldest email I have (that was back when I had a Hotmail address… I feel so dirty admitting that!).

The next step is weird, but it’s the only way I’ve been able to get Thunderbird to play “nice” with Gmail. Open a browser, log in to the Gmail account you’re using, and empty your trash. Trust me, you’ll want to have the trash empty for this next step.

Now, returning to Thunderbird, select the emails you want to transfer to your local folder and drag them over the “Trash” folder in your Gmail account in Thunderbird. This won’t delete them but it will assign them the “Trash” tag in Gmail. Once they have all been moved into the Trash, select them again (CTRL+A) and drag them into the folder you created to store your archived emails. In the screenshot below, I’m moving just a few emails from 2003 to the Trash to test this process:

Once the transfer is complete, click on the Local Folder where you transferred the emails to make sure they are there:

And there are the emails. Just where I want them. This also means that you have a local copy of all your emails in a folder exactly where you want them. At this point, you have technically made a backup of all the email you wanted to backup.

To remove them from your Gmail account, you need to do one additional thing. Go back to the browser where you have your Gmail account open, click on the Trash, and empty the Trash. When you do, the emails will no longer be on Gmail’s server. The only copy is on your local computer.

Now, the next tricky part to this (I didn’t say this was perfectly easy, but it’s pretty easy). Thunderbird doesn’t really store the Local Folder emails in an obvious location. But you can find the location easy enough. Right-click your Local Folder where you are archiving the emails and select “Properties.”

You’ll get this window:

Basically, in the Location box you’ll see the folder’s location. This is telling you where to find your Local Folder where your email is stored. On Linux, make sure that you have “view hidden files” turned on in your file manager (I’m using Dolphin), the location is your home folder, followed by your user folder, then it’s inside the hidden “.thunderbird” folder followed by a randomly generated folder that Thunderbird creates. Inside that folder, look for the “Mail/Local Folders” folder. Or, simply:

/home/ryan/.thunderbird/R$ND0M.default-release/Mail/Local Folders/
I have opened all the relevant folders on my computer in Dolphin see you can see the file structure.

Since I created an additional folder, there are two files in my Archive.sbd folder that contain all the emails I have put into that folder: “2003” and “2003.msf.” You can learn more about the contents of those files here, but, basically, the file with no file extension stores the actual contents of the emails. The .msf file is basically an index of the emails (I was able to open them both in Kate, a text editor, and read them fine). In short, you won’t have a bunch of files in your archive. You’ll have two files – one with the contents of the emails and one that serves as an index of the emails that Thunderbird can read. These are the two files that you’ll want to backup.

I’ll admit, this was the part that scared me. I needed to know that I could just take those two files, move them to wherever I wanted to ultimately store them and then, when needed, move them back into my Thunderbird profile and read them just fine. So, I tested it repeatedly.

Here’s what I did. First, I clicked on my backup folder in Thunderbird to make sure all of the emails were there:

I then went into the Local Folders directory and moved the files to where I want to back them up.

I then clicked on a different folder in Thunderbird and then hit F5 to make Thunderbird refresh the Local Folders. It took a couple of minutes for Thunderbird to refresh the folder, but eventually, it did. Then, I selected the 2003 Archive folder again and the emails were gone:

This is what I expected. The emails are in the “2003.msf” and “2003” files on my backup server. Now for the real test. I copied the two backed up files back to the Archive.sbd folder in my Thunderbird profile, selected the parent folder in Thunderbird, and hit F5 to refresh the folders again. It took a minute for the folder to refresh, but eventually, when I clicked on the 2003 folder and…

The emails are back!

It worked!!!

What this means is that you can put all of the email you want to back up into a folder; that folder is stored in your Thunderbird profile. You can then find the relevant .msf file and its corresponding data file, move them wherever you want for storage and, if needed, move them back to your Thunderbird profile (or, technically, any Thunderbird profile using the same folder structure) and you’ll still have all of your email.

This may not be the most elegant method for backing up your email but it’s free, it’s relatively simple and straightforward, and works reliably. Your email is not in a proprietary format but rather in an open source format that can actually be ready in a simple text editor. Of course, it’s easiest to read it in Thunderbird, but you have the files in a format that is open and secure.


If you don’t think you’re going to need to access your email on a regular basis, you can always compress the files before storing them. Given that most of email is text, you’ll likely realize a savings of close to 50% if space is at a premium (once I moved all of my 2003 email to storage, I compressed it and saw a savings of 60%). This will add a small amount of time to accessing the email as you’ll have to extract it from the compressed format, but it could mean pretty substantial space savings depending on how many emails you’re archiving.


This is also a way to move emails between computers. I ended up using this approach to move my email archives to my laptop so I could go through my old email while I’m watching TV at night and delete all the emails I’ll never want in the future (you could of course do that with the email online before you archive it). I’m pretty good about deleting useless emails as I go, but I don’t catch them all. With the .msf file and its accompanying data file, I was able to transport my email archives to whichever computer I wanted and modify the file, then return it to my file server for long term storage.

 2,822 total views

Linux – Bulk UnRAR

If you’re not familiar with RAR files, they are like ZIP files. RAR is an archive format.

I had a collection of more than 150 RAR files in a single folder I needed to unrar (that is, open and extract from the archive). Doing them one at a time via KDE’s Ark software would work, but it would have taken a long time. Why spend that much time when I could automate the process.

Enter a loop bash script in KDE’s Konsole:

for i in *.rar; do unrar x "$i"; done

Here’s how the command works. The “for i in” part starts the loop (note: you can use any letter here). The “*.rar” component indicates that we want the loop to run through all the RAR files in the directory, regardless of the name of the file. The “do” command tells the loop what command to run. The “unrar x “$i”” component tells the software to use the unrar function which unpacks the archive. The “x” in that command tells the software to use the directory structure inside the RAR archive. The final piece of the loop after the second semi-colon – “done” – indicates what the terminal should do once the loop completes.

It took about 20 minutes to run through all the RAR files, but I used that time to create this tutorial. Doing this by hand would have taken me hours.

 1,720 total views

Linux: Batch Convert .avi files to .mp4/.mkv

I’ve been trying to clean up my video library since building my latest NAS. In the process, I found a number of .avi files, which is an older file format that isn’t widely used these days. While every time a file is converted it loses some of its quality, I was willing to risk the slight quality reduction to convert the remaining few files I had to convert into more modern file formats.

I initially tried converting the files using HandBrake. But given the number I needed to convert, I decided pretty quickly that I needed a faster method for this. Enter stackoverflow.

Assuming you have all of your .avi video files in a single directory, navigate to that directory in a terminal and you can use the following single line of code to iterate through all of the .avi files and convert them to .mp4 files:

for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done

In case you’re interested, the code is a loop. The first part starts the loop (“for i in *.avi;”), telling the computer to look for every file with the file extension .avi. The second part tells the computer what to do with every file with that extension – convert it to a .mp4 file with the same name. The last piece indicates what to do when the loop is completed – done.

Of course, this code could also be used to convert any other file format into a different format by replacing the .avi or .mp4 file extensions in the appropriate places. For instance, to convert all the .avi files to .mkv, the code would look like this:

for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mkv"; done

Or if you wanted to convert a bunch of .mp4 files into .mkv files, you could do this:

for i in *.mp4; do ffmpeg -i "$i" "${i%.*}.mkv"; done


If you have .avi files in a number of subfolders, you’ll want to use this script:

find . -exec ffmpeg -i {} {}.mp4 \;

To use it, navigate in a terminal to the top-level folder, then execute this command. It will search through all the subfolders, find all the files in those subfolders, and convert them all to .mp4 files.

Of course, if you have a mixture of file types in the folders, you’ll want a variation of this command that searches for just the files of a certain type. To do that, use this command:

find . -name *.avi -exec ffmpeg -i {} {}.mp4 \;

This command will find all the files with the extension .avi and convert them all to .mp4 files using ffmpeg.

And, if you’re feeling particularly adventurous, you could search for multiple file types and convert them all:

find . -name *.avi -or -name *.mkv -exec ffmpeg -i {} {}.mp4 \;

This code would find every file with the extension .avi or .mkv and convert it to .mp4 using ffmpeg.

NOTE: This command uses the default conversion settings of ffmpeg. If you want more fine-tuned conversions, you can always check the options available in converting video files using ffmpeg.


If you want to specify the codec to use in converting the files, that is a little more complicated. For instance, if I want to use H265 instead of H264 as my codec, I could use the following code to convert all of my .avi files in a folder into .mkv files with H265 encoding:

for i in *.avi; do ffmpeg -i "$i" -c:v libx265 -crf 26 -preset fast -c:a aac -b:a 128k "${i%.*}.mkv"; done

The default setting in ffmpeg for audio is to pass it through. Thus, if you wanted to just convert the video to a new codec but leave the audio, you could use the following command:

for i in *.avi; do ffmpeg -i "$i" -c:v libx265 -crf 26 -preset fast "${i%.*}.mkv"; done

This will convert the video to H265 but retain whatever audio was included with the video file (the default is to take the audio with the highest number of channels).

Additional information on the various settings for H.265 is available here. Some quick notes: the number after “-crf” is basically an indicator of quality, but is inverted. Lower numbers improve the quality; higher numbers reduce the quality. Depending on what I’m encoding, I vary this from 24 (higher quality) to 32 (lower quality). This will affect the resulting file size. If time is not a concern, you can also change the variable after “-preset.” The options are ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, and veryslow. Slower encodes will result in better quality output but it will take substantially longer to do the encode.

If you run into the problem where you are trying to do bulk conversions but the names of the videos you are converting have spaces in them, you may get the error: “find: paths must precede expression.” The solution is to put the pattern in single quotes, like this:

find . -name '*.mkv' -exec ffmpeg -i {} -c:v libx265 -crf 26 -preset fast {}-new.mkv \;

 4,459 total views,  3 views today

HandBrake – H.265 NVEnc 1080p Ripping Chart and Guidelines

With a Plex server, I want my collection of movies backed up digitally so I can watch them when and where I want to. This involves a two-step process. First, I have to rip the video from Blu Ray, which I do using MakeMKV. Since that process is pretty straightforward, I’m not going to cover how to do it here. It’s the second step that is more complicated – compressing the video using HandBrake.

I’ve been using HandBrake for years, but have typically just used the default settings. That’s a terrible idea for a number of reasons, which I’ll detail in this post. But the primary reason why I’m posting is to detail how different settings translate into different file sizes so people have a better sense of what settings to use.


The first thing you need to decide when ripping a video using HandBrake is the resulting file format. I’m using HandBrake 1.3.3 which includes three options: MPEG-4, Matroska, and WebM. Each of these formats has advantages and disadvantages.

You can choose which format you want on the summary tab of Handbrake

MPEG-4 (or mp4/MP4) is the most widespread format and the most compatible with various devices and programs. This is likely going to be the default for most people. However, MPEG-4 has a major limitation – you cannot store multiple subtitles in the video file itself. If you don’t care about subtitles (e.g., you never watch foreign films), that may not matter to you. But it is a problem for those of us who enjoy a good foreign film. (NOTE: The workaround for most people is to save the subtitles as an .srt file in the same folder, assuming your playback device can then load a separate SRT file.)

Matroska (or MKV) is kind of odd. It’s actually not a video codec. It’s an open-standard container. Basically, it’s like a zip file or folder for the actual media. Inside, it can have video files in a lot of different formats, including MPEG-4, but it can also include subtitle tracks and other media. Thus, the major advantage is that you can store more inside a Matroska file than you can in MPEG-4 files. The disadvantage is that not every device or app supports Matroska files natively. However, support for the format has increased quite a bit. Matroska is now my preferred format, mostly because all of the devices I use for playback can play MKV files and I can store subtitles in the same file.

WebM is actually a variant of Matroska but is meant to be a royalty-free alternative to MP4 that is primarily sponsored by Google and supports Google’s VP8 and VP9 codecs. It is licensed under a BSD license. Basically, MP4 is a proprietary codec while WebM is an open-source one. (NOTE: I don’t have any videos stored in WebM format. However, when I create videos to upload to YouTube, I typically rip them into VP9, which is the preferred format for YouTube.)


HandBrake searches for the default audio track from the video you are planning on converting but then does something very odd. By default, it sets whatever audio track that is to be converted to stereo audio (i.e., 2.0 or 2 channels – left and right). You can see that in the screenshot below:

HandBrake’s default setting on audio is to convert the default audio track to Stereo (2.0) sound.

If you have a home theater or good headphones, you’ll want 5.1 surround sound at a minimum. If you have a nicer setup, you’ll want 7.1 surround sound. So, make sure that you delete the default Audio option and instead include a 5.1 surround sound option into your new file. Like this:

5.1 audio track instead of stereo.

(NOTE: I haven’t figured out the best options for 5.1 surround sound. I’m not sure whether AC3 or AC3 passthrough is better. And I’m not sure if Dolby Surround, Dolby ProLogic II, or 5.1 Surround is better. Perhaps someone out there will have insights on this.)

(NOTE: Most modern video players are capable of converting 5.1 surround sound into stereo sound [a.k.a. downsampling]. Not including a 2.0 option is perfectly fine for most people as playback devices will compensate.)


If you haven’t ever used the Tags tab in Handbrake, you really should. By default, the “Title” tag is filled in with whatever information is stored in the video file or DVD you are converting, like this:

Default tag information loaded by HandBrake

However, what you include in the “Title” tag is also what video playback software or devices will think is the name of the video. It is worth taking two minutes to fill in the tags. I typically will change the “Title,” at a minimum, as well as the “Release Date” and “Genre” tags, like this:

I have filled in the tags in this screenshot.


Now on to the primary purpose of this post – video quality settings. To determine the ideal balance between quality and file size, I actually converted the same file using different settings. The original file is a rip of the film Amadeus (Director’s Cut) from the Blu-Ray disc that was 28.4 GB in size. The table below illustrates the results of converting the file using different Constant Quality options – all into 1080p video. For each of these conversions, I used identical settings except I changed the Constant Quality option in HandBrake. Each of these used the H.265 (NVenc) encoder with all the other video options on their default settings. Each conversion took about 1 hour (give or take 10 to 15 minutes).

SettingResulting File SizeCompression
(% of original file)
CQ 2214.3 GB50.35%
CQ 248.6 GB30.28%
CQ 266.5 GB22.89%
CQ 284.9 GB17.23%
CQ 303.7 GB13.03%
CQ 322.9 GB10.21%

The big question, of course, is how much degradation there is in quality with the smaller file sizes. To illustrate this, I took a screenshot using VLC from four of the video files: the original, unconverted Blu-Ray rip (28.4 GB file), from the CQ 22 rip, the CQ 28 file, and the CQ 32 file. I uploaded the full resolution files below so you can see and compare the differences.

Screenshot from the original MKV file – 28.4 GB.
Screenshot from the converted file at CQ 22.
Screenshot from the converted file at CQ 28.
Screenshot from the converted file at CQ 32.

To help my old eyes see the differences, I zoomed in on just one part of these photos to see if I could tell if there were any meaningful differences:

I thought I might see differences in the quality of the screenshots with the musical score (that’s why I chose this frame). I thought the lines might get blurred or the notes would become fuzzier. But that isn’t actually the case. Most of the space savings actually came from the detail in the brown section of this frame. In the original, if you look closely at the bottom left of the image, you can see lots of “noise.” This is basically film grain. The compression algorithm must look for that kind of noise and then remove it. If you look closely at the CQ 22 frame, there is less film grain. In CQ 28, large swathes of the film grain have been removed. And in CQ 32, all of the film grain has been removed and converted to blocks of single colors. Where there is fine detail in the video or distinct color differences, that has been retained. I should probably try this same exercise with a more modern movie shot digitally and not on film to see how the compression varies. Even so, this is a good illustration of how compression algorithms save space – they look for areas that can be considered generally the same color and drop detail that is deemed unimportant.

TL:DR: My recommendation for file sizes and CQ settings…

Scenario 1: Storage space is genuinely not an issue and you have a very fast internet connection, file server, and home network. You should rip your BluRay disks using MakeMKV and leave them as an MKV file with their full size. That will give you the best resolution with lots of options for future conversion if you want.

Scenario 2: You have a fair amount of storage space, a decent internet connection, a reasonably fast/powerful file server, and a good home network, then I’d suggest a dual approach. If it’s a movie you absolutely love and want the ideal combination of quality while minimizing file size, use a CQ of 22 to 26. That will reduce the quality, but retain much of the detail. If it’s just a movie that you enjoyed and think you might want to watch it again in the future but don’t care so much about the quality, go with a lower quality setting (e.g., CQ of 30 or 32).

Scenario 3: You have very little storage space, your internet connection isn’t great, your file server cannot convert files on the fly, and your home network is meh, then you should probably go for higher levels of compression, like CQ 30 or 32. You’ll still get very good quality videos (compression algorithms are very impressive these days) but in a much smaller sized video. Oh, and you should probably convert your files to MP4.

 11,190 total views

go vote sign

Hillsborough County, FL – 2020 General Election

Below is the information I found on the various candidates and constitutional amendments for the 2020 general election in Hillsborough County, Florida for my district. You can find your own sample ballot here. I’m politically an independent but registered as a Democrat so I can vote in Florida’s primaries. I generally try not to endorse candidates in my election guides.

(NOTE 09-29-2020: I have entered information for every candidate and amendment. If I find new information, I will update this page. Feel free to comment if you think I missed something important.)


I’m fairly confident you’re not on my website looking for information about the candidates for President/Vice-President. Even so, I went ahead and put together the standard links I do for candidates.

Donald J. Trump & Michael R. Pence

Party: Republican
Background Information: Trump was in business and real estate. Pence was governor of Indiana.
Finances: Federal Election Commission
Websites: campaign website,

Joseph R. Biden & Kamala D. Harris

Party: Democrat
Background Information: Biden and Harris have been US Senators. Harris was also the attorney general of California.
Finances: Federal Election Commission
Websites: campaign website,
Endorsements: Tampa Bay Times

Jo Jorgensen & Jeremy “Spike” Cohen

Party: Libertarian
Background Information: Jo Jorgensen worked in the tech industry before becoming a professor at Clemson University, where she now teaches. Cohen is a former web-designer turned podcast and libertarian activist.
Finances: Federal Election Commission
Websites: campaign website, Twitter, Wikipedia – Jorgensen, Wikipedia – Cohen,

Roque “Rocky” De La Fuente & Darcy G. Richardson

Party: Reform Party (in Florida), Alliance Party (in other states)
Background Information: de la Fuente is in business, inheriting his father’s businesses. He’s wealthy and has engaged in some sketchy business practices. Richardson is an author and blogger focusing on third party candidates.
Finances: Federal Election Commission
Websites: campaign website, Twitter, Wikipedia – de la Fuente, Wikipedia – Richardson,

Gloria La Riva & Sunil Freeman

Party: Party for Socialism and Liberation (PSL) and the Peace and Freedom Party
Background Information: La Riva is an activist. Freeman is an author and activist.
Finances: Federal Election Commission
Websites: campaign website, Twitter, Wikipedia – La Riva,

Howie Hawkins & Angela Nicole Walker

Party: Green Party
Background Information: Hawkins is an activist and politician. Walker was a professional driver before becoming a union representative.
Finances: Federal Election Commission
Websites: campaign website, Twitter, Wikipedia – Hawkins, Wikipedia – Walker,

Don Blankenship & William Mohr

Party: Constitution Party
Background Information: Blankenship was a coal company CEO and is a convicted criminal. Mohr is self-employed in building and construction.
Finances: Federal Election Commission
Websites: campaign website, Twitter, Wikipedia – Blankenship, Wikipedia – Mohr,

Florida and Local Elections

The Tampa Bay Times now has their election guide up. It’s pretty similar to what I put together but with all the local candidates (I only covered the ones on my ballot). Also, the Tampa Bay Times doesn’t include links to candidates’ websites or information on candidates for the Water District. So, I guess my information is still helpful for those who want to learn about the candidates directly from the candidates.

Representative in Congress District 14

Christine Y. Quinn

Party: Republican
Background Information: Originally from California. Graduated from Cal State Fullerton with a degree in Child Development. Small business owner selling spices.
Finances: Federal Election Commission
Websites: campaign website, Twitter, Facebook

Kathy Castor

Party: Democrat
Background Information: Incumbent candidate. Daughter of a well-known Florida politician, Betty Castor. Graduated from Emory for undergrad and Florida State for law school. Was elected to Hillsborough County Board of Commissioners in 2002. Practiced law until being elected to the US House in 2006.
Finances: Federal Election Commission
Websites: campaign website, Twitter, Wikipedia
Endorsements: Tampa Bay Times

State Attorney, 13th Judicial Circuit

Mike Perotti

Party: Republican
Background Information: He’s a Tampa native and a graduate of Jesuit High School in Tampa. Earned a BA from the University of Florida and his JD from University of Florida College of Law. Per his LinkedIn page, he is currently a staff attorney at the Hillsborough County’s Sheriff’s Office. He previously was a prosecuting attorney in Hillsborough County and ran his own law firm.
Finances (per Florida Department of State Division of Elections): $123,207.25 (as of 2020-09-26)
Websites: campaign website, Facebook, LinkedIn,

Andrew Warren

Party: Democrat
Background Information: Incumbent candidate. Florida native. Earned BAs in Economics and Political Science at Brandeis University and his JD from Columbia Law School. Currently the State Attorney for the 13th district (since 2016). Married with two kids.
Finances (per Florida Department of State Division of Elections): $182,867.85 (as of 2020-09-26)
Websites: campaign website, Twitter, LinkedIn
Endorsements: Tampa Bay Times,

State Representative District 62

Angel S. Urbina Capo

Party: Republican
Background Information: Doesn’t provide any background information about himself on his website. I found this Tampa Bay Times article that provides some information: he is a cyber-security consultant with limited knowledge of politics and the issues facing Tampa Bay. (I still don’t know where he is from or if he went to college). Speaks Spanish and English. Advocate for “freedom of religion” which he interprets to mean that no one can force him to act against his religious principles (translation: he should be allowed to discriminate against LGBTQ individuals). Big fan of Donald Trump.
Finances (per Florida Department of State Division of Elections): $4,805.00 (as of 2020-09-26); Voterfocus indicates he has received more money.
Websites: campaign website, Twitter, Facebook

Susan L. Valdés

Party: Democrat
Background Information: Incumbent. Born in NY but moved to Florida at 8. Graduate of Leto High School. BASc in Business Administration and Management from Nova Southeastern University and an MA in Organizational Leadership from Manhattan College (notes an Honorary Doctorate from Everest University – former for-profit university that doesn’t have any meaningful credentials to grant such an honor). Was a member of the Hillsborough County School Board for 14 years (2004-2018). Elected to Florida House in 2018. Worked for St. Joseph’s Community Care Clinic before that.
Finances (per Florida Department of State Division of Elections): $58,950.00 (as of 2020-09-26); See Voterfocus as well.
Websites: Florida House page, campaign website, Twitter, Wikipedia, LinkedIn
Endorsements: Tampa Bay Times

Laurie Rodriguez-Person

Party: Independent? (ran against Susan Valdes in the Democratic Primary)
Background Information: Went to Leto High School; studied at USF (no indication of a degree). Teaches “exceptional education” at various schools in Tampa. Not a lot of information available. Found one Twitter post suggesting she is running to oppose Susan Valdes.
Finances (per Florida Department of State Division of Elections): $3,500.00 (as of 2020-09-26).
Websites: Facebook


Chad Chronister

Party: Republican
Background Information: Incumbent. BA in Criminal Justice and MA in Criminology from St. Leo University. Initially appointed by Rick Scott in 2017; elected in 2018. Served with Hillsborough County Sheriff’s Office for 28 years. Mentions his religion prominently on his website.
Finances (per
Websites: campaign website, Facebook,
Endorsements: Tampa Bay Times (though they also posted a story suggesting his office may be targeting gay men for prosecution)

Gary Pruitt

Party: Democrat
Background Information: Retired Tampa police Corporal; worked for 25 years for the Tampa Police department. Not a lot of personal information available on him (nothing on his website). This site suggests he’s not the best partner/father.
Finances (per
Websites: campaign website, Facebook, LinkedIn

Ron McMullen

Party: no party affiliation
Background Information: Tampa native. Graduated from Brandon High School. BA in Criminal Justice from St. Leo University and a MA in Criminology from Florida State. Retired Tampa police major; served for 29 years; last two years was in charge of Special Operations. Wanted to run as a Democrat but didn’t change his party affiliation from Republican by the legal deadline (deadline was June 8, 2019; he switched it in January 2020); see this Tampa Bay Times article.
Finances (per
Websites: campaign website, Facebook

Property Appraiser

D.C. Goutoufas

Party: Republican
Background Information: Tampa native. Graduated from University of Tampa with a degree in Business Administration. Worked in bank management then became a serial entrepreneur. Has also adjuncted at USF. He has served on a number of local boards. He lost his hearing at 4 and eventually got a cochlear implant.
Finances (per
Websites: campaign website, Facebook, Twitter

Bob “Coach” Henriquez

Party: Democrat
Background Information: Incumbent. Tampa native. Graduated from Tampa Catholic High School and Princeton University. Served in the Florida House of Representatives (1998-2006). Was the head coach of Tampa Catholic’s football team (thus the “coach” in his name)
Finances (per
Websites: campaign website, Facebook, Wikipedia
Endorsements: Tampa Bay Times,

Tax Collector

TK Mathew

Party: Republican
Background Information: Identifies himself as a conservative businessman. Worked for Doug Belden as a tax collector for a few years. Doesn’t know how to spell “Hillsborough” (major typo on the home page of his website – “Hillsbrorough”). The Tampa Bay Times calls him a “mystery candidate.” Given how little is known about him, that sounds about right.
Finances (per
Websites: campaign website, Facebook,

Nancy C. Millan

Party: Democrat
Background: Has worked for the tax collector’s office for decades (31 years), rising through the ranks; served on a number of boards, including the Board of Trinity School for Children from 2005-2008 (full disclosure – my son attended Trinity School for Children from about 2012 until 2020);
Finances (per
Websites: election website, Facebook, Twitter, Instagram
Personal Commentary: I received a flyer for Nancy Millan that was riddled with typos. That lack of detail bothers me. Millan is also purchasing ads on Google’s search engine. The Tax Collector’s website,, does use Cloudfare to protect against DDOS attacks, though the settings for the protection wouldn’t let me access the website, so someone set it up wrong.
Endorsements: Tampa Bay Times,

Board of County Commissioners District 3

Maura Cruz Lanz

Party: Republican
Background Information: Tampa native. Graduated from Jefferson High School. Attended a beauty school and became a licensed cosmetologist. Lives in Wellswood (full disclosure: that’s where I live!). Her husband works in construction and she was the vice president of his company.
Finances (per
Websites: campaign website, Facebook, LinkedIn

Gwen Myers

Party: Democrat
Background: Tampa native; graduate of FAMU; worked for Hillsborough County for 25 years; now retired; served on a variety of local boards (e.g., Salvation Army Adult Rehabilitation Council)
Endorsements: County Commissioner Pat Kemp among others, Tampa Bay Times
Finances (per
Websites: election website, Facebook, Twitter, Instagram
Personal Commentary: Likes the color green. Platform seems to be focused on public transit.

Board of County Commissioners District 6

Tampa Bay Times story on some of the policy differences between Murman and Kemp.

Sandra L. Murman

Party: Republican
Background Information: Current County Commissioner but term-limited for her seat so running for a county-wide seat. First elected in 2010. Served in the Florida House of Representatives for 8 years. Graduate of Indiana University (Marketing degree). Married to an attorney and have a daughter. Murman has a sizable fundraising lead over Kemp. (Her campaign website looks like it was designed in 2010.)
Finances (per
Websites: campaign website, Twitter, Facebook

Patricia “Pat” Kemp

Party: Democrat
Background Information: Incumbent. First elected in 2016. Was an aide to Kathy Castor when she was on the county commission. She is both an attorney and a journalist. Worked in private practice as an attorney and as a radio talk show host at WUSF and WMNF.
Finances (per
Websites: campaign website, Twitter, Facebook
Endorsements: Tampa Bay Times


In case you are wondering, if the majority of voters in Florida vote against retention, a judge will actually be removed from office (see here). Of course, the Governor will then be able to appoint a new judge to replace the judge who vacated the office. So, in making your decisions to vote for or against a judge, you should really weigh whether you think the existing judge is better than a judge who might be selected to replace them.

Justice of the Supreme Court

Shall Justice Carlos G. Muñiz of the Supreme Court be retained in office?

Party: non-partisan (appointed by Ron DeSantis)
Background Information: Appointed in 2019 by Ron DeSantis. Originally from Virginia. Attended Catholic schools as a youth. Graduated from University of Virginia for his undergraduate degree and Yale Law School. Prior to his appointment by DeSantis in 2019 he worked as the general counsel for the US Department of Education under Betsy DeVos. Before that, he worked as deputy attorney general in the state of Florida under Pam Bondi. Also worked as general counsel for Jeb Bush. He is a member of the conservative Federalist Society. You can see an interview with him here.
Websites: FL Supreme Court website, Wikipedia,
Endorsements: 71% of the Florida Bar voted to retain him

District Court of Appeal

Shall Judge Drew Atkinson of the Second District Court of Appeal be retained in office?

Party: non-partisan (appointed by Rick Scott)
Background Information: Appointed in 2018 by Rick Scott. Native of Tampa. BA from Florida State and law degree from Nova Southeastern. Veteran of the US Army. Worked in the Attorney General’s office, General Counsel for the state, and for a private law firm.
Websites: FL Second District Court of Appeal
Endorsements: 76% of the Florida Bar voted to retain him

Shall Judge Morris Silberman of the Second District Court of Appeal be retained in office?

Party: non-partisan (appointed by Jeb Bush)
Background Information: Appointed in 2001. Undergraduate degree from Tulane. Law degree from the University of Florida in 1982. Clerked with the Second District Court of Appeal then went into private practice in Sarasota and Clearwater.
Websites: FL Second District Court of Appeal
Endorsements: 90% of the Florida Bar voted to retain him

Shall Judge Daniel H. Sleet of the Second District Court of Appeal be retained in office?

Party: non-partisan (appointed by Jeb Bush)
Background Information: Appointed in 2005. Undergraduate degree from Furman University. Played college football. Law degree from Cumberland School of Law in 1987. Worked as an assistant state attorney then joined a private law firm. Has adjuncted at Stetson University and University of Tampa (full disclosure – that is where I teach).
Websites: FL Second District Court of Appeal
Endorsements: 85% of the Florida Bar voted to retain him

Shall Judge Andrea Teves Smith of the Second District Court of Appeal be retained in office?

Party: non-partisan (appointed by Rick Scott)
Background Information: Appointed in 2019. From Bradenton Florida. Bachelor’s in Business Administration from the University of Florida and her law degree from Stetson University in 1991. Worked for a private law firm in Lakeland. Was also a judge on the Tenth Judicial Circuit Court before being appointed to the Second District Court of Appeal.
Websites: FL Second District Court of Appeal
Endorsements: 82% of the Florida Bar voted to retain her

County Court Judge Group 7

The Tampa Bay Times endorsed Bill Yanger.

Monique Scott

Party: nonpartisan race
Background: BA in Criminology and Psychology from USF; former Tampa police officer (left for health reasons) and public school teacher; worked as an assistant state attorney; accident attorney; volunteers with epilepsy groups; married to a chiropractor
Personal Commentary:
Finances (per
Judicial Candidate Forum responses
Websites: election website, Franchi Law firm

Bill Yanger

Party: nonpartisan race
Background: Admitted to Florida Bar in 1989; admitted to Texas bar in 1986; graduate of Jesuit High School; went to University of Florida for undergrad; South Texas College of Law for law degree; founder of Yanger Law Group; works on complex business litigation; former Chair of the Tampa Chamber of Commerce; Board of Fellows member at the University of Tampa (full disclosure, I am a professor at the University of Tampa); Presbyterian – goes to Palma Ceia Presbyterian Church
Endorsements: local firefighters unions, Tampa City Council members Guido Maniscalco, Charlie Miranda, and Luis Viera; Tampa Bay Times
Personal Commentary: He drives a truck, per his flyer he circulated (seems important to him).
Finances (per
Judicial Candidate Forum responses
Websites: election website, Facebook, Instagram

School Board Member District 1

In the primary election, no candidate received sufficient votes to win the election outright. The two candidates below are the top vote getters and are competing in this runoff election.

Nadia Combs

Party: nonpartisan race
Background: BA in Social Studies Education and MA in Educational Leadership from USF; taught in Japan; taught in Hillsborough County Schools for 10 years; founded a company in 2005 as part of the Supplemental Education Services – provides free tutoring to students in Hillsborough County; opened Brighton Learning tutoring center in 2014
Personal Commentary:
Finances (per
Websites: election website, Brighton Learning
Endorsements: Tampa Bay Times

Steve Cona

Party: nonpartisan race
Background: Tampa native; Bachelor’s from USF; CEO of Associated Builders and Contractors Florida Gulf Coast Chapter; on the Board of Trustees of Hillsborough Community College; platform is to improve Florida’s skilled labor force; incumbent
Personal Commentary: Platform is three-fold: fiscal accountability, school security, and addressing maintenance problems in schools. Raised almost 10 times as much money as all the other candidates combined. Pretty telling that the Tampa Bay Times didn’t endorse him as the incumbent.
Finances (per
Websites: election website,

School Board Member District 5

This race isn’t on my ballot but someone asked if I’d look up information on the race. “As you wish…”

Tammy Shamburger

Party: nonpartisan race
Background: Incumbent. Tampa native. Graduated from Bloomingdale Senior High School. Has a Liberal Arts degree from HCC, BA in Political Science from USF, and an MBA from St. Leo University. Worked in the insurance industry before being elected to the school board. Elected to the board for District 5 in 2016.
Personal Commentary: No personal experience as an educator.
Finances (per
Websites: campaign website, Facebook, Twitter

Henry “Shake” Washington

Party: nonpartisan race
Background: Graduated from Middleton Senior High School. Played sports in high school. Served in the military for 22 years. Received his BA from the University of Southwest Louisiana. Worked his way through the Hillsborough County Public Schools. Started as an assistant teacher, taught physical education and driver’s ed. Was also a coach. Eventually became a principal and then an area superintendent. He is now retired. Member of Allen Temple African Methodist Episcopal Church.
Personal Commentary: Clearly has a lot of experience in Hillsborough County Public Schools.
Finances (per
Websites: campaign website, Facebook, Twitter
Endorsements: Tampa Bay Times

School Board Member District 7

In the primary election, no candidate received sufficient votes to win the election outright. The two candidates below are the top vote getters and are competing in this runoff election.

Lynn Gray

Party: nonpartisan race
Background: worked for over 20 years as a teacher in Tampa; incumbent on the school board; platform – healthier kids (healthier foods and recess); more support for students; improved literacy
Personal Commentary:
Finances (per
Websites: election website, Facebook, Twitter, Instagram
Endorsements: Tampa Bay Times

Sally A. Harris

Party: nonpartisan race
Background: South Tampa native; owner of Circle C Ranch Academy – early care and education company; focus is on safety, discipline, and management
Personal Commentary: She seems to care more about policing the kids than educating them.
Finances (per
Websites: election website

Soil and Water Conservation District Group 2

Erik S. Challenger

Party: non-partisan race (but he’s a Democrat)
Background Information: Lives in Apollo Beach. Has raised no money. Not sure how serious a candidate he is. I couldn’t find any useful information about him.
Finances (per
Websites: Facebook

Michael Harvey

Party: non-partisan race (but he’s a Democrat)
Background Information: Born into a military family. Graduated from something (per his website). Photo suggests he likes to fly. Married with five kids and a dog. Indicates he is a successful businessman on his website. He details his platform in this youtube video.
Finances (per
Websites: campaign website,

Karen Cox Jaroch

Party: non-partisan race (but she’s a Republican)
Background Information: Went to Plant High School. Studied engineering at USF. Worked for Northrup Grumman (1991-2002). Works for Heritage Action for America. Per her Facebook page, “God, Family, Country, Conservative & Blessed!”
Finances (per
Websites: campaign website, Facebook, LinkedIn

Douglas “Doug” Rivero

Party: non-partisan race (but he’s a Democrat)
Background Information: College professor. Immigrant from Cuba during the Mariel boatlift. Graduated from Florida International University with a BA in Environmental Science. Worked for AmeriCorps in Florida State Parks. His MA and PhD were in Political Science. Works at Saint Petersburg College. He gardens and is a birder. Can see an interview with him on Facebook. (Seems qualified to me.)
Finances (per
Websites: campaign website, Twitter, Facebook

Soil and Water Conservation District Group 4

Sonja P. Brookins

Party: non-partisan race (but she’s a Democrat)
Background Information: Tampa native. Graduate of Chamberlain HighSchool. Graduated from Texas Chiropractic College. Has a certificate in Nursing from Austin Peay State University and a Master of Education in Counseling from Prairie View A&M. Worked as an Executive Director for Emergency Shelters for domestic violence victims. Also taught school.
Finances (per
Websites: campaign website, Facebook

D.B. “Brig” Maynard

Party: non-partisan race
Background Information: From West Virginia. Studied at USF. Formerly held a seat on the Soil and Water Conservation Board. No campaign website. His name is David Maynard but he goes by “Brig.”
Finances (per
Websites: Facebook,

Mark Proctor

Party: non-partisan race (but he’s Republican)
Background Information: He’s the current chairman of the Soil & Water Conservation District. He is in real estate as an investor, agent, and broker. Posted on his twitter page that he voted for Trump on September 23rd. The website linked to from his Twitter profile redirects to a Chinese gambling website. Either he’s been hacked or he makes his money off Chinese gambling websites.
Finances (per
Websites: Twitter, LinkedIn

Constitutional Amendments

The Tampa Bay Times has an article explaining all of the constitutional amendments on the 2020 ballot.

No. 1 Constitutional Amendment

Citizenship Requirement to Vote in Florida Elections

This amendment provides that only United States Citizens who are at least eighteen years of age, a permanent resident of Florida, and registered to vote, as provided by law, shall be qualified to vote in a Florida election.

Because the proposed amendment is not expected to result in any changes to the voter registration process in Florida, it will have no impact on state or local government costs or revenue. Further, it will have no effect on the state’s economy.

My Translation: This is a very minor change to the Florida constitution that already says that “every citizen” can vote. So, the change would be from “every citizen” to “only a citizen.” This is basically an anti-immigrant amendment that is trying to circumvent a problem that doesn’t exist in Florida of some cities/counties allowing non-citizen immigrants/residents to vote in elections. This seems completely superfluous given that it doesn’t actually change anything but rather is a symbolic change to indicate that Florida is anti-immigrant. It’s also a voter intimidation amendment trying to reduce voter turnout.
Background Information: John Loudon, Republican, is the chairman of the sponsoring organization.
Websites: amendment website
Tampa Bay Times opposes this amendment.

No. 2 Constitutional Amendment

Raising Florida’s Minimum Wage

Raises minimum wage to $10.00 per hour effective September 30th, 2021. Each September 30th thereafter, minimum wage shall increase by $1.00 per hour until the minimum wage reaches $15.00 per hour on September 30th, 2026. From that point forward, future minimum wage increases shall revert to being adjusted annually for inflation starting September 30th, 2027.

State and local government costs will increase to comply with the new minimum wage levels. Additional annual wage costs will be approximately $16 million in 2022, increasing to about $540 million in 2027 and thereafter. Government actions to mitigate these costs are unlikely to produce material savings. Other government costs and revenue impacts, both positive and negative, are not quantifiable.

This proposed constitutional amendment is estimated to have a net negative impact on the state budget. This impact may result in higher taxes or a loss of government services in order to maintain a balanced state budget as required by the constitution.

My Translation: This amendment would increase Florida’s minimum wage over time. I am fascinated by the estimates that are included with this amendment. They seem like a straightforward effort to try to dissuade voters from approving this.
Background Information: Florida’s minimum wage does increase slightly with inflation at present. However, as of 01/01/2020, minimum wage in Florida is $8.56. John Morgan of Morgan & Morgan is the chairman of the sponsoring organization.
Websites: sponsor’s website
Tampa Bay Times opposes this amendment.

No. 3 Constitutional Amendment

All Voters Vote in Primary Elections for State Legislature, Governor, and Cabinet

Allows all registered voters to vote in primaries for state legislature, governor, and cabinet regardless of political party affiliation. All candidates for an office, including party nominated candidates, appear on the same primary ballot. Two highest vote getters advance to general election. If only two candidates qualify, no primary is held and winner is determined in general election. Candidate’s party affiliation may appear on ballot as provided by law. Effective January 1, 2024.

It is probably that the proposed amendment will result in additional local government costs to conduct elections in Florida. The Financial Impact Estimating Conference projects that the combined costs across counties will range from $5.2 million to $5.8 million for each of the first three election cycles occurring in even-numbered years after the amendment’s effective date, with the costs for each of the intervening years dropping to less than $450,000. With respect to state costs for oversight, the additional costs for administering elections are expected to be minimal. Further, there are no revenues linked to voting in Florida. Since there is no impact on state costs or revenues, there will be no impact on the state’s budget. While the proposed amendment will result in an increase in local expenditures, this change is expected to be below the threshold that would produce a statewide economic impact.

My Translation: This amendment would open up certain primary races in Florida so anyone can vote for any candidate. In other words, an independent voter could vote for Democratic or Republican candidates in the primaries. Likewise, a voter registered as a Democratic could vote for Republican candidates and vice versa. In principle, this seems like a good idea. The one possible drawback is that it is also coupled with a change that the top two vote-getters in a primary would then run in the general election. So, if two Republicans got the most votes in the primary, they would run against each other in the general election. In hyper-partisan districts, this could guarantee single-party dominance. Of course, it could also end up splitting the vote in one party, allowing the candidate in another party to win.
Background Information: Currently, in Florida, voters can only vote for candidates from their party in primaries.
Websites: amendment website
Tampa Bay Times opposes this amendment.

No. 4 Constitutional Amendment

Voter Approval of Constitutional Amendments

Requires all proposed amendments or revisions to the state constitution to be approved by the voters in two elections, instead of one, in order to take effect. The proposal applies the current thresholds for passage to each of the two elections.

It is probably that the proposed amendment will result in additional state and local government costs to conduct elections in Florida. Overall, these costs will vary from election cycle to election cycle depending on the unique circumstances of each ballot and cannot be estimated at this time. The key factors determining cost include the number of amendments appearing for the second time on each ballot and the length of those amendments. Since the maximum state cost is likely less than $1 million per cycle but the impact cannot be discretely quantified, the change to the state’s budget is unknown. Similarly, the economic impact cannot be modelled, although the spending increase is expected to be below the threshold that would produce a statewide economic impact. Because there are no revenues linked to voting in Florida, there will be no impact on government taxes or fees.

The financial impact of this amendment cannot be determined due to ambiguities and uncertainties surrounding the amendment’s impact.

My Translation: Per this article in the Tampa Bay Times, it’s not clear who funded this amendment, but it appears to be right-leaning corporations that are frustrated with the ability of Floridians to occasionally govern themselves. Powerful entities from political parties to corporations in Florida are frustrated when the citizens actually enact legislation that a super-majority wants. This is another attempt by shadowy figures to attempt to reduce the ability of the people to govern themselves by making it harder to pass a constitutional amendment. I’ll go ahead and make my position on this clear – vote NO on Amendment 4.
Background Information: Currently, in order for an amendment to be added to the Florida constitution it requires just one election and a supermajority of voters to approve it of 60%.
Websites: sponsor’s website
The Tampa Bay Times opposes this amendment.

No. 5 Constitutional Amendment

Limitations on Homestead Property Tax Assessments; increased portability period to transfer accrued benefit

Proposing an amendment to the State Constitution, effective January 1, 2021, to increase, from 2 years to 3 years, the period of time during which accrued Save-Our-Homes benefits may be transferred from a prior homestead to a new homestead.

My Translation: This is somewhat technical but basically gives people who sell their home that has the homestead exemption in Florida an extra year to buy another home so they can save some money through the homestead exemption.
Background Information: See the Tampa Bay Times’s analysis of this amendment. And you can learn about homestead exemptions here and here.
Websites: This actually got added to the ballot via a joint resolution of the Legislature where it passed with very little opposition.
Tampa Bay Times supports this amendment.

No. 6 Constitutional Amendment

Ad Valorem Tax Discount for Spouses of Certain Deceased Veterans Who Had Permanent, Combat-Related Disabilities

Provides that the homestead property tax discount for certain veterans with permanent combat-related disabilities carries over to such veteran’s surviving spouse who holds legal or beneficial title to, and who permanently resides on, the homestead property, until he or she remarries or sells or otherwise disposes of the property. The discount may be transferred to a new homestead property of the surviving spouse under certain conditions. The amendment takes effect January 1, 2021.

My Translation: This amendment would extend a tax exemption from veterans over 65 to their spouses when the veteran dies.
Background Information: There are a number of special exemptions to taxes that get carved out for different groups in Florida.
Websites: This also got added to the ballot via the Florida Legislature where it passed with no opposition.
Tampa Bay Times supports this amendment.

 25,581 total views

How to Export Garmin Tracks/Activities to Google Maps

While it’s possible to share your Garmin tracks or activities with people through the Garmin website, I like exporting my tracks to Google Maps so I can embed them on my website. Here’s how I do that.

First, log in to your Garmin Connect account. Once you have logged in, click on the Activities tab.

You’ll see a list of your activities. Look for and find the activity you want to share.

Click on the activity you want and you’ll see all the details for the activity. To export the GPS track of your activity, look for the gear icon on the upper right of the screen:

Click on the gear icon and you’ll see several options. The one you want is “Export to GPX.”

You should then get a prompt to download a GPX file. Download it to your computer (and, of course, remember where you downloaded it to). If you’re curious, you can open the GPX file with a text editor and see that it is basically just a list of points using a markup language.

Now, log in to your Google account. The next part is always the part that takes me the longest when doing this – figuring out the URL where I can upload the GPX file to create a map. Google doesn’t make this easy (and, admittedly, it has changed over time). The link to upload and create maps using Google Maps is this one: Assuming you are signed in and everything works, you should see a page called “My Maps” that looks like this:

I’ve made a fair number of maps!

Click on “+CREATE A NEW MAP”, the big red button. On the next screen, you’ll see a checkbox next to “Untitled Layer” and below that a link that says “Import.”

Click on the “Import” link and you’ll get this window:

You can either click on the blue button and select your GPX file or just drag it to the window. Either way, as soon as it has been uploaded, the site will process it and overlay your track onto a map, like this:

(BONUS: Since I have created quite a few of these for my hikes, I actually try to keep them organized in my Google Drive. If you’re going to create a lot of these, you should do the same.)

Now you have lots of options to customize your map. You should obviously click on where it says “Untitled map” and give it a name. You can also add layers, add points of interest, insert pins, etc. You can also change the Base map to terrain or satellite instead of the default map. I added three pins, a title, and a description to my map:

When you’re done modifying your map, you should do two things to share it. First, change the permissions by clicking on the “Share” icon.

By default, maps are restricted and you can only provide access to specific people. You can change that by clicking at the bottom of that window where it says “Change to anyone with the link.”

Now you can embed the map into a different website or just share the link with people. To embed the map, click the three little vertical dots near the title and select “Embed on my site”:

You’ll then get a window with the embed code:

The code should look something like this:

<iframe src="" width="640" height="480"></iframe>

And here’s how it looks actually embedded on your site:

 5,331 total views,  2 views today