xrayspx's blog

xrayspx's picture

Nixie Clock

Music: 

Bloodshot Bill - Mary Ann

Natalie got me a cool nixie clock project for Christmas. We've split duties putting it all together and we just finally got it all worked out and on the shelf.

Overall the project was pretty easy, though you can see there's one pretty badly folded in place resistor that wasn't in the directions so we had to cram it in last minute. And we had a couple of issues with certain numbers on certain tubes, but it looks great in the end.

xrayspx's picture

Haiku OS

Music: 

Dr. Octagon - Blue Flowers

I've been playing recently with different unix OS's, trying to resurrect some old hardware and see if I can't make some of these old machines useful again. Like at least have one as an XScreensaver-only machine to keep Natalie amused.

xrayspx's picture

2021 is Dumb

Music: 

  • February: Given until Sept 1 to vacate Atlanta datacenter and move to new facility. At the time, I thought that was crazy aggressive and unlikely. That was cute
  • February: Painful breathing led to shallow breathing led to collapsed lung. This turns out to be a chronic problem with the cartilage in my chest, chostochondritis.
  • March: Given 6 weeks to vacate our corporate offices. The only way this was achieved was to move all our datacenter items to our ISP's hosting facility over a weekend.
xrayspx's picture

Lattice of Convenience - MP3 Playlists

Music: 

Underworld - Kittens

Hopefully everyone can live in the future someday.

We do a lot with MP3 playlists. I run Airsonic for streaming around the house and in the car, and we have a playlist-based FM transmitter setup, etc. So I have scripts which run every night and generate playlists based on star ratings and other things (GET THE LED OUT ANYONE?).

Previously what I've done is dump the contents of a bunch of Smart Playlists in Clementine to a file and use those files to generate the randomized 200 track daily playlists. The downside to that is that every time I add music or change star ratings, I'd have to refresh these "base" files like some kind of animal. I had base playlists for "3+ stars", "4+ Stars" and "5 Stars", among others.

Today I decided to fix all that. Clementine uses a SQLite3 database, so now I'm just querying it instead, and it seems to be working well. For example, my "5 star" playlist in Clementine results in 10800 or so tracks. The same one built from the DB ends up with a couple hundred more tracks, but is pretty close. I'm not entirely sure what the difference there is just yet, but "close enough". What it looks like to me is I probably need to enable Samba case sensitivity.

The DB records ratings as decimal numbers from 0.0 (Zero stars) through 1.0 (5 Stars). So to build a "4-Star +" playlist, searching for rating >= "0.8", you get ratings like this:

1
1.10000002384186
0.800000011920929
0.800000011920929
0.800000011920929
1.10000002384186
1.10000002384186
0.800000011920929
0.800000011920929
1
1
1
1

! Caveat: Prior to Clementine 1.4.0rc1-533-gf4e70face there was a bug where it was possible to give a song a higher than 5 star rating (higher than 1.0 in the DB) as you can see above, so know that if you have Clementine from the repositories, it's likely you have that bug. For instance in the UI, if you want to show all 5 star songs, use "Rating is Greater Than 4.5 Stars" rather than "Rating is Equal to 5 Stars".

Now I can just have a cron job to copy the master Clementine DB once a day to my server and drop it in next to the playlist generation scripts.

The downside to all this is speed. When using the Clementine-Generated base playlists, I could be sure all the files actually exist on disk. However while Clementine will only show you files that exist in the UI, it doesn't seem to do a very good job of cleaning the database of stale files which no longer exist. So if you move or rename files, the old DB entries stick around unless you purge it completely and start over from scratch. That means I have to test every single file as I add it to the playlist, which takes time. It takes about 5-8 seconds to generate my 200 track 5-Star M3U file.

The 5-Star.sh script is below if you'd like to play along at home:

  


#!/bin/bash

rm /Volumes/Filestore/CDs/playlists/5\ Stars.m3u

i=1

while [ $i -le 200 ]
do
 file=$(sqlite3 ./clementine.db "select filename from songs where rating > "0.9" order by random() limit 1;" | awk -F "file://" '{print $2}')

 ### Clementine data encodes special characters and accent marks and stuff so I'm using
 ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649
 
 data=$(urldecode.sh "$file")
 if [ -f "$data" ]
 then
  ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
  ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

  escaped=$(echo "$data" | sed 's/\[/\\[/g')
  #echo "$escaped"

  ### Avoid duplicates
  match=$(grep -i "$escaped" /Volumes/Filestore/CDs/playlists/5\ Stars.m3u)
  if [ -z "$match" ]
  then
   echo "$data" >> /Volumes/Filestore/CDs/playlists/5\ Stars.m3u
   ((i++))
  fi
 fi
done

