catalog

package
v0.0.0-...-b9641ee Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 9, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

Functions

func IsVisibleInView

func IsVisibleInView(visibility View, view View) bool

IsVisibleInView determines if the specified visibility should be visible at a specific view level

func NewJSONFileFromCatalog

func NewJSONFileFromCatalog(jsonFile string, catalog *Catalog) error

Types

type Catalog

type Catalog struct {
	Created  time.Time        `json:"created,omitempty"`
	Series   []CatalogSeri    `json:"series,omitempty"`   // series defined in the online content
	Messages []CatalogMessage `json:"messages,omitempty"` // messages defined in the online content
	// contains filtered or unexported fields
}

Catalog contains all information about online content

func NewCatalogFromJSON

func NewCatalogFromJSON(jsonFilePath string) (*Catalog, error)

NewCatalogFromJSON reads a catalog from a file.

func (*Catalog) FindMessagesInSeries

func (c *Catalog) FindMessagesInSeries(seriesName string) []CatalogMessage

Given a series name, finds all the messages that are in that series. This returns a slice of such messages which is a copy of the original messages, except that all the series information that not for the requested series has been removed. In other words, the messages in the result will only have one Series element and it will be for the series requested. The messages will also be order by the series track number ascending but 0's at the end, so like 1, 2, 3, 4, 0, 0, 0. This makes no evaluation of "relevance" in that all messages are added to the series, even if they don't have a track index or are private

func (*Catalog) FindSeriByName

func (c *Catalog) FindSeriByName(seriesName string) (seri *CatalogSeri, ok bool)

Finds a series by name and returns it. (nil, false) if not found

func (*Catalog) FindSeriesByMinistry

func (c *Catalog) FindSeriesByMinistry(ministries ...Ministry) []CatalogSeri

FindSeriesByMinistry searches the catalog for all series that are in a specific ministry. Returns a copy of those series, or nil slice if no series with the ministry can be found

func (*Catalog) Initialize

func (c *Catalog) Initialize() error

initialize prepares the catalog for use. It will - add the messages to the series - create single-message series for all the standalone messages

func (*Catalog) IsMessageSeriesIndexValid

func (c *Catalog) IsMessageSeriesIndexValid(report *util.IndentingReport) bool

Validates that all the series referenced by messages have consistent track indexes. Checks for duplicate or skipped track numbers. Allows any number of track "0" though (which flags a message as part of a series that should not be displayed). Skipped track numbers are ok as long as the next group is a multiple of 100

func (*Catalog) IsMessageSeriesValid

func (c *Catalog) IsMessageSeriesValid(report *util.IndentingReport) bool

Validates that all the series referenced by messages actually exist in the series records. Any problems will be output to stderr

func (*Catalog) IsSeriesNamesValid

func (c *Catalog) IsSeriesNamesValid(report *util.IndentingReport) bool

Verifies that all series names are unique

func (*Catalog) IsValid

func (c *Catalog) IsValid(reportLoud bool) bool

Validates that all aspects of the catalog are valid. Returns true if the entire catalog is valid. Returns false and outputs to stderr if any problems are found. Note that just because the catalog is not valid does not mean it cannot be used.

If reporting is loud then warnings will be sent to stderr, otherwise they are logged

Validations:

  • All series referenced in messages exist
  • Series track indexes start with 1 and are sequential
  • Series names are unique
  • Message names are unique
  • Message names not in a series are unique wrt Series names

type CatalogMessage

type CatalogMessage struct {
	Date        DateOnly          `json:"date"`                  // date message was given/recorded (required)
	Name        string            `json:"name"`                  // name of the message (required)
	Description string            `json:"description,omitempty"` // detailed description of this message
	Speakers    []string          `json:"speakers"`              // names of significant speakers in the message, typically in order they spoke
	Ministry    Ministry          `json:"ministry"`              // which ministry this message was presented for
	Type        MessageType       `json:"type"`                  // category of this message
	Visibility  View              `json:"visibility,omitempty"`  // visibility of this message
	Series      []SeriesReference `json:"series,omitempty"`      // which series this message belongs to
	Audio       *OnlineResource   `json:"audio,omitempty"`       // URL of the audio file
	Video       *OnlineResource   `json:"video,omitempty"`       // URL of the video. normally on YouTube, BitChute, Rumble, or S3
	Resources   []OnlineResource  `json:"resources,omitempty"`   // list of online resources for this message (links, docs, video, etc)
	// contains filtered or unexported fields
}

