-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsidecars.go
141 lines (126 loc) · 3.92 KB
/
sidecars.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package luminosity
import (
"fmt"
"os"
)
const (
sidecarColumns = `
select
image.id_local as id
, root.absolutePath
, folder.pathFromRoot
, file.baseName
, file.extension
, file.sidecarExtensions
`
sidecarFrom = `
from AgLibraryFile as file
inner join Adobe_images as image
on file.id_local = image.rootFile
inner join AgLibraryFolder as folder
on file.folder = folder.id_local
inner join AgLibraryRootFolder as root
on folder.rootFolder = root.id_local
where file.sidecarExtensions = 'JPG'
and image.fileFormat = 'RAW'
`
)
// SidecarFileStats records summary information about the sidecars of
// a catalog, including total count, total size on disk, and how many
// sidecars or original photos are missing.
type SidecarFileStats struct {
// Count indicates the total number of sidecar files in a catalog.
Count uint
// MissingSidecarCount indicates the total number of sidecar files
// which are missing on disk.
MissingSidecarCount uint
// MissingOriginalCount indicates the total number of files for
// which a sidecar record exists, but the original file is missing
// on disk.
MissingOriginalCount uint
// TotalSizeBytes indicates the total size in bytes of the sidecar
// files on disk.
TotalSizeBytes int64
}
type SidecarFileRecord struct {
PhotoId string
RootPath string
FilePath string
FileName string
Extension string
SidecarExtension string
// Absolute path to the sidecar file. Reconstructed from RootPath
// + FilePath + FileName + SidecarExtension.
SidecarPath string
// Absolute path to the original photo file the sidecar is
// associated with. Reconstructed from RootPath + FilePath +
// FileName + Extension.
OriginalPath string
}
// GetSidecarCount returns the number of sidecar files that have
// entries in the catalog. This is independent of whether or not those
// files are known to actually exist on disk or not. To get the
// current status of what sidecar files exist and how much space they
// occupy, use GetSidecarFileStats().
func (c *Catalog) GetSidecarCount() (int, error) {
row := c.db.queryRow("get_sidecar_count", "select count(*) "+sidecarFrom)
count := -1
err := row.Scan(&count)
return count, err
}
// GetSidecarFileStats returns summary statistics about a catalog's
// sidecar files, including how much space they take up on disk, and
// how many are missing.
func (c *Catalog) GetSidecarFileStats() (*SidecarFileStats, error) {
var count, missingSidecars, missingOriginals uint
var size int64
err := c.ForEachSidecar(func(record *SidecarFileRecord) error {
if file, err := os.Open(record.OriginalPath); err != nil {
if os.IsNotExist(err) {
missingOriginals++
}
} else {
file.Close()
}
if file, err := os.Open(record.SidecarPath); err != nil {
if os.IsNotExist(err) {
missingSidecars++
}
} else {
if info, err := file.Stat(); err == nil {
size += info.Size()
count++
}
file.Close()
}
return nil
})
return &SidecarFileStats{
Count: count,
MissingSidecarCount: missingSidecars,
MissingOriginalCount: missingOriginals,
TotalSizeBytes: size,
}, err
}
// ForEachSidecar takes a callback function and executes it once for
// every sidecar record in the catalog.
func (c *Catalog) ForEachSidecar(handler func(*SidecarFileRecord) error) error {
rows, err := c.db.query("for_each_sidecar", sidecarColumns+sidecarFrom)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
r := &SidecarFileRecord{}
err = rows.Scan(&r.PhotoId, &r.RootPath, &r.FilePath, &r.FileName, &r.Extension, &r.SidecarExtension)
if err != nil {
return err
}
r.SidecarPath = fmt.Sprintf("%s%s%s.%s",
r.RootPath, r.FilePath, r.FileName, r.SidecarExtension)
r.OriginalPath = fmt.Sprintf("%s%s%s.%s",
r.RootPath, r.FilePath, r.FileName, r.Extension)
handler(r)
}
return nil
}