From 9438d3704bbfa96712f4ed9d149f84810dbf7157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Thu, 22 May 2025 02:30:59 +0300 Subject: [PATCH] make default avatar use the avatars table --- .gitignore | 3 ++- apps/users.lua | 4 +++- create_default_accounts.lua | 12 ++++++++++++ migrations.lua | 6 ++++++ models.lua | 2 +- static/avatars/default.webp | Bin 0 -> 8548 bytes util.lua | 25 ++++++++++++++++++++++--- views/threads/post.etlua | 2 +- 8 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 static/avatars/default.webp diff --git a/.gitignore b/.gitignore index 369bf78..665fef9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ nginx.conf.compiled db.*.sqlite .vscode/ .local/ -static/avatars/ +static/avatars/* +!static/avatars/default.webp secrets.lua diff --git a/apps/users.lua b/apps/users.lua index 0d11dde..341f4a9 100644 --- a/apps/users.lua +++ b/apps/users.lua @@ -150,8 +150,10 @@ app:post("user_clear_avatar", "/:username/clear_avatar", function(self) if me.id ~= target_user.id then return {redirect_to = self:url_for("user", {username = self.params.username})} end + local old_avatar_id = target_user.avatar_id + util.destroy_avatar(old_avatar_id) target_user:update({ - avatar_id = db.NULL, + avatar_id = 1, }) util.inject_infobox(self, "Avatar cleared.") return {redirect_to = self:url_for("user_settings", {username = self.params.username})} diff --git a/create_default_accounts.lua b/create_default_accounts.lua index aab40ed..318bbff 100644 --- a/create_default_accounts.lua +++ b/create_default_accounts.lua @@ -4,6 +4,17 @@ local constants = require("constants") local alphabet = "-_@0123456789abcdefghijklmnopqrstuvwABCDEFGHIJKLMNOPQRSTUVWXYZ" +local function create_default_avatar() + if models.Avatars:count() > 0 then + print("default avatar must exist") + return + end + models.Avatars:create({ + file_path = "/avatars/default.webp", + uploaded_at = os.time(), + }) +end + local function create_admin() local username = "admin" local root_count = models.Users:count("username = ?", username) @@ -44,5 +55,6 @@ local function create_deleted_user() }) end +create_default_avatar() create_admin() create_deleted_user() diff --git a/migrations.lua b/migrations.lua index 8709a74..7ed91e9 100644 --- a/migrations.lua +++ b/migrations.lua @@ -52,4 +52,10 @@ return { [6] = function () schema.drop_column("post_history", "user_id") end, + + [7] = function () + db.query('DROP INDEX "idx_users_avatar"') + schema.drop_column("users", "avatar_id") + schema.add_column("users", "avatar_id", "REFERENCES avatars(id) DEFAULT 1") + end } diff --git a/models.lua b/models.lua index 8466db0..24ee4e5 100644 --- a/models.lua +++ b/models.lua @@ -25,7 +25,7 @@ function Users_mt:is_logged_in_guest() end function Users_mt:is_default_avatar() - return self.avatar_id == nil + return self.avatar_id == 1 end function Users_mt:is_logged_in() diff --git a/static/avatars/default.webp b/static/avatars/default.webp new file mode 100644 index 0000000000000000000000000000000000000000..a352e1b81748c8e47da9b7dd3454d5ecafb005d7 GIT binary patch literal 8548 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 literal 0 HcmV?d00001 diff --git a/util.lua b/util.lua index 044b8b0..54f2314 100644 --- a/util.lua +++ b/util.lua @@ -34,9 +34,6 @@ util.TransientUser = { } function util.get_user_avatar_url(req, user) - if not user.avatar_id then - return "/avatars/default.webp" - end return Avatars:find(user.avatar_id).file_path end @@ -72,6 +69,28 @@ function util.validate_and_create_image(input_image, filename) return true end +function util.destroy_avatar(avatar_id) + if avatar_id == 1 then + print("won't delete default avatar") + return + end + + local avatar = Avatars:find(avatar_id) + + if not avatar then + return + end + + local file_path = "static" .. avatar.file_path + local f = io.open(file_path, "r") + if not f then + print("can't open avatar file") + else + f:close() + os.remove(file_path) + end +end + function util.get_logged_in_user(req) if req.session.session_key == nil then return nil diff --git a/views/threads/post.etlua b/views/threads/post.etlua index 6ac2652..44f4597 100644 --- a/views/threads/post.etlua +++ b/views/threads/post.etlua @@ -1,7 +1,7 @@