promote flag: feature out of the experimental sandbox
Ted Unangst tedu@tedunangst.com
Tue, 07 Jul 2020 20:34:59 -0400
6 files changed,
93 insertions(+),
95 deletions(-)
M
activity.go
→
activity.go
@@ -1151,7 +1151,7 @@ i["url"] = e.ID
t["icon"] = i tags = append(tags, t) } - for _, e := range bloat_fixupflags(h) { + for _, e := range fixupflags(h) { t := junk.New() t["id"] = e.ID t["type"] = "Emoji"
M
avatar.go
→
avatar.go
@@ -19,11 +19,16 @@ import (
"bufio" "bytes" "crypto/sha512" + "fmt" "image" "image/png" "log" + "net/http" + "regexp" "strconv" "strings" + + "github.com/gorilla/mux" ) var avatarcolors = [4][4]byte{@@ -98,3 +103,83 @@ var buf bytes.Buffer
png.Encode(&buf, img) return buf.Bytes() } + +func showflag(writer http.ResponseWriter, req *http.Request) { + code := mux.Vars(req)["code"] + colors := strings.Split(code, ",") + numcolors := len(colors) + vert := false + if colors[0] == "vert" { + vert = true + colors = colors[1:] + numcolors-- + if numcolors == 0 { + http.Error(writer, "bad flag", 400) + return + } + } + pixels := make([][4]byte, numcolors) + for i := 0; i < numcolors; i++ { + hex := colors[i] + if len(hex) == 3 { + hex = fmt.Sprintf("%c%c%c%c%c%c", + hex[0], hex[0], hex[1], hex[1], hex[2], hex[2]) + } + c, _ := strconv.ParseUint(hex, 16, 32) + r := byte(c >> 16 & 0xff) + g := byte(c >> 8 & 0xff) + b := byte(c >> 0 & 0xff) + pixels[i][0] = r + pixels[i][1] = g + pixels[i][2] = b + pixels[i][3] = 255 + } + + h := 128 + w := h * 3 / 2 + img := image.NewRGBA(image.Rect(0, 0, w, h)) + if vert { + for j := 0; j < w; j++ { + pix := pixels[j*numcolors/w][:] + for i := 0; i < h; i++ { + p := i*img.Stride + j*4 + copy(img.Pix[p:], pix) + } + } + } else { + for i := 0; i < h; i++ { + pix := pixels[i*numcolors/h][:] + for j := 0; j < w; j++ { + p := i*img.Stride + j*4 + copy(img.Pix[p:], pix) + } + } + } + + writer.Header().Set("Cache-Control", "max-age="+somedays()) + png.Encode(writer, img) +} + +var re_flags = regexp.MustCompile("flag:[[:alnum:],]+") + +func fixupflags(h *Honk) []Emu { + var emus []Emu + count := 0 + h.Noise = re_flags.ReplaceAllStringFunc(h.Noise, func(m string) string { + count++ + var e Emu + e.Name = fmt.Sprintf(":flag%d:", count) + e.ID = fmt.Sprintf("https://%s/flag/%s", serverName, m[5:]) + emus = append(emus, e) + return e.Name + }) + return emus +} + +func renderflags(h *Honk) { + h.Noise = re_flags.ReplaceAllStringFunc(h.Noise, func(m string) string { + code := m[5:] + src := fmt.Sprintf("https://%s/flag/%s", serverName, code) + return fmt.Sprintf(`<img class="emu" title="%s" src="%s">`, "flag", src) + }) +}
M
bloat.go
→
bloat.go
@@ -14,95 +14,3 @@ // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. package main - -import ( - "fmt" - "image" - "image/png" - "net/http" - "regexp" - "strconv" - "strings" - - "github.com/gorilla/mux" -) - -func bloat_showflag(writer http.ResponseWriter, req *http.Request) { - code := mux.Vars(req)["code"] - colors := strings.Split(code, ",") - numcolors := len(colors) - vert := false - if colors[0] == "vert" { - vert = true - colors = colors[1:] - numcolors-- - if numcolors == 0 { - http.Error(writer, "bad flag", 400) - return - } - } - pixels := make([][4]byte, numcolors) - for i := 0; i < numcolors; i++ { - hex := colors[i] - if len(hex) == 3 { - hex = fmt.Sprintf("%c%c%c%c%c%c", - hex[0], hex[0], hex[1], hex[1], hex[2], hex[2]) - } - c, _ := strconv.ParseUint(hex, 16, 32) - r := byte(c >> 16 & 0xff) - g := byte(c >> 8 & 0xff) - b := byte(c >> 0 & 0xff) - pixels[i][0] = r - pixels[i][1] = g - pixels[i][2] = b - pixels[i][3] = 255 - } - - h := 128 - w := h * 3 / 2 - img := image.NewRGBA(image.Rect(0, 0, w, h)) - if vert { - for j := 0; j < w; j++ { - pix := pixels[j*numcolors/w][:] - for i := 0; i < h; i++ { - p := i*img.Stride + j*4 - copy(img.Pix[p:], pix) - } - } - } else { - for i := 0; i < h; i++ { - pix := pixels[i*numcolors/h][:] - for j := 0; j < w; j++ { - p := i*img.Stride + j*4 - copy(img.Pix[p:], pix) - } - } - } - - writer.Header().Set("Cache-Control", "max-age="+somedays()) - png.Encode(writer, img) -} - -var re_flags = regexp.MustCompile("flag:[[:alnum:],]+") - -func bloat_fixupflags(h *Honk) []Emu { - var emus []Emu - count := 0 - h.Noise = re_flags.ReplaceAllStringFunc(h.Noise, func(m string) string { - count++ - var e Emu - e.Name = fmt.Sprintf(":flag%d:", count) - e.ID = fmt.Sprintf("https://%s/flag/%s", serverName, m[5:]) - emus = append(emus, e) - return e.Name - }) - return emus -} - -func bloat_renderflags(h *Honk) { - h.Noise = re_flags.ReplaceAllStringFunc(h.Noise, func(m string) string { - code := m[5:] - src := fmt.Sprintf("https://%s/flag/%s", serverName, code) - return fmt.Sprintf(`<img class="emu" title="%s" src="%s">`, "flag", src) - }) -}
M
docs/honk.5
→
docs/honk.5
@@ -104,6 +104,11 @@ .Dl meme: honk.mp4
A full list of emoji and memes may be found in the .Pa funzone . .Pp +Custom flag emoji may be generated on the fly by specifying comma separated +hexadecimal RGB values, one for each stripe. +.Dl flag:306,002,dcf +Vertical stripes may be selected by specfying "vert" for the first value. +.Pp There are no length restrictions, but remember, somebody is going to have to read this noise. .Pp
M
web.go
→
web.go
@@ -2477,7 +2477,7 @@ getters.HandleFunc("/emu/{emu:[^.]*[^/]+}", serveemu)
getters.HandleFunc("/meme/{meme:[^.]*[^/]+}", servememe) getters.HandleFunc("/.well-known/webfinger", fingerlicker) - getters.HandleFunc("/flag/{code:.+}", bloat_showflag) + getters.HandleFunc("/flag/{code:.+}", showflag) getters.HandleFunc("/server", serveractor) posters.HandleFunc("/server/inbox", serverinbox)