-
-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(plugins/tgbotstatplugin): 0.1.0
- Loading branch information
Showing
62 changed files
with
27,918 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
name: TgBotStatPlugin Release | ||
|
||
on: | ||
push: | ||
tags: | ||
- 'TgBotStatPlugin-v*' | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout source | ||
uses: actions/checkout@v2 | ||
with: | ||
# 为了让 git 有日志 (git log) 可寻,还得在检出的时候顺带把所有提交历史一并拉下来,指定 fetch-depth 就能做到 | ||
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod | ||
|
||
- name: Set outputs | ||
id: vars | ||
run: | | ||
tagPrefix=refs/tags/TgBotStatPlugin- | ||
# 获取字符串长度 | ||
tagPrefixLen=${#tagPrefix} | ||
# 去掉前面的 refs/tags/TgBotStatPlugin- | ||
RELEASE_VERSION=${GITHUB_REF:$tagPrefixLen} | ||
# 提取出 v1.0.0 | ||
echo "RELEASE_VERSION=${RELEASE_VERSION}" >> $GITHUB_OUTPUT | ||
shell: bash | ||
|
||
- name: Setup .NET Core | ||
uses: actions/setup-dotnet@v1 | ||
with: | ||
dotnet-version: 6.0.100 | ||
|
||
- name: Build | ||
run: | | ||
cd ./plugins/TgBotStatPlugin | ||
dotnet build --configuration Release | ||
ls | ||
ls ./bin/Release/ | ||
ls ./bin/Release/net6.0/ | ||
shell: bash | ||
|
||
- name: Zip the Build | ||
run: | | ||
cd ./plugins/TgBotStatPlugin/bin/Release/net6.0 | ||
zip -r TgBotStatPlugin-${{ steps.vars.outputs.RELEASE_VERSION }}-net6.0.zip * | ||
shell: bash | ||
|
||
- name: Create temp-release-note.md | ||
run: | | ||
cp utils/generate-release-note.ps1 generate-release-note.ps1 | ||
$env:GitProjectTagName="TgBotStatPlugin" | ||
$env:GitProjectPath="plugins/TgBotStatPlugin/*" | ||
./generate-release-note.ps1 | ||
shell: pwsh | ||
|
||
- name: Create Release and Upload Release Asset | ||
uses: softprops/action-gh-release@v1 | ||
if: startsWith(github.ref, 'refs/tags/') | ||
with: | ||
#tag_name: ${{ github.ref }} | ||
#name: ${{ github.ref }} | ||
# body: TODO New Release. | ||
body_path: temp-release-note.md | ||
draft: false | ||
prerelease: false | ||
files: | | ||
./plugins/TgBotStatPlugin/bin/Release/net6.0/TgBotStatPlugin-${{ steps.vars.outputs.RELEASE_VERSION }}-net6.0.zip | ||
./plugins/TgBotStatPlugin/README.md | ||
./plugins/TgBotStatPlugin/LICENSE |
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,83 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using PluginCore; | ||
using PluginCore.Interfaces; | ||
using TgBotStatPlugin.Utils; | ||
using TgBotStatPlugin.ResponseModels; | ||
using TgBotStatPlugin.RequestModels; | ||
using PluginCore.IPlugins; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
|
||
namespace TgBotStatPlugin.Controllers | ||
{ | ||
/// <summary> | ||
/// 其实也可以不写这个, 直接访问 Plugins/TgBotStatPlugin/index.html | ||
/// | ||
/// 下面的方法, 是去掉 index.html | ||
/// | ||
/// 若 wwwroot 下有其它需要访问的文件, 如何 css, js, 而你又不想每次新增 action 指定返回, 则 Route 必须 Plugins/{PluginId}, | ||
/// 这样访问 Plugins/TgBotStatPlugin/css/main.css 就会访问到你插件下的 wwwroot/css/main.css | ||
/// </summary> | ||
[Route($"api/Plugins/{nameof(TgBotStatPlugin)}")] | ||
[Authorize("PluginCore.Admin")] | ||
public class HomeController : Controller | ||
{ | ||
#region Fields | ||
|
||
private readonly IPluginFinder _pluginFinder; | ||
private readonly bool _debug; | ||
|
||
#endregion | ||
|
||
#region Propertities | ||
|
||
#endregion | ||
|
||
#region Ctor | ||
public HomeController(IPluginFinder pluginFinder) | ||
{ | ||
_pluginFinder = pluginFinder; | ||
string debugStr = EnvUtil.GetEnv("DEBUG"); | ||
if (!string.IsNullOrEmpty(debugStr) && bool.TryParse(debugStr, out bool debug)) | ||
{ | ||
_debug = debug; | ||
} | ||
else | ||
{ | ||
_debug = false; | ||
} | ||
} | ||
#endregion | ||
|
||
|
||
#region Actions | ||
|
||
[Route($"/Plugins/{nameof(TgBotStatPlugin)}")] | ||
[HttpGet] | ||
public async Task<ActionResult> Index() | ||
{ | ||
string indexFilePath = System.IO.Path.Combine(PluginPathProvider.PluginWwwRootDir(nameof(TgBotStatPlugin)), "index.html"); | ||
|
||
return PhysicalFile(indexFilePath, "text/html"); | ||
} | ||
|
||
[Route(nameof(Download))] | ||
public async Task<ActionResult> Download() | ||
{ | ||
string dbFilePath = DbContext.DbFilePath; | ||
var fileStream = System.IO.File.OpenRead(dbFilePath); | ||
//System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(); | ||
|
||
return File(fileStream: fileStream, contentType: "application/x-sqlite3", fileDownloadName: $"{nameof(TgBotStatPlugin)}.sqlite", enableRangeProcessing: true); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
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,147 @@ | ||
using Dapper; | ||
using PluginCore; | ||
using TgBotStatPlugin.Models; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Data; | ||
using System.Data.SQLite; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using DapperExtensions; | ||
|
||
namespace TgBotStatPlugin | ||
{ | ||
public class DbContext | ||
{ | ||
public static string DbFilePath | ||
{ | ||
get | ||
{ | ||
string dbFilePath = Path.Combine(PluginPathProvider.PluginsRootPath(), nameof(TgBotStatPlugin), $"{nameof(TgBotStatPlugin)}.sqlite"); | ||
|
||
return dbFilePath; | ||
} | ||
} | ||
|
||
public static string ConnStr | ||
{ | ||
get | ||
{ | ||
return $"Data Source={DbFilePath};Cache Size=0"; // 连接符字串 | ||
} | ||
} | ||
|
||
|
||
public static int InsertIntoMessage(Message model) | ||
{ | ||
using (IDbConnection con = new SQLiteConnection(ConnStr)) | ||
{ | ||
con.Open(); | ||
|
||
string sql = "INSERT INTO Message (UName,UId,Content,GroupName,GroupId,CreateTime) Values (@UName,@UId,@Content,@GroupName,@GroupId,@CreateTime);"; | ||
|
||
return con.Execute(sql, model); | ||
} | ||
} | ||
|
||
public static List<Message> QueryAllMessage() | ||
{ | ||
using (IDbConnection con = new SQLiteConnection(ConnStr)) | ||
{ | ||
con.Open(); | ||
|
||
string sql = "SELECT * FROM Message;"; | ||
|
||
return con.Query<Message>(sql).ToList(); | ||
} | ||
} | ||
|
||
public async static Task<long> Count() | ||
{ | ||
using (IDbConnection con = new SQLiteConnection(ConnStr)) | ||
{ | ||
con.Open(); | ||
|
||
string sql = "SELECT COUNT(*) FROM Message;"; | ||
|
||
return await con.QueryFirstAsync<long>(sql); | ||
} | ||
} | ||
|
||
public async static Task<IEnumerable<(string UId, long TotalContentLen)>> TopByGroup(string groupId) | ||
{ | ||
using (IDbConnection con = new SQLiteConnection(ConnStr)) | ||
{ | ||
con.Open(); | ||
|
||
string sql = @"SELECT UId, SUM(ContentLen) AS TotalContentLen | ||
FROM(SELECT Id, UId, LENGTH(Content) AS ContentLen FROM Message WHERE GroupId = @GroupId) | ||
GROUP BY UId | ||
ORDER BY TotalContentLen DESC | ||
LIMIT 10;"; | ||
|
||
return await con.QueryAsync<(string UId, long TotalContentLen)>(sql, new | ||
{ | ||
GroupId = groupId | ||
}); | ||
} | ||
} | ||
|
||
public async static Task<long> CountByGroupId(string groupId) | ||
{ | ||
using (IDbConnection con = new SQLiteConnection(ConnStr)) | ||
{ | ||
con.Open(); | ||
|
||
string sql = @"SELECT COUNT(*) FROM Message | ||
WHERE GroupId = @GroupId;"; | ||
|
||
return await con.QueryFirstAsync<long>(sql, new | ||
{ | ||
GroupId = groupId | ||
}); | ||
} | ||
} | ||
|
||
public async static Task<IEnumerable<Message>> QueryByGroupId(string groupId, Pager pager) | ||
{ | ||
using (IDbConnection con = new SQLiteConnection(ConnStr)) | ||
{ | ||
con.Open(); | ||
|
||
string sql = @"SELECT * FROM Message | ||
WHERE GroupId = @GroupId | ||
ORDER BY Id | ||
OFFSET @Offset ROWS | ||
FETCH NEXT @Next ROWS ONLY;"; | ||
|
||
return await con.QueryAsync<Message>(sql, new | ||
{ | ||
GroupId = groupId, | ||
Offset = pager.Offset, | ||
Next = pager.Next | ||
}); | ||
} | ||
} | ||
} | ||
|
||
public class Pager | ||
{ | ||
public int Page { get; set; } | ||
public int PageSize { get; set; } | ||
|
||
public int Offset { get; set; } | ||
public int Next { get; set; } | ||
|
||
public Pager(int page, int pageSize = 10) | ||
{ | ||
Page = page < 1 ? 1 : page; | ||
PageSize = pageSize < 1 ? 10 : pageSize; | ||
|
||
Next = pageSize; | ||
Offset = (Page - 1) * Next; | ||
} | ||
} | ||
} |
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,34 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace TgBotStatPlugin.Models | ||
{ | ||
/// <summary> | ||
/// 消息 | ||
/// </summary> | ||
public class Message | ||
{ | ||
public long Id { get; set; } | ||
|
||
public string UName { get; set; } | ||
|
||
public string UId { get; set; } | ||
|
||
public string Content { get; set; } | ||
|
||
/// <summary> | ||
/// 若私聊则为 null | ||
/// </summary> | ||
public string GroupName { get; set; } | ||
|
||
/// <summary> | ||
/// 若私聊则为 null | ||
/// </summary> | ||
public string GroupId { get; set; } | ||
|
||
public long CreateTime { get; set; } | ||
} | ||
} |
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,26 @@ | ||
|
||
|
||
|
||
## 使用 | ||
|
||
|
||
> 在机器人所在群, 发送 `/export` | ||
|
||
## 下载数据库 | ||
|
||
> 所有数据保存到数据库 **TgBotStatPlugin.sqlite** 中 | ||
- [下载数据库 (TgBotStatPlugin.sqlite)](/api/Plugins/TgBotStatPlugin/Download) | ||
|
||
|
||
|
||
|
||
## 相关 | ||
|
||
> 项目地址: [https://github.com/yiyungent/KnifeHub/tree/main/plugins/TgBotStatPlugin](https://github.com/yiyungent/KnifeHub/tree/main/plugins/TgBotStatPlugin) | ||
|
||
<!-- Matomo Image Tracker--> | ||
<img referrerpolicy="no-referrer-when-downgrade" src="https://matomo.moeci.com/matomo.php?idsite=2&rec=1&action_name=Plugins.TgBotStatPlugin-v0.1.0.README" style="border:0" alt="" /> | ||
<!-- End Matomo --> |
Oops, something went wrong.