gosora/utils.go
Azareal 534ef10194 You can now upvote topics and replies. The number of upvotes is visible on the posts.
The static resources now support Gzip Compression. Software-wide support is coming with the upcoming router rewrite!
Revamped Tempra Simple's topic view. We now use emojis instead of text for the fields. Experimental.
Simplified the json permissions in the installer.
Fixed some places where the wrong error handler is used.
Fixed a bug in the word counter where it was off by one.
The word count is now tracked by the topics and replies.
2017-02-10 13:39:13 +00:00

218 lines
4.5 KiB
Go

package main
import "log"
import "fmt"
import "time"
import "os"
import "math"
import "strings"
import "unicode"
import "encoding/base64"
import "crypto/rand"
import "net/smtp"
// Generate a cryptographically secure set of random bytes..
func GenerateSafeString(length int) (string, error) {
rb := make([]byte,length)
_, err := rand.Read(rb)
if err != nil {
return "", err
}
return base64.URLEncoding.EncodeToString(rb), nil
}
func relative_time(in string) (string, error) {
if in == "" {
return "", nil
}
layout := "2006-01-02 15:04:05"
t, err := time.Parse(layout, in)
if err != nil {
return "", err
}
diff := time.Since(t)
hours := diff.Hours()
seconds := diff.Seconds()
weeks := int(hours / 24 / 7)
months := int(hours / 24 / 31)
switch {
case months > 11:
//return t.Format("Mon Jan 2 2006"), err
return t.Format("Jan 2 2006"), err
case months > 1:
return fmt.Sprintf("%d months ago", months), err
case months == 1:
return "a month ago", err
case weeks > 1:
return fmt.Sprintf("%d weeks ago", weeks), err
case int(hours / 24) == 7:
return "a week ago", err
case int(hours / 24) == 1:
return "1 day ago", err
case int(hours / 24) > 1:
return fmt.Sprintf("%d days ago", int(hours / 24)), err
case seconds <= 1:
return "a moment ago", err
case seconds < 60:
return fmt.Sprintf("%d seconds ago", int(seconds)), err
case seconds < 120:
return "a minute ago", err
case seconds < 3600:
return fmt.Sprintf("%d minutes ago", int(seconds / 60)), err
case seconds < 7200:
return "an hour ago", err
default:
return fmt.Sprintf("%d hours ago", int(seconds / 60 / 60)), err
}
}
func SendEmail(email string, subject string, msg string) bool {
// This hook is useful for plugin_sendmail or for testing tools. Possibly to hook it into some sort of mail server?
if vhooks["email_send_intercept"] != nil {
return vhooks["email_send_intercept"](email, subject, msg).(bool)
}
body := "Subject: " + subject + "\n\n" + msg + "\n"
con, err := smtp.Dial(smtp_server)
if err != nil {
return false
}
err = con.Mail(site_email)
if err != nil {
return false
}
err = con.Rcpt(email)
if err != nil {
return false
}
email_data, err := con.Data()
if err != nil {
return false
}
_, err = fmt.Fprintf(email_data, body)
if err != nil {
return false
}
err = email_data.Close()
if err != nil {
return false
}
err = con.Quit()
if err != nil {
return false
}
return true
}
func write_file(name string, content string) {
f, err := os.Create(name)
if err != nil {
log.Fatal(err)
}
_, err = f.WriteString(content)
if err != nil {
log.Fatal(err)
}
f.Sync()
f.Close()
}
func word_count(input string) (count int) {
input = strings.TrimSpace(input)
if input == "" {
return 0
}
in_space := false
for _, value := range input {
if unicode.IsSpace(value) {
if !in_space {
in_space = true
}
} else if in_space {
count++
in_space = false
}
}
return count + 1
}
func getLevel(score int) (level int) {
var base float64 = 25
var current float64
var prev float64
exp_factor := 2.8
for i := 1;;i++ {
_, bit := math.Modf(float64(i) / 10)
if bit == 0 {
exp_factor += 0.1
}
current = base + math.Pow(float64(i), exp_factor) + (prev / 3)
prev = current
if float64(score) < current {
break
}
level++
}
return level
}
func getLevelScore(getLevel int) (score int) {
var base float64 = 25
var current float64
var prev float64
var level int
exp_factor := 2.8
for i := 1;;i++ {
_, bit := math.Modf(float64(i) / 10)
if bit == 0 {
exp_factor += 0.1
}
current = base + math.Pow(float64(i), exp_factor) + (prev / 3)
prev = current
level++
if level <= getLevel {
break
}
}
return int(math.Ceil(current))
}
func getLevels(maxLevel int) []float64 {
var base float64 = 25
var current float64 = 0
var prev float64 = 0
exp_factor := 2.8
var out []float64
out = append(out, 0)
for i := 1;i <= maxLevel;i++ {
_, bit := math.Modf(float64(i) / 10)
if bit == 0 {
exp_factor += 0.1
}
current = base + math.Pow(float64(i), exp_factor) + (prev / 3)
prev = current
out = append(out, current)
}
return out
}
func fill_forum_id_gap(biggerID int, smallerID int) {
dummy := Forum{ID:0,Name:"",Active:false,Preset:"all"}
for i := smallerID; i > biggerID;i++ {
forums = append(forums, dummy)
}
}
func fill_group_id_gap(biggerID int, smallerID int) {
dummy := Group{ID:0, Name:""}
for i := smallerID; i > biggerID;i++ {
groups = append(groups, dummy)
}
}