Skip to content

Commit

Permalink
Merge branch 'main' into prod
Browse files Browse the repository at this point in the history
  • Loading branch information
p-shubh committed Dec 18, 2024
2 parents 816be39 + 8e53777 commit 73e7c9e
Show file tree
Hide file tree
Showing 8 changed files with 421 additions and 22 deletions.
113 changes: 113 additions & 0 deletions api/v1/nodes/nodeActivity/nodeActivity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package nodeactivity

import (
"errors"
"math"
"time"

"github.com/NetSepio/erebrus-gateway/config/dbconfig"
"github.com/NetSepio/erebrus-gateway/models"
"github.com/NetSepio/erebrus-gateway/util/pkg/logwrapper"
"gorm.io/gorm"
)

func CalculateTotalAndTodayActiveDuration(peerID string) (totalDurationHr, todayDurationHr float64) {
db := dbconfig.GetDb()
now := time.Now()

// Fetch all activities for the given peer
var activities []models.NodeActivity
if err := db.Where("peer_id = ?", peerID).Find(&activities).Error; err != nil {
logwrapper.Errorf("failed to fetch activities for peer_id %s: %s", peerID, err)
return
}

var (
totalDuration int
todayDuration int
)

for _, activity := range activities {
// Calculate total active duration
if activity.EndTime != nil {
totalDuration += int(activity.EndTime.Sub(activity.StartTime).Seconds())
} else {
// If the node is still active, calculate the duration until now
totalDuration += int(now.Sub(activity.StartTime).Seconds())
}

// Calculate today's active duration
startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
if activity.EndTime != nil {
// If the activity occurred today and ended today
if activity.StartTime.After(startOfDay) {
todayDuration += int(activity.EndTime.Sub(activity.StartTime).Seconds())
}
} else {
// If the node is still active and the activity is today
if activity.StartTime.After(startOfDay) {
todayDuration += int(now.Sub(activity.StartTime).Seconds())
}
}
}

// Convert totalDuration and todayDuration from seconds to hours
// totalDurationHr = float64(totalDuration) / 3600
// todayDurationHr = float64(todayDuration) / 3600

// math.Round(i.TotalActiveDuration*100) / 100

// float64(totalDuration) / 3600

// float64(todayDuration) / 3600

return math.Round((float64(totalDuration)/3600)*100) / 100, math.Round((float64(todayDuration)/3600)*100) / 100
}

func TrackNodeActivity(peerID string, isActive bool) {
db := dbconfig.GetDb()
now := time.Now()

var activity models.NodeActivity
// Try to fetch an existing record with NULL end_time (active node)
err := db.Where("peer_id = ? AND end_time IS NULL", peerID).
First(&activity).Error

if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
logwrapper.Errorf("failed to fetch node activity: %s", err)
return
}

if isActive {
// If the node is active, check if an active record exists
if errors.Is(err, gorm.ErrRecordNotFound) {
// No active record, create a new one
newActivity := models.NodeActivity{
PeerID: peerID,
StartTime: now,
}
if err := db.Create(&newActivity).Error; err != nil {
logwrapper.Errorf("failed to create new node activity: %s", err)
}
} else {
// If node was already active, update the existing record
logwrapper.Infof("Node with peer_id %s is already active", peerID)
// Optionally, you can update any other fields if needed
}
} else {
// If the node becomes inactive
if !errors.Is(err, gorm.ErrRecordNotFound) {
// Update the activity record with the end time and duration
duration := int(now.Sub(activity.StartTime).Seconds()) // Duration in seconds
activity.EndTime = &now
activity.DurationSeconds = duration

if err := db.Save(&activity).Error; err != nil {
logwrapper.Errorf("failed to update node activity: %s", err)
}
} else {
// If there's no active record and the node is inactive, log the event
logwrapper.Infof("No active record found for peer_id %s to mark as inactive", peerID)
}
}
}
101 changes: 101 additions & 0 deletions api/v1/nodes/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package nodes

