diff --git a/.idea/.idea.TransitUI/.idea/.gitignore b/.idea/.idea.TransitUI/.idea/.gitignore
new file mode 100644
index 0000000..37d22b8
--- /dev/null
+++ b/.idea/.idea.TransitUI/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/modules.xml
+/contentModel.xml
+/projectSettingsUpdater.xml
+/.idea.TransitUI.iml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.idea.TransitUI/.idea/indexLayout.xml b/.idea/.idea.TransitUI/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/.idea/.idea.TransitUI/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.TransitUI/.idea/vcs.xml b/.idea/.idea.TransitUI/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/.idea.TransitUI/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Animator/GifCreator.cs b/Animator/GifCreator.cs
index f2abe6a..37e5c60 100644
--- a/Animator/GifCreator.cs
+++ b/Animator/GifCreator.cs
@@ -5,37 +5,38 @@ namespace Animator;
public static class GifCreator
{
- private static Random random = new Random();
- public static string RandomString(int length)
+ private static Random Random { get; } = new();
+
+ private static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars, length)
- .Select(s => s[random.Next(s.Length)]).ToArray());
+ .Select(s => s[Random.Next(s.Length)]).ToArray());
}
- public static Stream ConvertImageStreamsToGifStream(IEnumerable streams)
+ public static async Task ConvertImageStreamsToGifStream(IEnumerable> streams)
{
- string randomPathPart = RandomString(64);
- string rootPath = $"/tmp/pngs/{randomPathPart}";
+ var randomPathPart = RandomString(64);
+ var rootPath = $"/tmp/pngs/{randomPathPart}";
Directory.CreateDirectory(rootPath);
- for (int i = 0; i < streams.Count(); i++)
+ var streamList = streams.ToList();
+ for (var i = 0; i < streamList.Count; i++)
{
- using FileStream fs = File.Create($"{rootPath}/{i.ToString().PadLeft(8, '0')}.png");
- streams.ElementAt(i).CopyTo(fs);
+ await using var fs = File.Create($"{rootPath}/{i.ToString().PadLeft(8, '0')}.png");
+ await (await streamList.ElementAt(i)).CopyToAsync(fs);
}
ProcessStartInfo psi = new()
{
FileName = "convert",
Arguments = $"-delay 500 -loop 0 {rootPath}/*.png {rootPath}/out.gif"
};
- Process? process = Process.Start(psi);
+ var process = Process.Start(psi);
if (process is null)
{
throw new Exception($"Process not started");
}
- process.WaitForExit();
- // return $"{rootPath}/out.gif";
- FileStream gifFS = File.OpenRead($"{rootPath}/out.gif");
- return gifFS;
+ await process.WaitForExitAsync();
+ var gifFs = File.OpenRead($"{rootPath}/out.gif");
+ return gifFs;
}
}
diff --git a/RealTimeDataCrawler/Vip/Crawler.cs b/RealTimeDataCrawler/Vip/Crawler.cs
index 2d23b31..00bf11f 100644
--- a/RealTimeDataCrawler/Vip/Crawler.cs
+++ b/RealTimeDataCrawler/Vip/Crawler.cs
@@ -6,16 +6,16 @@ namespace RealTimeDataCrawler.Vip;
public static class Crawler
{
private static string RequestUri { get; } = @"https://www.swp-potsdam.de/internetservice/services/passageInfo/stopPassages/stop?stop=%STOP_ID%&mode=departure&language=de";
-
- public static Station GetFromWeb(int stopId = 61)
+
+ public static async Task GetFromWeb(int stopId = 61)
{
- string jsonString = GetJsonSource(stopId);
+ var jsonString = await GetJsonSource(stopId);
return Station.GetFromJsonString(jsonString);
}
- public static string GetJsonSource(int stopId = 61)
+ public static async Task GetJsonSource(int stopId = 61)
{
- using WebClient wc = new WebClient();
- return wc.DownloadString(RequestUri.Replace("%STOP_ID%", stopId.ToString()));
+ using HttpClient httpClient = new();
+ return await httpClient.GetStringAsync(RequestUri.Replace("%STOP_ID%", stopId.ToString()));
}
}
diff --git a/RealTimeModels/RealTimeModels.csproj b/RealTimeModels/RealTimeModels.csproj
index eb2460e..ddc5e70 100644
--- a/RealTimeModels/RealTimeModels.csproj
+++ b/RealTimeModels/RealTimeModels.csproj
@@ -6,4 +6,9 @@
enable
+
+
+
+
+
diff --git a/RealTimeModels/Vip/Station.cs b/RealTimeModels/Vip/Station.cs
index 34b4b24..4a09694 100644
--- a/RealTimeModels/Vip/Station.cs
+++ b/RealTimeModels/Vip/Station.cs
@@ -33,13 +33,18 @@ internal Station(PredictionJsonObject json)
Actual = json.actual.Select((actual) => new RealTimeEntry(new TimeSpan(0, 0, actual.actualRelativeTime), actual.actualTime is null ? (DateTime?)null : DateTime.Parse(actual.actualTime), actual.alerts?.Select((alert) => new Alert(alert)).ToList(), actual.direction, actual.mixedTime, Convert.ToInt64(actual.passageid), actual.patternText, DateTime.Parse(actual.plannedTime), Routes.Where((route) => route.Id == Convert.ToInt64(actual.routeId)).First(), actual.status, Convert.ToInt64(actual.tripId), null, actual.vias)).ToList();
}
// Methods
- public static Station GetFromJsonString(string jsonString)
+ public static Station GetFromJsonString(string jsonString, bool catalogue = true)
{
var json = JsonSerializer.Deserialize(jsonString);
if (json is null)
throw new ArgumentNullException(nameof(json), $"JsonSerializer returned null.");
- return new Station(json);
+ Station station = new(json);
+ if (catalogue)
+ {
+ }
+
+ return station;
}
public override string ToString()
{
diff --git a/RealTimeModels/Vip/VipContext.cs b/RealTimeModels/Vip/VipContext.cs
new file mode 100644
index 0000000..2f28b62
--- /dev/null
+++ b/RealTimeModels/Vip/VipContext.cs
@@ -0,0 +1,35 @@
+using Microsoft.EntityFrameworkCore;
+
+namespace RealTimeModels.Vip;
+
+public class VipContext : DbContext
+{
+ public DbSet Stations => Set();
+ public DbSet RealTimeEntries => Set();
+ public DbSet Alerts => Set();
+ public DbSet Routes => Set();
+ public DbSet Vehicles => Set();
+
+ private string? ConnectionString { get; set; }
+
+ public VipContext(string? connectionString = null)
+ {
+ ConnectionString = connectionString;
+ }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ var stationEntity = modelBuilder.Entity();
+ stationEntity
+ .HasMany(station => station.Actual)
+ .WithOne();
+ stationEntity
+ }
+
+ protected override void OnConfiguring(DbContextOptionsBuilder options)
+ {
+ options.UseNpgsql(ConnectionString ?? "Host=127.0.0.1;Database=transit_vip;Username=postgres;Password=mysecretpassword");
+ options.EnableDetailedErrors();
+ options.EnableSensitiveDataLogging();
+ }
+}
diff --git a/RealTimeToDotMatrix/DotMatrixPicture.cs b/RealTimeToDotMatrix/DotMatrixPicture.cs
index daa82ff..7f7d95f 100644
--- a/RealTimeToDotMatrix/DotMatrixPicture.cs
+++ b/RealTimeToDotMatrix/DotMatrixPicture.cs
@@ -44,13 +44,16 @@ public string BuildUri()
//requestUri = HttpUtility.UrlEncode(requestUri);
return requestUri;
}
- public Stream GetPicture(string? requestUri = null)
+ public async Task GetPicture(string? requestUri = null)
{
requestUri ??= BuildUri();
string referer = @"http://avtanski.net/projects/lcd/";
- HttpWebRequest request = WebRequest.CreateHttp(requestUri);
- request.Referer = referer;
- HttpWebResponse response = (HttpWebResponse)request.GetResponse();
- return response.GetResponseStream();
+ // HttpWebRequest request = WebRequest.CreateHttp(requestUri);
+ using HttpClient httpClient = new();
+ httpClient.DefaultRequestHeaders.Referrer = new Uri(referer);
+ return await httpClient.GetStreamAsync(requestUri);
+ // request.Referer = referer;
+ // HttpWebResponse response = (HttpWebResponse)request.GetResponse();
+ // return response.GetResponseStream();
}
}
diff --git a/RealTimeToDotMatrix/Vip/RealTimeToDotMatrix.cs b/RealTimeToDotMatrix/Vip/RealTimeToDotMatrix.cs
index b8016fa..76e24cd 100644
--- a/RealTimeToDotMatrix/Vip/RealTimeToDotMatrix.cs
+++ b/RealTimeToDotMatrix/Vip/RealTimeToDotMatrix.cs
@@ -43,7 +43,7 @@ private static void AddAlertToList(string message, List lines, int cols)
message = message.Trim();
lines.Add($"{message}");
}
-
+
private static void AddHeaderToPage(Station station, List emptyPage, int cols, int gap)
{
emptyPage.Add(station.StationName);
@@ -163,14 +163,14 @@ private static (string[] messages, (uint cols, uint rows) dimensions) GenerateTa
return (pages.Select(page => string.Join(Environment.NewLine, page)).ToArray(), ((uint)targetCols, MaximalRows));
}
- public static Stream Convert(Station station)
+ public static async Task Convert(Station station)
{
var (messages, dimensions) = GenerateTarget(station);
var pictures = messages.Select(message => new DotMatrixPicture(message, RgbColor.Border, RgbColor.Background, RgbColor.InactivePixels, RgbColor.ActivePixels, dimensions));
// DotMatrixPicture picture = new DotMatrixPicture(message, RgbColor.Border, RgbColor.Background, RgbColor.InactivePixels, RgbColor.ActivePixels, dimensions);
- Stream gif = Animator.GifCreator.ConvertImageStreamsToGifStream(pictures.Select(picture => picture.GetPicture()));
+ Stream gif = await Animator.GifCreator.ConvertImageStreamsToGifStream(pictures.Select(picture => picture.GetPicture()));
return gif;
-
+
// return pictures.ElementAt(0).GetPicture();
//return string.Join($"{Environment.NewLine}NEW_LINE{Environment.NewLine}", messages);
}
diff --git a/TransitUI.sln b/TransitUI.sln
index 6a07dd3..cf10197 100644
--- a/TransitUI.sln
+++ b/TransitUI.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-#
+#
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TransitWeb", "TransitWeb\TransitWeb.csproj", "{DA1B73A1-9B61-4C62-9EB4-B4A3FF6980C7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RealTimeDataCrawler", "RealTimeDataCrawler\RealTimeDataCrawler.csproj", "{4BC68B1E-F133-4C78-81FA-B07B1EE4E614}"
diff --git a/TransitWeb/Controllers/WebApi/TransitController.cs b/TransitWeb/Controllers/WebApi/TransitController.cs
index adf050a..197a7d2 100644
--- a/TransitWeb/Controllers/WebApi/TransitController.cs
+++ b/TransitWeb/Controllers/WebApi/TransitController.cs
@@ -12,11 +12,11 @@ namespace TransitWeb.Controllers.WebApi;
public class TransitController : Controller
{
[HttpGet("vip/{id}")]
- public IActionResult CheckIfStationExists(int id)
+ public async Task CheckIfStationExists(int id)
{
try
{
- Crawler.GetFromWeb(id);
+ await Crawler.GetFromWeb(id);
return Ok();
}
catch
@@ -25,12 +25,12 @@ public IActionResult CheckIfStationExists(int id)
}
}
[HttpGet("vip/{id}/dotmatrix")]
- public IActionResult GetDotMatrixById(int id)
+ public async Task GetDotMatrixById(int id)
{
try
{
- Station station = Crawler.GetFromWeb(id);
- Stream stream = RealTimeToDotMatrix.Vip.RealTimeToDotMatrix.Convert(station);
+ var station = await Crawler.GetFromWeb(id);
+ var stream = await RealTimeToDotMatrix.Vip.RealTimeToDotMatrix.Convert(station);
// FileStream gif = System.IO.File.OpenRead(gifPath);
return File(stream, "image/gif");
// return Content(stream);
@@ -39,37 +39,37 @@ public IActionResult GetDotMatrixById(int id)
catch (System.Net.WebException ex)
{
ApiErrorViewModel error = new(ex);
- string json = JsonSerializer.Serialize(error);
+ var json = JsonSerializer.Serialize(error);
return NotFound(json);
}
}
[HttpGet("vip/{id}/info")]
- public IActionResult GetInfoById(int id)
+ public async Task GetInfoById(int id)
{
try
{
- Station station = Crawler.GetFromWeb(id);
+ Station station = await Crawler.GetFromWeb(id);
return Content(station.ToString());
}
catch (System.Net.WebException ex)
{
- ApiErrorViewModel error = new ApiErrorViewModel(ex);
- string json = JsonSerializer.Serialize(error);
+ ApiErrorViewModel error = new(ex);
+ var json = JsonSerializer.Serialize(error);
return NotFound(json);
}
}
[HttpGet("vip/{id}/json")]
- public IActionResult GetJsonSourceById(int id)
+ public async Task GetJsonSourceById(int id)
{
try
{
- string jsonSource = Crawler.GetJsonSource(id);
+ var jsonSource = await Crawler.GetJsonSource(id);
return Content(jsonSource, "application/json");
}
catch (System.Net.WebException ex)
{
- ApiErrorViewModel error = new ApiErrorViewModel(ex);
- string json = JsonSerializer.Serialize(error);
+ ApiErrorViewModel error = new(ex);
+ var json = JsonSerializer.Serialize(error);
return NotFound(json);
}
}
diff --git a/TransitWeb/Dockerfile b/TransitWeb/Dockerfile
index c8a4484..d113536 100644
--- a/TransitWeb/Dockerfile
+++ b/TransitWeb/Dockerfile
@@ -2,6 +2,7 @@
WORKDIR /app
EXPOSE 80
EXPOSE 443
+EXPOSE 3654
# Install ImageMagick (see https://askubuntu.com/a/648245)
RUN apt update
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..999e1a8
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,27 @@
+version: '3'
+services:
+ db:
+ image: postgres:13
+ container_name: transit_postgres
+ volumes:
+ - transit_db:/var/lib/postgresql/data
+ ports:
+ - "127.0.0.1:5432:5432"
+ environment:
+ - POSTGRES_USER=postgres
+ - POSTGRES_PASSWORD=mysecretpassword
+ - POSTGRES_DB=transit_vip
+ app:
+ build:
+ context: .
+ dockerfile: TransitWeb/Dockerfile
+ depends_on:
+ - db
+ container_name: transit-web
+ ports:
+ - "127.0.0.1:3654:80"
+ expose:
+ - 3654
+
+volumes:
+ transit_db: