Ejemplo n.º 1
0
            protected override async Task <int> OnExecuteAuthenticatedAsync(QBittorrentClient client, CommandLineApplication app, IConsole console)
            {
                var(apiVersion, legacyApiVersion, legacyApiMinVersion, qVersion) = await TaskHelper.WhenAll(
                    client.GetApiVersionAsync(),
                    client.GetLegacyApiVersionAsync(),
                    client.GetLegacyMinApiVersionAsync(),
                    client.GetQBittorrentVersionAsync());

                var doc = new Document(
                    new Grid
                {
                    Stroke   = UIHelper.NoneStroke,
                    Columns  = { UIHelper.FieldsColumns },
                    Children =
                    {
                        UIHelper.Row("QBittorrent version",    qVersion),
                        UIHelper.Row("API version",            apiVersion),
                        UIHelper.Row("Legacy API version",     legacyApiVersion),
                        UIHelper.Row("Legacy API min version", legacyApiMinVersion)
                    }
                }
                    ).SetColors(ColorScheme.Current.Normal);

                ConsoleRenderer.RenderDocument(doc);

                return(ExitCodes.Success);
            }
Ejemplo n.º 2
0
            protected override async Task <int> OnExecuteAuthenticatedAsync(QBittorrentClient client, CommandLineApplication app, IConsole console)
            {
                var apiVersion = await client.GetApiVersionAsync();

                var categories = apiVersion >= new ApiVersion(2, 1, 1)
                    ? await client.GetCategoriesAsync()
                    : (await client.GetPartialDataAsync()).CategoriesChanged;

                Print(categories.Values);
                return(ExitCodes.Success);
            }
Ejemplo n.º 3
0
            protected override async Task <int> OnExecuteAuthenticatedAsync(QBittorrentClient client, CommandLineApplication app, IConsole console)
            {
                var apiVersion = await client.GetApiVersionAsync();

                if (apiVersion < new ApiVersion(2, 1))
                {
                    console.WriteLineColored("The --save-path parameter requires qBittorrent 4.1.3 or later.",
                                             ColorScheme.Current.Warning);
                    return(ExitCodes.Failure);
                }

                await client.EditCategoryAsync(Name, SavePath);

                return(ExitCodes.Success);
            }
Ejemplo n.º 4
0
 public async Task EnsureLoggedInAsync()
 {
     try
     {
         await _client.GetApiVersionAsync();
     }
     catch (QBittorrentClientRequestException e)
     {
         if (e.StatusCode == HttpStatusCode.Forbidden)
         {
             _logger.LogWarning("Qbittorrent logged out, logging in Now");
             await _client.LoginAsync(_qbittorrentSetting.Username, _qbittorrentSetting.Password);
         }
     }
 }
                protected async Task WarnIfNotSupported(QBittorrentClient client, IConsole console,
                                                        ApiVersion version,
                                                        string message,
                                                        bool max,
                                                        params object[] properties)
                {
                    if (properties == null || properties.All(p => p == null))
                    {
                        return;
                    }

                    if ((await client.GetApiVersionAsync() < version) ^ max)
                    {
                        console.WriteLineColored(message, ColorScheme.Current.Warning);
                    }
                }
Ejemplo n.º 6
0
        private static async void Bot_OnMessage(object sender, MessageEventArgs e)
        {
            string messageText = e.Message.Text;
            ChatId chatId      = e.Message.Chat.Id;

            try
            {
                if (chatId.Identifier == _chatId.Identifier)
                {
                    if (messageText.ToLower() == "/status")
                    {
                        var startTimeInEt = TimeZoneInfo.ConvertTime(_startDateTime, GetEasternTimeZone());

                        await _botClient.SendTextMessageAsync(
                            chatId : _chatId,
                            text : string.Join(Environment.NewLine,
                                               $"Status is good. Running on container '{Environment.MachineName}'. Platform is {GetOsPlatform()}.",
                                               $"Bot uptime is {DateTimeOffset.UtcNow - _startDateTime} (since {startTimeInEt})."),
                            parseMode : ParseMode.Html
                            );
                    }
                    else if (messageText.ToLower() == "/qbittorrentstatus" && string.IsNullOrEmpty(_qBittorrentServer) == false)
                    {
                        // Instantiate the client
                        QBittorrentClient qBittorrentClient = new QBittorrentClient(new Uri($"http://{_qBittorrentServer}:8080"));
                        ApiVersion        apiVersion        = default;

                        try
                        {
                            await qBittorrentClient.LoginAsync(_qBittorrentUsername, _qBittorrentPassword);

                            apiVersion = await qBittorrentClient.GetApiVersionAsync();
                        }
                        catch (HttpRequestException ex) when(ex.InnerException is SocketException || ex is QBittorrentClientRequestException)
                        {
                            if ((ex.InnerException as SocketException)?.ErrorCode == 111)
                            {
                                // This means the login failed, which we will handle below.
                                await _botClient.SendTextMessageAsync(
                                    chatId : _chatId,
                                    text : "There was an error communicating with the qBittorrent server. It may be offline.");

                                return;
                            }

                            if ((ex as QBittorrentClientRequestException)?.StatusCode == HttpStatusCode.Forbidden)
                            {
                                // This means the login failed, which we will handle below.
                                await _botClient.SendTextMessageAsync(
                                    chatId : _chatId,
                                    text : "There was an error communicating with the qBittorrent server. You may have the wrong username/password.");

                                return;
                            }

                            throw;
                        }

                        // If we get here the server is online.
                        await _botClient.SendTextMessageAsync(
                            chatId : _chatId,
                            text : $"The qBittorrent server is online and running API version {apiVersion}.");
                    }
                    else
                    {
                        foreach (string messageLine in messageText.Split(Environment.NewLine))
                        {
                            if (Uri.TryCreate(messageLine, UriKind.Absolute, out Uri uri) && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
                            {
                                // Check if our data directory exists. If not, we can't download anything.
                                if (Directory.Exists("/data/") == false)
                                {
                                    await _botClient.SendTextMessageAsync(
                                        chatId : _chatId,
                                        text : "Data directory mapping does not exist. Cannot process video download request.");

                                    break;
                                }

                                // We got a valid URL, now check if it's a YouTube URL
                                // (This handles youtube.com and youtu.be)
                                if (messageLine.Contains("youtu", StringComparison.OrdinalIgnoreCase))
                                {
                                    string processName = "yt-dlp";
                                    string args        = $"-f bestvideo+bestaudio -o \"%(uploader)s [%(channel_id)s]/%(upload_date)s [%(id)s].%(ext)s\" --sponsorblock-mark all --sponsorblock-chapter-title \"%(category_names)l\" {messageLine}";

                                    Console.WriteLine($"Got a YouTube URL: {uri}. Executing command '{processName} {args}'");

                                    Process process = Process.Start(new ProcessStartInfo
                                    {
                                        FileName               = processName,
                                        Arguments              = args,
                                        UseShellExecute        = false,
                                        RedirectStandardOutput = true,
                                        CreateNoWindow         = true,
                                        WorkingDirectory       = "/data/"
                                    });

                                    // This is important to cause OutputDataReceived to be fired
                                    process.BeginOutputReadLine();

                                    Message        outputMessage   = default;
                                    List <string>  output          = new List <string>();
                                    string         lastLine        = string.Empty;
                                    DateTimeOffset lastMessageSent = DateTimeOffset.MinValue;
                                    process.OutputDataReceived += async(_, dataReceivedEventArgs) =>
                                    {
                                        string newLine = dataReceivedEventArgs.Data;

                                        // Don't print blank lines
                                        if (string.IsNullOrWhiteSpace(newLine))
                                        {
                                            return;
                                        }

                                        Console.WriteLine(newLine);

                                        // If the last line contains a % and this line contains a %, replace the last line with this one.
                                        if (lastLine.Contains('%') && newLine.Contains('%'))
                                        {
                                            output.Remove(lastLine);
                                        }

                                        output.Add(newLine);

                                        lastLine = newLine;

                                        // Don't send messages more often than 1/s
                                        // Do this skip after we've updated the output so that we get all of it by the end, even if we don't send it.
                                        if (DateTimeOffset.Now - lastMessageSent < TimeSpan.FromSeconds(1))
                                        {
                                            return;
                                        }

                                        lastMessageSent = DateTimeOffset.Now;

                                        if (outputMessage is null)
                                        {
                                            outputMessage = await _botClient.SendTextMessageAsync(
                                                chatId : _chatId,
                                                text : string.Join(Environment.NewLine, output));
                                        }
                                        // Only edit the message if the text has changed
                                        else
                                        {
                                            try
                                            {
                                                await _botClient.EditMessageTextAsync(
                                                    chatId : _chatId,
                                                    messageId : outputMessage.MessageId,
                                                    text : string.Join(Environment.NewLine, output));
                                            }
                                            catch
                                            {
                                                // Don't let this any exceptions kill us.
                                                // We could get MessageIsNotModifiedException if we try to edit with the same text.
                                                // We could get HttpRequestException if we try to edit in too rapid succession.
                                            }
                                        }
                                    };

                                    process.WaitForExit();

                                    // After the process exits, make sure we actually wrote the whole output
                                    while (true)
                                    {
                                        try
                                        {
                                            await _botClient.EditMessageTextAsync(
                                                chatId : _chatId,
                                                messageId : outputMessage.MessageId,
                                                text : string.Join(Environment.NewLine, output));

                                            break;
                                        }
                                        catch (HttpRequestException)
                                        {
                                        }
                                        catch (MessageIsNotModifiedException)
                                        {
                                            // This means we were able to successfully write the final message.
                                            break;
                                        }
                                    }

                                    Console.WriteLine($"yt-dlp return value is {process.ExitCode}");

                                    if (process.ExitCode == 0)
                                    {
                                        outputMessage = await _botClient.SendTextMessageAsync(
                                            chatId : _chatId,
                                            text : "Video downloaded successfully!");
                                    }
                                    else
                                    {
                                        outputMessage = await _botClient.SendTextMessageAsync(
                                            chatId : _chatId,
                                            text : "Video download failed.");
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                await _botClient.SendTextMessageAsync(
                    chatId : _chatId,
                    text : "There was an error processing your request.");

                Console.WriteLine(string.Join(Environment.NewLine,
                                              "Processing Error.",
                                              $"Message:  {messageText}",
                                              $"Sender name / ID:  {e.Message.Chat.Username} / {chatId}",
                                              "",
                                              ex.ToString()));
            }
        }