Mnemosyne 2.3 Headless Syncing Setup on Debian Jessie

🕓 Jul 19, 2016

Introduction

Debian Jessie ships Mnemosyne 2.2.x. As of Mnemosyne 2.3.x, the sync feature was much revamped, and a headless sync (& web server) modes were introduce into the application - making it possible to more easily use remote headless servers for central storage and synchronization. Rough instructions to set up mnemosyne 2.3.x in debian jessie follow.

Download & Installation

Download mnemosyne from their project page here.

The instructions in the README shipped with the project are fairly clear, following them and use python setup.py install as root to install mnemosyn.

Note: There is a bug in creating new empty databases in headless mode. If you need to create a new database on the headless machine, be sure to edit mnemosyne/libmnemosyne/databases/SQLite.py and make sure that in the function load(), if a path doesn’t exist self.new(path) is called instead of new(path). (In version 2.3.6, this is on line 343). @TODO: File a bug report, write a patch :)

For those of you who encounter this issue and aren’t super familiar with what the problem looks like, you will see a stacktrace roughly as follows when mnemosyne is started on the command line.

Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 1082, in run
self.function(*self.args, **self.kwargs)
File "/usr/local/lib/python2.7/dist-packages/Mnemosyne-2.3.6-py2.7.egg/EGG-INFO/scripts/mnemosyne", line 109, in heartbeat
File "build/bdist.linux-x86_64/egg/mnemosyne/libmnemosyne/databases/SQLite.py", line 343, in load
return new(path)
NameError: global name 'new' is not defined

Configuration

For the headless machine, I prefer to create a username for mnemosyne and use a custom data directory.

$> useradd mnemosyne
$> mkdir /home/mnemosyne
$> su mnemosyne
$> mkdir cd ~/mnemosyne-data

Configuring Mnemosyne Sync Credentials

Note: Mnemosyne seems to destroy the remote_access_username and remote_access_password when started in headless mode. I will update this article when I understand the problem and/or have a solution. @TODO Bug report!

There isn’t proper configuration file support for the remote access user and password setings, and the mainterner proposes a couple of different options.

In a headless setup, it’s not really convenient to do the configuration locally on your machine in a headed environment, and I found that sqlite3 wasn’t able to load the mnemosyne configuration database, config.db.

As a work around I use the python shell to set the information.

$> cd /path/to/mnemosyne-data-directory
$> python
>>> import sqlite3
>>> conn = sqlite3.connect('config.db')
>>> c = conn.cursor()
>>> print c.execute('select * from config where key like "%remote%"').fetchall()
[(u'remote_access_username', u"''"), (u'remote_access_password', u"''")]
>>> c.execute('update config set value = "YOUR PASSWORD" where key = "remote_access_password"')
<sqlite3.Cursor object at 0x7f6bc9916ab0>
>>> c.execute('update config set value = "YOUR USERNAME" where key = "remote_access_username"')
<sqlite3.Cursor object at 0x7f6bc9916ab0>
>>> conn.commit()
>>> conn.close()
>>> # just an extra check to see the file was written.
>>> conn = sqlite3.connect('config.db')
>>> c = conn.cursor()
>>> print c.execute('select * from config where key like "%remote%"').fetchall()
[(u'remote_access_username', u'YOUR USERNAME'), (u'remote_access_password', u'YOUR PASSWORD')]
>>> conn.close()

Copying over an existing mnemosyne database

Mnemosyne only supports syncing to a new empty database as a client. You can’t copy an existing database and sync to it right away. If you don’t have an existing database, you can skip this step and start mnemosyne.

  • Create a backup of your mnemosyne database (you can use Save-As in mnemosyne)
  • Copy mnemosyne.db, mnemosyne.db-journal, and the folder mnemosyne.db_media to the mnemosyne data directory on your headless server
    • Note: mnemosyne.db is whatever database name you were using before and may be different
    • Create a new database with the same name and path, overwriting the original mnemosyne.db on your local machine

Starting Mnemosyne as an Headless Sync-Server

$> cd ~/mnemosyne-data
$> mnemosyne -d /path/to/mnemosyne-data --sync-server --debug=/home/mnemosyne/mnemosyne.log /home/mnemosyne/mnemosyne-data/mnemosyne.db &

The final argument with mnemosyne.db should be the name of whatever database you want to use.

Synchronizing on the Client Side

Set the host, port (default 8512), username, and password then hit sync. You need to start from an empty database of the same name as the database running on the headless server.

If you run into username errors, mnemosyne may be over-writing the username/password on the headless version (see above for more details). In that case, you can just use an empty username and password or not use it all until a solution is found.