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
Release history Release notifications | RSS feed
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)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2bb057d3a6bfa8b2b899e40f857c7429c5f7c8300dec93b172158f0544d053dd
|
|
| MD5 |
bab947effdc22ed299b1d176880d1f0c
|
|
| BLAKE2b-256 |
26a3d270ff224680e851bbbb2d614dfd4f40fffaf92300a5a2f54492fe3d6d54
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe070e37a2e8e72d02048a582fff2f3890bb5faf341fbc6d61dd5e69923e93e7
|
|
| MD5 |
5a0209c82cd5a6070b7580d4dd249bf7
|
|
| BLAKE2b-256 |
f18285b01f6e7475bf99eda9d0e54a513c7c343bd6d50d7c88b26f7b80b8ed4f
|