mech-dump (part of Perl WWW::Mechanize) is incredibly stupid about it's input file name

If the file name it is dumping does not end in:

.html

the mech-dump will spit out an error that the file content is not text/html it is text/plain. And of course, it immediately quits without doing anything helpful.

And then you go and look inside the file, and this is right at the top:

content="text/html"

You ask yourself What the Hell?

It’s a terrible error message; that’s the hell of it. The error message should say “Input file name does not terminate with the string .html”

I use Linux a lot, and in Linux, files do not have to have file extensions in their names. Over in the Windows side, it is expected that a file name has an extension. Windows uses that file name extension to figure out which program should be associated to the file type. But in Linux, the program association data is written inside the file itself.

This has two effects. First, files in Linux don’t need file extensions in their name. Second, you can name a file in Linux to not have the file extension, and the file works anyway.

So, if I’m writing a Perl script on Linux and I want to dump out something I’ve just pulled down from a web server, using WWW::Mechanize, I might be inclined to name the file where I’m dumping this web form to www_mechanize_web_form_dump

And this would be a mistake, because when I later run

mech-dump www_mechanize_web_form_dump

I’m going to get spit at with the message that the file does not contain HTML, it contains only plain text.

It would have saved me a bunch of time, if the error message would have been “mech-dump does not interpret files with names that do not end in .html”

That might seem kind of a silly input file name constraint, but at least the error message wouldn’t be misleading.

Bitnami WordPress Multisite – DNS spoofing

In an earlier post, I said I hope you have pointed your domain name at your static IP address. Well, what if you don’t want to?

The point being that the DNS entry for the domain name currently points to the production WordPress site, and really, I would like to set up this multisite WordPress installation without having to change the public DNS entry.

Also, setting up this, my personal blog, I was using No-IP DNS services. I could update the DNS entry for gerisch.org, and the DNS replicated out almost instantly. It was great. But the other web site I’m working on (the one that got me into WordPress at all), is using Network Solutions for their DNS. They take their good sweet time replicating DNS entries out to the world. I don’t really want to post an update to DNS, wait, dink around with the new site while the production site is down, decide to revert to production, post an update to DNS, wait again while Network Solutions gets around to pointing everyone back to the production web site.

It would just be better if the new web server machine never got away from it’s own self when doing lookups for the domain name it will eventually be.

So I can start the WordPress install from the IP address of the server out on the public Internet. However, WordPress during it’s install, is going to do a DNS lookup, and try to invoke code on the server where the DNS really does resolve. Which isn’t where I am. So I’m going to try to install a fake DNS server on the new server, and have it redirect all calls to the old domain to the new server.

Step the first: install dnsmasq

sudo apt-get install dnsmasq

Next, set up listening on the local host address:

sudo vim /etc/dnsmasq.conf

Find your way to the line #listen-address= and edit it thus:

listen-address=www.gerisch.org

And save and exit

sudo vim /etc/dhcp/dhclient.conf

Find your way to #prepend domain-name-servers www.gerisch.org; and uncomment this line. Save and exit.

And now it gets weird.

The Bitnami / AWS Lightsail images use something called cloud-init : https://cloudinit.readthedocs.io/en/latest/topics/modules.html

So if you were going to try to edit /etc/hosts or /etc/resolv.conf you get warned to not edit them by hand, because they will be replaced on next boot. But they sure as heck don’t tell you where to implement edits. Just don’t do it here.

Turns out there are template files in /etc/cloud/templates that hold the magic.

cd /etc/cloud/templates
sudo cp hosts.debian.tmpl hosts.debian.tmpl.original
sudo vim hosts.debian.tmpl

Now I’m going add a line below www.gerisch.org localhost which will be the IP address I want this machine to go to whenever it tries to resolve the domain name of the production web site

And indeed, if I use dig from an ssh session in the machine, dig reports back the local machine’s address, not the one out on the public Internet

Apple Watch is kind of stupid – it cannot connect to Ford Sync

