Quick-note: Some useful combinations for disk usage sorting in the command line

Context

The du -h command shows disk usage in human-readable format. I usually use it as du -hs to get the total disk usage in a specific directory.

But there are some useful combinations I usually forget. Thus this note.

1. Sort by size (largest first)

du -h | sort -hr

This will output a list of all dirs , sorted by size, largest first. Example:

 du -h | sort -hr
156M    .
106M    ./.venv
79M ./.venv/lib/python3.13/site-packages
79M ./.venv/lib/python3.13
79M ./.venv/lib
33M ./.venv/lib/python3.13/site-packages/babel
32M ./.venv/lib/python3.13/site-packages/babel/locale-data
...
12M ./.venv/lib/python3.13/site-packages/pip
12M ./.venv/lib64/python3.13/site-packages/lxml
9.9M    ./.venv/lib/python3.13/site-packages/setuptools
9.2M    ./.venv/lib/python3.13/site-packages/pygments
8.3M    ./.venv/lib/python3.13/site-packages/pip/_vendor
7.9M    ./.venv/lib/python3.13/site-packages/pygments/lexers
7.5M    ./.venv/lib64/python3.13/site-packages/pillow.libs
6.8M    ./.venv/lib64/python3.13/site-packages/PIL
5.5M    ./nikola
4.8M    ./npm_assets/node_modules/bootstrap

2. Sort by size (smallest first)

du -h | sort -h

This will output a list of all dirs , sorted by size, smallest first. Example:

 du -h | sort -h
4.0K    ./.git/objects/info
4.0K    ./.git/refs/tags
4.0K    ./nikola/data/themes/bootblog4-jinja/assets/css
8.0K    ./.github/workflows
8.0K    ./.git/info
...
8.0K    ./.git/refs/heads
8.0K    ./.idea/inspectionProfiles
8.0K    ./nikola-baseline-build/cache/galleries/demo
8.0K    ./nikola-baseline-build/cache/posts
8.0K    ./nikola-baseline-build/files/images
8.0K    ./nikola-baseline-build/listings

3. Get the top 10 largest directories

du -h | sort -hr | head -10

This will output a list of the top 10 largest dirs, sorted by size, largest first. Example:

 du -h | sort -hr | head -10
156M    .
106M    ./.venv
79M ./.venv/lib/python3.13/site-packages
79M ./.venv/lib/python3.13
79M ./.venv/lib
33M ./.venv/lib/python3.13/site-packages/babel
32M ./.venv/lib/python3.13/site-packages/babel/locale-data
27M ./.venv/lib64/python3.13/site-packages
27M ./.venv/lib64/python3.13
27M ./.venv/lib64

4. For the current directory only (not subdirectories)

du -sh * | sort -hr

This will output a list of all the dirs in the current dir, sorted by size, largest first. Example:

 du -sh * | sort -hr
16M npm_assets
5.5M    nikola
4.2M    nikola-baseline-build
664K    docs
512K    tests
280K    translations
120K    CHANGES.txt
108K    Nikola.egg-info
96K scripts
56K du-demo.cast
44K logo
8.0K    CONTRIBUTING.rst
8.0K    AUTHORS.txt
4.0K    snapcraft.yaml
4.0K    setup.py
4.0K    setup.cfg
4.0K    README.rst
4.0K    pyproject.toml
4.0K    MANIFEST.in
4.0K    LICENSE.txt
4.0K    dodo.py
4.0K    CODE_OF_CONDUCT.md

5. Include hidden files/directories

du -sh .[^.]* * 2>/dev/null | sort -hr

Same as "4." but including hidden files and dirs

 du -sh .[^.]* * 2>/dev/null | sort -hr
106M    .venv
24M .git
16M npm_assets
5.5M    nikola
4.2M    nikola-baseline-build
664K    docs
512K    tests
280K    translations
120K    CHANGES.txt
108K    Nikola.egg-info
96K scripts
44K logo
36K .idea
32K .github
12K .pypt
8.0K    .tx
8.0K    CONTRIBUTING.rst
8.0K    AUTHORS.txt
4.0K    snapcraft.yaml
4.0K    setup.py
4.0K    setup.cfg
4.0K    .readthedocs.yaml
4.0K    README.rst
4.0K    pyproject.toml
4.0K    MANIFEST.in
4.0K    LICENSE.txt
4.0K    .gitignore
4.0K    .gitattributes
4.0K    .editorconfig
4.0K    dodo.py
4.0K    .coveragerc
4.0K    CODE_OF_CONDUCT.md

