srnd

package
v3.1.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Jan 28, 2019 License: MIT Imports: 59 Imported by: 0

Documentation

Overview

daemon.go

database.go

expiration.go content expiration

frontend.go srnd frontend interfaces

frontend_http.go

srnd http frontend implementation

markup.go memeposting markup parser

message.go

mod.go post moderation

model.go template model interfaces

model_mem.go

models held in memory

nntp.go -- nntp interface for peering

policy.go

postgres db backend

templates.go template model interfaces

templates.go template model interfaces

templates.go template model interfaces

tools.go -- srndv2 cli tool functions

Index

Constants

View Source
const ArticleBanned = "ArticleBanned"
View Source
const BumpLimit = 300
View Source
const CheckEncIPBanned = "CheckEncIPBanned"
View Source
const CheckNNTPLogin = "CheckNNTPLogin"
View Source
const CheckNNTPUserExists = "CheckNNTPUserExists"
View Source
const CountAllArticlesInGroup = "CountAllArticlesInGroup"
View Source
const CountUkko = "CountUkko"
View Source
const DefaultMaxMessageSize = 1024 * 1024 * 10

~ 10 MB unbased64'd

View Source
const DeleteArticleV8 = "DeleteArticleV8"
View Source
const DeleteArticle_1 = "DeleteArticle_1"
View Source
const DeleteArticle_2 = "DeleteArticle_2"
View Source
const DeleteArticle_3 = "DeleteArticle_3"
View Source
const DeleteArticle_4 = "DeleteArticle_4"
View Source
const DeleteArticle_5 = "DeleteArticle_5"
View Source
const DeleteThread = "DeleteThread"
View Source
const DeleteThreadV8 = "DeleteThreadV8"
View Source
const GetAllArticles = "GetAllArticles"
View Source
const GetAllArticlesInGroup = "GetAllArticlesInGroup"
View Source
const GetAllNewsgroups = "GetAllNewsgroups"
View Source
const GetArticlePubkey = "GetArticlePubkey"
View Source
const GetCitesByPostHashLike = "GetCitesByPostHashLike"
View Source
const GetFirstAndLastForGroup = "GetFirstAndLastForGroup"
View Source
const GetGroupThreads = "GetGroupThreads"
View Source
const GetHeadersForMessage = "GetHeadersForMessage"
View Source
const GetLastBumpedThreadsPaginated_1 = "GetLastBumpedThreadsPaginated_1"
View Source
const GetLastBumpedThreadsPaginated_2 = "GetLastBumpedThreadsPaginated_2"
View Source
const GetLastDaysPosts = "GetLastDaysPosts"
View Source
const GetLastDaysPostsForGroup = "GetLastDaysPostsForGroup"
View Source
const GetLastPostedPostModels = "GetLastPostedPostModels"
View Source
const GetMessageIDByCIDR = "GetMessageIDByCIDR"
View Source
const GetMessageIDByEncryptedIP = "GetMessageIDByEncryptedIP"
View Source
const GetMessageIDByHash = "GetMessageIDByHash"
View Source
const GetMessageIDByHeader = "GetMessageIDByHeader"
View Source
const GetMessageIDForNNTPID = "GetMessageIDForNNTPID"
View Source
const GetMonthlyPostHistory = "GetMonthlyPostHistory"
View Source
const GetNNTPIDForMessageID = "GetNNTPIDForMessageID"
View Source
const GetNNTPPostsInGroup = "GetNNTPPostsInGroup"
View Source
const GetNewsgroupList = "GetNewsgroupList"
View Source
const GetNewsgroupStats = "GetNewsgroupStats"
View Source
const GetPostAttachmentModels = "GetPostAttachmentModels"
View Source
const GetPostAttachments = "GetPostAttachments"
View Source
const GetPostModel = "GetPostModel"
View Source
const GetPostsBefore = "GetPostsBefore"
View Source
const GetPostsInGroup = "GetPostsInGroup"
View Source
const GetThreadAttachments = "GetThreadAttachments"
View Source
const GetThreadModel = "GetThreadModel"
View Source
const GetThreadModelAttachments = "GetThreadModelAttachments"
View Source
const GetThreadModelPubkeys = "GetThreadModelPubkeys"
View Source
const GetThreadReplies_1 = "GetThreadReplies_1"
View Source
const GetThreadReplies_2 = "GetThreadReplies_2"
View Source
const GetThreadReplyPostModels_1 = "GetThreadReplyPostModels_1"
View Source
const GetThreadReplyPostModels_2 = "GetThreadReplyPostModels_2"
View Source
const GetYearlyPostHistory = "GetYearlyPostHistory"
View Source
const HasArticle = "HasArticle"
View Source
const HasArticleLocal = "HasArticleLocal"
View Source
const HasNewsgroup = "HasNewsgroup"
View Source
const IsExpired = "IsExpired"
View Source
const MaxMessageSize = 1024 * 1024 * 1024

HARD max message size

View Source
const ModDelete = ModAction("delete")
View Source
const ModDeleteAlt = ModAction("delete")
View Source
const ModHam = ModAction("ham")
View Source
const ModHide = ModAction("overchan-hide")
View Source
const ModInetBan = ModAction("overchan-inet-ban")
View Source
const ModLock = ModAction("overchan-lock")
View Source
const ModRemove = ModAction("remove")
View Source
const ModRemoveAttachment = ModAction("overchan-del-attachment")
View Source
const ModSage = ModAction("overchan-sage")
View Source
const ModSpam = ModAction("spam")
View Source
const ModStick = ModAction("overchan-stick")
View Source
const NewsgroupBanned = "NewsgroupBanned"
View Source
const RegisterArticle_1 = "RegisterArticle_1"
View Source
const RegisterArticle_2 = "RegisterArticle_2"
View Source
const RegisterArticle_3 = "RegisterArticle_3"
View Source
const RegisterArticle_4 = "RegisterArticle_4"
View Source
const RegisterArticle_5 = "RegisterArticle_5"
View Source
const RegisterArticle_6 = "RegisterArticle_6"
View Source
const RegisterArticle_7 = "RegisterArticle_7"
View Source
const RegisterArticle_8 = "RegisterArticle_8"
View Source
const RegisterArticle_GetLastBump = "RegisterArticle_GetLastBump"
View Source
const RegisterSigned = "RegisterSigned"
View Source
const RemoveArticle = "RemoveArticle"
View Source
const SearchByHash_1 = "SearchByHash_1"
View Source
const SearchByHash_2 = "SearchByHash_2"
View Source
const SearchQuery_1 = "SearchQuery_1"
View Source
const SearchQuery_2 = "SearchQuery_2"

Variables

View Source
var Discard = new(discardCloser)

like ioutil.Discard but an io.WriteCloser

View Source
var ErrMessageIsSpam = errors.New("message is spam")
View Source
var ErrNoLang = errors.New("no such language")
View Source
var ErrNoThumbnailerFound = errors.New("no thumbnailer found")
View Source
var ErrOversizedMessage = errors.New("oversized message")
View Source
var ErrSpamFilterFailed = errors.New("spam filter failed")
View Source
var ErrSpamFilterNotEnabled = errors.New("spam filter access attempted when disabled")
View Source
var GitVersion string
View Source
var TlsFailedToLoadCA = errors.New("could not load CA files")
View Source
var TlsNotSupported = errors.New("TLS not supported")

Functions

func CheckConfig

func CheckConfig()

check for config files generate defaults on demand

func CheckFile

func CheckFile(fname string) bool

func DelFile

func DelFile(fname string)

func EnsureDir

func EnsureDir(dirname string)

ensure a directory exists

func GenFeedsConfig

func GenFeedsConfig() error

generate default feeds.ini

func GenSRNdConfig

func GenSRNdConfig() *configparser.Configuration

generate default srnd.ini

func GenTLS

func GenTLS(cfg *CryptoConfig) (tcfg *tls.Config, err error)

generate tls config, private key and certificate

func HandleStartTLS

func HandleStartTLS(conn net.Conn, config *tls.Config) (econn *textproto.Conn, state tls.ConnectionState, err error)

handle STARTTLS on connection

func HashMessageID

