Packaging RedNotebook for Mac OS X with PyInstaller

RedNotebook by Jendrik Seipp is one of my favourite free open-source multi-platforms applications.

It is a digital version of the good old lab notebook, that is usually red, and that is often used by scientists and researchers in labs around the world. It can be used to log experiment results, to take meeting notes, to manage a to do list, to write thoughts on a specific issue, to doodle, and the list of options goes on and on.

Analogue red notebooks are great, however, they are missing a crucial feature, namely, the ability to search for a specific word, or a combination of words. Another drawback on the analogue notebooks is size, weight, storage space needed. And if you are running a lab for 20 years, you must have many notebooks taking so much space in the office, and again looking for a specific result, or a specific idea that you noted in your notebook several years ago is a protracted process.

On the other hand rednotebook, the app, have all the features of analogue notebooks, with the added value that comes with the digital age, the search feature, the easy to navigate calendar, and the possibility to keep multiple-backups of the entire record regularly, and if ability to copy/paste text, images, code snippets, diagrams and tables.

A quick Google search for the terms “Agenda” or “Notes keeping apps” will yield many result. All looking sleep and attractive, teaming with killer features, integration with other apps and so on. So why rednotebook? Why settle for what seems to be a lesser tool at the first glimpse ?

The answer is a result of a 30+ years of experience as a multi-platform power user of IT solutions.

Basically when choosing a software/tool to keep notes for decades then the software should:

  1. Stores the notes as raw text (so that it is indexible and searchable with standard string search tools)
  2. Stores the data primarily locally (not remotely)
  3. Stores the data in an open standard format (to avoid data-locking).

This way, if the software you are using discontinued, you will still be able to search through the files and will still be able to find what you are looking for without the need for that App. This will also make it possible to migrate the alternative software.

rednotebook satisfies all three rule, on top of that, it is a free (free as in freedom) open-source software that is free of charge, it was developed for Linux. However, it can be ported to Windows, and also to Mac OS X (with a small manual effort)

In this blog post, I detail the steps I took to bundle rednotebook for Mac OS X using PyInstaller.

Preparing the prerequisites:

We need to install GTK+ for Mac OS X. The easy way to do it, is to use brew.

If you don’t have brew installed please install brew first. More on installing brew can be found on the official brew website: here: https://brew.sh/

Once brew is installed we will use it to install GTK3 and other required/optional tools, such as enchant for spell checking.

$ brew install gtk+3 gtksourceview3 enchant

Now let’s clone the repository to a special directory in our home folder

$ mkdir ~/Documents/workspace
$ cd ~/Documents/workspace
$ git clone https://github.com/jendrikseipp/rednotebook

Now let’s create a virtual environment for rednotebook to keep it isolated from the public environment

$ pip3 install -U pip
$ cd ~/Documents/workspace/rednotebook
$ python3 -m venv venv
$ ./venv/bin/activate
(venv)$

Now that the virtual environment has been activate, let’s install the required python packages:

(venv)$ pip3 install -U pygobject pyyaml

At this stage rednotebook should run if ./run was invoked:

(venv)$ ./run

(If that did not work. Please let me know so that I can improve this blog post).

Bundling rednotebook

Now let’s discuss bundling the rednotebook python code so that it runs as an app on Mac OS X. Towards that purpose we will use PyInstaller.

“PyInstaller bundles a Python application and all its dependencies into a single package. The user can run the packaged app without installing a Python interpreter or any modules. PyInstaller supports Python 3.7 and newer, and correctly bundles many major Python packages such as numpy, matplotlib, PyQt, wxPython, and others.” You can read more on the official website: https://pyinstaller.org/en/stable/

To use PyInstaller we need to install it first:

(venv)$ pip3 install -U pyinstaller

We also need to make sure all files required for the bundled version are there. After some experimentation I found that all but one required files are already available in the ./rednotebook/files and the rednotebook/images folders. The only missing file is the .icns which contains an icon of the app in different resolutions.

Generate the .icns file

Starting with the rednotebook.svg file we will generate a high resolution png version of the icon with a command-line invocation of Inkscape. If you don’t have Inkscape installed, install it with brew:

$ brew install inkscape

Change to the correct folder and invoke inkscape to generate a high resolution png from the svg file

$ cd ./rednotebook/images/rednotebook-icon
$ inkscape -w 1024 -h 1024 rednotebook.svg -o rn-1024.png

Then we will use sips to generate all .png versions of the icon with all necessary resolutions.

$ mkdir rn.iconset
$ sips -z 16 16 rn-1024.png --out rn.iconset/icon_16x16.png
$ sips -z 32 32 rn-1024.png --out rn.iconset/icon_16x16@2x.png
$ sips -z 32 32 rn-1024.png --out rn.iconset/icon_32x32.png
$ sips -z 64 64 rn-1024.png --out rn.iconset/icon_32x32@2x.png
$ sips -z 128 128 rn-1024.png --out rn.iconset/icon_128x128.png
$ sips -z 256 256 rn-1024.png --out rn.iconset/icon_128x128@2x.png
$ sips -z 256 256 rn-1024.png --out rn.iconset/icon_256x256.png
$ sips -z 512 512 rn-1024.png --out rn.iconset/icon_256x256@2x.png
$ sips -z 512 512 rn-1024.png --out rn.iconset/icon_512x512.png
$ cp rn-1024.png rn.iconset/icon_512x512@2x.png 

Finally we will combine all the generated versions using iconutil to generate the rednotebook.icns file we wanted:

$ iconutil -c icns rn.iconset
$ rm -rf rn.iconset
$ mv rn.icns rednotebook.icns

Invoking pyinstaller

Now we are ready to invoke pyinstaller. Make sure the virtual environment is sourced (activated) and use the following command on rednotebook project root.

(venv)$ pyinstaller --name "rednotebook" 
            -i ./rednotebook/images/rednotebook-icon/rednotebook.icns
            --windowed 
            --add-data ./rednotebook/files:files/ 
            --add-data ./rednotebook/images:images/ 
            ./rednotebook/journal.py

PyInstaller will create the build and the dist folders as well as a rednotebook.spec file.

The build folder is temporary and can be deleted, the rednotebook.spec file contains the configurations used in the latest pyinstaller invocation. To invoke pyinstaller with the same arguments it is sufficient to type:

(venv)$ pyinstaller rednotebook.spec

Edit the rednotebook.spec file to add or change the configurations

The bundled app can be found in the dist folder.

Congratulations.