精简后的项目:仅保留 api/ui 源码、文档、构建依赖

This commit is contained in:
gallery
2026-09-11 16:11:09 +08:00
commit 490e85634e
457 changed files with 86862 additions and 0 deletions
@@ -0,0 +1,175 @@
package periodic_scanner
import (
"fmt"
"sync"
"time"
"github.com/photoview/photoview/api/graphql/models"
"github.com/photoview/photoview/api/log"
"github.com/photoview/photoview/api/scanner/scanner_queue"
"gorm.io/gorm"
)
type ScannerQueue interface {
AddAllToQueue() error
}
type RealScannerQueue struct{}
func (r *RealScannerQueue) AddAllToQueue() error {
return scanner_queue.AddAllToQueue()
}
type periodicScanner struct {
ticker *time.Ticker
tickerLocker sync.Mutex
ticker_changed chan bool
done chan struct{}
db *gorm.DB
scannerQueue ScannerQueue
}
var mainPeriodicScanner *periodicScanner = nil
var mainPeriodicScannerLocker sync.Mutex
func getPeriodicScanInterval(db *gorm.DB) (time.Duration, error) {
var siteInfo models.SiteInfo
if err := db.First(&siteInfo).Error; err != nil {
return 0, err
}
return time.Duration(siteInfo.PeriodicScanInterval) * time.Second, nil
}
func InitializePeriodicScannerWithQueue(db *gorm.DB, queue ScannerQueue) error {
mainPeriodicScannerLocker.Lock()
defer mainPeriodicScannerLocker.Unlock()
if mainPeriodicScanner != nil {
return fmt.Errorf("periodic scanner has already been initialized")
}
scanInterval, err := getPeriodicScanInterval(db)
if err != nil {
return err
}
mainPeriodicScanner = &periodicScanner{
db: db,
ticker_changed: make(chan bool),
done: make(chan struct{}),
tickerLocker: sync.Mutex{},
scannerQueue: queue,
}
go mainPeriodicScanner.scanIntervalRunner()
var newTicker *time.Ticker = nil
if scanInterval > 0 {
newTicker = time.NewTicker(scanInterval)
log.Info(nil, "Periodic scan interval changed: "+scanInterval.String())
} else {
log.Info(nil, "Periodic scan interval changed: disabled")
}
mainPeriodicScanner.ticker = newTicker
select {
case mainPeriodicScanner.ticker_changed <- true:
default:
// Channel might be full, but that's okay
}
return nil
}
func InitializePeriodicScanner(db *gorm.DB) error {
return InitializePeriodicScannerWithQueue(db, &RealScannerQueue{})
}
func ChangePeriodicScanInterval(duration time.Duration) {
var newTicker *time.Ticker = nil
if duration > 0 {
newTicker = time.NewTicker(duration)
log.Info(nil, "Periodic scan interval changed: "+duration.String())
} else {
log.Info(nil, "Periodic scan interval changed: disabled")
}
mainPeriodicScannerLocker.Lock()
scanner := mainPeriodicScanner
mainPeriodicScannerLocker.Unlock()
if scanner != nil {
scanner.tickerLocker.Lock()
defer scanner.tickerLocker.Unlock()
if scanner.ticker != nil {
scanner.ticker.Stop()
}
scanner.ticker = newTicker
select {
case scanner.ticker_changed <- true:
default:
// Channel might be full, but that's okay
}
}
}
// ShutdownPeriodicScanner gracefully shuts down the periodic scanner
func ShutdownPeriodicScanner() {
mainPeriodicScannerLocker.Lock()
defer mainPeriodicScannerLocker.Unlock()
if mainPeriodicScanner != nil {
log.Info(nil, "Shutting down periodic scanner")
// Signal the runner goroutine to stop
close(mainPeriodicScanner.done)
// Stop the ticker if it exists
mainPeriodicScanner.tickerLocker.Lock()
if mainPeriodicScanner.ticker != nil {
mainPeriodicScanner.ticker.Stop()
mainPeriodicScanner.ticker = nil
}
mainPeriodicScanner.tickerLocker.Unlock()
// Reset the global scanner
mainPeriodicScanner = nil
}
}
func (ps *periodicScanner) scanIntervalRunner() {
for {
log.Info(nil, "Scan interval runner: Waiting for signal")
ps.tickerLocker.Lock()
ticker := ps.ticker
ps.tickerLocker.Unlock()
if ticker != nil {
select {
case <-ps.done:
log.Info(nil, "Scan interval runner: Shutting down")
return
case <-ps.ticker_changed:
log.Info(nil, "Scan interval runner: New ticker detected")
case <-ticker.C:
log.Info(nil, "Scan interval runner: Starting periodic scan")
if err := ps.scannerQueue.AddAllToQueue(); err != nil {
log.Error(nil, "Scan interval runner: Failed to add all users to queue", "error", err)
}
}
} else {
select {
case <-ps.done:
log.Info(nil, "Scan interval runner: Shutting down")
return
case <-ps.ticker_changed:
log.Info(nil, "Scan interval runner: New ticker detected")
}
}
}
}