@@ 2157,11 2157,60 @@ func somedays() string {
return fmt.Sprintf("%d", secs)
}
+type avaKey struct {
+ uid int64
+ url string
+}
+
+var avacache = cache.New(cache.Options{Filler: func(key avaKey) (string, bool) {
+ j, err := GetJunkFast(key.uid, key.url)
+ if err != nil {
+ dlog.Println("avatating: getting junk:", err)
+ return "", false
+ }
+ pfpurl, _ := j.GetString("icon", "url")
+ res, err := http.Get(pfpurl)
+ if res.StatusCode != 200 {
+ dlog.Printf("avatating: %s: not ok: %d", key.url, res.StatusCode)
+ return "", false
+ }
+ if err != nil {
+ dlog.Println("avatating: getting pfp url:", err)
+ return "", false
+ }
+ defer res.Body.Close()
+
+ data, err := io.ReadAll(res.Body)
+ if err != nil {
+ dlog.Println("avatating: io.ReadAll(), whoops:", err)
+ return "", false
+ }
+
+ img, err := shrinkit(data)
+ if err != nil {
+ return "", false
+ }
+ data = img.Data
+ format := img.Format
+ desc := fmt.Sprintf("avatar for %s", key.url)
+ media := "image/" + format
+ if format == "jpeg" {
+ format = "jpg"
+ }
+ name := xfiltrate() + "." + format
+ _, xid, err := savefileandxid(name, desc, "", media, true, data)
+ if err != nil {
+ elog.Printf("avatate: unable to save image: %s", err)
+ return "", false
+ }
+ return xid, true
+}, Reducer: func(key avaKey) string {
+ return key.url
+}, Duration: 24 * 7 * time.Hour})
+
func isURL(s string) bool {
- return false
- // XXX Temporarily disable avatar fetching. It's too slow as it is now
- // u, err := url.Parse(s)
- // return err == nil && u.Scheme != "" && u.Host != ""
+ u, err := url.Parse(s)
+ return err == nil && u.Scheme != "" && u.Host != ""
}
func avatateautogen(r *http.Request) []byte {
@@ 2174,43 2223,29 @@ func avatate(w http.ResponseWriter, r *h
if develMode {
loadAvatarColors()
}
- var a []byte
+ var (
+ xid string
+ uid int64
+ )
n := r.FormValue("a")
if isURL(n) {
uinfo := login.GetUserInfo(r)
- j, err := GetJunkFast(uinfo.UserID, n)
- if err != nil {
- dlog.Println("avatating: getting junk:", err)
- a = avatateautogen(r)
- goto nope
- }
- pfpurl, _ := j.GetString("icon", "url")
- res, err := http.Get(pfpurl)
- if res.StatusCode != 200 {
- dlog.Printf("avatating: %s: not ok: %d", n, res.StatusCode)
- a = avatateautogen(r)
- goto nope
+ if uinfo != nil {
+ uid = uinfo.UserID
+ } else {
+ uid = 0
}
- if err != nil {
- dlog.Println("avatating: getting pfp url:", err)
- a = avatateautogen(r)
- goto nope
+ avacache.Get(avaKey{uid, n}, &xid)
+ if xid != "" {
+ err := reallyservefile(xid, w)
+ if err == nil {
+ return
+ }
}
- defer res.Body.Close()
-
- pfpbytes, err := io.ReadAll(res.Body)
- if err != nil {
- dlog.Println("avatating: io.ReadAll(), whoops:", err)
- a = avatateautogen(r)
- goto nope
- }
- a = pfpbytes
- } else {
- a = avatateautogen(r)
}
-nope:
+ a := avatateautogen(r)
if !develMode {
w.Header().Set("Cache-Control", "max-age="+somedays())
}
@@ 2271,23 2306,32 @@ func servememe(w http.ResponseWriter, r
http.ServeFile(w, r, dataDir+"/memes/"+meme)
}
-func servefile(w http.ResponseWriter, r *http.Request) {
- xid := mux.Vars(r)["xid"]
+func reallyservefile(xid string, w http.ResponseWriter) error {
var media string
var data []byte
row := stmtGetFileData.QueryRow(xid)
err := row.Scan(&media, &data)
if err != nil {
elog.Printf("error loading file: %s", err)
- http.NotFound(w, r)
- return
+ return err
}
- w.Header().Set("Content-Type", media)
- w.Header().Set("X-Content-Type-Options", "nosniff")
- w.Header().Set("Cache-Control", "max-age="+somedays())
+
+ if !develMode {
+ w.Header().Set("Content-Type", media)
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ w.Header().Set("Cache-Control", "max-age="+somedays())
+ }
w.Write(data)
+ return nil
}
+func servefile(w http.ResponseWriter, r *http.Request) {
+ xid := mux.Vars(r)["xid"]
+ err := reallyservefile(xid, w)
+ if err != nil {
+ http.NotFound(w, r)
+ }
+}
func nomoroboto(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "User-agent: *\n")
io.WriteString(w, "Disallow: /a\n")