From 7f8e76b26e1d979b03e0d61fc9542f04b81acfc1 Mon Sep 17 00:00:00 2001 From: LibraHp_0928 <1941163264@qq.com> Date: Sun, 22 Sep 2024 00:38:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=81=E8=A3=85=E6=95=B0=E6=8D=AE=EF=BC=8C?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=99=BB=E5=BD=95=E5=8F=8A=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/logo.jpg | Bin 0 -> 49849 bytes main.py | 342 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 252 insertions(+), 90 deletions(-) create mode 100644 assets/logo.jpg diff --git a/assets/logo.jpg b/assets/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f694a072f5c3f5666da404f69413bcd49f5d7b9 GIT binary patch literal 49849 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 IcXQ?p0GP`6YybcN literal 0 HcmV?d00001 diff --git a/main.py b/main.py index cc9306b..e48d31c 100644 --- a/main.py +++ b/main.py @@ -3,6 +3,7 @@ import requests import base64 import re import time +from datetime import datetime import json import threading from bs4 import BeautifulSoup @@ -49,17 +50,20 @@ def ptqrToken(qrsig): return 2147483647 & e + def extract_string_between(source_string, start_string, end_string): start_index = source_string.find(start_string) + len(start_string) end_index = source_string.find(end_string) extracted_string = source_string[start_index:-37] return extracted_string + def replace_multiple_spaces(string): pattern = r'\s+' replaced_string = re.sub(pattern, ' ', string) return replaced_string + def process_old_html(message): def replace_hex(match): hex_value = match.group(0) @@ -73,19 +77,41 @@ def process_old_html(message): new_text = replace_multiple_spaces(new_text).replace('\\', '') return new_text + +def parse_time_strings(time_str): + today = datetime.today().date() # 获取今天的日期 + if len(time_str) == 5: # 格式为 HH:MM + return datetime.combine(today, datetime.strptime(time_str, "%H:%M").time()) + elif "年" in time_str: # 包含“年”的格式 + return datetime.strptime(time_str, "%Y年%m月%d日 %H:%M") + elif "月" in time_str: # 包含“月”的格式 + return datetime.strptime(time_str, "%m月%d日 %H:%M").replace(year=today.year) + return None + + class User: def __init__(self, uin, username): self.uin = uin self.avatar_url = f'http://q1.qlogo.cn/g?b=qq&nk={uin}&s=100' self.username = username self.link = f'https://user.qzone.qq.com/{uin}/' + - def get_controls(self): - return [ - ft.Image(src=self.avatar_url, border_radius=100), - ft.Text(self.username), - ft.Text(self.link), - ] +class Comment: + def __init__(self, user, time, content): + self.user = user + self.time = time + self.content = content + + +class Message: + def __init__(self, user, type, time, content, images=None, comment=None): + self.user = user + self.type = type + self.time = time + self.content = content + self.images = images + self.comment = comment def create_card(img_url, title, subtitle): @@ -95,17 +121,17 @@ def create_card(img_url, title, subtitle): [ ft.ListTile( # 如果img_url为空 显示https://picsum.photos/200 - leading=ft.Image(src=img_url, border_radius=100), + # leading=ft.Image(src=img_url, border_radius=100), title=ft.Text(title), subtitle=ft.Text(subtitle), ), - ft.Row( - [ft.TextButton("购票"), ft.TextButton("试听")], - alignment=ft.MainAxisAlignment.END, - ), + # ft.Row( + # [ft.TextButton("购票"), ft.TextButton("试听")], + # alignment=ft.MainAxisAlignment.END, + # ), ] ), - width=400, + expand=True, padding=10, ) ) @@ -117,15 +143,28 @@ def main(page: ft.Page): page.horizontal_alignment = "start" page.vertical_alignment = "center" page.window.resizable = False - page.padding = 20 + page.padding = ft.padding.only(20,20,20,5) page.bgcolor = "#f0f0f0" # page.window.icon = "https://picsum.photos/200" # 字体使用系统默认字体 page.theme= ft.Theme(font_family="Microsoft YaHei") + + def logout(): + page.session.clear() + user_info.content.controls[0].src = "assets/logo.jpg" + user_info.content.controls[1].value = "LibraHp" + content_area.content = create_get_content_page() + for tab in tabs.controls: + if tab.data != "GetContent" and tab.data != "Logout" and tab.data != "Github": + tab.disabled = True + page.update() + + def handle_close(e): page.close(dlg_modal) - print("Modal dialog closed with action: ", e.control.text) + if e.control.text == "Yes": + logout() dlg_modal = ft.AlertDialog( modal=True, @@ -135,11 +174,7 @@ def main(page: ft.Page): ft.TextButton("Yes", on_click=handle_close), ft.TextButton("No", on_click=handle_close), ], - actions_alignment=ft.MainAxisAlignment.END, - on_dismiss=lambda e: page.add( - # 弹窗 - - ), + actions_alignment=ft.MainAxisAlignment.END ) def QR(): # 获取 qq空间 二维码 @@ -176,37 +211,6 @@ def main(page: ft.Page): user_info.content.controls[0].src = f'http://q1.qlogo.cn/g?b=qq&nk={uin}&s=100' user_info.content.controls[1].value = info[uin][6] page.update() - - def get_user_messages(count): - for i in range(int(count / 100) + 1): - message = get_message(i * 100, 100).content.decode('utf-8') - time.sleep(0.2) - html = process_old_html(message) - if "li" not in html: - continue - soup = BeautifulSoup(html, 'html.parser') - for element in soup.find_all('li', class_='f-single f-s-s'): - put_time = None - text = None - img = None - friend_element = element.find('a', class_='f-name q_namecard') - # 获取好友昵称和QQ - if friend_element is not None: - friend_name = friend_element.get_text() - friend_qq = friend_element.get('link')[9:] - friend_link = friend_element.get('href') - if friend_qq not in [sublist[1] for sublist in all_friends]: - all_friends.append([friend_name, friend_qq, friend_link]) - time_element = element.find('div', class_='info-detail') - text_element = element.find('p', class_='txt-box-title ellipsis-one') - img_element = element.find('a', class_='img-item') - if time_element is not None and text_element is not None: - put_time = time_element.get_text().replace('\xa0', ' ') - text = text_element.get_text().replace('\xa0', ' ') - if img_element is not None: - img = img_element.find('img').get('src') - if text not in [sublist[1] for sublist in texts]: - texts.append([put_time, text, img]) # 路由改变函数 def change_route(e): @@ -235,14 +239,24 @@ def main(page: ft.Page): tab.disabled = False def show_login_content(): + progress_bar = None + login_text = None for content in content_area.content.controls: if content.data == 'not_login': content.visible = False - elif content.data == 'login': + elif content.data == 'login_progress': content.visible = True + progress_bar = content + elif content.data == 'login_text': + login_text = content + content.visible = True + return progress_bar, login_text + # 获取内容页面 def create_get_content_page(): + if page.session.contains_key("user_cookies"): + return get_message_result() base64_image = QR() # 更新二维码状态的函数(模拟,需实际实现逻辑) def update_qr_code_status(e): @@ -280,8 +294,8 @@ def main(page: ft.Page): page.snack_bar = ft.SnackBar(ft.Text(f"登录成功,欢迎您 {target_cookies.get('uin')}"),duration=2000) page.snack_bar.open = True get_login_user_info() - unlock_tabs() - show_login_content() + progress_bar, login_text = show_login_content() + create_card_list_view(progress_bar, login_text) # p_skey = requests.utils.dict_from_cookiejar(r.cookies).get('p_skey') except Exception as e: print(e) @@ -305,20 +319,16 @@ def main(page: ft.Page): # 使用 in 分别检查多个条件 if any(status in qr_status.value for status in ['已登录', '已拒绝', '已失效']): break - print(qr_status.value) + log(qr_status.value) update_qr_code_status(None) time.sleep(2) thread = threading.Thread(target=task) thread.start() - content_items = ["内容1", "内容2", "内容3", "内容4","内容5","内容6"] - total_progress = 0.75 # 进度值 - # 创建界面并添加卡片列表 - card_list_view = create_card_list_view(content_items, total_progress) + # 返回一个包含二维码和状态更新的布局 return ft.Column( controls=[ - card_list_view, ft.Text("请使用手机QQ扫码登录", size=24, weight="bold", data='not_login'), qr_image, # 展示二维码 qr_status, # 展示二维码状态 @@ -330,6 +340,8 @@ def main(page: ft.Page): alignment=ft.MainAxisAlignment.CENTER, data='not_login' ), + ft.Text("获取空间消息中...", size=24, weight="bold", data='login_text',visible=False), + ft.ProgressBar(data='login_progress', visible=False), ], alignment="center", horizontal_alignment="center", @@ -387,45 +399,187 @@ def main(page: ft.Page): # 请求失败,总量应该在当前总量的左侧 upper_bound = total - 1 total = (lower_bound + upper_bound) // 2 # 更新总量为新的中间值 + log(f"获取消息列表数量中... 当前 - Total: {total}") return total - def create_card_list_view(content_items, total_progress): - """ - 创建带有总进度条和卡片列表的Flet组件 - :param content_items: 一个列表,包含需要展示的内容 - :param total_progress: 获取内容的总进度值(0 到 1 之间的小数) - :return: 包含进度条和卡片列表的Flet组件 - """ - # 创建一个进度条组件,进度为 total_progress - progress_bar = ft.ProgressBar(value=total_progress, width=400) + def create_card_list_view(progress_bar, login_text): # 创建一个空的卡片列表,用于存放所有卡片 - card_list = ft.Column(scroll=ft.ScrollMode.AUTO) + login_text.value = "获取空间消息数量中..." + page.update() + count = get_message_count() + login_text.value = "获取空间消息列表中..." + page.update() + for i in range(int(count / 100) + 1): + message = get_message(i * 100, 100).content.decode('utf-8') + time.sleep(0.2) + html = process_old_html(message) + if "li" not in html: + continue + soup = BeautifulSoup(html, 'html.parser') + for element in soup.find_all('li', class_='f-single f-s-s'): + put_time = None + text = None + img = None + message_type = None + friend = User() + comment = Comment() + res_message = Message() + friend_element = element.find('a', class_='f-name q_namecard') + # 获取好友昵称和QQ + if friend_element is not None: + friend_name = friend_element.get_text() + friend_qq = friend_element.get('link')[9:] + # friend_link = friend_element.get('href') + friend.uin = friend_qq + friend.username = friend_name + comment.user = friend + res_message.user = friend + time_element = element.find('div', class_='info-detail') + text_element = element.find('p', class_='txt-box-title ellipsis-one') + img_element = element.find('a', class_='img-item') + message_type_element = element.find('span', class_='ui-mr10 state') + if message_type_element is not None: + message_type = message_type_element.get_text() + res_message.type = message_type + comment_element = element.find('div', class_='comments-content font-b') + if comment_element is not None: + comment_time_element = comment_element.find('span', class_='ui-mr10 state') + comment.time = parse_time_strings(comment_time_element.get_text()) + comment_text = comment_element.find(text=True, recursive=False).strip() + comment.content = comment_text + res_message.comment = comment + if time_element is not None and text_element is not None: + put_time = time_element.get_text().replace('\xa0', ' ') + put_time = parse_time_strings(put_time) + res_message.time = put_time + text = text_element.get_text().replace('\xa0', ' ') + res_message.content = text + log(f'{message_type} - {put_time} - {text}') + # log(f"{put_time} - {text}") + if img_element is not None: + img = img_element.find('img').get('src') + img = str(img).replace("/m&ek=1&kp=1", "/s&ek=1&kp=1") + img = str(img).replace(r"!/m/", "!/s/") + res_message.images = img + # if text not in [sublist[1] for sublist in texts]: + print(res_message) + progress_bar.value = i / int(count / 100) + page.update() + login_text.value = "获取成功!" + progress_bar.visible = False + unlock_tabs() + content_area.content.controls.append(get_message_result()) + page.update() - # 遍历 content_items 列表,为每个内容创建一个卡片并加入卡片列表 - for index, item in enumerate(content_items): - # 每个卡片展示内容的名称或信息 - card = create_card("https://picsum.photos/200", item, f"Content {index + 1}") - # 将卡片添加到卡片列表中 - card_list.controls.append(card) - - # 返回一个包含进度条和卡片列表的组件(Column 布局) - return ft.Column([ - ft.Text("正在获取消息列表数量...", style="headlineSmall"), # 标题 - progress_bar, # 进度条 - card_list, # 卡片列表 + def get_message_result(): + return ft.Column( + controls=[ + ft.Row( + controls=[ + ft.Card( + content=ft.Container( + content=ft.Text("说说共有 " + str(889) + " 条", size=25), + padding=20, + alignment=ft.alignment.center, + ), + elevation=5, + shape=ft.RoundedRectangleBorder(radius=15), + expand=True, + ), + ft.Card( + content=ft.Container( + content=ft.Text("留言共有 " + str(889) + " 条", size=25), + padding=20, + alignment=ft.alignment.center, + ), + elevation=5, + shape=ft.RoundedRectangleBorder(radius=15), + expand=True, + ), + ], + alignment="center", + spacing=20, # 控制两列卡片之间的间距 + expand=True, + ), + ft.Row( + controls=[ + ft.Card( + content=ft.Container( + content=ft.Text("转发共有 " + str(889) + " 条", size=25), + padding=20, + alignment=ft.alignment.center, + ), + elevation=5, + shape=ft.RoundedRectangleBorder(radius=15), + expand=True, + ), + ft.Card( + content=ft.Container( + content=ft.Text("图片共有 " + str(889) + " 张", size=25), + padding=20, + alignment=ft.alignment.center, + ), + elevation=5, + shape=ft.RoundedRectangleBorder(radius=15), + expand=True, + ), + ], + alignment="center", + spacing=20, + expand=True, + ), + ft.Row( + controls=[ + ft.Card( + content=ft.Container( + content=ft.Text("评论共有 " + str(889) + " 条", size=25), + padding=20, + alignment=ft.alignment.center, + ), + elevation=5, + shape=ft.RoundedRectangleBorder(radius=15), + expand=True, + ), + ft.Card( + content=ft.Container( + content=ft.Text("好友共有 " + str(889) + " 位", size=25), + padding=20, + alignment=ft.alignment.center, + ), + elevation=5, + shape=ft.RoundedRectangleBorder(radius=15), + expand=True, + ), + ], + alignment="center", + spacing=20, + expand=True, + ), + ft.Row( + controls=[ + ft.Text("最早的说说发布在 2022 年 3 月 20 日 12:00", size=20), + ft.Text("程序完全免费,请勿用于商业用途!", size=20), + ], + alignment="center", + ) ], - data='login', - visible=False + alignment="center", + horizontal_alignment="center", + spacing=20, # 控制每行之间的间距 + expand=True, ) - + + + + # 用户信息 user_info = ft.Container( content=ft.Column( controls=[ - ft.Image(src="https://picsum.photos/200", width=80, height=80, border_radius=100), # Replace with actual avatar URL - ft.Text("Username", size=20, weight="bold") + ft.Image(src="assets/logo.jpg", width=80, height=80, border_radius=100), # Replace with actual avatar URL + ft.Text("LibraHp", size=20, weight="bold") ], alignment="center", horizontal_alignment="center" @@ -434,6 +588,7 @@ def main(page: ft.Page): padding=20 ) + # 左侧标签页 tabs = ft.Column( controls=[ @@ -445,7 +600,7 @@ def main(page: ft.Page): ft.ElevatedButton("其他列表", on_click=change_route, data="Other", width=200, disabled=True), ft.ElevatedButton("图片列表", on_click=change_route, data="Pictures", width=200, disabled=True), ft.ElevatedButton("退出当前账号登录", on_click=change_route, data="Logout", width=200), - ft.TextButton("Powered by LibraHp", url="https://github.com/LibraHp", width=200), + ft.TextButton("Powered by LibraHp", url="https://github.com/LibraHp", data="Github", width=200), ], alignment="start", spacing=10 @@ -456,8 +611,7 @@ def main(page: ft.Page): content=ft.Column( controls=[user_info, tabs], spacing=20, - horizontal_alignment="start", - scroll=ft.ScrollMode.HIDDEN + horizontal_alignment="start" ), width=220, bgcolor="#ffffff", @@ -495,8 +649,16 @@ def main(page: ft.Page): expand=True, alignment="start" ) - + + def log(message): + now = time.strftime("%Y-%m-%d %H:%M:%S") + log_list.value = f"{now} - {message}" + page.update() + + log_list = ft.Text(size=12, color="blue") page.add(main_layout) + page.add(log_list) + log("开始运行...") if __name__ == "__main__":