paper-system/llm_processor/storage/storage.go

144 lines
3.5 KiB
Go
Raw Normal View History

2025-01-24 15:26:47 +00:00
package storage
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"sync"
"llm_processor/models"
)
var (
criteriaPath = "criteria.txt"
criteriaMux sync.RWMutex
)
// SetCriteriaPath sets the path for the criteria file
func SetCriteriaPath(path string) {
criteriaMux.Lock()
defer criteriaMux.Unlock()
criteriaPath = path
}
// LoadPapers loads papers from a JSON file
func LoadPapers(filePath string) ([]models.Paper, error) {
absPath, err := filepath.Abs(filePath)
if err != nil {
return nil, fmt.Errorf("failed to resolve absolute path: %w", err)
}
file, err := os.ReadFile(absPath)
if err != nil {
return nil, fmt.Errorf("failed to read papers file: %w", err)
}
var papers []models.Paper
if err := json.Unmarshal(file, &papers); err != nil {
return nil, fmt.Errorf("failed to parse papers JSON: %w", err)
}
return papers, nil
}
// LoadCriteria loads evaluation criteria from a text file
func LoadCriteria() (string, error) {
criteriaMux.RLock()
filePath := criteriaPath
criteriaMux.RUnlock()
content, err := os.ReadFile(filePath)
if err != nil {
return "", fmt.Errorf("failed to read criteria file: %w", err)
}
return string(content), nil
}
// InitializeResultsFile creates a new results file with empty categories
func InitializeResultsFile(filePath string) error {
results := models.OrganizedResults{
Accepted: []models.Result{},
Rejected: []models.Result{},
Errors: []models.Result{},
}
return saveToFile(filePath, results)
}
// SaveResult appends a result to the appropriate category in the results file
func SaveResult(result models.Result, filePath string) error {
// Read existing results
results, err := loadResults(filePath)
if err != nil {
return fmt.Errorf("failed to load results: %w", err)
}
// Append to appropriate category
switch result.Decision {
case "ACCEPT":
results.Accepted = append(results.Accepted, result)
case "REJECT":
results.Rejected = append(results.Rejected, result)
default:
results.Errors = append(results.Errors, result)
}
// Save updated results
if err := saveToFile(filePath, results); err != nil {
// Try fallback save
if fallbackErr := saveFallback(result, filePath); fallbackErr != nil {
return fmt.Errorf("failed to save results: %w (fallback also failed: %v)", err, fallbackErr)
}
return nil
}
return nil
}
func loadResults(filePath string) (*models.OrganizedResults, error) {
file, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("failed to read results file: %w", err)
}
var results models.OrganizedResults
if err := json.Unmarshal(file, &results); err != nil {
return nil, fmt.Errorf("failed to parse results JSON: %w", err)
}
return &results, nil
}
func saveToFile(filePath string, data interface{}) error {
file, err := os.Create(filePath)
if err != nil {
return fmt.Errorf("failed to create file: %w", err)
}
defer file.Close()
encoder := json.NewEncoder(file)
encoder.SetIndent("", " ")
if err := encoder.Encode(data); err != nil {
return fmt.Errorf("failed to encode JSON: %w", err)
}
return nil
}
func saveFallback(result models.Result, originalPath string) error {
fallbackPath := originalPath + ".fallback"
file, err := os.OpenFile(fallbackPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("failed to open fallback file: %w", err)
}
defer file.Close()
encoder := json.NewEncoder(file)
if err := encoder.Encode(result); err != nil {
return fmt.Errorf("failed to encode result to fallback file: %w", err)
}
return nil
}