func HashMessageID(msgid string) string

message id hash

func IPNet2MinMax

func IPNet2MinMax(inet *net.IPNet) (min, max net.IP)

func InitI18n

func InitI18n(locale, dir string)

Read all .ini files in dir, where the filenames are BCP 47 tags Use the language matcher to get the best match for the locale preference

func InstallerEnabled

func InstallerEnabled() bool

func IsDir

func IsDir(dirname string) bool

func IsSubnet

func IsSubnet(cidr string) (bool, *net.IPNet)

func KeygenTool

func KeygenTool()

generate a keypair from the command line

func MEMEPosting

func MEMEPosting(src, prefix string) (markup string)

func MessageIDWillDoDubs

func MessageIDWillDoDubs(msgid string) bool

will this message id produce dubs?

func MessageIDWillDoQuads

func MessageIDWillDoQuads(msgid string) bool

will this message id produce quads?

func MessageIDWillDoTrips

func MessageIDWillDoTrips(msgid string) bool

will this message id produce trips?

func OpenFileWriter

func OpenFileWriter(fname string) (io.WriteCloser, error)

func RegenTool

func RegenTool()

func ReloadTemplates

func ReloadTemplates()

func ReservedMessageID

func ReservedMessageID(id string) bool

func SaveFeeds

func SaveFeeds(feeds []FeedConfig, inboundPolicy *FeedPolicy) (err error)

save a list of feeds to overwrite feeds.ini

func SendStartTLS

func SendStartTLS(conn net.Conn, config *tls.Config) (econn *textproto.Conn, state tls.ConnectionState, err error)

func SetMarkupScriptFile

func SetMarkupScriptFile(fname string) error

func ShortHashMessageID

func ShortHashMessageID(msgid string) string

short message id hash

func ShorterHashMessageID

func ShorterHashMessageID(msgid string) string

shorter message id hash

func ThumbnailTool

func ThumbnailTool(threads int, missing bool)

run thumbnailer

func ValidMessageID

func ValidMessageID(id string) bool

func ValidNewsgroup

func ValidNewsgroup(newsgroup string) bool

func Version

func Version() string

func ZeroIPString

func ZeroIPString(ip net.IP) string

Types

type APIConfig

type APIConfig struct {
	// contains filtered or unexported fields
}

type APIModel

type APIModel struct {
	ErrorModel
	StepModel
	// contains filtered or unexported fields
}

func (*APIModel) Secret

func (self *APIModel) Secret() string

func (*APIModel) User

func (self *APIModel) User() string

type AdminFunc

type AdminFunc func(param map[string]interface{}) (interface{}, error)

does an action for the administrator takes in json

type ArticleEntry

type ArticleEntry [2]string

a ( MessageID , newsgroup ) tuple

func (ArticleEntry) MessageID

func (self ArticleEntry) MessageID() string

func (ArticleEntry) Newsgroup

func (self ArticleEntry) Newsgroup() string

type ArticleHeaders

type ArticleHeaders map[string][]string

func (ArticleHeaders) Add

func (self ArticleHeaders) Add(key, val string)

func (ArticleHeaders) Get

func (self ArticleHeaders) Get(key, fallback string) string

func (ArticleHeaders) Has

func (self ArticleHeaders) Has(key string) bool

func (ArticleHeaders) Len

func (self ArticleHeaders) Len() (l int)

func (ArticleHeaders) Set

func (self ArticleHeaders) Set(key, val string)

type ArticleStore

type ArticleStore interface {

	// full filepath to attachment directory
	AttachmentDir() string

	// get the filepath for an attachment
	AttachmentFilepath(fname string) string
	// get the filepath for an attachment's thumbnail
	ThumbnailFilepath(fname string) string
	// do we have this article?
	HasArticle(msgid string) bool
	// create a file for a message
	CreateFile(msgid string) io.WriteCloser
	// get the filename of a message
	GetFilename(msgid string) string
	// open a message in the store for reading given its message-id
	// return io.ReadCloser, error
	OpenMessage(msgid string) (io.ReadCloser, error)
	// get article headers only
	GetHeaders(msgid string) ArticleHeaders
	// get mime header
	GetMIMEHeader(msgid string) textproto.MIMEHeader
	// get our temp directory for articles
	TempDir() string
	// get temp filename for article
	GetFilenameTemp(msgid string) string
	// get a list of all the attachments we have
	GetAllAttachments() ([]string, error)
	// generate a thumbnail
	GenerateThumbnail(fname string) (ThumbInfo, error)
	// generate all thumbanils for this message
	ThumbnailMessage(msgid string) []ThumbInfo
	// did we enable compression?
	Compression() bool
	// process nntp message, register attachments and the article
	// write the body into writer as we go through the message
	// writes mime body and does any spam rewrite
	ProcessMessage(wr io.Writer, msg io.Reader, filter func(string) bool, group string) error
	// register this post with the daemon
	RegisterPost(nntp NNTPMessage) error
	// register signed message
	RegisterSigned(msgid, pk string) error

	GetMessage(msgid string) NNTPMessage

	// get size of message on disk
	GetMessageSize(msgid string) (int64, error)

	// get thumbnail info of file by path
	ThumbInfo(fpath string) (ThumbInfo, error)

	// delete message by message-id
	Remove(msgid string) error

	// move message to spam dir
	MarkSpam(msgid string) error

	// move message out of spam dir
	UnmarkSpam(msgid string) error

	// get filepath for spam file via msgid
	SpamFile(msgid string) string

	// iterate over all spam messages
	IterSpam(func(string) error) error

	// iterate over all spam message headers
	IterSpamHeaders(func(map[string][]string) error) error

	// move temp article to article store
	AcceptTempArticle(msgid string) error
}

type AttachmentModel

type AttachmentModel interface {
	BaseModel

	Thumbnail() string
	Source() string
	Filename() string
	Hash() string
	ThumbInfo() ThumbInfo
}

for attachments

type BaseDialogModel

type BaseDialogModel struct {
	ErrorModel
	StepModel
}

type BaseModel

type BaseModel interface {

	// set sfw flag
	MarkSFW(sfw bool)

	// site url prefix
	Prefix() string

	// impelements json.Marshaller
	MarshalJSON() ([]byte, error)

	// to json string
	JSON() string

	// inject I18N
	I18N(i *I18N)
}

base model type

type BinaryModel

type BinaryModel struct {
	ErrorModel
	StepModel
	// contains filtered or unexported fields
}

func (*BinaryModel) Convert

func (self *BinaryModel) Convert() string

func (*BinaryModel) FFmpeg

func (self *BinaryModel) FFmpeg() string

func (*BinaryModel) Sox

func (self *BinaryModel) Sox() string

type BoardModel

type BoardModel interface {
	BaseModel
	NavbarModel

	Frontend() string
	Name() string
	Threads() []ThreadModel

	AllowFiles() bool
	SetAllowFiles(files bool)

	// JUST update this thread
	// if we don't have it already loaded do nothing
	UpdateThread(message_id string, db Database)

	// get a thread model with this id
	// returns nil if we don't have it
	GetThread(message_id string) ThreadModel

	// put a thread back after updating externally
	PutThread(th ThreadModel)

	// deprecated, use GetThread
	HasThread(message_id string) bool

	// update the board's contents
	Update(db Database)
}

board interface for 1 page on a board

type CacheHandler

type CacheHandler interface {
	http.Handler
	GetI18N(r *http.Request) *I18N
}

type CacheInterface

type CacheInterface interface {
	RegenAll()
	RegenFrontPage(pagesstart int)
	RegenOnModEvent(newsgroup, msgid, root string, page int)
	RegenerateBoard(group string)
	Regen(msg ArticleEntry)

	DeleteThreadMarkup(root_post_id string)
	DeleteBoardMarkup(group string)

	Start()
	Close()
	GetHandler() CacheHandler

	SetRequireCaptcha(required bool)
	InvertPagination()
}

func NewCache

func NewCache(cache_type, host, port, user, password string, cache_config, config map[string]string, db Database, store ArticleStore) CacheInterface

TODO only pass needed config

func NewFileCache

