forked from Ikaros-521/AI-Vtuber
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
新增 数据分析 页面,统计分析最热弹幕词云、积分榜单、礼物榜单;webui右下角新增返回顶部按钮
- Loading branch information
1 parent
8b403bc
commit 504c4c3
Showing
8 changed files
with
1,015 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import sqlite3 | ||
import threading | ||
from queue import Queue | ||
from datetime import datetime | ||
|
||
|
||
class SQLiteDB: | ||
def __init__(self, db_file, max_connections=5): | ||
self.db_file = db_file | ||
self.connection_pool = self._create_connection_pool(max_connections) | ||
|
||
def _create_connection_pool(self, max_connections): | ||
connections = Queue(max_connections) | ||
for _ in range(max_connections): | ||
conn = sqlite3.connect(self.db_file) | ||
connections.put(conn) | ||
return connections | ||
|
||
def _get_connection(self): | ||
return self.connection_pool.get() | ||
|
||
def _release_connection(self, conn): | ||
self.connection_pool.put(conn) | ||
|
||
def execute(self, query, args=None): | ||
conn = sqlite3.connect(self.db_file) # 创建新的连接对象 | ||
cursor = conn.cursor() | ||
|
||
try: | ||
if args: | ||
cursor.execute(query, args) | ||
else: | ||
cursor.execute(query) | ||
conn.commit() | ||
finally: | ||
conn.close() | ||
|
||
# 执行SQLite数据库查询并返回结果 | ||
def fetch_all(self, query, args=None): | ||
conn = sqlite3.connect(self.db_file) # 创建新的连接对象 | ||
# 游标用于执行SQL查询和检索结果 | ||
cursor = conn.cursor() | ||
|
||
try: | ||
if args: | ||
# 执行SQL查询,如果提供了参数 args,它将被用来替换查询中的占位符。这是一个防止SQL注入的常见做法 | ||
cursor.execute(query, args) | ||
else: | ||
cursor.execute(query) | ||
# 从数据库游标中获取所有查询结果,并将其作为结果返回。fetchall() 方法返回一个包含查询结果的列表。 | ||
return cursor.fetchall() | ||
# 最后,无论try块中的代码是否成功执行,finally 块都会关闭数据库连接,以确保资源得到正确释放,避免资源泄漏。 | ||
finally: | ||
conn.close() | ||
|
||
# def __init__(self, db_file, max_connections=5): | ||
# self.db_file = db_file | ||
# self.connection_pool = self._create_connection_pool(max_connections) | ||
# self.db_lock = threading.Lock() | ||
|
||
# def _create_connection_pool(self, max_connections): | ||
# connections = Queue(max_connections) | ||
# for _ in range(max_connections): | ||
# conn = sqlite3.connect(self.db_file) | ||
# connections.put(conn) | ||
# return connections | ||
|
||
# def _get_connection(self): | ||
# return self.connection_pool.get() | ||
|
||
# def _release_connection(self, conn): | ||
# self.connection_pool.put(conn) | ||
|
||
# def execute(self, query, args=None): | ||
# conn = self._get_connection() | ||
# cursor = conn.cursor() | ||
|
||
# try: | ||
# with self.db_lock: | ||
# if args: | ||
# cursor.execute(query, args) | ||
# else: | ||
# cursor.execute(query) | ||
# conn.commit() | ||
# finally: | ||
# self._release_connection(conn) | ||
|
||
# def fetch_all(self, query, args=None): | ||
# conn = self._get_connection() | ||
# cursor = conn.cursor() | ||
|
||
# try: | ||
# with self.db_lock: | ||
# if args: | ||
# cursor.execute(query, args) | ||
# else: | ||
# cursor.execute(query) | ||
# return cursor.fetchall() | ||
# finally: | ||
# self._release_connection(conn) | ||
|
||
|
||
if __name__ == "__main__": | ||
db = SQLiteDB('data/test.db') | ||
|
||
# 创建表 | ||
create_table_sql = ''' | ||
CREATE TABLE IF NOT EXISTS danmu ( | ||
username TEXT, | ||
content TEXT, | ||
ts DATETIME | ||
) | ||
''' | ||
db.execute(create_table_sql) | ||
|
||
# 插入数据 | ||
insert_data_sql = ''' | ||
INSERT INTO danmu (username, content, ts) VALUES (?, ?, ?) | ||
''' | ||
db.execute(insert_data_sql, ('user1', 'test1', datetime.now())) | ||
|
||
# 查询数据 | ||
select_data_sql = ''' | ||
SELECT * FROM danmu | ||
''' | ||
data = db.fetch_all(select_data_sql) | ||
print(data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
from nicegui import ui | ||
from random import random | ||
from db import SQLiteDB | ||
|
||
def get_most_common_words(text_list, most_common=10): | ||
import jieba | ||
from collections import Counter | ||
|
||
# 假设这是您的字符串数组 | ||
# text_list = [ | ||
# "Python是一种广泛使用的高级编程语言", | ||
# "它结合了解释型、编译型、互动性和面向对象的脚本语言的特点", | ||
# "Python的设计哲学强调代码的可读性和简洁的语法", | ||
# "特别是使用空格缩进来划分代码块,而不是使用大括号或关键字", | ||
# "Python可以让开发者用更少的代码行进行表达", | ||
# "Python是一种解释型语言,意味着开发过程中没有了编译这个环节" | ||
# # ...更多字符串 | ||
# ] | ||
|
||
# 使用jieba进行中文分词 | ||
words = [] | ||
for text in text_list: | ||
cut_words = jieba.cut(text) | ||
# cut_words = jieba.cut_for_search(text) | ||
words.extend(cut_words) | ||
|
||
# 过滤掉单个字符的分词结果 | ||
words = [word for word in words if len(word) > 1] | ||
|
||
# 计算每个词的出现次数 | ||
word_counts = Counter(words) | ||
|
||
# 找出出现次数最多的词语 | ||
most_common_words = word_counts.most_common(most_common) # 获取前10个最常见的词 | ||
|
||
# 使用列表推导式和字典推导式进行转换 | ||
dict_list = [{'name': name, 'value': value} for name, value in most_common_words] | ||
|
||
print(dict_list) | ||
|
||
return dict_list | ||
|
||
|
||
db = SQLiteDB("E:\GitHub_pro\AI-Vtuber\data\data.db") | ||
# 查询数据 | ||
select_data_sql = ''' | ||
SELECT content FROM danmu | ||
''' | ||
data_list = db.fetch_all(select_data_sql) | ||
text_list = [data[0] for data in data_list] | ||
|
||
|
||
option = { | ||
'xAxis': {'type': 'value'}, | ||
'yAxis': {'type': 'category', 'data': ['A', 'B'], 'inverse': True}, | ||
'legend': {'textStyle': {'color': 'gray'}}, | ||
'series': [ | ||
{'type': 'bar', 'name': 'Alpha', 'data': [0.1, 0.2]}, | ||
{'type': 'bar', 'name': 'Beta', 'data': [0.3, 0.4]}, | ||
], | ||
} | ||
|
||
# option = { | ||
# 'tooltip': { | ||
# }, | ||
# 'series': [{ | ||
# 'type': 'wordCloud', #类型 | ||
# 'width': '100%', #宽度 | ||
# 'height': '100%', #高度 | ||
# 'sizeRange': [14, 60], #字体大小范围 | ||
# 'textStyle': { #随机获取样式 | ||
# 'fontFamily': 'sans-serif', | ||
# 'fontWeight': 'bold' | ||
# }, | ||
# 'emphasis': { #获得焦点时的样式 | ||
# 'focus': 'self', | ||
# 'textStyle': { | ||
# 'textShadowBlur': 10, | ||
# 'textShadowColor': '#333' | ||
# } | ||
# }, | ||
# 'data': [{'name':'中国','value':124}, {'name':'啊对','value':52}, {'name':'测试','value':20}] #数据源为数组eg:[{name:'中国',value:124}] | ||
# }] | ||
# } | ||
|
||
# 可滚动的图例 | ||
option = { | ||
'title': { | ||
'text': '弹幕关键词统计', | ||
'subtext': '源自本地数据库', | ||
'left': 'center' | ||
}, | ||
'tooltip': { | ||
'trigger': 'item', | ||
'formatter': '{a} <br/>{b} : {c} ({d}%)' | ||
}, | ||
'legend': { | ||
'type': 'scroll', | ||
'orient': 'vertical', | ||
'right': 10, | ||
'top': 20, | ||
'bottom': 20, | ||
'data': [d['name'] for d in get_most_common_words(text_list)] # 使用列表推导式提取所有'name'的值 | ||
}, | ||
'series': [ | ||
{ | ||
'name': '关键词', | ||
'type': 'pie', | ||
'radius': '55%', | ||
'center': ['50%', '60%'], | ||
'data': get_most_common_words(text_list), | ||
'emphasis': { | ||
'itemStyle': { | ||
'shadowBlur': 10, | ||
'shadowOffsetX': 0, | ||
'shadowColor': 'rgba(0, 0, 0, 0.5)' | ||
} | ||
} | ||
} | ||
] | ||
} | ||
|
||
echart = ui.echart(option) | ||
|
||
def update(): | ||
echart.options['series'][0]['data'][0] = random() | ||
echart.update() | ||
|
||
ui.button('Update', on_click=update) | ||
|
||
ui.run(port=8088) |
Oops, something went wrong.