app

package
v0.0.0-...-69ec8c5 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2017 License: MIT Imports: 39 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// PostStatusDraft not public visible yet
	PostStatusDraft = data.PostStatusDraft
	// PostStatusPublished publicly visible
	PostStatusPublished = data.PostStatusPublished
	//PostStatusClosed not searchable but link is still valid
	PostStatusClosed = data.PostStatusClosed
)
View Source
const (
	PostFormatStandard = "standard"
	PostFormatArticle  = "article"
	PostFormatGallery  = "gallery"
	PostFormatPoster   = "poster"
)

PostFormat is the types of formats available for posts

View Source
const (
	PostSearchSortNone           = data.PostSearchSortNone
	PostSearchPriceSortHighToLow = data.PostSearchPriceSortHighToLow
	PostSearchPriceSortLowToHigh = data.PostSearchPriceSortLowToHigh
)

PostSort sets the sort order or post search results

View Source
const (

	//UsernameSelf is the username that is reserved for self access
	UsernameSelf = "me"

	//UserForgotPasswordPath is the url path used in building the forgot password url
	UserForgotPasswordPath = "forgotpassword"
	//UserConfirmEmailPath is the url path used in building the confirm email url
	UserConfirmEmailPath = "confirmemail"
)
View Source
const AnnouncementTown = data.AnnouncementTown

AnnouncementTown is the key of the townsourced announcements town

View Source
const (
	// PostMaxImages is the max number of images in a post
	PostMaxImages = 10
)
View Source
const (

	//TownInviteAcceptPath is the url path used in building the forgot password url
	TownInviteAcceptPath = "towninvite"
)

Variables

View Source
var (
	// ErrCommentNoUser is the error returned when no use is specified
	ErrCommentNoUser = fail.New("You must be logged in to comment.")
	// ErrCommentEmpty is when there is no comment text
	ErrCommentEmpty = fail.New("Your comment must contain some text")
	// ErrCommentTooLong is when the comment is too long
	ErrCommentTooLong = fail.New("Your comment is too long. The max length is " + strconv.Itoa(commentMaxLength))
	// ErrCommentNotAllowed is when comments aren't allowed on a specific post
	ErrCommentNotAllowed = fail.New("Commenting is not allowed on this post.")
	// ErrCommentPostNotPublished is when a comment has been applied to a non-published post
	ErrCommentPostNotPublished = fail.New("This post is not published, and cannot be commented on.")
)
View Source
var (
	// ErrImageNotFound is the error returned when an image is not found
	ErrImageNotFound = &fail.Fail{
		Message:    "Image not found",
		HTTPStatus: http.StatusNotFound,
	}
	// ErrImageTooLarge is returned with the passed in image is too large
	ErrImageTooLarge = &fail.Fail{
		Message:    "The uploaded image is too large.  The max size is 5 MB",
		HTTPStatus: http.StatusRequestEntityTooLarge,
	}

	// ErrImageInvalidType is when the content type of the image is not supported
	ErrImageInvalidType = fail.New("Unsupported image type, please use a jpeg, png, or gif")

	// ErrImageNotOwner is when someone who is not the owner of the image is trying to modify it
	ErrImageNotOwner = fail.New("You cannot update an image you are not the owner of")

	// ErrImageDecodeError is when the image data can't be decoded properly
	ErrImageDecodeError = fail.New("The uploaded image cannot be decoded properly based on the content type")
)
View Source
var (
	//ErrPostNoTitle is the error when a post is created without a title
	ErrPostNoTitle = fail.New("Title is required for a new post")
	//ErrPostLongTitle is the error when a post is created without a title
	ErrPostLongTitle = fail.New("The Title is too long. The max is " + strconv.Itoa(postMaxTitle))
	//ErrPostNoContent is the error when a post is created without content
	ErrPostNoContent = fail.New("Post is empty.  Post content is required")
	//ErrPostBadCategory is the error when a post is created with an invalid category
	ErrPostBadCategory = fail.New("Invalid category")
	//ErrPostBadStatus is the error when a post is created with an invalid status
	ErrPostBadStatus = fail.New("Invalid status")
	//ErrPostBadFormat is the error when a post is created with an invalid format
	ErrPostBadFormat = fail.New("Invalid format")
	//ErrPostInvalidTown is the error when a post is created with an invalid town
	ErrPostInvalidTown = fail.New("One or more towns are invalid for the post")
	//ErrPostNoTown is the error when a post is created without a town
	ErrPostNoTown = fail.New("No town was specified for the post")
	//ErrPostTooManyImages is the error when a post is created with too many images
	ErrPostTooManyImages = fail.New("Too many images associated to this post.  The max is " +
		strconv.Itoa(PostMaxImages))
	//ErrPostNotOwner is the error when a post is edited by someone who isn't the creator of the post
	ErrPostNotOwner = fail.New("You cannot edit this post because you did not create it.")
	//ErrPostNotFound is an error when a specific post cannot be found
	ErrPostNotFound = fail.New("A Post cannot be found with the key specified")
	//ErrPostNotDraft is an error when trying to update a post that isn't in a draft status
	ErrPostNotDraft = fail.New("You cannot update a post that isn't in draft status")
	//ErrPostNotClosed is an error when trying to reopen a post that isn't in a closed status
	ErrPostNotClosed = fail.New("You cannot ReOpen a post that isn't in closed status")
	//ErrPostNotPublished is an error when trying to unpublish a post that isn't in a published status
	ErrPostNotPublished = fail.New("You cannot Unpublish a post that isn't in a published status")
	//ErrPostNoFeature is an error when no featured image is present
	ErrPostNoFeature = fail.New("A post must contain a featured image.  Please choose one.")
	//ErrPostEditExpired is when the edit period has passed for a published post
	ErrPostEditExpired = fail.New(fmt.Sprintf("A post can only be unpublished within %v after it's been published.",
		postReEditDuration))
)
View Source
var (
	//ErrTownExists is the error returned when a town already exists
	ErrTownExists = fail.New("A town already exists with the given url path, please choose another.")
	//ErrTownNotFound is the error returned when a town isn't found with the given key
	ErrTownNotFound = fail.New("Town not found")
	//ErrTownNotMod is the error returned when a user is trying to update a town, but they aren't a moderator
	ErrTownNotMod = fail.New("You cannot update this town because you are not currently a moderator of it.")
	//ErrTownDescriptionMax is the error when a town's description is too long
	ErrTownDescriptionMax = fail.New("A town's description can only be " + strconv.Itoa(townDescriptionMax) + " characters long.")
	//ErrTownNameMax is the error when a town's name is too long
	ErrTownNameMax = fail.New("A town's name can only be " + strconv.Itoa(townNameMax) + " characters long.")

	//ErrTownNotPrivate is the error when a Private update is made to a non-private town
	ErrTownNotPrivate = fail.New("You cannot make invite changes to a non-private town.")
	//ErrTownNoInvite is the error when a user tries to join a private town without an invite
	ErrTownNoInvite = fail.New("You cannot join this town because it is marked as private, and you do not currently have an invite.")
)
View Source
var (
	// ErrUserLogonFailure is when a user fails a login attempt
	ErrUserLogonFailure = fail.New("Invalid user and / or password")
	// ErrUserExists is when a user already exists
	ErrUserExists = fail.New("User already exists")
	//ErrUserEmailExists is when a particular email address is already in use
	ErrUserEmailExists = fail.New("Email already in use")
	// ErrUserNotFound is when a user is not found
	ErrUserNotFound = fail.New("User not found")
	// ErrUserEmailNotFound is when a user is not found by the given email
	ErrUserEmailNotFound = fail.New("No user is was found with this email address")
	// ErrUserPassShort is when a users password is too short
	ErrUserPassShort = fail.New(fmt.Sprintf("Invalid password.  Your password must be at least %d characters long",
		passwordMinLength))

	// ErrUserNeedUsername is when a townsourced user doesn't exist for this 3rdparty credential, and a new
	//  username is needed to create the user
	ErrUserNeedUsername = fail.New("Username needed")

	// ErrUserNoDisconnect is when a user can't disconnect their credentials from a 3rd party like twitter because they have
	// no other authentication method
	ErrUserNoDisconnect = fail.New("Can't disconnect user because there is no other way to log in")

	// ErrUserPrivatePosts is returned when trying to view posts that a user does not have permissions to see
	ErrUserPrivatePosts = fail.New("You do not have permissions to view these posts")
	// ErrUserInvalidEmailToken is returned when a user tries to reset a password with an invalid or expired reset token
	ErrUserInvalidEmailToken = fail.New("This email token is invalid or has expired")
)
View Source
var ErrNotAdmin = fail.New("You do not have access.")

