all database operations now take a context.Context, which is propagated through from sources
This commit is contained in:
+13
-13
@@ -32,22 +32,22 @@ import (
|
|||||||
*/
|
*/
|
||||||
func ShowCommunity(ctxt ui.AmContext) (string, any, error) {
|
func ShowCommunity(ctxt ui.AmContext) (string, any, error) {
|
||||||
me := ctxt.CurrentUser()
|
me := ctxt.CurrentUser()
|
||||||
prefs, err := me.Prefs()
|
prefs, err := me.Prefs(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
comm := ctxt.CurrentCommunity() // set by middleware
|
comm := ctxt.CurrentCommunity() // set by middleware
|
||||||
ci, err := comm.ContactInfo()
|
ci, err := comm.ContactInfo(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
host, err := comm.Host()
|
host, err := comm.Host(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
var cats []*database.Category
|
var cats []*database.Category
|
||||||
if !ctxt.GlobalFlags().Get(database.GlobalFlagNoCategories) {
|
if !ctxt.GlobalFlags().Get(database.GlobalFlagNoCategories) {
|
||||||
cats, err = database.AmGetCategoryHierarchy(comm.CategoryId)
|
cats, err = database.AmGetCategoryHierarchy(ctxt.Ctx(), comm.CategoryId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ func ShowCommunity(ctxt ui.AmContext) (string, any, error) {
|
|||||||
func JoinCommunity(ctxt ui.AmContext) (string, any, error) {
|
func JoinCommunity(ctxt ui.AmContext) (string, any, error) {
|
||||||
me := ctxt.CurrentUser()
|
me := ctxt.CurrentUser()
|
||||||
comm := ctxt.CurrentCommunity() // set by middleware
|
comm := ctxt.CurrentCommunity() // set by middleware
|
||||||
mbr, _, _, err := comm.Membership(me)
|
mbr, _, _, err := comm.Membership(ctxt.Ctx(), me)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ func JoinCommunity(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return dlg.Render(ctxt)
|
return dlg.Render(ctxt)
|
||||||
}
|
}
|
||||||
// if get here, this is a public community, and we can join
|
// if get here, this is a public community, and we can join
|
||||||
err = comm.SetMembership(me, database.AmDefaultRole("Community.NewUser").Level(), false, me.Uid, ctxt.RemoteIP())
|
err = comm.SetMembership(ctxt.Ctx(), me, database.AmDefaultRole("Community.NewUser").Level(), false, me.Uid, ctxt.RemoteIP())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ func JoinCommunity(ctxt ui.AmContext) (string, any, error) {
|
|||||||
func JoinCommunityWithKey(ctxt ui.AmContext) (string, any, error) {
|
func JoinCommunityWithKey(ctxt ui.AmContext) (string, any, error) {
|
||||||
me := ctxt.CurrentUser()
|
me := ctxt.CurrentUser()
|
||||||
comm := ctxt.CurrentCommunity() // set by middleware
|
comm := ctxt.CurrentCommunity() // set by middleware
|
||||||
mbr, _, _, err := comm.Membership(me)
|
mbr, _, _, err := comm.Membership(ctxt.Ctx(), me)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ func JoinCommunityWithKey(ctxt ui.AmContext) (string, any, error) {
|
|||||||
if comm.JoinKey != nil && key != *comm.JoinKey {
|
if comm.JoinKey != nil && key != *comm.JoinKey {
|
||||||
return dlg.RenderError(ctxt, "The join key does not match the community. Please try again.")
|
return dlg.RenderError(ctxt, "The join key does not match the community. Please try again.")
|
||||||
}
|
}
|
||||||
err = comm.SetMembership(me, database.AmDefaultRole("Community.NewUser").Level(), false, me.Uid, ctxt.RemoteIP())
|
err = comm.SetMembership(ctxt.Ctx(), me, database.AmDefaultRole("Community.NewUser").Level(), false, me.Uid, ctxt.RemoteIP())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dlg.RenderError(ctxt, fmt.Sprintf("Error joining: %v", err))
|
return dlg.RenderError(ctxt, fmt.Sprintf("Error joining: %v", err))
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ func JoinCommunityWithKey(ctxt ui.AmContext) (string, any, error) {
|
|||||||
func UnjoinCommunity(ctxt ui.AmContext) (string, any, error) {
|
func UnjoinCommunity(ctxt ui.AmContext) (string, any, error) {
|
||||||
me := ctxt.CurrentUser()
|
me := ctxt.CurrentUser()
|
||||||
comm := ctxt.CurrentCommunity() // set by middleware
|
comm := ctxt.CurrentCommunity() // set by middleware
|
||||||
mbr, lock, _, err := comm.Membership(me)
|
mbr, lock, _, err := comm.Membership(ctxt.Ctx(), me)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ func UnjoinCommunity(ctxt ui.AmContext) (string, any, error) {
|
|||||||
func UnjoinCommunityConfirm(ctxt ui.AmContext) (string, any, error) {
|
func UnjoinCommunityConfirm(ctxt ui.AmContext) (string, any, error) {
|
||||||
me := ctxt.CurrentUser()
|
me := ctxt.CurrentUser()
|
||||||
comm := ctxt.CurrentCommunity() // set by middleware
|
comm := ctxt.CurrentCommunity() // set by middleware
|
||||||
mbr, lock, _, err := comm.Membership(me)
|
mbr, lock, _, err := comm.Membership(ctxt.Ctx(), me)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -276,7 +276,7 @@ func UnjoinCommunityConfirm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
|
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
|
||||||
}
|
}
|
||||||
if ctxt.FormFieldIsSet("unjoin") {
|
if ctxt.FormFieldIsSet("unjoin") {
|
||||||
err = comm.SetMembership(me, 0, false, me.Uid, ctxt.RemoteIP())
|
err = comm.SetMembership(ctxt.Ctx(), me, 0, false, me.Uid, ctxt.RemoteIP())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -314,7 +314,7 @@ func MemberList(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.VarMap().Set("ofs", ofs)
|
ctxt.VarMap().Set("ofs", ofs)
|
||||||
ctxt.VarMap().Set("amsterdam_pageTitle", "List Members")
|
ctxt.VarMap().Set("amsterdam_pageTitle", "List Members")
|
||||||
listMax := int(ctxt.Globals().MaxCommunityMemberPage)
|
listMax := int(ctxt.Globals().MaxCommunityMemberPage)
|
||||||
results, total, err := comm.ListMembers(database.ListMembersFieldNone, database.ListMembersOperNone, "", ofs*listMax, listMax, showHidden)
|
results, total, err := comm.ListMembers(ctxt.Ctx(), database.ListMembersFieldNone, database.ListMembersOperNone, "", ofs*listMax, listMax, showHidden)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -385,7 +385,7 @@ func MemberSearch(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return "framed_template", "memberlist.jet", nil
|
return "framed_template", "memberlist.jet", nil
|
||||||
}
|
}
|
||||||
listMax := int(ctxt.Globals().MaxCommunityMemberPage)
|
listMax := int(ctxt.Globals().MaxCommunityMemberPage)
|
||||||
results, total, err := comm.ListMembers(iField, iOper, term, ofs*listMax, listMax, showHidden)
|
results, total, err := comm.ListMembers(ctxt.Ctx(), iField, iOper, term, ofs*listMax, listMax, showHidden)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-20
@@ -88,11 +88,11 @@ func CommunityProfileForm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
|
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
|
||||||
}
|
}
|
||||||
var ci *database.ContactInfo
|
var ci *database.ContactInfo
|
||||||
ci, err := comm.ContactInfo()
|
ci, err := comm.ContactInfo(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
flags, err := comm.Flags()
|
flags, err := comm.Flags(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -184,12 +184,12 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return dlg.RenderError(ctxt, err.Error())
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
}
|
}
|
||||||
var ci *database.ContactInfo
|
var ci *database.ContactInfo
|
||||||
ci, err = comm.ContactInfo()
|
ci, err = comm.ContactInfo(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dlg.RenderError(ctxt, err.Error())
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
}
|
}
|
||||||
var flags *util.OptionSet
|
var flags *util.OptionSet
|
||||||
flags, err = comm.Flags()
|
flags, err = comm.Flags(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,7 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
|
|||||||
nci.Region = dlg.Field("reg").ValPtr()
|
nci.Region = dlg.Field("reg").ValPtr()
|
||||||
nci.PostalCode = dlg.Field("pcode").ValPtr()
|
nci.PostalCode = dlg.Field("pcode").ValPtr()
|
||||||
nci.Country = dlg.Field("country").ValPtr()
|
nci.Country = dlg.Field("country").ValPtr()
|
||||||
_, err = nci.Save()
|
_, err = nci.Save(ctxt.Ctx())
|
||||||
ci = nci
|
ci = nci
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var joinkey *string = nil
|
var joinkey *string = nil
|
||||||
@@ -221,17 +221,17 @@ func EditCommunityProfile(ctxt ui.AmContext) (string, any, error) {
|
|||||||
hidedir = true
|
hidedir = true
|
||||||
hidesearch = true
|
hidesearch = true
|
||||||
}
|
}
|
||||||
err = comm.SetProfileData(dlg.Field("name").Value, dlg.Field("alias").Value, dlg.Field("synopsis").ValPtr(),
|
err = comm.SetProfileData(ctxt.Ctx(), dlg.Field("name").Value, dlg.Field("alias").Value, dlg.Field("synopsis").ValPtr(),
|
||||||
dlg.Field("rules").ValPtr(), dlg.Field("language").ValPtr(), joinkey, dlg.Field("membersonly").IsChecked(),
|
dlg.Field("rules").ValPtr(), dlg.Field("language").ValPtr(), joinkey, dlg.Field("membersonly").IsChecked(),
|
||||||
hidedir, hidesearch, dlg.Field("read_lvl").GetLevel(), dlg.Field("write_lvl").GetLevel(),
|
hidedir, hidesearch, dlg.Field("read_lvl").GetLevel(), dlg.Field("write_lvl").GetLevel(),
|
||||||
dlg.Field("create_lvl").GetLevel(), dlg.Field("delete_lvl").GetLevel(), dlg.Field("join_lvl").GetLevel())
|
dlg.Field("create_lvl").GetLevel(), dlg.Field("delete_lvl").GetLevel(), dlg.Field("join_lvl").GetLevel())
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
flags.Set(database.CommunityFlagPicturesInPosts, dlg.Field("pic_in_post").IsChecked())
|
flags.Set(database.CommunityFlagPicturesInPosts, dlg.Field("pic_in_post").IsChecked())
|
||||||
err = comm.SaveFlags(flags)
|
err = comm.SaveFlags(ctxt.Ctx(), flags)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = comm.TouchUpdate()
|
err = comm.TouchUpdate(ctxt.Ctx())
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxt.ClearCommunityContext()
|
ctxt.ClearCommunityContext()
|
||||||
@@ -259,7 +259,7 @@ func CommunityLogoForm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.SetRC(http.StatusForbidden)
|
ctxt.SetRC(http.StatusForbidden)
|
||||||
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
|
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
|
||||||
}
|
}
|
||||||
ci, err := comm.ContactInfo()
|
ci, err := comm.ContactInfo(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ctxt.VarMap().Set("commName", comm.Name)
|
ctxt.VarMap().Set("commName", comm.Name)
|
||||||
ctxt.VarMap().Set("commAlias", comm.Alias)
|
ctxt.VarMap().Set("commAlias", comm.Alias)
|
||||||
@@ -284,7 +284,7 @@ func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.SetRC(http.StatusForbidden)
|
ctxt.SetRC(http.StatusForbidden)
|
||||||
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
|
return ui.ErrorPage(ctxt, errors.New("you are not permitted to access this page"))
|
||||||
}
|
}
|
||||||
ci, err := comm.ContactInfo()
|
ci, err := comm.ContactInfo(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -300,13 +300,13 @@ func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ui.CommunityLogoMaxBytes)
|
ui.CommunityLogoMaxBytes)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var img *database.ImageStore
|
var img *database.ImageStore
|
||||||
img, err = database.AmStoreImage(database.ImageTypeCommunityLogo, comm.Id, mimeType, imageData)
|
img, err = database.AmStoreImage(ctxt.Ctx(), database.ImageTypeCommunityLogo, comm.Id, mimeType, imageData)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
photourl := fmt.Sprintf("/img/store/%d", img.ImgId)
|
photourl := fmt.Sprintf("/img/store/%d", img.ImgId)
|
||||||
ci.PhotoURL = &photourl
|
ci.PhotoURL = &photourl
|
||||||
_, err = ci.Save()
|
_, err = ci.Save(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = comm.TouchUpdate()
|
err = comm.TouchUpdate(ctxt.Ctx())
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return "redirect", "/comm/" + comm.Alias + "/admin/profile", nil
|
return "redirect", "/comm/" + comm.Alias + "/admin/profile", nil
|
||||||
@@ -336,7 +336,7 @@ func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
if happy {
|
if happy {
|
||||||
ampool.Submit(func(context.Context) {
|
ampool.Submit(func(context.Context) {
|
||||||
err := database.AmDeleteImage(int32(id))
|
err := database.AmDeleteImage(ctxt.Ctx(), int32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("unable to delete image ID %d: %v", id, err)
|
log.Errorf("unable to delete image ID %d: %v", id, err)
|
||||||
}
|
}
|
||||||
@@ -345,7 +345,7 @@ func EditCommunityLogo(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
ci.PhotoURL = nil
|
ci.PhotoURL = nil
|
||||||
_, err := ci.Save()
|
_, err := ci.Save(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -409,7 +409,7 @@ func CreateCommunity(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return dlg.RenderError(ctxt, err.Error())
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
}
|
}
|
||||||
var testcomm *database.Community
|
var testcomm *database.Community
|
||||||
testcomm, err = database.AmGetCommunityByAlias(dlg.Field("alias").Value)
|
testcomm, err = database.AmGetCommunityByAlias(ctxt.Ctx(), dlg.Field("alias").Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dlg.RenderError(ctxt, err.Error())
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
}
|
}
|
||||||
@@ -429,7 +429,7 @@ func CreateCommunity(ctxt ui.AmContext) (string, any, error) {
|
|||||||
hideSearch = true
|
hideSearch = true
|
||||||
}
|
}
|
||||||
var comm *database.Community
|
var comm *database.Community
|
||||||
comm, err = database.AmCreateCommunity(dlg.Field("name").Value, dlg.Field("alias").Value, user.Uid,
|
comm, err = database.AmCreateCommunity(ctxt.Ctx(), dlg.Field("name").Value, dlg.Field("alias").Value, user.Uid,
|
||||||
dlg.Field("language").ValPtr(), dlg.Field("synopsis").ValPtr(), dlg.Field("rules").ValPtr(),
|
dlg.Field("language").ValPtr(), dlg.Field("synopsis").ValPtr(), dlg.Field("rules").ValPtr(),
|
||||||
dlg.Field("joinkey").ValPtr(), hideDir, hideSearch, ctxt.RemoteIP())
|
dlg.Field("joinkey").ValPtr(), hideDir, hideSearch, ctxt.RemoteIP())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -440,12 +440,12 @@ func CreateCommunity(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ci.Region = dlg.Field("reg").ValPtr()
|
ci.Region = dlg.Field("reg").ValPtr()
|
||||||
ci.PostalCode = dlg.Field("pcode").ValPtr()
|
ci.PostalCode = dlg.Field("pcode").ValPtr()
|
||||||
ci.Country = dlg.Field("country").ValPtr()
|
ci.Country = dlg.Field("country").ValPtr()
|
||||||
_, err = ci.Save()
|
_, err = ci.Save(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = comm.SetContactID(ci.ContactId)
|
err = comm.SetContactID(ctxt.Ctx(), ci.ContactId)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = comm.TouchUpdate()
|
err = comm.TouchUpdate(ctxt.Ctx())
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dlg.RenderError(ctxt, err.Error())
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
|
|||||||
+28
-26
@@ -41,7 +41,7 @@ func Conferences(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.VarMap().Set("commName", comm.Name)
|
ctxt.VarMap().Set("commName", comm.Name)
|
||||||
ctxt.VarMap().Set("commAlias", comm.Alias)
|
ctxt.VarMap().Set("commAlias", comm.Alias)
|
||||||
ctxt.VarMap().Set("amsterdam_pageTitle", "Conference Listing: "+comm.Name)
|
ctxt.VarMap().Set("amsterdam_pageTitle", "Conference Listing: "+comm.Name)
|
||||||
clist, err := database.AmGetCommunityConferences(comm.Id,
|
clist, err := database.AmGetCommunityConferences(ctxt.Ctx(), comm.Id,
|
||||||
comm.TestPermission("Community.ShowHiddenObjects", ctxt.EffectiveLevel()))
|
comm.TestPermission("Community.ShowHiddenObjects", ctxt.EffectiveLevel()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
@@ -59,7 +59,7 @@ func Conferences(ctxt ui.AmContext) (string, any, error) {
|
|||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func Topics(ctxt ui.AmContext) (string, any, error) {
|
func Topics(ctxt ui.AmContext) (string, any, error) {
|
||||||
prefs, err := ctxt.CurrentUser().Prefs()
|
prefs, err := ctxt.CurrentUser().Prefs(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ func Topics(ctxt ui.AmContext) (string, any, error) {
|
|||||||
sort = ctxt.QueryParamInt("sort", sort)
|
sort = ctxt.QueryParamInt("sort", sort)
|
||||||
ctxt.SetSession("topic.sort", sort)
|
ctxt.SetSession("topic.sort", sort)
|
||||||
|
|
||||||
topics, err := database.AmListTopics(conf.ConfId, ctxt.CurrentUserId(), view, sort, false)
|
topics, err := database.AmListTopics(ctxt.Ctx(), conf.ConfId, ctxt.CurrentUserId(), view, sort, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -137,12 +137,12 @@ func NewTopicForm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.VarMap().Set("conferenceName", conf.Name)
|
ctxt.VarMap().Set("conferenceName", conf.Name)
|
||||||
ctxt.VarMap().Set("urlStem", fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.URLParam("confid")))
|
ctxt.VarMap().Set("urlStem", fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, ctxt.URLParam("confid")))
|
||||||
ctxt.VarMap().Set("topicName", "")
|
ctxt.VarMap().Set("topicName", "")
|
||||||
cs, err := conf.Settings(ctxt.CurrentUser())
|
cs, err := conf.Settings(ctxt.Ctx(), ctxt.CurrentUser())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
if cs == nil || cs.DefaultPseud == nil {
|
if cs == nil || cs.DefaultPseud == nil {
|
||||||
ci, err := ctxt.CurrentUser().ContactInfo()
|
ci, err := ctxt.CurrentUser().ContactInfo(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
if ctxt.FormFieldIsSet("preview") {
|
if ctxt.FormFieldIsSet("preview") {
|
||||||
// start by escaping the title
|
// start by escaping the title
|
||||||
checker, err := htmlcheck.AmNewHTMLChecker("escaper")
|
checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "escaper")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -203,7 +203,7 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.VarMap().Set("pb", v)
|
ctxt.VarMap().Set("pb", v)
|
||||||
|
|
||||||
// run the preview
|
// run the preview
|
||||||
checker, err = htmlcheck.AmNewHTMLChecker("preview")
|
checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "preview")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
if ctxt.FormFieldIsSet("post1") {
|
if ctxt.FormFieldIsSet("post1") {
|
||||||
// start by checking the title and pseud
|
// start by checking the title and pseud
|
||||||
checker, err := htmlcheck.AmNewHTMLChecker("post-pseud")
|
checker, err := htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-pseud")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
|
|||||||
zeroPostPseud, _ := checker.Value()
|
zeroPostPseud, _ := checker.Value()
|
||||||
|
|
||||||
// now check the post data itself
|
// now check the post data itself
|
||||||
checker, err = htmlcheck.AmNewHTMLChecker("post-body")
|
checker, err = htmlcheck.AmNewHTMLChecker(ctxt.Ctx(), "post-body")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -249,7 +249,7 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
|
|||||||
lines, _ := checker.Lines()
|
lines, _ := checker.Lines()
|
||||||
|
|
||||||
// Add the topic!
|
// Add the topic!
|
||||||
topic, err := database.AmNewTopic(conf, ctxt.CurrentUser(), topicName, zeroPostPseud, zeroPost, int32(lines), ctxt.RemoteIP())
|
topic, err := database.AmNewTopic(ctxt.Ctx(), conf, ctxt.CurrentUser(), topicName, zeroPostPseud, zeroPost, int32(lines), ctxt.RemoteIP())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -258,7 +258,7 @@ func NewTopic(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return "redirect", urlStem, nil // no attachment - just redisplay topic list
|
return "redirect", urlStem, nil // no attachment - just redisplay topic list
|
||||||
}
|
}
|
||||||
|
|
||||||
post, err := topic.GetPost(0) // get the initial post in the new topic
|
post, err := topic.GetPost(ctxt.Ctx(), 0) // get the initial post in the new topic
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -303,12 +303,12 @@ func AttachmentUpload(ctxt ui.AmContext) (string, any, error) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
if file.Size <= (1024 * 1024) { // 1 Mb
|
if file.Size <= (1024 * 1024) { // 1 Mb
|
||||||
var post *database.PostHeader
|
var post *database.PostHeader
|
||||||
post, err = database.AmGetPost(postId)
|
post, err = database.AmGetPost(ctxt.Ctx(), postId)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var data []byte
|
var data []byte
|
||||||
data, err = slurpFile(file)
|
data, err = slurpFile(file)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = post.SetAttachment(file.Filename, file.Header.Get("Content-Type"), int32(file.Size), data)
|
err = post.SetAttachment(ctxt.Ctx(), file.Filename, file.Header.Get("Content-Type"), int32(file.Size), data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return "redirect", target, nil
|
return "redirect", target, nil
|
||||||
}
|
}
|
||||||
@@ -370,7 +370,8 @@ func breakRange(topic *database.Topic, into []int32, param string, sep string) e
|
|||||||
func templateExtractUserName(args jet.Arguments) reflect.Value {
|
func templateExtractUserName(args jet.Arguments) reflect.Value {
|
||||||
rc := "<<ERROR>>"
|
rc := "<<ERROR>>"
|
||||||
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
|
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
|
||||||
user, err := database.AmGetUser(post.CreatorUid)
|
ctxt := args.Get(1).Convert(reflect.TypeFor[ui.AmContext]()).Interface().(ui.AmContext)
|
||||||
|
user, err := database.AmGetUser(ctxt.Ctx(), post.CreatorUid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc = user.Username
|
rc = user.Username
|
||||||
} else {
|
} else {
|
||||||
@@ -381,7 +382,8 @@ func templateExtractUserName(args jet.Arguments) reflect.Value {
|
|||||||
|
|
||||||
func templatePostText(args jet.Arguments) reflect.Value {
|
func templatePostText(args jet.Arguments) reflect.Value {
|
||||||
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
|
post := args.Get(0).Convert(reflect.TypeFor[*database.PostHeader]()).Interface().(*database.PostHeader)
|
||||||
rc, err := post.Text()
|
ctxt := args.Get(1).Convert(reflect.TypeFor[ui.AmContext]()).Interface().(ui.AmContext)
|
||||||
|
rc, err := post.Text(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("templatePostText could not get post text from post #%d: %v", post.PostId, err)
|
log.Errorf("templatePostText could not get post text from post #%d: %v", post.PostId, err)
|
||||||
rc = ""
|
rc = ""
|
||||||
@@ -395,10 +397,10 @@ func templateOverrideLine(args jet.Arguments) reflect.Value {
|
|||||||
rc := ""
|
rc := ""
|
||||||
if post.IsScribbled() {
|
if post.IsScribbled() {
|
||||||
scr_date := ""
|
scr_date := ""
|
||||||
scr_user, err := database.AmGetUser(*post.ScribbleUid)
|
scr_user, err := database.AmGetUser(ctxt.Ctx(), *post.ScribbleUid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var p *database.UserPrefs
|
var p *database.UserPrefs
|
||||||
p, err = ctxt.CurrentUser().Prefs()
|
p, err = ctxt.CurrentUser().Prefs(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
scr_date = p.Localizer().Strftime("%b %e, %Y %r", *post.ScribbleDate)
|
scr_date = p.Localizer().Strftime("%b %e, %Y %r", *post.ScribbleDate)
|
||||||
}
|
}
|
||||||
@@ -430,20 +432,20 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
rst := strings.Split(ctxt.Parameter("rst"), ",")
|
rst := strings.Split(ctxt.Parameter("rst"), ",")
|
||||||
if len(rst) >= 2 {
|
if len(rst) >= 2 {
|
||||||
user := ctxt.CurrentUser()
|
user := ctxt.CurrentUser()
|
||||||
ampool.Submit(func(context.Context) {
|
ampool.Submit(func(ctx context.Context) {
|
||||||
topicId, e1 := strconv.ParseInt(rst[0], 10, 32)
|
topicId, e1 := strconv.ParseInt(rst[0], 10, 32)
|
||||||
lastRead, e2 := strconv.ParseInt(rst[1], 10, 32)
|
lastRead, e2 := strconv.ParseInt(rst[1], 10, 32)
|
||||||
if e1 == nil && e2 == nil {
|
if e1 == nil && e2 == nil {
|
||||||
topic, _ := database.AmGetTopic(int32(topicId))
|
topic, _ := database.AmGetTopic(ctx, int32(topicId))
|
||||||
if topic != nil {
|
if topic != nil {
|
||||||
topic.SetLastRead(user, int32(lastRead))
|
topic.SetLastRead(ctx, user, int32(lastRead))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Get user prefs.
|
// Get user prefs.
|
||||||
prefs, err := ctxt.CurrentUser().Prefs()
|
prefs, err := ctxt.CurrentUser().Prefs(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -452,7 +454,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
conf := ctxt.GetScratch("currentConference").(*database.Conference)
|
||||||
var topic *database.Topic = nil
|
var topic *database.Topic = nil
|
||||||
if rawTopic, err := strconv.ParseInt(ctxt.URLParam("topic"), 10, 16); err == nil {
|
if rawTopic, err := strconv.ParseInt(ctxt.URLParam("topic"), 10, 16); err == nil {
|
||||||
topic, err = database.AmGetTopicByNumber(conf, int16(rawTopic))
|
topic, err = database.AmGetTopicByNumber(ctxt.Ctx(), conf, int16(rawTopic))
|
||||||
}
|
}
|
||||||
if topic == nil {
|
if topic == nil {
|
||||||
ctxt.SetRC(http.StatusNotFound)
|
ctxt.SetRC(http.StatusNotFound)
|
||||||
@@ -460,7 +462,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine the range of posts to display. The "pin" is the post number after which we display the horizontal line separating old and new posts.
|
// Determine the range of posts to display. The "pin" is the post number after which we display the horizontal line separating old and new posts.
|
||||||
lastRead, err := topic.GetLastRead(ctxt.CurrentUser())
|
lastRead, err := topic.GetLastRead(ctxt.Ctx(), ctxt.CurrentUser())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxt.SetRC(http.StatusNotFound)
|
ctxt.SetRC(http.StatusNotFound)
|
||||||
return ui.ErrorPage(ctxt, fmt.Errorf("posts not found in topic %d - %v", topic.Number, err))
|
return ui.ErrorPage(ctxt, fmt.Errorf("posts not found in topic %d - %v", topic.Number, err))
|
||||||
@@ -495,7 +497,7 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load the actual posts.
|
// Load the actual posts.
|
||||||
posts, err := database.AmGetPostRange(topic, postRange[0], postRange[1])
|
posts, err := database.AmGetPostRange(ctxt.Ctx(), topic, postRange[0], postRange[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, fmt.Errorf("internal error getting posts <%d:%d-%d> - %v", topic.Number, postRange[0], postRange[1], err))
|
return ui.ErrorPage(ctxt, fmt.Errorf("internal error getting posts <%d:%d-%d> - %v", topic.Number, postRange[0], postRange[1], err))
|
||||||
}
|
}
|
||||||
@@ -533,8 +535,8 @@ func ReadPosts(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ctxt.VarMap().Set("amsterdam_pageTitle", fmt.Sprintf("%s: %s", topic.Name, summaryLine))
|
ctxt.VarMap().Set("amsterdam_pageTitle", fmt.Sprintf("%s: %s", topic.Name, summaryLine))
|
||||||
if resetLastRead {
|
if resetLastRead {
|
||||||
user := ctxt.CurrentUser()
|
user := ctxt.CurrentUser()
|
||||||
ampool.Submit(func(context.Context) {
|
ampool.Submit(func(ctx context.Context) {
|
||||||
topic.SetLastRead(user, topic.TopMessage)
|
topic.SetLastRead(ctx, user, topic.TopMessage)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return "framed_template", "posts.jet", nil
|
return "framed_template", "posts.jet", nil
|
||||||
|
|||||||
+4
-3
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -113,12 +114,12 @@ func AmNewAudit(rectype int32, uid int32, ip string, data ...string) *AuditRecor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store stores the audit record in the database.
|
// Store stores the audit record in the database.
|
||||||
func (ar *AuditRecord) Store() error {
|
func (ar *AuditRecord) Store(ctx context.Context) error {
|
||||||
if ar.Record > 0 {
|
if ar.Record > 0 {
|
||||||
return fmt.Errorf("audit record %d already stored", ar.Record)
|
return fmt.Errorf("audit record %d already stored", ar.Record)
|
||||||
}
|
}
|
||||||
moment := time.Now().UTC()
|
moment := time.Now().UTC()
|
||||||
rs, err := amdb.Exec(`INSERT INTO audit (on_date, event, uid, commid, ip, data1, data2, data3, data4)
|
rs, err := amdb.ExecContext(ctx, `INSERT INTO audit (on_date, event, uid, commid, ip, data1, data2, data3, data4)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);`, moment, ar.Event, ar.Uid, ar.CommId, ar.IP,
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);`, moment, ar.Event, ar.Uid, ar.CommId, ar.IP,
|
||||||
ar.Data1, ar.Data2, ar.Data3, ar.Data4)
|
ar.Data1, ar.Data2, ar.Data3, ar.Data4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -132,7 +133,7 @@ func (ar *AuditRecord) Store() error {
|
|||||||
// auditWriter is the routine that stores audit records in trhe background.
|
// auditWriter is the routine that stores audit records in trhe background.
|
||||||
func auditWriter(workChan chan *AuditRecord, doneChan chan bool) {
|
func auditWriter(workChan chan *AuditRecord, doneChan chan bool) {
|
||||||
for ar := range workChan {
|
for ar := range workChan {
|
||||||
err := ar.Store()
|
err := ar.Store(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("dropped audit record (%+v) on the floor: %v", *ar, err)
|
log.Errorf("dropped audit record (%+v) on the floor: %v", *ar, err)
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-21
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -45,12 +46,12 @@ var categoryIdMap map[int32]*Category = make(map[int32]*Category)
|
|||||||
var categoryMutex sync.Mutex
|
var categoryMutex sync.Mutex
|
||||||
|
|
||||||
// isCatEnabled determines if category features are enabled.
|
// isCatEnabled determines if category features are enabled.
|
||||||
func isCatEnabled() (bool, error) {
|
func isCatEnabled(ctx context.Context) (bool, error) {
|
||||||
g, err := AmGlobals()
|
g, err := AmGlobals(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
set, err := g.Flags()
|
set, err := g.Flags(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -58,11 +59,11 @@ func isCatEnabled() (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loadCategories loads the categories list from the database.
|
// loadCategories loads the categories list from the database.
|
||||||
func loadCategories() error {
|
func loadCategories(ctx context.Context) error {
|
||||||
categoryMutex.Lock()
|
categoryMutex.Lock()
|
||||||
defer categoryMutex.Unlock()
|
defer categoryMutex.Unlock()
|
||||||
if allCategories == nil {
|
if allCategories == nil {
|
||||||
rs, err := amdb.Query("SELECT COUNT(*) FROM refcategory")
|
rs, err := amdb.QueryContext(ctx, "SELECT COUNT(*) FROM refcategory")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -72,7 +73,7 @@ func loadCategories() error {
|
|||||||
var ncats int32
|
var ncats int32
|
||||||
rs.Scan(&ncats)
|
rs.Scan(&ncats)
|
||||||
allCategories = make([]Category, 0, ncats)
|
allCategories = make([]Category, 0, ncats)
|
||||||
err = amdb.Select(&allCategories, "SELECT * FROM refcategory ORDER BY parent, name")
|
err = amdb.SelectContext(ctx, &allCategories, "SELECT * FROM refcategory ORDER BY parent, name")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -85,20 +86,21 @@ func loadCategories() error {
|
|||||||
|
|
||||||
/* AmGetCategory returns the category for the given name.
|
/* AmGetCategory returns the category for the given name.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* catid - The ID of the category to get.
|
* catid - The ID of the category to get.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to the appropriate Category, or nil.
|
* Pointer to the appropriate Category, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetCategory(catid int32) (*Category, error) {
|
func AmGetCategory(ctx context.Context, catid int32) (*Category, error) {
|
||||||
ok, err := isCatEnabled()
|
ok, err := isCatEnabled(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("category feature not supported")
|
return nil, errors.New("category feature not supported")
|
||||||
}
|
}
|
||||||
err = loadCategories()
|
err = loadCategories(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -116,20 +118,21 @@ func AmGetCategory(catid int32) (*Category, error) {
|
|||||||
|
|
||||||
/* AmGetCategoryHierarchy returns the category hierarchy for the given ID.
|
/* AmGetCategoryHierarchy returns the category hierarchy for the given ID.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* catid - The ID of the category to get.
|
* catid - The ID of the category to get.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Array of pointers to the categories in hierarchical order, or nil.
|
* Array of pointers to the categories in hierarchical order, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetCategoryHierarchy(catid int32) ([]*Category, error) {
|
func AmGetCategoryHierarchy(ctx context.Context, catid int32) ([]*Category, error) {
|
||||||
ok, err := isCatEnabled()
|
ok, err := isCatEnabled(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("category feature not supported")
|
return nil, errors.New("category feature not supported")
|
||||||
}
|
}
|
||||||
err = loadCategories()
|
err = loadCategories(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -154,20 +157,21 @@ func AmGetCategoryHierarchy(catid int32) ([]*Category, error) {
|
|||||||
|
|
||||||
/* AmGetSubCategories returns a list of all subcategories of the given category ID.
|
/* AmGetSubCategories returns a list of all subcategories of the given category ID.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* catid - The parent category ID to use. May be -1 to return all "top level" categories.
|
* catid - The parent category ID to use. May be -1 to return all "top level" categories.
|
||||||
* Returns:
|
* Returns:
|
||||||
* List of subcategories of this category.
|
* List of subcategories of this category.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetSubCategories(catid int32) ([]*Category, error) {
|
func AmGetSubCategories(ctx context.Context, catid int32) ([]*Category, error) {
|
||||||
ok, err := isCatEnabled()
|
ok, err := isCatEnabled(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("category feature not supported")
|
return nil, errors.New("category feature not supported")
|
||||||
}
|
}
|
||||||
err = loadCategories()
|
err = loadCategories(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -185,6 +189,7 @@ func AmGetSubCategories(catid int32) ([]*Category, error) {
|
|||||||
|
|
||||||
/* AmSearchCategories searches for categories matching certain criteria.
|
/* AmSearchCategories searches for categories matching certain criteria.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* oper - The operation to perform on the category name:
|
* oper - The operation to perform on the category name:
|
||||||
* SearchCatOperPrefix - The category name has the string "term" as a prefix.
|
* SearchCatOperPrefix - The category name has the string "term" as a prefix.
|
||||||
* SearchCatOperSubstring - The category name contains the string "term".
|
* SearchCatOperSubstring - The category name contains the string "term".
|
||||||
@@ -197,8 +202,8 @@ func AmGetSubCategories(catid int32) ([]*Category, error) {
|
|||||||
* The total number of categories matching this query (could be greater than max)
|
* The total number of categories matching this query (could be greater than max)
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmSearchCategories(oper int, term string, offset int, max int, showAll bool, searchAll bool) ([]*Category, int, error) {
|
func AmSearchCategories(ctx context.Context, oper int, term string, offset int, max int, showAll bool, searchAll bool) ([]*Category, int, error) {
|
||||||
ok, err := isCatEnabled()
|
ok, err := isCatEnabled(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, err
|
||||||
}
|
}
|
||||||
@@ -230,7 +235,7 @@ func AmSearchCategories(oper int, term string, offset int, max int, showAll bool
|
|||||||
queryString.WriteString(" AND hide_search = 0")
|
queryString.WriteString(" AND hide_search = 0")
|
||||||
}
|
}
|
||||||
q := queryString.String()
|
q := queryString.String()
|
||||||
rs, err := amdb.Query("SELECT COUNT(*) FROM refcategory WHERE " + q)
|
rs, err := amdb.QueryContext(ctx, "SELECT COUNT(*) FROM refcategory WHERE "+q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, err
|
||||||
}
|
}
|
||||||
@@ -243,9 +248,9 @@ func AmSearchCategories(oper int, term string, offset int, max int, showAll bool
|
|||||||
return make([]*Category, 0), 0, nil
|
return make([]*Category, 0), 0, nil
|
||||||
}
|
}
|
||||||
if offset > 0 {
|
if offset > 0 {
|
||||||
rs, err = amdb.Query("SELECT catid FROM refcategory WHERE "+q+" ORDER BY parent, name LIMIT ? OFFSET ?", max, offset)
|
rs, err = amdb.QueryContext(ctx, "SELECT catid FROM refcategory WHERE "+q+" ORDER BY parent, name LIMIT ? OFFSET ?", max, offset)
|
||||||
} else {
|
} else {
|
||||||
rs, err = amdb.Query("SELECT catid FROM refcategory WHERE "+q+" ORDER BY parent, name LIMIT ?", max)
|
rs, err = amdb.QueryContext(ctx, "SELECT catid FROM refcategory WHERE "+q+" ORDER BY parent, name LIMIT ?", max)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, total, err
|
return nil, total, err
|
||||||
@@ -254,7 +259,7 @@ func AmSearchCategories(oper int, term string, offset int, max int, showAll bool
|
|||||||
for rs.Next() {
|
for rs.Next() {
|
||||||
var catid int32
|
var catid int32
|
||||||
rs.Scan(&catid)
|
rs.Scan(&catid)
|
||||||
c, err := AmGetCategory(catid)
|
c, err := AmGetCategory(ctx, catid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc = append(rc, c)
|
rc = append(rc, c)
|
||||||
}
|
}
|
||||||
|
|||||||
+107
-90
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -151,27 +152,27 @@ func (c *Community) Public() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ContactInfo returns the contact info structure for the community.
|
// ContactInfo returns the contact info structure for the community.
|
||||||
func (c *Community) ContactInfo() (*ContactInfo, error) {
|
func (c *Community) ContactInfo(ctx context.Context) (*ContactInfo, error) {
|
||||||
if c.ContactId < 0 {
|
if c.ContactId < 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return AmGetContactInfo(c.ContactId)
|
return AmGetContactInfo(ctx, c.ContactId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Host returns the reference to the host of the community.
|
// Host returns the reference to the host of the community.
|
||||||
func (c *Community) Host() (*User, error) {
|
func (c *Community) Host(ctx context.Context) (*User, error) {
|
||||||
if c.HostUid == nil {
|
if c.HostUid == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return AmGetUser(*c.HostUid)
|
return AmGetUser(ctx, *c.HostUid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HostQ returns the reference to the community's host, quietly.
|
// HostQ returns the reference to the community's host, quietly.
|
||||||
func (c *Community) HostQ() *User {
|
func (c *Community) HostQ(ctx context.Context) *User {
|
||||||
if c.HostUid == nil {
|
if c.HostUid == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
u, err := AmGetUser(*c.HostUid)
|
u, err := AmGetUser(ctx, *c.HostUid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -192,6 +193,7 @@ func (c *Community) LanguageTag() (*language.Tag, error) {
|
|||||||
|
|
||||||
/* Membership returns the details of the specified user's membership in the community.
|
/* Membership returns the details of the specified user's membership in the community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctxt - Standard Go context value.
|
||||||
* u - The user to check the membership of.
|
* u - The user to check the membership of.
|
||||||
* Returns:
|
* Returns:
|
||||||
* true if the user is a member, false if not.
|
* true if the user is a member, false if not.
|
||||||
@@ -199,7 +201,7 @@ func (c *Community) LanguageTag() (*language.Tag, error) {
|
|||||||
* User's access level in the community, or 0 if the user is not a member.
|
* User's access level in the community, or 0 if the user is not a member.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func (c *Community) Membership(u *User) (bool, bool, uint16, error) {
|
func (c *Community) Membership(ctx context.Context, u *User) (bool, bool, uint16, error) {
|
||||||
key := fmt.Sprintf("%d:%d", c.Id, u.Uid)
|
key := fmt.Sprintf("%d:%d", c.Id, u.Uid)
|
||||||
memberMutex.Lock()
|
memberMutex.Lock()
|
||||||
defer memberMutex.Unlock()
|
defer memberMutex.Unlock()
|
||||||
@@ -212,7 +214,7 @@ func (c *Community) Membership(u *User) (bool, bool, uint16, error) {
|
|||||||
// "no join required" - they are effectively a member, but don't cache that
|
// "no join required" - they are effectively a member, but don't cache that
|
||||||
return true, false, u.BaseLevel, nil
|
return true, false, u.BaseLevel, nil
|
||||||
}
|
}
|
||||||
rs, err := amdb.Query("SELECT locked, granted_lvl FROM commmember WHERE commid = ? AND uid = ?", c.Id, u.Uid)
|
rs, err := amdb.QueryContext(ctx, "SELECT locked, granted_lvl FROM commmember WHERE commid = ? AND uid = ?", c.Id, u.Uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if rs.Next() {
|
if rs.Next() {
|
||||||
var locked bool
|
var locked bool
|
||||||
@@ -227,13 +229,13 @@ func (c *Community) Membership(u *User) (bool, bool, uint16, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MemberCount returns the number of members in the community.
|
// MemberCount returns the number of members in the community.
|
||||||
func (c *Community) MemberCount(hidden bool) (int, error) {
|
func (c *Community) MemberCount(ctx context.Context, hidden bool) (int, error) {
|
||||||
var rs *sql.Rows
|
var rs *sql.Rows
|
||||||
var err error
|
var err error
|
||||||
if hidden {
|
if hidden {
|
||||||
rs, err = amdb.Query("SELECT COUNT(*) FROM commmember WHERE commid = ?", c.Id)
|
rs, err = amdb.QueryContext(ctx, "SELECT COUNT(*) FROM commmember WHERE commid = ?", c.Id)
|
||||||
} else {
|
} else {
|
||||||
rs, err = amdb.Query("SELECT COUNT(*) FROM commmember WHERE commid = ? AND hidden = 0", c.Id)
|
rs, err = amdb.QueryContext(ctx, "SELECT COUNT(*) FROM commmember WHERE commid = ? AND hidden = 0", c.Id)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
@@ -248,6 +250,7 @@ func (c *Community) MemberCount(hidden bool) (int, error) {
|
|||||||
|
|
||||||
/* ListMembers lists or searches for community members matching certain criteria.
|
/* ListMembers lists or searches for community members matching certain criteria.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* field - A value indicating which field to search:
|
* field - A value indicating which field to search:
|
||||||
* ListMembersFieldNone - Do not search, just return all community members.
|
* ListMembersFieldNone - Do not search, just return all community members.
|
||||||
* ListMembersFieldName - The user name.
|
* ListMembersFieldName - The user name.
|
||||||
@@ -267,7 +270,7 @@ func (c *Community) MemberCount(hidden bool) (int, error) {
|
|||||||
* The total number of members matching this query (could be greater than max)
|
* The total number of members matching this query (could be greater than max)
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func (c *Community) ListMembers(field int, oper int, term string, offset int, max int, showHidden bool) ([]*User, int, error) {
|
func (c *Community) ListMembers(ctx context.Context, field int, oper int, term string, offset int, max int, showHidden bool) ([]*User, int, error) {
|
||||||
var query strings.Builder
|
var query strings.Builder
|
||||||
if field != ListMembersFieldNone && oper != ListMembersOperNone {
|
if field != ListMembersFieldNone && oper != ListMembersOperNone {
|
||||||
query.WriteString(" AND ")
|
query.WriteString(" AND ")
|
||||||
@@ -304,7 +307,7 @@ func (c *Community) ListMembers(field int, oper int, term string, offset int, ma
|
|||||||
query.WriteString(" AND m.hidden = 0")
|
query.WriteString(" AND m.hidden = 0")
|
||||||
}
|
}
|
||||||
q := query.String()
|
q := query.String()
|
||||||
rs, err := amdb.Query(`SELECT COUNT(*) FROM commmember m, users u, contacts c WHERE m.commid = ? AND m.uid = u.uid
|
rs, err := amdb.QueryContext(ctx, `SELECT COUNT(*) FROM commmember m, users u, contacts c WHERE m.commid = ? AND m.uid = u.uid
|
||||||
AND u.contactid = c.contactid`+q, c.Id)
|
AND u.contactid = c.contactid`+q, c.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, err
|
||||||
@@ -315,10 +318,10 @@ func (c *Community) ListMembers(field int, oper int, term string, offset int, ma
|
|||||||
var total int
|
var total int
|
||||||
rs.Scan(&total)
|
rs.Scan(&total)
|
||||||
if offset > 0 {
|
if offset > 0 {
|
||||||
rs, err = amdb.Query(`SELECT m.uid FROM commmember m, users u, contacts c WHERE m.commid = ? AND m.uid = u.uid
|
rs, err = amdb.QueryContext(ctx, `SELECT m.uid FROM commmember m, users u, contacts c WHERE m.commid = ? AND m.uid = u.uid
|
||||||
AND u.contactid = c.contactid`+q+" ORDER BY u.username LIMIT ? OFFSET ?", c.Id, max, offset)
|
AND u.contactid = c.contactid`+q+" ORDER BY u.username LIMIT ? OFFSET ?", c.Id, max, offset)
|
||||||
} else {
|
} else {
|
||||||
rs, err = amdb.Query(`SELECT m.uid FROM commmember m, users u, contacts c WHERE m.commid = ? AND m.uid = u.uid
|
rs, err = amdb.QueryContext(ctx, `SELECT m.uid FROM commmember m, users u, contacts c WHERE m.commid = ? AND m.uid = u.uid
|
||||||
AND u.contactid = c.contactid`+q+" ORDER BY u.username LIMIT ?", c.Id, max)
|
AND u.contactid = c.contactid`+q+" ORDER BY u.username LIMIT ?", c.Id, max)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -328,7 +331,7 @@ func (c *Community) ListMembers(field int, oper int, term string, offset int, ma
|
|||||||
for rs.Next() {
|
for rs.Next() {
|
||||||
var uid int32
|
var uid int32
|
||||||
rs.Scan(&uid)
|
rs.Scan(&uid)
|
||||||
u, err := AmGetUser(uid)
|
u, err := AmGetUser(ctx, uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc = append(rc, u)
|
rc = append(rc, u)
|
||||||
}
|
}
|
||||||
@@ -338,6 +341,7 @@ func (c *Community) ListMembers(field int, oper int, term string, offset int, ma
|
|||||||
|
|
||||||
/* SetMembership sets a user's membership status within the community.
|
/* SetMembership sets a user's membership status within the community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* u - The user to change the membership status of.
|
* u - The user to change the membership status of.
|
||||||
* level - Their membership level. If this is 0, they are removed from membership.
|
* level - Their membership level. If this is 0, they are removed from membership.
|
||||||
* locked - Whether they can unjoin the community themselves. Ignored if removing them.
|
* locked - Whether they can unjoin the community themselves. Ignored if removing them.
|
||||||
@@ -346,7 +350,7 @@ func (c *Community) ListMembers(field int, oper int, term string, offset int, ma
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func (c *Community) SetMembership(u *User, level uint16, locked bool, personUID int32, ipaddr string) error {
|
func (c *Community) SetMembership(ctx context.Context, u *User, level uint16, locked bool, personUID int32, ipaddr string) error {
|
||||||
success := false
|
success := false
|
||||||
tx := amdb.MustBegin()
|
tx := amdb.MustBegin()
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -355,20 +359,20 @@ func (c *Community) SetMembership(u *User, level uint16, locked bool, personUID
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if level == 0 {
|
if level == 0 {
|
||||||
res, err := tx.Exec("DELETE FROM commmember WHERE commid = ? AND uid = ?", c.Id, u.Uid)
|
res, err := tx.ExecContext(ctx, "DELETE FROM commmember WHERE commid = ? AND uid = ?", c.Id, u.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
stuffMembership(c.Id, u.Uid, false, false, 0)
|
stuffMembership(c.Id, u.Uid, false, false, 0)
|
||||||
ra, err := res.RowsAffected()
|
ra, err := res.RowsAffected()
|
||||||
if err == nil && ra > 0 {
|
if err == nil && ra > 0 {
|
||||||
err = AmOnUserLeaveCommunityServices(tx, c, u)
|
err = AmOnUserLeaveCommunityServices(ctx, tx, c, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rs, err := tx.Query("SELECT granted_lvl, locked FROM commmember WHERE commid = ? AND uid = ?", c.Id, u.Uid)
|
rs, err := tx.QueryContext(ctx, "SELECT granted_lvl, locked FROM commmember WHERE commid = ? AND uid = ?", c.Id, u.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -377,7 +381,7 @@ func (c *Community) SetMembership(u *User, level uint16, locked bool, personUID
|
|||||||
var lockStatus bool
|
var lockStatus bool
|
||||||
rs.Scan(&oldLevel, &lockStatus)
|
rs.Scan(&oldLevel, &lockStatus)
|
||||||
if level != oldLevel || lockStatus != locked {
|
if level != oldLevel || lockStatus != locked {
|
||||||
_, err := tx.Exec("UPDATE commmember SET granted_lvl = ?, locked = ? WHERE commid = ? AND uid = ?",
|
_, err := tx.ExecContext(ctx, "UPDATE commmember SET granted_lvl = ?, locked = ? WHERE commid = ? AND uid = ?",
|
||||||
level, locked, c.Id, u.Uid)
|
level, locked, c.Id, u.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -385,19 +389,19 @@ func (c *Community) SetMembership(u *User, level uint16, locked bool, personUID
|
|||||||
stuffMembership(c.Id, u.Uid, true, locked, level)
|
stuffMembership(c.Id, u.Uid, true, locked, level)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_, err := tx.Exec("INSERT INTO commmember (commid, uid, granted_lvl, locked) VALUES (?, ?, ?, ?)",
|
_, err := tx.ExecContext(ctx, "INSERT INTO commmember (commid, uid, granted_lvl, locked) VALUES (?, ?, ?, ?)",
|
||||||
c.Id, u.Uid, level, locked)
|
c.Id, u.Uid, level, locked)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
stuffMembership(c.Id, u.Uid, true, locked, level)
|
stuffMembership(c.Id, u.Uid, true, locked, level)
|
||||||
err = AmOnUserJoinCommunityServices(tx, c, u)
|
err = AmOnUserJoinCommunityServices(ctx, tx, c, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := c.TouchUpdateTx(tx)
|
err := c.TouchUpdateTx(ctx, tx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ar := AmNewAudit(AuditCommunitySetMembership, personUID, ipaddr, fmt.Sprintf("cid=%d", c.Id),
|
ar := AmNewAudit(AuditCommunitySetMembership, personUID, ipaddr, fmt.Sprintf("cid=%d", c.Id),
|
||||||
fmt.Sprintf("uid=%d", u.Uid), fmt.Sprintf("level=%d", level))
|
fmt.Sprintf("uid=%d", u.Uid), fmt.Sprintf("level=%d", level))
|
||||||
@@ -450,11 +454,11 @@ func (c *Community) PermissionLevel(perm string) uint16 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetFlags retrieves the flags from the properties.
|
// GetFlags retrieves the flags from the properties.
|
||||||
func (c *Community) Flags() (*util.OptionSet, error) {
|
func (c *Community) Flags(ctx context.Context) (*util.OptionSet, error) {
|
||||||
c.Mutex.Lock()
|
c.Mutex.Lock()
|
||||||
defer c.Mutex.Unlock()
|
defer c.Mutex.Unlock()
|
||||||
if c.flags == nil {
|
if c.flags == nil {
|
||||||
s, err := AmGetCommunityProperty(c.Id, CommunityPropFlags)
|
s, err := AmGetCommunityProperty(ctx, c.Id, CommunityPropFlags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -468,11 +472,11 @@ func (c *Community) Flags() (*util.OptionSet, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SaveFlags writes the flags to the database and stores them.
|
// SaveFlags writes the flags to the database and stores them.
|
||||||
func (c *Community) SaveFlags(f *util.OptionSet) error {
|
func (c *Community) SaveFlags(ctx context.Context, f *util.OptionSet) error {
|
||||||
s := f.AsString()
|
s := f.AsString()
|
||||||
c.Mutex.Lock()
|
c.Mutex.Lock()
|
||||||
defer c.Mutex.Unlock()
|
defer c.Mutex.Unlock()
|
||||||
err := AmSetCommunityProperty(c.Id, CommunityPropFlags, &s)
|
err := AmSetCommunityProperty(ctx, c.Id, CommunityPropFlags, &s)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.flags = f
|
c.flags = f
|
||||||
}
|
}
|
||||||
@@ -480,12 +484,12 @@ func (c *Community) SaveFlags(f *util.OptionSet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetProfileData sets all the "settable" profile data
|
// SetProfileData sets all the "settable" profile data
|
||||||
func (c *Community) SetProfileData(name string, alias string, synopsis *string, rules *string, language *string,
|
func (c *Community) SetProfileData(ctx context.Context, name string, alias string, synopsis *string, rules *string, language *string,
|
||||||
joinkey *string, membersonly bool, hideDirectory bool, hideSearch bool, read_lvl uint16, write_lvl uint16,
|
joinkey *string, membersonly bool, hideDirectory bool, hideSearch bool, read_lvl uint16, write_lvl uint16,
|
||||||
create_lvl uint16, delete_lvl uint16, join_lvl uint16) error {
|
create_lvl uint16, delete_lvl uint16, join_lvl uint16) error {
|
||||||
c.Mutex.Lock()
|
c.Mutex.Lock()
|
||||||
defer c.Mutex.Unlock()
|
defer c.Mutex.Unlock()
|
||||||
_, err := amdb.Exec(`UPDATE communities SET commname = ?, alias = ?, synopsis = ?, rules = ?, language = ?,
|
_, err := amdb.ExecContext(ctx, `UPDATE communities SET commname = ?, alias = ?, synopsis = ?, rules = ?, language = ?,
|
||||||
joinkey = ?, membersonly = ?, hide_dir = ?, hide_search = ?, read_lvl = ?, write_lvl = ?, create_lvl = ?,
|
joinkey = ?, membersonly = ?, hide_dir = ?, hide_search = ?, read_lvl = ?, write_lvl = ?, create_lvl = ?,
|
||||||
delete_lvl = ?, join_lvl = ?, lastupdate = NOW() WHERE commid = ?`,
|
delete_lvl = ?, join_lvl = ?, lastupdate = NOW() WHERE commid = ?`,
|
||||||
name, alias, synopsis, rules, language, joinkey, membersonly, hideDirectory, hideSearch, read_lvl, write_lvl,
|
name, alias, synopsis, rules, language, joinkey, membersonly, hideDirectory, hideSearch, read_lvl, write_lvl,
|
||||||
@@ -505,7 +509,7 @@ func (c *Community) SetProfileData(name string, alias string, synopsis *string,
|
|||||||
c.CreateLevel = create_lvl
|
c.CreateLevel = create_lvl
|
||||||
c.DeleteLevel = delete_lvl
|
c.DeleteLevel = delete_lvl
|
||||||
c.JoinLevel = join_lvl
|
c.JoinLevel = join_lvl
|
||||||
rs, err2 := amdb.Query("SELECT lastupdate FROM communities WHERE commid = ?", c.Id)
|
rs, err2 := amdb.QueryContext(ctx, "SELECT lastupdate FROM communities WHERE commid = ?", c.Id)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
rs.Next()
|
rs.Next()
|
||||||
rs.Scan(&c.LastUpdate)
|
rs.Scan(&c.LastUpdate)
|
||||||
@@ -515,10 +519,10 @@ func (c *Community) SetProfileData(name string, alias string, synopsis *string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetContactID sets the contact ID for the community.
|
// SetContactID sets the contact ID for the community.
|
||||||
func (c *Community) SetContactID(cid int32) error {
|
func (c *Community) SetContactID(ctx context.Context, cid int32) error {
|
||||||
c.Mutex.Lock()
|
c.Mutex.Lock()
|
||||||
defer c.Mutex.Unlock()
|
defer c.Mutex.Unlock()
|
||||||
if _, err := amdb.Exec("UPDATE communities SET contactid = ? WHERE commid = ?", cid, c.Id); err != nil {
|
if _, err := amdb.ExecContext(ctx, "UPDATE communities SET contactid = ? WHERE commid = ?", cid, c.Id); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.ContactId = cid
|
c.ContactId = cid
|
||||||
@@ -526,12 +530,12 @@ func (c *Community) SetContactID(cid int32) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Touch updates the last access time of the community.
|
// Touch updates the last access time of the community.
|
||||||
func (c *Community) Touch() error {
|
func (c *Community) Touch(ctx context.Context) error {
|
||||||
c.Mutex.Lock()
|
c.Mutex.Lock()
|
||||||
defer c.Mutex.Unlock()
|
defer c.Mutex.Unlock()
|
||||||
_, err := amdb.Exec("UPDATE communities SET lastaccess = NOW() WHERE commid = ?", c.Id)
|
_, err := amdb.ExecContext(ctx, "UPDATE communities SET lastaccess = NOW() WHERE commid = ?", c.Id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rs, err := amdb.Query("SELECT lastaccess FROM communities WHERE commid = ?", c.Id)
|
rs, err := amdb.QueryContext(ctx, "SELECT lastaccess FROM communities WHERE commid = ?", c.Id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rs.Next()
|
rs.Next()
|
||||||
var na time.Time
|
var na time.Time
|
||||||
@@ -543,12 +547,12 @@ func (c *Community) Touch() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TouchUpdateTx updates the last access and last update times of the community.
|
// TouchUpdateTx updates the last access and last update times of the community.
|
||||||
func (c *Community) TouchUpdateTx(tx *sqlx.Tx) error {
|
func (c *Community) TouchUpdateTx(ctx context.Context, tx *sqlx.Tx) error {
|
||||||
c.Mutex.Lock()
|
c.Mutex.Lock()
|
||||||
defer c.Mutex.Unlock()
|
defer c.Mutex.Unlock()
|
||||||
_, err := tx.Exec("UPDATE communities SET lastaccess = NOW(), lastupdate = NOW() WHERE commid = ?", c.Id)
|
_, err := tx.ExecContext(ctx, "UPDATE communities SET lastaccess = NOW(), lastupdate = NOW() WHERE commid = ?", c.Id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rs, err := tx.Query("SELECT lastaccess, lastupdate FROM communities WHERE commid = ?", c.Id)
|
rs, err := tx.QueryContext(ctx, "SELECT lastaccess, lastupdate FROM communities WHERE commid = ?", c.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rs.Next()
|
rs.Next()
|
||||||
var na, nu time.Time
|
var na, nu time.Time
|
||||||
@@ -561,9 +565,9 @@ func (c *Community) TouchUpdateTx(tx *sqlx.Tx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TouchUpdateTx updates the last access and last update times of the community.
|
// TouchUpdateTx updates the last access and last update times of the community.
|
||||||
func (c *Community) TouchUpdate() error {
|
func (c *Community) TouchUpdate(ctx context.Context) error {
|
||||||
tx := amdb.MustBegin()
|
tx := amdb.MustBegin()
|
||||||
err := c.TouchUpdateTx(tx)
|
err := c.TouchUpdateTx(ctx, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
}
|
}
|
||||||
@@ -575,18 +579,19 @@ func (c *Community) TouchUpdate() error {
|
|||||||
|
|
||||||
/* AmGetCommunity returns a reference to the specified community.
|
/* AmGetCommunity returns a reference to the specified community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* id - The ID of the community.
|
* id - The ID of the community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to Community containing community data, or nil
|
* Pointer to Community containing community data, or nil
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmGetCommunity(id int32) (*Community, error) {
|
func AmGetCommunity(ctx context.Context, id int32) (*Community, error) {
|
||||||
getCommunityMutex.Lock()
|
getCommunityMutex.Lock()
|
||||||
defer getCommunityMutex.Unlock()
|
defer getCommunityMutex.Unlock()
|
||||||
rc, ok := communityCache.Get(id)
|
rc, ok := communityCache.Get(id)
|
||||||
if !ok {
|
if !ok {
|
||||||
var dbdata []Community
|
var dbdata []Community
|
||||||
err := amdb.Select(&dbdata, "SELECT * from communities WHERE commid = ?", id)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * from communities WHERE commid = ?", id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -603,19 +608,20 @@ func AmGetCommunity(id int32) (*Community, error) {
|
|||||||
|
|
||||||
/* AmGetCommunityTx returns a reference to the specified community, in a transaction.
|
/* AmGetCommunityTx returns a reference to the specified community, in a transaction.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* tx - The transaction to use.
|
* tx - The transaction to use.
|
||||||
* id - The ID of the community.
|
* id - The ID of the community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to Community containing community data, or nil
|
* Pointer to Community containing community data, or nil
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmGetCommunityTx(tx *sqlx.Tx, id int32) (*Community, error) {
|
func AmGetCommunityTx(ctx context.Context, tx *sqlx.Tx, id int32) (*Community, error) {
|
||||||
getCommunityMutex.Lock()
|
getCommunityMutex.Lock()
|
||||||
defer getCommunityMutex.Unlock()
|
defer getCommunityMutex.Unlock()
|
||||||
rc, ok := communityCache.Get(id)
|
rc, ok := communityCache.Get(id)
|
||||||
if !ok {
|
if !ok {
|
||||||
var dbdata []Community
|
var dbdata []Community
|
||||||
err := tx.Select(&dbdata, "SELECT * from communities WHERE commid = ?", id)
|
err := tx.SelectContext(ctx, &dbdata, "SELECT * from communities WHERE commid = ?", id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -632,18 +638,19 @@ func AmGetCommunityTx(tx *sqlx.Tx, id int32) (*Community, error) {
|
|||||||
|
|
||||||
/* AmGetCommunityByAlias returns a reference to the specified community.
|
/* AmGetCommunityByAlias returns a reference to the specified community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* alias - The alias for the community.
|
* alias - The alias for the community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to Community containing community data, or nil
|
* Pointer to Community containing community data, or nil
|
||||||
* Standard Go error status (nil if community not found)
|
* Standard Go error status (nil if community not found)
|
||||||
*/
|
*/
|
||||||
func AmGetCommunityByAlias(alias string) (*Community, error) {
|
func AmGetCommunityByAlias(ctx context.Context, alias string) (*Community, error) {
|
||||||
rs, err := amdb.Query("SELECT commid FROM communities WHERE alias = ?", alias)
|
rs, err := amdb.QueryContext(ctx, "SELECT commid FROM communities WHERE alias = ?", alias)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if rs.Next() {
|
if rs.Next() {
|
||||||
var cid int32
|
var cid int32
|
||||||
rs.Scan(&cid)
|
rs.Scan(&cid)
|
||||||
return AmGetCommunity(cid)
|
return AmGetCommunity(ctx, cid)
|
||||||
} else {
|
} else {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -653,19 +660,20 @@ func AmGetCommunityByAlias(alias string) (*Community, error) {
|
|||||||
|
|
||||||
/* AmGetCommunityByAliasTx returns a reference to the specified community, within a transaction.
|
/* AmGetCommunityByAliasTx returns a reference to the specified community, within a transaction.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* tx - The transaction to use.
|
* tx - The transaction to use.
|
||||||
* alias - The alias for the community.
|
* alias - The alias for the community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to Community containing community data, or nil
|
* Pointer to Community containing community data, or nil
|
||||||
* Standard Go error status (nil if community not found)
|
* Standard Go error status (nil if community not found)
|
||||||
*/
|
*/
|
||||||
func AmGetCommunityByAliasTx(tx *sqlx.Tx, alias string) (*Community, error) {
|
func AmGetCommunityByAliasTx(ctx context.Context, tx *sqlx.Tx, alias string) (*Community, error) {
|
||||||
rs, err := tx.Query("SELECT commid FROM communities WHERE alias = ?", alias)
|
rs, err := tx.QueryContext(ctx, "SELECT commid FROM communities WHERE alias = ?", alias)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if rs.Next() {
|
if rs.Next() {
|
||||||
var cid int32
|
var cid int32
|
||||||
rs.Scan(&cid)
|
rs.Scan(&cid)
|
||||||
return AmGetCommunityTx(tx, cid)
|
return AmGetCommunityTx(ctx, tx, cid)
|
||||||
} else {
|
} else {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -677,21 +685,22 @@ func AmGetCommunityByAliasTx(tx *sqlx.Tx, alias string) (*Community, error) {
|
|||||||
* If the parameter is numeric, it's interpreted as a community ID. Otherwise, it's interpreted
|
* If the parameter is numeric, it's interpreted as a community ID. Otherwise, it's interpreted
|
||||||
* as a community alias.
|
* as a community alias.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* id - The ID of the community.
|
* id - The ID of the community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to Community containing community data, or nil
|
* Pointer to Community containing community data, or nil
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmGetCommunityFromParam(param string) (*Community, error) {
|
func AmGetCommunityFromParam(ctx context.Context, param string) (*Community, error) {
|
||||||
if util.IsNumeric(param) {
|
if util.IsNumeric(param) {
|
||||||
v, _ := strconv.Atoi(param)
|
v, _ := strconv.Atoi(param)
|
||||||
c, err := AmGetCommunity(int32(v))
|
c, err := AmGetCommunity(ctx, int32(v))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
// else fall through to trying as alias
|
// else fall through to trying as alias
|
||||||
}
|
}
|
||||||
rc, err := AmGetCommunityByAlias(param)
|
rc, err := AmGetCommunityByAlias(ctx, param)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if rc == nil {
|
if rc == nil {
|
||||||
return nil, fmt.Errorf("community with alias \"%s\" not found", param)
|
return nil, fmt.Errorf("community with alias \"%s\" not found", param)
|
||||||
@@ -702,18 +711,19 @@ func AmGetCommunityFromParam(param string) (*Community, error) {
|
|||||||
|
|
||||||
/* AmGetCommunitiesForUser returns a list of communities the user is a member of.
|
/* AmGetCommunitiesForUser returns a list of communities the user is a member of.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* uid - The ID of the user.
|
* uid - The ID of the user.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Array of pointers to communities for the user
|
* Array of pointers to communities for the user
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmGetCommunitiesForUser(uid int32) ([]*Community, error) {
|
func AmGetCommunitiesForUser(ctx context.Context, uid int32) ([]*Community, error) {
|
||||||
var rc []*Community = make([]*Community, 0)
|
var rc []*Community = make([]*Community, 0)
|
||||||
var ids []int32 = make([]int32, 0)
|
var ids []int32 = make([]int32, 0)
|
||||||
err := amdb.Select(&ids, "SELECT commid FROM commmember WHERE uid = ?", uid)
|
err := amdb.SelectContext(ctx, &ids, "SELECT commid FROM commmember WHERE uid = ?", uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
c, err := AmGetCommunity(id)
|
c, err := AmGetCommunity(ctx, id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc = append(rc, c)
|
rc = append(rc, c)
|
||||||
} else {
|
} else {
|
||||||
@@ -727,15 +737,16 @@ func AmGetCommunitiesForUser(uid int32) ([]*Community, error) {
|
|||||||
/* AmGetCommunityAccessLevel returns the access level of the specified user with respect to the community.
|
/* AmGetCommunityAccessLevel returns the access level of the specified user with respect to the community.
|
||||||
* This may reflect the user's admin status as well as their status within the community.
|
* This may reflect the user's admin status as well as their status within the community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* uid - The UID of the user.
|
* uid - The UID of the user.
|
||||||
* commid - The ID of the community.
|
* commid - The ID of the community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Access level within the community, or 0 if the user is not a member.
|
* Access level within the community, or 0 if the user is not a member.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetCommunityAccessLevel(uid int32, commid int32) (uint16, error) {
|
func AmGetCommunityAccessLevel(ctx context.Context, uid int32, commid int32) (uint16, error) {
|
||||||
var rc uint16 = 0
|
var rc uint16 = 0
|
||||||
rows, err := amdb.Queryx(`SELECT GREATEST(m.granted_lvl, u.base_lvl) AS level FROM users u, commmember m
|
rows, err := amdb.QueryxContext(ctx, `SELECT GREATEST(m.granted_lvl, u.base_lvl) AS level FROM users u, commmember m
|
||||||
WHERE u.uid = m.uid AND m.uid = ? AND m.commid = ?`, uid, commid)
|
WHERE u.uid = m.uid AND m.uid = ? AND m.commid = ?`, uid, commid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
@@ -748,21 +759,22 @@ func AmGetCommunityAccessLevel(uid int32, commid int32) (uint16, error) {
|
|||||||
|
|
||||||
/* AmAutoJoinCommunities joins the specified user to any communities they're not yet a part of.
|
/* AmAutoJoinCommunities joins the specified user to any communities they're not yet a part of.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* tx - The current transaction to be used for database access.
|
* tx - The current transaction to be used for database access.
|
||||||
* user - The user to be auto-joined to communities.
|
* user - The user to be auto-joined to communities.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmAutoJoinCommunities(tx *sqlx.Tx, user *User) error {
|
func AmAutoJoinCommunities(ctx context.Context, tx *sqlx.Tx, user *User) error {
|
||||||
// get list of current communities
|
// get list of current communities
|
||||||
var current []int32 = make([]int32, 0)
|
var current []int32 = make([]int32, 0)
|
||||||
err := tx.Select(¤t, "SELECT commid FROM commmember WHERE uid = ?", user.Uid)
|
err := tx.SelectContext(ctx, ¤t, "SELECT commid FROM commmember WHERE uid = ?", user.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for candidate communities
|
// look for candidate communities
|
||||||
rows, err := tx.Queryx(`SELECT m.commid, m.locked FROM users u, communities c, commmember m
|
rows, err := tx.QueryxContext(ctx, `SELECT m.commid, m.locked FROM users u, communities c, commmember m
|
||||||
WHERE m.uid = u.uid AND m.commid = c.commid AND u.is_anon = 1 AND c.join_lvl <= ?`, user.BaseLevel)
|
WHERE m.uid = u.uid AND m.commid = c.commid AND u.is_anon = 1 AND c.join_lvl <= ?`, user.BaseLevel)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
@@ -772,7 +784,7 @@ func AmAutoJoinCommunities(tx *sqlx.Tx, user *User) error {
|
|||||||
var lock bool
|
var lock bool
|
||||||
rows.Scan(&cid, &lock)
|
rows.Scan(&cid, &lock)
|
||||||
if !slices.Contains(current, cid) {
|
if !slices.Contains(current, cid) {
|
||||||
_, err = tx.Exec("INSERT INTO commmember (commid, uid, granted_lvl, locked) VALUES (?, ?, ?, ?)",
|
_, err = tx.ExecContext(ctx, "INSERT INTO commmember (commid, uid, granted_lvl, locked) VALUES (?, ?, ?, ?)",
|
||||||
cid, user.Uid, grantLevel, lock)
|
cid, user.Uid, grantLevel, lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
@@ -785,7 +797,7 @@ func AmAutoJoinCommunities(tx *sqlx.Tx, user *User) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internalGetProp is a helper used by the property functions.
|
// internalGetProp is a helper used by the property functions.
|
||||||
func internalGetCommProp(cid int32, ndx int32) (*CommunityProperties, error) {
|
func internalGetCommProp(ctx context.Context, cid int32, ndx int32) (*CommunityProperties, error) {
|
||||||
var err error = nil
|
var err error = nil
|
||||||
key := fmt.Sprintf("%d:%d", cid, ndx)
|
key := fmt.Sprintf("%d:%d", cid, ndx)
|
||||||
getCommunityPropMutex.Lock()
|
getCommunityPropMutex.Lock()
|
||||||
@@ -793,7 +805,7 @@ func internalGetCommProp(cid int32, ndx int32) (*CommunityProperties, error) {
|
|||||||
rc, ok := communityPropCache.Get(key)
|
rc, ok := communityPropCache.Get(key)
|
||||||
if !ok {
|
if !ok {
|
||||||
var dbdata []CommunityProperties
|
var dbdata []CommunityProperties
|
||||||
err = amdb.Select(&dbdata, "SELECT * from propcomm WHERE cid = ? AND ndx = ?", cid, ndx)
|
err = amdb.SelectContext(ctx, &dbdata, "SELECT * from propcomm WHERE cid = ? AND ndx = ?", cid, ndx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -811,14 +823,15 @@ func internalGetCommProp(cid int32, ndx int32) (*CommunityProperties, error) {
|
|||||||
|
|
||||||
/* AmGetCommunityProperty retrieves the value of a user property.
|
/* AmGetCommunityProperty retrieves the value of a user property.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* cid - The ID of the community to get the property for.
|
* cid - The ID of the community to get the property for.
|
||||||
* ndx - The index of the property to retrieve.
|
* ndx - The index of the property to retrieve.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Value of the property string.
|
* Value of the property string.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetCommunityProperty(cid int32, ndx int32) (*string, error) {
|
func AmGetCommunityProperty(ctx context.Context, cid int32, ndx int32) (*string, error) {
|
||||||
p, err := internalGetCommProp(cid, ndx)
|
p, err := internalGetCommProp(ctx, cid, ndx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if p == nil {
|
} else if p == nil {
|
||||||
@@ -829,27 +842,28 @@ func AmGetCommunityProperty(cid int32, ndx int32) (*string, error) {
|
|||||||
|
|
||||||
/* AmSetCommunityProperty sets the value of a community property.
|
/* AmSetCommunityProperty sets the value of a community property.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* cid - The ID of the community to set the property for.
|
* cid - The ID of the community to set the property for.
|
||||||
* ndx - The index of the property to set.
|
* ndx - The index of the property to set.
|
||||||
* val - The new value of the property.
|
* val - The new value of the property.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmSetCommunityProperty(cid int32, ndx int32, val *string) error {
|
func AmSetCommunityProperty(ctx context.Context, cid int32, ndx int32, val *string) error {
|
||||||
p, err := internalGetCommProp(cid, ndx)
|
p, err := internalGetCommProp(ctx, cid, ndx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
getCommunityPropMutex.Lock()
|
getCommunityPropMutex.Lock()
|
||||||
defer getCommunityPropMutex.Unlock()
|
defer getCommunityPropMutex.Unlock()
|
||||||
if p != nil {
|
if p != nil {
|
||||||
_, err = amdb.Exec("UPDATE propcomm SET data = ? WHERE cid = ? AND ndx = ?", val, cid, ndx)
|
_, err = amdb.ExecContext(ctx, "UPDATE propcomm SET data = ? WHERE cid = ? AND ndx = ?", val, cid, ndx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
p.Data = val
|
p.Data = val
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
prop := CommunityProperties{Cid: cid, Index: ndx, Data: val}
|
prop := CommunityProperties{Cid: cid, Index: ndx, Data: val}
|
||||||
_, err := amdb.NamedExec("INSERT INTO propcomm (cid, ndx, data) VALUES(:cid, :ndx, :data)", prop)
|
_, err := amdb.NamedExecContext(ctx, "INSERT INTO propcomm (cid, ndx, data) VALUES(:cid, :ndx, :data)", prop)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
communityPropCache.Add(fmt.Sprintf("%d:%d", cid, ndx), prop)
|
communityPropCache.Add(fmt.Sprintf("%d:%d", cid, ndx), prop)
|
||||||
}
|
}
|
||||||
@@ -859,6 +873,7 @@ func AmSetCommunityProperty(cid int32, ndx int32, val *string) error {
|
|||||||
|
|
||||||
/* AmCreateCommunity creates a new community.
|
/* AmCreateCommunity creates a new community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* name - The name for the new community.
|
* name - The name for the new community.
|
||||||
* alias - The alias for the new community. Must be unique.
|
* alias - The alias for the new community. Must be unique.
|
||||||
* hostUid - The UID of the creator and new host of the community.
|
* hostUid - The UID of the creator and new host of the community.
|
||||||
@@ -873,7 +888,7 @@ func AmSetCommunityProperty(cid int32, ndx int32, val *string) error {
|
|||||||
* Pointer to new Community record, or nil.
|
* Pointer to new Community record, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmCreateCommunity(name string, alias string, hostUid int32, language *string, synopsis *string,
|
func AmCreateCommunity(ctx context.Context, name string, alias string, hostUid int32, language *string, synopsis *string,
|
||||||
rules *string, joinkey *string, hideDirectory bool, hideSearch bool, remoteIP string) (*Community, error) {
|
rules *string, joinkey *string, hideDirectory bool, hideSearch bool, remoteIP string) (*Community, error) {
|
||||||
var ar *AuditRecord = nil
|
var ar *AuditRecord = nil
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -888,7 +903,7 @@ func AmCreateCommunity(name string, alias string, hostUid int32, language *strin
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// validate alias does not already exist
|
// validate alias does not already exist
|
||||||
rs, err := tx.Query("SELECT commid FROM communities WHERE alias = ?", alias)
|
rs, err := tx.QueryContext(ctx, "SELECT commid FROM communities WHERE alias = ?", alias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -897,7 +912,7 @@ func AmCreateCommunity(name string, alias string, hostUid int32, language *strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// establish the community record
|
// establish the community record
|
||||||
_, err = tx.Exec(`INSERT INTO communities (createdate, lastaccess, lastupdate, read_lvl, write_lvl,
|
_, err = tx.ExecContext(ctx, `INSERT INTO communities (createdate, lastaccess, lastupdate, read_lvl, write_lvl,
|
||||||
create_lvl, delete_lvl, join_lvl, host_uid, hide_dir, hide_search, commname, language,
|
create_lvl, delete_lvl, join_lvl, host_uid, hide_dir, hide_search, commname, language,
|
||||||
synopsis, rules, joinkey, alias) VALUES (NOW(), NOW(), NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
synopsis, rules, joinkey, alias) VALUES (NOW(), NOW(), NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||||
AmRoleList("Community.Read").Default().Level(), AmRoleList("Community.Write").Default().Level(),
|
AmRoleList("Community.Read").Default().Level(), AmRoleList("Community.Write").Default().Level(),
|
||||||
@@ -909,7 +924,7 @@ func AmCreateCommunity(name string, alias string, hostUid int32, language *strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read back the community, which also puts it in the cache.
|
// Read back the community, which also puts it in the cache.
|
||||||
comm, err := AmGetCommunityByAliasTx(tx, alias)
|
comm, err := AmGetCommunityByAliasTx(ctx, tx, alias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if comm == nil {
|
} else if comm == nil {
|
||||||
@@ -918,7 +933,7 @@ func AmCreateCommunity(name string, alias string, hostUid int32, language *strin
|
|||||||
|
|
||||||
// Ensure the new host has host privileges in the community. The host's membership is "locked" so they
|
// Ensure the new host has host privileges in the community. The host's membership is "locked" so they
|
||||||
// can't unjoin and leave the community hostless.
|
// can't unjoin and leave the community hostless.
|
||||||
_, err = tx.Exec("INSERT INTO commmember (commid, uid, granted_lvl, locked) VALUES (?, ?, ?, 1)", comm.Id, hostUid,
|
_, err = tx.ExecContext(ctx, "INSERT INTO commmember (commid, uid, granted_lvl, locked) VALUES (?, ?, ?, 1)", comm.Id, hostUid,
|
||||||
AmDefaultRole("Community.Creator").Level())
|
AmDefaultRole("Community.Creator").Level())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -926,7 +941,7 @@ func AmCreateCommunity(name string, alias string, hostUid int32, language *strin
|
|||||||
stuffMembership(comm.Id, hostUid, true, true, AmDefaultRole("Community.Creator").Level())
|
stuffMembership(comm.Id, hostUid, true, true, AmDefaultRole("Community.Creator").Level())
|
||||||
|
|
||||||
// Establish the community services.
|
// Establish the community services.
|
||||||
err = AmEstablishCommunityServices(tx, comm)
|
err = AmEstablishCommunityServices(ctx, tx, comm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -945,6 +960,7 @@ func AmCreateCommunity(name string, alias string, hostUid int32, language *strin
|
|||||||
|
|
||||||
/* AmGetCommunitiesForCategory returns a list of communities for the specified category.
|
/* AmGetCommunitiesForCategory returns a list of communities for the specified category.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* catid - Category ID to search for.
|
* catid - Category ID to search for.
|
||||||
* offset - Number of communities to skip at beginning of list.
|
* offset - Number of communities to skip at beginning of list.
|
||||||
* max - Maximum number of communities to return.
|
* max - Maximum number of communities to return.
|
||||||
@@ -954,13 +970,13 @@ func AmCreateCommunity(name string, alias string, hostUid int32, language *strin
|
|||||||
* The total number of communities matching this query (could be greater than max)
|
* The total number of communities matching this query (could be greater than max)
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetCommunitiesForCategory(catid int32, offset int, max int, showAll bool) ([]*Community, int, error) {
|
func AmGetCommunitiesForCategory(ctx context.Context, catid int32, offset int, max int, showAll bool) ([]*Community, int, error) {
|
||||||
var rs *sql.Rows
|
var rs *sql.Rows
|
||||||
var err error
|
var err error
|
||||||
if showAll {
|
if showAll {
|
||||||
rs, err = amdb.Query("SELECT COUNT(*) FROM communities WHERE catid = ?", catid)
|
rs, err = amdb.QueryContext(ctx, "SELECT COUNT(*) FROM communities WHERE catid = ?", catid)
|
||||||
} else {
|
} else {
|
||||||
rs, err = amdb.Query("SELECT COUNT(*) FROM communities WHERE catid = ? AND hide_dir = 0", catid)
|
rs, err = amdb.QueryContext(ctx, "SELECT COUNT(*) FROM communities WHERE catid = ? AND hide_dir = 0", catid)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, err
|
||||||
@@ -975,17 +991,17 @@ func AmGetCommunitiesForCategory(catid int32, offset int, max int, showAll bool)
|
|||||||
}
|
}
|
||||||
if showAll {
|
if showAll {
|
||||||
if offset > 0 {
|
if offset > 0 {
|
||||||
rs, err = amdb.Query("SELECT commid FROM communities WHERE catid = ? ORDER BY commname LIMIT ? OFFSET ?",
|
rs, err = amdb.QueryContext(ctx, "SELECT commid FROM communities WHERE catid = ? ORDER BY commname LIMIT ? OFFSET ?",
|
||||||
catid, max, offset)
|
catid, max, offset)
|
||||||
} else {
|
} else {
|
||||||
rs, err = amdb.Query("SELECT commid FROM communities WHERE catid = ? ORDER BY commname LIMIT ?", catid, max)
|
rs, err = amdb.QueryContext(ctx, "SELECT commid FROM communities WHERE catid = ? ORDER BY commname LIMIT ?", catid, max)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if offset > 0 {
|
if offset > 0 {
|
||||||
rs, err = amdb.Query("SELECT commid FROM communities WHERE catid = ? AND hide_dir = 0 ORDER BY commname LIMIT ? OFFSET ?",
|
rs, err = amdb.QueryContext(ctx, "SELECT commid FROM communities WHERE catid = ? AND hide_dir = 0 ORDER BY commname LIMIT ? OFFSET ?",
|
||||||
catid, max, offset)
|
catid, max, offset)
|
||||||
} else {
|
} else {
|
||||||
rs, err = amdb.Query("SELECT commid FROM communities WHERE catid = ? AND hide_dir = 0 ORDER BY commname LIMIT ?", catid, max)
|
rs, err = amdb.QueryContext(ctx, "SELECT commid FROM communities WHERE catid = ? AND hide_dir = 0 ORDER BY commname LIMIT ?", catid, max)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -995,7 +1011,7 @@ func AmGetCommunitiesForCategory(catid int32, offset int, max int, showAll bool)
|
|||||||
for rs.Next() {
|
for rs.Next() {
|
||||||
var commid int32
|
var commid int32
|
||||||
rs.Scan(&commid)
|
rs.Scan(&commid)
|
||||||
c, err := AmGetCommunity(commid)
|
c, err := AmGetCommunity(ctx, commid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc = append(rc, c)
|
rc = append(rc, c)
|
||||||
}
|
}
|
||||||
@@ -1005,6 +1021,7 @@ func AmGetCommunitiesForCategory(catid int32, offset int, max int, showAll bool)
|
|||||||
|
|
||||||
/* AmSearchCommunities searches for communities matching certain criteria.
|
/* AmSearchCommunities searches for communities matching certain criteria.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* field - A value indicating which field to search:
|
* field - A value indicating which field to search:
|
||||||
* SearchCommFieldName - The community name.
|
* SearchCommFieldName - The community name.
|
||||||
* SearchCommFieldSynopsis - The communty synopsis.
|
* SearchCommFieldSynopsis - The communty synopsis.
|
||||||
@@ -1021,7 +1038,7 @@ func AmGetCommunitiesForCategory(catid int32, offset int, max int, showAll bool)
|
|||||||
* The total number of communities matching this query (could be greater than max)
|
* The total number of communities matching this query (could be greater than max)
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmSearchCommunities(field int, oper int, term string, offset int, max int, showAll bool) ([]*Community, int, error) {
|
func AmSearchCommunities(ctx context.Context, field int, oper int, term string, offset int, max int, showAll bool) ([]*Community, int, error) {
|
||||||
var queryPortion strings.Builder
|
var queryPortion strings.Builder
|
||||||
queryPortion.WriteString("WHERE ")
|
queryPortion.WriteString("WHERE ")
|
||||||
switch field {
|
switch field {
|
||||||
@@ -1052,7 +1069,7 @@ func AmSearchCommunities(field int, oper int, term string, offset int, max int,
|
|||||||
queryPortion.WriteString(" AND hide_search = 0")
|
queryPortion.WriteString(" AND hide_search = 0")
|
||||||
}
|
}
|
||||||
q := queryPortion.String()
|
q := queryPortion.String()
|
||||||
rs, err := amdb.Query("SELECT COUNT(*) FROM communities " + q)
|
rs, err := amdb.QueryContext(ctx, "SELECT COUNT(*) FROM communities "+q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, err
|
||||||
}
|
}
|
||||||
@@ -1065,9 +1082,9 @@ func AmSearchCommunities(field int, oper int, term string, offset int, max int,
|
|||||||
return make([]*Community, 0), 0, nil // short-circuit return
|
return make([]*Community, 0), 0, nil // short-circuit return
|
||||||
}
|
}
|
||||||
if offset > 0 {
|
if offset > 0 {
|
||||||
rs, err = amdb.Query("SELECT commid FROM communities "+q+" ORDER BY commname LIMIT ? OFFSET ?", max, offset)
|
rs, err = amdb.QueryContext(ctx, "SELECT commid FROM communities "+q+" ORDER BY commname LIMIT ? OFFSET ?", max, offset)
|
||||||
} else {
|
} else {
|
||||||
rs, err = amdb.Query("SELECT commid FROM communities "+q+" ORDER BY commname LIMIT ?", max)
|
rs, err = amdb.QueryContext(ctx, "SELECT commid FROM communities "+q+" ORDER BY commname LIMIT ?", max)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, total, err
|
return nil, total, err
|
||||||
@@ -1076,7 +1093,7 @@ func AmSearchCommunities(field int, oper int, term string, offset int, max int,
|
|||||||
for rs.Next() {
|
for rs.Next() {
|
||||||
var commid int32
|
var commid int32
|
||||||
rs.Scan(&commid)
|
rs.Scan(&commid)
|
||||||
c, err := AmGetCommunity(commid)
|
c, err := AmGetCommunity(ctx, commid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc = append(rc, c)
|
rc = append(rc, c)
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-35
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -66,8 +67,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Aliases returns the list of aliases for this conference.
|
// Aliases returns the list of aliases for this conference.
|
||||||
func (c *Conference) Aliases() ([]string, error) {
|
func (c *Conference) Aliases(ctx context.Context) ([]string, error) {
|
||||||
rs, err := amdb.Query("SELECT alias FROM confalias WHERE confid = ? ORDER BY alias", c.ConfId)
|
rs, err := amdb.QueryContext(ctx, "SELECT alias FROM confalias WHERE confid = ? ORDER BY alias", c.ConfId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -81,14 +82,14 @@ func (c *Conference) Aliases() ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AliasesQ returns the list of aliases for this conference, quietly.
|
// AliasesQ returns the list of aliases for this conference, quietly.
|
||||||
func (c *Conference) AliasesQ() []string {
|
func (c *Conference) AliasesQ(ctx context.Context) []string {
|
||||||
rc, _ := c.Aliases()
|
rc, _ := c.Aliases(ctx)
|
||||||
return rc
|
return rc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hosts returns the list of users that host this conference.
|
// Hosts returns the list of users that host this conference.
|
||||||
func (c *Conference) Hosts() ([]*User, error) {
|
func (c *Conference) Hosts(ctx context.Context) ([]*User, error) {
|
||||||
rs, err := amdb.Query("SELECT uid FROM confmember WHERE confid = ? AND granted_lvl = ?",
|
rs, err := amdb.QueryContext(ctx, "SELECT uid FROM confmember WHERE confid = ? AND granted_lvl = ?",
|
||||||
c.ConfId, AmRole("Conference.Host").Level())
|
c.ConfId, AmRole("Conference.Host").Level())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -97,7 +98,7 @@ func (c *Conference) Hosts() ([]*User, error) {
|
|||||||
for rs.Next() {
|
for rs.Next() {
|
||||||
var uid int32
|
var uid int32
|
||||||
rs.Scan(&uid)
|
rs.Scan(&uid)
|
||||||
u, err := AmGetUser(uid)
|
u, err := AmGetUser(ctx, uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc = append(rc, u)
|
rc = append(rc, u)
|
||||||
}
|
}
|
||||||
@@ -106,14 +107,14 @@ func (c *Conference) Hosts() ([]*User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hosts returns the list of users that host this conference, quietly.
|
// Hosts returns the list of users that host this conference, quietly.
|
||||||
func (c *Conference) HostsQ() []*User {
|
func (c *Conference) HostsQ(ctx context.Context) []*User {
|
||||||
rc, _ := c.Hosts()
|
rc, _ := c.Hosts(ctx)
|
||||||
return rc
|
return rc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Membership returns a membership flag and granted level for the user in this conference.
|
// Membership returns a membership flag and granted level for the user in this conference.
|
||||||
func (c *Conference) Membership(u *User) (bool, uint16, error) {
|
func (c *Conference) Membership(ctx context.Context, u *User) (bool, uint16, error) {
|
||||||
rs, err := amdb.Query("SELECT granted_lvl FROM confmember WHERE confid = ? AND uid = ?", c.ConfId, u.Uid)
|
rs, err := amdb.QueryContext(ctx, "SELECT granted_lvl FROM confmember WHERE confid = ? AND uid = ?", c.ConfId, u.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, err
|
return false, 0, err
|
||||||
}
|
}
|
||||||
@@ -155,9 +156,9 @@ func (c *Conference) TestPermission(perm string, level uint16) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Settings returns the settings for a user.
|
// Settings returns the settings for a user.
|
||||||
func (c *Conference) Settings(u *User) (*ConferenceSettings, error) {
|
func (c *Conference) Settings(ctx context.Context, u *User) (*ConferenceSettings, error) {
|
||||||
var dbdata []ConferenceSettings
|
var dbdata []ConferenceSettings
|
||||||
err := amdb.Select(&dbdata, "SELECT * FROM confsettings WHERE confid = ? AND uid = ?", c.ConfId, u.Uid)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM confsettings WHERE confid = ? AND uid = ?", c.ConfId, u.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -171,24 +172,24 @@ func (c *Conference) Settings(u *User) (*ConferenceSettings, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TouchRead updates the "last posted" date/time in the conference for the user.
|
// TouchRead updates the "last posted" date/time in the conference for the user.
|
||||||
func (c *Conference) TouchRead(tx *sqlx.Tx, u *User) (*ConferenceSettings, error) {
|
func (c *Conference) TouchRead(ctx context.Context, tx *sqlx.Tx, u *User) (*ConferenceSettings, error) {
|
||||||
cs, err := c.Settings(u)
|
cs, err := c.Settings(ctx, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !u.IsAnon { // anon user can't update squat
|
if !u.IsAnon { // anon user can't update squat
|
||||||
if cs == nil {
|
if cs == nil {
|
||||||
ci, cerr := u.ContactInfo()
|
ci, cerr := u.ContactInfo(ctx)
|
||||||
if cerr != nil {
|
if cerr != nil {
|
||||||
return nil, cerr
|
return nil, cerr
|
||||||
}
|
}
|
||||||
_, err = tx.Exec("INSERT INTO confsettings (confid, uid, default_pseud, last_read) VALUES (?, ?, ?, NOW())",
|
_, err = tx.ExecContext(ctx, "INSERT INTO confsettings (confid, uid, default_pseud, last_read) VALUES (?, ?, ?, NOW())",
|
||||||
c.ConfId, u.Uid, ci.FullName(false))
|
c.ConfId, u.Uid, ci.FullName(false))
|
||||||
} else {
|
} else {
|
||||||
_, err = tx.Exec("UPDATE confsettings SET last_read = NOW() WHERE confid = ? AND uid = ?", c.ConfId, u.Uid)
|
_, err = tx.ExecContext(ctx, "UPDATE confsettings SET last_read = NOW() WHERE confid = ? AND uid = ?", c.ConfId, u.Uid)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cs, err = c.Settings(u) // reread to get updated or inserted values
|
cs, err = c.Settings(ctx, u) // reread to get updated or inserted values
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -198,14 +199,14 @@ func (c *Conference) TouchRead(tx *sqlx.Tx, u *User) (*ConferenceSettings, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TouchPost updates the "last posted" date/time in the conference for the user.
|
// TouchPost updates the "last posted" date/time in the conference for the user.
|
||||||
func (c *Conference) TouchPost(tx *sqlx.Tx, u *User, lastPost time.Time) (*ConferenceSettings, error) {
|
func (c *Conference) TouchPost(ctx context.Context, tx *sqlx.Tx, u *User, lastPost time.Time) (*ConferenceSettings, error) {
|
||||||
cs, err := c.Settings(u)
|
cs, err := c.Settings(ctx, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !u.IsAnon { // anon user can't update squat
|
if !u.IsAnon { // anon user can't update squat
|
||||||
if cs == nil {
|
if cs == nil {
|
||||||
ci, cerr := u.ContactInfo()
|
ci, cerr := u.ContactInfo(ctx)
|
||||||
if cerr != nil {
|
if cerr != nil {
|
||||||
return nil, cerr
|
return nil, cerr
|
||||||
}
|
}
|
||||||
@@ -217,10 +218,10 @@ func (c *Conference) TouchPost(tx *sqlx.Tx, u *User, lastPost time.Time) (*Confe
|
|||||||
LastRead: &lastPost,
|
LastRead: &lastPost,
|
||||||
LastPost: &lastPost,
|
LastPost: &lastPost,
|
||||||
}
|
}
|
||||||
_, err = tx.Exec("INSERT INTO confsettings (confid, uid, default_pseud, last_read, last_post) VALUES (?, ?, ?, ?, ?)",
|
_, err = tx.ExecContext(ctx, "INSERT INTO confsettings (confid, uid, default_pseud, last_read, last_post) VALUES (?, ?, ?, ?, ?)",
|
||||||
c.ConfId, u.Uid, defaultPseud, lastPost, lastPost)
|
c.ConfId, u.Uid, defaultPseud, lastPost, lastPost)
|
||||||
} else {
|
} else {
|
||||||
_, err = tx.Exec("UPDATE confsettings SET last_post = ? WHERE confid = ? AND uid = ?", lastPost, c.ConfId, u.Uid)
|
_, err = tx.ExecContext(ctx, "UPDATE confsettings SET last_post = ? WHERE confid = ? AND uid = ?", lastPost, c.ConfId, u.Uid)
|
||||||
cs.LastPost = &lastPost
|
cs.LastPost = &lastPost
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -232,19 +233,20 @@ func (c *Conference) TouchPost(tx *sqlx.Tx, u *User, lastPost time.Time) (*Confe
|
|||||||
|
|
||||||
/* AmGetConference returns a conference given its ID.
|
/* AmGetConference returns a conference given its ID.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* id - The ID of the conference.
|
* id - The ID of the conference.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to the conference, or nil.
|
* Pointer to the conference, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetConference(id int32) (*Conference, error) {
|
func AmGetConference(ctx context.Context, id int32) (*Conference, error) {
|
||||||
var err error = nil
|
var err error = nil
|
||||||
getConferenceMutex.Lock()
|
getConferenceMutex.Lock()
|
||||||
defer getConferenceMutex.Unlock()
|
defer getConferenceMutex.Unlock()
|
||||||
rc, ok := conferenceCache.Get(id)
|
rc, ok := conferenceCache.Get(id)
|
||||||
if !ok {
|
if !ok {
|
||||||
var dbdata []Conference
|
var dbdata []Conference
|
||||||
err = amdb.Select(&dbdata, "SELECT * from confs where confid = ?", id)
|
err = amdb.SelectContext(ctx, &dbdata, "SELECT * from confs where confid = ?", id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -261,18 +263,19 @@ func AmGetConference(id int32) (*Conference, error) {
|
|||||||
|
|
||||||
/* AmGetConferenceByAlias returns a conference given its alias.
|
/* AmGetConferenceByAlias returns a conference given its alias.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* alias - The alias to look up.
|
* alias - The alias to look up.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to the conference, or nil.
|
* Pointer to the conference, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetConferenceByAlias(alias string) (*Conference, error) {
|
func AmGetConferenceByAlias(ctx context.Context, alias string) (*Conference, error) {
|
||||||
var confid int32
|
var confid int32
|
||||||
xconf, ok := conferenceAliasMap.Load(alias)
|
xconf, ok := conferenceAliasMap.Load(alias)
|
||||||
if ok {
|
if ok {
|
||||||
confid = xconf.(int32)
|
confid = xconf.(int32)
|
||||||
} else {
|
} else {
|
||||||
rs, err := amdb.Query("SELECT confid FROM confalias WHERE alias = ?", alias)
|
rs, err := amdb.QueryContext(ctx, "SELECT confid FROM confalias WHERE alias = ?", alias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -282,19 +285,20 @@ func AmGetConferenceByAlias(alias string) (*Conference, error) {
|
|||||||
rs.Scan(&confid)
|
rs.Scan(&confid)
|
||||||
conferenceAliasMap.Store(alias, confid)
|
conferenceAliasMap.Store(alias, confid)
|
||||||
}
|
}
|
||||||
return AmGetConference(confid)
|
return AmGetConference(ctx, confid)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AmGetConferenceByAliasInCommunity returns a conference in a community given its alias.
|
/* AmGetConferenceByAliasInCommunity returns a conference in a community given its alias.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* cid - The community to look inside.
|
* cid - The community to look inside.
|
||||||
* alias - The alias to look up.
|
* alias - The alias to look up.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to the conference, or nil.
|
* Pointer to the conference, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetConferenceByAliasInCommunity(cid int32, alias string) (*Conference, error) {
|
func AmGetConferenceByAliasInCommunity(ctx context.Context, cid int32, alias string) (*Conference, error) {
|
||||||
rs, err := amdb.Query(`SELECT c.confid FROM commtoconf c, confalias a WHERE c.confid = a.confid
|
rs, err := amdb.QueryContext(ctx, `SELECT c.confid FROM commtoconf c, confalias a WHERE c.confid = a.confid
|
||||||
AND c.commid = ? AND a.alias = ?`, cid, alias)
|
AND c.commid = ? AND a.alias = ?`, cid, alias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -304,23 +308,24 @@ func AmGetConferenceByAliasInCommunity(cid int32, alias string) (*Conference, er
|
|||||||
}
|
}
|
||||||
var confid int32
|
var confid int32
|
||||||
rs.Scan(&confid)
|
rs.Scan(&confid)
|
||||||
return AmGetConference(confid)
|
return AmGetConference(ctx, confid)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AmGetCommunityConferences returns all conferences for a given community.
|
/* AmGetCommunityConferences returns all conferences for a given community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* cid - Community ID to get conferences for.
|
* cid - Community ID to get conferences for.
|
||||||
* showHidden - true to show hidden conferences.
|
* showHidden - true to show hidden conferences.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Array containing the COnference pointers, or nil.
|
* Array containing the COnference pointers, or nil.
|
||||||
* Stanbard Go error status.
|
* Stanbard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetCommunityConferences(cid int32, showHidden bool) ([]*Conference, error) {
|
func AmGetCommunityConferences(ctx context.Context, cid int32, showHidden bool) ([]*Conference, error) {
|
||||||
q := ""
|
q := ""
|
||||||
if !showHidden {
|
if !showHidden {
|
||||||
q = " AND x.hide_list = 0"
|
q = " AND x.hide_list = 0"
|
||||||
}
|
}
|
||||||
rs, err := amdb.Query(`SELECT x.confid FROM commtoconf x, confs c WHERE x.confid = c.confid
|
rs, err := amdb.QueryContext(ctx, `SELECT x.confid FROM commtoconf x, confs c WHERE x.confid = c.confid
|
||||||
AND x.commid = ?`+q+" ORDER BY x.sequence, c.name", cid)
|
AND x.commid = ?`+q+" ORDER BY x.sequence, c.name", cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -329,7 +334,7 @@ func AmGetCommunityConferences(cid int32, showHidden bool) ([]*Conference, error
|
|||||||
for rs.Next() {
|
for rs.Next() {
|
||||||
var confid int32
|
var confid int32
|
||||||
rs.Scan(&confid)
|
rs.Scan(&confid)
|
||||||
conf, err := AmGetConference(confid)
|
conf, err := AmGetConference(ctx, confid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc = append(rc, conf)
|
rc = append(rc, conf)
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-15
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -51,9 +52,9 @@ type ContactInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lookupCommunityContact looks up the ID of a contact for a community.
|
// lookupCommunityContact looks up the ID of a contact for a community.
|
||||||
func lookupCommunityContact(id int32) (int32, error) {
|
func lookupCommunityContact(ctx context.Context, id int32) (int32, error) {
|
||||||
var rc int32 = -1
|
var rc int32 = -1
|
||||||
rs, err := amdb.Query("SELECT contactid FROM contacts WHERE owner_commid = ?", id)
|
rs, err := amdb.QueryContext(ctx, "SELECT contactid FROM contacts WHERE owner_commid = ?", id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if rs.Next() {
|
if rs.Next() {
|
||||||
rs.Scan(&rc)
|
rs.Scan(&rc)
|
||||||
@@ -63,9 +64,9 @@ func lookupCommunityContact(id int32) (int32, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lookupUserContact looks up the ID of a contact for a user.
|
// lookupUserContact looks up the ID of a contact for a user.
|
||||||
func lookupUserContact(uid int32) (int32, error) {
|
func lookupUserContact(ctx context.Context, uid int32) (int32, error) {
|
||||||
var rc int32 = -1
|
var rc int32 = -1
|
||||||
rs, err := amdb.Query("SELECT contactid FROM contacts WHERE owner_uid = ? AND owner_commid = -1", uid)
|
rs, err := amdb.QueryContext(ctx, "SELECT contactid FROM contacts WHERE owner_uid = ? AND owner_commid = -1", uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if rs.Next() {
|
if rs.Next() {
|
||||||
rs.Scan(&rc)
|
rs.Scan(&rc)
|
||||||
@@ -114,11 +115,13 @@ func (ci *ContactInfo) FullName(ps bool) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save saves the contact info to the database.
|
/* Save saves the contact info to the database.
|
||||||
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* Returns:
|
* Returns:
|
||||||
* true if the E-mail address on this account has been changed, false if not.
|
* true if the E-mail address on this account has been changed, false if not.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func (ci *ContactInfo) Save() (bool, error) {
|
func (ci *ContactInfo) Save(ctx context.Context) (bool, error) {
|
||||||
ci.Mutex.Lock()
|
ci.Mutex.Lock()
|
||||||
defer ci.Mutex.Unlock()
|
defer ci.Mutex.Unlock()
|
||||||
|
|
||||||
@@ -129,9 +132,9 @@ func (ci *ContactInfo) Save() (bool, error) {
|
|||||||
var nx int32
|
var nx int32
|
||||||
var err error
|
var err error
|
||||||
if ci.OwnerCommId > 0 {
|
if ci.OwnerCommId > 0 {
|
||||||
nx, err = lookupCommunityContact(ci.OwnerCommId)
|
nx, err = lookupCommunityContact(ctx, ci.OwnerCommId)
|
||||||
} else {
|
} else {
|
||||||
nx, err = lookupUserContact(ci.OwnerUid)
|
nx, err = lookupUserContact(ctx, ci.OwnerUid)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@@ -147,7 +150,7 @@ func (ci *ContactInfo) Save() (bool, error) {
|
|||||||
}
|
}
|
||||||
if !emailChange {
|
if !emailChange {
|
||||||
// we don't THINK the E-mail address is changing, but we could be wrong...
|
// we don't THINK the E-mail address is changing, but we could be wrong...
|
||||||
rs, err := amdb.Query("SELECT contactid FROM contacts WHERE contactid = ? AND email = ?", ci.ContactId, ci.Email)
|
rs, err := amdb.QueryContext(ctx, "SELECT contactid FROM contacts WHERE contactid = ? AND email = ?", ci.ContactId, ci.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -157,7 +160,7 @@ func (ci *ContactInfo) Save() (bool, error) {
|
|||||||
}
|
}
|
||||||
// Handle the database heavy lifting.
|
// Handle the database heavy lifting.
|
||||||
if updateMode {
|
if updateMode {
|
||||||
_, err := amdb.NamedExec(`UPDATE contacts SET given_name = :given_name, family_name = :family_name, middle_init = :middle_init,
|
_, err := amdb.NamedExecContext(ctx, `UPDATE contacts SET given_name = :given_name, family_name = :family_name, middle_init = :middle_init,
|
||||||
prefix = :prefix, suffix = :suffix, company = :company, addr1 = :addr1, addr2 = :addr2, locality = :locality, region = :region,
|
prefix = :prefix, suffix = :suffix, company = :company, addr1 = :addr1, addr2 = :addr2, locality = :locality, region = :region,
|
||||||
pcode = :pcode, country = :country, phone = :phone, fax = :fax, mobile = :mobile, email = :email, pvt_addr = :pvt_addr,
|
pcode = :pcode, country = :country, phone = :phone, fax = :fax, mobile = :mobile, email = :email, pvt_addr = :pvt_addr,
|
||||||
pvt_phone = :pvt_phone, pvt_fax = :pvt_fax, pvt_email = :pvt_email, photo_url = :photo_url, url = :url, lastupdate = NOW()
|
pvt_phone = :pvt_phone, pvt_fax = :pvt_fax, pvt_email = :pvt_email, photo_url = :photo_url, url = :url, lastupdate = NOW()
|
||||||
@@ -167,7 +170,7 @@ func (ci *ContactInfo) Save() (bool, error) {
|
|||||||
}
|
}
|
||||||
contactCache.Add(ci.ContactId, ci)
|
contactCache.Add(ci.ContactId, ci)
|
||||||
} else {
|
} else {
|
||||||
res, err := amdb.NamedExec(`INSERT INTO contacts (given_name, family_name, middle_init, prefix, suffix, company, addr1,
|
res, err := amdb.NamedExecContext(ctx, `INSERT INTO contacts (given_name, family_name, middle_init, prefix, suffix, company, addr1,
|
||||||
addr2, locality, region, pcode, country, phone, fax, mobile, email, pvt_addr, pvt_phone, pvt_fax,
|
addr2, locality, region, pcode, country, phone, fax, mobile, email, pvt_addr, pvt_phone, pvt_fax,
|
||||||
pvt_email, owner_uid, owner_commid, photo_url, url, lastupdate)
|
pvt_email, owner_uid, owner_commid, photo_url, url, lastupdate)
|
||||||
VALUES (:given_name, :family_name, :middle_init, :prefix, :suffix, :company, :addr1, :addr2, :locality,
|
VALUES (:given_name, :family_name, :middle_init, :prefix, :suffix, :company, :addr1, :addr2, :locality,
|
||||||
@@ -181,7 +184,7 @@ func (ci *ContactInfo) Save() (bool, error) {
|
|||||||
contactCache.Add(ci.ContactId, ci)
|
contactCache.Add(ci.ContactId, ci)
|
||||||
}
|
}
|
||||||
// Refresh the last update date.
|
// Refresh the last update date.
|
||||||
rs, err := amdb.Query("SELECT lastupdate FROM contacts WHERE contactid = ?", ci.ContactId)
|
rs, err := amdb.QueryContext(ctx, "SELECT lastupdate FROM contacts WHERE contactid = ?", ci.ContactId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -241,9 +244,9 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internalContactInfo retrieves the contact info from the database.
|
// internalContactInfo retrieves the contact info from the database.
|
||||||
func internalContactInfo(id int32) (*ContactInfo, error) {
|
func internalContactInfo(ctx context.Context, id int32) (*ContactInfo, error) {
|
||||||
var dbdata []ContactInfo
|
var dbdata []ContactInfo
|
||||||
err := amdb.Select(&dbdata, "SELECT * from contacts WHERE contactid = ?", id)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * from contacts WHERE contactid = ?", id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if len(dbdata) > 1 {
|
if len(dbdata) > 1 {
|
||||||
err = fmt.Errorf("internalContactInfo(%d): Too many responses (%d)", id, len(dbdata))
|
err = fmt.Errorf("internalContactInfo(%d): Too many responses (%d)", id, len(dbdata))
|
||||||
@@ -258,19 +261,20 @@ func internalContactInfo(id int32) (*ContactInfo, error) {
|
|||||||
|
|
||||||
/* AmGetContactInfo retrieves the contact info for a given identifier.
|
/* AmGetContactInfo retrieves the contact info for a given identifier.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* id - The contact info ID top retrieve.
|
* id - The contact info ID top retrieve.
|
||||||
* Returns:
|
* Returns:
|
||||||
* ContactInfo retrieved, or nil.
|
* ContactInfo retrieved, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetContactInfo(id int32) (*ContactInfo, error) {
|
func AmGetContactInfo(ctx context.Context, id int32) (*ContactInfo, error) {
|
||||||
getContactMutex.Lock()
|
getContactMutex.Lock()
|
||||||
defer getContactMutex.Unlock()
|
defer getContactMutex.Unlock()
|
||||||
rc, ok := contactCache.Get(id)
|
rc, ok := contactCache.Get(id)
|
||||||
if ok {
|
if ok {
|
||||||
return rc.(*ContactInfo), nil
|
return rc.(*ContactInfo), nil
|
||||||
}
|
}
|
||||||
rc2, err := internalContactInfo(id)
|
rc2, err := internalContactInfo(ctx, id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if rc2 != nil {
|
if rc2 != nil {
|
||||||
contactCache.Add(id, rc2)
|
contactCache.Add(id, rc2)
|
||||||
|
|||||||
@@ -9,15 +9,18 @@
|
|||||||
// The database package contains database management and storage logic.
|
// The database package contains database management and storage logic.
|
||||||
package database
|
package database
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
/* AmIsEmailAddressBanned returns true if the given E-mail address is on the "banned" list.
|
/* AmIsEmailAddressBanned returns true if the given E-mail address is on the "banned" list.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* address - The E-mail address to be checked.
|
* address - The E-mail address to be checked.
|
||||||
* Returns:
|
* Returns:
|
||||||
* true if the address is banned, false if not.
|
* true if the address is banned, false if not.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmIsEmailAddressBanned(address string) (bool, error) {
|
func AmIsEmailAddressBanned(ctx context.Context, address string) (bool, error) {
|
||||||
rs, err := amdb.Query("SELECT by_uid FROM emailban WHERE address = ?", address)
|
rs, err := amdb.QueryContext(ctx, "SELECT by_uid FROM emailban WHERE address = ?", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-12
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@@ -60,11 +61,11 @@ var globalProps map[int32]string = make(map[int32]string)
|
|||||||
var globalPropMutex sync.Mutex
|
var globalPropMutex sync.Mutex
|
||||||
|
|
||||||
// Flags returns the global flags.
|
// Flags returns the global flags.
|
||||||
func (g *Globals) Flags() (*util.OptionSet, error) {
|
func (g *Globals) Flags(ctx context.Context) (*util.OptionSet, error) {
|
||||||
g.Mutex.Lock()
|
g.Mutex.Lock()
|
||||||
defer g.Mutex.Unlock()
|
defer g.Mutex.Unlock()
|
||||||
if g.flags == nil {
|
if g.flags == nil {
|
||||||
s, err := AmGetGlobalProperty(GlobalPropFlags)
|
s, err := AmGetGlobalProperty(ctx, GlobalPropFlags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -74,11 +75,11 @@ func (g *Globals) Flags() (*util.OptionSet, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SaveFlags saves off the global flags.
|
// SaveFlags saves off the global flags.
|
||||||
func (g *Globals) SaveFlags(f *util.OptionSet) error {
|
func (g *Globals) SaveFlags(ctx context.Context, f *util.OptionSet) error {
|
||||||
s := f.AsString()
|
s := f.AsString()
|
||||||
g.Mutex.Lock()
|
g.Mutex.Lock()
|
||||||
defer g.Mutex.Unlock()
|
defer g.Mutex.Unlock()
|
||||||
err := AmSetGlobalProperty(GlobalPropFlags, s)
|
err := AmSetGlobalProperty(ctx, GlobalPropFlags, s)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
g.flags = f
|
g.flags = f
|
||||||
}
|
}
|
||||||
@@ -86,12 +87,12 @@ func (g *Globals) SaveFlags(f *util.OptionSet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AmGlobals returns trhe pointer to the singleton Globals instance.
|
// AmGlobals returns trhe pointer to the singleton Globals instance.
|
||||||
func AmGlobals() (*Globals, error) {
|
func AmGlobals(ctx context.Context) (*Globals, error) {
|
||||||
globalsMutex.Lock()
|
globalsMutex.Lock()
|
||||||
defer globalsMutex.Unlock()
|
defer globalsMutex.Unlock()
|
||||||
if theGlobals == nil {
|
if theGlobals == nil {
|
||||||
var dbdata []Globals
|
var dbdata []Globals
|
||||||
err := amdb.Select(&dbdata, "SELECT * FROM globals")
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM globals")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -105,17 +106,18 @@ func AmGlobals() (*Globals, error) {
|
|||||||
|
|
||||||
/* AmGetGlobalProperty returns the value of a global property.
|
/* AmGetGlobalProperty returns the value of a global property.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* index - The index of the property to retrieve.
|
* index - The index of the property to retrieve.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Value of the property, or empty string.
|
* Value of the property, or empty string.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetGlobalProperty(index int32) (string, error) {
|
func AmGetGlobalProperty(ctx context.Context, index int32) (string, error) {
|
||||||
globalPropMutex.Lock()
|
globalPropMutex.Lock()
|
||||||
defer globalPropMutex.Unlock()
|
defer globalPropMutex.Unlock()
|
||||||
rc, ok := globalProps[index]
|
rc, ok := globalProps[index]
|
||||||
if !ok {
|
if !ok {
|
||||||
rs, err := amdb.Query("SELECT data FROM propglobal WHERE ndx = ?", index)
|
rs, err := amdb.QueryContext(ctx, "SELECT data FROM propglobal WHERE ndx = ?", index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -131,17 +133,18 @@ func AmGetGlobalProperty(index int32) (string, error) {
|
|||||||
|
|
||||||
/* AmSetGlobalProperty sets the value of a global property.
|
/* AmSetGlobalProperty sets the value of a global property.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* index - The index of the property to set.
|
* index - The index of the property to set.
|
||||||
* value - The value of the property to set.
|
* value - The value of the property to set.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmSetGlobalProperty(index int32, value string) error {
|
func AmSetGlobalProperty(ctx context.Context, index int32, value string) error {
|
||||||
globalPropMutex.Lock()
|
globalPropMutex.Lock()
|
||||||
defer globalPropMutex.Unlock()
|
defer globalPropMutex.Unlock()
|
||||||
_, updateMode := globalProps[index]
|
_, updateMode := globalProps[index]
|
||||||
if !updateMode {
|
if !updateMode {
|
||||||
rs, err := amdb.Query("SELECT data FROM propglobal WHERE ndx = ?", index)
|
rs, err := amdb.QueryContext(ctx, "SELECT data FROM propglobal WHERE ndx = ?", index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -149,9 +152,9 @@ func AmSetGlobalProperty(index int32, value string) error {
|
|||||||
}
|
}
|
||||||
var err error = nil
|
var err error = nil
|
||||||
if updateMode {
|
if updateMode {
|
||||||
_, err = amdb.Exec("UPDATE propglobal SET data = ? WHERE ndx = ?", value, index)
|
_, err = amdb.ExecContext(ctx, "UPDATE propglobal SET data = ? WHERE ndx = ?", value, index)
|
||||||
} else {
|
} else {
|
||||||
_, err = amdb.Exec("INSERT INTO propglobal (ndx, data) VALUES (?, ?)", index, value)
|
_, err = amdb.ExecContext(ctx, "INSERT INTO propglobal (ndx, data) VALUES (?, ?)", index, value)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
globalProps[index] = value
|
globalProps[index] = value
|
||||||
|
|||||||
+15
-11
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
@@ -31,14 +32,14 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Save persists the ImageStore record to the database.
|
// Save persists the ImageStore record to the database.
|
||||||
func (img *ImageStore) Save() error {
|
func (img *ImageStore) Save(ctx context.Context) error {
|
||||||
var err error
|
var err error
|
||||||
if img.ImgId > 0 {
|
if img.ImgId > 0 {
|
||||||
_, err = amdb.NamedExec(`UPDATE imagestore SET typecode = :typecode, ownerid = :ownerid, mimetype = :mimetype,
|
_, err = amdb.NamedExecContext(ctx, `UPDATE imagestore SET typecode = :typecode, ownerid = :ownerid, mimetype = :mimetype,
|
||||||
length = :length, data = :data WHERE imgid = :imgid`, img)
|
length = :length, data = :data WHERE imgid = :imgid`, img)
|
||||||
} else {
|
} else {
|
||||||
var rs sql.Result
|
var rs sql.Result
|
||||||
rs, err = amdb.NamedExec(`INSERT INTO imagestore (typecode, ownerid, mimetype, length, data)
|
rs, err = amdb.NamedExecContext(ctx, `INSERT INTO imagestore (typecode, ownerid, mimetype, length, data)
|
||||||
VALUES (:typecode, :ownerid, :mimetype, :length, :data)`, img)
|
VALUES (:typecode, :ownerid, :mimetype, :length, :data)`, img)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var lii int64
|
var lii int64
|
||||||
@@ -53,14 +54,15 @@ func (img *ImageStore) Save() error {
|
|||||||
|
|
||||||
/* AmLoadImage loads an image from the database.
|
/* AmLoadImage loads an image from the database.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* id - The ID of the image to be loaded.
|
* id - The ID of the image to be loaded.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to ImageStore, or nil.
|
* Pointer to ImageStore, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmLoadImage(id int32) (*ImageStore, error) {
|
func AmLoadImage(ctx context.Context, id int32) (*ImageStore, error) {
|
||||||
var dbdata []ImageStore
|
var dbdata []ImageStore
|
||||||
err := amdb.Select(&dbdata, "SELECT * FROM imagestore WHERE imgid = ?", id)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM imagestore WHERE imgid = ?", id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -74,6 +76,7 @@ func AmLoadImage(id int32) (*ImageStore, error) {
|
|||||||
|
|
||||||
/* AmStoreImage stores an image in the database, overwriting one with the same type code and owner if it exists.
|
/* AmStoreImage stores an image in the database, overwriting one with the same type code and owner if it exists.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* typecode - Type code for the image.
|
* typecode - Type code for the image.
|
||||||
* owner - Owner Id for the image (UID or community ID)
|
* owner - Owner Id for the image (UID or community ID)
|
||||||
* mimetype - MIME type of the image.
|
* mimetype - MIME type of the image.
|
||||||
@@ -82,8 +85,8 @@ func AmLoadImage(id int32) (*ImageStore, error) {
|
|||||||
* Pointer to ImageStore, or nil.
|
* Pointer to ImageStore, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmStoreImage(typecode int16, owner int32, mimetype string, data []byte) (*ImageStore, error) {
|
func AmStoreImage(ctx context.Context, typecode int16, owner int32, mimetype string, data []byte) (*ImageStore, error) {
|
||||||
rs, err := amdb.Query("SELECT imgid FROM imagestore WHERE typecode = ? AND ownerid = ?", typecode, owner)
|
rs, err := amdb.QueryContext(ctx, "SELECT imgid FROM imagestore WHERE typecode = ? AND ownerid = ?", typecode, owner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -91,7 +94,7 @@ func AmStoreImage(typecode int16, owner int32, mimetype string, data []byte) (*I
|
|||||||
if rs.Next() {
|
if rs.Next() {
|
||||||
var id int32
|
var id int32
|
||||||
rs.Scan(&id)
|
rs.Scan(&id)
|
||||||
img, err = AmLoadImage(id)
|
img, err = AmLoadImage(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -108,7 +111,7 @@ func AmStoreImage(typecode int16, owner int32, mimetype string, data []byte) (*I
|
|||||||
Data: data,
|
Data: data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = img.Save()
|
err = img.Save(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -117,11 +120,12 @@ func AmStoreImage(typecode int16, owner int32, mimetype string, data []byte) (*I
|
|||||||
|
|
||||||
/* AmDeleteImage erases an image from the database.
|
/* AmDeleteImage erases an image from the database.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* id - The ID of the image to be deleted.
|
* id - The ID of the image to be deleted.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmDeleteImage(id int32) error {
|
func AmDeleteImage(ctx context.Context, id int32) error {
|
||||||
_, err := amdb.Exec("DELETE FROM imagestore WHERE imgid = ?", id)
|
_, err := amdb.ExecContext(ctx, "DELETE FROM imagestore WHERE imgid = ?", id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
@@ -40,12 +41,13 @@ func init() {
|
|||||||
|
|
||||||
/* AmTestIPBan tests an IP address to see if it's on the banned list.
|
/* AmTestIPBan tests an IP address to see if it's on the banned list.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context parameter.
|
||||||
* ip_address - The IP address to be tested.
|
* ip_address - The IP address to be tested.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Ban message if the address is banned, or empty string if it isn't.
|
* Ban message if the address is banned, or empty string if it isn't.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmTestIPBan(ip_address string) (string, error) {
|
func AmTestIPBan(ctx context.Context, ip_address string) (string, error) {
|
||||||
banMutex.Lock()
|
banMutex.Lock()
|
||||||
defer banMutex.Unlock()
|
defer banMutex.Unlock()
|
||||||
rc := knownBans[ip_address]
|
rc := knownBans[ip_address]
|
||||||
@@ -63,8 +65,7 @@ func AmTestIPBan(ip_address string) (string, error) {
|
|||||||
iv.SetBytes(addr)
|
iv.SetBytes(addr)
|
||||||
iv_lo := big.NewInt(0).And(iv, low64mask).Uint64()
|
iv_lo := big.NewInt(0).And(iv, low64mask).Uint64()
|
||||||
iv_hi := big.NewInt(0).Rsh(iv, 64).Uint64()
|
iv_hi := big.NewInt(0).Rsh(iv, 64).Uint64()
|
||||||
rows, err := amdb.Query(`
|
rows, err := amdb.QueryContext(ctx, `SELECT message FROM ipban WHERE (address_lo & mask_lo) = (? & mask_lo)
|
||||||
SELECT message FROM ipban WHERE (address_lo & mask_lo) = (? & mask_lo)
|
|
||||||
AND (address_hi & mask_hi) = (? & mask_hi) AND (expire IS NULL OR expire >= ?)
|
AND (address_hi & mask_hi) = (? & mask_hi) AND (expire IS NULL OR expire >= ?)
|
||||||
AND enable <> 0 ORDER BY mask_hi DESC, mask_lo DESC`, iv_lo, iv_hi, time.Now().UTC())
|
AND enable <> 0 ORDER BY mask_hi DESC, mask_lo DESC`, iv_lo, iv_hi, time.Now().UTC())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+10
-8
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
@@ -43,6 +44,7 @@ func (p *PostHeader) IsScribbled() bool {
|
|||||||
|
|
||||||
/* SetAttachment sets the attachment data for a post.
|
/* SetAttachment sets the attachment data for a post.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* fileName - Name of the original attachment file.
|
* fileName - Name of the original attachment file.
|
||||||
* mimeType - MIME type of the attachment data.
|
* mimeType - MIME type of the attachment data.
|
||||||
* length - Length of the attachment data in bytes.
|
* length - Length of the attachment data in bytes.
|
||||||
@@ -50,16 +52,16 @@ func (p *PostHeader) IsScribbled() bool {
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func (p *PostHeader) SetAttachment(fileName string, mimeType string, length int32, data []byte) error {
|
func (p *PostHeader) SetAttachment(ctx context.Context, fileName string, mimeType string, length int32, data []byte) error {
|
||||||
_, err := amdb.Exec("INSERT INTO postattach (postid, datalen, filename, mimetype, data) VALUES (?, ?, ?, ?, ?)",
|
_, err := amdb.ExecContext(ctx, "INSERT INTO postattach (postid, datalen, filename, mimetype, data) VALUES (?, ?, ?, ?, ?)",
|
||||||
p.PostId, length, fileName, mimeType, data)
|
p.PostId, length, fileName, mimeType, data)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text returns the text associated with a post.
|
// Text returns the text associated with a post.
|
||||||
func (p *PostHeader) Text() (string, error) {
|
func (p *PostHeader) Text(ctx context.Context) (string, error) {
|
||||||
var dbdata []PostData
|
var dbdata []PostData
|
||||||
err := amdb.Select(&dbdata, "SELECT * FROM postdata WHERE postid = ?", p.PostId)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM postdata WHERE postid = ?", p.PostId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -72,9 +74,9 @@ func (p *PostHeader) Text() (string, error) {
|
|||||||
return *dbdata[0].Data, nil
|
return *dbdata[0].Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func AmGetPost(postId int64) (*PostHeader, error) {
|
func AmGetPost(ctx context.Context, postId int64) (*PostHeader, error) {
|
||||||
var dbdata []PostHeader
|
var dbdata []PostHeader
|
||||||
err := amdb.Select(&dbdata, "SELECT * FROM posts WHERE postid = ?", postId)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM posts WHERE postid = ?", postId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -87,9 +89,9 @@ func AmGetPost(postId int64) (*PostHeader, error) {
|
|||||||
return &(dbdata[0]), nil
|
return &(dbdata[0]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func AmGetPostRange(topic *Topic, first, last int32) ([]PostHeader, error) {
|
func AmGetPostRange(ctx context.Context, topic *Topic, first, last int32) ([]PostHeader, error) {
|
||||||
var rc []PostHeader
|
var rc []PostHeader
|
||||||
err := amdb.Select(&rc, "SELECT * FROM posts WHERE topicid = ? AND num >= ? AND num <= ? ORDER BY num", topic.TopicId, first, last)
|
err := amdb.SelectContext(ctx, &rc, "SELECT * FROM posts WHERE topicid = ? AND num >= ? AND num <= ? ORDER BY num", topic.TopicId, first, last)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
@@ -32,9 +33,9 @@ func (d *PostLinkData) NeedsDBVerification() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VerifyNames verifies the post link data against the database.
|
// VerifyNames verifies the post link data against the database.
|
||||||
func (d *PostLinkData) VerifyNames() error {
|
func (d *PostLinkData) VerifyNames(ctx context.Context) error {
|
||||||
if d.Community != "" {
|
if d.Community != "" {
|
||||||
comm, err := AmGetCommunityByAlias(d.Community)
|
comm, err := AmGetCommunityByAlias(ctx, d.Community)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -43,7 +44,7 @@ func (d *PostLinkData) VerifyNames() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if d.Conference != "" {
|
if d.Conference != "" {
|
||||||
conf, err := AmGetConferenceByAlias(d.Conference)
|
conf, err := AmGetConferenceByAlias(ctx, d.Conference)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-27
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"slices"
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -21,28 +22,28 @@ import (
|
|||||||
|
|
||||||
// ServiceVTable is a serioes of functions called for services on specific events.
|
// ServiceVTable is a serioes of functions called for services on specific events.
|
||||||
type ServiceVTable interface {
|
type ServiceVTable interface {
|
||||||
OnNewCommunity(*sqlx.Tx, *Community) error
|
OnNewCommunity(context.Context, *sqlx.Tx, *Community) error
|
||||||
OnDeleteCommunity(*sqlx.Tx, int32) error
|
OnDeleteCommunity(context.Context, *sqlx.Tx, int32) error
|
||||||
OnUserJoinCommunity(*sqlx.Tx, *Community, *User) error
|
OnUserJoinCommunity(context.Context, *sqlx.Tx, *Community, *User) error
|
||||||
OnUserLeaveCommunity(*sqlx.Tx, *Community, *User) error
|
OnUserLeaveCommunity(context.Context, *sqlx.Tx, *Community, *User) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// emptyServiceVTable is a default ServiceVTable that does nothing.
|
// emptyServiceVTable is a default ServiceVTable that does nothing.
|
||||||
type emptyServiceVTable struct{}
|
type emptyServiceVTable struct{}
|
||||||
|
|
||||||
func (*emptyServiceVTable) OnNewCommunity(*sqlx.Tx, *Community) error {
|
func (*emptyServiceVTable) OnNewCommunity(context.Context, *sqlx.Tx, *Community) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*emptyServiceVTable) OnDeleteCommunity(*sqlx.Tx, int32) error {
|
func (*emptyServiceVTable) OnDeleteCommunity(context.Context, *sqlx.Tx, int32) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*emptyServiceVTable) OnUserJoinCommunity(*sqlx.Tx, *Community, *User) error {
|
func (*emptyServiceVTable) OnUserJoinCommunity(context.Context, *sqlx.Tx, *Community, *User) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*emptyServiceVTable) OnUserLeaveCommunity(*sqlx.Tx, *Community, *User) error {
|
func (*emptyServiceVTable) OnUserLeaveCommunity(context.Context, *sqlx.Tx, *Community, *User) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,17 +125,18 @@ func init() {
|
|||||||
|
|
||||||
/* AmGetCommunityServices returns all the community service definitions for a community.
|
/* AmGetCommunityServices returns all the community service definitions for a community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* cid - Community ID to get services for.
|
* cid - Community ID to get services for.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Array of ServiceDef pointers for the community's services.
|
* Array of ServiceDef pointers for the community's services.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetCommunityServices(cid int32) ([]*ServiceDef, error) {
|
func AmGetCommunityServices(ctx context.Context, cid int32) ([]*ServiceDef, error) {
|
||||||
servicesCacheMutex.Lock()
|
servicesCacheMutex.Lock()
|
||||||
defer servicesCacheMutex.Unlock()
|
defer servicesCacheMutex.Unlock()
|
||||||
rc, ok := servicesCache.Get(cid)
|
rc, ok := servicesCache.Get(cid)
|
||||||
if !ok {
|
if !ok {
|
||||||
rs, err := amdb.Query("SELECT ftr_code FROM commftrs WHERE commid = ?", cid)
|
rs, err := amdb.QueryContext(ctx, "SELECT ftr_code FROM commftrs WHERE commid = ?", cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -153,18 +155,19 @@ func AmGetCommunityServices(cid int32) ([]*ServiceDef, error) {
|
|||||||
|
|
||||||
/* AmGetCommunityServices returns all the community service definitions for a community, using a transaction.
|
/* AmGetCommunityServices returns all the community service definitions for a community, using a transaction.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* tx - Transaction to be used.
|
* tx - Transaction to be used.
|
||||||
* cid - Community ID to get services for.
|
* cid - Community ID to get services for.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Array of ServiceDef pointers for the community's services.
|
* Array of ServiceDef pointers for the community's services.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetCommunityServicesTx(tx *sqlx.Tx, cid int32) ([]*ServiceDef, error) {
|
func AmGetCommunityServicesTx(ctx context.Context, tx *sqlx.Tx, cid int32) ([]*ServiceDef, error) {
|
||||||
servicesCacheMutex.Lock()
|
servicesCacheMutex.Lock()
|
||||||
defer servicesCacheMutex.Unlock()
|
defer servicesCacheMutex.Unlock()
|
||||||
rc, ok := servicesCache.Get(cid)
|
rc, ok := servicesCache.Get(cid)
|
||||||
if !ok {
|
if !ok {
|
||||||
rs, err := tx.Query("SELECT ftr_code FROM commftrs WHERE commid = ?", cid)
|
rs, err := tx.QueryContext(ctx, "SELECT ftr_code FROM commftrs WHERE commid = ?", cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -184,17 +187,18 @@ func AmGetCommunityServicesTx(tx *sqlx.Tx, cid int32) ([]*ServiceDef, error) {
|
|||||||
/* AmEstablishCommunityServices establishes the service (feature) records for a new community,
|
/* AmEstablishCommunityServices establishes the service (feature) records for a new community,
|
||||||
* and allows the services to establish themselves.
|
* and allows the services to establish themselves.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* tx - The transaction to use.
|
* tx - The transaction to use.
|
||||||
* c - The new community.
|
* c - The new community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmEstablishCommunityServices(tx *sqlx.Tx, c *Community) error {
|
func AmEstablishCommunityServices(ctx context.Context, tx *sqlx.Tx, c *Community) error {
|
||||||
dom := serviceRoot.byName["community"]
|
dom := serviceRoot.byName["community"]
|
||||||
a := make([]*ServiceDef, 0, len(dom.Services))
|
a := make([]*ServiceDef, 0, len(dom.Services))
|
||||||
for i, svc := range dom.Services {
|
for i, svc := range dom.Services {
|
||||||
if svc.Default {
|
if svc.Default {
|
||||||
_, err := tx.Exec("INSERT INTO commftrs (commid, ftr_code) VALUES (?, ?)", c.Id, svc.Index)
|
_, err := tx.ExecContext(ctx, "INSERT INTO commftrs (commid, ftr_code) VALUES (?, ?)", c.Id, svc.Index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -205,7 +209,7 @@ func AmEstablishCommunityServices(tx *sqlx.Tx, c *Community) error {
|
|||||||
servicesCache.Add(c.Id, a)
|
servicesCache.Add(c.Id, a)
|
||||||
servicesCacheMutex.Unlock()
|
servicesCacheMutex.Unlock()
|
||||||
for _, svc := range a {
|
for _, svc := range a {
|
||||||
err := svc.vtable.OnNewCommunity(tx, c)
|
err := svc.vtable.OnNewCommunity(ctx, tx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -216,23 +220,24 @@ func AmEstablishCommunityServices(tx *sqlx.Tx, c *Community) error {
|
|||||||
/* AmDeleteCommunityServices cleans up all services associated with a community that has gone away,
|
/* AmDeleteCommunityServices cleans up all services associated with a community that has gone away,
|
||||||
* and then cleans up the service records.
|
* and then cleans up the service records.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* tx - The transaction to use.
|
* tx - The transaction to use.
|
||||||
* cid - The ID of the departing community.
|
* cid - The ID of the departing community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmDeleteCommunityServices(tx *sqlx.Tx, cid int32) error {
|
func AmDeleteCommunityServices(ctx context.Context, tx *sqlx.Tx, cid int32) error {
|
||||||
arr, err := AmGetCommunityServices(cid)
|
arr, err := AmGetCommunityServices(ctx, cid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, svc := range arr {
|
for _, svc := range arr {
|
||||||
err = svc.vtable.OnDeleteCommunity(tx, cid)
|
err = svc.vtable.OnDeleteCommunity(ctx, tx, cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
_, err = tx.Exec("DELETE FROM commftrs WHERE commid = ?", cid)
|
_, err = tx.ExecContext(ctx, "DELETE FROM commftrs WHERE commid = ?", cid)
|
||||||
servicesCacheMutex.Lock()
|
servicesCacheMutex.Lock()
|
||||||
servicesCache.Remove(cid)
|
servicesCache.Remove(cid)
|
||||||
servicesCacheMutex.Unlock()
|
servicesCacheMutex.Unlock()
|
||||||
@@ -242,17 +247,18 @@ func AmDeleteCommunityServices(tx *sqlx.Tx, cid int32) error {
|
|||||||
|
|
||||||
/* AmOnUserJoinCommunityServices gives services a chance to update themselves when a user joins a community.
|
/* AmOnUserJoinCommunityServices gives services a chance to update themselves when a user joins a community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* tx - The current database transaction.
|
* tx - The current database transaction.
|
||||||
* c - The community that is being joined.
|
* c - The community that is being joined.
|
||||||
* u - The user leaving that community.
|
* u - The user leaving that community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmOnUserJoinCommunityServices(tx *sqlx.Tx, c *Community, u *User) error {
|
func AmOnUserJoinCommunityServices(ctx context.Context, tx *sqlx.Tx, c *Community, u *User) error {
|
||||||
arr, err := AmGetCommunityServicesTx(tx, c.Id)
|
arr, err := AmGetCommunityServicesTx(ctx, tx, c.Id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, svc := range arr {
|
for _, svc := range arr {
|
||||||
err = svc.vtable.OnUserJoinCommunity(tx, c, u)
|
err = svc.vtable.OnUserJoinCommunity(ctx, tx, c, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -263,17 +269,18 @@ func AmOnUserJoinCommunityServices(tx *sqlx.Tx, c *Community, u *User) error {
|
|||||||
|
|
||||||
/* AmOnUserLeaveCommunityServices gives services a chance to update themselves when a user leaves a community.
|
/* AmOnUserLeaveCommunityServices gives services a chance to update themselves when a user leaves a community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* tx - The current database transaction.
|
* tx - The current database transaction.
|
||||||
* c - The community that is being left.
|
* c - The community that is being left.
|
||||||
* u - The user leaving that community.
|
* u - The user leaving that community.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmOnUserLeaveCommunityServices(tx *sqlx.Tx, c *Community, u *User) error {
|
func AmOnUserLeaveCommunityServices(ctx context.Context, tx *sqlx.Tx, c *Community, u *User) error {
|
||||||
arr, err := AmGetCommunityServicesTx(tx, c.Id)
|
arr, err := AmGetCommunityServicesTx(ctx, tx, c.Id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, svc := range arr {
|
for _, svc := range arr {
|
||||||
err = svc.vtable.OnUserLeaveCommunity(tx, c, u)
|
err = svc.vtable.OnUserLeaveCommunity(ctx, tx, c, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -282,8 +289,8 @@ func AmOnUserLeaveCommunityServices(tx *sqlx.Tx, c *Community, u *User) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func AmTestService(c *Community, serviceId string) (bool, error) {
|
func AmTestService(ctx context.Context, c *Community, serviceId string) (bool, error) {
|
||||||
arr, err := AmGetCommunityServices(c.Id)
|
arr, err := AmGetCommunityServices(ctx, c.Id)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, svc := range arr {
|
for _, svc := range arr {
|
||||||
if svc.Id == serviceId {
|
if svc.Id == serviceId {
|
||||||
|
|||||||
+11
-6
@@ -9,7 +9,11 @@
|
|||||||
// The database package contains database management and storage logic.
|
// The database package contains database management and storage logic.
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import "github.com/jmoiron/sqlx"
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
type Sidebox struct {
|
type Sidebox struct {
|
||||||
Uid int32 `db:"uid"`
|
Uid int32 `db:"uid"`
|
||||||
@@ -19,12 +23,12 @@ type Sidebox struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copySideboxes copies sideboxes from one user to another.
|
// copySideboxes copies sideboxes from one user to another.
|
||||||
func copySideboxes(tx *sqlx.Tx, toUid int32, fromUid int32) error {
|
func copySideboxes(ctx context.Context, tx *sqlx.Tx, toUid int32, fromUid int32) error {
|
||||||
sbox := make([]Sidebox, 0, 3)
|
sbox := make([]Sidebox, 0, 3)
|
||||||
err := tx.Select(&sbox, "SELECT * from sideboxes WHERE uid = ?", fromUid)
|
err := tx.SelectContext(ctx, &sbox, "SELECT * from sideboxes WHERE uid = ?", fromUid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, sb := range sbox {
|
for _, sb := range sbox {
|
||||||
_, err := tx.Exec("INSERT INTO sideboxes (uid, boxid, sequence, param) VALUES (?, ?, ?, ?)", toUid, sb.Boxid, sb.Sequence, sb.Param)
|
_, err := tx.ExecContext(ctx, "INSERT INTO sideboxes (uid, boxid, sequence, param) VALUES (?, ?, ?, ?)", toUid, sb.Boxid, sb.Sequence, sb.Param)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -35,13 +39,14 @@ func copySideboxes(tx *sqlx.Tx, toUid int32, fromUid int32) error {
|
|||||||
|
|
||||||
/* AmGetSideboxes returns all the configured sideboxes for a user.
|
/* AmGetSideboxes returns all the configured sideboxes for a user.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx = Standard Go context value.
|
||||||
* uid = The ID of the user to retrieve sideboxes for.
|
* uid = The ID of the user to retrieve sideboxes for.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Array of Sidebox structures for the user, or nil
|
* Array of Sidebox structures for the user, or nil
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmGetSideboxes(uid int32) ([]*Sidebox, error) {
|
func AmGetSideboxes(ctx context.Context, uid int32) ([]*Sidebox, error) {
|
||||||
sboxes := make([]*Sidebox, 0, 3)
|
sboxes := make([]*Sidebox, 0, 3)
|
||||||
err := amdb.Select(&sboxes, "SELECT * FROM sideboxes WHERE uid = ? ORDER BY SEQUENCE", uid)
|
err := amdb.SelectContext(ctx, &sboxes, "SELECT * FROM sideboxes WHERE uid = ? ORDER BY SEQUENCE", uid)
|
||||||
return sboxes, err
|
return sboxes, err
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-26
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -34,12 +35,12 @@ type Topic struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPost returns a post in the topic by number.
|
// GetPost returns a post in the topic by number.
|
||||||
func (t *Topic) GetPost(num int32) (*PostHeader, error) {
|
func (t *Topic) GetPost(ctx context.Context, num int32) (*PostHeader, error) {
|
||||||
if num > t.TopMessage {
|
if num > t.TopMessage {
|
||||||
return nil, fmt.Errorf("no post %d in topic %d", num, t.TopicId)
|
return nil, fmt.Errorf("no post %d in topic %d", num, t.TopicId)
|
||||||
}
|
}
|
||||||
var dbdata []PostHeader
|
var dbdata []PostHeader
|
||||||
err := amdb.Select(&dbdata, "SELECT * FROM posts WHERE topicid = ? AND num = ?", t.TopicId, num)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM posts WHERE topicid = ? AND num = ?", t.TopicId, num)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if len(dbdata) == 0 {
|
if len(dbdata) == 0 {
|
||||||
err = fmt.Errorf("no post %d in topic %d", num, t.TopicId)
|
err = fmt.Errorf("no post %d in topic %d", num, t.TopicId)
|
||||||
@@ -53,8 +54,8 @@ func (t *Topic) GetPost(num int32) (*PostHeader, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetLastRead returns the "last read" message for a user on a topic.
|
// GetLastRead returns the "last read" message for a user on a topic.
|
||||||
func (t *Topic) GetLastRead(u *User) (int32, error) {
|
func (t *Topic) GetLastRead(ctx context.Context, u *User) (int32, error) {
|
||||||
rs, err := amdb.Query("SELECT last_message FROM topicsettings WHERE topicid = ? AND uid = ?", t.TopicId, u.Uid)
|
rs, err := amdb.QueryContext(ctx, "SELECT last_message FROM topicsettings WHERE topicid = ? AND uid = ?", t.TopicId, u.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
@@ -66,12 +67,14 @@ func (t *Topic) GetLastRead(u *User) (int32, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetLastRead sets the "last read" message for a user on a topic.
|
// SetLastRead sets the "last read" message for a user on a topic.
|
||||||
func (t *Topic) SetLastRead(u *User, postNum int32) error {
|
func (t *Topic) SetLastRead(ctx context.Context, u *User, postNum int32) error {
|
||||||
rs, err := amdb.Exec("UPDATE topicsettings SET last_message = ?, last_read = NOW() WHERE topicid = ? AND uid = ?", postNum, t.TopicId, u.Uid)
|
rs, err := amdb.ExecContext(ctx, "UPDATE topicsettings SET last_message = ?, last_read = NOW() WHERE topicid = ? AND uid = ?",
|
||||||
|
postNum, t.TopicId, u.Uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
nrow, _ := rs.RowsAffected()
|
nrow, _ := rs.RowsAffected()
|
||||||
if nrow == 0 {
|
if nrow == 0 {
|
||||||
_, err = amdb.Exec("INSERT INTO topicsettings (topicid, uid, last_message, last_read, last_post) VALUES (?, ?, ?, NOW(), NULL)", t.TopicId, u.Uid, postNum)
|
_, err = amdb.ExecContext(ctx, "INSERT INTO topicsettings (topicid, uid, last_message, last_read, last_post) VALUES (?, ?, ?, NOW(), NULL)",
|
||||||
|
t.TopicId, u.Uid, postNum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -104,14 +107,15 @@ type TopicSummary struct {
|
|||||||
|
|
||||||
/* AmGetTopic retrieves a topic by ID.
|
/* AmGetTopic retrieves a topic by ID.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* topicId - ID of the topic to retrieve.
|
* topicId - ID of the topic to retrieve.
|
||||||
* Returns:
|
* Returns:
|
||||||
* The topic pointer, or nil.
|
* The topic pointer, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetTopic(topicId int32) (*Topic, error) {
|
func AmGetTopic(ctx context.Context, topicId int32) (*Topic, error) {
|
||||||
var dbdata []Topic
|
var dbdata []Topic
|
||||||
err := amdb.Select(&dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -126,15 +130,16 @@ func AmGetTopic(topicId int32) (*Topic, error) {
|
|||||||
|
|
||||||
/* AmGetTopicTx retrieves a topic by ID, in a transaction.
|
/* AmGetTopicTx retrieves a topic by ID, in a transaction.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* tx - The transaction to use.
|
* tx - The transaction to use.
|
||||||
* topicId - ID of the topic to retrieve.
|
* topicId - ID of the topic to retrieve.
|
||||||
* Returns:
|
* Returns:
|
||||||
* The topic pointer, or nil.
|
* The topic pointer, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetTopicTx(tx *sqlx.Tx, topicId int32) (*Topic, error) {
|
func AmGetTopicTx(ctx context.Context, tx *sqlx.Tx, topicId int32) (*Topic, error) {
|
||||||
var dbdata []Topic
|
var dbdata []Topic
|
||||||
err := tx.Select(&dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId)
|
err := tx.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE topicid = ?", topicId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -149,15 +154,16 @@ func AmGetTopicTx(tx *sqlx.Tx, topicId int32) (*Topic, error) {
|
|||||||
|
|
||||||
/* AmGetTopicByNumber retrieves a topic by conference and sequence number.
|
/* AmGetTopicByNumber retrieves a topic by conference and sequence number.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* conf - The conference to look in.
|
* conf - The conference to look in.
|
||||||
* topicNum - The topic number within that conference.
|
* topicNum - The topic number within that conference.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to the Topic, or nil.
|
* Pointer to the Topic, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetTopicByNumber(conf *Conference, topicNum int16) (*Topic, error) {
|
func AmGetTopicByNumber(ctx context.Context, conf *Conference, topicNum int16) (*Topic, error) {
|
||||||
var dbdata []Topic
|
var dbdata []Topic
|
||||||
err := amdb.Select(&dbdata, "SELECT * FROM topics WHERE confid = ? AND num = ?", conf.ConfId, topicNum)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM topics WHERE confid = ? AND num = ?", conf.ConfId, topicNum)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if len(dbdata) == 0 {
|
if len(dbdata) == 0 {
|
||||||
err = fmt.Errorf("no topic numbered %d in conference %s (#%d)", topicNum, conf.Name, conf.ConfId)
|
err = fmt.Errorf("no topic numbered %d in conference %s (#%d)", topicNum, conf.Name, conf.ConfId)
|
||||||
@@ -189,6 +195,7 @@ const (
|
|||||||
|
|
||||||
/* AmListTopics produces a list of topic summary information according to specific options.
|
/* AmListTopics produces a list of topic summary information according to specific options.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* confid - The ID of the conference to list topics in.
|
* confid - The ID of the conference to list topics in.
|
||||||
* uid - The UID of the user to consider the settings of.
|
* uid - The UID of the user to consider the settings of.
|
||||||
* viewOption - One of the following constants:
|
* viewOption - One of the following constants:
|
||||||
@@ -210,7 +217,7 @@ const (
|
|||||||
* List of TopicSummary pointers.
|
* List of TopicSummary pointers.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmListTopics(confid int32, uid int32, viewOption int, sortOption int, ignoreSticky bool) ([]*TopicSummary, error) {
|
func AmListTopics(ctx context.Context, confid int32, uid int32, viewOption int, sortOption int, ignoreSticky bool) ([]*TopicSummary, error) {
|
||||||
// Decode the viewOption into a WHERE clause.
|
// Decode the viewOption into a WHERE clause.
|
||||||
var whereClause string
|
var whereClause string
|
||||||
switch viewOption {
|
switch viewOption {
|
||||||
@@ -296,7 +303,7 @@ func AmListTopics(confid int32, uid int32, viewOption int, sortOption int, ignor
|
|||||||
fullStatement.WriteString(orderByClause)
|
fullStatement.WriteString(orderByClause)
|
||||||
|
|
||||||
// Execute and capture results
|
// Execute and capture results
|
||||||
rs, err := amdb.Query(fullStatement.String(), uid, confid)
|
rs, err := amdb.QueryContext(ctx, fullStatement.String(), uid, confid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -310,7 +317,7 @@ func AmListTopics(confid int32, uid int32, viewOption int, sortOption int, ignor
|
|||||||
return rc, nil
|
return rc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func AmNewTopic(conf *Conference, user *User, title string, zeroPostPseud string, zeroPost string,
|
func AmNewTopic(ctx context.Context, conf *Conference, user *User, title string, zeroPostPseud string, zeroPost string,
|
||||||
zeroPostLines int32, ipaddr string) (*Topic, error) {
|
zeroPostLines int32, ipaddr string) (*Topic, error) {
|
||||||
var ar *AuditRecord = nil
|
var ar *AuditRecord = nil
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -325,16 +332,16 @@ func AmNewTopic(conf *Conference, user *User, title string, zeroPostPseud string
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
unlock := true
|
unlock := true
|
||||||
tx.Exec("LOCK TABLES confs WRITE, topics WRITE, topicsettings WRITE, posts WRITE, postdata WRITE;")
|
tx.ExecContext(ctx, "LOCK TABLES confs WRITE, topics WRITE, topicsettings WRITE, posts WRITE, postdata WRITE;")
|
||||||
defer func() {
|
defer func() {
|
||||||
if unlock {
|
if unlock {
|
||||||
tx.Exec("UNLOCK TABLES;")
|
tx.ExecContext(ctx, "UNLOCK TABLES;")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Insert the new topic into the database.
|
// Insert the new topic into the database.
|
||||||
conf.Mutex.Lock()
|
conf.Mutex.Lock()
|
||||||
rs, err := tx.Exec("INSERT INTO topics (confid, num, creator_uid, createdate, lastupdate, name) VALUES (?, ?, ?, NOW(), NOW(), ?)",
|
rs, err := tx.ExecContext(ctx, "INSERT INTO topics (confid, num, creator_uid, createdate, lastupdate, name) VALUES (?, ?, ?, NOW(), NOW(), ?)",
|
||||||
conf.ConfId, conf.TopTopic+1, user.Uid, title)
|
conf.ConfId, conf.TopTopic+1, user.Uid, title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conf.Mutex.Unlock()
|
conf.Mutex.Unlock()
|
||||||
@@ -347,14 +354,14 @@ func AmNewTopic(conf *Conference, user *User, title string, zeroPostPseud string
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Get the topic.
|
// Get the topic.
|
||||||
topic, err := AmGetTopicTx(tx, int32(xid))
|
topic, err := AmGetTopicTx(ctx, tx, int32(xid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conf.Mutex.Unlock()
|
conf.Mutex.Unlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the conference to set the last update and top topic.
|
// Update the conference to set the last update and top topic.
|
||||||
_, err = tx.Exec("UPDATE confs SET lastupdate = ?, top_topic = ? WHERE confid = ?", topic.CreateDate, conf.TopTopic+1, conf.ConfId)
|
_, err = tx.ExecContext(ctx, "UPDATE confs SET lastupdate = ?, top_topic = ? WHERE confid = ?", topic.CreateDate, conf.TopTopic+1, conf.ConfId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conf.Mutex.Unlock()
|
conf.Mutex.Unlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -364,7 +371,7 @@ func AmNewTopic(conf *Conference, user *User, title string, zeroPostPseud string
|
|||||||
conf.Mutex.Unlock()
|
conf.Mutex.Unlock()
|
||||||
|
|
||||||
// Add the "header record" for the first post.
|
// Add the "header record" for the first post.
|
||||||
rs, err = tx.Exec("INSERT INTO posts (topicid, num, linecount, creator_uid, posted, pseud) VALUES (?, 0, ?, ?, ?, ?)",
|
rs, err = tx.ExecContext(ctx, "INSERT INTO posts (topicid, num, linecount, creator_uid, posted, pseud) VALUES (?, 0, ?, ?, ?, ?)",
|
||||||
topic.TopicId, zeroPostLines, user.Uid, topic.CreateDate, zeroPostPseud)
|
topic.TopicId, zeroPostLines, user.Uid, topic.CreateDate, zeroPostPseud)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -374,23 +381,23 @@ func AmNewTopic(conf *Conference, user *User, title string, zeroPostPseud string
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Add the post data.
|
// Add the post data.
|
||||||
_, err = tx.Exec("INSERT INTO postdata (postid, data) VALUES (?, ?)", int32(xid), zeroPost)
|
_, err = tx.ExecContext(ctx, "INSERT INTO postdata (postid, data) VALUES (?, ?)", int32(xid), zeroPost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new topic settings record for the user, too.
|
// Add a new topic settings record for the user, too.
|
||||||
_, err = tx.Exec("INSERT INTO topicsettings (topicid, uid, last_post) VALUES (?, ?, ?)",
|
_, err = tx.ExecContext(ctx, "INSERT INTO topicsettings (topicid, uid, last_post) VALUES (?, ?, ?)",
|
||||||
topic.TopicId, user.Uid, topic.CreateDate)
|
topic.TopicId, user.Uid, topic.CreateDate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.Exec("UNLOCK TABLES;")
|
tx.ExecContext(ctx, "UNLOCK TABLES;")
|
||||||
unlock = false
|
unlock = false
|
||||||
|
|
||||||
// update the "last posted" date in the conference settings
|
// update the "last posted" date in the conference settings
|
||||||
_, err = conf.TouchPost(tx, user, topic.CreateDate)
|
_, err = conf.TouchPost(ctx, tx, user, topic.CreateDate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+90
-75
@@ -10,6 +10,7 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -53,11 +54,11 @@ func (p *UserPrefs) Clone() *UserPrefs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save saves off the user preferences, replacing the prefs on the user if necessary.
|
// Save saves off the user preferences, replacing the prefs on the user if necessary.
|
||||||
func (p *UserPrefs) Save(u *User) error {
|
func (p *UserPrefs) Save(ctx context.Context, u *User) error {
|
||||||
if u != nil && u.Uid != p.Uid {
|
if u != nil && u.Uid != p.Uid {
|
||||||
return errors.New("internal mismatch of IDs")
|
return errors.New("internal mismatch of IDs")
|
||||||
}
|
}
|
||||||
_, err := amdb.NamedExec("UPDATE userprefs SET localeid = :localeid, tzid = :tzid WHERE uid = :uid", p)
|
_, err := amdb.NamedExecContext(ctx, "UPDATE userprefs SET localeid = :localeid, tzid = :tzid WHERE uid = :uid", p)
|
||||||
if err == nil && u != nil {
|
if err == nil && u != nil {
|
||||||
u.prefs = p
|
u.prefs = p
|
||||||
}
|
}
|
||||||
@@ -181,27 +182,27 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ContactInfo returns the contact info structure for the user.
|
// ContactInfo returns the contact info structure for the user.
|
||||||
func (u *User) ContactInfo() (*ContactInfo, error) {
|
func (u *User) ContactInfo(ctx context.Context) (*ContactInfo, error) {
|
||||||
if u.ContactID < 0 {
|
if u.ContactID < 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return AmGetContactInfo(u.ContactID)
|
return AmGetContactInfo(ctx, u.ContactID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContactInfo returns the contact info structure for the user, quietly.
|
// ContactInfo returns the contact info structure for the user, quietly.
|
||||||
func (u *User) ContactInfoQ() *ContactInfo {
|
func (u *User) ContactInfoQ(ctx context.Context) *ContactInfo {
|
||||||
if u.ContactID < 0 {
|
if u.ContactID < 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ci, _ := AmGetContactInfo(u.ContactID)
|
ci, _ := AmGetContactInfo(ctx, u.ContactID)
|
||||||
return ci
|
return ci
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContactID sets the contact ID of a user.
|
// SetContactID sets the contact ID of a user.
|
||||||
func (u *User) SetContactID(cid int32) error {
|
func (u *User) SetContactID(ctx context.Context, cid int32) error {
|
||||||
u.Mutex.Lock()
|
u.Mutex.Lock()
|
||||||
defer u.Mutex.Unlock()
|
defer u.Mutex.Unlock()
|
||||||
if _, err := amdb.Exec("UPDATE users SET contactid = ? WHERE uid = ?", cid, u.Uid); err != nil {
|
if _, err := amdb.ExecContext(ctx, "UPDATE users SET contactid = ? WHERE uid = ?", cid, u.Uid); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
u.ContactID = cid
|
u.ContactID = cid
|
||||||
@@ -213,14 +214,14 @@ func (u *User) SetContactID(cid int32) error {
|
|||||||
* Authentication token value
|
* Authentication token value
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func (u *User) NewAuthToken() (string, error) {
|
func (u *User) NewAuthToken(ctx context.Context) (string, error) {
|
||||||
if u.IsAnon {
|
if u.IsAnon {
|
||||||
return "", errors.New("cannot generate token for anonymous user")
|
return "", errors.New("cannot generate token for anonymous user")
|
||||||
}
|
}
|
||||||
u.Mutex.Lock()
|
u.Mutex.Lock()
|
||||||
defer u.Mutex.Unlock()
|
defer u.Mutex.Unlock()
|
||||||
newToken := util.GenerateRandomAuthString()
|
newToken := util.GenerateRandomAuthString()
|
||||||
if _, err := amdb.Exec("UPDATE users SET tokenauth = ? WHERE uid = ?", newToken, u.Uid); err != nil {
|
if _, err := amdb.ExecContext(ctx, "UPDATE users SET tokenauth = ? WHERE uid = ?", newToken, u.Uid); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
u.Tokenauth = &newToken
|
u.Tokenauth = &newToken
|
||||||
@@ -230,12 +231,13 @@ func (u *User) NewAuthToken() (string, error) {
|
|||||||
|
|
||||||
/* ConfirmEMailAddress checks the E-mail confirmation number and sets "verified" status if it's OK.
|
/* ConfirmEMailAddress checks the E-mail confirmation number and sets "verified" status if it's OK.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* confnum - The entered confirmation number.
|
* confnum - The entered confirmation number.
|
||||||
* remoteIP - The remote IP address for audit messages.
|
* remoteIP - The remote IP address for audit messages.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func (u *User) ConfirmEMailAddress(confnum int32, remoteIP string) error {
|
func (u *User) ConfirmEMailAddress(ctx context.Context, confnum int32, remoteIP string) error {
|
||||||
var ar *AuditRecord = nil
|
var ar *AuditRecord = nil
|
||||||
defer func() {
|
defer func() {
|
||||||
AmStoreAudit(ar)
|
AmStoreAudit(ar)
|
||||||
@@ -260,12 +262,12 @@ func (u *User) ConfirmEMailAddress(confnum int32, remoteIP string) error {
|
|||||||
ar = AmNewAudit(AuditVerifyEmailFail, u.Uid, remoteIP, "Invalid confirmation number")
|
ar = AmNewAudit(AuditVerifyEmailFail, u.Uid, remoteIP, "Invalid confirmation number")
|
||||||
return errors.New("confirmation number is incorrect. Please try again")
|
return errors.New("confirmation number is incorrect. Please try again")
|
||||||
}
|
}
|
||||||
_, err := tx.Exec("UPDATE users SET verify_email = 1, base_lvl = ? WHERE uid = ?",
|
_, err := tx.ExecContext(ctx, "UPDATE users SET verify_email = 1, base_lvl = ? WHERE uid = ?",
|
||||||
AmDefaultRole("Global.AfterVerify").Level(), u.Uid)
|
AmDefaultRole("Global.AfterVerify").Level(), u.Uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
u.VerifyEMail = true
|
u.VerifyEMail = true
|
||||||
u.BaseLevel = AmDefaultRole("Global.AfterVerify").Level()
|
u.BaseLevel = AmDefaultRole("Global.AfterVerify").Level()
|
||||||
err = AmAutoJoinCommunities(tx, u)
|
err = AmAutoJoinCommunities(ctx, tx, u)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -278,11 +280,11 @@ func (u *User) ConfirmEMailAddress(confnum int32, remoteIP string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewEmailConfirmationNumber creates a new confirmation number for a user and saves it off.
|
// NewEmailConfirmationNumber creates a new confirmation number for a user and saves it off.
|
||||||
func (u *User) NewEmailConfirmationNumber() error {
|
func (u *User) NewEmailConfirmationNumber(ctx context.Context) error {
|
||||||
u.Mutex.Lock()
|
u.Mutex.Lock()
|
||||||
defer u.Mutex.Unlock()
|
defer u.Mutex.Unlock()
|
||||||
newnum := util.GenerateRandomConfirmationNumber()
|
newnum := util.GenerateRandomConfirmationNumber()
|
||||||
_, err := amdb.Exec("UPDATE users SET email_confnum = ? WHERE uid = ?", newnum, u.Uid)
|
_, err := amdb.ExecContext(ctx, "UPDATE users SET email_confnum = ? WHERE uid = ?", newnum, u.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
u.EmailConfNum = newnum
|
u.EmailConfNum = newnum
|
||||||
}
|
}
|
||||||
@@ -290,7 +292,7 @@ func (u *User) NewEmailConfirmationNumber() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ChangePassword resets a user's password.
|
// ChangePassword resets a user's password.
|
||||||
func (u *User) ChangePassword(password string, remoteIP string) error {
|
func (u *User) ChangePassword(ctx context.Context, password string, remoteIP string) error {
|
||||||
var ar *AuditRecord = nil
|
var ar *AuditRecord = nil
|
||||||
defer func() {
|
defer func() {
|
||||||
AmStoreAudit(ar)
|
AmStoreAudit(ar)
|
||||||
@@ -299,7 +301,7 @@ func (u *User) ChangePassword(password string, remoteIP string) error {
|
|||||||
u.Mutex.Lock()
|
u.Mutex.Lock()
|
||||||
defer u.Mutex.Unlock()
|
defer u.Mutex.Unlock()
|
||||||
pval := hashPassword(password)
|
pval := hashPassword(password)
|
||||||
_, err := amdb.Exec("UPDATE users SET passhash = ? WHERE uid = ?", pval, u.Uid)
|
_, err := amdb.ExecContext(ctx, "UPDATE users SET passhash = ? WHERE uid = ?", pval, u.Uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
u.Passhash = pval
|
u.Passhash = pval
|
||||||
ar = AmNewAudit(AuditChangePassword, u.Uid, remoteIP, "via password change request")
|
ar = AmNewAudit(AuditChangePassword, u.Uid, remoteIP, "via password change request")
|
||||||
@@ -308,11 +310,11 @@ func (u *User) ChangePassword(password string, remoteIP string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetFlags retrieves the flags from the properties.
|
// GetFlags retrieves the flags from the properties.
|
||||||
func (u *User) Flags() (*util.OptionSet, error) {
|
func (u *User) Flags(ctx context.Context) (*util.OptionSet, error) {
|
||||||
u.Mutex.Lock()
|
u.Mutex.Lock()
|
||||||
defer u.Mutex.Unlock()
|
defer u.Mutex.Unlock()
|
||||||
if u.flags == nil {
|
if u.flags == nil {
|
||||||
s, err := AmGetUserProperty(u.Uid, UserPropFlags)
|
s, err := AmGetUserProperty(ctx, u.Uid, UserPropFlags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -325,11 +327,11 @@ func (u *User) Flags() (*util.OptionSet, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SaveFlags writes the flags to the database and stores them.
|
// SaveFlags writes the flags to the database and stores them.
|
||||||
func (u *User) SaveFlags(f *util.OptionSet) error {
|
func (u *User) SaveFlags(ctx context.Context, f *util.OptionSet) error {
|
||||||
s := f.AsString()
|
s := f.AsString()
|
||||||
u.Mutex.Lock()
|
u.Mutex.Lock()
|
||||||
defer u.Mutex.Unlock()
|
defer u.Mutex.Unlock()
|
||||||
err := AmSetUserProperty(u.Uid, UserPropFlags, &s)
|
err := AmSetUserProperty(ctx, u.Uid, UserPropFlags, &s)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
u.flags = f
|
u.flags = f
|
||||||
}
|
}
|
||||||
@@ -337,8 +339,8 @@ func (u *User) SaveFlags(f *util.OptionSet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FlagValue returns the boolean value of one of the user flags.
|
// FlagValue returns the boolean value of one of the user flags.
|
||||||
func (u *User) FlagValue(ndx uint) bool {
|
func (u *User) FlagValue(ctx context.Context, ndx uint) bool {
|
||||||
f, err := u.Flags()
|
f, err := u.Flags(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("flag retrieval error for user %d: %v", u.Uid, err)
|
log.Errorf("flag retrieval error for user %d: %v", u.Uid, err)
|
||||||
return false
|
return false
|
||||||
@@ -347,12 +349,12 @@ func (u *User) FlagValue(ndx uint) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prefs returns the user's preferences record.
|
// Prefs returns the user's preferences record.
|
||||||
func (u *User) Prefs() (*UserPrefs, error) {
|
func (u *User) Prefs(ctx context.Context) (*UserPrefs, error) {
|
||||||
u.Mutex.Lock()
|
u.Mutex.Lock()
|
||||||
defer u.Mutex.Unlock()
|
defer u.Mutex.Unlock()
|
||||||
if u.prefs == nil {
|
if u.prefs == nil {
|
||||||
var dbdata []UserPrefs
|
var dbdata []UserPrefs
|
||||||
err := amdb.Select(&dbdata, "SELECT * FROM userprefs WHERE uid = ?", u.Uid)
|
err := amdb.SelectContext(ctx, &dbdata, "SELECT * FROM userprefs WHERE uid = ?", u.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -366,13 +368,14 @@ func (u *User) Prefs() (*UserPrefs, error) {
|
|||||||
|
|
||||||
/* SetProfileData sets the "profile" variables for this user.
|
/* SetProfileData sets the "profile" variables for this user.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* reminder - Password reminder string.
|
* reminder - Password reminder string.
|
||||||
* dob - Date of birth field.
|
* dob - Date of birth field.
|
||||||
* descr - Description string.
|
* descr - Description string.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func (u *User) SetProfileData(reminder string, dob *time.Time, descr *string) error {
|
func (u *User) SetProfileData(ctx context.Context, reminder string, dob *time.Time, descr *string) error {
|
||||||
u.Mutex.Lock()
|
u.Mutex.Lock()
|
||||||
defer u.Mutex.Unlock()
|
defer u.Mutex.Unlock()
|
||||||
_, err := amdb.Exec("UPDATE users SET passreminder = ?, dob = ?, description = ? WHERE uid = ?", reminder, dob, descr, u.Uid)
|
_, err := amdb.Exec("UPDATE users SET passreminder = ?, dob = ?, description = ? WHERE uid = ?", reminder, dob, descr, u.Uid)
|
||||||
@@ -386,19 +389,20 @@ func (u *User) SetProfileData(reminder string, dob *time.Time, descr *string) er
|
|||||||
|
|
||||||
/* AmGetUser returns a reference to the specified user.
|
/* AmGetUser returns a reference to the specified user.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* uid - The UID of the user.
|
* uid - The UID of the user.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to User containing user data, or nil
|
* Pointer to User containing user data, or nil
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmGetUser(uid int32) (*User, error) {
|
func AmGetUser(ctx context.Context, uid int32) (*User, error) {
|
||||||
var err error = nil
|
var err error = nil
|
||||||
getUserMutex.Lock()
|
getUserMutex.Lock()
|
||||||
defer getUserMutex.Unlock()
|
defer getUserMutex.Unlock()
|
||||||
rc, ok := userCache.Get(uid)
|
rc, ok := userCache.Get(uid)
|
||||||
if !ok {
|
if !ok {
|
||||||
var dbdata []User
|
var dbdata []User
|
||||||
err = amdb.Select(&dbdata, "SELECT * from users WHERE uid = ?", uid)
|
err = amdb.SelectContext(ctx, &dbdata, "SELECT * from users WHERE uid = ?", uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -413,20 +417,21 @@ func AmGetUser(uid int32) (*User, error) {
|
|||||||
|
|
||||||
/* AmGetUserTx returns a reference to the specified user inside a transaction.
|
/* AmGetUserTx returns a reference to the specified user inside a transaction.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctxt - Standard Go context value.
|
||||||
* tx - The transaction we're in.
|
* tx - The transaction we're in.
|
||||||
* uid - The UID of the user.
|
* uid - The UID of the user.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to User containing user data, or nil
|
* Pointer to User containing user data, or nil
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmGetUserTx(tx *sqlx.Tx, uid int32) (*User, error) {
|
func AmGetUserTx(ctx context.Context, tx *sqlx.Tx, uid int32) (*User, error) {
|
||||||
var err error = nil
|
var err error = nil
|
||||||
getUserMutex.Lock()
|
getUserMutex.Lock()
|
||||||
defer getUserMutex.Unlock()
|
defer getUserMutex.Unlock()
|
||||||
rc, ok := userCache.Get(uid)
|
rc, ok := userCache.Get(uid)
|
||||||
if !ok {
|
if !ok {
|
||||||
var dbdata []User
|
var dbdata []User
|
||||||
err = tx.Select(&dbdata, "SELECT * from users WHERE uid = ?", uid)
|
err = tx.SelectContext(ctx, &dbdata, "SELECT * from users WHERE uid = ?", uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -441,19 +446,20 @@ func AmGetUserTx(tx *sqlx.Tx, uid int32) (*User, error) {
|
|||||||
|
|
||||||
/* AmGetUserByName returns a reference to the specified user.
|
/* AmGetUserByName returns a reference to the specified user.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* name - The username of the user.
|
* name - The username of the user.
|
||||||
* tx - If this is not nil, use this transaction.
|
* tx - If this is not nil, use this transaction.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to User containing user data, or nil
|
* Pointer to User containing user data, or nil
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmGetUserByName(name string, tx *sqlx.Tx) (*User, error) {
|
func AmGetUserByName(ctx context.Context, name string, tx *sqlx.Tx) (*User, error) {
|
||||||
var dbdata []User
|
var dbdata []User
|
||||||
var err error
|
var err error
|
||||||
if tx != nil {
|
if tx != nil {
|
||||||
err = tx.Select(&dbdata, "SELECT * FROM users WHERE username = ?", name)
|
err = tx.SelectContext(ctx, &dbdata, "SELECT * FROM users WHERE username = ?", name)
|
||||||
} else {
|
} else {
|
||||||
err = amdb.Select(&dbdata, "SELECT * FROM users WHERE username = ?", name)
|
err = amdb.SelectContext(ctx, &dbdata, "SELECT * FROM users WHERE username = ?", name)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -472,9 +478,9 @@ func AmGetUserByName(name string, tx *sqlx.Tx) (*User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getAnonUserID retrieves the UID of the "anonymous" user from the database.
|
// getAnonUserID retrieves the UID of the "anonymous" user from the database.
|
||||||
func getAnonUserID() (int32, error) {
|
func getAnonUserID(ctx context.Context) (int32, error) {
|
||||||
if anonUid < 0 {
|
if anonUid < 0 {
|
||||||
rows, err := amdb.Query("SELECT uid FROM users WHERE is_anon = 1")
|
rows, err := amdb.QueryContext(ctx, "SELECT uid FROM users WHERE is_anon = 1")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
if rows.Next() {
|
if rows.Next() {
|
||||||
@@ -495,26 +501,29 @@ func getAnonUserID() (int32, error) {
|
|||||||
|
|
||||||
/* AmIsUserAnon returns true if the specified user ID is the anonymous one.
|
/* AmIsUserAnon returns true if the specified user ID is the anonymous one.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx = Standard Go context value.
|
||||||
* uid = The user ID to test.
|
* uid = The user ID to test.
|
||||||
* Returns:
|
* Returns:
|
||||||
* true if the user is anonymous, false if not
|
* true if the user is anonymous, false if not
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmIsUserAnon(uid int32) (bool, error) {
|
func AmIsUserAnon(ctx context.Context, uid int32) (bool, error) {
|
||||||
auid, err := getAnonUserID()
|
auid, err := getAnonUserID(ctx)
|
||||||
return (uid == auid), err
|
return (uid == auid), err
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AmGetAnonUser returns a reference to the anonymous user.
|
/* AmGetAnonUser returns a reference to the anonymous user.
|
||||||
|
* Parameters:
|
||||||
|
* ctx = Standard Go context value.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to User containing anonymous user data, or nil
|
* Pointer to User containing anonymous user data, or nil
|
||||||
* Standard Go error status
|
* Standard Go error status
|
||||||
*/
|
*/
|
||||||
func AmGetAnonUser() (*User, error) {
|
func AmGetAnonUser(ctx context.Context) (*User, error) {
|
||||||
var rc *User = nil
|
var rc *User = nil
|
||||||
auid, err := getAnonUserID()
|
auid, err := getAnonUserID(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc, err = AmGetUser(auid)
|
rc, err = AmGetUser(ctx, auid)
|
||||||
}
|
}
|
||||||
return rc, err
|
return rc, err
|
||||||
}
|
}
|
||||||
@@ -531,16 +540,17 @@ func hashPassword(password string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// touchUser updates the last access time for the user.
|
// touchUser updates the last access time for the user.
|
||||||
func touchUser(tx *sqlx.Tx, user *User) {
|
func touchUser(ctx context.Context, tx *sqlx.Tx, user *User) {
|
||||||
user.Mutex.Lock()
|
user.Mutex.Lock()
|
||||||
defer user.Mutex.Unlock()
|
defer user.Mutex.Unlock()
|
||||||
moment := time.Now().UTC()
|
moment := time.Now().UTC()
|
||||||
tx.Exec("UPDATE user SET lastaccess = ? WHERE uid = ?", moment, user.Uid)
|
tx.ExecContext(ctx, "UPDATE user SET lastaccess = ? WHERE uid = ?", moment, user.Uid)
|
||||||
user.LastAccess = &moment
|
user.LastAccess = &moment
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AmAuthenticateUser authenticates a user by name and password.
|
/* AmAuthenticateUser authenticates a user by name and password.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context parameter.
|
||||||
* name - The user name to try.
|
* name - The user name to try.
|
||||||
* password - The password to try.
|
* password - The password to try.
|
||||||
* remote_ip - The remote IP address, for audit records.
|
* remote_ip - The remote IP address, for audit records.
|
||||||
@@ -548,8 +558,8 @@ func touchUser(tx *sqlx.Tx, user *User) {
|
|||||||
* The User pointer if authenticated, or nil if not.
|
* The User pointer if authenticated, or nil if not.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmAuthenticateUser(name string, password string, remoteIP string) (*User, error) {
|
func AmAuthenticateUser(ctx context.Context, name string, password string, remoteIP string) (*User, error) {
|
||||||
log.Debugf("AmAuthenicate() authenticating user %s...", name)
|
log.Debugf("AmAuthenticateUser() authenticating user %s...", name)
|
||||||
var ar *AuditRecord = nil
|
var ar *AuditRecord = nil
|
||||||
defer func() {
|
defer func() {
|
||||||
AmStoreAudit(ar)
|
AmStoreAudit(ar)
|
||||||
@@ -562,7 +572,7 @@ func AmAuthenticateUser(name string, password string, remoteIP string) (*User, e
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
user, err := AmGetUserByName(name, tx)
|
user, err := AmGetUserByName(ctx, name, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("...user not found")
|
log.Error("...user not found")
|
||||||
ar = AmNewAudit(AuditLoginFail, 0, remoteIP, fmt.Sprintf("Bad username: %s", name))
|
ar = AmNewAudit(AuditLoginFail, 0, remoteIP, fmt.Sprintf("Bad username: %s", name))
|
||||||
@@ -585,7 +595,7 @@ func AmAuthenticateUser(name string, password string, remoteIP string) (*User, e
|
|||||||
return nil, errors.New("the password you have specified is incorrect; please try again")
|
return nil, errors.New("the password you have specified is incorrect; please try again")
|
||||||
}
|
}
|
||||||
log.Debug("...authenticated")
|
log.Debug("...authenticated")
|
||||||
touchUser(tx, user)
|
touchUser(ctx, tx, user)
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -621,13 +631,14 @@ func crackAuthString(authString string) (int32, string, error) {
|
|||||||
|
|
||||||
/* AmAuthenticateUserByToken authenticates a user via the stored cookie authentication string.
|
/* AmAuthenticateUserByToken authenticates a user via the stored cookie authentication string.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* authString - The stored cookie authentication string.
|
* authString - The stored cookie authentication string.
|
||||||
* remoteIP - The remote IP address wheter trhe user is logging in from.
|
* remoteIP - The remote IP address wheter trhe user is logging in from.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to the authenticated User, or nil.
|
* Pointer to the authenticated User, or nil.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmAuthenticateUserByToken(authString string, remoteIP string) (*User, error) {
|
func AmAuthenticateUserByToken(ctx context.Context, authString string, remoteIP string) (*User, error) {
|
||||||
var ar *AuditRecord = nil
|
var ar *AuditRecord = nil
|
||||||
defer func() {
|
defer func() {
|
||||||
AmStoreAudit(ar)
|
AmStoreAudit(ar)
|
||||||
@@ -645,7 +656,7 @@ func AmAuthenticateUserByToken(authString string, remoteIP string) (*User, error
|
|||||||
return nil, fmt.Errorf("authString not valid, ignored: %v", err)
|
return nil, fmt.Errorf("authString not valid, ignored: %v", err)
|
||||||
}
|
}
|
||||||
var user *User
|
var user *User
|
||||||
user, err = AmGetUserTx(tx, uid)
|
user, err = AmGetUserTx(ctx, tx, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("...user not found")
|
log.Error("...user not found")
|
||||||
ar = AmNewAudit(AuditLoginFail, 0, remoteIP, fmt.Sprintf("Bad uid: %d", uid))
|
ar = AmNewAudit(AuditLoginFail, 0, remoteIP, fmt.Sprintf("Bad uid: %d", uid))
|
||||||
@@ -668,7 +679,7 @@ func AmAuthenticateUserByToken(authString string, remoteIP string) (*User, error
|
|||||||
return nil, errors.New("token mismatch")
|
return nil, errors.New("token mismatch")
|
||||||
}
|
}
|
||||||
log.Debug("...authenticated")
|
log.Debug("...authenticated")
|
||||||
touchUser(tx, user)
|
touchUser(ctx, tx, user)
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -680,6 +691,7 @@ func AmAuthenticateUserByToken(authString string, remoteIP string) (*User, error
|
|||||||
|
|
||||||
/* AmCreateNewUser creates a new user record in the database.
|
/* AmCreateNewUser creates a new user record in the database.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* username - New user name.
|
* username - New user name.
|
||||||
* password - New password.
|
* password - New password.
|
||||||
* reminder - Password reminder string.
|
* reminder - Password reminder string.
|
||||||
@@ -689,12 +701,12 @@ func AmAuthenticateUserByToken(authString string, remoteIP string) (*User, error
|
|||||||
* Pointer to new user record.
|
* Pointer to new user record.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmCreateNewUser(username string, password string, reminder string, dob *time.Time, remoteIP string) (*User, error) {
|
func AmCreateNewUser(ctx context.Context, username string, password string, reminder string, dob *time.Time, remoteIP string) (*User, error) {
|
||||||
var ar *AuditRecord = nil
|
var ar *AuditRecord = nil
|
||||||
defer func() {
|
defer func() {
|
||||||
AmStoreAudit(ar)
|
AmStoreAudit(ar)
|
||||||
}()
|
}()
|
||||||
anon, _ := getAnonUserID()
|
anon, _ := getAnonUserID(ctx)
|
||||||
success := false
|
success := false
|
||||||
tx := amdb.MustBegin()
|
tx := amdb.MustBegin()
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -703,15 +715,15 @@ func AmCreateNewUser(username string, password string, reminder string, dob *tim
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
unlock := true
|
unlock := true
|
||||||
tx.Exec("LOCK TABLES users WRITE, userprefs WRITE, propuser WRITE, commmember WRITE, sideboxes WRITE, confhotlist WRITE;")
|
tx.ExecContext(ctx, "LOCK TABLES users WRITE, userprefs WRITE, propuser WRITE, commmember WRITE, sideboxes WRITE, confhotlist WRITE;")
|
||||||
defer func() {
|
defer func() {
|
||||||
if unlock {
|
if unlock {
|
||||||
tx.Exec("UNLOCK TABLES;")
|
tx.ExecContext(ctx, "UNLOCK TABLES;")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Test if the user name is already taken.
|
// Test if the user name is already taken.
|
||||||
rs, err := tx.Query("SELECT uid FROM users WHERE username = ?", username)
|
rs, err := tx.QueryContext(ctx, "SELECT uid FROM users WHERE username = ?", username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if rs.Next() {
|
} else if rs.Next() {
|
||||||
@@ -720,7 +732,7 @@ func AmCreateNewUser(username string, password string, reminder string, dob *tim
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert the user record.
|
// Insert the user record.
|
||||||
_, err2 := tx.Exec(`INSERT INTO users (username, passhash, verify_email, lockout, email_confnum,
|
_, err2 := tx.ExecContext(ctx, `INSERT INTO users (username, passhash, verify_email, lockout, email_confnum,
|
||||||
base_lvl, created, lastaccess, passreminder, description, dob) VALUES (?, ?, 0, 0, ?, ?, NOW(), NOW(), ?, '', ?)`,
|
base_lvl, created, lastaccess, passreminder, description, dob) VALUES (?, ?, 0, 0, ?, ?, NOW(), NOW(), ?, '', ?)`,
|
||||||
username, hashPassword(password), util.GenerateRandomConfirmationNumber(), AmDefaultRole("Global.NewUser").Level(),
|
username, hashPassword(password), util.GenerateRandomConfirmationNumber(), AmDefaultRole("Global.NewUser").Level(),
|
||||||
reminder, dob)
|
reminder, dob)
|
||||||
@@ -728,42 +740,42 @@ func AmCreateNewUser(username string, password string, reminder string, dob *tim
|
|||||||
return nil, err2
|
return nil, err2
|
||||||
}
|
}
|
||||||
// Read back the user, which also puts it in the cache.
|
// Read back the user, which also puts it in the cache.
|
||||||
user, err3 := AmGetUserByName(username, tx)
|
user, err3 := AmGetUserByName(ctx, username, tx)
|
||||||
if err3 != nil {
|
if err3 != nil {
|
||||||
return nil, err3
|
return nil, err3
|
||||||
}
|
}
|
||||||
log.Debugf("...created new user \"%s\" with UID %d", username, user.Uid)
|
log.Debugf("...created new user \"%s\" with UID %d", username, user.Uid)
|
||||||
|
|
||||||
// add user preferences
|
// add user preferences
|
||||||
_, err = tx.Exec("INSERT INTO userprefs (uid) VALUES (?)", user.Uid)
|
_, err = tx.ExecContext(ctx, "INSERT INTO userprefs (uid) VALUES (?)", user.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// add user properties
|
// add user properties
|
||||||
props := make([]UserProperties, 0)
|
props := make([]UserProperties, 0)
|
||||||
err = tx.Select(&props, "SELECT * FROM propuser WHERE uid = ?", anon)
|
err = tx.SelectContext(ctx, &props, "SELECT * FROM propuser WHERE uid = ?", anon)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, p := range props {
|
for _, p := range props {
|
||||||
_, err := tx.Exec("INSERT INTO propuser (uid, ndx, data) VALUES (?, ?, ?)", user.Uid, p.Index, p.Data)
|
_, err := tx.ExecContext(ctx, "INSERT INTO propuser (uid, ndx, data) VALUES (?, ?, ?)", user.Uid, p.Index, p.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add user sideboxes
|
// add user sideboxes
|
||||||
err = copySideboxes(tx, user.Uid, anon)
|
err = copySideboxes(ctx, tx, user.Uid, anon)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.Exec("UNLOCK TABLES;")
|
tx.ExecContext(ctx, "UNLOCK TABLES;")
|
||||||
unlock = false
|
unlock = false
|
||||||
|
|
||||||
// auto-join communities
|
// auto-join communities
|
||||||
err = AmAutoJoinCommunities(tx, user)
|
err = AmAutoJoinCommunities(ctx, tx, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -782,7 +794,7 @@ func AmCreateNewUser(username string, password string, reminder string, dob *tim
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internalGetProp is a helper used by the property functions.
|
// internalGetProp is a helper used by the property functions.
|
||||||
func internalGetProp(uid int32, ndx int32) (*UserProperties, error) {
|
func internalGetProp(ctx context.Context, uid int32, ndx int32) (*UserProperties, error) {
|
||||||
var err error = nil
|
var err error = nil
|
||||||
key := fmt.Sprintf("%d:%d", uid, ndx)
|
key := fmt.Sprintf("%d:%d", uid, ndx)
|
||||||
getUserPropMutex.Lock()
|
getUserPropMutex.Lock()
|
||||||
@@ -790,7 +802,7 @@ func internalGetProp(uid int32, ndx int32) (*UserProperties, error) {
|
|||||||
rc, ok := userPropCache.Get(key)
|
rc, ok := userPropCache.Get(key)
|
||||||
if !ok {
|
if !ok {
|
||||||
var dbdata []UserProperties
|
var dbdata []UserProperties
|
||||||
err = amdb.Select(&dbdata, "SELECT * from propuser WHERE uid = ? AND ndx = ?", uid, ndx)
|
err = amdb.SelectContext(ctx, &dbdata, "SELECT * from propuser WHERE uid = ? AND ndx = ?", uid, ndx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -808,14 +820,15 @@ func internalGetProp(uid int32, ndx int32) (*UserProperties, error) {
|
|||||||
|
|
||||||
/* AmGetUserProperty retrieves the value of a user property.
|
/* AmGetUserProperty retrieves the value of a user property.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* uid - The UID of the user to get the property for.
|
* uid - The UID of the user to get the property for.
|
||||||
* ndx - The index of the property to retrieve.
|
* ndx - The index of the property to retrieve.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Value of the property string.
|
* Value of the property string.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmGetUserProperty(uid int32, ndx int32) (*string, error) {
|
func AmGetUserProperty(ctx context.Context, uid int32, ndx int32) (*string, error) {
|
||||||
p, err := internalGetProp(uid, ndx)
|
p, err := internalGetProp(ctx, uid, ndx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -824,27 +837,28 @@ func AmGetUserProperty(uid int32, ndx int32) (*string, error) {
|
|||||||
|
|
||||||
/* AmSetUserProperty sets the value of a user property.
|
/* AmSetUserProperty sets the value of a user property.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* uid - The UID of the user to set the property for.
|
* uid - The UID of the user to set the property for.
|
||||||
* ndx - The index of the property to set.
|
* ndx - The index of the property to set.
|
||||||
* val - The new value of the property.
|
* val - The new value of the property.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmSetUserProperty(uid int32, ndx int32, val *string) error {
|
func AmSetUserProperty(ctx context.Context, uid int32, ndx int32, val *string) error {
|
||||||
p, err := internalGetProp(uid, ndx)
|
p, err := internalGetProp(ctx, uid, ndx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
getUserPropMutex.Lock()
|
getUserPropMutex.Lock()
|
||||||
defer getUserPropMutex.Unlock()
|
defer getUserPropMutex.Unlock()
|
||||||
if p != nil {
|
if p != nil {
|
||||||
_, err = amdb.Exec("UPDATE propuser SET data = ? WHERE uid = ? AND ndx = ?", val, uid, ndx)
|
_, err = amdb.ExecContext(ctx, "UPDATE propuser SET data = ? WHERE uid = ? AND ndx = ?", val, uid, ndx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
p.Data = val
|
p.Data = val
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
prop := UserProperties{Uid: uid, Index: ndx, Data: val}
|
prop := UserProperties{Uid: uid, Index: ndx, Data: val}
|
||||||
_, err := amdb.NamedExec("INSERT INTO propuser (uid, ndx, data) VALUES(:uid, :ndx, :data)", prop)
|
_, err := amdb.NamedExecContext(ctx, "INSERT INTO propuser (uid, ndx, data) VALUES(:uid, :ndx, :data)", prop)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
userPropCache.Add(fmt.Sprintf("%d:%d", uid, ndx), prop)
|
userPropCache.Add(fmt.Sprintf("%d:%d", uid, ndx), prop)
|
||||||
}
|
}
|
||||||
@@ -854,6 +868,7 @@ func AmSetUserProperty(uid int32, ndx int32, val *string) error {
|
|||||||
|
|
||||||
/* AmSearchUsers searches for users matching certain criteria.
|
/* AmSearchUsers searches for users matching certain criteria.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* field - A value indicating which field to search:
|
* field - A value indicating which field to search:
|
||||||
* SearchUserFieldName - The user name.
|
* SearchUserFieldName - The user name.
|
||||||
* SearchUserFieldDescription - The user description.
|
* SearchUserFieldDescription - The user description.
|
||||||
@@ -871,7 +886,7 @@ func AmSetUserProperty(uid int32, ndx int32, val *string) error {
|
|||||||
* The total number of users matching this query (could be greater than max)
|
* The total number of users matching this query (could be greater than max)
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmSearchUsers(field int, oper int, term string, offset int, max int) ([]*User, int, error) {
|
func AmSearchUsers(ctx context.Context, field int, oper int, term string, offset int, max int) ([]*User, int, error) {
|
||||||
var queryPortion strings.Builder
|
var queryPortion strings.Builder
|
||||||
switch field {
|
switch field {
|
||||||
case SearchUserFieldName:
|
case SearchUserFieldName:
|
||||||
@@ -902,7 +917,7 @@ func AmSearchUsers(field int, oper int, term string, offset int, max int) ([]*Us
|
|||||||
return nil, -1, errors.New("invalid operator selector")
|
return nil, -1, errors.New("invalid operator selector")
|
||||||
}
|
}
|
||||||
q := queryPortion.String()
|
q := queryPortion.String()
|
||||||
rs, err := amdb.Query("SELECT COUNT(*) FROM users u, contacts c WHERE u.contactid = c.contactid AND u.is_anon = 0 AND " + q)
|
rs, err := amdb.QueryContext(ctx, "SELECT COUNT(*) FROM users u, contacts c WHERE u.contactid = c.contactid AND u.is_anon = 0 AND "+q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, err
|
return nil, -1, err
|
||||||
}
|
}
|
||||||
@@ -915,10 +930,10 @@ func AmSearchUsers(field int, oper int, term string, offset int, max int) ([]*Us
|
|||||||
return make([]*User, 0), 0, nil
|
return make([]*User, 0), 0, nil
|
||||||
}
|
}
|
||||||
if offset > 0 {
|
if offset > 0 {
|
||||||
rs, err = amdb.Query("SELECT u.uid FROM users u, contacts c WHERE u.contactid = c.contactid AND u.is_anon = 0 AND "+q+
|
rs, err = amdb.QueryContext(ctx, "SELECT u.uid FROM users u, contacts c WHERE u.contactid = c.contactid AND u.is_anon = 0 AND "+q+
|
||||||
" ORDER BY u.username LIMIT ? OFFSET ?", max, offset)
|
" ORDER BY u.username LIMIT ? OFFSET ?", max, offset)
|
||||||
} else {
|
} else {
|
||||||
rs, err = amdb.Query("SELECT u.uid FROM users u, contacts c WHERE u.contactid = c.contactid AND u.is_anon = 0 AND "+q+
|
rs, err = amdb.QueryContext(ctx, "SELECT u.uid FROM users u, contacts c WHERE u.contactid = c.contactid AND u.is_anon = 0 AND "+q+
|
||||||
" ORDER BY u.username LIMIT ?", max)
|
" ORDER BY u.username LIMIT ?", max)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -928,7 +943,7 @@ func AmSearchUsers(field int, oper int, term string, offset int, max int) ([]*Us
|
|||||||
for rs.Next() {
|
for rs.Next() {
|
||||||
var uid int32
|
var uid int32
|
||||||
rs.Scan(&uid)
|
rs.Scan(&uid)
|
||||||
u, err := AmGetUser(uid)
|
u, err := AmGetUser(ctx, uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc = append(rc, u)
|
rc = append(rc, u)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -12,6 +12,7 @@ package email
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"embed"
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -47,7 +48,7 @@ var mailHost string
|
|||||||
var auth smtp.Auth
|
var auth smtp.Auth
|
||||||
|
|
||||||
// formatMessage takes a message and turns it into serialized bytes for sending.
|
// formatMessage takes a message and turns it into serialized bytes for sending.
|
||||||
func formatMessage(m *amMessage) ([]byte, error) {
|
func formatMessage(ctx context.Context, m *amMessage) ([]byte, error) {
|
||||||
if m.template != "" {
|
if m.template != "" {
|
||||||
// Render the template for the message, which may reset Subject.
|
// Render the template for the message, which may reset Subject.
|
||||||
templ, err := emailRenderer.GetTemplate(m.template)
|
templ, err := emailRenderer.GetTemplate(m.template)
|
||||||
@@ -62,7 +63,7 @@ func formatMessage(m *amMessage) ([]byte, error) {
|
|||||||
return make([]byte, 0), err
|
return make([]byte, 0), err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
user, err := database.AmGetUser(m.uid)
|
user, err := database.AmGetUser(ctx, m.uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Build the final headers.
|
// Build the final headers.
|
||||||
hdrs := make(map[string]string)
|
hdrs := make(map[string]string)
|
||||||
@@ -177,7 +178,7 @@ func transmitMessage(m *amMessage, body []byte) {
|
|||||||
// senderLoop collects E-mail messages from the channel and pushes them out.
|
// senderLoop collects E-mail messages from the channel and pushes them out.
|
||||||
func senderLoop(sent chan *amMessage, done chan bool) {
|
func senderLoop(sent chan *amMessage, done chan bool) {
|
||||||
for m := range sent {
|
for m := range sent {
|
||||||
body, err := formatMessage(m)
|
body, err := formatMessage(context.Background(), m)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
transmitMessage(m, body)
|
transmitMessage(m, body)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func loadCategoryInformation(ctxt ui.AmContext, offset int) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if catid > -1 {
|
if catid > -1 {
|
||||||
cat, err := database.AmGetCategory(catid) // this step also resolves symlinks
|
cat, err := database.AmGetCategory(ctxt.Ctx(), catid) // this step also resolves symlinks
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -48,12 +48,12 @@ func loadCategoryInformation(ctxt ui.AmContext, offset int) error {
|
|||||||
ctxt.VarMap().Set("catid", catid)
|
ctxt.VarMap().Set("catid", catid)
|
||||||
showHidden := database.AmTestPermission("Global.ShowHiddenCategories", u.BaseLevel)
|
showHidden := database.AmTestPermission("Global.ShowHiddenCategories", u.BaseLevel)
|
||||||
ctxt.VarMap().Set("showHiddenCat", showHidden)
|
ctxt.VarMap().Set("showHiddenCat", showHidden)
|
||||||
hier, err := database.AmGetCategoryHierarchy(catid)
|
hier, err := database.AmGetCategoryHierarchy(ctxt.Ctx(), catid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ctxt.VarMap().Set("catHierarchy", hier)
|
ctxt.VarMap().Set("catHierarchy", hier)
|
||||||
subs, err := database.AmGetSubCategories(catid)
|
subs, err := database.AmGetSubCategories(ctxt.Ctx(), catid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ func loadCategoryInformation(ctxt ui.AmContext, offset int) error {
|
|||||||
if catid > -1 {
|
if catid > -1 {
|
||||||
// search for communities in this category
|
// search for communities in this category
|
||||||
listMax := int(ctxt.Globals().MaxSearchPage)
|
listMax := int(ctxt.Globals().MaxSearchPage)
|
||||||
commList, numComm, err := database.AmGetCommunitiesForCategory(catid, offset*listMax, listMax, showHidden)
|
commList, numComm, err := database.AmGetCommunitiesForCategory(ctxt.Ctx(), catid, offset*listMax, listMax, showHidden)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -207,7 +207,7 @@ func Find(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return "framed_template", "find.jet", nil
|
return "framed_template", "find.jet", nil
|
||||||
}
|
}
|
||||||
var clist []*database.Community
|
var clist []*database.Community
|
||||||
clist, total, err = database.AmSearchCommunities(iField, iOper, term, ofs*listMax, listMax,
|
clist, total, err = database.AmSearchCommunities(ctxt.Ctx(), iField, iOper, term, ofs*listMax, listMax,
|
||||||
ctxt.TestPermission("Global.SearchHiddenCommunities"))
|
ctxt.TestPermission("Global.SearchHiddenCommunities"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if clist == nil {
|
if clist == nil {
|
||||||
@@ -244,7 +244,7 @@ func Find(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return "framed_template", "find.jet", nil
|
return "framed_template", "find.jet", nil
|
||||||
}
|
}
|
||||||
var ulist []*database.User
|
var ulist []*database.User
|
||||||
ulist, total, err = database.AmSearchUsers(iField, iOper, term, ofs*listMax, listMax)
|
ulist, total, err = database.AmSearchUsers(ctxt.Ctx(), iField, iOper, term, ofs*listMax, listMax)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if ulist == nil {
|
if ulist == nil {
|
||||||
numResults = 0
|
numResults = 0
|
||||||
@@ -268,7 +268,7 @@ func Find(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return "framed_template", "find.jet", nil
|
return "framed_template", "find.jet", nil
|
||||||
}
|
}
|
||||||
var catlist []*database.Category
|
var catlist []*database.Category
|
||||||
catlist, total, err = database.AmSearchCategories(iOper, term, ofs*listMax, listMax,
|
catlist, total, err = database.AmSearchCategories(ctxt.Ctx(), iOper, term, ofs*listMax, listMax,
|
||||||
ctxt.TestPermission("Global.ShowHiddenCategories"), ctxt.TestPermission("Global.SearchHiddenCategories"))
|
ctxt.TestPermission("Global.ShowHiddenCategories"), ctxt.TestPermission("Global.SearchHiddenCategories"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if catlist == nil {
|
if catlist == nil {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
package htmlcheck
|
package htmlcheck
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -81,6 +82,7 @@ const hyphApos = "-'"
|
|||||||
|
|
||||||
// htmlCheckerImpl is the implementation of the HTML checker.
|
// htmlCheckerImpl is the implementation of the HTML checker.
|
||||||
type htmlCheckerImpl struct {
|
type htmlCheckerImpl struct {
|
||||||
|
ctx context.Context // request context, as instances are generally per-request
|
||||||
config *HTMLCheckerConfig // pointer to configuration
|
config *HTMLCheckerConfig // pointer to configuration
|
||||||
started bool // has checker been started?
|
started bool // has checker been started?
|
||||||
finished bool // has checker been finished?
|
finished bool // has checker been finished?
|
||||||
@@ -147,13 +149,14 @@ func (ht *htmlCheckerImpl) copyOutputFilters(dest []outputFilter, source []strin
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* AmNewHTMLChecker creates a new HTML Checker object.
|
/* AmNewHTMLChecker creates a new HTML Checker object.
|
||||||
* Parametrers:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* configName - Name of the configuration to use.
|
* configName - Name of the configuration to use.
|
||||||
* Returns:
|
* Returns:
|
||||||
* New HTML checker reference.
|
* New HTML checker reference.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmNewHTMLChecker(configName string) (HTMLChecker, error) {
|
func AmNewHTMLChecker(ctx context.Context, configName string) (HTMLChecker, error) {
|
||||||
config, ok := configsRegistry[configName]
|
config, ok := configsRegistry[configName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("configuration %s not found", configName)
|
return nil, fmt.Errorf("configuration %s not found", configName)
|
||||||
@@ -166,6 +169,7 @@ func AmNewHTMLChecker(configName string) (HTMLChecker, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc := htmlCheckerImpl{
|
rc := htmlCheckerImpl{
|
||||||
|
ctx: ctx,
|
||||||
config: config,
|
config: config,
|
||||||
started: false,
|
started: false,
|
||||||
finished: false,
|
finished: false,
|
||||||
@@ -486,7 +490,7 @@ func (ht *htmlCheckerImpl) emitFromStartOfTempBuffer(nrunes int) {
|
|||||||
// attemptRewrite attempts to apply a list of rewriters on the text, returning the first one that matches.
|
// attemptRewrite attempts to apply a list of rewriters on the text, returning the first one that matches.
|
||||||
func (ht *htmlCheckerImpl) attemptRewrite(rewriters []rewriter, data string) *markupData {
|
func (ht *htmlCheckerImpl) attemptRewrite(rewriters []rewriter, data string) *markupData {
|
||||||
for _, r := range rewriters {
|
for _, r := range rewriters {
|
||||||
rc := r.Rewrite(data, ht)
|
rc := r.Rewrite(ht.ctx, data, ht)
|
||||||
if rc != nil {
|
if rc != nil {
|
||||||
return rc
|
return rc
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
package htmlcheck
|
package htmlcheck
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@@ -76,12 +77,13 @@ func (rw *spellingRewriter) Name() string {
|
|||||||
|
|
||||||
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go error status.
|
||||||
* data - The data to be rewritten.
|
* data - The data to be rewritten.
|
||||||
* svc - Services interface we can use.
|
* svc - Services interface we can use.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to markup data, or nil.
|
* Pointer to markup data, or nil.
|
||||||
*/
|
*/
|
||||||
func (rw *spellingRewriter) Rewrite(data string, svc rewriterServices) *markupData {
|
func (rw *spellingRewriter) Rewrite(ctx context.Context, data string, svc rewriterServices) *markupData {
|
||||||
if rw.dict.CheckWord(data) {
|
if rw.dict.CheckWord(data) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
package htmlcheck
|
package htmlcheck
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"math"
|
"math"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -90,12 +91,13 @@ func (rw *emoticonRewriter) Name() string {
|
|||||||
|
|
||||||
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* data - The data to be rewritten.
|
* data - The data to be rewritten.
|
||||||
* svc - Services interface we can use.
|
* svc - Services interface we can use.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to markup data, or nil.
|
* Pointer to markup data, or nil.
|
||||||
*/
|
*/
|
||||||
func (rw *emoticonRewriter) Rewrite(data string, svc rewriterServices) *markupData {
|
func (rw *emoticonRewriter) Rewrite(ctx context.Context, data string, svc rewriterServices) *markupData {
|
||||||
pos := math.MaxInt
|
pos := math.MaxInt
|
||||||
for _, c := range rw.prefixChars {
|
for _, c := range rw.prefixChars {
|
||||||
foo := strings.IndexByte(data, c)
|
foo := strings.IndexByte(data, c)
|
||||||
@@ -163,12 +165,13 @@ func (rw *emoticonTagRewriter) Name() string {
|
|||||||
|
|
||||||
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* data - The data to be rewritten.
|
* data - The data to be rewritten.
|
||||||
* svc - Services interface we can use.
|
* svc - Services interface we can use.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to markup data, or nil.
|
* Pointer to markup data, or nil.
|
||||||
*/
|
*/
|
||||||
func (rw *emoticonTagRewriter) Rewrite(data string, svc rewriterServices) *markupData {
|
func (rw *emoticonTagRewriter) Rewrite(ctx context.Context, data string, svc rewriterServices) *markupData {
|
||||||
m := rw.re.FindStringSubmatch(data)
|
m := rw.re.FindStringSubmatch(data)
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+10
-8
@@ -10,6 +10,7 @@
|
|||||||
package htmlcheck
|
package htmlcheck
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -41,7 +42,7 @@ type rewriterServices interface {
|
|||||||
// rewriter is the interface for components that rewrite source text and place markup around it.
|
// rewriter is the interface for components that rewrite source text and place markup around it.
|
||||||
type rewriter interface {
|
type rewriter interface {
|
||||||
Name() string
|
Name() string
|
||||||
Rewrite(string, rewriterServices) *markupData
|
Rewrite(context.Context, string, rewriterServices) *markupData
|
||||||
}
|
}
|
||||||
|
|
||||||
// rewriterRegistry contains a list of all rewriters.
|
// rewriterRegistry contains a list of all rewriters.
|
||||||
@@ -72,7 +73,7 @@ func (rw *emailRewriter) Name() string {
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to markup data, or nil.
|
* Pointer to markup data, or nil.
|
||||||
*/
|
*/
|
||||||
func (rw *emailRewriter) Rewrite(data string, svc rewriterServices) *markupData {
|
func (rw *emailRewriter) Rewrite(ctx context.Context, data string, svc rewriterServices) *markupData {
|
||||||
_, err := mail.ParseAddress(data)
|
_, err := mail.ParseAddress(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -154,7 +155,7 @@ func buildPostLink(decoded, context *database.PostLinkData) string {
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to markup data, or nil.
|
* Pointer to markup data, or nil.
|
||||||
*/
|
*/
|
||||||
func (rw *postLinkRewriter) Rewrite(data string, svc rewriterServices) *markupData {
|
func (rw *postLinkRewriter) Rewrite(ctx context.Context, data string, svc rewriterServices) *markupData {
|
||||||
q := svc.rewriterContextValue("PostLinkDecoderContext")
|
q := svc.rewriterContextValue("PostLinkDecoderContext")
|
||||||
if q == nil {
|
if q == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -165,7 +166,7 @@ func (rw *postLinkRewriter) Rewrite(data string, svc rewriterServices) *markupDa
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = mydata.VerifyNames()
|
err = mydata.VerifyNames(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -205,17 +206,18 @@ func (rw *userLinkRewriter) Name() string {
|
|||||||
|
|
||||||
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* data - The data to be rewritten.
|
* data - The data to be rewritten.
|
||||||
* svc - Services interface we can use.
|
* svc - Services interface we can use.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to markup data, or nil.
|
* Pointer to markup data, or nil.
|
||||||
*/
|
*/
|
||||||
func (rw *userLinkRewriter) Rewrite(data string, svc rewriterServices) *markupData {
|
func (rw *userLinkRewriter) Rewrite(ctx context.Context, data string, svc rewriterServices) *markupData {
|
||||||
if data == "" || len(data) > 64 || !database.AmIsValidAmsterdamID(data) {
|
if data == "" || len(data) > 64 || !database.AmIsValidAmsterdamID(data) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := database.AmGetUserByName(data, nil)
|
user, err := database.AmGetUserByName(ctx, data, nil)
|
||||||
if err != nil || user == nil {
|
if err != nil || user == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -258,8 +260,8 @@ func (rw *countingRewriter) Name() string {
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to markup data, or nil.
|
* Pointer to markup data, or nil.
|
||||||
*/
|
*/
|
||||||
func (rw *countingRewriter) Rewrite(data string, svc rewriterServices) *markupData {
|
func (rw *countingRewriter) Rewrite(ctx context.Context, data string, svc rewriterServices) *markupData {
|
||||||
rc := rw.inner.Rewrite(data, svc)
|
rc := rw.inner.Rewrite(ctx, data, svc)
|
||||||
if rc != nil && !rc.rescan {
|
if rc != nil && !rc.rescan {
|
||||||
rw.count++
|
rw.count++
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
package htmlcheck
|
package htmlcheck
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -72,12 +73,13 @@ func (rw *urlRewriter) Name() string {
|
|||||||
|
|
||||||
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
/* Rewrite rewrites the given string data and adds markup before and after if needed.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* data - The data to be rewritten.
|
* data - The data to be rewritten.
|
||||||
* svc - Services interface we can use.
|
* svc - Services interface we can use.
|
||||||
* Returns:
|
* Returns:
|
||||||
* Pointer to markup data, or nil.
|
* Pointer to markup data, or nil.
|
||||||
*/
|
*/
|
||||||
func (rw *urlRewriter) Rewrite(data string, svc rewriterServices) *markupData {
|
func (rw *urlRewriter) Rewrite(ctx context.Context, data string, svc rewriterServices) *markupData {
|
||||||
for _, ue := range urlElements {
|
for _, ue := range urlElements {
|
||||||
s := ue.eval(data)
|
s := ue.eval(data)
|
||||||
if s != "" {
|
if s != "" {
|
||||||
|
|||||||
@@ -80,10 +80,10 @@ func Login(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return dlg.RenderError(ctxt, "User name not specified.")
|
return dlg.RenderError(ctxt, "User name not specified.")
|
||||||
}
|
}
|
||||||
if action == "remind" { // Password Reminder button pressed
|
if action == "remind" { // Password Reminder button pressed
|
||||||
user, uerr := database.AmGetUserByName(username, nil)
|
user, uerr := database.AmGetUserByName(ctxt.Ctx(), username, nil)
|
||||||
if uerr == nil {
|
if uerr == nil {
|
||||||
var ci *database.ContactInfo
|
var ci *database.ContactInfo
|
||||||
ci, uerr = user.ContactInfo()
|
ci, uerr = user.ContactInfo(ctxt.Ctx())
|
||||||
if uerr == nil {
|
if uerr == nil {
|
||||||
if ci != nil && ci.Email != nil && *ci.Email != "" {
|
if ci != nil && ci.Email != nil && *ci.Email != "" {
|
||||||
pchange := database.AmNewPasswordChangeRequest(user.Uid, user.Username, *ci.Email)
|
pchange := database.AmNewPasswordChangeRequest(user.Uid, user.Username, *ci.Email)
|
||||||
@@ -109,14 +109,14 @@ func Login(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
if action == "login" { // Login button pressed
|
if action == "login" { // Login button pressed
|
||||||
// authenticate the user
|
// authenticate the user
|
||||||
user, uerr := database.AmAuthenticateUser(username, dlg.Field("pass").Value, ctxt.RemoteIP())
|
user, uerr := database.AmAuthenticateUser(ctxt.Ctx(), username, dlg.Field("pass").Value, ctxt.RemoteIP())
|
||||||
if uerr != nil {
|
if uerr != nil {
|
||||||
return dlg.RenderError(ctxt, uerr.Error())
|
return dlg.RenderError(ctxt, uerr.Error())
|
||||||
}
|
}
|
||||||
ctxt.ReplaceUser(user)
|
ctxt.ReplaceUser(user)
|
||||||
if dlg.Field("saveme").IsChecked() {
|
if dlg.Field("saveme").IsChecked() {
|
||||||
// create and save an authentication token
|
// create and save an authentication token
|
||||||
authString, cerr := user.NewAuthToken()
|
authString, cerr := user.NewAuthToken(ctxt.Ctx())
|
||||||
if cerr == nil {
|
if cerr == nil {
|
||||||
ctxt.SetLoginCookie(authString)
|
ctxt.SetLoginCookie(authString)
|
||||||
|
|
||||||
@@ -240,9 +240,9 @@ func VerifyEMail(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
if action == "sendagain" {
|
if action == "sendagain" {
|
||||||
var ci *database.ContactInfo
|
var ci *database.ContactInfo
|
||||||
ci, err = user.ContactInfo()
|
ci, err = user.ContactInfo(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = user.NewEmailConfirmationNumber()
|
err = user.NewEmailConfirmationNumber(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = sendEmailConfirmationEmail(user, ci, ctxt.RemoteIP())
|
err = sendEmailConfirmationEmail(user, ci, ctxt.RemoteIP())
|
||||||
}
|
}
|
||||||
@@ -257,7 +257,7 @@ func VerifyEMail(ctxt ui.AmContext) (string, any, error) {
|
|||||||
err = dlg.Validate()
|
err = dlg.Validate()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cn, _ := dlg.Field("num").ValueInt()
|
cn, _ := dlg.Field("num").ValueInt()
|
||||||
err = user.ConfirmEMailAddress(int32(cn), ctxt.RemoteIP())
|
err = user.ConfirmEMailAddress(ctxt.Ctx(), int32(cn), ctxt.RemoteIP())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return "redirect", target, nil
|
return "redirect", target, nil
|
||||||
}
|
}
|
||||||
@@ -358,14 +358,14 @@ func NewAccount(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return dlg.RenderError(ctxt, "The typed passwords do not match.")
|
return dlg.RenderError(ctxt, "The typed passwords do not match.")
|
||||||
}
|
}
|
||||||
var banned bool
|
var banned bool
|
||||||
banned, err = database.AmIsEmailAddressBanned(dlg.Field("email").Value)
|
banned, err = database.AmIsEmailAddressBanned(ctxt.Ctx(), dlg.Field("email").Value)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if banned {
|
if banned {
|
||||||
return dlg.RenderError(ctxt, "This E-mail address may not register a new account.")
|
return dlg.RenderError(ctxt, "This E-mail address may not register a new account.")
|
||||||
}
|
}
|
||||||
// Create new user account
|
// Create new user account
|
||||||
var user *database.User
|
var user *database.User
|
||||||
user, err = database.AmCreateNewUser(dlg.Field("user").Value, dlg.Field("pass1").Value,
|
user, err = database.AmCreateNewUser(ctxt.Ctx(), dlg.Field("user").Value, dlg.Field("pass1").Value,
|
||||||
dlg.Field("remind").Value, dlg.Field("dob").AsDate(), ctxt.RemoteIP())
|
dlg.Field("remind").Value, dlg.Field("dob").AsDate(), ctxt.RemoteIP())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// create and save contact info
|
// create and save contact info
|
||||||
@@ -384,9 +384,9 @@ func NewAccount(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ci.PostalCode = dlg.Field("pcode").ValPtr()
|
ci.PostalCode = dlg.Field("pcode").ValPtr()
|
||||||
ci.Country = dlg.Field("country").ValPtr()
|
ci.Country = dlg.Field("country").ValPtr()
|
||||||
ci.Email = dlg.Field("email").ValPtr()
|
ci.Email = dlg.Field("email").ValPtr()
|
||||||
_, err = ci.Save()
|
_, err = ci.Save(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = user.SetContactID(ci.ContactId)
|
err = user.SetContactID(ctxt.Ctx(), ci.ContactId)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = sendEmailConfirmationEmail(user, ci, ctxt.RemoteIP())
|
err = sendEmailConfirmationEmail(user, ci, ctxt.RemoteIP())
|
||||||
@@ -435,10 +435,10 @@ func PasswordRecovery(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
user, err := database.AmGetUser(int32(uid))
|
user, err := database.AmGetUser(ctxt.Ctx(), int32(uid))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
newpass := util.GenerateRandomPassword()
|
newpass := util.GenerateRandomPassword()
|
||||||
err = user.ChangePassword(newpass, ctxt.RemoteIP())
|
err = user.ChangePassword(ctxt.Ctx(), newpass, ctxt.RemoteIP())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// send the password change message
|
// send the password change message
|
||||||
msg := email.AmNewEmailMessage(user.Uid, ctxt.RemoteIP())
|
msg := email.AmNewEmailMessage(user.Uid, ctxt.RemoteIP())
|
||||||
|
|||||||
@@ -124,9 +124,6 @@ func main() {
|
|||||||
closer = ui.SetupAmContext()
|
closer = ui.SetupAmContext()
|
||||||
defer closer()
|
defer closer()
|
||||||
|
|
||||||
// Set up Echo.
|
|
||||||
e := setupEcho()
|
|
||||||
|
|
||||||
// Set up to trap SIGINT and shut down gracefully
|
// Set up to trap SIGINT and shut down gracefully
|
||||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||||
defer stop()
|
defer stop()
|
||||||
@@ -138,6 +135,9 @@ func main() {
|
|||||||
ampool.Shutdown()
|
ampool.Shutdown()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// Set up Echo.
|
||||||
|
e := setupEcho()
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
go func() {
|
go func() {
|
||||||
if err := e.Start(":1323"); err != nil && err != http.ErrServerClosed {
|
if err := e.Start(":1323"); err != nil && err != http.ErrServerClosed {
|
||||||
|
|||||||
@@ -48,11 +48,11 @@ type RenderedSidebox struct {
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func buildCommunitiesSidebox(uid int32, out *RenderedSidebox, in *database.Sidebox) error {
|
func buildCommunitiesSidebox(ctxt ui.AmContext, uid int32, out *RenderedSidebox, in *database.Sidebox) error {
|
||||||
user, err := database.AmGetUser(uid)
|
user, err := database.AmGetUser(ctxt.Ctx(), uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var g *database.Globals
|
var g *database.Globals
|
||||||
g, err = database.AmGlobals()
|
g, err = database.AmGlobals(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if user.IsAnon {
|
if user.IsAnon {
|
||||||
out.Title = "Featured Communities"
|
out.Title = "Featured Communities"
|
||||||
@@ -60,7 +60,7 @@ func buildCommunitiesSidebox(uid int32, out *RenderedSidebox, in *database.Sideb
|
|||||||
out.Title = "Your Communities"
|
out.Title = "Your Communities"
|
||||||
}
|
}
|
||||||
var l []*database.Community
|
var l []*database.Community
|
||||||
l, err = database.AmGetCommunitiesForUser(uid)
|
l, err = database.AmGetCommunitiesForUser(ctxt.Ctx(), uid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
out.Items = make([]RenderedSideboxItem, len(l))
|
out.Items = make([]RenderedSideboxItem, len(l))
|
||||||
for i, c := range l {
|
for i, c := range l {
|
||||||
@@ -69,7 +69,7 @@ func buildCommunitiesSidebox(uid int32, out *RenderedSidebox, in *database.Sideb
|
|||||||
out.Items[i].Link = &lk
|
out.Items[i].Link = &lk
|
||||||
out.Items[i].Flags = make(map[string]bool)
|
out.Items[i].Flags = make(map[string]bool)
|
||||||
var level uint16
|
var level uint16
|
||||||
level, err = database.AmGetCommunityAccessLevel(uid, c.Id)
|
level, err = database.AmGetCommunityAccessLevel(ctxt.Ctx(), uid, c.Id)
|
||||||
if err == nil && database.AmTestPermission("Community.ShowAdmin", level) {
|
if err == nil && database.AmTestPermission("Community.ShowAdmin", level) {
|
||||||
out.Items[i].Flags["admin"] = true
|
out.Items[i].Flags["admin"] = true
|
||||||
}
|
}
|
||||||
@@ -150,10 +150,10 @@ func buildUsersOnline(uid int32, out *RenderedSidebox, in *database.Sidebox) err
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func buildRenderedSidebox(uid int32, out *RenderedSidebox, in *database.Sidebox) error {
|
func buildRenderedSidebox(ctxt ui.AmContext, uid int32, out *RenderedSidebox, in *database.Sidebox) error {
|
||||||
switch in.Boxid {
|
switch in.Boxid {
|
||||||
case 1:
|
case 1:
|
||||||
return buildCommunitiesSidebox(uid, out, in)
|
return buildCommunitiesSidebox(ctxt, uid, out, in)
|
||||||
case 2:
|
case 2:
|
||||||
return buildFeaturedConferences(uid, out, in)
|
return buildFeaturedConferences(uid, out, in)
|
||||||
case 3:
|
case 3:
|
||||||
@@ -177,14 +177,14 @@ func TopPage(ctxt ui.AmContext) (string, any, error) {
|
|||||||
|
|
||||||
// Retrieve the sideboxes and create the data to be presented.
|
// Retrieve the sideboxes and create the data to be presented.
|
||||||
uid := ctxt.CurrentUserId()
|
uid := ctxt.CurrentUserId()
|
||||||
sboxes, err := database.AmGetSideboxes(uid)
|
sboxes, err := database.AmGetSideboxes(ctxt.Ctx(), uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "string", "Unable to retrieve sideboxes", err
|
return "string", "Unable to retrieve sideboxes", err
|
||||||
}
|
}
|
||||||
|
|
||||||
rc := make([]RenderedSidebox, len(sboxes))
|
rc := make([]RenderedSidebox, len(sboxes))
|
||||||
for i, sb := range sboxes {
|
for i, sb := range sboxes {
|
||||||
err = buildRenderedSidebox(uid, &(rc[i]), sb)
|
err = buildRenderedSidebox(ctxt, uid, &(rc[i]), sb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "string", "Unable to render sideboxes", err
|
return "string", "Unable to render sideboxes", err
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -120,7 +120,7 @@ func (c *amContext) ClearLoginCookie() {
|
|||||||
|
|
||||||
// ClearSession clears the current session.
|
// ClearSession clears the current session.
|
||||||
func (c *amContext) ClearSession() {
|
func (c *amContext) ClearSession() {
|
||||||
AmResetSession(c.session)
|
AmResetSession(c.echoContext.Request().Context(), c.session)
|
||||||
c.user = nil
|
c.user = nil
|
||||||
c.effectiveLevel = 0
|
c.effectiveLevel = 0
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ func (c *amContext) CurrentCommunity() *database.Community {
|
|||||||
// CurrentUser returns the current user from the session.
|
// CurrentUser returns the current user from the session.
|
||||||
func (c *amContext) CurrentUser() *database.User {
|
func (c *amContext) CurrentUser() *database.User {
|
||||||
if c.user == nil {
|
if c.user == nil {
|
||||||
u, err := database.AmGetUser(AmSessionUid(c.session))
|
u, err := database.AmGetUser(c.echoContext.Request().Context(), AmSessionUid(c.session))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("unable to retrieve current user")
|
log.Errorf("unable to retrieve current user")
|
||||||
}
|
}
|
||||||
@@ -327,12 +327,12 @@ func (c *amContext) SubRender(name string) ([]byte, error) {
|
|||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func (c *amContext) SetCommunityContext(param string) error {
|
func (c *amContext) SetCommunityContext(param string) error {
|
||||||
comm, err := database.AmGetCommunityFromParam(param)
|
comm, err := database.AmGetCommunityFromParam(c.echoContext.Request().Context(), param)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if c.community == nil || c.community.Id != comm.Id {
|
if c.community == nil || c.community.Id != comm.Id {
|
||||||
mbr, lock, level, err := comm.Membership(c.CurrentUser())
|
mbr, lock, level, err := comm.Membership(c.echoContext.Request().Context(), c.CurrentUser())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -459,11 +459,11 @@ func newContext(ctxt echo.Context) (*amContext, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if rc.globals, err = database.AmGlobals(); err != nil {
|
if rc.globals, err = database.AmGlobals(ctxt.Request().Context()); err != nil {
|
||||||
amContextRecycleBin <- rc
|
amContextRecycleBin <- rc
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if rc.globalFlags, err = rc.globals.Flags(); err != nil {
|
if rc.globalFlags, err = rc.globals.Flags(ctxt.Request().Context()); err != nil {
|
||||||
amContextRecycleBin <- rc
|
amContextRecycleBin <- rc
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -475,12 +475,12 @@ func newContext(ctxt echo.Context) (*amContext, error) {
|
|||||||
rc.session = sess
|
rc.session = sess
|
||||||
sess.Options = defoptions
|
sess.Options = defoptions
|
||||||
if sess.IsNew {
|
if sess.IsNew {
|
||||||
AmSessionFirstTime(sess)
|
AmSessionFirstTime(ctxt.Request().Context(), sess)
|
||||||
} else {
|
} else {
|
||||||
AmHitSession(sess)
|
AmHitSession(sess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc.user, err = database.AmGetUser(AmSessionUid(sess))
|
rc.user, err = database.AmGetUser(ctxt.Request().Context(), AmSessionUid(sess))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rc.effectiveLevel = rc.user.BaseLevel
|
rc.effectiveLevel = rc.user.BaseLevel
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -78,7 +78,7 @@ func AmServeImage(ctxt AmContext) (string, any, error) {
|
|||||||
id, err = strconv.Atoi(components[3])
|
id, err = strconv.Atoi(components[3])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var img *database.ImageStore
|
var img *database.ImageStore
|
||||||
img, err = database.AmLoadImage(int32(id))
|
img, err = database.AmLoadImage(ctxt.Ctx(), int32(id))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ctxt.SetOutputType(img.MimeType)
|
ctxt.SetOutputType(img.MimeType)
|
||||||
return "bytes", img.Data, nil
|
return "bytes", img.Data, nil
|
||||||
|
|||||||
+4
-2
@@ -10,6 +10,7 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
@@ -141,19 +142,20 @@ func AmMenu(name string) *MenuDefinition {
|
|||||||
|
|
||||||
/* AmBuildCommunityMenu buids a community menu for the specified community.
|
/* AmBuildCommunityMenu buids a community menu for the specified community.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
|
* ctx - Standard Go context value.
|
||||||
* comm - The community to build the menu for.
|
* comm - The community to build the menu for.
|
||||||
* Returns:
|
* Returns:
|
||||||
* The new menu definition.
|
* The new menu definition.
|
||||||
* Standard Go error status.
|
* Standard Go error status.
|
||||||
*/
|
*/
|
||||||
func AmBuildCommunityMenu(comm *database.Community) (*MenuDefinition, error) {
|
func AmBuildCommunityMenu(ctx context.Context, comm *database.Community) (*MenuDefinition, error) {
|
||||||
menuCacheMutex.Lock()
|
menuCacheMutex.Lock()
|
||||||
defer menuCacheMutex.Unlock()
|
defer menuCacheMutex.Unlock()
|
||||||
m, ok := menuCache.Get(comm.Id)
|
m, ok := menuCache.Get(comm.Id)
|
||||||
if ok {
|
if ok {
|
||||||
return m.(*MenuDefinition), nil
|
return m.(*MenuDefinition), nil
|
||||||
}
|
}
|
||||||
sdef, err := database.AmGetCommunityServices(comm.Id)
|
sdef, err := database.AmGetCommunityServices(ctx, comm.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -31,7 +31,7 @@ func middlewareErrorPage(c echo.Context, ctxt AmContext, err error) error {
|
|||||||
func IPBanTest(next echo.HandlerFunc) echo.HandlerFunc {
|
func IPBanTest(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
// Check IP banning.
|
// Check IP banning.
|
||||||
banmsg, banerr := database.AmTestIPBan(c.RealIP())
|
banmsg, banerr := database.AmTestIPBan(c.Request().Context(), c.RealIP())
|
||||||
if banerr != nil {
|
if banerr != nil {
|
||||||
c.Logger().Warnf("address %s could not be tested: %v", c.RealIP(), banerr)
|
c.Logger().Warnf("address %s could not be tested: %v", c.RealIP(), banerr)
|
||||||
// but let the request pass anyway
|
// but let the request pass anyway
|
||||||
@@ -55,12 +55,12 @@ func CookieLoginTest(next echo.HandlerFunc) echo.HandlerFunc {
|
|||||||
cookie, err := c.Cookie(config.GlobalConfig.Site.LoginCookieName)
|
cookie, err := c.Cookie(config.GlobalConfig.Site.LoginCookieName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var user *database.User
|
var user *database.User
|
||||||
user, err = database.AmAuthenticateUserByToken(cookie.Value, c.RealIP())
|
user, err = database.AmAuthenticateUserByToken(c.Request().Context(), cookie.Value, c.RealIP())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// log the user in and rotate login cookie
|
// log the user in and rotate login cookie
|
||||||
amctxt.ReplaceUser(user)
|
amctxt.ReplaceUser(user)
|
||||||
var newToken string
|
var newToken string
|
||||||
if newToken, err = user.NewAuthToken(); err == nil {
|
if newToken, err = user.NewAuthToken(c.Request().Context()); err == nil {
|
||||||
amctxt.SetLoginCookie(newToken)
|
amctxt.SetLoginCookie(newToken)
|
||||||
} else {
|
} else {
|
||||||
log.Warnf("unable to rotate login cookie: %v", err)
|
log.Warnf("unable to rotate login cookie: %v", err)
|
||||||
@@ -99,7 +99,7 @@ func ValidateConference(next echo.HandlerFunc) echo.HandlerFunc {
|
|||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
ctxt := AmContextFromEchoContext(c)
|
ctxt := AmContextFromEchoContext(c)
|
||||||
comm := ctxt.CurrentCommunity() // set by middleware
|
comm := ctxt.CurrentCommunity() // set by middleware
|
||||||
b, err := database.AmTestService(comm, "Conference")
|
b, err := database.AmTestService(c.Request().Context(), comm, "Conference")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return middlewareErrorPage(c, ctxt, err)
|
return middlewareErrorPage(c, ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -122,11 +122,11 @@ func ValidateConference(next echo.HandlerFunc) echo.HandlerFunc {
|
|||||||
func SetConference(next echo.HandlerFunc) echo.HandlerFunc {
|
func SetConference(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
ctxt := AmContextFromEchoContext(c)
|
ctxt := AmContextFromEchoContext(c)
|
||||||
conf, err := database.AmGetConferenceByAliasInCommunity(ctxt.CurrentCommunity().Id, ctxt.URLParam("confid"))
|
conf, err := database.AmGetConferenceByAliasInCommunity(ctxt.Ctx(), ctxt.CurrentCommunity().Id, ctxt.URLParam("confid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return middlewareErrorPage(c, ctxt, err)
|
return middlewareErrorPage(c, ctxt, err)
|
||||||
}
|
}
|
||||||
m, lvl, err := conf.Membership(ctxt.CurrentUser())
|
m, lvl, err := conf.Membership(ctxt.Ctx(), ctxt.CurrentUser())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return middlewareErrorPage(c, ctxt, err)
|
return middlewareErrorPage(c, ctxt, err)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ func AmSendPageData(ctxt echo.Context, amctxt AmContext, command string, data an
|
|||||||
case "top":
|
case "top":
|
||||||
menus[0] = AmMenu("top")
|
menus[0] = AmMenu("top")
|
||||||
case "community":
|
case "community":
|
||||||
md, err := AmBuildCommunityMenu(amctxt.CurrentCommunity())
|
md, err := AmBuildCommunityMenu(ctxt.Request().Context(), amctxt.CurrentCommunity())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-6
@@ -11,6 +11,7 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@@ -220,8 +221,8 @@ func AmSetSessionUser(session *sessions.Session, user *database.User) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setSessionAnon sets the user for the session to the anonymous user.
|
// setSessionAnon sets the user for the session to the anonymous user.
|
||||||
func setSessionAnon(session *sessions.Session) {
|
func setSessionAnon(ctx context.Context, session *sessions.Session) {
|
||||||
u, err := database.AmGetAnonUser()
|
u, err := database.AmGetAnonUser(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
AmSetSessionUser(session, u)
|
AmSetSessionUser(session, u)
|
||||||
} else {
|
} else {
|
||||||
@@ -232,20 +233,20 @@ func setSessionAnon(session *sessions.Session) {
|
|||||||
var lastHitMutex sync.Mutex
|
var lastHitMutex sync.Mutex
|
||||||
|
|
||||||
// AmSessionFirstTime initializes the session after it's first created.
|
// AmSessionFirstTime initializes the session after it's first created.
|
||||||
func AmSessionFirstTime(session *sessions.Session) {
|
func AmSessionFirstTime(ctx context.Context, session *sessions.Session) {
|
||||||
lastHitMutex.Lock()
|
lastHitMutex.Lock()
|
||||||
setSessionAnon(session)
|
setSessionAnon(ctx, session)
|
||||||
session.Values["lasthit"] = time.Now()
|
session.Values["lasthit"] = time.Now()
|
||||||
lastHitMutex.Unlock()
|
lastHitMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// AmResetSession clears the specified session.
|
// AmResetSession clears the specified session.
|
||||||
func AmResetSession(session *sessions.Session) {
|
func AmResetSession(ctx context.Context, session *sessions.Session) {
|
||||||
lastHitMutex.Lock()
|
lastHitMutex.Lock()
|
||||||
for k := range session.Values {
|
for k := range session.Values {
|
||||||
delete(session.Values, k)
|
delete(session.Values, k)
|
||||||
}
|
}
|
||||||
setSessionAnon(session)
|
setSessionAnon(ctx, session)
|
||||||
session.Values["lasthit"] = time.Now()
|
session.Values["lasthit"] = time.Now()
|
||||||
lastHitMutex.Unlock()
|
lastHitMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -112,7 +112,8 @@ func immediateIf(a jet.Arguments) reflect.Value {
|
|||||||
func extractCommunityLogo(a jet.Arguments) reflect.Value {
|
func extractCommunityLogo(a jet.Arguments) reflect.Value {
|
||||||
rc := "/img/builtin/default-community.jpg"
|
rc := "/img/builtin/default-community.jpg"
|
||||||
comm := a.Get(0).Convert(reflect.TypeFor[*database.Community]()).Interface().(*database.Community)
|
comm := a.Get(0).Convert(reflect.TypeFor[*database.Community]()).Interface().(*database.Community)
|
||||||
ci, err := comm.ContactInfo()
|
ctxt := a.Get(1).Convert(reflect.TypeFor[AmContext]()).Interface().(AmContext)
|
||||||
|
ci, err := comm.ContactInfo(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if ci.PhotoURL != nil && *ci.PhotoURL != "" {
|
if ci.PhotoURL != nil && *ci.PhotoURL != "" {
|
||||||
rc = *ci.PhotoURL
|
rc = *ci.PhotoURL
|
||||||
@@ -125,7 +126,7 @@ func extractCommunityLogo(a jet.Arguments) reflect.Value {
|
|||||||
func displayDateTime(a jet.Arguments) reflect.Value {
|
func displayDateTime(a jet.Arguments) reflect.Value {
|
||||||
timeval := a.Get(0).Convert(reflect.TypeFor[time.Time]()).Interface().(time.Time)
|
timeval := a.Get(0).Convert(reflect.TypeFor[time.Time]()).Interface().(time.Time)
|
||||||
ctxt := a.Get(1).Convert(reflect.TypeFor[AmContext]()).Interface().(AmContext)
|
ctxt := a.Get(1).Convert(reflect.TypeFor[AmContext]()).Interface().(AmContext)
|
||||||
prefs, err := ctxt.CurrentUser().Prefs()
|
prefs, err := ctxt.CurrentUser().Prefs(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
loc := prefs.Localizer()
|
loc := prefs.Localizer()
|
||||||
return reflect.ValueOf(loc.Strftime("%b %e, %Y %r", timeval))
|
return reflect.ValueOf(loc.Strftime("%b %e, %Y %r", timeval))
|
||||||
@@ -137,7 +138,7 @@ func displayDateTime(a jet.Arguments) reflect.Value {
|
|||||||
func displayActivity(a jet.Arguments) reflect.Value {
|
func displayActivity(a jet.Arguments) reflect.Value {
|
||||||
timeval := a.Get(0).Convert(reflect.TypeFor[*time.Time]()).Interface().(*time.Time)
|
timeval := a.Get(0).Convert(reflect.TypeFor[*time.Time]()).Interface().(*time.Time)
|
||||||
ctxt := a.Get(1).Convert(reflect.TypeFor[AmContext]()).Interface().(AmContext)
|
ctxt := a.Get(1).Convert(reflect.TypeFor[AmContext]()).Interface().(AmContext)
|
||||||
prefs, err := ctxt.CurrentUser().Prefs()
|
prefs, err := ctxt.CurrentUser().Prefs(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return reflect.ValueOf(util.AmActivityString(timeval, prefs.Localizer()))
|
return reflect.ValueOf(util.AmActivityString(timeval, prefs.Localizer()))
|
||||||
}
|
}
|
||||||
@@ -150,14 +151,14 @@ func displayMemberCount(a jet.Arguments) reflect.Value {
|
|||||||
comm := a.Get(0).Convert(reflect.TypeFor[*database.Community]()).Interface().(*database.Community)
|
comm := a.Get(0).Convert(reflect.TypeFor[*database.Community]()).Interface().(*database.Community)
|
||||||
ctxt := a.Get(1).Convert(reflect.TypeFor[AmContext]()).Interface().(AmContext)
|
ctxt := a.Get(1).Convert(reflect.TypeFor[AmContext]()).Interface().(AmContext)
|
||||||
level := ctxt.CurrentUser().BaseLevel
|
level := ctxt.CurrentUser().BaseLevel
|
||||||
mbr, _, clevel, err := comm.Membership(ctxt.CurrentUser())
|
mbr, _, clevel, err := comm.Membership(ctxt.Ctx(), ctxt.CurrentUser())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if mbr && clevel > level {
|
if mbr && clevel > level {
|
||||||
level = clevel
|
level = clevel
|
||||||
}
|
}
|
||||||
showHidden = comm.TestPermission("Community.ShowHiddenMembers", level)
|
showHidden = comm.TestPermission("Community.ShowHiddenMembers", level)
|
||||||
}
|
}
|
||||||
count, err := comm.MemberCount(showHidden)
|
count, err := comm.MemberCount(ctxt.Ctx(), showHidden)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return reflect.ValueOf(-1)
|
return reflect.ValueOf(-1)
|
||||||
}
|
}
|
||||||
@@ -194,7 +195,8 @@ func displayFullName(a jet.Arguments) reflect.Value {
|
|||||||
// displayExpandCat displays a category expanded into a hierarchy.
|
// displayExpandCat displays a category expanded into a hierarchy.
|
||||||
func displayExpandCat(a jet.Arguments) reflect.Value {
|
func displayExpandCat(a jet.Arguments) reflect.Value {
|
||||||
cat := a.Get(0).Convert(reflect.TypeFor[*database.Category]()).Interface().(*database.Category)
|
cat := a.Get(0).Convert(reflect.TypeFor[*database.Category]()).Interface().(*database.Category)
|
||||||
hier, _ := database.AmGetCategoryHierarchy(cat.CatId)
|
ctxt := a.Get(1).Convert(reflect.TypeFor[AmContext]()).Interface().(AmContext)
|
||||||
|
hier, _ := database.AmGetCategoryHierarchy(ctxt.Ctx(), cat.CatId)
|
||||||
var rc strings.Builder
|
var rc strings.Builder
|
||||||
for i, c := range hier {
|
for i, c := range hier {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
|
|||||||
+1
-1
@@ -257,7 +257,7 @@
|
|||||||
<span class="text-sm pt-0.5 flex-shrink-0">🟣</span>
|
<span class="text-sm pt-0.5 flex-shrink-0">🟣</span>
|
||||||
<div class="flex-1 mb-2">
|
<div class="flex-1 mb-2">
|
||||||
<a href="/find?mode=COM&catid={{ rx.CatId }}"
|
<a href="/find?mode=COM&catid={{ rx.CatId }}"
|
||||||
class="text-blue-700 hover:text-blue-900 font-bold text-base">{{ DisplayExpandCat(rx) }}</a>
|
class="text-blue-700 hover:text-blue-900 font-bold text-base">{{ DisplayExpandCat(rx, .) }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ else if mode == "PST" }}
|
{{ else if mode == "PST" }}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
{{ comm := .CurrentCommunity() }}
|
{{ comm := .CurrentCommunity() }}
|
||||||
<div class="mb-2 mt-2">
|
<div class="mb-2 mt-2">
|
||||||
<div class="mb-1">
|
<div class="mb-1">
|
||||||
<img src="{{ ExtractCommunityLogo(comm) }}" alt="{{ comm.Name }}" class="w-28 h-16 rounded">
|
<img src="{{ ExtractCommunityLogo(comm, .) }}" alt="{{ comm.Name }}" class="w-28 h-16 rounded">
|
||||||
</div>
|
</div>
|
||||||
<div class="font-bold mb-1">{{ menu.Title }}</div>
|
<div class="font-bold mb-1">{{ menu.Title }}</div>
|
||||||
{{ ctxt := . }}
|
{{ ctxt := . }}
|
||||||
|
|||||||
+2
-2
@@ -79,8 +79,8 @@
|
|||||||
{{ post_overrideLine := "" }}
|
{{ post_overrideLine := "" }}
|
||||||
{{ post_overrideLink := "" }}
|
{{ post_overrideLink := "" }}
|
||||||
{{ range i, post_cur := posts }}
|
{{ range i, post_cur := posts }}
|
||||||
{{ post_userName = post_getUserName(post_cur) }}
|
{{ post_userName = post_getUserName(post_cur, .) }}
|
||||||
{{ post_text = post_getText(post_cur) }}
|
{{ post_text = post_getText(post_cur, .) }}
|
||||||
{{ post_overrideLine = post_getOverrideLine(post_cur, .) }}
|
{{ post_overrideLine = post_getOverrideLine(post_cur, .) }}
|
||||||
{{ post_overrideLink = post_getOverrideLink(post_cur, post_topicPermalink) }}
|
{{ post_overrideLink = post_getOverrideLink(post_cur, post_topicPermalink) }}
|
||||||
{{ .SubRender("singlepost.jet") | raw }}
|
{{ .SubRender("singlepost.jet") | raw }}
|
||||||
|
|||||||
+24
-24
@@ -57,10 +57,10 @@ func EditProfileForm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
dlg.Field("tgt").Value = target
|
dlg.Field("tgt").Value = target
|
||||||
ctxt.VarMap().Set("target", target)
|
ctxt.VarMap().Set("target", target)
|
||||||
var ci *database.ContactInfo
|
var ci *database.ContactInfo
|
||||||
ci, err = u.ContactInfo()
|
ci, err = u.ContactInfo(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var prefs *database.UserPrefs
|
var prefs *database.UserPrefs
|
||||||
prefs, err = u.Prefs()
|
prefs, err = u.Prefs(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
dlg.Field("remind").Value = u.PassReminder
|
dlg.Field("remind").Value = u.PassReminder
|
||||||
dlg.Field("prefix").SetVal(ci.Prefix)
|
dlg.Field("prefix").SetVal(ci.Prefix)
|
||||||
@@ -87,8 +87,8 @@ func EditProfileForm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
dlg.Field("dob").SetDate(u.DOB)
|
dlg.Field("dob").SetDate(u.DOB)
|
||||||
dlg.Field("descr").SetVal(u.Description)
|
dlg.Field("descr").SetVal(u.Description)
|
||||||
dlg.Field("photo").Value = userPhotoURL(ci)
|
dlg.Field("photo").Value = userPhotoURL(ci)
|
||||||
dlg.Field("pic_in_post").SetChecked(u.FlagValue(database.UserFlagPicturesInPosts))
|
dlg.Field("pic_in_post").SetChecked(u.FlagValue(ctxt.Ctx(), database.UserFlagPicturesInPosts))
|
||||||
dlg.Field("no_mass_mail").SetChecked(u.FlagValue(database.UserFlagMassMailOptOut))
|
dlg.Field("no_mass_mail").SetChecked(u.FlagValue(ctxt.Ctx(), database.UserFlagMassMailOptOut))
|
||||||
dlg.Field("locale").Value = prefs.ReadLocale()
|
dlg.Field("locale").Value = prefs.ReadLocale()
|
||||||
dlg.Field("tz").Value = prefs.TimeZoneID
|
dlg.Field("tz").Value = prefs.TimeZoneID
|
||||||
return dlg.Render(ctxt)
|
return dlg.Render(ctxt)
|
||||||
@@ -130,15 +130,15 @@ func EditProfile(ctxt ui.AmContext) (string, any, error) {
|
|||||||
return dlg.RenderError(ctxt, err.Error())
|
return dlg.RenderError(ctxt, err.Error())
|
||||||
}
|
}
|
||||||
var ci *database.ContactInfo
|
var ci *database.ContactInfo
|
||||||
ci, err = u.ContactInfo()
|
ci, err = u.ContactInfo(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var prefs *database.UserPrefs
|
var prefs *database.UserPrefs
|
||||||
emailChange := false
|
emailChange := false
|
||||||
prefs, err = u.Prefs()
|
prefs, err = u.Prefs(ctxt.Ctx())
|
||||||
if err == nil && !(dlg.Field("pass1").IsEmpty() && dlg.Field("pass2").IsEmpty()) {
|
if err == nil && !(dlg.Field("pass1").IsEmpty() && dlg.Field("pass2").IsEmpty()) {
|
||||||
p1 := dlg.Field("pass1").Value
|
p1 := dlg.Field("pass1").Value
|
||||||
if p1 == dlg.Field("pass2").Value {
|
if p1 == dlg.Field("pass2").Value {
|
||||||
err = u.ChangePassword(p1, ctxt.RemoteIP())
|
err = u.ChangePassword(ctxt.Ctx(), p1, ctxt.RemoteIP())
|
||||||
} else {
|
} else {
|
||||||
err = errors.New("passwords do not match")
|
err = errors.New("passwords do not match")
|
||||||
}
|
}
|
||||||
@@ -166,27 +166,27 @@ func EditProfile(ctxt ui.AmContext) (string, any, error) {
|
|||||||
nci.Email = dlg.Field("email").ValPtr()
|
nci.Email = dlg.Field("email").ValPtr()
|
||||||
nci.PrivateEmail = dlg.Field("pvt_email").IsChecked()
|
nci.PrivateEmail = dlg.Field("pvt_email").IsChecked()
|
||||||
nci.URL = dlg.Field("url").ValPtr()
|
nci.URL = dlg.Field("url").ValPtr()
|
||||||
emailChange, err = nci.Save()
|
emailChange, err = nci.Save(ctxt.Ctx())
|
||||||
ci = nci
|
ci = nci
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
nprefs := prefs.Clone()
|
nprefs := prefs.Clone()
|
||||||
nprefs.WriteLocale(dlg.Field("locale").Value)
|
nprefs.WriteLocale(dlg.Field("locale").Value)
|
||||||
nprefs.TimeZoneID = dlg.Field("tz").Value
|
nprefs.TimeZoneID = dlg.Field("tz").Value
|
||||||
err = nprefs.Save(u)
|
err = nprefs.Save(ctxt.Ctx(), u)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var f *util.OptionSet
|
var f *util.OptionSet
|
||||||
f, err = u.Flags()
|
f, err = u.Flags(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
nf := f.Clone()
|
nf := f.Clone()
|
||||||
nf.Set(database.UserFlagPicturesInPosts, dlg.Field("pic_in_post").IsChecked())
|
nf.Set(database.UserFlagPicturesInPosts, dlg.Field("pic_in_post").IsChecked())
|
||||||
nf.Set(database.UserFlagMassMailOptOut, dlg.Field("no_mass_mail").IsChecked())
|
nf.Set(database.UserFlagMassMailOptOut, dlg.Field("no_mass_mail").IsChecked())
|
||||||
err = u.SaveFlags(nf)
|
err = u.SaveFlags(ctxt.Ctx(), nf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = u.SetProfileData(dlg.Field("remind").Value, dlg.Field("dob").AsDate(), dlg.Field("descr").ValPtr())
|
err = u.SetProfileData(ctxt.Ctx(), dlg.Field("remind").Value, dlg.Field("dob").AsDate(), dlg.Field("descr").ValPtr())
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if emailChange {
|
if emailChange {
|
||||||
@@ -223,7 +223,7 @@ func ProfilePhotoForm(ctxt ui.AmContext) (string, any, error) {
|
|||||||
if u.IsAnon {
|
if u.IsAnon {
|
||||||
return ui.ErrorPage(ctxt, errors.New("you are not logged in"))
|
return ui.ErrorPage(ctxt, errors.New("you are not logged in"))
|
||||||
}
|
}
|
||||||
ci, err := u.ContactInfo()
|
ci, err := u.ContactInfo(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ctxt.VarMap().Set("target", target)
|
ctxt.VarMap().Set("target", target)
|
||||||
ctxt.VarMap().Set("photo_url", userPhotoURL(ci))
|
ctxt.VarMap().Set("photo_url", userPhotoURL(ci))
|
||||||
@@ -247,7 +247,7 @@ func ProfilePhoto(ctxt ui.AmContext) (string, any, error) {
|
|||||||
if u.IsAnon {
|
if u.IsAnon {
|
||||||
return ui.ErrorPage(ctxt, errors.New("you are not logged in"))
|
return ui.ErrorPage(ctxt, errors.New("you are not logged in"))
|
||||||
}
|
}
|
||||||
ci, err := u.ContactInfo()
|
ci, err := u.ContactInfo(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -267,11 +267,11 @@ func ProfilePhoto(ctxt ui.AmContext) (string, any, error) {
|
|||||||
ui.UserPhotoMaxBytes)
|
ui.UserPhotoMaxBytes)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var img *database.ImageStore
|
var img *database.ImageStore
|
||||||
img, err = database.AmStoreImage(database.ImageTypeUserPhoto, u.Uid, mimeType, imageData)
|
img, err = database.AmStoreImage(ctxt.Ctx(), database.ImageTypeUserPhoto, u.Uid, mimeType, imageData)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
photourl := fmt.Sprintf("/img/store/%d", img.ImgId)
|
photourl := fmt.Sprintf("/img/store/%d", img.ImgId)
|
||||||
ci.PhotoURL = &photourl
|
ci.PhotoURL = &photourl
|
||||||
_, err = ci.Save()
|
_, err = ci.Save(ctxt.Ctx())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return "redirect", "/profile?tgt=" + url.QueryEscape(target), nil
|
return "redirect", "/profile?tgt=" + url.QueryEscape(target), nil
|
||||||
}
|
}
|
||||||
@@ -300,7 +300,7 @@ func ProfilePhoto(ctxt ui.AmContext) (string, any, error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
if happy {
|
if happy {
|
||||||
ampool.Submit(func(context.Context) {
|
ampool.Submit(func(context.Context) {
|
||||||
err := database.AmDeleteImage(int32(id))
|
err := database.AmDeleteImage(ctxt.Ctx(), int32(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("unable to delete image ID %d: %v", id, err)
|
log.Errorf("unable to delete image ID %d: %v", id, err)
|
||||||
}
|
}
|
||||||
@@ -309,7 +309,7 @@ func ProfilePhoto(ctxt ui.AmContext) (string, any, error) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
ci.PhotoURL = nil
|
ci.PhotoURL = nil
|
||||||
_, err := ci.Save()
|
_, err := ci.Save(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -329,18 +329,18 @@ func ProfilePhoto(ctxt ui.AmContext) (string, any, error) {
|
|||||||
*/
|
*/
|
||||||
func ShowProfile(ctxt ui.AmContext) (string, any, error) {
|
func ShowProfile(ctxt ui.AmContext) (string, any, error) {
|
||||||
me := ctxt.CurrentUser()
|
me := ctxt.CurrentUser()
|
||||||
prefs, err := me.Prefs()
|
prefs, err := me.Prefs(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather the info on the current user.
|
// Gather the info on the current user.
|
||||||
user, err := database.AmGetUserByName(ctxt.URLParam("uname"), nil)
|
user, err := database.AmGetUserByName(ctxt.Ctx(), ctxt.URLParam("uname"), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctxt.SetRC(http.StatusNotFound)
|
ctxt.SetRC(http.StatusNotFound)
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
ci, err := user.ContactInfo()
|
ci, err := user.ContactInfo(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -449,7 +449,7 @@ func QuickEMail(ctxt ui.AmContext) (string, any, error) {
|
|||||||
if me.IsAnon {
|
if me.IsAnon {
|
||||||
return ui.ErrorPage(ctxt, errors.New("you are not logged in"))
|
return ui.ErrorPage(ctxt, errors.New("you are not logged in"))
|
||||||
}
|
}
|
||||||
myCI, err := me.ContactInfo()
|
myCI, err := me.ContactInfo(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
@@ -457,14 +457,14 @@ func QuickEMail(ctxt ui.AmContext) (string, any, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
user, err := database.AmGetUser(int32(toUid))
|
user, err := database.AmGetUser(ctxt.Ctx(), int32(toUid))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
if user.IsAnon {
|
if user.IsAnon {
|
||||||
return ui.ErrorPage(ctxt, errors.New("cannot send quick E-mail to anonymous user"))
|
return ui.ErrorPage(ctxt, errors.New("cannot send quick E-mail to anonymous user"))
|
||||||
}
|
}
|
||||||
ci, err := user.ContactInfo()
|
ci, err := user.ContactInfo(ctxt.Ctx())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ui.ErrorPage(ctxt, err)
|
return ui.ErrorPage(ctxt, err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user