CasaOS and Caddy

Briefly – Caddy wouldn’t work out of the box for me on CasaOS. In this build, the default container path for the caddyfile is incorrect. Change the container path from

to

Also, don’t forget to adjust ports, our you’ll inevitably be running into CasaOS itself. I changed my HTTP ports to 85:

Then you can SSH into your CasaOS Pi, head to /DATA/AppData/caddy/caddyfile, create your Caddyfile, er, file, and populate it appropriately. If you’ve been running Caddy elsewhere, I recommend running the below to confirm your file’s format:

CasaOS and bash in Docker

I installed ArchiveBox on CasaOS and came upon a problem – I couldn’t figure out what the default credentials are, or even if there were any, and I didn’t know how to generate them from the command line. ArchiveBox told me to create a new superuser by running

From the command line, but doing so within the container terminal resulted in this:

But I found my way into the container bash thusly:

  • SSH into your pi running CasaOS
  • search for your ArchiveBox container ID:
  • You’ll see a path in your return with a long, long directory name, something like
  • This is your container ID. CD to /var/lib/docker/containers/and run the following, where containerID is the above ID:
  • This will invoke a bash within that container. From within it, run:
  • And follow the prompts to create a superuser for ArchiveBox. To drop out of bash, just input exit.

 

CasaOS – Tinkering

Somewhere in my intertoobs wanderings I came across CasaOS and, given I had an idle Pi 4 laying around, I decided to poke at it. After all, if it works worth a damn it could help consolidate all the disparate systems I have running locally.

CasaOS is basically a slick Docker manager that rides atop another OS. Getting it up and running on the Pi with a fresh Raspbian install was painless. Simple configs, like mounting network shares, is a breeze. So far I have the following running in it:

  • PiHole – Installed without a hitch. If this runs well it’ll replace the standalone PiHole Pi 3 I have running.
  • Calibre Web – Also installed without a hitch. Love this, because I hate running the Calibre thick client full time on my server simply for its web interface. Not a lot of instructions on this one – just make sure you have your library mounted and defined as a volume in the container settings.
  • Jellyfin – Another painless install (make sure to mount your files volume as described in the above Calibre Web settings). I installed this as a replacement for my current Jellyfin music server, which runs standalone in a fully fledged VM, gobbling unnecessary resources. But I stopped it midway through indexing my gajillion files because I discovered:
  • Navidrome – Will it be better than Jellyfin for audio? I don’t know, but I’m giving it a shot.  Currently still indexing – on directory number 12406. Heh. Now, Navidrome wouldn’t run initially, and CasaOS kept screaming that it was unhealthy. Its log filled with “exec /app/navidrome: exec format.” I discovered that the image I was pulling isn’t the most recent. I exported the ComposeFile from within the settings of the failed install, uninstalled it, and updated the image source in the ComposeFile to point to “ghcr.io/navidrome/navidrome:develop.” I then imported the file (Custom Install > Import from within the App Store) and it installed fine
  • Memos – Completely painless install. Came across this randomly and figured maybe it’d replace my TiddlyWiki instance running on my server. We’ll see.
  • Mealie – I ran across this neat app via some Youtubers Apps of The Year vid and was intrigued. An app that’ll scrape a online recipe page, pull the pertinent details of the recipe and ditch all the ads and fluff? Yes please! However, Mealie wasn’t in the default app store for CasaOS. I found CoolStore for Casa and added it as a source. From there Mealie installed no problem, and now I have a slew of other apps to sift through as well. Perhaps Casa can even replace my standalone VPN Pi. We shall see.

Powershell – Monitoring a log file

