Saturday, June 16, 2018

Fix your iTunes names (and numbers!)

I made a thing!

When Amazon announced they were retiring their Music Storage Subscriptions, I decided to download all of my music.
This was troublesome in a number of ways. The metadata was pretty well screwed up, so there would be songs without an artist name or album name. So I ended up downloading just one album at a time, so I would know which album was which. Yeah, total PITA.
But once that was done, I found I had a number of songs with names like 'dd-tt- Title of the Song' where dd is the disc number and tt is the track number. And thankfully so, since some of these tracks didn't have the disc or track number in the metadata.
So what I've done is made this little AppleScript (called Fix_iTunes_names.scpt) that will go through all of the songs and rename them from 'dd-tt- Title of the Song' to just 'Title of the Song' - but ONLY IF dd matches the disc number and tt matches the track number. So totally safe!
And then I added another Applescript (called Fix_itunes_names_and_numbers.scpt) for more adventurous folks that will also rename songs from 'dd-tt- Title of the Song' to just 'Title of the Song' and ALSO set the disc number and tarck number to dd and tt - but ONLY IF either number was blank to start with.
You don't have to buy me a beer or anything, but if you want to, feel free - and thanks!

Sunday, February 11, 2018

Use curl to test nginx rewrite rules

Be very careful using nginx rewrite. Consider this answer on SO:

The answer author wrote this correct rewrite rule:
location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
Which was later edited erroneously:
location  /foo {
  rewrite /foo(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
That very subtle change causes nginx to redirect, which is undesirable.

This can easily go unnoticed without curl testing:
$ curl -i http://localhost:8080/foo/bar
HTTP/1.1 301 Moved Permanently
Server: nginx/1.13.8
Date: Sun, 11 Feb 2018 14:18:12 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 40
Connection: keep-alive
Location: /bar

<a href="/bar">Moved Permanently</a>.
I've edited the answer back to the original.

Here's a great article about setting up nginx for serving Go apps.

NOTE: you'll need the GVM readme for an up-to-date command to install GVM.

Friday, December 15, 2017

ISP's and Markets

​The idea that an ISP can collect money from a content provider because a consumer requested content is like saying Safeway should be able to charge Kellog's for the Pop-Tarts I want to eat.

Just wait until Disney starts telling Time Warner to pony up for all the Toy Story they've been carrying. The real problem is that consumers have little or no choice of ISP. Each ISP has a practical monopoly in the markets where they operate.

In order for a free market to be a solution to some problem, there has to be a choice. I may choose from a variety of content providers, but I don't get to choose my cable company.

If a consumer doesn't like the way their ISP is regulating content, they should be able to choose a different ISP. But they can't. Maybe it's time we start regulating ISP's like the monopolies they really are.

Sunday, July 09, 2017

When resources unavail

Every so often my Linux system starts feeling poorly. Firefox will hang and won't let me close its window. So I ALT-TAB over to my terminal window to kill it.

$ ps -fewww | grep -v grep | grep firefox
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: Resource temporarily unavailable

When this first happened, I figured I would reboot and that, of course, would fix it. But I couldn't even run shutdown! That's when I thought of this extremely inelegant but useful solution:

$ cd /proc
$ kill *

And that freed up enough of whatever that I could get on with the reboot and then with my life.

When it happened today, I googled around and saw saw solutions suggesting...
  • su root and (WRONG: can't su)
  • ps blah blah and (WRONG: can't ps)
  • ulimit (hmmm... OK I'll try that.)
This particular solution suggests setting NPROC (max user processes) using ulimit -u like so:

$ ulimit -a

max user processes              (-u) 2047

$ ulimit -u 2100

Upping that value allowed me to kill and restart Firefox without rebooting!!

Thanks, IBM!!

Friday, March 24, 2017

Mac + Virtualbox/Linux ALT=CMD

By default it seems that when you run Linux in Virtualbox on a Mac, ALT will be mapped to the OPTION key and SUPER will be mapped to CMD.

It's much more natural to swap these, i.e. to map ALT to CMD.

And here's how you do it:

Create ~/.Xmodmap containing...

clear mod1
clear mod4

keycode 133 = Alt_L NoSymbol Alt_L
keycode 64 = Super_L NoSymbol Super_L

add mod1 = Alt_L
add mod4 = Super_L

And then

$ xmodmap ~/.Xmodmap


Monday, January 23, 2017

VNC + Mac OS + Option Key = WINNING!!

I love my Macs, but sometimes through no real fault of their own, they can be a bit of a pain in the butt.

Take the Option Key. Very helpful if you're using the Finder.

Ever try using the Option Key when you're connected remotely to your Mac Desktop using VNC? It just doesn't work. VNC settings, nothing.

But I have discovered a solution. Simply turn on Sticky Keys and use the Keyboard Viewer. Now you can use your mouse to press the Option Key - not ideal, but in a pinch, it's better than nothing!

Here are the step-by-step instructions for setting this up:

1. Open up the Preferences

2. Choose Accessibility

3. Turn on Sticky Keys

4. Go back to Preferences and choose Keyboard

5. Turn on "Shoe keyboard and emoji viewers in menu bar"

6. Open up the Keyboard Viewer

7. Now whenever you need to hold down the Option Key, tap it in the Keyboard Viewer

8. If you didn't have Sticky Keys turned on, you'd have to keep it held down in the viewer, but you can just tap it the once. Tapping it again puts it into some other state. Tapping it a third time turns it off. So whenever I want Option, I double click it in the viewer. Then I do whatever it was that needed the Option Key in the first place. And then I tap it again to turn it off.

I hope you find this helpful!

Saturday, December 24, 2016

#selector vs Selector

TLDR: In Swift 3, use #selector instead of Selector (see here).

The warning (No method declared with Objective-C selector 'swipedLeft:') should be your first clue that there's a problem...

If you use this code in Swift 3, the left-swipe will result in an error like this:

2016-12-24 08:15:12.645 SpriteSimpleGame[65853:2987246] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SpriteSimpleGame.GameScene swipedLeft:]: unrecognized selector sent to instance 0x7fb99e4101f0'

Worst of all, examples like this are all over the place because leaving out the colon results in a similar error.

Thanks to this answer I learned that what you want instead is this:

let swipeLeft = UISwipeGestureRecognizer(
    target: self,
    action: #selector(swipedLeft(sender:))

Thanks, internets!!