package liber import ( "encoding/xml" "io" "os" "path/filepath" "strings" ) type opfIdentifier struct { Scheme string `xml:"http://www.idpf.org/2007/opf scheme,attr"` Value string `xml:",chardata"` } type opfMeta struct { XMLName xml.Name `xml:"http://www.idpf.org/2007/opf metadata"` Title string `xml:"http://purl.org/dc/elements/1.1/ title"` Date string `xml:"http://purl.org/dc/elements/1.1/ date"` Description string `xml:"http://purl.org/dc/elements/1.1/ description"` Creator []string `xml:"http://purl.org/dc/elements/1.1/ creator"` Language []string `xml:"http://purl.org/dc/elements/1.1/ language"` Publisher []string `xml:"http://purl.org/dc/elements/1.1/ publisher"` Identifier []opfIdentifier `xml:"http://purl.org/dc/elements/1.1/ identifier"` } type opfPackage struct { Meta *opfMeta } func (o *opfMeta) ToMetadata() *Metadata { m := &Metadata{ Title: o.Title, Description: o.Description, Publisher: o.Publisher, Language: o.Language, } if o.Date != "" && o.Date != "0101-01-01T00:00:00+00:00" { m.Date = toYear(o.Date) } for _, c := range o.Creator { for _, cc := range strings.Split(c, ",") { m.Creator = append(m.Creator, strings.TrimSpace(cc)) } } var uuid string for _, id := range o.Identifier { if id.Scheme == "ISBN" { m.ISBN = append(m.ISBN, id.Value) } else if id.Scheme == "uuid" { uuid = id.Value } } m.Sources = []MetadataSource{{ Name: "opf", ID: uuid, }} return m } func opfParse(r io.Reader) (*Metadata, error) { var opf opfPackage if err := xml.NewDecoder(r).Decode(&opf); err != nil { return nil, err } return opf.Meta.ToMetadata(), nil } func opfOpen(path string) (*Metadata, error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() return opfParse(file) } func opfMetadataPath(epubPath string) string { return filepath.Join(filepath.Dir(epubPath), "metadata.opf") } func opfCoverPath(epubPath string) string { return filepath.Join(filepath.Dir(epubPath), "cover.jpg") }