import (
"encoding/json"
"fmt"
"net/http"

nodeactivity "github.com/NetSepio/erebrus-gateway/api/v1/nodes/nodeActivity"
"github.com/NetSepio/erebrus-gateway/config/dbconfig"
"github.com/NetSepio/erebrus-gateway/models"
"github.com/NetSepio/erebrus-gateway/util/pkg/logwrapper"
Expand All @@ -16,6 +18,7 @@ func ApplyRoutes(r *gin.RouterGroup) {
{
g.GET("/all", FetchAllNodes)
g.GET("/:status", FetchAllNodesByStatus)
g.GET("/status_wallet_address/:status/:wallet_address", FetchAllNodesByStatusAndWalletAddress)
}
}

Expand Down Expand Up @@ -75,6 +78,12 @@ func FetchAllNodes(c *gin.Context) {
response.IpInfoOrg = ipGeoAddress.IpInfoOrg
response.IpInfoPostal = ipGeoAddress.IpInfoPostal
response.IpInfoTimezone = ipGeoAddress.IpInfoTimezone
// Round TotalActiveDuration and TodayActiveDuration to two decimal places

response.TotalActiveDuration, response.TodayActiveDuration = nodeactivity.CalculateTotalAndTodayActiveDuration(i.PeerId)

// response.TotalActiveDuration = math.Round(i.TotalActiveDuration*100) / 100
// response.TodayActiveDuration = math.Round(i.TodayActiveDuration*100) / 100

responses = append(responses, response)
}
Expand Down Expand Up @@ -139,6 +148,98 @@ func FetchAllNodesByStatus(c *gin.Context) {
response.IpInfoOrg = ipGeoAddress.IpInfoOrg
response.IpInfoPostal = ipGeoAddress.IpInfoPostal
response.IpInfoTimezone = ipGeoAddress.IpInfoTimezone
// Round TotalActiveDuration and TodayActiveDuration to two decimal places
// response.TotalActiveDuration = math.Round(i.TotalActiveDuration*100) / 100
// response.TodayActiveDuration = math.Round(i.TodayActiveDuration*100) / 100

response.TotalActiveDuration, response.TodayActiveDuration = nodeactivity.CalculateTotalAndTodayActiveDuration(i.PeerId)

responses = append(responses, response)
}

httpo.NewSuccessResponseP(200, "Nodes fetched succesfully", responses).SendD(c)
}

func FetchAllNodesByStatusAndWalletAddress(c *gin.Context) {
status := c.Param("status") // active , inactive
walletAddress := c.Param("wallet_address") // active , inactive

fmt.Printf("status : %v , wallet address : %v ", status, walletAddress)

if len(walletAddress) == 0 || walletAddress == "wallet_address" {
logwrapper.Errorf("please pass the wallet address : ", walletAddress)
httpo.NewErrorResponse(http.StatusBadRequest, "Please provide the wallet_address").SendD(c)
return
}

db := dbconfig.GetDb()
var nodes *[]models.Node
// var node *models.Node
if len(status) == 0 || status == ":status" {
if err := db.Where("wallet_address = ?", walletAddress).Find(&nodes).Error; err != nil {
logwrapper.Errorf("failed to get nodes from DB: %s", err)
httpo.NewErrorResponse(http.StatusInternalServerError, err.Error()).SendD(c)
return
}
} else {
if err := db.Where("wallet_address = ? AND status = ? ", walletAddress, status).Find(&nodes).Error; err != nil {
logwrapper.Errorf("failed to get nodes from DB: %s", err)
httpo.NewErrorResponse(http.StatusInternalServerError, err.Error()).SendD(c)
return
}
}

// Unmarshal SystemInfo into OSInfo struct

var responses []models.NodeResponse
var response models.NodeResponse

for _, i := range *nodes {
var osInfo models.OSInfo
if len(i.SystemInfo) > 0 {
err := json.Unmarshal([]byte(i.SystemInfo), &osInfo)
if err != nil {
logwrapper.Errorf("failed to get nodes from DB OSInfo: %s", err)
// httpo.NewErrorResponse(http.StatusInternalServerError, err.Error()).SendD(c)
}
}
// Unmarshal IpInfo into IPInfo struct
var ipGeoAddress models.IpGeoAddress
if len(i.IpGeoData) > 0 {
err := json.Unmarshal([]byte(i.IpGeoData), &ipGeoAddress)
if err != nil {
logwrapper.Errorf("failed to get nodes from DB IpGeoAddress: %s", err)
// httpo.NewErrorResponse(http.StatusInternalServerError, err.Error()).SendD(c)
}
}

response.Id = i.PeerId
response.Name = i.Name
response.HttpPort = i.HttpPort
response.Domain = i.Host
response.NodeName = i.Name
response.Address = i.PeerAddress
response.Region = i.Region
response.Status = i.Status
response.DownloadSpeed = i.DownloadSpeed
response.UploadSpeed = i.UploadSpeed
response.StartTimeStamp = i.RegistrationTime
response.LastPingedTimeStamp = i.LastPing
response.Chain = i.Chain
response.WalletAddressSui = i.WalletAddress
response.WalletAddressSolana = i.WalletAddress
response.IpInfoIP = ipGeoAddress.IpInfoIP
response.IpInfoCity = ipGeoAddress.IpInfoCity
response.IpInfoCountry = ipGeoAddress.IpInfoCountry
response.IpInfoLocation = ipGeoAddress.IpInfoLocation
response.IpInfoOrg = ipGeoAddress.IpInfoOrg
response.IpInfoPostal = ipGeoAddress.IpInfoPostal
response.IpInfoTimezone = ipGeoAddress.IpInfoTimezone
// Round TotalActiveDuration and TodayActiveDuration to two decimal places
// response.TotalActiveDuration = math.Round(i.TotalActiveDuration*100) / 100
// response.TodayActiveDuration = math.Round(i.TodayActiveDuration*100) / 100

response.TotalActiveDuration, response.TodayActiveDuration = nodeactivity.CalculateTotalAndTodayActiveDuration(i.PeerId)

responses = append(responses, response)
}
Expand Down
3 changes: 2 additions & 1 deletion api/v1/v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"github.com/NetSepio/erebrus-gateway/api/v1/client"
nodedwifi "github.com/NetSepio/erebrus-gateway/api/v1/nodeDwifi"
"github.com/NetSepio/erebrus-gateway/api/v1/nodeOperatorForm"

"github.com/NetSepio/erebrus-gateway/api/v1/nodes"
"github.com/NetSepio/erebrus-gateway/api/v1/registerDwifi"
"github.com/NetSepio/erebrus-gateway/api/v1/subscription"
"github.com/NetSepio/erebrus-gateway/api/v1/walrusFileStorage"
"github.com/gin-gonic/gin"
)

