x_posts tests are passing

This commit is contained in:
CJ_Clippy 2025-03-17 15:30:16 -08:00
parent d4db1eb2ed
commit 3f199a86fe
8 changed files with 474 additions and 390 deletions
apps/bright
terraform

@ -122,13 +122,22 @@ defmodule Bright.Platforms do
"""
def create_platform_alias(attrs \\ %{}) do
IO.inspect(attrs, label: "PlatformAlias Attributes Before Insert")
%PlatformAlias{}
|> PlatformAlias.changeset(attrs)
|> Repo.insert()
end
def match_platform?(a, b) do
URI.parse(a.url).host === URI.parse(b.url).host
host_a = URI.parse(a.url).host
host_b = URI.parse(b.url).host
Logger.debug(
"🚨 Comparing hosts: #{inspect(host_a)} vs #{inspect(host_b)} (#{host_a === host_b})"
)
host_a === host_b
end
@doc """

@ -16,8 +16,8 @@ defmodule Bright.Platforms.Platform do
@doc false
def changeset(platform, attrs) do
platform
|> cast(attrs, [:name, :url, :slug])
|> validate_required([:name, :url, :slug])
|> cast(attrs, [:name, :url, :slug, :nsfw])
|> validate_required([:name, :url, :slug, :nsfw])
|> unique_constraint(:name)
end
end

@ -12,7 +12,7 @@ defmodule Bright.Platforms.PlatformAlias do
@doc false
def changeset(platform_alias, attrs) do
platform_alias
|> cast(attrs, [:url])
|> validate_required([:url])
|> cast(attrs, [:url, :platform_id])
|> validate_required([:url, :platform_id])
end
end

@ -116,6 +116,12 @@ defmodule Bright.Socials.XPost do
%Platform{url: url, platform_aliases: %Ecto.Association.NotLoaded{}} = platform
) do
platform = Repo.preload(platform, :platform_aliases)
Logger.debug(
"include_platform? called with a platform that doesnt have platform_aliases preloaded, so we will preload for them."
)
Logger.debug(inspect(platform))
includes_platform?(raw_text, platform)
end
@ -124,18 +130,17 @@ defmodule Bright.Socials.XPost do
end
def includes_platform?(raw_text, %Platform{url: url, platform_aliases: aliases}) do
host = URI.parse(url).host
platform_host = URI.parse(url).host
Logger.debug(
"includes_platform? with raw_text=#{inspect(raw_text)} and aliases=#{inspect(aliases)}"
)
aliases =
aliases_hosts =
aliases
# Assuming platform_aliases have an `alias` field.
|> Enum.map(& &1.alias)
|> Enum.map(&URI.parse(&1.url).host)
values_to_match = [host | aliases]
values_to_match = [platform_host | aliases_hosts]
Enum.any?(values_to_match, fn value ->
String.contains?(raw_text, value)
@ -145,9 +150,29 @@ defmodule Bright.Socials.XPost do
def includes_platform?(_, _), do: false
def get_platforms_mentioned(raw_text, platforms) do
Logger.debug(
"get_platforms_mentioned with raw_text=#{inspect(raw_text)} platforms=#{inspect(platforms)}"
)
Enum.filter(platforms, &includes_platform?(raw_text, &1))
end
# def platform_alias_mentioned?(%XPost{id: xpost_id}) do
# xpost = Repo.get(XPost, xpost_id)
# if xpost do
# aliases =
# from(pa in PlatformAlias, select: pa.url)
# |> Repo.all()
# Enum.any?(aliases, fn alias ->
# String.contains?(xpost.raw, alias)
# end)
# else
# false
# end
# end
def parse(%XPost{} = post) do
known_platforms = Platforms.list_platforms()
parse(post, known_platforms)
@ -181,15 +206,19 @@ defmodule Bright.Socials.XPost do
) do
mentioned_platforms = get_platforms_mentioned(post, known_platforms)
Logger.debug("Checking if post is NSFW live announcement: #{inspect(post)}")
Logger.debug("🐉 known_platforms: #{inspect(known_platforms)}")
nsfw_platforms = Enum.filter(known_platforms, & &1.nsfw)
sfw_platforms = Enum.reject(known_platforms, & &1.nsfw)
Logger.debug("🐉 Mentioned platforms: #{inspect(mentioned_platforms)}")
Logger.debug("🐉 NSFW platforms: #{inspect(nsfw_platforms)}")
conditions = [
{:is_not_rt, XPost.authored_by_vtuber?(post, vtuber)},
{:is_not_vod, not String.contains?(String.downcase(post.raw), "vod")},
{:is_nsfw_platform, Platforms.contains_platform?(mentioned_platforms, nsfw_platforms)},
{:is_not_sfw_platform, not Platforms.contains_platform?(mentioned_platforms, sfw_platforms)}
{:is_nsfw_platform, Platforms.contains_platform?(nsfw_platforms, mentioned_platforms)},
{:is_no_sfw_platform, not Platforms.contains_platform?(mentioned_platforms, sfw_platforms)}
]
Enum.reduce_while(conditions, true, fn {label, condition}, _acc ->

@ -120,7 +120,8 @@ defmodule Bright.XPostTest do
post =
SocialsFixtures.x_post_fixture(%{
raw: "check me out LIVE at https://chaturbate.com/projektmelody",
raw:
"check me out LIVE at https://chaturbate.com/projektmelody https://fansly.com/projektmelody https://onlyfans.com/projektmelody",
vtuber_id: vtuber.id
})
|> Repo.preload(:vtuber)
@ -137,78 +138,87 @@ defmodule Bright.XPostTest do
assert is_live
end
@tag :taco
test "get platforms_mentioned", %{
known_platforms: known_platforms,
vtuber: vtuber,
post: post
} do
%{platforms_mentioned: platforms_mentioned} = XPost.parse(post, known_platforms)
assert length(platforms_mentioned) > 3
assert length(platforms_mentioned) === 3
end
end
describe "includes_alias?/2" do
setup do
{:ok, ytmnd} =
Platforms.create_platform(%{
name: "You're The Man Now Dog",
slug: "ytmnd",
url: "https://blueballfixed.ytmnd.com",
nsfw: false
})
# describe "platform_alias_mentioned?/1" do
# setup do
# {:ok, ytmnd} =
# Platforms.create_platform(%{
# name: "You're The Man Now Dog",
# slug: "ytmnd",
# url: "https://blueballfixed.ytmnd.com",
# nsfw: false
# })
Platforms.create_platform_alias(%{url: "https://shorturl.at/lZ3NM", platform_id: ytmnd.id})
# Platforms.create_platform_alias(%{url: "https://shorturl.at/lZ3NM", platform_id: ytmnd.id})
Platforms.create_platform(%{
name: "Twitch",
slug: "twitch",
url: "https://twitch.tv",
nsfw: false
})
# Platforms.create_platform(%{
# name: "Twitch",
# slug: "twitch",
# url: "https://twitch.tv",
# nsfw: false
# })
:ok
end
# :ok
# end
@tag :unit
test "returns true when a platform alias url is found in XPost raw content" do
platform = Platform |> Repo.get_by!(slug: "ytmnd") |> Repo.preload(:platform_aliases)
x_post = %XPost{raw: "Hello World please join my stream rn https://shorturl.at/lZ3NM"}
assert XPost.includes_alias?(x_post, platform)
end
# @tag :unit
# test "returns true when a platform alias url is found in XPost raw content" do
# platform = Platform |> Repo.get_by!(slug: "ytmnd") |> Repo.preload(:platform_aliases)
# x_post = %XPost{raw: "Hello World please join my stream rn https://shorturl.at/lZ3NM"}
# assert XPost.platform_alias_mentioned?(x_post)
# end
@tag :unit
test "returns false when no platform alias url is present in XPost raw content" do
platform = Platform |> Repo.get_by!(slug: "ytmnd") |> Repo.preload(:platform_aliases)
x_post = %XPost{raw: "i just ate breakfast and then i went outside it was gret"}
assert not XPost.includes_alias?(x_post, platform)
end
# @tag :unit
# test "returns false when no platform alias url is present in XPost raw content" do
# platform = Platform |> Repo.get_by!(slug: "ytmnd") |> Repo.preload(:platform_aliases)
# x_post = %XPost{raw: "i just ate breakfast and then i went outside it was gret"}
# assert not XPost.platform_alias_mentioned?(x_post)
# end
@tag :unit
test "returns true when a platform alias url is found in raw_text" do
platform = Platform |> Repo.get_by!(slug: "ytmnd") |> Repo.preload(:platform_aliases)
raw_text = "GOING LIVE NOW shorturl.at/lZ3NM"
assert XPost.includes_alias?(raw_text, platform)
end
# @tag :unit
# test "returns true when a platform alias url is found in raw_text" do
# platform = Platform |> Repo.get_by!(slug: "ytmnd") |> Repo.preload(:platform_aliases)
# raw_text = "GOING LIVE NOW shorturl.at/lZ3NM"
# assert XPost.platform_alias_mentioned?(raw_text)
# end
@tag :unit
test "returns false when no platform alias url is present in raw_text" do
platform = Platform |> Repo.get_by!(slug: "ytmnd") |> Repo.preload(:platform_aliases)
raw_text = "#420 #blazeit #bbq #LuL"
assert not XPost.includes_alias?(raw_text, platform)
end
end
# @tag :unit
# test "returns false when no platform alias url is present in raw_text" do
# platform = Platform |> Repo.get_by!(slug: "ytmnd") |> Repo.preload(:platform_aliases)
# raw_text = "#420 #blazeit #bbq #LuL"
# assert not XPost.platform_alias_mentioned?(raw_text)
# end
# end
describe "includes_platform?" do
setup do
%Platform{
%{
name: "Chaturbate",
slug: "chaturbate",
url: "https://chaturbate.com",
nsfw: true
}
|> Repo.insert!()
|> Platforms.create_platform()
%Platform{name: "Twitch", slug: "twitch", url: "https://twitch.tv", nsfw: false}
|> Repo.insert!()
%{name: "Twitch", slug: "twitch", url: "https://twitch.tv", nsfw: false}
|> Platforms.create_platform()
{:ok, fansly} =
%{name: "Fansly", slug: "fansly", url: "https://fansly.com", nsfw: true}
|> Platforms.create_platform()
%{url: "https://melody.buzz", platform_id: fansly.id}
|> Platforms.create_platform_alias()
:ok
end
@ -227,6 +237,20 @@ defmodule Bright.XPostTest do
XPost.includes_platform?(raw_text, platform)
end
@tag :unit
test "includes_platform? matches associated PlatformAlias" do
raw_text = "hello world check out my stream: http://melody.buzz"
platforms = Platform |> Repo.all()
platform =
Platform
|> Repo.get_by!(slug: "fansly")
|> Repo.preload(:platform_aliases)
XPost.includes_platform?(raw_text, platform)
end
@tag :unit
test "includes_platform? with x_post" do
x_post = %XPost{raw: "LIVE NOW https://chaturbate.com"}
@ -243,20 +267,23 @@ defmodule Bright.XPostTest do
describe "get_platforms_mentioned" do
setup %{} do
known_platforms = PlatformsFixtures.known_platforms_fixture()
known_platforms = Repo.preload(known_platforms, :platform_aliases)
vtuber = VtubersFixtures.projektmelody_fixture()
{:ok, known_platforms: known_platforms}
idk = Repo.all(PlatformAlias)
{:ok, known_platforms: known_platforms, vtuber: vtuber}
end
@tag :unit
@tag :taco
test "post with no links" do
test "post with no links", %{vtuber: vtuber} do
platforms = Platforms.list_platforms()
expected_platform_names = []
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_offline_1() |> Map.get(:raw),
XPostsFixtures.fixture_offline_1(%{vtuber_id: vtuber.id}) |> Map.get(:raw),
platforms
)
# Extract only names
@ -266,98 +293,12 @@ defmodule Bright.XPostTest do
end
@tag :unit
test "post with non-invite links" do
platforms = Platforms.list_platforms()
expected_platform_names = []
test "post with non-invite links", %{known_platforms: known_platforms, vtuber: vtuber} do
expected_platform_names = ["Linktree"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_offline_2() |> Map.get(:raw),
platforms
)
# Extract only names
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
test "post with only SFW invite links" do
platforms = Platforms.list_platforms()
expected_platform_names = ["Fansly", "Twitch"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_offline_3() |> Map.get(:raw),
platforms
)
# Extract only names
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
test "another post with only SFW invite links" do
platforms = Platforms.list_platforms()
expected_platform_names = ["Fansly", "Twitch"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_offline_4() |> Map.get(:raw),
platforms
)
# Extract only names
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
test "post with 3 platform invites 1" do
platforms = Platforms.list_platforms()
expected_platform_names = ["Fansly", "OnlyFans", "Chaturbate"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_live_1() |> Map.get(:raw),
platforms
)
# Extract only names
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
test "post with 3 platform invites 2" do
platforms = Platforms.list_platforms()
expected_platform_names = ["Fansly", "OnlyFans", "Chaturbate"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_live_2() |> Map.get(:raw),
platforms
)
# Extract only names
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
@tag :taco
test "post with 3 platform invites 3", %{known_platforms: known_platforms} do
expected_platform_names = ["Fansly", "OnlyFans", "Chaturbate"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_live_3() |> Map.get(:raw),
XPostsFixtures.fixture_offline_2(%{vtuber_id: vtuber.id}) |> Map.get(:raw),
known_platforms
)
# Extract only names
@ -367,12 +308,92 @@ defmodule Bright.XPostTest do
end
@tag :unit
test "post with a platform alias", %{known_platforms: known_platforms} do
test "post with only SFW invite links", %{known_platforms: known_platforms, vtuber: vtuber} do
expected_platform_names = ["Fansly", "Twitch"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_offline_3(%{vtuber_id: vtuber.id}) |> Map.get(:raw),
known_platforms
)
# Extract only names
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
test "another post with only SFW invite links", %{vtuber: vtuber} do
platforms = Platforms.list_platforms()
expected_platform_names = ["Fansly", "Twitch"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_offline_4(%{vtuber_id: vtuber.id}) |> Map.get(:raw),
platforms
)
# Extract only names
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
test "post with 3 platform invites 1", %{vtuber: vtuber} do
platforms = Platforms.list_platforms()
expected_platform_names = ["Fansly", "OnlyFans", "Chaturbate"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_live_1(%{vtuber_id: vtuber.id}) |> Map.get(:raw),
platforms
)
# Extract only names
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
test "post with 3 platform invites 2", %{vtuber: vtuber} do
platforms = Platforms.list_platforms()
expected_platform_names = ["Fansly", "OnlyFans", "Chaturbate"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_live_2(%{vtuber_id: vtuber.id}) |> Map.get(:raw),
platforms
)
# Extract only names
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
test "post with 3 platform invites 3", %{known_platforms: known_platforms, vtuber: vtuber} do
expected_platform_names = ["Fansly", "OnlyFans", "Chaturbate"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_live_3(%{vtuber_id: vtuber.id}) |> Map.get(:raw),
known_platforms
)
|> Enum.map(& &1.name)
assert Enum.sort(actual_platform_names) == Enum.sort(expected_platform_names)
end
@tag :unit
test "post with a platform alias", %{known_platforms: known_platforms, vtuber: vtuber} do
expected_platform_names = ["Fansly"]
actual_platform_names =
XPost.get_platforms_mentioned(
XPostsFixtures.fixture_live_4() |> Map.get(:raw),
XPostsFixtures.fixture_live_4(%{vtuber_id: vtuber.id}) |> Map.get(:raw),
known_platforms
)
|> Enum.map(& &1.name)
@ -381,109 +402,88 @@ defmodule Bright.XPostTest do
end
end
# describe "is_nsfw_live_announcement?/3" do
# setup do
# vtuber = VtubersFixtures.projektmelody_fixture()
describe "is_nsfw_live_announcement?/2" do
setup do
vtuber = VtubersFixtures.projektmelody_fixture()
# {:ok, x_post} =
# Socials.create_x_post(%{
# raw: "I'm going live https://chaturbate.com/projektmelody",
# url: "https://x.com/projektmelody/status/1234",
# date: DateTime.utc_now(:second),
# vtuber_id: vtuber.id
# })
{:ok, x_post} =
Socials.create_x_post(%{
raw: "I'm going live https://chaturbate.com/projektmelody",
url: "https://x.com/projektmelody/status/1234",
date: DateTime.utc_now(:second),
vtuber_id: vtuber.id
})
# x_post = Repo.preload(x_post, :vtuber)
# known_platforms = PlatformsFixtures.known_platforms_fixture()
x_post = Repo.preload(x_post, :vtuber)
# mentioned_platforms = [
# PlatformsFixtures.onlyfans_fixture(),
# PlatformsFixtures.chaturbate_fixture(),
# PlatformsFixtures.fansly_fixture()
# ]
known_platforms = PlatformsFixtures.known_platforms_fixture()
# {:ok,
# vtuber: vtuber,
# x_post: x_post,
# known_platforms: known_platforms,
# mentioned_platforms: mentioned_platforms}
# end
{:ok, vtuber: vtuber, x_post: x_post, known_platforms: known_platforms}
end
# @tag :integration
# test "should return false when receiving a XPost linking to a SFW platform", %{
# vtuber: vtuber,
# x_post: x_post,
# known_platforms: known_platforms
# } do
# mentioned_platforms = [
# PlatformsFixtures.twitch_fixture(),
# PlatformsFixtures.fansly_fixture(),
# PlatformsFixtures.onlyfans_fixture(),
# PlatformsFixtures.chaturbate_fixture()
# ]
@tag :integration
@tag :taco
test "should return false when receiving a XPost linking to a SFW platform", %{
known_platforms: known_platforms,
vtuber: vtuber
} do
x_post = XPostsFixtures.fixture_offline_3(%{vtuber_id: vtuber.id})
x_post = Repo.preload(x_post, :vtuber)
IO.puts(">>> x_post=#{inspect(x_post)}")
assert not XPost.is_nsfw_live_announcement?(x_post, known_platforms)
end
# assert not XPost.is_nsfw_live_announcement?(x_post, mentioned_platforms, known_platforms)
# end
test "should return true when receiving an XPost with only Chaturbate mentioned", %{
vtuber: vtuber,
x_post: x_post,
known_platforms: known_platforms
} do
assert XPost.is_nsfw_live_announcement?(x_post, known_platforms)
end
# test "should return true when receiving an XPost with only Chaturbate mentioned", %{
# vtuber: vtuber,
# x_post: x_post,
# known_platforms: known_platforms,
# mentioned_platforms: mentioned_platforms
# } do
# mentioned_platforms = [
# PlatformsFixtures.chaturbate_fixture()
# ]
test "should return true when receiving an XPost with only NSFW platforms mentioned", %{
vtuber: vtuber,
x_post: x_post,
known_platforms: known_platforms
} do
assert XPost.is_nsfw_live_announcement?(x_post, known_platforms)
end
# assert XPost.is_nsfw_live_announcement?(x_post, mentioned_platforms, known_platforms)
# end
test "should return false when the XPost is a retweet", %{
known_platforms: known_platforms
} do
vtuber = VtubersFixtures.el_xox_fixture()
# test "should return true when receiving an XPost with only NSFW platforms mentioned", %{
# vtuber: vtuber,
# x_post: x_post,
# known_platforms: known_platforms,
# mentioned_platforms: mentioned_platforms
# } do
# assert XPost.is_nsfw_live_announcement?(x_post, mentioned_platforms, known_platforms)
# end
x_post = %XPost{
url: "https://x.com/mangel0399/status/1898602105851506907",
raw: "#34_XoX",
date: ~U[2025-03-09T05:09:51.000Z],
processed_at: nil,
vtuber_id: vtuber.id
}
# test "should return false when the XPost is a retweet", %{
# known_platforms: known_platforms,
# mentioned_platforms: mentioned_platforms
# } do
# vtuber = VtubersFixtures.el_xox_fixture()
x_post = Repo.preload(x_post, :vtuber)
# x_post = %XPost{
# url: "https://x.com/mangel0399/status/1898602105851506907",
# raw: "#34_XoX",
# date: ~U[2025-03-09T05:09:51.000Z],
# processed_at: nil,
# vtuber_id: vtuber.id
# }
assert not XPost.is_nsfw_live_announcement?(x_post, known_platforms)
end
# x_post = Repo.preload(x_post, :vtuber)
test "should return false when receiving an XPost with `vod/i`", %{
known_platforms: known_platforms
} do
vtuber = VtubersFixtures.el_xox_fixture()
# assert not XPost.is_nsfw_live_announcement?(x_post, mentioned_platforms, known_platforms)
# end
x_post = %XPost{
raw:
"IRL JOI handcam stream! Listen to my instructions and stroke your cock for me until you cum 🍆💦\n\nThe rest of the VOD is available here for Tier 1 subscribers or for $10! 💛\n▶️ https://fansly.com/post/755934614",
url: "https://x.com/el_XoX34/status/1900275678152712493",
date: ~U[2025-03-09T05:09:51.000Z],
processed_at: nil,
vtuber_id: vtuber.id
}
# test "should return false when receiving an XPost with `vod/i`", %{
# known_platforms: known_platforms
# } do
# vtuber = VtubersFixtures.el_xox_fixture()
x_post = Repo.preload(x_post, :vtuber)
# x_post = %XPost{
# raw:
# "IRL JOI handcam stream! Listen to my instructions and stroke your cock for me until you cum 🍆💦\n\nThe rest of the VOD is available here for Tier 1 subscribers or for $10! 💛\n▶ https://fansly.com/post/755934614",
# url: "https://x.com/el_XoX34/status/1900275678152712493",
# date: ~U[2025-03-09T05:09:51.000Z],
# processed_at: nil,
# vtuber_id: vtuber.id
# }
# x_post = Repo.preload(x_post, :vtuber)
# mentioned_platforms = [PlatformsFixtures.fansly_fixture()]
# assert not XPost.is_nsfw_live_announcement?(x_post, mentioned_platforms, known_platforms)
# end
# end
assert not XPost.is_nsfw_live_announcement?(x_post, known_platforms)
end
end
end

@ -16,7 +16,8 @@ defmodule Bright.PlatformsFixtures do
|> Enum.into(%{
slug: "some_slug",
name: "some name",
url: "some url"
url: "some url",
nsfw: true
})
|> Bright.Platforms.create_platform()
@ -54,14 +55,13 @@ defmodule Bright.PlatformsFixtures do
}
|> Bright.Platforms.create_platform()
{:ok, alias} =
{:ok, platform_alias} =
%{
url: "https://melody.buzz",
platform_id: platform.id
}
|> Bright.Platforms.create_platform_alias()
# Repo.preload(platform, :platform_aliases)
platform
end

@ -1,5 +1,6 @@
defmodule Bright.XPostsFixtures do
alias Bright.Socials.XPost
alias Bright.Socials
@moduledoc """
This module defines test helpers for creating
@ -9,85 +10,130 @@ defmodule Bright.XPostsFixtures do
@doc """
A x_post which does NOT contain an invite link to any of Chaturbate, Fansly, OnlyFans.
"""
def fixture_offline_1() do
%XPost{
raw:
"sry i got off early, gots a headphone headache but regardles.... I REALLY LIKE MONSTER HUNTER (we kicked 2 monster asses solo today!!!!)",
date: ~U[2025-03-12T05:00:00.000Z],
url: "https://x.com/ProjektMelody/status/1899686928913412421"
}
def fixture_offline_1(attrs \\ %{}) do
{:ok, x_post} =
attrs
|> Enum.into(%{
raw:
"sry i got off early, gots a headphone headache but regardles.... I REALLY LIKE MONSTER HUNTER (we kicked 2 monster asses solo today!!!!)",
date: ~U[2025-03-12T05:00:00.000Z],
url: "https://x.com/ProjektMelody/status/1899686928913412421"
})
|> Socials.create_x_post()
x_post
end
def fixture_offline_2() do
%XPost{
raw:
"▀▄▀▄▀▄ SCHEDULE ▄▀▄▀▄▀\n: http://linktr.ee/projektmelody\n⦉╰( ߬⚈ o⚈ꪷ)╯𖹭 ˗ˏˋ(‿(ᶅ͒)‿) ˎˊ˗ : https://afterdark.market\n",
date: ~U[2025-03-05T06:25:35.000Z],
url: "https://x.com/ProjektMelody/status/1897171614439223545"
}
def fixture_offline_2(attrs \\ %{}) do
{:ok, x_post} =
attrs
|> Enum.into(%{
raw:
"▀▄▀▄▀▄ SCHEDULE ▄▀▄▀▄▀\n: http://linktr.ee/projektmelody\n⦉╰( ߬⚈ o⚈ꪷ)╯𖹭 ˗ˏˋ(‿(ᶅ͒)‿) ˎˊ˗ : https://afterdark.market\n",
date: ~U[2025-03-05T06:25:35.000Z],
url: "https://x.com/ProjektMelody/status/1897171614439223545"
})
|> Socials.create_x_post()
x_post
end
def fixture_offline_3() do
%XPost{
raw:
"I'M LIVE! FEELIN GOOD! LETS GAEM! \n\nhttp://twitch.tv/projektmelody \nhttp://melody.buzz\n\nWe're also doin' a lil giveaway, as @GFuelEnergy\n\n sponsored us :D ---- use !join in twitch chat at spec. times!\n\nFeelin' shoppy? Code MEL gets ur butt 20% OFF ur order-- http://gfuel.ly/mel",
date: ~U[2025-02-25T03:22:57.000Z],
url: "https://x.com/ProjektMelody/status/1894226549215281249"
}
def fixture_offline_3(attrs \\ %{}) do
{:ok, x_post} =
attrs
|> Enum.into(%{
raw:
"I'M LIVE! FEELIN GOOD! LETS GAEM! \n\nhttp://twitch.tv/projektmelody \nhttp://melody.buzz\n\nWe're also doin' a lil giveaway, as @GFuelEnergy\n\n sponsored us :D ---- use !join in twitch chat at spec. times!\n\nFeelin' shoppy? Code MEL gets ur butt 20% OFF ur order-- http://gfuel.ly/mel",
date: ~U[2025-02-25T03:22:57.000Z],
url: "https://x.com/ProjektMelody/status/1894226549215281249"
})
|> Socials.create_x_post()
x_post
end
def fixture_offline_4() do
%XPost{
raw:
"HAPPY TWITCHIVERSARY!\n\nsadly ive succombed to doom scrolling & family issues lately. i couldnt push myself to bring my A-game.... so, we're 2D. however, @iJinzu is joining us! he offered to coach me in monster hunter! :,)\n\nlive: http://twitch.tv/projektmelody\nhttp://melody.buzz",
date: ~U[2025-03-07T22:15:00.000Z],
url: "https://x.com/ProjektMelody/status/1898135320874344448"
}
def fixture_offline_4(attrs \\ %{}) do
{:ok, x_post} =
attrs
|> Enum.into(%{
raw:
"HAPPY TWITCHIVERSARY!\n\nsadly ive succombed to doom scrolling & family issues lately. i couldnt push myself to bring my A-game.... so, we're 2D. however, @iJinzu is joining us! he offered to coach me in monster hunter! :,)\n\nlive: http://twitch.tv/projektmelody\nhttp://melody.buzz",
date: ~U[2025-03-07T22:15:00.000Z],
url: "https://x.com/ProjektMelody/status/1898135320874344448"
})
|> Socials.create_x_post()
x_post
end
def fixture_offline_5() do
%XPost{
raw: "It's happening.. hold my hands please.. 🥺 ▶ twitch.tv/el_xox",
date: ~U[2025-03-12 22:53:24Z],
url: "https://x.com/el_XoX34/status/1832215752591470655"
}
def fixture_offline_5(attrs \\ %{}) do
{:ok, x_post} =
attrs
|> Enum.into(%{
raw: "It's happening.. hold my hands please.. 🥺 ▶ twitch.tv/el_xox",
date: ~U[2025-03-12 22:53:24Z],
url: "https://x.com/el_XoX34/status/1832215752591470655"
})
|> Socials.create_x_post()
x_post
end
@doc """
A x_post which contains an invite link to any of Fansly, Chaturbate, OnlyFans.
"""
def fixture_live_1() do
%XPost{
raw: "🥯fansly: melody.buzz \n📷onlyfans.com/?ref=16786030 \n📷chaturbate.com/projektmelody",
date: ~U[2025-03-05T18:30:00.000Z],
url: "https://x.com/ProjektMelody/status/1897385055640805666"
}
def fixture_live_1(attrs \\ %{}) do
{:ok, x_post} =
attrs
|> Enum.into(%{
raw: "🥯fansly: melody.buzz \n📷onlyfans.com/?ref=16786030 \n📷chaturbate.com/projektmelody",
date: ~U[2025-03-05T18:30:00.000Z],
url: "https://x.com/ProjektMelody/status/1897385055640805666"
})
|> Socials.create_x_post()
x_post
end
def fixture_live_2() do
%XPost{
raw:
"bruh wassup, it's movie night~\n(have a faptastic day!!!!)\n\n🥯fansly: http://melody.buzz \n🍆http://onlyfans.com/?ref=16786030 \n💦http://chaturbate.com/projektmelody",
date: ~U[2025-02-26T02:14:59.000Z],
url: "https://x.com/ProjektMelody/status/1894571836408504825"
}
def fixture_live_2(attrs \\ %{}) do
{:ok, x_post} =
attrs
|> Enum.into(%{
raw:
"bruh wassup, it's movie night~\n(have a faptastic day!!!!)\n\n🥯fansly: http://melody.buzz \n🍆http://onlyfans.com/?ref=16786030 \n💦http://chaturbate.com/projektmelody",
date: ~U[2025-02-26T02:14:59.000Z],
url: "https://x.com/ProjektMelody/status/1894571836408504825"
})
|> Socials.create_x_post()
x_post
end
def fixture_live_3() do
%XPost{
raw:
"oh, damn---if @Lovense\never starts making tip-assissted ejaculating dildos. my community would frost my ass like a 30-layer wedding cake. i;d become a literal cannoli-hole... hmmm...\nANYWAY, i'm live: \n🥯fansly: http://melody.buzz \n🍆http://onlyfans.com/?ref=16786030 \n💦http://chaturbate.com/projektmelody\n",
date: ~U[2025-03-01T01:05:12.000Z],
url: "https://x.com/ProjektMelody/status/1895641435187151207"
}
def fixture_live_3(attrs \\ %{}) do
{:ok, x_post} =
attrs
|> Enum.into(%{
raw:
"oh, damn---if @Lovense\never starts making tip-assissted ejaculating dildos. my community would frost my ass like a 30-layer wedding cake. i;d become a literal cannoli-hole... hmmm...\nANYWAY, i'm live: \n🥯fansly: http://melody.buzz \n🍆http://onlyfans.com/?ref=16786030 \n💦http://chaturbate.com/projektmelody\n",
date: ~U[2025-03-01T01:05:12.000Z],
url: "https://x.com/ProjektMelody/status/1895641435187151207"
})
|> Socials.create_x_post()
x_post
end
def fixture_live_4() do
%XPost{
raw: "http://melody.buzz",
date: ~U[2025-05-05T05:05:05.000Z],
url: "https://x.com/ProjektMelody/status/5555"
}
def fixture_live_4(attrs \\ %{}) do
{:ok, x_post} =
attrs
|> Enum.into(%{
raw: "http://melody.buzz",
date: ~U[2025-05-05T05:05:05.000Z],
url: "https://x.com/ProjektMelody/status/5555"
})
|> Socials.create_x_post()
x_post
end
@doc """

