package products import ( "encoding/json" "net/http" "sort" "strconv" "time" "git.t5de.dev/t5de/t5de-proxy/internal/hub" "git.t5de.dev/t5de/t5de-proxy/internal/proxy" ) // The inventory's Recently Added (api/recently_added_inventory.php?type=clothing|furni|scenes) is a list of product // IDs from IMVU; T5 products the person added to their library lately go first, newest first. // recentFor is how long a T5 product counts as recently added. const recentFor = 30 * 24 * time.Hour // IMVU's categories for furniture and rooms (the inventory's FURNI_CATEGORIES and ROOM_CATEGORIES, and rooms' 107). var ( furniCategories = map[int64]bool{1027: true, 110: true} roomCategories = map[int64]bool{107: true, 109: true, 366: true, 626: true, 2386: true} ) // inventoryType is which Recently Added list a product belongs in: clothing (anything worn), furni or scenes. func inventoryType(categories []hub.Category) string { for _, c := range categories { if furniCategories[c.ID] { return "furni" } } for _, c := range categories { if roomCategories[c.ID] { return "scenes" } } return "clothing" } func (p *Products) interceptRecent(x *proxy.Exchange) error { if p.Library == nil { return nil } kind := x.URL.Query().Get("type") x.ModifyResponse = func(resp *http.Response, body []byte) ([]byte, error) { var ids []json.RawMessage if resp.StatusCode != http.StatusOK || json.Unmarshal(body, &ids) != nil { return body, nil } ours := p.recentLocals(kind, time.Now()) if len(ours) == 0 { return body, nil } out := make([]json.RawMessage, 0, len(ours)+len(ids)) for _, local := range ours { out = append(out, json.RawMessage(strconv.FormatInt(local, 10))) } return json.Marshal(append(out, ids...)) } return nil } // recentLocals is the local IDs of T5 products of that kind added to the library within recentFor, newest first. func (p *Products) recentLocals(kind string, now time.Time) []int64 { lib := p.Library() sort.SliceStable(lib, func(i, j int) bool { return lib[i].AddedAt.After(lib[j].AddedAt) }) var out []int64 for _, e := range lib { if now.Sub(e.AddedAt) > recentFor || inventoryType(e.Product.Categories) != kind { continue } if s := p.byProductID(e.Product.ID); s != nil && p.inHubDir(e.Product.ID) { out = append(out, s.local) } } return out }