package account import ( "net/http" "strconv" "code.nonshy.com/nonshy/website/pkg/config" "code.nonshy.com/nonshy/website/pkg/geoip" "code.nonshy.com/nonshy/website/pkg/log" "code.nonshy.com/nonshy/website/pkg/models" "code.nonshy.com/nonshy/website/pkg/session" "code.nonshy.com/nonshy/website/pkg/templates" "code.nonshy.com/nonshy/website/pkg/worker" ) // Search controller. func Search() http.HandlerFunc { tmpl := templates.Must("account/search.html") // Whitelist for ordering options. var sortWhitelist = []string{ "last_login_at desc", "created_at desc", "username", "username desc", "lower(name)", "lower(name) desc", "distance", } return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Search filters. var ( isCertified = r.FormValue("certified") username = r.FormValue("username") // username search gender = r.FormValue("gender") orientation = r.FormValue("orientation") maritalStatus = r.FormValue("marital_status") hereFor = r.FormValue("here_for") friendSearch = r.FormValue("friends") == "true" sort = r.FormValue("sort") sortOK bool ) ageMin, err1 := strconv.Atoi(r.FormValue("age_min")) ageMax, err2 := strconv.Atoi(r.FormValue("age_max")) if ageMin > ageMax && err1 == nil && err2 == nil { ageMin, ageMax = ageMax, ageMin } // Get current user. currentUser, err := session.CurrentUser(r) if err != nil { session.FlashError(w, r, "Couldn't get current user!") templates.Redirect(w, "/") return } // Geolocation/Who's Nearby: if the current user uses GeoIP, update // their coordinates now. myLocation, err := models.RefreshGeoIP(currentUser.ID, r) if err != nil { log.Error("RefreshGeoIP: %s", err) } // Sort options. for _, v := range sortWhitelist { if sort == v { sortOK = true break } } if !sortOK { sort = "last_login_at desc" } // Default if isCertified == "" { isCertified = "true" } pager := &models.Pagination{ PerPage: config.PageSizeMemberSearch, Sort: sort, } pager.ParsePage(r) users, err := models.SearchUsers(currentUser, &models.UserSearch{ Username: username, Gender: gender, Orientation: orientation, MaritalStatus: maritalStatus, HereFor: hereFor, Certified: isCertified == "true", NotCertified: isCertified == "false", InnerCircle: isCertified == "circle", ShyAccounts: isCertified == "shy", IsBanned: isCertified == "banned", Friends: friendSearch, AgeMin: ageMin, AgeMax: ageMax, }, pager) if err != nil { session.FlashError(w, r, "Couldn't search users: %s", err) } // Who's Nearby feature, get some data. insights, _ := geoip.GetRequestInsights(r) // Collect usernames to map to chat online status. var usernames = []string{} for _, user := range users { usernames = append(usernames, user.Username) } var vars = map[string]interface{}{ "Users": users, "Pager": pager, "Enum": config.ProfileEnums, // Search filter values. "Certified": isCertified, "Gender": gender, "Orientation": orientation, "MaritalStatus": maritalStatus, "HereFor": hereFor, "EmailOrUsername": username, "AgeMin": ageMin, "AgeMax": ageMax, "FriendSearch": friendSearch, "Sort": sort, // Photo counts mapped to users "PhotoCountMap": models.MapPhotoCounts(users), // Map Shy Account badges for these results "ShyMap": models.MapShyAccounts(users), // Map friendships to these users. "FriendMap": models.MapFriends(currentUser, users), // Users on the chat room map. "UserOnChatMap": worker.GetChatStatistics().MapUsersOnline(usernames), // Current user's location setting. "MyLocation": myLocation, "GeoIPInsights": insights, "DistanceMap": models.MapDistances(currentUser, users), } if err := tmpl.Execute(w, r, vars); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }) }