Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/sh

# checks for filenames with non-ASCII characters
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=$(git hash-object -t tree /dev/null)
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --type=bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
# Note that the use of brackets around a tr range is ok here, (it's
# even required, for portability to Solaris 10's /usr/bin/tr), since
# the square bracket bytes happen to fall in the designated range.
test $(git diff-index --cached --name-only --diff-filter=A -z $against |
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

git config hooks.allownonascii true
EOF
exit 1
fi

# runs pseudo-lint on staged files
git diff --name-only --cached | grep -E ".*\.(ex|exs)$" | xargs mix format --check-formatted

PSEUDOLINT_STATUS=$?
if [ "$PSEUDOLINT_STATUS" != "0" ]; then
echo 'run `mix format` then use `git add` to restage the formatted file'
exit $PSEUDOLINT_STATUS
fi
31 changes: 24 additions & 7 deletions .github/workflows/lint-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,17 @@ jobs:
- elixir: '1.17'
otp: '27.3'

- elixir: '1.18'
otp: '25.1'
- elixir: '1.18'
otp: '28.0'

os:
- 'ubuntu-22.04'
- 'ubuntu-24.04'

exclude:
- versions: # current
- versions: # current versions; already tested above
elixir: '1.16'
otp: '25.3'

Expand Down Expand Up @@ -142,23 +147,35 @@ jobs:


pseudo-lint:
continue-on-error: true # TODO: use `mix format` & check in files, then set this false
continue-on-error: false # `mix format` MUST be run before committing
strategy:
fail-fast: false
matrix:
versions:
- elixir: '1.14'
otp: '24.3'

- elixir: '1.15'
otp: '24.3'
# - elixir: '1.14'
# otp: '24.3'
#
# - elixir: '1.15'
# otp: '24.3'

- elixir: '1.16'
otp: '24.3'

# - elixir: '1.16'
# otp: '25.1'

- elixir: '1.17'
otp: '25.3'

# - elixir: '1.18'
# otp: '25.1'

# - elixir: '1.17'
# otp: '25.0'

- elixir: '1.18'
otp: '28.0'

runs-on: 'ubuntu-24.04'

steps:
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,14 @@ https://hexdocs.pm/phoenix/installation.html

https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html

### 2. Setup Reticulum:
### 2. Enable git hooks

Run
```shell
. scripts/setup.sh
```

### 3. Setup Reticulum:

Run the following commands at the root of the reticulum directory:

Expand All @@ -48,7 +55,7 @@ Run the following commands at the root of the reticulum directory:
- If you receive an error that the `ret_dev` database does not exist, (using psql again) enter `create database ret_dev;`
3. From the project directory `mkdir -p storage/dev`

### 3. Start Reticulum
### 4. Start Reticulum

Run `scripts/run.sh` if you have the hubs secret repo cloned. Otherwise `iex -S mix phx.server`

Expand Down
5 changes: 4 additions & 1 deletion lib/ret/account.ex
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ defmodule Ret.Account do
_ -> false
end

Repo.insert!(%Account{login: %Login{identifier_hash: identifier_hash}, is_admin: is_admin})
Repo.insert!(%Account{
login: %Login{identifier_hash: identifier_hash},
is_admin: is_admin
})

true ->
nil
Expand Down
81 changes: 52 additions & 29 deletions lib/ret/discord_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,23 @@ defmodule Ret.DiscordClient do
{status, result} when status in [:commit, :ok] -> "#{result["nick"]}"
end

nickname = if !nickname or nickname == "" do
case Cachex.fetch(:discord_api, "/users/#{provider_account_id}") do
{status, result} when status in [:commit, :ok] -> "#{result["global_name"]}"
end
nickname =
if !nickname or nickname == "" do
case Cachex.fetch(:discord_api, "/users/#{provider_account_id}") do
{status, result} when status in [:commit, :ok] -> "#{result["global_name"]}"
end
else
nickname
end

nickname = if !nickname or nickname == "" do
case Cachex.fetch(:discord_api, "/users/#{provider_account_id}") do
{status, result} when status in [:commit, :ok] -> "#{result["username"]}"
end

nickname =
if !nickname or nickname == "" do
case Cachex.fetch(:discord_api, "/users/#{provider_account_id}") do
{status, result} when status in [:commit, :ok] -> "#{result["username"]}"
end
else
nickname
end
end
end

def fetch_community_identifier(%Ret.OAuthProvider{
Expand Down Expand Up @@ -169,18 +171,21 @@ defmodule Ret.DiscordClient do
case Cachex.fetch(:discord_api, "/guilds/#{community_id}/roles") do
{status, result} when status in [:commit, :ok] -> result |> Map.new(&{&1["id"], &1})
end
# Note: Whether the bitfield values in guild_roles are represented as strings or integers is inconsistent (possibly based on what permissions the user has), so every time they're used they need to be checked and, if needed, converted to integers.

# Note: Whether the bitfield values in guild_roles are represented as strings or integers is inconsistent (possibly based on what permissions the user has), so every time they're used they need to be checked and, if needed, converted to integers.

role_everyone = guild_roles[community_id]
permissions = role_everyone["permissions"]

user_permissions = user_roles |> Enum.map(&guild_roles[&1]["permissions"])

permissions = user_permissions |>
Enum.reduce(permissions, &(
(if is_binary(&1), do: String.to_integer(&1), else: &1) |||
(if is_binary(&2), do: String.to_integer(&2), else: &2)
))
permissions =
user_permissions
|> Enum.reduce(
permissions,
&(if(is_binary(&1), do: String.to_integer(&1), else: &1) |||
if(is_binary(&2), do: String.to_integer(&2), else: &2))
)

if (permissions &&& @administrator) == @administrator do
@all
Expand All @@ -203,15 +208,21 @@ defmodule Ret.DiscordClient do
|> Map.get("permission_overwrites")
|> Map.new(&{&1["id"], &1})
end
# Note: Whether the bitfield values in channel_overwrites are represented as strings or integers is inconsistent (possibly based on what permissions the user has), so every time they're used they need to be checked and, if needed, converted to integers.

# Note: Whether the bitfield values in channel_overwrites are represented as strings or integers is inconsistent (possibly based on what permissions the user has), so every time they're used they need to be checked and, if needed, converted to integers.

overwrite_everyone = channel_overwrites[community_id]

permissions =
if overwrite_everyone do
(permissions &&&
~~~(if is_binary(overwrite_everyone["deny"]), do: String.to_integer(overwrite_everyone["deny"]), else: overwrite_everyone["deny"])) |||
(if is_binary(overwrite_everyone["allow"]), do: String.to_integer(overwrite_everyone["allow"]), else: overwrite_everyone["allow"])
~~~if(is_binary(overwrite_everyone["deny"]),
do: String.to_integer(overwrite_everyone["deny"]),
else: overwrite_everyone["deny"]
)) |||
if is_binary(overwrite_everyone["allow"]),
do: String.to_integer(overwrite_everyone["allow"]),
else: overwrite_everyone["allow"]
else
permissions
end
Expand All @@ -220,14 +231,21 @@ defmodule Ret.DiscordClient do
user_permissions =
user_roles |> Enum.map(&channel_overwrites[&1]) |> Enum.filter(&(&1 != nil))

allow = user_permissions |> Enum.reduce(@none, &(
(if is_binary(&1["allow"]), do: String.to_integer(&1["allow"]), else: &1["allow"]) |||
&2
))
deny = user_permissions |> Enum.reduce(@none, &(
(if is_binary(&1["deny"]), do: String.to_integer(&1["deny"]), else: &1["deny"]) |||
&2
))
allow =
user_permissions
|> Enum.reduce(
@none,
&(if(is_binary(&1["allow"]), do: String.to_integer(&1["allow"]), else: &1["allow"]) |||
&2)
)

deny =
user_permissions
|> Enum.reduce(
@none,
&(if(is_binary(&1["deny"]), do: String.to_integer(&1["deny"]), else: &1["deny"]) |||
&2)
)

permissions = (permissions &&& ~~~deny) ||| allow

Expand All @@ -237,8 +255,13 @@ defmodule Ret.DiscordClient do
permissions =
if overwrite_member do
(permissions &&&
~~~(if is_binary(overwrite_member["deny"]), do: String.to_integer(overwrite_member["deny"]), else: overwrite_member["deny"])) |||
(if is_binary(overwrite_member["allow"]), do: String.to_integer(overwrite_member["allow"]), else: overwrite_member["allow"])
~~~if(is_binary(overwrite_member["deny"]),
do: String.to_integer(overwrite_member["deny"]),
else: overwrite_member["deny"]
)) |||
if is_binary(overwrite_member["allow"]),
do: String.to_integer(overwrite_member["allow"]),
else: overwrite_member["allow"]
else
permissions
end
Expand Down
15 changes: 8 additions & 7 deletions lib/ret/http_utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,19 @@ defmodule Ret.HttpUtils do
end

def join_smart(enum) do
Enum.reduce(enum, "", fn(x, acc) ->
x = cond do
!x -> nil
is_binary(x) -> String.trim(x)
true -> "#{x}"
end
Enum.reduce(enum, "", fn x, acc ->
x =
cond do
!x -> nil
is_binary(x) -> String.trim(x)
true -> "#{x}"
end

if x && x != "" do
if acc && acc != "", do: acc <> " — " <> x, else: x
else
acc
end
end)
end

end
8 changes: 7 additions & 1 deletion lib/ret/media_search.ex
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,12 @@ defmodule Ret.MediaSearch do
sketchfab_search(query)
end

def search(%Ret.MediaSearchQuery{source: "youtube_videos", cursor: cursor, filter: filter, q: q}) do
def search(%Ret.MediaSearchQuery{
source: "youtube_videos",
cursor: cursor,
filter: filter,
q: q
}) do
with api_key when is_binary(api_key) <- resolver_config(:youtube_api_key) do
query =
URI.encode_query(
Expand Down Expand Up @@ -559,6 +564,7 @@ defmodule Ret.MediaSearch do

defp created_rooms_search(cursor, account_id, _query) do
page_number = (cursor || "1") |> Integer.parse() |> elem(0)

ecto_query =
from h in Hub,
where: h.created_by_account_id == ^account_id,
Expand Down
11 changes: 6 additions & 5 deletions lib/ret/scene.ex
Original file line number Diff line number Diff line change
Expand Up @@ -226,37 +226,38 @@ defmodule Ret.Scene do
model_owned_file: old_model_owned_file,
account: account
} = scene

new_scene_owned_file =
Storage.create_new_owned_file_with_replaced_string(
old_scene_owned_file,
account,
old_domain_url,
new_domain_url
)

{:ok, new_model_owned_file} =
Storage.duplicate_and_transform(old_model_owned_file, account, fn glb_stream,
_total_bytes ->
GLTFUtils.replace_in_glb(glb_stream, old_domain_url, new_domain_url)
end)

scene
|> change()
|> put_change(:scene_owned_file_id, new_scene_owned_file.owned_file_id)
|> put_change(:model_owned_file_id, new_model_owned_file.owned_file_id)
|> Repo.update!()

for old_owned_file <- [old_scene_owned_file, old_model_owned_file] do
OwnedFile.set_inactive(old_owned_file)
Storage.rm_files_for_owned_file(old_owned_file)
Repo.delete(old_owned_file)
end
rescue
e ->
e ->
IO.warn("Failed to process scene due to an error: #{inspect(e)}")
end
end)

:ok
end)
end
Expand Down
8 changes: 6 additions & 2 deletions lib/ret/storage.ex
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ defmodule Ret.Storage do
_account,
_require_token
) do
{:ok, owned_file}
{:ok, owned_file}
end

# Promoting a stored file to being owned has two side effects: the file is moved
Expand All @@ -310,7 +310,11 @@ defmodule Ret.Storage do
"promotion_token" => actual_promotion_token
} <-
File.read!(meta_file_path) |> Poison.decode!(),
{:ok} <- (if require_token, do: check_promotion_token(actual_promotion_token, promotion_token), else: {:ok}),
{:ok} <-
if(require_token,
do: check_promotion_token(actual_promotion_token, promotion_token),
else: {:ok}
),
{:ok} <- check_blob_file_key(blob_file_path, key)
) do
owned_file_params = %{
Expand Down
Loading
Loading