<commit_before>import piexif from 'piexifjs'

import { getMasterPath } from 'common/util/DataUtil'
import { parsePath } from 'common/util/TextUtil'
import { Photo, PhotoExportOptions } from 'common/CommonTypes'

import { fetchPhotoWorkOfPhoto } from 'background/store/PhotoWorkStore'
import { fsExists, fsWriteFile, fsReadFile, fsStat, fsUtimes } from 'background/util/FileUtil'
import { parseImageDataUrl } from 'background/util/NodeUtil'
import ForegroundClient from 'background/ForegroundClient'


export async function exportPhoto(photo: Photo, folderPath: string, options: PhotoExportOptions): Promise<void> {
    const masterPath = getMasterPath(photo)
    const photoWork = await fetchPhotoWorkOfPhoto(photo)
    let imageDataUrl = await ForegroundClient.renderPhoto(photo, photoWork, null, options)

    let exportFilePath: string
    let counter = 1
    const filenameParts = parsePath(photo.master_filename)
    do {
        exportFilePath = `${folderPath}/${filenameParts.name}${counter === 1 ? '' : '_' + counter}.${options.format}`
        counter++
    } while (await fsExists(exportFilePath))

    if (options.withMetadata) {
        const masterImageBuffer = await fsReadFile(masterPath)
        const masterImageData = masterImageBuffer.toString('binary')
        const metaData = piexif.load(masterImageData)
        imageDataUrl = piexif.insert(piexif.dump(metaData), imageDataUrl)
    }
<commit_msg>Use three digit suffix if export file already exists<commit_after>import piexif from 'piexifjs'

import { getMasterPath } from 'common/util/DataUtil'
import { parsePath } from 'common/util/TextUtil'
import { Photo, PhotoExportOptions } from 'common/CommonTypes'

import { fetchPhotoWorkOfPhoto } from 'background/store/PhotoWorkStore'
import { fsExists, fsWriteFile, fsReadFile, fsStat, fsUtimes } from 'background/util/FileUtil'
import { parseImageDataUrl } from 'background/util/NodeUtil'
import ForegroundClient from 'background/ForegroundClient'


export async function exportPhoto(photo: Photo, folderPath: string, options: PhotoExportOptions): Promise<void> {
    const masterPath = getMasterPath(photo)
    const photoWork = await fetchPhotoWorkOfPhoto(photo)
    let imageDataUrl = await ForegroundClient.renderPhoto(photo, photoWork, null, options)

    let exportFilePath: string
    let counter = 0
    const filenameParts = parsePath(photo.master_filename)
    do {
        const suffix = counter === 0 ? '' : ('_' + (counter < 10 ? '00' : counter < 100 ? '0' : '') + counter)
        exportFilePath = `${folderPath}/${filenameParts.name}${suffix}.${options.format}`
        counter++
    } while (await fsExists(exportFilePath))

    if (options.withMetadata) {
        const masterImageBuffer = await fsReadFile(masterPath)
        const masterImageData = masterImageBuffer.toString('binary')
        const metaData = piexif.load(masterImageData)
        imageDataUrl = piexif.insert(piexif.dump(metaData), imageDataUrl)
    }

{'fraction_non_alphanumeric': 0.10135135135135136, 'fraction_numerical': 0.004054054054054054, 'mean_word_length': 4.661567877629063, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4313490', 'n_tokens_mistral': 835, 'n_tokens_neox': 823, 'n_words': 205}