From e22a256af17c93a8dc0538ee010c9b8e7cb9ce8d Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Tue, 25 Feb 2025 14:21:29 +0000 Subject: [PATCH 01/10] feat: activitys and announcements english description and titles --- priv/repo/seeds/feed.exs | 44 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/priv/repo/seeds/feed.exs b/priv/repo/seeds/feed.exs index cdc2a161f..013c4b38e 100644 --- a/priv/repo/seeds/feed.exs +++ b/priv/repo/seeds/feed.exs @@ -22,6 +22,43 @@ defmodule Atomic.Repo.Seeds.Feed do "Study session" ] + @activity_sentences [ + "Join us for an engaging activity where you'll meet like-minded individuals, learn new skills, and participate in meaningful discussions.", + "activity is a fantastic opportunity to collaborate, exchange ideas, and immerse yourself in a dynamic learning environment.", + "Whether you're a beginner or an experienced professional, our activity is designed to be an inclusive space for growth and exploration.", + "Get ready for an interactive activity filled with insightful talks, hands-on activities, and opportunities to connect with industry experts.", + "At our activity, you'll have the chance to explore new trends, tackle real-world challenges, and expand your professional network.", + "We believe that learning should be both fun and impactful, and our activity is crafted to provide just that.", + "Expect a mix of structured learning, open discussions, and hands-on collaboration in this unique activity experience.", + "activity is more than just an event—it’s a chance to be part of a passionate community that values curiosity and innovation." + ] + + @announcement_titles [ + "Important Update from the Student Community", + "Exciting News for All Students!", + "An Announcement You Won’t Want to Miss!", + "Stay Informed: Here’s What’s Happening!", + "Big Changes Coming Soon!", + "A Special Message for Our Student Members", + "Let’s Talk: Important Notice for You", + "Great Opportunities Await – Read More Inside", + "Here’s What You Need to Know!", + "Attention Students: We Have Something to Share" + ] + + @announcement_sentences [ + "We have an important update regarding upcoming student services, so be sure to stay tuned for more details.", + "A new initiative is launching soon, and we’re excited to have you all be a part of it!", + "Exciting changes are happening behind the scenes, and we can’t wait to share them with you soon.", + "Make sure to check your emails for a special announcement regarding student benefits and resources.", + "Your feedback matters! We’re introducing new ways for students to have a say in campus decisions.", + "Looking for a way to get more involved? Stay tuned for some great opportunities coming your way.", + "We appreciate your support and can’t wait to unveil something special just for you!", + "The student group is growing, and we’re making big plans to improve your experience.", + "Have questions or suggestions? We’re always listening—reach out to us anytime!", + "Something exciting is happening on campus, and you’ll want to be part of it!" + ] + def run do seed_posts() end @@ -53,7 +90,7 @@ defmodule Atomic.Repo.Seeds.Feed do %{ title: Enum.random(@activity_titles), - description: Faker.Lorem.paragraph(), + description: Enum.random(@activity_sentences), start: build_start_date(i), finish: build_finish_date(i), location: location, @@ -71,8 +108,8 @@ defmodule Atomic.Repo.Seeds.Feed do def seed_announcement(organization_id) do %{ - title: Faker.Lorem.sentence(), - description: Faker.Lorem.paragraph(), + title: Enum.random(@announcement_titles), + description: Enum.random(@announcement_sentences), organization_id: organization_id } |> Organizations.create_announcement_with_post() @@ -94,6 +131,7 @@ defmodule Atomic.Repo.Seeds.Feed do |> NaiveDateTime.add(Enum.random(1..4), :hour) |> NaiveDateTime.truncate(:second) end + end Atomic.Repo.Seeds.Feed.run() From ce6290de0c3a8aba0a925038b5937715e0eae7a7 Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Sat, 1 Mar 2025 16:34:50 +0000 Subject: [PATCH 02/10] fix: placeholder information for orgs with missing attributes --- priv/fake/organizations.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/priv/fake/organizations.json b/priv/fake/organizations.json index d5f27ae48..453eac32c 100644 --- a/priv/fake/organizations.json +++ b/priv/fake/organizations.json @@ -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", @@ -226,7 +226,7 @@ }, { "name": "PoliticUM", - "long_name": "", - "description": "" + "long_name": "PoliticUM", + "description": "PoliticUM" } ] From 5e924613325a0efdace29b6b7c1d76557f81ea54 Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Sun, 2 Mar 2025 11:52:12 +0000 Subject: [PATCH 03/10] feat: text dependent of the organzation and/or activity in portuguese with emojis --- priv/repo/seeds/feed.exs | 123 ++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 53 deletions(-) diff --git a/priv/repo/seeds/feed.exs b/priv/repo/seeds/feed.exs index 013c4b38e..240dc24a2 100644 --- a/priv/repo/seeds/feed.exs +++ b/priv/repo/seeds/feed.exs @@ -9,55 +9,69 @@ 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" ] - @activity_sentences [ - "Join us for an engaging activity where you'll meet like-minded individuals, learn new skills, and participate in meaningful discussions.", - "activity is a fantastic opportunity to collaborate, exchange ideas, and immerse yourself in a dynamic learning environment.", - "Whether you're a beginner or an experienced professional, our activity is designed to be an inclusive space for growth and exploration.", - "Get ready for an interactive activity filled with insightful talks, hands-on activities, and opportunities to connect with industry experts.", - "At our activity, you'll have the chance to explore new trends, tackle real-world challenges, and expand your professional network.", - "We believe that learning should be both fun and impactful, and our activity is crafted to provide just that.", - "Expect a mix of structured learning, open discussions, and hands-on collaboration in this unique activity experience.", - "activity is more than just an event—it’s a chance to be part of a passionate community that values curiosity and innovation." - ] - @announcement_titles [ - "Important Update from the Student Community", - "Exciting News for All Students!", - "An Announcement You Won’t Want to Miss!", - "Stay Informed: Here’s What’s Happening!", - "Big Changes Coming Soon!", - "A Special Message for Our Student Members", - "Let’s Talk: Important Notice for You", - "Great Opportunities Await – Read More Inside", - "Here’s What You Need to Know!", - "Attention Students: We Have Something to Share" + "📢 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!" ] - @announcement_sentences [ - "We have an important update regarding upcoming student services, so be sure to stay tuned for more details.", - "A new initiative is launching soon, and we’re excited to have you all be a part of it!", - "Exciting changes are happening behind the scenes, and we can’t wait to share them with you soon.", - "Make sure to check your emails for a special announcement regarding student benefits and resources.", - "Your feedback matters! We’re introducing new ways for students to have a say in campus decisions.", - "Looking for a way to get more involved? Stay tuned for some great opportunities coming your way.", - "We appreciate your support and can’t wait to unveil something special just for you!", - "The student group is growing, and we’re making big plans to improve your experience.", - "Have questions or suggestions? We’re always listening—reach out to us anytime!", - "Something exciting is happening on campus, and you’ll want to be part of it!" - ] + 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() @@ -72,8 +86,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 @@ -82,21 +96,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: Enum.random(@activity_sentences), + 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() @@ -106,11 +122,12 @@ defmodule Atomic.Repo.Seeds.Feed do end end - def seed_announcement(organization_id) do + def seed_announcement(organization) do + %{ title: Enum.random(@announcement_titles), - description: Enum.random(@announcement_sentences), - organization_id: organization_id + description: announcement_description(organization), + organization_id: organization.id } |> Organizations.create_announcement_with_post() |> case do From 3efe9799362cb2e384ad1da0c7d8fad9a1ced6b1 Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Tue, 4 Mar 2025 15:35:22 +0000 Subject: [PATCH 04/10] feat: add github like default icon generator --- lib/atomic/icon.ex | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 lib/atomic/icon.ex diff --git a/lib/atomic/icon.ex b/lib/atomic/icon.ex new file mode 100644 index 000000000..115027e94 --- /dev/null +++ b/lib/atomic/icon.ex @@ -0,0 +1,49 @@ +defmodule Atomic.Icon do + @grid_size 5 + @cell_size 50 + 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 = """ + + """ + footer = "" + + body = + grid + |> Enum.with_index() + |> Enum.filter(fn {val, _} -> rem(val, 2) == 0 end) + |> Enum.map(fn {_val, index} -> + x = rem(index, @grid_size) * @cell_size + y = div(index, @grid_size) * @cell_size + "" + end) + |> Enum.join("\n") + + header <> body <> footer + end +end From f8d20cd3aa4ed77999b166603be37a7d1773f23a Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Tue, 4 Mar 2025 15:41:28 +0000 Subject: [PATCH 05/10] feat: new icon uploader --- priv/repo/seeds/organizations.exs | 34 ++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/priv/repo/seeds/organizations.exs b/priv/repo/seeds/organizations.exs index 2aaf5fea8..490b2bda1 100644 --- a/priv/repo/seeds/organizations.exs +++ b/priv/repo/seeds/organizations.exs @@ -1,10 +1,11 @@ -defmodule Atomic.Repo.Seeds.Organizations do +defmodule Atomic.Repo.Seeds.Organizations do @moduledoc """ Seeds the database with organizations. """ alias Atomic.Organizations alias Atomic.Organizations.Organization alias Atomic.Repo + alias Atomic.Icon @organizations File.read!("priv/fake/organizations.json") |> Jason.decode!() @@ -44,12 +45,31 @@ 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 From d41cf09b8567b0fa86768e013500a283805ce030 Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Tue, 4 Mar 2025 16:36:20 +0000 Subject: [PATCH 06/10] format --- lib/atomic/icon.ex | 4 +- priv/repo/seeds/feed.exs | 72 +++++++++++++++---------------- priv/repo/seeds/organizations.exs | 12 +++--- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/lib/atomic/icon.ex b/lib/atomic/icon.ex index 115027e94..3e1e023f2 100644 --- a/lib/atomic/icon.ex +++ b/lib/atomic/icon.ex @@ -2,7 +2,6 @@ defmodule Atomic.Icon do @grid_size 5 @cell_size 50 def generate_icon(organization) do - input = organization["name"] hash = :crypto.hash(:sha256, input) |> :binary.bin_to_list() color = Enum.take(hash, 3) @@ -28,9 +27,11 @@ defmodule Atomic.Icon do defp draw(grid, color) do [r, g, b] = color + header = """ """ + footer = "" body = @@ -40,6 +41,7 @@ defmodule Atomic.Icon do |> Enum.map(fn {_val, index} -> x = rem(index, @grid_size) * @cell_size y = div(index, @grid_size) * @cell_size + "" end) |> Enum.join("\n") diff --git a/priv/repo/seeds/feed.exs b/priv/repo/seeds/feed.exs index 240dc24a2..6bab9c678 100644 --- a/priv/repo/seeds/feed.exs +++ b/priv/repo/seeds/feed.exs @@ -33,45 +33,43 @@ defmodule Atomic.Repo.Seeds.Feed do "📣 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!" ] - 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 + 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 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() @@ -123,7 +121,6 @@ defmodule Atomic.Repo.Seeds.Feed do end def seed_announcement(organization) do - %{ title: Enum.random(@announcement_titles), description: announcement_description(organization), @@ -148,7 +145,6 @@ defmodule Atomic.Repo.Seeds.Feed do |> NaiveDateTime.add(Enum.random(1..4), :hour) |> NaiveDateTime.truncate(:second) end - end Atomic.Repo.Seeds.Feed.run() diff --git a/priv/repo/seeds/organizations.exs b/priv/repo/seeds/organizations.exs index 490b2bda1..abcd0de38 100644 --- a/priv/repo/seeds/organizations.exs +++ b/priv/repo/seeds/organizations.exs @@ -1,4 +1,4 @@ -defmodule Atomic.Repo.Seeds.Organizations do +defmodule Atomic.Repo.Seeds.Organizations do @moduledoc """ Seeds the database with organizations. """ @@ -46,8 +46,8 @@ defmodule Atomic.Repo.Seeds.Organizations do @organizations |> Enum.each(fn organization -> case Repo.get_by(Organization, name: organization["name"]) do - nil -> - {:ok, new_org}= + nil -> + {:ok, new_org} = %{ name: organization["name"], long_name: organization["long_name"], @@ -59,16 +59,18 @@ defmodule Atomic.Repo.Seeds.Organizations do new_org |> Organization.logo_changeset(%{ - logo: %Plug.Upload{ + 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...") + IO.puts("Organization '#{organization["name"]}' already exists. Skipping...") end end) end From fc663ade0d4605676151782348df3392bc211636 Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Tue, 4 Mar 2025 16:53:21 +0000 Subject: [PATCH 07/10] fix: improve code readability --- priv/repo/seeds/organizations.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/priv/repo/seeds/organizations.exs b/priv/repo/seeds/organizations.exs index abcd0de38..7fed12cb2 100644 --- a/priv/repo/seeds/organizations.exs +++ b/priv/repo/seeds/organizations.exs @@ -2,10 +2,10 @@ 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 - alias Atomic.Icon @organizations File.read!("priv/fake/organizations.json") |> Jason.decode!() From 094befcf139cd7d8c927bbf6df008009b0036847 Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Tue, 4 Mar 2025 17:11:07 +0000 Subject: [PATCH 08/10] docs: documentation for module icon --- lib/atomic/icon.ex | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/atomic/icon.ex b/lib/atomic/icon.ex index 3e1e023f2..c5b8f605f 100644 --- a/lib/atomic/icon.ex +++ b/lib/atomic/icon.ex @@ -1,6 +1,21 @@ 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() @@ -13,6 +28,9 @@ defmodule Atomic.Icon do path end + @doc """ + Builds a 5x5 mirrored grid based on the hash values. + """ defp build_grid(hash) do hash |> Enum.chunk_every(@grid_size, @grid_size, :discard) @@ -20,11 +38,17 @@ defmodule Atomic.Icon do |> List.flatten() end + @doc """ + Mirrors a row to ensure symmetry. + """ defp mirror(row) do [a, b, c | _] = row [a, b, c, b, a] end + @doc """ + Draws the SVG representation of the grid. + """ defp draw(grid, color) do [r, g, b] = color From 8ac3e0a51b75515479761ab7cb9a8f6b828dca29 Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Tue, 4 Mar 2025 17:17:03 +0000 Subject: [PATCH 09/10] docs: remove documentation from anonymous functions --- lib/atomic/icon.ex | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/atomic/icon.ex b/lib/atomic/icon.ex index c5b8f605f..80f5fa2d7 100644 --- a/lib/atomic/icon.ex +++ b/lib/atomic/icon.ex @@ -28,9 +28,6 @@ defmodule Atomic.Icon do path end - @doc """ - Builds a 5x5 mirrored grid based on the hash values. - """ defp build_grid(hash) do hash |> Enum.chunk_every(@grid_size, @grid_size, :discard) @@ -38,17 +35,11 @@ defmodule Atomic.Icon do |> List.flatten() end - @doc """ - Mirrors a row to ensure symmetry. - """ defp mirror(row) do [a, b, c | _] = row [a, b, c, b, a] end - @doc """ - Draws the SVG representation of the grid. - """ defp draw(grid, color) do [r, g, b] = color From 651a5888fe1f4257c92c2e67fdd583e7592b77ee Mon Sep 17 00:00:00 2001 From: GuilhermePSF Date: Tue, 4 Mar 2025 17:45:13 +0000 Subject: [PATCH 10/10] refactor: use join with 3 arity instead of 3 for efficiency --- lib/atomic/icon.ex | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/atomic/icon.ex b/lib/atomic/icon.ex index 80f5fa2d7..b6f2cb4f5 100644 --- a/lib/atomic/icon.ex +++ b/lib/atomic/icon.ex @@ -50,16 +50,18 @@ defmodule Atomic.Icon do footer = "" body = - grid - |> Enum.with_index() - |> Enum.filter(fn {val, _} -> rem(val, 2) == 0 end) - |> Enum.map(fn {_val, index} -> - x = rem(index, @grid_size) * @cell_size - y = div(index, @grid_size) * @cell_size + 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 - "" - end) - |> Enum.join("\n") + "" + end + ) header <> body <> footer end