Change default auto-close on all categories

AI-generated summary

The discussion revolves around changing the default auto-close setting for all categories on a Discourse platform. wjjjjt wants to set all categories to auto-close topics 7 days after the last post and has found a method to apply this to existing topics, but is looking for a way to update the auto-close configuration for all categories at once.

wjjjjt shares a Python script, courtesy of colleague Nimrod, which uses the Discourse API to update the auto-close settings for categories. The script appears to work for the user’s instance, but may not account for categories nested more than one level deep.

We’ve found that our users like to add new comments on very old topics, often only tangentially related to their problem. I would like to set all categories to auto-close topics some time after the last post (7 days – just for the sake of argument!).

I have found this thread on how to apply a new auto-close configuration to existing topics, but I can’t find any way to adjust the auto-close configuration for all categories. I don’t especially want to do this by hand for two dozen (sub-)categories or so.

Perhaps it’d be safe to UPDATE categories SET auto_close_hours = 168, auto_close_based_on_last_post = true; if I had access to the database?

My colleague Nimrod came up with the following script to do this:

#!/usr/bin/env python3
import os
import requests


if __name__ == '__main__':
    username = os.environ['DISCOURSE_API_USERNAME']
    key = os.environ['DISCOURSE_API_KEY']
    s = requests.session()
    s.headers.update({'Accept': 'application/json'})
    s.params.update({'api_key': key, 'api_username': username})
    base = 'https://community.endlessos.com/'
    update = {'auto_close_hours': '168', 'auto_close_based_on_last_post': True}
    parents = s.get(base + 'categories').json()['category_list']['categories']
    for p in parents:
        p.update(update)
        r = s.put(base + 'categories/' + str(p['id']), params=p)
        assert r.ok
        categories = s.get(base + 'categories', params={'parent_category_id': p['id']}).json()['category_list']['categories']
        for c in categories:
            c.update(update)
            r = s.put(base + 'categories/' + str(c['id']), params=c)
            assert r.ok

It seemed to work fine – now that I look at it, if categories can be nested more than one level deep, it will miss third- and subsequent-level categories. On our instance we only have one level of nesting, and I don’t know whether it’s possible to go further in general.