package server import ( "fmt" "net/http" "strconv" "strings" "odoo-go/pkg/orm" ) // handleImage serves images for model records. // Mirrors: odoo/addons/web/controllers/binary.py content_image() // // The client requests images like: // /web/image/res.partner/5/avatar_128 // /web/image/product.product/1/image_1920 // // We first try to read the binary field from the database. // If no data is found, we fall back to an SVG placeholder. func (s *Server) handleImage(w http.ResponseWriter, r *http.Request) { // Parse: /web/image/// parts := strings.Split(strings.TrimPrefix(r.URL.Path, "/web/image/"), "/") model := "" id := int64(0) field := "image_1920" // Also accept query parameters (legacy format) if qm := r.URL.Query().Get("model"); qm != "" { model = qm } if qf := r.URL.Query().Get("field"); qf != "" { field = qf } if len(parts) >= 1 && parts[0] != "" { model = parts[0] } if len(parts) >= 2 { if n, err := strconv.ParseInt(parts[1], 10, 64); err == nil { id = n } } if len(parts) >= 3 && parts[2] != "" { field = parts[2] } // Try to read binary data from DB if model != "" && id > 0 { m := orm.Registry.Get(model) if m != nil { f := m.GetField(field) if f != nil && f.Type == orm.TypeBinary { table := m.Table() var data []byte ctx := r.Context() _ = s.pool.QueryRow(ctx, fmt.Sprintf(`SELECT "%s" FROM "%s" WHERE id = $1`, f.Column(), table), id, ).Scan(&data) if len(data) > 0 { // Detect content type contentType := http.DetectContentType(data) w.Header().Set("Content-Type", contentType) w.Header().Set("Cache-Control", "public, max-age=604800") w.Write(data) return } } } } // Fallback: SVG placeholder with the record's initial letter initial := "?" if model != "" && id > 0 { m := orm.Registry.Get(model) if m != nil { var name string _ = s.pool.QueryRow(r.Context(), fmt.Sprintf(`SELECT COALESCE(name, '') FROM "%s" WHERE id = $1`, m.Table()), id, ).Scan(&name) if len(name) > 0 { initial = strings.ToUpper(name[:1]) } } } w.Header().Set("Content-Type", "image/svg+xml") w.Header().Set("Cache-Control", "public, max-age=604800") fmt.Fprintf(w, ` %s `, initial) }