Expand All @@ -22,5 +22,6 @@ func ApplyRoutes(r *gin.RouterGroup) {
nodeOperatorForm.ApplyRoutes(v1)
registerDwifi.ApplyRoutes(v1)
nodedwifi.ApplyRoutes(v1)
walrusFileStorage.ApplyRoutes(v1)
}
}
119 changes: 119 additions & 0 deletions api/v1/walrusFileStorage/walrusFileStorage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package walrusFileStorage

import (
"net/http"

"github.com/NetSepio/erebrus-gateway/config/dbconfig"
"github.com/NetSepio/erebrus-gateway/models"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)

func ApplyRoutes(r *gin.RouterGroup) {
g := r.Group("/walrusFileStorage")
{
g.POST("", upsertWalrusStorage)
g.DELETE("/:address", deleteWalrusStorage)
g.DELETE("/:address/blob/:blob_id", deleteBlobID)
g.GET("/:address", getAllWalrusStorage)
}
}

func upsertWalrusStorage(c *gin.Context) {
var walrus models.WalrusStorage
if err := c.ShouldBindJSON(&walrus); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

db := dbconfig.GetDb()

var existingWalrus models.WalrusStorage
result := db.Where("wallet_address = ?", walrus.WalletAddress).First(&existingWalrus)

if result.Error == nil {
existingWalrus.FileBlobs = append(existingWalrus.FileBlobs, walrus.FileBlobs...)
if err := db.Save(&existingWalrus).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update wallet"})
return
}
c.JSON(http.StatusOK, existingWalrus)
} else if result.Error == gorm.ErrRecordNotFound {
if err := db.Create(&walrus).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create wallet"})
return
}
c.JSON(http.StatusCreated, walrus)
} else {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
}
}

func deleteBlobID(c *gin.Context) {
walletAddress := c.Param("address")
blobID := c.Param("blob_id")
db := dbconfig.GetDb()

var walrus models.WalrusStorage
if err := db.Where("wallet_address = ?", walletAddress).First(&walrus).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Wallet not found"})
return
}

index := -1
for i, fileObj := range walrus.FileBlobs {
if fileObj.BlobID == blobID {
index = i
break
}
}

if index == -1 {
c.JSON(http.StatusNotFound, gin.H{"error": "Blob ID not found"})
return
}

walrus.FileBlobs = append(walrus.FileBlobs[:index], walrus.FileBlobs[index+1:]...)

if err := db.Save(&walrus).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update wallet"})
return
}

c.JSON(http.StatusOK, gin.H{"message": "Blob ID removed successfully"})
}

func deleteWalrusStorage(c *gin.Context) {
address := c.Param("address")
db := dbconfig.GetDb()

var walrus models.WalrusStorage
if err := db.Where("wallet_address = ?", address).First(&walrus).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Wallet not found"})
return
}

if err := db.Delete(&walrus).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete wallet"})
return
}

c.JSON(http.StatusOK, gin.H{"message": "Wallet deleted successfully"})
}

func getAllWalrusStorage(c *gin.Context) {
address := c.Param("address")
db := dbconfig.GetDb()

var walrus models.WalrusStorage
if err := db.Where("wallet_address = ?", address).First(&walrus).Error; err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusNotFound, gin.H{"error": "Wallet not found"})
} else {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve wallet"})
}
return
}

c.JSON(http.StatusOK, gin.H{"file_blobs": walrus.FileBlobs})
}
Loading

0 comments on commit 73e7c9e

Please sign in to comment.