Jump to content

User:Commander Keane/Wishlist report/wish report.py

From Meta, a Wikimedia project coordination wiki
import pywikibot, os, datetime, re
import mwparserfromhell as mwp

site = pywikibot.Site('meta', 'meta')

category_name = 'Category:Community Wishlist/Wishes' 
cat = pywikibot.Category(site, category_name)

#Take the list and make the wikicode ready for saving to wiki
def genWikicode(list, big_total, req_number):
    preamble_text = """
Discovered from the [[:Category:Community Wishlist/Wishes|Community Wishlist/Wishes]] category. \n
Support votes are extracted from support templates used on the talk page of wishes. \n
This report is English-centric.
"![*]" before the title indicates that a wish hasn't been translated into English. Can be a false positive if baselang isn't en but wish is written in en.
"""
    master_text = str(req_number) + ' wishes found! ' + preamble_text
    master_text = master_text + '\nGenerated ' + str(datetime.datetime.now(datetime.UTC).strftime('%Y-%m-%d %H:%M')) + '\n'
    master_text = master_text + '{| class=\'wikitable sortable\'\n|-\n!Title\n!Talk page (# edits)\n!Status\n!Focus area\n!Order created\n![[File:Symbol support vote.svg|15px]]\n'
    column_names = ['title', 'talk', 'status', 'area', 'order', 'votes']
   
    for line in range(len(list)):        
        master_text =  master_text + '|-\n'

        for name in column_names:
            master_text =  master_text + '| ' + str(list[line][1][name]) + '\n'

    master_text = master_text + '|}'
    master_text = master_text + ' ' #Put page categories here
    return master_text

#Returns string of translated title
def translatedTitle(page_object):
    text = page_object.text
    wikicode = mwp.parse(text)
    templates = wikicode.filter_templates()
    if not templates:
        return 'error'
    else:
        main_template = templates[0]
        en_title = main_template.get("title").value.strip()
        return en_title
    
def count_page_supports(text):

    def filter_content(text):
        text = strip_tag(text, "[Ss]")
        text = strip_tag(text, "[Nn]owiki")
        text = strip_tag(text, "[Ss]trike")
        text = strip_tag(text, "[Dd]el")
        text = re.sub(r"(?s)<!--.*?-->", "", text)
        return text

    def strip_tag(text, tag):
        return re.sub(r"(?s)<%s>.*?</%s>" % (tag, tag), "", text)

    cleaned_text = filter_content(text)
    support_regex = re.compile(
    r"{{\s*(?:%s)(\|.*)?\s*}}" % "|".join(support_templates), re.MULTILINE
    )
    num_votes = len(re.findall(support_regex, cleaned_text))
    return(num_votes)

# List of valid templates
# They are taken from the page Commons:Polling_templates and some common redirects
# https://github.com/Zitrax/FPCBot/blob/master/fpc.py
support_templates = (
    "[Ss]upport",
    "[Pp]ro",
    "[Ss]im",
    "[Tt]ak",
    "[Ss]í",
    "[Pp]RO",
    "[Ss]up",
    "[Yy]es",
    "[Oo]ui",
    "[Kk]yllä",  # First support + redirects
    "падтрымліваю",
    "[Pp]our",
    "[Tt]acaíocht",
    "דעב",
    "[Ww]eak support",
    "[Ww]eak [Ss]",
    "[Ss]amþykkt",
    "支持",
    "찬성",
    "[Ss]for",
    "за",
    "[Ss]tödjer",
    "เห็นด้วย",
    "[Dd]estek",
    "[Aa] favore?",
    "[Ss]trong support",
    "[Ss]Support",
    "Υπέρ",
    "[Ww]Support",
    "[Ss]",
    "[Aa]poio",
)

# Start main work
support_total = 0
number_of_wishes = 0
table = {}

list_new = [page for page in cat.newest_pages(total=None)] #total = 5 for testing, = None for full list
#list_new = [page for page in cat.articles(recurse=False, total=5)]   #total=5 for testing

list_new.reverse()

index = 1

for page in list_new:
    supports = 0
    focus_area = '' #seems to be an optional template parameter
    orig_text = page.text
    wikicode = mwp.parse(orig_text)
    if "{{Community Wishlist/Wish" in wikicode:

        try:
            templates = wikicode.filter_templates()
            
            main_template = templates[0] #Assumes {{Community Wishlist/Wish}} comes first
            title = main_template.get("title").value.strip() #Not currently used, we use Page Title instead
            status = main_template.get("status").value.strip()
            baselang = main_template.get("baselang").value.strip()
            try:
                focus_area = main_template.get("area").value.strip()
                
            except Exception:
                print('No focus area found') #NOT ACTUALLY PRINTING ANYTHING

            link_title = str(page.title())
            #print('Origninal title: ' + link_title)

            en_title = link_title + r'/en' #possible page to visit if orig was LOTE
            disp_title =  link_title[link_title.rfind('/') + 1:] #Default
            en_title_obj = pywikibot.Page(site, title=en_title, ns=0)
            en_ver_exists = en_title_obj.exists()
            
            if en_ver_exists:
                link_title = en_title
                disp_title = translatedTitle(en_title_obj)
                en_translation_needed = False
            elif baselang != 'en':
                en_translation_needed = True
            else:
                en_translation_needed = False

            talk_page = page.toggleTalkPage()
            talk_page_exists = talk_page.exists()
            talk_title = str(talk_page.title())

            if talk_page_exists:
                talk_revs = talk_page.revision_count() #includes bots
                supports = count_page_supports(talk_page.text)
                support_total = support_total + supports
                
            else:
                talk_revs = 0


            wikilinked_title = '[[' + link_title + '|' + disp_title + ']]'
            wikilinked_talk_page_title = '[[' + talk_title + '|' + 'Discuss' + ']] (' + str(talk_revs) + ')'

            if en_translation_needed:
                wikilinked_title = '![*] ' + wikilinked_title

            table[index] = {'title': wikilinked_title, 
                        'talk': wikilinked_talk_page_title, 
                        'status': status, 
                        'area' : focus_area,
                        'votes': supports,  
                        'order': index} 
            index += 1
        except Exception:
            print('Error in a wish found:' + str(page))
    else:
        print("Page skipped, no template found")
        

list_table = list(table.items())
sorted_by_order = sorted(list_table, key = lambda x: x[1].get('order'), reverse=True)
sorted_by_votes = sorted(sorted_by_order, key = lambda x: x[1].get('votes'), reverse=True)
number_of_wishes = len(sorted_by_votes)
final_wikitext = genWikicode(sorted_by_votes, support_total, number_of_wishes)

#Output
file_name = 'wish_report.txt'
with open(file_name, 'w', encoding="utf-8") as f:
    f.writelines(final_wikitext)
pywikibot.info("File " + file_name + ' saved in: ' + os.getcwd())  
pywikibot.info( str(number_of_wishes) + ' wishes were found')
pywikibot.info('From ' + str(number_of_wishes) + ' wishes with talk pages the grand total of support votes is: ' + str(support_total))
pywikibot.info('Generated ' + str(datetime.datetime.now(datetime.UTC).strftime('%Y-%m-%d %H:%M:%S')))