...

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  	Files         int
   157  	Instances     int
   158  	Identifiers   BoardIdentifiers
   159  	Gallery       bool
   160  
   161  	// Calculated fields.
   162  	Uploads []string
   163  	Embeds  []string
   164  	Rules   []string
   165  	Unique  int `diff:"-"`
   166  }
   167  
   168  const (
   169  	DefaultBoardThreads     = 10
   170  	DefaultBoardReplies     = 3
   171  	DefaultBoardMaxName     = 75
   172  	DefaultBoardMaxEmail    = 75
   173  	DefaultBoardMaxSubject  = 75
   174  	DefaultBoardMaxMessage  = 8000
   175  	DefaultBoardWordBreak   = 200
   176  	DefaultBoardDefaultName = "Anonymous"
   177  	DefaultBoardTruncate    = 15
   178  	DefaultBoardMaxSize     = 2097152
   179  	DefaultBoardThumbWidth  = 250
   180  	DefaultBoardThumbHeight = 250
   181  	DefaultBoardFiles       = 1
   182  	DefaultBoardInstances   = 1
   183  	DefaultBoardGallery     = true
   184  )
   185  
   186  func NewBoard() *Board {
   187  	return &Board{
   188  		Threads:       DefaultBoardThreads,
   189  		Replies:       DefaultBoardReplies,
   190  		MaxName:       DefaultBoardMaxName,
   191  		MaxEmail:      DefaultBoardMaxEmail,
   192  		MaxSubject:    DefaultBoardMaxSubject,
   193  		MaxMessage:    DefaultBoardMaxMessage,
   194  		DefaultName:   DefaultBoardDefaultName,
   195  		WordBreak:     DefaultBoardWordBreak,
   196  		Truncate:      DefaultBoardTruncate,
   197  		MaxSizeThread: DefaultBoardMaxSize,
   198  		MaxSizeReply:  DefaultBoardMaxSize,
   199  		ThumbWidth:    DefaultBoardThumbWidth,
   200  		ThumbHeight:   DefaultBoardThumbHeight,
   201  		Files:         DefaultBoardFiles,
   202  		Instances:     DefaultBoardInstances,
   203  		Gallery:       DefaultBoardGallery,
   204  	}
   205  }
   206  
   207  func (b *Board) Validate() error {
   208  	switch {
   209  	case b.Dir != "" && !AlphaNumericAndSymbols.MatchString(b.Dir):
   210  		return fmt.Errorf("dir must only consist of letters, numbers, hyphens and underscores")
   211  	case strings.TrimSpace(b.Name) == "":
   212  		return fmt.Errorf("name must be set")
   213  	case b.MinName > b.MaxName:
   214  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "name length")
   215  	case b.MinEmail > b.MaxEmail:
   216  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "email length")
   217  	case b.MinSubject > b.MaxSubject:
   218  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "subject length")
   219  	case b.MinMessage > b.MaxMessage:
   220  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "message length")
   221  	case b.MinSizeThread > b.MaxSizeThread:
   222  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "thread file size")
   223  	case b.MinSizeReply > b.MaxSizeReply:
   224  		return fmt.Errorf("minimum %[1]s must be less than or equal to maximum %[1]s", "reply file size")
   225  	}
   226  	reservedDirs := []string{"captcha", "static", "sriracha", "sriracha_all"}
   227  	for _, reserved := range reservedDirs {
   228  		if strings.EqualFold(b.Dir, reserved) {
   229  			return fmt.Errorf("%s is a reserved name", reserved)
   230  		}
   231  	}
   232  	return nil
   233  }
   234  
   235  func (b *Board) Path() string {
   236  	if b.Dir == "" {
   237  		return "/"
   238  	}
   239  	return "/" + b.Dir + "/"
   240  }
   241  
   242  func (b *Board) MaxSizeLabel(thread bool) string {
   243  	if thread {
   244  		return FormatFileSize(b.MaxSizeThread)
   245  	}
   246  	return FormatFileSize(b.MaxSizeReply)
   247  }
   248  
   249  func (b *Board) HasUpload(mimeType string) bool {
   250  	if len(b.Uploads) == 0 {
   251  		return false
   252  	}
   253  	for _, upload := range b.Uploads {
   254  		if upload == mimeType {
   255  			return true
   256  		}
   257  	}
   258  	return false
   259  }
   260  
   261  func (b *Board) HasEmbed(name string) bool {
   262  	if len(b.Embeds) == 0 {
   263  		return false
   264  	}
   265  	for _, embed := range b.Embeds {
   266  		if embed == name {
   267  			return true
   268  		}
   269  	}
   270  	return false
   271  }
   272  
   273  func (b *Board) UploadTypesLabel(uploadTypes []*UploadType) string {
   274  	if len(b.Uploads) == 0 {
   275  		return ""
   276  	}
   277  	var types []string
   278  	found := make(map[string]bool)
   279  	for _, u := range uploadTypes {
   280  		if b.HasUpload(u.MIME) && !found[u.Ext] {
   281  			found[u.Ext] = true
   282  			types = append(types, strings.ToUpper(u.Ext))
   283  		}
   284  	}
   285  	buf := &strings.Builder{}
   286  	for i, t := range types {
   287  		if i > 0 {
   288  			if i == len(types)-1 {
   289  				buf.WriteString(" and ")
   290  			} else {
   291  				buf.WriteString(", ")
   292  			}
   293  		}
   294  		buf.WriteString(t)
   295  	}
   296  	return buf.String()
   297  }
   298  

View as plain text