Installing Syncthing on a Raspberry Pi

Installing Syncthing on a Raspberry Pi is a straightforward process that involves a few steps to get it up and running. Here’s a guide to help you install Syncthing on your Raspberry Pi:

  1. Update Your System
    Before installing any new software, it’s a good practice to update your system. Open a terminal and run the following commands:
    sudo apt update
    sudo apt upgrade
  2. Add the Syncthing Repository
    Syncthing isn’t available directly from the default Raspberry Pi OS repositories, so you’ll need to add the Syncthing repository. First, download release PGP keys:
    curl -s -o syncthing-release-key.asc
  3. Add it to a keyring:
    sudo mv syncthing-release-key.asc /etc/apt/trusted.gpg.d/
  4. Add the Syncthing repository to your sources list:
    echo "deb syncthing stable" | sudo tee /etc/apt/sources.list.d/syncthing.list
  5. Install Syncthing
    Now that the repository is added, update your package lists and install Syncthing:
    sudo apt install syncthing
  6. Configure Syncthing to Run Automatically
    Syncthing can be configured to start automatically for your user. Use systemctl to enable and start the Syncthing service. Replace pi with your username if you are not using the default Raspberry Pi OS user:
    systsudo systemctl enable syncthing@pi.service
    sudo systemctl start syncthing@pi.service
  7. Accessing Syncthing
    By default, Syncthing runs on port 8384. You can access it through a web browser at http://localhost:8384 if you are on the Raspberry Pi, or at http://<Raspberry-Pi-IP>:8384 from another computer on the same network.
  8. Adjust Firewall Settings (if necessary)
    If you have a firewall enabled on your Raspberry Pi, make sure to allow traffic on port 8384. This command can open the necessary port:
    sudo ufw allow 8384
  9. Update and Maintenance
    Syncthing will be updated along with your system packages whenever you run sudo apt update and sudo apt upgrade.

Now you should have Syncthing installed and running on your Raspberry Pi. You can start adding devices and sharing folders as per your requirements.

Cathy Directory Printer is amazing

The directory print software named Cathy is pretty amazing. It was designed for creating file catalogues of different disks, so that it is easy to search for your files even if the physical disk is not currently attached to the computer.

What makes this software really weird is that it hasn’t been updated since 2009 -but it still works great! And being so old, the file size is ridiculously small, just 153 KB.

Here is a link for downloading Cathy 2.33:

This is the basic workflow:

Run the Cathy.exe file and go to the “Catalog” tab. Click on the three dots … to point it to a disk to scan and click “add”.

After a little while the disk has been indexed and a new .caf file has been created for it, right next to the Cathy.exe. Now you can browse to that directory to see what files it has, even if the disk is no longer connected.

This allows you to search hundreds of disks at once, without any of them being physically present. Just go to the “Search” tab and type your search term to the “pattern” field and hit search. Cathy will breeze through all your catalogs and show you all matches from all the different drives. Now you know which drive you need to connect, in order to get to your file.

The .caf files are interchangeable, so you can create them on a different computer and just copy and paste them next to Cathy.exe and it will “see” them when you restart the program.

Free script: Easy focusing while animating a camera in Blender

While animating a camera, it is often desirable to quickly set the focus on a specific object. The “Focus on Object” field in Blender is incredibly useful for this, allowing the quick selection of a focus object via the eyedropper tool. However, once this link is set, it remains permanent. If the link is severed, the focus on the specified object is lost. I sought a solution that would allow me to capture the correct focus distance based on the focus object before severing the link. This led me to develop a script that not only calculates but also sets the “Focus Distance” field automatically to the appropriate value. This script triggers when the focus object property changes from empty to populated. It then calculates the distance, logs it in the console, and sets the focus distance. Now, you can break the link to the focus object while retaining the focus based on the last calculated distance.

How to Use the Script:

  1. Open Blender and Set Up Your Scene: Ensure your scene contains at least one camera and other objects you might want to focus on.
  2. Open the Scripting Tab: Navigate to the ‘Scripting’ tab in Blender to access the Python console and scripting area.
  3. Paste the Script: Copy the script provided below and paste it into a new text editor within the Scripting tab.
  4. Run the Script: After pasting, run the script by pressing the ‘Run Script’ button. This will activate the script, and it will start monitoring changes to the focus object property.
  5. Use the Camera’s Focus Object Field: Go to your camera’s object data properties and under the depth of field settings, use the eyedropper to select a focus object from your scene. The script will automatically update the “Focus Distance” to match the distance to the selected object.
  6. View the Output: Check the console (located in the same Scripting tab) to see the printed focus distance. This value is also automatically set in the camera’s “Focus Distance” field.
  7. Sever the Link If Desired: You can now sever the link to the focus object without losing the focus distance, as it has been set manually based on the last calculation.
  8. Here is the script:

import bpy

# Global variable to keep track of the last focus object
last_focus_object = None

