User:Non-robot/userscripts.py

维基百科,自由的百科全书
import pywikibot
import re
import js2py
from urllib.parse import urlparse, parse_qs


def Userskins_js():
    import toolforge
    conn = toolforge.connect('zhwiki_p')
    q = """
    SELECT page_title FROM page WHERE 
      page_title REGEXP "/common\.js|/vector\.js|/monobook\.js|/modern\.js|/timeless\.js|/cologneblue\.js|/vector-2022\.js" and 
      page_title LIKE "%/%.js" and page_namespace=2
    """
    with conn.cursor() as cur:
        cur.execute(q)
    # print(cur)
    userskins_js = []
    for c in cur:
        # print(c[0].decode('utf-8'))
        # 将’User:'与每一行的第0个元素(即page_title)拼接起来
        userskins_js.append('User:' + c[0].decode('utf-8'))
    # print(userskins_js)
    return userskins_js


def Extract_script(text):
    raws = []
    try:
        js = js2py.parse_js(text)
    # print(js)

        for body in js['body']:
            if body.get('type') == 'ExpressionStatement':
                try:
                    # 检查表达式是否调用了名为'importScript'的函数
                    if body.get('expression').get('callee').get('name') == 'importScript':
                        # print(body.get('expression').get('arguments'))
                        for argument in body.get('expression').get('arguments'):
                            # print(argument.get('raw').strip('\'"'))
                            raws.append(argument.get('raw').strip('\'"'))
                    # 检查表达式是否调用了名为'mw.loader.load'的函数
                    elif body.get('expression').get('callee').get('object').get('object').get('name') == 'mw':
                        if body.get('expression').get('callee').get('object').get('property').get('name') == 'loader':
                            if body.get('expression').get('callee').get('property').get('name') == 'load':
                                for argument in body.get('expression').get('arguments'):
                                    # print(argument.get('raw').strip('\'"'))
                                    raws.append(argument.get(
                                        'raw').strip('\'"'))
                except AttributeError:
                    pass
    except Exception as e:
        print(e)
        pass
    # print(raws)
    return raws


def is_url(string):
    """
    判断给定字符串是否为URL。

    :param string: 要检查的字符串
    :return: 如果字符串是URL,则返回True;否则返回False。
    """
    try:
        result = urlparse(string)
        # 检查解析结果中的path和query属性是否都存在
        return all([result.path, result.query])
    except ValueError:
        # 如果解析过程中发生错误,则返回False
        return False


def User_script(script):
    user_script = ''
    # 判断给定的脚本是否为URL
    if is_url(script):
        # 解析URL
        parsed_url = urlparse(script)
        # 获取查询参数
        query_params = parse_qs(parsed_url.query)
        # 判断网络位置是否存在
        if parsed_url.netloc:
            if parsed_url.netloc.split('.')[0] == 'zh':
                # query_params = parse_qs(parsed_url.query)
                if 'title' in query_params:
                    user_script = query_params['title'][0]
                # 否则从路径中获取用户脚本
                else:
                    user_script = parsed_url.path.split('/', 2)[-1]
        # 如果网络位置不存在,则直接从查询参数中获取title值作为用户脚本
        else:
            if 'title' in query_params:
                user_script = query_params['title'][0]
    else:
        # 如果给定的脚本不是一个URL,则直接返回给定的脚本作为用户脚本
        user_script = script
    return user_script


site = pywikibot.Site('wikipedia:zh')
# page = pywikibot.Page(site, "User:Shizhao/common.js")
# text = page.text
# print(text)

script_dict_list = {}
userskins = Userskins_js()
# 遍历用户皮肤列表
for userskin in userskins:
    # 获取用户皮肤页面
    page = pywikibot.Page(site, userskin)
    # print(userskin)
    user = userskin.split('/')[0]
    text = page.text
    # 从页面文本中提取脚本列表
    script_list = Extract_script(text)
    # print(script_list)
    for script in script_list:
        # 提取用户脚本
        user_script = User_script(script)
        # 获取脚本页面
        script_page = pywikibot.Page(site, script)

        try:
            # 检查用户脚本和脚本页面是否存在
            if user_script and script_page.exists():
                if user_script in script_dict_list:
                    # 如果字典中已经包含了该用户脚本,则将用户名添加到对应的值列表中(如果尚未添加)
                    if user not in script_dict_list[user_script]:

                        script_dict_list[user_script].append(user)
                else:
                    # 否则,在字典中创建一个新条目,并将用户名添加到值列表中
                    script_dict_list.setdefault(user_script, []).append(user)
        except Exception as e:
            print(e)
            pass

script_total = []
# 遍历字典中的每个脚本和用户列表
for script, userlist in script_dict_list.items():
    # 计算总用户数
    total = len(userlist)
    # pywikibot.User(site, ).last_edit(userlist)
    # 初始化活跃用户数
    active_users = len(userlist)
    # 遍历用户列表
    for user in userlist:
        # 获取最后编辑时间
        try:
            last_edit = pywikibot.User(site, user).last_edit[2]
            # 如果最后编辑时间距离当前时间超过30天,则将活跃用户数减1
            if (pywikibot.Timestamp.utcnow()-last_edit).days > 30:
                active_users = active_users - 1
        except TypeError:
            active_users = active_users - 1
            # userlist.remove(user)
    # active_users = len(userlist)
    if pywikibot.Link(script, site).parse_site()[1] == 'zh':
        # 将脚本、总用户数和活跃用户数作为元组添加到列表中
        tuble = (script, total, active_users)
        script_total.append(tuble)
# print(script_total)
# 定义表格标题和列名
text = '''
{| class="wikitable sortable" style="text-align: center"
|-
! 脚本 !! 总用户数 !! 活跃用户数 '''
# 定义单元格文本模板
cell_text = '''
|-
| {} || {} || {} '''
cell = ''
# 遍历脚本总用户数和活跃用户数数据
for tuble in script_total:
    # 将脚本名称转换为链接
    script_link = pywikibot.Link(tuble[0])
    # 添加单元格文本
    cell += cell_text.format(script_link, str(tuble[1]), str(tuble[2]))
# 将所有单元格添加到表格中
text = text + cell + '\n|}'

userscripts_page = pywikibot.Page(site, "User:Shizhao/User scripts list")
userscripts_page.text = text
userscripts_page.save("BOT更新用户脚本使用数据")
# print(text)