예제 #1
0
        public async Task <SocialShareInfo> CreateShare(string itemId, string userId)
        {
            if (string.IsNullOrWhiteSpace(itemId))
            {
                throw new ArgumentNullException("itemId");
            }
            if (string.IsNullOrWhiteSpace(userId))
            {
                throw new ArgumentNullException("userId");
            }

            var item = _libraryManager.GetItemById(itemId);

            if (item == null)
            {
                throw new ResourceNotFoundException();
            }

            var externalUrl = (await _appHost.GetPublicSystemInfo(CancellationToken.None).ConfigureAwait(false)).WanAddress;

            if (string.IsNullOrWhiteSpace(externalUrl))
            {
                throw new InvalidOperationException("No external server address is currently available.");
            }

            var info = new SocialShareInfo
            {
                Id             = Guid.NewGuid().ToString("N"),
                ExpirationDate = DateTime.UtcNow.AddDays(_config.Configuration.SharingExpirationDays),
                ItemId         = itemId,
                UserId         = userId
            };

            AddShareInfo(info, externalUrl);

            _repository.CreateShare(info);

            return(info);
        }
예제 #2
0
 public ActionResult <PublicSystemInfo> GetPublicSystemInfo()
 {
     return(_appHost.GetPublicSystemInfo(Request));
 }
예제 #3
0
        private void CheckForMetadata(object sender, ElapsedEventArgs eventArgs)
        {
            try
            {
                queuedUpdateCheck.ToList().ForEach(async updateCheck =>
                {
                    Guid itemId = updateCheck.Key;

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

                    BaseItem item = _libraryManager.GetItemById(itemId);

                    LibraryOptions itemLibraryOptions = _libraryManager.GetLibraryOptions(item);
                    DiscordOptions options            = Plugin.Instance.Configuration.Options.FirstOrDefault(opt => opt.MediaAddedOverride == true);
                    PublicSystemInfo sysInfo          = await _applicationHost.GetPublicSystemInfo(CancellationToken.None);
                    ServerConfiguration serverConfig  = _serverConfiguration.Configuration;

                    if (!isInVisibleLibrary(options.MediaBrowserUserId, item))
                    {
                        queuedUpdateCheck.Remove(itemId);
                        _logger.Debug("User does not have access to library, skipping...");
                        return;
                    }

                    // 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
                    Boolean localMetadataFallback = queuedUpdateCheck[itemId] >= (itemLibraryOptions.ExtractChapterImagesDuringLibraryScan ? Constants.MaxRetriesBeforeFallback * 5.5 : Constants.MaxRetriesBeforeFallback);

                    if (item.ProviderIds.Count > 0 || localMetadataFallback)
                    {
                        _logger.Debug("{0}[{1}] has metadata, sending notification", item.Id, item.Name);

                        string serverName  = options.ServerNameOverride ? serverConfig.ServerName : "Emby Server";
                        string LibraryType = item.GetType().Name;

                        // build primary info
                        DiscordMessage mediaAddedEmbed = new DiscordMessage
                        {
                            username   = options.Username,
                            avatar_url = options.AvatarUrl,
                            embeds     = new List <DiscordEmbed>()
                            {
                                new DiscordEmbed()
                                {
                                    color  = DiscordWebhookHelper.FormatColorCode(options.EmbedColor),
                                    footer = new Footer
                                    {
                                        text     = $"From {serverName}",
                                        icon_url = options.AvatarUrl
                                    },
                                    timestamp = DateTime.Now
                                }
                            },
                        };

                        // populate title

                        string titleText;

                        if (LibraryType == "Episode")
                        {
                            titleText = $"{item.Parent.Parent.Name} {(item.ParentIndexNumber != null ? $"S{formatIndex(item.ParentIndexNumber)}" : "")}{(item.IndexNumber != null ? $"E{formatIndex(item.IndexNumber)}" : "")} {item.Name}";
                        }
                        else
                        {
                            titleText = $"{item.Name} {(!String.IsNullOrEmpty(item.ProductionYear.ToString()) ? $"({item.ProductionYear.ToString()})" : "")}";
                        }

                        mediaAddedEmbed.embeds.First().title = _localizationManager.GetLocalizedString("ValueHasBeenAddedToLibrary").Replace("{0}", titleText).Replace("{1}", serverName);

                        // populate description
                        if (LibraryType == "Audio")
                        {
                            List <BaseItem> artists = _libraryManager.GetAllArtists(item);

                            IEnumerable <string> artistsFormat = artists.Select(artist =>
                            {
                                if (artist.ProviderIds.Count() > 0)
                                {
                                    KeyValuePair <string, string> firstProvider = artist.ProviderIds.FirstOrDefault();

                                    string providerUrl = firstProvider.Key == "MusicBrainzArtist" ? $"https://musicbrainz.org/artist/{firstProvider.Value}" : $"https://theaudiodb.com/artist/{firstProvider.Value}";

                                    return($"[{artist.Name}]({providerUrl})");
                                }
                                else
                                {
                                    return(artist.Name);
                                }
                            });

                            if (artists.Count() > 0)
                            {
                                mediaAddedEmbed.embeds.First().description = $"By {string.Join(", ", artistsFormat)}";
                            }
                        }
                        else
                        {
                            if (!String.IsNullOrEmpty(item.Overview))
                            {
                                mediaAddedEmbed.embeds.First().description = item.Overview;
                            }
                        }

                        // populate title URL
                        if (!String.IsNullOrEmpty(sysInfo.WanAddress) && !options.ExcludeExternalServerLinks)
                        {
                            mediaAddedEmbed.embeds.First().url = $"{sysInfo.WanAddress}/web/index.html#!/item?id={itemId}&serverId={sysInfo.Id}";
                        }

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

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

                                try
                                {
                                    imageUrl = await MemesterServiceHelper.UploadImage(imageData, _jsonSerializer, _httpClient);
                                }
                                catch (Exception e)
                                {
                                    _logger.ErrorException("Failed to proxy image", e);
                                }
                            }

                            mediaAddedEmbed.embeds.First().thumbnail = new Thumbnail
                            {
                                url = imageUrl
                            };
                        }


                        if (options.MentionType == MentionTypes.Everyone)
                        {
                            mediaAddedEmbed.content = "@everyone";
                        }
                        else if (options.MentionType == MentionTypes.Here)
                        {
                            mediaAddedEmbed.content = "@here";
                        }

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

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

                                Boolean didPopulate = true;

                                switch (provider.Key.ToLower())
                                {
                                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 == true)
                                {
                                    providerFields.Add(field);
                                }
                            });

                            if (providerFields.Count() > 0)
                            {
                                mediaAddedEmbed.embeds.First().fields = providerFields;
                            }
                        }

                        pendingSendQueue.Add(mediaAddedEmbed, options);

                        queuedUpdateCheck.Remove(itemId);
                    }
                    else
                    {
                        queuedUpdateCheck[itemId]++;

                        _logger.Debug("Attempt: {0}", queuedUpdateCheck[itemId]);
                    }
                });
            }
            catch (Exception e)
            {
                _logger.ErrorException("Something unexpected happened in the update checker", e);
            }
        }