ErrNotAdmin is when a user fails a login attempt

View Source
var ErrNotificationInvalidUser = fail.New("Invalid recipient user for the notification")

ErrNotificationInvalidUser is the error returned when a notification is sent to an invalid user

View Source
var ErrRequestMax = &fail.Fail{
	Message:    "Too many requests are being made.",
	HTTPStatus: 429,
}

ErrRequestMax is when too many requests are attempted

View Source
var ErrSessionInvalid = fail.New("Invalid or expired session")

ErrSessionInvalid is returned when a sesssion is invalid or expired

View Source
var (
	//ErrShareURL is the error returned when the share URL could not be retrieved
	ErrShareURL = fail.New("The URL could not be retrieved or processed")
)

Functions

func AttemptRequest

func AttemptRequest(id string, reqType RequestType) error

AttemptRequest logs a new attempt for the given ip address / or session ID of the given type, and waits appropriately if they are exceeding the rate limit for the type

func ConfirmEmail

func ConfirmEmail(token string) error

ConfirmEmail confirms via the passed in token that a user's email address is working, in that they must have recieved the email containing the token URL.

func ContactMessage

func ContactMessage(fromEmail, toEmail, subject, message string) error

ContactMessage send a contact message email to the townsourced info inbox

func FacebookAppID

func FacebookAppID() string

FacebookAppID is the facebook appID for townsourced

func ForgotPassword

func ForgotPassword(usernameOrEmail string) error

ForgotPassword is when a user forgets their password and needs to be sent a reset password email

func GoogleOpenIDConfig

func GoogleOpenIDConfig() (clientID, authURL string, err error)

GoogleOpenIDConfig retrieves the open ID connection information

func Halt

func Halt(msg string, a ...interface{})

Halt cleanups the townsourced app, and shuts it down as clean as possible logging the passed in message, and printing it to the stderr

func Init

func Init(cfg *Config, hostname, siteURL, runningDir string) error

Init initializes the application layer

func PostGetByLocation

func PostGetByLocation(longitude, latitude, milesDistant float64, category string, since time.Time,
	limit int) ([]Post, []Town, error)

PostGetByLocation retrieves posts based on the passed in location information

func Random

func Random(bits int) string

Random returns a random, url safe value of the bit length passed in

func RetrievePasswordToken

func RetrievePasswordToken(token string) (data.Key, error)

RetrievePasswordToken retrieves a previously requested password token

func ThirdPartyStateNew

func ThirdPartyStateNew(returnURL, provider string) (string, error)

ThirdPartyStateNew generates a new 3rdparty state tracking token.

func TwitterGetLoginURL

func TwitterGetLoginURL(redirectURL, stateToken string) (string, error)

TwitterGetLoginURL requests a new oauth token for use with sign in with twitter

func UserEmailExists

func UserEmailExists(email string) error

UserEmailExists checks if the passed in email is already in use

Types

type AdminStats