func NewFileCache(prefix, webroot, name string, threads int, attachments bool, db Database, store ArticleStore) CacheInterface

func NewNullCache

func NewNullCache(prefix, webroot, name, translations string, attachments bool, db Database, store ArticleStore) CacheInterface

func NewVarnishCache

func NewVarnishCache(varnish_url, bind_addr, prefix, webroot, name, translations string, workers int, attachments bool, db Database, store ArticleStore) CacheInterface

type CatalogItemModel

type CatalogItemModel interface {
	OP() PostModel
	ReplyCount() string
	Page() string
	MarkSFW(sfw bool)
}

type CatalogModel

type CatalogModel interface {
	BaseModel
	NavbarModel

	Frontend() string
	Name() string
	Threads() []CatalogItemModel
}

type CryptoConfig

type CryptoConfig struct {
	// contains filtered or unexported fields
}

type CryptoModel

type CryptoModel struct {
	ErrorModel
	StepModel
	// contains filtered or unexported fields
}

func (*CryptoModel) Host

func (self *CryptoModel) Host() string

func (*CryptoModel) Key

func (self *CryptoModel) Key() string

type DBModel

type DBModel struct {
	ErrorModel
	StepModel
	// contains filtered or unexported fields
}

func (*DBModel) Host

func (self *DBModel) Host() string

func (*DBModel) Port

func (self *DBModel) Port() string

func (*DBModel) Username

func (self *DBModel) Username() string

type Database

type Database interface {
	Close()
	CreateTables()
	HasNewsgroup(group string) bool
	HasArticle(message_id string) bool
	HasArticleLocal(message_id string) bool
	RegisterNewsgroup(group string)
	RegisterArticle(article NNTPMessage) error
	GetAllArticlesInGroup(group string, send chan ArticleEntry)
	CountAllArticlesInGroup(group string) (int64, error)
	GetAllArticles() []ArticleEntry

	SetConnectionLifetime(seconds int)
	SetMaxOpenConns(n int)
	SetMaxIdleConns(n int)

	// check if a newsgroup is banned
	NewsgroupBanned(group string) (bool, error)

	// ban / unban newsgroup
	BanNewsgroup(group string) error
	UnbanNewsgroup(group string) error

	// delete an entire newsgroup
	// delete from the article store too
	NukeNewsgroup(group string, store ArticleStore)

	// return true if this is root post has expired
	IsExpired(root_message_id string) bool

	// get an article's MessageID given the hash of the MessageID
	// return an article entry or nil when it doesn't exist + and error if it happened
	GetMessageIDByHash(hash string) (ArticleEntry, error)

	// get root message_id, newsgroup, pageno for a post regardless if it's rootpost or not
	GetInfoForMessage(msgid string) (string, string, int64, error)

	// what page is the thread with this root post on?
	// return newsgroup, pageno
	GetPageForRootMessage(root_message_id string) (string, int64, error)

	// record that a message given a message id was posted signed by this pubkey
	RegisterSigned(message_id, pubkey string) error

	// get the number of articles we have
	ArticleCount() int64

	// return true if this thread has any replies
	ThreadHasReplies(root_message_id string) bool

	// get the number of posts in a certain newsgroup since N seconds ago
	// if N <= 0 then count all we have now
	CountPostsInGroup(group string, time_frame int64) int64

	// get the stats for the overview page
	GetNewsgroupStats() ([]NewsgroupStats, error)

	// get all replies to a thread
	// if last > 0 then get that many of the last replies
	// start at reply number start
	GetThreadReplies(root_message_id string, start, last int) []string

	// count the number of replies to this thread
	CountThreadReplies(root_message_id string) int64

	// get all attachments for this message
	GetPostAttachments(message_id string) []string

	// get all attachments in a thread
	GetThreadAttachments(rootmsgid string) ([]string, error)

	// get all attachments for this message
	GetPostAttachmentModels(prefix, message_id string) []AttachmentModel

	// return true if this newsgroup has posts
	GroupHasPosts(newsgroup string) bool

	// get all active threads on a board
	// send each thread's ArticleEntry down a channel
	GetGroupThreads(newsgroup string, send chan ArticleEntry)

	// get every message id for root posts that need to be expired in a newsgroup
	// threadcount is the upperbound limit to how many root posts we keep
	GetRootPostsForExpiration(newsgroup string, threadcount int) []string

	// get the number of pages a board has
	GetGroupPageCount(newsgroup string) int64

	// get board page number N
	// prefix and frontend are injected
	// does not load replies for thread, only gets root posts
	GetGroupForPage(prefix, frontend, newsgroup string, pageno, perpage int) BoardModel

	// get the root posts of the last N bumped threads in a given newsgroup or "" for ukko
	GetLastBumpedThreads(newsgroup string, threadcount int) []ArticleEntry

	// get root posts of last N bumped threads with pagination offset
	GetLastBumpedThreadsPaginated(newsgroup string, threadcount, offset int) []ArticleEntry

	// get the PostModels for replies to a thread
	// prefix is injected into the post models
	GetThreadReplyPostModels(prefix, rootMessageID string, start, limit int) []PostModel

	// get a post model for a post
	// prefix is injected into the post model
	GetPostModel(prefix, messageID string) PostModel

	// add a public key to the database
	AddModPubkey(pubkey string) error

	// mark that a mod with this pubkey can act on all boards
	MarkModPubkeyGlobal(pubkey string) error

	// revoke mod with this pubkey the privilege of being able to act on all boards
	UnMarkModPubkeyGlobal(pubkey string) error

	// check if this mod pubkey can moderate at a global level
	CheckModPubkeyGlobal(pubkey string) bool

	// check if a mod with this pubkey has permission to moderate at all
	CheckModPubkey(pubkey string) bool

	// check if a pubkey has admin privs
	CheckAdminPubkey(pubkey string) (bool, error)

	// mark a key as having admin privs
	MarkPubkeyAdmin(pubkey string) error

	// unmark a key as having admin privs
	UnmarkPubkeyAdmin(pubkey string) error

	// check if a mod with this pubkey can moderate on the given newsgroup
	CheckModPubkeyCanModGroup(pubkey, newsgroup string) bool

	// add a pubkey to be able to mod a newsgroup
	MarkModPubkeyCanModGroup(pubkey, newsgroup string) error

	// remote a pubkey to they can't mod a newsgroup
	UnMarkModPubkeyCanModGroup(pubkey, newsgroup string) error

	// ban an article
	BanArticle(messageID, reason string) error

	// check if an article is banned or not
	ArticleBanned(messageID string) bool

	// Get ip address given the encrypted version
	// return emtpy string if we don't have it
	GetIPAddress(encAddr string) (string, error)

	// check if an ip is banned from our local
	CheckIPBanned(addr string) (bool, error)

	// check if an encrypted ip is banned from our local
	CheckEncIPBanned(encAddr string) (bool, error)

	// ban an ip address from the local
	BanAddr(addr string) error

	// unban an ip address from the local
	UnbanAddr(addr string) error

	// ban an encrypted ip address from the remote
	BanEncAddr(encAddr string) error

	// return the encrypted version of an IPAddress
	// if it's not already there insert it into the database
	GetEncAddress(addr string) (string, error)

	// get the decryption key for an encrypted address
	// return empty string if we don't have it
	GetEncKey(encAddr string) (string, error)

	// delete an article from the database
	DeleteArticle(msg_id string) error

	// remove an article from the database
	RemoveArticle(msg_id string) error

	// detele the existance of a thread from the threads table, does NOT remove replies
	DeleteThread(root_msg_id string) error

	// get threads per page for a newsgroup
	GetThreadsPerPage(group string) (int, error)

	// get pages per board for a newsgroup
	GetPagesPerBoard(group string) (int, error)

	// get every newsgroup we know of
	GetAllNewsgroups() []string

	// get all post models in a newsgroup
	// ordered from oldest to newest
	GetPostsInGroup(group string) ([]PostModel, error)

	// get the numerical id of the last , first article for a given group
	GetLastAndFirstForGroup(group string) (int64, int64, error)

	// get a message id give a newsgroup and the nntp id
	GetMessageIDForNNTPID(group string, id int64) (string, error)

	// get nntp id for a given message-id
	GetNNTPIDForMessageID(group, msgid string) (int64, error)

	// get the last N days post count in decending order
	GetLastDaysPosts(n int64) []PostEntry

	// get the last N days post count in decending order
	GetLastDaysPostsForGroup(newsgroup string, n int64) []PostEntry

	// get post history per month since beginning of time
	GetMonthlyPostHistory() []PostEntry

	// get the last N posts that were made globally
	GetLastPostedPostModels(prefix string, n int64) []PostModel

	// check if an nntp login cred is correct
	CheckNNTPLogin(username, passwd string) (bool, error)

	// add an nntp login credential
	AddNNTPLogin(username, passwd string) error

	// remove an nntp login credential
	RemoveNNTPLogin(username string) error

	// check if an nntp login credential given a user exists
	CheckNNTPUserExists(username string) (bool, error)

	// get the message ids of an article that has this header with the given value
	GetMessageIDByHeader(name, value string) ([]string, error)

	// get the headers for a message given its message-id
	GetHeadersForMessage(msgid string) (ArticleHeaders, error)

	// get all message-ids posted by posters in this cidr
	GetMessageIDByCIDR(cidr *net.IPNet) ([]string, error)

	// get all message-ids posted by poster with encrypted ip
	GetMessageIDByEncryptedIP(encaddr string) ([]string, error)

	// check if this public key is banned from posting
	PubkeyRejected(pubkey string) (bool, error)

	// ban a public key from posting
	BlacklistPubkey(pubkey string) error
	WhitelistPubkey(pubkey string) error
	DeletePubkey(pubkey string) error

	// get all message-id posted before a time
	GetPostsBefore(t time.Time) ([]string, error)

	// get statistics about posting in a time slice
	GetPostingStats(granularity, begin, end int64) (PostingStats, error)

	// peform search query
	SearchQuery(prefix, group, text string, chnl chan PostModel) error

	// find posts with similar hash
	SearchByHash(prefix, group, posthash string, chnl chan PostModel) error

	// get full thread model
	GetThreadModel(prefix, root_msgid string) (ThreadModel, error)

	// get post models with nntp id in a newsgroup
	GetNNTPPostsInGroup(newsgroup string) ([]PostModel, error)

	// get post message-id where hash is similar to string
	GetCitesByPostHashLike(like string) ([]MessageIDTuple, error)

	// get newsgroup list with watermarks
	GetNewsgroupList() (NewsgroupList, error)

	// find cites in text
	FindCitesInText(msg string) ([]string, error)

	// find headers in group with lo/hi watermark and list of patterns
	FindHeaders(group, headername string, lo, hi int64) (ArticleHeaders, error)

	// count ukko pages
	GetUkkoPageCount(perpage int) (int64, error)
}

