This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
func CheckAllowed(c *gin.Context) {
|
||||
secret := c.GetHeader("X-SECRET-KEY")
|
||||
if secret != initializers.SECRET {
|
||||
if secret != initializers.SecretKey {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "Forbidden"})
|
||||
c.Abort()
|
||||
return
|
||||
@@ -18,7 +18,7 @@ func CheckAllowed(c *gin.Context) {
|
||||
|
||||
func CheckAdmin(c *gin.Context) {
|
||||
adminSecret := c.GetHeader("X-ADMIN-KEY")
|
||||
if adminSecret != initializers.ADMIN_SECRET {
|
||||
if adminSecret != initializers.AdminSecret {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "Forbidden"})
|
||||
c.Abort()
|
||||
return
|
||||
|
||||
@@ -52,113 +52,6 @@ func convertToSimplifiedAddonWithoutFiles(addon models.Addon) models.SimplifiedA
|
||||
|
||||
func GetDuplicates(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
// First check if addon exists (lightweight query)
|
||||
var exists bool
|
||||
if err := initializers.DB.Model(&models.Addon{}).Select("1").Where("id = ?", id).Limit(1).Find(&exists).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Addon not found"})
|
||||
return
|
||||
}
|
||||
|
||||
// Get only the hashes from source addon files (don't load full addon yet)
|
||||
var sourceHashes []string
|
||||
if err := initializers.DB.Model(&models.AddonFile{}).
|
||||
Where("addon_id = ? AND hash != ''", id).
|
||||
Pluck("hash", &sourceHashes).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch source addon files"})
|
||||
return
|
||||
}
|
||||
|
||||
// Now load the full source addon for the response
|
||||
var sourceAddon models.Addon
|
||||
if err := initializers.DB.Preload("AddonFiles").First(&sourceAddon, "id = ?", id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Addon not found"})
|
||||
return
|
||||
}
|
||||
|
||||
simplifiedSourceAddon := convertToSimplifiedAddon(sourceAddon)
|
||||
|
||||
if len(sourceHashes) == 0 {
|
||||
c.JSON(http.StatusOK, models.DuplicatesResponse{
|
||||
SourceAddon: simplifiedSourceAddon,
|
||||
DuplicateAddons: make(map[string]models.AddonWithDuplicates),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Single query with JOIN to get all data
|
||||
type DuplicateRow struct {
|
||||
Hash string
|
||||
Path string
|
||||
Version string
|
||||
AddonID string
|
||||
AddonName string
|
||||
AddonType string
|
||||
Summary string
|
||||
Preview string
|
||||
Author string
|
||||
SubscriberCount int
|
||||
CurrentVersionNumber string
|
||||
}
|
||||
|
||||
var duplicates []DuplicateRow
|
||||
err := initializers.DB.Table("addon_files af").
|
||||
Select(`af.hash, af.path, af.version, af.addon_id,
|
||||
a.name as addon_name, a.type as addon_type, a.summary,
|
||||
a.preview, a.author, a.subscriber_count, a.current_version_number`).
|
||||
Joins("INNER JOIN addons a ON a.id = af.addon_id").
|
||||
Joins("LEFT JOIN whitelisted_hashes wh ON wh.hash = af.hash").
|
||||
Where(`af.hash IN ?
|
||||
AND af.addon_id != ?
|
||||
AND af.deleted_at IS NULL
|
||||
AND wh.hash IS NULL`,
|
||||
sourceHashes, id).
|
||||
Scan(&duplicates).Error
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch duplicates"})
|
||||
return
|
||||
}
|
||||
|
||||
// Build response from single result set
|
||||
response := models.DuplicatesResponse{
|
||||
SourceAddon: simplifiedSourceAddon,
|
||||
DuplicateAddons: make(map[string]models.AddonWithDuplicates),
|
||||
}
|
||||
|
||||
for _, dup := range duplicates {
|
||||
if _, exists := response.DuplicateAddons[dup.AddonID]; !exists {
|
||||
response.DuplicateAddons[dup.AddonID] = models.AddonWithDuplicates{
|
||||
Addon: models.SimplifiedAddon{
|
||||
ID: dup.AddonID,
|
||||
Name: dup.AddonName,
|
||||
Type: dup.AddonType,
|
||||
Summary: dup.Summary,
|
||||
Preview: dup.Preview,
|
||||
Author: dup.Author,
|
||||
SubscriberCount: dup.SubscriberCount,
|
||||
CurrentVersionNumber: dup.CurrentVersionNumber,
|
||||
AddonFiles: []models.SimplifiedAddonFile{},
|
||||
},
|
||||
Duplicates: []models.DuplicateFileInfo{},
|
||||
}
|
||||
}
|
||||
|
||||
entry := response.DuplicateAddons[dup.AddonID]
|
||||
entry.Duplicates = append(entry.Duplicates, models.DuplicateFileInfo{
|
||||
Path: dup.Path,
|
||||
Hash: dup.Hash,
|
||||
Version: dup.Version,
|
||||
AddonID: dup.AddonID,
|
||||
})
|
||||
response.DuplicateAddons[dup.AddonID] = entry
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
/*func GetDuplicates(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
fmt.Println("Fetching addon with ID:", id)
|
||||
|
||||
// Fetch the source addon with its files
|
||||
@@ -236,6 +129,19 @@ func GetDuplicates(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// Set Recheck flag for source addon and all duplicate addons
|
||||
if err := initializers.DB.Model(&models.Addon{}).Where("id = ?", id).Update("recheck", true).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update source addon"})
|
||||
return
|
||||
}
|
||||
|
||||
for _, addon := range duplicateAddons {
|
||||
if err := initializers.DB.Model(&models.Addon{}).Where("id = ?", addon.ID).Update("recheck", true).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update duplicate addon"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Build the response
|
||||
response := models.DuplicatesResponse{
|
||||
SourceAddon: simplifiedSourceAddon,
|
||||
@@ -269,7 +175,7 @@ func GetDuplicates(c *gin.Context) {
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response)
|
||||
}*/
|
||||
}
|
||||
|
||||
func GetPossibleAddons(c *gin.Context) {
|
||||
query := c.Query("q")
|
||||
|
||||
@@ -105,7 +105,7 @@ func SaveIndexingResult(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if initializers.DiscordWebhook != "" {
|
||||
if initializers.DiscordWebhookURL != "" {
|
||||
text := "Indexing of addon " + addon.Name + " (" + addon.ID + ") was successful."
|
||||
colour := 2228479
|
||||
nbr := strconv.Itoa(len(result.Files))
|
||||
@@ -118,16 +118,16 @@ func SaveIndexingResult(c *gin.Context) {
|
||||
|
||||
percentage := 0.0
|
||||
if addonsCount > 0 {
|
||||
percentage = (float64(addonsCount - addonsToBeIndexed) / float64(addonsCount)) * 100
|
||||
percentage = (float64(addonsCount-addonsToBeIndexed) / float64(addonsCount)) * 100
|
||||
}
|
||||
|
||||
txt := fmt.Sprintf("%d/%d (%.2f%%).", addonsCount - addonsToBeIndexed, addonsCount, percentage)
|
||||
txt := fmt.Sprintf("%d/%d (%.2f%%).", addonsCount-addonsToBeIndexed, addonsCount, percentage)
|
||||
|
||||
myEmbed := models.CustomEmbed{
|
||||
Title: text,
|
||||
Title: text,
|
||||
Description: fmt.Sprintf("Files Indexed: %s\nOverall Progress: %s", nbr, txt),
|
||||
Color: colour,
|
||||
Timestamp: time.Now(),
|
||||
Color: colour,
|
||||
Timestamp: time.Now(),
|
||||
Image: models.CustomImage{
|
||||
URL: addon.Preview,
|
||||
},
|
||||
@@ -152,10 +152,10 @@ func SaveIndexingResult(c *gin.Context) {
|
||||
|
||||
myHook := models.CustomHook{
|
||||
Username: "Reforger Crawler",
|
||||
Embeds: []models.CustomEmbed{myEmbed},
|
||||
Embeds: []models.CustomEmbed{myEmbed},
|
||||
}
|
||||
|
||||
err := SendCustomWebhook(initializers.DiscordWebhook, myHook)
|
||||
err := SendCustomWebhook(initializers.DiscordWebhookURL, myHook)
|
||||
if err != nil {
|
||||
fmt.Println("Error sending webhook:", err)
|
||||
}
|
||||
@@ -208,27 +208,27 @@ func checkIndexingTimeout() {
|
||||
}
|
||||
|
||||
func SendCustomWebhook(webhookURL string, hook models.CustomHook) error {
|
||||
payload, err := json.Marshal(hook)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
payload, err := json.Marshal(hook)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(payload))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(payload))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||
return fmt.Errorf("webhook failed with status code %d", resp.StatusCode)
|
||||
}
|
||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||
return fmt.Errorf("webhook failed with status code %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -15,10 +17,14 @@ var nbrOfUnsentWebhooks int
|
||||
|
||||
func CreateAddon(c *gin.Context) {
|
||||
var addonR models.Addon
|
||||
body := make([]byte, 0)
|
||||
c.Request.Body.Read(body)
|
||||
fmt.Println(body)
|
||||
err := c.ShouldBindJSON(&addonR)
|
||||
body, err := io.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{"error": "Failed to read request body"})
|
||||
return
|
||||
}
|
||||
fmt.Println(string(body))
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
|
||||
err = c.ShouldBindJSON(&addonR)
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{"error": "Invalid JSON"})
|
||||
return
|
||||
@@ -44,7 +50,7 @@ func CreateAddon(c *gin.Context) {
|
||||
nbrOfUnsentWebhooks = 0
|
||||
|
||||
go func() {
|
||||
webhookURL := initializers.ScraperWebhook
|
||||
webhookURL := initializers.ScraperWebhookURL
|
||||
if webhookURL != "" {
|
||||
text := fmt.Sprintf("New %d addons found\nLast: %s (%s).", oldNbr, addon.ID, addon.Name)
|
||||
colour := 2228479
|
||||
@@ -102,44 +108,44 @@ func CreateAddon(c *gin.Context) {
|
||||
|
||||
// send webhook about update
|
||||
go func() {
|
||||
webhookURL := initializers.ScraperWebhook
|
||||
if webhookURL != "" {
|
||||
text := fmt.Sprintf("Addon: %s (%s) updated", addon.ID, addon.Name)
|
||||
colour := 2228479
|
||||
size := fmt.Sprintf("%.2f MB", float64(addon.CurrentVersionSize)/1_000_000)
|
||||
webhookURL := initializers.ScraperWebhookURL
|
||||
if webhookURL != "" {
|
||||
text := fmt.Sprintf("Addon: %s (%s) updated", addon.ID, addon.Name)
|
||||
colour := 2228479
|
||||
size := fmt.Sprintf("%.2f MB", float64(addon.CurrentVersionSize)/1_000_000)
|
||||
|
||||
myEmbed := models.CustomEmbed{
|
||||
Title: text,
|
||||
Color: colour,
|
||||
Timestamp: time.Now(),
|
||||
Image: models.CustomImage{
|
||||
URL: addon.Preview,
|
||||
},
|
||||
Fields: []models.CustomEmbedField{
|
||||
{
|
||||
Name: "Size",
|
||||
Value: size,
|
||||
Inline: true,
|
||||
myEmbed := models.CustomEmbed{
|
||||
Title: text,
|
||||
Color: colour,
|
||||
Timestamp: time.Now(),
|
||||
Image: models.CustomImage{
|
||||
URL: addon.Preview,
|
||||
},
|
||||
{
|
||||
Name: "Current Version",
|
||||
Value: addon.CurrentVersionNumber,
|
||||
Inline: true,
|
||||
Fields: []models.CustomEmbedField{
|
||||
{
|
||||
Name: "Size",
|
||||
Value: size,
|
||||
Inline: true,
|
||||
},
|
||||
{
|
||||
Name: "Current Version",
|
||||
Value: addon.CurrentVersionNumber,
|
||||
Inline: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
myHook := models.CustomHook{
|
||||
Username: "Reforger Crawler",
|
||||
Embeds: []models.CustomEmbed{myEmbed},
|
||||
}
|
||||
myHook := models.CustomHook{
|
||||
Username: "Reforger Crawler",
|
||||
Embeds: []models.CustomEmbed{myEmbed},
|
||||
}
|
||||
|
||||
err := SendCustomWebhook(webhookURL, myHook)
|
||||
if err != nil {
|
||||
fmt.Println("Error sending webhook:", err)
|
||||
err := SendCustomWebhook(webhookURL, myHook)
|
||||
if err != nil {
|
||||
fmt.Println("Error sending webhook:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}()
|
||||
}
|
||||
}
|
||||
c.JSON(200, gin.H{"status": "success"})
|
||||
|
||||
Reference in New Issue
Block a user