type AdminStats struct {
	UserCount      int `json:"userCount"`
	UserCountTrend []struct {
		Count int       `json:"count" gorethink:"reduction"`
		Date  time.Time `json:"date" gorethink:"group"`
	} `json:"userCountTrend"`
	UserLast []*User `json:"userLast"`

	TownCount      int `json:"townCount"`
	TownCountTrend []struct {
		Count int       `json:"count" gorethink:"reduction"`
		Date  time.Time `json:"date" gorethink:"group"`
	} `json:"townCountTrend"`
	TownLast []*Town `json:"townLast"`

	PostCount      int `json:"postCount"`
	PostCountTrend []struct {
		Count int       `json:"count" gorethink:"reduction"`
		Date  time.Time `json:"date" gorethink:"group"`
	} `json:"postCountTrend"`
	PostLast []*Post `json:"postLast"`
}

AdminStats holds the stats presented on the admin page

func AdminStatsGet

func AdminStatsGet(who *User, since time.Time) (*AdminStats, error)

AdminStatsGet retrieves current admin page stats Any errors will be returned as failures as it is assumed the user is an admin and can view full errors

type Comment

type Comment struct {
	Key      data.UUID `json:"key,omitempty" gorethink:",omitempty"`
	PostKey  data.UUID `json:"postKey,omitempty" gorethink:",omitempty"`
	Parent   data.UUID `json:"parent,omitempty" gorethink:",omitempty"`
	Username data.Key  `json:"username,omitempty" gorethink:",omitempty"`
	Comment  string    `json:"comment,omitempty" gorethink:",omitempty"`
	data.Version
	// contains filtered or unexported fields
}

Comment is a comment on a post. A comment is associated to one post, and may have a parent comment so comments can be nested conversations

func CommentGet

func CommentGet(key data.UUID) (*Comment, error)

CommentGet retrieves a single comment

func CommentNew

func CommentNew(who *User, post *Post, comment string) (*Comment, error)

CommentNew adds a new root comment on a post

func (*Comment) ParentComment

func (c *Comment) ParentComment() (*Comment, error)

ParentComment retrieves the comments parent

func (*Comment) Post

func (c *Comment) Post() (*Post, error)

Post retrieves the root post for a given comment

func (*Comment) Reply

func (c *Comment) Reply(who *User, comment string) (*Comment, error)

Reply relies to a specific comment

func (*Comment) User

func (c *Comment) User() (*User, error)

User returns the user on a given comment

type CommentTree

type CommentTree struct {
	Comment
	Children    []CommentTree `json:"children,omitempty" gorethink:",omitempty"`
	HasChildren bool          `json:"hasChildren,omitempty" gorethink:",omitempty"`
	More        bool          `json:"more,omitempty" gorethink:",omitempty"` // more children exist
}

CommentTree is a tree of comments including their children and a "HasChildren" tag if children exist that weren't retrieved.

func CommentGetTree

func CommentGetTree(key data.UUID, limit int, sort string) (*CommentTree, error)

CommentGetTree retrieves a single comment and it's child comments

func CommentsGet

func CommentsGet(post *Post, parent *Comment, from, limit int, sort string) (comments []CommentTree, more bool, err error)

CommentsGet retrieves comments from a given post or parent comment

type Config

type Config struct {
	HTTPClientTimeout string `json:"httpClientTimeout"`
	DevMode           bool   `json:"-"`
	TestMode          bool   `json:"-"`
	TaskQueueSize     uint   `json:"taskQueueSize"`
	TaskPollTime      string `json:"taskPollTime"`
}

Config are the config values for starting up the application layer

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns the default configuration for the app layer

type Help

type Help struct {
	Key      data.Key `json:"key"`
	Title    string   `json:"title"`
	Document string   `json:"document"`
}

Help is a help document entry

func HelpGet

func HelpGet(key data.Key) (*Help, error)

HelpGet Retrieves a help document

type IPLocation

type IPLocation struct {
	IPFrom      uint64  `json:"-"`
	IPTo        uint64  `json:"-"`
	CountryCode string  `json:"-"`
	RegionName  string  `json:"region,omitempty"`
	CityName    string  `json:"city,omitempty"`
	Latitude    float64 `json:"latitude,omitempty"`
	Longitude   float64 `json:"longitude,omitempty"`
}

IPLocation is the data structure from the IP2Location csv DB

func IPToLocation

func IPToLocation(ipAddress string) (*IPLocation, error)

IPToLocation returns a location for the passed in IP Address

type Image

type Image struct {
	Key data.UUID `json:"key,omitempty" gorethink:",omitempty"`

	OwnerKey    data.Key `json:"ownerKey,omitempty" gorethink:",omitempty"`
	ContentType string   `json:"contentType,omitempty" gorethink:",omitempty"`

	// whether or not the image is used by a post or elsewhere
	// images not in use will be cleaned up by a task
	InUse bool `json:"-"`
	data.Version

	Data            []byte `json:"-" gorethink:",omitempty"` // full image
	ThumbData       []byte `json:"-" gorethink:",omitempty"` // thumbnail image
	PlaceholderData []byte `json:"-" gorethink:",omitempty"` // Placeholder image small, and downloads quick
	// contains filtered or unexported fields
}

Image is a user uploaded image for use in posts, or other items

func ImageGet

func ImageGet(key data.UUID) (*Image, error)

ImageGet retrieves an image by it's key

func ImageGetPlaceholder

func ImageGetPlaceholder(key data.UUID) (*Image, error)

ImageGetPlaceholder retrieves an image by it's key

func ImageGetThumb

func ImageGetThumb(key data.UUID) (*Image, error)

ImageGetThumb retrieves an image by it's key

func ImageNew

func ImageNew(owner *User, contentType string, reader io.ReadCloser) (img *Image, err error)

ImageNew inserts a new image into the database closes the reader when finished

func (*Image) Etag

func (i *Image) Etag() string

Etag returns an appropriate string to use as an HTTP etag, or database version

func (*Image) ReadSeeker

func (i *Image) ReadSeeker() io.ReadSeeker

ReadSeeker returns a ReadSeeker for the available image data uses the highest quality image data available

type InviteRequest

type InviteRequest struct {
	Who  data.Key  `json:"who,omitempty"`
	When time.Time `json:"when,omitempty"`
}

InviteRequest contains a request for invitation to a Private town

type LogEntry

type LogEntry struct {
	Time    time.Time
	Fields  map[string]interface{}
	Level   string
	Message string
}

LogEntry is an entry in the townsourced log

type LogHook

type LogHook struct {
}

LogHook is a hook for logging townsourced errors in the database

func (*LogHook) Fire

func (l *LogHook) Fire(entry *logrus.Entry) error

Fire implements the logrus.Hook interface for LogHook

func (*LogHook) Levels

func (l *LogHook) Levels() []logrus.Level

Levels implements the logrus.Hook interface for LogHook

type MessageTemplate

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

MessageTemplate is a templated message with a subject and body used for notifications and emails

func (*MessageTemplate) Execute

func (m *MessageTemplate) Execute(data interface{}) (subject, body string, err error)

Execute executes the given message with the passed in data

type Moderated

type Moderated struct {
	Town   data.Key `json:"town,omitempty" gorethink:",omitempty"`
	Who    data.Key `json:"who,omitempty" gorethink:",omitempty"`
	Reason string   `json:"reason,omitempty" gorethink:",omitempty"`
}

Moderated contains which moderators have moderated this post and their reason

type Moderator

type Moderator struct {
	Start      time.Time `json:"start,omitempty" gorethink:",omitempty"`
	End        time.Time `json:"end,omitempty" gorethink:",omitempty"`
	Username   data.Key  `json:"username,omitempty" gorethink:",omitempty"`
	InviteSent time.Time `json:"inviteSent,omitempty" gorethink:",omitempty"`
}

Moderator is the record of moderator's start and end dates moderating a town used to determine any profit sharing for the town

type Notification

type Notification struct {
	Key      data.UUID `json:"key,omitempty" gorethink:",omitempty"`
	Username data.Key  `json:"username,omitempty" gorethink:",omitempty"`
	From     data.Key  `json:"from,omitempty" gorethink:",omitempty"`
	Subject  string    `json:"subject,omitempty" gorethink:",omitempty"`
	Message  string    `json:"message,omitempty" gorethink:",omitempty"`
	When     time.Time `json:"when,omitempty" gorethink:",omitempty"`
	Read     bool      `json:"read,omitempty"`
}

Notification is a notification sent to a user. This can be a message from townsourced telling them they've just gotten a comment on their post, or a direct message from another user, or anything that needs to be sent to a user

func (*Notification) MarkRead

func (n *Notification) MarkRead()

MarkRead marks the notification as read

func (*Notification) Update

func (n *Notification) Update() error

Update updates a specific notification with all the changes that have been applied to it

type Post

type Post struct {
	Key             data.UUID           `json:"key,omitempty" gorethink:",omitempty"`
	Title           string              `json:"title,omitempty" gorethink:",omitempty"`
	Content         string              `json:"content,omitempty" gorethink:",omitempty"`
	Category        string              `json:"category,omitempty" gorethink:",omitempty"`
	TownKeys        []data.Key          `json:"townKeys,omitempty"`
	Images          []data.UUID         `json:"images,omitempty"`
	FeaturedImage   data.UUID           `json:"featuredImage,omitempty" gorethink:",omitempty"`
	Status          string              `json:"status,omitempty" gorethink:",omitempty"`
	Format          string              `json:"format,omitempty" gorethink:",omitempty"`
	Creator         data.Key            `json:"creator,omitempty" gorethink:",omitempty"`
	Moderation      []Moderated         `json:"moderation,omitempty"`
	HashTags        []data.Key          `json:"hashTags,omitempty"`
	Prices          []float64           `json:"prices,omitempty"`
	Reported        map[data.Key]string `json:"reported,omitempty" gorethink:",omitempty"`
	AllowComments   bool                `json:"allowComments,omitempty"`
	NotifyOnComment bool                `json:"notifyOnComment,omitempty"`
	Published       time.Time           `json:"published,omitempty" gorethink:",omitempty"`
	StatusLine      string              `json:"statusLine,omitempty" gorethink:","`

	data.Version
	// contains filtered or unexported fields
}

Post is a townsourced post, it can exist in multiple towns as once

func PostGet

func PostGet(key data.UUID) (*Post, error)

PostGet retrieves a specific post

func PostGetByTowns

func PostGetByTowns(who *User, townKeys []data.Key, category string, since time.Time, limit int,
	showModerated bool) ([]Post, error)

PostGetByTowns returns the list of published posts by passed in town keys if category is blank, then returns all categories

func PostNew

func PostNew(title, content, category, format string, creator *User, towns []data.Key, images []data.UUID, featuredImage data.UUID,
	allowComments, notifyOnComment, draft bool) (*Post, error)

PostNew creates a new Post

func PostSearch

func PostSearch(who *User, searchText string, tags []string, towns []Town, category string,
	from, limit int, postSort string, minPrice, maxPrice float64, showModerated bool) ([]Post, error)

PostSearch searches for post in the passed in towns

func Share

func Share(who *User, strURL, title, content, useragent string, town data.Key, images []string, imageKeys []data.UUID,
	selector string) (*Post, error)

Share processes a share call to add a temporary post from a url or from the passed in params it'll generate a draft post from the passed in params and return that post Note this function does not save the post in the database, it only returns a temporary post object from the passed in variables if full then we'll attempt to convert the entire page to markdown in the post

func (*Post) CanEdit

func (p *Post) CanEdit(who *User) error

