Documentation
¶
Overview ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License ¶
antennaApp is a package for creating and curating blog, link blogs and social websites Copyright (C) 2025 R. S. Doiel
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
Index ¶
- Constants
- Variables
- func AccessHandler(next http.Handler, a *Access) http.Handler
- func CheckWaitInterval(iTime time.Time, wait time.Duration) (time.Time, bool)
- func FmtHelp(src string, appName string, version string, releaseDate string, ...) string
- func IncludeCodeBlock(text string) string
- func IncludeTextBlock(text string) string
- func InitPageGenerator(pageName string) error
- func IsDotPath(p string) bool
- func JSONMarshal(data interface{}) ([]byte, error)
- func JSONMarshalIndent(data interface{}, prefix string, indent string) ([]byte, error)
- func JSONUnmarshal(src []byte, data interface{}) error
- func LoadRedirects(fName string) (map[string]string, error)
- func ProgressETA(t0 time.Time, i int, tot int) string
- func ProgressIPS(t0 time.Time, i int, timeUnit time.Duration) string
- func RequestLogger(next http.Handler) http.Handler
- func ResponseLogger(r *http.Request, status int, err error)
- func SplitFrontMatter(src []byte) (map[string]interface{}, string, error)
- func StaticRouter(next http.Handler) http.Handler
- type Access
- func (a *Access) DumpAccess(fName string) error
- func (a *Access) GetUsername(r *http.Request) (string, error)
- func (a *Access) Handler(next http.Handler) http.Handler
- func (a *Access) Login(username string, password string) bool
- func (a *Access) RemoveAccess(username string) bool
- func (a *Access) UpdateAccess(username string, password string) bool
- type AntennaApp
- func (app *AntennaApp) Add(cfgName string, args []string) error
- func (app AntennaApp) ApplyTheme(cfgName string, args []string) error
- func (app *AntennaApp) Curate(cfgName string, args []string) error
- func (app *AntennaApp) Del(cfgName string, args []string) error
- func (app AntennaApp) Generate(out io.Writer, eout io.Writer, cfgName string, args []string) error
- func (app AntennaApp) Harvest(out io.Writer, eout io.Writer, cfgName string, args []string) error
- func (app *AntennaApp) Init(cfgName string, args []string) error
- func (app *AntennaApp) Page(cfgName string, args []string) error
- func (app *AntennaApp) Pages(cfgName string, args []string) error
- func (app *AntennaApp) Post(cfgName string, args []string) error
- func (app *AntennaApp) Posts(cfgName string, args []string) error
- func (app *AntennaApp) Preview(cfgName string) error
- func (app *AntennaApp) QuoteTextFragment(out io.Writer, cfgName string, args []string) error
- func (app *AntennaApp) RssPosts(cfgName string, args []string) error
- func (app *AntennaApp) Run(in io.Reader, out io.Writer, eout io.Writer, cfgName string, action string, ...) error
- func (app *AntennaApp) Sitemap(cfgName string, args []string) error
- func (app *AntennaApp) Unpage(cfgName string, args []string) error
- func (app *AntennaApp) Unpost(cfgName string, args []string) error
- type AppConfig
- func (cfg *AppConfig) AddCollection(cfgName string, cName string) error
- func (cfg *AppConfig) CollectionIndex(cName string) int
- func (cfg *AppConfig) DelCollection(cfgName string, cName string) error
- func (cfg *AppConfig) GetCollection(cName string) (*Collection, error)
- func (cfg *AppConfig) LoadConfig(cfgName string) error
- func (cfg *AppConfig) SaveConfig(cfgName string) error
- type CORSPolicy
- type Collection
- func (collection *Collection) ApplyFilters(db *sql.DB) error
- func (collection *Collection) Generate(out io.Writer, eout io.Writer, appName string, cfg *AppConfig) error
- func (collection *Collection) Harvest(out io.Writer, eout io.Writer, userAgent string) error
- func (col *Collection) Name() string
- func (collection *Collection) UpdateFrontMatter(frontMatter map[string]interface{}, cfg *AppConfig) error
- type CommonMark
- func (doc *CommonMark) GetAttributeBool(key string, defaultValue bool) bool
- func (doc *CommonMark) GetAttributeString(key string, defaultValue string) string
- func (doc *CommonMark) GetLinks() ([]Link, error)
- func (doc *CommonMark) GetPersons(key string, isRequired bool) ([]*gofeed.Person, error)
- func (doc *CommonMark) Parse(src []byte) error
- func (doc *CommonMark) ToHTML() (string, error)
- func (doc *CommonMark) ToUnsafeHTML() (string, error)
- type Enclosure
- type Generator
- func (gen *Generator) Generate(eout io.Writer, appName string, cfg *AppConfig, collection *Collection) error
- func (gen *Generator) LoadConfig(cfgName string) error
- func (gen *Generator) WriteCustomRSS(out io.Writer, db *sql.DB, sqlStmt string, feedLink string, appName string, ...) error
- func (gen *Generator) WriteHTML(out io.Writer, db *sql.DB, cfgName string, collection *Collection) error
- func (gen *Generator) WriteHtmlPage(htmlName string, link string, postPath, pubDate string, innerHTML string) error
- func (gen *Generator) WriteItem(out io.Writer, link string, title string, description string, ...) error
- func (gen *Generator) WriteItemRSS(out io.Writer, link string, title string, description string, ...) error
- func (gen *Generator) WriteOPML(out io.Writer, db *sql.DB, appName string, collection *Collection) error
- func (gen *Generator) WriteRSS(out io.Writer, db *sql.DB, appName string, collection *Collection) error
- type Link
- type RedirectService
- func (r *RedirectService) AddRedirectRoute(target, destination string) error
- func (r *RedirectService) HasRedirectRoutes() bool
- func (r *RedirectService) HasRoute(key string) bool
- func (r *RedirectService) RedirectRouter(next http.Handler) http.Handler
- func (r *RedirectService) Route(key string) (string, bool)
- type SafeFile
- type SafeFileSystem
- type Secrets
- type Service
- type SitemapIndex
- type TextFragment
- type URL
- type URLSet
- type WebService
Constants ¶
const ( // Version number of release Version = "0.0.20" // ReleaseDate, the date version.go was generated ReleaseDate = "2025-12-24" // ReleaseHash, the Git hash when version.go was generated ReleaseHash = "13763d0" LicenseText = `` /* 34525-byte string literal not displayed */ )
Variables ¶
var ( HelpText = `` /* 10598-byte string literal not displayed */ ThemeHelpText = `` /* 4766-byte string literal not displayed */ )
var ( DefaultPageCollectionMarkdown = `` /* 140-byte string literal not displayed */ DefaultGeneratorYaml = `` /* 830-byte string literal not displayed */ )
var ( // SQLCreateTables provides the statements that are use to create our tables // It has two percent s, first is feed list name, second is datetime scheme // was generated. // // See <https://source.scripting.com> when I am ready to support more the // source namespace. SQLCreateTables = `` /* 774-byte string literal not displayed */ // SQLResetChannels clear the channels table SQLResetChannels = `DELETE FROM channels;` // Update the channels table SQLUpdateChannel = `` /* 221-byte string literal not displayed */ // Display the channels in the table SQLDisplayChannels = `` /* 186-byte string literal not displayed */ // Update a feed item in the items table SQLUpdateItem = `` /* 457-byte string literal not displayed */ // SQLItemCount returns a list of items in the items table SQLItemCount = `SELECT COUNT(*) FROM items;` // SQLDisplayItems returns a list of items in decending chronological order. SQLDisplayItems = `` /* 285-byte string literal not displayed */ // SQLRssPosts generate an RSS feed for all posts SQLRssPosts = `` /* 279-byte string literal not displayed */ // SQLRssRecentPosts generate an RSS feed for recent posts SQLRssRecentPosts = `` /* 288-byte string literal not displayed */ // SQLRssDateRangePosts generate an RSS feed for recent posts SQLRssDateRangePosts = `` /* 306-byte string literal not displayed */ // SQLListPosts will list all published posts with a postPath by their descending pubDate SQLListPosts = `` /* 147-byte string literal not displayed */ // SQLListRecentPosts will list recent published posts with a postPath by their descending pubDate SQLListRecentPosts = `` /* 155-byte string literal not displayed */ // SQLListDateRangePosts will list all published posts with a postPath by their descending pubDate SQLListDateRangePosts = `` /* 168-byte string literal not displayed */ // SQLSetStatusToReview SQLUpdateStatusToReview = `UPDATE items SET status = 'review';` // SQLSetStatusPublishedForRecentlyPublished will the will set status to "published" where // Items have a published date greater than or equal to the date provided. SQLSetStatusPublishedForRecentlyPublished = `UPDATE items SET status = 'published' WHERE pubDate >= date('now', '-21 days');` // SQLDeleteItemByLinkOrPostPath removes an item in the items table with provided link SQLDeleteItemByLinkOrPostPath = `DELETE FROM items WHERE link = ? OR postPath = ?` // SQLSetItemStatus is used when curating items in collections SQLSetItemStatus = `UPDATE items SET status = ? WHERE link = ?` // Update a feed item in the items table SQLUpdatePage = `` /* 151-byte string literal not displayed */ // SQLCountPage returns a list of items in the items table SQLCountPage = `SELECT COUNT(*) FROM pages;` // SQLDisplayPage returns a list of pages in the pages table SQLDisplayPage = `SELECT inputPath, outputPath, updated FROM pages ORDER BY updated desc ;` // SQLSitemapListPages returns a list of pages by outputPath SQLSitemapListPages = `SELECT outputPath, updated FROM pages ORDER BY outputPath ;` // SQLListPosts will list all posts by post path SQLSitemapListPosts = `` /* 215-byte string literal not displayed */ // SQLDeletePageByPath removes a page by either input or output paths. SQLDeletePageByPath = `DELETE FROM pages WHERE inputPath = ?1 or outputPath = ?2 ;` // SQLListRecentItems will list recent Itemsby their descending pubDate SQLListRecentItems = `` /* 142-byte string literal not displayed */ // SQLListDateRangeItems will list items in date range by their descending pubDate SQLListDateRangeItems = `` /* 180-byte string literal not displayed */ // SQLListItems will list all items by their descending pubDate SQLListItems = `` /* 134-byte string literal not displayed */ // SQLViewItem returns a single item SQLViewItem = `` /* 127-byte string literal not displayed */ )
Functions ¶
func AccessHandler ¶
AccessHandler is a wrapping handler that checks if Access.Routes matches the req.URL.Path and if so applies access contraints. If *Access is nil then it just passes through to the next handler.
func CheckWaitInterval ¶
CheckWaitInterval checks to see if an interval of time has been met or exceeded. It returns the remaining time interval (possibly reset) and a boolean. The boolean is true when the time interval has been met or exceeded, false otherwise.
``` tot := len(something) // calculate the total number of items to process t0 := time.Now() iTime := time.Now() reportProgress := false
for i, key := range records {
// ... process stuff ...
if iTime, reportProgress = checkWaitInterval(rptTime, (30 * time.Second)); reportProgress {
log.Printf("%s", ProgressETA(t0, i, tot))
}
}
```
func FmtHelp ¶
func FmtHelp(src string, appName string, version string, releaseDate string, releaseHash string) string
FmtHelp lets you process a text block with simple curly brace markup.
func IncludeCodeBlock ¶ added in v0.0.15
IncludeCodeBlock takes a text string and replaces the code blocks based on the file path included in the line and the language name. The generated code block uses the `~~~` sequence to delimit the block with the language name provided in the opening delimiter.
Parameters:
text (string): the text to be transformed
Returns:
string: the transformed text
func IncludeTextBlock ¶ added in v0.0.15
IncludeTextBlock takes a text string and replaces the text blocks based on the file path included in the line.
Parameters:
text (string): the text to be transformed
Returns:
string: the transformed text
func InitPageGenerator ¶ added in v0.0.8
InitPageGenerator initializes a YAML configuration for the default page layout. It takes a filename and returns an error
func IsDotPath ¶
IsDotPath checks to see if a path is requested with a dot file (e.g. docs/.git/* or docs/.htaccess)
func JSONMarshal ¶
JSONMarshal provides provide a custom json encoder to solve a an issue with HTML entities getting converted to UTF-8 code points by json.Marshal(), json.MarshalIndent().
func JSONMarshalIndent ¶
JSONMarshalIndent provides provide a custom json encoder to solve a an issue with HTML entities getting converted to UTF-8 code points by json.Marshal(), json.MarshalIndent().
func JSONUnmarshal ¶
JSONUnmarshal is a custom JSON decoder so we can treat numbers easier
func LoadRedirects ¶
LoadRedirects reads a CSV file of redirects and returns a map[string]string of from/to static rediects.
func ProgressETA ¶
ProgressETA returns a string with the percentage processed and estimated time remaining. It requires the a counter of records processed, the total count of records and a time zero value.
``` tot := len(something) // calculate the total number of items to process t0 := time.Now() iTime := time.Now() reportProgress := false
for i, key := range records {
// ... process stuff ...
if iTime, reportProgress = CheckWaitInterval(rptTime, (30 * time.Second)); reportProgress {
log.Printf("%s", ProgressETA(t0, i, tot))
}
}
```
func ProgressIPS ¶
ProgressIPS returns a string with the elapsed time and increments per second. Takes a time zero, a counter and time unit. Returns a string with count, running time and increments per time unit. ``` t0 := time.Now() iTime := time.Now() reportProgress := false
for i, key := range records {
// ... process stuff ...
if iTime, reportProgress = CheckWaitInterval(rptTime, (30 * time.Second)); reportProgress || i = 0 {
log.Printf("%s", ProgressIPS(t0, i, time.Second))
}
}
```
func RequestLogger ¶
RequestLogger logs the request based on the request object passed into it.
func ResponseLogger ¶
ResponseLogger logs the response based on a request, status and error message
func SplitFrontMatter ¶
SplitFrontMatter splits a CommonMark document into FrontMatter and the rest of the content. It uses bufio.ScanLines to find the "---" delimiters.
Types ¶
type Access ¶
type Access struct {
// AuthType (e.g. Basic)
AuthType string `json:"auth_type" yaml:"auth_type"`
// AuthName (e.g. string describing authorization, e.g. realm in basic auth)
AuthName string `json:"auth_name" yaml:"auth_name"`
// Encryption is a string describing the encryption used
// e.g. argon2id, pbkds2, md5 or sha512
Encryption string `json:"encryption" yaml:"encryption"`
// Map holds a user to secret map. It is usually populated
// after reading in the users file with LoadAccessYAML() or
// LoadAccessJSON().
Map map[string]*Secrets `json:"access" yaml:"access"`
// Routes is a list of URL path prefixes covered by
// this Access control object.
Routes []string `json:"routes" yaml:"routes"`
}
Access holds the necessary configuration for doing basic auth authentication. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication using Go's http.Request object.
func LoadAccess ¶
LoadAccess loads a YAML or JSON access file.
func (*Access) DumpAccess ¶
DumpAccess writes a access file.
func (*Access) GetUsername ¶
GetUsername takes an Request object, inspects the headers and returns the username if possible, otherwise an error.
func (*Access) Handler ¶
Handler takes a handler and returns handler. If *Access is null it pass thru unchanged. Otherwise it applies the access policy.
func (*Access) Login ¶
Login accepts username, password and ok boolean. Returns true if they match auth's settings false otherwise.
How to choosing an appropriate hash method see ¶
https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
md5 and sha512 are included for historic reasons They are NOT considered secure anymore as they are breakable with brute force using today's CPU/GPUs.
func (*Access) RemoveAccess ¶
RemoveAccess takes an *Access and username and deletes the username from .Map returns true if delete applied, false if user not found in map
type AntennaApp ¶
type AntennaApp struct {
// contains filtered or unexported fields
}
func NewAntennaApp ¶
func NewAntennaApp(appName string) *AntennaApp
func (AntennaApp) ApplyTheme ¶ added in v0.0.11
func (app AntennaApp) ApplyTheme(cfgName string, args []string) error
ApplyTheme takes a theme directory and an optional generator YAML filename and applies the theme to that generator YAML name saving the result.
func (*AntennaApp) Curate ¶ added in v0.0.20
func (app *AntennaApp) Curate(cfgName string, args []string) error
Curate provides a simple terminal interface to curating collections and feed items for publication in your Antenna site.
func (*AntennaApp) Del ¶
func (app *AntennaApp) Del(cfgName string, args []string) error
Del removes one or more collections from your Antenna instance. NOTE: It does not remove generated files, e.g. SQLite3 database, YAML, HTML or RSS files.
func (*AntennaApp) Page ¶ added in v0.0.7
func (app *AntennaApp) Page(cfgName string, args []string) error
Page will add a CommonMark document as an HTML page based on postPath. It **will not** get added to an RSS feed or to the collection's db. It is designed to relieve the requirement of using Pandoc for a handful of page.
func (*AntennaApp) Pages ¶ added in v0.0.16
func (app *AntennaApp) Pages(cfgName string, args []string) error
Pages will list the pages in the pages collection
func (*AntennaApp) Post ¶
func (app *AntennaApp) Post(cfgName string, args []string) error
Post will add a CommonMark document as a feed item and if the postPath and link are provided it will convert the CommonMark document to HTML and save it in the postPath.
func (*AntennaApp) Posts ¶ added in v0.0.18
func (app *AntennaApp) Posts(cfgName string, args []string) error
func (*AntennaApp) Preview ¶
func (app *AntennaApp) Preview(cfgName string) error
Preview runs a webserver that will preview the AntennaApp instance's htdocs on the port specified in the config.
func (*AntennaApp) QuoteTextFragment ¶ added in v0.0.19
QuoteTextFragment takes a text fragment URL and writes a Markdown text from it to standard output.
func (*AntennaApp) RssPosts ¶ added in v0.0.19
func (app *AntennaApp) RssPosts(cfgName string, args []string) error
RssPosts, gernate RSS to stdout for posts
func (*AntennaApp) Run ¶
func (app *AntennaApp) Run(in io.Reader, out io.Writer, eout io.Writer, cfgName string, action string, args []string) error
Run implements the command line functionality of the Antenna App.
func (*AntennaApp) Sitemap ¶ added in v0.0.16
func (app *AntennaApp) Sitemap(cfgName string, args []string) error
Sitemap implements the antenna sitemap action.
type AppConfig ¶
type AppConfig struct {
// Port holds the port number the preview web service will run on
Port int `json:"port,omitempty" yaml:"port,omitempty"`
// Host holds the IP address or machine name the preview service
// will listen on. By default is is "localhost"
Host string `json:"host,omitempty" yaml:"host,omitempty"`
// Htdocs holds the path to directory that will recieve the generated content
// It is also the directory used in the "preview" the static website.
Htdocs string `json:"htdocs,omitempty" yaml:"htdocs,omitempty"`
// UserAgent this holds a custom user agent string
UserAgent string `json:"userAgent,omitempty" yaml:"userAgent,omitempty"`
// BaseURL for the Antenna instance
BaseURL string `json:"base_url,omitempty" yaml:"base_url,omitempty"`
// Generator holds a YAML file that describes the HTML page structure.
// This holds the default page generator description. Each collection can
// use a custom one or the default one.
Generator string `json:"generator,omitempty" yaml:"generator,omitempty"`
// Collections holds a list of collections to curate
Collections []*Collection `json:"collections,omitempty" yaml:"collections,omitempty"`
// Sitemap settings, these should get sane defaults in the sitemap action
ChunkSize int
DefaultFreq string
DefaultPri string
FreqRules map[string]string // outputPath prefix -> changefreq
PriRules map[string]string // outputPath prefix -> priority
}
AntennaApp configuration structure
func (*AppConfig) AddCollection ¶ added in v0.0.20
AddCollection adds and saves a new collection to AppConfig
func (*AppConfig) CollectionIndex ¶
func (*AppConfig) DelCollection ¶ added in v0.0.20
DelCollection removes a collection from the configuration, saving it.
func (*AppConfig) GetCollection ¶
func (cfg *AppConfig) GetCollection(cName string) (*Collection, error)
func (*AppConfig) LoadConfig ¶
LoadConfig process the AntennaApp YAML file and sets the attributes of the AntennaApp structure.
func (*AppConfig) SaveConfig ¶
SaveConfig save the current configuration of the AntennaApp
type CORSPolicy ¶
type CORSPolicy struct {
// Origin usually would be set the hostname of the service.
Origin string `json:"origin,omitempty" yaml:"origin,omitempty"`
// Options to include in the policy (e.g. GET, POST)
Options []string `json:"options,omitempty" yaml:"options,omitempty"`
// Headers to include in the policy
Headers []string `json:"headers,omitempty" yaml:"headers,omitempty"`
// ExposedHeaders to include in the policy
ExposedHeaders []string `json:"exposed_headers,omitempty" yaml:"exposed_headers,omitempty"`
// AllowCredentials header handling in the policy either true or not set
AllowCredentials bool `json:"allow_credentials,omitempty" yaml:"allow_credentials,omitempty"`
}
CORSPolicy defines the policy elements for our CORS settings.
func (*CORSPolicy) Handler ¶
func (cors *CORSPolicy) Handler(next http.Handler) http.Handler
Handler accepts an http.Handler and returns a http.Handler. It Wraps the response with the CORS headers based on configuration in CORSPolicy struct. If cors is nil then it passes thru to next http.Handler unaltered.
type Collection ¶
type Collection struct {
// Title of the collection
Title string `json:"title,omitempty" yaml:"title,omitempty"`
// Links holds the Link element used in the published RSS 2.0 output.
Link string `json:"link,omitempty" yaml:"link,omitempty"`
// Description holds the description of the collection
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// The language the collect is written in
Language string `json:"language,omitempty" yaml:"language,omitempty"`
// Copyright notice for content in the collection
Copyright string `json:"copyright,omitempty" yaml:"copyright,omitempty"`
// ManagingEditor holds an Email address for person responsible for editorial content
// of the collection.
ManagingEditor string `json:"managingEditor,omitempty" yaml:"managingEditor,omitempty"`
// WebMaster holds an Email address for person responsible for technical issues relating to collection
WebMaster string `json:"webMaster,omitempty" yaml:"webMaster,omitempty"`
// PubDate holds the publication date for the content in the collection
PubDate string `json:"pubDate,omitempty" yaml:"pubDate,omitempty"`
// TTL is the time to live, the number of seconds to wait before trying a refresh
TTL int `json:"ttl,omitempty" yaml:"ttl,omitempty"`
// File holds the filepath to the Markdown document used to
// define the collection.
File string `json:"file,omitempty" yaml:"file,omitempty"`
// Generator points to the YAML file to use when generating
// a collection's HTML page.
Generator string `json:"generator,omitempty" yaml:"generator,omitempty"`
// Filters holds custom SQL that will be run against the Source to
// determine which items to include and had off to the Generator.
Filters []string `json:"filters,omitempty" yaml:"filters,omitempty"`
// DbName holds the SQLite3 database filename
DbName string `json:"dbName,omitempty" yaml:"dbName,omitempty"`
}
Collection describes the metadata about a collection of feeds. A collection can also be used to generate an RSS 2.0 feed of items harvested and related to the collection forming an aggregated item view of the collection of feeds.
Some of the fields from the RSS 2.0 Channel can be set from the Markdown document's front matter.
See https://cyber.harvard.edu/rss/rss.html#optionalChannelElements
func (*Collection) ApplyFilters ¶
func (collection *Collection) ApplyFilters(db *sql.DB) error
func (*Collection) Name ¶ added in v0.0.20
func (col *Collection) Name() string
Name returns the collection basename used for the collection
func (*Collection) UpdateFrontMatter ¶
func (collection *Collection) UpdateFrontMatter(frontMatter map[string]interface{}, cfg *AppConfig) error
type CommonMark ¶
type CommonMark struct {
// FrontMatter holds the object of the parsed FrontMatter if available
// in the document.
FrontMatter map[string]interface{} `json:"frontMatter,omitempty" yaml:"frontMatter,omitempty"`
// Text holds the CommonMark text that comes after any front matter
Text string `json:"text,omitempty" yaml:"text,omitempty"`
}
CommonMark holds the structure of front matter and the CommonMark text.
func (*CommonMark) GetAttributeBool ¶
func (doc *CommonMark) GetAttributeBool(key string, defaultValue bool) bool
GetAttributeBool returns a boolean attribute from the front matter the document
func (*CommonMark) GetAttributeString ¶
func (doc *CommonMark) GetAttributeString(key string, defaultValue string) string
GetAttributeString returns a string attribute from the front matter the document
func (*CommonMark) GetLinks ¶
func (doc *CommonMark) GetLinks() ([]Link, error)
GetLinks process the Text of a CommonMark struct and returns a list of Link objects if found.
func (*CommonMark) GetPersons ¶ added in v0.0.2
GetPersons returns a list of `*gofeed.Person{}` from the front matter in the document document
func (*CommonMark) Parse ¶
func (doc *CommonMark) Parse(src []byte) error
Parse will read a byte slice and populate any FrontMatter found and set the remaining text as the Text element of CommonMark structure.
func (*CommonMark) ToHTML ¶
func (doc *CommonMark) ToHTML() (string, error)
func (*CommonMark) ToUnsafeHTML ¶ added in v0.0.10
func (doc *CommonMark) ToUnsafeHTML() (string, error)
type Enclosure ¶
type Enclosure struct {
Url string `json:"url,omitempty" yaml:"url,omitempty"`
Length string `json:"length,omitempty" yaml:"length,omitempty"`
Type string `json:"type,omitempty" yaml:"type,omitempty"`
}
Enclosure holds the data for RSS enclusure support
type Generator ¶
type Generator struct {
// AppName holds the name of application running the generator
AppName string `json:"appName,omitempty" yaml:"appName,omitempty"`
// BaseURL used to form the feed Link
BaseURL string `json:"base_url,omitempty" yaml:"base_url,omitempty"`
// Version holds the version of the generator application
// used when generating the "generator" metadata
Version string `json:"version,omitempty" yaml:"version,omitempty"`
// DbName holds the path to the SQLite3 database
DBName string `json:"dbName,omitempty" yaml:"dbName,omitempty"`
// Title if this is set the title will be included
// when generating the markdown of saved items
Title string `json:"title,omitempty" yaml:"title,omitempty"`
// Description, included as metadata in head element
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// CMarkFilters are Lua filters applied to the CommonMark document when
// rendering HTML.
CMarkFilters []string `json:"cm_filters,omitempty" yaml:"cm_filters,omitempty"`
// Meta holds a list of of meta elements rendered into the head element of HTML pages
Meta []map[string]string `json:"meta,omitempty" yaml:"meta,omitempty"`
// Link holds the list of links elements rendered into the head element of HTML pages
Link []map[string]string `json:"link,omitempty" yaml:"link,omitempty"`
// Script holds a list of script elements rendered into the head element of HTML pages
Script []map[string]string `json:"script,omitempty" yaml:"script,omitempty"`
// Style holds an explicit Style blog that gets inserted as the last into the HTML head element
Style string `json:"style:omitempty" yaml:"style,omitempty"`
// Header hold the HTML markdup of the Header element. If not included
// then it will be generated using the Title and timestamp
Header string `json:"header,omitempty" yaml:"header,omitempty"`
Nav string `json:"nav,omitempty" yaml:"nav,omitempty"`
// TopContent holds HTML that comes before the selecton element
// containing articles
TopContent string `json:"top_content,omitempty" yaml:"top_content,omitempty"`
// BottomContent holds HTML that comes before the selecton element
// containing articles
BottomContent string `json:"bottom_content,omitempty" yaml:"bottom_content,omitempty"`
Footer string `json:"footer,omitempty" yaml:"footer,omitempty"`
// contains filtered or unexported fields
}
Generator supports the generation of HTML pages from a YAML configuration
func NewGenerator ¶
NewGenerator initialized a new Generator struct
func (*Generator) LoadConfig ¶
LoadConfig read in the generator configuration (not AppConfig) and map the settings into the Generator object.
func (*Generator) WriteCustomRSS ¶ added in v0.0.19
func (gen *Generator) WriteCustomRSS(out io.Writer, db *sql.DB, sqlStmt string, feedLink string, appName string, collection *Collection) error
WriteCustomRSS generates a custom RSS feed given a SQL statement
func (*Generator) WriteHTML ¶
func (gen *Generator) WriteHTML(out io.Writer, db *sql.DB, cfgName string, collection *Collection) error
WriteHTML writes aggregated items into an HTML page from the contents of the database
func (*Generator) WriteHtmlPage ¶
func (gen *Generator) WriteHtmlPage(htmlName string, link string, postPath, pubDate string, innerHTML string) error
WriteHtmlPage renders a post as an HTML Page using HTML connent and wrapping it based on the generator configuration.
func (*Generator) WriteItem ¶
func (gen *Generator) WriteItem(out io.Writer, link string, title string, description string, authors []*gofeed.Person, sourceMarkdown string, enclosures []*Enclosure, guid string, pubDate string, dcExt string, channel string, status string, updated string, label string) error
Write HTML for an item
func (*Generator) WriteItemRSS ¶
type Link ¶
type Link struct {
// Label holds the text label that will be used when displaying the feed
Label string `json:"label,omitempty" yaml:"label,omitempty"`
// The URL holds the link text to the feed
URL string `json:"url,omitempty" yaml:"url,omitempty"`
// The optional description holds any description text associated with the link
Description string `json:"description,omitempty" yaml:"description,omitempty"`
}
Link represents a Markdown link with Label, URL, and optional Description.
func ParseMarkdownLinks ¶
ParseMarkdownLinks parses a Markdown text for links in the format `- [LABEL](URL "DESCRIPTION")` and returns a slice of Link structures.
type RedirectService ¶
type RedirectService struct {
// contains filtered or unexported fields
}
RedirectService holds our redirect targets in an ordered list and a map to our applied routes.
func MakeRedirectService ¶
func MakeRedirectService(m map[string]string) (*RedirectService, error)
MakeRedirectService takes a m[string]string of redirects and loads it into our service's private routes attribute. It returns a new *RedirectService and error
func (*RedirectService) AddRedirectRoute ¶
func (r *RedirectService) AddRedirectRoute(target, destination string) error
AddRedirectRoute takes a target and a destination prefix and populates the internal datastructures to handle the redirecting target prefix to the destination prefix.
func (*RedirectService) HasRedirectRoutes ¶
func (r *RedirectService) HasRedirectRoutes() bool
HasRedirectRoutes returns true if redirects have been defined, false if not.
func (*RedirectService) HasRoute ¶
func (r *RedirectService) HasRoute(key string) bool
HasRoute returns true if the target route is defined
func (*RedirectService) RedirectRouter ¶
func (r *RedirectService) RedirectRouter(next http.Handler) http.Handler
RedirectRouter handles redirect requests before passing on to the handler.
type SafeFileSystem ¶
type SafeFileSystem struct {
http.FileSystem
}
SafeFileSystem is used to hide dot file paths from our web services.
func MakeSafeFileSystem ¶
func MakeSafeFileSystem(docRoot string) (SafeFileSystem, error)
MakeSafeFileSystem without a *WebService takes a doc root and returns a SafeFileSystem struct.
Example usage:
fs, err := MakeSafeFileSystem("/var/www/htdocs")
if err != nil {
log.Fatalf("%s\n", err)
}
http.Handle("/", http.FileServer(fs)) log.Fatal(http.ListenAndService(":8000", nil))
type Secrets ¶
type Secrets struct {
// NOTE: salt is needed by Argon2 and pbkdb2.
// If the yaml/json file functions as the database then
// this file MUST be kept safe with restricted permissions.
// If not you just gave away your system a cracker.
Salt []byte `json:"salt,omitempty" yaml:"salt,omitempty"`
// Key holds the salted hash ...
Key []byte `json:"key,omitempty" yaml:"key,omitempty"`
}
type Service ¶
type Service struct {
// Scheme holds the protocol to use, defaults to http if not set.
Scheme string `json:"scheme,omitempty" yaml:"scheme,omitempty"`
// Host is the hostname to use, if empty "localhost" is assumed"
Host string `json:"host,omitempty" yaml:"host,omitempty"`
// Port is a string holding the port number to listen on
// An empty strings defaults port to 8000
Port string `json:"port,omitempty" yaml:"port,omitempty"`
// CertPEM describes the location of cert.pem used for TLS support
CertPEM string `json:"cert_pem,omitempty" yaml:"cert_pem,omitempty"`
// KeyPEM describes the location of the key.pem used for TLS support
KeyPEM string `json:"key_pem,omitempty" yaml:"key_pem,omitempty"`
}
Service holds the description needed to startup a service e.g. https, http.
func NewService ¶
NewService is http, port 8000 on localhost.
type SitemapIndex ¶ added in v0.0.16
type SitemapIndex struct {
XMLName xml.Name `xml:"sitemapindex"`
Xmlns string `xml:"xmlns,attr"`
Sitemaps []struct {
Loc string `xml:"loc"`
} `xml:"sitemap"`
}
SitemapIndex represents the root of the sitemap index XML.
type TextFragment ¶ added in v0.0.17
type TextFragment struct {
Text string `json:"text,omitempty" yaml:"text,omitempty" xml:"text,omitempty"`
Link string `json:"link,omitempty" yaml:"link,omitempty" yaml:"text,omitempty"`
Host string `json:"host,omitempty" yaml:"host,omitempty" xml:"host,omitempty"`
Created time.Time `json:"created,omitemtpy" yaml:"created,omitempty" xml:"created,omitempt"`
}
TextFragment holds the elements of a text fragment link along with useful metadata like time the link was created.
func ParseTextFragmentURL ¶ added in v0.0.17
func ParseTextFragmentURL(s string) (*TextFragment, error)
ParseTextFragmentURL takes a text fragment expressed as a URL and returns a TextFragment struct and error
func (*TextFragment) String ¶ added in v0.0.17
func (tf *TextFragment) String() string
String renders the text fragment as a
type URL ¶ added in v0.0.16
type URL struct {
Loc string `xml:"loc"`
LastMod string `xml:"lastmod"`
ChangeFreq string `xml:"changefreq,omitempty"`
Priority string `xml:"priority,omitempty"`
}
URL represents a single URL entry in the sitemap.
type URLSet ¶ added in v0.0.16
type URLSet struct {
XMLName xml.Name `xml:"urlset"`
Xmlns string `xml:"xmlns,attr"`
URLs []URL `xml:"url"`
}
URLSet represents the root of the sitemap XML.
type WebService ¶
type WebService struct {
// This is the document root for static file services
// If an empty string then assume current working directory.
DocRoot string `json:"htdocs" yaml:"htdocs"`
// Https describes an Https service
Https *Service `json:"https,omitempty" yaml:"https,omitempty"`
// Http describes an Http service
Http *Service `json:"http,omitempty" yaml:"http,omitempty"`
// AccessFile holds a name of an access file to load and
// populate .Access from.
AccessFile string `json:"access_file,omitempty" yaml:"access_file,omitempty"`
// Access adds access related features to the service.
// E.g. BasicAUTH support.
Access *Access `json:"access,omitempty" yaml:"access,omitempty"`
// CORS describes the CORS policy for the web services
CORS *CORSPolicy `json:"cors,omitempty" yaml:"cors,omitempty"`
// ContentTypes describes a file extension mapped to a single
// MimeType.
ContentTypes map[string]string `json:"content_types,omitempty" yaml:"content_types,omitempty"`
// RedirectsCSV is the filename/path to a CSV file describing
// redirects.
RedirectsCSV string `json:"redirects_csv,omitempty" yaml:"redirects_csv,omitempty"`
// Redirects describes a target path to destination path.
// Normally this is populated by a redirects.csv file.
Redirects map[string]string `json:"redirects,omitempty" yaml:"redirects,omitempty"`
// ReverseProxy descibes the path web paths that are sent
// to another proxied URL.
ReverseProxy map[string]string `json:"reverse_proxy,omitempty" yaml:"reverse_proxy,omitempty"`
}
WebService describes all the configuration and capabilities of running a wsfn based web service.
func LoadWebService ¶
func LoadWebService(setup string) (*WebService, error)
LoadWebService loads a configuration file of *WebService
func NewWebService ¶
func NewWebService(htdocs string, scheme string, host string, port string) *WebService
NewWebService setups to listen for http://localhost:8000 with the htdocs of the current working directory.
func (*WebService) DumpWebService ¶
func (ws *WebService) DumpWebService(fName string) error
DumpWebService writes a access file.
func (*WebService) Run ¶
func (w *WebService) Run() error
Run() starts a web service(s) described in the *WebService struct.
func (*WebService) SafeFileSystem ¶
func (w *WebService) SafeFileSystem() (SafeFileSystem, error)
/ SafeFileSystem returns a new safe file system using the *WebService.DocRoot as the directory source.
Example usage:
ws := antennaApp.LoadYAML("antenna.yaml") fs, err := ws.SafeFileSystem()
if err != nil {
log.Fatalf("%s\n", err)
}
http.Handle("/", http.FileServer(ws.SafeFileSystem())) log.Fatal(http.ListenAndService(ws.Http.Hostname(), nil))