Skip to main content

Statisics of the last x days for your Mastodon messages

Project description

* tootsnoop - You Mastodon message statistics tool

# #+BEGIN_SRC sh :results output :wrap src
# uv run ./tootsnoop/__init__.py --help
# #+END_SRC

: usage: tootsnoop [-h] --days DAYNUMBER --count COUNTNUMBER
: [--verbose]
:
: This tool prints a brief statistics about your Mastodon messages of the latest DAYNUMBER days.
:
: The output constist of:
: - timestamp (now)
: - number of toots retrieved
: - your current number of followers
: - top COUNTNUMBER most boosted messages (or less if no more found)
: - top COUNTNUMBER most favored messages (or less if no more found)
: - top COUNTNUMBER most replied messages (or less if no more found)
:
: Example usages:
: poetry run python3 PATH/TO/tootsnoop/__init__.py --days 7 --count 10
: … prints the topmost 10 entries for the last 7 days
:
: One-time setup:
:
: 1. Configure you access token:
: - Login to your Mastodon instance in your web browser.
: - Go to Preference → Development and click on "New Application".
: - Enter "tootsnoop" as the name of the new application and modify the scopes:
: - You will need only read permissions, no write permissions.
: - Submit and click on "tootsnoop".
: - Copy your new Access Token.
: - Paste this Access Token into a "access_token.txt" file in the main directory of this tool.
: 2. Configure your mastodon instance:
: - Paste the main URL of your Mastodon instance into a "instance_url.txt" file in the main
: directory of this tool.
: - It looks like: "https://graz.social"
:
: options:
: -h, --help show this help message and exit
: --days DAYNUMBER Number of days to look back
: --count COUNTNUMBER Number of topmost entries to show
: --verbose Enable verbose mode
:
: :copyright: (c) by Karl Voit <tools@Karl-Voit.at>
: :license: GPL v3 or any later version
: :URL: https://gitlab.com/publicvoit/tootsnoop
: :bugreports: via https://gitlab.com/publicvoit/tootsnoop/-/issues
: :version: 2026-03-01
: ·
:

