144 lines
3.5 KiB
Go
144 lines
3.5 KiB
Go
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
|
|
}
|