func NewDatabase

func NewDatabase(db_type, schema, host, port, user, password string) Database

func NewPostgresDatabase

func NewPostgresDatabase(host, port, user, password string) Database

create postgres database driver

type ErrorModel

type ErrorModel struct {
	Err error
}

func (*ErrorModel) Error

func (self *ErrorModel) Error() string

func (*ErrorModel) HasError

func (self *ErrorModel) HasError() bool

type ExpirationCore

type ExpirationCore interface {
	// do expiration for a group
	ExpireGroup(newsgroup string, keep int)
	// Delete a single post and all children
	ExpirePost(messageID string)
	// expire all orphaned articles
	ExpireOrphans()
	// expire all articles posted before time
	ExpireBefore(t time.Time)
}

content expiration interface

type ExpireCacheFunc

type ExpireCacheFunc func(string, string, string)

type FeedConfig

type FeedConfig struct {
	Addr string

	Name string
	// contains filtered or unexported fields
}

type FeedPolicy

type FeedPolicy struct {
	// contains filtered or unexported fields
}

func (*FeedPolicy) AllowsNewsgroup

func (self *FeedPolicy) AllowsNewsgroup(newsgroup string) (result bool)

do we allow this newsgroup?

type FileCache

type FileCache struct {
	// contains filtered or unexported fields
}

func (*FileCache) Close

func (self *FileCache) Close()

func (*FileCache) DeleteBoardMarkup

func (self *FileCache) DeleteBoardMarkup(group string)

func (*FileCache) DeleteThreadMarkup

func (self *FileCache) DeleteThreadMarkup(root_post_id string)

try to delete root post's page

func (*FileCache) GetGroupChan

func (self *FileCache) GetGroupChan() chan groupRegenRequest

func (*FileCache) GetHandler

func (self *FileCache) GetHandler() CacheHandler

func (*FileCache) GetI18N

func (self *FileCache) GetI18N(r *http.Request) *I18N

func (*FileCache) GetThreadChan

func (self *FileCache) GetThreadChan() chan ArticleEntry

func (*FileCache) InvertPagination

func (self *FileCache) InvertPagination()

func (*FileCache) Regen

func (self *FileCache) Regen(msg ArticleEntry)

func (*FileCache) RegenAll

func (self *FileCache) RegenAll()

regen every newsgroup

func (*FileCache) RegenFrontPage

func (self *FileCache) RegenFrontPage(_ int)

regenerate the front page

func (*FileCache) RegenOnModEvent

func (self *FileCache) RegenOnModEvent(newsgroup, msgid, root string, page int)

regenerate pages after a mod event

func (*FileCache) RegenerateBoard

func (self *FileCache) RegenerateBoard(group string)

regen every page of the board

func (*FileCache) ServeHTTP

func (self *FileCache) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*FileCache) SetRequireCaptcha

func (self *FileCache) SetRequireCaptcha(require bool)

func (*FileCache) Start

func (self *FileCache) Start()

type FilterConfig

type FilterConfig struct {
	// contains filtered or unexported fields
}

func (*FilterConfig) LoadFile

func (fc *FilterConfig) LoadFile(fname string) (err error)

type Frontend

type Frontend interface {

	// handle new post from nntpd
	HandleNewPost(p frontendPost)

	// run mainloop
	Mainloop()

	// do we want posts from a newsgroup?
	AllowNewsgroup(group string) bool

	// trigger a manual regen of indexes for a root post
	Regen(msg ArticleEntry)

	// regenerate on mod event
	RegenOnModEvent(newsgroup, msgid, root string, page int)

	GetCacheHandler() CacheHandler

	// set archive mode
	ArchiveMode()
}

frontend interface for any type of frontend

func MuxFrontends

func MuxFrontends(fronts ...Frontend) Frontend

func NewHTTPFrontend

func NewHTTPFrontend(daemon *NNTPDaemon, cache CacheInterface, config map[string]string, url string) Frontend

create a new http based frontend

type FrontendModel

type FrontendModel struct {
	ErrorModel
	StepModel
	// contains filtered or unexported fields
}

func (*FrontendModel) Locale

func (self *FrontendModel) Locale() string

func (*FrontendModel) Name

func (self *FrontendModel) Name() string

type GroupModel

type GroupModel []BoardModel

newsgroup model every page on a newsgroup

func (*GroupModel) Update

func (self *GroupModel) Update(page int, db Database)

update a certain page does nothing if out of bounds

func (*GroupModel) UpdateAll

func (self *GroupModel) UpdateAll(db Database)

TODO: optimize using 1 query? update every page

type HookConfig

type HookConfig struct {
	// contains filtered or unexported fields
}

func (*HookConfig) Exec

func (config *HookConfig) Exec(group, msgid, ref string)

type I18N

type I18N struct {

	// loaded translations
	Translations map[string]string
	// loaded formats
	Formats map[string]string

	// name of locale
	Name string
	// contains filtered or unexported fields
}
var I18nProvider *I18N = nil

func NewI18n

func NewI18n(locale, dir string) (*I18N, error)

func (*I18N) Format

func (self *I18N) Format(key string) string

func (*I18N) Translate

func (self *I18N) Translate(key string) string

type Installer

type Installer struct {
	// contains filtered or unexported fields
}

func NewInstaller

func NewInstaller(result chan *configparser.Configuration) *Installer

func (*Installer) HandleInstallerGet

func (self *Installer) HandleInstallerGet(wr http.ResponseWriter, r *http.Request)

