def web(): M = Monitor() try: data = json.loads(request.data.decode("utf8")) if "message" in data: m_date = data["message"]["date"] m_chat_id = int(data["message"]["chat"]["id"]) m_user_id = int(data["message"]["from"]["id"]) if "reply_to_message" in data["message"]: reply_from = data["message"]["reply_to_message"]["from"] from_user_id = reply_from["id"] from_firstname = reply_from["first_name"] from_lastname = "" if "last_name" in reply_from: from_lastname = reply_from["last_name"] if "text" in data["message"]: M.chat_id = m_chat_id m_text = data["message"]["text"] M.log(m_text, logtype='webhook') if not m_text.startswith("/"): return "OK" def checkadmin(): M.cur.execute( """SELECT `name` FROM `admin` WHERE `user_id` = %s""", (str(m_user_id))) rows = M.cur.fetchall() if len(rows) == 0: M.sendmessage("你沒有權限") return None return rows[0][0] def handle_parser(parser, cmd): with io.StringIO() as buf, contextlib.redirect_stdout( buf), contextlib.redirect_stderr(buf): try: args = parser.parse_args(cmd) except SystemExit: output = buf.getvalue() M.sendmessage(output) return None except Exception: M.error(traceback.format_exc()) return None else: return args cmd = shlex.split(m_text) action = cmd[0] cmd = cmd[1:] action = action[1:] action = re.sub(r'@cvn_smart_bot$', '', action) action = action.lower() if action in ['gettoken'] and m_chat_id == m_user_id: if not checkadmin(): return "OK" M.cur.execute( """SELECT `token` FROM `admin` WHERE `user_id` = %s""", (str(m_user_id))) rows = M.cur.fetchall() if len(rows) > 0: M.sendmessage("您的存取權杖是\ncvn_smart(" + rows[0][0] + ")\n使用 /newtoken 取得新的", nolog=True) else: M.sendmessage("查詢存取權杖失敗,使用 /newtoken 取得新的", nolog=True) return "OK" if action in ['newtoken'] and m_chat_id == m_user_id: if not checkadmin(): return "OK" import random import string token = ''.join( random.choice(string.ascii_lowercase + string.digits) for _ in range(32)) M.cur.execute( """UPDATE `admin` SET `token` = %s WHERE `user_id` = %s""", (token, m_user_id)) M.db.commit() M.sendmessage("您的存取權杖是\ncvn_smart(" + token + ")\n舊的存取權杖已失效", nolog=True) return "OK" if m_chat_id not in M.response_chat_id: return "OK" if action in ['setadmin']: if not checkadmin(): return "OK" parser = argparse.ArgumentParser( prog='/{0}'.format(action)) parser.add_argument('nickname', type=str, default=None, nargs='?', help='用戶暱稱') args = handle_parser(parser, cmd) if args is None: return 'OK' if "reply_to_message" not in data["message"]: M.sendmessage("需要reply訊息") return "OK" name = from_firstname if args.nickname is not None and args.nickname.strip( ) != '': name = args.nickname M.cur.execute( """REPLACE INTO `admin` (`user_id`, `name`) VALUES (%s, %s)""", (str(from_user_id), name)) M.db.commit() M.sendmessage("設定" + name + "(" + (from_firstname + " " + from_lastname).strip() + ")(" + str(from_user_id) + ")為管理員") return "OK" if action in ['deladmin']: if not checkadmin(): return "OK" if "reply_to_message" not in data["message"]: M.sendmessage("需要reply訊息") return "OK" from_user_id = ( data["message"]["reply_to_message"]["from"]["id"]) if from_user_id == m_user_id: M.sendmessage("你不能將自己除權") return "OK" count = M.cur.execute( """DELETE FROM `admin` WHERE `user_id` = %s""", (str(from_user_id))) M.db.commit() if count == 0: M.sendmessage("該用戶不是管理員") else: M.sendmessage("移除" + (from_firstname + " " + from_lastname).strip() + "(" + str(from_user_id) + ")為管理員") return "OK" if action in ['adduser', 'au']: name = checkadmin() if name is None: return "OK" parser = argparse.ArgumentParser( prog='/{0}'.format(action)) parser.add_argument('username', type=str, default=None, nargs='?', help='用戶名') parser.add_argument('reason', type=str, default='無原因', nargs='?', help='原因') parser.add_argument( '-w', '--wiki', type=str, metavar='站點', help= '參見 https://quarry.wmflabs.org/query/278 ,預設:zhwiki') parser.add_argument('-r', '--reason', type=str, metavar='原因', default='無原因', help='預設:%(default)s') parser.add_argument('-p', '--point', type=int, metavar='點數', default=10, help='預設:%(default)s') args = handle_parser(parser, cmd) if args is None: return 'OK' user = args.username if user is None and 'reply_to_message' in data['message']: user = M.get_user_from_message_id( data["message"]["reply_to_message"]["message_id"]) if len(user) == 0: M.sendmessage("無法從訊息找到所對應的對象") return "OK" user = user[0][0] if user is None: M.sendmessage('未指定用戶名') return "OK" user, wiki = M.parse_user(user) if args.wiki is not None: wiki = args.wiki reason = name + '加入:' + args.reason M.addblack_user(user, m_date, reason, wiki) M.adduser_score(M.user_type(user), args.point) return 'OK' if action in ['userscore', 'us']: name = checkadmin() if name is None: return "OK" parser = argparse.ArgumentParser( prog='/{0}'.format(action)) if 'reply_to_message' in data['message']: user = M.get_user_from_message_id( data["message"]["reply_to_message"]["message_id"]) if len(user) == 0: M.sendmessage("無法從訊息找到所對應的對象") return "OK" user = user[0][0] parser.add_argument('point', type=int, nargs='?', default=10, help='點數,預設:%(default)s') else: parser.add_argument('username', type=str, help='用戶名') parser.add_argument('point', type=int, nargs='?', default=10, help='點數,預設:%(default)s') args = handle_parser(parser, cmd) if args is None: return 'OK' if 'reply_to_message' not in data['message']: user = args.username user, wiki = M.parse_user(user) point = args.point userobj = M.user_type(user) M.adduser_score(userobj, point) point2 = M.getuser_score(userobj) message = "為 {0} 調整分數 {1:+d} 為 {2}".format( user, point, point2) M.sendmessage(message) return "OK" if action in ['deluser', 'du']: if not checkadmin(): return "OK" parser = argparse.ArgumentParser( prog='/{0}'.format(action)) parser.add_argument('username', type=str, default=None, nargs='?', help='用戶名') parser.add_argument('reason', type=str, default=None, nargs='?', help='原因') # Unused parser.add_argument('-r', '--reason', type=str, metavar='原因') # Unused parser.add_argument( '-w', '--wiki', type=str, metavar='站點', help= '參見 https://quarry.wmflabs.org/query/278 ,預設:zhwiki') args = handle_parser(parser, cmd) if args is None: return 'OK' user = args.username if user is None and 'reply_to_message' in data['message']: user = M.get_user_from_message_id( data["message"]["reply_to_message"]["message_id"]) if len(user) == 0: M.sendmessage("無法從訊息找到所對應的對象") return "OK" user = user[0][0] if user is None: M.sendmessage('未指定用戶名') return "OK" user, wiki = M.parse_user(user) if args.wiki is not None: wiki = args.wiki M.delblack_user(user, wiki) return "OK" if action in ['setwiki']: if not checkadmin(): return "OK" parser = argparse.ArgumentParser( prog='/{0}'.format(action)) parser.add_argument( 'wiki', type=str, default='zhwiki', metavar='站點', help= '參見 https://quarry.wmflabs.org/query/278 ,預設:zhwiki') parser.add_argument('-u', '--user', dest='username', type=str, metavar='用戶名') args = handle_parser(parser, cmd) if args is None: return 'OK' user = args.username if user is None and 'reply_to_message' in data['message']: user = M.get_user_from_message_id( data["message"]["reply_to_message"]["message_id"]) if len(user) == 0: M.sendmessage("無法從訊息找到所對應的對象") return "OK" user = user[0][0] if user is None: return 'OK' user, _ = M.parse_user(user) M.setwikiblack_user(user, args.wiki) return "OK" if action in ['addpage', 'ap']: name = checkadmin() if name is None: return "OK" parser = argparse.ArgumentParser( prog='/{0}'.format(action)) parser.add_argument('pagetitle', type=str, default=None, nargs='?', help='頁面名') parser.add_argument('reason', type=str, default='無原因', nargs='?', help='原因') parser.add_argument( '-w', '--wiki', type=str, metavar='站點', help= '參見 https://quarry.wmflabs.org/query/278 ,預設:zhwiki') parser.add_argument('-r', '--reason', type=str, metavar='原因', default='無原因', help='預設:%(default)s') parser.add_argument('-p', '--point', type=int, metavar='點數', default=30, help='預設:%(default)s') args = handle_parser(parser, cmd) if args is None: return 'OK' page = args.pagetitle if page is None and 'reply_to_message' in data['message']: page = M.get_page_from_message_id( data["message"]["reply_to_message"]["message_id"]) if len(page) == 0: M.sendmessage("無法從訊息找到所對應的頁面") return "OK" page = page[0][0] if page is None: M.sendmessage('未指定頁面標題') return 'OK' page, wiki = M.parse_page(page) if args.wiki is not None: wiki = args.wiki reason = name + '加入:' + M.parse_reason(args.reason) M.addblack_page(page, m_date, reason, wiki=wiki, point=args.point) return "OK" if action in ['massaddpage']: name = checkadmin() if name is None: return "OK" parser = argparse.ArgumentParser( prog='/{0}'.format(action)) parser.add_argument('pagetitle', type=str, nargs='+', help='頁面名') parser.add_argument( '-w', '--wiki', type=str, metavar='站點', help= '參見 https://quarry.wmflabs.org/query/278 ,預設:zhwiki') parser.add_argument('-r', '--reason', type=str, metavar='原因', default='無原因', help='預設:%(default)s') parser.add_argument('-p', '--point', type=int, metavar='點數', default=30, help='預設:%(default)s') args = handle_parser(parser, cmd) if args is None: return 'OK' for page in args.pagetitle: page, wiki = M.parse_page(page) if args.wiki is not None: wiki = args.wiki reason = name + '加入:' + M.parse_reason(args.reason) M.addblack_page(page, m_date, reason, wiki=wiki, point=args.point) return "OK" if action in ['delpage', 'dp']: if not checkadmin(): return "OK" parser = argparse.ArgumentParser( prog='/{0}'.format(action)) parser.add_argument('pagetitle', type=str, default=None, nargs='?', help='頁面名') parser.add_argument('reason', type=str, default=None, nargs='?', help='原因') # Unused parser.add_argument( '-w', '--wiki', type=str, metavar='站點', help= '參見 https://quarry.wmflabs.org/query/278 ,預設:zhwiki') args = handle_parser(parser, cmd) if args is None: return 'OK' page = args.pagetitle if page is None and 'reply_to_message' in data['message']: page = M.get_page_from_message_id( data["message"]["reply_to_message"]["message_id"]) if len(page) == 0: M.sendmessage("無法從訊息找到所對應的頁面") return "OK" page = page[0][0] if page is None: M.sendmessage('未指定頁面標題') return 'OK' page, wiki = M.parse_page(page) if args.wiki is not None: wiki = args.wiki M.delblack_page(page, wiki) return "OK" if action in ['checkuser', 'cu']: parser = argparse.ArgumentParser( prog='/{0}'.format(action)) parser.add_argument('username', type=str, default=None, nargs='?', help='用戶名') parser.add_argument( '-w', '--wiki', type=str, metavar='站點', help= '參見 https://quarry.wmflabs.org/query/278 ,預設:zhwiki') parser.add_argument('-r', '--reason', type=str, metavar='原因', help='篩選指定原因') args = handle_parser(parser, cmd) if args is None: return 'OK' user = args.username if user is None and 'reply_to_message' in data['message']: user = M.get_user_from_message_id( data["message"]["reply_to_message"]["message_id"]) if len(user) == 0: M.sendmessage("無法從訊息找到所對應的對象") return "OK" user = user[0][0] if user is None: M.sendmessage('未指定用戶名') return "OK" user, wiki = M.parse_user(user) if args.wiki is not None: wiki = args.wiki message = M.checkuser(user, wiki, reason=args.reason) M.sendmessage(message, user + '|' + wiki) return "OK" if action in ['checkpage', 'cp']: parser = argparse.ArgumentParser( prog='/{0}'.format(action)) parser.add_argument('pagetitle', type=str, default=None, nargs='?', help='頁面名') parser.add_argument( '-w', '--wiki', type=str, metavar='站點', help= '參見 https://quarry.wmflabs.org/query/278 ,預設:zhwiki') args = handle_parser(parser, cmd) if args is None: return 'OK' page = args.pagetitle if page is None and 'reply_to_message' in data['message']: page = M.get_page_from_message_id( data["message"]["reply_to_message"]["message_id"]) if len(page) == 0: M.sendmessage("無法從訊息找到所對應的頁面") return "OK" page = page[0][0] if page is None: M.sendmessage('未指定頁面標題') return 'OK' page, wiki = M.parse_page(page) if args.wiki is not None: wiki = args.wiki message = "" rows = M.check_page_blacklist(page, wiki) if len(rows) != 0: message += "\n於黑名單:" for record in rows: message += ("\n" + M.parse_wikicode(record[0]) + ', ' + M.formattimediff(record[1])) if message != "": M.sendmessage(page + "@" + wiki + message) else: M.sendmessage(page + "@" + wiki + ":查無結果") return "OK" if action in ['os'] and 'reply_to_message' in data['message']: if not checkadmin(): return "OK" M.deletemessage(data["message"]["message_id"]) M.deletemessage( data["message"]["reply_to_message"]["message_id"]) return "OK" if action in ['osall' ] and 'reply_to_message' in data['message']: if not checkadmin(): return "OK" M.deletemessage(data["message"]["message_id"]) message_id = ( data["message"]["reply_to_message"]["message_id"]) M.cur.execute( """SELECT `user` FROM `bot_message` WHERE `message_id` = %s""", (message_id)) rows = M.cur.fetchall() if len(rows) == 0: M.sendmessage("無法從訊息找到所對應的對象") return "OK" user = rows[0][0] M.cur.execute( """SELECT `message_id` FROM `bot_message` WHERE `user` = %s""", (user)) rows = M.cur.fetchall() for row in rows: M.deletemessage(row[0]) return "OK" if action in ['status']: message = (('Webhook: <a href="{}">WORKING!!</a>\n' + '<a href="{}status">查看資料接收狀況</a>').format( 'https://zh.wikipedia.org/wiki/WORKING!!', M.siteurl)) M.sendmessage(message) return "OK" return "OK" except Exception: traceback.print_exc() M.error(traceback.format_exc()) return "OK"
def web(): M = Monitor() try: data = request.form.to_dict() if "token" not in data: return json.dumps({"message": "沒有給予存取權杖"}) m = re.search(r"cvn_smart\(([a-z0-9]{32})\)", data["token"]) if m is not None: data["token"] = m.group(1) def checkadmin(): M.cur.execute("""SELECT `name` FROM `admin` WHERE `token` = %s""", (data["token"])) rows = M.cur.fetchall() if len(rows) == 0: return None return rows[0][0] if "action" not in data: return json.dumps({"message": "沒有給予操作類型"}) if data["action"] == "authorize": name = checkadmin() if name is None: return json.dumps({"result": "fail"}) return json.dumps({"result": "success", "user": name}) if data["action"] == "centralauthorize": query = { "format": "json", "action": "query", "meta": "userinfo", "centralauthtoken": data["centralauthtoken"] } query = urllib.parse.urlencode(query) url = "https://meta.wikimedia.org/w/api.php?" + query res = urllib.request.urlopen(url).read().decode("utf8") res = json.loads(res) if "query" in res: wiki_username = res["query"]["userinfo"]["name"] M.cur.execute( """SELECT `name`, `token` FROM `admin` WHERE `wiki_username` = %s""", (wiki_username)) rows = M.cur.fetchall() if len(rows) == 0: return json.dumps({"result": "fail"}) return json.dumps({ "result": "success", "user": rows[0][0], "token": rows[0][1] }) return json.dumps({"result": "fail"}) if data["action"] == "updatecentralinfo": name = checkadmin() if name is None: return json.dumps({"result": "fail"}) query = { "format": "json", "action": "query", "meta": "userinfo", "centralauthtoken": data["centralauthtoken"] } query = urllib.parse.urlencode(query) url = "https://meta.wikimedia.org/w/api.php?" + query res = urllib.request.urlopen(url).read().decode("utf8") res = json.loads(res) if "query" in res: wiki_username = res["query"]["userinfo"]["name"] count = M.cur.execute( """UPDATE `admin` SET `wiki_username` = %s WHERE `token` = %s""", (wiki_username, data["token"])) M.db.commit() if count == 0: return json.dumps({"result": "fail"}) return json.dumps({ "result": "success", "wiki_username": wiki_username, "user": name }) return json.dumps({"result": "fail"}) if data["action"] == "addpage": name = checkadmin() if name is None: return json.dumps({"message": "你沒有權限", "nopermission": True}) page, wiki = M.parse_page(data["page"]) try: point = int(data["point"]) except ValueError: point = 30 reason = name + "加入:" + M.parse_reason(data["reason"]) message = M.addblack_page(page, int(time.time()), reason, point, wiki, msgprefix=name + "透過API") return json.dumps({"message": message}) if data["action"] == "delpage": name = checkadmin() if name is None: return json.dumps({"message": "你沒有權限", "nopermission": True}) page, wiki = M.parse_page(data["page"]) message = M.delblack_page(page, wiki, msgprefix=name + "透過API將") return json.dumps({"message": message}) if data["action"] == "pagescore": name = checkadmin() if name is None: return json.dumps({"message": "你沒有權限", "nopermission": True}) page, wiki = M.parse_user(data["page"]) try: point = int(data["point"]) except ValueError: point = 30 M.addpage_score(page, wiki, point) point2 = M.getpage_score(page, wiki) message = "為 {0} 調整分數 {1:+d} 為 {2}".format(page, point, point2) return json.dumps({"message": message}) if data["action"] == "adduser": name = checkadmin() if name is None: return json.dumps({"message": "你沒有權限", "nopermission": True}) user, wiki = M.parse_user(data["user"]) reason = name + "加入:" + M.parse_reason(data["reason"]) message = M.addblack_user(user, int(time.time()), reason, wiki, msgprefix=name + "透過API") try: point = int(data["point"]) except ValueError: point = 10 M.adduser_score(M.user_type(user), point) return json.dumps({"message": message}) if data["action"] == "deluser": name = checkadmin() if name is None: return json.dumps({"message": "你沒有權限", "nopermission": True}) user, wiki = M.parse_user(data["user"]) message = M.delblack_user(user, wiki, msgprefix=name + "透過API將") return json.dumps({"message": message}) if data["action"] == "userscore": name = checkadmin() if name is None: return json.dumps({"message": "你沒有權限", "nopermission": True}) user, wiki = M.parse_user(data["user"]) try: point = int(data["point"]) except ValueError: point = 10 userobj = M.user_type(user) M.adduser_score(userobj, point) point2 = M.getuser_score(userobj) message = "為 {0} 調整分數 {1:+d} 為 {2}".format(user, point, point2) return json.dumps({"message": message}) data["token"] = "" M.log(json.dumps(data, ensure_ascii=False)) return json.dumps({"message": "伺服器沒有進行任何動作"}) except Exception: traceback.print_exc() M.error(traceback.format_exc()) return json.dumps({"message": traceback.format_exc()})