CanEdit returns nil if the passed in user can edit otherwise it returns an error showing why the user can't edit

func (*Post) Close

func (p *Post) Close(who *User) error

Close closes a post to hide it from searches and from the main listing but the post is still accessible from a direct link

func (*Post) Etag

func (p *Post) Etag() string

Etag returns an appropriate string to use as an HTTP etag

func (*Post) Moderate

func (p *Post) Moderate(town *Town, who *User, reason string) error

Moderate puts a post into moderation for a specific town, and makes it not publically visible for the given town

func (*Post) Publish

func (p *Post) Publish(who *User) error

Publish publishes the post to make it visible publically

func (*Post) RawContent

func (p *Post) RawContent() string

RawContent returns the content of the post with markdown and new lines removed For use in description meta tags, and other areas where just the contents and not the styling is needed

func (*Post) ReOpen

func (p *Post) ReOpen(who *User) error

ReOpen reopens a post that has been closed

func (*Post) RemoveModeration

func (p *Post) RemoveModeration(town *Town, who *User) error

RemoveModeration removes moderation for a specific town, i.e. makes it publically visible again

func (*Post) Report

func (p *Post) Report(who *User, reason string) error

Report sends a notification to all of the moderators of the towns the post is a part of usually to notify them of why the post should be moderated

func (*Post) SetAllowComments

func (p *Post) SetAllowComments(who *User, allowComments bool) error

SetAllowComments sets the allow comments flag on a draft version of a post

func (*Post) SetCategory

func (p *Post) SetCategory(who *User, category string) error

SetCategory sets the category on a draft version of a post

func (*Post) SetContent

func (p *Post) SetContent(who *User, content string) error

SetContent sets the content on a draft version of a post

func (*Post) SetFormat

func (p *Post) SetFormat(who *User, format string) error

SetFormat sets the format on a draft version of a post

func (*Post) SetImages

func (p *Post) SetImages(who *User, images []data.UUID, featuredImage data.UUID) error

SetImages updates a post's set of images

func (*Post) SetNotifyOnComment

func (p *Post) SetNotifyOnComment(who *User, notifyOnComment bool) error

SetNotifyOnComment sets the notify on comment flag on a post can be done on already published posts

func (*Post) SetTitle

func (p *Post) SetTitle(who *User, title string) error

SetTitle sets the title on a draft version of a post

func (*Post) SetTowns

func (p *Post) SetTowns(who *User, towns []data.Key) error

SetTowns sets the towns a draft post is associated to

func (*Post) SetVer

func (p *Post) SetVer(verTag string)

SetVer prepares the post data for an update based on the passed in vertag, if the vertag doesn't match the current record, then the update won't complete

func (*Post) Towns

func (p *Post) Towns() ([]*Town, error)

Towns returns the towns a post is associated to

func (*Post) Unpublish

func (p *Post) Unpublish(who *User) error

Unpublish puts a post back into draft status so it can be edited. This can only be done within a certain amount of time

func (*Post) Update

func (p *Post) Update() error

Update updates the post

func (*Post) Visible

func (p *Post) Visible(u *User) (bool, error)

Visible is whether or not a given post is visible to the passed in user

type RegexpReason

type RegexpReason struct {
	Regexp string `json:"regexp,omitempty"`
	Reason string `json:"reason,omitempty"`
}

RegexpReason is a reason for moderation tied to a regular expression

type RequestAttempt

type RequestAttempt struct {
	ID   string // ID is a unique identifier for the requestor, e.g. IP address, sessionID, or API key
	Type RequestType
	When time.Time
}

RequestAttempt is a client request of some type Login attempt, town submission, user creation, etc Used to prevent rapid requests / attempts

type RequestType

type RequestType struct {
	Type         string
	FreeAttempts int           //Number of attempts before delay occurs
	Scale        time.Duration //attempt # * scale = delay
	Range        time.Duration // Range to look for previous requests
	MaxWait      time.Duration //Max wait time that can be accumulated
}

RequestType is a type of request that needs to be rate limited

type Session

type Session struct {
	Key       string //userkey+sessionID - not a traditional data.Key
	UserKey   data.Key
	SessionID string
	CSRFToken string
	Valid     bool
	Expires   time.Time
	When      time.Time
	IPAddress string
	UserAgent string
	// contains filtered or unexported fields
}

Session is an authenticated session into townsourced

func SessionGet

func SessionGet(sessionKey string) (*Session, error)

SessionGet retrieves a session

func SessionNew

func SessionNew(user *User, expires time.Time, ipAddress, userAgent string) (*Session, error)

SessionNew generates a new session for the passed in user

func (*Session) Logout

func (s *Session) Logout() error

Logout logs out of a session

func (*Session) ResetCSRF

func (s *Session) ResetCSRF() error

ResetCSRF will generate a new CRSF token, an update the session with it allows CSRF token to change more than once per session if need be

func (*Session) User

func (s *Session) User() (*User, error)

User Returns the user for the given session, includes private info

type Task

type Task struct {
	Key       data.UUID `gorethink:",omitempty"`
	Type      string    `gorethink:",omitempty"`
	Owner     data.Key
	Priority  uint          `gorethink:",omitempty"`
	NextRun   time.Time     `gorethink:",omitempty"`
	Variables []interface{} `gorethink:",omitempty"`
	Created   time.Time     `gorethink:",omitempty"`
	Failed    time.Time     `gorethink:",omitempty"`
	Completed time.Time     `gorethink:",omitempty"`
	Closed    bool
	Retry     int
	// contains filtered or unexported fields
}

Task is a unit of work stored in the database, corresponds to a pre-registered tasker interface

func (*Task) Run

func (t *Task) Run()

Run runs the given task exported in case this needs to be run from an external process

type Tasker

