From 7bc97ee999e57ac8c25c85f600881a8cbcf48bba Mon Sep 17 00:00:00 2001 From: b1ackd0t <28790446+rodneyosodo@users.noreply.github.com> Date: Wed, 7 Feb 2024 23:38:42 +0300 Subject: [PATCH] feat(linter): Add more linter to the codebase (#147) * chore(golangci): add more linters This commit adds an exclusion for the "Added to album" issues in the `.golangci.yml` file. This change allows the linter to ignore these specific issues during the code analysis. The commit also includes additional linters such as `stylecheck`, `unused`, `goconst`, `makezero`, `unparam`, `prealloc`, `predeclared`, `unconvert`, and `whitespace` to enhance the code quality analysis. Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com> * Refactor stack_test.go and fix error in Test_Stack() The changes made in this commit involve refactoring the stack_test.go file and fixing an error in the Test_Stack() function. The error was causing the test to fail when the expected and actual results did not match. The commit message includes a concise and informative description of the changes made. Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com> * Refactor condition checks for improved readability and efficiency This commit introduces changes to the codebase in the `immich/call.go` and `main.go` files. The modifications involve utilizing a shorter and more readable syntax for condition checks in one file, and a more efficient and concise syntax for condition checks in the other file. Specifically, the changes involve replacing the length check of a string variable with a check for non-empty string. Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com> --------- Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com> --- .golangci.yml | 12 +++++ browser/files/localassets.go | 23 ++++---- browser/gp/googlephotos.go | 37 +++++++------ browser/gp/json.go | 4 +- browser/gp/testgp_samples_test.go | 8 +-- browser/readersearch.go | 39 -------------- cmdduplicate/duplicate.go | 8 +-- cmdstack/cmdstack.go | 4 +- cmdupload/upload.go | 64 ++++++++++------------ cmdupload/upload_test.go | 2 +- helpers/docker/docker.go | 8 +-- helpers/docker/local.go | 4 +- helpers/docker/ssh.go | 2 +- helpers/stacking/stack.go | 6 +-- helpers/stacking/statck_test.go | 4 +- immich/albums.go | 2 +- immich/asset.go | 20 +++---- immich/call.go | 25 ++++----- immich/client.go | 4 +- immich/immich.go | 2 +- immich/metadata/quicktime.go | 37 ++++++++++--- immich/metadata/sidecar.go | 12 ----- immich/trace.go | 33 ------------ logger/journal.go | 88 +++++++++++++++---------------- main.go | 10 ++-- 25 files changed, 190 insertions(+), 268 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index facb9dd3..37f8562d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -4,6 +4,8 @@ run: issues: max-issues-per-linter: 100 max-same-issues: 100 + exclude: + - "Added to album: " linters-settings: gocritic: @@ -48,3 +50,13 @@ linters: - mirror - nakedret - gofumpt + - stylecheck + - unused + - goconst + - makezero + - unparam + - prealloc + - predeclared + - unconvert + - unparam + - whitespace diff --git a/browser/files/localassets.go b/browser/files/localassets.go index 3fc8ae21..2862b7d6 100644 --- a/browser/files/localassets.go +++ b/browser/files/localassets.go @@ -96,26 +96,26 @@ func (la *LocalAssetBrowser) handleFolder(ctx context.Context, fsys fs.FS, fileC continue } fileName := path.Join(folder, e.Name()) - la.log.AddEntry(fileName, logger.DISCOVERED_FILE, "") + la.log.AddEntry(fileName, logger.DiscoveredFile, "") name := e.Name() ext := strings.ToLower(path.Ext(name)) if fshelper.IsMetadataExt(ext) { - la.log.AddEntry(name, logger.METADATA, "") + la.log.AddEntry(name, logger.Metadata, "") continue } else if fshelper.IsIgnoredExt(ext) { - la.log.AddEntry(fileName, logger.UNSUPPORTED, "") + la.log.AddEntry(fileName, logger.Unsupported, "") continue } m, err := fshelper.MimeFromExt(strings.ToLower(ext)) if err != nil { - la.log.AddEntry(fileName, logger.UNSUPPORTED, "") + la.log.AddEntry(fileName, logger.Unsupported, "") continue } ss := strings.Split(m[0], "/") if ss[0] == "image" { - la.log.AddEntry(name, logger.SCANNED_IMAGE, "") + la.log.AddEntry(name, logger.ScannedImage, "") } else { - la.log.AddEntry(name, logger.SCANNED_VIDEO, "") + la.log.AddEntry(name, logger.ScannedVideo, "") } f := browser.LocalAssetFile{ @@ -139,7 +139,7 @@ func (la *LocalAssetBrowser) handleFolder(ctx context.Context, fsys fs.FS, fileC f.DateTaken = time.Now() } } - la.checkSidecar(fsys, &f, entries, folder, name) + la.checkSidecar(&f, entries, folder, name) } // Check if the context has been cancelled select { @@ -153,7 +153,7 @@ func (la *LocalAssetBrowser) handleFolder(ctx context.Context, fsys fs.FS, fileC return nil } -func (la *LocalAssetBrowser) checkSidecar(fsys fs.FS, f *browser.LocalAssetFile, entries []fs.DirEntry, dir, name string) bool { +func (la *LocalAssetBrowser) checkSidecar(f *browser.LocalAssetFile, entries []fs.DirEntry, dir, name string) bool { assetBase := baseNames(name) for _, name := range assetBase { @@ -168,7 +168,7 @@ func (la *LocalAssetBrowser) checkSidecar(fsys fs.FS, f *browser.LocalAssetFile, FileName: path.Join(dir, e.Name()), OnFSsys: true, } - la.log.AddEntry(name, logger.ASSOCIATED_META, "") + la.log.AddEntry(name, logger.AssociatedMetadata, "") return true } } @@ -210,11 +210,6 @@ func escapeName(n string) string { return b.String() } -func (la *LocalAssetBrowser) addAlbum(dir string) { - base := path.Base(dir) - la.albums[dir] = base -} - func (la *LocalAssetBrowser) ReadMetadataFromFile(a *browser.LocalAssetFile) error { ext := strings.ToLower(path.Ext(a.FileName)) diff --git a/browser/gp/googlephotos.go b/browser/gp/googlephotos.go index d67ecc56..f33f06e6 100644 --- a/browser/gp/googlephotos.go +++ b/browser/gp/googlephotos.go @@ -71,7 +71,7 @@ func NewTakeout(ctx context.Context, jnl *logger.Journal, fsyss ...fs.FS) (*Take return nil, err } - to.solvePuzzle(ctx) + to.solvePuzzle() return &to, err } @@ -106,13 +106,13 @@ func (to *Takeout) passOneFsWalk(ctx context.Context, w fs.FS) error { return nil } - to.jnl.AddEntry(name, logger.DISCOVERED_FILE, "") + to.jnl.AddEntry(name, logger.DiscoveredFile, "") dir, base := path.Split(name) dir = strings.TrimSuffix(dir, "/") ext := strings.ToLower(path.Ext(base)) if slices.Contains(uselessFiles, base) { - to.jnl.AddEntry(name, logger.DISCARDED, "Useless file") + to.jnl.AddEntry(name, logger.Discarded, "Useless file") return nil } @@ -130,34 +130,34 @@ func (to *Takeout) passOneFsWalk(ctx context.Context, w fs.FS) error { if err == nil { switch { case md.isAsset(): - to.addJson(w, dir, base, md) - to.jnl.AddEntry(name, logger.METADATA, "Asset Title: "+md.Title) + to.addJSON(dir, base, md) + to.jnl.AddEntry(name, logger.Metadata, "Asset Title: "+md.Title) case md.isAlbum(): to.albums[dir] = md.Title - to.jnl.AddEntry(name, logger.METADATA, "Album title: "+md.Title) + to.jnl.AddEntry(name, logger.Metadata, "Album title: "+md.Title) default: - to.jnl.AddEntry(name, logger.DISCARDED, "Unknown json file") + to.jnl.AddEntry(name, logger.Discarded, "Unknown json file") return nil } } else { - to.jnl.AddEntry(name, logger.DISCARDED, "Unknown json file") + to.jnl.AddEntry(name, logger.Discarded, "Unknown json file") return nil } default: if fshelper.IsIgnoredExt(ext) { - to.jnl.AddEntry(name, logger.DISCARDED, "File ignored") + to.jnl.AddEntry(name, logger.Discarded, "File ignored") return nil } m, err := fshelper.MimeFromExt(ext) if err != nil { - to.jnl.AddEntry(name, logger.UNSUPPORTED, "") + to.jnl.AddEntry(name, logger.Unsupported, "") return nil } if strings.Contains(name, "Failed Videos") { - to.jnl.AddEntry(name, logger.FAILED_VIDEO, "") + to.jnl.AddEntry(name, logger.FailedVideo, "") return nil } dirCatalog.files[base] = fileInfo{ @@ -165,9 +165,9 @@ func (to *Takeout) passOneFsWalk(ctx context.Context, w fs.FS) error { } ss := strings.Split(m[0], "/") if ss[0] == "image" { - to.jnl.AddEntry(name, logger.SCANNED_IMAGE, "") + to.jnl.AddEntry(name, logger.ScannedImage, "") } else { - to.jnl.AddEntry(name, logger.SCANNED_VIDEO, "") + to.jnl.AddEntry(name, logger.ScannedVideo, "") } } to.catalogs[w][dir] = dirCatalog @@ -177,8 +177,8 @@ func (to *Takeout) passOneFsWalk(ctx context.Context, w fs.FS) error { return err } -// addJson stores metadata and all paths where the combo base+year has been found -func (to *Takeout) addJson(w fs.FS, dir, base string, md *GoogleMetaData) { +// addJSON stores metadata and all paths where the combo base+year has been found +func (to *Takeout) addJSON(dir, base string, md *GoogleMetaData) { k := jsonKey{ name: base, year: md.PhotoTakenTime.Time().Year(), @@ -227,7 +227,7 @@ var matchers = []matcherFn{ // The duplicates files (same name, same length in bytes) found in the local source are discarded before been presented to the immich server. // -func (to *Takeout) solvePuzzle(ctx context.Context) error { +func (to *Takeout) solvePuzzle() { to.jnl.OK("Associating JSON and assets...") jsonKeys := gen.MapKeys(to.jsonByYear) sort.Slice(jsonKeys, func(i, j int) bool { @@ -259,7 +259,7 @@ func (to *Takeout) solvePuzzle(ctx context.Context) error { for f := range l.files { if l.files[f].md == nil { if matcher(k.name, f) { - to.jnl.AddEntry(path.Join(d, f), logger.ASSOCIATED_META, fmt.Sprintf("%s (%d)", k.name, k.year)) + to.jnl.AddEntry(path.Join(d, f), logger.AssociatedMetadata, fmt.Sprintf("%s (%d)", k.name, k.year)) // if not already matched i := l.files[f] i.md = md @@ -272,7 +272,6 @@ func (to *Takeout) solvePuzzle(ctx context.Context) error { } } } - return nil } // normalMatch @@ -460,7 +459,7 @@ func (to *Takeout) passTwoWalk(ctx context.Context, w fs.FS, assetChan chan *bro year: f.md.PhotoTakenTime.Time().Year(), } if _, exists := to.uploaded[key]; exists { - to.jnl.AddEntry(name, logger.LOCAL_DUPLICATE, "") + to.jnl.AddEntry(name, logger.LocalDuplicate, "") return nil } a := to.googleMDToAsset(f.md, key, w, name) diff --git a/browser/gp/json.go b/browser/gp/json.go index ca09b050..a2b220d9 100644 --- a/browser/gp/json.go +++ b/browser/gp/json.go @@ -40,8 +40,8 @@ func (gmd GoogleMetaData) isPartner() bool { // Key return an expected unique key for the asset // based on the title and the timestamp -func (md GoogleMetaData) Key() string { - return fmt.Sprintf("%s,%s", md.Title, md.PhotoTakenTime.Timestamp) +func (gmd GoogleMetaData) Key() string { + return fmt.Sprintf("%s,%s", gmd.Title, gmd.PhotoTakenTime.Timestamp) } // googIsPresent is set when the field is present. The content of the field is not relevant diff --git a/browser/gp/testgp_samples_test.go b/browser/gp/testgp_samples_test.go index 68c080f9..f5a2f68f 100644 --- a/browser/gp/testgp_samples_test.go +++ b/browser/gp/testgp_samples_test.go @@ -52,12 +52,6 @@ func takenTime(date string) func(md *GoogleMetaData) { } } -func descriptionField(description string) jsonFn { - return func(md *GoogleMetaData) { - md.Description = description - } -} - func (mfs *inMemFS) addJSONImage(name string, title string, modifiers ...jsonFn) *inMemFS { md := GoogleMetaData{ Title: title, @@ -73,7 +67,7 @@ func (mfs *inMemFS) addJSONImage(name string, title string, modifiers ...jsonFn) if err != nil { panic(err) } - mfs.addFile(name, []byte(content.Bytes())) + mfs.addFile(name, content.Bytes()) return mfs } diff --git a/browser/readersearch.go b/browser/readersearch.go index 0a2b8208..8217f6a0 100644 --- a/browser/readersearch.go +++ b/browser/readersearch.go @@ -45,42 +45,3 @@ func searchPattern(r io.Reader, pattern []byte, maxDataLen int) ([]byte, error) return nil, io.EOF } - -func seekReaderAtPattern(r io.Reader, pattern []byte) (io.Reader, error) { - var err error - pos := 0 - // Create a buffer to hold the chunk of dataZ - buffer := make([]byte, searchBufferSize) - ofs := 0 - - var bytesRead int - for { - // Read a chunk of data into the buffer - bytesRead, err = r.Read(buffer[bytesRead-ofs:]) - if err != nil && err != io.EOF { - return nil, err - } - - // Search for the pattern within the buffer - index := bytes.Index(buffer, pattern) - if index >= 0 { - if index < searchBufferSize-len(pattern) { - return io.MultiReader(bytes.NewReader(buffer[index:]), r), nil - } - ofs = index - } else { - ofs = bytesRead - len(pattern) - 1 - } - - // Check if end of file is reached - if err == io.EOF { - break - } - - // Move the remaining bytes of the current buffer to the beginning - copy(buffer, buffer[ofs:bytesRead]) - pos += bytesRead - } - - return nil, io.EOF -} diff --git a/cmdduplicate/duplicate.go b/cmdduplicate/duplicate.go index 2cad2380..b3ea7d08 100644 --- a/cmdduplicate/duplicate.go +++ b/cmdduplicate/duplicate.go @@ -26,7 +26,7 @@ type DuplicateCmd struct { DateRange immich.DateRange // Set capture date range IgnoreTZErrors bool // Enable TZ error tolerance - assetsById map[string]*immich.Asset + assetsByID map[string]*immich.Asset assetsByBaseAndDate map[duplicateKey][]*immich.Asset } @@ -43,7 +43,7 @@ func NewDuplicateCmd(ctx context.Context, ic *immich.ImmichClient, logger *logge logger: logger, Immich: ic, DateRange: validRange, - assetsById: map[string]*immich.Asset{}, + assetsByID: map[string]*immich.Asset{}, assetsByBaseAndDate: map[duplicateKey][]*immich.Asset{}, } @@ -69,7 +69,7 @@ func DuplicateCommand(ctx context.Context, ic *immich.ImmichClient, log *logger. if !app.DateRange.InRange(a.ExifInfo.DateTimeOriginal.Time) { return } - app.assetsById[a.ID] = a + app.assetsByID[a.ID] = a d := a.ExifInfo.DateTimeOriginal.Time.Round(time.Minute) if app.IgnoreTZErrors { d = time.Date(d.Year(), d.Month(), d.Day(), 0, d.Minute(), d.Second(), 0, time.UTC) @@ -88,7 +88,7 @@ func DuplicateCommand(ctx context.Context, ic *immich.ImmichClient, log *logger. if err != nil { return err } - log.MessageTerminate(logger.OK, "%d received", len(app.assetsById)) + log.MessageTerminate(logger.OK, "%d received", len(app.assetsByID)) log.MessageTerminate(logger.OK, "%d duplicate(s) determined.", dupCount) keys := gen.MapFilterKeys(app.assetsByBaseAndDate, func(i []*immich.Asset) bool { diff --git a/cmdstack/cmdstack.go b/cmdstack/cmdstack.go index b8eddb49..a27f7749 100644 --- a/cmdstack/cmdstack.go +++ b/cmdstack/cmdstack.go @@ -21,7 +21,7 @@ type StackCmd struct { DateRange immich.DateRange // Set capture date range } -func initSack(xtx context.Context, ic *immich.ImmichClient, log *logger.Log, args []string) (*StackCmd, error) { +func initSack(ic *immich.ImmichClient, log *logger.Log, args []string) (*StackCmd, error) { cmd := flag.NewFlagSet("stack", flag.ExitOnError) validRange := immich.DateRange{} @@ -43,7 +43,7 @@ func initSack(xtx context.Context, ic *immich.ImmichClient, log *logger.Log, arg } func NewStackCommand(ctx context.Context, ic *immich.ImmichClient, log *logger.Log, args []string) error { - app, err := initSack(ctx, ic, log, args) + app, err := initSack(ic, log, args) if err != nil { return err } diff --git a/cmdupload/upload.go b/cmdupload/upload.go index 265ab9c2..05fb1c23 100644 --- a/cmdupload/upload.go +++ b/cmdupload/upload.go @@ -36,7 +36,7 @@ type iClient interface { GetAllAlbums(context.Context) ([]immich.AlbumSimplified, error) AddAssetToAlbum(context.Context, string, []string) ([]immich.UpdateAlbumResult, error) CreateAlbum(context.Context, string, []string) (immich.AlbumSimplified, error) - UpdateAssets(ctx context.Context, IDs []string, isArchived bool, isFavorite bool, latitude float64, longitude float64, removeParent bool, stackParentId string) error + UpdateAssets(ctx context.Context, IDs []string, isArchived bool, isFavorite bool, latitude float64, longitude float64, removeParent bool, stackParentID string) error StackAssets(ctx context.Context, cover string, IDs []string) error UpdateAsset(ctx context.Context, ID string, a *browser.LocalAssetFile) (*immich.Asset, error) } @@ -273,7 +273,7 @@ assetLoop: } } - if app.CreateAlbums || app.CreateAlbumAfterFolder || (app.KeepPartner && len(app.PartnerAlbum) > 0) || len(app.ImportIntoAlbum) > 0 { + if app.CreateAlbums || app.CreateAlbumAfterFolder || (app.KeepPartner && app.PartnerAlbum != "") || app.ImportIntoAlbum != "" { app.Journal.OK("Managing albums") err = app.ManageAlbums(ctx) if err != nil { @@ -315,42 +315,42 @@ func (app *UpCmd) handleAsset(ctx context.Context, a *browser.LocalAssetFile) er // } ext := path.Ext(a.FileName) if app.BrowserConfig.ExcludeExtensions.Exclude(ext) { - app.journalAsset(a, logger.NOT_SELECTED, "extension excluded") + app.journalAsset(a, logger.NotSelected, "extension excluded") return nil } if !app.BrowserConfig.SelectExtensions.Include(ext) { - app.journalAsset(a, logger.NOT_SELECTED, "extension not selected") + app.journalAsset(a, logger.NotSelected, "extension not selected") return nil } if !app.KeepPartner && a.FromPartner { - app.journalAsset(a, logger.NOT_SELECTED, "partners asset excluded") + app.journalAsset(a, logger.NotSelected, "partners asset excluded") return nil } if !app.KeepTrashed && a.Trashed { - app.journalAsset(a, logger.NOT_SELECTED, "trashed asset excluded") + app.journalAsset(a, logger.NotSelected, "trashed asset excluded") return nil } - if len(app.ImportFromAlbum) > 0 && !app.isInAlbum(a, app.ImportFromAlbum) { - app.journalAsset(a, logger.NOT_SELECTED, "asset excluded because not from the required album") + if app.ImportFromAlbum != "" && !app.isInAlbum(a, app.ImportFromAlbum) { + app.journalAsset(a, logger.NotSelected, "asset excluded because not from the required album") return nil } if app.DiscardArchived && a.Archived { - app.journalAsset(a, logger.NOT_SELECTED, "asset excluded because archives are discarded") + app.journalAsset(a, logger.NotSelected, "asset excluded because archives are discarded") return nil } if app.DateRange.IsSet() { d := a.DateTaken if d.IsZero() { - app.journalAsset(a, logger.NOT_SELECTED, "asset excluded because the date of capture is unknown and a date range is given") + app.journalAsset(a, logger.NotSelected, "asset excluded because the date of capture is unknown and a date range is given") return nil } if !app.DateRange.InRange(d) { - app.journalAsset(a, logger.NOT_SELECTED, "asset excluded because the date of capture out of the date range") + app.journalAsset(a, logger.NotSelected, "asset excluded because the date of capture out of the date range") return nil } } @@ -376,7 +376,7 @@ func (app *UpCmd) handleAsset(ctx context.Context, a *browser.LocalAssetFile) er app.deleteLocalList = append(app.deleteLocalList, a) } case SmallerOnServer: - app.journalAsset(a, logger.UPGRADED, advice.Message) + app.journalAsset(a, logger.Upgraded, advice.Message) // add the superior asset into albums of the original asset for _, al := range advice.ServerAsset.Albums { app.journalAsset(a, logger.INFO, "Added to album: "+al.AlbumName) @@ -392,9 +392,9 @@ func (app *UpCmd) handleAsset(ctx context.Context, a *browser.LocalAssetFile) er case SameOnServer: // Set add the server asset into albums determined locally if !advice.ServerAsset.JustUploaded { - app.journalAsset(a, logger.SERVER_DUPLICATE, advice.Message) + app.journalAsset(a, logger.ServerDuplicate, advice.Message) } else { - app.journalAsset(a, logger.LOCAL_DUPLICATE) + app.journalAsset(a, logger.LocalDuplicate) } ID = advice.ServerAsset.ID if app.CreateAlbums { @@ -419,7 +419,7 @@ func (app *UpCmd) handleAsset(ctx context.Context, a *browser.LocalAssetFile) er return nil } case BetterOnServer: - app.journalAsset(a, logger.SERVER_BETTER, advice.Message) + app.journalAsset(a, logger.ServerBetter, advice.Message) ID = advice.ServerAsset.ID // keep the server version but update albums if app.CreateAlbums { @@ -472,7 +472,7 @@ func (app *UpCmd) handleAsset(ctx context.Context, a *browser.LocalAssetFile) er Names = append(Names, Name) } if len(Names) > 0 { - app.journalAsset(a, logger.ALBUM, strings.Join(Names, ", ")) + app.journalAsset(a, logger.Album, strings.Join(Names, ", ")) for _, n := range Names { app.AddToAlbum(ID, n) } @@ -480,7 +480,7 @@ func (app *UpCmd) handleAsset(ctx context.Context, a *browser.LocalAssetFile) er } } - shouldUpdate := len(a.Description) > 0 + shouldUpdate := a.Description != "" shouldUpdate = shouldUpdate || a.Favorite shouldUpdate = shouldUpdate || a.Longitude != 0 || a.Latitude != 0 shouldUpdate = shouldUpdate || a.Archived @@ -504,13 +504,13 @@ func (app *UpCmd) isInAlbum(a *browser.LocalAssetFile, album string) bool { return false } -func (a *UpCmd) ReadGoogleTakeOut(ctx context.Context, fsyss []fs.FS) (browser.Browser, error) { - a.Delete = false - return gp.NewTakeout(ctx, a.Journal, fsyss...) +func (app *UpCmd) ReadGoogleTakeOut(ctx context.Context, fsyss []fs.FS) (browser.Browser, error) { + app.Delete = false + return gp.NewTakeout(ctx, app.Journal, fsyss...) } -func (a *UpCmd) ExploreLocalFolder(ctx context.Context, fsyss []fs.FS) (browser.Browser, error) { - return files.NewLocalFiles(ctx, a.Journal, fsyss...) +func (app *UpCmd) ExploreLocalFolder(ctx context.Context, fsyss []fs.FS) (browser.Browser, error) { + return files.NewLocalFiles(ctx, app.Journal, fsyss...) } // UploadAsset upload the asset on the server @@ -536,18 +536,18 @@ func (app *UpCmd) UploadAsset(ctx context.Context, a *browser.LocalAssetFile) (s resp.ID = uuid.NewString() } if err != nil { - app.journalAsset(a, logger.SERVER_ERROR, err.Error()) + app.journalAsset(a, logger.ServerError, err.Error()) return "", err } if !resp.Duplicate { - app.journalAsset(a, logger.UPLOADED, a.Title) + app.journalAsset(a, logger.Uploaded, a.Title) app.AssetIndex.AddLocalAsset(a, resp.ID) app.mediaUploaded += 1 if app.CreateStacks { app.stacks.ProcessAsset(resp.ID, a.FileName, a.DateTaken) } } else { - app.journalAsset(a, logger.SERVER_DUPLICATE, "already on the server") + app.journalAsset(a, logger.ServerDuplicate, "already on the server") } return resp.ID, nil @@ -709,14 +709,6 @@ func formatBytes(s int) string { return fmt.Sprintf("%.1f %s", roundedSize, suffixes[exp]) } -func (ai *AssetIndex) adviceIDontKnow(la *browser.LocalAssetFile) *Advice { - return &Advice{ - Advice: IDontKnow, - Message: fmt.Sprintf("Can't decide what to do with %q. Check this file", la.FileName), - LocalAsset: la, - } -} - func (ai *AssetIndex) adviceSameOnServer(sa *immich.Asset) *Advice { return &Advice{ Advice: SameOnServer, @@ -758,7 +750,7 @@ func (ai *AssetIndex) ShouldUpload(la *browser.LocalAssetFile) (*Advice, error) if path.Ext(filename) == "" { filename += path.Ext(la.FileName) } - var err error + ID := la.DeviceAssetID() sa := ai.byID[ID] @@ -781,9 +773,7 @@ func (ai *AssetIndex) ShouldUpload(la *browser.LocalAssetFile) (*Advice, error) if len(l) > 0 { dateTaken := la.DateTaken size := int(la.Size()) - if err != nil { - return ai.adviceIDontKnow(la), nil - } + for _, sa = range l { compareDate := compareDate(dateTaken, sa.ExifInfo.DateTimeOriginal.Time) compareSize := size - sa.ExifInfo.FileSizeInByte diff --git a/cmdupload/upload_test.go b/cmdupload/upload_test.go index 51cd7cfa..b3f81312 100644 --- a/cmdupload/upload_test.go +++ b/cmdupload/upload_test.go @@ -42,7 +42,7 @@ func (c *stubIC) CreateAlbum(context.Context, string, []string) (immich.AlbumSim return immich.AlbumSimplified{}, nil } -func (c *stubIC) UpdateAssets(ctx context.Context, ids []string, isArchived bool, isFavorite bool, latitude float64, longitude float64, removeParent bool, stackParentId string) error { +func (c *stubIC) UpdateAssets(ctx context.Context, ids []string, isArchived bool, isFavorite bool, latitude float64, longitude float64, removeParent bool, stackParentID string) error { return nil } diff --git a/helpers/docker/docker.go b/helpers/docker/docker.go index 03cb60f5..32771b05 100644 --- a/helpers/docker/docker.go +++ b/helpers/docker/docker.go @@ -58,7 +58,7 @@ func NewDockerConnection(ctx context.Context, host string, container string) (*D Container: container, } - err := d.connect(ctx, host, container) + err := d.connect(ctx, host) if err != nil { return nil, fmt.Errorf("can't open docker: %w", err) } @@ -66,12 +66,12 @@ func NewDockerConnection(ctx context.Context, host string, container string) (*D } // Connect test the connection with docker, and get instance parameters -func (d *DockerConnect) connect(ctx context.Context, host string, container string) error { +func (d *DockerConnect) connect(ctx context.Context, host string) error { var err error if host == "" || host == "local" { - d.proxy, err = newLocalProxy(d) + d.proxy = newLocalProxy(d) } else { - d.proxy, err = newSshProxy(ctx, d, host, container) + d.proxy, err = newSSHProxy(host) } if err != nil { return err diff --git a/helpers/docker/local.go b/helpers/docker/local.go index 920acbf4..1c2cb0bc 100644 --- a/helpers/docker/local.go +++ b/helpers/docker/local.go @@ -9,8 +9,8 @@ type localProxy struct { c *DockerConnect } -func newLocalProxy(c *DockerConnect) (*localProxy, error) { - return &localProxy{c: c}, nil +func newLocalProxy(c *DockerConnect) *localProxy { + return &localProxy{c: c} } func (localProxy) connect(ctx context.Context) error { diff --git a/helpers/docker/ssh.go b/helpers/docker/ssh.go index be9198cc..6f02027b 100644 --- a/helpers/docker/ssh.go +++ b/helpers/docker/ssh.go @@ -18,7 +18,7 @@ type sshProxy struct { sshClient *goph.Client } -func newSshProxy(ctx context.Context, c *DockerConnect, host string, container string) (*sshProxy, error) { +func newSSHProxy(host string) (*sshProxy, error) { u, err := url.Parse(host) if err != nil { return nil, err diff --git a/helpers/stacking/stack.go b/helpers/stacking/stack.go index 6f0e5069..52f44954 100644 --- a/helpers/stacking/stack.go +++ b/helpers/stacking/stack.go @@ -112,7 +112,7 @@ func huaweiBurst(name string) (bool, string, bool) { if len(parts) == 0 { return false, "", false } - return true, parts[1], len(parts[3]) > 0 + return true, parts[1], parts[3] != "" } var pixelBurstRE = regexp.MustCompile(`^(.*)(.RAW-\d+)(\.MP)?(\.COVER)?(\..*)$`) @@ -122,7 +122,7 @@ func pixelBurst(name string) (bool, string, bool) { if len(parts) == 0 { return false, "", false } - return true, parts[1], len(parts[4]) > 0 + return true, parts[1], parts[4] != "" } var samsungBurstRE = regexp.MustCompile(`^(\d{8}_\d{6})_(\d{3})\..{3}$`) @@ -150,7 +150,7 @@ func (sb *StackBuilder) Stacks() []Stack { return len(i.IDs) > 1 }) - var stacks []Stack + stacks := make([]Stack, 0, len(keys)) for _, k := range keys { s := sb.stacks[k] diff --git a/helpers/stacking/statck_test.go b/helpers/stacking/statck_test.go index e28a0ce9..7dacc3db 100644 --- a/helpers/stacking/statck_test.go +++ b/helpers/stacking/statck_test.go @@ -28,6 +28,7 @@ func Test_Stack(t *testing.T) { {ID: "1", FileName: "IMG_1234.JPG", DateTaken: metadata.TakeTimeFromName("2023-10-01 10.15.00")}, {ID: "2", FileName: "IMG_1234.DNG", DateTaken: metadata.TakeTimeFromName("2023-10-01 10.45.00")}, }, + want: []Stack{}, }, { name: "issue #67", @@ -35,6 +36,7 @@ func Test_Stack(t *testing.T) { {ID: "1", FileName: "IMG_5580.HEIC", DateTaken: metadata.TakeTimeFromName("2023-10-01 10.15.00")}, {ID: "2", FileName: "IMG_5580.MP4", DateTaken: metadata.TakeTimeFromName("2023-10-01 10.15.00")}, }, + want: []Stack{}, }, { name: "stack JPG+DNG", @@ -212,7 +214,7 @@ func Test_Stack(t *testing.T) { return got[i].CoverID < got[j].CoverID }) if !reflect.DeepEqual(got, tt.want) { - t.Errorf("difference\n") + t.Errorf("differece expected %+v got %+v", tt.want, got) pretty.Ldiff(t, tt.want, got) } }) diff --git a/immich/albums.go b/immich/albums.go index ce7fa0a7..90597655 100644 --- a/immich/albums.go +++ b/immich/albums.go @@ -132,5 +132,5 @@ func (ic *ImmichClient) GetAssetAlbums(ctx context.Context, id string) ([]AlbumS } func (ic *ImmichClient) DeleteAlbum(ctx context.Context, id string) error { - return ic.newServerCall(ctx, "DeleteAlbum").do(delete("/album/" + id)) + return ic.newServerCall(ctx, "DeleteAlbum").do(deleteItem("/album/" + id)) } diff --git a/immich/asset.go b/immich/asset.go index 12829eab..b1e9bff6 100644 --- a/immich/asset.go +++ b/immich/asset.go @@ -147,7 +147,7 @@ func escapeQuotes(s string) string { } type GetAssetOptions struct { - UserId string + UserID string IsFavorite bool IsArchived bool WithoutThumbs bool @@ -159,7 +159,7 @@ func (o *GetAssetOptions) Values() url.Values { return url.Values{} } v := url.Values{} - v.Add("userId", o.UserId) + v.Add("userId", o.UserID) v.Add("isFavorite", myBool(o.IsFavorite).String()) v.Add("isArchived", myBool(o.IsArchived).String()) v.Add("withoutThumbs", myBool(o.WithoutThumbs).String()) @@ -180,12 +180,12 @@ func (ic *ImmichClient) GetAllAssets(ctx context.Context, opt *GetAssetOptions) values.Set("withExif", "true") values.Set("isVisible", "true") values.Del("trashedBefore") - err := ic.newServerCall(ctx, "GetAllAssets", setPaginator("page", 1)).do(get("/assets", setUrlValues(values), setAcceptJSON()), responseAccumulateJSON(&r)) + err := ic.newServerCall(ctx, "GetAllAssets", setPaginator()).do(get("/assets", setURLValues(values), setAcceptJSON()), responseAccumulateJSON(&r)) if err != nil { return r, err } values.Set("trashedBefore", "9999-01-01") - err = ic.newServerCall(ctx, "GetAllAssets", setPaginator("page", 1)).do(get("/assets", setUrlValues(values), setAcceptJSON()), responseAccumulateJSON(&r)) + err = ic.newServerCall(ctx, "GetAllAssets", setPaginator()).do(get("/assets", setURLValues(values), setAcceptJSON()), responseAccumulateJSON(&r)) if err != nil { return r, err } @@ -204,12 +204,12 @@ func (ic *ImmichClient) GetAllAssetsWithFilter(ctx context.Context, opt *GetAsse values.Set("withExif", "true") values.Set("isVisible", "true") values.Del("trashedBefore") - err := ic.newServerCall(ctx, "GetAllAssets", setPaginator("page", 1)).do(get("/assets", setUrlValues(values), setAcceptJSON()), responseJSONWithFilter(filter)) + err := ic.newServerCall(ctx, "GetAllAssets", setPaginator()).do(get("/assets", setURLValues(values), setAcceptJSON()), responseJSONWithFilter(filter)) if err != nil { return err } values.Set("trashedBefore", "9999-01-01") - err = ic.newServerCall(ctx, "GetAllAssets", setPaginator("page", 1)).do(get("/assets", setUrlValues(values), setAcceptJSON()), responseJSONWithFilter(filter)) + err = ic.newServerCall(ctx, "GetAllAssets", setPaginator()).do(get("/assets", setURLValues(values), setAcceptJSON()), responseJSONWithFilter(filter)) if err != nil { return err } @@ -227,7 +227,7 @@ func (ic *ImmichClient) DeleteAssets(ctx context.Context, id []string, forceDele Force: forceDelete, } - return ic.newServerCall(ctx, "DeleteAsset").do(delete("/asset", setAcceptJSON(), setJSONBody(req))) + return ic.newServerCall(ctx, "DeleteAsset").do(deleteItem("/asset", setAcceptJSON(), setJSONBody(req))) } func (ic *ImmichClient) GetAssetByID(ctx context.Context, id string) (*Asset, error) { @@ -239,7 +239,7 @@ func (ic *ImmichClient) GetAssetByID(ctx context.Context, id string) (*Asset, er func (ic *ImmichClient) UpdateAssets(ctx context.Context, ids []string, isArchived bool, isFavorite bool, latitude float64, longitude float64, - removeParent bool, stackParentId string, + removeParent bool, stackParentID string, ) error { type updAssets struct { IDs []string `json:"ids"` @@ -248,7 +248,7 @@ func (ic *ImmichClient) UpdateAssets(ctx context.Context, ids []string, Latitude float64 `json:"latitude"` Longitude float64 `json:"longitude"` RemoveParent bool `json:"removeParent"` - StackParentId string `json:"stackParentId,omitempty"` + StackParentID string `json:"stackParentId,omitempty"` } param := updAssets{ @@ -258,7 +258,7 @@ func (ic *ImmichClient) UpdateAssets(ctx context.Context, ids []string, Latitude: latitude, Longitude: longitude, RemoveParent: removeParent, - StackParentId: stackParentId, + StackParentID: stackParentID, } return ic.newServerCall(ctx, "updateAssets").do(put("/asset", setJSONBody(param))) } diff --git a/immich/call.go b/immich/call.go index 5f943f6c..7efba097 100644 --- a/immich/call.go +++ b/immich/call.go @@ -49,7 +49,7 @@ type ServerMessage struct { Message []string `json:"message"` } -func (u callError) Is(target error) bool { +func (ce callError) Is(target error) bool { _, ok := target.(*callError) return ok } @@ -71,7 +71,7 @@ func (ce callError) Error() string { b.WriteRune('\n') } if ce.message != nil { - if len(ce.message.Error) > 0 { + if ce.message.Error != "" { b.WriteString(ce.message.Error) b.WriteRune('\n') } @@ -135,11 +135,11 @@ func (p *paginator) nextPage() { p.pageNumber++ } -func setPaginator(pageParameter string, startPage int) serverCallOption { +func setPaginator() serverCallOption { return func(sc *serverCall) error { p := paginator{ - pageParameter: pageParameter, - pageNumber: startPage, + pageParameter: "page", + pageNumber: 1, } sc.p = &p return nil @@ -180,7 +180,7 @@ func post(url string, ctype string, opts ...serverRequestOption) requestFunction } } -func delete(url string, opts ...serverRequestOption) requestFunction { +func deleteItem(url string, opts ...serverRequestOption) requestFunction { return func(sc *serverCall) *http.Request { if sc.err != nil { return nil @@ -233,7 +233,7 @@ func (sc *serverCall) _callDo(fnRequest requestFunction, opts ...serverResponseO sc.p.setPage(v) req.URL.RawQuery = v.Encode() } - if sc.ic.ApiTrace /* && req.Header.Get("Content-Type") == "application/json"*/ { + if sc.ic.APITrace /* && req.Header.Get("Content-Type") == "application/json"*/ { setTraceJSONRequest()(sc, req) } @@ -278,13 +278,6 @@ func setBody(body io.ReadCloser) serverRequestOption { } } -func setHeader(key, value string) serverRequestOption { - return func(sc *serverCall, req *http.Request) error { - req.Header.Set(key, value) - return nil - } -} - func setAcceptJSON() serverRequestOption { return func(sc *serverCall, req *http.Request) error { req.Header.Add("Accept", "application/json") @@ -303,7 +296,7 @@ func setJSONBody(object any) serverRequestOption { return func(sc *serverCall, req *http.Request) error { b := bytes.NewBuffer(nil) enc := json.NewEncoder(b) - if sc.ic.ApiTrace { + if sc.ic.APITrace { enc.SetIndent("", " ") } if sc.joinError(enc.Encode(object)) == nil { @@ -321,7 +314,7 @@ func setContentType(ctype string) serverRequestOption { } } -func setUrlValues(values url.Values) serverRequestOption { +func setURLValues(values url.Values) serverRequestOption { return func(sc *serverCall, req *http.Request) error { if values != nil { rValues := req.URL.Query() diff --git a/immich/client.go b/immich/client.go index a35bea3e..345bbc5c 100644 --- a/immich/client.go +++ b/immich/client.go @@ -22,7 +22,7 @@ type ImmichClient struct { DeviceUUID string // Device Retries int // Number of attempts on 500 errors RetriesDelay time.Duration // Duration between retries - ApiTrace bool + APITrace bool } func (ic *ImmichClient) SetEndPoint(endPoint string) *ImmichClient { @@ -36,7 +36,7 @@ func (ic *ImmichClient) SetDeviceUUID(deviceUUID string) *ImmichClient { } func (ic *ImmichClient) EnableAppTrace(state bool) *ImmichClient { - ic.ApiTrace = state + ic.APITrace = state return ic } diff --git a/immich/immich.go b/immich/immich.go index f242a2d5..97d28dda 100644 --- a/immich/immich.go +++ b/immich/immich.go @@ -108,7 +108,7 @@ type Asset struct { LivePhotoVideoID string `json:"livePhotoVideoId"` Tags []any `json:"tags"` Checksum string `json:"checksum"` - StackParentId string `json:"stackParentId"` + StackParentID string `json:"stackParentId"` JustUploaded bool `json:"-"` Albums []AlbumSimplified `json:"-"` // Albums that asset belong to } diff --git a/immich/metadata/quicktime.go b/immich/metadata/quicktime.go index 01df664c..3b14f455 100644 --- a/immich/metadata/quicktime.go +++ b/immich/metadata/quicktime.go @@ -49,28 +49,49 @@ type MvhdAtom struct { func decodeMvhdAtom(r *sliceReader) (*MvhdAtom, error) { a := &MvhdAtom{} - + var err error // Read the mvhd marker (4 bytes) - a.Marker, _ = r.ReadSlice(4) + a.Marker, err = r.ReadSlice(4) + if err != nil { + return nil, err + } // Read the mvhd version (1 byte) - a.Version, _ = r.ReadByte() + a.Version, err = r.ReadByte() + if err != nil { + return nil, err + } // Read the mvhd flags (3 bytes) - a.Flags, _ = r.ReadSlice(3) + a.Flags, err = r.ReadSlice(3) + if err != nil { + return nil, err + } if a.Version == 0 { // Read the creation time (4 bytes) - b, _ := r.ReadSlice(4) + b, err := r.ReadSlice(4) + if err != nil { + return nil, err + } a.ModificationTime = convertTime32(binary.BigEndian.Uint32(b)) - b, _ = r.ReadSlice(4) + b, err = r.ReadSlice(4) + if err != nil { + return nil, err + } a.CreationTime = convertTime32(binary.BigEndian.Uint32(b)) } else { // Read the creation time (4 bytes) - b, _ := r.ReadSlice(8) + b, err := r.ReadSlice(8) + if err != nil { + return nil, err + } a.ModificationTime = convertTime64(binary.BigEndian.Uint64(b)) - b, _ = r.ReadSlice(8) + b, err = r.ReadSlice(8) + if err != nil { + return nil, err + } a.CreationTime = convertTime64(binary.BigEndian.Uint64(b)) } diff --git a/immich/metadata/sidecar.go b/immich/metadata/sidecar.go index 495c94b4..0fdf865c 100644 --- a/immich/metadata/sidecar.go +++ b/immich/metadata/sidecar.go @@ -5,7 +5,6 @@ import ( "fmt" "io" "io/fs" - "math" "text/template" "time" ) @@ -21,17 +20,6 @@ type SideCar struct { Elevation float64 } -func cmpFloats(a, b float64) int { - d := a - b - if math.Abs(d) < 1e-5 { - return 0 - } - if a < b { - return -1 - } - return 1 -} - func (sc *SideCar) Open(fsys fs.FS, name string) (io.ReadCloser, error) { if sc.OnFSsys { return fsys.Open(name) diff --git a/immich/trace.go b/immich/trace.go index 4c54b937..b76ed8b7 100644 --- a/immich/trace.go +++ b/immich/trace.go @@ -5,7 +5,6 @@ import ( "io" "net/http" "os" - "strings" ) /* @@ -41,35 +40,3 @@ func setTraceJSONRequest() serverRequestOption { return nil } } - -func setTraceJSONResponse() serverResponseOption { - return func(sc *serverCall, resp *http.Response) error { - fmt.Println("--- API RESPONSE -- ") - for h, v := range resp.Header { - fmt.Println(h, strings.Join(v, ",")) - } - fmt.Println("--- RESPONSE BODY ---") - tr := io.TeeReader(resp.Body, os.Stdout) - resp.Body = &smartBodyCloser{body: resp.Body, r: tr} - return nil - } -} - -func traceRequest(req *http.Request) { - isJSON := req.Header.Get("Content-Type") == "application/json" - fmt.Println("--- API CALL ---") - u := *req.URL - u.Host = "***" - fmt.Println(req.Method, u.String()) - for h, vs := range req.Header { - if h == "X-Api-Key" { - vs = []string{"***"} - } - fmt.Println(h, ":", strings.Join(vs, ",")) - } - if isJSON { - fmt.Println("--- JSON BODY ---") - tr := io.TeeReader(req.Body, os.Stdout) - req.Body = &smartBodyCloser{body: req.Body, r: tr} - } -} diff --git a/logger/journal.go b/logger/journal.go index 60b44327..ea2be9c5 100644 --- a/logger/journal.go +++ b/logger/journal.go @@ -14,26 +14,26 @@ type Journal struct { type Action string const ( - DISCOVERED_FILE Action = "File" - SCANNED_IMAGE Action = "Scanned image" - SCANNED_VIDEO Action = "Scanned video" - DISCARDED Action = "Discarded" - UPLOADED Action = "Uploaded" - UPGRADED Action = "Server's asset upgraded" - ERROR Action = "Error" - LOCAL_DUPLICATE Action = "Local duplicate" - SERVER_DUPLICATE Action = "Server has photo" - STACKED Action = "Stacked" - SERVER_BETTER Action = "Server's asset is better" - ALBUM Action = "Added to an album" - LIVE_PHOTO Action = "Live photo" - FAILED_VIDEO Action = "Failed video" - UNSUPPORTED Action = "File type not supported" - METADATA Action = "Metadata files" - ASSOCIATED_META Action = "Associated with metadata" - INFO Action = "Info" - NOT_SELECTED Action = "Not selected because options" - SERVER_ERROR Action = "Server error" + DiscoveredFile Action = "File" + ScannedImage Action = "Scanned image" + ScannedVideo Action = "Scanned video" + Discarded Action = "Discarded" + Uploaded Action = "Uploaded" + Upgraded Action = "Server's asset upgraded" + ERROR Action = "Error" + LocalDuplicate Action = "Local duplicate" + ServerDuplicate Action = "Server has photo" + Stacked Action = "Stacked" + ServerBetter Action = "Server's asset is better" + Album Action = "Added to an album" + LivePhoto Action = "Live photo" + FailedVideo Action = "Failed video" + Unsupported Action = "File type not supported" + Metadata Action = "Metadata files" + AssociatedMetadata Action = "Associated with metadata" + INFO Action = "Info" + NotSelected Action = "Not selected because options" + ServerError Action = "Server error" ) func NewJournal(log Logger) *Journal { @@ -51,11 +51,11 @@ func (j *Journal) AddEntry(file string, action Action, comment ...string) { c := strings.Join(comment, ", ") if j.Logger != nil { switch action { - case ERROR, SERVER_ERROR: + case ERROR, ServerError: j.Logger.Error("%-25s: %s: %s", action, file, c) - case DISCOVERED_FILE: + case DiscoveredFile: j.Logger.Debug("%-25s: %s: %s", action, file, c) - case UPLOADED: + case Uploaded: j.Logger.OK("%-25s: %s: %s", action, file, c) default: j.Logger.Info("%-25s: %s: %s", action, file, c) @@ -63,36 +63,36 @@ func (j *Journal) AddEntry(file string, action Action, comment ...string) { } j.mut.Lock() j.counts[action]++ - if action == UPGRADED { - j.counts[UPLOADED]-- + if action == Upgraded { + j.counts[Uploaded]-- } j.mut.Unlock() } func (j *Journal) Report() { - checkFiles := j.counts[SCANNED_IMAGE] + j.counts[SCANNED_VIDEO] + j.counts[METADATA] + j.counts[UNSUPPORTED] + j.counts[FAILED_VIDEO] + j.counts[DISCARDED] - handledFiles := j.counts[NOT_SELECTED] + j.counts[LOCAL_DUPLICATE] + j.counts[SERVER_DUPLICATE] + j.counts[SERVER_BETTER] + j.counts[UPLOADED] + j.counts[UPGRADED] + j.counts[SERVER_ERROR] + checkFiles := j.counts[ScannedImage] + j.counts[ScannedVideo] + j.counts[Metadata] + j.counts[Unsupported] + j.counts[FailedVideo] + j.counts[Discarded] + handledFiles := j.counts[NotSelected] + j.counts[LocalDuplicate] + j.counts[ServerDuplicate] + j.counts[ServerBetter] + j.counts[Uploaded] + j.counts[Upgraded] + j.counts[ServerError] j.Logger.OK("Scan of the sources:") - j.Logger.OK("%6d files in the input", j.counts[DISCOVERED_FILE]) + j.Logger.OK("%6d files in the input", j.counts[DiscoveredFile]) j.Logger.OK("--------------------------------------------------------") - j.Logger.OK("%6d photos", j.counts[SCANNED_IMAGE]) - j.Logger.OK("%6d videos", j.counts[SCANNED_VIDEO]) - j.Logger.OK("%6d metadata files", j.counts[METADATA]) - j.Logger.OK("%6d files with metadata", j.counts[ASSOCIATED_META]) - j.Logger.OK("%6d discarded files", j.counts[DISCARDED]) - j.Logger.OK("%6d files having a type not supported", j.counts[UNSUPPORTED]) - j.Logger.OK("%6d discarded files because in folder failed videos", j.counts[FAILED_VIDEO]) + j.Logger.OK("%6d photos", j.counts[ScannedImage]) + j.Logger.OK("%6d videos", j.counts[ScannedVideo]) + j.Logger.OK("%6d metadata files", j.counts[Metadata]) + j.Logger.OK("%6d files with metadata", j.counts[AssociatedMetadata]) + j.Logger.OK("%6d discarded files", j.counts[Discarded]) + j.Logger.OK("%6d files having a type not supported", j.counts[Unsupported]) + j.Logger.OK("%6d discarded files because in folder failed videos", j.counts[FailedVideo]) - j.Logger.OK("%6d input total (difference %d)", checkFiles, j.counts[DISCOVERED_FILE]-checkFiles) + j.Logger.OK("%6d input total (difference %d)", checkFiles, j.counts[DiscoveredFile]-checkFiles) j.Logger.OK("--------------------------------------------------------") - j.Logger.OK("%6d uploaded files on the server", j.counts[UPLOADED]) - j.Logger.OK("%6d upgraded files on the server", j.counts[UPGRADED]) - j.Logger.OK("%6d files already on the server", j.counts[SERVER_DUPLICATE]) - j.Logger.OK("%6d discarded files because of options", j.counts[NOT_SELECTED]) - j.Logger.OK("%6d discarded files because duplicated in the input", j.counts[LOCAL_DUPLICATE]) - j.Logger.OK("%6d discarded files because server has a better image", j.counts[SERVER_BETTER]) - j.Logger.OK("%6d errors when uploading", j.counts[SERVER_ERROR]) + j.Logger.OK("%6d uploaded files on the server", j.counts[Uploaded]) + j.Logger.OK("%6d upgraded files on the server", j.counts[Upgraded]) + j.Logger.OK("%6d files already on the server", j.counts[ServerDuplicate]) + j.Logger.OK("%6d discarded files because of options", j.counts[NotSelected]) + j.Logger.OK("%6d discarded files because duplicated in the input", j.counts[LocalDuplicate]) + j.Logger.OK("%6d discarded files because server has a better image", j.counts[ServerBetter]) + j.Logger.OK("%6d errors when uploading", j.counts[ServerError]) - j.Logger.OK("%6d handled total (difference %d)", handledFiles, j.counts[SCANNED_IMAGE]+j.counts[SCANNED_VIDEO]-handledFiles) + j.Logger.OK("%6d handled total (difference %d)", handledFiles, j.counts[ScannedImage]+j.counts[ScannedVideo]-handledFiles) } diff --git a/main.go b/main.go index 9216834e..fa16d6c5 100644 --- a/main.go +++ b/main.go @@ -65,7 +65,7 @@ type Application struct { API string // Immich api endpoint (http://container_ip:3301) Key string // API Key DeviceUUID string // Set a device UUID - ApiTrace bool // Enable API call traces + APITrace bool // Enable API call traces NoLogColors bool // Disable log colors LogLevel string // Idicate the log level Debug bool // Enable the debug mode @@ -88,7 +88,7 @@ func Run(ctx context.Context, log *logger.Log) (*logger.Log, error) { flag.BoolFunc("no-colors-log", "Disable colors on logs", myflag.BoolFlagFn(&app.NoLogColors, runtime.GOOS == "windows")) flag.StringVar(&app.LogLevel, "log-level", "ok", "Log level (Error|Warning|OK|Info), default OK") flag.StringVar(&app.LogFile, "log-file", "", "Write log messages into the file") - flag.BoolFunc("api-trace", "enable api call traces", myflag.BoolFlagFn(&app.ApiTrace, false)) + flag.BoolFunc("api-trace", "enable api call traces", myflag.BoolFlagFn(&app.APITrace, false)) flag.BoolFunc("debug", "enable debug messages", myflag.BoolFlagFn(&app.Debug, false)) flag.StringVar(&app.TimeZone, "time-zone", "", "Override the system time zone") flag.BoolFunc("skip-verify-ssl", "Skip SSL verification", myflag.BoolFlagFn(&app.SkipSSL, false)) @@ -101,7 +101,7 @@ func Run(ctx context.Context, log *logger.Log) (*logger.Log, error) { return log, err } - if len(app.LogFile) > 0 { + if app.LogFile != "" { flog, err := os.Create(app.LogFile) if err != nil { return log, fmt.Errorf("can't open the log file: %w", err) @@ -113,7 +113,7 @@ func Run(ctx context.Context, log *logger.Log) (*logger.Log, error) { switch { case app.Server == "" && app.API == "": err = errors.Join(err, errors.New("missing -server, Immich server address (http://:2283 or https://)")) - case len(app.Server) > 0 && len(app.API) > 0: + case app.Server != "" && app.API != "": err = errors.Join(err, errors.New("give either the -server or the -api option")) } if app.Key == "" { @@ -146,7 +146,7 @@ func Run(ctx context.Context, log *logger.Log) (*logger.Log, error) { if app.API != "" { app.Immich.SetEndPoint(app.API) } - if app.ApiTrace { + if app.APITrace { app.Immich.EnableAppTrace(true) } if app.DeviceUUID != "" {