180 lines
4.1 KiB
Go
180 lines
4.1 KiB
Go
package reports
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"time"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
"github.com/atridad/wrapped-cli/pkg/config"
|
|
"github.com/atridad/wrapped-cli/pkg/models"
|
|
)
|
|
|
|
type ReportMetadata struct {
|
|
Timestamp time.Time `yaml:"timestamp"`
|
|
Username string `yaml:"username"`
|
|
TotalCommits int `yaml:"total_commits"`
|
|
Repositories int `yaml:"repositories"`
|
|
Stats *models.UserStats `yaml:"stats"`
|
|
}
|
|
|
|
type Report struct {
|
|
Metadata *ReportMetadata
|
|
MarkdownID string
|
|
MetadataID string
|
|
Timestamp time.Time
|
|
}
|
|
|
|
func SaveReport(stats *models.UserStats) (string, error) {
|
|
resultsDir, err := config.GetResultsDir()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
now := time.Now()
|
|
timestamp := now.Format("2006-01-02 15-04-05")
|
|
metadataID := fmt.Sprintf("%s.yaml", now.Format("2006-01-02-15-04-05"))
|
|
imageID := fmt.Sprintf("%s - Gitea Wrapped.png", timestamp)
|
|
|
|
metadata := &ReportMetadata{
|
|
Timestamp: now,
|
|
Username: stats.Username,
|
|
TotalCommits: stats.TotalCommits,
|
|
Repositories: stats.TotalRepositories,
|
|
Stats: stats,
|
|
}
|
|
|
|
metadataPath := filepath.Join(resultsDir, metadataID)
|
|
data, err := yaml.Marshal(metadata)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if err := os.WriteFile(metadataPath, data, 0o644); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if _, err := ExportReportAsImage(stats, "png"); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Warning: failed to generate image: %v\n", err)
|
|
}
|
|
|
|
return imageID, nil
|
|
}
|
|
|
|
func ListReports() ([]Report, error) {
|
|
resultsDir, err := config.GetResultsDir()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
entries, err := os.ReadDir(resultsDir)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return []Report{}, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
var reports []Report
|
|
for _, entry := range entries {
|
|
if entry.IsDir() {
|
|
continue
|
|
}
|
|
|
|
if filepath.Ext(entry.Name()) == ".yaml" {
|
|
metadataPath := filepath.Join(resultsDir, entry.Name())
|
|
data, err := os.ReadFile(metadataPath)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
var metadata ReportMetadata
|
|
if err := yaml.Unmarshal(data, &metadata); err != nil {
|
|
continue
|
|
}
|
|
|
|
reports = append(reports, Report{
|
|
Metadata: &metadata,
|
|
MetadataID: entry.Name(),
|
|
Timestamp: metadata.Timestamp,
|
|
})
|
|
}
|
|
}
|
|
|
|
sort.Slice(reports, func(i, j int) bool {
|
|
return reports[i].Timestamp.After(reports[j].Timestamp)
|
|
})
|
|
|
|
return reports, nil
|
|
}
|
|
|
|
func GetReport(metadataID string) (*ReportMetadata, error) {
|
|
resultsDir, err := config.GetResultsDir()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
metadataPath := filepath.Join(resultsDir, metadataID)
|
|
data, err := os.ReadFile(metadataPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var metadata ReportMetadata
|
|
if err := yaml.Unmarshal(data, &metadata); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &metadata, nil
|
|
}
|
|
|
|
func generateMarkdown(stats *models.UserStats) string {
|
|
md := fmt.Sprintf("# Gitea Wrapped — %s\n\n", time.Now().Format("January 2, 2006"))
|
|
|
|
md += fmt.Sprintf("**User**: %s\n\n", stats.Username)
|
|
|
|
md += "## Overview\n\n"
|
|
md += fmt.Sprintf("- **Total Commits**: %d\n", stats.TotalCommits)
|
|
md += fmt.Sprintf("- **Total Repositories**: %d\n", stats.TotalRepositories)
|
|
md += fmt.Sprintf("- **Average Commits/Day**: %.2f\n", stats.AverageCommitsPerDay)
|
|
md += fmt.Sprintf("- **Most Active Day**: %s\n", stats.MostActiveDay)
|
|
md += fmt.Sprintf("- **Most Active Month**: %s\n\n", stats.MostActiveMonth)
|
|
|
|
md += "## Languages\n\n"
|
|
for i, lang := range stats.Languages {
|
|
if i >= 10 {
|
|
break
|
|
}
|
|
md += fmt.Sprintf("- %s: %d repos (%.1f%%)\n", lang.Language, lang.Count, lang.Percent)
|
|
}
|
|
md += "\n"
|
|
|
|
md += "## Top Repositories\n\n"
|
|
for i, repo := range stats.TopRepositories {
|
|
md += fmt.Sprintf("%d. [%s](%s)\n", i+1, repo.Name, repo.HTMLURL)
|
|
}
|
|
md += "\n"
|
|
|
|
md += "## Most Active Days\n\n"
|
|
for i, day := range stats.CommitsByWeekday {
|
|
if i >= 7 {
|
|
break
|
|
}
|
|
md += fmt.Sprintf("- %s: %d commits\n", day.Day, day.Count)
|
|
}
|
|
md += "\n"
|
|
|
|
md += "## Most Active Months\n\n"
|
|
for i, month := range stats.CommitsByMonth {
|
|
if i >= 12 {
|
|
break
|
|
}
|
|
md += fmt.Sprintf("- %s: %d commits\n", month.Date.Format("January 2006"), month.Count)
|
|
}
|
|
|
|
return md
|
|
}
|