CatalogMessage describes one message. The message may be part of a series or not. A message is one media event (audio + video recording). A message may contain information linking it to a series, but the message just has that metadata (like series name and index), and it is up to an external process if that information will be used to assemble related messages into a series

func (*CatalogMessage) Copy

func (m *CatalogMessage) Copy() CatalogMessage

func (*CatalogMessage) DateString

func (m *CatalogMessage) DateString() string

func (*CatalogMessage) FindSeriesReference

func (m *CatalogMessage) FindSeriesReference(seriesName string) *SeriesReference

FindSeriesReference returns this messages reference to the specfied series. Return nil if this message not in the series

func (*CatalogMessage) GetAudioSize

func (m *CatalogMessage) GetAudioSize() int

GetAudioSize gets the size of the audio file in bytes. Returns -1 on error, or 0 if no audio URL. Note this makes network calls to get the content size

func (*CatalogMessage) GetTranscriptURL

func (m *CatalogMessage) GetTranscriptURL(ext string) string

func (*CatalogMessage) HasAudio

func (m *CatalogMessage) HasAudio() bool

func (*CatalogMessage) HasTranscript

func (m *CatalogMessage) HasTranscript() bool

func (*CatalogMessage) HasVideo

func (m *CatalogMessage) HasVideo() bool

func (*CatalogMessage) Initialize

func (m *CatalogMessage) Initialize() error

initialize prepares the message for use. Performs the following checks:

  • If the audio/video URL isn't a URL, then deletes it (assumes it was one of the statuses, like "in progress", "rendering", etc)
  • If the speakers are one of the well-known ones (Vern, Mary, Dave), then make sure the name is correct

func (*CatalogMessage) IsInSeries

func (m *CatalogMessage) IsInSeries(seriesName string) bool

Determines if the message is in the specified series

func (*CatalogMessage) IsValid

func (m *CatalogMessage) IsValid(report *util.IndentingReport) bool

IsValid checks if this message has valid values in it's fields

func (*CatalogMessage) LoadTranscriptCacheForYear

func (m *CatalogMessage) LoadTranscriptCacheForYear(year int) []string

LoadTranscriptCacheForYear loads the transcript cache for the specified year. Given the year, this will call the aws cli to list the transcript files for s3://wordoflife.mn.audio/<year>/xscript/ and return a list of the base names (without extensions) of each transcript file ending with .text for that year.

func (*CatalogMessage) SpeakerString

func (m *CatalogMessage) SpeakerString() string

SpeakerString gets all the speakers in a descriptive string

type CatalogSeri

type CatalogSeri struct {
	ID          string           `json:"id"`                    // web- and file-safe ID
	Name        string           `json:"name"`                  // display name
	StartDate   DateOnly         `json:"start-date,omitempty"`  // date of first message in the series
	StopDate    DateOnly         `json:"end-date,omitempty"`    // date of last message in the series
	Description string           `json:"description,omitempty"` // detailed description of contents of series
	Booklets    []OnlineResource `json:"booklets,omitempty"`    // list of study booklets for this series (pdf)
	Visibility  View             `json:"visibility"`            // visibility of this series as a whole
	Jacket      string           `json:"jacket,omitempty"`      // link to the DVD (or CD) jacket for this series
	Thumbnail   string           `json:"thumbnail,omitempty"`   // link to the thumbnail to use for the series

	// cached or generated data. note that this data could be customized for different views of
	// the series. when read from the online content, the view is "Raw" and the list of messages
	// could contain messages with different visibilities, however, after calling GetView(), the
	// returned series view is not "Raw" and the rest of the data will only include information
	// consistent with the view
	View      View             `json:"-"`                   // view of this cached data, "Raw" if unfiltered yet
	Messages  []CatalogMessage `json:"-"`                   // list of messages in the series
	Speakers  []string         `json:"speakers,omitempty"`  // list of speakers in the series (does not include message speakers)
	Resources []OnlineResource `json:"resources,omitempty"` // any other online resources (links, docs, youtube, etc) (does not include message resources)
	State     SeriesState      `json:"state,omitempty"`     // is the series in progress?
	// contains filtered or unexported fields
}

CatalogSeri describes one series in a catalog. A Series describes a collection of related messages. This could be a collection of one or more messages.

IsRaw determines if the data is raw from the online content source. In this view,

func FilterSeriesByMinistry

