Shitposter Club Blog

Moon Man

Gnu Social Pretty Formatted User Backup

How to create a pretty-printed backup for non-technical users

There is already a facility in GNU Social for making a full backup of a user. In practice this means just a giant dump of XML or JSON. This might be OK for a technical user, but Iʼll show you how you can take that JSON and turn it into a slightly more aesthetically-pleasing HTML document the user can just load in their browser and enjoy.

Normal Export

Here is how a normal export works:

php ${GNU_SOCIAL}/scripts/backupuser.php --json --nickname=someuser > someuser.json

This will get you a megabytes-large file of unformatted JSON. Good for some, maybe…

Extract Relevant Fields

Next we will extract only fields we care about. We will use the tool https://stedolan.github.io/jq/ to do this.

sudo apt-get install jq

cat someuser.json | \
jq -M '{ "posts":  [ .items | select(.object.objectType = "comment")
| .[] | { "content": .content, "published": .published } ] }' \
> filtered.json

Now weʼve got a file that is an array of only the status text, and the timestamp of when it was posted. To explain the jq command:

  1. we are grabbing the “item” key of the someuser.json JSON, whose value is an array
  2. selecting only those elements where nested inside the element “object”.“objectType” equals “comment” (there are other types as well, we are ignoring them)
  3. wrapping those results in an array
  4. then grabbing only the “content” and “published” fields
  5. and finally, wrapping the entire array of results in an object, with the key “posts”.

At this point, you have a smaller subset of JSON you could give to a user, and they might be happy. But we are going to go one step further, and turn it into HTML for them.

Turn JSON into HTML

First, we will install some python tools. I assume you already have Python and pip.

pip install --user jinja2-cli

Jinja2 is a templating language that can use JSON as input data. We will use this to convert to HTML. To do that we will need to create a template file.

<html>
<head>
<style>
    table { table-layout:fixed; width:100%;}
    table, th, td {
        border: 1px solid black;
        word-wrap: break-word;
    }
    tr td:first-child{
        width:20em;
    }
</style>
</head>
<table>
{% for post in posts %}
<tr>
<td>
{{ post.published }}
</td>
<td>
{{ post.content }}
</td>
</tr>
{% endfor %}
</table>

…and name it backup.j2

Next we will run the data through the template:

export PYTHONIOENCODING=utf_8
jinja2 --format=json backup.j2 filtered.json > backup.html

Now we have a nicely formatted HTML version of the notice export. Obviously, you can style your template however you like.