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, anddirect. | 
| 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_visibilityvisibility. | 
| 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