コード例 #1
0
        public async Task PostAsync(TestNotification request)
        {
            DiscordOptions options = GetOptions(request.UserID);

            string footerText;

            if (options.ServerNameOverride)
            {
                footerText = $"From {_serverConfiguration.Configuration.ServerName}";
            }
            else
            {
                footerText = "From Emby Server";
            }

            DiscordMessage discordMessage = new DiscordMessage()
            {
                avatar_url = options.AvatarUrl,
                username   = options.Username,
                embeds     = new List <DiscordEmbed>()
                {
                    new DiscordEmbed()
                    {
                        color       = int.Parse(options.EmbedColor.Substring(1, 6), System.Globalization.NumberStyles.HexNumber),
                        description = "This is a test notification from Emby",
                        title       = "It worked!",
                        footer      = new Footer
                        {
                            icon_url = options.AvatarUrl,
                            text     = footerText
                        },
                        timestamp = DateTime.Now
                    }
                }
            };

            switch (options.MentionType)
            {
            case MentionTypes.Everyone:
                discordMessage.content = "@everyone";
                break;

            case MentionTypes.Here:
                discordMessage.content = "@here";
                break;
            }

            try {
                await DiscordWebhookHelper.ExecuteWebhook(discordMessage, options.DiscordWebhookURI, _jsonSerializer);
            }
            catch (System.Exception e) {
                _logger.ErrorException("Failed to execute webhook", e);
                throw new ArgumentException();
            }
        }
コード例 #2
0
        /// <inheritdoc />
        public Task SendNotification(UserNotification request, CancellationToken cancellationToken)
        {
            var options = GetOptions(request.User);

            if ((!options.MediaAddedOverride || request.Name.Contains(_localizationManager.GetLocalizedString("ValueHasBeenAddedToLibrary").Replace("{0} ", string.Empty, StringComparison.OrdinalIgnoreCase).Replace(" {1}", string.Empty, StringComparison.OrdinalIgnoreCase), StringComparison.OrdinalIgnoreCase)) && options.MediaAddedOverride)
            {
                return(Task.CompletedTask);
            }

            var serverName = _serverConfiguration.Configuration.ServerName;

            string footerText;
            string requestName;

            if (options.ServerNameOverride)
            {
                footerText  = $"From {serverName}";
                requestName = request.Name.Replace("Jellyfin Server", serverName, StringComparison.OrdinalIgnoreCase);
            }
            else
            {
                requestName = request.Name;
                footerText  = "From Jellyfin Server";
            }

            var discordMessage = new DiscordMessage();

            discordMessage.AvatarUrl = options.AvatarUrl;
            discordMessage.Username  = options.Username;
            discordMessage.Embeds.Add(
                new DiscordEmbed
            {
                Color       = DiscordWebhookHelper.FormatColorCode(options.EmbedColor),
                Title       = requestName,
                Description = request.Description,
                Footer      = new Footer
                {
                    IconUrl = options.AvatarUrl,
                    Text    = footerText
                },
                Timestamp = DateTime.Now
            });

            discordMessage.Content = options.MentionType switch
            {
                MentionType.Everyone => "@everyone",
                MentionType.Here => "@here",
                _ => string.Empty
            };

            _pendingSendQueue.Add(discordMessage, options);

            return(Task.CompletedTask);
        }
コード例 #3
0
        /// <summary>
        /// Post test notification async.
        /// </summary>
        /// <param name="request">The test notification request.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public async Task PostAsync(TestNotification request)
        {
            var options = GetOptions(request.UserId);

            var footerText = options.ServerNameOverride ? $"From {_serverConfiguration.Configuration.ServerName}" : "From Jellyfin Server";

            var discordMessage = new DiscordMessage();

            discordMessage.AvatarUrl = options.AvatarUrl;
            discordMessage.Username  = options.Username;
            discordMessage.Embeds.Add(
                new DiscordEmbed
            {
                Color       = int.Parse(options.EmbedColor.Substring(1, 6), NumberStyles.HexNumber, CultureInfo.InvariantCulture),
                Description = "This is a test notification from Jellyfin",
                Title       = "It worked!",
                Footer      = new Footer
                {
                    IconUrl = options.AvatarUrl,
                    Text    = footerText
                },
                Timestamp = DateTime.Now
            });

            discordMessage.Content = options.MentionType switch
            {
                MentionType.Everyone => "@everyone",
                MentionType.Here => "@here",
                _ => string.Empty
            };

            try
            {
                await DiscordWebhookHelper.ExecuteWebhook(_httpClient, _logger, discordMessage, options.DiscordWebhookUri, _jsonSerializerOptions)
                .ConfigureAwait(false);
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Failed to execute webhook", e);
                throw;
            }
        }
    }