Setup with [[https://docs.astral.sh/uv/][uv]]:

1. Install uv itself
2. Use =uv --project /path/to/tootsnoop run path/to/tootsnoop/__init__.py= command from above to run =tootsnoop=

Or:

Install via pip:

: pip install tootsnoop

... and start =tootsnoop -h=

* Example Output

: uv run tootsnoop/tootsnoop/__init__.py --days 7 --count 10

<2025-02-02 Sun 16:04> Summary of Mastodon Activity over the last 7 days:

- Toots retrieved: 40
- Current number of followers: 2936

*Top 10 Most Boosted Messages*

- 16 Boosts: [[https://graz.social/users/publicvoit/statuses/113929726001217896][<2025-02-01 Sat 17:07>]] This is golden: a non-tech guy is using [[https://graz.social/tags/Emacs][#Emacs]] and [[https://graz.social/tags/orgmode][#orgmode]] in his work life as well as at home: [[https://irreal.org/blog/?p=12755][https://irreal.org/blog/?p=12755]] • He amazes his colleagues with the usual Emacs foo other tools can not offer. • [[https://graz.social/tags/Fun][#Fun]] to read.
- 7 Boosts: [[https://graz.social/users/publicvoit/statuses/113928326035465290][<2025-02-01 Sat 11:11>]] Informatik ist [[https://graz.social/tags/Allgemeinbildung][#Allgemeinbildung]] und sollte [[https://graz.social/tags/Pflichtfach][#Pflichtfach]] werden\\ [[https://www.derstandard.at/story/3000000254867/informatik-ist-allgemeinbildung-und-sollte-pflichtfach-werden?ref=shpost#posting-1133628571][https://www.derstandard.at/story/3000000254867/informatik-ist-allgemeinbildung-und-sollte-pflichtfach-werden?ref=shpost#posting-1133628571]] • [[https://graz.social/tags/Informatik][#Informatik]] ist nicht nur ein [[https://graz.social/tags/Schulfach][#Schulfach]]. • Informatik erklärt die Grundlagen unserer modernen Welt und macht Menschen zu mündigen Bürgern, die sich beispielsweise nicht von [[https://graz.social/tags/Algorithmen][#Algorithmen]] ausnutzen lassen (wollen). • Außerdem sorgt es dafür, dass wir in [[https://graz.social/tags/Europa][#Europa]] eine [[https://graz.social/tags/Zukunft][#Zukunft]] in dieser modernen Welt haben werden und nicht nur die passiven Datenlieferanten für außereuropäische Großkonzerne spielen, die uns damit massiv ausnutzen. • [[https://graz.social/tags/Schule][#Schule]] [[https://graz.social/tags/Bildung][#Bildung]] [[https://graz.social/tags/NAWI][#NAWI]] [[https://graz.social/tags/Naturwissenschaft][#Naturwissenschaft]] [[https://graz.social/tags/Zukunft][#Zukunft]] [[https://graz.social/tags/SozialeNetzwerke][#SozialeNetzwerke]] [[https://graz.social/tags/SozialeNetze][#SozialeNetze]] [[https://graz.social/tags/facebook][#facebook]] [[https://graz.social/tags/instagram][#instagram]] [[https://graz.social/tags/tiktok][#tiktok]] [[https://graz.social/tags/digitaleSouver%C3%A4nit%C3%A4t][#digitaleSouveränität]]
- 1 Boosts: [[https://graz.social/users/publicvoit/statuses/113929755885888564][<2025-02-01 Sat 17:15>]] Marcin ‘mbork' Borkowski about his version of [[https://graz.social/tags/pomodoro][#pomodoro]] which he calls [[https://graz.social/tags/tomato][#tomato]]: [[https://mbork.pl/2025-02-01_ketchup.el][https://mbork.pl/2025-02-01_ketchup.el]] • Well, it sounds to me that the pomodoro method is not working for him for the same reasons it was not working for me - although I only tried for a brief period of time. • Marcin found some interesting variant. I would have declared this method non-functional for me instead. 😈 • [[https://graz.social/tags/PIM][#PIM]] [[https://graz.social/tags/timemanagement][#timemanagement]] [[https://graz.social/tags/productivity][#productivity]] [[https://graz.social/tags/pomodorotechnique][#pomodorotechnique]] [[https://graz.social/tags/Beeminder][#Beeminder]]

*Top 10 Most Favored Messages*

- 23 Favorites: [[https://graz.social/users/publicvoit/statuses/113929726001217896][<2025-02-01 Sat 17:07>]] This is golden: a non-tech guy is using [[https://graz.social/tags/Emacs][#Emacs]] and [[https://graz.social/tags/orgmode][#orgmode]] in his work life as well as at home: [[https://irreal.org/blog/?p=12755][https://irreal.org/blog/?p=12755]] • He amazes his colleagues with the usual Emacs foo other tools can not offer. • [[https://graz.social/tags/Fun][#Fun]] to read.
- 9 Favorites: [[https://graz.social/users/publicvoit/statuses/113928326035465290][<2025-02-01 Sat 11:11>]] Informatik ist [[https://graz.social/tags/Allgemeinbildung][#Allgemeinbildung]] und sollte [[https://graz.social/tags/Pflichtfach][#Pflichtfach]] werden\\ [[https://www.derstandard.at/story/3000000254867/informatik-ist-allgemeinbildung-und-sollte-pflichtfach-werden?ref=shpost#posting-1133628571][https://www.derstandard.at/story/3000000254867/informatik-ist-allgemeinbildung-und-sollte-pflichtfach-werden?ref=shpost#posting-1133628571]] • [[https://graz.social/tags/Informatik][#Informatik]] ist nicht nur ein [[https://graz.social/tags/Schulfach][#Schulfach]]. • Informatik erklärt die Grundlagen unserer modernen Welt und macht Menschen zu mündigen Bürgern, die sich beispielsweise nicht von [[https://graz.social/tags/Algorithmen][#Algorithmen]] ausnutzen lassen (wollen). • Außerdem sorgt es dafür, dass wir in [[https://graz.social/tags/Europa][#Europa]] eine [[https://graz.social/tags/Zukunft][#Zukunft]] in dieser modernen Welt haben werden und nicht nur die passiven Datenlieferanten für außereuropäische Großkonzerne spielen, die uns damit massiv ausnutzen. • [[https://graz.social/tags/Schule][#Schule]] [[https://graz.social/tags/Bildung][#Bildung]] [[https://graz.social/tags/NAWI][#NAWI]] [[https://graz.social/tags/Naturwissenschaft][#Naturwissenschaft]] [[https://graz.social/tags/Zukunft][#Zukunft]] [[https://graz.social/tags/SozialeNetzwerke][#SozialeNetzwerke]] [[https://graz.social/tags/SozialeNetze][#SozialeNetze]] [[https://graz.social/tags/facebook][#facebook]] [[https://graz.social/tags/instagram][#instagram]] [[https://graz.social/tags/tiktok][#tiktok]] [[https://graz.social/tags/digitaleSouver%C3%A4nit%C3%A4t][#digitaleSouveränität]]
- 2 Favorites: [[https://graz.social/users/publicvoit/statuses/113929755885888564][<2025-02-01 Sat 17:15>]] Marcin ‘mbork' Borkowski about his version of [[https://graz.social/tags/pomodoro][#pomodoro]] which he calls [[https://graz.social/tags/tomato][#tomato]]: [[https://mbork.pl/2025-02-01_ketchup.el][https://mbork.pl/2025-02-01_ketchup.el]] • Well, it sounds to me that the pomodoro method is not working for him for the same reasons it was not working for me - although I only tried for a brief period of time. • Marcin found some interesting variant. I would have declared this method non-functional for me instead. 😈 • [[https://graz.social/tags/PIM][#PIM]] [[https://graz.social/tags/timemanagement][#timemanagement]] [[https://graz.social/tags/productivity][#productivity]] [[https://graz.social/tags/pomodorotechnique][#pomodorotechnique]] [[https://graz.social/tags/Beeminder][#Beeminder]]
- 1 Favorites: [[https://graz.social/users/publicvoit/statuses/113923808732027509][<2025-01-31 Fri 16:02>]] [[https://graz.social/tags/Apple][#Apple]]-Besitzer sind schon ein seltsames Völkchen. • Offenbar ist es nicht möglich, ein Apple-Silicon-MacBook aufzuklappen ohne, dass es gestartet wird: [[https://www.heise.de/news/Fuer-Tastaturhygieniker-So-bleibt-das-MacBook-beim-Oeffnen-aus-10265728.html][https://www.heise.de/news/Fuer-Tastaturhygieniker-So-bleibt-das-MacBook-beim-Oeffnen-aus-10265728.html]] (von wegen Frickelsystem) • Wenn die wüssten, was ich alles bei meinem (Linux-lenovo-)Notebook alles anpassen darf ... 😈

*Top 10 Most Replied Messages*

- 3 Replies: [[https://graz.social/users/publicvoit/statuses/113928326035465290][<2025-02-01 Sat 11:11>]] Informatik ist [[https://graz.social/tags/Allgemeinbildung][#Allgemeinbildung]] und sollte [[https://graz.social/tags/Pflichtfach][#Pflichtfach]] werden\\ [[https://www.derstandard.at/story/3000000254867/informatik-ist-allgemeinbildung-und-sollte-pflichtfach-werden?ref=shpost#posting-1133628571][https://www.derstandard.at/story/3000000254867/informatik-ist-allgemeinbildung-und-sollte-pflichtfach-werden?ref=shpost#posting-1133628571]] • [[https://graz.social/tags/Informatik][#Informatik]] ist nicht nur ein [[https://graz.social/tags/Schulfach][#Schulfach]]. • Informatik erklärt die Grundlagen unserer modernen Welt und macht Menschen zu mündigen Bürgern, die sich beispielsweise nicht von [[https://graz.social/tags/Algorithmen][#Algorithmen]] ausnutzen lassen (wollen). • Außerdem sorgt es dafür, dass wir in [[https://graz.social/tags/Europa][#Europa]] eine [[https://graz.social/tags/Zukunft][#Zukunft]] in dieser modernen Welt haben werden und nicht nur die passiven Datenlieferanten für außereuropäische Großkonzerne spielen, die uns damit massiv ausnutzen. • [[https://graz.social/tags/Schule][#Schule]] [[https://graz.social/tags/Bildung][#Bildung]] [[https://graz.social/tags/NAWI][#NAWI]] [[https://graz.social/tags/Naturwissenschaft][#Naturwissenschaft]] [[https://graz.social/tags/Zukunft][#Zukunft]] [[https://graz.social/tags/SozialeNetzwerke][#SozialeNetzwerke]] [[https://graz.social/tags/SozialeNetze][#SozialeNetze]] [[https://graz.social/tags/facebook][#facebook]] [[https://graz.social/tags/instagram][#instagram]] [[https://graz.social/tags/tiktok][#tiktok]] [[https://graz.social/tags/digitaleSouver%C3%A4nit%C3%A4t][#digitaleSouveränität]]
- 1 Replies: [[https://graz.social/users/publicvoit/statuses/113929726001217896][<2025-02-01 Sat 17:07>]] This is golden: a non-tech guy is using [[https://graz.social/tags/Emacs][#Emacs]] and [[https://graz.social/tags/orgmode][#orgmode]] in his work life as well as at home: [[https://irreal.org/blog/?p=12755][https://irreal.org/blog/?p=12755]] • He amazes his colleagues with the usual Emacs foo other tools can not offer. • [[https://graz.social/tags/Fun][#Fun]] to read.
- 1 Replies: [[https://graz.social/users/publicvoit/statuses/113923817200519535][<2025-01-31 Fri 16:04>]] [[https://bildung.social/@vermutliCHEmie][@vermutliCHEmie]] You would need to define the problem which is caused by that. I don't see any. • Furthermore: I don't use such tool-proprietary annotation workarounds. I annotate using my BOOX NoteAir which writes its annotations in the PDF directly - as PDF annotations. • YMMV.
- 1 Replies: [[https://graz.social/users/publicvoit/statuses/113923808732027509][<2025-01-31 Fri 16:02>]] [[https://graz.social/tags/Apple][#Apple]]-Besitzer sind schon ein seltsames Völkchen. • Offenbar ist es nicht möglich, ein Apple-Silicon-MacBook aufzuklappen ohne, dass es gestartet wird: [[https://www.heise.de/news/Fuer-Tastaturhygieniker-So-bleibt-das-MacBook-beim-Oeffnen-aus-10265728.html][https://www.heise.de/news/Fuer-Tastaturhygieniker-So-bleibt-das-MacBook-beim-Oeffnen-aus-10265728.html]] (von wegen Frickelsystem) • Wenn die wüssten, was ich alles bei meinem (Linux-lenovo-)Notebook alles anpassen darf ... 😈

* Optional: Convert Result to a Different Syntax
:PROPERTIES:
:CREATED: [2025-02-04 Tue 16:42]
:END:

If you don't like [[https://gitlab.com/publicvoit/orgdown/][orgdown syntax]] as output, you might convert the script output on-the-fly via [[https://pandoc.org/][pandoc]].

Here is an example for [[https://karl-voit.at/2017/09/23/orgmode-as-markup-only/][the inferior Markdown syntax]] (in one flavour of many):

: uv --project /path/to/tootsnoop run /path/to/tootsnoop/__init__.py --days 1 --count 3 | pandoc --from org --to markdown --wrap=none

* Optional: Integration into Emacs Org-mode
:PROPERTIES:
:CREATED: [2025-02-04 Tue 16:50]
:END:

In case you want to invoke tootsnoop from within [[https://karl-voit.at/orgmode/][Emacs Org-mode]], you can use a source block like that:

: #+BEGIN_SRC sh :results output raw
: cd /path/to/tootsnoop/
: uv --project /path/to/tootsnoop run /path/to/tootsnoop/tootsnoop/__init__.py --days 7 --count 10 --inactive
: #+END_SRC

If you've installed tootsnoop via =pip= this might probably work (not tested):

: #+BEGIN_SRC sh :results output raw
: tootsnoop --days 7 --count 10 --inactive
: #+END_SRC

* Optional: A Reccuring Job That Generates a Weekly Statistics
:PROPERTIES:
:CREATED: [2025-02-06 Thu 19:45]
:END:

This is particularily interesting to people using [[https://karl-voit.at/orgmode/][Emacs Org-mode]]: I
want a weekly statisics generated each Sunday at 23:59.

For that, I created a shell script that contains the command to generate that statistics:

#+BEGIN_SRC bash
#!/usr/bin/env bash

TEMPFILE=$(mktemp) ## used to storing the tootsnoop output
NOW_IN_ORG_TIMESTAMP="<`date '+%Y-%m-%d %a %H:%M'`>" ## time-stamp for Org heading
TARGET_REFILE_ORG_FILE="notes.org"
TARGET_REFILE_HEADING="Weekly Mastodon statistics"

## adding a custom refile code snippet that
## moves the heading to the desired heading
## after inspecting and on invoking C-c C-c:
echo -e "\n#+BEGIN_SRC emacs-lisp\n(my-org-refile \"${TARGET_REFILE_ORG_FILE}\" \"${TARGET_REFILE_HEADING}\")\n#+END_SRC\n\n" > ${TEMPFILE}

## generate the statistics:
cd /path/to/tootsnoop/
uv --project /path/to/tootsnoop run /path/to/tootsnoop/__init__.py --days 7 --count 10 --inactive 2>&1 >>${TEMPFILE}
if [ "$?" != 0 ]; then
echo "tootsnoop execution had an issue."
appendorgheading --output ~/org/inbox.org \
--level 1 \
--title "${NOW_IN_ORG_TIMESTAMP} Weekly Mastodon Statistics: ERROR" \
--filecontent ${TEMPFILE} \
--daily --quiet
exit 1
fi

## appends a new Orgdown heading to the output file with the statistics as body:
appendorgheading --output ~/org/inbox.org \
--level 1 \
--title "${NOW_IN_ORG_TIMESTAMP} Weekly Mastodon Statistics" \
--filecontent ${TEMPFILE} \
--blocktype NONE --nosanitize \
--nodaily --quiet

rm "${TEMPFILE}" ## remove temporary file
#end
#+END_SRC

This script requires:

- my other script: https://github.com/novoid/appendorgheading
- e.g., via =pip install appendorgheading=
- an Orgdown file where the results gets appended
- an Orgdown heading title within that Orgdown file where this should get manually refiled to
- proper script paths (please adapt accordingly)

What it does:

- it generates a weekly statistics (7 days, top 10 each) with inactive time-stamps
- a handy babel snippet which refiles the heading to its final destination (after I took a brief look at it in my inbox file)

If you understand, what's going on, this is really a nice way of running tootsnoop. ;-)

* Related Projects
:PROPERTIES:
:CREATED: [2025-02-10 Mon 11:25]
:END:

This is a far-from-complete list of projects with similar goals:

- <2024-09-18 Wed> Sacha Chua did [[https://sachachua.com/blog/2024/09/archiving-public-toots-on-my-blog/][an Elisp implementation of archiving
her toots]]. I might have used her code as an starting point if I had
read it earlier.

- https://mastometrics.com/ is a cool service with analytical
features. I was using the service for many months, even spent a few
Euros for it until it stopped working for me (constantly re-indexing
without showing the most current results). Maybe it's working for
you?

* How to Thank Me

I'm glad you like my tools. If you want to support me:

- Send old-fashioned *postcard* per snailmail - I love personal feedback!
- see [[http://tinyurl.com/j6w8hyo][my address]]
- Send feature wishes or improvements as an issue on GitLab
- Create issues on GitLab for bugs
- Contribute merge requests for bug fixes
- Check out my other cool [[https://github.com/novoid][projects on GitHub]] and [[https://gitlab.com/publicvoit/][GitLab]]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tootsnoop-2026.3.1.2.tar.gz (13.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tootsnoop-2026.3.1.2-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file tootsnoop-2026.3.1.2.tar.gz.

File metadata

  • Download URL: tootsnoop-2026.3.1.2.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tootsnoop-2026.3.1.2.tar.gz
Algorithm Hash digest
SHA256 2bb057d3a6bfa8b2b899e40f857c7429c5f7c8300dec93b172158f0544d053dd
MD5 bab947effdc22ed299b1d176880d1f0c
BLAKE2b-256 26a3d270ff224680e851bbbb2d614dfd4f40fffaf92300a5a2f54492fe3d6d54

See more details on using hashes here.

File details

Details for the file tootsnoop-2026.3.1.2-py3-none-any.whl.

File metadata

  • Download URL: tootsnoop-2026.3.1.2-py3-none-any.whl
  • Upload date:
  • Size: 9.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tootsnoop-2026.3.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 fe070e37a2e8e72d02048a582fff2f3890bb5faf341fbc6d61dd5e69923e93e7
MD5 5a0209c82cd5a6070b7580d4dd249bf7
BLAKE2b-256 f18285b01f6e7475bf99eda9d0e54a513c7c343bd6d50d7c88b26f7b80b8ed4f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page