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

Bump mix_test_interactive from 2.0.4 to 4.1.2 #202

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
4e57f31
feat: Update database configuration and dependencies in dev and runti…
talk2MeGooseman Dec 13, 2024
f0cc39e
feat: Optimize database queries with limits and improve user experien…
talk2MeGooseman Dec 18, 2024
605b3b8
Bump nebulex from 2.6.1 to 2.6.3
dependabot[bot] Aug 6, 2024
9cf7341
feat: Upgrade New Relic agent and add tracing to captions pipeline co…
talk2MeGooseman Dec 20, 2024
43f823c
refactor: Simplify bits balance retrieval by removing unnecessary pre…
talk2MeGooseman Dec 20, 2024
cd67b99
Merge branch 'master' of https://github.com/talk2MeGooseman/stream_cl…
talk2MeGooseman Dec 20, 2024
95e58a6
Create elixir.yml
talk2MeGooseman Dec 22, 2024
895c8bc
feat: Add bits balance check to translation activation logic
talk2MeGooseman Dec 22, 2024
9698e1b
feat: Update database configuration to use DATABASE_URL for development
talk2MeGooseman Dec 22, 2024
1fbd9b0
Bump tailwind from 0.2.2 to 0.2.4
dependabot[bot] Dec 22, 2024
90b5fae
Bump credo from 1.7.7 to 1.7.10
dependabot[bot] Dec 22, 2024
3dd2c7a
Bump exconstructor from 1.2.8 to 1.2.13
dependabot[bot] Apr 12, 2024
4d489db
feat: Add PostgreSQL service to GitHub Actions workflow
talk2MeGooseman Dec 23, 2024
63a3bcf
feat: Add CI test task to mix.exs for streamlined testing
talk2MeGooseman Dec 23, 2024
ffbc4d9
feat: Update test command in GitHub Actions workflow for CI compatibi…
talk2MeGooseman Dec 23, 2024
de26943
Bump guardian from 2.3.1 to 2.3.2
dependabot[bot] Dec 23, 2024
6889031
Bump mix_test_interactive from 2.0.4 to 4.1.2
dependabot[bot] Dec 24, 2024
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
54 changes: 54 additions & 0 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Elixir CI

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

permissions:
contents: read

jobs:
build:

name: Build and test
runs-on: ubuntu-latest

services:
postgres:
image: postgres:latest
ports:
- 5432:5432
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: app
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- uses: actions/checkout@v4
- name: Set up Elixir
uses: erlef/setup-beam@61e01a43a562a89bfc54c7f9a378ff67b03e4a21 # v1.16.0
with:
elixir-version: '1.14.0' # [Required] Define the Elixir version
otp-version: '25.0' # [Required] Define the Erlang/OTP version
- name: Restore dependencies cache
uses: actions/cache@v3
with:
path: deps
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: mix deps.get
- name: Run tests
run: mix test.ci
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@
}
],
"elixirLinter.useStrict": true,
"editor.formatOnSave": true
"editor.formatOnSave": true,
"cSpell.words": [
"Captioner"
]
}
26 changes: 20 additions & 6 deletions config/dev.exs
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import Config

# Configure your database
# config :stream_closed_captioner_phoenix, StreamClosedCaptionerPhoenix.Repo,
# username: "postgres",
# password: "",
# database: "stream-cc-development",
# hostname: "localhost",
# show_sensitive_data_on_connection_error: false,
# pool_size: 10,
# stacktrace: true,
# # The App was started from Rails which used the `schema_migrations` table with the same name but different schema
# # To continue with migrations from ecto from now on, we use choose a custom name for the ecto migrations
# # !!! From now on, migrations should only be done from Ecto !!!
# migration_source: "ecto_schema_migrations"

database_url = System.get_env("DATABASE_URL")

config :stream_closed_captioner_phoenix, StreamClosedCaptionerPhoenix.Repo,
username: "postgres",
password: "",
database: "stream-cc-development",
hostname: "localhost",
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
ssl: [cacerts: :public_key.cacerts_get()],
show_sensitive_data_on_connection_error: false,
pool_size: 10,
stacktrace: true,
# The App was started from Rails which used the `schema_migrations` table with the same name but different schema
# To continue with migrations from ecto from now on, we use choose a custom name for the ecto migrations
# !!! From now on, migrations should only be done from Ecto !!!
migration_source: "ecto_schema_migrations"
migration_source: "ecto_schema_migrations",
migration_lock: :pg_advisory_lock

# For development, we disable any cache and enable
# debugging and code reloading.
Expand Down
19 changes: 13 additions & 6 deletions config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import Config

config :absinthe_security, AbsintheSecurity.Phase.IntrospectionCheck,
enable_introspection: System.get_env("GRAPHQL_ENABLE_INTROSPECTION") || true

config :absinthe_security, AbsintheSecurity.Phase.FieldSuggestionsCheck,
enable_field_suggestions: System.get_env("GRAPHQL_ENABLE_FIELD_SUGGESTIONS") || true

