package grils import ( "fagott.pw/charakterin" "fagott.pw/grilist/frontend" "fagott.pw/grilist/grilist" "fmt" "github.com/julienschmidt/httprouter" "log" "net/http" "regexp" "strconv" "strings" ) var ( pgArrayReg = regexp.MustCompile(`(((?P(([^",\\{}\s(NULL)])+|"([^"\\]|\\"|\\\\)*")))(,)?)`) pgValueIdx int ) func findIdx() { for i, subexp := range pgArrayReg.SubexpNames() { if subexp == "value" { pgValueIdx = i break } } } type GrilsModule struct { g *grilist.Grilist } func (m *GrilsModule) Name() string { return "Grils" } func (m *GrilsModule) Init(g *grilist.Grilist) { findIdx() m.g = g m.g.Router.GET("/gril/:id", m.viewGril) } func (m *GrilsModule) Interface() interface{} { return m } func (m *GrilsModule) getGrils(whereClause string, params ...interface{}) ([]*Gril, error) { var grils []*Gril rows, err := m.g.DB.Query(fmt.Sprintf(`SELECT id, kanji_name, romaji_name, other_names, updated_at, age, birthday, tags FROM grilist.grils_flattened WHERE %s`, whereClause), params...) if err != nil { return nil, err } defer rows.Close() for rows.Next() { gril := &Gril{} var tags []byte var otherNames []byte err = rows.Scan(&gril.ID, &gril.KanjiName, &gril.RomajiName, &otherNames, &gril.UpdatedAt, &gril.Age, &gril.Birthday, &tags) if err != nil { log.Println(gril.ID) log.Println("error scanning in getGrils:", err) continue } gril.Tags = pgArray(tags) gril.OtherNames = pgArray(otherNames) grils = append(grils, gril) } return grils, nil } func (m *GrilsModule) GetListsOfGril(gril *Gril) error { rows, err := m.g.DB.Query(`SELECT list_id FROM grilist.lists_grils WHERE gril_id = $1`, gril.ID) if err != nil { return err } defer rows.Close() for rows.Next() { var listID int if err := rows.Scan(&listID); err != nil { log.Println(err) continue } gril.Lists = append(gril.Lists, listID) } return nil } func (m *GrilsModule) ProvideDashboardData(user *charakterin.User) []grilist.DashboardCategory { var categories []grilist.DashboardCategory rows, err := m.g.DB.Query(`SELECT id FROM grilist.grils ORDER BY updated_at DESC LIMIT 5`) if err != nil { log.Println(err) return categories } defer rows.Close() cat := grilist.DashboardCategory{ Title: "Neue Grils", } for rows.Next() { var id int if err := rows.Scan(&id); err != nil { log.Println(err) continue } gril, err := m.FromID(id) if err != nil { log.Println(err) continue } cat.Cards = append(cat.Cards, frontend.Card{ Title: gril.RomajiName, Description: gril.KanjiName, Size: "medium", Actions: []frontend.Action{ frontend.Action{ Name: "anguckieren", Link: fmt.Sprintf("/gril/%d", gril.ID), }, }, }) } categories = append(categories, cat) return categories } func (m *GrilsModule) FromID(id int) (*Gril, error) { gril := &Gril{ ID: id, } var tags []byte var otherNames []byte err := m.g.DB.QueryRow(`SELECT kanji_name, romaji_name, other_names, updated_at, age, birthday, tags FROM grilist.grils_flattened WHERE id = $1`, id).Scan(&gril.KanjiName, &gril.RomajiName, &otherNames, &gril.UpdatedAt, &gril.Age, &gril.Birthday, &tags) gril.Tags = pgArray(tags) gril.OtherNames = pgArray(otherNames) if err != nil { return nil, err } return gril, nil } func (m *GrilsModule) viewGril(w http.ResponseWriter, r *http.Request, p httprouter.Params) { user, _ := m.g.Charakterin.GetUserFromRequest(r) sid := p.ByName("id") id, err := strconv.Atoi(sid) if err != nil { http.Redirect(w, r, "/", 302) return } gril, err := m.FromID(id) if err != nil { http.Redirect(w, r, "/", 302) return } if err := m.GetListsOfGril(gril); err != nil { log.Println(err) } data := m.g.Renderer.DefaultData() data["user"] = user data["gril"] = gril m.g.Renderer.RenderPage("gril", w, data) } func pgArray(array []byte) []string { var results []string matches := pgArrayReg.FindAllStringSubmatch(string(array), -1) for _, match := range matches { s := match[pgValueIdx] s = strings.Trim(s, "\"") results = append(results, s) } return results } func New() *GrilsModule { return &GrilsModule{} }