コード例 #4
0
        private async void QueuedMessageSender(object sender, ElapsedEventArgs eventArgs)
        {
            try
            {
                if (_pendingSendQueue.Count > 0)
                {
                    var message = _pendingSendQueue.First().Key;
                    var options = _pendingSendQueue.First().Value;

                    await DiscordWebhookHelper.ExecuteWebhook(_httpClient, _logger, message, options.DiscordWebhookUri, _jsonSerializerOptions).ConfigureAwait(false);

                    if (_pendingSendQueue.ContainsKey(message))
                    {
                        _pendingSendQueue.Remove(message);
                    }
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Failed to execute webhook");
            }
        }
コード例 #5
0
        private void CheckForMetadata(object sender, ElapsedEventArgs eventArgs)
        {
            try
            {
                var queueCount = _queuedUpdateCheck.Count;
                if (queueCount > 0)
                {
                    _logger.LogDebug("Item in queue : {0}", queueCount);
                }

                _queuedUpdateCheck.ToList().ForEach(queuedItem =>
                {
                    // sometimes an update check might execute while another one is hanging and causes crash !
                    if (_queuedUpdateCheck.ContainsKey(queuedItem.Key))
                    {
                        var options = queuedItem.Value.Configuration;
                        var itemId  = queuedItem.Value.ItemId;

                        _logger.LogDebug("{0} queued for recheck", itemId.ToString());

                        var item = _libraryManager.GetItemById(itemId);

                        var itemLibraryOptions = _libraryManager.GetLibraryOptions(item);
                        // var sysInfo = await _applicationHost.GetPublicSystemInfo(CancellationToken.None);
                        var serverConfig = _serverConfiguration.Configuration;

                        var libraryType = item.GetType().Name;
                        var serverName  = options.ServerNameOverride ? serverConfig.ServerName : "Jellyfin Server";
                        serverName ??= "Jellyfin Server";

                        // for whatever reason if you have extraction on during library scans then it waits for the extraction to finish before populating the metadata.... I don't get why the f**k it goes in that order
                        // its basically impossible to make a prediction on how long it could take as its dependent on the bitrate, duration, codec, and processing power of the system
                        var localMetadataFallback = _queuedUpdateCheck[queuedItem.Key].Retries >= (itemLibraryOptions.ExtractChapterImagesDuringLibraryScan ? Constants.MaxRetriesBeforeFallback * 5.5 : Constants.MaxRetriesBeforeFallback);

                        if (item.ProviderIds.Count > 0 || localMetadataFallback)
                        {
                            _logger.LogDebug("{0}[{1}] has metadata (Local fallback: {2}), adding to queue", item.Id, item.Name, localMetadataFallback, options.UserId);

                            if (_queuedUpdateCheck.ContainsKey(queuedItem.Key))
                            {
                                // remove it beforehand because if some operation takes any longer amount of time it might allow enough time for another notification to slip through
                                _queuedUpdateCheck.Remove(queuedItem.Key);
                            }

                            // build primary info
                            var mediaAddedEmbed       = new DiscordMessage();
                            mediaAddedEmbed.Username  = options.Username;
                            mediaAddedEmbed.AvatarUrl = options.AvatarUrl;
                            mediaAddedEmbed.Embeds.Add(
                                new DiscordEmbed
                            {
                                Color  = DiscordWebhookHelper.FormatColorCode(options.EmbedColor),
                                Footer = new Footer
                                {
                                    Text    = $"From {serverName}",
                                    IconUrl = options.AvatarUrl
                                },
                                Timestamp = DateTime.Now
                            });

                            // populate title

                            string titleText;

                            if (libraryType == "Episode")
                            {
                                titleText = $"{item.Parent.Parent.Name}{(item.ParentIndexNumber.HasValue ? $" S{item.ParentIndexNumber:00}" : string.Empty)}{(item.IndexNumber.HasValue ? $"E{item.IndexNumber:00}" : string.Empty)} {item.Name}";
                            }
                            else if (libraryType == "Season")
                            {
                                titleText = $"{item.Parent.Name} {item.Name}";
                            }
                            else
                            {
                                titleText = $"{item.Name}{(item.ProductionYear.HasValue ? $" ({item.ProductionYear.ToString()})" : string.Empty)}";
                            }

                            mediaAddedEmbed.Embeds[0].Title = $"{titleText} has been added to {serverName.Trim()}";

                            // populate description
                            if (libraryType == "Audio")
                            {
                                var artists = _libraryManager.GetAllArtists(new InternalItemsQuery {
                                    ItemIds = new[] { itemId }
                                });

                                var artistsFormat = artists.Items.Select(baseItem =>
                                {
                                    var artist          = baseItem.Item1;
                                    var formattedArtist = artist.Name;

                                    if (artist.ProviderIds.Count != 0)
                                    {
                                        var(key, value) = artist.ProviderIds.FirstOrDefault();

                                        var providerUrl = key == "MusicBrainzArtist"
                                            ? $"https://musicbrainz.org/artist/{value}"
                                            : $"https://theaudiodb.com/artist/{value}";

                                        formattedArtist += $" [(Music Brainz)]({providerUrl})";
                                    }

                                    if (serverConfig.EnableRemoteAccess && !options.ExcludeExternalServerLinks)
                                    {
                                        formattedArtist += $" [(Jellyfin)]({options.ServerUrl}/web/index.html#!/details?id={itemId}&serverId={_applicationHost.SystemId})";
                                    }

                                    return(formattedArtist);
                                });

                                if (artists.Items.Count != 0)
                                {
                                    mediaAddedEmbed.Embeds[0].Description = $"By {string.Join(", ", artistsFormat)}";
                                }
                            }
                            else
                            {
                                if (!string.IsNullOrEmpty(item.Overview))
                                {
                                    mediaAddedEmbed.Embeds[0].Description = item.Overview;
                                }
                            }

                            // populate title URL
                            if (serverConfig.EnableRemoteAccess && !options.ExcludeExternalServerLinks)
                            {
                                mediaAddedEmbed.Embeds[0].Url = $"{options.ServerUrl}/web/index.html#!/details?id={itemId}&serverId={_applicationHost.SystemId}";
                            }

                            // populate images
                            if (item.HasImage(ImageType.Primary))
                            {
                                var imageUrl = string.Empty;

                                if (!item.GetImageInfo(ImageType.Primary, 0).IsLocalFile)
                                {
                                    imageUrl = item.GetImagePath(ImageType.Primary);
                                }
                                else if (serverConfig.EnableRemoteAccess && !options.ExcludeExternalServerLinks) // in the future we can proxy images through memester server if people want to hide their server address
                                {
                                    imageUrl = $"{options.ServerUrl}/Items/{itemId}/Images/Primary";
                                }
                                else
                                {
                                    var localPath = item.GetImagePath(ImageType.Primary);

                                    try
                                    {
                                        var response = MemesterServiceHelper.UploadImage(localPath);
                                        imageUrl     = response.FilePath;
                                    }
                                    catch (Exception e)
                                    {
                                        _logger.LogError(e, "Failed to proxy image");
                                    }
                                }

                                mediaAddedEmbed.Embeds[0].Thumbnail = new Thumbnail
                                {
                                    Url = imageUrl
                                };
                            }

                            mediaAddedEmbed.Content = options.MentionType switch
                            {
                                MentionType.Everyone => "@everyone",
                                MentionType.Here => "@here",
                                _ => string.Empty
                            };

                            // populate external URLs
                            var providerFields = new List <Field>();

                            if (!localMetadataFallback)
                            {
                                item.ProviderIds.ToList().ForEach(provider =>
                                {
                                    var field = new Field
                                    {
                                        Name = "External Links"
                                    };

                                    var didPopulate = true;

                                    switch (provider.Key.ToLower(CultureInfo.InvariantCulture))
                                    {
                                    case "imdb":
                                        field.Value = $"[IMDb](https://www.imdb.com/title/{provider.Value}/)";
                                        break;

                                    case "tmdb":
                                        field.Value = $"[TMDb](https://www.themoviedb.org/{(libraryType == "Movie" ? "movie" : "tv")}/{provider.Value})";
                                        break;

                                    case "musicbrainztrack":
                                        field.Value = $"[MusicBrainz Track](https://musicbrainz.org/track/{provider.Value})";
                                        break;

                                    case "musicbrainzalbum":
                                        field.Value = $"[MusicBrainz Album](https://musicbrainz.org/release/{provider.Value})";
                                        break;

                                    case "theaudiodbalbum":
                                        field.Value = $"[TADb Album](https://theaudiodb.com/album/{provider.Value})";
                                        break;

                                    default:
                                        didPopulate = false;
                                        break;
                                    }

                                    if (didPopulate)
                                    {
                                        providerFields.Add(field);
                                    }
                                });

                                if (providerFields.Count > 0)
                                {
                                    mediaAddedEmbed.Embeds[0].Fields.AddRange(providerFields);
                                }
                            }

                            _pendingSendQueue.Add(mediaAddedEmbed, options);
                        }
                        else
                        {
                            if (_queuedUpdateCheck.ContainsKey(queuedItem.Key))
                            {
                                _queuedUpdateCheck[queuedItem.Key].Retries++;
                            }
                        }
                    }
                });
            }
            catch (Exception e)
            {
                _logger.LogError(e, "Something unexpected happened in the item update checker");
            }
        }