OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
 
master @ 146 LINES
 
[ HISTORY ]  [ UP ]
 

package indexes

import (
	"database/sql"
	"fmt"
	"path/filepath"
	"strings"

	"github.com/charmbracelet/log"

	"ookstats/internal/writer"
)

var dungeonShortNames = map[string]string{
	"temple-of-the-jade-serpent": "TJS",
	"stormstout-brewery":         "SB",
	"shado-pan-monastery":        "SPM",
	"mogu-shan-palace":           "MSP",
	"siege-of-niuzao-temple":     "SNT",
	"gate-of-the-setting-sun":    "GSS",
	"scarlet-halls":              "SH",
	"scarlet-monastery":          "SM",
	"scholomance":                "SCHOLO",
}

func generateShortName(name string) string {
	words := strings.Fields(name)
	if len(words) == 0 {
		return ""
	}

	var acronym strings.Builder
	for _, word := range words {
		if len(word) > 0 && word != "of" && word != "the" {
			acronym.WriteRune([]rune(strings.ToUpper(word))[0])
		}
	}

	result := acronym.String()
	if len(result) > 6 {
		result = result[:6]
	}
	return result
}

func loadDungeons(db *sql.DB) ([]DungeonData, error) {
	rows, err := db.Query(`
		SELECT id, slug, name, map_challenge_mode_id
		FROM dungeons
		ORDER BY name
	`)
	if err != nil {
		return nil, fmt.Errorf("query dungeons: %w", err)
	}
	defer rows.Close()

	var dungeons []DungeonData
	for rows.Next() {
		var id int
		var slug, name string
		var mapChallengeModeID sql.NullInt64

		if err := rows.Scan(&id, &slug, &name, &mapChallengeModeID); err != nil {
			return nil, fmt.Errorf("scan dungeon: %w", err)
		}

		shortName := dungeonShortNames[slug]
		if shortName == "" {
			shortName = generateShortName(name)
		}

		var mapChallengeID *int
		if mapChallengeModeID.Valid {
			val := int(mapChallengeModeID.Int64)
			mapChallengeID = &val
		}

		dungeons = append(dungeons, DungeonData{
			ID:                 id,
			Slug:               slug,
			Name:               name,
			ShortName:          shortName,
			MapChallengeModeID: mapChallengeID,
		})
	}

	return dungeons, nil
}