I had a situation at work where I needed to monitor a log file for a particular entry. I needed to be notified when that entry appeared. This log file gets created anew, with the current date, every day. Here’s what I came up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
while($true)
{
# get the date
$now = get-date
# create the log name from said date eg :20231223Err.txt
$fileName = '{0}{1}{2}Err.txt' -f $now.Year, $now.Month, $now.Day
# network path to said log
$fullPath = "\\path\e$\LogFiles\app\$($fileName)"

#I don't need this to run in perpetuity - it's a temp situation - so I'm just
#invoking this in a Powershell window and letting it rip.
Write-Host "[$(Get-Date)] Starting job for file $fullPath"
$latest = Start-Job -Arg $fullPath -ScriptBlock {
param($file)

# wait until the file exists, just in case
while(-not (Test-Path $file)){ sleep -sec 10 }
# matching the phrase Queue Count. could make all these variables
Get-Content $file -wait | where {$_ -match 'Queue Count'} |
foreach {
Send-MailMessage -SmtpServer SMTPSERVER -From me@email.com -To me@email.com -Subject 'Queue Count' -Body $_
write-host $_
}
}

# wait until date change
while($now.Date -eq (Get-Date).Date){ sleep -Sec 10 }

# kill the job and start anew
Write-Host "[$(Get-Date)] Stopping job for file $fullPath"
$latest | Stop-Job
}

Jellyfin as a Music Server – Missing Artist Tag

See previous post about Jellyfin for details on Jellyfin database access.

1
2
3
4
5
select artists,album,IndexNumber,name,path
from TypedBaseItems where artists is NULL
and IsFolder = 0
and path not like '%Metadata%'
ORDER BY Path

 

The Magic of Logparser

I had a slew of IIS FTP logs to dig through for a work project. I needed unique visitor details, and I needed it from a month of logs. Some of these daily logs were in excess of 40mb. I threw together a PowerShell script to do just so, kicked it off, and waited. And waited. I reconfigured the script to be more efficient in its processing, kicked it off again, and waited. And waited. And researched, because this was taking far too long. And – late to the game, I know – I found Microsoft’s Logparser. Logparser is a free tool, and it’s filled with magic. With one simple query it managed to pull the raw data I needed from the log files in *seconds*.

1
2
3
4
5
#log files in c:\temp\iis, results to same path

logparser "SELECT DISTINCT c-ip, cs-username INTO C:\temp\iis\results.txt FROM 'C:\temp\iis\*.log'" -i:W3C -o:W3C

#

In less than a minute I had a text file of unique visits gleaned from 550 MB worth of plaintext log files. From there I could use PowerShell to filter out any IP dupes (some connections do not have user details, thus producing some leftover duplication) and resolve hostnames from IP addresses to create a final masterlist. I’m not sure how Logparser does what it does so quickly.

Jellyfin as a Music Server – Duplicates

Updated query for better detail!

1
2
3
4
5
6
7
8
9
10
11
12
SELECT a.artists,a.album,a.IndexNumber,a.name,a.path
FROM TypedBaseItems a
JOIN (SELECT name, album, IndexNumber
FROM TypedBaseItems
WHERE album IS NOT NULL
AND IsFolder = 0
GROUP BY name, album, IndexNumber
HAVING COUNT(*) > 1 ) b
ON a.name = b.name
AND a.album = b.album
AND a.IndexNumber = b.IndexNumber
ORDER BY a.artists, a.album, a.IndexNumber, a.name

I run 2 Jellyfin servers – one for video, and one for music. In the world of streaming I’m old school in that I still curate a huge library of audio files. I don’t like being at the whim of streaming services, I don’t like how they treat artists, and I don’t like how I’m limited to artists on their platforms. I listen to a lot of obscure music across nearly all genres, and quite a bit of it can’t be found on *any* streaming service.

Jellyfin isn’t the perfect solution for a music server, but so far it’s the best I’ve found. Admittedly I may be biased due to my familiarity with the product, but every time I come across an alternative I give it a go only to wind up back at Jellyfin. Over the course of decades I’ve wound up with many duplicates in my library and, because often they aren’t identical in name or size, it’s not easy to identify them. The other day, as I saw yet another double listing for an album in Jellyfin, it dawned on me: Jellyfin knows these are dupes. Can I leverage it to my advantage?

