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
# poetry run python3 ./tootsnoop/__init__.py --help
# #+END_SRC
: usage: ./tootsnoop/__init__.py [-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: 2025-02-02
: ·
:
If you haven't used [[https://python-poetry.org/][Python Poetry]] before, you might also be able to do
this with a classic virtualenv or similar. However, I won't maintain
the =requirements.txt= any more. Please extract them yourself from the
=pyproject.py= which is used by Poetry.
Setup with Poetry:
1. [[https://python-poetry.org/docs/][Install Poetry itself]]: =pipx install poetry=
2. Install the project's dependencies via =poetry install=
3. Use my =poetry run ...= command from above to run =tootsnoop=
* Example Output
: poetry run python3 /home/vk/src/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):
: poetry run python3 /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/
: poetry run python3 /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/
poetry run python3 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.1.tar.gz
(13.5 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.1.tar.gz.
File metadata
- Download URL: tootsnoop-2026.3.1.1.tar.gz
- Upload date:
- Size: 13.5 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 |
1771301a86d255351ec20d1de509b5ba973bbf25fb8073a60521b61b8db49977
|
|
| MD5 |
e50e83309df3c8a355eadb4edca3e147
|
|
| BLAKE2b-256 |
51721e8765d3603d72648c1c265c9cedd5b174e989494f4ef746616f93740e27
|
File details
Details for the file tootsnoop-2026.3.1.1-py3-none-any.whl.
File metadata
- Download URL: tootsnoop-2026.3.1.1-py3-none-any.whl
- Upload date:
- Size: 9.8 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 |
15577f98fb9ac36d52faa83e07811255661d1e93b835a080cf2d6aeec6a53eb0
|
|
| MD5 |
a8031a2680a309f44351a37514576931
|
|
| BLAKE2b-256 |
149239d4b05841773b2f50f420160361b90acf53b266860bba9073886d89c041
|