diff --git a/.gitignore b/.gitignore index a3fa6d5..fc490ee 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ npm-debug.log *.db *.db-* +# Uploads +/uploads/ diff --git a/README.md b/README.md index 68f6653..5fb40ad 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ - [x] Making posts locally - [x] Figuring out follower list - [x] Sending to followers - - [ ] Post formatting + - [x] Post formatting - [ ] Sending posts w/ images / videos - [ ] Receiving posts w/ images / videos - [ ] Timeline - [x] My posts - - [ ] Posts from accounts you follow + - [x] Posts from accounts you follow - [ ] Show the actor avatar and display name - [ ] Deleting posts - [ ] Profile @@ -30,17 +30,22 @@ ## UX - [x] Posting -- [ ] Timeline - - [~] My posts - - [ ] Posts from accounts you follow +- [x] Timeline + - [x] My posts + - [x] Posts from accounts you follow - [ ] Deleting posts - [~] Following - [ ] Unfollowing - [ ] Being followed - [ ] Accepting follows -- Approving / declining follows and authorized instance list +- [ ] Approving / declining follows and authorized instance list - [ ] Liking - [ ] Unliking - [ ] CW posts - [ ] Polls - [ ] DMs + +## Testing + +- [ ] Measure test coverage +- [ ] Add tests diff --git a/config/config.exs b/config/config.exs index cf79f35..ea65ce7 100644 --- a/config/config.exs +++ b/config/config.exs @@ -11,6 +11,16 @@ config :postland, ecto_repos: [Postland.Repo], generators: [timestamp_type: :utc_datetime] +upload_path = + if config_env() == :prod do + System.get_env("DATABASE_PATH") |> Path.dirname() |> Path.join("uploads/") + else + File.cwd!() |> Path.join("uploads/") + end + +config :postland, + upload_path: upload_path + # Configures the endpoint config :postland, PostlandWeb.Endpoint, url: [host: "localhost"], diff --git a/lib/postland.ex b/lib/postland.ex index 56a62fd..c3e7d76 100644 --- a/lib/postland.ex +++ b/lib/postland.ex @@ -9,6 +9,8 @@ defmodule Postland do use Phoenix.VerifiedRoutes, endpoint: PostlandWeb.Endpoint, router: PostlandWeb.Router + require Logger + alias Postland.Accounts def temporary_password() do @@ -31,6 +33,9 @@ defmodule Postland do end def on_boot_setup() do + File.mkdir_p!(Postland.Uploads.upload_path()) + Logger.info("File upload path: #{Postland.Uploads.upload_path()}") + if !setup?() do # TODO: Require the DB have restrictive permissions %{public: public_key, private: private_key} = generate_keys() diff --git a/lib/postland/accounts/user.ex b/lib/postland/accounts/user.ex index 3409aa6..96bf26f 100644 --- a/lib/postland/accounts/user.ex +++ b/lib/postland/accounts/user.ex @@ -5,6 +5,7 @@ defmodule Postland.Accounts.User do schema "users" do field :name, :string field :summary, :string + field :icon, :string field :username, :string field :password, :string, virtual: true, redact: true field :hashed_password, :string, redact: true @@ -119,6 +120,11 @@ defmodule Postland.Accounts.User do |> cast(attrs, [:name, :summary]) end + def icon_changeset(user, path) do + user + |> cast(%{icon: path}, [:icon]) + end + @doc """ Verifies the password. diff --git a/lib/postland/uploads.ex b/lib/postland/uploads.ex new file mode 100644 index 0000000..7c6aa15 --- /dev/null +++ b/lib/postland/uploads.ex @@ -0,0 +1,27 @@ +defmodule Postland.Uploads do + use Phoenix.VerifiedRoutes, + endpoint: PostlandWeb.Endpoint, + router: PostlandWeb.Router, + statics: ["uploads"] + + def upload_path() do + Application.get_env(:postland, :upload_path) + end + + def handle_upload(%{client_type: mime_type, uuid: uuid}, %{path: path} = meta) do + extension = extension_from_mime(mime_type) + dest = Path.join(upload_path(), "#{uuid}#{extension}") + File.cp!(path, dest) + {:ok, ~p"/uploads/#{Path.basename(dest)}"} + end + + def extension_from_mime(mime_type) do + case MIME.extensions(mime_type) do + [] -> + "" + + [ext | _rest] -> + ".#{ext}" + end + end +end diff --git a/lib/postland_web/components/core_components.ex b/lib/postland_web/components/core_components.ex index cfce2b6..221b547 100644 --- a/lib/postland_web/components/core_components.ex +++ b/lib/postland_web/components/core_components.ex @@ -15,17 +15,29 @@ defmodule PostlandWeb.CoreComponents do Icons are provided by [heroicons](https://heroicons.com). See `icon/1` for usage. """ use Phoenix.Component + use Phoenix.VerifiedRoutes, endpoint: PostlandWeb.Endpoint, router: PostlandWeb.Router alias Phoenix.LiveView.JS use Gettext, backend: PostlandWeb.Gettext def post_form(assigns) do + user = Postland.Accounts.solo_user() + ~H"""