I had a need to leave my iPhone behind, but I wanted to listen to an audiobook while I drove somewhere. I downloaded the book to the Apple Watch, and then went to the car to run my errand. But the Apple Watch would fail to pair to Ford Sync.

Ford Sync was introduced to the world in 2007. The Apple Watch was introduced to the world in 2015. Apple, a company with plenty of money to do research and development, should have gotten this right.

It’s not like Ford is some small niche car company.

The Apple Watch and Ford Sync would talk with each other and show me the PIN, and ask me to verify that the PIN showed up. It did. And then the pairing would fail. This is stupid. Apple has enough market share to do quality control, and be good at this sort of thing.

But apparently at Apple, Quality is Job 3.

Amazon Transcribe – mildly amusing transcription attempt

I’m using Amazon Transcribe, to do that, with MP3 files of a talk given by couple guys with thick southern accents (Arkansas / Louisiana). Machine translation is still pretty new. Even with superb AI, this audio would be tough. Still, the following was mildly amusing to me.

What the transcription came up with: “the moment after rescue from the shipwreck, when camaraderie, Georgian markets evade a vessel for misters to the captain’s table.”

What the actual audio is: “the moment after rescue from the shipwreck, when camaraderie, joyousness and democracy pervade the vessel from steerage to the captain’s table.”

Admittedly, evade versus pervade is very close; pervade isn’t exactly a common word. The difference between misters and steerage is pretty far. But what tickled my funny bone was that apparently, joyousness and democracy are what you get going to Georgian markets.

As one popular meme goes right now: Why not both?

WordPress super admin – three tables to update

I recently did a migration from a single site to a multisite here in WordPress. It was painful. But I did learn how to change the super admin login name.

The three tables are: wp_users, wp_usermeta, and wp_sitemeta

Upon creation of a brand-spanking-new WordPress multisite, wp_users has but one record in it. ID = 1, which is the super admin user. I changed the user_login field (and other fields) to the login name I wanted. WordPress “knew” that this did not qualify me to be a network admin, so it would present me with only the one site.

A little bit of searching told me that I needed to make sure that in table wp_usermeta, the field wp_capabilities was correct. Well, it was. But there were other parts of my login name that I wanted to update here. So I suppose that technically, only two fields must be updated, to swap out the super admin login name.

The last piece, that was not easy to find, was that the table wp_sitemeta has a field: site_admins which needs to have a PHP array entry in it. There was an entry in it already, but, it listed the default login ID, not the one I wanted to log in as. Because it’s an array, there is an index number, and a string length, that precede the actual data in quotes.

Once both wp_sitemeta:site_admins and wp_users:user_login both linked up, then I could log in with my preferred login ID and be super admin.

Bitnami WordPress multisite installation

Make an ssh connection in to your Bitnami server installation. I’m using AWS, and they had instructions for me to get the password / ssh private key. ssh bitnami@your-ip-address-here

cat bitnami_application_password

While logged in to the ssh session, execute the Bitnami configuration script that assigns a domain name to your WordPress multisite server.

cd /opt/bitnami/apps/wordpress

sudo ./bnconfig --machine_hostname your-domain-name-here.tld

sudo mv bnconfig bnconfig.disabled

First, we changed to the directory with the bnconfig script. Then we ran it, with the machine_hostname option. (I wanted to put a dash in there, between machine and hostname, but it’s an underscore). Lastly, we moved the bnconfig script out of the way. This is because if the server rebooted, and bnconfig did run, it would be as if it ran bnconfig –machine_hostname your-ip-address-here.xip.io

xip.io is a Bitnami thing, I guess.

Hopefully, you already have the domain name, and have pointed it at the static IP address of your server.

On to configuring WordPress the familiar way: point your favorite browser at the ip address and go to https://your-domain-name-here/wp-admin

This redirected me, but really it was the same as going to https://your-ip-address-here.xip.io/wp-login.php

Log in as user with the password from bitnami_application_password