config :absinthe_security, AbsintheSecurity.Phase.MaxAliasesCheck, max_alias_count: 0
config :absinthe_security, AbsintheSecurity.Phase.MaxDepthCheck, max_depth_count: 10
config :absinthe_security, AbsintheSecurity.Phase.MaxDirectivesCheck, max_directive_count: 0
Expand All @@ -19,17 +21,22 @@ if config_env() == :prod do
config :stream_closed_captioner_phoenix, twitch_helix_client: Twitch.Helix
config :stream_closed_captioner_phoenix, azure_cognitive_client: Azure.Cognitive

database_url =
System.get_env("DATABASE_URL") ||
raise """
environment variable DATABASE_URL is missing.
For example: ecto://USER:PASS@HOST/DATABASE
"""

config :stream_closed_captioner_phoenix, StreamClosedCaptionerPhoenix.Repo,
username: System.get_env("RDS_USERNAME"),
password: System.get_env("RDS_PASSWORD"),
database: System.get_env("RDS_DB_NAME"),
hostname: System.get_env("RDS_HOSTNAME"),
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
ssl: true,
ssl: [cacerts: :public_key.cacerts_get()],
# The App was started from Rails which used the `schema_migrations` table with the same name but different schema
# To continue with migrations from ecto from now on, we use choose a custom name for the ecto migrations
# !!! From now on, migrations should only be done from Ecto !!!
migration_source: "ecto_schema_migrations"
migration_source: "ecto_schema_migrations",
migration_lock: :pg_advisory_lock

secret_key_base =
System.get_env("SECRET_KEY_BASE") ||
Expand Down
3 changes: 3 additions & 0 deletions lib/stream_closed_captioner_phoenix/accounts/user_queries.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule StreamClosedCaptionerPhoenix.Accounts.UserQueries do
def with_id(query \\ base(), id) do
query
|> where([user], user.id == ^id)
|> limit(1)
end

def with_ids(query \\ base(), ids) do
Expand All @@ -23,11 +24,13 @@ defmodule StreamClosedCaptionerPhoenix.Accounts.UserQueries do
def with_uid(query \\ base(), uid) do
query
|> where([user], user.uid == ^uid)
|> limit(1)
end

def select_id_user_pair(query \\ base()) do
query
|> select([user], {user.id, user})
|> limit(1)
end

def with_email(query \\ base(), email) do
Expand Down
3 changes: 2 additions & 1 deletion lib/stream_closed_captioner_phoenix/accounts/user_token.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ defmodule StreamClosedCaptionerPhoenix.Accounts.UserToken do
from token in token_and_context_query(token, "session"),
join: user in assoc(token, :user),
where: token.inserted_at > ago(@session_validity_in_days, "day"),
select: user
select: user,
limit: 1

{:ok, query}
end
Expand Down
40 changes: 34 additions & 6 deletions lib/stream_closed_captioner_phoenix/bits.ex
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ defmodule StreamClosedCaptionerPhoenix.Bits do

defp bits_balance_check(user) do
fn _repo, _ ->
user = Repo.preload(user, :bits_balance, force: true)
bits_balance = get_bits_balance_for_user(user)

if user.bits_balance.balance >= 500 do
{:ok, user.bits_balance}
if bits_balance.balance >= 500 do
{:ok, bits_balance}
else
{:error, :insufficent_balance}
end
Expand Down Expand Up @@ -115,6 +115,7 @@ defmodule StreamClosedCaptionerPhoenix.Bits do
def get_users_bits_balance_debit!(%{id: user_id}, id) do
BitsBalanceDebitQueries.with_user_id(user_id)
|> BitsBalanceDebitQueries.with_id(id)
|> limit(1)
|> Repo.one!()
end

Expand All @@ -130,15 +131,22 @@ defmodule StreamClosedCaptionerPhoenix.Bits do
nil

"""
def get_user_active_debit(user_id) do
BitsBalanceDebitQueries.with_user_id(user_id)
|> BitsBalanceDebitQueries.less_than_one_day_ago()
|> limit(1)
|> Repo.one()
end

@decorate cacheable(
cache: Cache,
key: {BitsBalanceDebit, user_id},
opts: [ttl: 60_000]
opts: [ttl: :timer.minutes(5)]
)
def get_user_active_debit(user_id) do
def user_active_debit_exists?(user_id) do
BitsBalanceDebitQueries.with_user_id(user_id)
|> BitsBalanceDebitQueries.less_than_one_day_ago()
|> Repo.one()
|> Repo.exists?()
end

@doc """
Expand Down Expand Up @@ -195,11 +203,24 @@ defmodule StreamClosedCaptionerPhoenix.Bits do
"""
def get_bits_balance!(id) when is_integer(id) do
BitsBalanceQueries.with_id(id)
|> limit(1)
|> Repo.one!()
end

@decorate cacheable(
cache: Cache,
key: {BitsBalance, user.id},
opts: [ttl: :timer.minutes(2)]
)
def get_bits_balance_for_user(%User{} = user) do
BitsBalanceQueries.with_user_id(user.id)
|> limit(1)
|> Repo.one()
end

def get_bits_balance!(%User{} = user) do
BitsBalanceQueries.with_user_id(user.id)
|> limit(1)
|> Repo.one!()
end

Expand All @@ -216,6 +237,7 @@ defmodule StreamClosedCaptionerPhoenix.Bits do
"""
def get_bits_balance_by_user_id(user_id) do
BitsBalanceQueries.with_user_id(user_id)
|> limit(1)
|> Repo.one()
|> case do
nil -> {:error, nil}
Expand Down Expand Up @@ -254,6 +276,10 @@ defmodule StreamClosedCaptionerPhoenix.Bits do
{:error, %Ecto.Changeset{}}

