Files
pinchflat/lib/pinchflat/lifecycle/notifications/source_notifications.ex
T
Kieran a2a0f48065 [Enhancement] Add media count to sources page (#251)
* [WIP] Got query kinda working, now to refactor other queries

* Refactored all query methods to use dynamic snippets

* Refactored tab layout to grab tabs by name

* Removed standalone show buttons from in-app tables

* Removed unneeded comment
2024-05-21 08:53:22 -07:00

82 lines
2.2 KiB
Elixir

defmodule Pinchflat.Lifecycle.Notifications.SourceNotifications do
@moduledoc """
Contains utilities for sending notifications about sources
"""
require Logger
use Pinchflat.Media.MediaQuery
alias Pinchflat.Repo
@doc """
Wraps a function that may change the number of pending or downloaded
media items for a source, sending an apprise notification if
the count changes.
Returns the return value of the provided function
"""
def wrap_new_media_notification(servers, source, func) do
before_count = relevant_media_item_count(source)
retval = func.()
after_count = relevant_media_item_count(source)
send_new_media_notification(servers, source, after_count - before_count)
retval
end
@doc """
Sends a notification if the count of new media items has changed
Returns :ok
"""
def send_new_media_notification(_, _, count) when count <= 0, do: :ok
def send_new_media_notification(servers, source, changed_count) do
opts = [
title: "[Pinchflat] New media found",
body: "Found #{changed_count} new media item(s) for #{source.custom_name}. Downloading them now"
]
case backend_runner().run(servers, opts) do
{:ok, _} ->
Logger.info("Sent new media notification for source #{source.id}")
{:error, :no_servers} ->
Logger.info("No notification servers provided for source #{source.id}")
{:error, err} ->
Logger.error("Failed to send new media notification for source #{source.id}: #{err}")
end
:ok
end
defp relevant_media_item_count(source) do
if source.download_media do
pending_media_item_count(source) + downloaded_media_item_count(source)
else
0
end
end
defp pending_media_item_count(source) do
MediaQuery.new()
|> MediaQuery.require_assoc(:media_profile)
|> where(^dynamic(^MediaQuery.for_source(source) and ^MediaQuery.pending()))
|> Repo.aggregate(:count)
end
defp downloaded_media_item_count(source) do
MediaQuery.new()
|> where(^dynamic(^MediaQuery.for_source(source) and ^MediaQuery.downloaded()))
|> Repo.aggregate(:count)
end
defp backend_runner do
# This approach lets us mock the command for testing
Application.get_env(:pinchflat, :apprise_runner)
end
end