mirror of
https://github.com/celogeek/piwigo-cli.git
synced 2025-05-25 10:12:37 +02:00
lazy compute file
This commit is contained in:
parent
31441a3e3c
commit
234a63f208
@ -29,25 +29,28 @@ func (p *Piwigo) FileExists(md5 string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piwigo) CheckUploadFile(file *piwigotools.FileToUpload, stat *piwigotools.FileToUploadStat) (err error) {
|
func (p *Piwigo) CheckUploadFile(file *piwigotools.FileToUpload, stat *piwigotools.FileToUploadStat) (err error) {
|
||||||
if !file.Checked() {
|
if file.Checked() {
|
||||||
if file.MD5() == "" {
|
return nil
|
||||||
stat.Fail()
|
|
||||||
stat.Check()
|
|
||||||
err = fmt.Errorf("%s: checksum error", file.FullPath())
|
|
||||||
stat.Error("CheckUploadFile", file.FullPath(), err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.FileExists(file.MD5()) {
|
|
||||||
stat.Skip()
|
|
||||||
stat.Check()
|
|
||||||
err = fmt.Errorf("%s: file already exists", file.FullPath())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
stat.Check()
|
|
||||||
stat.AddBytes(file.Size())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if file.MD5() == nil {
|
||||||
|
stat.Fail()
|
||||||
|
stat.Check()
|
||||||
|
err = fmt.Errorf("%s: checksum error", *file.FullPath())
|
||||||
|
stat.Error("CheckUploadFile", *file.FullPath(), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.FileExists(*file.MD5()) {
|
||||||
|
stat.Skip()
|
||||||
|
stat.Check()
|
||||||
|
err = fmt.Errorf("%s: file already exists", *file.FullPath())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stat.Check()
|
||||||
|
stat.AddBytes(*file.Size())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +62,7 @@ func (p *Piwigo) Upload(file *piwigotools.FileToUpload, stat *piwigotools.FileTo
|
|||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
chunks, err := file.Base64Chunker()
|
chunks, err := file.Base64Chunker()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stat.Error("Base64Chunker", file.FullPath(), err)
|
stat.Error("Base64Chunker", *file.FullPath(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +80,7 @@ func (p *Piwigo) Upload(file *piwigotools.FileToUpload, stat *piwigotools.FileTo
|
|||||||
|
|
||||||
var resp *FileUploadResult
|
var resp *FileUploadResult
|
||||||
data := &url.Values{}
|
data := &url.Values{}
|
||||||
data.Set("original_sum", file.MD5())
|
data.Set("original_sum", *file.MD5())
|
||||||
data.Set("original_filename", file.Name)
|
data.Set("original_filename", file.Name)
|
||||||
data.Set("check_uniqueness", "true")
|
data.Set("check_uniqueness", "true")
|
||||||
if file.CreatedAt() != nil {
|
if file.CreatedAt() != nil {
|
||||||
@ -95,7 +98,7 @@ func (p *Piwigo) Upload(file *piwigotools.FileToUpload, stat *piwigotools.FileTo
|
|||||||
err = nil
|
err = nil
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
stat.Error(fmt.Sprintf("Upload %d", i), file.FullPath(), err)
|
stat.Error(fmt.Sprintf("Upload %d", i), *file.FullPath(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,7 +107,7 @@ func (p *Piwigo) Upload(file *piwigotools.FileToUpload, stat *piwigotools.FileTo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if hasVideoJS {
|
if hasVideoJS {
|
||||||
switch file.Ext() {
|
switch *file.Ext() {
|
||||||
case "ogg", "ogv", "mp4", "m4v", "webm", "webmv":
|
case "ogg", "ogv", "mp4", "m4v", "webm", "webmv":
|
||||||
p.VideoJSSync(resp.ImageId)
|
p.VideoJSSync(resp.ImageId)
|
||||||
}
|
}
|
||||||
@ -118,7 +121,7 @@ func (p *Piwigo) UploadChunk(file *piwigotools.FileToUpload, chunks chan *piwigo
|
|||||||
for chunk := range chunks {
|
for chunk := range chunks {
|
||||||
var err error
|
var err error
|
||||||
data := &url.Values{
|
data := &url.Values{
|
||||||
"original_sum": []string{file.MD5()},
|
"original_sum": []string{*file.MD5()},
|
||||||
"position": []string{fmt.Sprint(chunk.Position)},
|
"position": []string{fmt.Sprint(chunk.Position)},
|
||||||
"type": []string{"file"},
|
"type": []string{"file"},
|
||||||
"data": []string{chunk.Buffer.String()},
|
"data": []string{chunk.Buffer.String()},
|
||||||
@ -128,7 +131,7 @@ func (p *Piwigo) UploadChunk(file *piwigotools.FileToUpload, chunks chan *piwigo
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
stat.Error(fmt.Sprintf("UploadChunk %d", i), file.FullPath(), err)
|
stat.Error(fmt.Sprintf("UploadChunk %d", i), *file.FullPath(), err)
|
||||||
}
|
}
|
||||||
stat.Commit(chunk.Size)
|
stat.Commit(chunk.Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -193,7 +196,7 @@ func (p *Piwigo) ScanTree(
|
|||||||
Name: dir.Name(),
|
Name: dir.Name(),
|
||||||
CategoryId: parentCategoryId,
|
CategoryId: parentCategoryId,
|
||||||
}
|
}
|
||||||
if !filter.Has(file.Ext()) {
|
if !filter.Has(*file.Ext()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
stat.Add()
|
stat.Add()
|
||||||
|
@ -15,9 +15,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type FileInfo struct {
|
type FileInfo struct {
|
||||||
md5 string
|
fullpath *string
|
||||||
size int64
|
md5 *string
|
||||||
ext string
|
size *int64
|
||||||
|
ext *string
|
||||||
createdAt *TimeResult
|
createdAt *TimeResult
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,73 +27,119 @@ type FileToUpload struct {
|
|||||||
Name string
|
Name string
|
||||||
CategoryId int
|
CategoryId int
|
||||||
|
|
||||||
info *FileInfo
|
info FileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileToUpload) FullPath() string {
|
func (f *FileToUpload) FullPath() *string {
|
||||||
return filepath.Join(f.Dir, f.Name)
|
if f.info.fullpath != nil {
|
||||||
|
return f.info.fullpath
|
||||||
|
}
|
||||||
|
fp := filepath.Join(f.Dir, f.Name)
|
||||||
|
f.info.fullpath = &fp
|
||||||
|
|
||||||
|
return f.info.fullpath
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileToUpload) Info() *FileInfo {
|
func (f *FileToUpload) Size() *int64 {
|
||||||
if f.info != nil {
|
if f.info.size != nil {
|
||||||
return f.info
|
return f.info.size
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open(f.FullPath())
|
st, err := os.Stat(*f.FullPath())
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
size := st.Size()
|
||||||
|
|
||||||
|
f.info.size = &size
|
||||||
|
|
||||||
|
return f.info.size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileToUpload) Ext() *string {
|
||||||
|
if f.info.ext != nil {
|
||||||
|
return f.info.ext
|
||||||
|
}
|
||||||
|
|
||||||
|
ext := strings.ToLower(filepath.Ext(f.Name)[1:])
|
||||||
|
f.info.ext = &ext
|
||||||
|
|
||||||
|
return f.info.ext
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileToUpload) MD5() *string {
|
||||||
|
if f.info.md5 != nil {
|
||||||
|
return f.info.md5
|
||||||
|
}
|
||||||
|
file, err := os.Open(*f.FullPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
st, err := file.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
hash := md5.New()
|
hash := md5.New()
|
||||||
if _, err = io.Copy(hash, file); err != nil {
|
if _, err = io.Copy(hash, file); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
checksum := fmt.Sprintf("%x", hash.Sum(nil))
|
checksum := fmt.Sprintf("%x", hash.Sum(nil))
|
||||||
|
f.info.md5 = &checksum
|
||||||
|
|
||||||
info := FileInfo{
|
return f.info.md5
|
||||||
size: st.Size(),
|
|
||||||
md5: checksum,
|
|
||||||
createdAt: f.exifCreatedAt(),
|
|
||||||
}
|
|
||||||
|
|
||||||
f.info = &info
|
|
||||||
return f.info
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FileToUpload) Checked() bool {
|
|
||||||
return f.info != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FileToUpload) MD5() string {
|
|
||||||
if info := f.Info(); info != nil {
|
|
||||||
return info.md5
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FileToUpload) Size() int64 {
|
|
||||||
if info := f.Info(); info != nil {
|
|
||||||
return info.size
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FileToUpload) Ext() string {
|
|
||||||
return strings.ToLower(filepath.Ext(f.Name)[1:])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileToUpload) CreatedAt() *TimeResult {
|
func (f *FileToUpload) CreatedAt() *TimeResult {
|
||||||
if info := f.Info(); info != nil {
|
if f.info.createdAt != nil {
|
||||||
return info.createdAt
|
return f.info.createdAt
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
et, err := exiftool.NewExiftool()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer et.Close()
|
||||||
|
|
||||||
|
var createdAt *time.Time
|
||||||
|
var CreateDateFormat = "2006:01:02 15:04:05-07:00"
|
||||||
|
|
||||||
|
fileInfos := et.ExtractMetadata(*f.FullPath())
|
||||||
|
for _, fileInfo := range fileInfos {
|
||||||
|
if fileInfo.Err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var t time.Time
|
||||||
|
for k, v := range fileInfo.Fields {
|
||||||
|
switch k {
|
||||||
|
case "CreateDate":
|
||||||
|
offset, ok := fileInfo.Fields["OffsetTime"]
|
||||||
|
if !ok {
|
||||||
|
offset = "+00:00"
|
||||||
|
}
|
||||||
|
v := fmt.Sprintf("%s%s", v, offset)
|
||||||
|
t, err = time.Parse(CreateDateFormat, v)
|
||||||
|
case "CreationDate":
|
||||||
|
t, err = time.Parse(CreateDateFormat, fmt.Sprint(v))
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if createdAt == nil || createdAt.After(t) {
|
||||||
|
createdAt = &t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if createdAt != nil {
|
||||||
|
result := TimeResult(*createdAt)
|
||||||
|
f.info.createdAt = &result
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.info.createdAt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileToUpload) Checked() bool {
|
||||||
|
return f.info.md5 != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -108,7 +155,7 @@ type FileToUploadChunk struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileToUpload) Base64Chunker() (chan *FileToUploadChunk, error) {
|
func (f *FileToUpload) Base64Chunker() (chan *FileToUploadChunk, error) {
|
||||||
fh, err := os.Open(f.FullPath())
|
fh, err := os.Open(*f.FullPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -144,49 +191,3 @@ func (f *FileToUpload) Base64Chunker() (chan *FileToUploadChunk, error) {
|
|||||||
|
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileToUpload) exifCreatedAt() *TimeResult {
|
|
||||||
et, err := exiftool.NewExiftool()
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
defer et.Close()
|
|
||||||
|
|
||||||
var createdAt *time.Time
|
|
||||||
var CreateDateFormat = "2006:01:02 15:04:05-07:00"
|
|
||||||
|
|
||||||
fileInfos := et.ExtractMetadata(f.FullPath())
|
|
||||||
for _, fileInfo := range fileInfos {
|
|
||||||
if fileInfo.Err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var t time.Time
|
|
||||||
for k, v := range fileInfo.Fields {
|
|
||||||
switch k {
|
|
||||||
case "CreateDate":
|
|
||||||
offset, ok := fileInfo.Fields["OffsetTime"]
|
|
||||||
if !ok {
|
|
||||||
offset = "+00:00"
|
|
||||||
}
|
|
||||||
v := fmt.Sprintf("%s%s", v, offset)
|
|
||||||
t, err = time.Parse(CreateDateFormat, v)
|
|
||||||
case "CreationDate":
|
|
||||||
t, err = time.Parse(CreateDateFormat, fmt.Sprint(v))
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if createdAt == nil || createdAt.After(t) {
|
|
||||||
createdAt = &t
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if createdAt != nil {
|
|
||||||
result := TimeResult(*createdAt)
|
|
||||||
return &result
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user