Still working on the yarn ball, but I’ve got a pouncing knight.
Category: Technology
Cat Chess – Rook
DNF5 History *UNDO*?!?
This is cool – I’ve only tested with a package I didn’t need and didn’t matter if it got mucked up. No idea if there’s an undo for, say, kernels. Or if undo on an update would roll back to the previous version. That’s the sort of testing to do on a sandbox that you don’t want running 30 minutes from now!
[root@fedora log]# dnf5 install bvi
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Installing:
bvi x86_64 1.5.0-1.fc43 fedora 157.1 KiB
Transaction Summary:
Installing: 1 package
Total size of inbound packages is 83 KiB. Need to download 83 KiB.
After this operation, 157 KiB extra will be used (install 157 KiB, remove 0 B).
Is this ok [y/N]: y
[1/1] bvi-0:1.5.0-1.fc43.x86_64 100% | 351.6 KiB/s | 83.0 KiB | 00m00s
———————————————————————————————————————————————————————————————————————————————
[1/1] Total 100% | 164.9 KiB/s | 83.0 KiB | 00m01s
Running transaction
[1/3] Verify package files 100% | 142.0 B/s | 1.0 B | 00m00s
[2/3] Prepare transaction 100% | 2.0 B/s | 1.0 B | 00m00s
[3/3] Installing bvi-0:1.5.0-1.fc43.x86_64 100% | 243.9 KiB/s | 160.0 KiB | 00m01s
Complete!
[root@fedora log]# dnf5 history list
ID Command line Date and time Action(s) Altered
29 dnf install bvi 2026-02-06 04:50:43 1
28 dnf remove kernel-core-6.18.3-200.fc43.x86_64 kernel-modules-6.18.3-200.fc43.x86_64 kernel-modules-extra-6.18.3-200.fc43.x86_64 2026-01-14 05:07:22 4
27 dnf update 2026-01-14 05:01:58 70
26 dnf remove kernel-core-6.17.9-300.fc43.x86_64 kernel-modules-6.17.9-300.fc43.x86_64 kernel-modules-extra-6.17.9-300.fc43.x86_64 2026-01-14 05:01:28 4
25 dnf update 2026-01-09 19:19:48 42
24 dnf update 2026-01-08 19:57:05 618
23 dnf5 remove kernel-core-6.11.10-300.fc41.x86_64 kernel-modules-6.11.10-300.fc41.x86_64 kernel-modules-core-6.11.10-300.fc41.x86_64 2026-01-08 19:53:42 3
22 dnf remove kernel-6.11.10-300.fc41 2025-12-26 02:06:47 1
21 dnf install speedtest-cli 2025-12-19 23:06:12 1
20 yum install chromedriver 2025-12-08 00:20:24 3
19 dnf system-upgrade download –releasever=43 2025-12-06 18:40:14 3792
18 dnf upgrade –refresh 2025-12-06 08:22:19 1422
17 dnf install -y cloud-utils-growpart 2025-12-06 08:16:00 1
16 dnf install xmlsec1 xmlsec1-openssl 2025-10-27 20:44:39 1
15 yum install xmlsec1 2025-10-27 20:42:29 1
14 dnf install mod_md 2025-07-03 19:22:36 1
13 yum install npm 2025-06-23 20:05:13 5
12 dnf update 2025-02-23 19:56:36 482
11 dnf update 2025-01-31 16:01:33 626
10 dnf5 install dnf5-plugin-automatic 2025-01-31 15:59:29 9
9 yum install xxd 2025-01-15 21:38:38 1
8 dnf install mosquitto 2025-01-04 23:40:52 3
7 dnf update 2025-01-03 04:51:41 14
6 dnf update 2025-01-01 00:19:22 358
5 dnf update 2024-12-06 04:30:32 18
4 dnf update 2024-12-06 04:14:41 404
3 dnf update 2024-11-22 17:21:43 65
2 dnf update 2024-11-18 18:33:18 116
1 dnf update 2024-11-14 18:58:09 54
[root@fedora log]# dnf5 history undo 29
Updating and loading repositories:
Repositories loaded.
Package Arch Version Repository Size
Removing:
bvi x86_64 1.5.0-1.fc43 fedora 157.1 KiB
Transaction Summary:
Removing: 1 package
After this operation, 157 KiB will be freed (install 0 B, remove 157 KiB).
Is this ok [y/N]: y
Running transaction
[1/2] Prepare transaction 100% | 4.0 B/s | 1.0 B | 00m00s
[2/2] Removing bvi-0:1.5.0-1.fc43.x86_64 100% | 35.0 B/s | 20.0 B | 00m01s
Complete!
Kitten Chess – Bishop
DOS Command – Bulk Change File Extension
There is a one-line DOS command to get all files with a specific extension and change it to a different extension. In my case, I had a bunch of p12 files that I wanted to be pfx so they’d open magically without creating a new association.
for %f in (*.p12) do ren "%f" "%~nf.pfx"
Cat Chess – Kitten Queen
I copied the pawn and grew her a little. Added a crown and necklace … voila, a kitten queen! I’ve been using the smooth brush a lot to even out the surface. I’m curious how these will 3d print because the model is made up of a lot of little triangles.
421,132 to be exact. As I’ve discovered, you can configure the viewport to add data in overlays. Statistics is a nice one!
Cat Chess – The Pawn
Chess Set – Sculpting Begins
OK, so I don’t know that anyone would see this and say “cat!” … but it’s a start!
My idea is to have a king and queen, a knight pouncing on something, a bishop based on the beckoning cat, and a rook that is a cat sleeping in a little cat tree. Pawns will just be kittens. Should probably start there since they’re the least adorned.
Cat Chess – A Starting Place
Did you know … Powershell can create Visio diagrams!?!
I had to create a number of Visio diagrams for a new project. Since Blender has a Python API, I wondered if I could do something similar with Visio. There does appear to be an VSDX library for Python, I also found that Powershell can just control the Visio instance on my laptop.
This is a demo creating a diagram for a simple web server with a database back end. You can, however, use any stencils and make more complicated diagrams. The lines aren’t great — part of my Visio diagramming process is moving things around to optimize placement to avoid overlapping and confusing lines. The programmatic approach doesn’t do that, but it gets everything in the diagram. You can then move them as needed.
# Sample Visio diagram: Firewall -> Load Balancer -> Web Servers -> Database
# Auto-discovers stencils
# Works on Windows PowerShell 5.x
$ErrorActionPreference = "Stop"
# Output
$docName = "WebApp-LB-Firewall-DB.vsdx"
$outPath = Join-Path $HOME "Documents\$docName"
# Start Visio
$visio = New-Object -ComObject Visio.Application
$visio.Visible = $true
# New document/page
$doc = $visio.Documents.Add("")
$page = $visio.ActivePage
$page.Name = "Architecture"
$page.PageSheet.CellsU("PageWidth").ResultIU = 22.0
$page.PageSheet.CellsU("PageHeight").ResultIU = 14.0
# -------------------------------
# Stencil discovery and loading
# -------------------------------
$searchRoots = @(
"$env:PROGRAMFILES\Microsoft Office\root\Office16\Visio Content",
"$env:PROGRAMFILES\Microsoft Office\root\Office16\Visio Content\1033",
"$env:ProgramFiles(x86)\Microsoft Office\root\Office16\Visio Content",
"$env:ProgramFiles(x86)\Microsoft Office\root\Office16\Visio Content\1033",
"$env:PROGRAMFILES\Microsoft Office\root\Office15\Visio Content",
"$env:ProgramFiles(x86)\Microsoft Office\root\Office15\Visio Content",
"$env:PROGRAMFILES\Microsoft",
"$env:ProgramFiles(x86)\Microsoft",
"$env:PROGRAMFILES",
"$env:ProgramFiles(x86)"
) | Where-Object { Test-Path $_ }
# Keywords to select useful stencils (filename match, case-insensitive)
$stencilKeywords = @("network","server","compute","computer","azure","cloud","firewall","security","database","sql","load","balancer","web","iis")
function Find-StencilFiles {
param([string[]]$roots, [string[]]$keywords)
$results = @()
foreach ($root in $roots) {
try {
Get-ChildItem -Path $root -Filter *.vssx -Recurse -ErrorAction SilentlyContinue | ForEach-Object {
$fname = $_.Name.ToLower()
foreach ($kw in $keywords) {
if ($fname -match $kw) { $results += $_.FullName; break }
}
}
} catch { }
}
$results | Select-Object -Unique
}
function Load-Stencils {
param([string[]]$files)
$loaded = @()
foreach ($file in $files) {
try {
Write-Host "Loading stencil: $file"
$loaded += $visio.Documents.OpenEx($file, 64) # read-only
} catch {
Write-Warning "Could not load stencil: $file"
}
}
foreach ($docX in $visio.Documents) {
if ($docX.FullName -ne $doc.FullName) { $loaded += $docX }
}
$loaded | Sort-Object FullName -Unique
}
$files = Find-StencilFiles -roots $searchRoots -keywords $stencilKeywords
$stencils = Load-Stencils -files $files
if (!$stencils -or $stencils.Count -eq 0) {
Write-Warning "No stencil files loaded automatically. Fallback rectangles will be used."
} else {
Write-Host "`nLoaded stencils:" -ForegroundColor Cyan
foreach ($s in $stencils) { Write-Host " - $($s.FullName)" }
}
# -------------------------------
# Master selection helpers
# -------------------------------
function List-Masters {
foreach ($st in $stencils) {
Write-Host ("Stencil/Doc: {0}" -f $st.Name) -ForegroundColor Cyan
foreach ($m in $st.Masters) {
Write-Host (" - {0} (NameU: {1})" -f $m.Name, $m.NameU)
}
}
}
function Get-MasterByPattern([string[]]$patterns) {
foreach ($st in $stencils) {
foreach ($m in $st.Masters) {
foreach ($p in $patterns) {
if ($m.NameU -match $p -or $m.Name -match $p) {
Write-Host ("Selected master '{0}' from '{1}' for pattern '{2}'" -f $m.Name, $st.Name, $p) -ForegroundColor Green
return $m
}
}
}
}
return $null
}
# Drop master centered at x,y; keep default size; label it
function Add-Device([double]$x,[double]$y,[string]$label,[string[]]$patterns,[double]$fontSize=10) {
$m = Get-MasterByPattern $patterns
if ($null -eq $m) {
Write-Warning ("No master matched patterns: {0}. Using fallback rectangle." -f ($patterns -join ", "))
$w = 2.0; $h = 1.2
$shape = $page.DrawRectangle($x - ($w/2), $y - ($h/2), $x + ($w/2), $y + ($h/2))
} else {
$shape = $page.Drop($m, $x, $y)
}
$shape.Text = $label
$shape.CellsU("Char.Size").FormulaU = "$fontSize pt"
return $shape
}
# Simple transparent containers (thin gray outline; sent behind shapes)
function Add-Container([double]$x,[double]$y,[double]$w,[double]$h,[string]$text) {
$shape = $page.DrawRectangle($x, $y, $x + $w, $y + $h)
$shape.CellsU("LineColor").FormulaU = "RGB(180,180,180)"
$shape.CellsU("LineWeight").FormulaU = "1 pt"
$shape.CellsU("FillForegnd").FormulaU = "RGB(255,255,255)"
$shape.CellsU("FillForegndTrans").ResultIU = 1.0
$shape.Text = $text
$shape.CellsU("Char.Size").FormulaU = "12 pt"
try { $shape.SendToBack() } catch {}
return $shape
}
# Connector
function Connect($fromShape,$toShape,[string]$text="") {
$conn = $page.Drop($visio.Application.ConnectorToolDataObject, 0, 0)
$conn.CellsU("LineColor").FormulaU = "RGB(60,60,60)"
$conn.CellsU("LineWeight").FormulaU = "0.75 pt"
$fromShape.AutoConnect($toShape, 0, $conn)
if ($text) { $conn.Text = $text }
return $conn
}
# -------------------------------
# Diagram content
# -------------------------------
# Title
$title = $page.DrawRectangle(1.0, 13.4, 21.0, 13.9)
$title.Text = "Web App Architecture: Firewall -> Load Balancer -> Web Servers -> Database"
$title.CellsU("Char.Size").FormulaU = "14 pt"
# Patterns for official icons (broad to match common stencils)
$patFirewall = @("Firewall|Security|Shield|Azure.*Firewall")
$patLoadBalancer= @("Load.*Balancer|Application.*Gateway|LB|Azure.*Load.*Balancer")
$patWebServer = @("Web.*Server|IIS|Server(?! Rack)|Computer|Windows.*Server")
$patDatabase = @("Database|SQL|Azure.*SQL|DB|Cylinder")
# Containers (optional zones)
$dmz = Add-Container 1.0 10.8 20.0 2.0 "DMZ (Edge/Ingress)"
$webtier = Add-Container 4.0 6.8 14.0 3.2 "Web Tier"
$dbtier = Add-Container 8.0 3.5 10.0 2.8 "Database Tier"
$clients = Add-Container 1.0 1.0 6.0 2.2 "Clients"
# Devices (kept at native size; spaced widely)
# Edge/Ingress
$fw = Add-Device 3.0 11.8 "Firewall" $patFirewall 10
$lb = Add-Device 8.0 11.8 "Load Balancer" $patLoadBalancer 10
# Web servers (pair)
$web1 = Add-Device 9.5 8.0 "Web Server 1\nIIS" $patWebServer 10
$web2 = Add-Device 13.5 8.0 "Web Server 2\nIIS" $patWebServer 10
# Database
$db = Add-Device 13.0 4.6 "Database\nSQL" $patDatabase 10
# Clients
$client1 = Add-Device 2.0 1.8 "Client\nPC" @("Desktop|PC|Computer|Laptop") 10
$client2 = Add-Device 5.0 1.8 "Client\nServer" @("Server(?! Rack)|Windows.*Server|Computer") 10
# Connectors (flow: clients -> firewall -> LB -> web servers -> database)
Connect $client1 $fw "HTTPS"
Connect $client2 $fw "HTTPS"
Connect $fw $lb "Allow: 443"
Connect $lb $web1 "HTTP/HTTPS"
Connect $lb $web2 "HTTP/HTTPS"
Connect $web1 $db "SQL (1433/Encrypted)"
Connect $web2 $db "SQL (1433/Encrypted)"
# Save
$doc.SaveAs($outPath)
Write-Host "Saved Visio to: $outPath"







