Add per-user profile comment visibility settings.
Honor user blocks in ProfileReplyEditSubmit. Reduce boilerplate. Update account_privacy_profile_comments phrase. Add account_privacy_profile_comments_public phrase. Add account_privacy_profile_comments_registered phrase. Add account_privacy_profile_comments_self phrase. Add account_privacy_enable_embeds phrase. Add profile_comments column to users table. Add who_can_convo column to users table. You will need to run the updater / patcher for this commit.
This commit is contained in:
parent
4bdc528744
commit
b1af963916
|
@ -5,12 +5,16 @@ import qgen "github.com/Azareal/Gosora/query_gen"
|
||||||
var mysqlPre = "utf8mb4"
|
var mysqlPre = "utf8mb4"
|
||||||
var mysqlCol = "utf8mb4_general_ci"
|
var mysqlCol = "utf8mb4_general_ci"
|
||||||
|
|
||||||
|
var tables []string
|
||||||
|
|
||||||
type tblColumn = qgen.DBTableColumn
|
type tblColumn = qgen.DBTableColumn
|
||||||
type tC = tblColumn
|
type tC = tblColumn
|
||||||
type tblKey = qgen.DBTableKey
|
type tblKey = qgen.DBTableKey
|
||||||
|
|
||||||
func createTables(a qgen.Adapter) error {
|
func createTables(a qgen.Adapter) error {
|
||||||
|
tables = nil
|
||||||
f := func(table, charset, collation string, cols []tC, keys []tblKey) error {
|
f := func(table, charset, collation string, cols []tC, keys []tblKey) error {
|
||||||
|
tables = append(tables, table)
|
||||||
return qgen.Install.CreateTable(table, charset, collation, cols, keys)
|
return qgen.Install.CreateTable(table, charset, collation, cols, keys)
|
||||||
}
|
}
|
||||||
return createTables2(a, f)
|
return createTables2(a, f)
|
||||||
|
@ -23,30 +27,65 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
}
|
}
|
||||||
err = f(table, charset, collation, cols, keys)
|
err = f(table, charset, collation, cols, keys)
|
||||||
}
|
}
|
||||||
|
bcol := func(col string, val bool) qgen.DBTableColumn {
|
||||||
|
if val {
|
||||||
|
return tC{col, "boolean", 0, false, false, "1"}
|
||||||
|
}
|
||||||
|
return tC{col, "boolean", 0, false, false, "0"}
|
||||||
|
}
|
||||||
|
ccol := func(col string, size int, sdefault string) qgen.DBTableColumn {
|
||||||
|
return tC{col, "varchar", size, false, false, sdefault}
|
||||||
|
}
|
||||||
|
text := func(params ...string) qgen.DBTableColumn {
|
||||||
|
if len(params) == 0 {
|
||||||
|
return tC{"", "text", 0, false, false, ""}
|
||||||
|
}
|
||||||
|
col, sdefault := params[0], ""
|
||||||
|
if len(params) > 1 {
|
||||||
|
sdefault = params[1]
|
||||||
|
if sdefault == "" {
|
||||||
|
sdefault = "''"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tC{col, "text", 0, false, false, sdefault}
|
||||||
|
}
|
||||||
|
createdAt := func(coll ...string) qgen.DBTableColumn {
|
||||||
|
var col string
|
||||||
|
if len(coll) > 0 {
|
||||||
|
col = coll[0]
|
||||||
|
}
|
||||||
|
if col == "" {
|
||||||
|
col = "createdAt"
|
||||||
|
}
|
||||||
|
return tC{col, "createdAt", 0, false, false, ""}
|
||||||
|
}
|
||||||
|
|
||||||
createTable("users", mysqlPre, mysqlCol,
|
createTable("users", mysqlPre, mysqlCol,
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"uid", "int", 0, false, true, ""},
|
tC{"uid", "int", 0, false, true, ""},
|
||||||
tC{"name", "varchar", 100, false, false, ""},
|
ccol("name", 100, ""),
|
||||||
tC{"password", "varchar", 100, false, false, ""},
|
ccol("password", 100, ""),
|
||||||
|
|
||||||
tC{"salt", "varchar", 80, false, false, "''"},
|
ccol("salt", 80, "''"),
|
||||||
tC{"group", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"group", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"active", "boolean", 0, false, false, "0"},
|
bcol("active", false),
|
||||||
tC{"is_super_admin", "boolean", 0, false, false, "0"},
|
bcol("is_super_admin", false),
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
createdAt(),
|
||||||
tC{"lastActiveAt", "datetime", 0, false, false, ""},
|
tC{"lastActiveAt", "datetime", 0, false, false, ""},
|
||||||
tC{"session", "varchar", 200, false, false, "''"},
|
ccol("session", 200, "''"),
|
||||||
//tC{"authToken", "varchar", 200, false, false, "''"},
|
//ccol("authToken", 200, "''"),
|
||||||
tC{"last_ip", "varchar", 200, false, false, "''"},
|
ccol("last_ip", 200, "''"),
|
||||||
|
tC{"profile_comments", "int", 0, false, false, "0"},
|
||||||
|
tC{"who_can_convo", "int", 0, false, false, "0"},
|
||||||
tC{"enable_embeds", "int", 0, false, false, "-1"},
|
tC{"enable_embeds", "int", 0, false, false, "-1"},
|
||||||
tC{"email", "varchar", 200, false, false, "''"},
|
ccol("email", 200, "''"),
|
||||||
tC{"avatar", "varchar", 100, false, false, "''"},
|
ccol("avatar", 100, "''"),
|
||||||
tC{"message", "text", 0, false, false, "''"},
|
text("message"),
|
||||||
|
|
||||||
// TODO: Drop these columns?
|
// TODO: Drop these columns?
|
||||||
tC{"url_prefix", "varchar", 20, false, false, "''"},
|
ccol("url_prefix", 20, "''"),
|
||||||
tC{"url_name", "varchar", 100, false, false, "''"},
|
ccol("url_name", 100, "''"),
|
||||||
//tC{"pub_key", "text", 0, false, false, "''"},
|
//text("pub_key"),
|
||||||
|
|
||||||
tC{"level", "smallint", 0, false, false, "0"},
|
tC{"level", "smallint", 0, false, false, "0"},
|
||||||
tC{"score", "int", 0, false, false, "0"},
|
tC{"score", "int", 0, false, false, "0"},
|
||||||
|
@ -63,27 +102,27 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
//tC{"penalty_count","int",0,false,false,"0"},
|
//tC{"penalty_count","int",0,false,false,"0"},
|
||||||
tC{"temp_group", "int", 0, false, false, "0"}, // For temporary groups, set this to zero when a temporary group isn't in effect
|
tC{"temp_group", "int", 0, false, false, "0"}, // For temporary groups, set this to zero when a temporary group isn't in effect
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"uid", "primary", "", false},
|
tK{"uid", "primary", "", false},
|
||||||
tblKey{"name", "unique", "", false},
|
tK{"name", "unique", "", false},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
createTable("users_groups", mysqlPre, mysqlCol,
|
createTable("users_groups", mysqlPre, mysqlCol,
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"gid", "int", 0, false, true, ""},
|
tC{"gid", "int", 0, false, true, ""},
|
||||||
tC{"name", "varchar", 100, false, false, ""},
|
ccol("name", 100, ""),
|
||||||
tC{"permissions", "text", 0, false, false, ""},
|
text("permissions"),
|
||||||
tC{"plugin_perms", "text", 0, false, false, ""},
|
text("plugin_perms"),
|
||||||
tC{"is_mod", "boolean", 0, false, false, "0"},
|
bcol("is_mod", false),
|
||||||
tC{"is_admin", "boolean", 0, false, false, "0"},
|
bcol("is_admin", false),
|
||||||
tC{"is_banned", "boolean", 0, false, false, "0"},
|
bcol("is_banned", false),
|
||||||
tC{"user_count", "int", 0, false, false, "0"}, // TODO: Implement this
|
tC{"user_count", "int", 0, false, false, "0"}, // TODO: Implement this
|
||||||
|
|
||||||
tC{"tag", "varchar", 50, false, false, "''"},
|
ccol("tag", 50, "''"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"gid", "primary", "", false},
|
tK{"gid", "primary", "", false},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -92,7 +131,7 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
tC{"pid", "int", 0, false, true, ""},
|
tC{"pid", "int", 0, false, true, ""},
|
||||||
tC{"from_gid", "int", 0, false, false, ""},
|
tC{"from_gid", "int", 0, false, false, ""},
|
||||||
tC{"to_gid", "int", 0, false, false, ""},
|
tC{"to_gid", "int", 0, false, false, ""},
|
||||||
tC{"two_way", "boolean", 0, false, false, "0"}, // If a user no longer meets the requirements for this promotion then they will be demoted if this flag is set
|
bcol("two_way", false), // If a user no longer meets the requirements for this promotion then they will be demoted if this flag is set
|
||||||
|
|
||||||
// Requirements
|
// Requirements
|
||||||
tC{"level", "int", 0, false, false, ""},
|
tC{"level", "int", 0, false, false, ""},
|
||||||
|
@ -100,8 +139,8 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
tC{"minTime", "int", 0, false, false, ""}, // How long someone needs to have been in their current group before being promoted
|
tC{"minTime", "int", 0, false, false, ""}, // How long someone needs to have been in their current group before being promoted
|
||||||
tC{"registeredFor", "int", 0, false, false, "0"}, // minutes
|
tC{"registeredFor", "int", 0, false, false, "0"}, // minutes
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"pid", "primary", "", false},
|
tK{"pid", "primary", "", false},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -122,15 +161,15 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
createTable("users_2fa_keys", mysqlPre, mysqlCol,
|
createTable("users_2fa_keys", mysqlPre, mysqlCol,
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"uid", "int", 0, false, false, ""},
|
tC{"uid", "int", 0, false, false, ""},
|
||||||
tC{"secret", "varchar", 100, false, false, ""},
|
ccol("secret", 100, ""),
|
||||||
tC{"scratch1", "varchar", 50, false, false, ""},
|
ccol("scratch1", 50, ""),
|
||||||
tC{"scratch2", "varchar", 50, false, false, ""},
|
ccol("scratch2", 50, ""),
|
||||||
tC{"scratch3", "varchar", 50, false, false, ""},
|
ccol("scratch3", 50, ""),
|
||||||
tC{"scratch4", "varchar", 50, false, false, ""},
|
ccol("scratch4", 50, ""),
|
||||||
tC{"scratch5", "varchar", 50, false, false, ""},
|
ccol("scratch5", 50, ""),
|
||||||
tC{"scratch6", "varchar", 50, false, false, ""},
|
ccol("scratch6", 50, ""),
|
||||||
tC{"scratch7", "varchar", 50, false, false, ""},
|
ccol("scratch7", 50, ""),
|
||||||
tC{"scratch8", "varchar", 50, false, false, ""},
|
ccol("scratch8", 50, ""),
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
tC{"createdAt", "createdAt", 0, false, false, ""},
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
|
@ -148,12 +187,12 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"uid","int",0,false,false,""},
|
tC{"uid","int",0,false,false,""},
|
||||||
tC{"element_id","int",0,false,false,""},
|
tC{"element_id","int",0,false,false,""},
|
||||||
tC{"element_type","varchar",50,false,false,""}, //forum, profile?, and social_group. Leave blank for global.
|
ccol("element_type",50,""), //forum, profile?, and social_group. Leave blank for global.
|
||||||
tC{"overrides","text",0,false,false,"{}"},
|
text("overrides","{}"),
|
||||||
|
|
||||||
tC{"mod_queue","boolean",0,false,false,"0"},
|
bcol("mod_queue",false),
|
||||||
tC{"shadow_ban","boolean",0,false,false,"0"},
|
bcol("shadow_ban",false),
|
||||||
tC{"no_avatar","boolean",0,false,false,"0"}, // Coming Soon. Should this be a perm override instead?
|
bcol("no_avatar",false), // Coming Soon. Should this be a perm override instead?
|
||||||
|
|
||||||
// Do we *really* need rate-limit penalty types? Are we going to be allowing bots or something?
|
// Do we *really* need rate-limit penalty types? Are we going to be allowing bots or something?
|
||||||
//tC{"posts_per_hour","int",0,false,false,"0"},
|
//tC{"posts_per_hour","int",0,false,false,"0"},
|
||||||
|
@ -163,7 +202,7 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
//tC{"last_hour","int",0,false,false,"0"}, // UNIX Time, as we don't need to do anything too fancy here. When an hour has elapsed since that time, reset the hourly penalty counters.
|
//tC{"last_hour","int",0,false,false,"0"}, // UNIX Time, as we don't need to do anything too fancy here. When an hour has elapsed since that time, reset the hourly penalty counters.
|
||||||
|
|
||||||
tC{"issued_by","int",0,false,false,""},
|
tC{"issued_by","int",0,false,false,""},
|
||||||
tC{"issued_at","createdAt",0,false,false,""},
|
createdAt("issued_at"),
|
||||||
tC{"expires_at","datetime",0,false,false,""},
|
tC{"expires_at","datetime",0,false,false,""},
|
||||||
}, nil,
|
}, nil,
|
||||||
)*/
|
)*/
|
||||||
|
@ -174,7 +213,7 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
tC{"set_group", "int", 0, false, false, ""},
|
tC{"set_group", "int", 0, false, false, ""},
|
||||||
|
|
||||||
tC{"issued_by", "int", 0, false, false, ""},
|
tC{"issued_by", "int", 0, false, false, ""},
|
||||||
tC{"issued_at", "createdAt", 0, false, false, ""},
|
createdAt("issued_at"),
|
||||||
tC{"revert_at", "datetime", 0, false, false, ""},
|
tC{"revert_at", "datetime", 0, false, false, ""},
|
||||||
tC{"temporary", "boolean", 0, false, false, ""}, // special case for permanent bans to do the necessary bookkeeping, might be removed in the future
|
tC{"temporary", "boolean", 0, false, false, ""}, // special case for permanent bans to do the necessary bookkeeping, might be removed in the future
|
||||||
},
|
},
|
||||||
|
@ -197,10 +236,10 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
// TODO: Add an autoincrement key?
|
// TODO: Add an autoincrement key?
|
||||||
createTable("emails", "", "",
|
createTable("emails", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"email", "varchar", 200, false, false, ""},
|
ccol("email", 200, ""),
|
||||||
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"validated", "boolean", 0, false, false, "0"},
|
bcol("validated", false),
|
||||||
tC{"token", "varchar", 200, false, false, "''"},
|
ccol("token", 200, "''"),
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -208,11 +247,11 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
/*
|
/*
|
||||||
createTable("email_domain_blacklist", "", "",
|
createTable("email_domain_blacklist", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"domain", "varchar", 200, false, false, ""},
|
ccol("domain", 200, ""),
|
||||||
tC{"gtld", "boolean", 0, false, false, "0"},
|
bcol("gtld", false),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"domain", "primary"},
|
tK{"domain", "primary"},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
*/
|
*/
|
||||||
|
@ -220,26 +259,26 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
// TODO: Implement password resets
|
// TODO: Implement password resets
|
||||||
createTable("password_resets", "", "",
|
createTable("password_resets", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"email", "varchar", 200, false, false, ""},
|
ccol("email", 200, ""),
|
||||||
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"validated", "varchar", 200, false, false, ""}, // Token given once the one-use token is consumed, used to prevent multiple people consuming the same one-use token
|
ccol("validated", 200, ""), // Token given once the one-use token is consumed, used to prevent multiple people consuming the same one-use token
|
||||||
tC{"token", "varchar", 200, false, false, ""},
|
ccol("token", 200, ""),
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
createdAt(),
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
createTable("forums", mysqlPre, mysqlCol,
|
createTable("forums", mysqlPre, mysqlCol,
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"fid", "int", 0, false, true, ""},
|
tC{"fid", "int", 0, false, true, ""},
|
||||||
tC{"name", "varchar", 100, false, false, ""},
|
ccol("name", 100, ""),
|
||||||
tC{"desc", "varchar", 200, false, false, ""},
|
ccol("desc", 200, ""),
|
||||||
tC{"tmpl", "varchar", 200, false, false, "''"},
|
ccol("tmpl", 200, "''"),
|
||||||
tC{"active", "boolean", 0, false, false, "1"},
|
bcol("active", true),
|
||||||
tC{"order", "int", 0, false, false, "0"},
|
tC{"order", "int", 0, false, false, "0"},
|
||||||
tC{"topicCount", "int", 0, false, false, "0"},
|
tC{"topicCount", "int", 0, false, false, "0"},
|
||||||
tC{"preset", "varchar", 100, false, false, "''"},
|
ccol("preset", 100, "''"),
|
||||||
tC{"parentID", "int", 0, false, false, "0"},
|
tC{"parentID", "int", 0, false, false, "0"},
|
||||||
tC{"parentType", "varchar", 50, false, false, "''"},
|
ccol("parentType", 50, "''"),
|
||||||
tC{"lastTopicID", "int", 0, false, false, "0"},
|
tC{"lastTopicID", "int", 0, false, false, "0"},
|
||||||
tC{"lastReplyerID", "int", 0, false, false, "0"},
|
tC{"lastReplyerID", "int", 0, false, false, "0"},
|
||||||
},
|
},
|
||||||
|
@ -252,8 +291,8 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"fid", "int", 0, false, false, ""},
|
tC{"fid", "int", 0, false, false, ""},
|
||||||
tC{"gid", "int", 0, false, false, ""},
|
tC{"gid", "int", 0, false, false, ""},
|
||||||
tC{"preset", "varchar", 100, false, false, "''"},
|
ccol("preset", 100, "''"),
|
||||||
tC{"permissions", "text", 0, false, false, ""},
|
text("permissions", "{}"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
// TODO: Test to see that the compound primary key works
|
// TODO: Test to see that the compound primary key works
|
||||||
|
@ -264,19 +303,19 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
createTable("topics", mysqlPre, mysqlCol,
|
createTable("topics", mysqlPre, mysqlCol,
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"tid", "int", 0, false, true, ""},
|
tC{"tid", "int", 0, false, true, ""},
|
||||||
tC{"title", "varchar", 100, false, false, ""}, // TODO: Increase the max length to 200?
|
ccol("title", 100, ""), // TODO: Increase the max length to 200?
|
||||||
tC{"content", "text", 0, false, false, ""},
|
text("content"),
|
||||||
tC{"parsed_content", "text", 0, false, false, ""},
|
text("parsed_content"),
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
createdAt(),
|
||||||
tC{"lastReplyAt", "datetime", 0, false, false, ""},
|
tC{"lastReplyAt", "datetime", 0, false, false, ""},
|
||||||
tC{"lastReplyBy", "int", 0, false, false, ""},
|
tC{"lastReplyBy", "int", 0, false, false, ""},
|
||||||
tC{"lastReplyID", "int", 0, false, false, "0"},
|
tC{"lastReplyID", "int", 0, false, false, "0"},
|
||||||
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"is_closed", "boolean", 0, false, false, "0"},
|
bcol("is_closed", false),
|
||||||
tC{"sticky", "boolean", 0, false, false, "0"},
|
bcol("sticky", false),
|
||||||
// TODO: Add an index for this
|
// TODO: Add an index for this
|
||||||
tC{"parentID", "int", 0, false, false, "2"},
|
tC{"parentID", "int", 0, false, false, "2"},
|
||||||
tC{"ip", "varchar", 200, false, false, "''"},
|
ccol("ip", 200, "''"),
|
||||||
tC{"postCount", "int", 0, false, false, "1"},
|
tC{"postCount", "int", 0, false, false, "1"},
|
||||||
tC{"likeCount", "int", 0, false, false, "0"},
|
tC{"likeCount", "int", 0, false, false, "0"},
|
||||||
tC{"attachCount", "int", 0, false, false, "0"},
|
tC{"attachCount", "int", 0, false, false, "0"},
|
||||||
|
@ -288,14 +327,14 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
// ? - A little hacky, maybe we could do something less likely to bite us with huge numbers of topics?
|
// ? - A little hacky, maybe we could do something less likely to bite us with huge numbers of topics?
|
||||||
// TODO: Add an index for this?
|
// TODO: Add an index for this?
|
||||||
//tC{"lastMonth", "datetime", 0, false, false, ""},
|
//tC{"lastMonth", "datetime", 0, false, false, ""},
|
||||||
tC{"css_class", "varchar", 100, false, false, "''"},
|
ccol("css_class", 100, "''"),
|
||||||
tC{"poll", "int", 0, false, false, "0"},
|
tC{"poll", "int", 0, false, false, "0"},
|
||||||
tC{"data", "varchar", 200, false, false, "''"},
|
ccol("data", 200, "''"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"tid", "primary", "", false},
|
tK{"tid", "primary", "", false},
|
||||||
tblKey{"title", "fulltext", "", false},
|
tK{"title", "fulltext", "", false},
|
||||||
tblKey{"content", "fulltext", "", false},
|
tK{"content", "fulltext", "", false},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -303,23 +342,23 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"rid", "int", 0, false, true, ""}, // TODO: Rename to replyID?
|
tC{"rid", "int", 0, false, true, ""}, // TODO: Rename to replyID?
|
||||||
tC{"tid", "int", 0, false, false, ""}, // TODO: Rename to topicID?
|
tC{"tid", "int", 0, false, false, ""}, // TODO: Rename to topicID?
|
||||||
tC{"content", "text", 0, false, false, ""},
|
text("content"),
|
||||||
tC{"parsed_content", "text", 0, false, false, ""},
|
text("parsed_content"),
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
createdAt(),
|
||||||
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"lastEdit", "int", 0, false, false, "0"},
|
tC{"lastEdit", "int", 0, false, false, "0"},
|
||||||
tC{"lastEditBy", "int", 0, false, false, "0"},
|
tC{"lastEditBy", "int", 0, false, false, "0"},
|
||||||
tC{"lastUpdated", "datetime", 0, false, false, ""},
|
tC{"lastUpdated", "datetime", 0, false, false, ""},
|
||||||
tC{"ip", "varchar", 200, false, false, "''"},
|
ccol("ip", 200, "''"),
|
||||||
tC{"likeCount", "int", 0, false, false, "0"},
|
tC{"likeCount", "int", 0, false, false, "0"},
|
||||||
tC{"attachCount", "int", 0, false, false, "0"},
|
tC{"attachCount", "int", 0, false, false, "0"},
|
||||||
tC{"words", "int", 0, false, false, "1"}, // ? - replies has a default of 1 and topics has 0? why?
|
tC{"words", "int", 0, false, false, "1"}, // ? - replies has a default of 1 and topics has 0? why?
|
||||||
tC{"actionType", "varchar", 20, false, false, "''"},
|
ccol("actionType", 20, "''"),
|
||||||
tC{"poll", "int", 0, false, false, "0"},
|
tC{"poll", "int", 0, false, false, "0"},
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"rid", "primary", "", false},
|
tK{"rid", "primary", "", false},
|
||||||
tblKey{"content", "fulltext", "", false},
|
tK{"content", "fulltext", "", false},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -327,12 +366,12 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"attachID", "int", 0, false, true, ""},
|
tC{"attachID", "int", 0, false, true, ""},
|
||||||
tC{"sectionID", "int", 0, false, false, "0"},
|
tC{"sectionID", "int", 0, false, false, "0"},
|
||||||
tC{"sectionTable", "varchar", 200, false, false, "forums"},
|
ccol("sectionTable", 200, "forums"),
|
||||||
tC{"originID", "int", 0, false, false, ""},
|
tC{"originID", "int", 0, false, false, ""},
|
||||||
tC{"originTable", "varchar", 200, false, false, "replies"},
|
ccol("originTable", 200, "replies"),
|
||||||
tC{"uploadedBy", "int", 0, false, false, ""}, // TODO; Make this a foreign key
|
tC{"uploadedBy", "int", 0, false, false, ""}, // TODO; Make this a foreign key
|
||||||
tC{"path", "varchar", 200, false, false, ""},
|
ccol("path", 200, ""),
|
||||||
tC{"extra", "varchar", 200, false, false, ""},
|
ccol("extra", 200, ""),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"attachID", "primary", "", false},
|
tblKey{"attachID", "primary", "", false},
|
||||||
|
@ -342,10 +381,10 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
createTable("revisions", mysqlPre, mysqlCol,
|
createTable("revisions", mysqlPre, mysqlCol,
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"reviseID", "int", 0, false, true, ""},
|
tC{"reviseID", "int", 0, false, true, ""},
|
||||||
tC{"content", "text", 0, false, false, ""},
|
text("content"),
|
||||||
tC{"contentID", "int", 0, false, false, ""},
|
tC{"contentID", "int", 0, false, false, ""},
|
||||||
tC{"contentType", "varchar", 100, false, false, "replies"},
|
ccol("contentType", 100, "replies"),
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
createdAt(),
|
||||||
// TODO: Add a createdBy column?
|
// TODO: Add a createdBy column?
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
|
@ -357,7 +396,7 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"pollID", "int", 0, false, true, ""},
|
tC{"pollID", "int", 0, false, true, ""},
|
||||||
tC{"parentID", "int", 0, false, false, "0"},
|
tC{"parentID", "int", 0, false, false, "0"},
|
||||||
tC{"parentTable", "varchar", 100, false, false, "topics"}, // topics, replies
|
ccol("parentTable", 100, "topics"), // topics, replies
|
||||||
tC{"type", "int", 0, false, false, "0"},
|
tC{"type", "int", 0, false, false, "0"},
|
||||||
tC{"options", "json", 0, false, false, ""},
|
tC{"options", "json", 0, false, false, ""},
|
||||||
tC{"votes", "int", 0, false, false, "0"},
|
tC{"votes", "int", 0, false, false, "0"},
|
||||||
|
@ -380,8 +419,8 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
tC{"pollID", "int", 0, false, false, ""},
|
tC{"pollID", "int", 0, false, false, ""},
|
||||||
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"option", "int", 0, false, false, "0"},
|
tC{"option", "int", 0, false, false, "0"},
|
||||||
tC{"castAt", "createdAt", 0, false, false, ""},
|
createdAt("castAt"),
|
||||||
tC{"ip", "varchar", 200, false, false, "''"},
|
ccol("ip", 200, "''"),
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -389,13 +428,13 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"rid", "int", 0, false, true, ""},
|
tC{"rid", "int", 0, false, true, ""},
|
||||||
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"content", "text", 0, false, false, ""},
|
text("content"),
|
||||||
tC{"parsed_content", "text", 0, false, false, ""},
|
text("parsed_content"),
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
createdAt(),
|
||||||
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"lastEdit", "int", 0, false, false, "0"},
|
tC{"lastEdit", "int", 0, false, false, "0"},
|
||||||
tC{"lastEditBy", "int", 0, false, false, "0"},
|
tC{"lastEditBy", "int", 0, false, false, "0"},
|
||||||
tC{"ip", "varchar", 200, false, false, "''"},
|
ccol("ip", 200, "''"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"rid", "primary", "", false},
|
tblKey{"rid", "primary", "", false},
|
||||||
|
@ -406,9 +445,9 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"weight", "tinyint", 0, false, false, "1"},
|
tC{"weight", "tinyint", 0, false, false, "1"},
|
||||||
tC{"targetItem", "int", 0, false, false, ""},
|
tC{"targetItem", "int", 0, false, false, ""},
|
||||||
tC{"targetType", "varchar", 50, false, false, "replies"},
|
ccol("targetType", 50, "replies"),
|
||||||
tC{"sentBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"sentBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
createdAt(),
|
||||||
tC{"recalc", "tinyint", 0, false, false, "0"},
|
tC{"recalc", "tinyint", 0, false, false, "0"},
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
@ -418,7 +457,7 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"cid", "int", 0, false, true, ""},
|
tC{"cid", "int", 0, false, true, ""},
|
||||||
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
createdAt(),
|
||||||
tC{"lastReplyAt", "datetime", 0, false, false, ""},
|
tC{"lastReplyAt", "datetime", 0, false, false, ""},
|
||||||
tC{"lastReplyBy", "int", 0, false, false, ""},
|
tC{"lastReplyBy", "int", 0, false, false, ""},
|
||||||
},
|
},
|
||||||
|
@ -432,8 +471,8 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
tC{"pid", "int", 0, false, true, ""},
|
tC{"pid", "int", 0, false, true, ""},
|
||||||
tC{"cid", "int", 0, false, false, ""},
|
tC{"cid", "int", 0, false, false, ""},
|
||||||
tC{"createdBy", "int", 0, false, false, ""},
|
tC{"createdBy", "int", 0, false, false, ""},
|
||||||
tC{"body", "varchar", 50, false, false, ""},
|
ccol("body", 50, ""),
|
||||||
tC{"post", "varchar", 50, false, false, "''"},
|
ccol("post", 50, "''"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"pid", "primary", "", false},
|
tblKey{"pid", "primary", "", false},
|
||||||
|
@ -482,35 +521,39 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
createTable("activity_stream", "", "",
|
createTable("activity_stream", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"asid", "int", 0, false, true, ""},
|
tC{"asid", "int", 0, false, true, ""},
|
||||||
tC{"actor", "int", 0, false, false, ""}, /* the one doing the act */ // TODO: Make this a foreign key
|
tC{"actor", "int", 0, false, false, ""}, /* the one doing the act */ // TODO: Make this a foreign key
|
||||||
tC{"targetUser", "int", 0, false, false, ""}, /* the user who created the item the actor is acting on, some items like forums may lack a targetUser field */
|
tC{"targetUser", "int", 0, false, false, ""}, /* the user who created the item the actor is acting on, some items like forums may lack a targetUser field */
|
||||||
tC{"event", "varchar", 50, false, false, ""}, /* mention, like, reply (as in the act of replying to an item, not the reply item type, you can "reply" to a forum by making a topic in it), friend_invite */
|
ccol("event", 50, ""), /* mention, like, reply (as in the act of replying to an item, not the reply item type, you can "reply" to a forum by making a topic in it), friend_invite */
|
||||||
tC{"elementType", "varchar", 50, false, false, ""}, /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */
|
ccol("elementType", 50, ""), /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */
|
||||||
tC{"elementID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */
|
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
// replacement for elementType
|
||||||
tC{"extra", "varchar", 200, false, false, "''"},
|
tC{"elementTable", "int", 0, false, false, "0"},
|
||||||
|
|
||||||
|
tC{"elementID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */
|
||||||
|
createdAt(),
|
||||||
|
ccol("extra", 200, "''"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"asid", "primary", "", false},
|
tK{"asid", "primary", "", false},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
createTable("activity_subscriptions", "", "",
|
createTable("activity_subscriptions", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"user", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
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 */
|
tC{"targetID", "int", 0, false, false, ""}, /* the ID of the element being acted upon */
|
||||||
tC{"targetType", "varchar", 50, false, false, ""}, /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */
|
ccol("targetType", 50, ""), /* topic, post (calling it post here to differentiate it from the 'reply' event), forum, user */
|
||||||
tC{"level", "int", 0, false, false, "0"}, /* 0: Mentions (aka the global default for any post), 1: Replies To You, 2: All Replies*/
|
tC{"level", "int", 0, false, false, "0"}, /* 0: Mentions (aka the global default for any post), 1: Replies To You, 2: All Replies*/
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
/* 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 */
|
/* 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 */
|
||||||
createTable("settings", "", "",
|
createTable("settings", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"name", "varchar", 180, false, false, ""},
|
ccol("name", 180, ""),
|
||||||
tC{"content", "varchar", 250, false, false, ""},
|
ccol("content", 250, ""),
|
||||||
tC{"type", "varchar", 50, false, false, ""},
|
ccol("type", 50, ""),
|
||||||
tC{"constraints", "varchar", 200, false, false, "''"},
|
ccol("constraints", 200, "''"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"name", "unique", "", false},
|
tblKey{"name", "unique", "", false},
|
||||||
|
@ -520,8 +563,8 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
createTable("word_filters", "", "",
|
createTable("word_filters", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"wfid", "int", 0, false, true, ""},
|
tC{"wfid", "int", 0, false, true, ""},
|
||||||
tC{"find", "varchar", 200, false, false, ""},
|
ccol("find", 200, ""),
|
||||||
tC{"replacement", "varchar", 200, false, false, ""},
|
ccol("replacement", 200, ""),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"wfid", "primary", "", false},
|
tblKey{"wfid", "primary", "", false},
|
||||||
|
@ -530,9 +573,9 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
|
|
||||||
createTable("plugins", "", "",
|
createTable("plugins", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"uname", "varchar", 180, false, false, ""},
|
ccol("uname", 180, ""),
|
||||||
tC{"active", "boolean", 0, false, false, "0"},
|
bcol("active", false),
|
||||||
tC{"installed", "boolean", 0, false, false, "0"},
|
bcol("installed", false),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"uname", "unique", "", false},
|
tblKey{"uname", "unique", "", false},
|
||||||
|
@ -541,9 +584,9 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
|
|
||||||
createTable("themes", "", "",
|
createTable("themes", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"uname", "varchar", 180, false, false, ""},
|
ccol("uname", 180, ""),
|
||||||
tC{"default", "boolean", 0, false, false, "0"},
|
bcol("default", false),
|
||||||
//tC{"profileUserVars", "text", 0, false, false, "''"},
|
//text("profileUserVars"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"uname", "unique", "", false},
|
tblKey{"uname", "unique", "", false},
|
||||||
|
@ -554,11 +597,11 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"wid", "int", 0, false, true, ""},
|
tC{"wid", "int", 0, false, true, ""},
|
||||||
tC{"position", "int", 0, false, false, ""},
|
tC{"position", "int", 0, false, false, ""},
|
||||||
tC{"side", "varchar", 100, false, false, ""},
|
ccol("side", 100, ""),
|
||||||
tC{"type", "varchar", 100, false, false, ""},
|
ccol("type", 100, ""),
|
||||||
tC{"active", "boolean", 0, false, false, "0"},
|
bcol("active", false),
|
||||||
tC{"location", "varchar", 100, false, false, ""},
|
ccol("location", 100, ""),
|
||||||
tC{"data", "text", 0, false, false, "''"},
|
text("data"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"wid", "primary", "", false},
|
tblKey{"wid", "primary", "", false},
|
||||||
|
@ -578,51 +621,51 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"miid", "int", 0, false, true, ""},
|
tC{"miid", "int", 0, false, true, ""},
|
||||||
tC{"mid", "int", 0, false, false, ""},
|
tC{"mid", "int", 0, false, false, ""},
|
||||||
tC{"name", "varchar", 200, false, false, "''"},
|
ccol("name", 200, "''"),
|
||||||
tC{"htmlID", "varchar", 200, false, false, "''"},
|
ccol("htmlID", 200, "''"),
|
||||||
tC{"cssClass", "varchar", 200, false, false, "''"},
|
ccol("cssClass", 200, "''"),
|
||||||
tC{"position", "varchar", 100, false, false, ""},
|
ccol("position", 100, ""),
|
||||||
tC{"path", "varchar", 200, false, false, "''"},
|
ccol("path", 200, "''"),
|
||||||
tC{"aria", "varchar", 200, false, false, "''"},
|
ccol("aria", 200, "''"),
|
||||||
tC{"tooltip", "varchar", 200, false, false, "''"},
|
ccol("tooltip", 200, "''"),
|
||||||
tC{"tmplName", "varchar", 200, false, false, "''"},
|
ccol("tmplName", 200, "''"),
|
||||||
tC{"order", "int", 0, false, false, "0"},
|
tC{"order", "int", 0, false, false, "0"},
|
||||||
|
|
||||||
tC{"guestOnly", "boolean", 0, false, false, "0"},
|
bcol("guestOnly", false),
|
||||||
tC{"memberOnly", "boolean", 0, false, false, "0"},
|
bcol("memberOnly", false),
|
||||||
tC{"staffOnly", "boolean", 0, false, false, "0"},
|
bcol("staffOnly", false),
|
||||||
tC{"adminOnly", "boolean", 0, false, false, "0"},
|
bcol("adminOnly", false),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"miid", "primary", "", false},
|
tK{"miid", "primary", "", false},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
createTable("pages", mysqlPre, mysqlCol,
|
createTable("pages", mysqlPre, mysqlCol,
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"pid", "int", 0, false, true, ""},
|
tC{"pid", "int", 0, false, true, ""},
|
||||||
//tC{"path", "varchar", 200, false, false, ""},
|
//ccol("path", 200, ""),
|
||||||
tC{"name", "varchar", 200, false, false, ""},
|
ccol("name", 200, ""),
|
||||||
tC{"title", "varchar", 200, false, false, ""},
|
ccol("title", 200, ""),
|
||||||
tC{"body", "text", 0, false, false, ""},
|
text("body"),
|
||||||
// TODO: Make this a table?
|
// TODO: Make this a table?
|
||||||
tC{"allowedGroups", "text", 0, false, false, ""},
|
text("allowedGroups"),
|
||||||
tC{"menuID", "int", 0, false, false, "-1"}, // simple sidebar menu
|
tC{"menuID", "int", 0, false, false, "-1"}, // simple sidebar menu
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"pid", "primary", "", false},
|
tK{"pid", "primary", "", false},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
createTable("registration_logs", "", "",
|
createTable("registration_logs", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"rlid", "int", 0, false, true, ""},
|
tC{"rlid", "int", 0, false, true, ""},
|
||||||
tC{"username", "varchar", 100, false, false, ""},
|
ccol("username", 100, ""),
|
||||||
tC{"email", "varchar", 100, false, false, ""},
|
tC{"email", "varchar", 100, false, false, ""},
|
||||||
tC{"failureReason", "varchar", 100, false, false, ""},
|
ccol("failureReason", 100, ""),
|
||||||
tC{"success", "bool", 0, false, false, "0"}, // Did this attempt succeed?
|
bcol("success", false), // Did this attempt succeed?
|
||||||
tC{"ipaddress", "varchar", 200, false, false, ""},
|
ccol("ipaddress", 200, ""),
|
||||||
tC{"doneAt", "createdAt", 0, false, false, ""},
|
createdAt("doneAt"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"rlid", "primary", "", false},
|
tblKey{"rlid", "primary", "", false},
|
||||||
|
@ -633,9 +676,9 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"lid", "int", 0, false, true, ""},
|
tC{"lid", "int", 0, false, true, ""},
|
||||||
tC{"uid", "int", 0, false, false, ""},
|
tC{"uid", "int", 0, false, false, ""},
|
||||||
tC{"success", "bool", 0, false, false, "0"}, // Did this attempt succeed?
|
bcol("success", false), // Did this attempt succeed?
|
||||||
tC{"ipaddress", "varchar", 200, false, false, ""},
|
ccol("ipaddress", 200, ""),
|
||||||
tC{"doneAt", "createdAt", 0, false, false, ""},
|
createdAt("doneAt"),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tblKey{
|
||||||
tblKey{"lid", "primary", "", false},
|
tblKey{"lid", "primary", "", false},
|
||||||
|
@ -644,25 +687,25 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
|
|
||||||
createTable("moderation_logs", "", "",
|
createTable("moderation_logs", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"action", "varchar", 100, false, false, ""},
|
ccol("action", 100, ""),
|
||||||
tC{"elementID", "int", 0, false, false, ""},
|
tC{"elementID", "int", 0, false, false, ""},
|
||||||
tC{"elementType", "varchar", 100, false, false, ""},
|
ccol("elementType", 100, ""),
|
||||||
tC{"ipaddress", "varchar", 200, false, false, ""},
|
ccol("ipaddress", 200, ""),
|
||||||
tC{"actorID", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"actorID", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"doneAt", "datetime", 0, false, false, ""},
|
tC{"doneAt", "datetime", 0, false, false, ""},
|
||||||
tC{"extra", "text", 0, false, false, ""},
|
text("extra"),
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
createTable("administration_logs", "", "",
|
createTable("administration_logs", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"action", "varchar", 100, false, false, ""},
|
ccol("action", 100, ""),
|
||||||
tC{"elementID", "int", 0, false, false, ""},
|
tC{"elementID", "int", 0, false, false, ""},
|
||||||
tC{"elementType", "varchar", 100, false, false, ""},
|
ccol("elementType", 100, ""),
|
||||||
tC{"ipaddress", "varchar", 200, false, false, ""},
|
ccol("ipaddress", 200, ""),
|
||||||
tC{"actorID", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"actorID", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"doneAt", "datetime", 0, false, false, ""},
|
tC{"doneAt", "datetime", 0, false, false, ""},
|
||||||
tC{"extra", "text", 0, false, false, ""},
|
text("extra"),
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -671,7 +714,7 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
tC{"count", "int", 0, false, false, "0"},
|
tC{"count", "int", 0, false, false, "0"},
|
||||||
tC{"avg", "int", 0, false, false, "0"},
|
tC{"avg", "int", 0, false, false, "0"},
|
||||||
tC{"createdAt", "datetime", 0, false, false, ""},
|
tC{"createdAt", "datetime", 0, false, false, ""},
|
||||||
tC{"route", "varchar", 200, false, false, ""}, // todo: set a default empty here
|
ccol("route", 200, ""), // TODO: set a default empty here
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -679,8 +722,8 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"count", "int", 0, false, false, "0"},
|
tC{"count", "int", 0, false, false, "0"},
|
||||||
tC{"createdAt", "datetime", 0, false, false, ""},
|
tC{"createdAt", "datetime", 0, false, false, ""},
|
||||||
tC{"browser", "varchar", 200, false, false, ""}, // googlebot, firefox, opera, etc.
|
ccol("browser", 200, ""), // googlebot, firefox, opera, etc.
|
||||||
//tC{"version","varchar",0,false,false,""}, // the version of the browser or bot
|
//ccol("version",0,""), // the version of the browser or bot
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -688,7 +731,7 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"count", "int", 0, false, false, "0"},
|
tC{"count", "int", 0, false, false, "0"},
|
||||||
tC{"createdAt", "datetime", 0, false, false, ""},
|
tC{"createdAt", "datetime", 0, false, false, ""},
|
||||||
tC{"system", "varchar", 200, false, false, ""}, // windows, android, unknown, etc.
|
ccol("system", 200, ""), // windows, android, unknown, etc.
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -696,7 +739,7 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"count", "int", 0, false, false, "0"},
|
tC{"count", "int", 0, false, false, "0"},
|
||||||
tC{"createdAt", "datetime", 0, false, false, ""},
|
tC{"createdAt", "datetime", 0, false, false, ""},
|
||||||
tC{"lang", "varchar", 200, false, false, ""}, // en, ru, etc.
|
ccol("lang", 200, ""), // en, ru, etc.
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -704,7 +747,7 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"count", "int", 0, false, false, "0"},
|
tC{"count", "int", 0, false, false, "0"},
|
||||||
tC{"createdAt", "datetime", 0, false, false, ""},
|
tC{"createdAt", "datetime", 0, false, false, ""},
|
||||||
tC{"domain", "varchar", 200, false, false, ""},
|
ccol("domain", 200, ""),
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -764,18 +807,19 @@ func createTables2(a qgen.Adapter, f func(table, charset, collation string, colu
|
||||||
|
|
||||||
createTable("meta", "", "",
|
createTable("meta", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"name", "varchar", 200, false, false, ""},
|
ccol("name", 200, ""),
|
||||||
tC{"value", "varchar", 200, false, false, ""},
|
ccol("value", 200, ""),
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
/*createTable("tables", mysqlPre, mysqlCol,
|
/*createTable("tables", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"id", "int", 0, false, true, ""},
|
tC{"id", "int", 0, false, true, ""},
|
||||||
tC{"name", "varchar", 200, false, false, ""},
|
ccol("name", 200, ""),
|
||||||
},
|
},
|
||||||
[]tblKey{
|
[]tK{
|
||||||
tblKey{"id", "primary", "", false},
|
tK{"id", "primary", "", false},
|
||||||
|
tK{"name", "unique", "", false},
|
||||||
},
|
},
|
||||||
)*/
|
)*/
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ func NewDefaultAuth() (*DefaultAuth, error) {
|
||||||
// Authenticate checks if a specific username and password is valid and returns the UID for the corresponding user, if so. Otherwise, a user safe error.
|
// Authenticate checks if a specific username and password is valid and returns the UID for the corresponding user, if so. Otherwise, a user safe error.
|
||||||
// IF MFA is enabled, then pass it back a flag telling the caller that authentication isn't complete yet
|
// IF MFA is enabled, then pass it back a flag telling the caller that authentication isn't complete yet
|
||||||
// TODO: Find a better way of handling errors we don't want to reach the user
|
// TODO: Find a better way of handling errors we don't want to reach the user
|
||||||
func (auth *DefaultAuth) Authenticate(name string, password string) (uid int, err error, requiresExtraAuth bool) {
|
func (auth *DefaultAuth) Authenticate(name, password string) (uid int, err error, requiresExtraAuth bool) {
|
||||||
var realPassword, salt string
|
var realPassword, salt string
|
||||||
err = auth.login.QueryRow(name).Scan(&uid, &realPassword, &salt)
|
err = auth.login.QueryRow(name).Scan(&uid, &realPassword, &salt)
|
||||||
if err == ErrNoRows {
|
if err == ErrNoRows {
|
||||||
|
@ -211,7 +211,7 @@ func (auth *DefaultAuth) SetCookies(w http.ResponseWriter, uid int, session stri
|
||||||
|
|
||||||
// TODO: Set the cookie domain
|
// TODO: Set the cookie domain
|
||||||
// SetProvisionalCookies sets the two cookies required for guests to be recognised as having passed the initial login but not having passed the additional checks (e.g. multi-factor authentication)
|
// SetProvisionalCookies sets the two cookies required for guests to be recognised as having passed the initial login but not having passed the additional checks (e.g. multi-factor authentication)
|
||||||
func (auth *DefaultAuth) SetProvisionalCookies(w http.ResponseWriter, uid int, provSession string, signedSession string) {
|
func (auth *DefaultAuth) SetProvisionalCookies(w http.ResponseWriter, uid int, provSession, signedSession string) {
|
||||||
cookie := http.Cookie{Name: "uid", Value: strconv.Itoa(uid), Path: "/", MaxAge: int(Year)}
|
cookie := http.Cookie{Name: "uid", Value: strconv.Itoa(uid), Path: "/", MaxAge: int(Year)}
|
||||||
setCookie(w, &cookie, "lax")
|
setCookie(w, &cookie, "lax")
|
||||||
cookie = http.Cookie{Name: "provSession", Value: provSession, Path: "/", MaxAge: int(Year)}
|
cookie = http.Cookie{Name: "provSession", Value: provSession, Path: "/", MaxAge: int(Year)}
|
||||||
|
@ -282,7 +282,7 @@ func (auth *DefaultAuth) CreateSession(uid int) (session string, err error) {
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (auth *DefaultAuth) CreateProvisionalSession(uid int) (provSession string, signedSession string, err error) {
|
func (auth *DefaultAuth) CreateProvisionalSession(uid int) (provSession, signedSession string, err error) {
|
||||||
provSession, err = GenerateSafeString(SessionLength)
|
provSession, err = GenerateSafeString(SessionLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
|
|
|
@ -232,6 +232,7 @@ type ProfilePage struct {
|
||||||
Blocked bool
|
Blocked bool
|
||||||
CanMessage bool
|
CanMessage bool
|
||||||
CanComment bool
|
CanComment bool
|
||||||
|
ShowComments bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateTopicPage struct {
|
type CreateTopicPage struct {
|
||||||
|
@ -249,7 +250,7 @@ type IPSearchPage struct {
|
||||||
type RegisterPage struct {
|
type RegisterPage struct {
|
||||||
*Header
|
*Header
|
||||||
RequireEmail bool
|
RequireEmail bool
|
||||||
Token string
|
Token string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Account struct {
|
type Account struct {
|
||||||
|
@ -278,8 +279,8 @@ type AccountBlocksPage struct {
|
||||||
|
|
||||||
type AccountPrivacyPage struct {
|
type AccountPrivacyPage struct {
|
||||||
*Header
|
*Header
|
||||||
ProfileComments bool
|
ProfileComments int
|
||||||
ReceiveConvos bool
|
ReceiveConvos int
|
||||||
EnableEmbeds bool
|
EnableEmbeds bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,14 +95,14 @@ var Template_account_handle = genIntTmpl("account")
|
||||||
|
|
||||||
func tmplInitUsers() (*User, *User, *User) {
|
func tmplInitUsers() (*User, *User, *User) {
|
||||||
avatar, microAvatar := BuildAvatar(62, "")
|
avatar, microAvatar := BuildAvatar(62, "")
|
||||||
u := 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, StartTime, "0.0.0.0.0", 0, 0, nil}
|
u := 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, StartTime, "0.0.0.0.0", 0, 0, nil, UserPrivacy{}}
|
||||||
|
|
||||||
// TODO: Do a more accurate level calculation for this?
|
// TODO: Do a more accurate level calculation for this?
|
||||||
avatar, microAvatar = BuildAvatar(1, "")
|
avatar, microAvatar = BuildAvatar(1, "")
|
||||||
u2 := 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, StartTime, "127.0.0.1", 0, 0, nil}
|
u2 := 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, StartTime, "127.0.0.1", 0, 0, nil, UserPrivacy{}}
|
||||||
|
|
||||||
avatar, microAvatar = BuildAvatar(2, "")
|
avatar, microAvatar = BuildAvatar(2, "")
|
||||||
u3 := 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, StartTime, "::1", 0, 0, nil}
|
u3 := 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, StartTime, "::1", 0, 0, nil, UserPrivacy{}}
|
||||||
return &u, &u2, &u3
|
return &u, &u2, &u3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ppage := ProfilePage{htitle("User 526"), replyList, *user, 0, 0, false, false, false} // TODO: Use the score from user to generate the currentScore and nextScore
|
ppage := ProfilePage{htitle("User 526"), replyList, *user, 0, 0, false, false, false, false} // TODO: Use the score from user to generate the currentScore and nextScore
|
||||||
t.Add("profile", "c.ProfilePage", ppage)
|
t.Add("profile", "c.ProfilePage", ppage)
|
||||||
|
|
||||||
var topicsList []*TopicsRow
|
var topicsList []*TopicsRow
|
||||||
|
@ -349,7 +349,7 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
|
||||||
}
|
}
|
||||||
|
|
||||||
t.AddStd("login", "c.Page", Page{htitle("Login Page"), tList, nil})
|
t.AddStd("login", "c.Page", Page{htitle("Login Page"), tList, nil})
|
||||||
t.AddStd("register", "c.RegisterPage", RegisterPage{htitle("Registration Page"), false,""})
|
t.AddStd("register", "c.RegisterPage", RegisterPage{htitle("Registration Page"), false, ""})
|
||||||
t.AddStd("error", "c.ErrorPage", ErrorPage{htitle("Error"), "A problem has occurred in the system."})
|
t.AddStd("error", "c.ErrorPage", ErrorPage{htitle("Error"), "A problem has occurred in the system."})
|
||||||
|
|
||||||
ipSearchPage := IPSearchPage{htitle("IP Search"), map[int]*User{1: user2}, "::1"}
|
ipSearchPage := IPSearchPage{htitle("IP Search"), map[int]*User{1: user2}, "::1"}
|
||||||
|
|
|
@ -62,6 +62,12 @@ type User struct {
|
||||||
TempGroup int
|
TempGroup int
|
||||||
|
|
||||||
ParseSettings *ParseSettings
|
ParseSettings *ParseSettings
|
||||||
|
Privacy UserPrivacy
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserPrivacy struct {
|
||||||
|
ShowComments int // 0 = default, 1 = public, 2 = registered, 3 = friends, 4 = mods / self
|
||||||
|
AllowMessage int // 0 = default, 1 = registered, 2 = friends, 3 = mods / self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) WebSockets() *WsJSONUser {
|
func (u *User) WebSockets() *WsJSONUser {
|
||||||
|
@ -191,7 +197,7 @@ func init() {
|
||||||
decLiked: acc.Update(u).Set("liked=liked-?").Where(w).Prepare(),
|
decLiked: acc.Update(u).Set("liked=liked-?").Where(w).Prepare(),
|
||||||
//recalcLastLiked: acc...
|
//recalcLastLiked: acc...
|
||||||
updateLastIP: acc.SimpleUpdate(u, "last_ip=?", w),
|
updateLastIP: acc.SimpleUpdate(u, "last_ip=?", w),
|
||||||
updatePrivacy: acc.Update(u).Set("enable_embeds=?").Where(w).Prepare(),
|
updatePrivacy: acc.Update(u).Set("profile_comments=?,enable_embeds=?").Where(w).Prepare(),
|
||||||
|
|
||||||
setPassword: acc.Update(u).Set("password=?,salt=?").Where(w).Prepare(),
|
setPassword: acc.Update(u).Set("password=?,salt=?").Where(w).Prepare(),
|
||||||
|
|
||||||
|
@ -211,6 +217,10 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) Init() {
|
func (u *User) Init() {
|
||||||
|
// TODO: Let admins configure the minimum default?
|
||||||
|
if u.Privacy.ShowComments < 1 {
|
||||||
|
u.Privacy.ShowComments = 1
|
||||||
|
}
|
||||||
u.Avatar, u.MicroAvatar = BuildAvatar(u.ID, u.RawAvatar)
|
u.Avatar, u.MicroAvatar = BuildAvatar(u.ID, u.RawAvatar)
|
||||||
u.Link = BuildProfileURL(NameToSlug(u.Name), u.ID)
|
u.Link = BuildProfileURL(NameToSlug(u.Name), u.ID)
|
||||||
u.Tag = Groups.DirtyGet(u.Group).Tag
|
u.Tag = Groups.DirtyGet(u.Group).Tag
|
||||||
|
@ -554,12 +564,27 @@ func (u *User) UpdateIP(ip string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) UpdatePrivacy(enableEmbeds int) error {
|
//var ErrMalformedInteger = errors.New("malformed integer")
|
||||||
_, err := userStmts.updatePrivacy.Exec(enableEmbeds, u.ID)
|
var ErrProfileCommentsOutOfBounds = errors.New("profile_comments must be an integer between -1 and 4")
|
||||||
|
var ErrEnableEmbedsOutOfBounds = errors.New("enable_embeds must be -1, 0 or 1")
|
||||||
|
|
||||||
|
/*func (u *User) UpdatePrivacyS(sProfileComments, sEnableEmbeds string) error {
|
||||||
|
|
||||||
|
return u.UpdatePrivacy(profileComments, enableEmbeds)
|
||||||
|
}*/
|
||||||
|
|
||||||
|
func (u *User) UpdatePrivacy(profileComments, enableEmbeds int) error {
|
||||||
|
if profileComments < -1 || profileComments > 4 {
|
||||||
|
return ErrProfileCommentsOutOfBounds
|
||||||
|
}
|
||||||
|
if enableEmbeds < -1 || enableEmbeds > 1 {
|
||||||
|
return ErrEnableEmbedsOutOfBounds
|
||||||
|
}
|
||||||
|
_, e := userStmts.updatePrivacy.Exec(profileComments, enableEmbeds, u.ID)
|
||||||
if uc := Users.GetCache(); uc != nil {
|
if uc := Users.GetCache(); uc != nil {
|
||||||
uc.Remove(u.ID)
|
uc.Remove(u.ID)
|
||||||
}
|
}
|
||||||
return err
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) Update(name, email string, group int) (err error) {
|
func (u *User) Update(name, email string, group int) (err error) {
|
||||||
|
@ -790,3 +815,17 @@ func BuildProfileURL(slug string, uid int) string {
|
||||||
}
|
}
|
||||||
return "/user/" + slug + "." + strconv.Itoa(uid)
|
return "/user/" + slug + "." + strconv.Itoa(uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BuildProfileURLSb(sb *strings.Builder, slug string, uid int) {
|
||||||
|
if slug == "" || !Config.BuildSlugs {
|
||||||
|
sb.Grow(6 + 1)
|
||||||
|
sb.WriteString("/user/")
|
||||||
|
sb.WriteString(strconv.Itoa(uid))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sb.Grow(7 + 1 + len(slug))
|
||||||
|
sb.WriteString("/user/")
|
||||||
|
sb.WriteString(slug)
|
||||||
|
sb.WriteRune('.')
|
||||||
|
sb.WriteString(strconv.Itoa(uid))
|
||||||
|
}
|
||||||
|
|
|
@ -54,16 +54,16 @@ func NewDefaultUserStore(cache UserCache) (*DefaultUserStore, error) {
|
||||||
cache = NewNullUserCache()
|
cache = NewNullUserCache()
|
||||||
}
|
}
|
||||||
u := "users"
|
u := "users"
|
||||||
allCols := "uid,name,group,active,is_super_admin,session,email,avatar,message,level,score,posts,liked,last_ip,temp_group,createdAt,enable_embeds"
|
allCols := "uid,name,group,active,is_super_admin,session,email,avatar,message,level,score,posts,liked,last_ip,temp_group,createdAt,enable_embeds,profile_comments,who_can_convo"
|
||||||
// TODO: Add an admin version of registerStmt with more flexibility?
|
// TODO: Add an admin version of registerStmt with more flexibility?
|
||||||
return &DefaultUserStore{
|
return &DefaultUserStore{
|
||||||
cache: cache,
|
cache: cache,
|
||||||
get: acc.Select(u).Columns("name, group, active, is_super_admin, session, email, avatar, message, level, score, posts, liked, last_ip, temp_group, createdAt, enable_embeds").Where("uid=?").Prepare(),
|
get: acc.Select(u).Columns("name,group,active,is_super_admin,session,email,avatar,message,level,score,posts,liked,last_ip,temp_group,createdAt,enable_embeds,profile_comments,who_can_convo").Where("uid=?").Prepare(),
|
||||||
getByName: acc.Select(u).Columns(allCols).Where("name=?").Prepare(),
|
getByName: acc.Select(u).Columns(allCols).Where("name=?").Prepare(),
|
||||||
getOffset: acc.Select(u).Columns(allCols).Orderby("uid ASC").Limit("?,?").Prepare(),
|
getOffset: acc.Select(u).Columns(allCols).Orderby("uid ASC").Limit("?,?").Prepare(),
|
||||||
getAll: acc.Select(u).Columns(allCols).Prepare(),
|
getAll: acc.Select(u).Columns(allCols).Prepare(),
|
||||||
exists: acc.Exists(u, "uid").Prepare(),
|
exists: acc.Exists(u, "uid").Prepare(),
|
||||||
register: acc.Insert(u).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
|
register: acc.Insert(u).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
|
||||||
nameExists: acc.Exists(u, "name").Prepare(),
|
nameExists: acc.Exists(u, "name").Prepare(),
|
||||||
count: acc.Count(u).Prepare(),
|
count: acc.Count(u).Prepare(),
|
||||||
}, acc.FirstError()
|
}, acc.FirstError()
|
||||||
|
@ -93,16 +93,7 @@ func (s *DefaultUserStore) Get(id int) (*User, error) {
|
||||||
|
|
||||||
u = &User{ID: id, Loggedin: true}
|
u = &User{ID: id, Loggedin: true}
|
||||||
var embeds int
|
var embeds int
|
||||||
err = s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds)
|
err = s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds, &u.Privacy.ShowComments, &u.Privacy.AllowMessage)
|
||||||
/*if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if embeds != -1 {
|
|
||||||
u.ParseSettings = DefaultParseSettings.CopyPtr()
|
|
||||||
u.ParseSettings.NoEmbed = embeds == 0
|
|
||||||
}
|
|
||||||
u.Init()
|
|
||||||
s.cache.Set(u)*/
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if embeds != -1 {
|
if embeds != -1 {
|
||||||
u.ParseSettings = DefaultParseSettings.CopyPtr()
|
u.ParseSettings = DefaultParseSettings.CopyPtr()
|
||||||
|
@ -122,7 +113,7 @@ func (s *DefaultUserStore) Getn(id int) *User {
|
||||||
|
|
||||||
u = &User{ID: id, Loggedin: true}
|
u = &User{ID: id, Loggedin: true}
|
||||||
var embeds int
|
var embeds int
|
||||||
err := s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds)
|
err := s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds, &u.Privacy.ShowComments, &u.Privacy.AllowMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -140,7 +131,7 @@ func (s *DefaultUserStore) Getn(id int) *User {
|
||||||
func (s *DefaultUserStore) GetByName(name string) (*User, error) {
|
func (s *DefaultUserStore) GetByName(name string) (*User, error) {
|
||||||
u := &User{Loggedin: true}
|
u := &User{Loggedin: true}
|
||||||
var embeds int
|
var embeds int
|
||||||
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.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds)
|
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.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds, &u.Privacy.ShowComments, &u.Privacy.AllowMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -165,7 +156,7 @@ func (s *DefaultUserStore) GetOffset(offset, perPage int) (users []*User, err er
|
||||||
var embeds int
|
var embeds int
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
u := &User{Loggedin: true}
|
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.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds)
|
err := rows.Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds, &u.Privacy.ShowComments, &u.Privacy.AllowMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -180,24 +171,24 @@ func (s *DefaultUserStore) GetOffset(offset, perPage int) (users []*User, err er
|
||||||
return users, rows.Err()
|
return users, rows.Err()
|
||||||
}
|
}
|
||||||
func (s *DefaultUserStore) Each(f func(*User) error) error {
|
func (s *DefaultUserStore) Each(f func(*User) error) error {
|
||||||
rows, err := s.getAll.Query()
|
rows, e := s.getAll.Query()
|
||||||
if err != nil {
|
if e != nil {
|
||||||
return err
|
return e
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var embeds int
|
var embeds int
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
u := new(User)
|
u := new(User)
|
||||||
if err := rows.Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds); err != nil {
|
if e := rows.Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds, &u.Privacy.ShowComments, &u.Privacy.AllowMessage); e != nil {
|
||||||
return err
|
return e
|
||||||
}
|
}
|
||||||
if embeds != -1 {
|
if embeds != -1 {
|
||||||
u.ParseSettings = DefaultParseSettings.CopyPtr()
|
u.ParseSettings = DefaultParseSettings.CopyPtr()
|
||||||
u.ParseSettings.NoEmbed = embeds == 0
|
u.ParseSettings.NoEmbed = embeds == 0
|
||||||
}
|
}
|
||||||
u.Init()
|
u.Init()
|
||||||
if err := f(u); err != nil {
|
if e := f(u); e != nil {
|
||||||
return err
|
return e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rows.Err()
|
return rows.Err()
|
||||||
|
@ -246,7 +237,7 @@ func (s *DefaultUserStore) BulkGetMap(ids []int) (list map[int]*User, err error)
|
||||||
}
|
}
|
||||||
q = q[0 : len(q)-1]
|
q = q[0 : len(q)-1]
|
||||||
|
|
||||||
rows, err := qgen.NewAcc().Select("users").Columns("uid,name,group,active,is_super_admin,session,email,avatar,message,level,score,posts,liked,last_ip,temp_group,createdAt,enable_embeds").Where("uid IN(" + q + ")").Query(idList...)
|
rows, err := qgen.NewAcc().Select("users").Columns("uid,name,group,active,is_super_admin,session,email,avatar,message,level,score,posts,liked,last_ip,temp_group,createdAt,enable_embeds,profile_comments,who_can_convo").Where("uid IN(" + q + ")").Query(idList...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return list, err
|
return list, err
|
||||||
}
|
}
|
||||||
|
@ -255,7 +246,7 @@ func (s *DefaultUserStore) BulkGetMap(ids []int) (list map[int]*User, err error)
|
||||||
var embeds int
|
var embeds int
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
u := &User{Loggedin: true}
|
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.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds)
|
err := rows.Scan(&u.ID, &u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds, &u.Privacy.ShowComments, &u.Privacy.AllowMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return list, err
|
return list, err
|
||||||
}
|
}
|
||||||
|
@ -292,7 +283,7 @@ func (s *DefaultUserStore) BulkGetMap(ids []int) (list map[int]*User, err error)
|
||||||
func (s *DefaultUserStore) BypassGet(id int) (*User, error) {
|
func (s *DefaultUserStore) BypassGet(id int) (*User, error) {
|
||||||
u := &User{ID: id, Loggedin: true}
|
u := &User{ID: id, Loggedin: true}
|
||||||
var embeds int
|
var embeds int
|
||||||
err := s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds)
|
err := s.get.QueryRow(id).Scan(&u.Name, &u.Group, &u.Active, &u.IsSuperAdmin, &u.Session, &u.Email, &u.RawAvatar, &u.Message, &u.Level, &u.Score, &u.Posts, &u.Liked, &u.LastIP, &u.TempGroup, &u.CreatedAt, &embeds, &u.Privacy.ShowComments, &u.Privacy.AllowMessage)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if embeds != -1 {
|
if embeds != -1 {
|
||||||
u.ParseSettings = DefaultParseSettings.CopyPtr()
|
u.ParseSettings = DefaultParseSettings.CopyPtr()
|
||||||
|
|
|
@ -577,7 +577,11 @@
|
||||||
"account_password_update_button":"Update",
|
"account_password_update_button":"Update",
|
||||||
|
|
||||||
"account_privacy_head":"Privacy",
|
"account_privacy_head":"Privacy",
|
||||||
"account_privacy_profile_comments":"Enable Profile Comments",
|
"account_privacy_profile_comments":"Profile Comment Visibility",
|
||||||
|
"account_privacy_profile_comments_public":"Anyone",
|
||||||
|
"account_privacy_profile_comments_registered":"Registered Users",
|
||||||
|
"account_privacy_profile_comments_self":"Only Me",
|
||||||
|
"account_privacy_enable_embeds":"Enable Embeds",
|
||||||
"account_privacy_button":"Update",
|
"account_privacy_button":"Update",
|
||||||
|
|
||||||
"account_mfa_head":"Manage 2FA",
|
"account_mfa_head":"Manage 2FA",
|
||||||
|
|
|
@ -51,18 +51,21 @@ func init() {
|
||||||
addPatch(31, patch31)
|
addPatch(31, patch31)
|
||||||
addPatch(32, patch32)
|
addPatch(32, patch32)
|
||||||
addPatch(33, patch33)
|
addPatch(33, patch33)
|
||||||
|
addPatch(34, patch34)
|
||||||
|
//addPatch(35, patch35)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bcol(col string, val bool) qgen.DBTableColumn {
|
||||||
|
if val {
|
||||||
|
return tC{col, "boolean", 0, false, false, "1"}
|
||||||
|
}
|
||||||
|
return tC{col, "boolean", 0, false, false, "0"}
|
||||||
|
}
|
||||||
|
func ccol(col string, size int, sdefault string) qgen.DBTableColumn {
|
||||||
|
return tC{col, "varchar", size, false, false, sdefault}
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch0(scanner *bufio.Scanner) (err error) {
|
func patch0(scanner *bufio.Scanner) (err error) {
|
||||||
err = execStmt(qgen.Builder.DropTable("menus"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = execStmt(qgen.Builder.DropTable("menu_items"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = createTable("menus", "", "",
|
err = createTable("menus", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"mid", "int", 0, false, true, ""},
|
tC{"mid", "int", 0, false, true, ""},
|
||||||
|
@ -79,20 +82,20 @@ func patch0(scanner *bufio.Scanner) (err error) {
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"miid", "int", 0, false, true, ""},
|
tC{"miid", "int", 0, false, true, ""},
|
||||||
tC{"mid", "int", 0, false, false, ""},
|
tC{"mid", "int", 0, false, false, ""},
|
||||||
tC{"name", "varchar", 200, false, false, ""},
|
ccol("name", 200, ""),
|
||||||
tC{"htmlID", "varchar", 200, false, false, "''"},
|
ccol("htmlID", 200, "''"),
|
||||||
tC{"cssClass", "varchar", 200, false, false, "''"},
|
ccol("cssClass", 200, "''"),
|
||||||
tC{"position", "varchar", 100, false, false, ""},
|
ccol("position", 100, ""),
|
||||||
tC{"path", "varchar", 200, false, false, "''"},
|
ccol("path", 200, "''"),
|
||||||
tC{"aria", "varchar", 200, false, false, "''"},
|
ccol("aria", 200, "''"),
|
||||||
tC{"tooltip", "varchar", 200, false, false, "''"},
|
ccol("tooltip", 200, "''"),
|
||||||
tC{"tmplName", "varchar", 200, false, false, "''"},
|
ccol("tmplName", 200, "''"),
|
||||||
tC{"order", "int", 0, false, false, "0"},
|
tC{"order", "int", 0, false, false, "0"},
|
||||||
|
|
||||||
tC{"guestOnly", "boolean", 0, false, false, "0"},
|
bcol("guestOnly", false),
|
||||||
tC{"memberOnly", "boolean", 0, false, false, "0"},
|
bcol("memberOnly", false),
|
||||||
tC{"staffOnly", "boolean", 0, false, false, "0"},
|
bcol("staffOnly", false),
|
||||||
tC{"adminOnly", "boolean", 0, false, false, "0"},
|
bcol("adminOnly", false),
|
||||||
},
|
},
|
||||||
[]tK{
|
[]tK{
|
||||||
tK{"miid", "primary", "", false},
|
tK{"miid", "primary", "", false},
|
||||||
|
@ -194,11 +197,11 @@ func patch3(scanner *bufio.Scanner) error {
|
||||||
return createTable("registration_logs", "", "",
|
return createTable("registration_logs", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"rlid", "int", 0, false, true, ""},
|
tC{"rlid", "int", 0, false, true, ""},
|
||||||
tC{"username", "varchar", 100, false, false, ""},
|
ccol("username", 100, ""),
|
||||||
tC{"email", "varchar", 100, false, false, ""},
|
ccol("email", 100, ""),
|
||||||
tC{"failureReason", "varchar", 100, false, false, ""},
|
ccol("failureReason", 100, ""),
|
||||||
tC{"success", "bool", 0, false, false, "0"}, // Did this attempt succeed?
|
bcol("success", false), // Did this attempt succeed?
|
||||||
tC{"ipaddress", "varchar", 200, false, false, ""},
|
ccol("ipaddress", 200, ""),
|
||||||
tC{"doneAt", "createdAt", 0, false, false, ""},
|
tC{"doneAt", "createdAt", 0, false, false, ""},
|
||||||
},
|
},
|
||||||
[]tK{
|
[]tK{
|
||||||
|
@ -258,8 +261,8 @@ func patch4(scanner *bufio.Scanner) error {
|
||||||
err = createTable("pages", "utf8mb4", "utf8mb4_general_ci",
|
err = createTable("pages", "utf8mb4", "utf8mb4_general_ci",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"pid", "int", 0, false, true, ""},
|
tC{"pid", "int", 0, false, true, ""},
|
||||||
tC{"name", "varchar", 200, false, false, ""},
|
ccol("name", 200, ""),
|
||||||
tC{"title", "varchar", 200, false, false, ""},
|
ccol("title", 200, ""),
|
||||||
tC{"body", "text", 0, false, false, ""},
|
tC{"body", "text", 0, false, false, ""},
|
||||||
tC{"allowedGroups", "text", 0, false, false, ""},
|
tC{"allowedGroups", "text", 0, false, false, ""},
|
||||||
tC{"menuID", "int", 0, false, false, "-1"},
|
tC{"menuID", "int", 0, false, false, "-1"},
|
||||||
|
@ -293,29 +296,24 @@ func patch5(scanner *bufio.Scanner) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = createTable("users_2fa_keys", "utf8mb4", "utf8mb4_general_ci",
|
return createTable("users_2fa_keys", "utf8mb4", "utf8mb4_general_ci",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"uid", "int", 0, false, false, ""},
|
tC{"uid", "int", 0, false, false, ""},
|
||||||
tC{"secret", "varchar", 100, false, false, ""},
|
ccol("secret", 100, ""),
|
||||||
tC{"scratch1", "varchar", 50, false, false, ""},
|
ccol("scratch1", 50, ""),
|
||||||
tC{"scratch2", "varchar", 50, false, false, ""},
|
ccol("scratch2", 50, ""),
|
||||||
tC{"scratch3", "varchar", 50, false, false, ""},
|
ccol("scratch3", 50, ""),
|
||||||
tC{"scratch4", "varchar", 50, false, false, ""},
|
ccol("scratch4", 50, ""),
|
||||||
tC{"scratch5", "varchar", 50, false, false, ""},
|
ccol("scratch5", 50, ""),
|
||||||
tC{"scratch6", "varchar", 50, false, false, ""},
|
ccol("scratch6", 50, ""),
|
||||||
tC{"scratch7", "varchar", 50, false, false, ""},
|
ccol("scratch7", 50, ""),
|
||||||
tC{"scratch8", "varchar", 50, false, false, ""},
|
ccol("scratch8", 50, ""),
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
tC{"createdAt", "createdAt", 0, false, false, ""},
|
||||||
},
|
},
|
||||||
[]tK{
|
[]tK{
|
||||||
tK{"uid", "primary", "", false},
|
tK{"uid", "primary", "", false},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch6(scanner *bufio.Scanner) error {
|
func patch6(scanner *bufio.Scanner) error {
|
||||||
|
@ -382,10 +380,6 @@ func patch8(scanner *bufio.Scanner) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = execStmt(qgen.Builder.DropTable("updates"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return createTable("updates", "", "",
|
return createTable("updates", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"dbVersion", "int", 0, false, false, "0"},
|
tC{"dbVersion", "int", 0, false, false, "0"},
|
||||||
|
@ -404,8 +398,8 @@ func patch9(scanner *bufio.Scanner) error {
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"lid", "int", 0, false, true, ""},
|
tC{"lid", "int", 0, false, true, ""},
|
||||||
tC{"uid", "int", 0, false, false, ""},
|
tC{"uid", "int", 0, false, false, ""},
|
||||||
tC{"success", "bool", 0, false, false, "0"}, // Did this attempt succeed?
|
bcol("success", false), // Did this attempt succeed?
|
||||||
tC{"ipaddress", "varchar", 200, false, false, ""},
|
ccol("ipaddress", 200, ""),
|
||||||
tC{"doneAt", "createdAt", 0, false, false, ""},
|
tC{"doneAt", "createdAt", 0, false, false, ""},
|
||||||
},
|
},
|
||||||
[]tK{
|
[]tK{
|
||||||
|
@ -463,7 +457,7 @@ func patch11(scanner *bufio.Scanner) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attachments for replies got the topicID rather than the replyID for a while in error, so we want to separate these out
|
// Attachments for replies got the topicID rather than the replyID for a while in error, so we want to separate these out
|
||||||
_, err = acc().Update("attachments").Set("originTable = 'freplies'").Where("originTable = 'replies'").Exec()
|
_, err = acc().Update("attachments").Set("originTable='freplies'").Where("originTable='replies'").Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -491,39 +485,26 @@ func patch11(scanner *bufio.Scanner) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch12(scanner *bufio.Scanner) error {
|
func patch12(scanner *bufio.Scanner) error {
|
||||||
err := execStmt(qgen.Builder.AddIndex("topics", "parentID", "parentID"))
|
var e error
|
||||||
if err != nil {
|
addIndex := func(tbl, iname, colname string) {
|
||||||
return err
|
if e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
/*e = execStmt(qgen.Builder.RemoveIndex(tbl, iname))
|
||||||
|
if e != nil {
|
||||||
|
return
|
||||||
|
}*/
|
||||||
|
e = execStmt(qgen.Builder.AddIndex(tbl, iname, colname))
|
||||||
}
|
}
|
||||||
err = execStmt(qgen.Builder.AddIndex("replies", "tid", "tid"))
|
addIndex("topics", "parentID", "parentID")
|
||||||
if err != nil {
|
addIndex("replies", "tid", "tid")
|
||||||
return err
|
addIndex("polls", "parentID", "parentID")
|
||||||
}
|
addIndex("likes", "targetItem", "targetItem")
|
||||||
err = execStmt(qgen.Builder.AddIndex("polls", "parentID", "parentID"))
|
addIndex("emails", "uid", "uid")
|
||||||
if err != nil {
|
addIndex("attachments", "originID", "originID")
|
||||||
return err
|
addIndex("attachments", "path", "path")
|
||||||
}
|
addIndex("activity_stream_matches", "watcher", "watcher")
|
||||||
err = execStmt(qgen.Builder.AddIndex("likes", "targetItem", "targetItem"))
|
return e
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = execStmt(qgen.Builder.AddIndex("emails", "uid", "uid"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = execStmt(qgen.Builder.AddIndex("attachments", "originID", "originID"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = execStmt(qgen.Builder.AddIndex("attachments", "path", "path"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = execStmt(qgen.Builder.AddIndex("activity_stream_matches", "watcher", "watcher"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch13(scanner *bufio.Scanner) error {
|
func patch13(scanner *bufio.Scanner) error {
|
||||||
|
@ -554,17 +535,17 @@ func patch15(scanner *bufio.Scanner) error {
|
||||||
func patch16(scanner *bufio.Scanner) error {
|
func patch16(scanner *bufio.Scanner) error {
|
||||||
return createTable("password_resets", "", "",
|
return createTable("password_resets", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"email", "varchar", 200, false, false, ""},
|
ccol("email", 200, ""),
|
||||||
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
tC{"validated", "varchar", 200, false, false, ""}, // Token given once the one-use token is consumed, used to prevent multiple people consuming the same one-use token
|
ccol("validated", 200, ""), // Token given once the one-use token is consumed, used to prevent multiple people consuming the same one-use token
|
||||||
tC{"token", "varchar", 200, false, false, ""},
|
ccol("token", 200, ""),
|
||||||
tC{"createdAt", "createdAt", 0, false, false, ""},
|
tC{"createdAt", "createdAt", 0, false, false, ""},
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch17(scanner *bufio.Scanner) error {
|
func patch17(scanner *bufio.Scanner) error {
|
||||||
err := execStmt(qgen.Builder.AddColumn("attachments", tC{"extra", "varchar", 200, false, false, ""}, nil))
|
err := execStmt(qgen.Builder.AddColumn("attachments", ccol("extra", 200, ""), nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -575,7 +556,7 @@ func patch17(scanner *bufio.Scanner) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = acc().Update("attachments").Set("sectionID=?").Where("originTable = 'topics' AND originID = ?").Exec(parentID, tid)
|
_, err = acc().Update("attachments").Set("sectionID=?").Where("originTable='topics' AND originID=?").Exec(parentID, tid)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -592,7 +573,7 @@ func patch17(scanner *bufio.Scanner) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = acc().Update("attachments").Set("sectionID=?, extra=?").Where("originTable = 'replies' AND originID = ?").Exec(sectionID, tid, rid)
|
_, err = acc().Update("attachments").Set("sectionID=?, extra=?").Where("originTable='replies' AND originID=?").Exec(sectionID, tid, rid)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -613,16 +594,15 @@ func patch19(scanner *bufio.Scanner) error {
|
||||||
func patch20(scanner *bufio.Scanner) error {
|
func patch20(scanner *bufio.Scanner) error {
|
||||||
err := acc().Select("activity_stream_matches").Cols("asid").Each(func(rows *sql.Rows) error {
|
err := acc().Select("activity_stream_matches").Cols("asid").Each(func(rows *sql.Rows) error {
|
||||||
var asid int
|
var asid int
|
||||||
err := rows.Scan(&asid)
|
if e := rows.Scan(&asid); e != nil {
|
||||||
if err != nil {
|
return e
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
err = acc().Select("activity_stream").Cols("asid").Where("asid = ?").QueryRow(asid).Scan(&asid)
|
e := acc().Select("activity_stream").Cols("asid").Where("asid=?").QueryRow(asid).Scan(&asid)
|
||||||
if err != sql.ErrNoRows {
|
if e != sql.ErrNoRows {
|
||||||
return err
|
return e
|
||||||
}
|
}
|
||||||
_, err = acc().Delete("activity_stream_matches").Where("asid = ?").Run(asid)
|
_, e = acc().Delete("activity_stream_matches").Where("asid=?").Run(asid)
|
||||||
return err
|
return e
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -644,8 +624,8 @@ func patch21(scanner *bufio.Scanner) error {
|
||||||
|
|
||||||
err = createTable("meta", "", "",
|
err = createTable("meta", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"name", "varchar", 200, false, false, ""},
|
ccol("name", 200, ""),
|
||||||
tC{"value", "varchar", 200, false, false, ""},
|
ccol("value", 200, ""),
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -656,15 +636,11 @@ func patch21(scanner *bufio.Scanner) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch22(scanner *bufio.Scanner) error {
|
func patch22(scanner *bufio.Scanner) error {
|
||||||
return execStmt(qgen.Builder.AddColumn("forums", tC{"tmpl", "varchar", 200, false, false, "''"}, nil))
|
return execStmt(qgen.Builder.AddColumn("forums", ccol("tmpl", 200, "''"), nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch23(scanner *bufio.Scanner) error {
|
func patch23(scanner *bufio.Scanner) error {
|
||||||
err := execStmt(qgen.Builder.DropTable("conversations"))
|
err := createTable("conversations", "", "",
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = createTable("conversations", "", "",
|
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"cid", "int", 0, false, true, ""},
|
tC{"cid", "int", 0, false, true, ""},
|
||||||
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
|
||||||
|
@ -680,17 +656,13 @@ func patch23(scanner *bufio.Scanner) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = execStmt(qgen.Builder.DropTable("conversations_posts"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = createTable("conversations_posts", "", "",
|
err = createTable("conversations_posts", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"pid", "int", 0, false, true, ""},
|
tC{"pid", "int", 0, false, true, ""},
|
||||||
tC{"cid", "int", 0, false, false, ""},
|
tC{"cid", "int", 0, false, false, ""},
|
||||||
tC{"createdBy", "int", 0, false, false, ""},
|
tC{"createdBy", "int", 0, false, false, ""},
|
||||||
tC{"body", "varchar", 50, false, false, ""},
|
ccol("body", 50, ""),
|
||||||
tC{"post", "varchar", 50, false, false, "''"},
|
ccol("post", 50, "''"),
|
||||||
},
|
},
|
||||||
[]tK{
|
[]tK{
|
||||||
tK{"pid", "primary", "", false},
|
tK{"pid", "primary", "", false},
|
||||||
|
@ -700,10 +672,6 @@ func patch23(scanner *bufio.Scanner) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = execStmt(qgen.Builder.DropTable("conversations_participants"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return createTable("conversations_participants", "", "",
|
return createTable("conversations_participants", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"uid", "int", 0, false, false, ""},
|
tC{"uid", "int", 0, false, false, ""},
|
||||||
|
@ -713,16 +681,12 @@ func patch23(scanner *bufio.Scanner) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch24(scanner *bufio.Scanner) error {
|
func patch24(scanner *bufio.Scanner) error {
|
||||||
err := execStmt(qgen.Builder.DropTable("users_groups_promotions"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return createTable("users_groups_promotions", "", "",
|
return createTable("users_groups_promotions", "", "",
|
||||||
[]tC{
|
[]tC{
|
||||||
tC{"pid", "int", 0, false, true, ""},
|
tC{"pid", "int", 0, false, true, ""},
|
||||||
tC{"from_gid", "int", 0, false, false, ""},
|
tC{"from_gid", "int", 0, false, false, ""},
|
||||||
tC{"to_gid", "int", 0, false, false, ""},
|
tC{"to_gid", "int", 0, false, false, ""},
|
||||||
tC{"two_way", "boolean", 0, false, false, "0"}, // If a user no longer meets the requirements for this promotion then they will be demoted if this flag is set
|
bcol("two_way", false), // If a user no longer meets the requirements for this promotion then they will be demoted if this flag is set
|
||||||
|
|
||||||
// Requirements
|
// Requirements
|
||||||
tC{"level", "int", 0, false, false, ""},
|
tC{"level", "int", 0, false, false, ""},
|
||||||
|
@ -812,28 +776,21 @@ func patch29(scanner *bufio.Scanner) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fixCol := func(tbl string) error {
|
fixCols := func(tbls ...string) error {
|
||||||
//err := execStmt(qgen.Builder.RenameColumn(tbl, "ipaddress","ip"))
|
for _, tbl := range tbls {
|
||||||
err := execStmt(qgen.Builder.ChangeColumn(tbl, "ipaddress", tC{"ip", "varchar", 200, false, false, "''"}))
|
//err := execStmt(qgen.Builder.RenameColumn(tbl, "ipaddress","ip"))
|
||||||
if err != nil {
|
err := execStmt(qgen.Builder.ChangeColumn(tbl, "ipaddress", ccol("ip", 200, "''")))
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = execStmt(qgen.Builder.SetDefaultColumn(tbl, "ip", "varchar", ""))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return execStmt(qgen.Builder.SetDefaultColumn(tbl, "ip", "varchar", ""))
|
return nil
|
||||||
}
|
}
|
||||||
|
err = fixCols("topics", "replies", "polls_votes", "users_replies")
|
||||||
err = fixCol("topics")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = fixCol("replies")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = fixCol("polls_votes")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = fixCol("users_replies")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -867,36 +824,31 @@ func patch30(scanner *bufio.Scanner) error {
|
||||||
return execStmt(qgen.Builder.SetDefaultColumn("users", "last_ip", "varchar", ""))
|
return execStmt(qgen.Builder.SetDefaultColumn("users", "last_ip", "varchar", ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch31(scanner *bufio.Scanner) error {
|
func patch31(scanner *bufio.Scanner) (e error) {
|
||||||
err := execStmt(qgen.Builder.RemoveIndex("topics", "title"))
|
addKey := func(tbl, col string, tk qgen.DBTableKey) error {
|
||||||
|
/*err := execStmt(qgen.Builder.RemoveIndex(tbl, col))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}*/
|
||||||
|
return execStmt(qgen.Builder.AddKey(tbl, col, tk))
|
||||||
|
}
|
||||||
|
err := addKey("topics", "title", tK{"title", "fulltext", "", false})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = execStmt(qgen.Builder.RemoveIndex("topics", "content"))
|
err = addKey("topics", "content", tK{"content", "fulltext", "", false})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = execStmt(qgen.Builder.RemoveIndex("replies", "content"))
|
return addKey("replies", "content", tK{"content", "fulltext", "", false})
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = execStmt(qgen.Builder.AddKey("topics", "title", tK{"title", "fulltext", "", false}))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = execStmt(qgen.Builder.AddKey("topics", "content", tK{"content", "fulltext", "", false}))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = execStmt(qgen.Builder.AddKey("replies", "content", tK{"content", "fulltext", "", false}))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTable(table, charset, collation string, cols []tC, keys []tK) error {
|
func createTable(tbl, charset, collation string, cols []tC, keys []tK) error {
|
||||||
return execStmt(qgen.Builder.CreateTable(table, charset, collation, cols, keys))
|
err := execStmt(qgen.Builder.DropTable(tbl))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return execStmt(qgen.Builder.CreateTable(tbl, charset, collation, cols, keys))
|
||||||
}
|
}
|
||||||
|
|
||||||
func patch32(scanner *bufio.Scanner) error {
|
func patch32(scanner *bufio.Scanner) error {
|
||||||
|
@ -913,3 +865,75 @@ func patch32(scanner *bufio.Scanner) error {
|
||||||
func patch33(scanner *bufio.Scanner) error {
|
func patch33(scanner *bufio.Scanner) error {
|
||||||
return execStmt(qgen.Builder.AddColumn("viewchunks", tC{"avg", "int", 0, false, false, "0"}, nil))
|
return execStmt(qgen.Builder.AddColumn("viewchunks", tC{"avg", "int", 0, false, false, "0"}, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func patch34(scanner *bufio.Scanner) error {
|
||||||
|
/*err := createTable("tables", "", "",
|
||||||
|
[]tC{
|
||||||
|
tC{"id", "int", 0, false, true, ""},
|
||||||
|
ccol("name", 200, ""),
|
||||||
|
},
|
||||||
|
[]tK{
|
||||||
|
tK{"id", "primary", "", false},
|
||||||
|
tK{"name", "unique", "", false},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
insert := func(tbl, cols, fields string) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = execStmt(qgen.Builder.SimpleInsert(tbl, cols, fields))
|
||||||
|
}
|
||||||
|
insert("tables", "name", "forums")
|
||||||
|
insert("tables", "name", "topics")
|
||||||
|
insert("tables", "name", "replies")
|
||||||
|
// ! Hold onto freplies for a while longer
|
||||||
|
insert("tables", "name", "freplies")*/
|
||||||
|
/*err := execStmt(qgen.Builder.AddColumn("topics", tC{"attachCount", "int", 0, false, false, "0"}, nil))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}*/
|
||||||
|
overwriteColumn := func(tbl, col string, tc qgen.DBTableColumn) error {
|
||||||
|
/*e := execStmt(qgen.Builder.DropColumn(tbl, col))
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}*/
|
||||||
|
return execStmt(qgen.Builder.AddColumn(tbl, tc, nil))
|
||||||
|
}
|
||||||
|
err := overwriteColumn("users", "profile_comments", tC{"profile_comments", "int", 0, false, false, "0"})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = overwriteColumn("users", "who_can_convo", tC{"who_can_convo", "int", 0, false, false, "0"})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefault := func(tbl, col, typ, val string) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = execStmt(qgen.Builder.SetDefaultColumn(tbl, col, typ, val))
|
||||||
|
}
|
||||||
|
setDefault("users_groups", "permissions", "text", "{}")
|
||||||
|
setDefault("users_groups", "plugin_perms", "text", "{}")
|
||||||
|
setDefault("forums_permissions", "permissions", "text", "{}")
|
||||||
|
setDefault("topics", "content", "text", "")
|
||||||
|
setDefault("topics", "parsed_content", "text", "")
|
||||||
|
setDefault("replies", "content", "text", "")
|
||||||
|
setDefault("replies", "parsed_content", "text", "")
|
||||||
|
//setDefault("revisions", "content", "text", "")
|
||||||
|
setDefault("users_replies", "content", "text", "")
|
||||||
|
setDefault("users_replies", "parsed_content", "text", "")
|
||||||
|
setDefault("pages", "body", "text", "")
|
||||||
|
setDefault("pages", "allowedGroups", "text", "")
|
||||||
|
setDefault("moderation_logs", "extra", "text", "")
|
||||||
|
setDefault("administration_logs", "extra", "text", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ type DBStmt struct {
|
||||||
Type string // create-table, insert, update, delete
|
Type string // create-table, insert, update, delete
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add the DropTable, TableExists, AddColumn, ColumnExists, and RemoveColumn methods
|
// TODO: Add the TableExists and ColumnExists methods
|
||||||
type Adapter interface {
|
type Adapter interface {
|
||||||
GetName() string
|
GetName() string
|
||||||
BuildConn(config map[string]string) (*sql.DB, error)
|
BuildConn(config map[string]string) (*sql.DB, error)
|
||||||
|
|
|
@ -614,8 +614,8 @@ func AccountEditMFADisableSubmit(w http.ResponseWriter, r *http.Request, u *c.Us
|
||||||
|
|
||||||
func AccountEditPrivacy(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
|
func AccountEditPrivacy(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
|
||||||
accountEditHead("account_privacy", w, r, u, h)
|
accountEditHead("account_privacy", w, r, u, h)
|
||||||
profileComments := false
|
profileComments := u.Privacy.ShowComments
|
||||||
receiveConvos := false
|
receiveConvos := u.Privacy.AllowMessage
|
||||||
enableEmbeds := !c.DefaultParseSettings.NoEmbed
|
enableEmbeds := !c.DefaultParseSettings.NoEmbed
|
||||||
if u.ParseSettings != nil {
|
if u.ParseSettings != nil {
|
||||||
enableEmbeds = !u.ParseSettings.NoEmbed
|
enableEmbeds = !u.ParseSettings.NoEmbed
|
||||||
|
@ -626,14 +626,21 @@ func AccountEditPrivacy(w http.ResponseWriter, r *http.Request, u *c.User, h *c.
|
||||||
|
|
||||||
func AccountEditPrivacySubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
func AccountEditPrivacySubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
//headerLite, _ := c.SimpleUserCheck(w, r, u)
|
//headerLite, _ := c.SimpleUserCheck(w, r, u)
|
||||||
|
sProfileComments := r.FormValue("profile_comments")
|
||||||
sEnableEmbeds := r.FormValue("enable_embeds")
|
sEnableEmbeds := r.FormValue("enable_embeds")
|
||||||
enableEmbeds, e := strconv.Atoi(sEnableEmbeds)
|
oProfileComments := r.FormValue("o_profile_comments")
|
||||||
if e != nil {
|
oEnableEmbeds := r.FormValue("o_enable_embeds")
|
||||||
return c.LocalError("enable_embeds must be 0 or 1", w, r, u)
|
|
||||||
}
|
if sProfileComments != oProfileComments || sEnableEmbeds != oEnableEmbeds {
|
||||||
if sEnableEmbeds != r.FormValue("o_enable_embeds") {
|
profileComments, e := strconv.Atoi(sProfileComments)
|
||||||
if e = u.UpdatePrivacy(enableEmbeds); e != nil {
|
enableEmbeds, e2 := strconv.Atoi(sEnableEmbeds)
|
||||||
|
if e != nil || e2 != nil {
|
||||||
|
return c.LocalError("malformed integer", w, r, u)
|
||||||
|
}
|
||||||
|
e = u.UpdatePrivacy(profileComments, enableEmbeds)
|
||||||
|
if e == c.ErrProfileCommentsOutOfBounds || e == c.ErrEnableEmbedsOutOfBounds {
|
||||||
|
return c.LocalError(e.Error(), w, r, u)
|
||||||
|
} else if e != nil {
|
||||||
return c.InternalError(e, w, r)
|
return c.InternalError(e, w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -399,24 +399,18 @@ func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user *c.User,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
return actionSuccess(w, r, "/user/convo/"+strconv.Itoa(post.CID), js)
|
||||||
if !js {
|
|
||||||
http.Redirect(w, r, "/user/convo/"+strconv.Itoa(post.CID), http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
w.Write(successJSONBytes)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RelationsBlockCreate(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header, spid string) c.RouteError {
|
func RelationsBlockCreate(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header, spid string) c.RouteError {
|
||||||
h.Title = p.GetTitlePhrase("create_block")
|
h.Title = p.GetTitlePhrase("create_block")
|
||||||
pid, err := strconv.Atoi(spid)
|
pid, err := strconv.Atoi(spid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, u)
|
||||||
}
|
}
|
||||||
puser, err := c.Users.Get(pid)
|
puser, err := c.Users.Get(pid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to block doesn't exist.", w, r, user)
|
return c.LocalError("The user you're trying to block doesn't exist.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -425,22 +419,22 @@ func RelationsBlockCreate(w http.ResponseWriter, r *http.Request, user *c.User,
|
||||||
return renderTemplate("are_you_sure", w, r, h, pi)
|
return renderTemplate("are_you_sure", w, r, h, pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RelationsBlockCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User, spid string) c.RouteError {
|
func RelationsBlockCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c.RouteError {
|
||||||
pid, err := strconv.Atoi(spid)
|
pid, err := strconv.Atoi(spid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, u)
|
||||||
}
|
}
|
||||||
puser, err := c.Users.Get(pid)
|
puser, err := c.Users.Get(pid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to block doesn't exist.", w, r, user)
|
return c.LocalError("The user you're trying to block doesn't exist.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
if user.ID == puser.ID {
|
if u.ID == puser.ID {
|
||||||
return c.LocalError("You can't block yourself.", w, r, user)
|
return c.LocalError("You can't block yourself.", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.UserBlocks.Add(user.ID, puser.ID)
|
err = c.UserBlocks.Add(u.ID, puser.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -449,15 +443,15 @@ func RelationsBlockCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RelationsBlockRemove(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header, spid string) c.RouteError {
|
func RelationsBlockRemove(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header, spid string) c.RouteError {
|
||||||
h.Title = p.GetTitlePhrase("remove_block")
|
h.Title = p.GetTitlePhrase("remove_block")
|
||||||
pid, err := strconv.Atoi(spid)
|
pid, err := strconv.Atoi(spid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, u)
|
||||||
}
|
}
|
||||||
puser, err := c.Users.Get(pid)
|
puser, err := c.Users.Get(pid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to block doesn't exist.", w, r, user)
|
return c.LocalError("The user you're trying to block doesn't exist.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -466,19 +460,19 @@ func RelationsBlockRemove(w http.ResponseWriter, r *http.Request, user *c.User,
|
||||||
return renderTemplate("are_you_sure", w, r, h, pi)
|
return renderTemplate("are_you_sure", w, r, h, pi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RelationsBlockRemoveSubmit(w http.ResponseWriter, r *http.Request, user *c.User, spid string) c.RouteError {
|
func RelationsBlockRemoveSubmit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c.RouteError {
|
||||||
pid, err := strconv.Atoi(spid)
|
pid, err := strconv.Atoi(spid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, u)
|
||||||
}
|
}
|
||||||
puser, err := c.Users.Get(pid)
|
puser, err := c.Users.Get(pid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to unblock doesn't exist.", w, r, user)
|
return c.LocalError("The user you're trying to unblock doesn't exist.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.UserBlocks.Remove(user.ID, puser.ID)
|
err = c.UserBlocks.Remove(u.ID, puser.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,23 +35,23 @@ func Pages(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_list", "", "panel_pages", &pi})
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_list", "", "panel_pages", &pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
|
||||||
name := c.SanitiseSingleLine(r.PostFormValue("name"))
|
name := c.SanitiseSingleLine(r.PostFormValue("name"))
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return c.LocalError("No name was provided for this page", w, r, user)
|
return c.LocalError("No name was provided for this page", w, r, u)
|
||||||
}
|
}
|
||||||
title := c.SanitiseSingleLine(r.PostFormValue("title"))
|
title := c.SanitiseSingleLine(r.PostFormValue("title"))
|
||||||
if title == "" {
|
if title == "" {
|
||||||
return c.LocalError("No title was provided for this page", w, r, user)
|
return c.LocalError("No title was provided for this page", w, r, u)
|
||||||
}
|
}
|
||||||
body := r.PostFormValue("body")
|
body := r.PostFormValue("body")
|
||||||
if body == "" {
|
if body == "" {
|
||||||
return c.LocalError("No body was provided for this page", w, r, user)
|
return c.LocalError("No body was provided for this page", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
page := c.BlankCustomPage()
|
page := c.BlankCustomPage()
|
||||||
|
@ -62,7 +62,7 @@ func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.R
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.Create("create", pid, "page", user.GetIP(), user.ID)
|
err = c.AdminLogs.Create("create", pid, "page", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -95,27 +95,27 @@ func PagesEdit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_edit", "", "panel_pages_edit", &pi})
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_edit", "", "panel_pages_edit", &pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, spid string) c.RouteError {
|
func PagesEditSubmit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
|
|
||||||
pid, err := strconv.Atoi(spid)
|
pid, err := strconv.Atoi(spid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError("Page ID needs to be an integer", w, r, user)
|
return c.LocalError("Page ID needs to be an integer", w, r, u)
|
||||||
}
|
}
|
||||||
name := c.SanitiseSingleLine(r.PostFormValue("name"))
|
name := c.SanitiseSingleLine(r.PostFormValue("name"))
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return c.LocalError("No name was provided for this page", w, r, user)
|
return c.LocalError("No name was provided for this page", w, r, u)
|
||||||
}
|
}
|
||||||
title := c.SanitiseSingleLine(r.PostFormValue("title"))
|
title := c.SanitiseSingleLine(r.PostFormValue("title"))
|
||||||
if title == "" {
|
if title == "" {
|
||||||
return c.LocalError("No title was provided for this page", w, r, user)
|
return c.LocalError("No title was provided for this page", w, r, u)
|
||||||
}
|
}
|
||||||
body := r.PostFormValue("body")
|
body := r.PostFormValue("body")
|
||||||
if body == "" {
|
if body == "" {
|
||||||
return c.LocalError("No body was provided for this page", w, r, user)
|
return c.LocalError("No body was provided for this page", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
page, err := c.Pages.Get(pid)
|
page, err := c.Pages.Get(pid)
|
||||||
|
@ -129,7 +129,7 @@ func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, spid
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.Create("edit", pid, "page", user.GetIP(), user.ID)
|
err = c.AdminLogs.Create("edit", pid, "page", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,54 +26,54 @@ func Plugins(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Abstract more of the plugin activation / installation / deactivation logic, so we can test all that more reliably and easily
|
// TODO: Abstract more of the plugin activation / installation / deactivation logic, so we can test all that more reliably and easily
|
||||||
func PluginsActivate(w http.ResponseWriter, r *http.Request, user *c.User, uname string) c.RouteError {
|
func PluginsActivate(w http.ResponseWriter, r *http.Request, u *c.User, uname string) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManagePlugins {
|
if !u.Perms.ManagePlugins {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin, ok := c.Plugins[uname]
|
pl, ok := c.Plugins[uname]
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.LocalError("The plugin isn't registered in the system", w, r, user)
|
return c.LocalError("The plugin isn't registered in the system", w, r, u)
|
||||||
}
|
}
|
||||||
if plugin.Installable && !plugin.Installed {
|
if pl.Installable && !pl.Installed {
|
||||||
return c.LocalError("You can't activate this plugin without installing it first", w, r, user)
|
return c.LocalError("You can't activate this plugin without installing it first", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
active, err := plugin.BypassActive()
|
active, err := pl.BypassActive()
|
||||||
hasPlugin, err2 := plugin.InDatabase()
|
hasPlugin, err2 := pl.InDatabase()
|
||||||
if err != nil || err2 != nil {
|
if err != nil || err2 != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if plugin.Activate != nil {
|
if pl.Activate != nil {
|
||||||
err = plugin.Activate(plugin)
|
err = pl.Activate(pl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasPlugin {
|
if hasPlugin {
|
||||||
if active {
|
if active {
|
||||||
return c.LocalError("The plugin is already active", w, r, user)
|
return c.LocalError("The plugin is already active", w, r, u)
|
||||||
}
|
}
|
||||||
err = plugin.SetActive(true)
|
err = pl.SetActive(true)
|
||||||
} else {
|
} else {
|
||||||
err = plugin.AddToDatabase(true, false)
|
err = pl.AddToDatabase(true, false)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Activating plugin '%s'", plugin.Name)
|
log.Printf("Activating plugin '%s'", pl.Name)
|
||||||
err = plugin.Init(plugin)
|
err = pl.Init(pl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, u)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.CreateExtra("activate", 0, "plugin", user.GetIP(), user.ID, c.SanitiseSingleLine(plugin.Name))
|
err = c.AdminLogs.CreateExtra("activate", 0, "plugin", u.GetIP(), u.ID, c.SanitiseSingleLine(pl.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -82,36 +82,36 @@ func PluginsActivate(w http.ResponseWriter, r *http.Request, user *c.User, uname
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PluginsDeactivate(w http.ResponseWriter, r *http.Request, user *c.User, uname string) c.RouteError {
|
func PluginsDeactivate(w http.ResponseWriter, r *http.Request, u *c.User, uname string) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManagePlugins {
|
if !u.Perms.ManagePlugins {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin, ok := c.Plugins[uname]
|
pl, ok := c.Plugins[uname]
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.LocalError("The plugin isn't registered in the system", w, r, user)
|
return c.LocalError("The plugin isn't registered in the system", w, r, u)
|
||||||
}
|
}
|
||||||
log.Printf("plugin: %+v\n", plugin)
|
log.Printf("plugin: %+v\n", pl)
|
||||||
|
|
||||||
active, err := plugin.BypassActive()
|
active, err := pl.BypassActive()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
} else if !active {
|
} else if !active {
|
||||||
return c.LocalError("The plugin you're trying to deactivate isn't active", w, r, user)
|
return c.LocalError("The plugin you're trying to deactivate isn't active", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = plugin.SetActive(false)
|
err = pl.SetActive(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
if plugin.Deactivate != nil {
|
if pl.Deactivate != nil {
|
||||||
plugin.Deactivate(plugin)
|
pl.Deactivate(pl)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.CreateExtra("deactivate", 0, "plugin", user.GetIP(), user.ID, c.SanitiseSingleLine(plugin.Name))
|
err = c.AdminLogs.CreateExtra("deactivate", 0, "plugin", u.GetIP(), u.ID, c.SanitiseSingleLine(pl.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -120,28 +120,28 @@ func PluginsDeactivate(w http.ResponseWriter, r *http.Request, user *c.User, una
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PluginsInstall(w http.ResponseWriter, r *http.Request, user *c.User, uname string) c.RouteError {
|
func PluginsInstall(w http.ResponseWriter, r *http.Request, u *c.User, uname string) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManagePlugins {
|
if !u.Perms.ManagePlugins {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin, ok := c.Plugins[uname]
|
pl, ok := c.Plugins[uname]
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.LocalError("The plugin isn't registered in the system", w, r, user)
|
return c.LocalError("The plugin isn't registered in the system", w, r, u)
|
||||||
}
|
}
|
||||||
if !plugin.Installable {
|
if !pl.Installable {
|
||||||
return c.LocalError("This plugin is not installable", w, r, user)
|
return c.LocalError("This plugin is not installable", w, r, u)
|
||||||
}
|
}
|
||||||
if plugin.Installed {
|
if pl.Installed {
|
||||||
return c.LocalError("This plugin has already been installed", w, r, user)
|
return c.LocalError("This plugin has already been installed", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
active, err := plugin.BypassActive()
|
active, err := pl.BypassActive()
|
||||||
hasPlugin, err2 := plugin.InDatabase()
|
hasPlugin, err2 := pl.InDatabase()
|
||||||
if err != nil || err2 != nil {
|
if err != nil || err2 != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -149,39 +149,39 @@ func PluginsInstall(w http.ResponseWriter, r *http.Request, user *c.User, uname
|
||||||
return c.InternalError(errors.New("An uninstalled plugin is still active"), w, r)
|
return c.InternalError(errors.New("An uninstalled plugin is still active"), w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
if plugin.Install != nil {
|
if pl.Install != nil {
|
||||||
err = plugin.Install(plugin)
|
err = pl.Install(pl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if plugin.Activate != nil {
|
if pl.Activate != nil {
|
||||||
err = plugin.Activate(plugin)
|
err = pl.Activate(pl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasPlugin {
|
if hasPlugin {
|
||||||
err = plugin.SetInstalled(true)
|
err = pl.SetInstalled(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = plugin.SetActive(true)
|
err = pl.SetActive(true)
|
||||||
} else {
|
} else {
|
||||||
err = plugin.AddToDatabase(true, true)
|
err = pl.AddToDatabase(true, true)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Installing plugin '%s'", plugin.Name)
|
log.Printf("Installing plugin '%s'", pl.Name)
|
||||||
err = plugin.Init(plugin)
|
err = pl.Init(pl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(err.Error(), w, r, user)
|
return c.LocalError(err.Error(), w, r, u)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.CreateExtra("install", 0, "plugin", user.GetIP(), user.ID, c.SanitiseSingleLine(plugin.Name))
|
err = c.AdminLogs.CreateExtra("install", 0, "plugin", u.GetIP(), u.ID, c.SanitiseSingleLine(pl.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,13 @@ import (
|
||||||
p "github.com/Azareal/Gosora/common/phrases"
|
p "github.com/Azareal/Gosora/common/phrases"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Themes(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
func Themes(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, user, "themes", "themes")
|
basePage, ferr := buildBasePage(w, r, u, "themes", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
var pThemeList, vThemeList []*c.Theme
|
var pThemeList, vThemeList []*c.Theme
|
||||||
|
@ -37,28 +37,28 @@ func Themes(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_themes", "", "panel_themes", &pi})
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_themes", "", "panel_themes", &pi})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user *c.User, uname string) c.RouteError {
|
func ThemesSetDefault(w http.ResponseWriter, r *http.Request, u *c.User, uname string) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
theme, ok := c.Themes[uname]
|
theme, ok := c.Themes[uname]
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.LocalError("The theme isn't registered in the system", w, r, user)
|
return c.LocalError("The theme isn't registered in the system", w, r, u)
|
||||||
}
|
}
|
||||||
if theme.Disabled {
|
if theme.Disabled {
|
||||||
return c.LocalError("You must not enable this theme", w, r, user)
|
return c.LocalError("You must not enable this theme", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := c.UpdateDefaultTheme(theme)
|
err := c.UpdateDefaultTheme(theme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.CreateExtra("set_default", 0, "theme", user.GetIP(), user.ID, c.SanitiseSingleLine(theme.Name))
|
err = c.AdminLogs.CreateExtra("set_default", 0, "theme", u.GetIP(), u.ID, c.SanitiseSingleLine(theme.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -67,13 +67,13 @@ func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user *c.User, unam
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenus(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
func ThemesMenus(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, user, "themes_menus", "themes")
|
basePage, ferr := buildBasePage(w, r, u, "themes_menus", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
var menuList []c.PanelMenuListItem
|
var menuList []c.PanelMenuListItem
|
||||||
|
@ -92,21 +92,21 @@ func ThemesMenus(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteEr
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus", &c.PanelMenuListPage{basePage, menuList}})
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus", &c.PanelMenuListPage{basePage, menuList}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user *c.User, smid string) c.RouteError {
|
func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, u *c.User, smid string) c.RouteError {
|
||||||
// TODO: Something like Menu #1 for the title?
|
// TODO: Something like Menu #1 for the title?
|
||||||
basePage, ferr := buildBasePage(w, r, user, "themes_menus_edit", "themes")
|
basePage, ferr := buildBasePage(w, r, u, "themes_menus_edit", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
basePage.Header.AddScript("Sortable-1.4.0/Sortable.min.js")
|
basePage.Header.AddScript("Sortable-1.4.0/Sortable.min.js")
|
||||||
basePage.Header.AddScriptAsync("panel_menu_items.js")
|
basePage.Header.AddScriptAsync("panel_menu_items.js")
|
||||||
|
|
||||||
mid, err := strconv.Atoi(smid)
|
mid, err := strconv.Atoi(smid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, u)
|
||||||
}
|
}
|
||||||
menuHold, err := c.Menus.Get(mid)
|
menuHold, err := c.Menus.Get(mid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
|
@ -138,19 +138,19 @@ func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user *c.User, smid
|
||||||
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus_items", &c.PanelMenuPage{basePage, mid, menuList}})
|
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus_items", &c.PanelMenuPage{basePage, mid, menuList}})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user *c.User, sitemID string) c.RouteError {
|
func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, u *c.User, sitemID string) c.RouteError {
|
||||||
// TODO: Something like Menu #1 for the title?
|
// TODO: Something like Menu #1 for the title?
|
||||||
basePage, ferr := buildBasePage(w, r, user, "themes_menus_edit", "themes")
|
basePage, ferr := buildBasePage(w, r, u, "themes_menus_edit", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemID, err := strconv.Atoi(sitemID)
|
itemID, err := strconv.Atoi(sitemID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, user)
|
return c.LocalError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, u)
|
||||||
}
|
}
|
||||||
menuItem, err := c.Menus.ItemStore().Get(itemID)
|
menuItem, err := c.Menus.ItemStore().Get(itemID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
|
@ -205,23 +205,23 @@ func themesMenuItemSetters(r *http.Request, i c.MenuItem) c.MenuItem {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sitemID string) c.RouteError {
|
func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, u *c.User, sitemID string) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemID, err := strconv.Atoi(sitemID)
|
itemID, err := strconv.Atoi(sitemID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, user, js)
|
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, u, js)
|
||||||
}
|
}
|
||||||
menuItem, err := c.Menus.ItemStore().Get(itemID)
|
menuItem, err := c.Menus.ItemStore().Get(itemID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalErrorJSQ("This item doesn't exist.", w, r, user, js)
|
return c.LocalErrorJSQ("This item doesn't exist.", w, r, u, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user *c.Us
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.Create("edit", menuItem.ID, "menu_item", user.GetIP(), user.ID)
|
err = c.AdminLogs.Create("edit", menuItem.ID, "menu_item", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -240,23 +240,23 @@ func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user *c.Us
|
||||||
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, js)
|
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
smenuID := r.PostFormValue("mid")
|
smenuID := r.PostFormValue("mid")
|
||||||
if smenuID == "" {
|
if smenuID == "" {
|
||||||
return c.LocalErrorJSQ("No menuID provided", w, r, user, js)
|
return c.LocalErrorJSQ("No menuID provided", w, r, u, js)
|
||||||
}
|
}
|
||||||
menuID, err := strconv.Atoi(smenuID)
|
menuID, err := strconv.Atoi(smenuID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, user, js)
|
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
menuItem := c.MenuItem{MenuID: menuID}
|
menuItem := c.MenuItem{MenuID: menuID}
|
||||||
|
@ -265,7 +265,7 @@ func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.Create("create", itemID, "menu_item", user.GetIP(), user.ID)
|
err = c.AdminLogs.Create("create", itemID, "menu_item", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -273,23 +273,23 @@ func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.
|
||||||
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, js)
|
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sitemID string) c.RouteError {
|
func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, u *c.User, sitemID string) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemID, err := strconv.Atoi(sitemID)
|
itemID, err := strconv.Atoi(sitemID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, user, js)
|
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, u, js)
|
||||||
}
|
}
|
||||||
menuItem, err := c.Menus.ItemStore().Get(itemID)
|
menuItem, err := c.Menus.ItemStore().Get(itemID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalErrorJSQ("This item doesn't exist.", w, r, user, js)
|
return c.LocalErrorJSQ("This item doesn't exist.", w, r, u, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
@ -299,7 +299,7 @@ func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.Create("delete", menuItem.ID, "menu_item", user.GetIP(), user.ID)
|
err = c.AdminLogs.Create("delete", menuItem.ID, "menu_item", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -307,23 +307,23 @@ func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.
|
||||||
return successRedirect("/panel/themes/menus/", w, r, js)
|
return successRedirect("/panel/themes/menus/", w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user *c.User, smid string) c.RouteError {
|
func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, u *c.User, smid string) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
mid, err := strconv.Atoi(smid)
|
mid, err := strconv.Atoi(smid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, user, js)
|
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, u, js)
|
||||||
}
|
}
|
||||||
menuHold, err := c.Menus.Get(mid)
|
menuHold, err := c.Menus.Get(mid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalErrorJSQ("Can't find menu", w, r, user, js)
|
return c.LocalErrorJSQ("Can't find menu", w, r, u, js)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
@ -335,13 +335,13 @@ func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user *c.U
|
||||||
for index, smiid := range strings.Split(sitems, ",") {
|
for index, smiid := range strings.Split(sitems, ",") {
|
||||||
miid, err := strconv.Atoi(smiid)
|
miid, err := strconv.Atoi(smiid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ("Invalid integer in menu item list", w, r, user, js)
|
return c.LocalErrorJSQ("Invalid integer in menu item list", w, r, u, js)
|
||||||
}
|
}
|
||||||
updateMap[miid] = index
|
updateMap[miid] = index
|
||||||
}
|
}
|
||||||
menuHold.UpdateOrder(updateMap)
|
menuHold.UpdateOrder(updateMap)
|
||||||
|
|
||||||
err = c.AdminLogs.Create("suborder", menuHold.MenuID, "menu", user.GetIP(), user.ID)
|
err = c.AdminLogs.Create("suborder", menuHold.MenuID, "menu", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -349,13 +349,13 @@ func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user *c.U
|
||||||
return successRedirect("/panel/themes/menus/edit/"+strconv.Itoa(mid), w, r, js)
|
return successRedirect("/panel/themes/menus/edit/"+strconv.Itoa(mid), w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesWidgets(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
func ThemesWidgets(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
basePage, ferr := buildBasePage(w, r, user, "themes_widgets", "themes")
|
basePage, ferr := buildBasePage(w, r, u, "themes_widgets", "themes")
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
basePage.Header.AddScript("widgets.js")
|
basePage.Header.AddScript("widgets.js")
|
||||||
|
|
||||||
|
@ -414,20 +414,20 @@ func widgetsParseInputs(r *http.Request, widget *c.Widget) (*c.WidgetEdit, error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ThemesWidgetsEditSubmit is an action which is triggered when someone sends an update request for a widget
|
// ThemesWidgetsEditSubmit is an action which is triggered when someone sends an update request for a widget
|
||||||
func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, swid string) c.RouteError {
|
func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, u *c.User, swid string) c.RouteError {
|
||||||
//fmt.Println("in ThemesWidgetsEditSubmit")
|
//fmt.Println("in ThemesWidgetsEditSubmit")
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
wid, err := strconv.Atoi(swid)
|
wid, err := strconv.Atoi(swid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, user, js)
|
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, u, js)
|
||||||
}
|
}
|
||||||
widget, err := c.Widgets.Get(wid)
|
widget, err := c.Widgets.Get(wid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
|
@ -438,14 +438,14 @@ func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user *c.Use
|
||||||
|
|
||||||
ewidget, err := widgetsParseInputs(r, widget.Copy())
|
ewidget, err := widgetsParseInputs(r, widget.Copy())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ(err.Error(), w, r, user, js)
|
return c.LocalErrorJSQ(err.Error(), w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ewidget.Commit()
|
err = ewidget.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.Create("edit", widget.ID, "widget", user.GetIP(), user.ID)
|
err = c.AdminLogs.Create("edit", widget.ID, "widget", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -454,25 +454,25 @@ func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user *c.Use
|
||||||
}
|
}
|
||||||
|
|
||||||
// ThemesWidgetsCreateSubmit is an action which is triggered when someone sends a create request for a widget
|
// ThemesWidgetsCreateSubmit is an action which is triggered when someone sends a create request for a widget
|
||||||
func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
|
func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
ewidget, err := widgetsParseInputs(r, &c.Widget{})
|
ewidget, err := widgetsParseInputs(r, &c.Widget{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ(err.Error(), w, r, user, js)
|
return c.LocalErrorJSQ(err.Error(), w, r, u, js)
|
||||||
}
|
}
|
||||||
wid, err := ewidget.Create()
|
wid, err := ewidget.Create()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.Create("create", wid, "widget", user.GetIP(), user.ID)
|
err = c.AdminLogs.Create("create", wid, "widget", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -480,19 +480,19 @@ func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.U
|
||||||
return successRedirect("/panel/themes/widgets/", w, r, js)
|
return successRedirect("/panel/themes/widgets/", w, r, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, swid string) c.RouteError {
|
func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, u *c.User, swid string) c.RouteError {
|
||||||
_, ferr := c.SimplePanelUserCheck(w, r, user)
|
_, ferr := c.SimplePanelUserCheck(w, r, u)
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
if !user.Perms.ManageThemes {
|
if !u.Perms.ManageThemes {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
wid, err := strconv.Atoi(swid)
|
wid, err := strconv.Atoi(swid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, user, js)
|
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, u, js)
|
||||||
}
|
}
|
||||||
widget, err := c.Widgets.Get(wid)
|
widget, err := c.Widgets.Get(wid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
|
@ -504,7 +504,7 @@ func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.U
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = c.AdminLogs.Create("delete", widget.ID, "widget", user.GetIP(), user.ID)
|
err = c.AdminLogs.Create("delete", widget.ID, "widget", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,9 +110,49 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Head
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canMessage := (!blockedInv && user.Perms.UseConvos) || (!blockedInv && puser.IsSuperMod && user.Perms.UseConvosOnlyWithMod) || user.IsSuperMod
|
canMessage := (!blockedInv && user.Perms.UseConvos) || (!blockedInv && puser.IsSuperMod && user.Perms.UseConvosOnlyWithMod) || user.IsSuperMod
|
||||||
canComment := !blockedInv && user.Perms.CreateProfileReply
|
canComment := !blockedInv && user.Perms.CreateProfileReply
|
||||||
|
showComments := profileCommentsShow(puser, user)
|
||||||
|
if !showComments {
|
||||||
|
canComment = false
|
||||||
|
}
|
||||||
|
if !profileAllowMessage(puser, user) {
|
||||||
|
canMessage = false
|
||||||
|
}
|
||||||
|
|
||||||
ppage := c.ProfilePage{h, reList, *puser, currentScore, nextScore, blocked, canMessage, canComment}
|
ppage := c.ProfilePage{h, reList, *puser, currentScore, nextScore, blocked, canMessage, canComment, showComments}
|
||||||
return renderTemplate("profile", w, r, h, ppage)
|
return renderTemplate("profile", w, r, h, ppage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func profileAllowMessage(pu, u *c.User) (canMsg bool) {
|
||||||
|
switch pu.Privacy.AllowMessage {
|
||||||
|
case 4: // Unused
|
||||||
|
canMsg = false
|
||||||
|
case 3: // mods / self
|
||||||
|
canMsg = u.IsSuperMod
|
||||||
|
//case 2: // friends
|
||||||
|
case 1: // registered
|
||||||
|
canMsg = true
|
||||||
|
default: // 0
|
||||||
|
canMsg = true
|
||||||
|
}
|
||||||
|
return canMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
func profileCommentsShow(pu, u *c.User) (showComments bool) {
|
||||||
|
switch pu.Privacy.ShowComments {
|
||||||
|
case 5: // Unused
|
||||||
|
showComments = false
|
||||||
|
case 4: // Self
|
||||||
|
showComments = u.ID == pu.ID
|
||||||
|
//case 3: // friends
|
||||||
|
case 2: // registered
|
||||||
|
showComments = u.Loggedin
|
||||||
|
case 1: // public
|
||||||
|
showComments = true
|
||||||
|
default: // 0
|
||||||
|
showComments = true
|
||||||
|
}
|
||||||
|
return showComments
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.Us
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError("Invalid UID", w, r, user)
|
return c.LocalError("Invalid UID", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
profileOwner, err := c.Users.Get(uid)
|
profileOwner, err := c.Users.Get(uid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The profile you're trying to post on doesn't exist.", w, r, user)
|
return c.LocalError("The profile you're trying to post on doesn't exist.", w, r, user)
|
||||||
|
@ -30,7 +29,7 @@ func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.Us
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
// Supermods can bypass blocks so they can tell people off when they do something stupid or have to convey important information
|
// Supermods can bypass blocks so they can tell people off when they do something stupid or have to convey important information
|
||||||
if blocked && !user.IsSuperMod {
|
if (blocked || !profileCommentsShow(profileOwner, user)) && !user.IsSuperMod {
|
||||||
return c.LocalError("You don't have permission to send messages to one of these users.", w, r, user)
|
return c.LocalError("You don't have permission to send messages to one of these users.", w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,13 +55,12 @@ func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.Us
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, srid string) c.RouteError {
|
func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid string) c.RouteError {
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := c.Prstore.Get(rid)
|
reply, err := c.Prstore.Get(rid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, js)
|
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, js)
|
||||||
|
@ -74,34 +72,41 @@ func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
if !user.Perms.CreateProfileReply {
|
if !u.Perms.CreateProfileReply {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
// ? Does the admin understand that this group perm affects this?
|
// ? Does the admin understand that this group perm affects this?
|
||||||
if user.ID != creator.ID && !user.Perms.EditReply {
|
if u.ID != creator.ID && !u.Perms.EditReply {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Stop blocked users from modifying profile replies?
|
profileOwner, err := c.Users.Get(reply.ParentID)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return c.LocalError("The profile you're trying to edit a post on doesn't exist.", w, r, u)
|
||||||
|
} else if err != nil {
|
||||||
|
return c.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
blocked, err := c.UserBlocks.IsBlockedBy(profileOwner.ID, u.ID)
|
||||||
|
if err != nil {
|
||||||
|
return c.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
// Supermods can bypass blocks so they can tell people off when they do something stupid or have to convey important information
|
||||||
|
if (blocked || !profileCommentsShow(profileOwner, u)) && !u.IsSuperMod {
|
||||||
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
|
}
|
||||||
|
|
||||||
err = reply.SetBody(r.PostFormValue("edit_item"))
|
err = reply.SetBody(r.PostFormValue("edit_item"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
return actionSuccess(w, r, "/user/"+strconv.Itoa(creator.ID)+"#reply-"+strconv.Itoa(rid), js)
|
||||||
if !js {
|
|
||||||
http.Redirect(w, r, "/user/"+strconv.Itoa(creator.ID)+"#reply-"+strconv.Itoa(rid), http.StatusSeeOther)
|
|
||||||
} else {
|
|
||||||
w.Write(successJSONBytes)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, srid string) c.RouteError {
|
func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid string) c.RouteError {
|
||||||
js := r.PostFormValue("js") == "1"
|
js := r.PostFormValue("js") == "1"
|
||||||
rid, err := strconv.Atoi(srid)
|
rid, err := strconv.Atoi(srid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, user, js)
|
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
reply, err := c.Prstore.Get(rid)
|
reply, err := c.Prstore.Get(rid)
|
||||||
|
@ -115,15 +120,15 @@ func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.Us
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
if user.ID != creator.ID && !user.Perms.DeleteReply {
|
if u.ID != creator.ID && !u.Perms.DeleteReply {
|
||||||
return c.NoPermissionsJSQ(w, r, user, js)
|
return c.NoPermissionsJSQ(w, r, u, js)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reply.Delete()
|
err = reply.Delete()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
//log.Printf("The profile post '%d' was deleted by c.User #%d", reply.ID, user.ID)
|
//log.Printf("The profile post '%d' was deleted by c.User #%d", reply.ID, u.ID)
|
||||||
|
|
||||||
if !js {
|
if !js {
|
||||||
//http.Redirect(w,r, "/user/" + strconv.Itoa(creator.ID), http.StatusSeeOther)
|
//http.Redirect(w,r, "/user/" + strconv.Itoa(creator.ID), http.StatusSeeOther)
|
||||||
|
@ -131,7 +136,7 @@ func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.Us
|
||||||
w.Write(successJSONBytes)
|
w.Write(successJSONBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.ModLogs.Create("delete", reply.ParentID, "profile-reply", user.GetIP(), user.ID)
|
err = c.ModLogs.Create("delete", reply.ParentID, "profile-reply", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalErrorJSQ(err, w, r, js)
|
return c.InternalErrorJSQ(err, w, r, js)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,46 +9,46 @@ import (
|
||||||
c "github.com/Azareal/Gosora/common"
|
c "github.com/Azareal/Gosora/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BanUserSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
|
func BanUserSubmit(w http.ResponseWriter, r *http.Request, u *c.User, suid string) c.RouteError {
|
||||||
if !user.Perms.BanUsers {
|
if !u.Perms.BanUsers {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
uid, err := strconv.Atoi(suid)
|
uid, err := strconv.Atoi(suid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError("The provided UserID is not a valid number.", w, r, user)
|
return c.LocalError("The provided UserID is not a valid number.", w, r, u)
|
||||||
}
|
}
|
||||||
if uid == -2 {
|
if uid == -2 {
|
||||||
return c.LocalError("Why don't you like Merlin?", w, r, user)
|
return c.LocalError("Why don't you like Merlin?", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser, err := c.Users.Get(uid)
|
targetUser, err := c.Users.Get(uid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to ban no longer exists.", w, r, user)
|
return c.LocalError("The user you're trying to ban no longer exists.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
// TODO: Is there a difference between IsMod and IsSuperMod? Should we delete the redundant one?
|
// TODO: Is there a difference between IsMod and IsSuperMod? Should we delete the redundant one?
|
||||||
if targetUser.IsMod {
|
if targetUser.IsMod {
|
||||||
return c.LocalError("You may not ban another staff member.", w, r, user)
|
return c.LocalError("You may not ban another staff member.", w, r, u)
|
||||||
}
|
}
|
||||||
if uid == user.ID {
|
if uid == u.ID {
|
||||||
return c.LocalError("Why are you trying to ban yourself? Stop that.", w, r, user)
|
return c.LocalError("Why are you trying to ban yourself? Stop that.", w, r, u)
|
||||||
}
|
}
|
||||||
if targetUser.IsBanned {
|
if targetUser.IsBanned {
|
||||||
return c.LocalError("The user you're trying to unban is already banned.", w, r, user)
|
return c.LocalError("The user you're trying to unban is already banned.", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
durDays, err := strconv.Atoi(r.FormValue("dur-days"))
|
durDays, err := strconv.Atoi(r.FormValue("dur-days"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError("You can only use whole numbers for the number of days", w, r, user)
|
return c.LocalError("You can only use whole numbers for the number of days", w, r, u)
|
||||||
}
|
}
|
||||||
durWeeks, err := strconv.Atoi(r.FormValue("dur-weeks"))
|
durWeeks, err := strconv.Atoi(r.FormValue("dur-weeks"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError("You can only use whole numbers for the number of weeks", w, r, user)
|
return c.LocalError("You can only use whole numbers for the number of weeks", w, r, u)
|
||||||
}
|
}
|
||||||
durMonths, err := strconv.Atoi(r.FormValue("dur-months"))
|
durMonths, err := strconv.Atoi(r.FormValue("dur-months"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError("You can only use whole numbers for the number of months", w, r, user)
|
return c.LocalError("You can only use whole numbers for the number of months", w, r, u)
|
||||||
}
|
}
|
||||||
deletePosts := false
|
deletePosts := false
|
||||||
switch r.FormValue("delete-posts") {
|
switch r.FormValue("delete-posts") {
|
||||||
|
@ -67,13 +67,13 @@ func BanUserSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid st
|
||||||
dur, _ = time.ParseDuration(strconv.Itoa(secs) + "s")
|
dur, _ = time.ParseDuration(strconv.Itoa(secs) + "s")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = targetUser.Ban(dur, user.ID)
|
err = targetUser.Ban(dur, u.ID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to ban no longer exists.", w, r, user)
|
return c.LocalError("The user you're trying to ban no longer exists.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = c.ModLogs.Create("ban", uid, "user", user.GetIP(), user.ID)
|
err = c.ModLogs.Create("ban", uid, "user", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -81,11 +81,11 @@ func BanUserSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid st
|
||||||
if deletePosts {
|
if deletePosts {
|
||||||
err = targetUser.DeletePosts()
|
err = targetUser.DeletePosts()
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to ban no longer exists.", w, r, user)
|
return c.LocalError("The user you're trying to ban no longer exists.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = c.ModLogs.Create("delete-posts", uid, "user", user.GetIP(), user.ID)
|
err = c.ModLogs.Create("delete-posts", uid, "user", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ func BanUserSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid st
|
||||||
|
|
||||||
// TODO: Trickle the hookTable down from the router
|
// TODO: Trickle the hookTable down from the router
|
||||||
hTbl := c.GetHookTable()
|
hTbl := c.GetHookTable()
|
||||||
skip, rerr := hTbl.VhookSkippable("action_end_ban_user", targetUser.ID, user)
|
skip, rerr := hTbl.VhookSkippable("action_end_ban_user", targetUser.ID, u)
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
@ -102,42 +102,42 @@ func BanUserSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid st
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UnbanUser(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
|
func UnbanUser(w http.ResponseWriter, r *http.Request, u *c.User, suid string) c.RouteError {
|
||||||
if !user.Perms.BanUsers {
|
if !u.Perms.BanUsers {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
uid, err := strconv.Atoi(suid)
|
uid, err := strconv.Atoi(suid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError("The provided UserID is not a valid number.", w, r, user)
|
return c.LocalError("The provided UserID is not a valid number.", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser, err := c.Users.Get(uid)
|
targetUser, err := c.Users.Get(uid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to unban no longer exists.", w, r, user)
|
return c.LocalError("The user you're trying to unban no longer exists.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
if !targetUser.IsBanned {
|
if !targetUser.IsBanned {
|
||||||
return c.LocalError("The user you're trying to unban isn't banned.", w, r, user)
|
return c.LocalError("The user you're trying to unban isn't banned.", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = targetUser.Unban()
|
err = targetUser.Unban()
|
||||||
if err == c.ErrNoTempGroup {
|
if err == c.ErrNoTempGroup {
|
||||||
return c.LocalError("The user you're trying to unban is not banned", w, r, user)
|
return c.LocalError("The user you're trying to unban is not banned", w, r, u)
|
||||||
} else if err == sql.ErrNoRows {
|
} else if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to unban no longer exists.", w, r, user)
|
return c.LocalError("The user you're trying to unban no longer exists.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.ModLogs.Create("unban", uid, "user", user.GetIP(), user.ID)
|
err = c.ModLogs.Create("unban", uid, "user", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Trickle the hookTable down from the router
|
// TODO: Trickle the hookTable down from the router
|
||||||
hTbl := c.GetHookTable()
|
hTbl := c.GetHookTable()
|
||||||
skip, rerr := hTbl.VhookSkippable("action_end_unban_user", targetUser.ID, user)
|
skip, rerr := hTbl.VhookSkippable("action_end_unban_user", targetUser.ID, u)
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
@ -146,23 +146,23 @@ func UnbanUser(w http.ResponseWriter, r *http.Request, user *c.User, suid string
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ActivateUser(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
|
func ActivateUser(w http.ResponseWriter, r *http.Request, u *c.User, suid string) c.RouteError {
|
||||||
if !user.Perms.ActivateUsers {
|
if !u.Perms.ActivateUsers {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
uid, err := strconv.Atoi(suid)
|
uid, err := strconv.Atoi(suid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError("The provided UserID is not a valid number.", w, r, user)
|
return c.LocalError("The provided UserID is not a valid number.", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser, err := c.Users.Get(uid)
|
targetUser, err := c.Users.Get(uid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The account you're trying to activate no longer exists.", w, r, user)
|
return c.LocalError("The account you're trying to activate no longer exists.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
if targetUser.Active {
|
if targetUser.Active {
|
||||||
return c.LocalError("The account you're trying to activate has already been activated.", w, r, user)
|
return c.LocalError("The account you're trying to activate has already been activated.", w, r, u)
|
||||||
}
|
}
|
||||||
err = targetUser.Activate()
|
err = targetUser.Activate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -171,7 +171,7 @@ func ActivateUser(w http.ResponseWriter, r *http.Request, user *c.User, suid str
|
||||||
|
|
||||||
targetUser, err = c.Users.Get(uid)
|
targetUser, err = c.Users.Get(uid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The account you're trying to activate no longer exists.", w, r, user)
|
return c.LocalError("The account you're trying to activate no longer exists.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
@ -181,14 +181,14 @@ func ActivateUser(w http.ResponseWriter, r *http.Request, user *c.User, suid str
|
||||||
}
|
}
|
||||||
targetUser.CacheRemove()
|
targetUser.CacheRemove()
|
||||||
|
|
||||||
err = c.ModLogs.Create("activate", targetUser.ID, "user", user.GetIP(), user.ID)
|
err = c.ModLogs.Create("activate", targetUser.ID, "user", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Trickle the hookTable down from the router
|
// TODO: Trickle the hookTable down from the router
|
||||||
hTbl := c.GetHookTable()
|
hTbl := c.GetHookTable()
|
||||||
skip, rerr := hTbl.VhookSkippable("action_end_activate_user", targetUser.ID, user)
|
skip, rerr := hTbl.VhookSkippable("action_end_activate_user", targetUser.ID, u)
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
@ -197,40 +197,40 @@ func ActivateUser(w http.ResponseWriter, r *http.Request, user *c.User, suid str
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeletePostsSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
|
func DeletePostsSubmit(w http.ResponseWriter, r *http.Request, u *c.User, suid string) c.RouteError {
|
||||||
if !user.Perms.BanUsers {
|
if !u.Perms.BanUsers {
|
||||||
return c.NoPermissions(w, r, user)
|
return c.NoPermissions(w, r, u)
|
||||||
}
|
}
|
||||||
uid, err := strconv.Atoi(suid)
|
uid, err := strconv.Atoi(suid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.LocalError("The provided UserID is not a valid number.", w, r, user)
|
return c.LocalError("The provided UserID is not a valid number.", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser, err := c.Users.Get(uid)
|
targetUser, err := c.Users.Get(uid)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to purge posts of no longer exists.", w, r, user)
|
return c.LocalError("The user you're trying to purge posts of no longer exists.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
// TODO: Is there a difference between IsMod and IsSuperMod? Should we delete the redundant one?
|
// TODO: Is there a difference between IsMod and IsSuperMod? Should we delete the redundant one?
|
||||||
if targetUser.IsMod {
|
if targetUser.IsMod {
|
||||||
return c.LocalError("You may not purge the posts of another staff member.", w, r, user)
|
return c.LocalError("You may not purge the posts of another staff member.", w, r, u)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = targetUser.DeletePosts()
|
err = targetUser.DeletePosts()
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return c.LocalError("The user you're trying to purge posts of no longer exists.", w, r, user)
|
return c.LocalError("The user you're trying to purge posts of no longer exists.", w, r, u)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
err = c.ModLogs.Create("delete-posts", uid, "user", user.GetIP(), user.ID)
|
err = c.ModLogs.Create("delete-posts", uid, "user", u.GetIP(), u.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.InternalError(err, w, r)
|
return c.InternalError(err, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Trickle the hookTable down from the router
|
// TODO: Trickle the hookTable down from the router
|
||||||
hTbl := c.GetHookTable()
|
hTbl := c.GetHookTable()
|
||||||
skip, rerr := hTbl.VhookSkippable("action_end_delete_posts", targetUser.ID, user)
|
skip, rerr := hTbl.VhookSkippable("action_end_delete_posts", targetUser.ID, u)
|
||||||
if skip || rerr != nil {
|
if skip || rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
CREATE TABLE `login_logs` (
|
CREATE TABLE `login_logs` (
|
||||||
`lid` int not null AUTO_INCREMENT,
|
`lid` int not null AUTO_INCREMENT,
|
||||||
`uid` int not null,
|
`uid` int not null,
|
||||||
`success` bool DEFAULT 0 not null,
|
`success` boolean DEFAULT 0 not null,
|
||||||
`ipaddress` varchar(200) not null,
|
`ipaddress` varchar(200) not null,
|
||||||
`doneAt` datetime not null,
|
`doneAt` datetime not null,
|
||||||
primary key(`lid`)
|
primary key(`lid`)
|
||||||
|
|
|
@ -3,7 +3,7 @@ CREATE TABLE `registration_logs` (
|
||||||
`username` varchar(100) not null,
|
`username` varchar(100) not null,
|
||||||
`email` varchar(100) not null,
|
`email` varchar(100) not null,
|
||||||
`failureReason` varchar(100) not null,
|
`failureReason` varchar(100) not null,
|
||||||
`success` bool DEFAULT 0 not null,
|
`success` boolean DEFAULT 0 not null,
|
||||||
`ipaddress` varchar(200) not null,
|
`ipaddress` varchar(200) not null,
|
||||||
`doneAt` datetime not null,
|
`doneAt` datetime not null,
|
||||||
primary key(`rlid`)
|
primary key(`rlid`)
|
||||||
|
|
|
@ -10,6 +10,8 @@ CREATE TABLE `users` (
|
||||||
`lastActiveAt` datetime not null,
|
`lastActiveAt` datetime not null,
|
||||||
`session` varchar(200) DEFAULT '' not null,
|
`session` varchar(200) DEFAULT '' not null,
|
||||||
`last_ip` varchar(200) DEFAULT '' not null,
|
`last_ip` varchar(200) DEFAULT '' not null,
|
||||||
|
`profile_comments` int DEFAULT 0 not null,
|
||||||
|
`who_can_convo` int DEFAULT 0 not null,
|
||||||
`enable_embeds` int DEFAULT -1 not null,
|
`enable_embeds` int DEFAULT -1 not null,
|
||||||
`email` varchar(200) DEFAULT '' not null,
|
`email` varchar(200) DEFAULT '' not null,
|
||||||
`avatar` varchar(100) DEFAULT '' not null,
|
`avatar` varchar(100) DEFAULT '' not null,
|
||||||
|
|
|
@ -2,6 +2,6 @@ CREATE TABLE "forums_permissions" (
|
||||||
`fid` int not null,
|
`fid` int not null,
|
||||||
`gid` int not null,
|
`gid` int not null,
|
||||||
`preset` varchar (100) DEFAULT '' not null,
|
`preset` varchar (100) DEFAULT '' not null,
|
||||||
`permissions` text not null,
|
`permissions` text DEFAULT '{}' not null,
|
||||||
primary key(`fid`,`gid`)
|
primary key(`fid`,`gid`)
|
||||||
);
|
);
|
|
@ -1,7 +1,7 @@
|
||||||
CREATE TABLE "login_logs" (
|
CREATE TABLE "login_logs" (
|
||||||
`lid` serial not null,
|
`lid` serial not null,
|
||||||
`uid` int not null,
|
`uid` int not null,
|
||||||
`success` bool DEFAULT 0 not null,
|
`success` boolean DEFAULT 0 not null,
|
||||||
`ipaddress` varchar (200) not null,
|
`ipaddress` varchar (200) not null,
|
||||||
`doneAt` timestamp not null,
|
`doneAt` timestamp not null,
|
||||||
primary key(`lid`)
|
primary key(`lid`)
|
||||||
|
|
|
@ -3,7 +3,7 @@ CREATE TABLE "registration_logs" (
|
||||||
`username` varchar (100) not null,
|
`username` varchar (100) not null,
|
||||||
`email` varchar (100) not null,
|
`email` varchar (100) not null,
|
||||||
`failureReason` varchar (100) not null,
|
`failureReason` varchar (100) not null,
|
||||||
`success` bool DEFAULT 0 not null,
|
`success` boolean DEFAULT 0 not null,
|
||||||
`ipaddress` varchar (200) not null,
|
`ipaddress` varchar (200) not null,
|
||||||
`doneAt` timestamp not null,
|
`doneAt` timestamp not null,
|
||||||
primary key(`rlid`)
|
primary key(`rlid`)
|
||||||
|
|
|
@ -3,17 +3,18 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item the_form">
|
<div class="colstack_item the_form">
|
||||||
<form action="/user/edit/privacy/submit/?s={{.CurrentUser.Session}}" method="post">
|
<form action="/user/edit/privacy/submit/?s={{.CurrentUser.Session}}" method="post">
|
||||||
<!--<input name="o_profile_comments" value="{{if .ProfileComments}}1{{else}}0{{end}}" type="hidden">
|
<input name="o_profile_comments" value="{{.ProfileComments}}" type="hidden">
|
||||||
<input name="o_receive_convos" value="{{if .ReceiveConvos}}1{{else}}0{{end}}" type="hidden">-->
|
<!--<input name="o_receive_convos" value="{{if .ReceiveConvos}}1{{else}}0{{end}}" type="hidden">-->
|
||||||
<input name="o_enable_embeds" value="{{if .EnableEmbeds}}1{{else}}0{{end}}" type="hidden">
|
<input name="o_enable_embeds" value="{{if .EnableEmbeds}}1{{else}}0{{end}}" type="hidden">
|
||||||
<!--<div class="formrow real_first_child">
|
<div class="formrow real_first_child">
|
||||||
<div class="formitem formlabel">{{lang "account_privacy_profile_comments"}}</div>
|
<div class="formitem formlabel">{{lang "account_privacy_profile_comments"}}</div>
|
||||||
<div class="formitem"><select name="profile_comments">
|
<div class="formitem"><select name="profile_comments">
|
||||||
<option{{if .ProfileComments}} selected{{end}} value=1>{{lang "option_yes"}}</option>
|
<option{{if eq .ProfileComments 1}} selected{{end}} value=1>{{lang "account_privacy_profile_comments_public"}}</option>
|
||||||
<option{{if not .ProfileComments}} selected{{end}} value=0>{{lang "option_no"}}</option>
|
<option{{if eq .ProfileComments 2}} selected{{end}} value=2>{{lang "account_privacy_profile_comments_registered"}}</option>
|
||||||
|
<option{{if eq .ProfileComments 4}} selected{{end}} value=4>{{lang "account_privacy_profile_comments_self"}}</option>
|
||||||
</select></div>
|
</select></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<!--<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>Receive Conversations</a></div>
|
<div class="formitem formlabel"><a>Receive Conversations</a></div>
|
||||||
<div class="formitem"><select name="receive_convos">
|
<div class="formitem"><select name="receive_convos">
|
||||||
<option{{if .ReceiveConvos}} selected{{end}} value=1>{{lang "option_yes"}}</option>
|
<option{{if .ReceiveConvos}} selected{{end}} value=1>{{lang "option_yes"}}</option>
|
||||||
|
@ -21,7 +22,7 @@
|
||||||
</select></div>
|
</select></div>
|
||||||
</div>-->
|
</div>-->
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>Enable Embeds</a></div>
|
<div class="formitem formlabel"><a>{{lang "account_privacy_enable_embeds"}}</a></div>
|
||||||
<div class="formitem"><select name="enable_embeds">
|
<div class="formitem"><select name="enable_embeds">
|
||||||
<option{{if .EnableEmbeds}} selected{{end}} value=1>{{lang "option_yes"}}</option>
|
<option{{if .EnableEmbeds}} selected{{end}} value=1>{{lang "option_yes"}}</option>
|
||||||
<option{{if not .EnableEmbeds}} selected{{end}} value=0>{{lang "option_no"}}</option>
|
<option{{if not .EnableEmbeds}} selected{{end}} value=0>{{lang "option_no"}}</option>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{{template "header.html" . }}
|
{{template "header.html" . }}
|
||||||
<main id="forumItemList" itemscope itemtype="http://schema.org/ItemList">
|
<main id="forumItemList"itemscope itemtype="http://schema.org/ItemList">
|
||||||
<link rel="canonical" href="//{{.Site.URL}}{{.Forum.Link}}{{if gt .Page 1}}?page={{.Page}}{{end}}"/>
|
<link rel="canonical"href="//{{.Site.URL}}{{.Forum.Link}}{{if gt .Page 1}}?page={{.Page}}{{end}}">
|
||||||
|
|
||||||
<div id="forum_head_block" class="rowblock rowhead topic_list_title_block{{if .CurrentUser.Loggedin}} has_opt{{end}}">
|
<div id="forum_head_block"class="rowblock rowhead topic_list_title_block{{if .CurrentUser.Loggedin}} has_opt{{end}}">
|
||||||
<div class="rowitem forum_title">
|
<div class="rowitem forum_title">
|
||||||
<h1 itemprop="name">{{.Title}}</h1>
|
<h1 itemprop="name">{{.Title}}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_stats_active_memory_head"}}</h1>
|
<h1>{{lang "panel_stats_active_memory_head"}}</h1>
|
||||||
<select form="timeRangeForm" class="typeSelector to_right autoSubmitRedirect" name="mtype">
|
<select form="timeRangeForm"class="typeSelector to_right autoSubmitRedirect"name="mtype">
|
||||||
<option value="0"{{if eq .MemType 0}} selected{{end}}>{{lang "panel_stats_memory_type_total"}}</option>
|
<option value="0"{{if eq .MemType 0}}selected{{end}}>{{lang "panel_stats_memory_type_total"}}</option>
|
||||||
<option value="1"{{if eq .MemType 1}} selected{{end}}>{{lang "panel_stats_memory_type_stack"}}</option>
|
<option value="1"{{if eq .MemType 1}}selected{{end}}>{{lang "panel_stats_memory_type_stack"}}</option>
|
||||||
<option value="2"{{if eq .MemType 2}} selected{{end}}>{{lang "panel_stats_memory_type_heap"}}</option>
|
<option value="2"{{if eq .MemType 2}}selected{{end}}>{{lang "panel_stats_memory_type_heap"}}</option>
|
||||||
</select>
|
</select>
|
||||||
<noscript><input form="timeRangeForm" type="submit"></noscript>
|
<noscript><input form="timeRangeForm"type="submit"></noscript>
|
||||||
{{template "panel_analytics_time_range_month.html" . }}
|
{{template "panel_analytics_time_range_month.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/active-memory/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/active-memory/"method="get"></form>
|
||||||
<div id="panel_analytics_memory" class="colstack_graph_holder">
|
<div id="panel_analytics_memory"class="colstack_graph_holder">
|
||||||
<div class="ct_chart" aria-label="{{lang "panel_stats_memory_chart_aria"}}"></div>
|
<div class="ct_chart"aria-label="{{lang "panel_stats_memory_chart_aria"}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_stats_details_head"}}</h1>
|
<h1>{{lang "panel_stats_details_head"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_memory_table" class="colstack_item rowlist" aria-label="{{lang "panel_stats_memory_table_aria"}}">
|
<div id="panel_analytics_memory_table"class="colstack_item rowlist"aria-label="{{lang "panel_stats_memory_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift unix_to_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}24_hour_time{{else}}date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_to_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}24_hour_time{{else}}date{{end}}">{{.Time}}</a>
|
||||||
|
|
|
@ -4,16 +4,16 @@
|
||||||
{{template "panel_analytics_time_range_month.html" . }}
|
{{template "panel_analytics_time_range_month.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/memory/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/memory/"method="get"></form>
|
||||||
<div id="panel_analytics_memory" class="colstack_graph_holder">
|
<div id="panel_analytics_memory"class="colstack_graph_holder">
|
||||||
<div class="ct_chart" aria-label="{{lang "panel_stats_memory_chart_aria"}}"></div>
|
<div class="ct_chart"aria-label="{{lang "panel_stats_memory_chart_aria"}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_stats_details_head"}}</h1>
|
<h1>{{lang "panel_stats_details_head"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_memory_table" class="colstack_item rowlist" aria-label="{{lang "panel_stats_memory_table_aria"}}">
|
<div id="panel_analytics_memory_table"class="colstack_item rowlist"aria-label="{{lang "panel_stats_memory_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_stats_perf_head"}}</h1>
|
<h1>{{lang "panel_stats_perf_head"}}</h1>
|
||||||
<select form="timeRangeForm" class="typeSelector to_right autoSubmitRedirect" name="type">
|
<select form="timeRangeForm"class="typeSelector to_right autoSubmitRedirect" name="type">
|
||||||
<option value="0"{{if eq .PerfType 0}} selected{{end}}>{{lang "panel_stats_perf_low"}}</option>
|
<option value="0"{{if eq .PerfType 0}}selected{{end}}>{{lang "panel_stats_perf_low"}}</option>
|
||||||
<option value="1"{{if eq .PerfType 1}} selected{{end}}>{{lang "panel_stats_perf_high"}}</option>
|
<option value="1"{{if eq .PerfType 1}}selected{{end}}>{{lang "panel_stats_perf_high"}}</option>
|
||||||
<option value="2"{{if eq .PerfType 2}} selected{{end}}>{{lang "panel_stats_perf_avg"}}</option>
|
<option value="2"{{if eq .PerfType 2}}selected{{end}}>{{lang "panel_stats_perf_avg"}}</option>
|
||||||
</select>
|
</select>
|
||||||
<noscript><input form="timeRangeForm" type="submit"></noscript>
|
<noscript><input form="timeRangeForm"type="submit"></noscript>
|
||||||
{{template "panel_analytics_time_range_month.html" . }}
|
{{template "panel_analytics_time_range_month.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/perf/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/perf/" method="get"></form>
|
||||||
<div id="panel_analytics_memory" class="colstack_graph_holder">
|
<div id="panel_analytics_memory"class="colstack_graph_holder">
|
||||||
<div class="ct_chart" aria-label="{{lang "panel_stats_perf_chart_aria"}}"></div>
|
<div class="ct_chart"aria-label="{{lang "panel_stats_perf_chart_aria"}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_stats_details_head"}}</h1>
|
<h1>{{lang "panel_stats_details_head"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_perf_table" class="colstack_item rowlist" aria-label="{{lang "panel_stats_perf_table_aria"}}">
|
<div id="panel_analytics_perf_table"class="colstack_item rowlist"aria-label="{{lang "panel_stats_perf_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift unix_to_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}24_hour_time{{else}}date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_to_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}24_hour_time{{else}}date{{end}}">{{.Time}}</a>
|
||||||
|
|
|
@ -4,16 +4,16 @@
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/posts/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/posts/"method="get"></form>
|
||||||
<div id="panel_analytics_posts" class="colstack_graph_holder">
|
<div id="panel_analytics_posts"class="colstack_graph_holder">
|
||||||
<div class="ct_chart" aria-label="{{lang "panel_stats_post_counts_chart_aria"}}"></div>
|
<div class="ct_chart"aria-label="{{lang "panel_stats_post_counts_chart_aria"}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_stats_details_head"}}</h1>
|
<h1>{{lang "panel_stats_details_head"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_posts_table" class="colstack_item rowlist" aria-label="{{lang "panel_stats_post_counts_table_aria"}}">
|
<div id="panel_analytics_posts_table"class="colstack_item rowlist"aria-label="{{lang "panel_stats_post_counts_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}to_24_hour_time{{else}}to_date{{end}}">{{.Time}}</a>
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/referrer/{{.Agent}}" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/referrer/{{.Agent}}"method="get"></form>
|
||||||
<div id="panel_analytics_referrers" class="colstack_graph_holder">
|
<div id="panel_analytics_referrers"class="colstack_graph_holder">
|
||||||
<div class="ct_chart"></div>
|
<div class="ct_chart"></div>
|
||||||
</div>
|
</div>
|
||||||
{{template "panel_analytics_script.html" . }}
|
{{template "panel_analytics_script.html" . }}
|
|
@ -1,19 +1,19 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_stats_referrers_head"}}</h1>
|
<h1>{{lang "panel_stats_referrers_head"}}</h1>
|
||||||
<select form="timeRangeForm" class="spamSelector to_right autoSubmitRedirect" name="spam">
|
<select form="timeRangeForm"class="spamSelector to_right autoSubmitRedirect"name="spam">
|
||||||
<option value="0"{{if not .ShowSpam}} selected{{end}}>{{lang "panel_stats_spam_hide"}}</option>
|
<option value="0"{{if not .ShowSpam}}selected{{end}}>{{lang "panel_stats_spam_hide"}}</option>
|
||||||
<option value="1"{{if .ShowSpam}} selected{{end}}>{{lang "panel_stats_spam_show"}}</option>
|
<option value="1"{{if .ShowSpam}}selected{{end}}>{{lang "panel_stats_spam_show"}}</option>
|
||||||
</select>
|
</select>
|
||||||
<noscript><input form="timeRangeForm" type="submit"></noscript>
|
<noscript><input form="timeRangeForm"type="submit"></noscript>
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/referrers/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/referrers/"method="get"></form>
|
||||||
<div id="panel_analytics_referrers" class="colstack_item rowlist">
|
<div id="panel_analytics_referrers"class="colstack_item rowlist">
|
||||||
{{range .ItemList}}
|
{{range .ItemList}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a href="/panel/analytics/referrer/{{.Agent}}" class="panel_upshift">{{.Agent}}</a>
|
<a href="/panel/analytics/referrer/{{.Agent}}"class="panel_upshift">{{.Agent}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_stats_views_suffix"}}</span>
|
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_stats_views_suffix"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_stats_referrers_no_referrers"}}</div>{{end}}
|
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_stats_referrers_no_referrers"}}</div>{{end}}
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/route/{{.Route}}" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/route/{{.Route}}"method="get"></form>
|
||||||
<div id="panel_analytics_views" class="colstack_graph_holder">
|
<div id="panel_analytics_views"class="colstack_graph_holder">
|
||||||
<div class="ct_chart"></div>
|
<div class="ct_chart"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><a>{{lang "panel_stats_details_head"}}</a></div>
|
<div class="rowitem"><a>{{lang "panel_stats_details_head"}}</a></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_views_table" class="colstack_item rowlist" aria-label="{{lang "panel_stats_route_views_table_aria"}}">
|
<div id="panel_analytics_views_table"class="colstack_item rowlist"aria-label="{{lang "panel_stats_route_views_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift unix_to_24_hour_time">{{.Time}}</a>
|
<a class="panel_upshift unix_to_24_hour_time">{{.Time}}</a>
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/routes/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/routes/"method="get"></form>
|
||||||
<div id="panel_analytics_routes_chart" class="colstack_graph_holder">
|
<div id="panel_analytics_routes_chart"class="colstack_graph_holder">
|
||||||
<div class="ct_chart"></div>
|
<div class="ct_chart"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_routes" class="colstack_item rowlist">
|
<div id="panel_analytics_routes"class="colstack_item rowlist">
|
||||||
{{range .ItemList}}
|
{{range .ItemList}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a href="/panel/analytics/route/{{.Route}}" class="panel_upshift">{{.Route}}</a>
|
<a href="/panel/analytics/route/{{.Route}}"class="panel_upshift">{{.Route}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_stats_views_suffix"}}</span>
|
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_stats_views_suffix"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_stats_routes_no_routes"}}</div>{{end}}
|
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_stats_routes_no_routes"}}</div>{{end}}
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/routes-perf/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/routes-perf/"method="get"></form>
|
||||||
<div id="panel_analytics_routes_chart" class="colstack_graph_holder">
|
<div id="panel_analytics_routes_chart"class="colstack_graph_holder">
|
||||||
<div class="ct_chart"></div>
|
<div class="ct_chart"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_routes" class="colstack_item rowlist">
|
<div id="panel_analytics_routes"class="colstack_item rowlist">
|
||||||
{{range .ItemList}}
|
{{range .ItemList}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a href="/panel/analytics/route/{{.Route}}" class="panel_upshift">{{.Route}}</a>
|
<a href="/panel/analytics/route/{{.Route}}"class="panel_upshift">{{.Route}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}}{{.Unit}}</span>
|
<span class="panel_compacttext to_right">{{.Count}}{{.Unit}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_stats_routes_no_routes"}}</div>{{end}}
|
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_stats_routes_no_routes"}}</div>{{end}}
|
||||||
|
|
|
@ -13,7 +13,7 @@ let legendNames = [{{range .Graph.Legends}}
|
||||||
addInitHook("after_phrases", () => {
|
addInitHook("after_phrases", () => {
|
||||||
addInitHook("end_init", () => {
|
addInitHook("end_init", () => {
|
||||||
addInitHook("analytics_loaded", () => {
|
addInitHook("analytics_loaded", () => {
|
||||||
buildStatsChart(rawLabels, seriesData, "{{.TimeRange}}",legendNames);
|
buildStatsChart(rawLabels,seriesData,"{{.TimeRange}}",legendNames);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,8 +13,8 @@ let legendNames = [{{range .Graph.Legends}}
|
||||||
addInitHook("after_phrases", () => {
|
addInitHook("after_phrases", () => {
|
||||||
addInitHook("end_init", () => {
|
addInitHook("end_init", () => {
|
||||||
addInitHook("analytics_loaded", () => {
|
addInitHook("analytics_loaded", () => {
|
||||||
memStuff(window, document, Chartist);
|
memStuff(window,document,Chartist);
|
||||||
buildStatsChart(rawLabels, seriesData, "{{.TimeRange}}",legendNames,1);
|
buildStatsChart(rawLabels,seriesData,"{{.TimeRange}}",legendNames,1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,8 +13,8 @@ let legendNames = [{{range .Graph.Legends}}
|
||||||
addInitHook("after_phrases", () => {
|
addInitHook("after_phrases", () => {
|
||||||
addInitHook("end_init", () => {
|
addInitHook("end_init", () => {
|
||||||
addInitHook("analytics_loaded", () => {
|
addInitHook("analytics_loaded", () => {
|
||||||
perfStuff(window, document, Chartist);
|
perfStuff(window,document,Chartist);
|
||||||
buildStatsChart(rawLabels, seriesData, "{{.TimeRange}}",legendNames,2);
|
buildStatsChart(rawLabels,seriesData,"{{.TimeRange}}",legendNames,2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/system/{{.Agent}}" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/system/{{.Agent}}"method="get"></form>
|
||||||
<div id="panel_analytics_systems" class="colstack_graph_holder">
|
<div id="panel_analytics_systems"class="colstack_graph_holder">
|
||||||
<div class="ct_chart"></div>
|
<div class="ct_chart"></div>
|
||||||
</div>
|
</div>
|
||||||
{{template "panel_analytics_script.html" . }}
|
{{template "panel_analytics_script.html" . }}
|
|
@ -4,14 +4,14 @@
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/systems/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/systems/"method="get"></form>
|
||||||
<div id="panel_analytics_systems_chart" class="colstack_graph_holder">
|
<div id="panel_analytics_systems_chart"class="colstack_graph_holder">
|
||||||
<div class="ct_chart"></div>
|
<div class="ct_chart"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_systems" class="colstack_item rowlist">
|
<div id="panel_analytics_systems"class="colstack_item rowlist">
|
||||||
{{range .ItemList}}
|
{{range .ItemList}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a href="/panel/analytics/system/{{.Agent}}" class="panel_upshift">{{.FriendlyAgent}}</a>
|
<a href="/panel/analytics/system/{{.Agent}}"class="panel_upshift">{{.FriendlyAgent}}</a>
|
||||||
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_stats_views_suffix"}}</span>
|
<span class="panel_compacttext to_right">{{.Count}}{{lang "panel_stats_views_suffix"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_stats_operating_systems_no_operating_systems"}}</div>{{end}}
|
{{else}}<div class="rowitem passive rowmsg">{{lang "panel_stats_operating_systems_no_operating_systems"}}</div>{{end}}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<select form="timeRangeForm" class="timeRangeSelector to_right autoSubmitRedirect" name="timeRange">
|
<select form="timeRangeForm"class="timeRangeSelector to_right autoSubmitRedirect"sname="timeRange">
|
||||||
<option value="one-month"{{if eq .TimeRange "one-month"}} selected{{end}}>{{lang "panel_stats_time_range_one_month"}}</option>
|
<option value="one-month"{{if eq .TimeRange "one-month"}}selected{{end}}>{{lang "panel_stats_time_range_one_month"}}</option>
|
||||||
<option value="one-week"{{if eq .TimeRange "one-week"}} selected{{end}}>{{lang "panel_stats_time_range_one_week"}}</option>
|
<option value="one-week"{{if eq .TimeRange "one-week"}}selected{{end}}>{{lang "panel_stats_time_range_one_week"}}</option>
|
||||||
<option value="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>{{lang "panel_stats_time_range_two_days"}}</option>
|
<option value="two-days"{{if eq .TimeRange "two-days"}}selected{{end}}>{{lang "panel_stats_time_range_two_days"}}</option>
|
||||||
<option value="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>{{lang "panel_stats_time_range_one_day"}}</option>
|
<option value="one-day"{{if eq .TimeRange "one-day"}}selected{{end}}>{{lang "panel_stats_time_range_one_day"}}</option>
|
||||||
<option value="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>{{lang "panel_stats_time_range_twelve_hours"}}</option>
|
<option value="twelve-hours"{{if eq .TimeRange "twelve-hours"}}selected{{end}}>{{lang "panel_stats_time_range_twelve_hours"}}</option>
|
||||||
<option value="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>{{lang "panel_stats_time_range_six_hours"}}</option>
|
<option value="six-hours"{{if eq .TimeRange "six-hours"}}selected{{end}}>{{lang "panel_stats_time_range_six_hours"}}</option>
|
||||||
</select>
|
</select>
|
||||||
<noscript><input form="timeRangeForm" type="submit"></noscript>
|
<noscript><input form="timeRangeForm"type="submit"></noscript>
|
|
@ -4,16 +4,16 @@
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/topics/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/topics/"method="get"></form>
|
||||||
<div id="panel_analytics_topics" class="colstack_graph_holder">
|
<div id="panel_analytics_topics"class="colstack_graph_holder">
|
||||||
<div class="ct_chart" aria-label="{{lang "panel_stats_topic_counts_chart_aria"}}"></div>
|
<div class="ct_chart"aria-label="{{lang "panel_stats_topic_counts_chart_aria"}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_stats_details_head"}}</h1>
|
<h1>{{lang "panel_stats_details_head"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_topics_table" class="colstack_item rowlist" aria-label="{{lang "panel_stats_topic_counts_table_aria"}}">
|
<div id="panel_analytics_topics_table"class="colstack_item rowlist"aria-label="{{lang "panel_stats_topic_counts_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift unix_to_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}24_hour_time{{else}}date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_to_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}24_hour_time{{else}}date{{end}}">{{.Time}}</a>
|
||||||
|
|
|
@ -4,16 +4,16 @@
|
||||||
{{template "panel_analytics_time_range.html" . }}
|
{{template "panel_analytics_time_range.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/views/" method="get"></form>
|
<form id="timeRangeForm"name="timeRangeForm"action="/panel/analytics/views/"method="get"></form>
|
||||||
<div id="panel_analytics_views" class="colstack_graph_holder">
|
<div id="panel_analytics_views"class="colstack_graph_holder">
|
||||||
<div class="ct_chart" aria-label="{{lang "panel_stats_requests_chart_aria"}}"></div>
|
<div class="ct_chart"aria-label="{{lang "panel_stats_requests_chart_aria"}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem">
|
<div class="rowitem">
|
||||||
<h1>{{lang "panel_stats_details_head"}}</h1>
|
<h1>{{lang "panel_stats_details_head"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_analytics_views_table" class="colstack_item rowlist" aria-label="{{lang "panel_stats_requests_table_aria"}}">
|
<div id="panel_analytics_views_table"class="colstack_item rowlist"aria-label="{{lang "panel_stats_requests_table_aria"}}">
|
||||||
{{range .ViewItems}}
|
{{range .ViewItems}}
|
||||||
<div class="rowitem panel_compactrow editable_parent">
|
<div class="rowitem panel_compactrow editable_parent">
|
||||||
<a class="panel_upshift unix_to_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}24_hour_time{{else}}date{{end}}">{{.Time}}</a>
|
<a class="panel_upshift unix_to_{{if or (or (or (eq $.TimeRange "six-hours") (eq $.TimeRange "twelve-hours")) (eq $.TimeRange "one-day")) (eq $.TimeRange "two-days")}}24_hour_time{{else}}date{{end}}">{{.Time}}</a>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_backups_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_backups_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_backups" class="colstack_item rowlist">
|
<div id="panel_backups"class="colstack_item rowlist">
|
||||||
{{range .Backups}}
|
{{range .Backups}}
|
||||||
<div class="rowitem panel_compactrow">
|
<div class="rowitem panel_compactrow">
|
||||||
<span>{{.SQLURL}}</span>
|
<span>{{.SQLURL}}</span>
|
||||||
<span class="panel_floater">
|
<span class="panel_floater">
|
||||||
<a href="/panel/backups/{{.SQLURL}}" class="panel_tag panel_right_button">{{lang "panel_backups_download"}}</a>
|
<a href="/panel/backups/{{.SQLURL}}"class="panel_tag panel_right_button">{{lang "panel_backups_download"}}</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{else}}<div class="rowitem rowmsg">{{lang "panel_backups_no_backups"}}</div>{{end}}
|
{{else}}<div class="rowitem rowmsg">{{lang "panel_backups_no_backups"}}</div>{{end}}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{.Name}}{{lang "panel_forum_head_suffix"}}</h1></div>
|
<div class="rowitem"><h1>{{.Name}}{{lang "panel_forum_head_suffix"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_forum" class="colstack_item the_form">
|
<div id="panel_forum"class="colstack_item the_form">
|
||||||
<form action="/panel/forums/edit/submit/{{.ID}}?s={{.CurrentUser.Session}}" method="post">
|
<form action="/panel/forums/edit/submit/{{.ID}}?s={{.CurrentUser.Session}}" method="post">
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_forum_name"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_forum_name"}}</a></div>
|
||||||
<div class="formitem"><input name="forum_name" type="text" value="{{.Name}}" placeholder="{{lang "panel_forum_name_placeholder"}}"></div>
|
<div class="formitem"><input name="forum_name"type="text"value="{{.Name}}"placeholder="{{lang "panel_forum_name_placeholder"}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_forum_description"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_forum_description"}}</a></div>
|
||||||
<div class="formitem"><input name="forum_desc" type="text" value="{{.Desc}}" placeholder="{{lang "panel_forum_description_placeholder"}}"></div>
|
<div class="formitem"><input name="forum_desc"type="text"value="{{.Desc}}"placeholder="{{lang "panel_forum_description_placeholder"}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_forum_active"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_forum_active"}}</a></div>
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
<div class="formitem">
|
<div class="formitem">
|
||||||
<select name="forum_preset">
|
<select name="forum_preset">
|
||||||
<option{{if eq .Preset "all"}} selected{{end}} value="all">{{lang "panel_preset_everyone"}}</option>
|
<option{{if eq .Preset "all"}} selected{{end}} value="all">{{lang "panel_preset_everyone"}}</option>
|
||||||
<option{{if eq .Preset "announce"}} selected{{end}} value="announce">{{lang "panel_preset_announcements"}}</option>
|
<option{{if eq .Preset "announce"}} selected{{end}} value="announce">{{lang "panel_preset_announcements"}}</option>
|
||||||
<option{{if eq .Preset "members"}} selected{{end}} value="members">{{lang "panel_preset_member_only"}}</option>
|
<option{{if eq .Preset "members"}} selected{{end}} value="members">{{lang "panel_preset_member_only"}}</option>
|
||||||
<option{{if eq .Preset "staff"}} selected{{end}} value="staff">{{lang "panel_preset_staff_only"}}</option>
|
<option{{if eq .Preset "staff"}} selected{{end}} value="staff">{{lang "panel_preset_staff_only"}}</option>
|
||||||
<option{{if eq .Preset "admins"}} selected{{end}} value="admins">{{lang "panel_preset_admin_only"}}</option>
|
<option{{if eq .Preset "admins"}} selected{{end}} value="admins">{{lang "panel_preset_admin_only"}}</option>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem"><button name="panel-button" class="formbutton form_middle_button">{{lang "panel_forum_update_button"}}</button></div>
|
<div class="formitem"><button name="panel-button"class="formbutton form_middle_button">{{lang "panel_forum_update_button"}}</button></div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,17 +42,17 @@
|
||||||
<h1>{{lang "panel_forum_permissions_head"}}</h1>
|
<h1>{{lang "panel_forum_permissions_head"}}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="forum_quick_perms" class="colstack_item rowlist formlist the_form">
|
<div id="forum_quick_perms"class="colstack_item rowlist formlist the_form">
|
||||||
{{range .Groups}}
|
{{range .Groups}}
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem editable_parent">
|
<div class="formitem editable_parent">
|
||||||
<a>{{.Group.Name}}</a>
|
<a>{{.Group.Name}}</a>
|
||||||
<input name="gid" value="{{.Group.ID}}" type="hidden" class="editable_block" data-field="gid" data-type="hidden" data-value="{{.Group.ID}}">
|
<input name="gid"value="{{.Group.ID}}"type="hidden"class="editable_block"data-field="gid"data-type="hidden"data-value="{{.Group.ID}}">
|
||||||
<span class="edit_fields hide_on_edit rowsmall">{{lang "panel_forum_edit_button"}}</span>
|
<span class="edit_fields hide_on_edit rowsmall">{{lang "panel_forum_edit_button"}}</span>
|
||||||
<div class="panel_floater">
|
<div class="panel_floater">
|
||||||
<span data-field="perm_preset" data-type="list" data-value="{{.Preset}}" class="editable_block perm_preset perm_preset_{{.Preset}}"></span>
|
<span data-field="perm_preset"data-type="list"data-value="{{.Preset}}" class="editable_block perm_preset perm_preset_{{.Preset}}"></span>
|
||||||
<a class="panel_right_button has_inner_button show_on_edit" href="/panel/forums/edit/perms/submit/{{$.ID}}"><button class='panel_tag submit_edit' type='submit'>{{lang "panel_forum_short_update_button"}}</button></a>
|
<a class="panel_right_button has_inner_button show_on_edit"href="/panel/forums/edit/perms/submit/{{$.ID}}"><button class='panel_tag submit_edit'type='submit'>{{lang "panel_forum_short_update_button"}}</button></a>
|
||||||
<a class="panel_right_button has_inner_button show_on_edit" href="/panel/forums/edit/perms/{{$.ID}}-{{.Group.ID}}"><button class='panel_tag' type='submit'>{{lang "panel_forum_full_edit_button"}}</button></a>
|
<a class="panel_right_button has_inner_button show_on_edit"href="/panel/forums/edit/perms/{{$.ID}}-{{.Group.ID}}"><button class='panel_tag'type='submit'>{{lang "panel_forum_full_edit_button"}}</button></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{.Name}}{{lang "panel_forum_head_suffix"}}</h1></div>
|
<div class="rowitem"><h1>{{.Name}}{{lang "panel_forum_head_suffix"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<form action="/panel/forums/edit/perms/adv/submit/{{.ForumID}}-{{.GroupID}}?s={{.CurrentUser.Session}}" method="post">
|
<form action="/panel/forums/edit/perms/adv/submit/{{.ForumID}}-{{.GroupID}}?s={{.CurrentUser.Session}}"method="post">
|
||||||
<div class="colstack_item rowlist formlist the_form panel_forum_perms">
|
<div class="colstack_item rowlist formlist the_form panel_forum_perms">
|
||||||
{{range .Perms}}
|
{{range .Perms}}
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>{{end}}
|
</div>{{end}}
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem"><button name="panel-button" class="formbutton form_middle_button">{{lang "panel_forum_update_button"}}</button></div>
|
<div class="formitem"><button name="panel-button"class="formbutton form_middle_button">{{lang "panel_forum_update_button"}}</button></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_logs_mod_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_logs_mod_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_modlogs" class="colstack_item rowlist loglist">
|
<div id="panel_modlogs"class="colstack_item rowlist loglist">
|
||||||
{{range .Logs}}
|
{{range .Logs}}
|
||||||
<div class="rowitem panel_compactrow">
|
<div class="rowitem panel_compactrow">
|
||||||
<span class="to_left">
|
<span class="to_left">
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_pages_edit_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_pages_edit_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<form action="/panel/pages/edit/submit/{{.Page.ID}}?s={{.CurrentUser.Session}}" method="post">
|
<form action="/panel/pages/edit/submit/{{.Page.ID}}?s={{.CurrentUser.Session}}"method="post">
|
||||||
<div id="panel_page_edit_item" class="colstack_item the_form">
|
<div id="panel_page_edit_item"class="colstack_item the_form">
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_pages_name"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_pages_name"}}</a></div>
|
||||||
<div class="formitem"><input name="name" type="text" value="{{.Page.Name}}"></div>
|
<div class="formitem"><input name="name"type="text"value="{{.Page.Name}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_pages_title"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_pages_title"}}</a></div>
|
||||||
<div class="formitem"><input name="title" type="text" value="{{.Page.Title}}"></div>
|
<div class="formitem"><input name="title"type="text"value="{{.Page.Title}}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem">
|
<div class="formitem">
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem"><button name="panel-button" class="formbutton">{{lang "panel_pages_edit_update_button"}}</button></div>
|
<div class="formitem"><button name="panel-button"class="formbutton">{{lang "panel_pages_edit_update_button"}}</button></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
|
@ -1,20 +1,20 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_plugins_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_plugins_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_plugins" class="colstack_item complex_rowlist">
|
<div id="panel_plugins"class="colstack_item complex_rowlist">
|
||||||
{{range .ItemList}}
|
{{range .ItemList}}
|
||||||
<div class="rowitem editable_parent">
|
<div class="rowitem editable_parent">
|
||||||
<span class="panel_plugin_meta">
|
<span class="panel_plugin_meta">
|
||||||
<a {{if .URL}}href="{{.URL}}"{{end}}class="editable_block"class="panel_upshift">{{.Name}}</a><br>
|
<a{{if .URL}} href="{{.URL}}"{{end}}class="editable_block"class="panel_upshift">{{.Name}}</a><br>
|
||||||
<small style="margin-left:2px;">{{lang "panel_plugins_author_prefix"}}{{.Author}}</small>
|
<small style="margin-left:2px;">{{lang "panel_plugins_author_prefix"}}{{.Author}}</small>
|
||||||
</span>
|
</span>
|
||||||
<span class="to_right">
|
<span class="to_right">
|
||||||
{{if .Settings}}<a href="/panel/settings/" class="panel_tag panel_plugin_settings panel_right_button">{{lang "panel_plugins_settings"}}</a>{{end}}
|
{{if .Settings}}<a href="/panel/settings/"class="panel_tag panel_plugin_settings panel_right_button">{{lang "panel_plugins_settings"}}</a>{{end}}
|
||||||
{{if .Active}}<a href="/panel/plugins/deactivate/{{.UName}}?s={{$.CurrentUser.Session}}" class="panel_tag panel_plugin_deactivate panel_right_button">{{lang "panel_plugins_deactivate"}}</a>
|
{{if .Active}}<a href="/panel/plugins/deactivate/{{.UName}}?s={{$.CurrentUser.Session}}"class="panel_tag panel_plugin_deactivate panel_right_button">{{lang "panel_plugins_deactivate"}}</a>
|
||||||
{{else if .Installable}}
|
{{else if .Installable}}
|
||||||
{{/** TODO: Write a custom template interpreter to fix this nonsense **/}}
|
{{/** TODO: Write a custom template interpreter to fix this nonsense **/}}
|
||||||
{{if .Installed}}<a href="/panel/plugins/activate/{{.UName}}?s={{$.CurrentUser.Session}}" class="panel_tag panel_plugin_activate panel_right_button">{{lang "panel_plugins_activate"}}</a>{{else}}<a href="/panel/plugins/install/{{.UName}}?s={{$.CurrentUser.Session}}" class="panel_tag panel_plugin_install panel_right_button">{{lang "panel_plugins_install"}}</a>{{end}}
|
{{if .Installed}}<a href="/panel/plugins/activate/{{.UName}}?s={{$.CurrentUser.Session}}"class="panel_tag panel_plugin_activate panel_right_button">{{lang "panel_plugins_activate"}}</a>{{else}}<a href="/panel/plugins/install/{{.UName}}?s={{$.CurrentUser.Session}}"class="panel_tag panel_plugin_install panel_right_button">{{lang "panel_plugins_install"}}</a>{{end}}
|
||||||
{{else}}<a href="/panel/plugins/activate/{{.UName}}?s={{$.CurrentUser.Session}}" class="panel_tag panel_plugin_activate panel_right_button">{{lang "panel_plugins_activate"}}</a>{{end}}
|
{{else}}<a href="/panel/plugins/activate/{{.UName}}?s={{$.CurrentUser.Session}}"class="panel_tag panel_plugin_activate panel_right_button">{{lang "panel_plugins_activate"}}</a>{{end}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
<h2 class="hguide">{{lang "panel_hints_reorder"}}</h2>
|
<h2 class="hguide">{{lang "panel_hints_reorder"}}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="panel_menu_item_holder" class="colstack_item rowlist">
|
<div id="panel_menu_item_holder"class="colstack_item rowlist">
|
||||||
{{range .ItemList}}
|
{{range .ItemList}}
|
||||||
<div class="panel_menu_item rowitem panel_compactrow editable_parent" data-miid="{{.ID}}">
|
<div class="panel_menu_item rowitem panel_compactrow editable_parent"data-miid="{{.ID}}">
|
||||||
<span class="grip"></span>
|
<span class="grip"></span>
|
||||||
<a href="/panel/themes/menus/item/edit/{{.ID}}" class="editable_block panel_upshift">{{.Name}}</a>
|
<a href="/panel/themes/menus/item/edit/{{.ID}}"class="editable_block panel_upshift">{{.Name}}</a>
|
||||||
<span class="panel_buttons">
|
<span class="panel_buttons">
|
||||||
<a href="/panel/themes/menus/item/edit/{{.ID}}" class="panel_tag panel_right_button edit_button" aria-label="{{lang "panel_themes_menus_items_edit_button_aria"}}"></a>
|
<a href="/panel/themes/menus/item/edit/{{.ID}}"class="panel_tag panel_right_button edit_button"aria-label="{{lang "panel_themes_menus_items_edit_button_aria"}}"></a>
|
||||||
<a href="/panel/themes/menus/item/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}" class="panel_tag panel_right_button delete_button" aria-label="{{lang "panel_themes_menus_items_delete_button_aria"}}"></a>
|
<a href="/panel/themes/menus/item/delete/submit/{{.ID}}?s={{$.CurrentUser.Session}}"class="panel_tag panel_right_button delete_button"aria-label="{{lang "panel_themes_menus_items_delete_button_aria"}}"></a>
|
||||||
</span>
|
</span>
|
||||||
</div>{{end}}
|
</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,9 +21,9 @@
|
||||||
<div class="colstack_item colstack_head">
|
<div class="colstack_item colstack_head">
|
||||||
<div class="rowitem"><h1>{{lang "panel_themes_menus_create_head"}}</h1></div>
|
<div class="rowitem"><h1>{{lang "panel_themes_menus_create_head"}}</h1></div>
|
||||||
</div>
|
</div>
|
||||||
<form action="/panel/themes/menus/item/create/submit/?s={{.CurrentUser.Session}}" method="post">
|
<form action="/panel/themes/menus/item/create/submit/?s={{.CurrentUser.Session}}"method="post">
|
||||||
<input name="mid" value="{{.MenuID}}" type="hidden">
|
<input name="mid"value="{{.MenuID}}"type="hidden">
|
||||||
<div id="panel_themes_menu_item_create" class="colstack_item the_form">
|
<div id="panel_themes_menu_item_create"class="colstack_item the_form">
|
||||||
{{/** TODO: Let an admin move a menu item from one menu to another? **/}}
|
{{/** TODO: Let an admin move a menu item from one menu to another? **/}}
|
||||||
<div class="formrow">
|
<div class="formrow">
|
||||||
<div class="formitem formlabel"><a>{{lang "panel_themes_menus_name"}}</a></div>
|
<div class="formitem formlabel"><a>{{lang "panel_themes_menus_name"}}</a></div>
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
{{if .CurrentUser.Loggedin}}
|
{{if .CurrentUser.Loggedin}}
|
||||||
{{if .CurrentUser.Perms.BanUsers}}
|
{{if .CurrentUser.Perms.BanUsers}}
|
||||||
<!-- TODO: Inline the display:none; CSS -->
|
<!-- TODO: Inline the display:none; CSS -->
|
||||||
<div id="ban_user_head"class="colstack_item colstack_head hash_hide ban_user_hash" style="display:none;">
|
<div id="ban_user_head"class="colstack_item colstack_head hash_hide ban_user_hash"style="display:none;">
|
||||||
<div class="rowitem"><h1><a>{{lang "profile.ban_user_head"}}</a></h1></div>
|
<div class="rowitem"><h1><a>{{lang "profile.ban_user_head"}}</a></h1></div>
|
||||||
</div>
|
</div>
|
||||||
<form id="ban_user_form"class="hash_hide ban_user_hash"action="/users/ban/submit/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}"method="post"style="display:none;">
|
<form id="ban_user_form"class="hash_hide ban_user_hash"action="/users/ban/submit/{{.ProfileOwner.ID}}?s={{.CurrentUser.Session}}"method="post"style="display:none;">
|
||||||
|
@ -120,8 +120,8 @@
|
||||||
|
|
||||||
<div id="profile_comments_head"class="colstack_item colstack_head hash_hide">
|
<div id="profile_comments_head"class="colstack_item colstack_head hash_hide">
|
||||||
<div class="rowitem"><h1><a>{{lang "profile.comments_head"}}</a></h1></div>
|
<div class="rowitem"><h1><a>{{lang "profile.comments_head"}}</a></h1></div>
|
||||||
</div>
|
</div>{{if .ShowComments}}
|
||||||
<div id="profile_comments"class="colstack_item hash_hide">{{template "profile_comments_row.html" . }}</div>
|
<div id="profile_comments"class="colstack_item hash_hide">{{template "profile_comments_row.html" . }}</div>{{end}}
|
||||||
|
|
||||||
{{if .CurrentUser.Loggedin}}
|
{{if .CurrentUser.Loggedin}}
|
||||||
{{if .CanComment}}
|
{{if .CanComment}}
|
||||||
|
|
Loading…
Reference in New Issue