func FilterSeriesByMinistry(corpus []CatalogSeri, ministries ...Ministry) []CatalogSeri

FilterSeriesByMinistry takes a slice of series and returns another slice that only contains the series that are in any of the specified ministries. Returns nil slice if none of the series in the input slice is in the ministries

func FilterSeriesByView

func FilterSeriesByView(corpus []CatalogSeri, view View) []CatalogSeri

FilterSeriesByView takes a slice of series and returns another slice that contains the series that are applicable for the view. So a "partner" view can still display series with visibility of "public" and "partner" but not "private". The resulting slice will be updated so that only messages that match the view are included. In other words, if you ask for a "public" view and there is a "public" series with a "private" message, the "private" message will be removed from the series before returning

func FilterSeriesByVisibility

func FilterSeriesByVisibility(corpus []CatalogSeri, view View) []CatalogSeri

FilterSeriesByVisibility takes a slice of series and returns another slice that contains the series that have the specific visibility. In other words, if you ask for a "public" view and there is a "public" series with a "private" message, the "private" message will be removed from the series before returning

func NewSeriesFromMessage

func NewSeriesFromMessage(msg *CatalogMessage) CatalogSeri

Creates a new series record from a message. This creates a Series that is a Series of the one message that was passed in

func (*CatalogSeri) AddResourceToSeries

func (s *CatalogSeri) AddResourceToSeries(resource OnlineResource)

AddResourceToSeries adds a resource to the list of series and message resources if it isn't already in the list

func (*CatalogSeri) AddSpeakerToSeries

func (s *CatalogSeri) AddSpeakerToSeries(speaker string)

AddSpeakerToSeries adds a speaker to the list of series and message speakers if they aren't already in the list

func (*CatalogSeri) ComputeState

func (s *CatalogSeri) ComputeState()

ComputeState looks at the dates for the series and determines what state the message is in

func (*CatalogSeri) Copy

func (s *CatalogSeri) Copy() CatalogSeri

Copy creates a deep copy of the Series

func (*CatalogSeri) DateString

func (s *CatalogSeri) DateString() string

DateString gets the date of the series in a displayable string

func (*CatalogSeri) GetCatalogFileName

func (s *CatalogSeri) GetCatalogFileName(view View) string

GetCatalogFileName returns the file name of this seri with the specified view

func (*CatalogSeri) GetID

func (s *CatalogSeri) GetID() string

Gets the ID of a series. If the series has an explicit ID (from the spreadsheet) then it will be returned. If the series doesn't have an ID yet, then one will be created from the name. Ideally, the ID of a series should be unique and persistent, so this is why we use the ID from the spreadsheet first (because it should never change). Generating an ID from the name is second-best because it is only persistent unless someone changes the name

func (*CatalogSeri) GetMinistry

func (s *CatalogSeri) GetMinistry() Ministry

Gets the Ministry of a series

func (*CatalogSeri) GetViewID

func (s *CatalogSeri) GetViewID(view View) string

GetViewID gets an ID for the series for a specific view. If the view is public, then the mystic ID is the same as the normal ID. However, if the view is partner or private, then the mystic ID is additionally hashed to obscure/uniqueify the name

func (*CatalogSeri) Initialize

func (s *CatalogSeri) Initialize() error

Initializes the series for use. This assumes that the series was just read in from disk or network and will take care of setting up the internal bookkeeping that is necessary for performance

func (*CatalogSeri) IsBooklet

func (s *CatalogSeri) IsBooklet() bool

IsBooklet determines if this series just represents a booklet. A booklet "series" looks like a series, except it has a booklet but no messages or ID. Note that a normal series can also have a booklet but a "booklet series" has no messages

func (*CatalogSeri) IsMessageRelevant

func (s *CatalogSeri) IsMessageRelevant(msg *CatalogMessage) bool

IsMessageRelevant reports whether the specified message is relavant for this series. In order for a message to be relevant, it needs to belong to the series, have a non-zero track number, and have a visibility compatible with the series current view

func (*CatalogSeri) IsValid

func (s *CatalogSeri) IsValid(report *util.IndentingReport) bool

IsValid checks if this series has valid values in it's fields

func (*CatalogSeri) MessageTitlesString

func (s *CatalogSeri) MessageTitlesString() string

