import pywikibot
import sys
from difflib import context_diff
from pywikibot import pagegenerators, Timestamp, textlib
from pywikibot.logging import stdout, warning, error, log, debug, error
import datetime

site = pywikibot.Site('zh', 'wikipedia')
ensite = pywikibot.Site('en', 'wikipedia')
repo = site.data_repository()
cat = pywikibot.Category(site,'Category:活跃维基专题')
gen = pagegenerators.CategorizedPageGenerator(cat)

def last_non_bot_revision(page):
    for entry in page.revisions():
        if entry.user and (not page.site.isBot(entry.user)) and entry.user!="Vizbot":
            return entry
    
def last_revision_ago(page):
    try:
        title = page.title()
        nowtimestamp = pywikibot.site.APISite.server_time(site)
        timestamp = last_non_bot_revision(page).timestamp
        timediff = nowtimestamp - timestamp
#         stdout(f"find {page.title()} last updated {timediff.days} days ago")
        return (title, timediff.days)
    except:
        return None

def all_subpages_revision_ago(page):
    stdout("---")
    stdout(page.title())
    
    
    subpages = pagegenerators.PrefixingPageGenerator(prefix = page.title())
    withTalkpages = pagegenerators.PageWithTalkPageGenerator(subpages)
    latest_revisions_ago = (t for t in map(last_revision_ago, withTalkpages) if t is not None)
    result = min(list(latest_revisions_ago), key = lambda t: t[1])
    stdout(f"last updated page in wikiproject: {result}")
    return result

def replace_status(page, status):
    nextstr = page.text
    templates = textlib.extract_templates_and_params(nextstr, strip=True)
    builder = textlib._MultiTemplateMatchBuilder(site)
    template_regexes = [builder.pattern(i) for i in ("专题", "專題", "WikiProject status", "维基专题状态")]

    for template in templates:
        (tname, tpars) = template
        log(f"found {template}")
        if tname in ("WikiProject status", "专题", "專題"):
            tname = "维基专题状态"
        stdout(f"found template {tname}")
        if tname == "维基专题状态":
            if '1' not in tpars or tpars['1'] != status:
                tpars['1'] = status
                tpars.move_to_end('1', last=False)
                glued = textlib.glue_template_and_params((tname, tpars))
                for template_regex in template_regexes:
                    nextstr = textlib.replaceExcept(nextstr, template_regex, glued, [], count=1)
            break
    return nextstr

def natural_date(daysAgo):
        monthsAgo = daysAgo // 30
        daysRemain=daysAgo-monthsAgo*30
        if(monthsAgo>0):
            if(daysRemain>0):
                return f"{monthsAgo}{daysRemain}天"
            else:
                return f"{monthsAgo}月"
        else:
            return f"{daysRemain}天"

status2zh = {
    "semi-active": "半活跃",
    "defunct": "废弃",
    "inactive": "不活跃",
    "active": "活跃"
}
    
count = 0
pagelimit = 10
update=False
 
checked_page = 0
for page in gen:
    checked_page+=1
    if (count >= pagelimit):
        stdout(f"已更新{count}页,现在退出...")
        break
    #Do something with the page object, for example:
    (latestPage, daysAgo) = all_subpages_revision_ago(page)
    status = "active"
    if(daysAgo > 70):
        status = "semi-active"
    if(daysAgo > 200):
        status = "inactive"
    if(daysAgo > 700):
        status = "defunct"
    nextstr = replace_status(page, status)
    diff = list(context_diff(page.text, nextstr))
    if (len(diff)>0):
        stdout(f"==执行第({count}/{pagelimit})项更新==")
        saveMessage=f"维基专题状态已标记为{status2zh[status]},最新的相关页面[[{latestPage}]]于{natural_date(daysAgo)}天前编辑。"
        stdout(saveMessage)
        for line in diff:
            sys.stdout.write(line)
        if(update==True):
            page.save(saveMessage)
        else:
            print("test mode, change not saved.")
        count +=1
print(f"Checked page {checked_page}")
---
Wikipedia:ACG专题