Upon logging in, the administration page looks almost the same as a regular WordPress installation. However, in the upper left corner, there is now a menu named “My Sites”. Hanging off of it is “Network Admin”

Hanging off of “Network Admin” are a whole bunch more sub-menu items, but I’m going to ignore those for the moment.

Clicking on “Network Admin” actually takes me to the first sub-menu item: “Dashboard”

And here, I had made my life more complicated. I’m actually trying to move this site, gerisch.org to the multisite, under the same domain name. Tell me “good luck with that.” Part of the multisite login process is to redirect to the domain name – which is the production server on some other IP address.

I’m going to have to go into DNS, and point the gerisch.org at the multisite IP address, before I can successfully log in (and remain logged in) to the multisite server still being set up.

Of course, I’m going to have to export this (the production site) to a file, for importing later, prior to taking it’s presence off teh interwebs.

And I don’t know if there is going to be any weird http://www.gerisch.org versus http://gerisch.org versus https://

Yeah, “stuff” in the databases that will need to be cleaned out during export, for import later.

Follow up to xdotool doesn't work nicely

My previous post was that Windows “just works”, and Linux was “good luck with that”. Indeed, I had a deadline, and to get the job done, I used Windows and WinBatch, just got it done. On time. On a laptop. In my car. Yay.

But really, my nice setup is here at home, instead of on the laptop in my car. And my preferred setup is this OpenSuSE box here at home. So, now that the time pressure is lessened, I can spend a little more time, trying to figure it out. The secret is to not use the one-liner feature of xdotool. If you do the one-liner format of xdotool, it composes the command to throw at the window with “XSendEvent”

If you do multiple xdotool commands in order, it composes the commands to throw at the window with “XTEST”

More accurately, if the xdotool command has –window in the line, then XSendEvent is used. If xdotool command has only the “key” command in it, XTEST is used.

Apparently, most programs ignore window commands send with XSendEvent, so xdotool does it’s tool do to X, and the window ignores it.

Yay.

Here is one of the scripts that finally worked. Note I did have to add a time delay in, because otherwise the audio player window wasn’t ready in time for the following key stroke to be input.

!/bin/bash
 WIDLibre=$(/usr/bin/xdotool search --name "LibreOffice Writer")
 WIDAudio=$(/usr/bin/xdotool search --name "Insert Name Of Window of audio player here")
 /usr/bin/xdotool windowactivate $WIDAudio
 /usr/bin/sleep 0.5
 /usr/bin/xdotool key Control_L+comma
 /usr/bin/xdotool windowactivate $WIDLibre

This script sends a comma (with the Control key modifier) to the audio player. In WinBatch, this would be SendKey("^,")

Ctrl+, is the pause / unpause keystroke for the audio player. The other script, uses the left arrow key to rewind the audio. One script each is attached to a couple KDE shortcuts. Each of those keytroke combinations is programmed into a Kinesis Savant Elite2 foot pedal. So the left pedal backtracks the audio a few seconds, and the right pedal pauses / unpauses the audio. Window focus remains in LibreOffice.

To figure out what to use for “Insert Name Of Window of audio player here“, use the command wmctrl -l

One thing to note: the full name of the window (because of the audio player I used) had the length of the audio in it. That time had special characters in it (colons to separate minutes from seconds); so either I would have had to escape them out, or, I just put the first part of the window name in, up to the time / length.

The whole secret to the thing was that this did not work:

/usr/bin/xdotool --window $WIDAudio key Control_L+comma

and this did work:

/usr/bin/xdotool windowactivate $WIDAudio
/usr/bin/xdotool key Control_L+comma

Windows "just works" versus Linux "good luck with that"

I’m trying to do some audio transcription, so that I have text to go along with the audio. Transcription is still quite the labor intensive problem, even here a few months away from 2020. Sure, I can get Amazon to do a basic transcription for very little cost (pennies more than dollars); but, the transcription isn’t very good. Part of the problem is that one of the speakers has a thick Southern accent.