func (*Installer) HandleInstallerPost

func (self *Installer) HandleInstallerPost(wr http.ResponseWriter, r *http.Request)

func (*Installer) Start

func (self *Installer) Start()

func (*Installer) Stop

func (self *Installer) Stop()

type KeyModel

type KeyModel struct {
	ErrorModel
	StepModel
	// contains filtered or unexported fields
}

func (*KeyModel) Public

func (self *KeyModel) Public() string

func (*KeyModel) Secret

func (self *KeyModel) Secret() string

type LineWriter

type LineWriter struct {
	// contains filtered or unexported fields
}

func NewLineWriter

func NewLineWriter(w io.Writer, limit int64) *LineWriter

func (*LineWriter) Write

func (l *LineWriter) Write(data []byte) (n int, err error)

type LinkModel

type LinkModel interface {
	Text() string
	LinkURL() string
}

type MessageIDTuple

type MessageIDTuple [2]string

a (messageID , parent messageID) tuple

func (MessageIDTuple) MessageID

func (self MessageIDTuple) MessageID() string

func (MessageIDTuple) Reference

func (self MessageIDTuple) Reference() string

type ModAction

type ModAction string

type ModEngine

type ModEngine interface {
	// load and handle a mod message from ctl after it's verified
	HandleMessage(msgid string)
	// delete post of a poster
	DeletePost(msgid string) error
	// mark message as spam
	MarkSpam(msgid string) error
	// ban a cidr
	BanAddress(cidr string) error
	// do we allow this public key to delete this message-id ?
	AllowDelete(pubkey, msgid string) bool
	// do we allow this public key to do inet-ban?
	AllowBan(pubkey string) bool
	// allow janitor
	AllowJanitor(pubkey string) bool
	// load a mod message
	LoadMessage(msgid string) NNTPMessage
	// execute 1 mod action line by a mod with pubkey
	Execute(ev ModEvent, pubkey string)
	// do a mod event unconditionally
	Do(ev ModEvent)
}

type ModEvent

type ModEvent interface {
	// turn it into a string for putting into an article
	String() string
	// what type of mod event
	Action() ModAction
	// what reason for the event
	Reason() string
	// what is the event acting on
	Target() string
	// scope of the event, regex of newsgroup
	Scope() string
	// when this mod event expires, unix nano
	Expires() int64
}

func ParseModEvent

func ParseModEvent(line string) ModEvent

type ModMessage

type ModMessage []ModEvent

moderation message wraps multiple mod events is turned into an NNTPMessage later

func (ModMessage) WriteTo

func (self ModMessage) WriteTo(wr io.Writer, delim []byte) (err error)

write this mod message's body

type ModUI

type ModUI interface {
	// check if this key is allowed to access
	// return true if it can otherwise false
	CheckKey(privkey, scope string) (bool, error)
	// serve the base page
	ServeModPage(wr http.ResponseWriter, r *http.Request)
	// handle a login POST request
	HandleLogin(wr http.ResponseWriter, r *http.Request)
	// handle a delete article request
	HandleDeletePost(wr http.ResponseWriter, r *http.Request)
	// handle a ban address request
	HandleBanAddress(wr http.ResponseWriter, r *http.Request)
	// handle an unban address request
	HandleUnbanAddress(wr http.ResponseWriter, r *http.Request)
	// handle add a pubkey
	HandleAddPubkey(wr http.ResponseWriter, r *http.Request)
	// handle removing a pubkey
	HandleDelPubkey(wr http.ResponseWriter, r *http.Request)
	// handle key generation
	HandleKeyGen(wr http.ResponseWriter, r *http.Request)
	// handle admin command
	HandleAdminCommand(wr http.ResponseWriter, r *http.Request)
	// handle mark a post as spam
	HandlePostSpam(wr http.ResponseWriter, r *http.Request)

	// get outbound message channel
	MessageChan() chan NNTPMessage
}

interface for moderation ui

type NNTPAttachment

type NNTPAttachment interface {
	io.WriterTo
	io.Writer
	// the name of the file
	Filename() string
	// the filepath to the saved file
	Filepath() string
	// the mime type of the attachment
	Mime() string
	// the file extension of the attachment
	Extension() string
	// get the sha512 hash of the attachment
	Hash() []byte
	// do we need to generate a thumbnail?
	NeedsThumbnail() bool
	// mime header
	Header() textproto.MIMEHeader
	// make into a model
	ToModel(prefix string) AttachmentModel
	// base64'd file data
	Filedata() string
	// as raw string
	AsString() string
	// reset contents
	Reset()
	// get bytes
	Bytes() []byte
	// save to directory, filename is decided by the attachment
	Save(dir string) error
	// get body as io.ReadCloser
	OpenBody() (io.ReadCloser, error)
}

type NNTPDaemon

type NNTPDaemon struct {
	// contains filtered or unexported fields
}

func (*NNTPDaemon) AddNNTPLogin

func (self *NNTPDaemon) AddNNTPLogin(username, password string)

for srnd tool

func (*NNTPDaemon) AllowsNewsgroup

func (self *NNTPDaemon) AllowsNewsgroup(group string) bool

func (*NNTPDaemon) CanTLS

func (self *NNTPDaemon) CanTLS() (can bool)

return true if we can do tls

func (*NNTPDaemon) CheckText

func (self *NNTPDaemon) CheckText(text string) bool

return true if text passes all checks and is okay for posting

func (*NNTPDaemon) DelNNTPLogin

func (self *NNTPDaemon) DelNNTPLogin(username string)

for srnd tool

func (NNTPDaemon) End

func (self NNTPDaemon) End()

func (*NNTPDaemon) ExpireAll

func (self *NNTPDaemon) ExpireAll()

func (*NNTPDaemon) Federate

func (self *NNTPDaemon) Federate() (federate bool)

func (*NNTPDaemon) GetDatabase

func (self *NNTPDaemon) GetDatabase() Database

func (*NNTPDaemon) GetOurTLSConfig

func (self *NNTPDaemon) GetOurTLSConfig() *tls.Config

func (*NNTPDaemon) GetTLSConfig

func (self *NNTPDaemon) GetTLSConfig(hostname string) *tls.Config

func (*NNTPDaemon) MarkSpam

func (self *NNTPDaemon) MarkSpam(msgid string)

func (*NNTPDaemon) ModEngine

func (daemon *NNTPDaemon) ModEngine() ModEngine

func (*NNTPDaemon) Reload

func (self *NNTPDaemon) Reload()

reload all configs etc

func (*NNTPDaemon) RequireTLS

func (self *NNTPDaemon) RequireTLS() (require bool)

func (*NNTPDaemon) Run

func (self *NNTPDaemon) Run()

run daemon

func (*NNTPDaemon) Setup

func (self *NNTPDaemon) Setup()

func (*NNTPDaemon) WrapSign

func (self *NNTPDaemon) WrapSign(nntp NNTPMessage)

sign an article as coming from our daemon

type NNTPMessage

type NNTPMessage interface {
	// this message's messsge id
	MessageID() string
	// the parent message's messageid if it's specified
	Reference() string
	// the newsgroup this post is in
	Newsgroup() string
	// the name of the poster
	Name() string
	// any email address associated with the post
	Email() string
	// the subject of the post
	Subject() string
	// when this was posted
	Posted() int64
	// the path header
	Path() string
	// get signed part
	SignedPart() NNTPAttachment
	// append something to path
	// return message with new path
	AppendPath(part string) NNTPMessage
	// the type of this message usually a mimetype
	ContentType() string
	// was this post a sage?
	Sage() bool
	// was this post a root post?
	OP() bool
	// all attachments
	Attachments() []NNTPAttachment
	FrontendPubkey() string
	// all headers
	Headers() ArticleHeaders
	MIMEHeader() textproto.MIMEHeader
	// write out everything
	WriteTo(wr io.Writer, limit int64) error
	// write out body
	WriteBody(wr io.Writer, limit int64) error
	// attach a file
	Attach(att NNTPAttachment)
	// get the plaintext message if it exists
	Message() string
	// pack the whole message and prepare for write
	Pack()
	// get the pubkey for this message if it was signed, otherwise empty string
	Pubkey() string
	// get the origin encrypted address, i2p destination or empty string for onion posters
	Addr() string
	// reset contents
	Reset()
	// get body as reader
	BodyReader() io.Reader
}

