mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 14:22:25 -05:00 
			
		
		
		
	* Add Swagger spec test script * Fix Swagger spec errors not related to statuses with polls * Add API tests that post a status with a poll * Fix creating a status with a poll from form params * Fix Swagger spec errors related to statuses with polls (this is the last error) * Fix Swagger spec warnings not related to unused definitions * Suppress a duplicate list update params definition that was somehow causing wrong param names * Add Swagger test to CI - updates Drone config - vendorizes go-swagger - fixes a file extension issue that caused the test script to generate JSON instead of YAML with the vendorized version * Put `Sample: ` on its own line everywhere * Remove unused id param from emojiCategoriesGet * Add 5 more pairs of profile fields to account update API Swagger * Remove Swagger prefix from dummy fields It makes the generated code look weird * Manually annotate params for statusCreate operation * Fix all remaining Swagger spec warnings - Change some models into operation parameters - Ignore models that already correspond to manually documented operation parameters but can't be trivially changed (those with file fields) * Documented that creating a status with scheduled_at isn't implemented yet * sign drone.yml * Fix filter API Swagger errors * fixup! Fix filter API Swagger errors --------- Co-authored-by: tobi <tobi.smethurst@protonmail.com>
		
			
				
	
	
		
			270 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			270 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package govalidator
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"html"
 | |
| 	"math"
 | |
| 	"path"
 | |
| 	"regexp"
 | |
| 	"strings"
 | |
| 	"unicode"
 | |
| 	"unicode/utf8"
 | |
| )
 | |
| 
 | |
| // Contains checks if the string contains the substring.
 | |
| func Contains(str, substring string) bool {
 | |
| 	return strings.Contains(str, substring)
 | |
| }
 | |
| 
 | |
| // Matches checks if string matches the pattern (pattern is regular expression)
 | |
| // In case of error return false
 | |
| func Matches(str, pattern string) bool {
 | |
| 	match, _ := regexp.MatchString(pattern, str)
 | |
| 	return match
 | |
| }
 | |
| 
 | |
| // LeftTrim trims characters from the left side of the input.
 | |
| // If second argument is empty, it will remove leading spaces.
 | |
| func LeftTrim(str, chars string) string {
 | |
| 	if chars == "" {
 | |
| 		return strings.TrimLeftFunc(str, unicode.IsSpace)
 | |
| 	}
 | |
| 	r, _ := regexp.Compile("^[" + chars + "]+")
 | |
| 	return r.ReplaceAllString(str, "")
 | |
| }
 | |
| 
 | |
| // RightTrim trims characters from the right side of the input.
 | |
| // If second argument is empty, it will remove trailing spaces.
 | |
| func RightTrim(str, chars string) string {
 | |
| 	if chars == "" {
 | |
| 		return strings.TrimRightFunc(str, unicode.IsSpace)
 | |
| 	}
 | |
| 	r, _ := regexp.Compile("[" + chars + "]+$")
 | |
| 	return r.ReplaceAllString(str, "")
 | |
| }
 | |
| 
 | |
| // Trim trims characters from both sides of the input.
 | |
| // If second argument is empty, it will remove spaces.
 | |
| func Trim(str, chars string) string {
 | |
| 	return LeftTrim(RightTrim(str, chars), chars)
 | |
| }
 | |
| 
 | |
| // WhiteList removes characters that do not appear in the whitelist.
 | |
| func WhiteList(str, chars string) string {
 | |
| 	pattern := "[^" + chars + "]+"
 | |
| 	r, _ := regexp.Compile(pattern)
 | |
| 	return r.ReplaceAllString(str, "")
 | |
| }
 | |
| 
 | |
| // BlackList removes characters that appear in the blacklist.
 | |
| func BlackList(str, chars string) string {
 | |
| 	pattern := "[" + chars + "]+"
 | |
| 	r, _ := regexp.Compile(pattern)
 | |
| 	return r.ReplaceAllString(str, "")
 | |
| }
 | |
| 
 | |
| // StripLow removes characters with a numerical value < 32 and 127, mostly control characters.
 | |
| // If keep_new_lines is true, newline characters are preserved (\n and \r, hex 0xA and 0xD).
 | |
| func StripLow(str string, keepNewLines bool) string {
 | |
| 	chars := ""
 | |
| 	if keepNewLines {
 | |
| 		chars = "\x00-\x09\x0B\x0C\x0E-\x1F\x7F"
 | |
| 	} else {
 | |
| 		chars = "\x00-\x1F\x7F"
 | |
| 	}
 | |
| 	return BlackList(str, chars)
 | |
| }
 | |
