...

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

View as plain text