type Tasker interface {
	Type() string                      // Type of the task
	Priority() uint                    // Task Priority so high priority tasks (1) will be run before low priority tasks (5)
	NextRun() time.Time                // detrmines when to next run this task, a zero time means the task is complete, and is not run again
	Do(variables ...interface{}) error // The task to be run
	Retry() int                        // Number of times to retry this task before marking it as failed, return -1 will retry forever
}

Tasker is a unit of work that can be scheduled or queued to run later by the task runner tasks should be atomic operations, and if a task fails, it should leave no paritially commited data behind

type ThirdPartyState

type ThirdPartyState struct {
	Token     string `json:"token" gorethink:",omitempty"`
	ReturnURL string `json:"returnURL" gorethink:",omitempty"`
	Provider  string `json:"provider" gorethink:",omitempty"`
}

ThirdPartyState is used both for getting the user back to where they were when they logged in, as well as CSRF protection

func ThirdPartyStateGet

func ThirdPartyStateGet(token string) (*ThirdPartyState, error)

ThirdPartyStateGet retrieves the 3rdparty user state from the passed in token

type Town

type Town struct {
	Key data.Key `json:"key,omitempty"` //Unique Url Name, case insensitive

	Name        string      `json:"name,omitempty"`
	Description string      `json:"description,omitempty"`
	Information string      `json:"information,omitempty"` //markdown page for detailed information
	Moderators  []Moderator `json:"moderators,omitempty"`
	CreatorKey  data.Key    `json:"creatorKey,omitempty" gorethink:",omitempty"`

	HeaderImage data.UUID `json:"headerImage,omitempty"`
	Color       string    `json:"color,omitempty"`
	Location    rt.Point  `json:"location,omitempty" gorethink:",omitempty"`

	//Private towns are where only invitees can post or join the town, and only members can view
	// Note that you may be a member, and not an invitee, as in the announcements town
	Private        bool            `json:"private,omitempty"`
	Invites        []data.Key      `json:"invites,omitempty"`
	InviteRequests []InviteRequest `json:"inviteRequests,omitempty"`
	AutoModerator  struct {
		Categories   []string       `json:"categories,omitempty"`   //automod posts in these categories
		MinUserDays  uint           `json:"minUserDays,omitempty"`  //automod if posted by user younger than x days MaxNumLinks  uint           `json:"maxNumLinks,omitempty"`  //automod if has more than x links in post
		MaxNumLinks  uint           `json:"maxNumLinks,omitempty"`  //automod if has more than x links in post
		Users        []data.Key     `json:"users,omitempty"`        //automod if post is submitted by one of these users
		RegexpReject []RegexpReason `json:"regexpReject,omitempty"` //automod if regexp matches with given reason

	} `json:"autoModerator,omitempty"`

	Population int `json:"population,omitempty" gorethink:",omitempty"` //Calculated field - not pulled from document

	data.Version
}

Town is a community in townsourced

func IPToTowns

func IPToTowns(ipAddress string, limit int) ([]Town, error)

IPToTowns returns the nearest registered towns to the given IP address

func TownAcceptEmailInvite

func TownAcceptEmailInvite(invitee *User, token string) (*Town, error)

TownAcceptEmailInvite associates an email invite to a user and adds them to the invite list

func TownGet

func TownGet(key data.Key) (*Town, error)

TownGet retrieves a town

func TownNew

func TownNew(key data.Key, name, description string, creator *User, longitude, latitude float64, private bool) (*Town, error)

TownNew creates a new town

func TownSearch

func TownSearch(search string, from, limit int) ([]Town, error)

TownSearch searches for towns by their name or description

func TownSearchArea

func TownSearchArea(northBounds, southBounds, eastBounds, westBounds float64, from, limit int) ([]Town, error)

TownSearchArea retrieves all towns within the passed in area

func TownSearchDistance

func TownSearchDistance(longitude, latitude, milesDistant float64, from, limit int) ([]Town, error)

TownSearchDistance retrieves a town by a passed in location and distance from that location to search

func TownsGet

func TownsGet(keys ...data.Key) ([]Town, error)

TownsGet retrieves a list of towns from the passed in keys

func (*Town) AcceptInviteRequest

func (t *Town) AcceptInviteRequest(who *User, invitee *User) error

AcceptInviteRequest accepts a request for invitation to a private town, removes the request and adds the user to the town

func (*Town) AcceptModeratorInvite

func (t *Town) AcceptModeratorInvite(who *User) error

AcceptModeratorInvite adds a new moderator to the town

func (*Town) AddAutoModCategory

func (t *Town) AddAutoModCategory(who *User, category string) error

AddAutoModCategory adds a category to the auto moderator

func (*Town) AddAutoModRegexp

func (t *Town) AddAutoModRegexp(who *User, expr, reason string) error

AddAutoModRegexp adds a new regular expression to auto moderator

func (*Town) AddAutoModUser

func (t *Town) AddAutoModUser(who *User, username data.Key) error

AddAutoModUser adds a user to the auto moderator

func (*Town) AddInvite

func (t *Town) AddInvite(who *User, invitee *User) error

AddInvite adds an invite to a private town

func (*Town) AddInviteByEmail

func (t *Town) AddInviteByEmail(who *User, emailAddr string) error

AddInviteByEmail adds an invite to a private town by email

func (*Town) CanSearch

func (t *Town) CanSearch(who *User) bool

CanSearch is whether or not the passed in user can run searches against this town e.g. town isn't private or they are a member

func (*Town) InviteModerator

func (t *Town) InviteModerator(who *User, newMod *User) error

InviteModerator sends an invitation to a user that they need to accept before they become a moderator

func (*Town) Invited

func (t *Town) Invited(who *User) bool

Invited checks if the passed in user has an invite to this town Note: this should only be used to check if a user is invited or not Not whether or not posts are or aren't visible in a town FOr the Announcement's town a user is a member, but not invited. They become a member automatically

func (*Town) IsMember

func (t *Town) IsMember(user *User) bool

