node build fixed
This commit is contained in:
363
seanime-2.9.10/internal/library/summary/scan_summary.go
Normal file
363
seanime-2.9.10/internal/library/summary/scan_summary.go
Normal file
@@ -0,0 +1,363 @@
|
||||
package summary
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"seanime/internal/api/anilist"
|
||||
"seanime/internal/library/anime"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
LogFileNotMatched LogType = iota
|
||||
LogComparison
|
||||
LogSuccessfullyMatched
|
||||
LogFailedMatch
|
||||
LogMatchValidated
|
||||
LogUnmatched
|
||||
LogMetadataMediaTreeFetched
|
||||
LogMetadataMediaTreeFetchFailed
|
||||
LogMetadataEpisodeNormalized
|
||||
LogMetadataEpisodeNormalizationFailed
|
||||
LogMetadataEpisodeZero
|
||||
LogMetadataNC
|
||||
LogMetadataSpecial
|
||||
LogMetadataMain
|
||||
LogMetadataHydrated
|
||||
LogPanic
|
||||
LogDebug
|
||||
)
|
||||
|
||||
type (
|
||||
LogType int
|
||||
|
||||
ScanSummaryLogger struct {
|
||||
Logs []*ScanSummaryLog
|
||||
LocalFiles []*anime.LocalFile
|
||||
AllMedia []*anime.NormalizedMedia
|
||||
AnimeCollection *anilist.AnimeCollectionWithRelations
|
||||
}
|
||||
|
||||
ScanSummaryLog struct { // Holds a log entry. The log entry will then be used to generate a ScanSummary.
|
||||
ID string `json:"id"`
|
||||
FilePath string `json:"filePath"`
|
||||
Level string `json:"level"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
ScanSummary struct {
|
||||
ID string `json:"id"`
|
||||
Groups []*ScanSummaryGroup `json:"groups"`
|
||||
UnmatchedFiles []*ScanSummaryFile `json:"unmatchedFiles"`
|
||||
}
|
||||
|
||||
ScanSummaryFile struct {
|
||||
ID string `json:"id"`
|
||||
LocalFile *anime.LocalFile `json:"localFile"`
|
||||
Logs []*ScanSummaryLog `json:"logs"`
|
||||
}
|
||||
|
||||
ScanSummaryGroup struct {
|
||||
ID string `json:"id"`
|
||||
Files []*ScanSummaryFile `json:"files"`
|
||||
MediaId int `json:"mediaId"`
|
||||
MediaTitle string `json:"mediaTitle"`
|
||||
MediaImage string `json:"mediaImage"`
|
||||
MediaIsInCollection bool `json:"mediaIsInCollection"` // Whether the media is in the user's AniList collection
|
||||
}
|
||||
|
||||
ScanSummaryItem struct { // Database item
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
ScanSummary *ScanSummary `json:"scanSummary"`
|
||||
}
|
||||
)
|
||||
|
||||
func NewScanSummaryLogger() *ScanSummaryLogger {
|
||||
return &ScanSummaryLogger{
|
||||
Logs: make([]*ScanSummaryLog, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// HydrateData will hydrate the data needed to generate the summary.
|
||||
func (l *ScanSummaryLogger) HydrateData(lfs []*anime.LocalFile, media []*anime.NormalizedMedia, animeCollection *anilist.AnimeCollectionWithRelations) {
|
||||
l.LocalFiles = lfs
|
||||
l.AllMedia = media
|
||||
l.AnimeCollection = animeCollection
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) GenerateSummary() *ScanSummary {
|
||||
if l == nil || l.LocalFiles == nil || l.AllMedia == nil || l.AnimeCollection == nil {
|
||||
return nil
|
||||
}
|
||||
summary := &ScanSummary{
|
||||
ID: uuid.NewString(),
|
||||
Groups: make([]*ScanSummaryGroup, 0),
|
||||
UnmatchedFiles: make([]*ScanSummaryFile, 0),
|
||||
}
|
||||
|
||||
groupsMap := make(map[int][]*ScanSummaryFile)
|
||||
|
||||
// Generate summary files
|
||||
for _, lf := range l.LocalFiles {
|
||||
|
||||
if lf.MediaId == 0 {
|
||||
summary.UnmatchedFiles = append(summary.UnmatchedFiles, &ScanSummaryFile{
|
||||
ID: uuid.NewString(),
|
||||
LocalFile: lf,
|
||||
Logs: l.getFileLogs(lf),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
summaryFile := &ScanSummaryFile{
|
||||
ID: uuid.NewString(),
|
||||
LocalFile: lf,
|
||||
Logs: l.getFileLogs(lf),
|
||||
}
|
||||
|
||||
//summary.Files = append(summary.Files, summaryFile)
|
||||
|
||||
// Add to group
|
||||
if _, ok := groupsMap[lf.MediaId]; !ok {
|
||||
groupsMap[lf.MediaId] = make([]*ScanSummaryFile, 0)
|
||||
groupsMap[lf.MediaId] = append(groupsMap[lf.MediaId], summaryFile)
|
||||
} else {
|
||||
groupsMap[lf.MediaId] = append(groupsMap[lf.MediaId], summaryFile)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate summary groups
|
||||
for mediaId, files := range groupsMap {
|
||||
mediaTitle := ""
|
||||
mediaImage := ""
|
||||
mediaIsInCollection := false
|
||||
for _, m := range l.AllMedia {
|
||||
if m.ID == mediaId {
|
||||
mediaTitle = m.GetPreferredTitle()
|
||||
mediaImage = ""
|
||||
if m.GetCoverImage() != nil && m.GetCoverImage().GetLarge() != nil {
|
||||
mediaImage = *m.GetCoverImage().GetLarge()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if _, found := l.AnimeCollection.GetListEntryFromMediaId(mediaId); found {
|
||||
mediaIsInCollection = true
|
||||
}
|
||||
|
||||
summary.Groups = append(summary.Groups, &ScanSummaryGroup{
|
||||
ID: uuid.NewString(),
|
||||
Files: files,
|
||||
MediaId: mediaId,
|
||||
MediaTitle: mediaTitle,
|
||||
MediaImage: mediaImage,
|
||||
MediaIsInCollection: mediaIsInCollection,
|
||||
})
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogComparison(lf *anime.LocalFile, algo string, bestTitle string, ratingType string, rating string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("Comparison using %s. Best title: \"%s\". %s: %s", algo, bestTitle, ratingType, rating)
|
||||
l.logType(LogComparison, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogSuccessfullyMatched(lf *anime.LocalFile, mediaId int) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Successfully matched to media %d", mediaId)
|
||||
l.logType(LogSuccessfullyMatched, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogPanic(lf *anime.LocalFile, stackTrace string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
//msg := fmt.Sprintf("Panic occurred, please report this issue on the GitHub repository with the stack trace printed in the terminal")
|
||||
l.logType(LogPanic, lf, "PANIC! "+stackTrace)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogFailedMatch(lf *anime.LocalFile, reason string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Failed to match: %s", reason)
|
||||
l.logType(LogFailedMatch, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMatchValidated(lf *anime.LocalFile, mediaId int) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Match validated for media %d", mediaId)
|
||||
l.logType(LogMatchValidated, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogUnmatched(lf *anime.LocalFile, reason string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Unmatched: %s", reason)
|
||||
l.logType(LogUnmatched, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogFileNotMatched(lf *anime.LocalFile, reason string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Not matched: %s", reason)
|
||||
l.logType(LogFileNotMatched, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMetadataMediaTreeFetched(lf *anime.LocalFile, ms int64, branches int) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Media tree fetched in %dms. Branches: %d", ms, branches)
|
||||
l.logType(LogMetadataMediaTreeFetched, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMetadataMediaTreeFetchFailed(lf *anime.LocalFile, err error, ms int64) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Could not fetch media tree: %s. Took %dms", err.Error(), ms)
|
||||
l.logType(LogMetadataMediaTreeFetchFailed, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMetadataEpisodeNormalized(lf *anime.LocalFile, mediaId int, episode int, newEpisode int, newMediaId int, aniDBEpisode string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Episode %d normalized to %d. New media ID: %d. AniDB episode: %s", episode, newEpisode, newMediaId, aniDBEpisode)
|
||||
l.logType(LogMetadataEpisodeNormalized, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMetadataEpisodeNormalizationFailed(lf *anime.LocalFile, err error, episode int, aniDBEpisode string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Episode normalization failed. Reason \"%s\". Episode %d. AniDB episode %s", err.Error(), episode, aniDBEpisode)
|
||||
l.logType(LogMetadataEpisodeNormalizationFailed, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMetadataNC(lf *anime.LocalFile) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Marked as NC file")
|
||||
l.logType(LogMetadataNC, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMetadataSpecial(lf *anime.LocalFile, episode int, aniDBEpisode string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Marked as Special episode. Episode %d. AniDB episode: %s", episode, aniDBEpisode)
|
||||
l.logType(LogMetadataSpecial, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMetadataMain(lf *anime.LocalFile, episode int, aniDBEpisode string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Marked as main episode. Episode %d. AniDB episode: %s", episode, aniDBEpisode)
|
||||
l.logType(LogMetadataMain, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMetadataEpisodeZero(lf *anime.LocalFile, episode int, aniDBEpisode string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Marked as main episode. Episode %d. AniDB episode set to %s assuming AniDB does not include episode 0 in the episode count.", episode, aniDBEpisode)
|
||||
l.logType(LogMetadataEpisodeZero, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogMetadataHydrated(lf *anime.LocalFile, mediaId int) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("Metadata hydrated for media %d", mediaId)
|
||||
l.logType(LogMetadataHydrated, lf, msg)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) LogDebug(lf *anime.LocalFile, message string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
l.log(lf, "info", message)
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) logType(logType LogType, lf *anime.LocalFile, message string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
switch logType {
|
||||
case LogComparison:
|
||||
l.log(lf, "info", message)
|
||||
case LogSuccessfullyMatched:
|
||||
l.log(lf, "info", message)
|
||||
case LogFailedMatch:
|
||||
l.log(lf, "warning", message)
|
||||
case LogMatchValidated:
|
||||
l.log(lf, "info", message)
|
||||
case LogUnmatched:
|
||||
l.log(lf, "warning", message)
|
||||
case LogMetadataMediaTreeFetched:
|
||||
l.log(lf, "info", message)
|
||||
case LogMetadataMediaTreeFetchFailed:
|
||||
l.log(lf, "error", message)
|
||||
case LogMetadataEpisodeNormalized:
|
||||
l.log(lf, "info", message)
|
||||
case LogMetadataEpisodeNormalizationFailed:
|
||||
l.log(lf, "error", message)
|
||||
case LogMetadataHydrated:
|
||||
l.log(lf, "info", message)
|
||||
case LogMetadataNC:
|
||||
l.log(lf, "info", message)
|
||||
case LogMetadataSpecial:
|
||||
l.log(lf, "info", message)
|
||||
case LogMetadataMain:
|
||||
l.log(lf, "info", message)
|
||||
case LogMetadataEpisodeZero:
|
||||
l.log(lf, "warning", message)
|
||||
case LogFileNotMatched:
|
||||
l.log(lf, "warning", message)
|
||||
case LogPanic:
|
||||
l.log(lf, "error", message)
|
||||
case LogDebug:
|
||||
l.log(lf, "info", message)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) log(lf *anime.LocalFile, level string, message string) {
|
||||
if l == nil {
|
||||
return
|
||||
}
|
||||
l.Logs = append(l.Logs, &ScanSummaryLog{
|
||||
ID: uuid.NewString(),
|
||||
FilePath: lf.Path,
|
||||
Level: level,
|
||||
Message: message,
|
||||
})
|
||||
}
|
||||
|
||||
func (l *ScanSummaryLogger) getFileLogs(lf *anime.LocalFile) []*ScanSummaryLog {
|
||||
logs := make([]*ScanSummaryLog, 0)
|
||||
if l == nil {
|
||||
return logs
|
||||
}
|
||||
for _, log := range l.Logs {
|
||||
if lf.HasSamePath(log.FilePath) {
|
||||
logs = append(logs, log)
|
||||
}
|
||||
}
|
||||
return logs
|
||||
}
|
||||
Reference in New Issue
Block a user