| 
 | |
| // ReplacePattern replaces regular expression pattern in string
 | |
| func ReplacePattern(str, pattern, replace string) string {
 | |
| 	r, _ := regexp.Compile(pattern)
 | |
| 	return r.ReplaceAllString(str, replace)
 | |
| }
 | |
| 
 | |
| // Escape replaces <, >, & and " with HTML entities.
 | |
| var Escape = html.EscapeString
 | |
| 
 | |
| func addSegment(inrune, segment []rune) []rune {
 | |
| 	if len(segment) == 0 {
 | |
| 		return inrune
 | |
| 	}
 | |
| 	if len(inrune) != 0 {
 | |
| 		inrune = append(inrune, '_')
 | |
| 	}
 | |
| 	inrune = append(inrune, segment...)
 | |
| 	return inrune
 | |
| }
 | |
| 
 | |
| // UnderscoreToCamelCase converts from underscore separated form to camel case form.
 | |
| // Ex.: my_func => MyFunc
 | |
| func UnderscoreToCamelCase(s string) string {
 | |
| 	return strings.Replace(strings.Title(strings.Replace(strings.ToLower(s), "_", " ", -1)), " ", "", -1)
 | |
| }
 | |
| 
 | |
| // CamelCaseToUnderscore converts from camel case form to underscore separated form.
 | |
| // Ex.: MyFunc => my_func
 | |
| func CamelCaseToUnderscore(str string) string {
 | |
| 	var output []rune
 | |
| 	var segment []rune
 | |
| 	for _, r := range str {
 | |
| 
 | |
| 		// not treat number as separate segment
 | |
| 		if !unicode.IsLower(r) && string(r) != "_" && !unicode.IsNumber(r) {
 | |
| 			output = addSegment(output, segment)
 | |
| 			segment = nil
 | |
| 		}
 | |
| 		segment = append(segment, unicode.ToLower(r))
 | |
| 	}
 | |
| 	output = addSegment(output, segment)
 | |
| 	return string(output)
 | |
| }
 | |
| 
 | |
| // Reverse returns reversed string
 | |
| func Reverse(s string) string {
 | |
| 	r := []rune(s)
 | |
| 	for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
 | |
| 		r[i], r[j] = r[j], r[i]
 | |
| 	}
 | |
| 	return string(r)
 | |
| }
 | |
| 
 | |
| // GetLines splits string by "\n" and return array of lines
 | |
| func GetLines(s string) []string {
 | |
| 	return strings.Split(s, "\n")
 | |
| }
 | |
| 
 | |
| // GetLine returns specified line of multiline string
 | |
| func GetLine(s string, index int) (string, error) {
 | |
| 	lines := GetLines(s)
 | |
| 	if index < 0 || index >= len(lines) {
 | |
| 		return "", errors.New("line index out of bounds")
 | |
| 	}
 | |
| 	return lines[index], nil
 | |
| }
 | |
| 
 | |
| // RemoveTags removes all tags from HTML string
 | |
| func RemoveTags(s string) string {
 | |
| 	return ReplacePattern(s, "<[^>]*>", "")
 | |
| }
 | |
| 
 | |
| // SafeFileName returns safe string that can be used in file names
 | |
| func SafeFileName(str string) string {
 | |
| 	name := strings.ToLower(str)
 | |
| 	name = path.Clean(path.Base(name))
 | |
| 	name = strings.Trim(name, " ")
 | |
| 	separators, err := regexp.Compile(`[ &_=+:]`)
 | |
| 	if err == nil {
 | |
| 		name = separators.ReplaceAllString(name, "-")
 | |
| 	}
 | |
| 	legal, err := regexp.Compile(`[^[:alnum:]-.]`)
 | |
| 	if err == nil {
 | |
| 		name = legal.ReplaceAllString(name, "")
 | |
| 	}
 | |
| 	for strings.Contains(name, "--") {
 | |
| 		name = strings.Replace(name, "--", "-", -1)
 | |
| 	}
 | |
| 	return name
 | |
| }
 | |
| 
 | |
| // NormalizeEmail canonicalize an email address.
 | |
| // The local part of the email address is lowercased for all domains; the hostname is always lowercased and
 | |
| // the local part of the email address is always lowercased for hosts that are known to be case-insensitive (currently only GMail).
 | |
| // Normalization follows special rules for known providers: currently, GMail addresses have dots removed in the local part and
 | |