Fine, whatever – I’ll just fix it.

Years ago, I was a “programmer” for an NC Drill. “NC” is the acronym for Numerical Control. So this drill just put holes in circuit board material at numerical X Y coordinates. My job was to digitize the artwork (or at least, line up the crosshairs on digitizer with the pads on the artwork, and then tap a foot pedal. As I spun the dials, the X and Y positions would be counted, and when I hit the foot pedal, the current position was recorded. (Actually, it was punched onto a paper tape).

So I learned that foot pedals are a nice way of interfacing with the computer. Especially with your shoes off. 😉

For this transcription work, I need to be editing a document (with my hands), but I’d like to pause and rewind the audio with foot pedals. I bought a somewhat expensive foot pedal from a company in the Pacific Northwest (Made in USA). It works well.

But what to have it do?

At first, I programmed it to do direct keystrokes: Alt-Tab to switch to the last window, Space to pause, Alt-Tab to switch back.

But this has the drawback that the last two windows I’ve used must be the one’s I need, and it’s terribly inflexible. How about picking an un-used set of keys as shortcuts / hotkeys, and attaching scripts? This way, the script can pick the name of the window from the open list, and go right there no matter if it’s been pushed to the back by something else.

Windows, with WinBatch, it just works.

Linux, with xdotools is a nightmare. Someone said xvkbd is the right way to go, to get around the fact that xdotools doesn’t work. Tried the combo, and now one run of one of the scripts kills off the other script from being able to work. I’ve got both, because xdotools does know now to do a “WinActivate” (to use WinBatch terminology), and it doesn’t appear that xvkbd doesn’t do window management. And it wasn’t written for that, either. But xdotools doesn’t know how to send the Space character to the media player, so I’ve got to mash these two together.

The xdotools people say it’s not their fault; most applications block input. Although somehow the xvkbd people are managing it.

I’ve used xdotools at work, and it does great with mouse clicks; so there’s that. But VLC and other Linux media players (many based on VLC) refuse to use a mouse click as “pause” for the video (where YouTube and Facebook don’t have a chip on their shoulder, and just do what is natural for people).

Anyway, I had a deadline to meet, and Windows actually got the job done.

Super WordPress Day – Meetup Fresno – 2019-09-24

Phil Derksen: Plugins you should install on every WordPress site

Akismet Anti-Spam

Backups:

  • BackWPup
  • UpdraftPlus
  • VaultPress (JetPack)
  • BackupBuddy
  • BlogVault

SEO

  • Yoast SEO
  • All in One SEO Pack
  • The SEO Framework
  • Broken Link Checker (resource intensive; run manually after changes)

Forms

  • Gravity Forms (long history of the product)
  • Ninja Forms
  • WPForms
  • Formidable
  • Contact Form 7 (very popular and free, but older and takes more work / detailed to implement)

Email – don’t skip this step

  • WP Mail SMTP
  • Easy WP SMTP
  • Service-specific (Postmark, Mandrill, Sendgrid)

Site Migration

  • WP Migrate DB
  • Duplicator
  • (most backup plugins)

What do Phil’s co-workers say?

  • User Switching – see what logged in users see.
  • Regenerate Thumbnails – change your theme or thumbnail size? This does the work.
  • Public Post Preview
  • Duplicate Post
  • Plugin Toggle
  • Editorial Calendar – Calendar view of past and future posts 😉

Community says

  • Simple Links – will randomize a list of links
  • WP Simple Pay – uses Stripe and other payment processors
  • Woo Commerce – manage inventory for physical sales, among other things
  • Event Espresso – booking
  • Sugar Calendar – booking

Generate WP for plugin development – generatewp.com

Matt Reeves: WordPress Customizer

The customizer does do instant WYSIWYG – which is better than before.

While inside the customizer, you can change the device type: full PC web site, tablet, and smartphone.

Kirki Theme Customizer; but can be temperamental re: the themes it works with.

Elementor is a theme builder that Matt has started using, that he actually admires the power in it.