type NameModel

type NameModel struct {
	ErrorModel
	StepModel
	// contains filtered or unexported fields
}

func (*NameModel) Name

func (self *NameModel) Name() string
type NavbarModel interface {
	Navbar() string
}

interface for models that have a navbar

type NewsgroupList

type NewsgroupList []NewsgroupListEntry

type NewsgroupListEntry

type NewsgroupListEntry [3]string

newsgroup, first, last

type NewsgroupStats

type NewsgroupStats struct {
	PPD  int64
	Name string
}

stats about newsgroup postings

type NullCache

type NullCache struct {
	// contains filtered or unexported fields
}

func (*NullCache) Close

func (self *NullCache) Close()

func (*NullCache) DeleteBoardMarkup

func (self *NullCache) DeleteBoardMarkup(group string)

func (*NullCache) DeleteThreadMarkup

func (self *NullCache) DeleteThreadMarkup(root_post_id string)

try to delete root post's page

func (*NullCache) GetHandler

func (self *NullCache) GetHandler() CacheHandler

func (*NullCache) InvertPagination

func (self *NullCache) InvertPagination()

func (*NullCache) Regen

func (self *NullCache) Regen(msg ArticleEntry)

func (*NullCache) RegenAll

func (self *NullCache) RegenAll()

regen every newsgroup

func (*NullCache) RegenFrontPage

func (self *NullCache) RegenFrontPage(pagestart int)

func (*NullCache) RegenOnModEvent

func (self *NullCache) RegenOnModEvent(newsgroup, msgid, root string, page int)

regenerate pages after a mod event

func (*NullCache) RegenerateBoard

func (self *NullCache) RegenerateBoard(group string)

regen every page of the board

func (*NullCache) SetRequireCaptcha

func (self *NullCache) SetRequireCaptcha(required bool)

func (*NullCache) Start

func (self *NullCache) Start()

type PostEntry

type PostEntry [2]int64

a ( time point, magnitude ) tuple

func (PostEntry) Count

func (self PostEntry) Count() int64

func (PostEntry) Time

func (self PostEntry) Time() time.Time

type PostEntryList

type PostEntryList []PostEntry

type PostModel

type PostModel interface {
	BaseModel

	Brief() string
	CSSClass() string
	FrontendPubkey() string
	MessageID() string
	PostHash() string
	ShortHash() string
	PostURL() string
	Frontend() string
	Subject() string
	Name() string
	Date() string
	OP() bool
	Attachments() []AttachmentModel
	NumAttachments() int
	Board() string
	Sage() bool
	Pubkey() string
	PubkeyHex() string
	Reference() string
	ReferenceHash() string

	RenderBody() string
	RenderPost() string
	RenderBodyPre() string

	// replaces Truncate().RenderBody()
	RenderTruncatedBody() string

	// replaces Truncate().RenderPost()
	RenderTruncatedPost() string

	// returns true if this post was truncated
	IsTruncated() bool

	IsI2P() bool
	IsTor() bool
	IsClearnet() bool

	// deprecated
	// truncate body to a certain size
	// return copy
	Truncate() PostModel

	// what is our position in this thread?
	// 0 for OP, nonzero for reply
	Index() int
	// set post index
	SetIndex(idx int)

	// nntp id number
	NNTPID() int
}

for individual posts

func PostModelFromMessage

func PostModelFromMessage(parent, prefix string, nntp NNTPMessage) PostModel

type PostgresDatabase

type PostgresDatabase struct {
	// contains filtered or unexported fields
}

postgres database driver implementation

func (*PostgresDatabase) AddModPubkey

func (self *PostgresDatabase) AddModPubkey(pubkey string) error

func (*PostgresDatabase) AddNNTPLogin

func (self *PostgresDatabase) AddNNTPLogin(username, passwd string) (err error)

func (*PostgresDatabase) ArticleBanned

func (self *PostgresDatabase) ArticleBanned(messageID string) (result bool)

func (*PostgresDatabase) ArticleCount

func (self *PostgresDatabase) ArticleCount() (count int64)

count articles we have

func (*PostgresDatabase) BanAddr

func (self *PostgresDatabase) BanAddr(addr string) (err error)

func (*PostgresDatabase) BanArticle

func (self *PostgresDatabase) BanArticle(messageID, reason string) error

func (*PostgresDatabase) BanEncAddr

func (self *PostgresDatabase) BanEncAddr(encaddr string) (err error)

func (*PostgresDatabase) BanNewsgroup

func (self *PostgresDatabase) BanNewsgroup(group string) (err error)

func (*PostgresDatabase) BlacklistPubkey

func (self *PostgresDatabase) BlacklistPubkey(pubkey string) (err error)

func (*PostgresDatabase) CheckAdminPubkey

func (self *PostgresDatabase) CheckAdminPubkey(pubkey string) (admin bool, err error)

func (*PostgresDatabase) CheckEncIPBanned

func (self *PostgresDatabase) CheckEncIPBanned(encaddr string) (banned bool, err error)

func (*PostgresDatabase) CheckIPBanned

func (self *PostgresDatabase) CheckIPBanned(addr string) (banned bool, err error)

func (*PostgresDatabase) CheckModPubkey

func (self *PostgresDatabase) CheckModPubkey(pubkey string) bool

func (*PostgresDatabase) CheckModPubkeyCanModGroup

func (self *PostgresDatabase) CheckModPubkeyCanModGroup(pubkey, newsgroup string) bool

func (*PostgresDatabase) CheckModPubkeyGlobal

func (self *PostgresDatabase) CheckModPubkeyGlobal(pubkey string) bool

func (*PostgresDatabase) CheckNNTPLogin

func (self *PostgresDatabase) CheckNNTPLogin(username, passwd string) (valid bool, err error)

func (*PostgresDatabase) CheckNNTPUserExists

func (self *PostgresDatabase) CheckNNTPUserExists(username string) (exists bool, err error)

func (*PostgresDatabase) Close

func (self *PostgresDatabase) Close()

finalize all transactions close database connections

func (*PostgresDatabase) CountAllArticlesInGroup

func (self *PostgresDatabase) CountAllArticlesInGroup(group string) (count int64, err error)

func (*PostgresDatabase) CountPostsInGroup

func (self *PostgresDatabase) CountPostsInGroup(newsgroup string, time_frame int64) (result int64)

func (*PostgresDatabase) CountThreadReplies

func (self *PostgresDatabase) CountThreadReplies(root_message_id string) (repls int64)

func (*PostgresDatabase) CreateTables

func (self *PostgresDatabase) CreateTables()

func (*PostgresDatabase) DeleteArticle

func (self *PostgresDatabase) DeleteArticle(msgid string) (err error)

func (*PostgresDatabase) DeletePubkey

func (self *PostgresDatabase) DeletePubkey(pubkey string) (err error)

func (*PostgresDatabase) DeleteThread

func (self *PostgresDatabase) DeleteThread(msgid string) (err error)

func (*PostgresDatabase) FindCitesInText

func (self *PostgresDatabase) FindCitesInText(text string) (msgids []string, err error)

func (*PostgresDatabase) FindHeaders

func (self *PostgresDatabase) FindHeaders(group, headername string, lo, hi int64) (hdr ArticleHeaders, err error)

func (*PostgresDatabase) GetAllArticles

func (self *PostgresDatabase) GetAllArticles() (articles []ArticleEntry)

get all articles send result down a channel

func (*PostgresDatabase) GetAllArticlesInGroup

func (self *PostgresDatabase) GetAllArticlesInGroup(group string, recv chan ArticleEntry)

get all articles in a newsgroup send result down a channel

func (*PostgresDatabase) GetAllNewsgroups

func (self *PostgresDatabase) GetAllNewsgroups() (groups []string)

func (*PostgresDatabase) GetCitesByPostHashLike

func (self *PostgresDatabase) GetCitesByPostHashLike(like string) (cites []MessageIDTuple, err error)

