Skip to content

Commit

Permalink
Track the full paths of attachments in the Attachment object (#71)
Browse files Browse the repository at this point in the history
<!-- Please add a title in the form of a great git commit message in the
imperative mood (https://cbea.ms/git-commit/) -->

**What is changing**:
1. Disambiguate `Filename` and `Filepath` in the `Attachment` object.
2. Replace relative export paths with absolute ones.

**Why this change is being made**:
1. Previously, we were computing the absolute path of the attachments in
multiple places in different ways depending on the options given and
whether the attachment was converted or not. This was confusing and
error prone (see #70).
2. As a result of the first change, we are using the copied path as the
file to embed or reference. When embedding in PDFs, relative paths do
not work, so we need to specify the copied path (under the export path
in the case of the `--copy-attachments` option) as an absolute path.

**Related issue(s)**: Fixes #70 

**Follow-up changes needed**: None AFAIK

**Is the change completely covered by unit tests? If not, why not?**:
No, similarly to converting the attachments path to an absolute path, we
are not testing failures of the `filepath.Abs` function.
  • Loading branch information
tagatac authored Nov 17, 2024
1 parent f767ab8 commit 3c6af3e
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 91 deletions.
1 change: 1 addition & 0 deletions chatdb/attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
type Attachment struct {
ID int
Filename string
Filepath string
MIMEType string
TransferName string
}
Expand Down
13 changes: 9 additions & 4 deletions internal/bagoup/bagoup.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,17 @@ func (cfg *configuration) validatePaths() error {
if err := cfg.OS.FileAccess(cfg.Options.DBPath); err != nil {
return errors.Wrapf(err, "test DB file %q - FIX: %s", cfg.Options.DBPath, _readmeURL)
}
if ok, err := cfg.OS.FileExist(cfg.Options.ExportPath); err != nil {
return errors.Wrapf(err, "check export path %q", cfg.Options.ExportPath)
var err error
var exportPathAbs string
if exportPathAbs, err = filepath.Abs(cfg.Options.ExportPath); err != nil {
return errors.Wrapf(err, "convert export path %q to an absolute path", cfg.Options.ExportPath)
}
cfg.Options.ExportPath = exportPathAbs
if ok, err := cfg.OS.FileExist(exportPathAbs); err != nil {
return errors.Wrapf(err, "check export path %q", exportPathAbs)
} else if ok {
return fmt.Errorf("export folder %q already exists - FIX: move it or specify a different export path with the --export-path option", cfg.Options.ExportPath)
return fmt.Errorf("export folder %q already exists - FIX: move it or specify a different export path with the --export-path option", exportPathAbs)
}
var err error
var attPathAbs string
if attPathAbs, err = filepath.Abs(cfg.Options.AttachmentsPath); err != nil {
return errors.Wrapf(err, "convert attachments path %q to an absolute path", cfg.Options.AttachmentsPath)
Expand Down
109 changes: 57 additions & 52 deletions internal/bagoup/bagoup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package bagoup

import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
Expand All @@ -29,6 +30,10 @@ func TestBagoup(t *testing.T) {
SelfHandle: "Me",
AttachmentsPath: "/",
}
exportPathAbs := filepath.Join(wd, "messages-export")
logDirAbs := filepath.Join(exportPathAbs, ".bagoup")
logFileAbs := filepath.Join(logDirAbs, "out.log")
tildeexpansionAbs := filepath.Join(exportPathAbs, PreservedPathDir, PreservedPathTildeExpansionFile)
tenDotTwelve := "10.12"
tenDotTenDotTenDotTen := "10.10.10.10"
contactsPath := "contacts.vcf"
Expand All @@ -48,9 +53,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, ptMock *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
dbMock.EXPECT().Init(semver.MustParse("12.4")),
dbMock.EXPECT().GetHandleMap(nil),
Expand All @@ -72,9 +77,9 @@ func TestBagoup(t *testing.T) {
gomock.InOrder(
osMock.EXPECT().ReadFile("testrelativepath/.tildeexpansion"),
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
dbMock.EXPECT().Init(semver.MustParse("12.4")),
dbMock.EXPECT().GetHandleMap(nil),
Expand Down Expand Up @@ -111,9 +116,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, _ *mock_chatdb.MockChatDB, _ *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(nil, errors.New("this is an exec error")),
)
},
Expand All @@ -125,30 +130,30 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, _ *mock_chatdb.MockChatDB, _ *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export").Return(true, nil),
osMock.EXPECT().FileExist(exportPathAbs).Return(true, nil),
)
},
wantErr: `export folder "messages-export" already exists - FIX: move it or specify a different export path with the --export-path option`,
wantErr: fmt.Sprintf(`export folder %q already exists - FIX: move it or specify a different export path with the --export-path option`, exportPathAbs),
},
{
msg: "error checking export path",
opts: defaultOpts,
setupMocks: func(osMock *mock_opsys.MockOS, _ *mock_chatdb.MockChatDB, _ *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export").Return(false, errors.New("this is a stat error")),
osMock.EXPECT().FileExist(exportPathAbs).Return(false, errors.New("this is a stat error")),
)
},
wantErr: `check export path "messages-export": this is a stat error`,
wantErr: fmt.Sprintf(`check export path %q: this is a stat error`, exportPathAbs),
},
{
msg: "error creating log directory",
opts: defaultOpts,
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, _ *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm).Return(errors.New("this is a permissions error")),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm).Return(errors.New("this is a permissions error")),
)
},
wantErr: "make log directory: this is a permissions error",
Expand All @@ -159,9 +164,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, _ *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, errors.New("this is a permissions error")),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, errors.New("this is a permissions error")),
)
},
wantErr: "create log file: this is a permissions error",
Expand All @@ -178,9 +183,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, ptMock *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
dbMock.EXPECT().Init(semver.MustParse("10.12")),
dbMock.EXPECT().GetHandleMap(nil),
dbMock.EXPECT().GetAttachmentPaths(ptMock),
Expand All @@ -201,9 +206,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, _ *mock_chatdb.MockChatDB, _ *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
)
},
wantErr: `parse Mac OS version "10.10.10.10": Invalid Semantic Version`,
Expand All @@ -220,9 +225,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, ptMock *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
osMock.EXPECT().GetContactMap("contacts.vcf"),
dbMock.EXPECT().Init(semver.MustParse("12.4")),
Expand All @@ -245,9 +250,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, _ *mock_chatdb.MockChatDB, _ *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
osMock.EXPECT().GetContactMap("contacts.vcf").Return(nil, errors.New("this is an os error")),
)
Expand All @@ -260,9 +265,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, _ *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
dbMock.EXPECT().Init(semver.MustParse("12.4")).Return(errors.New("this is a DB error")),
)
Expand All @@ -275,9 +280,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, _ *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
dbMock.EXPECT().Init(semver.MustParse("12.4")),
dbMock.EXPECT().GetHandleMap(nil).Return(nil, errors.New("this is a DB error")),
Expand All @@ -291,9 +296,9 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, ptMock *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
dbMock.EXPECT().Init(semver.MustParse("12.4")),
dbMock.EXPECT().GetHandleMap(nil),
Expand All @@ -317,16 +322,16 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, ptMock *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
dbMock.EXPECT().Init(semver.MustParse("12.4")),
dbMock.EXPECT().GetHandleMap(nil),
dbMock.EXPECT().GetAttachmentPaths(ptMock),
dbMock.EXPECT().GetChats(nil),
ptMock.EXPECT().GetHomeDir(),
osMock.EXPECT().Create("messages-export/bagoup-attachments/.tildeexpansion").Return(afero.NewMemMapFs().Create("dummy")),
osMock.EXPECT().Create(tildeexpansionAbs).Return(afero.NewMemMapFs().Create("dummy")),
osMock.EXPECT().RmTempDir().Times(2),
)
},
Expand All @@ -344,16 +349,16 @@ func TestBagoup(t *testing.T) {
setupMocks: func(osMock *mock_opsys.MockOS, dbMock *mock_chatdb.MockChatDB, ptMock *mock_pathtools.MockPathTools) {
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
dbMock.EXPECT().Init(semver.MustParse("12.4")),
dbMock.EXPECT().GetHandleMap(nil),
dbMock.EXPECT().GetAttachmentPaths(ptMock),
dbMock.EXPECT().GetChats(nil),
ptMock.EXPECT().GetHomeDir(),
osMock.EXPECT().Create("messages-export/bagoup-attachments/.tildeexpansion").Return(nil, errors.New("this is a permissions error")),
osMock.EXPECT().Create(tildeexpansionAbs).Return(nil, errors.New("this is a permissions error")),
osMock.EXPECT().RmTempDir(),
)
},
Expand All @@ -376,16 +381,16 @@ func TestBagoup(t *testing.T) {
rofs := afero.NewReadOnlyFs(rwfs)
gomock.InOrder(
osMock.EXPECT().FileAccess("~/Library/Messages/chat.db"),
osMock.EXPECT().FileExist("messages-export"),
osMock.EXPECT().MkdirAll("messages-export/.bagoup", os.ModePerm),
osMock.EXPECT().Create("messages-export/.bagoup/out.log").Return(devnull, nil),
osMock.EXPECT().FileExist(exportPathAbs),
osMock.EXPECT().MkdirAll(logDirAbs, os.ModePerm),
osMock.EXPECT().Create(logFileAbs).Return(devnull, nil),
osMock.EXPECT().GetMacOSVersion().Return(semver.MustParse("12.4"), nil),
dbMock.EXPECT().Init(semver.MustParse("12.4")),
dbMock.EXPECT().GetHandleMap(nil),
dbMock.EXPECT().GetAttachmentPaths(ptMock),
dbMock.EXPECT().GetChats(nil),
ptMock.EXPECT().GetHomeDir(),
osMock.EXPECT().Create("messages-export/bagoup-attachments/.tildeexpansion").Return(rofs.Open("dummy")),
osMock.EXPECT().Create(tildeexpansionAbs).Return(rofs.Open("dummy")),
osMock.EXPECT().RmTempDir(),
)
},
Expand All @@ -407,7 +412,7 @@ func TestBagoup(t *testing.T) {
osMock,
dbMock,
ptMock,
"messages-export/.bagoup",
logDirAbs,
time.Now(),
"",
)
Expand Down
35 changes: 16 additions & 19 deletions internal/bagoup/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,16 @@ func (cfg *configuration) handleAttachments(outFile opsys.OutFile, msgID int, at
return nil
}
for _, att := range msgPaths {
attPath, mimeType, transferName := att.Filename, att.MIMEType, att.TransferName
err := cfg.validateAttachmentPath(attPath)
att.Filepath = filepath.Join(cfg.Options.AttachmentsPath, att.Filename)
err := cfg.validateAttachmentPath(att)
if _, ok := err.(errorMissingAttachment); ok {
// Attachment is missing. Just reference it, and skip copying/embedding.
cfg.counts.attachmentsMissing++
log.Printf("WARN: chat file %q - message %d - %s attachment %q (ID %d) - %s", outFile.Name(), msgID, mimeType, transferName, att.ID, err)
if err := outFile.ReferenceAttachment(transferName); err != nil {
return errors.Wrapf(err, "reference attachment %q", transferName)
log.Printf("WARN: chat file %q - message %d - %s attachment %q (ID %d) - %s", outFile.Name(), msgID, att.MIMEType, att.TransferName, att.ID, err)
if err := outFile.ReferenceAttachment(att.TransferName); err != nil {
return errors.Wrapf(err, "reference attachment %q", att.TransferName)
}
cfg.counts.attachments[mimeType]++
cfg.counts.attachments[att.MIMEType]++
continue
} else if err != nil {
return err
Expand All @@ -175,13 +175,12 @@ type errorMissingAttachment struct{ err error }

func (e errorMissingAttachment) Error() string { return e.err.Error() }

func (cfg configuration) validateAttachmentPath(attPath string) error {
if attPath == "" {
func (cfg configuration) validateAttachmentPath(att chatdb.Attachment) error {
if att.Filename == "" {
return errorMissingAttachment{err: errors.New("attachment has no local filename")}
}
attPath = filepath.Join(cfg.Options.AttachmentsPath, attPath)
if ok, err := cfg.OS.FileExist(attPath); err != nil {
return errors.Wrapf(err, "check existence of file %q - POSSIBLE FIX: %s", attPath, _readmeURL)
if ok, err := cfg.OS.FileExist(att.Filepath); err != nil {
return errors.Wrapf(err, "check existence of file %q - POSSIBLE FIX: %s", att.Filepath, _readmeURL)
} else if !ok {
return errorMissingAttachment{err: errors.New("attachment does not exist locally")}
}
Expand All @@ -192,27 +191,25 @@ func (cfg *configuration) copyAttachment(att *chatdb.Attachment, attDir string)
if !cfg.Options.CopyAttachments {
return nil
}
attPath, mimeType := att.Filename, att.MIMEType
unique := true
if cfg.Options.PreservePaths {
unique = false
attDir = filepath.Join(cfg.Options.ExportPath, PreservedPathDir, filepath.Dir(attPath))
attDir = filepath.Join(cfg.Options.ExportPath, PreservedPathDir, filepath.Dir(att.Filename))
if err := cfg.OS.MkdirAll(attDir, os.ModePerm); err != nil {
return errors.Wrapf(err, "create directory %q", attDir)
}
}
attPath = filepath.Join(cfg.Options.AttachmentsPath, attPath)
dstPath, err := cfg.OS.CopyFile(attPath, attDir, unique)
dstPath, err := cfg.OS.CopyFile(att.Filepath, attDir, unique)
if err != nil {
return errors.Wrapf(err, "copy attachment %q to %q", attPath, attDir)
return errors.Wrapf(err, "copy attachment %q to %q", att.Filepath, attDir)
}
att.Filename = dstPath
cfg.counts.attachmentsCopied[mimeType]++
att.Filepath = dstPath
cfg.counts.attachmentsCopied[att.MIMEType]++
return nil
}

func (cfg *configuration) writeAttachment(outFile opsys.OutFile, att chatdb.Attachment) error {
attPath, mimeType := filepath.Join(cfg.Options.AttachmentsPath, att.Filename), att.MIMEType
attPath, mimeType := att.Filepath, att.MIMEType
if cfg.Options.OutputPDF {
if jpgPath, err := cfg.OS.HEIC2JPG(attPath); err != nil {
cfg.counts.conversionsFailed++
Expand Down
Loading

0 comments on commit 3c6af3e

Please sign in to comment.