mirror of
https://github.com/Kizuren/uLinkShortener.git
synced 2025-12-21 21:16:17 +01:00
126 lines
3.9 KiB
Go
126 lines
3.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/marcus7i/ulinkshortener/internal/database"
|
|
"github.com/marcus7i/ulinkshortener/internal/models"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
)
|
|
|
|
func (h *Handler) GetAnalytics(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
accountID := vars["accountID"]
|
|
|
|
ctx := context.Background()
|
|
var user models.User
|
|
err := h.DB.Collection(database.UsersCollection).FindOne(ctx, bson.M{"account_id": accountID}).Decode(&user)
|
|
if err != nil {
|
|
respondWithError(w, http.StatusUnauthorized, "Invalid account")
|
|
return
|
|
}
|
|
|
|
cursor, err := h.DB.Collection(database.LinksCollection).Find(ctx, bson.M{"account_id": accountID})
|
|
if err != nil {
|
|
respondWithError(w, http.StatusInternalServerError, "Failed to retrieve links")
|
|
return
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var links []models.Link
|
|
if err = cursor.All(ctx, &links); err != nil {
|
|
respondWithError(w, http.StatusInternalServerError, "Failed to process links")
|
|
return
|
|
}
|
|
|
|
cursor, err = h.DB.Collection(database.AnalyticsCollection).Find(ctx, bson.M{"account_id": accountID})
|
|
if err != nil {
|
|
respondWithError(w, http.StatusInternalServerError, "Failed to retrieve analytics")
|
|
return
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var analytics []map[string]interface{}
|
|
if err = cursor.All(ctx, &analytics); err != nil {
|
|
respondWithError(w, http.StatusInternalServerError, "Failed to process analytics")
|
|
return
|
|
}
|
|
|
|
respondWithJSON(w, http.StatusOK, map[string]interface{}{
|
|
"links": links,
|
|
"analytics": analytics,
|
|
})
|
|
}
|
|
|
|
func (h *Handler) GetStatsData(ctx context.Context) (models.Stats, error) {
|
|
|
|
totalLinks, err := h.DB.Collection(database.LinksCollection).CountDocuments(ctx, bson.M{})
|
|
if err != nil {
|
|
totalLinks = 0
|
|
}
|
|
|
|
totalClicks, err := h.DB.Collection(database.AnalyticsCollection).CountDocuments(ctx, bson.M{})
|
|
if err != nil {
|
|
totalClicks = 0
|
|
}
|
|
|
|
ipVersionsPipeline := mongo.Pipeline{
|
|
{{Key: "$group", Value: bson.D{{Key: "_id", Value: "$ip_version"}, {Key: "count", Value: bson.D{{Key: "$sum", Value: 1}}}}}},
|
|
{{Key: "$sort", Value: bson.D{{Key: "count", Value: -1}}}},
|
|
}
|
|
ipVersionsCursor, err := h.DB.Collection(database.AnalyticsCollection).Aggregate(ctx, ipVersionsPipeline)
|
|
var ipVersions []models.StatItem
|
|
if err == nil {
|
|
ipVersionsCursor.All(ctx, &ipVersions)
|
|
}
|
|
|
|
osPipeline := mongo.Pipeline{
|
|
{{Key: "$group", Value: bson.D{{Key: "_id", Value: "$platform"}, {Key: "count", Value: bson.D{{Key: "$sum", Value: 1}}}}}},
|
|
{{Key: "$sort", Value: bson.D{{Key: "count", Value: -1}}}},
|
|
{{Key: "$limit", Value: 10}},
|
|
}
|
|
osCursor, err := h.DB.Collection(database.AnalyticsCollection).Aggregate(ctx, osPipeline)
|
|
var osStats []models.StatItem
|
|
if err == nil {
|
|
osCursor.All(ctx, &osStats)
|
|
}
|
|
|
|
countryPipeline := mongo.Pipeline{
|
|
{{Key: "$group", Value: bson.D{{Key: "_id", Value: "$country"}, {Key: "count", Value: bson.D{{Key: "$sum", Value: 1}}}}}},
|
|
{{Key: "$sort", Value: bson.D{{Key: "count", Value: -1}}}},
|
|
{{Key: "$limit", Value: 10}},
|
|
}
|
|
countryCursor, err := h.DB.Collection(database.AnalyticsCollection).Aggregate(ctx, countryPipeline)
|
|
var countryStats []models.StatItem
|
|
if err == nil {
|
|
countryCursor.All(ctx, &countryStats)
|
|
}
|
|
|
|
ispPipeline := mongo.Pipeline{
|
|
{{Key: "$group", Value: bson.D{{Key: "_id", Value: "$isp"}, {Key: "count", Value: bson.D{{Key: "$sum", Value: 1}}}}}},
|
|
{{Key: "$sort", Value: bson.D{{Key: "count", Value: -1}}}},
|
|
{{Key: "$limit", Value: 10}},
|
|
}
|
|
ispCursor, err := h.DB.Collection(database.AnalyticsCollection).Aggregate(ctx, ispPipeline)
|
|
var ispStats []models.StatItem
|
|
if err == nil {
|
|
ispCursor.All(ctx, &ispStats)
|
|
}
|
|
|
|
stats := models.Stats{
|
|
TotalLinks: totalLinks,
|
|
TotalClicks: totalClicks,
|
|
ChartData: models.ChartData{
|
|
IPVersions: ipVersions,
|
|
OSStats: osStats,
|
|
CountryStats: countryStats,
|
|
ISPStats: ispStats,
|
|
},
|
|
LoggedIn: false,
|
|
}
|
|
|
|
return stats, nil
|
|
}
|