def update_focus_distance_if_needed(scene):
    global last_focus_object
    camera =

    if camera and
        current_focus_object =

        # Check if the focus object was None and now is set
        if last_focus_object is None and current_focus_object is not None:
            # Calculate and update the focus distance
            camera_location = camera.matrix_world.translation
            target_location = current_focus_object.matrix_world.translation
            focus_distance = (target_location - camera_location).length

   = focus_distance
            print(f"Focus distance updated to: {focus_distance}")

        # Update the last known focus object
        last_focus_object = current_focus_object

def register_handlers():
    global last_focus_object
    # Initialize last focus object
    camera =
    if camera and
        last_focus_object =

    # Add handler
    print("Handler registered to monitor focus object changes.")


Solution to “Incorrect function” when trying to initialize a disk in the Windows Disk Manager

I cloned my Windows installation to a larger M.2 disk and then put the old smaller M.2 disk into an external usb enclosure. But no computer would recognize it properly. The Windows Disk Manager wanted me to “initialize” the disk but neither the MBR nor the GPT option would work, they both throw an error saying “incorrect function”.

I finally decided to try the disk in another usb enclosure, and it started working immediately. It turns out I was trying to use a SATA M.2 disk in a enclosure meant for NVMe SSD enclosures. While they looked the same, the functionalities were different and not interchangeable.

So the lesson is that you need to make sure you have the right kind of enclosure depending on if your disk is a SATA M.2 or NVMe M.2 SSD disk.

SATA M.2: These SSDs use the Serial ATA (SATA) interface protocol, which is the same interface used by traditional 2.5-inch SATA SSDs and hard drives. They typically have slower transfer speeds compared to NVMe SSDs, but are still much faster than traditional hard drives.

NVMe SSD: NVMe stands for Non-Volatile Memory Express. This is a newer interface protocol designed specifically for SSDs to take advantage of the high-speed PCIe bus. NVMe SSDs offer significantly faster transfer speeds compared to SATA SSDs, making them ideal for high-performance applications and tasks that require fast data transfer rates.

Both SATA M.2 and NVMe M.2 SSDs are physically installed into the same M.2 slot inside a computer. The difference lies in how they communicate with the motherboard once installed.

The M.2 slot is a small, form-factor slot on the motherboard specifically designed to accommodate M.2 SSDs. This slot can support both SATA and NVMe M.2 SSDs, but the SSDs themselves use different interface protocols once connected.

So, regardless of whether you have a SATA M.2 SSD or an NVMe M.2 SSD, you would physically install it into the same M.2 slot on your motherboard. However, the interface protocol and speed capabilities differ between the two types of SSDs.

Automating the import of hundreds of sprites to Construct

I’m making a game where an area of ground is broken piece by piece. I managed to create a python script that uses a voronoi pattern to shatter my image into several small irregular pieces. Here’s how that looked:

I then needed to import those 200 pieces into Construct. I figured out that if I set the position of each piece to 0,0, they would form the full image perfectly. After that I can just crop the pieces to their actual pixels and things work really nicely: the voronoi jigsaw puzzle comes together like it should.

The only pain point I had left was importing 200 sprites one by one into Construct. I knew that I could drag them all at the same time on top of Construct, which would create an animation. But I needed to create several individual sprites instead of animation frames.

The real life saver in this situation turned out to be the Project Folder feature in Construct (works best in Chrome), since it gives direct access to the project file structure. So here are the steps I performed and the scripts I used:

Please don’t attempt this with your production code, instead start a new empty Construct project and save it as a Project Folder on your local hard disk

1. Use a Python script to loop through all the image files in a folder and have it generate the JSON files Construct expects to have in the objectTypes folder. Here is the script for that (zipped due to security considerations). To run that, just unzip, place it in the same folder with the images, open a terminal there and type: python and hit enter. A bunch of JSON files should appear which you should copy to your Project Folder’s objectTypes folder.

2. Next the project.c3proj file needed to have the files listed in the items array in this manner:

“objectTypes”: {
“items”: [

So made a script to generate the array. Note that this is a very simple script and could be improved to support more files name conventions. At the moment it is just adding an incrementing number at the end of each image name. This script will output a simple array in a file called names.txt. Copy the array to your project.c3proj file.

3. The images needed to be renamed with -default-000.png appended to their file name. Time for another script, run this similarly in the folder with the images. After that I copied the images into the images folder inside the Project Folder.

4. That’s basically it but I also wanted the sprites already placed in the layout at coordinates 0,0 so I wrote one more script to do that. Run this script where you have your JSON files (that we generated earlier) and it will give you a new file called new_layout.json. Take the “instances” array from the generated file and merge it with your Layout 1.json file (which can be found in the layouts folder).

Now just reload the project and something magical happens: all your images will appear in the project and in the layout! Even if it’s hundreds or even thousands of images.

So there we have it. This workflow is obviously not useful if you just need to import a small number of sprites. But if you needs hundreds, then this can definitely save you some frustrating manual labor.