public void GivenSimpleArguments_FindReleases_RetrievesTagsAndReleases() { const string repoOwner = "foo"; const string repoName = "bar"; var repoMock = new Mock <IRepositoriesClient>(); clientMock.Setup(client => client.Repository).Returns(repoMock.Object).Verifiable(); var releasesMock = new Mock <IReleasesClient>(); repoMock.SetupGet(repo => repo.Release).Returns(releasesMock.Object).Verifiable(); releasesMock.Setup(releases => releases.GetAll(repoOwner, repoName)) .Returns(Task.FromResult <IReadOnlyList <Release> >(new List <Release>())) .Verifiable(); var argBuilder = new ArgumentsBuilder(); argBuilder.AddMatcher(".*"); argBuilder.SetOwner(repoOwner); argBuilder.SetProject(repoName); var results = cut.FindReleases(argBuilder.Build(), new ConstantValueFilter(true)); Mock.VerifyAll(clientMock, repoMock, releasesMock); Assert.AreEqual(0, results.Count); }
internal static async Task ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return; } var builder = new ArgumentsBuilder(); configure(builder); var args = builder.Build(); Logger.WriteLine($"{ToolPath} {args}", LogLevel.Normal); var stdOutBuffer = new StringBuilder(); var stdOut = PipeTarget.Merge(PipeTarget.ToStringBuilder(stdOutBuffer), PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Verbose))); var stdError = PipeTarget.ToDelegate(l => { if (string.IsNullOrEmpty(l)) { return; } // Suppress errors Logger.WriteWarning(l); }); var result = await Cli.Wrap(ToolPath) .WithArguments(args) .WithValidation(CommandResultValidation.None) .WithStandardErrorPipe(stdError) .WithStandardOutputPipe(stdOut) .ExecuteAsync(cancellationToken); }
internal static async Task <string> ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken) { var toolPath = ToolPath; ThrowIfNull(toolPath, nameof(Emulator)); var builder = new ArgumentsBuilder(); configure(builder); var args = builder.Build(); Logger.WriteLine($"{toolPath} {args}", LogLevel.Normal); var stdErrBuffer = new StringBuilder(); var stdOutBuffer = new StringBuilder(); var stdOut = PipeTarget.Merge(PipeTarget.ToStringBuilder(stdOutBuffer), PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Verbose))); await Cli.Wrap(toolPath) .WithArguments(args) .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer)) .WithStandardOutputPipe(stdOut) .ExecuteAsync(cancellationToken); var stdErr = stdErrBuffer.ToString().Trim(); if (!string.IsNullOrEmpty(stdErr)) { throw new Exception(stdErr); } return(stdOutBuffer.ToString().Trim()); }
/// <summary> /// Creates a copy of this command, setting the arguments to the value configured by the specified delegate. /// </summary> public Command WithArguments(Action <ArgumentsBuilder> configure) { var builder = new ArgumentsBuilder(); configure(builder); return(WithArguments(builder.Build())); }
public static Task Build(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken) { var builder = new ArgumentsBuilder() .Add("build"); configure(builder); return(Execute(builder.Build(), LogLevel.Detailed, cancellationToken)); }
protected string BuildArguments() { var credentials = this.CreateCredentials(); var favorite = this.CreateFavorite(); favorite.Setup(p => p.ProtocolProperties).Returns(this.Options); var builder = new ArgumentsBuilder(credentials.Object, favorite.Object); return(builder.Build()); }
private static async Task <string> ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken, PipeSource stdInput = null) { var toolPath = ToolPath; ThrowIfNull(toolPath, nameof(AvdManager)); var builder = new ArgumentsBuilder(); configure(builder); var args = builder.Build(); Logger.WriteLine($"{toolPath} {args}", LogLevel.Normal); var errorBuffer = new List <string>(); var stdOutBuffer = new StringBuilder(); var stdOut = PipeTarget.Merge(PipeTarget.ToStringBuilder(stdOutBuffer), PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Verbose))); var stdErr = PipeTarget.ToDelegate(l => { if (string.IsNullOrEmpty(l)) { return; } else if (l.Contains("Warning: ")) { Logger.WriteWarning(l); } else { errorBuffer.Add(l); } }); var cmd = Cli.Wrap(toolPath) .WithArguments(args) .WithValidation(CommandResultValidation.None) .WithStandardErrorPipe(stdErr) .WithStandardOutputPipe(stdOut); if (stdInput != null) { cmd = cmd.WithStandardInputPipe(stdInput); } await cmd.ExecuteAsync(cancellationToken); if (errorBuffer.Any()) { throw new Exception(string.Join(Environment.NewLine, errorBuffer)); } return(stdOutBuffer.ToString().Trim()); }
internal static async Task <string> ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(null); } var toolPath = ToolPath; var builder = new ArgumentsBuilder(); configure(builder); var args = builder.Build(); Logger.WriteLine($"{toolPath} {args}", LogLevel.Normal); var stdErrBuffer = new StringBuilder(); var stdOutBuffer = new StringBuilder(); var stdOut = PipeTarget.Merge(PipeTarget.ToStringBuilder(stdOutBuffer), PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Verbose))); var result = await Cli.Wrap(toolPath) .WithArguments(args) .WithValidation(CommandResultValidation.None) .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer)) .WithStandardOutputPipe(stdOut) .ExecuteAsync(cancellationToken); var stdErr = stdErrBuffer.ToString().Trim(); if (!string.IsNullOrEmpty(stdErr)) { if (stdErr.Split('\n').Select(x => x.Trim()).All(x => x.StartsWith("Warning:", StringComparison.InvariantCultureIgnoreCase))) { Logger.WriteWarning(stdErr); } else { throw new Exception(stdErr); } } return(stdOutBuffer.ToString().Trim()); }
/// <summary> /// Parse arguments accordinating to options. /// </summary> /// <param name="args"> /// Input arguments, full form or abbreviation form. /// </param> /// <returns> /// A parsing result <see cref="ArgsParsingResult"/>. /// </returns> /// <exception cref="ArgumentNullException"> /// The args is null. /// </exception> /// <exception cref="ArgumentException"> /// The args has null value. /// </exception> public ArgsParsingResult Parse(IList <string> args) { if (args == null) { throw new ArgumentNullException(nameof(args)); } if (args.Any(e => e == null)) { throw new ArgumentException(nameof(args)); } try { return(new ArgsParsingResult(argumentsBuilder.Build(args))); } catch (ParsingException e) { return(new ArgsParsingResult(new ArgsParsingError(e.Code, e.Trigger))); } }
private async Task <Unit> ExtractSubtitles( TvContext dbContext, int mediaItemId, string ffmpegPath, CancellationToken cancellationToken) { Option <MediaItem> maybeMediaItem = await dbContext.MediaItems .Include(mi => (mi as Episode).MediaVersions) .ThenInclude(mv => mv.MediaFiles) .Include(mi => (mi as Episode).MediaVersions) .ThenInclude(mv => mv.Streams) .Include(mi => (mi as Episode).EpisodeMetadata) .ThenInclude(em => em.Subtitles) .Include(mi => (mi as Movie).MediaVersions) .ThenInclude(mv => mv.MediaFiles) .Include(mi => (mi as Movie).MediaVersions) .ThenInclude(mv => mv.Streams) .Include(mi => (mi as Movie).MovieMetadata) .ThenInclude(em => em.Subtitles) .Include(mi => (mi as MusicVideo).MediaVersions) .ThenInclude(mv => mv.MediaFiles) .Include(mi => (mi as MusicVideo).MediaVersions) .ThenInclude(mv => mv.Streams) .Include(mi => (mi as MusicVideo).MusicVideoMetadata) .ThenInclude(em => em.Subtitles) .Include(mi => (mi as OtherVideo).MediaVersions) .ThenInclude(mv => mv.MediaFiles) .Include(mi => (mi as OtherVideo).MediaVersions) .ThenInclude(mv => mv.Streams) .Include(mi => (mi as OtherVideo).OtherVideoMetadata) .ThenInclude(em => em.Subtitles) .SelectOneAsync(e => e.Id, e => e.Id == mediaItemId); foreach (MediaItem mediaItem in maybeMediaItem) { foreach (List <Subtitle> allSubtitles in GetSubtitles(mediaItem)) { var subtitlesToExtract = new List <SubtitleToExtract>(); // find each subtitle that needs extraction IEnumerable <Subtitle> subtitles = allSubtitles .Filter( s => s.SubtitleKind == SubtitleKind.Embedded && s.IsExtracted == false && s.Codec != "hdmv_pgs_subtitle" && s.Codec != "dvd_subtitle"); // find cache paths for each subtitle foreach (Subtitle subtitle in subtitles) { Option <string> maybePath = GetRelativeOutputPath(mediaItem.Id, subtitle); foreach (string path in maybePath) { subtitlesToExtract.Add(new SubtitleToExtract(subtitle, path)); } } string mediaItemPath = await GetMediaItemPath(mediaItem); ArgumentsBuilder args = new ArgumentsBuilder() .Add("-nostdin") .Add("-hide_banner") .Add("-i").Add(mediaItemPath); foreach (SubtitleToExtract subtitle in subtitlesToExtract) { string fullOutputPath = Path.Combine(FileSystemLayout.SubtitleCacheFolder, subtitle.OutputPath); Directory.CreateDirectory(Path.GetDirectoryName(fullOutputPath)); if (_localFileSystem.FileExists(fullOutputPath)) { File.Delete(fullOutputPath); } args.Add("-map").Add($"0:{subtitle.Subtitle.StreamIndex}").Add("-c").Add("copy") .Add(fullOutputPath); } BufferedCommandResult result = await Cli.Wrap(ffmpegPath) .WithArguments(args.Build()) .WithValidation(CommandResultValidation.None) .ExecuteBufferedAsync(cancellationToken); if (result.ExitCode == 0) { foreach (SubtitleToExtract subtitle in subtitlesToExtract) { subtitle.Subtitle.IsExtracted = true; subtitle.Subtitle.Path = subtitle.OutputPath; } int count = await dbContext.SaveChangesAsync(cancellationToken); _logger.LogDebug("Successfully extracted {Count} subtitles", count); } else { _logger.LogError("Failed to extract subtitles. {Error}", result.StandardError); } } } return(Unit.Default); }
private async ValueTask ProcessAsync( string filePath, Container container, IReadOnlyList <StreamInput> streamInputs, IReadOnlyList <SubtitleInput> subtitleInputs, IProgress <double>?progress = null, CancellationToken cancellationToken = default) { var arguments = new ArgumentsBuilder(); // Stream inputs foreach (var streamInput in streamInputs) { arguments.Add("-i").Add(streamInput.FilePath); } // Subtitle inputs foreach (var subtitleInput in subtitleInputs) { arguments.Add("-i").Add(subtitleInput.FilePath); } // Format arguments.Add("-f").Add(container.Name); // Preset arguments.Add("-preset").Add(_preset); // Mapping for (var i = 0; i < streamInputs.Count + subtitleInputs.Count; i++) { arguments.Add("-map").Add(i); } // Avoid transcoding if possible if (streamInputs.All(s => s.Info.Container == container)) { arguments .Add("-c:a").Add("copy") .Add("-c:v").Add("copy"); } // MP4: specify subtitle codec manually, otherwise they're not injected if (container == Container.Mp4 && subtitleInputs.Any()) { arguments.Add("-c:s").Add("mov_text"); } // MP3: specify bitrate manually, otherwise the metadata will contain wrong duration // https://superuser.com/questions/892996/ffmpeg-is-doubling-audio-length-when-extracting-from-video if (container == Container.Mp3) { arguments.Add("-b:a").Add("165k"); } // Inject language metadata for subtitles for (var i = 0; i < subtitleInputs.Count; i++) { arguments .Add($"-metadata:s:s:{i}") .Add($"language={subtitleInputs[i].Info.Language.Code}") .Add($"-metadata:s:s:{i}") .Add($"title={subtitleInputs[i].Info.Language.Name}"); } // Misc settings arguments .Add("-threads").Add(Environment.ProcessorCount) .Add("-nostdin") .Add("-y"); // Output arguments.Add(filePath); // Run FFmpeg await _ffmpeg.ExecuteAsync(arguments.Build(), progress, cancellationToken); }
/// <summary> /// Provides a convenient way to list /// and modify projects in a solution /// file. /// </summary> protected virtual void SlnAction(string solution, IEnumerable <string> projects, ArgumentsBuilder builder) { if (projects.Any()) { CliWrap.Command command = Cli.Wrap("dotnet").WithWorkingDirectory(Path.GetDirectoryName(solution)) .WithArguments(args => args.Add("sln").Add(solution).Add(builder.Build(), false)); BufferedCommandResult result = command.ExecuteBufferedAsync().GetAwaiter().GetResult(); if (!string.IsNullOrWhiteSpace(result.StandardOutput)) { MessageProvider.Clear(); MessageProvider.AddMessage(result.StandardOutput, MessageCategory.ME); } if (!string.IsNullOrWhiteSpace(result.StandardError)) { MessageProvider.Clear(); MessageProvider.AddMessage(result.StandardError, MessageCategory.ER); } } }
public ActionResult Index() { dynamic result = null; ViewBag.TempDirectory = null; var script = routeParser.GetScript(RouteData); if (script == null) { return(BadRequest()); } var interpreter = interpretersManager.GetInterpreter(script.Interpreter); if (interpreter == null) { return(BadRequest()); } if (Request.Method == "POST") { // We will save posted data into a temp directory script.CopyToTemp = true; } if (script.CopyToTemp) { ViewBag.TempDirectory = Utilities.CreateTempDirectory(interpretersManager.WorkingDirectory); Utilities.CopyFiles(script.Location, ViewBag.TempDirectory); } if (Request.Method == "POST") { string path = Path.Combine(ViewBag.TempDirectory, "input.json"); Utilities.SavePostRequestData(this.Request, path); } string arguments = ArgumentsBuilder.Build(interpreter, script, this.Request); string workDirectory = script.CopyToTemp ? ViewBag.TempDirectory : script.Location; var process = ProcessExt.Create(); process.NoOutput = script.NoOutput; process.StartInfo.FileName = interpreter.Path; process.StartInfo.Arguments = arguments; process.StartInfo.WorkingDirectory = workDirectory; process.StartAndWait(); var outputFile = new OutputFile(script); if (outputFile.IsDefined) { string path = Path.Combine(workDirectory, outputFile.FileName); logger.LogInformation($"Output file: \"{path}\""); if (!System.IO.File.Exists(path)) { logger.LogError($"Output file \"{outputFile.FileName}\" not found"); return(BadRequest()); } if (outputFile.IsJson) { result = outputFile.ReadJson(path); } else { return(outputFile.ReadFileStream(path)); } } return(Json(new { Output = process.Output, Result = result }, new JsonSerializerSettings { Formatting = Formatting.Indented })); }