// GenerateGlobalDungeonsIndex generates index of dungeons for global leaderboards
func GenerateGlobalDungeonsIndex(db *sql.DB, outDir string, seasonID int) error {
	log.Info("Generating global dungeons index", "season", seasonID)

	dungeons, err := loadDungeons(db)
	if err != nil {
		return err
	}

	// Add links for global scope
	for i := range dungeons {
		dungeons[i].Links = DungeonLinks{
			Leaderboard: Link{Href: fmt.Sprintf("/api/leaderboard/season/%d/global/%s/{page
}.json", seasonID, dungeons[i].Slug)},
		}
	}

	index := DungeonsIndex{
		Data:     dungeons,
		Metadata: NewIndexMetadata(len(dungeons)),
	}

	outPath := filepath.Join(outDir, "api", "leaderboard", "season", fmt.Sprintf("%d"
, seasonID), "global", "index.json")
	if err := writer.WriteJSONFile(outPath, index); err != nil {
		return err
	}

	log.Info("Generated global dungeons index", "season", seasonID, "count", len(dung
eons), "path", outPath)
	return nil
}

// GenerateRealmDungeonsIndex generates index of dungeons for a specific realm
func GenerateRealmDungeonsIndex(db *sql.DB, outDir string, seasonID int, region, r
ealm string) error {
	dungeons, err := loadDungeons(db)
	if err != nil {
		return err
	}

	// Add links for realm scope
	for i := range dungeons {
		dungeons[i].Links = DungeonLinks{
			Leaderboard: Link{Href: fmt.Sprintf("/api/leaderboard/season/%d/%s/%s/%s/{page}
.json", seasonID, region, realm, dungeons[i].Slug)},
		}
	}

	index := RealmDungeonsIndex{
		Data:     dungeons,
		Metadata: NewIndexMetadata(len(dungeons)),
	}

	outPath := filepath.Join(outDir, "api", "leaderboard", "season", fmt.Sprintf("%d"
, seasonID), region, realm, "index.json")
	if err := writer.WriteJSONFile(outPath, index); err != nil {
		return err
	}

	return nil
}

package indexes

import (
	"database/sql"
	"fmt"
	"path/filepath"
	"strings"

	"github.com/charmbracelet/log"

	"ookstats/internal/writer"
)

var dungeonShortNames = map[string]string{
	"temple-of-the-jade-serpent": "TJS",
	"stormstout-brewery":         "SB",
	"shado-pan-monastery":        "SPM",
	"mogu-shan-palace":           "MSP",
	"siege-of-niuzao-temple":     "SNT",
	"gate-of-the-setting-sun":    "GSS",
	"scarlet-halls":              "SH",
	"scarlet-monastery":          "SM",
	"scholomance":                "SCHOLO",
}

func generateShortName(name string) string {
	words := strings.Fields(name)
	if len(words) == 0 {
		return ""
	}

	var acronym strings.Builder
	for _, word := range words {
		if len(word) > 0 && word != "of" && word !
= "the" {
			acronym.WriteRune([]rune(strings.ToUpper(
word))[0])
		}
	}

	result := acronym.String()
	if len(result) > 6 {
		result = result[:6]
	}
	return result
}

func loadDungeons(db *sql.DB) ([]DungeonData
, error) {
	rows, err := db.Query(`
		SELECT id, slug, name, map_challenge_mode_
id
		FROM dungeons
		ORDER BY name
	`)
	if err != nil {
		return nil, fmt.Errorf("query dungeons: %w
", err)
	}
	defer rows.Close()

	var dungeons []DungeonData
	for rows.Next() {
		var id int
		var slug, name string
		var mapChallengeModeID sql.NullInt64

		if err := rows.Scan(&id, &slug, &name, &ma
pChallengeModeID); err != nil {
			return nil, fmt.Errorf("scan dungeon: %w"
, err)
		}

		shortName := dungeonShortNames[slug]
		if shortName == "" {
			shortName = generateShortName(name)
		}

		var mapChallengeID *int
		if mapChallengeModeID.Valid {
			val := int(mapChallengeModeID.Int64)
			mapChallengeID = &val
		}

		dungeons = append(dungeons, DungeonData{
			ID:                 id,
			Slug:               slug,
			Name:               name,
			ShortName:          shortName,
			MapChallengeModeID: mapChallengeID,
		})
	}

	return dungeons, nil
}

// GenerateGlobalDungeonsIndex generates ind
ex of dungeons for global leaderboards
func GenerateGlobalDungeonsIndex(db *sql.DB,
 outDir string, seasonID int) error {
	log.Info("Generating global dungeons index"
, "season", seasonID)

	dungeons, err := loadDungeons(db)
	if err != nil {
		return err
	}

	// Add links for global scope
	for i := range dungeons {
		dungeons[i].Links = DungeonLinks{
			Leaderboard: Link{Href: fmt.Sprintf("/api
/leaderboard/season/%d/global/%s/{page}.json
", seasonID, dungeons[i].Slug)},
		}
	}

	index := DungeonsIndex{
		Data:     dungeons,
		Metadata: NewIndexMetadata(len(dungeons)),
	}

	outPath := filepath.Join(outDir, "api", "le
aderboard", "season", fmt.Sprintf("%d", seas
onID), "global", "index.json")
	if err := writer.WriteJSONFile(outPath, ind
ex); err != nil {
		return err
	}

	log.Info("Generated global dungeons index",
 "season", seasonID, "count", len(dungeons),
 "path", outPath)
	return nil
}

// GenerateRealmDungeonsIndex generates inde
x of dungeons for a specific realm
func GenerateRealmDungeonsIndex(db *sql.DB, 
outDir string, seasonID int, region, realm s
tring) error {
	dungeons, err := loadDungeons(db)
	if err != nil {
		return err
	}

	// Add links for realm scope
	for i := range dungeons {
		dungeons[i].Links = DungeonLinks{
			Leaderboard: Link{Href: fmt.Sprintf("/api
/leaderboard/season/%d/%s/%s/%s/{page}.json"
, seasonID, region, realm, dungeons[i].Slug)
},
		}
	}

	index := RealmDungeonsIndex{
		Data:     dungeons,
		Metadata: NewIndexMetadata(len(dungeons)),
	}

	outPath := filepath.Join(outDir, "api", "le
aderboard", "season", fmt.Sprintf("%d", seas
onID), region, realm, "index.json")
	if err := writer.WriteJSONFile(outPath, ind
ex); err != nil {
		return err
	}

	return nil
}
 
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET