diff --git a/lib/philomena/comments.ex b/lib/philomena/comments.ex index 1c94a1d8..6a118125 100644 --- a/lib/philomena/comments.ex +++ b/lib/philomena/comments.ex @@ -55,7 +55,7 @@ defmodule Philomena.Comments do |> Multi.run(:subscribe, fn _repo, _changes -> Images.create_subscription(image, attribution[:user]) end) - |> Repo.transaction() + |> Repo.isolated_transaction(:serializable) end def notify_comment(comment) do diff --git a/lib/philomena/processors.ex b/lib/philomena/processors.ex index 3f745795..d21592d5 100644 --- a/lib/philomena/processors.ex +++ b/lib/philomena/processors.ex @@ -142,8 +142,15 @@ defmodule Philomena.Processors do File.mkdir_p!(dir) File.rm(new_destination) - File.ln_s!(file, new_destination) - File.chmod!(new_destination, 0o755) + platform_symlink(file, new_destination) + File.chmod(new_destination, 0o755) + end + + defp platform_symlink(source, destination) do + case File.ln_s(source, destination) do + :ok -> :ok + _err -> File.cp!(source, destination) + end end defp analysis_to_changes(analysis, file, upload_name) do diff --git a/lib/philomena/servers/image_processor.ex b/lib/philomena/servers/image_processor.ex index 6a8961ba..5e9bc7b0 100644 --- a/lib/philomena/servers/image_processor.ex +++ b/lib/philomena/servers/image_processor.ex @@ -10,6 +10,11 @@ defmodule Philomena.Servers.ImageProcessor do GenServer.cast(pid, {:enqueue, image_id}) end + def call do + pid = Process.whereis(:processor) + GenServer.call(pid, :wait, :infinity) + end + @impl true def init([]) do Process.register(self(), :processor) @@ -32,4 +37,9 @@ defmodule Philomena.Servers.ImageProcessor do # _ -> # nil end + + @impl true + def handle_call(:wait, _from, []) do + {:reply, nil, []} + end end \ No newline at end of file diff --git a/lib/philomena/tags/tag.ex b/lib/philomena/tags/tag.ex index d5fe25c5..e3187fb2 100644 --- a/lib/philomena/tags/tag.ex +++ b/lib/philomena/tags/tag.ex @@ -181,7 +181,7 @@ defmodule Philomena.Tags.Tag do case @namespace_categories[namespace] do nil -> changeset - category -> change(changeset, category: @namespace_categories[namespace]) + category -> change(changeset, category: category) end end end diff --git a/lib/philomena_web/controllers/activity_controller.ex b/lib/philomena_web/controllers/activity_controller.ex index 3248720b..996825c5 100644 --- a/lib/philomena_web/controllers/activity_controller.ex +++ b/lib/philomena_web/controllers/activity_controller.ex @@ -53,7 +53,7 @@ defmodule PhilomenaWeb.ActivityController do pagination: %{conn.assigns.image_pagination | page_number: 1} ) - watched_images + if Enum.any?(watched_images), do: watched_images end featured_image = diff --git a/mix.exs b/mix.exs index c6af87ed..12adaee5 100644 --- a/mix.exs +++ b/mix.exs @@ -72,6 +72,7 @@ defmodule Philomena.MixProject do defp aliases do [ "ecto.setup": ["ecto.create", "ecto.load", "run priv/repo/seeds.exs"], + "ecto.setup_dev": ["ecto.create", "ecto.load", "run priv/repo/seeds.exs", "run priv/repo/seeds_development.exs"], "ecto.reset": ["ecto.drop", "ecto.setup"], "ecto.migrate": ["ecto.migrate", "ecto.dump"], "ecto.rollback": ["ecto.rollback", "ecto.dump"], diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 36b27d77..e275329e 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -15,12 +15,10 @@ alias Philomena.Tags import Ecto.Query IO.puts "---- Creating Elasticsearch indices" -Image.create_index! -Comment.create_index! -Gallery.create_index! -Tag.create_index! -Post.create_index! -# Report.create_index! +for model <- [Image, Comment, Gallery, Tag, Post] do # Report + model.delete_index! + model.create_index! +end resources = "priv/repo/seeds.json" diff --git a/priv/repo/seeds_development.exs b/priv/repo/seeds_development.exs new file mode 100644 index 00000000..96bfe592 --- /dev/null +++ b/priv/repo/seeds_development.exs @@ -0,0 +1,145 @@ +# Script for populating the database. You can run it as: +# +# mix run priv/repo/seeds.exs +# +# Inside the script, you can read and write to any of your +# repositories directly: +# +# Philomena.Repo.insert!(%Philomena.SomeSchema{}) +# +# We recommend using the bang functions (`insert!`, `update!` +# and so on) as they will fail if something goes wrong. + +alias Philomena.{Repo, Forums.Forum, Users.User} +alias Philomena.Servers.ImageProcessor +alias Philomena.Comments +alias Philomena.Images +alias Philomena.Topics +alias Philomena.Posts +alias Philomena.Tags + +{:ok, ip} = EctoNetwork.INET.cast({203, 0, 113, 0}) +{:ok, _} = Application.ensure_all_started(:plug) + +resources = + "priv/repo/seeds_development.json" + |> File.read!() + |> Jason.decode!() + +IO.puts "---- Generating users" +for user_def <- resources["users"] do + %User{} + |> User.creation_changeset(user_def) + |> Repo.insert(on_conflict: :nothing) +end + +pleb = Repo.get_by!(User, name: "Pleb") +request_attributes = [ + fingerprint: "c1836832948", + ip: ip, + user_agent: "Hopefully not IE", + referrer: "localhost", + user_id: pleb.id, + user: pleb +] + +IO.puts "---- Generating images" +for image_def <- resources["remote_images"] do + file = Briefly.create!() + now = DateTime.utc_now() |> DateTime.to_unix(:microsecond) + + IO.puts "Fetching #{image_def["url"]} ..." + %{body: body} = Philomena.Http.get!(image_def["url"]) + + File.write!(file, body) + + upload = %Plug.Upload{ + path: file, + content_type: "application/octet-stream", + filename: "fixtures-#{now}" + } + + IO.puts "Inserting ..." + + Images.create_image( + request_attributes, + Map.merge(image_def, %{"image" => upload}) + ) + |> case do + {:ok, %{image: image}} -> + ImageProcessor.cast(image.id) + Images.reindex_image(image) + Tags.reindex_tags(image.added_tags) + + IO.puts "Created image ##{image.id}" + + {:error, :image, changeset, _so_far} -> + IO.inspect changeset.errors + end +end + +IO.puts "---- Generating comments for image #1" +for comment_body <- resources["comments"] do + image = Images.get_image!(1) + + Comments.create_comment( + image, + request_attributes, + %{"body" => comment_body} + ) + |> case do + {:ok, %{comment: comment}} -> + Comments.reindex_comment(comment) + Images.reindex_image(image) + + {:error, :comment, changeset, _so_far} -> + IO.inspect changeset.errors + end +end + +IO.puts "---- Generating forum posts" +for resource <- resources["forum_posts"] do + for {forum_name, topics} <- resource do + forum = Repo.get_by!(Forum, short_name: forum_name) + + for {topic_name, [first_post | posts]} <- topics do + Topics.create_topic( + forum, + request_attributes, + %{ + "title" => topic_name, + "posts" => %{ + "0" => %{ + "body" => first_post, + } + } + } + ) + |> case do + {:ok, %{topic: topic}} -> + for post <- posts do + Posts.create_post( + topic, + request_attributes, + %{"body" => post} + ) + |> case do + {:ok, %{post: post}} -> + Posts.reindex_post(post) + + {:error, :post, changeset, _so_far} -> + IO.inspect changeset.errors + end + end + + {:error, :topic, changeset, _so_far} -> + IO.inspect changeset.errors + end + end + end +end + +# Wait for processor to finish +ImageProcessor.call() + +IO.puts "---- Done." \ No newline at end of file diff --git a/priv/repo/seeds_development.json b/priv/repo/seeds_development.json index cce01ef2..bfa16a9d 100644 --- a/priv/repo/seeds_development.json +++ b/priv/repo/seeds_development.json @@ -3,34 +3,56 @@ "name": "Hot Pocket Consumer", "email": "moderator@example.com", "password": "willdeleteglimmerposts4hotpockets", + "confirm_password": "willdeleteglimmerposts4hotpockets", "role": "moderator" }, { "name": "Hoping For a Promotion", "email": "assistant@example.com", "password": "hotpocketfetchingass", + "confirm_password": "hotpocketfetchingass", "role": "assistant" }, { "name": "Pleb", "email": "user@example.com", "password": "glimmerpostingplebeian", + "confirm_password": "glimmerpostingplebeian", "role": "user" } ], - "tags": [ - "spacebar heating", - "fair dice roll", - "correcthorsebatterystaple", - "spaghetti", - "piƱata", - "dot.dot" - ], "remote_images": [{ - "url": "http://orig14.deviantart.net/c2d0/f/2015/269/9/b/tirek_battle_12exp_by_equumamici-d9ax5yd.gif", - "description": "Fairly large GIF (~23MB), use to test WebM stuff.", - "tags": "artist:equum_amici, safe, large gif" - }], + "url": "https://derpicdn.net/img/view/2015/9/26/988000.gif", + "source_url": "https://derpibooru.org/988000", + "description": "Fairly large GIF (~23MB), use to test WebM stuff.", + "tag_input": "alicorn, angry, animated, art, artist:assasinmonkey, artist:equum_amici, badass, barrier, crying, dark, epic, female, fight, force field, glare, glow, good vs evil, lord tirek, low angle, magic, mare, messy mane, metal as fuck, perspective, plot, pony, raised hoof, safe, size difference, spread wings, stomping, twilight's kingdom, twilight sparkle, twilight sparkle (alicorn), twilight vs tirek, underhoof" + }, + { + "url": "https://derpicdn.net/img/2012/1/2/25/large.png", + "source_url": "https://derpibooru.org/25", + "tag_input": "artist:moe, canterlot, castle, cliff, cloud, detailed background, fog, forest, grass, mountain, mountain range, nature, no pony, outdoors, path, river, safe, scenery, scenery porn, signature, source needed, sunset, technical advanced, town, tree, useless source url, water, waterfall, widescreen, wood" + }, + { + "url": "https://derpicdn.net/img/2018/6/28/1767886/full.webm", + "source_url": "http://hydrusbeta.deviantart.com/art/Gleaming-in-the-Sun-Our-Colors-Shine-in-Every-Hue-611497309", + "tag_input": "3d, animated, architecture, artist:hydrusbeta, castle, cloud, crystal empire, crystal palace, flag, flag waving, no pony, no sound, safe, scenery, webm" + }, + { + "url": "https://derpicdn.net/img/view/2015/2/19/832750.jpg", + "source_url": "http://sovietrussianbrony.tumblr.com/post/111504505079/this-image-actually-took-me-ages-to-edit-the", + "tag_input": "artist:rhads, artist:the sexy assistant, canterlot, cloud, cloudsdale, cloudy, edit, lens flare, no pony, ponyville, rainbow, river, safe, scenery, sweet apple acres" + }, + { + "url": "https://derpicdn.net/img/view/2016/3/17/1110529.jpg", + "source_url": "https://www.deviantart.com/devinian/art/Commission-Crystals-of-thy-heart-511134926", + "tag_input": "artist:devinian, aurora crystialis, bridge, cloud, crepuscular rays, crystal empire, crystal palace, edit, flower, forest, grass, log, mountain, no pony, river, road, safe, scenery, scenery porn, source needed, stars, sunset, swing, tree, wallpaper" + }, + { + "url": "https://derpicdn.net/img/view/2019/6/16/2067468.svg", + "source_url": "https://derpibooru.org/2067468", + "tag_input": "artist:cheezedoodle96, babs seed, bloom and gloom, cutie mark, cutie mark only, no pony, safe, scissors, simple background, svg, .svg available, transparent background, vector" + } + ], "comments": [ "bold is *bold*, italic is _italic_, spoiler is [spoiler]spoiler[/spoiler], code is @code@, underline is +underline+, strike is -strike-, sup is ^sup^, sub is ~sub~.", "inline embedded thumbnails (tsp): >>1t >>1s >>1p", @@ -45,7 +67,8 @@ }, { "Second example topic": [ - "post" + "post", + "post 2" ] } ]