...

Source file src/codeberg.org/tslocum/sriracha/model/model_board.go

Documentation: codeberg.org/tslocum/sriracha/model

     1  package model
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	. "codeberg.org/tslocum/sriracha/util"
     8  )
     9  
    10  type BoardType int
    11  
    12  // Board types.
    13  const (
    14  	TypeImageboard BoardType = 0
    15  	TypeForum      BoardType = 1
    16  )
    17  
    18  func FormatBoardType(t BoardType) string {
    19  	switch t {
    20  	case TypeImageboard:
    21  		return "Imageboard"
    22  	case TypeForum:
    23  		return "Forum"
    24  	default:
    25  		return "Unknown"
    26  	}
    27  }
    28  
    29  type BoardHide int
    30  
    31  const (
    32  	HideNowhere    BoardHide = 0
    33  	HideIndex      BoardHide = 1
    34  	HideOverboard  BoardHide = 2
    35  	HideEverywhere BoardHide = 3
    36  )
    37  
    38  func FormatBoardHide(a BoardHide) string {
    39  	switch a {
    40  	case HideNowhere:
    41  		return "Show everywhere"
    42  	case HideIndex:
    43  		return "Hide from index"
    44  	case HideOverboard:
    45  		return "Hide from overboard"
    46  	case HideEverywhere:
    47  		return "Hide everywhere"
    48  	default:
    49  		return "Unknown"
    50  	}
    51  }
    52  
    53  type BoardLock int
    54  
    55  // Board lock types.
    56  const (
    57  	LockNone   BoardLock = 0
    58  	LockThread BoardLock = 1
    59  	LockPost   BoardLock = 2
    60  	LockStaff  BoardLock = 3
    61  )
    62  
    63  func FormatBoardLock(l BoardLock) string {
    64  	switch l {
    65  	case LockNone:
    66  		return "Allow all"
    67  	case LockThread:
    68  		return "No visitor threads"
    69  	case LockPost:
    70  		return "No visitor posts"
    71  	case LockStaff:
    72  		return "No posts"
    73  	default:
    74  		return "Unknown"
    75  	}
    76  }
    77  
    78  type BoardApproval int
    79  
    80  const (
    81  	ApprovalNone BoardApproval = 0
    82  	ApprovalFile BoardApproval = 1
    83  	ApprovalAll  BoardApproval = 2
    84  )
    85  
    86  func FormatBoardApproval(a BoardApproval) string {
    87  	switch a {
    88  	case ApprovalNone:
    89  		return "None"
    90  	case ApprovalFile:
    91  		return "File"
    92  	case ApprovalAll:
    93  		return "All"
    94  	default:
    95  		return "Unknown"
    96  	}
    97  }
    98  
    99  type BoardIdentifiers int
   100  
   101  const (
   102  	IdentifiersDisable BoardIdentifiers = 0
   103  	IdentifiersBoard   BoardIdentifiers = 1
   104  	IdentifiersGlobal  BoardIdentifiers = 2
   105  )
   106  
   107  func FormatBoardIdentifiers(i BoardIdentifiers) string {
   108  	switch i {
   109  	case IdentifiersDisable:
   110  		return "Disable"
   111  	case IdentifiersBoard:
   112  		return "Board"
   113  	case IdentifiersGlobal:
   114  		return "Global"
   115  	default:
   116  		return "Unknown"
   117  	}
   118  }
   119  
   120  type Board struct {
   121  	ID            int
   122  	Dir           string
   123  	Name          string
   124  	Description   string
   125  	Type          BoardType
   126  	Hide          BoardHide
   127  	Lock          BoardLock
   128  	Approval      BoardApproval
   129  	Reports       bool
   130  	Style         string
   131  	Locale        string
   132  	Delay         int
   133  	MinName       int
   134  	MaxName       int
   135  	MinEmail      int
   136  	MaxEmail      int
   137  	MinSubject    int
   138  	MaxSubject    int
   139  	MinMessage    int
   140  	MaxMessage    int
   141  	MinSizeThread int64
   142  	MaxSizeThread int64
   143  	MinSizeReply  int64
   144  	MaxSizeReply  int64
   145  	ThumbWidth    int
   146  	ThumbHeight   int
   147  	DefaultName   string
   148  	WordBreak     int
   149  	Truncate      int
   150  	Threads       int
   151  	Replies       int
   152  	MaxThreads    int
   153  	MaxReplies    int
   154  	Oekaki        bool
   155  	Backlinks     bool
   156  	Instances     int
   157  	Identifiers   BoardIdentifiers
   158  
   159  	// Calculated fields.
   160  	Uploads []string
   161  	Embeds  []string
   162  	Rules   []string
   163  	Unique  int `diff:"-"`
   164  }
   165  
   166  const (
   167  	DefaultBoardThreads     = 10
   168  	DefaultBoardReplies     = 3
   169  	DefaultBoardMaxName     = 75
   170  	DefaultBoardMaxEmail    = 75
   171  	DefaultBoardMaxSubject  = 75
   172  	DefaultBoardMaxMessage  = 8000
   173  	DefaultBoardWordBreak   = 200
   174  	DefaultBoardDefaultName = "Anonymous"
   175  	DefaultBoardTruncate    = 15
   176  	DefaultBoardMaxSize     = 2097152
   177  	DefaultBoardThumbWidth  = 250
   178  	DefaultBoardThumbHeight = 250
   179  	DefaultBoardInstances   = 1
   180  )
   181  
   182  func NewBoard() *Board {
   183  	return &Board{
   184  		Threads:       DefaultBoardThreads,
   185  		Replies:       DefaultBoardReplies,
   186  		MaxName:       DefaultBoardMaxName,
   187  		MaxEmail:      DefaultBoardMaxEmail,
   188  		MaxSubject:    DefaultBoardMaxSubject,
   189  		MaxMessage:    DefaultBoardMaxMessage,
   190  		DefaultName:   DefaultBoardDefaultName,
   191  		WordBreak:     DefaultBoardWordBreak,
   192  		Truncate:      DefaultBoardTruncate,
   193  		MaxSizeThread: DefaultBoardMaxSize,
   194  		MaxSizeReply:  DefaultBoardMaxSize,
   195  		ThumbWidth:    DefaultBoardThumbWidth,
   196  		ThumbHeight:   DefaultBoardThumbHeight,
   197  		Instances:     DefaultBoardInstances,
   198  	}
   199  }
   200  
   201  func (b *Board) Validate() error {
   202  	switch {
   203  	case b.Dir != "" && !AlphaNumericAndSymbols.MatchString(b.Dir):
   204  		return fmt.Errorf("dir must only consist of letters, numbers, hyphens and underscores")
   205  	case strings.TrimSpace(b.Name) == "":
   206  		return fmt.Errorf("name must be set")
   207  	case b.MinName > b.MaxName:
   208  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "name length")
   209  	case b.MinEmail > b.MaxEmail:
   210  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "email length")
   211  	case b.MinSubject > b.MaxSubject:
   212  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "subject length")
   213  	case b.MinMessage > b.MaxMessage:
   214  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "message length")
   215  	case b.MinSizeThread > b.MaxSizeThread:
   216  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "thread file size")
   217  	case b.MinSizeReply > b.MaxSizeReply:
   218  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "reply file size")
   219  	}
   220  	reservedDirs := []string{"captcha", "static", "sriracha", "sriracha_all"}
   221  	for _, reserved := range reservedDirs {
   222  		if strings.EqualFold(b.Dir, reserved) {
   223  			return fmt.Errorf("%s is a reserved name", reserved)
   224  		}
   225  	}
   226  	return nil
   227  }
   228  
   229  func (b *Board) Path() string {
   230  	if b.Dir == "" {
   231  		return "/"
   232  	}
   233  	return "/" + b.Dir + "/"
   234  }
   235  
   236  func (b *Board) MaxSizeLabel(thread bool) string {
   237  	if thread {
   238  		return FormatFileSize(b.MaxSizeThread)
   239  	}
   240  	return FormatFileSize(b.MaxSizeReply)
   241  }
   242  
   243  func (b *Board) HasUpload(mimeType string) bool {
   244  	if len(b.Uploads) == 0 {
   245  		return false
   246  	}
   247  	for _, upload := range b.Uploads {
   248  		if upload == mimeType {
   249  			return true
   250  		}
   251  	}
   252  	return false
   253  }
   254  
   255  func (b *Board) HasEmbed(name string) bool {
   256  	if len(b.Embeds) == 0 {
   257  		return false
   258  	}
   259  	for _, embed := range b.Embeds {
   260  		if embed == name {
   261  			return true
   262  		}
   263  	}
   264  	return false
   265  }
   266  
   267  func (b *Board) UploadTypesLabel(uploadTypes []*UploadType) string {
   268  	if len(b.Uploads) == 0 {
   269  		return ""
   270  	}
   271  	var types []string
   272  	found := make(map[string]bool)
   273  	for _, u := range uploadTypes {
   274  		if b.HasUpload(u.MIME) && !found[u.Ext] {
   275  			found[u.Ext] = true
   276  			types = append(types, strings.ToUpper(u.Ext))
   277  		}
   278  	}
   279  	buf := &strings.Builder{}
   280  	for i, t := range types {
   281  		if i > 0 {
   282  			if i == len(types)-1 {
   283  				buf.WriteString(" and ")
   284  			} else {
   285  				buf.WriteString(", ")
   286  			}
   287  		}
   288  		buf.WriteString(t)
   289  	}
   290  	return buf.String()
   291  }
   292  

View as plain text