(opts: Options)
| 126 | |
| 127 | |
| 128 | def rename_photos(opts: Options) -> int: |
| 129 | photos = gather_photos(opts.folder, opts.recursive) |
| 130 | photos.sort() |
| 131 | |
| 132 | if not photos: |
| 133 | print("No supported photo files found.") |
| 134 | return 0 |
| 135 | |
| 136 | if opts.prefix: |
| 137 | pref = sanitize_prefix(opts.prefix) |
| 138 | else: |
| 139 | pref = "" |
| 140 | |
| 141 | renamed = 0 |
| 142 | for p in photos: |
| 143 | if opts.keep_original and already_formatted(p.name): |
| 144 | continue |
| 145 | |
| 146 | dt = exif_datetime_original(p) or file_mtime(p) |
| 147 | base = dt.strftime("%Y-%m-%d_%H-%M-%S") |
| 148 | if pref: |
| 149 | base = f"{pref}_{base}" |
| 150 | |
| 151 | dest = unique_name(p.parent, base, p.suffix.lower()) |
| 152 | |
| 153 | if dest.name == p.name: |
| 154 | continue |
| 155 | |
| 156 | if opts.dry_run: |
| 157 | print(f"[DRY] {p.relative_to(opts.folder)} -> {dest.name}") |
| 158 | else: |
| 159 | p.rename(dest) |
| 160 | print(f"[OK ] {p.relative_to(opts.folder)} -> {dest.name}") |
| 161 | renamed += 1 |
| 162 | |
| 163 | if not opts.dry_run: |
| 164 | print(f"\nDone. Renamed {renamed} file(s).") |
| 165 | return renamed |
| 166 | |
| 167 | |
| 168 | def main(argv: list[str]) -> int: |
no test coverage detected