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, analysis)
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186 | def post(config, analysis: dict):
"""
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)
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 idx in top.index:
text = text + f"<li><a href=\"{top['url'][idx]}\">This toot</a> from "\
f"<a href=\"{top['account.url'][idx]}\">{top['account.display_name'][idx]} "\
f"({tag}{top['userid'][idx]})</a>" \
f" had {top['reblogs_count'][idx]} 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 idx in top.index:
text = text + f"<li><a href=\"{top['url'][idx]}\">This toot</a> from "\
f"<a href=\"{top['account.url'][idx]}\">{top['account.display_name'][idx]} "\
f"({tag}{top['userid'][idx]})</a>" \
f" had {top['favourites_count'][idx]} 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 idx in top.index:
text = text + f"<li><a href=\"{top['url'][idx]}\">This toot</a> from "\
f"<a href=\"{top['account.url'][idx]}\">{top['account.display_name'][idx]} "\
f"({tag}{top['userid'][idx]})</a>" \
f" had {top['replies_count'][idx]} replies.</li>\n"
text = text + "</ol>"
tootlist.append(text)
post_toots(config, tootlist)
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 | def post_toots(config, tootlist) -> int:
"""
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.warn(f"dry_run is true. Not actually tooting")
else:
try:
t = Tooter(config, 'post')
except Exception as e:
logger.critical("Failed to create 'post' Tooter")
logger.critical(e)
return 0
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
for toot in tootlist:
visibility = root_visibility if n == 1 else thread_visibility
text = toot + f"<p>#{hashtag} {n}/{len(tootlist)+1}</p>"
if dry_run:
print(f"{text}\nVisibility: {visibility}")
next_status['id'] = n
else:
try:
next_status = t.status_post(text, visibility=visibility, language='en',
in_reply_to_id=reply, content_type="text/html")
logger.info(f"anchor: {n}")
except Exception as e:
logger.error(f"anchor post")
logger.error(e)
return n # Now boost about boosts
n = n+1
reply = next_status
logger.info(f"Posted {n} toots")
if dry_run:
print(HTML_TAIL)
return n
|