Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve seeds #568

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
68 changes: 68 additions & 0 deletions lib/atomic/icon.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
defmodule Atomic.Icon do
@moduledoc """
A module for generating unique, GitHub-style avatars for organizations.

This module takes an organization's name as input, hashes it, and then generates
a 5x5 grid-based icon using a mirroring pattern. The resulting icon is saved as
an SVG file in the `priv/static/images` directory.
"""

@grid_size 5
@cell_size 50

@doc """
Generates an icon for the given organization based on its name.

## Returns
- The file path of the generated SVG icon.
"""
def generate_icon(organization) do
input = organization["name"]
hash = :crypto.hash(:sha256, input) |> :binary.bin_to_list()
color = Enum.take(hash, 3)
grid = build_grid(hash)

svg = draw(grid, color)
path = "priv/static/images/#{input}.svg"
File.write!(path, svg)
path
end

defp build_grid(hash) do
hash
|> Enum.chunk_every(@grid_size, @grid_size, :discard)
|> Enum.map(&mirror/1)
|> List.flatten()
end

defp mirror(row) do
[a, b, c | _] = row
[a, b, c, b, a]
end

defp draw(grid, color) do
[r, g, b] = color

header = """
<svg width="#{@grid_size * @cell_size}" height="#{@grid_size * @cell_size}" xmlns="http://www.w3.org/2000/svg">
"""

footer = "</svg>"

body =
Enum.map_join(
grid
|> Enum.with_index()
|> Enum.filter(fn {val, _} -> rem(val, 2) == 0 end),
"\n",
fn {_val, index} ->
x = rem(index, @grid_size) * @cell_size
y = div(index, @grid_size) * @cell_size

"<rect x='#{x}' y='#{y}' width='#{@cell_size}' height='#{@cell_size}' fill='rgb(#{r},#{g},#{b})' />"
end
)

header <> body <> footer
end
end
8 changes: 4 additions & 4 deletions priv/fake/organizations.json
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@
},
{
"name": "Núcleo de Estudante de Contabilidade da Universidade do Minho",
"long_name": "",
"description": ""
"long_name": "Núcleo de Estudante de Contabilidade da Universidade do Minho",
"description": "Núcleo de Estudante de Contabilidade da Universidade do Minho"
},
{
"name": "NUMERUM",
Expand All @@ -226,7 +226,7 @@
},
{
"name": "PoliticUM",
"long_name": "",
"description": ""
"long_name": "PoliticUM",
"description": "PoliticUM"
}
]
93 changes: 72 additions & 21 deletions priv/repo/seeds/feed.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,68 @@ defmodule Atomic.Repo.Seeds.Feed do
alias Atomic.Repo

@activity_titles [
"Geek Night",
"Hack Night",
"Hackathon",
"Workshop",
"Talk",
"Meetup",
"Conference",
"Seminar",
"Course",
"Bootcamp",
"Study session"
"🌌 Geek Night",
"💻 Hack Night",
"🚀 Hackathon",
"🛠️ Workshop",
"🎤 Palestra",
"🤝 Meetup",
"🌍 Conferência",
"📚 Seminário",
"🎓 Curso",
"🏋️ Bootcamp",
"📖 Sessão de Estudo"
]

@announcement_titles [
"📢 Atualização importante da comunidade estudantil!",
"🚀 Novidades emocionantes para todos os estudantes!",
"🔔 Um anúncio que não vais querer perder!",
"💡 Mantém-te informado: aqui está o que está a acontecer!",
"📅 Grandes mudanças a caminho!",
"🎉 Uma mensagem especial para os nossos membros!",
"🚨 Vamos falar: aviso importante para ti!",
"📣 Grandes oportunidades esperam por ti – lê mais aqui!",
"🌟 Aqui está o que precisas de saber!",
"🏆 Atenção, estudantes: temos algo para partilhar!"
]

def activity_description(organization, activity_title) do
activity_paragraphs = [
"O #{organization.name} preparou mais uma edição de #{activity_title}! Esta é uma excelente oportunidade para te juntares a uma comunidade dinâmica, explorando novas ideias e desenvolvendo as tuas habilidades num ambiente envolvente e colaborativo.",
"Junta-te ao #{organization.name} na próxima #{activity_title}! Um evento pensado para todos os que querem aprender, partilhar conhecimento e conectar-se com outros entusiastas da área.",
"O #{organization.name} convida-te para a #{activity_title}! Prepara-te para um momento repleto de aprendizagem, desafios estimulantes e oportunidades de networking num ambiente descontraído.",
"A #{activity_title} organizada pelo #{organization.name} está quase a chegar! Uma experiência única onde podes desenvolver novas competências e conhecer pessoas com interesses semelhantes.",
"Não percas a #{activity_title} promovida pelo #{organization.name}! Um evento pensado para criar um espaço de partilha, crescimento e inovação. Fica atento para mais detalhes e garante já a tua presença! 🚀",
"O #{organization.name} traz-te a #{activity_title}, um evento onde a aprendizagem e a diversão andam de mãos dadas. Vem descobrir novas oportunidades e expandir os teus horizontes!",
"Vem participar na #{activity_title} organizada pelo #{organization.name}! Um momento perfeito para trocares experiências, aprenderes algo novo e te conectares com a comunidade.",
"A #{activity_title} do #{organization.name} é uma oportunidade imperdível para todos os interessados em explorar novas áreas e desafios. Não fiques de fora!",
"O #{organization.name} preparou a #{activity_title} a pensar em ti! Participa neste evento e aproveita para desenvolver as tuas competências num ambiente dinâmico e inspirador.",
"Se procuras uma experiência enriquecedora, a #{activity_title} promovida pelo #{organization.name} é o evento certo para ti. Marca já na tua agenda e junta-te a nós!"
]

