Skip to content

Commit

Permalink
feta: 增加仅获取数据 路由
Browse files Browse the repository at this point in the history
  • Loading branch information
soxft committed Aug 2, 2024
1 parent 2e7e127 commit 6c3d33a
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 53 deletions.
97 changes: 83 additions & 14 deletions app/controller/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ import (
"net/url"
)

var defaultData = gin.H{
"project": "https://github.com/soxft/busuanzi",
"usage": "https://github.com/soxft/busuanzi/wiki/usage",
}

func ApiHandler(c *gin.Context) {
var referer = c.Request.Header.Get("x-bsz-referer")
if referer == "" {
c.JSON(200, gin.H{
"success": false,
"message": "invalid referer",
"data": gin.H{
"project": "https://github.com/soxft/busuanzi",
"usage": "https://github.com/soxft/busuanzi/wiki/usage",
},
"data": defaultData,
})
return
}
Expand All @@ -25,31 +27,98 @@ func ApiHandler(c *gin.Context) {
c.JSON(200, gin.H{
"success": false,
"message": "unable to parse referer",
"data": gin.H{
"project": "https://github.com/soxft/busuanzi",
"usage": "https://github.com/soxft/busuanzi/wiki/usage",
},
"data": defaultData,
})
return
} else if u.Host == "" {
c.JSON(200, gin.H{
"success": false,
"message": "invalid referer",
"data": gin.H{
"project": "https://github.com/soxft/busuanzi",
"usage": "https://github.com/soxft/busuanzi/wiki/usage",
},
"data": defaultData,
})
return
}

var host = u.Host
var path = u.Path

userIdentity := c.GetString("user_identity")
// count
counts := core.Count(c, host, path, c.GetString("user_identity"))

// json
c.JSON(200, gin.H{
"success": true,
"message": "ok",
"data": gin.H{
"site_pv": counts.SitePv,
"site_uv": counts.SiteUv,
"page_pv": counts.PagePv,
"page_uv": counts.PageUv,
},
})
}

// PutHandler 仅提交数据, 不做返回
func PutHandler(c *gin.Context) {
var referer = c.Request.Header.Get("x-bsz-referer")
if referer == "" {
c.Status(400)
return
}

u, err := url.Parse(referer)
if err != nil {
c.Status(400)
return
} else if u.Host == "" {
c.Status(400)
return
}

var host = u.Host
var path = u.Path

// count
go core.Put(c, host, path, c.GetString("user_identity"))

// json
c.Status(204)
}

