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  }