github.com/boki/go-xmp@v1.0.1/models/xmp_base/model.go (about) 1 // Copyright (c) 2017-2018 Alexander Eichhorn 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 // Package xmpbase implements the XMP namespace as defined by XMP Specification Part 2. 16 package xmpbase 17 18 import ( 19 "fmt" 20 "strings" 21 "trimmer.io/go-xmp/xmp" 22 ) 23 24 var ( 25 NsXmp = xmp.NewNamespace("xmp", "http://ns.adobe.com/xap/1.0/", NewModel) 26 27 nsXmpIdq = xmp.NewNamespace("xmpidq", "http://ns.adobe.com/xmp/Identifier/qual/1.0/", nil) 28 nsXmpG = xmp.NewNamespace("xmpG", "http://ns.adobe.com/xap/1.0/g/", nil) 29 nsXmpGImg = xmp.NewNamespace("xmpGImg", "http://ns.adobe.com/xap/1.0/g/img/", nil) 30 ) 31 32 func init() { 33 xmp.Register(NsXmp, xmp.XmpMetadata) 34 xmp.Register(nsXmpIdq) 35 xmp.Register(nsXmpG) 36 xmp.Register(nsXmpGImg) 37 } 38 39 func NewModel(name string) xmp.Model { 40 return &XmpBase{} 41 } 42 43 func MakeModel(d *xmp.Document) (*XmpBase, error) { 44 m, err := d.MakeModel(NsXmp) 45 if err != nil { 46 return nil, err 47 } 48 x, _ := m.(*XmpBase) 49 return x, nil 50 } 51 52 func FindModel(d *xmp.Document) *XmpBase { 53 if m := d.FindModel(NsXmp); m != nil { 54 return m.(*XmpBase) 55 } 56 return nil 57 } 58 59 type XmpBase struct { 60 Advisory xmp.StringArray `xmp:"xmp:Advisory"` 61 BaseURL xmp.Uri `xmp:"xmp:BaseURL"` 62 CreateDate xmp.Date `xmp:"xmp:CreateDate"` 63 CreatorTool xmp.AgentName `xmp:"xmp:CreatorTool"` 64 Identifier IdentifierArray `xmp:"xmp:Identifier"` 65 Label string `xmp:"xmp:Label"` 66 MetadataDate xmp.Date `xmp:"xmp:MetadataDate"` 67 ModifyDate xmp.Date `xmp:"xmp:ModifyDate"` 68 Nickname string `xmp:"xmp:Nickname"` 69 Rating Rating `xmp:"xmp:Rating"` 70 Thumbnails ThumbnailArray `xmp:"xmp:Thumbnails"` 71 Extensions xmp.NamedExtensionArray `xmp:"xmp:extension"` 72 } 73 74 func (x XmpBase) Can(nsName string) bool { 75 return NsXmp.GetName() == nsName 76 } 77 78 func (x XmpBase) Namespaces() xmp.NamespaceList { 79 return xmp.NamespaceList{NsXmp} 80 } 81 82 func prefixer(prefix string) xmp.ConverterFunc { 83 return func(val string) string { 84 return strings.Join([]string{prefix, val}, ":") 85 } 86 } 87 88 var identifierDesc = xmp.SyncDescList{ 89 &xmp.SyncDesc{"trim:Asset/UUID", "xmp:Identifier", xmp.MERGE, nil}, 90 &xmp.SyncDesc{"exif:ImageUniqueID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:exif")}, 91 &xmp.SyncDesc{"arri:UUID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:arri")}, 92 &xmp.SyncDesc{"arri:SMPTE_UMID", "xmp:Identifier", xmp.MERGE, prefixer("umid:smpte")}, 93 &xmp.SyncDesc{"iXML:fileUid", "xmp:Identifier", xmp.MERGE, prefixer("uuid:ixml")}, 94 &xmp.SyncDesc{"qt:mdta/ContentIdentifier", "xmp:Identifier", xmp.MERGE, prefixer("uuid:cid")}, 95 &xmp.SyncDesc{"iTunes:StoreFrontID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:sfid")}, 96 &xmp.SyncDesc{"qt:GUID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:guid")}, 97 &xmp.SyncDesc{"qt:ISRCCode", "xmp:Identifier", xmp.MERGE, prefixer("uuid:isrc")}, 98 &xmp.SyncDesc{"qt:ContentID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:cid")}, 99 &xmp.SyncDesc{"qt:ClipID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:clipid")}, 100 &xmp.SyncDesc{"qt:proapps/ClipID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:clipid")}, 101 &xmp.SyncDesc{"bext:umid", "xmp:Identifier", xmp.MERGE, prefixer("umid:smpte")}, 102 &xmp.SyncDesc{"id3:podcastID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:podcast")}, 103 &xmp.SyncDesc{"id3:uniqueFileIdentifier", "xmp:Identifier", xmp.MERGE, prefixer("uuid:id3")}, 104 &xmp.SyncDesc{"GettyImagesGIFT:AssetID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:getty")}, 105 &xmp.SyncDesc{"Iptc4xmpExt:DigImageGUID", "xmp:Identifier", xmp.MERGE, prefixer("uuid:iptc")}, 106 &xmp.SyncDesc{"mxf:PackageID", "xmp:Identifier", xmp.MERGE, prefixer("umid:smpte")}, 107 108 // TODO: map more id schemes here 109 // FCPX: Asset UID from fcpxml uuid:fcpx: 110 // Panasonic: GlobalClipID (SMPTE UMID) umid:smpte: 111 } 112 113 func (x *XmpBase) SyncModel(d *xmp.Document) error { 114 return d.SyncMulti(identifierDesc, x) 115 } 116 117 func (x *XmpBase) SyncFromXMP(d *xmp.Document) error { 118 return nil 119 } 120 121 func (x XmpBase) SyncToXMP(d *xmp.Document) error { 122 return nil 123 } 124 125 func (x *XmpBase) CanTag(tag string) bool { 126 _, err := xmp.GetNativeField(x, tag) 127 return err == nil 128 } 129 130 func (x *XmpBase) GetTag(tag string) (string, error) { 131 if v, err := xmp.GetNativeField(x, tag); err != nil { 132 return "", fmt.Errorf("%s: %v", NsXmp.GetName(), err) 133 } else { 134 return v, nil 135 } 136 } 137 138 func (x *XmpBase) SetTag(tag, value string) error { 139 if err := xmp.SetNativeField(x, tag, value); err != nil { 140 return fmt.Errorf("%s: %v", NsXmp.GetName(), err) 141 } 142 return nil 143 } 144 145 func (x *XmpBase) AddID(id string) { 146 x.Identifier = append(x.Identifier, Identifier{ID: id}) 147 } 148 149 func (x *XmpBase) AddIDWithScheme(id, scheme string) { 150 x.Identifier = append(x.Identifier, Identifier{ID: id, Scheme: scheme}) 151 }