func (*PostgresDatabase) GetEncAddress

func (self *PostgresDatabase) GetEncAddress(addr string) (encaddr string, err error)

func (*PostgresDatabase) GetEncKey

func (self *PostgresDatabase) GetEncKey(encAddr string) (enckey string, err error)

func (*PostgresDatabase) GetGroupForMessage

func (self *PostgresDatabase) GetGroupForMessage(message_id string) (group string, err error)

func (*PostgresDatabase) GetGroupForPage

func (self *PostgresDatabase) GetGroupForPage(prefix, frontend, newsgroup string, pageno, perpage int) BoardModel

only fetches root posts does not update the thread contents

func (*PostgresDatabase) GetGroupPageCount

func (self *PostgresDatabase) GetGroupPageCount(newsgroup string) int64

func (*PostgresDatabase) GetGroupThreads

func (self *PostgresDatabase) GetGroupThreads(group string, recv chan ArticleEntry)

func (*PostgresDatabase) GetHeadersForMessage

func (self *PostgresDatabase) GetHeadersForMessage(msgid string) (hdr ArticleHeaders, err error)

func (*PostgresDatabase) GetIPAddress

func (self *PostgresDatabase) GetIPAddress(encaddr string) (addr string, err error)

func (*PostgresDatabase) GetInfoForMessage

func (self *PostgresDatabase) GetInfoForMessage(msgid string) (root string, newsgroup string, page int64, err error)

func (*PostgresDatabase) GetLastAndFirstForGroup

func (self *PostgresDatabase) GetLastAndFirstForGroup(group string) (last, first int64, err error)

func (*PostgresDatabase) GetLastBumpedThreads

func (self *PostgresDatabase) GetLastBumpedThreads(newsgroups string, threads int) []ArticleEntry

func (*PostgresDatabase) GetLastBumpedThreadsPaginated

func (self *PostgresDatabase) GetLastBumpedThreadsPaginated(newsgroup string, threads, offset int) (roots []ArticleEntry)

func (*PostgresDatabase) GetLastDaysPosts

func (self *PostgresDatabase) GetLastDaysPosts(n int64) (posts []PostEntry)

func (*PostgresDatabase) GetLastDaysPostsForGroup

func (self *PostgresDatabase) GetLastDaysPostsForGroup(newsgroup string, n int64) (posts []PostEntry)

func (*PostgresDatabase) GetLastPostedPostModels

func (self *PostgresDatabase) GetLastPostedPostModels(prefix string, n int64) (posts []PostModel)

func (*PostgresDatabase) GetMessageIDByCIDR

func (self *PostgresDatabase) GetMessageIDByCIDR(cidr *net.IPNet) (msgids []string, err error)

func (*PostgresDatabase) GetMessageIDByEncryptedIP

func (self *PostgresDatabase) GetMessageIDByEncryptedIP(encaddr string) (msgids []string, err error)

func (*PostgresDatabase) GetMessageIDByHash

func (self *PostgresDatabase) GetMessageIDByHash(hash string) (article ArticleEntry, err error)

func (*PostgresDatabase) GetMessageIDByHeader

func (self *PostgresDatabase) GetMessageIDByHeader(name, val string) (msgids []string, err error)

get message ids of articles with this header name and value

func (*PostgresDatabase) GetMessageIDForNNTPID

func (self *PostgresDatabase) GetMessageIDForNNTPID(group string, id int64) (msgid string, err error)

func (*PostgresDatabase) GetMonthlyPostHistory

func (self *PostgresDatabase) GetMonthlyPostHistory() (posts []PostEntry)

func (*PostgresDatabase) GetNNTPIDForMessageID

func (self *PostgresDatabase) GetNNTPIDForMessageID(group, msgid string) (id int64, err error)

func (*PostgresDatabase) GetNNTPPostsInGroup

func (self *PostgresDatabase) GetNNTPPostsInGroup(newsgroup string) (models []PostModel, err error)

func (*PostgresDatabase) GetNewsgroupList

func (self *PostgresDatabase) GetNewsgroupList() (list NewsgroupList, err error)

func (*PostgresDatabase) GetNewsgroupStats

func (self *PostgresDatabase) GetNewsgroupStats() (stats []NewsgroupStats, err error)

func (*PostgresDatabase) GetPageForRootMessage

func (self *PostgresDatabase) GetPageForRootMessage(root_message_id string) (group string, page int64, err error)

func (*PostgresDatabase) GetPagesPerBoard

func (self *PostgresDatabase) GetPagesPerBoard(group string) (int, error)

func (*PostgresDatabase) GetPostAttachmentModels

func (self *PostgresDatabase) GetPostAttachmentModels(prefix, messageID string) (atts []AttachmentModel)

func (*PostgresDatabase) GetPostAttachments

func (self *PostgresDatabase) GetPostAttachments(messageID string) (atts []string)

func (*PostgresDatabase) GetPostModel

func (self *PostgresDatabase) GetPostModel(prefix, messageID string) PostModel

func (*PostgresDatabase) GetPostingStats

func (self *PostgresDatabase) GetPostingStats(gran, begin, end int64) (st PostingStats, err error)

func (*PostgresDatabase) GetPostsBefore

func (self *PostgresDatabase) GetPostsBefore(t time.Time) (msgids []string, err error)

func (*PostgresDatabase) GetPostsInGroup

func (self *PostgresDatabase) GetPostsInGroup(newsgroup string) (models []PostModel, err error)

func (*PostgresDatabase) GetRootPostsForExpiration

func (self *PostgresDatabase) GetRootPostsForExpiration(newsgroup string, threadcount int) (roots []string)

func (*PostgresDatabase) GetThreadAttachments

func (self *PostgresDatabase) GetThreadAttachments(rootmsgid string) (atts []string, err error)

func (*PostgresDatabase) GetThreadModel

func (self *PostgresDatabase) GetThreadModel(prefix, msgid string) (th ThreadModel, err error)

func (*PostgresDatabase) GetThreadReplies

func (self *PostgresDatabase) GetThreadReplies(rootpost string, start, limit int) (repls []string)

func (*PostgresDatabase) GetThreadReplyPostModels

func (self *PostgresDatabase) GetThreadReplyPostModels(prefix, rootpost string, start, limit int) (repls []PostModel)

func (*PostgresDatabase) GetThreadsPerPage

func (self *PostgresDatabase) GetThreadsPerPage(group string) (int, error)

func (*PostgresDatabase) GetUkkoPageCount

func (self *PostgresDatabase) GetUkkoPageCount(perpage int) (count int64, err error)

func (*PostgresDatabase) GroupHasPosts

func (self *PostgresDatabase) GroupHasPosts(group string) bool

func (*PostgresDatabase) HasArticle

func (self *PostgresDatabase) HasArticle(message_id string) bool

check if an article exists

func (*PostgresDatabase) HasArticleLocal

func (self *PostgresDatabase) HasArticleLocal(message_id string) bool

check if an article exists locally

func (*PostgresDatabase) HasNewsgroup

func (self *PostgresDatabase) HasNewsgroup(group string) bool

check if a newsgroup exists

func (*PostgresDatabase) IsExpired

func (self *PostgresDatabase) IsExpired(root_message_id string) bool

func (*PostgresDatabase) MarkModPubkeyCanModGroup

func (self *PostgresDatabase) MarkModPubkeyCanModGroup(pubkey, group string) (err error)

func (*PostgresDatabase) MarkModPubkeyGlobal

func (self *PostgresDatabase) MarkModPubkeyGlobal(pubkey string) (err error)

func (*PostgresDatabase) MarkPubkeyAdmin

func (self *PostgresDatabase) MarkPubkeyAdmin(pubkey string) (err error)

func (*PostgresDatabase) NewsgroupBanned

func (self *PostgresDatabase) NewsgroupBanned(group string) (banned bool, err error)

func (*PostgresDatabase) NukeNewsgroup

func (self *PostgresDatabase) NukeNewsgroup(group string, store ArticleStore)

func (*PostgresDatabase) PubkeyRejected

func (self *PostgresDatabase) PubkeyRejected(pubkey string) (bool, error)