"""
@decorate cache_evict(
cache: Cache,
key: {BitsBalance, bits_balance.user_id}
)
def update_bits_balance(%BitsBalance{} = bits_balance, attrs) do
bits_balance
|> BitsBalance.update_changeset(attrs)
Expand Down Expand Up @@ -321,6 +347,7 @@ defmodule StreamClosedCaptionerPhoenix.Bits do
"""
def get_bits_transaction!(id) when is_integer(id) do
BitsTransactionQueries.with_id(id)
|> limit(1)
|> Repo.one!()
end

Expand All @@ -343,6 +370,7 @@ defmodule StreamClosedCaptionerPhoenix.Bits do
"""
def get_bits_transaction_by(transaction_id) when is_binary(transaction_id) do
BitsTransactionQueries.with_transaction_id(transaction_id)
|> limit(1)
|> Repo.one()
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ defmodule StreamClosedCaptionerPhoenix.Bits.BitsBalanceDebitQueries do

def less_than_one_day_ago(query \\ base()) do
one_day_ago = NaiveDateTime.utc_now() |> NaiveDateTime.add(@seconds_in_hours * -24)
# set seconds to 0
one_day_ago =
NaiveDateTime.new!(
one_day_ago.year,
one_day_ago.month,
one_day_ago.day,
one_day_ago.hour,
one_day_ago.minute,
0
)

query
|> where([bits_balance_debit], bits_balance_debit.created_at >= ^one_day_ago)
Expand Down
2 changes: 2 additions & 0 deletions lib/stream_closed_captioner_phoenix/captions_pipeline.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule StreamClosedCaptionerPhoenix.CaptionsPipeline do
require Logger
use NewRelic.Tracer

alias Azure.Cognitive.Translations
alias StreamClosedCaptionerPhoenix.Accounts.User
Expand Down Expand Up @@ -34,6 +35,7 @@ defmodule StreamClosedCaptionerPhoenix.CaptionsPipeline do
{:ok, payload}
end

@trace :pipeline_to
def pipeline_to(:twitch, %User{} = user, message) do
{:ok, stream_settings} = Settings.get_stream_settings_by_user_id(user.id)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
defmodule StreamClosedCaptionerPhoenix.CaptionsPipeline.Translations do
use NewRelic.Tracer

alias Azure.Cognitive.Translations
alias StreamClosedCaptionerPhoenix.Accounts.User
alias StreamClosedCaptionerPhoenix.Bits
alias StreamClosedCaptionerPhoenix.Bits.BitsBalanceDebit
alias StreamClosedCaptionerPhoenix.Settings

@trace :maybe_translate
def maybe_translate(payload, key, %User{} = user) do
text = Map.get(payload, key)

case Bits.get_user_active_debit(user.id) do
%BitsBalanceDebit{} ->
%Translations{translations: translations} = get_translations(user, text)
%{payload | translations: translations}

nil ->
to_languages = Settings.get_formatted_translate_languages_by_user(user.id)
if Bits.user_active_debit_exists?(user.id) do
%Translations{translations: translations} = get_translations(user, text)
%{payload | translations: translations}
else
to_languages = Settings.get_formatted_translate_languages_by_user(user.id)
bits_balance = Bits.get_bits_balance_for_user(user)

if Enum.empty?(to_languages) do
payload
else
activate_translations_for(user, payload, text)
end
if Enum.empty?(to_languages) || bits_balance.balance < 500 do
payload
else
activate_translations_for(user, payload, text)
end
end
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
defmodule StreamClosedCaptionerPhoenixWeb.CaptionsChannel do
use StreamClosedCaptionerPhoenixWeb, :channel
use NewRelic.Tracer
alias StreamClosedCaptionerPhoenixWeb.UserTracker

@impl true
def join("captions:" <> user_id, _payload, socket) do
if authorized?(socket, user_id) do
send(self(), :after_join)

if FunWithFlags.enabled?(:deepgram, for: socket.assigns.current_user) do
{:ok, pid} = DeepgramWebsocket.start_link(%{user: socket.assigns.current_user})

{:ok, assign(socket, :wss_pid, pid)}
else
{:ok, socket}
end
{:ok, socket}
else
{:error, %{reason: "unauthorized"}}
end
Expand Down Expand Up @@ -45,6 +40,7 @@ defmodule StreamClosedCaptionerPhoenixWeb.CaptionsChannel do
end
end

@trace :handle_in
def handle_in(_publish_state, %{"twitch" => %{"enabled" => true}} = payload, socket) do
NewRelic.start_transaction("Captions", "twitch")
sent_on_time = Map.get(payload, "sentOn")
Expand Down
Loading
Loading