MessageTitlesString gets the list of message titles as a display string. This is for display and only produces output if the list of message titles is different than the series name (i.e. if this isn't a stand-alone message)

func (*CatalogSeri) Normalize

func (s *CatalogSeri) Normalize()

Normalize updates all the series fields to reflect the data in the messages list. This includes start and stop dates, speakers, and resources.

func (*CatalogSeri) SpeakerString

func (s *CatalogSeri) SpeakerString() string

SpeakerString gets the list of speakers as a display string

type DateOnly

type DateOnly struct {
	time.Time
}

func MustParseDateOnly

func MustParseDateOnly(t string) DateOnly

func NewDateOnly

func NewDateOnly(t time.Time) DateOnly

func NewDateToday

func NewDateToday() DateOnly

func ParseDateOnly

func ParseDateOnly(t string) (d DateOnly, err error)

func (DateOnly) MarshalJSON

func (d DateOnly) MarshalJSON() ([]byte, error)

func (DateOnly) String

func (d DateOnly) String() string

func (*DateOnly) UnmarshalJSON

func (d *DateOnly) UnmarshalJSON(b []byte) (err error)

type MessageType

type MessageType string

message types

const (
	UnknownType  MessageType = "unknown"       // unknown type
	Message      MessageType = "message"       // a teaching or preached message
	Prayer       MessageType = "prayer"        // prayer for someone or something
	Song         MessageType = "song"          // song
	SpecialEvent MessageType = "special-event" // wedding, funeral, child-dedication, etc
	Testimony    MessageType = "testimony"     // someone testifying about something God has done
	Training     MessageType = "training"      // general leadership training or specific ministry training
	Word         MessageType = "word"          // a prophesy, encouragment, or other utterance under the Holy Spirit
	MinistryTime MessageType = "ministry-time" // time of individual prayr, normally at the end of service
)

func NewMessageTypeFromString

func NewMessageTypeFromString(s string) MessageType

type Ministry

type Ministry string

ministries

const (
	UnknownMinistry                Ministry = "unknown"
	WordOfLife                     Ministry = "wol"
	CenterOfRelationshipExperience Ministry = "core"
	CORE_HealthMatters             Ministry = "core_health"
	CORE_HopeDealers               Ministry = "core_hope"
	CORE_RecoveryClasses           Ministry = "core_recovery"
	CORE_CounselingClasses         Ministry = "core_counseling"
	TheBridgeOutreach              Ministry = "tbo"
	AskThePastor                   Ministry = "ask-pastor"
	FaithAndFreedom                Ministry = "faith-freedom"
)

func NewMinistryFromString

func NewMinistryFromString(s string) Ministry

func (Ministry) Description

func (ministry Ministry) Description() string

type OnlineResource

type OnlineResource struct {
	// URL of the resource, required
	URL string `json:"url"`
	// name of the resource, optional. if undefined, then GetDisplayName() will generate one from the URL
	Name string `json:"name,omitempty"`
	// Metadata contains miscellaneous metadata
	Metadata map[string]string `json:"metadata,omitempty"`

	// special references. these are only used for generating independent resources that need to
	// reference back to the series or message that they came from. in every other instance,
	// these will be nil
	Seri    *CatalogSeri    `json:"-"`
	Message *CatalogMessage `json:"-"`
	// contains filtered or unexported fields
}

OnlineResource describes a resource (pdf, document, video, website, etc) online that is used as reference material for a series or message

func NewResourceFromString

func NewResourceFromString(s string) *OnlineResource

NewResourceFromString creates a new OnlineResource from a string definition. If the input string is empty or only whitespace, returns an unititialized Online Resource

String definitions can be in multiple formats:

  • Raw URL: "http://blah/path+to+file.doc", in which case the name is the file name without the extension
  • Markdown: "[name](url)"
  • Wiki: "name|url"
  • Metadata can be included as a JSON object, like `{"iframe":"https://rumble.com/embed/vjrceb/?pub=r095p"}`. This can be embedded anywhere in the string, everything from the first to last brace will be treated as metadata.

func NewResourcesFromString

func NewResourcesFromString(s string) []OnlineResource

NewResourcesFromString parses a string that may contain multiple resources separated by semi-colons. Returns an array of resources found, in the order they were found. Empty array if nothing found

func (*OnlineResource) GetClassifier

func (r *OnlineResource) GetClassifier() string

GetClassifier returns a short description of the file type. Examples: YouTube video, PDF, Microsoft Word, etc

func (*OnlineResource) GetEmbeddedURL

func (r *OnlineResource) GetEmbeddedURL() string

GetEmbeddedURL returns a version of the URL used for embedding the resource in an iframe. For example, the format for a YouTube URL is different depending on whether it's a clickable link or a reference to a video to play in an iframe.

func (*OnlineResource) GetEmbeddedVideo

func (r *OnlineResource) GetEmbeddedVideo(width int) template.HTML

func (*OnlineResource) GetFileName

func (r *OnlineResource) GetFileName() string

GetFileName returns the file name of the URL

func (*OnlineResource) GetIcon

func (r *OnlineResource) GetIcon() string

GetIcon returns the path to the icon for this file type. The icon is very small and is a suitable as a decorator for the link

func (*OnlineResource) GetNameFromURL

func (r *OnlineResource) GetNameFromURL() string

GetNameFromURL creates a human-readable name from the resource's URL. It does this by extracting the last field of the URL and trying to eliminate any URL encoding or markup

func (*OnlineResource) GetThumbnail

func (r *OnlineResource) GetThumbnail() string

GetThumbnail returns the path to the thumbnail to use for this file type. The thumbnail is bigger than the icon and can be use in place of the resource. For instance, the thumbnail is an image the user can click on to go to the resource (as opposed to a decorator for the link)

func (*OnlineResource) IsValid

func (r *OnlineResource) IsValid(report *util.IndentingReport) bool

type SeriesReference

type SeriesReference struct {
	// name of a series. it is a warning if this series isn't defined, but not
	// an error. however, if the series doesn't exist, then this message may not
	// be displayed
	Name string `json:"name"`
	// index within a series. same as a track on a CD. the first index in a
	// series is "1".
	//
	// index "0" means it is part of the series but hidden. this is not
	// recommended as you should use the "View" to mark a message private if it
	// shouldn't be visible in a series, but sometimes a message is in multiple
	// series, and it should be private in one and public in another
	Index int `json:"index,omitempty"`
}

SeriesReference contains information that a message stores about the series it belongs to. This information may or may not be accurate or meaningful, it is just data without meaning until an external process decides to give it meaning

func NewSeriesReferencesFromStrings

func NewSeriesReferencesFromStrings(names string, tracks string) []SeriesReference

NewSeriesReferencesFromStrings takes two strings and returns an array of series references. The input strings are semi-colon delimited and each string should have the same number of entries, like ("a; b; c", "1; 2; 1"). The number of returned references will be the number of names, and any missing track numbers will default to 0

func (*SeriesReference) IsStandAloneMessage

func (r *SeriesReference) IsStandAloneMessage() bool

Determines if this is a special case of a reference to a message that is stand-alone

type SeriesState

type SeriesState int
const (
	State_Unknown       SeriesState = 0
	State_HasNotStarted SeriesState = 1
	State_InProgress    SeriesState = 2
	State_Complete      SeriesState = 3
)

type SortSeriByName

type SortSeriByName []CatalogSeri

sort by name

func (SortSeriByName) Len

func (a SortSeriByName) Len() int

func (SortSeriByName) Less

func (a SortSeriByName) Less(i, j int) bool

func (SortSeriByName) Swap

func (a SortSeriByName) Swap(i, j int)

type SortSeriNewestToOldest

type SortSeriNewestToOldest []CatalogSeri

sort newest to oldest

func (SortSeriNewestToOldest) Len

func (a SortSeriNewestToOldest) Len() int

func (SortSeriNewestToOldest) Less

func (a SortSeriNewestToOldest) Less(i, j int) bool

func (SortSeriNewestToOldest) Swap

func (a SortSeriNewestToOldest) Swap(i, j int)

type SortSeriOldestToNewest

type SortSeriOldestToNewest []CatalogSeri

sort oldest to newest

func (SortSeriOldestToNewest) Len

func (a SortSeriOldestToNewest) Len() int

func (SortSeriOldestToNewest) Less

func (a SortSeriOldestToNewest) Less(i, j int) bool

func (SortSeriOldestToNewest) Swap

func (a SortSeriOldestToNewest) Swap(i, j int)

type View

type View string

visibility of series and messages

const (
	UnknownView View = "unknown" // undetermined view
	Raw         View = "raw"     // unedited, raw footage - assumed to be private
	Public      View = "public"  // available to anyone
	Partner     View = "partner" // available to covenant partners
	Private     View = "private" // not to be displayed online to anyone
)

func NewViewFromString

func NewViewFromString(s string) View

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL