Documentation
¶
Index ¶
- Variables
- func IsVisibleInView(visibility View, view View) bool
- func NewJSONFileFromCatalog(jsonFile string, catalog *Catalog) error
- type Catalog
- func (c *Catalog) FindMessagesInSeries(seriesName string) []CatalogMessage
- func (c *Catalog) FindSeriByName(seriesName string) (seri *CatalogSeri, ok bool)
- func (c *Catalog) FindSeriesByMinistry(ministries ...Ministry) []CatalogSeri
- func (c *Catalog) Initialize() error
- func (c *Catalog) IsMessageSeriesIndexValid(report *util.IndentingReport) bool
- func (c *Catalog) IsMessageSeriesValid(report *util.IndentingReport) bool
- func (c *Catalog) IsSeriesNamesValid(report *util.IndentingReport) bool
- func (c *Catalog) IsValid(reportLoud bool) bool
- type CatalogMessage
- func (m *CatalogMessage) Copy() CatalogMessage
- func (m *CatalogMessage) DateString() string
- func (m *CatalogMessage) FindSeriesReference(seriesName string) *SeriesReference
- func (m *CatalogMessage) GetAudioSize() int
- func (m *CatalogMessage) GetTranscriptURL(ext string) string
- func (m *CatalogMessage) HasAudio() bool
- func (m *CatalogMessage) HasTranscript() bool
- func (m *CatalogMessage) HasVideo() bool
- func (m *CatalogMessage) Initialize() error
- func (m *CatalogMessage) IsInSeries(seriesName string) bool
- func (m *CatalogMessage) IsValid(report *util.IndentingReport) bool
- func (m *CatalogMessage) LoadTranscriptCacheForYear(year int) []string
- func (m *CatalogMessage) SpeakerString() string
- type CatalogSeri
- func (s *CatalogSeri) AddResourceToSeries(resource OnlineResource)
- func (s *CatalogSeri) AddSpeakerToSeries(speaker string)
- func (s *CatalogSeri) ComputeState()
- func (s *CatalogSeri) Copy() CatalogSeri
- func (s *CatalogSeri) DateString() string
- func (s *CatalogSeri) GetCatalogFileName(view View) string
- func (s *CatalogSeri) GetID() string
- func (s *CatalogSeri) GetMinistry() Ministry
- func (s *CatalogSeri) GetViewID(view View) string
- func (s *CatalogSeri) Initialize() error
- func (s *CatalogSeri) IsBooklet() bool
- func (s *CatalogSeri) IsMessageRelevant(msg *CatalogMessage) bool
- func (s *CatalogSeri) IsValid(report *util.IndentingReport) bool
- func (s *CatalogSeri) MessageTitlesString() string
- func (s *CatalogSeri) Normalize()
- func (s *CatalogSeri) SpeakerString() string
- type DateOnly
- type MessageType
- type Ministry
- type OnlineResource
- func (r *OnlineResource) GetClassifier() string
- func (r *OnlineResource) GetEmbeddedURL() string
- func (r *OnlineResource) GetEmbeddedVideo(width int) template.HTML
- func (r *OnlineResource) GetFileName() string
- func (r *OnlineResource) GetIcon() string
- func (r *OnlineResource) GetNameFromURL() string
- func (r *OnlineResource) GetThumbnail() string
- func (r *OnlineResource) IsValid(report *util.IndentingReport) bool
- type SeriesReference
- type SeriesState
- type SortSeriByName
- type SortSeriNewestToOldest
- type SortSeriOldestToNewest
- type View
Constants ¶
This section is empty.
Variables ¶
Functions ¶
func IsVisibleInView ¶
IsVisibleInView determines if the specified visibility should be visible at a specific view level
func NewJSONFileFromCatalog ¶
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 ¶
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 ¶
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 ¶
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 ¶
func MustParseDateOnly ¶
func NewDateOnly ¶
func NewDateToday ¶
func NewDateToday() DateOnly
func ParseDateOnly ¶
func (DateOnly) MarshalJSON ¶
func (*DateOnly) UnmarshalJSON ¶
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 (Ministry) Description ¶
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)