6. Sort specific directory

du -h /path/to/directory | sort -hr

This will output a list of dirs, sorted by size, largest first, for a specific dir. Example:

 du -h nikola | sort -hr
5.5M    nikola
2.4M    nikola/data
2.0M    nikola/plugins
1.4M    nikola/data/themes
1.1M    nikola/data/samplesite
656K    nikola/plugins/command
568K    nikola/data/themes/base
524K    nikola/plugins/task
492K    nikola/__pycache__
436K    nikola/data/samplesite/files
392K    nikola/plugins/compile
256K    nikola/plugins/shortcode

7. One-level deep only

du -h --max-depth=1 | sort -hr

This will output a list of dirs, sorted by size, largest first, for a specific depth. Example:

 du -h --max-depth=1 | sort -hr
156M    .
106M    ./.venv
24M ./.git
16M ./npm_assets
5.5M    ./nikola
4.2M    ./nikola-baseline-build
664K    ./docs
512K    ./tests
280K    ./translations
108K    ./Nikola.egg-info
96K ./scripts
44K ./logo
36K ./.idea
32K ./.github
12K ./.pypt
8.0K    ./.tx

# You can also change the max depth. du -h --max-depth=2 | sort -hr
156M    .
106M    ./.venv
79M ./.venv/lib
27M ./.venv/lib64
24M ./.git/objects
24M ./.git
16M ./npm_assets/node_modules
16M ./npm_assets
5.5M    ./nikola
4.2M    ./nikola-baseline-build
2.4M    ./nikola/data
2.4M    ./nikola-baseline-build/output
2.0M    ./nikola/plugins

The flags

The -r flag reverses the sort order, and the -h flag in sort tells it to understand human-readable sizes (like 1K, 2M, 3G).

How to make an image of an existing physical hard drive and attach it to a VM in virsh-manager and boot from it

Context

I replaced the hard drive of my desktop, and I wanted to have a full clone of the disk in case I forgot to save anything and stuff like that. As I wanted to use the disk in another device, I made a Disk Image and then attached it to a VM to boot from it and get the same state I previously had. Here are my notes for that.

NOTE: This is a note for myself as I tend to forget these steps and commands and spent several hours trying to make this work.

Create the disk image

To create the image use dd

sudo dd if=/dev/sdX of=/path/to/image.img bs=4M status=progress

or using qemu-img

qemu-img create -f qcow2 -o size=10G /path/to/image.qcow2 # set the right size

I used dd

Create the VM in virsh-manager

Then create a new VM in virsh-manager with UEFI instead of BIOS (only if your original machine used UEFI. If it booted using BIOS, then the default will be enough).

If the option is not shown, change the defaults for the new machines in vish-manager -> Preferences -> New VM -> x86 Firmware.

NOTE: As stated above, if your original device used BIOS, then ignore this part.

Screenshot of the settings screen of virsh manager

Convert the .img image to .qcow2 to use with qemu and virsh-manager

If you created the disk image as .img, convert it to qcow2 with the following command:

qemu-img convert -f raw -O qcow2 originak_image.img converted_image.qcow2

NOTE: If you get a permissions problem, try sudo or set the right permissions of the image using chmod or chown

The problems I had

I had several thing not really working:

  1. In my case the VM was not booting at all, and the first issue was the BIOS → UEFI part (see above).

  2. Then it was loading the boot menu but not booting. When trying to boot Linux Mint (the OS inside the disk image), it went to black. I had to go to advanced options and select the recovery boot. There I could get into root, and edit the /etc/fstab by commenting out the other hard drives I had in the original machine that were no longer available in this machine.

I have done this more than once, and more than once have I forgotten how this goes. Thus, it is now here.

How to upgrade the firmware of a Prusa MK3S+ with a Revo6 HotEnd

Disclaimer: I'm new to the whole 3D-Printing world. I've researched for quite a while and decided for a used and modified Prusa MK3S+ I got from Kleinanzeigen.de. I could have gotten a Bambu Labs printer, but I did not like the last news on their updated firmware.

I wanted to upgrade the firmware of my new (used) Prusa MK3S+. I managed to install a new firmware I downloaded from the official website, but any time I tried to unload the filament or do a thermal calibration, I got a "Thermal Anomaly" error.

After a bit of searching, reading GitHub issues and asking Mistral AI, I found out that there is a special firmware for this model when using the Revo6 HotEnd, which I did not see on the official website. You have to look in the GitHub Repository, under releases.

At the time of writing this, the last available firmware is the 3.14.1. There you have to choose the one starting with E3D_REVO.

Pasted image 20250525220255

That will download a zip file with several files in it. I used "MK3S_MK3S+-E3DREVO_FW_3.14.1_MULTILANG.hex"

Pasted image 20250525220413

I flashed the new firmware with Prusa Slicer -> Configuration -> Flash printer firmware. After a couple of minutes it said that the flash process was ready.

After that the printer worked again and I didn't get any "Thermal Anomaly" error. I could unload the filament and do a Thermal Calibration (which took a while).

Now I am fighting with the bed and nozzle calibration (Z Axis). It should be easy, but the filament (a Silk PLA) is not correctly adhering itself to the bed.

I also just now remembered that "Filament Humidity" is a thing in 3D printers, so I will dry the PLA and try again later. Maybe that solves the issue.

I got a 3D printer Prusa MK3S+!

Some context

The title says it all, doesn't it?

I got a used, modified, Prusa MK3S+ to get into 3D printing. I've been thinking about this for a while (around 4 years since I saw the SnapMaker 1.0), but I was delaying the buy until I had something I really wanted to print. I think now I've gotten to that point. I know it's not the latest and best machine ever, but I liked what I read about it, and I found it for a good price with some extras.

I evaluated a lot of printers:

  • Bambu Labs (as recommended by a colleague),
  • Artillery,
  • SnapMaker,
  • Prusa,
  • Voron
  • and others.

Key Factors

Some key factors for me where:

  • Not-so-small printing bed (the Prusa has a 25 x 21 x 21 cm or 9,84 x 8,3 x 8,3 in, although it can print a little more)
  • Being able to easily get replacement parts (I can print many parts of this machine and get replacements directly from Prusa).
  • Being able to change the Nozzle quickly. The machine I got comes with a Revo6 HotEnd, which allows for quick change of nozzles.
  • High quality prints
  • Multi-material print capabilities (I didn't want to buy a machine only for PLA)
  • Don't break my bank (I didn't want to buy a new machine for a "new hobby")

But the key deciding factor is that I want to own my machine. I want to modify it, to upgrade it, to decide when it stops working. This was a huge decision point! I don't want a tool that works, until it doesn't. Much like the Apple Products. They are great, no doubt. Great design, great performance, but stop working when the company decides the machine is too old for the new software, and then you can't install any new apps. (This may seem a bit extreme, but I do have several iPhones I cannot longer use as daily drivers just because of this)

Given that, and after re-reading this article about the new Bambu Firmware, which can allow the company to block your machine. I may be a real issue, maybe not. For a plug-and-play device that should just work, controlling it remotely and allowing the company to "access" it could be a good idea for some. I just don't like it. And many others seem to agree, as OrcaSlicer has added mode to "block" network access from Bambu Labs.

After checking kleinanzeigen.de for a while, I found a machine that seemed about right. I got it yesterday, but I still have not managed to print (I know it does print because the seller was printing a sample when I got there). Why? Because I needed to upgrade the firmware to the latest version, and I didn't find how to remove the message and just print. I will document the issues I had in additional articles, but in the end I managed to install the new firmware and found out why I couldn't print.

The machine!

But enough of that. Look and behold my new toy!

