diff --git a/Controllers/ValuesController.cs b/Controllers/ValuesController.cs new file mode 100644 index 0000000..88fcb3d --- /dev/null +++ b/Controllers/ValuesController.cs @@ -0,0 +1,46 @@ +using System.IO; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace tv7playlist.Controllers +{ + [Route("api/playlist")] + [ApiController] + public class PlayListTV7Controller : ControllerBase + { + private const string Tv7OriginUrl = "https://api.init7.net/tvchannels.m3u"; + private const string UdpxyRootUrl = "http://tv1.haefelfinger.net:4022/udp"; + + private static readonly Regex MulticastRegex = new Regex(@"(udp\:\/\/@)([0-9.:]+)", + RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase); + + [HttpGet] + public async Task Get() + { + var httpClient = new HttpClient(); + var tv7Response = await httpClient.GetAsync(Tv7OriginUrl); + + + var outStream = new MemoryStream(); + var outWriter = new StreamWriter(outStream); + + using (var tv7ReadStream = await tv7Response.Content.ReadAsStreamAsync()) + using (var reader = new StreamReader(tv7ReadStream)) + { + while (!reader.EndOfStream) + { + var line = await reader.ReadLineAsync(); + line = MulticastRegex.Replace(line, $"{UdpxyRootUrl}/$2/"); + outWriter.WriteLine(line); + } + + await outWriter.FlushAsync(); + } + + outStream.Seek(0, SeekOrigin.Begin); + return new FileStreamResult(outStream, "audio/mpegurl") {FileDownloadName = "PlaylistTV7udpxy.m3u"}; + } + } +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e60725f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM microsoft/dotnet:sdk AS build-env +WORKDIR /app + +# Copy csproj and restore as distinct layers +COPY *.csproj ./ +RUN dotnet restore + +# Copy everything else and build +COPY . ./ +RUN dotnet publish -c Release -o out + +# Build runtime image +FROM microsoft/dotnet:aspnetcore-runtime +WORKDIR /app +COPY --from=build-env /app/out . +ENTRYPOINT ["dotnet", "aspnetapp.dll"] diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..8a26866 --- /dev/null +++ b/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace tv7playlist +{ + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup(); + } +} diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 0000000..78a6815 --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:18699", + "sslPort": 44374 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "api/values", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "tv7playlist": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "api/values", + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/Startup.cs b/Startup.cs new file mode 100644 index 0000000..8044b8d --- /dev/null +++ b/Startup.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.HttpsPolicy; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace tv7playlist +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseMvc(); + } + } +} diff --git a/appsettings.Development.json b/appsettings.Development.json new file mode 100644 index 0000000..a2880cb --- /dev/null +++ b/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..7376aad --- /dev/null +++ b/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/tv7playlist.csproj b/tv7playlist.csproj new file mode 100644 index 0000000..e7a1cb8 --- /dev/null +++ b/tv7playlist.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp2.1 + + + + + + + + + + + +