<commit_before>package api

import (
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/mdlayher/wavepipe/common"

	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/mdlayher/goset"
	"github.com/unrolled/render"
)

// databaseMetricsCache is used to cache database metrics until a database update occurs
var databaseMetricsCache *common.DatabaseMetrics

// cacheTime is used to determine when metrics were last cached
var cacheTime int64

// StatusResponse represents the JSON response for /api/status
type StatusResponse struct {
	Error   *Error          `json:"error"`
	Status  *common.Status  `json:"status"`
	Metrics *common.Metrics `json:"metrics"`
}

// GetStatus returns the current server status, with an HTTP status and JSON
func GetStatus(res http.ResponseWriter, req *http.Request) {
	// Retrieve render
	r := context.Get(req, CtxRender).(*render.Render)

	// Output struct for songs request
	out := StatusResponse{}

	// Check API version
	if version, ok := mux.Vars(req)["version"]; ok {
		// Check if this API call is supported in the advertised version
		if !apiVersionSet.Has(version) {
			r.JSON(res, 400, errRes(400, "unsupported API version: "+version))
			return
		}
	}

	// Retrieve current server status
	status, err := common.ServerStatus()
	if err != nil {
		log.Println(err)
		r.JSON(res, 500, serverErr)
		return
	}

	// Copy into response
	out.Status = status

	// If requested, fetch additional metrics (not added by default due to full table scans in database)
	if metricTypes := req.URL.Query().Get("metrics"); metricTypes != "" {
		// Begin building metrics
		metrics := &common.Metrics{}

		// Constants to check for various metric types
		const (
			mAll      = "all"
			mDatabase = "database"
			mNetwork  = "network"
		)

		// Set of valid metric types
		validSet := set.New(mAll, mDatabase, mNetwork)

		// Check for comma-separated list of metric types
		metricSet := set.New()
		for _, m := range strings.Split(metricTypes, ",") {
			// Add valid types to set
			if validSet.Has(m) {
				metricSet.Add(m)
			}
		}

		// If requested, get metrics about the database
		if metricSet.Has(mAll) || metricSet.Has(mDatabase) {
			// Check for cached metrics, and make sure they are up to date
			if databaseMetricsCache != nil && common.ScanTime() <= cacheTime {
				metrics.Database = databaseMetricsCache
			} else {
				// Fetch new metrics
				dbMetrics, err := common.GetDatabaseMetrics()
				if err != nil {
					log.Println(err)
					r.JSON(res, 500, serverErr)
					return
				}
				metrics.Database = dbMetrics

				// Cache metrics and update time
				databaseMetricsCache = dbMetrics
				cacheTime = time.Now().Unix()
			}
		}

		// If requested, get metrics about the network
		if metricSet.Has(mAll) || metricSet.Has(mNetwork) {
			metrics.Network = &common.NetworkMetrics{
				RXBytes: common.RXBytes(),
				TXBytes: common.TXBytes(),
			}
		}

		// Return metrics
		out.Metrics = metrics
	}

	// HTTP 200 OK with JSON
	out.Error = nil
	r.JSON(res, 200, out)
	return
}<commit_msg>api/status: cleanup<commit_after>package api

import (
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/mdlayher/wavepipe/common"

	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/mdlayher/goset"
	"github.com/unrolled/render"
)

// databaseMetricsCache is used to cache database metrics until a database update occurs
var databaseMetricsCache *common.DatabaseMetrics

// cacheTime is used to determine when metrics were last cached
var cacheTime int64

// StatusResponse represents the JSON response for /api/status
type StatusResponse struct {
	Error   *Error          `json:"error"`
	Status  *common.Status  `json:"status"`
	Metrics *common.Metrics `json:"metrics"`
}

// GetStatus returns the current server status, and optionally, server metrics, with
// an HTTP status and JSON.
func GetStatus(w http.ResponseWriter, r *http.Request) {
	// Retrieve render
	ren := context.Get(r, CtxRender).(*render.Render)

	// Output struct for songs request
	out := StatusResponse{}

	// Check API version
	if version, ok := mux.Vars(r)["version"]; ok {
		// Check if this API call is supported in the advertised version
		if !apiVersionSet.Has(version) {
			ren.JSON(w, 400, errRes(400, "unsupported API version: "+version))
			return
		}
	}

	// Retrieve current server status
	status, err := common.ServerStatus()
	if err != nil {
		log.Println(err)
		ren.JSON(w, 500, serverErr)
		return
	}

	// Copy into response
	out.Status = status

	// If requested, fetch additional metrics (not added by default due to full table scans in database)
	if metricTypes := r.URL.Query().Get("metrics"); metricTypes != "" {
		// Begin building metrics
		metrics := &common.Metrics{}

		// Constants to check for various metric types
		const (
			mAll      = "all"
			mDatabase = "database"
			mNetwork  = "network"
		)

		// Set of valid metric types
		validSet := set.New(mAll, mDatabase, mNetwork)

		// Check for comma-separated list of metric types
		metricSet := set.New()
		for _, m := range strings.Split(metricTypes, ",") {
			// Add valid types to set
			if validSet.Has(m) {
				metricSet.Add(m)
			}
		}

		// If requested, get metrics about the database
		if metricSet.Has(mAll) || metricSet.Has(mDatabase) {
			// Check for cached metrics, and make sure they are up to date
			if databaseMetricsCache != nil && common.ScanTime() <= cacheTime {
				metrics.Database = databaseMetricsCache
			} else {
				// Fetch new metrics
				dbMetrics, err := common.GetDatabaseMetrics()
				if err != nil {
					log.Println(err)
					ren.JSON(w, 500, serverErr)
					return
				}
				metrics.Database = dbMetrics

				// Cache metrics and update time
				databaseMetricsCache = dbMetrics
				cacheTime = time.Now().Unix()
			}
		}

		// If requested, get metrics about the network
		if metricSet.Has(mAll) || metricSet.Has(mNetwork) {
			metrics.Network = &common.NetworkMetrics{
				RXBytes: common.RXBytes(),
				TXBytes: common.TXBytes(),
			}
		}

		// Return metrics
		out.Metrics = metrics
	}

	// HTTP 200 OK with JSON
	out.Error = nil
	ren.JSON(w, 200, out)
	return
}
{'fraction_non_alphanumeric': 0.11515844495262986, 'fraction_numerical': 0.006533812479581836, 'mean_word_length': 3.2668989547038327, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7097071', 'n_tokens_mistral': 2155, 'n_tokens_neox': 1878, 'n_words': 589}