QZ qz thoughts
a blog from Eli the Bearded
Tag search results for blog Page 1 of 17

Sticker Roller Box

Shelf full of sticker rolls

Each of these rolls has a label for a different product.

My wife sells sewing patterns. Patterns directly sold to customers through the website have the package just taped shut (with color coded tape). Patterns sold in stores need information on the back about sizes and how what materials are needed. Originally she just used to print stickers in a laser printer, but as sales grew that became expensive and awkward. So she had stickers printed by a service. For price-per-sticker reasons, she gets a thousand at a time for each pattern. These come in heavy rolls. Sometimes it will be a single large roll of 1000, sometimes two medium rolls of 500 each.

Rolls want to be rolled. But if you just put them up on a closet hanger pole, they don't roll well. The bar isn't near the center, there's friction, and it ends up being a mess.

So instead support these giant rolls with two smaller bars. And make a "roller bearing" to help them spin. I made a set of boxes to do just that.

One view of an empty roller box

The box doesn't have a bottom, that's just the wooden shelf it is setting on. I orginally planned it around using the rollers in the upper position only. For a full large sticker roll that is necessary. The medium sticker roll is more forgiving of variations. Both will fall through the wide one eventually, and need the narrow.

Another view of an empty roller box

The box partially visible on the left has the narrow roller on top configuration for a small (500 sticker) roll. The empty box has the configuration for a large (1000 sticker) roll.

Each box is made from four identically sized pieces of wood, with sides each having four holes corresponding to two high rollers and two low rollers. One pair of rollers is wide, for big rolls, one pair is narrow for smaller. The box can be flipped to make wide or narrow the higher pair.

The rollers are 3/8" (9.4mm) steel bars with 1/2" (12.7mm) inner diameter PVC water pipe for a roller bearing. There are only two rollers at a time in a box, the steel bars are just friction fit and can be swapped.

This works great. If I were doing it all again, I'd not use the all four identically sized pieces of wood design.

Simplied sketch of construction

The holes have to be offset differently on left and right sides with this layout which ended up making the drilling of the holes and the assembly a lot more complicated than it needed to be. Setting up the table saw for cutting longer and shorter pieces of wood would have been much easier overall.


I saw this antique wearable abacus recently and thought "How small an abacus can I make?" Answer is "Not quite that small, but pretty tiny."

Abacus ring

Chinese abacus ring, about 12mm x 7mm (0.5" x 0.36"), that inspired me.

Wood frame on blue tape as glue dries

I cut some thin slivers of wood, drilled tiny (#66 drill bit, .033", .838mm) holes, and then glued into a frame shape. To hold it while the glue dried, I stuck it to blue painters tape. My smallest seed beads are 1.5mm, so I drilled holes 2mm apart. Final size will be about twice as wide as the ring.

Starting to bead

I stained the wood and glued a brass angle iron on for reinforcement. I'm using colored jewelry wire.

Custom bead tweezers

I'm using a bead tweezers I cut from a coffee stirrer (see first picture, next to blue tape). It flexes to grasp beads pushed in, then the wire catches them to remove. Grid on ruler is in tenths of an inch.

Finished, next to a Lego plate

Smaller than a 4x2 Lego plate. Functional abacus with ten rods of seven beads each, brass reinforced wood frame.

Special Breakfast

Once a month my dogs need to get dosed up. There's a pill for flea and tick prevention and a "treat" for heartworm. Willie hates them. The treat is inedible to him and the pill a terror. He is not tricked by embedding medicine in tasty things like cheese or hot dogs. So how to get him to take it?

Special Breakfast.

This is a literal dog's breakfast of a meal. Crush the pill, finely chop the "treat".

Dog food bowl with medicine.

Add to that some of this and some of that, basically any dog-tasty leftovers in the fridge. Maybe like pesto linguini, grilled chicken, and french fries, then top with some crushed cheese crackers. Looking good, right?


Now add a few pieces of kibble and dress with mayo and water. I use hot water to make it a warm meal. Delicious.

Dog food bowl with medicine, human food, kibble, and dressing.

And that's how Willie manages to tolerate medicine. Hazel, on the other hand loves to eat and will easily accept pills in cheese or the like. She gets Special Breakfast to be fair, not because it's necessary.

Manual restore of Firefox sessions

Recently I needed to downgrade my Firefox install from 87 to 84 due to a bug. With multiple windows open, I was intermitantly finding some events were being sent to the wrong window. An example is open a new (private) window and start to navigate to a new page, but discover mouse clicks and other events were still being sent to the original window. I started seeing this in FF86 and FF87 did not fix it. By that point the bug was testing my patience, and worse FF87 seemed to have new (unrelated) bugs specifically with one site I use.

So downgrade.

It's been a long time since some Firefox bug has been serious enough to force me to install a different version, particularly a downgrade. So I was surprised to find that Firefox now marks every profile with a browser version and does not let older browsers use profiles from newer ones. Originally when profiles introduced compatibility changes it was somewhat infrequent, and downgrades were usually easy to do.

There are three things I really wanted to preserve:

  1. My open tabs (actual state in the tab, not as critical).
  2. My (few) bookmarks. Of 40 or so bookmarks, about 30 I had created (the others shipped with Firefox), and about half of those I still want.
  3. My preferences.

These have varying degrees of difficulty uncovering from the files in a profile. Session tabs ended up being the most complicated. Working backwards in that list.

Changed preferences are stored one-per-line in prefs.js in the profile directory. The chief complication is the number of entries. Many of them are related to extensions or printing and can just be ignored. Many more are related to internal settings like toolkit.telemetry.* or most of the browser.* ones.

The bookmarks are available in compressed JSON files in the bookmarkbackups profile subdirectory. The compression format is a bit of an oddball. The actual compression type is not so rare, LZ4, but apparently the Mozilla implementation is slightly non-standard. There are a lot of tools out there which can apply the standard LZ4 algorithm to the .jsonlz4 files Firefox makes. I used lz4jsoncat by Andi Kleen. Here ls -rt finds the most recent backup file to operate on.

lz4jsoncat $(ls -rt bookmarkbackups/*.jsonlz4) | jq . | grep '"uri"'

If you are unaware, jq is a JSON Query tool. In the simple usage there, the query is for the whole structure and functions as a JSON pretty printer. Why not use jq to slice and dice the uri entries out? Because they exist in several groups (probably for bookmark folders) and grep was way faster than figuring out the correct jq query to use.

But that brings us to the remaining item of interest for me: the URLs of all my tabs in the session data. There are several files in the sessionstore-backups profile subdirectory. In my inspection they all appeared to be valid sessions from different times, and recovery.jsonlz4 seemed to be the most recent one. No need to resort to time sorted file lists here.

The JSON structure holds a lot of data, from cookies to apparently thumbnail images of the page (base64 encoded for safely storing in JSON). Getting just tab URLs was not easily done with grep, and I needed to work out a jq query. There is a windows[] array with an entry for each window, inside that there is a tabs[] array with a state for each tab, and inside that an entries[] array with the history for each tab. The history is a stack with latest entry first.

lz4jsoncat sessionstore-backups/recovery.jsonlz4 |
    jq -r '.windows[].tabs[].entries[0].url'

For each item ([]) in windows array,
  for each item ([]) in tabs array within it,
    for the first ([0]) item in entries array within it,
      print the url field.
The -r makes the output "raw", which is to say without quotes.

Not as neat and clean as actual session recovery, but a lot better than trying to recover my two dozen tabs from memory.