package models
import (
"errors"
"time"
"gorm.io/gorm"
)
// Photo table.
type Photo struct {
ID uint64 `gorm:"primaryKey"`
UserID uint64 `gorm:"index"`
Filename string
CroppedFilename string // if cropped, e.g. for profile photo
Filesize int64
Caption string
Flagged bool // photo has been reported by the community
Visibility PhotoVisibility
Gallery bool // photo appears in the public gallery (if public)
Explicit bool // is an explicit photo
CreatedAt time.Time
UpdatedAt time.Time
}
// PhotoVisibility settings.
type PhotoVisibility string
const (
PhotoPublic PhotoVisibility = "public" // on profile page and/or public gallery
PhotoFriends = "friends" // only friends can see it
PhotoPrivate = "private" // private
// CreatePhoto with most of the settings you want (not ID or timestamps) in the database.
func CreatePhoto(tmpl Photo) (*Photo, error) {
if tmpl.UserID == 0 {
return nil, errors.New("UserID required")
p := &Photo{
UserID: tmpl.UserID,
Filename: tmpl.Filename,
CroppedFilename: tmpl.CroppedFilename,
Caption: tmpl.Caption,
Visibility: tmpl.Visibility,
Gallery: tmpl.Gallery,
Explicit: tmpl.Explicit,
result := DB.Create(p)
return p, result.Error
// GetPhoto by ID.
func GetPhoto(id uint64) (*Photo, error) {
p := &Photo{}
result := DB.First(&p, id)
/*
PaginateUserPhotos gets a page of photos belonging to a user ID.
*/
func PaginateUserPhotos(userID uint64, visibility []PhotoVisibility, explicitOK bool, pager *Pagination) ([]*Photo, error) {
var p = []*Photo{}
var explicit = []bool{false}
if explicitOK {
explicit = []bool{true, false}
query := DB.Where(
"user_id = ? AND visibility IN ? AND explicit IN ?",
userID,
visibility,
explicit,
).Order(
pager.Sort,
// Get the total count.
query.Model(&Photo{}).Count(&pager.Total)
result := query.Offset(
pager.GetOffset(),
).Limit(pager.PerPage).Find(&p)
// CountExplicitPhotos returns the number of explicit photos a user has (so non-explicit viewers can see some do exist)
func CountExplicitPhotos(userID uint64, visibility []PhotoVisibility) (int64, error) {
"user_id = ? AND visibility IN ? AND explicit = ?",
true,
var count int64
result := query.Model(&Photo{}).Count(&count)
return count, result.Error
// PaginateGalleryPhotos gets a page of all public user photos for the site gallery. Admin view
// returns ALL photos regardless of Gallery status.
func PaginateGalleryPhotos(adminView bool, explicitOK bool, pager *Pagination) ([]*Photo, error) {
var (
p = []*Photo{}
query *gorm.DB
// Admin view: get ALL PHOTOS on the site, period.
if adminView {
query = DB
} else {
query = DB.Where(
"visibility = ? AND gallery = ? AND explicit IN ?",
PhotoPublic,
query = query.Order(pager.Sort)
result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&p)
// Save photo.
func (p *Photo) Save() error {
result := DB.Save(p)
return result.Error
// Delete photo.
func (p *Photo) Delete() error {
result := DB.Delete(p)