IsMember tests if the passed in user is a member of the town

func (*Town) IsMod

func (t *Town) IsMod(user *User) bool

IsMod is whether or not the passed in user is an active moderator

func (*Town) Posts

func (t *Town) Posts(who *User, category string, since time.Time, limit int, showModerated bool) ([]Post, error)

Posts returns the posts for the given town

func (*Town) RejectInviteRequest

func (t *Town) RejectInviteRequest(who *User, invitee *User) error

RejectInviteRequest rejects a request for invitation to a private town

func (*Town) RemoveAutoModCategory

func (t *Town) RemoveAutoModCategory(who *User, category string) error

RemoveAutoModCategory removes a category from the auto moderator

func (*Town) RemoveAutoModRegexp

func (t *Town) RemoveAutoModRegexp(who *User, expr string) error

RemoveAutoModRegexp removes a regular expression from the auto moderator

func (*Town) RemoveAutoModUser

func (t *Town) RemoveAutoModUser(who *User, username data.Key) error

RemoveAutoModUser removes a user from the auto moderator

func (*Town) RemoveHeaderImage

func (t *Town) RemoveHeaderImage(who *User) error

RemoveHeaderImage removes the header image for a given town

func (*Town) RemoveInvite

func (t *Town) RemoveInvite(who *User, toRemove *User) error

RemoveInvite removes an invite from a private town

func (*Town) RemoveModerator

func (t *Town) RemoveModerator(who *User, removeMod *User) error

RemoveModerator removes a moderator from a town

func (*Town) RequestInvite

func (t *Town) RequestInvite(who *User) error

RequestInvite requests an invite to be a member of a private town. It sends a PM to all the moderators of the town

func (t *Town) SetAutoModMaxNumLinks(who *User, maxNumLinks uint) error

SetAutoModMaxNumLinks sets the maxiumum number of links allowed in a post to this town

func (*Town) SetAutoModMinUserDays

func (t *Town) SetAutoModMinUserDays(who *User, minUserDays uint) error

SetAutoModMinUserDays sets the minimum days old a user must be to post to this town

func (*Town) SetColor

func (t *Town) SetColor(who *User, newColor string) error

SetColor sets the towns color theme

func (*Town) SetDescription

func (t *Town) SetDescription(who *User, newDescription string) error

SetDescription sets the town's description

func (*Town) SetHeaderImage

func (t *Town) SetHeaderImage(who *User, image *Image, x0, y0, x1, y1 float64) error

SetHeaderImage sets the header image for a given town

func (*Town) SetInformation

func (t *Town) SetInformation(who *User, newInformation string) error

SetInformation sets the town's information panel

func (*Town) SetName

func (t *Town) SetName(who *User, newName string) error

SetName sets the town's name

func (*Town) SetPrivate

func (t *Town) SetPrivate(who *User, private bool) error

SetPrivate sets the town to Private, or removes the private setting

func (*Town) SetVer

func (t *Town) SetVer(verTag string)

SetVer prepares the user data for an update based on the passed in vertag, if the vertag doesn't match the current record, then the update won't complete

func (*Town) Update

func (t *Town) Update() error

Update updates the town

type User

type User struct {
	Username       data.Key        `json:"username,omitempty" gorethink:",omitempty"`
	Email          string          `json:"email,omitempty" gorethink:",omitempty"`
	EmailSearch    string          `json:"-" gorethink:",omitempty"` // for case insensitive searching, sending emails should use the email field
	EmailValidated bool            `json:"emailValidated,omitempty"`
	GoogleID       string          `json:"googleID,omitempty"`
	FacebookID     string          `json:"facebookID,omitempty"`
	TwitterID      string          `json:"twitterID,omitempty"`
	Name           string          `json:"name,omitempty"`
	Password       []byte          `json:"-" gorethink:",omitempty"`
	HasPassword    bool            `json:"hasPassword,omitempty"`
	TownKeys       []data.KeyWhen  `json:"townKeys,omitempty"`
	Badges         []int           `json:"badges,omitempty" gorethink:",omitempty"` // Awards given by townsourced (i.e. 5 year badge)
	Stamps         []data.Key      `json:"stamps,omitempty" gorethink:",omitempty"`
	ProfileImage   data.UUID       `json:"profileImage,omitempty" gorethink:",omitempty"`
	ProfileIcon    data.UUID       `json:"profileIcon,omitempty" gorethink:",omitempty"`
	Admin          bool            `json:"admin,omitempty"` // Only set directly in DB currently
	SavedPosts     []data.UUIDWhen `json:"savedPosts,omitempty"`

	NotifyPost    bool `json:"notifyPost,omitempty"`
	NotifyComment bool `json:"notifyComment,omitempty"`

	EmailPrivateMsg     bool `json:"emailPrivateMsg,omitempty"`
	EmailPostMention    bool `json:"emailPostMention,omitempty"`
	EmailCommentMention bool `json:"emailCommentMention,omitempty"`
	EmailCommentReply   bool `json:"emailCommentReply,omitempty"`
	EmailPostComment    bool `json:"emailPostComment,omitempty"`

	data.Version
	// contains filtered or unexported fields
}

User is a townsourced user

func FacebookNewUser

func FacebookNewUser(username, email, userID, userToken, appToken string) (*User, error)

FacebookNewUser creates a new facebook user with the passed in username and email, using the passed in temporary tokens

func FacebookUser

func FacebookUser(redirectURI, code string) (*User, error)

FacebookUser gets a user (if possible) from the passed in facebook code

func GoogleNewUser

func GoogleNewUser(username, email, googleID, idToken, accessToken string) (*User, error)

GoogleNewUser creates a new google user with the passed in username and email, using the passed in temporary token

func GoogleUser

func GoogleUser(code, redirectURI string) (*User, error)

GoogleUser gets a user (if possible) from the passed in google code

func ResetPassword