Indeed I can.

First you’ll need DB Browser for SQLite. It’s free. Then you’ll want to locate your database file for Jellyfin. I’m running on Windows, and my path is

C:\Users\USERNAME\AppData\Local\Jellyfin\data\library.db

For the purpose of learning, I recommend making a copy of this file elsewhere to tinker with. If you accidentally change data in it, you could sink yourself.  Everything happening below is strictly reading data, not manipulating, but still. You’ll have to shut Jellyfin down to access this file in DB Browser. Open it up, head to the Execute SQL tab, slap this query in, and execute it.

1
2
3
4
5
6
7
8
9
10
SELECT a.artists,a.album,a.name,a.path
FROM TypedBaseItems a
JOIN (SELECT name, album
FROM TypedBaseItems
WHERE album IS NOT NULL
GROUP BY name, album
HAVING COUNT(*) > 1 ) b
ON a.name = b.name
AND a.album = b.album
ORDER BY a.name

This will return you a comma delimited list of dupes. It’s keying off of song title and album title. Mind you, it’s not perfect. It’s going to find dupes that aren’t here and there, especially on boxed sets and compilations where there might be multiple takes of the same tune. You could obviously add in track number (IndexNumber in the database) and leverage IsFolder to skip directory names (1 is yes, 0 is no), but for my purposes the above gave me accurate enough data to sort in a Google spreadsheet and start hacking away at my duplicates.

The Return of The Site

I shuttered this site in early 2020 for personal reasons. Having found myself in need of an outlet, and a place to keep random thoughts and information, I decided to revive it.

Giant Cell Tumor – The Gym and Running

I recently realized that my left leg is still far weaker than its companion.  That I’ve grown accustomed to allowing the right to carry more than its fair share of the burden.  During my initial recovery from surgery I did physical therapy and then signed up for and started going to a gym.  I continued the gym through the first winter.  Trying to exercise in the cold was difficult, and navigating snow and ice seemed treacherous.  But as soon as spring arrived I told myself that going out for walks and bike rides was sufficient, and I could skip the gym.

Truthfully, I hate the gym.  I don’t hate exercise – I hate the gym.  If I could go to the gym and be alone I’d be fine.  And I recognize that this isn’t the fault of other gym attendees – this is my anxiety, my hangup.   Everyone’s here for the same reason, I tell myself.  No one’s watching you.  No one cares.

I returned to the gym about a week ago.  It was confirmation of how weak my leg is.  On many of the machines, my left leg can only handle half – or even less – of the weight that my right can.  And it’s not just muscle weakness, though that’s profound.  It’s also flexibility.  And it’s pain.  Doing leg lifts with a mere 30 pounds hurts my knee.  It’s not a severe pain, not a pain that’s sufficient to stop me from doing the exercise, but it’s more than enough to acknowledge.

Continue reading

Small Intestine Bacterial Overgrowth Redux

Back in 2016 I wrote one post about my battle with SIBO – Small Intestine Bacterial Overgrowth – and nothing since.  Little did I know then that I’d be diagnosed with a bone tumor and life would change in dramatic ways.

At the time of my post I was seeing a nutritionist who had me on a strict diet regimen, and it appeared that it was working.  However, my weight continued to drop.  I reached 130 pounds.  One of our clients, a doc at a local hospital, expressed extreme concern over my condition, and even asked if I’d had an HIV test.  My clothes hung on me loosely, my face was sunken, my pallor made people uncomfortable.  I looked desperately ill.

My attempts to lead a semi-normal life proved to be dangerous.  I had no reserves, my constitution was nil.  I’d fall out exerting the slightest of efforts – literally nearly collapsing.  I wound up in the hospital after an attempt at a casual mountain bike ride, bonking out and wrecking a mere mile and a half into a trail I used to ride without giving it a second thought.

Continue reading