Fix new credo warnings
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
52e624bb88
commit
51afec1856
|
@ -155,7 +155,7 @@ defmodule Mobilizon.Federation.ActivityPub do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create an activity from an event
|
# Create an activity from an event
|
||||||
@spec event_to_activity(%Event{}, boolean()) :: Activity.t()
|
@spec event_to_activity(Event.t(), boolean()) :: Activity.t()
|
||||||
defp event_to_activity(%Event{} = event, local \\ true) do
|
defp event_to_activity(%Event{} = event, local \\ true) do
|
||||||
%Activity{
|
%Activity{
|
||||||
recipients: [@public_ap_adress],
|
recipients: [@public_ap_adress],
|
||||||
|
@ -166,7 +166,7 @@ defmodule Mobilizon.Federation.ActivityPub do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create an activity from a comment
|
# Create an activity from a comment
|
||||||
@spec comment_to_activity(%Comment{}, boolean()) :: Activity.t()
|
@spec comment_to_activity(Comment.t(), boolean()) :: Activity.t()
|
||||||
defp comment_to_activity(%Comment{} = comment, local \\ true) do
|
defp comment_to_activity(%Comment{} = comment, local \\ true) do
|
||||||
%Activity{
|
%Activity{
|
||||||
recipients: [@public_ap_adress],
|
recipients: [@public_ap_adress],
|
||||||
|
|
|
@ -77,7 +77,7 @@ defmodule Mobilizon.Federation.ActivityPub.Permission do
|
||||||
|
|
||||||
@spec can_manage_group_object?(
|
@spec can_manage_group_object?(
|
||||||
existing_object_permissions(),
|
existing_object_permissions(),
|
||||||
%Actor{url: String.t()},
|
Actor.t(),
|
||||||
object()
|
object()
|
||||||
) :: boolean()
|
) :: boolean()
|
||||||
defp can_manage_group_object?(permission, %Actor{url: actor_url} = actor, object) do
|
defp can_manage_group_object?(permission, %Actor{url: actor_url} = actor, object) do
|
||||||
|
|
|
@ -967,10 +967,8 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
||||||
defp do_handle_incoming_reject_invite(invite_object, %Actor{} = actor_rejecting) do
|
defp do_handle_incoming_reject_invite(invite_object, %Actor{} = actor_rejecting) do
|
||||||
with {:invite, {:ok, %Member{role: :invited, actor_id: actor_id} = member}} <-
|
with {:invite, {:ok, %Member{role: :invited, actor_id: actor_id} = member}} <-
|
||||||
{:invite, get_member(invite_object)},
|
{:invite, get_member(invite_object)},
|
||||||
{:same_actor, true} <- {:same_actor, actor_rejecting.id == actor_id},
|
{:same_actor, true} <- {:same_actor, actor_rejecting.id == actor_id} do
|
||||||
{:ok, activity, member} <-
|
Actions.Reject.reject(:invite, member, false)
|
||||||
Actions.Reject.reject(:invite, member, false) do
|
|
||||||
{:ok, activity, member}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -149,25 +149,23 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
|
||||||
),
|
),
|
||||||
tags <- ConverterUtils.fetch_tags(tags),
|
tags <- ConverterUtils.fetch_tags(tags),
|
||||||
mentions <- Map.get(args, :mentions, []) ++ ConverterUtils.fetch_mentions(mentions),
|
mentions <- Map.get(args, :mentions, []) ++ ConverterUtils.fetch_mentions(mentions),
|
||||||
lang <- Map.get(args, :language, "und"),
|
lang <- Map.get(args, :language, "und") do
|
||||||
args <-
|
Map.merge(args, %{
|
||||||
Map.merge(args, %{
|
actor_id: Map.get(args, :actor_id),
|
||||||
actor_id: Map.get(args, :actor_id),
|
text: text,
|
||||||
text: text,
|
mentions: mentions,
|
||||||
mentions: mentions,
|
tags: tags,
|
||||||
tags: tags,
|
event: event,
|
||||||
event: event,
|
in_reply_to_comment: in_reply_to_comment,
|
||||||
in_reply_to_comment: in_reply_to_comment,
|
in_reply_to_comment_id:
|
||||||
in_reply_to_comment_id:
|
if(is_nil(in_reply_to_comment), do: nil, else: Map.get(in_reply_to_comment, :id)),
|
||||||
if(is_nil(in_reply_to_comment), do: nil, else: Map.get(in_reply_to_comment, :id)),
|
origin_comment_id:
|
||||||
origin_comment_id:
|
if(is_nil(in_reply_to_comment),
|
||||||
if(is_nil(in_reply_to_comment),
|
do: nil,
|
||||||
do: nil,
|
else: Comment.get_thread_id(in_reply_to_comment)
|
||||||
else: Comment.get_thread_id(in_reply_to_comment)
|
),
|
||||||
),
|
language: if(lang == "und", do: LanguageDetection.detect(:comment, args), else: lang)
|
||||||
language: if(lang == "und", do: LanguageDetection.detect(:comment, args), else: lang)
|
})
|
||||||
}) do
|
|
||||||
args
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ defmodule Mobilizon.Federation.WebFinger do
|
||||||
{:ok, String.t()} | {:error, :link_not_found} | {:error, any()}
|
{:ok, String.t()} | {:error, :link_not_found} | {:error, any()}
|
||||||
defp find_webfinger_endpoint(domain) when is_binary(domain) do
|
defp find_webfinger_endpoint(domain) when is_binary(domain) do
|
||||||
with {:ok, %Tesla.Env{status: 200, body: body}} <-
|
with {:ok, %Tesla.Env{status: 200, body: body}} <-
|
||||||
fetch_document("http://#{domain}/.well-known/host-meta"),
|
HostMetaClient.get("http://#{domain}/.well-known/host-meta"),
|
||||||
link_template when is_binary(link_template) <- find_link_from_template(body) do
|
link_template when is_binary(link_template) <- find_link_from_template(body) do
|
||||||
{:ok, link_template}
|
{:ok, link_template}
|
||||||
else
|
else
|
||||||
|
@ -258,11 +258,6 @@ defmodule Mobilizon.Federation.WebFinger do
|
||||||
{:error, :link_not_found}
|
{:error, :link_not_found}
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec fetch_document(String.t()) :: Tesla.Env.result()
|
|
||||||
defp fetch_document(endpoint) do
|
|
||||||
with {:error, err} <- HostMetaClient.get(endpoint), do: {:error, err}
|
|
||||||
end
|
|
||||||
|
|
||||||
@spec address_invalid(String.t()) :: false | {:error, :invalid_address}
|
@spec address_invalid(String.t()) :: false | {:error, :invalid_address}
|
||||||
defp address_invalid(address) do
|
defp address_invalid(address) do
|
||||||
with %URI{host: host, scheme: scheme} <- URI.parse(address),
|
with %URI{host: host, scheme: scheme} <- URI.parse(address),
|
||||||
|
|
|
@ -39,9 +39,7 @@ defmodule Mobilizon.Federation.WebFinger.XmlBuilder do
|
||||||
defp to_xml(content) when is_binary(content), do: to_string(content)
|
defp to_xml(content) when is_binary(content), do: to_string(content)
|
||||||
|
|
||||||
defp to_xml(content) when is_list(content) do
|
defp to_xml(content) when is_list(content) do
|
||||||
content
|
Enum.map_join(content, &to_xml/1)
|
||||||
|> Enum.map(&to_xml/1)
|
|
||||||
|> Enum.join()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp to_xml(%NaiveDateTime{} = time), do: NaiveDateTime.to_iso8601(time)
|
defp to_xml(%NaiveDateTime{} = time), do: NaiveDateTime.to_iso8601(time)
|
||||||
|
@ -49,9 +47,7 @@ defmodule Mobilizon.Federation.WebFinger.XmlBuilder do
|
||||||
@spec make_open_tag(tag :: atom, attributes :: map()) :: String.t()
|
@spec make_open_tag(tag :: atom, attributes :: map()) :: String.t()
|
||||||
defp make_open_tag(tag, attributes) do
|
defp make_open_tag(tag, attributes) do
|
||||||
attributes_string =
|
attributes_string =
|
||||||
attributes
|
Enum.map_join(attributes, " ", fn {attribute, value} -> "#{attribute}=\"#{value}\"" end)
|
||||||
|> Enum.map(fn {attribute, value} -> "#{attribute}=\"#{value}\"" end)
|
|
||||||
|> Enum.join(" ")
|
|
||||||
|
|
||||||
[to_string(tag), attributes_string] |> Enum.join(" ") |> String.trim()
|
[to_string(tag), attributes_string] |> Enum.join(" ") |> String.trim()
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,7 +21,7 @@ defmodule Mobilizon.GraphQL.API.Utils do
|
||||||
text
|
text
|
||||||
|> Formatter.html_escape("text/plain")
|
|> Formatter.html_escape("text/plain")
|
||||||
|> Formatter.linkify(options)
|
|> Formatter.linkify(options)
|
||||||
|> (fn {text, mentions, tags} -> {String.replace(text, ~r/\r?\n/, "<br>"), mentions, tags} end).()
|
|> inject_new_lines()
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_input(text, "text/html", options) do
|
def format_input(text, "text/html", options) do
|
||||||
|
@ -30,6 +30,10 @@ defmodule Mobilizon.GraphQL.API.Utils do
|
||||||
|> Formatter.linkify(options)
|
|> Formatter.linkify(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp inject_new_lines({text, mentions, tags}) do
|
||||||
|
{String.replace(text, ~r/\r?\n/, "<br>"), mentions, tags}
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Use the data-media-id attributes to extract media from body text
|
Use the data-media-id attributes to extract media from body text
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -15,7 +15,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Media do
|
||||||
See Mobilizon.Web.Resolvers.Event.create_event/3
|
See Mobilizon.Web.Resolvers.Event.create_event/3
|
||||||
"""
|
"""
|
||||||
def media(%{picture_id: media_id} = _parent, _args, _resolution) do
|
def media(%{picture_id: media_id} = _parent, _args, _resolution) do
|
||||||
with {:ok, media} <- do_fetch_media(media_id), do: {:ok, media}
|
do_fetch_media(media_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def media(%{picture: media} = _parent, _args, _resolution), do: {:ok, media}
|
def media(%{picture: media} = _parent, _args, _resolution), do: {:ok, media}
|
||||||
|
|
|
@ -559,11 +559,9 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||||
Enum.each(actors, fn actor ->
|
Enum.each(actors, fn actor ->
|
||||||
actor_performing = Keyword.get(options, :actor_performing, actor)
|
actor_performing = Keyword.get(options, :actor_performing, actor)
|
||||||
Actions.Delete.delete(actor, actor_performing, true)
|
Actions.Delete.delete(actor, actor_performing, true)
|
||||||
end),
|
end) do
|
||||||
# Delete user
|
# Delete user
|
||||||
{:ok, user} <-
|
Users.delete_user(user, reserve_email: Keyword.get(options, :reserve_email, activated))
|
||||||
Users.delete_user(user, reserve_email: Keyword.get(options, :reserve_email, activated)) do
|
|
||||||
{:ok, user}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ defmodule Mix.Tasks.Mobilizon.Instance do
|
||||||
else
|
else
|
||||||
shell_error(
|
shell_error(
|
||||||
"The task would have overwritten the following files:\n" <>
|
"The task would have overwritten the following files:\n" <>
|
||||||
(will_overwrite |> Enum.map(&"- #{&1}\n") |> Enum.join("")) <>
|
Enum.map_join(will_overwrite, "", &"- #{&1}\n") <>
|
||||||
"Rerun with `-f/--force` to overwrite them."
|
"Rerun with `-f/--force` to overwrite them."
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,7 +47,7 @@ defmodule Mix.Tasks.Mobilizon.Users.Show do
|
||||||
defp display_actors(actors) do
|
defp display_actors(actors) do
|
||||||
"""
|
"""
|
||||||
Identities (#{length(actors)}):
|
Identities (#{length(actors)}):
|
||||||
#{actors |> Enum.map(&display_actor/1) |> Enum.join("")}
|
#{Enum.map_join(actors, &display_actor/1)}
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,7 @@ defmodule Mobilizon.Service.Address do
|
||||||
name: if(defined?(postal_code), do: "#{description} (#{postal_code})", else: description),
|
name: if(defined?(postal_code), do: "#{description} (#{postal_code})", else: description),
|
||||||
alternative_name:
|
alternative_name:
|
||||||
[locality, country]
|
[locality, country]
|
||||||
|> Enum.filter(& &1)
|
|> Enum.filter(&(&1 && &1 != description))
|
||||||
|> Enum.filter(&(&1 != description))
|
|
||||||
|> Enum.join(", ")
|
|> Enum.join(", ")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,10 +46,9 @@ defmodule Mobilizon.Service.CleanOrphanMedia do
|
||||||
[from: "posts_medias", param: "media_id"],
|
[from: "posts_medias", param: "media_id"],
|
||||||
[from: "comments_medias", param: "media_id"]
|
[from: "comments_medias", param: "media_id"]
|
||||||
]
|
]
|
||||||
|> Enum.map(fn [from: from, param: param] ->
|
|> Enum.map_join(" UNION ", fn [from: from, param: param] ->
|
||||||
"SELECT 1 FROM #{from} WHERE #{from}.#{param} = m0.id"
|
"SELECT 1 FROM #{from} WHERE #{from}.#{param} = m0.id"
|
||||||
end)
|
end)
|
||||||
|> Enum.join(" UNION ")
|
|
||||||
|> (&"NOT EXISTS(#{&1})").()
|
|> (&"NOT EXISTS(#{&1})").()
|
||||||
|
|
||||||
@spec find_media(Keyword.t()) :: list(list(Media.t()))
|
@spec find_media(Keyword.t()) :: list(list(Media.t()))
|
||||||
|
|
|
@ -41,7 +41,7 @@ defmodule Mobilizon.Service.Export.Participants.CSV do
|
||||||
|> Repo.stream()
|
|> Repo.stream()
|
||||||
|> Stream.map(&to_list/1)
|
|> Stream.map(&to_list/1)
|
||||||
|> NimbleCSV.RFC4180.dump_to_iodata()
|
|> NimbleCSV.RFC4180.dump_to_iodata()
|
||||||
|> (fn stream -> Stream.concat([Enum.join(columns(), ","), "\n"], stream) end).()
|
|> add_header_column()
|
||||||
|> Stream.each(fn line -> IO.write(file, line) end)
|
|> Stream.each(fn line -> IO.write(file, line) end)
|
||||||
|> Stream.run()
|
|> Stream.run()
|
||||||
|
|
||||||
|
@ -63,6 +63,10 @@ defmodule Mobilizon.Service.Export.Participants.CSV do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp add_header_column(stream) do
|
||||||
|
Stream.concat([Enum.join(columns(), ","), "\n"], stream)
|
||||||
|
end
|
||||||
|
|
||||||
@spec save_csv_upload(String.t(), String.t(), Event.t()) ::
|
@spec save_csv_upload(String.t(), String.t(), Event.t()) ::
|
||||||
{:ok, Export.t()} | {:error, atom() | Ecto.Changeset.t()}
|
{:ok, Export.t()} | {:error, atom() | Ecto.Changeset.t()}
|
||||||
defp save_csv_upload(full_path, filename, %Event{id: event_id, title: title}) do
|
defp save_csv_upload(full_path, filename, %Event{id: event_id, title: title}) do
|
||||||
|
|
|
@ -39,7 +39,7 @@ defmodule Mobilizon.Service.Export.Participants.ODS do
|
||||||
|> Events.participant_for_event_export_query(Keyword.get(options, :roles, []))
|
|> Events.participant_for_event_export_query(Keyword.get(options, :roles, []))
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|> Enum.map(&to_list/1)
|
|> Enum.map(&to_list/1)
|
||||||
|> (fn data -> Enum.concat([columns()], data) end).()
|
|> add_header_columns()
|
||||||
|> generate_ods()
|
|> generate_ods()
|
||||||
|
|
||||||
File.write!(full_path, content)
|
File.write!(full_path, content)
|
||||||
|
@ -62,6 +62,10 @@ defmodule Mobilizon.Service.Export.Participants.ODS do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp add_header_columns(data) do
|
||||||
|
Enum.concat([columns()], data)
|
||||||
|
end
|
||||||
|
|
||||||
defp generate_ods(data) do
|
defp generate_ods(data) do
|
||||||
data
|
data
|
||||||
|> Jason.encode!()
|
|> Jason.encode!()
|
||||||
|
|
|
@ -15,6 +15,8 @@ defmodule Mobilizon.Service.Formatter do
|
||||||
|
|
||||||
alias Mobilizon.Web.Endpoint
|
alias Mobilizon.Web.Endpoint
|
||||||
|
|
||||||
|
# https://github.com/rrrene/credo/issues/912
|
||||||
|
# credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
|
||||||
@link_regex ~r"((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+"ui
|
@link_regex ~r"((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+"ui
|
||||||
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
|
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,6 @@ defmodule Mobilizon.Service.Workers.BuildSearch do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_tags_string(%Event{tags: tags}) do
|
defp get_tags_string(%Event{tags: tags}) do
|
||||||
tags
|
Enum.map_join(tags, " ", & &1.title)
|
||||||
|> Enum.map(& &1.title)
|
|
||||||
|> Enum.join(" ")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -77,12 +77,16 @@ defmodule Mobilizon.Service.Workers.LegacyNotifierBuilder do
|
||||||
) do
|
) do
|
||||||
event_uuid
|
event_uuid
|
||||||
|> Events.get_event_by_uuid_with_preload()
|
|> Events.get_event_by_uuid_with_preload()
|
||||||
|> (fn %Event{organizer_actor: %Actor{id: actor_id}} -> [actor_id] end).()
|
|> organizer_actor_id()
|
||||||
|> users_from_actor_ids(Keyword.fetch!(options, :author_id))
|
|> users_from_actor_ids(Keyword.fetch!(options, :author_id))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp users_to_notify(_, _), do: []
|
defp users_to_notify(_, _), do: []
|
||||||
|
|
||||||
|
defp organizer_actor_id(%Event{organizer_actor: %Actor{id: actor_id}}) do
|
||||||
|
[actor_id]
|
||||||
|
end
|
||||||
|
|
||||||
@spec users_from_actor_ids(list(), integer() | String.t()) :: list(Users.t())
|
@spec users_from_actor_ids(list(), integer() | String.t()) :: list(Users.t())
|
||||||
defp users_from_actor_ids(actor_ids, author_id) do
|
defp users_from_actor_ids(actor_ids, author_id) do
|
||||||
actor_ids
|
actor_ids
|
||||||
|
|
|
@ -294,20 +294,22 @@ defmodule Mobilizon.Web.ReverseProxy do
|
||||||
headers
|
headers
|
||||||
|> downcase_headers()
|
|> downcase_headers()
|
||||||
|> Enum.filter(fn {k, _} -> k in @keep_req_headers end)
|
|> Enum.filter(fn {k, _} -> k in @keep_req_headers end)
|
||||||
|> (fn headers ->
|
|> maybe_keep_user_agent(opts)
|
||||||
headers = headers ++ Keyword.get(opts, :req_headers, [])
|
end
|
||||||
|
|
||||||
if Keyword.get(opts, :keep_user_agent, false) do
|
defp maybe_keep_user_agent(headers, opts) do
|
||||||
List.keystore(
|
headers = headers ++ Keyword.get(opts, :req_headers, [])
|
||||||
headers,
|
|
||||||
"user-agent",
|
if Keyword.get(opts, :keep_user_agent, false) do
|
||||||
0,
|
List.keystore(
|
||||||
{"user-agent", Mobilizon.user_agent()}
|
headers,
|
||||||
)
|
"user-agent",
|
||||||
else
|
0,
|
||||||
headers
|
{"user-agent", Mobilizon.user_agent()}
|
||||||
end
|
)
|
||||||
end).()
|
else
|
||||||
|
headers
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec build_resp_headers(list(tuple()), Keyword.t()) :: list(tuple())
|
@spec build_resp_headers(list(tuple()), Keyword.t()) :: list(tuple())
|
||||||
|
@ -316,7 +318,11 @@ defmodule Mobilizon.Web.ReverseProxy do
|
||||||
|> Enum.filter(fn {k, _} -> k in @keep_resp_headers end)
|
|> Enum.filter(fn {k, _} -> k in @keep_resp_headers end)
|
||||||
|> build_resp_cache_headers(opts)
|
|> build_resp_cache_headers(opts)
|
||||||
|> build_resp_content_disposition_header(opts)
|
|> build_resp_content_disposition_header(opts)
|
||||||
|> (fn headers -> headers ++ Keyword.get(opts, :resp_headers, []) end).()
|
|> maybe_add_headers_from_opts(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_add_headers_from_opts(headers, opts) do
|
||||||
|
headers ++ Keyword.get(opts, :resp_headers, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec build_resp_cache_headers(list(tuple()), Keyword.t()) :: list(tuple())
|
@spec build_resp_cache_headers(list(tuple()), Keyword.t()) :: list(tuple())
|
||||||
|
|
|
@ -19,7 +19,7 @@ defmodule Mobilizon.Service.ICalendarTest do
|
||||||
VERSION:2.0
|
VERSION:2.0
|
||||||
PRODID:-//Elixir ICalendar//Mobilizon #{Mobilizon.Config.instance_version()}//EN
|
PRODID:-//Elixir ICalendar//Mobilizon #{Mobilizon.Config.instance_version()}//EN
|
||||||
BEGIN:VEVENT
|
BEGIN:VEVENT
|
||||||
CATEGORIES:#{event.tags |> Enum.map(& &1.title) |> Enum.join(",")}
|
CATEGORIES:#{Enum.map_join(event.tags, ",", & &1.title)}
|
||||||
DESCRIPTION:Ceci est une description avec une première phrase assez longue\\,\\n puis sur une seconde ligne
|
DESCRIPTION:Ceci est une description avec une première phrase assez longue\\,\\n puis sur une seconde ligne
|
||||||
DTEND:#{Value.to_ics(event.ends_on)}Z
|
DTEND:#{Value.to_ics(event.ends_on)}Z
|
||||||
DTSTAMP:#{Value.to_ics(event.publish_at)}Z
|
DTSTAMP:#{Value.to_ics(event.publish_at)}Z
|
||||||
|
|
Loading…
Reference in a new issue