Module: post¶
The post command actually uses your credentials to post a few toots of the stats we
gathered. I find it very useful to set dry_run to True in the [post] part of the
config and see what it's going to post before I actually post.
The JSON files from analyse need to exist.
Dry Run¶
Running a dry run will spit out the toots in HTML format on stdout. I like to use w3m to display it on the terminal.
mastoscore inifile.ini post | w3m -T text/html
Module for posting toots that summarise what's happening.
NOTE: You can have values like api_base_url, username, or cred_file
in the [post] section of the config file and they will
override the general options. I use that for testing, where I will fetch()
from one server, but post() to another so I don't muck-up people's timelines
with test toots.
If post:dry_run is set to True, then it only posts the toots on stdout, it
doesn't actually toot them.
post(config)
¶
Expects the config options for the program and the output dictionary from the analyse()
method. Connects to the target server and posts the various summaries. Calls
post_toots() to actually post (or display) the toots.
Parameters¶
- config: A ConfigParser object from the config module
- tootlist: A list of strings which are the toots to be tooted. This module doesn't change them.
Config Parameters Used¶
NOTE: This method is very unusual in that it pulls config values from many sections of the config file. Most other methods restrict themselves to only their own section.
| Option | Description |
|---|---|
graph:start_time |
Start time of the event we're looking at. ISO8601 formatted date string. |
graph:end_time |
End time of the event we're looking at. ISO8601 formatted date string. |
analyse:top_n |
How many top toots we will be reporting |
analyse:tag_users |
Whether we tag users with an @ or not |
Returns¶
Number of toots tooted.
Source code in mastoscore/post.py
def post(config):
"""
Expects the config options for the program and the output dictionary from the analyse()
method. Connects to the target server and posts the various summaries. Calls
[`post_toots()`](module-post.md#mastoscore.post.post_toots) to actually post (or display) the toots.
# Parameters
- **config**: A ConfigParser object from the [config](module-config.md) module
- **tootlist**: A list of strings which are the toots to be tooted. This module doesn't change them.
# Config Parameters Used
**NOTE**: This method is very unusual in that it pulls config values from many sections
of the config file. Most other methods restrict themselves to only their own section.
| Option | Description |
| ------- | ------- |
| `graph:start_time` | Start time of the event we're looking at. ISO8601 formatted date string.
| `graph:end_time` | End time of the event we're looking at. ISO8601 formatted date string.
| `analyse:top_n` | How many top toots we will be reporting
| `analyse:tag_users` | Whether we tag users with an @ or not |
# Returns
Number of toots tooted.
"""
debug = config.getint('post', 'debug')
# I don't like having 'post' read from 'analyse' but I'm too lazy to do better
top_n = config.getint('analyse', 'top_n')
tag_users = config.getboolean('post', 'tag_users')
logger = logging.getLogger(__name__)
logging.basicConfig(format='%(levelname)s\t%(message)s')
logger.setLevel(debug)
analysis = read_json(config, 'analysis')
if not analysis:
logger.error("Couldn't open JSON file")
return []
tootlist = []
text = analysis['preamble']
text = text + "<ul>" \
f"<li>{analysis['num_toots']}</li>" \
f"<li>{analysis['most_toots']}</li>" \
"</ul><p>Additional details are replies to this toot.</p>"
tootlist.append(text)
top = analysis['max_boosts']
tag = "@" if tag_users else ""
text = f"<p>The top {top_n} boosted toots:</p><ol>"
for post in top:
text = text + f"<li><a href=\"{post['url']}\">This toot</a> from "\
f"<a href=\"{post['account.url']}\">{post['account.display_name']} "\
f"({tag}{post['userid']})</a>" \
f" had {post['reblogs_count']} boosts.</li>\n"
text = text + "</ol>"
tootlist.append(text)
# Now post about faves
top = analysis['max_faves']
text = f"<p>The top {top_n} favourited toots:</p><ol>"
for post in top:
text = text + f"<li><a href=\"{post['url']}\">This toot</a> from "\
f"<a href=\"{post['account.url']}\">{post['account.display_name']} "\
f"({tag}{post['userid']})</a>" \
f" had {post['favourites_count']} favourites.</li>\n"
text = text + "</ol>"
tootlist.append(text)
# Now post about replies
top = analysis['max_replies']
text = f"<p>The top {top_n} most-replied-to toots:</p><ol>"
for post in top:
text = text + f"<li><a href=\"{post['url']}\">This toot</a> from "\
f"<a href=\"{post['account.url']}\">{post['account.display_name']} "\
f"({tag}{post['userid']})</a>" \
f" had {post['replies_count']} replies.</li>\n"
text = text + "</ol>"
tootlist.append(text)
tootids = {}
tootids['tootlist'] = post_toots(config, tootlist)
# This will open up the hashtag-results.json file and insert all the IDs for all
# the toots into it. That will be used in the blog and in the graph posting.
update_json(config, 'analysis', tootids)
return len(tootlist)
post_toots(config, tootlist)
¶
Given the config and list of toots, create a Tooter and toot them.
Parameters¶
- config: A ConfigParser object from the config module
- tootlist: A list of strings which are the toots to be tooted. This module doesn't change them.
Config Parameters Used¶
| Option | Description |
|---|---|
post:dry_run |
Boolean. If True, print HTML on stdout. If False, really post toots. |
post:root_visibility |
The very first post in the thread will be set to this visibility. Usually 'public'. Must be a valid string for mastodon statuses which currently are: public, unlisted, private, and direct. |
post:thread_visibility |
All toots are tooted as replies to each other. root → first → second, etc. All posts other than the root will have thread_visibility visibility. |
post:hashtag |
We tag all the toots with the hashtag. |
post:api_base_url |
Implicitly used when we create our Tooter |
post:cred_file |
Implicitly used when we create our Tooter |
Returns¶
Number of toots tooted.
TODO¶
- Take the maximum post size into account and break into multiple toots.
Source code in mastoscore/post.py
def post_toots(config, tootlist) -> List[str]:
"""
Given the config and list of toots, create a [Tooter](module-tooter.md) and toot them.
# Parameters
- **config**: A ConfigParser object from the [config](module-config.md) module
- **tootlist**: A list of strings which are the toots to be tooted. This module doesn't change them.
# Config Parameters Used
| Option | Description |
| ------- | ------- |
| `post:dry_run` | Boolean. If True, print HTML on stdout. If False, really post toots. |
| `post:root_visibility` | The very first post in the thread will be set to this visibility. Usually 'public'. Must be a valid string for [mastodon statuses](https://docs.joinmastodon.org/methods/statuses/#form-data-parameters) which currently are: `public`, `unlisted`, `private`, and `direct`. |
| `post:thread_visibility` | All toots are tooted as replies to each other. root → first → second, etc. All posts other than the root will have `thread_visibility` visibility. |
| `post:hashtag` | We tag all the toots with the hashtag. |
| `post:api_base_url` | Implicitly used when we create our [Tooter](module-tooter.md) |
| `post:cred_file` | Implicitly used when we create our [Tooter](module-tooter.md) |
# Returns
Number of toots tooted.
# TODO
- Take the maximum post size into account and break into multiple toots.
"""
debug = config.getint('post', 'debug')
dry_run = config.getboolean('post', 'dry_run')
root_visibility = config.get('post', 'root_visibility')
thread_visibility = config.get('post', 'thread_visibility')
hashtag = config.get('post', 'hashtag')
logger = logging.getLogger(__name__)
logging.basicConfig(format='%(levelname)s\t%(message)s')
logger.setLevel(debug)
if dry_run:
logger.warning(f"dry_run is true. Not actually tooting")
t = None
else:
try:
t = Tooter(config, 'post')
except Exception as e:
logger.critical("Failed to create 'post' Tooter")
logger.critical(e)
return []
reply = None
next_status = {}
n = 1
# if we're a dry run, put HTML header and footer so we can pipe it
# to `w3m -T text/html` for pretty viewing
if dry_run:
print(HTML_HEAD)
# First an anchor post with some details
uidlist = []
for toot in tootlist:
visibility = root_visibility if n == 1 else thread_visibility
text = toot + f"<p>#{hashtag} {n}/{len(tootlist)+1}</p>"
if t is None:
print(f"{text}\nVisibility: {visibility}")
next_status['id'] = n
uidlist.append(str(n))
else:
try:
next_status = t.status_post(text, visibility=visibility, language='en',
in_reply_to_id=reply, content_type="text/html")
uidlist.append(str(next_status))
logger.info(f"anchor: {n}")
except Exception as e:
logger.error(f"anchor post")
logger.error(e)
return uidlist # Now boost about boosts
n = n+1
reply = next_status['id']
logger.info(f"Posted {n} toots")
if dry_run:
print(HTML_TAIL)
return uidlist