| // are stripped of tags (e.g. some.one+tag@gmail.com becomes someone@gmail.com) and all @googlemail.com addresses are
 | |
| // normalized to @gmail.com.
 | |
| func NormalizeEmail(str string) (string, error) {
 | |
| 	if !IsEmail(str) {
 | |
| 		return "", fmt.Errorf("%s is not an email", str)
 | |
| 	}
 | |
| 	parts := strings.Split(str, "@")
 | |
| 	parts[0] = strings.ToLower(parts[0])
 | |
| 	parts[1] = strings.ToLower(parts[1])
 | |
| 	if parts[1] == "gmail.com" || parts[1] == "googlemail.com" {
 | |
| 		parts[1] = "gmail.com"
 | |
| 		parts[0] = strings.Split(ReplacePattern(parts[0], `\.`, ""), "+")[0]
 | |
| 	}
 | |
| 	return strings.Join(parts, "@"), nil
 | |
| }
 | |
| 
 | |
| // Truncate a string to the closest length without breaking words.
 | |
| func Truncate(str string, length int, ending string) string {
 | |
| 	var aftstr, befstr string
 | |
| 	if len(str) > length {
 | |
| 		words := strings.Fields(str)
 | |
| 		before, present := 0, 0
 | |
| 		for i := range words {
 | |
| 			befstr = aftstr
 | |
| 			before = present
 | |
| 			aftstr = aftstr + words[i] + " "
 | |
| 			present = len(aftstr)
 | |
| 			if present > length && i != 0 {
 | |
| 				if (length - before) < (present - length) {
 | |
| 					return Trim(befstr, " /\\.,\"'#!?&@+-") + ending
 | |
| 				}
 | |
| 				return Trim(aftstr, " /\\.,\"'#!?&@+-") + ending
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return str
 | |
| }
 | |
| 
 | |
| // PadLeft pads left side of a string if size of string is less then indicated pad length
 | |
| func PadLeft(str string, padStr string, padLen int) string {
 | |
| 	return buildPadStr(str, padStr, padLen, true, false)
 | |
| }
 | |
| 
 | |
| // PadRight pads right side of a string if size of string is less then indicated pad length
 | |
| func PadRight(str string, padStr string, padLen int) string {
 | |
| 	return buildPadStr(str, padStr, padLen, false, true)
 | |
| }
 | |
| 
 | |
| // PadBoth pads both sides of a string if size of string is less then indicated pad length
 | |
| func PadBoth(str string, padStr string, padLen int) string {
 | |
| 	return buildPadStr(str, padStr, padLen, true, true)
 | |
| }
 | |
| 
 | |
| // PadString either left, right or both sides.
 | |
| // Note that padding string can be unicode and more then one character
 | |
| func buildPadStr(str string, padStr string, padLen int, padLeft bool, padRight bool) string {
 | |
| 
 | |
| 	// When padded length is less then the current string size
 | |
| 	if padLen < utf8.RuneCountInString(str) {
 | |
| 		return str
 | |
| 	}
 | |
| 
 | |
| 	padLen -= utf8.RuneCountInString(str)
 | |
| 
 | |
| 	targetLen := padLen
 | |
| 
 | |
| 	targetLenLeft := targetLen
 | |
| 	targetLenRight := targetLen
 | |
| 	if padLeft && padRight {
 | |
| 		targetLenLeft = padLen / 2
 | |
| 		targetLenRight = padLen - targetLenLeft
 | |
| 	}
 | |
| 
 | |
| 	strToRepeatLen := utf8.RuneCountInString(padStr)
 | |
| 
 | |
| 	repeatTimes := int(math.Ceil(float64(targetLen) / float64(strToRepeatLen)))
 | |
| 	repeatedString := strings.Repeat(padStr, repeatTimes)
 | |
| 
 | |
| 	leftSide := ""
 | |
| 	if padLeft {
 | |
| 		leftSide = repeatedString[0:targetLenLeft]
 | |
| 	}
 | |
| 
 | |
| 	rightSide := ""
 | |
| 	if padRight {
 | |
| 		rightSide = repeatedString[0:targetLenRight]
 | |
| 	}
 | |
| 
 | |
| 	return leftSide + str + rightSide
 | |
| }
 | |
| 
 | |
| // TruncatingErrorf removes extra args from fmt.Errorf if not formatted in the str object
 | |
| func TruncatingErrorf(str string, args ...interface{}) error {
 | |
| 	n := strings.Count(str, "%s")
 | |
| 	return fmt.Errorf(str, args[:n]...)
 | |
| }
 |