func ResetPassword(resetToken, newPass string) (*User, error)

ResetPassword resets a users password from a forgot password request

func TwitterGetUser

func TwitterGetUser(stateToken, verificationCode string) (*User, error)

TwitterGetUser returns a townsourced user (if one exists) associated with the passed in oauth verification code. If a user doesn't yet exist it'll pass back username and email hints for creating a new user

func TwitterNewUser

func TwitterNewUser(username, email, stateToken string) (*User, error)

TwitterNewUser creates a new twitter user with the passed in username and email, using the passed in temporary token

func UserGet

func UserGet(username data.Key) (*User, error)

UserGet returns a user including private information

func UserGetMatch

func UserGetMatch(match string, limit int) ([]User, error)

UserGetMatch returns a all users who's username starts with match

func UserLogin

func UserLogin(usernameOrEmail, password string) (*User, error)

UserLogin logs in a user via their password and either their username or email

func UserNew

func UserNew(username data.Key, email, password string) (*User, error)

UserNew creates a new user

func (*User) AllNotifications

func (u *User) AllNotifications(since time.Time, limit int) ([]Notification, error)

AllNotifications returns all unread notifications for a user

func (*User) ClearPrivate

func (u *User) ClearPrivate()

ClearPrivate clears the private information from the user record

func (*User) Comments

func (u *User) Comments(who *User, since time.Time, limit int) ([]Comment, error)

Comments retrieves the comments made by this user

func (*User) DisconnectFacebook

func (u *User) DisconnectFacebook() error

DisconnectFacebook disconnects this user from Facebook credentials

func (*User) DisconnectGoogle

func (u *User) DisconnectGoogle() error

DisconnectGoogle disconnects this user from Google credentials

func (*User) DisconnectTwitter

func (u *User) DisconnectTwitter() error

DisconnectTwitter disconnects this user from Twitter credentials

func (*User) DisplayName

func (u *User) DisplayName() string

DisplayName returns the users display name. If they haven't specified a name, it'll return the username

func (*User) Etag

func (u *User) Etag() string

Etag returns an appropriate string to use as an HTTP etag

func (*User) GetSavedPosts

func (u *User) GetSavedPosts(who *User, status string, from, limit int) ([]*Post, error)

GetSavedPosts returns a users saved posts

func (*User) JoinTown

func (u *User) JoinTown(town *Town) error

JoinTown joins a user a to a town

func (*User) LeaveTown

func (u *User) LeaveTown(town *Town)

LeaveTown is when a user leaves a town

func (*User) LinkFacebook

func (u *User) LinkFacebook(redirectURI, code string) error

LinkFacebook links a facebook account to an existing user

func (*User) LinkGoogle

func (u *User) LinkGoogle(redirectURI, code string) error

LinkGoogle links a google account to an existing user

func (*User) LinkTwitter

func (u *User) LinkTwitter(stateToken, verificationCode string) error

LinkTwitter links a twitter account to an existing user

func (*User) MarkAllNotificationsAsRead

func (u *User) MarkAllNotificationsAsRead() error

MarkAllNotificationsAsRead marks all unread notifications as read for a specific user

func (*User) Notification

func (u *User) Notification(key data.UUID) (*Notification, error)

Notification will retrieve a specific notification

func (*User) Posts

func (u *User) Posts(who *User, status string, since time.Time, limit int) ([]*Post, error)

Posts returns a users posts since the passed in time

func (*User) RemoveSavedPost

func (u *User) RemoveSavedPost(post *Post)

RemoveSavedPost removes a post from a users saved posts list

func (*User) SavePost

func (u *User) SavePost(post *Post)

SavePost saves / favorites a post to a user

func (*User) SendEmailConfirmation

func (u *User) SendEmailConfirmation() error

SendEmailConfirmation sends an email to validate a users email address

func (*User) SendMessage

func (u *User) SendMessage(to *User, subject, message string) error

SendMessage sends a private message to another user

func (*User) SentNotifications

func (u *User) SentNotifications(since time.Time, limit int) ([]Notification, error)

SentNotifications returns all notifications sent by a user

func (*User) SetEmail

func (u *User) SetEmail(email string, password string) error

SetEmail updates the users email address, requires their current password to be passed in

func (*User) SetName

func (u *User) SetName(name string)

SetName sets the users name

func (*User) SetPassword

func (u *User) SetPassword(currentPass, newPass string) error

SetPassword updates a users password

func (*User) SetProfileImage

func (u *User) SetProfileImage(image *Image, x0, y0, x1, y1 float64) error

SetProfileImage sets the user's profile image to the specified dimensions resizes it to the max profile image size, and creates an icon

func (*User) SetVer

func (u *User) SetVer(verTag string)

SetVer prepares the user data for an update based on the passed in vertag, if the vertag doesn't match the current record, then the update won't complete

func (*User) Towns

func (u *User) Towns() ([]Town, error)

Towns returns the towns a user is a member of

func (*User) UnreadNotificationCount

func (u *User) UnreadNotificationCount() (int, error)

UnreadNotificationCount returns the number of unread notifications for a user

func (*User) UnreadNotifications

func (u *User) UnreadNotifications(since time.Time, limit int) ([]Notification, error)

UnreadNotifications returns all unread notifications for a user

func (*User) Update

func (u *User) Update() error

Update updates the user

Directories

Path Synopsis
Package email is for sending emails for townsourced There are many different transactional email providers, and I expect which ones we use to change in the future, so this package will abstract away all access to those providers so nothing in townsourced should need to change if we change providers API keys will be stored in the private package with the rest of our keys
Package email is for sending emails for townsourced There are many different transactional email providers, and I expect which ones we use to change in the future, so this package will abstract away all access to those providers so nothing in townsourced should need to change if we change providers API keys will be stored in the private package with the rest of our keys

Jump to

Keyboard shortcuts

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