diff --git a/cmd/query_gen/tables.go b/cmd/query_gen/tables.go index c2eb48c1..5189dfd4 100644 --- a/cmd/query_gen/tables.go +++ b/cmd/query_gen/tables.go @@ -9,8 +9,14 @@ type tblColumn = qgen.DBTableColumn type tC = tblColumn type tblKey = qgen.DBTableKey -func createTables(adapter qgen.Adapter) error { - qgen.Install.CreateTable("users", mysqlPre, mysqlCol, +func createTables(adapter qgen.Adapter) (err error) { + createTable := func(table string, charset string, collation string, columns []qgen.DBTableColumn, keys []qgen.DBTableKey) { + if err != nil { + return + } + err = qgen.Install.CreateTable(table, charset, collation, columns, keys) + } + createTable("users", mysqlPre, mysqlCol, []tC{ tC{"uid", "int", 0, false, true, ""}, tC{"name", "varchar", 100, false, false, ""}, @@ -51,7 +57,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("users_groups", mysqlPre, mysqlCol, + createTable("users_groups", mysqlPre, mysqlCol, []tC{ tC{"gid", "int", 0, false, true, ""}, tC{"name", "varchar", 100, false, false, ""}, @@ -69,7 +75,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("users_groups_promotions", mysqlPre, mysqlCol, + createTable("users_groups_promotions", mysqlPre, mysqlCol, []tC{ tC{"pid", "int", 0, false, true, ""}, tC{"from_gid", "int", 0, false, false, ""}, @@ -78,6 +84,7 @@ func createTables(adapter qgen.Adapter) error { // Requirements tC{"level", "int", 0, false, false, ""}, + tC{"posts", "int", 0, false, false, "0"}, tC{"minTime", "int", 0, false, false, ""}, // How long someone needs to have been in their current group before being promoted }, []tblKey{ @@ -85,7 +92,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("users_2fa_keys", mysqlPre, mysqlCol, + createTable("users_2fa_keys", mysqlPre, mysqlCol, []tC{ tC{"uid", "int", 0, false, false, ""}, tC{"secret", "varchar", 100, false, false, ""}, @@ -110,7 +117,7 @@ func createTables(adapter qgen.Adapter) error { // TODO: Add a mod-queue and other basic auto-mod features. This is needed for awaiting activation and the mod_queue penalty flag // TODO: Add a penalty type where a user is stopped from creating plugin_guilds social groups // TODO: Shadow bans. We will probably have a CanShadowBan permission for this, as we *really* don't want people using this lightly. - /*qgen.Install.CreateTable("users_penalties","","", + /*createTable("users_penalties","","", []tC{ tC{"uid","int",0,false,false,""}, tC{"element_id","int",0,false,false,""}, @@ -134,7 +141,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, )*/ - qgen.Install.CreateTable("users_groups_scheduler", "", "", + createTable("users_groups_scheduler", "", "", []tC{ tC{"uid", "int", 0, false, false, ""}, tC{"set_group", "int", 0, false, false, ""}, @@ -150,7 +157,7 @@ func createTables(adapter qgen.Adapter) error { ) // TODO: Can we use a piece of software dedicated to persistent queues for this rather than relying on the database for it? - qgen.Install.CreateTable("users_avatar_queue", "", "", + createTable("users_avatar_queue", "", "", []tC{ tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key }, @@ -160,7 +167,7 @@ func createTables(adapter qgen.Adapter) error { ) // TODO: Should we add a users prefix to this table to fit the "unofficial convention"? - qgen.Install.CreateTable("emails", "", "", + createTable("emails", "", "", []tC{ tC{"email", "varchar", 200, false, false, ""}, tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key @@ -171,7 +178,7 @@ func createTables(adapter qgen.Adapter) error { // TODO: Allow for patterns in domains, if the bots try to shake things up there? /* - qgen.Install.CreateTable("email_domain_blacklist", "", "", + createTable("email_domain_blacklist", "", "", []tC{ tC{"domain", "varchar", 200, false, false, ""}, tC{"gtld", "boolean", 0, false, false, "0"}, @@ -183,7 +190,7 @@ func createTables(adapter qgen.Adapter) error { */ // TODO: Implement password resets - qgen.Install.CreateTable("password_resets", "", "", + createTable("password_resets", "", "", []tC{ tC{"email", "varchar", 200, false, false, ""}, tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key @@ -193,7 +200,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("forums", mysqlPre, mysqlCol, + createTable("forums", mysqlPre, mysqlCol, []tC{ tC{"fid", "int", 0, false, true, ""}, tC{"name", "varchar", 100, false, false, ""}, @@ -213,7 +220,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("forums_permissions", "", "", + createTable("forums_permissions", "", "", []tC{ tC{"fid", "int", 0, false, false, ""}, tC{"gid", "int", 0, false, false, ""}, @@ -226,7 +233,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("topics", mysqlPre, mysqlCol, + createTable("topics", mysqlPre, mysqlCol, []tC{ tC{"tid", "int", 0, false, true, ""}, tC{"title", "varchar", 100, false, false, ""}, // TODO: Increase the max length to 200? @@ -263,7 +270,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("replies", mysqlPre, mysqlCol, + createTable("replies", mysqlPre, mysqlCol, []tC{ tC{"rid", "int", 0, false, true, ""}, // TODO: Rename to replyID? tC{"tid", "int", 0, false, false, ""}, // TODO: Rename to topicID? @@ -287,7 +294,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("attachments", mysqlPre, mysqlCol, + createTable("attachments", mysqlPre, mysqlCol, []tC{ tC{"attachID", "int", 0, false, true, ""}, tC{"sectionID", "int", 0, false, false, "0"}, @@ -303,7 +310,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("revisions", mysqlPre, mysqlCol, + createTable("revisions", mysqlPre, mysqlCol, []tC{ tC{"reviseID", "int", 0, false, true, ""}, tC{"content", "text", 0, false, false, ""}, @@ -317,7 +324,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("polls", mysqlPre, mysqlCol, + createTable("polls", mysqlPre, mysqlCol, []tC{ tC{"pollID", "int", 0, false, true, ""}, tC{"parentID", "int", 0, false, false, "0"}, @@ -331,7 +338,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("polls_options", "", "", + createTable("polls_options", "", "", []tC{ tC{"pollID", "int", 0, false, false, ""}, tC{"option", "int", 0, false, false, "0"}, @@ -339,7 +346,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("polls_votes", mysqlPre, mysqlCol, + createTable("polls_votes", mysqlPre, mysqlCol, []tC{ tC{"pollID", "int", 0, false, false, ""}, tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key @@ -349,7 +356,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("users_replies", mysqlPre, mysqlCol, + createTable("users_replies", mysqlPre, mysqlCol, []tC{ tC{"rid", "int", 0, false, true, ""}, tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key @@ -366,7 +373,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("likes", "", "", + createTable("likes", "", "", []tC{ tC{"weight", "tinyint", 0, false, false, "1"}, tC{"targetItem", "int", 0, false, false, ""}, @@ -378,7 +385,7 @@ func createTables(adapter qgen.Adapter) error { ) //columns("participants, createdBy, createdAt, lastReplyBy, lastReplyAt").Where("cid = ?") - qgen.Install.CreateTable("conversations", "", "", + createTable("conversations", "", "", []tC{ tC{"cid", "int", 0, false, true, ""}, tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key @@ -391,7 +398,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("conversations_posts", "", "", + createTable("conversations_posts", "", "", []tC{ tC{"pid", "int", 0, false, true, ""}, tC{"cid", "int", 0, false, false, ""}, @@ -404,14 +411,14 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("conversations_participants", "", "", + createTable("conversations_participants", "", "", []tC{ tC{"uid", "int", 0, false, false, ""}, tC{"cid", "int", 0, false, false, ""}, }, nil, ) - qgen.Install.CreateTable("activity_stream_matches", "", "", + createTable("activity_stream_matches", "", "", []tC{ tC{"watcher", "int", 0, false, false, ""}, // TODO: Make this a foreign key tC{"asid", "int", 0, false, false, ""}, // TODO: Make this a foreign key @@ -421,7 +428,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("activity_stream", "", "", + createTable("activity_stream", "", "", []tC{ tC{"asid", "int", 0, false, true, ""}, tC{"actor", "int", 0, false, false, ""}, /* the one doing the act */ // TODO: Make this a foreign key @@ -436,7 +443,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("activity_subscriptions", "", "", + createTable("activity_subscriptions", "", "", []tC{ tC{"user", "int", 0, false, false, ""}, // TODO: Make this a foreign key tC{"targetID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */ @@ -446,7 +453,7 @@ func createTables(adapter qgen.Adapter) error { ) /* Due to MySQL's design, we have to drop the unique keys for table settings, plugins, and themes down from 200 to 180 or it will error */ - qgen.Install.CreateTable("settings", "", "", + createTable("settings", "", "", []tC{ tC{"name", "varchar", 180, false, false, ""}, tC{"content", "varchar", 250, false, false, ""}, @@ -458,7 +465,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("word_filters", "", "", + createTable("word_filters", "", "", []tC{ tC{"wfid", "int", 0, false, true, ""}, tC{"find", "varchar", 200, false, false, ""}, @@ -469,7 +476,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("plugins", "", "", + createTable("plugins", "", "", []tC{ tC{"uname", "varchar", 180, false, false, ""}, tC{"active", "boolean", 0, false, false, "0"}, @@ -480,7 +487,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("themes", "", "", + createTable("themes", "", "", []tC{ tC{"uname", "varchar", 180, false, false, ""}, tC{"default", "boolean", 0, false, false, "0"}, @@ -491,7 +498,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("widgets", "", "", + createTable("widgets", "", "", []tC{ tC{"wid", "int", 0, false, true, ""}, tC{"position", "int", 0, false, false, ""}, @@ -506,7 +513,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("menus", "", "", + createTable("menus", "", "", []tC{ tC{"mid", "int", 0, false, true, ""}, }, @@ -515,7 +522,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("menu_items", "", "", + createTable("menu_items", "", "", []tC{ tC{"miid", "int", 0, false, true, ""}, tC{"mid", "int", 0, false, false, ""}, @@ -539,7 +546,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("pages", mysqlPre, mysqlCol, + createTable("pages", mysqlPre, mysqlCol, []tC{ tC{"pid", "int", 0, false, true, ""}, //tC{"path", "varchar", 200, false, false, ""}, @@ -555,7 +562,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("registration_logs", "", "", + createTable("registration_logs", "", "", []tC{ tC{"rlid", "int", 0, false, true, ""}, tC{"username", "varchar", 100, false, false, ""}, @@ -570,7 +577,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("login_logs", "", "", + createTable("login_logs", "", "", []tC{ tC{"lid", "int", 0, false, true, ""}, tC{"uid", "int", 0, false, false, ""}, @@ -583,7 +590,7 @@ func createTables(adapter qgen.Adapter) error { }, ) - qgen.Install.CreateTable("moderation_logs", "", "", + createTable("moderation_logs", "", "", []tC{ tC{"action", "varchar", 100, false, false, ""}, tC{"elementID", "int", 0, false, false, ""}, @@ -594,7 +601,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("administration_logs", "", "", + createTable("administration_logs", "", "", []tC{ tC{"action", "varchar", 100, false, false, ""}, tC{"elementID", "int", 0, false, false, ""}, @@ -605,7 +612,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("viewchunks", "", "", + createTable("viewchunks", "", "", []tC{ tC{"count", "int", 0, false, false, "0"}, tC{"createdAt", "datetime", 0, false, false, ""}, @@ -613,7 +620,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("viewchunks_agents", "", "", + createTable("viewchunks_agents", "", "", []tC{ tC{"count", "int", 0, false, false, "0"}, tC{"createdAt", "datetime", 0, false, false, ""}, @@ -622,7 +629,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("viewchunks_systems", "", "", + createTable("viewchunks_systems", "", "", []tC{ tC{"count", "int", 0, false, false, "0"}, tC{"createdAt", "datetime", 0, false, false, ""}, @@ -630,7 +637,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("viewchunks_langs", "", "", + createTable("viewchunks_langs", "", "", []tC{ tC{"count", "int", 0, false, false, "0"}, tC{"createdAt", "datetime", 0, false, false, ""}, @@ -638,7 +645,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("viewchunks_referrers", "", "", + createTable("viewchunks_referrers", "", "", []tC{ tC{"count", "int", 0, false, false, "0"}, tC{"createdAt", "datetime", 0, false, false, ""}, @@ -646,7 +653,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("viewchunks_forums", "", "", + createTable("viewchunks_forums", "", "", []tC{ tC{"count", "int", 0, false, false, "0"}, tC{"createdAt", "datetime", 0, false, false, ""}, @@ -654,7 +661,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("topicchunks", "", "", + createTable("topicchunks", "", "", []tC{ tC{"count", "int", 0, false, false, "0"}, tC{"createdAt", "datetime", 0, false, false, ""}, @@ -662,7 +669,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("postchunks", "", "", + createTable("postchunks", "", "", []tC{ tC{"count", "int", 0, false, false, "0"}, tC{"createdAt", "datetime", 0, false, false, ""}, @@ -670,7 +677,7 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("memchunks", "", "", + createTable("memchunks", "", "", []tC{ tC{"count", "int", 0, false, false, "0"}, tC{"stack", "int", 0, false, false, "0"}, @@ -679,24 +686,24 @@ func createTables(adapter qgen.Adapter) error { }, nil, ) - qgen.Install.CreateTable("sync", "", "", + createTable("sync", "", "", []tC{ tC{"last_update", "datetime", 0, false, false, ""}, }, nil, ) - qgen.Install.CreateTable("updates", "", "", + createTable("updates", "", "", []tC{ tC{"dbVersion", "int", 0, false, false, "0"}, }, nil, ) - qgen.Install.CreateTable("meta", "", "", + createTable("meta", "", "", []tC{ tC{"name", "varchar", 200, false, false, ""}, tC{"value", "varchar", 200, false, false, ""}, }, nil, ) - return nil + return err } diff --git a/common/promotions.go b/common/promotions.go index e91eb263..38d29b83 100644 --- a/common/promotions.go +++ b/common/promotions.go @@ -6,7 +6,7 @@ import ( qgen "github.com/Azareal/Gosora/query_gen" ) -var GroupPromotions *DefaultGroupPromotionStore +var GroupPromotions GroupPromotionStore type GroupPromotion struct { ID int @@ -15,15 +15,16 @@ type GroupPromotion struct { TwoWay bool Level int + Posts int MinTime int } type GroupPromotionStore interface { - GetByGroup() ([]*GroupPromotion, error) + GetByGroup(gid int) (gps []*GroupPromotion, err error) Get(id int) (*GroupPromotion, error) - PromoteIfEligible(u *User, level int) error + PromoteIfEligible(u *User, level int, posts int) error Delete(id int) error - Create(from int, to int, twoWay bool, level int) (int, error) + Create(from int, to int, twoWay bool, level int, posts int) (int, error) } type DefaultGroupPromotionStore struct { @@ -39,13 +40,13 @@ type DefaultGroupPromotionStore struct { func NewDefaultGroupPromotionStore(acc *qgen.Accumulator) (*DefaultGroupPromotionStore, error) { ugp := "users_groups_promotions" return &DefaultGroupPromotionStore{ - getByGroup: acc.Select(ugp).Columns("pid, from_gid, to_gid, two_way, level, minTime").Where("from_gid=? OR to_gid=?").Prepare(), - get: acc.Select(ugp).Columns("from_gid, to_gid, two_way, level, minTime").Where("pid = ?").Prepare(), + getByGroup: acc.Select(ugp).Columns("pid, from_gid, to_gid, two_way, level, posts, minTime").Where("from_gid=? OR to_gid=?").Prepare(), + get: acc.Select(ugp).Columns("from_gid, to_gid, two_way, level, posts, minTime").Where("pid = ?").Prepare(), delete: acc.Delete(ugp).Where("pid = ?").Prepare(), - create: acc.Insert(ugp).Columns("from_gid, to_gid, two_way, level, minTime").Fields("?,?,?,?,?").Prepare(), + create: acc.Insert(ugp).Columns("from_gid, to_gid, two_way, level, posts, minTime").Fields("?,?,?,?,?,?").Prepare(), - getByUser: acc.Select(ugp).Columns("pid, to_gid, two_way, level, minTime").Where("from_gid=? AND level>=?").Orderby("level DESC").Limit("1").Prepare(), - updateUser: acc.Update("users").Set("group = ?").Where("level >= ?").Prepare(), + getByUser: acc.Select(ugp).Columns("pid, to_gid, two_way, level, posts, minTime").Where("from_gid=? AND level>=? AND posts>=?").Orderby("level DESC").Limit("1").Prepare(), + updateUser: acc.Update("users").Set("group = ?").Where("level >= ? AND posts >= ?").Prepare(), }, acc.FirstError() } @@ -58,7 +59,7 @@ func (s *DefaultGroupPromotionStore) GetByGroup(gid int) (gps []*GroupPromotion, for rows.Next() { g := &GroupPromotion{} - err := rows.Scan(&g.ID, &g.From, &g.To, &g.TwoWay, &g.Level, &g.MinTime) + err := rows.Scan(&g.ID, &g.From, &g.To, &g.TwoWay, &g.Level, &g.Posts, &g.MinTime) if err != nil { return nil, err } @@ -75,22 +76,22 @@ func (s *DefaultGroupPromotionStore) Get(id int) (*GroupPromotion, error) { }*/ g := &GroupPromotion{ID: id} - err := s.get.QueryRow(id).Scan(&g.From, &g.To, &g.TwoWay, &g.Level, &g.MinTime) + err := s.get.QueryRow(id).Scan(&g.From, &g.To, &g.TwoWay, &g.Level, &g.Posts, &g.MinTime) if err == nil { //s.cache.Set(u) } return g, err } -func (s *DefaultGroupPromotionStore) PromoteIfEligible(u *User, level int) error { +func (s *DefaultGroupPromotionStore) PromoteIfEligible(u *User, level int, posts int) error { g := &GroupPromotion{From: u.Group} - err := s.getByUser.QueryRow(u.Group, level).Scan(&g.ID, &g.To, &g.TwoWay, &g.Level, &g.MinTime) + err := s.getByUser.QueryRow(u.Group, level, posts).Scan(&g.ID, &g.To, &g.TwoWay, &g.Level, &g.Posts, &g.MinTime) if err == sql.ErrNoRows { return nil } else if err != nil { return err } - _, err = s.updateUser.Exec(g.To, g.Level) + _, err = s.updateUser.Exec(g.To, g.Level, g.Posts) return err } @@ -99,8 +100,8 @@ func (s *DefaultGroupPromotionStore) Delete(id int) error { return err } -func (s *DefaultGroupPromotionStore) Create(from int, to int, twoWay bool, level int) (int, error) { - res, err := s.create.Exec(from, to, twoWay, level, 0) +func (s *DefaultGroupPromotionStore) Create(from int, to int, twoWay bool, level int, posts int) (int, error) { + res, err := s.create.Exec(from, to, twoWay, level, posts, 0) if err != nil { return 0, err } diff --git a/common/reply.go b/common/reply.go index fe2f0ca1..aa3c5e2f 100644 --- a/common/reply.go +++ b/common/reply.go @@ -113,7 +113,7 @@ func (r *Reply) Like(uid int) (err error) { if err != nil { return err } - _, err = userStmts.incrementLiked.Exec(1, uid) + _, err = userStmts.incLiked.Exec(1, uid) _ = Rstore.GetCache().Remove(r.ID) return err } diff --git a/common/template_init.go b/common/template_init.go index 0cef94a0..888c67b0 100644 --- a/common/template_init.go +++ b/common/template_init.go @@ -91,14 +91,14 @@ var Template_account_handle = genIntTmpl("account") func tmplInitUsers() (User, User, User) { avatar, microAvatar := BuildAvatar(62, "") - user := User{62, BuildProfileURL("fake-user", 62), "Fake User", "compiler@localhost", 0, false, false, false, false, false, false, GuestPerms, make(map[string]bool), "", false, "", avatar, microAvatar, "", "", "", "", 0, 0, 0, "0.0.0.0.0", "", 0} + user := User{62, BuildProfileURL("fake-user", 62), "Fake User", "compiler@localhost", 0, false, false, false, false, false, false, GuestPerms, make(map[string]bool), "", false, "", avatar, microAvatar, "", "", "", "", 0, 0, 0, 0,"0.0.0.0.0", "", 0} // TODO: Do a more accurate level calculation for this? avatar, microAvatar = BuildAvatar(1, "") - user2 := User{1, BuildProfileURL("admin-alice", 1), "Admin Alice", "alice@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", "", "", 58, 1000, 0, "127.0.0.1", "", 0} + user2 := User{1, BuildProfileURL("admin-alice", 1), "Admin Alice", "alice@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", "", "", 58, 1000, 0, 1000, "127.0.0.1", "", 0} avatar, microAvatar = BuildAvatar(2, "") - user3 := User{2, BuildProfileURL("admin-fred", 62), "Admin Fred", "fred@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", "", "", 42, 900, 0, "::1", "", 0} + user3 := User{2, BuildProfileURL("admin-fred", 62), "Admin Fred", "fred@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", "", "", 42, 900, 0, 900, "::1", "", 0} return user, user2, user3 } diff --git a/common/topic.go b/common/topic.go index c8c84b1c..d4234eaa 100644 --- a/common/topic.go +++ b/common/topic.go @@ -318,7 +318,7 @@ func (t *Topic) Like(score int, uid int) (err error) { if err != nil { return err } - _, err = userStmts.incrementLiked.Exec(1, uid) + _, err = userStmts.incLiked.Exec(1, uid) t.cacheRemove() return err } diff --git a/common/user.go b/common/user.go index d5262e57..443111b8 100644 --- a/common/user.go +++ b/common/user.go @@ -13,7 +13,7 @@ import ( "strings" "time" - "github.com/Azareal/Gosora/query_gen" + qgen "github.com/Azareal/Gosora/query_gen" "github.com/go-sql-driver/mysql" ) @@ -51,6 +51,7 @@ type User struct { Tag string Level int Score int + Posts int Liked int LastIP string // ! This part of the UserCache data might fall out of date LastAgent string // ! Temporary hack, don't use @@ -104,7 +105,7 @@ type MeUser struct { //Perms Perms //PluginPerms map[string]bool - S string // Session + S string // Session Avatar string MicroAvatar string Tag string @@ -114,24 +115,24 @@ type MeUser struct { } type UserStmts struct { - activate *sql.Stmt - changeGroup *sql.Stmt - delete *sql.Stmt - setAvatar *sql.Stmt - setUsername *sql.Stmt - incrementTopics *sql.Stmt - updateLevel *sql.Stmt - update *sql.Stmt + activate *sql.Stmt + changeGroup *sql.Stmt + delete *sql.Stmt + setAvatar *sql.Stmt + setUsername *sql.Stmt + incTopics *sql.Stmt + updateLevel *sql.Stmt + update *sql.Stmt // TODO: Split these into a sub-struct - incrementScore *sql.Stmt - incrementPosts *sql.Stmt - incrementBigposts *sql.Stmt - incrementMegaposts *sql.Stmt - incrementLiked *sql.Stmt + incScore *sql.Stmt + incPosts *sql.Stmt + incBigposts *sql.Stmt + incMegaposts *sql.Stmt + incLiked *sql.Stmt - decrementLiked *sql.Stmt - updateLastIP *sql.Stmt + decLiked *sql.Stmt + updateLastIP *sql.Stmt setPassword *sql.Stmt @@ -142,23 +143,23 @@ var userStmts UserStmts func init() { DbInits.Add(func(acc *qgen.Accumulator) error { - var w = "uid = ?" + w := "uid = ?" userStmts = UserStmts{ - activate: acc.SimpleUpdate("users", "active = 1", w), - changeGroup: acc.SimpleUpdate("users", "group = ?", w), // TODO: Implement user_count for users_groups here - delete: acc.SimpleDelete("users", w), - setAvatar: acc.Update("users").Set("avatar = ?").Where(w).Prepare(), - setUsername: acc.Update("users").Set("name = ?").Where(w).Prepare(), - incrementTopics: acc.SimpleUpdate("users", "topics = topics + ?", w), - updateLevel: acc.SimpleUpdate("users", "level = ?", w), - update: acc.Update("users").Set("name = ?, email = ?, group = ?").Where(w).Prepare(), // TODO: Implement user_count for users_groups on things which use this + activate: acc.SimpleUpdate("users", "active = 1", w), + changeGroup: acc.SimpleUpdate("users", "group = ?", w), // TODO: Implement user_count for users_groups here + delete: acc.SimpleDelete("users", w), + setAvatar: acc.Update("users").Set("avatar = ?").Where(w).Prepare(), + setUsername: acc.Update("users").Set("name = ?").Where(w).Prepare(), + incTopics: acc.SimpleUpdate("users", "topics = topics + ?", w), + updateLevel: acc.SimpleUpdate("users", "level = ?", w), + update: acc.Update("users").Set("name = ?, email = ?, group = ?").Where(w).Prepare(), // TODO: Implement user_count for users_groups on things which use this - incrementScore: acc.SimpleUpdate("users", "score = score + ?", w), - incrementPosts: acc.SimpleUpdate("users", "posts = posts + ?", w), - incrementBigposts: acc.SimpleUpdate("users", "posts = posts + ?, bigposts = bigposts + ?", w), - incrementMegaposts: acc.SimpleUpdate("users", "posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ?", w), - incrementLiked: acc.SimpleUpdate("users", "liked = liked + ?, lastLiked = UTC_TIMESTAMP()", w), - decrementLiked: acc.SimpleUpdate("users", "liked = liked - ?", w), + incScore: acc.Update("users").Set("score = score + ?").Where(w).Prepare(), + incPosts: acc.Update("users").Set("posts = posts + ?").Where(w).Prepare(), + incBigposts: acc.Update("users").Set("posts = posts + ?, bigposts = bigposts + ?").Where(w).Prepare(), + incMegaposts: acc.Update("users").Set("posts = posts + ?, bigposts = bigposts + ?, megaposts = megaposts + ?").Where(w).Prepare(), + incLiked: acc.Update("users").Set("liked = liked + ?, lastLiked = UTC_TIMESTAMP()").Where(w).Prepare(), + decLiked: acc.Update("users").Set("liked = liked - ?").Where(w).Prepare(), //recalcLastLiked: acc... updateLastIP: acc.SimpleUpdate("users", "last_ip = ?", w), @@ -342,15 +343,15 @@ func (u *User) UpdateIP(host string) error { return err } -func (u *User) Update(newname string, newemail string, newgroup int) (err error) { - return u.bindStmt(userStmts.update, newname, newemail, newgroup) +func (u *User) Update(name string, email string, group int) (err error) { + return u.bindStmt(userStmts.update, name, email, group) } func (u *User) IncreasePostStats(wcount int, topic bool) (err error) { var mod int baseScore := 1 if topic { - _, err = userStmts.incrementTopics.Exec(1, u.ID) + _, err = userStmts.incTopics.Exec(1, u.ID) if err != nil { return err } @@ -359,31 +360,31 @@ func (u *User) IncreasePostStats(wcount int, topic bool) (err error) { settings := SettingBox.Load().(SettingMap) if wcount >= settings["megapost_min_words"].(int) { - _, err = userStmts.incrementMegaposts.Exec(1, 1, 1, u.ID) + _, err = userStmts.incMegaposts.Exec(1, 1, 1, u.ID) mod = 4 } else if wcount >= settings["bigpost_min_words"].(int) { - _, err = userStmts.incrementBigposts.Exec(1, 1, u.ID) + _, err = userStmts.incBigposts.Exec(1, 1, u.ID) mod = 1 } else { - _, err = userStmts.incrementPosts.Exec(1, u.ID) + _, err = userStmts.incPosts.Exec(1, u.ID) } if err != nil { return err } - _, err = userStmts.incrementScore.Exec(baseScore+mod, u.ID) + _, err = userStmts.incScore.Exec(baseScore+mod, u.ID) if err != nil { return err } //log.Print(u.Score + baseScore + mod) // TODO: Use a transaction to prevent level desyncs? - level := GetLevel(u.Score+baseScore+mod) + level := GetLevel(u.Score + baseScore + mod) //log.Print(level) _, err = userStmts.updateLevel.Exec(level, u.ID) if err != nil { return err } - err = GroupPromotions.PromoteIfEligible(u,level) + err = GroupPromotions.PromoteIfEligible(u, level, u.Posts+1) u.CacheRemove() return err } @@ -392,7 +393,7 @@ func (u *User) DecreasePostStats(wcount int, topic bool) (err error) { var mod int baseScore := -1 if topic { - _, err = userStmts.incrementTopics.Exec(-1, u.ID) + _, err = userStmts.incTopics.Exec(-1, u.ID) if err != nil { return err } @@ -401,19 +402,19 @@ func (u *User) DecreasePostStats(wcount int, topic bool) (err error) { settings := SettingBox.Load().(SettingMap) if wcount >= settings["megapost_min_words"].(int) { - _, err = userStmts.incrementMegaposts.Exec(-1, -1, -1, u.ID) + _, err = userStmts.incMegaposts.Exec(-1, -1, -1, u.ID) mod = 4 } else if wcount >= settings["bigpost_min_words"].(int) { - _, err = userStmts.incrementBigposts.Exec(-1, -1, u.ID) + _, err = userStmts.incBigposts.Exec(-1, -1, u.ID) mod = 1 } else { - _, err = userStmts.incrementPosts.Exec(-1, u.ID) + _, err = userStmts.incPosts.Exec(-1, u.ID) } if err != nil { return err } - _, err = userStmts.incrementScore.Exec(baseScore-mod, u.ID) + _, err = userStmts.incScore.Exec(baseScore-mod, u.ID) if err != nil { return err } @@ -479,7 +480,7 @@ func buildNoavatar(uid int, width int) string { } } if !Config.DisableDefaultNoavatar && uid < 5 { - return "/s/n"+strconv.Itoa(uid)+"-"+strconv.Itoa(width)+".png?i=0" + return "/s/n" + strconv.Itoa(uid) + "-" + strconv.Itoa(width) + ".png?i=0" } return strings.Replace(strings.Replace(Config.Noavatar, "{id}", strconv.Itoa(uid), 1), "{width}", strconv.Itoa(width), 1) } diff --git a/common/user_store.go b/common/user_store.go index b0b9b714..89ccfe60 100644 --- a/common/user_store.go +++ b/common/user_store.go @@ -53,9 +53,9 @@ func NewDefaultUserStore(cache UserCache) (*DefaultUserStore, error) { // TODO: Add an admin version of registerStmt with more flexibility? return &DefaultUserStore{ cache: cache, - get: acc.SimpleSelect("users", "name, group, active, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, liked, last_ip, temp_group", "uid = ?", "", ""), - getByName: acc.Select("users").Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, liked, last_ip, temp_group").Where("name = ?").Prepare(), - getOffset: acc.Select("users").Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, liked, last_ip, temp_group").Orderby("uid ASC").Limit("?,?").Prepare(), + get: acc.SimpleSelect("users", "name, group, active, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, posts, liked, last_ip, temp_group", "uid = ?", "", ""), + getByName: acc.Select("users").Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, posts, liked, last_ip, temp_group").Where("name = ?").Prepare(), + getOffset: acc.Select("users").Columns("uid, name, group, active, is_super_admin, session, email, avatar, message, url_prefix, url_name, level, score, posts, liked, last_ip, temp_group").Orderby("uid ASC").Limit("?,?").Prepare(), exists: acc.SimpleSelect("users", "uid", "uid = ?", "", ""), register: acc.Insert("users").Columns("name, email, password, salt, group, is_super_admin, session, active, message, createdAt, lastActiveAt, lastLiked, oldestItemLikedCreatedAt").Fields("?,?,?,?,?,0,'',?,'',UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP(),UTC_TIMESTAMP()").Prepare(), // TODO: Implement user_count on users_groups here usernameExists: acc.SimpleSelect("users", "name", "name = ?", "", ""), @@ -86,7 +86,7 @@ func (s *DefaultUserStore) Get(id int) (*User, error) { //log.Print("uncached user") u = &User{ID: id, Loggedin: true} - err = s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score,&u.Liked, &u.LastIP, &u.TempGroup) + err = s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Posts,&u.Liked, &u.LastIP, &u.TempGroup) if err == nil { u.Init() s.cache.Set(u) @@ -98,7 +98,7 @@ func (s *DefaultUserStore) Get(id int) (*User, error) { // ! This bypasses the cache, use frugally func (s *DefaultUserStore) GetByName(name string) (*User, error) { u := &User{Loggedin: true} - err := s.getByName.QueryRow(name).Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Liked, &u.LastIP, &u.TempGroup) + err := s.getByName.QueryRow(name).Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Posts,&u.Liked, &u.LastIP, &u.TempGroup) if err == nil { u.Init() s.cache.Set(u) @@ -117,7 +117,7 @@ func (s *DefaultUserStore) GetOffset(offset int, perPage int) (users []*User, er for rows.Next() { u := &User{Loggedin: true} - err := rows.Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Liked, &u.LastIP, &u.TempGroup) + err := rows.Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup) if err != nil { return nil, err } @@ -171,7 +171,7 @@ func (s *DefaultUserStore) BulkGetMap(ids []int) (list map[int]*User, err error) } q = q[0 : len(q)-1] - rows, err := qgen.NewAcc().Select("users").Columns("uid,name,group,active,is_super_admin,session,email,avatar,message,url_prefix,url_name,level,score,liked,last_ip,temp_group").Where("uid IN(" + q + ")").Query(idList...) + rows, err := qgen.NewAcc().Select("users").Columns("uid,name,group,active,is_super_admin,session,email,avatar,message,url_prefix,url_name,level,score,posts,liked,last_ip,temp_group").Where("uid IN(" + q + ")").Query(idList...) if err != nil { return list, err } @@ -179,7 +179,7 @@ func (s *DefaultUserStore) BulkGetMap(ids []int) (list map[int]*User, err error) for rows.Next() { u := &User{Loggedin: true} - err := rows.Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Liked, &u.LastIP, &u.TempGroup) + err := rows.Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup) if err != nil { return list, err } @@ -212,19 +212,19 @@ func (s *DefaultUserStore) BulkGetMap(ids []int) (list map[int]*User, err error) func (s *DefaultUserStore) BypassGet(id int) (*User, error) { u := &User{ID: id, Loggedin: true} - err := s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Liked, &u.LastIP, &u.TempGroup) - u.Init() + err := s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup) + if err == nil { + u.Init() + } return u, err } func (s *DefaultUserStore) Reload(id int) error { - u := &User{ID: id, Loggedin: true} - err := s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.URLPrefix, &u.URLName, &u.Level, &u.Score, &u.Liked, &u.LastIP, &u.TempGroup) + u, err := s.BypassGet(id) if err != nil { s.cache.Remove(id) return err } - u.Init() _ = s.cache.Set(u) TopicListThaw.Thaw() return nil diff --git a/general_test.go b/general_test.go index 6d767185..62659ac2 100644 --- a/general_test.go +++ b/general_test.go @@ -106,8 +106,7 @@ func gloinit() (err error) { } func init() { - err := gloinit() - if err != nil { + if err := gloinit(); err != nil { log.Print("Something bad happened") //debug.PrintStack() log.Fatalf("%+v\n", err) diff --git a/langs/english.json b/langs/english.json index 65484bd3..539da022 100644 --- a/langs/english.json +++ b/langs/english.json @@ -889,6 +889,7 @@ "panel_group_promotions_to":"To", "panel_group_promotions_two_way":"Two Way", "panel_group_promotions_level":"Level", + "panel_group_promotions_posts":"Posts", "panel_group_promotions_create_button":"Add Promotion", "panel_word_filters_head":"Word Filters", diff --git a/patcher/patches.go b/patcher/patches.go index e6b14758..9c0366d0 100644 --- a/patcher/patches.go +++ b/patcher/patches.go @@ -38,6 +38,7 @@ func init() { addPatch(22, patch22) addPatch(23, patch23) addPatch(24, patch24) + addPatch(25, patch25) } func patch0(scanner *bufio.Scanner) (err error) { @@ -734,4 +735,8 @@ func patch24(scanner *bufio.Scanner) error { tblKey{"pid", "primary","",false}, }, )) +} + +func patch25(scanner *bufio.Scanner) error { + return execStmt(qgen.Builder.AddColumn("users_groups_promotions", tC{"posts", "int", 0, false, false, "0"}, nil)) } \ No newline at end of file diff --git a/query_gen/install.go b/query_gen/install.go index 3e8a743d..1bce70ef 100644 --- a/query_gen/install.go +++ b/query_gen/install.go @@ -30,81 +30,81 @@ type installer struct { plugins []QueryPlugin } -func (install *installer) SetAdapter(name string) error { +func (ins *installer) SetAdapter(name string) error { adap, err := GetAdapter(name) if err != nil { return err } - install.SetAdapterInstance(adap) + ins.SetAdapterInstance(adap) return nil } -func (install *installer) SetAdapterInstance(adapter Adapter) { - install.adapter = adapter - install.instructions = []DBInstallInstruction{} +func (ins *installer) SetAdapterInstance(adapter Adapter) { + ins.adapter = adapter + ins.instructions = []DBInstallInstruction{} } -func (install *installer) AddPlugins(plugins ...QueryPlugin) { - install.plugins = append(install.plugins, plugins...) +func (ins *installer) AddPlugins(plugins ...QueryPlugin) { + ins.plugins = append(ins.plugins, plugins...) } -func (install *installer) CreateTable(table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) error { +func (ins *installer) CreateTable(table string, charset string, collation string, columns []DBTableColumn, keys []DBTableKey) error { tableStruct := &DBInstallTable{table, charset, collation, columns, keys} - err := install.RunHook("CreateTableStart", tableStruct) + err := ins.RunHook("CreateTableStart", tableStruct) if err != nil { return err } - res, err := install.adapter.CreateTable("", table, charset, collation, columns, keys) + res, err := ins.adapter.CreateTable("", table, charset, collation, columns, keys) if err != nil { return err } - err = install.RunHook("CreateTableAfter", tableStruct) + err = ins.RunHook("CreateTableAfter", tableStruct) if err != nil { return err } - install.instructions = append(install.instructions, DBInstallInstruction{table, res, "create-table"}) - install.tables = append(install.tables, tableStruct) + ins.instructions = append(ins.instructions, DBInstallInstruction{table, res, "create-table"}) + ins.tables = append(ins.tables, tableStruct) return nil } // TODO: Let plugins manipulate the parameters like in CreateTable -func (install *installer) AddIndex(table string, iname string, colname string) error { - err := install.RunHook("AddIndexStart", table, iname, colname) +func (ins *installer) AddIndex(table string, iname string, colname string) error { + err := ins.RunHook("AddIndexStart", table, iname, colname) if err != nil { return err } - res, err := install.adapter.AddIndex("", table, iname, colname) + res, err := ins.adapter.AddIndex("", table, iname, colname) if err != nil { return err } - err = install.RunHook("AddIndexAfter", table, iname, colname) + err = ins.RunHook("AddIndexAfter", table, iname, colname) if err != nil { return err } - install.instructions = append(install.instructions, DBInstallInstruction{table, res, "index"}) + ins.instructions = append(ins.instructions, DBInstallInstruction{table, res, "index"}) return nil } // TODO: Let plugins manipulate the parameters like in CreateTable -func (install *installer) SimpleInsert(table string, columns string, fields string) error { - err := install.RunHook("SimpleInsertStart", table, columns, fields) +func (ins *installer) SimpleInsert(table string, columns string, fields string) error { + err := ins.RunHook("SimpleInsertStart", table, columns, fields) if err != nil { return err } - res, err := install.adapter.SimpleInsert("", table, columns, fields) + res, err := ins.adapter.SimpleInsert("", table, columns, fields) if err != nil { return err } - err = install.RunHook("SimpleInsertAfter", table, columns, fields, res) + err = ins.RunHook("SimpleInsertAfter", table, columns, fields, res) if err != nil { return err } - install.instructions = append(install.instructions, DBInstallInstruction{table, res, "insert"}) + ins.instructions = append(ins.instructions, DBInstallInstruction{table, res, "insert"}) return nil } -func (install *installer) RunHook(name string, args ...interface{}) error { - for _, plugin := range install.plugins { +func (ins *installer) RunHook(name string, args ...interface{}) error { + for _, plugin := range ins.plugins { err := plugin.Hook(name, args...) if err != nil { return err @@ -113,12 +113,12 @@ func (install *installer) RunHook(name string, args ...interface{}) error { return nil } -func (install *installer) Write() error { +func (ins *installer) Write() error { var inserts string // We can't escape backticks, so we have to dump it out a file at a time - for _, instr := range install.instructions { + for _, instr := range ins.instructions { if instr.Type == "create-table" { - err := writeFile("./schema/"+install.adapter.GetName()+"/query_"+instr.Table+".sql", instr.Contents) + err := writeFile("./schema/"+ins.adapter.GetName()+"/query_"+instr.Table+".sql", instr.Contents) if err != nil { return err } @@ -127,12 +127,12 @@ func (install *installer) Write() error { } } - err := writeFile("./schema/"+install.adapter.GetName()+"/inserts.sql", inserts) + err := writeFile("./schema/"+ins.adapter.GetName()+"/inserts.sql", inserts) if err != nil { return err } - for _, plugin := range install.plugins { + for _, plugin := range ins.plugins { err := plugin.Write() if err != nil { return err diff --git a/routes/panel/forums.go b/routes/panel/forums.go index db8a4c75..aa0cf9fe 100644 --- a/routes/panel/forums.go +++ b/routes/panel/forums.go @@ -137,7 +137,7 @@ func ForumsOrderSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro if ferr != nil { return ferr } - js := (r.PostFormValue("js") == "1") + js := r.PostFormValue("js") == "1" if !user.Perms.ManageForums { return c.NoPermissionsJSQ(w, r, user, js) } @@ -218,7 +218,7 @@ func ForumsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid if !user.Perms.ManageForums { return c.NoPermissions(w, r, user) } - js := (r.PostFormValue("js") == "1") + js := r.PostFormValue("js") == "1" fid, err := strconv.Atoi(sfid) if err != nil { @@ -260,7 +260,7 @@ func ForumsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user c.User, if !user.Perms.ManageForums { return c.NoPermissions(w, r, user) } - js := (r.PostFormValue("js") == "1") + js := r.PostFormValue("js") == "1" fid, err := strconv.Atoi(sfid) if err != nil { diff --git a/routes/panel/groups.go b/routes/panel/groups.go index 6172fb8c..75898536 100644 --- a/routes/panel/groups.go +++ b/routes/panel/groups.go @@ -208,6 +208,10 @@ func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c if err != nil { return c.LocalError("level must be integer", w, r, user) } + posts, err := strconv.Atoi(r.FormValue("posts")) + if err != nil { + return c.LocalError("posts must be integer", w, r, user) + } g, err := c.Groups.Get(from) ferr := groupCheck(w, r, user, g, err) @@ -219,7 +223,7 @@ func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c if err != nil { return ferr } - _, err = c.GroupPromotions.Create(from, to, twoWay, level) + _, err = c.GroupPromotions.Create(from, to, twoWay, level, posts) if err != nil { return c.InternalError(err, w, r) } @@ -300,50 +304,50 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user c.User, sgid s // TODO: Load the phrases in bulk for efficiency? var localPerms []c.NameLangToggle - addLocalPerm := func(permStr string, perm bool) { + addPerm := func(permStr string, perm bool) { localPerms = append(localPerms, c.NameLangToggle{permStr, p.GetPermPhrase(permStr), perm}) } - addLocalPerm("ViewTopic", g.Perms.ViewTopic) - addLocalPerm("LikeItem", g.Perms.LikeItem) - addLocalPerm("CreateTopic", g.Perms.CreateTopic) + addPerm("ViewTopic", g.Perms.ViewTopic) + addPerm("LikeItem", g.Perms.LikeItem) + addPerm("CreateTopic", g.Perms.CreateTopic) //<-- - addLocalPerm("EditTopic", g.Perms.EditTopic) - addLocalPerm("DeleteTopic", g.Perms.DeleteTopic) - addLocalPerm("CreateReply", g.Perms.CreateReply) - addLocalPerm("EditReply", g.Perms.EditReply) - addLocalPerm("DeleteReply", g.Perms.DeleteReply) - addLocalPerm("PinTopic", g.Perms.PinTopic) - addLocalPerm("CloseTopic", g.Perms.CloseTopic) - addLocalPerm("MoveTopic", g.Perms.MoveTopic) + addPerm("EditTopic", g.Perms.EditTopic) + addPerm("DeleteTopic", g.Perms.DeleteTopic) + addPerm("CreateReply", g.Perms.CreateReply) + addPerm("EditReply", g.Perms.EditReply) + addPerm("DeleteReply", g.Perms.DeleteReply) + addPerm("PinTopic", g.Perms.PinTopic) + addPerm("CloseTopic", g.Perms.CloseTopic) + addPerm("MoveTopic", g.Perms.MoveTopic) var globalPerms []c.NameLangToggle - addGlobalPerm := func(permStr string, perm bool) { + addPerm = func(permStr string, perm bool) { globalPerms = append(globalPerms, c.NameLangToggle{permStr, p.GetPermPhrase(permStr), perm}) } - addGlobalPerm("BanUsers", g.Perms.BanUsers) - addGlobalPerm("ActivateUsers", g.Perms.ActivateUsers) - addGlobalPerm("EditUser", g.Perms.EditUser) - addGlobalPerm("EditUserEmail", g.Perms.EditUserEmail) - addGlobalPerm("EditUserPassword", g.Perms.EditUserPassword) - addGlobalPerm("EditUserGroup", g.Perms.EditUserGroup) - addGlobalPerm("EditUserGroupSuperMod", g.Perms.EditUserGroupSuperMod) - addGlobalPerm("EditUserGroupAdmin", g.Perms.EditUserGroupAdmin) - addGlobalPerm("EditGroup", g.Perms.EditGroup) - addGlobalPerm("EditGroupLocalPerms", g.Perms.EditGroupLocalPerms) - addGlobalPerm("EditGroupGlobalPerms", g.Perms.EditGroupGlobalPerms) - addGlobalPerm("EditGroupSuperMod", g.Perms.EditGroupSuperMod) - addGlobalPerm("EditGroupAdmin", g.Perms.EditGroupAdmin) - addGlobalPerm("ManageForums", g.Perms.ManageForums) - addGlobalPerm("EditSettings", g.Perms.EditSettings) - addGlobalPerm("ManageThemes", g.Perms.ManageThemes) - addGlobalPerm("ManagePlugins", g.Perms.ManagePlugins) - addGlobalPerm("ViewAdminLogs", g.Perms.ViewAdminLogs) - addGlobalPerm("ViewIPs", g.Perms.ViewIPs) - addGlobalPerm("UploadFiles", g.Perms.UploadFiles) - addGlobalPerm("UploadAvatars", g.Perms.UploadAvatars) - addGlobalPerm("UseConvos", g.Perms.UseConvos) + addPerm("BanUsers", g.Perms.BanUsers) + addPerm("ActivateUsers", g.Perms.ActivateUsers) + addPerm("EditUser", g.Perms.EditUser) + addPerm("EditUserEmail", g.Perms.EditUserEmail) + addPerm("EditUserPassword", g.Perms.EditUserPassword) + addPerm("EditUserGroup", g.Perms.EditUserGroup) + addPerm("EditUserGroupSuperMod", g.Perms.EditUserGroupSuperMod) + addPerm("EditUserGroupAdmin", g.Perms.EditUserGroupAdmin) + addPerm("EditGroup", g.Perms.EditGroup) + addPerm("EditGroupLocalPerms", g.Perms.EditGroupLocalPerms) + addPerm("EditGroupGlobalPerms", g.Perms.EditGroupGlobalPerms) + addPerm("EditGroupSuperMod", g.Perms.EditGroupSuperMod) + addPerm("EditGroupAdmin", g.Perms.EditGroupAdmin) + addPerm("ManageForums", g.Perms.ManageForums) + addPerm("EditSettings", g.Perms.EditSettings) + addPerm("ManageThemes", g.Perms.ManageThemes) + addPerm("ManagePlugins", g.Perms.ManagePlugins) + addPerm("ViewAdminLogs", g.Perms.ViewAdminLogs) + addPerm("ViewIPs", g.Perms.ViewIPs) + addPerm("UploadFiles", g.Perms.UploadFiles) + addPerm("UploadAvatars", g.Perms.UploadAvatars) + addPerm("UseConvos", g.Perms.UseConvos) pi := c.PanelEditGroupPermsPage{basePage, g.ID, g.Name, localPerms, globalPerms} return renderTemplate("panel_group_edit_perms", w, r, basePage.Header, pi) diff --git a/schema/mssql/query_users_groups_promotions.sql b/schema/mssql/query_users_groups_promotions.sql index 7cfc8f44..3e722449 100644 --- a/schema/mssql/query_users_groups_promotions.sql +++ b/schema/mssql/query_users_groups_promotions.sql @@ -4,6 +4,7 @@ CREATE TABLE [users_groups_promotions] ( [to_gid] int not null, [two_way] bit DEFAULT 0 not null, [level] int not null, + [posts] int DEFAULT 0 not null, [minTime] int not null, primary key([pid]) ); \ No newline at end of file diff --git a/schema/mysql/query_users_groups_promotions.sql b/schema/mysql/query_users_groups_promotions.sql index cf534c5a..8c1dec3e 100644 --- a/schema/mysql/query_users_groups_promotions.sql +++ b/schema/mysql/query_users_groups_promotions.sql @@ -4,6 +4,7 @@ CREATE TABLE `users_groups_promotions` ( `to_gid` int not null, `two_way` boolean DEFAULT 0 not null, `level` int not null, + `posts` int DEFAULT 0 not null, `minTime` int not null, primary key(`pid`) ) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci; \ No newline at end of file diff --git a/schema/pgsql/query_users_groups_promotions.sql b/schema/pgsql/query_users_groups_promotions.sql index 5f1fc701..5bec0a3e 100644 --- a/schema/pgsql/query_users_groups_promotions.sql +++ b/schema/pgsql/query_users_groups_promotions.sql @@ -4,6 +4,7 @@ CREATE TABLE "users_groups_promotions" ( `to_gid` int not null, `two_way` boolean DEFAULT 0 not null, `level` int not null, + `posts` int DEFAULT 0 not null, `minTime` int not null, primary key(`pid`) ); \ No newline at end of file diff --git a/templates/panel_group_edit_promotions.html b/templates/panel_group_edit_promotions.html index 92c475a1..8c25103a 100644 --- a/templates/panel_group_edit_promotions.html +++ b/templates/panel_group_edit_promotions.html @@ -57,6 +57,10 @@
+