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

     1  // Copyright 2020 Readium Foundation. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license
     3  // that can be found in the LICENSE file exposed on Github (readium) in the project repository.
     4  
     5  package rwpm
     6  
     7  import (
     8  	"errors"
     9  	"path"
    10  	"strings"
    11  )
    12  
    13  // Publication = Readium manifest
    14  type Publication struct {
    15  	Context      MultiString `json:"@context,omitempty"`
    16  	Metadata     Metadata    `json:"metadata"`
    17  	Links        []Link      `json:"links,omitempty"`
    18  	ReadingOrder []Link      `json:"readingOrder,omitempty"`
    19  	Resources    []Link      `json:"resources,omitempty"`
    20  	TOC          []Link      `json:"toc,omitempty"`
    21  	PageList     []Link      `json:"page-list,omitempty"`
    22  	Landmarks    []Link      `json:"landmarks,omitempty"`
    23  	LOI          []Link      `json:"loi,omitempty"` //List of illustrations
    24  	LOA          []Link      `json:"loa,omitempty"` //List of audio files
    25  	LOV          []Link      `json:"lov,omitempty"` //List of videos
    26  	LOT          []Link      `json:"lot,omitempty"` //List of tables
    27  
    28  	OtherLinks       []Link                  `json:"-"` //Extension point for links that shouldn't show up in the manifest
    29  	OtherCollections []PublicationCollection `json:"-"` //Extension point for collections that shouldn't show up in the manifest
    30  }
    31  
    32  // Link object used in collections and links
    33  type Link struct {
    34  	Href       string      `json:"href"`
    35  	Templated  bool        `json:"templated,omitempty"`
    36  	Type       string      `json:"type,omitempty"`
    37  	Title      string      `json:"title,omitempty"`
    38  	Rel        MultiString `json:"rel,omitempty"`
    39  	Height     int         `json:"height,omitempty"`
    40  	Width      int         `json:"width,omitempty"`
    41  	Duration   float32     `json:"duration,omitempty"`
    42  	Bitrate    int         `json:"bitrate,omitempty"`
    43  	Properties *Properties `json:"properties,omitempty"`
    44  	Alternate  []Link      `json:"alternate,omitempty"`
    45  	Children   []Link      `json:"children,omitempty"`
    46  }
    47  
    48  // PublicationCollection is used as an extension point for other collections in a Publication
    49  type PublicationCollection struct {
    50  	Role     string
    51  	Metadata []Meta
    52  	Links    []Link
    53  	Children []PublicationCollection
    54  }
    55  
    56  // Cover returns the link relative to the cover
    57  func (publication *Publication) Cover() (Link, error) {
    58  	return publication.searchLinkByRel("cover")
    59  }
    60  
    61  // NavDoc returns the link relative to the navigation document
    62  func (publication *Publication) NavDoc() (Link, error) {
    63  	return publication.searchLinkByRel("contents")
    64  }
    65  
    66  // SearchLinkByRel returns the link which has a specific relation
    67  func (publication *Publication) searchLinkByRel(rel string) (Link, error) {
    68  	for _, resource := range publication.Resources {
    69  		for _, resRel := range resource.Rel {
    70  			if resRel == rel {
    71  				return resource, nil
    72  			}
    73  		}
    74  	}
    75  
    76  	for _, item := range publication.ReadingOrder {
    77  		for _, spineRel := range item.Rel {
    78  			if spineRel == rel {
    79  				return item, nil
    80  			}
    81  		}
    82  	}
    83  
    84  	for _, link := range publication.Links {
    85  		for _, linkRel := range link.Rel {
    86  			if linkRel == rel {
    87  				return link, nil
    88  			}
    89  		}
    90  	}
    91  
    92  	return Link{}, errors.New("Can't find " + rel + " in publication")
    93  }
    94  
    95  // AddLink Adds a link to a publication
    96  func (publication *Publication) AddLink(linkType string, rel []string, url string, templated bool) {
    97  	link := Link{
    98  		Href: url,
    99  		Type: linkType,
   100  	}
   101  	if len(rel) > 0 {
   102  		link.Rel = rel
   103  	}
   104  
   105  	if templated == true {
   106  		link.Templated = true
   107  	}
   108  
   109  	publication.Links = append(publication.Links, link)
   110  }
   111  
   112  // AddRel adds a relation to a Link
   113  func (link *Link) AddRel(rel string) {
   114  	relAlreadyPresent := false
   115  
   116  	for _, r := range link.Rel {
   117  		if r == rel {
   118  			relAlreadyPresent = true
   119  			break
   120  		}
   121  	}
   122  
   123  	if !relAlreadyPresent {
   124  		link.Rel = append(link.Rel, rel)
   125  	}
   126  }
   127  
   128  // AddHrefAbsolute modifies Href with a calculated path based on a referend file
   129  func (link *Link) AddHrefAbsolute(href string, baseFile string) {
   130  	link.Href = path.Join(path.Dir(baseFile), href)
   131  }
   132  
   133  // TransformLinkToFullURL adds a base url to every link
   134  func (publication *Publication) TransformLinkToFullURL(baseURL string) {
   135  
   136  	for i := range publication.ReadingOrder {
   137  		if !(strings.Contains(publication.ReadingOrder[i].Href, "http://") || strings.Contains(publication.ReadingOrder[i].Href, "https://")) {
   138  			publication.ReadingOrder[i].Href = baseURL + publication.ReadingOrder[i].Href
   139  		}
   140  	}
   141  
   142  	for i := range publication.Resources {
   143  		if !(strings.Contains(publication.Resources[i].Href, "http://") || strings.Contains(publication.Resources[i].Href, "https://")) {
   144  			publication.Resources[i].Href = baseURL + publication.Resources[i].Href
   145  		}
   146  	}
   147  
   148  	for i := range publication.TOC {
   149  		if !(strings.Contains(publication.TOC[i].Href, "http://") || strings.Contains(publication.TOC[i].Href, "https://")) {
   150  			publication.TOC[i].Href = baseURL + publication.TOC[i].Href
   151  		}
   152  	}
   153  
   154  	for i := range publication.Landmarks {
   155  		if !(strings.Contains(publication.Landmarks[i].Href, "http://") || strings.Contains(publication.Landmarks[i].Href, "https://")) {
   156  			publication.Landmarks[i].Href = baseURL + publication.Landmarks[i].Href
   157  		}
   158  	}
   159  }