return true if we should drop this message with this frontend pubkey

func (*PostgresDatabase) RegisterArticle

func (self *PostgresDatabase) RegisterArticle(message NNTPMessage) (err error)

register a message with the database

func (*PostgresDatabase) RegisterNewsgroup

func (self *PostgresDatabase) RegisterNewsgroup(group string)

register a new newsgroup

func (*PostgresDatabase) RegisterSigned

func (self *PostgresDatabase) RegisterSigned(message_id, pubkey string) (err error)

func (*PostgresDatabase) RemoveArticle

func (self *PostgresDatabase) RemoveArticle(msgid string) (err error)

func (*PostgresDatabase) RemoveNNTPLogin

func (self *PostgresDatabase) RemoveNNTPLogin(username string) (err error)

func (*PostgresDatabase) SearchByHash

func (self *PostgresDatabase) SearchByHash(prefix, group, text string, chnl chan PostModel) (err error)

func (*PostgresDatabase) SearchQuery

func (self *PostgresDatabase) SearchQuery(prefix, group string, text string, chnl chan PostModel) (err error)

func (*PostgresDatabase) SetConnectionLifetime

func (db *PostgresDatabase) SetConnectionLifetime(seconds int)

func (*PostgresDatabase) SetMaxIdleConns

func (db *PostgresDatabase) SetMaxIdleConns(n int)

func (*PostgresDatabase) SetMaxOpenConns

func (db *PostgresDatabase) SetMaxOpenConns(n int)

func (*PostgresDatabase) ThreadHasReplies

func (self *PostgresDatabase) ThreadHasReplies(rootpost string) bool

func (*PostgresDatabase) UnMarkModPubkeyCanModGroup

func (self *PostgresDatabase) UnMarkModPubkeyCanModGroup(pubkey, group string) (err error)

func (*PostgresDatabase) UnMarkModPubkeyGlobal

func (self *PostgresDatabase) UnMarkModPubkeyGlobal(pubkey string) (err error)

func (*PostgresDatabase) UnbanAddr

func (self *PostgresDatabase) UnbanAddr(addr string) (err error)

assumes it is there

func (*PostgresDatabase) UnbanNewsgroup

func (self *PostgresDatabase) UnbanNewsgroup(group string) (err error)

func (*PostgresDatabase) UnmarkPubkeyAdmin

func (self *PostgresDatabase) UnmarkPubkeyAdmin(pubkey string) (err error)

func (*PostgresDatabase) WhitelistPubkey

func (self *PostgresDatabase) WhitelistPubkey(pubkey string) (err error)

type PostingStats

type PostingStats struct {
	History []PostingStatsEntry
}

type PostingStatsEntry

type PostingStatsEntry struct {
	Groups []NewsgroupStats
}

type ProfilingConfig

type ProfilingConfig struct {
	// contains filtered or unexported fields
}

pprof settings

type RegenFunc

type RegenFunc func(newsgroup, msgid, root string, page int)

regenerate pages function

type SRNdConfig

type SRNdConfig struct {
	// contains filtered or unexported fields
}

func ReadConfig

func ReadConfig() *SRNdConfig

read config files

func (*SRNdConfig) Validate

func (self *SRNdConfig) Validate()

fatals on failed validation

type SpamConfig

type SpamConfig struct {
	// contains filtered or unexported fields
}

type SpamFilter

type SpamFilter struct {
	// contains filtered or unexported fields
}

func (*SpamFilter) Configure

func (sp *SpamFilter) Configure(c SpamConfig)

func (*SpamFilter) Enabled

func (sp *SpamFilter) Enabled(newsgroup string) bool

func (*SpamFilter) MarkSpam

func (sp *SpamFilter) MarkSpam(msg io.Reader) (err error)

feed spam subsystem a spam post

func (*SpamFilter) Rewrite

func (sp *SpamFilter) Rewrite(msg io.Reader, out io.WriteCloser, group string) (result SpamResult)

type SpamResult

type SpamResult struct {
	Err    error
	IsSpam bool
}

type StepModel

type StepModel struct {
	Node *dialogNode
}

func (*StepModel) HasNext

func (self *StepModel) HasNext() bool

func (*StepModel) HasPrevious

func (self *StepModel) HasPrevious() bool

type TemplateDriver

type TemplateDriver interface {
	RenderString(template string, obj interface{}) (string, error)
	Render(template string, obj interface{}, w io.Writer) error
	Ext() string
}

type ThreadModel

type ThreadModel interface {
	BaseModel
	NavbarModel

	SetAllowFiles(allow bool)
	AllowFiles() bool
	OP() PostModel
	Replies() []PostModel
	Board() string
	BoardURL() string
	// return a short version of the thread
	// does not include all replies
	Truncate() ThreadModel

	// number of posts in this thread
	PostCount() int
	// number of images in this thread
	ImageCount() int
	// number of posts excluded during truncation
	// returns 0 if not truncated
	MissingPostCount() int
	// number of images excluded during truncation
	// returns 0 if not truncated
	MissingImageCount() int
	// returns true if this thread has truncated replies
	HasOmittedReplies() bool
	// returns true if this thread has truncated images
	HasOmittedImages() bool

	// update the thread's replies
	Update(db Database)
	// is this thread dirty and needing updating?
	IsDirty() bool
	// mark thread as dirty
	MarkDirty()
	// is the threa bumplocked?
	BumpLock() bool
}

for threads

type ThumbInfo

type ThumbInfo struct {
	Width  int
	Height int
}

type ThumbnailConfig

type ThumbnailConfig struct {
	// contains filtered or unexported fields
}

func (*ThumbnailConfig) FindRulesFor

func (th *ThumbnailConfig) FindRulesFor(mimetype string) (rules []ThumbnailRule)

func (*ThumbnailConfig) GenerateThumbnail

func (th *ThumbnailConfig) GenerateThumbnail(infname, outfname string, env map[string]string) (err error)

func (*ThumbnailConfig) Len

func (th *ThumbnailConfig) Len() int

func (*ThumbnailConfig) Less

func (th *ThumbnailConfig) Less(i, j int) bool

func (*ThumbnailConfig) Load

func (th *ThumbnailConfig) Load(opts map[string]string)

func (*ThumbnailConfig) Swap

func (th *ThumbnailConfig) Swap(i, j int)

type ThumbnailRule

type ThumbnailRule struct {
	AcceptsMimeType string
	CommandTemplate string
}

func (*ThumbnailRule) Accepts

func (th *ThumbnailRule) Accepts(mimetype string) bool

func (*ThumbnailRule) GenerateThumbnail

func (th *ThumbnailRule) GenerateThumbnail(infname, outfname string, env map[string]string) (err error)

type VarnishCache

type VarnishCache struct {
	// contains filtered or unexported fields
}

func (*VarnishCache) Close

func (self *VarnishCache) Close()

func (*VarnishCache) DeleteBoardMarkup

func (self *VarnishCache) DeleteBoardMarkup(group string)

func (*VarnishCache) DeleteThreadMarkup

func (self *VarnishCache) DeleteThreadMarkup(root_post_id string)

try to delete root post's page

func (*VarnishCache) GetHandler

func (self *VarnishCache) GetHandler() CacheHandler

func (*VarnishCache) InvertPagination

func (self *VarnishCache) InvertPagination()

func (*VarnishCache) Regen

func (self *VarnishCache) Regen(msg ArticleEntry)

func (*VarnishCache) RegenAll

func (self *VarnishCache) RegenAll()

regen every newsgroup

func (*VarnishCache) RegenFrontPage

func (self *VarnishCache) RegenFrontPage(pagestart int)

func (*VarnishCache) RegenOnModEvent

func (self *VarnishCache) RegenOnModEvent(newsgroup, msgid, root string, page int)

regenerate pages after a mod event

func (*VarnishCache) RegenerateBoard

func (self *VarnishCache) RegenerateBoard(group string)

regen every page of the board

func (*VarnishCache) SetRequireCaptcha

func (self *VarnishCache) SetRequireCaptcha(required bool)

func (*VarnishCache) Start

func (self *VarnishCache) Start()

Jump to

Keyboard shortcuts

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