@ -7,46 +7,46 @@ locals {
}
variable bright_port {
variable "bright_port" {
default = "4000"
}
variable database_host {
variable "database_host" {
default = "10.2.128.4"
}
variable public_s3_endpoint {
variable "public_s3_endpoint" {
default = "https://futureporn-b2.b-cdn.net"
}
variable patreon_redirect_uri {
variable "patreon_redirect_uri" {
default = "https://bright.futureporn.net/auth/patreon/callback"
}
variable site_url {
variable "site_url" {
default = "https://bright.futureporn.net"
}
variable phx_host {
variable "phx_host" {
default = "bright.futureporn.net"
}
variable aws_bucket {
variable "aws_bucket" {
default = "futureporn"
}
variable aws_region {
variable "aws_region" {
default = "us-west-000"
}
variable aws_host {
variable "aws_host" {
default = "s3.us-west-000.backblazeb2.com"
}
variable "vps_user_data" {
# most packages are installed using ansible, but we do use cloud-config
# to install python3, an ansible dependency
default = <<-EOT
# most packages are installed using ansible, but we do use cloud-config
# to install python3, an ansible dependency
default = <<-EOT
#cloud-config
package_update: true
packages:
@ -62,11 +62,11 @@ variable "vps_user_data" {
terraform {
required_providers {
vultr = {
source = "vultr/vultr"
source = "vultr/vultr"
version = "2.23.1"
}
ansible = {
source = "ansible/ansible"
source = "ansible/ansible"
version = "1.2.0"
}
}
@ -74,44 +74,44 @@ terraform {
provider "vultr" {
api_key = "${local.envs.VULTR_API_KEY}"
api_key = local.envs.VULTR_API_KEY
}
# reserved IP lets us spin down the system and spin up without losing the IP reservation
resource "vultr_reserved_ip" "futureporn_v2_ip" {
label = "futureporn-v2"
region = "ord"
ip_type = "v4"
label = "futureporn-v2"
region = "ord"
ip_type = "v4"
}
resource "vultr_reserved_ip" "futureporn_tracker_ip" {
label = "futureporn-tracker"
region = "ord"
ip_type = "v4"
label = "futureporn-tracker"
region = "ord"
ip_type = "v4"
}
# Virtual Private Cloud for connecting many VPS together on a private network
# We use this network connection for app<->db comms.
resource "vultr_vpc2" "futureporn_vpc2" {
region = "ord"
region = "ord"
description = "Futureporn V2 VPC2"
}
# load balancing instance
resource "vultr_instance" "load_balancer" {
count = 1
hostname = "fp-lb-${count.index}"
plan = "vc2-1c-2gb"
region = "ord"
backups = "disabled"
count = 1
hostname = "fp-lb-${count.index}"
plan = "vc2-1c-2gb"
region = "ord"
backups = "disabled"
ddos_protection = "false"
os_id = 1743
enable_ipv6 = true
label = "fp lb ${count.index}"
tags = ["futureporn", "load_balancer", "bright"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
user_data = base64encode(var.vps_user_data)
os_id = 1743
enable_ipv6 = true
label = "fp lb ${count.index}"
tags = ["futureporn", "load_balancer", "bright"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
user_data = base64encode(var.vps_user_data)
vpc2_ids = [
vultr_vpc2.futureporn_vpc2.id
]
@ -120,17 +120,17 @@ resource "vultr_instance" "load_balancer" {
# vultr instance for running bright app
resource "vultr_instance" "bright" {
count = 1
hostname = "fp-bright-${count.index}"
plan = "vc2-2c-4gb"
region = "ord"
backups = "disabled"
count = 1
hostname = "fp-bright-${count.index}"
plan = "vc2-2c-4gb"
region = "ord"
backups = "disabled"
ddos_protection = "false"
os_id = 1743
enable_ipv6 = true
label = "fp bright ${count.index}"
tags = ["futureporn", "phoenix", "bright"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
os_id = 1743
enable_ipv6 = true
label = "fp bright ${count.index}"
tags = ["futureporn", "phoenix", "bright"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
vpc2_ids = [
vultr_vpc2.futureporn_vpc2.id
]
@ -148,19 +148,19 @@ resource "vultr_instance" "capture_vps" {
ddos_protection = "false"
os_id = 1743
enable_ipv6 = true
vpc2_ids = [vultr_vpc2.futureporn_vpc2.id]
label = "fp capture ${count.index}"
tags = ["futureporn", "capture"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
user_data = base64encode(var.vps_user_data)
vpc2_ids = [vultr_vpc2.futureporn_vpc2.id]
label = "fp capture ${count.index}"
tags = ["futureporn", "capture"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
user_data = base64encode(var.vps_user_data)
}
resource "vultr_instance" "database" {
count = 1
hostname = "fp-db-${count.index}"
plan = "vc2-1c-2gb"
region = "ord"
backups = "enabled"
count = 1
hostname = "fp-db-${count.index}"
plan = "vc2-1c-2gb"
region = "ord"
backups = "enabled"
backups_schedule {
hour = "2"
type = "daily"
@ -168,11 +168,11 @@ resource "vultr_instance" "database" {
ddos_protection = "false"
os_id = 1743
enable_ipv6 = true
vpc2_ids = [vultr_vpc2.futureporn_vpc2.id]
label = "fp database ${count.index}"
tags = ["futureporn", "database"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
user_data = base64encode(var.vps_user_data)
vpc2_ids = [vultr_vpc2.futureporn_vpc2.id]
label = "fp database ${count.index}"
tags = ["futureporn", "database"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
user_data = base64encode(var.vps_user_data)
}
resource "vultr_instance" "tracker" {
@ -184,18 +184,18 @@ resource "vultr_instance" "tracker" {
ddos_protection = "false"
os_id = 1743
enable_ipv6 = true
vpc2_ids = [vultr_vpc2.futureporn_vpc2.id]
label = "fp tracker ${count.index}"
tags = ["futureporn", "tracker"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
user_data = base64encode(var.vps_user_data)
reserved_ip_id = vultr_reserved_ip.futureporn_tracker_ip.id
vpc2_ids = [vultr_vpc2.futureporn_vpc2.id]
label = "fp tracker ${count.index}"
tags = ["futureporn", "tracker"]
ssh_key_ids = [local.envs.VULTR_SSH_KEY_ID]
user_data = base64encode(var.vps_user_data)
reserved_ip_id = vultr_reserved_ip.futureporn_tracker_ip.id
}
resource "ansible_host" "capture_vps" {
for_each = { for idx, host in vultr_instance.capture_vps : idx => host }
name = each.value.hostname
groups = ["capture"] # Groups this host is part of.
name = each.value.hostname
groups = ["capture"] # Groups this host is part of.
variables = {
# Connection vars.
@ -210,42 +210,42 @@ resource "ansible_host" "capture_vps" {
resource "ansible_host" "load_balancer" {
for_each = { for idx, host in vultr_instance.load_balancer : idx => host }
name = each.value.hostname
groups = ["load_balancer"]
name = each.value.hostname
groups = ["load_balancer"]
variables = {
ansible_host = each.value.main_ip
internal_ip = each.value.internal_ip
internal_ip = each.value.internal_ip
}
}
resource "ansible_host" "database" {
for_each = { for idx, host in vultr_instance.database : idx => host }
name = each.value.hostname
groups = ["database"]
name = each.value.hostname
groups = ["database"]
variables = {
ansible_host = each.value.main_ip
internal_ip = each.value.internal_ip
internal_ip = each.value.internal_ip
}
}
resource "ansible_host" "bright" {
for_each = { for idx, host in vultr_instance.bright : idx => host }
name = each.value.hostname
groups = ["bright"]
name = each.value.hostname
groups = ["bright"]
variables = {
ansible_host = each.value.main_ip
internal_ip = each.value.internal_ip
ansible_host = each.value.main_ip
internal_ip = each.value.internal_ip
vultr_instance_id = each.value.id
}
}
resource "ansible_host" "tracker" {
for_each = { for idx, host in vultr_instance.tracker : idx => host }
name = each.value.hostname
groups = ["tracker"]
name = each.value.hostname
groups = ["tracker"]
variables = {
ansible_host = each.value.main_ip
internal_ip = each.value.internal_ip
ansible_host = each.value.main_ip
internal_ip = each.value.internal_ip
vultr_instance_id = each.value.id
}
}
@ -322,4 +322,4 @@ resource "ansible_group" "futureporn" {
# - ufw allow 4001
# EOT
# )
# )