For the 3+ and 4+ lists, I repeat this main block, but instead each rating dumps into a text file that I randomize into an .m3u at the end. So for the 3-Star + script below, I collect 130 5-star tracks, 45 4-star, and 25 3-star, push them out to a temp file and then cat temp.m3u | sort -R > "./3 Star +.m3u". I could do all this by creating a new table in the database and stuffing tracks into that, but this was faster for me to write and it works well enough:


#!/bin/bash

rm /Volumes/Filestore/CDs/playlists/3\ Stars\ +.m3u

i=1

while [ $i -le 130 ]
do
 file=$(sqlite3 ./clementine.db "select filename from songs where rating > "0.9" order by random() limit 1;" | awk -F "file://" '{print $2}')

 ### Clementine data encodes special characters and accent marks and stuff so I'm using
 ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649
 
 data=$(urldecode.sh "$file")
 if [ -f "$data" ]
 then
  ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
  ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

  escaped=$(echo "$data" | sed 's/\[/\\[/g')
  #echo "$escaped"

  ### Avoid duplicates
  match=$(grep -i "$escaped" ./3-star-tmp.m3u)
  if [ -z "$match" ]
  then
   echo "$data" >> ./3-star-tmp.m3u
   ((i++))
  fi
 fi
done

i=1

while [ $i -le 45 ]
do
  file=$(sqlite3 ./clementine.db "select filename from songs where rating >= "0.8" and rating

  ### Clementine data encodes special characters and accent marks and stuff so I'm using
  ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649

  data=$(urldecode.sh "$file")
  if [ -f "$data" ]
  then
   ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
   ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

   escaped=$(echo "$data" | sed 's/\[/\\[/g')
   #echo "$escaped"

   ### Avoid duplicates
   match=$(grep -i "$escaped" ./3-star-tmp.m3u)
   if [ -z "$match" ]
   then
    echo "$data" >> ./3-star-tmp.m3u
    ((i++))
   fi
  fi
done

i=1

while [ $i -le 25 ]
do
  file=$(sqlite3 ./clementine.db "select filename from songs where rating >= "0.6" and rating

  ### Clementine data encodes special characters and accent marks and stuff so I'm using
  ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649

  data=$(urldecode.sh "$file")
  if [ -f "$data" ]
  then
   ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
   ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

   escaped=$(echo "$data" | sed 's/\[/\\[/g')
   #echo "$escaped"

   ### Avoid duplicates
   match=$(grep -i "$escaped" ./3-star-tmp.m3u)
   if [ -z "$match" ]
   then
    echo "$data" >> ./3-star-tmp.m3u
    ((i++))
   fi
  fi
done

cat ./3-star-tmp.m3u | sort -R > /Volumes/Filestore/CDs/playlists/3\ Stars\ +.m3u

rm ./3-star-tmp.m3u

xrayspx's picture

Dr Pepper Clock

Music: 

We just got a really great Dr Pepper restaurant clock, as featured in the arcade scene of Wargames. We think it's meant to be modular and can be attached to lighted menu-boards. It's got a pass-through 110V plug so you can daisy chain stuff off of it, and the side trim is easily removable to clip in a sigh board on each side.

However, while it is beautiful, it doesn't need to be on all the time, so I added a switch. The wiring is very simple with just a couple of wire nuts tying the inbound power to the AC plug and fluorescent light. I found some suitably retro-ey looking switches on Amazon at 6 for $9.

We decided to put the switch on the bottom just in case I cracked the plastic or something similarly horrible happened. All in all, very straight forward, but one pro-tip was in drilling the hole. I started with a small drill bit and worked my way up, but when I got to the larger drill bits I ran the drill in reverse to just use friction to make the hole rather than trying to hog out a hole in very thin and brittle material with a way-too-big bit. This worked /great/, thanks Dave.

Wiring before:

Switch:

Wiring After:

Switch external:

Fixed Tags:
xrayspx's picture

Sharp Boombox Repair

Music: 

Tom Petty - Freefallin'

xrayspx's picture

DVD Ripping

Music: 

The Wipeouters - Ravin' Surf

Another note for myself for later, and boy this is dumb.

xrayspx's picture

TV History Time

Music: 

Mojo Nixon & Jello Biafra - Nostalgia For an Age That Never Existed

So this is super interesting. You know, interesting to me anyway.

I'm compiling another week of vintage TV shows, this time from 1963. It's remarkable how easy it is to get the exact episode of many of these even compared to getting episodes from 1980's shows. I'm making a playlist for each night and mixing in 1963 commercials throughout, should be fun. But first, see if you can spot why this week's playlist may present a particular challenge:

As I started out on Sunday night (TVue is boldly not adhering to the TVGuide dictate that Saturday is the first day of the week), I found that while I could find the episode of whatever show I was looking for, the air date listed in IMDB was for like, several months in the future, in some cases as far as March 1964. What the balls IMDB. So it made it kind of tricky to pin down given episodes.

After the 3rd or so show with this happening, I kind of noticed a pattern. Sunday, November 24, 1963 just doesn't seem to exist. IMDB consistently showed "Nov. 17" and then the next episode aired was 'Dec. 1".

So seriously what the he... Oh. Right. Yikes.

My TVue, from the Boston Advertiser, is listing the TV schedule for the week after the Kennedy assassination. I am building playlists to recreate a week of TV which ... ... never existed.

For the record, this being the 24th, we chose Mister Ed, My Favorite Martian and The Judy Garland Show. I got all the right episodes on those, but I'd have liked to have seen the Ed Sullivan Show, but since that's live I imagine it was just canceled altogether. It was supposed to have a Stiller and Meara sketch, so I just picked one of those sketches from another Ed Sullivan. Growing up with Seinfeld it's just so easy to see "SERENITY NOW!", or "I've got a lot of problems with you people!". Genius.

As in my previous week of vintage TV, if I can't find a thing, I'll go for the nearest I can get. So for instance What's My Line on Sunday, Nov. 24 Instead I opted for the December 1 episode with Colonel Sanders. I don't know what was scheduled for that episode, or indeed if it was ever actually shot.

In addition to the JFK assassination horror, one thing that bums me out about this week is that I don't seem to be able to find any episodes of Grindl with Imogene Coca. I really want to see Aunt Edna, but young ('er, she was still in her '50s).

So here's to building a playlist for a TV Guide week that never happened. Obviously this is going to be oddly similar to 9/11/2001, and ... that's about it really. I can't really think of any other week where the machine of commerce would have simply ground to a halt entirely.

xrayspx's picture

Lots of RDP

Music: 

Annie Lennox - Why?

Do you do lots of RDP? Like lots and lots? I do, and even with password management it's annoying. I tend to use generated passwords for all my normal user, Domain Admin user and obviously Administrator accounts. That means lots of workarounds to deal with those passwords while doing bulk RDP sessions.

A typical use case for me is to RDP to 20 machines at a time, run a thing, wait, and log out. I've always scripted this, but not always in strictly the safest way. Plaintext passwords stored in a script, or read off disk. The philosophy is "if someone can read this script, I've already lost the game anyway", but still it's ugly and sick, and so I fixed it. In my defense, the Red Team never did pop my laptop...

I already use gpg-agent to facilitate unpacking of log files. On my syslog servers I roll logs over hourly, gzip them and then gpg encrypt them to my key. Then I can download a bunch of them, run my logunpack script, enter my passphrase once and since gpg-agent caches that credential for a period of time, decrypt all my files in one go.

What I wanted here was basically a way to have keepassxc.cli "hold the door open" and cache the passphrase like gpg-agent does. So what I've done is to use gpg-agent itself for that purpose. I have a GPG encrypted file containing my KeePass-XC passphrase, and I open it using gpg-agent, so it can be reused until gpg-cache-ttl expires.

I've also always had slightly different copies of this script for use cases of "Fullscreen on my laptop" and "fullscreen on larger displays", so I have a switch here for "resolution" as well. "fs" for fullscreen or "fsbm" for "big monitors". Since I'll never go to my office again, that's pretty much never going to get used. The default for the $res value will remain 1280x960. Reasonable enough.

I also added prompts so that it'll ask for host, domain, user and password if you run the script with no prompts from a shell. So /that/ will be super useful to me when I have to do a one-off connection to some remote host but don't need a whole launcher for it. While I'm at it, I put in the -b switch so that you can have it generate a launcher based on that input. That saves me hand editing a template when I add a new RDP host.

I use Linux, but this should work with minimal-if-any changes on Mac and Windows/Cygwin, both of which can run xfreerdp and gpg-agent. I have a good automated ssh-tunneled RDP setup for my Mac, so I might try using that with this so I can use a 4k display for those "busy RDP days".

Being that I do run Linux, here's how I launch this. KDE desktop files like this:


xrayspx@dummyhost:~/rdps$ cat windowsmachine
#!/usr/bin/env xdg-open
[Desktop Entry]
Comment[en_US]=
Comment=
Exec=/home/xrayspx/bin/rdplauncher.sh -h windowsmachine -d domain -u xrayspx
GenericName[en_US]=
GenericName=windowsmachine
Icon=remmina
MimeType=
Name[en_US]=
Name=windowsmachine
Path=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
X-DBUS-ServiceName=windowsmachine
X-DBUS-StartupType=
X-KDE-SubstituteUID=false
X-KDE-Username=

So anyway, here's the thing: RDPLauncher

xrayspx's picture

Dog Day Afternoon

Music: 

Dogs are swell.

Today, Natalie and I we were just starting our daily walk, so we were only like 2 streets away when this dog kind of started running around. The guy said "He'll bite you", so we just stopped and stood still, and yeah, he really did bite Natalie pretty good. We were kind of shaken up so we didn't do what you're supposed to do and get the information about vaccinations and stuff and just kind of staggered Natalie home.

Fixed Tags:

Pages

Subscribe to RSS - xrayspx's blog