github.com/readium/readium-lcp-server@v0.0.0-20240509124024-799e77a0bbd6/epub/epub.go (about)

     1  // Copyright 2019 European Digital Reading Lab. All rights reserved.
     2  // Licensed to the Readium Foundation under one or more contributor license agreements.
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the LICENSE file exposed on Github (readium) in the project repository.
     5  
     6  package epub
     7  
     8  import (
     9  	"archive/zip"
    10  	"io"
    11  	"sort"
    12  	"strings"
    13  
    14  	"github.com/readium/readium-lcp-server/epub/opf"
    15  	"github.com/readium/readium-lcp-server/xmlenc"
    16  )
    17  
    18  const (
    19  	ContainerFile  = "META-INF/container.xml"
    20  	EncryptionFile = "META-INF/encryption.xml"
    21  	LicenseFile    = "META-INF/license.lcpl"
    22  
    23  	ContentType_XHTML = "application/xhtml+xml"
    24  	ContentType_HTML  = "text/html"
    25  
    26  	ContentType_NCX = "application/x-dtbncx+xml"
    27  
    28  	ContentType_EPUB = "application/epub+zip"
    29  )
    30  
    31  type Epub struct {
    32  	Encryption         *xmlenc.Manifest
    33  	Package            []opf.Package
    34  	Resource           []*Resource
    35  	cleartextResources []string
    36  }
    37  
    38  func (ep Epub) Cover() (bool, *Resource) {
    39  
    40  	for _, p := range ep.Package {
    41  
    42  		var coverImageID string
    43  		coverImageID = "cover-image"
    44  		for _, meta := range p.Metadata.Metas {
    45  			if meta.Name == "cover" {
    46  				coverImageID = meta.Content
    47  			}
    48  		}
    49  
    50  		for _, it := range p.Manifest.Items {
    51  
    52  			if strings.Contains(it.Properties, "cover-image") ||
    53  				it.ID == coverImageID {
    54  
    55  				// To be found later, resources in the EPUB root folder
    56  				// must not be prefixed by "./"
    57  				path := it.Href
    58  				if p.BasePath != "." {
    59  					path = p.BasePath + "/" + it.Href
    60  				}
    61  				for _, r := range ep.Resource {
    62  					if r.Path == path {
    63  						return true, r
    64  					}
    65  				}
    66  			}
    67  		}
    68  	}
    69  
    70  	return false, nil
    71  }
    72  
    73  func (ep *Epub) Add(name string, body io.Reader, size uint64) error {
    74  	ep.Resource = append(ep.Resource, &Resource{Contents: body, StorageMethod: zip.Deflate, Path: name, OriginalSize: size})
    75  
    76  	return nil
    77  }
    78  
    79  type Resource struct {
    80  	Path          string
    81  	ContentType   string
    82  	OriginalSize  uint64
    83  	ContentsSize  uint64
    84  	Compressed    bool
    85  	StorageMethod uint16
    86  	Contents      io.Reader
    87  }
    88  
    89  func (ep Epub) CanEncrypt(file string) bool {
    90  	i := sort.SearchStrings(ep.cleartextResources, file)
    91  
    92  	return i >= len(ep.cleartextResources) || ep.cleartextResources[i] != file
    93  }