// GetHandler 仅获取数据, 不增加
func GetHandler(c *gin.Context) {
var referer = c.Request.Header.Get("x-bsz-referer")
if referer == "" {
c.JSON(200, gin.H{
"success": false,
"message": "invalid referer",
"data": defaultData,
})
return
}

u, err := url.Parse(referer)
if err != nil {
c.JSON(200, gin.H{
"success": false,
"message": "unable to parse referer",
"data": defaultData,
})
return
} else if u.Host == "" {
c.JSON(200, gin.H{
"success": false,
"message": "invalid referer",
"data": defaultData,
})
return
}

var host = u.Host
var path = u.Path

// count
counts := core.Count(c, host, path, userIdentity)
counts := core.Get(c, host, path, c.GetString("user_identity"))

// json
c.JSON(200, gin.H{
Expand Down
133 changes: 98 additions & 35 deletions core/count.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package core

import (
"context"
"fmt"
"github.com/soxft/busuanzi/library/tool"
"github.com/soxft/busuanzi/process/redisutil"
"github.com/spf13/viper"
"strings"
"time"
)

Expand All @@ -22,58 +22,81 @@ type Counts struct {
PageUv int64
}

type RKeys struct {
SitePvKey string
SiteUvKey string
PagePvKey string
PageUvKey string
SiteUnique string
PathUnique string
}

// Count
// @description return and count the number of users in the redis
func Count(ctx context.Context, host string, path string, userIdentity string) Counts {
_redis := redisutil.RDB

// encode
var siteUnique = host
var pathUnique = path
rk := getKeys(host, path)

// 兼容旧版本
if viper.GetBool("bsz.pathStyle") == false {
pathUnique = host + "&" + path
}
// sitePV and pagePV 使用 Str / Zset 存储
sitePv, _ := _redis.Incr(ctx, rk.SitePvKey).Result()
pagePv, _ := _redis.ZIncrBy(ctx, rk.PagePvKey, 1, rk.PathUnique).Result()

// encrypt
switch viper.GetString("bsz.Encrypt") {
case "MD516":
siteUnique = tool.Md5(siteUnique)[8:24]
pathUnique = tool.Md5(pathUnique)[8:24]
case "MD532":
siteUnique = tool.Md5(siteUnique)
pathUnique = tool.Md5(pathUnique)
default:
siteUnique = tool.Md5(siteUnique)
pathUnique = tool.Md5(pathUnique)
}
// siteUv 和 pageUv 使用 HyperLogLog 存储
_redis.PFAdd(ctx, rk.SiteUvKey, userIdentity)
_redis.PFAdd(ctx, rk.PageUvKey, userIdentity)

// redisPrefix
redisPrefix := viper.GetString("redis.prefix")
// count siteUv and pageUv
siteUv, _ := _redis.PFCount(ctx, rk.SiteUvKey).Result()
pageUv, _ := _redis.PFCount(ctx, rk.PageUvKey).Result()

// user view keys 用户数
siteUvKey := fmt.Sprintf("%s:site_uv:%s", redisPrefix, siteUnique)
pageUvKey := fmt.Sprintf("%s:page_uv:%s:%s", redisPrefix, siteUnique, pathUnique)
// setExpire
go setExpire(ctx, rk.SiteUvKey, rk.PageUvKey, rk.SitePvKey, rk.PagePvKey)

// page view keys 页面访问数
sitePvKey := fmt.Sprintf("%s:site_pv:%s", redisPrefix, siteUnique)
pagePvKey := fmt.Sprintf("%s:page_pv:%s", redisPrefix, siteUnique)
return Counts{
SitePv: sitePv,
SiteUv: siteUv,
PagePv: int64(pagePv),
PageUv: pageUv,
}
}

// Put
// @description put data only
func Put(ctx context.Context, host string, path string, userIdentity string) {
_redis := redisutil.RDB

rk := getKeys(host, path)

// sitePV and pagePV 使用 Str / Zset 存储
sitePv, _ := _redis.Incr(ctx, sitePvKey).Result()
pagePv, _ := _redis.ZIncrBy(ctx, pagePvKey, 1, pathUnique).Result()
_redis.Incr(ctx, rk.SitePvKey)
_redis.ZIncrBy(ctx, rk.PagePvKey, 1, rk.PathUnique)

// siteUv 和 pageUv 使用 HyperLogLog 存储
_redis.PFAdd(ctx, siteUvKey, userIdentity)
_redis.PFAdd(ctx, pageUvKey, userIdentity)
_redis.PFAdd(ctx, rk.SiteUvKey, userIdentity)
_redis.PFAdd(ctx, rk.PageUvKey, userIdentity)

// setExpire
go setExpire(ctx, rk.SiteUvKey, rk.PageUvKey, rk.SitePvKey, rk.PagePvKey)
return
}

// Get bsz counts
func Get(ctx context.Context, host string, path string, userIdentity string) Counts {
_redis := redisutil.RDB

rk := getKeys(host, path)

// sitePV and pagePV 使用 Str / Zset 存储
sitePv, _ := _redis.Get(ctx, rk.SitePvKey).Int64()
pagePv, _ := _redis.ZScore(ctx, rk.PagePvKey, rk.PathUnique).Result()

// count siteUv and pageUv
siteUv, _ := _redis.PFCount(ctx, siteUvKey).Result()
pageUv, _ := _redis.PFCount(ctx, pageUvKey).Result()
siteUv, _ := _redis.PFCount(ctx, rk.SiteUvKey).Result()
pageUv, _ := _redis.PFCount(ctx, rk.PageUvKey).Result()

// setExpire
go setExpire(ctx, siteUvKey, pageUvKey, sitePvKey, pagePvKey)
go setExpire(ctx, rk.SiteUvKey, rk.PageUvKey, rk.SitePvKey, rk.PagePvKey)

return Counts{
SitePv: sitePv,
Expand All @@ -96,3 +119,43 @@ func setExpire(ctx context.Context, key ...string) {
_redis.Expire(ctx, k, viper.GetDuration("bsz.expire")*time.Second)
}
}

func getKeys(host string, path string) RKeys {
var siteUnique = host
var pathUnique = host + path

// 兼容旧版本
if viper.GetBool("bsz.pathStyle") == false {
pathUnique = host + "&" + path
}

// encrypt
switch viper.GetString("bsz.Encrypt") {
case "MD516":
siteUnique = tool.Md5(siteUnique)[8:24]
pathUnique = tool.Md5(pathUnique)[8:24]
case "MD532":
siteUnique = tool.Md5(siteUnique)
pathUnique = tool.Md5(pathUnique)
default:
siteUnique = tool.Md5(siteUnique)
pathUnique = tool.Md5(pathUnique)
}

redisPrefix := viper.GetString("redis.prefix")

siteUvKey := strings.Join([]string{redisPrefix, "site_uv", siteUnique}, ":")
pageUvKey := strings.Join([]string{redisPrefix, "page_uv", siteUnique, pathUnique}, ":")

sitePvKey := strings.Join([]string{redisPrefix, "site_pv", siteUnique}, ":")
pagePvKey := strings.Join([]string{redisPrefix, "page_pv", siteUnique}, ":")

return RKeys{
SitePvKey: sitePvKey,
SiteUvKey: siteUvKey,
PagePvKey: pagePvKey,
PageUvKey: pageUvKey,
SiteUnique: siteUnique,
PathUnique: pathUnique,
}
}
2 changes: 1 addition & 1 deletion dist/busuanzi.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/busuanzi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

let bsz_send: Function = function () {
let xhr: XMLHttpRequest = new XMLHttpRequest();
xhr.open("POST", api, true);
xhr.open("GET", api, true);

// set user identity
let token: string | null = localStorage.getItem(storageName);
Expand Down
17 changes: 16 additions & 1 deletion dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
<meta charset="UTF-8">
<title>不蒜子 - powered by xcsoft</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="xcsoft">
<meta name="description" content="基于golang的简易页面访问统计">
<link rel="shortcut icon" href="https://raw.githubusercontent.com/soxft/busuanzi/main/dist/favicon.svg">
<link rel="shortcut icon" href="favicon.svg">
<link href="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap/4.6.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<link href="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/highlight.js/11.4.0/styles/atom-one-dark.min.css" type="text/css" rel="stylesheet" />
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/highlight.js/11.4.0/highlight.min.js" type="application/javascript"></script>
Expand All @@ -27,6 +28,20 @@
</head>

<body>
<a href="https://github.com/soxft/busuanzi" class="github-corner" aria-label="View source on GitHub">
<svg width="80" height="80" viewBox="0 0 250 250"
style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm">
</path>
<path
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
fill="currentColor" class="octo-body">
</path>
</svg>
</a>
<div style="height:10vh"></div>
<div class="container">
<div class="card">
Expand Down
11 changes: 10 additions & 1 deletion process/webutil/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@ import (

func initRoute(r *gin.Engine) {
{
r.Any("/api", middleware.Identity(), controller.ApiHandler)
api := r.Group("/api")
{
api.GET("/status", controller.GetHandler)

api.Use(middleware.Identity())
api.POST("", controller.ApiHandler)
api.GET("", controller.ApiHandler)
api.PUT("", controller.PutHandler)
}

r.GET("/ping", controller.PingHandler)

static := r.Group("/")
Expand Down

0 comments on commit 6c3d33a

Please sign in to comment.