예제 #4
0
 public ActionResult <PublicSystemInfo> GetPublicSystemInfo()
 {
     return(_appHost.GetPublicSystemInfo(Request.HttpContext.Connection.RemoteIpAddress ?? IPAddress.Loopback));
 }
예제 #5
0
        public async Task <object> Get(GetPublicSystemInfo request)
        {
            var result = await _appHost.GetPublicSystemInfo(CancellationToken.None).ConfigureAwait(false);

            return(ToOptimizedResult(result));
        }
예제 #6
0
 public async Task <ActionResult <PublicSystemInfo> > GetPublicSystemInfo()
 {
     return(await _appHost.GetPublicSystemInfo(CancellationToken.None).ConfigureAwait(false));
 }
예제 #7
0
        private void CheckForMetadata(object sender, ElapsedEventArgs eventArgs)
        {
            try
            {
                int queueCount = queuedUpdateCheck.Count();
                if (queueCount > 0)
                {
                    _logger.Debug("Item in queue : {0}", queueCount);
                }

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

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

                        BaseItem item = _libraryManager.GetItemById(itemId);

                        LibraryOptions itemLibraryOptions = _libraryManager.GetLibraryOptions(item);
                        PublicSystemInfo sysInfo          = await _applicationHost.GetPublicSystemInfo(CancellationToken.None);
                        ServerConfiguration serverConfig  = _serverConfiguration.Configuration;

                        string LibraryType = item.GetType().Name;
                        string serverName  = options.ServerNameOverride ? serverConfig.ServerName : "Emby Server";

                        if (string.IsNullOrEmpty(serverName))
                        {
                            serverName = "Emby 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
                        Boolean localMetadataFallback = queuedUpdateCheck[queuedItem.Key].Retries >= (itemLibraryOptions.ExtractChapterImagesDuringLibraryScan ? Constants.MaxRetriesBeforeFallback * 5.5 : Constants.MaxRetriesBeforeFallback);

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

                            if (queuedUpdateCheck.ContainsKey(queuedItem.Key))
                            {
                                queuedUpdateCheck.Remove(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
                            }
                            // build primary info
                            DiscordMessage mediaAddedEmbed = new DiscordMessage
                            {
                                username   = options.Username,
                                avatar_url = options.AvatarUrl,
                                embeds     = new List <DiscordEmbed>()
                                {
                                    new DiscordEmbed()
                                    {
                                        color  = DiscordWebhookHelper.FormatColorCode(options.EmbedColor),
                                        footer = new Footer
                                        {
                                            text     = $"From {serverName}",
                                            icon_url = options.AvatarUrl
                                        },
                                        timestamp = DateTime.Now
                                    }
                                },
                            };

                            // populate title
                            string titleText;
                            if (LibraryType == "Episode")
                            {
                                titleText = $"{item.Parent.Parent.Name}{(item.ParentIndexNumber.HasValue ? $" S{formatIndex(item.ParentIndexNumber)}" : "")}{(item.IndexNumber.HasValue ? $"E{formatIndex(item.IndexNumber)}" : "")} {item.Name}";
                            }
                            else if (LibraryType == "Season")
                            {
                                titleText = $"{item.Parent.Name} {item.Name}";
                            }
                            else
                            {
                                titleText = $"{item.Name}{(item.ProductionYear.HasValue ? $" ({item.ProductionYear.ToString()})" : "")}";
                            }

                            mediaAddedEmbed.embeds.First().title = $"{titleText} has been added to {serverName.Trim()}";

                            // populate description
                            if (LibraryType == "Audio")
                            {
                                List <BaseItem> artists = _libraryManager.GetAllArtists(item);

                                IEnumerable <string> artistsFormat = artists.Select(artist =>
                                {
                                    string formattedArtist = artist.Name;

                                    if (artist.ProviderIds.Count() > 0)
                                    {
                                        KeyValuePair <string, string> firstProvider = artist.ProviderIds.FirstOrDefault();

                                        string providerUrl = firstProvider.Key == "MusicBrainzArtist" ? $"https://musicbrainz.org/artist/{firstProvider.Value}" : $"https://theaudiodb.com/artist/{firstProvider.Value}";

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

                                    if (serverConfig.EnableRemoteAccess && !options.ExcludeExternalServerLinks)
                                    {
                                        formattedArtist += $" [(Emby)]({sysInfo.WanAddress}/web/index.html#!/item?id={itemId}&serverId={artist.InternalId})";
                                    }

                                    return(formattedArtist);
                                });

                                if (artists.Count() > 0)
                                {
                                    mediaAddedEmbed.embeds.First().description = $"By {string.Join(", ", artistsFormat)}";
                                }
                            }
                            else
                            {
                                if (!String.IsNullOrEmpty(item.Overview))
                                {
                                    mediaAddedEmbed.embeds.First().description = item.Overview;
                                }
                            }

                            // populate title URL
                            if (serverConfig.EnableRemoteAccess && !options.ExcludeExternalServerLinks)
                            {
                                mediaAddedEmbed.embeds.First().url = $"{sysInfo.WanAddress}/web/index.html#!/item?id={itemId}&serverId={sysInfo.Id}";
                            }

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

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

                                    try
                                    {
                                        ImageServiceResponse response = MemesterServiceHelper.UploadImage(localPath, _jsonSerializer);
                                        imageUrl = response.filePath;
                                    }
                                    catch (Exception e)
                                    {
                                        _logger.ErrorException("Failed to proxy image", e);
                                    }
                                }

                                mediaAddedEmbed.embeds.First().thumbnail = new Thumbnail
                                {
                                    url = imageUrl
                                };
                            }

                            if (options.MentionType == MentionTypes.Everyone)
                            {
                                mediaAddedEmbed.content = "@everyone";
                            }
                            else if (options.MentionType == MentionTypes.Here)
                            {
                                mediaAddedEmbed.content = "@here";
                            }

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

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

                                    Boolean didPopulate = true;
                                    switch (provider.Key.ToLower())
                                    {
                                    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 == true)
                                    {
                                        providerFields.Add(field);
                                    }
                                });

                                if (providerFields.Count() > 0)
                                {
                                    mediaAddedEmbed.embeds.First().fields = providerFields;
                                }
                            }

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