paragraph = Enum.random(activity_paragraphs)
paragraph
end

def announcement_description(organization) do
announcement_paragraphs = [
"📢 O #{organization.name} tem novidades para ti! Fica atento, porque algo incrível está a caminho. Em breve revelamos mais detalhes!",
"🚀 Atenção, comunidade! O #{organization.name} está a preparar algo especial. Não vais querer perder esta novidade!",
"🔔 Tens acompanhado as novidades do #{organization.name}? Um anúncio importante será feito em breve. Fica ligado!",
"💡 Algo empolgante está a acontecer no #{organization.name}! Mal podemos esperar para partilhar contigo. Fica atento às nossas redes!",
"📅 O #{organization.name} tem um grande anúncio para fazer. Prepara-te para descobrir algo que vai fazer a diferença!",
"🎉 Boas notícias a caminho! O #{organization.name} está prestes a lançar uma nova iniciativa. Descobre tudo em breve!",
"🚨 O #{organization.name} tem uma surpresa reservada para ti! Mantém-te ligado para não perderes esta grande oportunidade.",
"📣 Está quase! Em breve o #{organization.name} vai anunciar algo que não vais querer perder. Fica atento!",
"🌟 A equipa do #{organization.name} tem trabalhado em algo muito especial para ti. O anúncio oficial está a chegar!",
"🏆 Uma grande novidade do #{organization.name} está prestes a ser revelada. Garante que não perdes esta oportunidade única!"
]

paragraph = Enum.random(announcement_paragraphs)
paragraph
end

def run do
seed_posts()
end
Expand All @@ -35,8 +84,8 @@ defmodule Atomic.Repo.Seeds.Feed do
type = Enum.random([:activity, :announcement])

case type do
:activity -> seed_activity(Enum.random(organizations).id, i)
:announcement -> seed_announcement(Enum.random(organizations).id)
:activity -> seed_activity(Enum.random(organizations), i)
:announcement -> seed_announcement(Enum.random(organizations))
end
end

Expand All @@ -45,21 +94,23 @@ defmodule Atomic.Repo.Seeds.Feed do
end
end

def seed_activity(organization_id, i) do
def seed_activity(organization, i) do
location = %{
name: Faker.Address.city(),
url: Faker.Internet.url()
}

title = Enum.random(@activity_titles)

%{
title: Enum.random(@activity_titles),
description: Faker.Lorem.paragraph(),
title: title,
description: activity_description(organization, title),
start: build_start_date(i),
finish: build_finish_date(i),
location: location,
minimum_entries: Enum.random(1..10),
maximum_entries: Enum.random(11..20),
organization_id: organization_id,
organization_id: organization.id,
enrolled: Enum.random(0..10)
}
|> Activities.create_activity_with_post()
Expand All @@ -69,11 +120,11 @@ defmodule Atomic.Repo.Seeds.Feed do
end
end

def seed_announcement(organization_id) do
def seed_announcement(organization) do
%{
title: Faker.Lorem.sentence(),
description: Faker.Lorem.paragraph(),
organization_id: organization_id
title: Enum.random(@announcement_titles),
description: announcement_description(organization),
organization_id: organization.id
}
|> Organizations.create_announcement_with_post()
|> case do
Expand Down
34 changes: 28 additions & 6 deletions priv/repo/seeds/organizations.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule Atomic.Repo.Seeds.Organizations do
@moduledoc """
Seeds the database with organizations.
"""
alias Atomic.Icon
alias Atomic.Organizations
alias Atomic.Organizations.Organization
alias Atomic.Repo
Expand Down Expand Up @@ -44,12 +45,33 @@ defmodule Atomic.Repo.Seeds.Organizations do
# Seed other organizations
@organizations
|> Enum.each(fn organization ->
%{
name: organization["name"],
long_name: organization["long_name"],
description: organization["description"]
}
|> Organizations.create_organization()
case Repo.get_by(Organization, name: organization["name"]) do
nil ->
{:ok, new_org} =
%{
name: organization["name"],
long_name: organization["long_name"],
description: organization["description"]
}
|> Organizations.create_organization()

logo_path = Atomic.Icon.generate_icon(organization)

new_org
|> Organization.logo_changeset(%{
logo: %Plug.Upload{
path: logo_path,
content_type: "image/svg",
filename: "#{organization["name"]}.svg"
}
})
|> Repo.update!()

File.rm(logo_path)

_existing_org ->
IO.puts("Organization '#{organization["name"]}' already exists. Skipping...")
end
end)
end
end
Expand Down
Loading