mirror of
https://github.com/Vyntral/god-eye.git
synced 2026-07-07 12:47:50 +02:00
v0.1.1: Major AI improvements, new security modules, and documentation fixes
## AI & CVE Improvements - Fix AI report to display actual subdomain names instead of generic placeholders - Add 10-year CVE filter to reduce false positives from outdated vulnerabilities - Integrate CISA KEV (Known Exploited Vulnerabilities) database support - Improve AI analysis prompt for more accurate security findings ## New Security Modules - Add wildcard DNS detection with multi-phase validation (DNS + HTTP) - Add TLS certificate analyzer for certificate chain inspection - Add comprehensive rate limiting module for API requests - Add retry mechanism with exponential backoff - Add stealth mode for reduced detection during scans - Add progress tracking module for better UX ## Code Refactoring - Extract scanner output logic to dedicated module - Add base source interface for consistent passive source implementation - Reduce admin panel paths to common generic patterns only - Improve HTTP client with connection pooling - Add JSON output formatter ## Documentation Updates - Correct passive source count to 20 (was incorrectly stated as 34) - Fix AI model names: deepseek-r1:1.5b (fast) + qwen2.5-coder:7b (deep) - Update all markdown files for consistency - Relocate demo GIFs to assets/ directory - Add benchmark disclaimer for test variability ## Files Changed - 4 documentation files updated (README, AI_SETUP, BENCHMARK, EXAMPLES) - 11 new source files added - 12 existing files modified
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
package progress
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"god-eye/internal/output"
|
||||
)
|
||||
|
||||
// Bar represents a progress bar
|
||||
type Bar struct {
|
||||
total int64
|
||||
current int64
|
||||
width int
|
||||
prefix string
|
||||
startTime time.Time
|
||||
lastUpdate time.Time
|
||||
mu sync.Mutex
|
||||
done bool
|
||||
silent bool
|
||||
}
|
||||
|
||||
// New creates a new progress bar
|
||||
func New(total int, prefix string, silent bool) *Bar {
|
||||
return &Bar{
|
||||
total: int64(total),
|
||||
current: 0,
|
||||
width: 40,
|
||||
prefix: prefix,
|
||||
startTime: time.Now(),
|
||||
silent: silent,
|
||||
}
|
||||
}
|
||||
|
||||
// Increment increases the progress by 1
|
||||
func (b *Bar) Increment() {
|
||||
atomic.AddInt64(&b.current, 1)
|
||||
b.render()
|
||||
}
|
||||
|
||||
// Add increases the progress by n
|
||||
func (b *Bar) Add(n int) {
|
||||
atomic.AddInt64(&b.current, int64(n))
|
||||
b.render()
|
||||
}
|
||||
|
||||
// SetCurrent sets the current progress value
|
||||
func (b *Bar) SetCurrent(n int) {
|
||||
atomic.StoreInt64(&b.current, int64(n))
|
||||
b.render()
|
||||
}
|
||||
|
||||
// render displays the progress bar
|
||||
func (b *Bar) render() {
|
||||
if b.silent {
|
||||
return
|
||||
}
|
||||
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
// Throttle updates to avoid flickering (max 10 updates/sec)
|
||||
if time.Since(b.lastUpdate) < 100*time.Millisecond && !b.done {
|
||||
return
|
||||
}
|
||||
b.lastUpdate = time.Now()
|
||||
|
||||
current := atomic.LoadInt64(&b.current)
|
||||
total := b.total
|
||||
|
||||
// Calculate percentage
|
||||
var percent float64
|
||||
if total > 0 {
|
||||
percent = float64(current) / float64(total) * 100
|
||||
}
|
||||
|
||||
// Calculate filled width
|
||||
filled := int(float64(b.width) * percent / 100)
|
||||
if filled > b.width {
|
||||
filled = b.width
|
||||
}
|
||||
|
||||
// Build progress bar
|
||||
bar := strings.Repeat("█", filled) + strings.Repeat("░", b.width-filled)
|
||||
|
||||
// Calculate ETA
|
||||
elapsed := time.Since(b.startTime)
|
||||
var eta string
|
||||
if current > 0 && current < total {
|
||||
remaining := time.Duration(float64(elapsed) / float64(current) * float64(total-current))
|
||||
eta = formatDuration(remaining)
|
||||
} else if current >= total {
|
||||
eta = "done"
|
||||
} else {
|
||||
eta = "..."
|
||||
}
|
||||
|
||||
// Calculate speed
|
||||
var speed float64
|
||||
if elapsed.Seconds() > 0 {
|
||||
speed = float64(current) / elapsed.Seconds()
|
||||
}
|
||||
|
||||
// Print progress bar (overwrite line with \r) - clean style without box characters
|
||||
fmt.Printf("\r %s [%s] %s/%s %.0f%% %s ETA %s ",
|
||||
b.prefix,
|
||||
output.Green(bar),
|
||||
output.BoldWhite(fmt.Sprintf("%d", current)),
|
||||
output.Dim(fmt.Sprintf("%d", total)),
|
||||
percent,
|
||||
output.Dim(fmt.Sprintf("%.0f/s", speed)),
|
||||
output.Dim(eta),
|
||||
)
|
||||
}
|
||||
|
||||
// Finish completes the progress bar
|
||||
func (b *Bar) Finish() {
|
||||
if b.silent {
|
||||
return
|
||||
}
|
||||
|
||||
b.mu.Lock()
|
||||
b.done = true
|
||||
b.mu.Unlock()
|
||||
|
||||
current := atomic.LoadInt64(&b.current)
|
||||
elapsed := time.Since(b.startTime)
|
||||
|
||||
// Clear the line and print final status - clean style
|
||||
fmt.Printf("\r %s %s %s completed in %s \n",
|
||||
output.Green("✓"),
|
||||
output.BoldWhite(fmt.Sprintf("%d", current)),
|
||||
b.prefix,
|
||||
output.Green(formatDuration(elapsed)),
|
||||
)
|
||||
}
|
||||
|
||||
// FinishWithMessage completes with a custom message
|
||||
func (b *Bar) FinishWithMessage(msg string) {
|
||||
if b.silent {
|
||||
return
|
||||
}
|
||||
|
||||
b.mu.Lock()
|
||||
b.done = true
|
||||
b.mu.Unlock()
|
||||
|
||||
// Clear the line and print message - clean style
|
||||
fmt.Printf("\r %s %s \n",
|
||||
output.Green("✓"),
|
||||
msg,
|
||||
)
|
||||
}
|
||||
|
||||
// formatDuration formats a duration nicely
|
||||
func formatDuration(d time.Duration) string {
|
||||
if d < time.Second {
|
||||
return "<1s"
|
||||
} else if d < time.Minute {
|
||||
return fmt.Sprintf("%ds", int(d.Seconds()))
|
||||
} else if d < time.Hour {
|
||||
mins := int(d.Minutes())
|
||||
secs := int(d.Seconds()) % 60
|
||||
return fmt.Sprintf("%dm%ds", mins, secs)
|
||||
}
|
||||
hours := int(d.Hours())
|
||||
mins := int(d.Minutes()) % 60
|
||||
return fmt.Sprintf("%dh%dm", hours, mins)
|
||||
}
|
||||
|
||||
// MultiBar manages multiple progress bars
|
||||
type MultiBar struct {
|
||||
bars []*Bar
|
||||
mu sync.Mutex
|
||||
silent bool
|
||||
}
|
||||
|
||||
// NewMulti creates a new multi-bar manager
|
||||
func NewMulti(silent bool) *MultiBar {
|
||||
return &MultiBar{
|
||||
bars: make([]*Bar, 0),
|
||||
silent: silent,
|
||||
}
|
||||
}
|
||||
|
||||
// AddBar adds a new progress bar
|
||||
func (m *MultiBar) AddBar(total int, prefix string) *Bar {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
bar := New(total, prefix, m.silent)
|
||||
m.bars = append(m.bars, bar)
|
||||
return bar
|
||||
}
|
||||
Reference in New Issue
Block a user