From 4bbe9c8f5ca0482a75c09335892c788c8de06a45 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Mon, 27 Mar 2023 10:03:12 +0100 Subject: [PATCH 1/7] Ship with hehe --- config/custom_emoji.txt | 2 ++ mix.lock | 14 +++++++------- priv/static/emoji/hehe.png | Bin 0 -> 15993 bytes priv/static/emoji/nothehe.png | Bin 0 -> 13628 bytes 4 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 priv/static/emoji/hehe.png create mode 100644 priv/static/emoji/nothehe.png diff --git a/config/custom_emoji.txt b/config/custom_emoji.txt index e69de29bb..7b2e51265 100644 --- a/config/custom_emoji.txt +++ b/config/custom_emoji.txt @@ -0,0 +1,2 @@ +hehe, /emoji/hehe.png, Akkoma +nothehe, /emoji/nothehe.png, Akkoma diff --git a/mix.lock b/mix.lock index 369d1ed25..bee2c1585 100644 --- a/mix.lock +++ b/mix.lock @@ -27,7 +27,7 @@ "earmark": {:hex, :earmark, "1.4.37", "56ce845c543393aa3f9b294c818c3d783452a4a67e4ab18c4303a954a8b59363", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "d86d5e12868db86d5321b00e62a4bbcb4150346e4acc9a90a041fb188a5cb106"}, "earmark_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"}, "eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"}, - "ecto": {:hex, :ecto, "3.9.4", "3ee68e25dbe0c36f980f1ba5dd41ee0d3eb0873bccae8aeaf1a2647242bffa35", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "de5f988c142a3aa4ec18b85a4ec34a2390b65b24f02385c1144252ff6ff8ee75"}, + "ecto": {:hex, :ecto, "3.9.5", "9f0aa7ae44a1577b651c98791c6988cd1b69b21bc724e3fd67090b97f7604263", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d4f3115d8cbacdc0bfa4b742865459fb1371d0715515842a1fb17fe31920b74c"}, "ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"}, "ecto_psql_extras": {:hex, :ecto_psql_extras, "0.7.10", "e14d400930f401ca9f541b3349212634e44027d7f919bbb71224d7ac0d0e8acd", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.15.7 or ~> 0.16.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "505e8cd81e4f17c090be0f99e92b1b3f0fd915f98e76965130b8ccfb891e7088"}, "ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"}, @@ -38,7 +38,7 @@ "ex_aws": {:hex, :ex_aws, "2.1.9", "dc4865ecc20a05190a34a0ac5213e3e5e2b0a75a0c2835e923ae7bfeac5e3c31", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "3e6c776703c9076001fbe1f7c049535f042cb2afa0d2cbd3b47cbc4e92ac0d10"}, "ex_aws_s3": {:hex, :ex_aws_s3, "2.4.0", "ce8decb6b523381812798396bc0e3aaa62282e1b40520125d1f4eff4abdff0f4", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "85dda6e27754d94582869d39cba3241d9ea60b6aa4167f9c88e309dc687e56bb"}, "ex_const": {:hex, :ex_const, "0.2.4", "d06e540c9d834865b012a17407761455efa71d0ce91e5831e86881b9c9d82448", [:mix], [], "hexpm", "96fd346610cc992b8f896ed26a98be82ac4efb065a0578f334a32d60a3ba9767"}, - "ex_doc": {:hex, :ex_doc, "0.29.2", "dfa97532ba66910b2a3016a4bbd796f41a86fc71dd5227e96f4c8581fdf0fdf0", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "6b5d7139eda18a753e3250e27e4a929f8d2c880dd0d460cb9986305dea3e03af"}, + "ex_doc": {:hex, :ex_doc, "0.29.3", "f07444bcafb302db86e4f02d8bbcd82f2e881a0dcf4f3e4740e4b8128b9353f7", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3dc6787d7b08801ec3b51e9bd26be5e8826fbf1a17e92d1ebc252e1a1c75bfe1"}, "ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"}, "ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"}, "excoveralls": {:hex, :excoveralls, "0.15.1", "83c8cf7973dd9d1d853dce37a2fb98aaf29b564bf7d01866e409abf59dac2c0e", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "f8416bd90c0082d56a2178cf46c837595a06575f70a5624f164a1ffe37de07e7"}, @@ -86,14 +86,14 @@ "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"}, "phoenix_html": {:hex, :phoenix_html, "3.3.1", "4788757e804a30baac6b3fc9695bf5562465dd3f1da8eb8460ad5b404d9a2178", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "bed1906edd4906a15fd7b412b85b05e521e1f67c9a85418c55999277e553d0d3"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.7.2", "97cc4ff2dba1ebe504db72cb45098cb8e91f11160528b980bd282cc45c73b29c", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.18.3", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0e5fdf063c7a3b620c566a30fcf68b7ee02e5e46fe48ee46a6ec3ba382dc05b7"}, - "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.17", "74938b02f3c531bed3f87fe1ea39af6b5b2d26ab1405e77e76b8ef5df9ffa8a1", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f4b5710e19a29b8dc93b7af4bab4739c067a3cb759af01ffc3057165453dce38"}, + "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.18", "1f38fbd7c363723f19aad1a04b5490ff3a178e37daaf6999594d5f34796c47fc", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a5810d0472f3189ede6d2a95bda7f31c6113156b91784a3426cb0ab6a6d85214"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, "phoenix_swoosh": {:hex, :phoenix_swoosh, "0.3.4", "615f8f393135de7e0cbb4bd00ba238b1e0cd324b0d90efbaee613c2f02ca5e5c", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.0", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "3971221846232021ab5e3c7489fd62ec5bfd6a2e01cae10a317ccf6fb350571c"}, "phoenix_template": {:hex, :phoenix_template, "1.0.1", "85f79e3ad1b0180abb43f9725973e3b8c2c3354a87245f91431eec60553ed3ef", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "157dc078f6226334c91cb32c1865bf3911686f8bcd6bcff86736f6253e6993ee"}, "phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"}, - "plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"}, - "plug_crypto": {:hex, :plug_crypto, "1.2.4", "34c380ef387cc7e8d537854ddd4b7096c79a4397d53587cb80419c782b03fdbc", [:mix], [], "hexpm", "4de415f03faec94d9da9be8c12cb51e9c98cbf66d732b6df669d4562d8e91acc"}, + "plug": {:hex, :plug, "1.14.2", "cff7d4ec45b4ae176a227acd94a7ab536d9b37b942c8e8fa6dfc0fff98ff4d80", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "842fc50187e13cf4ac3b253d47d9474ed6c296a8732752835ce4a86acdf68d13"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"}, + "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, "plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"}, "poison": {:hex, :poison, "5.0.0", "d2b54589ab4157bbb82ec2050757779bfed724463a544b6e20d79855a9e43b24", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "11dc6117c501b80c62a7594f941d043982a1bd05a1184280c0d9166eb4d8d3fc"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, @@ -117,7 +117,7 @@ "telemetry_poller": {:hex, :telemetry_poller, "0.5.1", "21071cc2e536810bac5628b935521ff3e28f0303e770951158c73eaaa01e962a", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4cab72069210bc6e7a080cec9afffad1b33370149ed5d379b81c7c5f0c663fd4"}, "temple": {:git, "https://akkoma.dev/AkkomaGang/temple.git", "066a699ade472d8fa42a9d730b29a61af9bc8b59", [ref: "066a699ade472d8fa42a9d730b29a61af9bc8b59"]}, "tesla": {:hex, :tesla, "1.4.4", "bb89aa0c9745190930366f6a2ac612cdf2d0e4d7fff449861baa7875afd797b2", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "d5503a49f9dec1b287567ea8712d085947e247cb11b06bc54adb05bfde466457"}, - "timex": {:hex, :timex, "3.7.9", "790cdfc4acfce434e442f98c02ea6d84d0239073bfd668968f82ac63e9a6788d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "64691582e5bb87130f721fc709acfb70f24405833998fabf35be968984860ce1"}, + "timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"}, "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"}, "tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"}, "ueberauth": {:hex, :ueberauth, "0.10.5", "806adb703df87e55b5615cf365e809f84c20c68aa8c08ff8a416a5a6644c4b02", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3efd1f31d490a125c7ed453b926f7c31d78b97b8a854c755f5c40064bf3ac9e1"}, diff --git a/priv/static/emoji/hehe.png b/priv/static/emoji/hehe.png new file mode 100644 index 0000000000000000000000000000000000000000..c02592d97604befbb241ef16c2016d84bc2bb89d GIT binary patch literal 15993 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 Dnw$bX literal 0 HcmV?d00001 diff --git a/priv/static/emoji/nothehe.png b/priv/static/emoji/nothehe.png new file mode 100644 index 0000000000000000000000000000000000000000..427bb6d61f1f4a24e4b89ed48f440a3038c2b594 GIT binary patch literal 13628 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 Date: Wed, 29 Mar 2023 01:59:19 +0100 Subject: [PATCH 2/7] Remove indexer plugin --- config/config.exs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/config.exs b/config/config.exs index e216caf9d..ffb62a28f 100644 --- a/config/config.exs +++ b/config/config.exs @@ -572,8 +572,7 @@ database_prune: 1 ], plugins: [ - Oban.Plugins.Pruner, - {Oban.Plugins.Reindexer, schedule: "@weekly"} + Oban.Plugins.Pruner ], crontab: [ {"0 0 * * 0", Pleroma.Workers.Cron.DigestEmailsWorker}, From 3f340cbc43948f3ce0e8bca23142be9cd2454960 Mon Sep 17 00:00:00 2001 From: sadposter Date: Wed, 29 Mar 2023 03:31:56 +0100 Subject: [PATCH 3/7] Only even attempt to fetch local activities by object_id TODO: PLEASE FOR THE LOVE OF KANATAN CACHE THIS --- lib/pleroma/activity.ex | 8 ++++++++ lib/pleroma/web/o_status/o_status_controller.ex | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index c5b514742..0a376be04 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -277,6 +277,14 @@ def get_create_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do def get_create_by_object_ap_id_with_object(_), do: nil + def get_local_create_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do + ap_id + |> create_by_object_ap_id_with_object() + |> where(local: true) + |> Repo.one() + end + + @spec create_by_id_with_object(String.t()) :: t() | nil def create_by_id_with_object(id) do get_by_id_with_opts(id, preload: [:object], filter: [type: "Create"]) diff --git a/lib/pleroma/web/o_status/o_status_controller.ex b/lib/pleroma/web/o_status/o_status_controller.ex index 7731d847f..79db112df 100644 --- a/lib/pleroma/web/o_status/o_status_controller.ex +++ b/lib/pleroma/web/o_status/o_status_controller.ex @@ -36,7 +36,7 @@ def object(%{assigns: %{format: format}} = conn, _params) def object(conn, _params) do with id <- Endpoint.url() <> conn.request_path, {_, %Activity{} = activity} <- - {:activity, Activity.get_create_by_object_ap_id_with_object(id)}, + {:activity, Activity.get_local_create_by_object_ap_id_with_object(id)}, {_, true} <- {:public?, Visibility.is_public?(activity)}, {_, false} <- {:local_public?, Visibility.is_local_public?(activity)} do redirect(conn, to: "/notice/#{activity.id}") From 0151ca1d52d383e4fa7a510a810975fbb09ee6f3 Mon Sep 17 00:00:00 2001 From: sadposter Date: Wed, 29 Mar 2023 03:32:30 +0100 Subject: [PATCH 4/7] Revert "Remove indexer plugin" This reverts commit 1d94f2a424e64082854c9ccf1e2086e314e07852. --- config/config.exs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/config.exs b/config/config.exs index ffb62a28f..e216caf9d 100644 --- a/config/config.exs +++ b/config/config.exs @@ -572,7 +572,8 @@ database_prune: 1 ], plugins: [ - Oban.Plugins.Pruner + Oban.Plugins.Pruner, + {Oban.Plugins.Reindexer, schedule: "@weekly"} ], crontab: [ {"0 0 * * 0", Pleroma.Workers.Cron.DigestEmailsWorker}, From d85d1e128a0ca836e8976202781902383aea3d89 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Wed, 29 Mar 2023 11:44:03 +0100 Subject: [PATCH 5/7] we don't actually need the object on redirect --- lib/pleroma/activity.ex | 4 ++-- lib/pleroma/web/o_status/o_status_controller.ex | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 0a376be04..925612d3c 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -277,9 +277,9 @@ def get_create_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do def get_create_by_object_ap_id_with_object(_), do: nil - def get_local_create_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do + def get_local_create_by_object_ap_id(ap_id) when is_binary(ap_id) do ap_id - |> create_by_object_ap_id_with_object() + |> create_by_object_ap_id() |> where(local: true) |> Repo.one() end diff --git a/lib/pleroma/web/o_status/o_status_controller.ex b/lib/pleroma/web/o_status/o_status_controller.ex index 79db112df..95a22895e 100644 --- a/lib/pleroma/web/o_status/o_status_controller.ex +++ b/lib/pleroma/web/o_status/o_status_controller.ex @@ -36,7 +36,7 @@ def object(%{assigns: %{format: format}} = conn, _params) def object(conn, _params) do with id <- Endpoint.url() <> conn.request_path, {_, %Activity{} = activity} <- - {:activity, Activity.get_local_create_by_object_ap_id_with_object(id)}, + {:activity, Activity.get_local_create_by_object_ap_id(id)}, {_, true} <- {:public?, Visibility.is_public?(activity)}, {_, false} <- {:local_public?, Visibility.is_local_public?(activity)} do redirect(conn, to: "/notice/#{activity.id}") From 66d162bb9edf79455558bdf7e267c08f8c3cf964 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Wed, 29 Mar 2023 12:01:16 +0100 Subject: [PATCH 6/7] Add debug logs to timeline rendering to assist debugging --- lib/pleroma/activity.ex | 1 - lib/pleroma/user.ex | 2 +- .../controllers/timeline_controller.ex | 27 +++++++++++++++++++ .../web/mastodon_api/views/status_view.ex | 13 +++++++-- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 925612d3c..c94667fb9 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -284,7 +284,6 @@ def get_local_create_by_object_ap_id(ap_id) when is_binary(ap_id) do |> Repo.one() end - @spec create_by_id_with_object(String.t()) :: t() | nil def create_by_id_with_object(id) do get_by_id_with_opts(id, preload: [:object], filter: [type: "Create"]) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 480521984..ead37ccca 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -374,7 +374,7 @@ def banner_url(user, options \\ []) do do_optional_url(user.banner, "#{Endpoint.url()}/images/banner.png", options) end - defp do_optional_url(field, default, options \\ []) do + defp do_optional_url(field, default, options) do case field do %{"url" => [%{"href" => href} | _]} when is_binary(href) -> href diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex index c9960187d..1d4e734a4 100644 --- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex @@ -37,10 +37,16 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do when action in [:public, :hashtag, :bubble] ) + require Logger + defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TimelineOperation # GET /api/v1/timelines/home def home(%{assigns: %{user: user}} = conn, params) do + %{nickname: nickname} = user + + Logger.debug("TimelineController.home: #{nickname}") + followed_hashtags = user |> User.followed_hashtags() @@ -58,11 +64,15 @@ def home(%{assigns: %{user: user}} = conn, params) do |> Map.put(:followed_hashtags, followed_hashtags) |> Map.delete(:local) + Logger.debug("TimelineController.home: #{nickname} - fetching activities") + activities = [user.ap_id | User.following(user)] |> ActivityPub.fetch_activities(params) |> Enum.reverse() + Logger.debug("TimelineController.home: #{nickname} - rendering") + conn |> add_link_headers(activities) |> render("index.json", @@ -75,6 +85,8 @@ def home(%{assigns: %{user: user}} = conn, params) do # GET /api/v1/timelines/direct def direct(%{assigns: %{user: user}} = conn, params) do + Logger.debug("TimelineController.direct: #{user.nickname}") + params = params |> Map.put(:type, "Create") @@ -82,11 +94,15 @@ def direct(%{assigns: %{user: user}} = conn, params) do |> Map.put(:user, user) |> Map.put(:visibility, "direct") + Logger.debug("TimelineController.direct: #{user.nickname} - fetching activities") + activities = [user.ap_id] |> ActivityPub.fetch_activities_query(params) |> Pagination.fetch_paginated(params) + Logger.debug("TimelineController.direct: #{user.nickname} - rendering") + conn |> add_link_headers(activities) |> render("index.json", @@ -102,6 +118,7 @@ defp restrict_unauthenticated?(type) do # GET /api/v1/timelines/public def public(%{assigns: %{user: user}} = conn, params) do + Logger.debug("TimelineController.public") local_only = params[:local] timeline_type = if local_only, do: :local, else: :federated @@ -109,6 +126,8 @@ def public(%{assigns: %{user: user}} = conn, params) do {:enabled, local_only || Config.get([:instance, :federated_timeline_available], true)}, {:authenticated, true} <- {:authenticated, !(is_nil(user) and restrict_unauthenticated?(timeline_type))} do + Logger.debug("TimelineController.public: fetching activities") + activities = params |> Map.put(:type, ["Create"]) @@ -121,6 +140,8 @@ def public(%{assigns: %{user: user}} = conn, params) do |> Map.put(:includes_local_public, not is_nil(user)) |> ActivityPub.fetch_public_activities() + Logger.debug("TimelineController.public: rendering") + conn |> add_link_headers(activities, %{"local" => local_only}) |> render("index.json", @@ -142,6 +163,8 @@ def public(%{assigns: %{user: user}} = conn, params) do # GET /api/v1/timelines/bubble def bubble(%{assigns: %{user: user}} = conn, params) do + Logger.debug("TimelineController.bubble") + if is_nil(user) and restrict_unauthenticated?(:bubble) do fail_on_bad_auth(conn) else @@ -151,6 +174,8 @@ def bubble(%{assigns: %{user: user}} = conn, params) do [Pleroma.Web.Endpoint.host()] ) + Logger.debug("TimelineController.bubble: fetching activities") + activities = params |> Map.put(:type, ["Create"]) @@ -160,6 +185,8 @@ def bubble(%{assigns: %{user: user}} = conn, params) do |> Map.put(:instance, bubble_instances) |> ActivityPub.fetch_public_activities() + Logger.debug("TimelineController.bubble: rendering") + conn |> add_link_headers(activities) |> render("index.json", diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 3868da8d9..47d1616c4 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MediaProxy alias Pleroma.Web.PleromaAPI.EmojiReactionController + require Logger import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1, visible_for_user?: 2] @@ -87,6 +88,7 @@ defp reblogged?(activity, %User{ap_id: ap_id}) do defp reblogged?(_activity, _user), do: false def render("index.json", opts) do + Logger.debug("Rendering index") reading_user = opts[:for] # To do: check AdminAPIControllerTest on the reasons behind nil activities in the list activities = Enum.filter(opts.activities, & &1) @@ -136,8 +138,10 @@ def render("index.json", opts) do def render( "show.json", - %{activity: %{data: %{"type" => "Announce", "object" => _object}} = activity} = opts + %{activity: %{id: id, data: %{"type" => "Announce", "object" => _object}} = activity} = + opts ) do + Logger.debug("Rendering reblog #{id}") user = CommonAPI.get_user(activity.data["actor"]) created_at = Utils.to_masto_date(activity.data["published"]) object = Object.normalize(activity, fetch: false) @@ -209,7 +213,9 @@ def render( } end - def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do + def render("show.json", %{activity: %{id: id, data: %{"object" => _object}} = activity} = opts) do + Logger.debug("Rendering status #{id}") + with %Object{} = object <- Object.normalize(activity, fetch: false) do user = CommonAPI.get_user(activity.data["actor"]) user_follower_address = user.follower_address @@ -428,6 +434,7 @@ def render("show.json", _) do end def render("history.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do + Logger.debug("Rendering history for #{activity.id}") object = Object.normalize(activity, fetch: false) hashtags = Object.hashtags(object) @@ -614,6 +621,8 @@ def render("attachment_meta.json", %{ def render("attachment_meta.json", _), do: nil def render("context.json", %{activity: activity, activities: activities, user: user}) do + Logger.debug("Rendering context for #{activity.id}") + %{ancestors: ancestors, descendants: descendants} = activities |> Enum.reverse() From 2a8c1f41924e3f7092ffea0fb407c2906f705242 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Wed, 29 Mar 2023 14:11:00 +0100 Subject: [PATCH 7/7] Add extra diagnostic tasks in --- lib/mix/tasks/pleroma/diagnostics.ex | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/lib/mix/tasks/pleroma/diagnostics.ex b/lib/mix/tasks/pleroma/diagnostics.ex index 3914540ca..3b6063723 100644 --- a/lib/mix/tasks/pleroma/diagnostics.ex +++ b/lib/mix/tasks/pleroma/diagnostics.ex @@ -82,4 +82,46 @@ def run(["user_timeline", nickname, reading_nickname]) do Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity) |> IO.puts() end + + def run(["notifications", nickname]) do + start_pleroma() + user = Repo.get_by!(User, nickname: nickname) + account_ap_id = user.ap_id + options = %{account_ap_id: user.ap_id} + + query = + user + |> Pleroma.Notification.for_user_query(options) + |> where([n, a], a.actor == ^account_ap_id) + |> limit(20) + + Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity) + |> IO.puts() + end + + def run(["known_network", nickname]) do + start_pleroma() + user = Repo.get_by!(User, nickname: nickname) + + params = + %{} + |> Map.put(:type, ["Create"]) + |> Map.put(:local_only, false) + |> Map.put(:blocking_user, user) + |> Map.put(:muting_user, user) + |> Map.put(:reply_filtering_user, user) + # Restricts unfederated content to authenticated users + |> Map.put(:includes_local_public, not is_nil(user)) + |> Map.put(:restrict_unlisted, true) + + query = + Pleroma.Web.ActivityPub.ActivityPub.fetch_activities_query( + [Pleroma.Constants.as_public()], + params + ) + |> limit(20) + + Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity) + |> IO.puts() + end end