It came with:

  • two Food Dehydrators adapted to dry filament (until a few days ago I didn't know that humidity can make a print fail)
  • one 250gr Silk PLA
  • Squash side feet to absorb vibrations
  • Prusa Black PSU 24V 240W
  • Revo6 HotEnd with 4 nozzles
  • A custom front cooling system (I haven't found the design yet)
  • 2 magnetic printing beds
  • The Prusa Book, original tools and original pieces.

I foresee a lot of invested hours understanding the machine and playing with it. I already have the following in the pipeline:

  • The Mostly Printed CNC (MPCNC)
  • A personal project (the main reason I bought this machine)
  • Toys for my daughters. They already chose some Pokémon designs. And my wife wants some Book Ends to hold the books on the shelf.

Thinking Out Loud: Don't Take Things for Granted

I've been having trouble breathing because of allergies. I've always had allergies, but it never affected my daily life in such a way that made me reflect on the things I take for granted. The title says it all after all, but I will nevertheless elaborate on it.

The Fallacy of Invulnerability

There is a mental model or fallacy that says something will not happen to us, without any background or reason whatsoever. That happens all the time, but it's a real eye-opener when you realize it.

I already wrote about the time I got facial paralysis and how that many-months experience changed part of the view I had on many things. For one, I gained insight into how my stepdaughter struggled with stuff I couldn't understand before. To put yourself in the shoes of someone else is regrettably not always possible. At least most of the time with stuff that really matter.

Learning the Lesson Again

Something I may have realized but forgot again is that you should not take things for granted. At least I, for one, shouldn't.

I'm relearning this regrettably again, as if all the lessons until now were not enough. Now it's not as extreme as last time, but incapacitating nonetheless.

And here I am again, reflecting on how I had taken things like breathing for granted. Because of allergies, I'm having trouble breathing, and it is worse than I thought. I have known people with asthma (although I've not been diagnosed with that), but having trouble breathing without coughing has had several consequences in the last days. One is not being able to sleep. If you wake up every 30 minutes for a 5-minute coughing session, after a couple of those you no longer want to sleep. And there you are, at 4 or 5 am, thinking about what you can do.

The Things We Never Think About

The thing is all that I've taken for granted. I move by bike all the time, and I use a helmet (because I want to keep being able to bike). But this issue makes that harder. When I got the temporal paralysis I could not completely close one of my eyes. That meant I had to use eye-drops to hydrate, and that it hurt riding the bike as I couldnt do anything against the wind. I managed to solve that using a help with a visor. And there I realised that, although the eyes are really important, there are not that many helms with a visor integrated. You may think a bicycle glasses would do the trick. They don´t, at least for my use case. And I tried a lot of them. I finally found an ALPINA SOHO VISOR, and that solved my issue. I still use it even now, although I can close my eye again. It protects my eyes from wind, insects and dirt, and works great with my normal glasses. Why do I write this? Because until the moment I had an issue with my eyes, I never even thought about how useful a Helment with an integrated visor could be.

I work using the computer, and for that I use a lot of senses. I have to see, hear, breathe, and touch. All things I never think about, until I have an issue with one of them (like not being able to close my eye). If one is missing you have to adapt, and that is a lot of effort. If two are missing, it gets harder. But what about having issues with all of them? In that case you cannot adapt by yourself. You have to depend on others. And not just to adapt your way of working, living and being, but you also have to depend on others to consider your use case.

Let's take for example the accessible web. How accessible is a website? Can it be read in high and low contrast, with screen readers? Do your images have descriptive and helpful alt texts? Do you have ARIA labels? There are a lot of variables that make a website accessible or not. It's the same for many other things.

Let's say you have a physical disability and little strength. A heavy door won't allow you to enter or leave a place. You have trouble in your knees and cannot go up the stairs? You will at some point stop trying.

Building a World for Everyone

Taking Thingsfor GrantedPersonalExperienceAccessibilityAwarenessInclusiveDesignexperiencessolutionsBenefits EveryoneUniversal Design:Designing for edge casesoften improves usabilityfor everyoneBreathingDifficultiesEyeParalysisMobilityChallengesHelmet withVisorAccessibleWebsitesAccessibleArchitectureChallenged byDevelopsLeads toCreatesCreatesCreatesReduces

Regrettably, most of the world is built and set up by people that are used to taking things for granted. Myself included sometimes. You realize such things when there is construction on the street that leaves no space for a wheelchair. Or when there are stairs without a railing to help yourself. You see this also in pharmaceuticals, where the instructions and contraindications are so small people with difficulty reading cannot read them at all.

When you build while taking things for granted, you are building a world that only works for people without any issues. And there are no such people. You may think nothing will happen to you, and I hope that it doesn't. But I thought the same and I've been proven wrong again and again.

Even if just for being egoistic and thinking about how to help a future self have fewer problems should anything happen to you, it is always good to not take things for granted. Your future self will be grateful, as one thing that is sure is that everyone gets old.

Of course, doing this implies higher cost and more resources and time, but you should at least think about it. Sometimes the difference is not so big and you will open a door for those that are in different situations you haven't even thought about. And this will be a lot of trial-and-error if you haven't being in those situations yourself. Just remember that your experience pool is filled with successes and failures. I know for one that I still have a lot of work for this site to be accessible.

That's all for this reflection. Mostly this was to remind myself of this and give it some thought.

Thinking Out Lout: Failing Forward - Get it wrong to get it right

Sometimes you have to get it wrong to get it right. Being scared of being wrong freezes you and prevents you from learning.

I'm sometimes told I learn fast, but what I really do is get stuff wrong really fast until I get it right -if I ever get it right-. I do a lot of experiments and little projects. I try stuff out and many times it just doesn't work. Until it does.

The Invisible Learning Process

The thing is that most of the time people don't see—or don't want to see—the failed tries. Somehow they are blind to the learning process and just see the result. But that result is, in reality, the consequence of many trials and errors until I get it right.

One example is all the how-to articles on this site. If I had gotten it right the first time, I wouldn't need to write it down. After all, I was right on the first try. If I found the solution to a problem quickly and easily, I wouldn't need to document it at all, because there was no effort required.

But what in reality happens is that I tried a lot of times before getting it right. Or that I forgot what I did before because I (wrongly) thought I would not forget and decided to not write it down. In most cases I read a lot of articles which, for my particular context, did not work on the first try. That's why I wrote it down in a way that I can use again in the future, should the same situation in a similar context arise. I just don't like to do the thinking and problem-solving twice, which is why I prefer to take the time to write it down (at least most of the time) instead of just trusting my memory.

Standing on the shoulders of others

And that's also why I link to references when I can or when I remember to write them down at the end of many articles on this site. I managed to solve something because someone else wrote it down, for whatever reason, somewhere for others to find. Be it a book, a forum, a mailing list, another personal website, it was out there for others to find. And given that I was able to find it, I managed to find one more piece to solve my puzzle. Maybe not the complete solution, but it adds up.

And sometimes just reading about how others think, or what others have tried also helps me in my research and problem-solving process. Reading is like talking and discussing with someone. It's seeing his or her thoughts on "paper." Sometimes in a stream-of-consciousness kind of way and sometimes as a structured written essay. In any way, it's an already-processed experience that is being made available for others to read and add to their "experience pool."

Building Your Experience Pool

Experience PoolInputsProblem-Solving AbilityFrustration ManagementDetermines how quicklythe pool fillsSuccessFailureExperimentReading...Trial & ErrorStudyPracticeExperimentationadds dropsadds dropsadds dropsadds dropsenables

And I think that part is interesting. Everyone has an experience pool, large or small. And I think the speed at which that pool grows and expands depends on two things: number of experiences and personal frustration-management.

The more you can allow and accept that you won't get it right the first few (or many) times and the more you are willing to keep trying (always within some limits) without getting frustrated, the more small (and big) experiences you add to your pool, the more "this-is-not-the-way-to-do-it" learnings you accumulate.

And what we sometimes fail to understand, or fail to see, is that those small experiences later relate to each other and make the pool. And when you get into it, you will not be asking about the origin of each individual drop. You will just swim and enjoy and make use of the water that's in the pool.

It's the same with experiences. Once you have them and accept them, it won't matter if they were "fails" or "rights." They will just be experiences, drops of water that make up your pool. And that pool will always be there in moments of need.

So, like I said at the beginning: sometimes you have to get it wrong to get it right, failing forward, so to speak.

Have you thought about experiences that way?

Thinking Out Loud - The Power of Metrics

Numbers have power and meaning - and I’m not talking about math here, just numbers themselves. Math is a whole different beast.

Ok, maybe it is not "just" numbers, but I’m talking about numbers as metrics. 100 is just a number, but it means completely different things if we’re talking about kilos or euros. The same number carries different weight and meaning for men versus women, for heavyweight lifters versus runners versus doctors. Numbers gain their power when they have context and information. They help us make plans ("I’ll save 100 euros monthly"), they can discourage us ("How did I reach 180 kilos? I was 80 just two months ago"), they show our progress ("We’ve grown our customer base by 20%"), and they can bring satisfaction ("Finally reached my goal weight of 75kg!").

Numbers vs. Metrics

Numbers by themselves don’t help us as much as numbers with units. And numbers with units are less useful when isolated. When we can compare numbers (against our history or others), that’s when they really shine. They provide a sense of progress and status. If the number moves, depending on the direction and what it measures, we feel better or worse than before - we become happy or frustrated.

If our numbers are better or worse than those of other people, we develop a sense of status, achievement, or belonging ("I’m now a runner because I managed to run X km in Y minutes").

Context Matters

Metrics are great, but only if we understand them. And for that, we need information and context. Is 100 kg body weight good or bad? It depends on your muscles, your stature, your body composition, your gender, your physical activity, your health, and many other factors. Many studies[1] show that focusing solely on weight can be misleading. The same applies to everything else. Is saving 100€ good? Sure! Unless you’ve stopped eating to save that money.

There are countless examples of how numbers help us when we understand them in context with sufficient information. I want to emphasize the words "context" and "information" again. In my last reflection, I wrote about information access, and before that about [the power of defaults](/the-power-of-defaults).

We now have access to abundant information (in much of the world, at least), but it’s so easy to avoid engaging with it thoughtfully (by relying on AI or treating social media posts as gospel). Even with access to vast data and numbers (and I’m sometimes guilty of this too), truly using and understanding them requires effort and time. And putting in work isn’t something everyone enjoys. Even if we frame it as "playing with numbers," it still takes focus and time to understand them properly. Once you do, you’ll be steps ahead of where you were. You’ll likely make better decisions and understand more of the big picture. But it takes time and effort - something we often take for granted or that prefer dedicate to something else.

Technology Changes Our Metrics

Technological advances help us in many ways, but they sometimes make us less capable (AKA dumber and lazier). It’s so easy to skip the work and still get by (at least temporarily) that we don’t notice how this erodes abilities we once had that got us where we are. And please don’t read that as if I were against technology…​ all the contrary. But I would say we need to be aware of how it influences and changes us, for good or bad.

The E-bike Example

A basic example is comparing an e-bike and a regular bike. I have both. For a specific route, my regular bike took me 30 minutes. Then I got an e-bike (a cargo bike) that took just 25 minutes and required less effort. Great! I arrived faster and sweated less.

Meanwhile, I got a smartwatch that calculates a PAI score[2] (a numeric value) and learned how it worked. After almost 2 years, my e-bike broke down, so I returned to my regular bike. Suddenly, my PAI jumped by 140 points in a single day!

That number means nothing if you don’t know what PAI is (again: numbers, context, and information). It’s a metric that quantifies your physical activity - like an index where higher is better. It calibrates according to your heart rate, meaning that as you get fitter, you need to work harder to earn the same points. With the e-bike, I was getting fewer than 10 points daily, sometimes none. Now I’m earning 140 points for essentially the same journey. Same distance, different tool, vastly different health impact.

E-bikes offer substantial health benefits, with research confirming that riding an electric bicycle provides significant health advantages compared to remaining sedentary.[3]

Choosing Better Metrics

So let’s extrapolate. If there’s such an enormous difference in health impact just from my choice of bike, what might happen if I change the metrics I use to optimize other aspects of life?

What if I coded with the metric of "write once, well-commented and documented" instead of "fast and under the make-it-work mentality"?

What if you read with a note-taking, explain-to-others approach? You’ll take longer, certainly, but you’ll also gain more from the same activity! Instead of reading a book 4 times and quickly forgetting the material, you’d have notes you understand and perhaps even a blog post explaining your understanding that you can share with others. When your memory gets foggy, you can refer back to these resources. The information gets embedded in your brain because you dedicated time, discussed topics with yourself, reflected on them, and made meaningful notes. It wasn’t wasted time - but this requires measuring success by different metrics, not just time and money.

Numbers Reveal What We Miss

Sometimes metrics help us understand things we wouldn’t otherwise grasp, like my PAI score. I noticed I was more out of breath covering the same distance on the regular bike, but I wouldn’t have thought the difference was so huge without seeing the numbers.

The same applies to habits. If you track time spent (automatically, like with screen time and app usage features), you’ll likely discover you don’t have a time problem but a priority and planning problem. It’s not that you don’t have time (though some genuinely don’t, and they should ignore this part), but that you haven’t set goals or metrics to follow. Three hours daily for a year adds up to 1000+ hours! That’s quite a lot and makes you (hopefully) reconsider the impact of certain decisions.

But ultimately, this reflection is about numbers as metrics and their power.

What do you think? Do they impact your life?

How to Fix Nextcloud Sync Issues with File Modification Dates on Linux

TL;DR

Nextcloud Desktop Sync can fail when file modification dates are earlier than creation dates. Fix it by updating timestamps with touch -m for individual files, directories, or recursively through your entire sync folder.

The Problem

Recently, I ran into a weird issue with my Nextcloud Desktop sync on Linux (the issue was in Aurora Linux, but should apply for other distros and systems). Some files simply refused to sync. After some investigation (aka: read the logs in the app), I discovered the culprit: the modification dates on some files were earlier than their creation dates, confusing Nextcloud's synchronisation algorithm.

I still don´t know how that happened. The files in questions were from a data export from ChatGPT, which had a creation date of, say, 2025-03-16 and a modification date of 1980-01-01, which does not make any sense.

The Solution

The fix turned out to be surprisingly simple: updating the modification timestamps of the problematic files and folders using the touch command.

touch is a command used to update the access date and/or modification date of a computer file or directory. - https://en.wikipedia.org/wiki/Touch_(command)

For a Single File

To update just one file:

touch -m /path/to/file

For a Directory (Just the Folder Itself)

To update just the directory's modification date (not the contents):

touch -m /path/to/directory

Important: touch -m folder only updates the timestamp of the folder itself, not any of the files inside it.

For All Files in a Directory

To update all files in a directory:

find /path/to/directory -type f -exec touch -m {} \;

How I Fixed My Sync

In my case, I had a folder structure with 51 files that wouldn't sync. Here's what I did:

  1. First, I identified which folders weren't syncing by checking the Nextcloud client logs
  2. I ran the following commands on my problematic folders and folders:

    bash find /path/to/directory -type f -exec touch -m {} \; touch -m /path/to/directory

  3. I issued a re-sync through the Nextcloud desktop client or closed and reopened the Desktop App to restart the sync process.

After a few minutes (depending on how many files you have), everything should be synced perfectly!

Why This Works

The touch -m command updates the modification time of a file or directory to the current time. By doing this, you ensure that:

  1. All modification dates are now newer than creation dates

which should, in turn, do the following

  1. The updated timestamps trigger Nextcloud to recognize the files as "changed"
  2. The sync algorithm properly processes them during the next sync cycle

Happy syncing!

FlexSearch Plugin for Nikola: New Version 0.2 Released

TLDR

Version 0.2 of the FlexSearch Plugin for Nikola is now available! This update adds page indexing, improved search relevance, better UI, and more configuration options. You can now search both posts and pages, with results showing content type badges and better formatting.

What's New in Version 0.2?

It's been a while since I first released the FlexSearch plugin, and I've been using it a lot and working on improvements (I developed the plugin because I use this site as a personal repository).

Version 0.2 brings several new features and improvements (IMHO) that make the search functionality more powerful and flexible.

Major New Features

1. Page Indexing

The original version only indexed posts (and I did not care until I wanted to find a page and couldn't find it), but now you can also index pages! This means you can search through all your content, not just blog posts. This is particularly useful for me as I published a lot of additional resources for my book "The Digital Marketer's Playbook," and they could not be found using the search. It took me a while but it now works 😁

You can control this with 3 new configuration options:

  • FLEXSEARCH_INDEX_POSTS (default: True) - Whether to index posts
  • FLEXSEARCH_INDEX_PAGES (default: False) - Whether to index pages
  • FLEXSEARCH_INDEX_DRAFTS (default: False) - Whether to index draft content

2. Improve the search index

The search index now includes titles, content, and tags (which you can change in the source code), making search results much more relevant. The plugin uses a multi-field search approach that combines all these elements when searching:

searchIndex.add(key, data[key].title + " " + data[key].content + data[key].tags + " " + data[key].content);

The data[key].content part is commented out by default as I was getting just too many results.

This means that searching for a tag will find all posts with that tag, and searching for words in titles will give those results higher priority. This is thanks to the flexsearch library.

3. Content Type Display

Search results now show whether an item is a post or a page, with styled badges. This makes it easier to distinguish between different types of content in your search results. (this is at least important for me)

Just search something on this sile, for example nikola to see how it behaves.

4. Keyboard Shortcuts

I've added some convenient keyboard shortcuts. I don't really remember why I did not add this before:

  • Press ESC to close the search overlay
  • Press Enter to submit your search

5. Better URL Handling

The plugin now uses absolute paths (/search_index.json) instead of relative ones, which fixes an issue with path resolution on different pages. It also adds ?utm_source=internal_search to result URLs, making it easier to track internal search usage in analytics, if you use any.

Technical Improvements

For those who like to tinker with their plugins, I've also made some technical improvements:

  • Added console logging for easier debugging
  • Updated to the latest FlexSearch v0.8.0 library, released 4 days ago by pure coincidence
  • Added better error handling throughout the code
  • Improved code organization and structure (or at least I hope so)

How to Update

IMPORTANT: Remember to update the javascript snippets with the new versions. Make sure you read the README and make a backup of your plugin version before updating.

If you're already using or if you want to install the FlexSearch plugin, you can use:

nikola plugin -i flexsearch_plugin

After updating, rebuild your site with nikola build -a to generate the updated search index.

Configuration

To enable page indexing, add these lines to your conf.py:

# FlexSearch Plugin Configuration
FLEXSEARCH_INDEX_POSTS = True  # Default is True
FLEXSEARCH_INDEX_PAGES = True  # Default is False
FLEXSEARCH_INDEX_DRAFTS = False  # Default is False

What's Next?

As I'm using the plugin myself, and I don't plan to migrate my site from Nikola anytime soon, I will at least keep maintaining the plugin to meet my needs.

That may include:

  • Better mobile support, although the snippets and css are already responsive and work for me)
  • More customization options for search results (maybe some filters)
  • Anything I find useful while I use this.

If you have suggestions or encounter any issues, feel free to open an issue with a pull request on the Nikola Plugins repository.

References

(Quick-note) RSS Feed Reader in Linux with Nextcloud News Integration

Researching for a Linux RSS Feed Reader (although, as after-thought, I don´t really know/ remember why I needed this if I use mainly my phone and tablet to read and the News Web-app in Nextcloud works really well), I started checking what was available.

My first thought was using Akregator, but it does not seem to have support to sync with Nextcloud News (as per this issue. There and some other places and there RSS Guard was mentioned as an alternative. The first screen in RSS Guard is a choice of provider

Pasted image 20250316155326

which looks good.

I added my credentials and Nextcloud URL in the next screen and clicked the button "Fetch articles for all feeds" to download the articles.

Pasted image 20250317191704

Everything just works. Kudos to Martin Rotter and his collaborators!

You can download it at https://github.com/martinrotter/rssguard

On Linux, you can install it using Flatpak from Flathub.