Esempio n. 1
0
 private string FormatLink(string text, Dictionary <string, string> externUrls, bool trim = true)
 {
     text = text.Truncate(trim ? 22 : int.MaxValue);
     if (externUrls.ContainsKey("spotify"))
     {
         return(DiscordHelpers.BuildMarkdownUri(text, externUrls["spotify"]));
     }
     else
     {
         return(text);
     }
 }
Esempio n. 2
0
        private void OnNotify(object state)
        {
            TaskHelper.FireForget(async() =>
            {
                try
                {
                    var(serverId, _) = ((ulong, int))state;
                    if (!_notifications.TryGetValue(serverId, out var context))
                    {
                        return;
                    }

                    using (await context.Lock.ClaimAsync())
                    {
                        if (!context.ValidateCallback(state))
                        {
                            return; // Old timer (can happen due to timer race conditions)
                        }
                        var guild = _client.GetGuild(serverId) as IGuild;
                        if (guild == null)
                        {
                            _logger.LogInformation("Server {" + LogFields.GuildId + "} not found", serverId);
                            return;
                        }

                        var logger   = _logger.WithScope(guild);
                        var settings = await _settings.Read <ScheduleSettings>(serverId, false);
                        if (settings == null)
                        {
                            logger.LogWarning("Settings for server not found");
                            return;
                        }

                        var dueTime = context.UtcDueTime.Value.Add(settings.TimezoneOffset);
                        var events  = settings.Events.Where(x => x.Date == dueTime && x.HasTime && x.Notify);
                        foreach (var e in events)
                        {
                            foreach (var s in settings.Notifications.Where(x => e.FitsTag(x.Tag)))
                            {
                                try
                                {
                                    var channel = await guild.GetTextChannelAsync(s.Channel);
                                    if (channel == null)
                                    {
                                        continue;
                                    }

                                    var role  = s.Role != default ? guild.GetRole(s.Role) : null;
                                    var embed = new EmbedBuilder()
                                                .WithTitle("🔔 Schedule")
                                                .WithDescription($"{(e.HasLink ? DiscordHelpers.BuildMarkdownUri(e.Description, e.Link) : e.Description)} is now on!");

                                    await channel.SendMessageAsync(role != null ? $"{role.Mention} " : "", embed: embed.Build());
                                    logger.LogInformation("Notified event {ScheduleEventDescription} ({ScheduleEventDate}, TZ: {ScheduleTimezone}, ID: {ScheduleEventId})", e.Description, e.Date, settings.TimezoneOffset, e.Id);
                                }
                                catch (Exception ex)
                                {
                                    logger.LogError(ex, "Failed to notify event {ScheduleEventDescription} ({ScheduleEventId})", e.Description, e.Id);
                                }
                            }
                        }

                        var now  = DateTime.UtcNow.Add(settings.TimezoneOffset);
                        var next = settings.Events.SkipWhile(x => x.Date <= dueTime).FirstOrDefault(x => x.Notify && x.HasTime);
                        if (next == default)
                        {
                            context.Disable();
                            return;
                        }

                        context.Replan(next.Date - now, next.Date.Subtract(settings.TimezoneOffset));
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Failed to process event notifications");
                }
            });
        }
Esempio n. 3
0
 private string FormatLink(string text, string url, bool trim = false)
 => DiscordHelpers.BuildMarkdownUri(text.Truncate(trim ? 22 : int.MaxValue), url);
Esempio n. 4
0
        public async Task NowPlaying(ICommand command)
        {
            try
            {
                var(settings, user) = await GetLastFmSettings(command["User"], (IGuildUser)command.Author);

                var client        = new LastFmClient(settings.LastFmUsername, _integrationOptions.Value.LastFmKey);
                var topTracksTask = client.GetTopTracks(LastFmDataPeriod.Month, 100);
                var tracks        = (await client.GetRecentTracks(count: 1)).ToList();

                if (!tracks.Any())
                {
                    await command.Reply(GetNoScrobblesMessage((await command["User"].AsGuildUserOrName)?.Item2));

                    return;
                }

                var nowPlaying = tracks[0].NowPlaying;
                var current    = await client.GetTrackInfo(tracks[0].Artist.Name, tracks[0].Name);

                // Description
                var description = new StringBuilder();
                description.AppendLine($"**{FormatTrackLink(current ?? tracks[0].ToTrack())}** by **{FormatArtistLink(current?.Artist ?? tracks[0].Artist)}**");
                if (!string.IsNullOrEmpty(current?.Album?.Name))
                {
                    description.AppendLine($"On {DiscordHelpers.BuildMarkdownUri(current.Album.Name, current.Album.Url)}");
                }
                else if (!string.IsNullOrEmpty(tracks[0].Album?.Name))
                {
                    description.AppendLine($"On {tracks[0].Album.Name}");
                }

                var embed = new EmbedBuilder()
                            .WithDescription(description.ToString())
                            .WithColor(0xd9, 0x23, 0x23);

                // Image
                var imageUri = current?.Album?.ImageUri ?? tracks[0]?.Album?.ImageUri;
                if (imageUri != null)
                {
                    embed.WithThumbnailUrl(imageUri.AbsoluteUri);
                }

                // Title
                var author = new EmbedAuthorBuilder().WithIconUrl(_websiteWalker.LfIconUrl);
                if (!settings.Anonymous)
                {
                    author.WithUrl($"https://www.last.fm/user/{settings.LastFmUsername}");
                }

                if (nowPlaying)
                {
                    author.WithName($"{user} is now listening to...");
                }
                else
                {
                    author.WithName($"{user} last listened to...");
                }

                embed.WithAuthor(author);

                // Playcount
                var playCount = (current?.Playcount ?? 0) + (nowPlaying ? 1 : 0);
                if (playCount == 1 && current?.Playcount != null)
                {
                    embed.WithFooter($"First listen");
                }
                else if (playCount > 1)
                {
                    embed.WithFooter($"{playCount.ToEnglishOrdinal()} listen");
                }

                // Month placement
                {
                    var topTracks = await topTracksTask;

                    int counter = 0, placement = 0, placementPlaycount = int.MaxValue;
                    foreach (var track in topTracks)
                    {
                        counter++;
                        if (placementPlaycount > track.Playcount)
                        {
                            placementPlaycount = track.Playcount.Value;
                            placement          = counter;
                        }

                        if (string.Compare(track.Url, (string)(current?.Url ?? tracks[0].Url), true) == 0)
                        {
                            var footer = placement == 1 ? "Most played track this month" : $"{placement.ToEnglishOrdinal()} most played this month";
                            if (embed.Footer != null)
                            {
                                embed.Footer.Text += " • " + footer;
                            }
                            else
                            {
                                embed.WithFooter(footer);
                            }

                            break;
                        }
                    }
                }

                // Previous
                if (nowPlaying && tracks.Count > 1)
                {
                    var previous = tracks[1];
                    embed.AddField(x => x.WithName("Previous").WithValue($"{FormatTrackLink(previous?.ToTrack())} by {FormatArtistLink(previous?.Artist)}"));
                }

                await command.Reply(embed.Build());
            }
            catch (WebException e) when((e.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound)
            {
                ThrowUserNotFound((await command["User"].AsGuildUserOrName)?.Item2);
            }
            catch (WebException e) when((e.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.Forbidden)
            {
                throw new CommandException("The bot can't access your recently listened tracks. \n\nPlease make sure you don't have `Hide recent listening information` checked in your Last.fm settings (Settings -> Privacy -> Recent listening).");
            }
            catch (WebException e)
            {
                await command.Reply($"Last.fm is down (error {(e.Response as HttpWebResponse)?.StatusCode.ToString() ?? e.Status.ToString()}). Please try again in a few seconds.");
            }
        }