Commit 967a535c authored by Ing. Jiří Fryč's avatar Ing. Jiří Fryč

new version.

parent 8970e319
......@@ -27,12 +27,13 @@ namespace KazetaNode
public override void Execute(AbstractLibraryInstance instance, CommandInput input)
{
ConsoleP.AppendLine("Starting network discovery protocol... (Timeout 5s)");
Postman.SendToChannel(Channels.Discovery, new DiscoveryMessage()).ExpectMultiple().Timeout(5_000)
.During(msg=> {
ConsoleP.AppendLine("Disovered node '" + msg.Sender + "':");
})
.Then(msgs=>{
foreach(var msg in msgs)
{
ConsoleP.AppendLine("Node: ");
}
ConsoleP.AppendLine("Network discovery protocol ended.");
return true;
}).Send();
}
......
......@@ -14,11 +14,13 @@ namespace KazetaNode.Coms
class Postman
{
public delegate bool ThenAction(List<IMessage> messages);
public delegate void DuringAction(IMessage message);
public delegate bool TimeoutAction();
public long TimeoutMax { get; private set; }
public long TimeStart { get; set; } = -1;
public TimeoutAction TimeoutAc { get; private set; }
public ThenAction ThenAc { get; private set; } = null;
public DuringAction DuringAc { get; private set; } = null;
public bool Multiple { get; private set; } = false;
public string Exchange { get; private set; }
......@@ -69,6 +71,13 @@ namespace KazetaNode.Coms
this.ThenAc = action;
return this;
}
public Postman During(DuringAction action)
{
if (TimeStart != -1)
throw new Exception("Already started");
this.DuringAc = action;
return this;
}
public Postman ExpectSingle()
{
if (TimeStart != -1)
......
......@@ -68,7 +68,8 @@ namespace KazetaNode.Coms
public static void DiscoveryReply(IMessage msg)
{
Program.Network.channel.BasicPublish("", QUEUE_PREFIX+msg.Sender, null, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new DiscoveryReplyMessage() { ResponseId = msg.MessageId })));
Program.Network.channel.BasicPublish("", QUEUE_PREFIX+msg.Sender, null, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new DiscoveryReplyMessage() { ResponseId = msg.MessageId,Sender=Program.NodeId })));
}
public void Connect()
{
......@@ -93,6 +94,7 @@ namespace KazetaNode.Coms
Postman p = Postmans[i];
if (p.Message.MessageId.Equals(msg.ResponseId))
{
p.DuringAc?.Invoke(msg);
p.Responses.Add(msg);
if (!p.Multiple)
{
......
......@@ -14,6 +14,11 @@ namespace KazetaNode.Helpers
Console.WriteLine(str);
Console.Write("kazeta@" + Program.NodeId + ": ");
}
public static int ToInt32(this string str)
{
return Int32.Parse(str);
}
public static string GenerateRandomString(this string str,int size)
{
var stringChars = new char[size];
......
......@@ -25,7 +25,6 @@
<ItemGroup>
<Folder Include="Libraries\BlackMagicVideoHub\" />
<Folder Include="Libraries\KosApi\" />
<Folder Include="Libraries\Visca\" />
</ItemGroup>
......@@ -33,15 +32,48 @@
<None Update="kazeta.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="kazeta.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\ffmpeg.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\ffplay.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\ffpresets\ffprobe.xsd">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\ffpresets\libvpx-1080p.ffpreset">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\ffpresets\libvpx-1080p50_60.ffpreset">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\ffpresets\libvpx-360p.ffpreset">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\ffpresets\libvpx-720p.ffpreset">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\ffpresets\libvpx-720p50_60.ffpreset">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\ffprobe.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\libx264-144.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\Processing.NDI.Lib.x64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Libraries\Ffmpeg\Processing.NDI.Lib.x86.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="rooms.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.106
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KazetaNode", "KazetaNode.csproj", "{547572FB-48B8-47C4-93B0-30EA2EB3725D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{547572FB-48B8-47C4-93B0-30EA2EB3725D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{547572FB-48B8-47C4-93B0-30EA2EB3725D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{547572FB-48B8-47C4-93B0-30EA2EB3725D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{547572FB-48B8-47C4-93B0-30EA2EB3725D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {71F36B1E-8013-42CA-B3AD-3626176F2B38}
EndGlobalSection
EndGlobal
......@@ -21,12 +21,13 @@ namespace KazetaNode.Libraries
public abstract Dictionary<string, Tuple<Type, ReceiveMessage>> Messages { get; }
private static List<AbstractLibrary> libraries =null;
public static List<AbstractLibrary> Initialize()
public static List<AbstractLibrary> Initialize(dynamic libraryConfig)
{
if(libraries==null)
libraries = new List<AbstractLibrary>
if (libraries == null)
libraries = new List<AbstractLibrary>
{
new Ffmpeg.Ffmpeg()
new Ffmpeg.Ffmpeg(),
new KosApi.KosApi(libraryConfig?["kosapi"])
};
return libraries;
}
......
......@@ -31,7 +31,7 @@ namespace KazetaNode.Libraries.Ffmpeg
public override string Id => throw new NotImplementedException();
public override List<Command> Commands => new List<Command>() { new CmdNdiFindSources() };
public override List<Command> Commands => new List<Command>() { new CmdNdiFindSources(), new CmdNdiTakeScreenshot(),new CmdNdiCapture() };
public override Dictionary<string, Tuple<Type, Network.ReceiveMessage>> Messages => throw new NotImplementedException();
......@@ -69,4 +69,22 @@ namespace KazetaNode.Libraries.Ffmpeg
ConsoleP.AppendLine(" - "+source.Id+" ("+source.Ip+")");
}
}
class CmdNdiTakeScreenshot : Command
{
public override string[] Aliases => new string[] { "ndi-screenshot" };
public override void Execute(AbstractLibraryInstance instance, CommandInput input)
{
throw new NotImplementedException();
}
}
class CmdNdiCapture : Command
{
public override string[] Aliases => new string[] { "ndi-capture" };
public override void Execute(AbstractLibraryInstance instance, CommandInput input)
{
throw new NotImplementedException();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace KazetaNode.Libraries.KosApi
{
class CmdKosApiRoomInfo : Command
{
public override string[] Aliases => new string[] { "kosapi-info-room" };
public override void Execute(AbstractLibraryInstance instance, CommandInput input)
{
throw new NotImplementedException();
}
}
class CmdKosApiCourseInfo : Command
{
public override string[] Aliases => new string[] { "kosapi-info-course" };
public override void Execute(AbstractLibraryInstance instance, CommandInput input)
{
throw new NotImplementedException();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using KazetaNode.Coms;
namespace KazetaNode.Libraries.KosApi
{
class KosApi : AbstractLibrary
{
public override string Id => "kosapi";
public override string Name => "KosApi";
public override string Version => "1.0";
public override List<Command> Commands => new List<Command>();
public override Dictionary<string, Tuple<Type, Network.ReceiveMessage>> Messages => throw new NotImplementedException();
protected internal RestEndpoint Endpoint { get; private set; }
public KosApi(dynamic config)
{
Endpoint = new RestEndpoint(config["clientid"], config["clientsecret"]);
}
public override AbstractLibraryInstance CreateCaptureInstance()
{
throw new NotImplementedException();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace KazetaNode.Libraries.KosApi
{
class KosCourse
{
public string Code { get; set; }
public string NameCs { get; set; }
public string NameEn { get; set; }
public string[] Teachers { get; set; }
public List<KosCourseParallel> Parallels { get; set; } = new List<KosCourseParallel>();
}
enum Parity { ODD,EVEN,BOTH}
enum ParallelType { Tutorial, Lecture, Laboratory}
class KosCourseParallel
{
public int Occupied { get; set; }
public int Capacity { get; set; }
public DayOfWeek Day { get; set; }
public int From { get; set; }
public int[] FromHM { get { return new int[] { From / 60, From % 60 }; } }
public int To { get; set; }
public int[] ToHM { get { return new int[] { To / 60, To % 60 }; } }
public Parity Parity { get; set; }
public ParallelType Type { get; set; }
public string RoomId { get; set; }
}
}
using KazetaNode.Helpers;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Web;
using System.Xml.Linq;
namespace KazetaNode.Libraries.KosApi
{
class RestEndpoint
{
HttpClient Client;
string ClientId, ClientSecret;
JObject Token;
long NextTokenGeneration = 0;
public RestEndpoint(string id,string secret)
{
ClientId = id;
ClientSecret = secret;
Client = new HttpClient
{
BaseAddress = new Uri("https://kosapi.feld.cvut.cz/api/3/")
};
Client.DefaultRequestHeaders.Accept.Clear();
Client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/xml"));
GetTokenAsync().Wait();
CourseInfoAsync("B4M36ESW");
}
private async System.Threading.Tasks.Task<JObject> GetTokenAsync()
{
if (NextTokenGeneration < DateTimeOffset.Now.ToUnixTimeSeconds())
{
var TokenClient = new HttpClient
{
BaseAddress = new Uri("https://auth.fit.cvut.cz/")
};
TokenClient.DefaultRequestHeaders.Accept.Clear();
TokenClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
TokenClient.DefaultRequestHeaders.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(ClientId + ":" + ClientSecret)));
var nvc = new List<KeyValuePair<string, string>>();
nvc.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
var req = new HttpRequestMessage(HttpMethod.Post, "oauth/token") { Content = new FormUrlEncodedContent(nvc) };
var res = await TokenClient.SendAsync(req);
Token = Newtonsoft.Json.JsonConvert.DeserializeObject<JObject>(await res.Content.ReadAsStringAsync());
NextTokenGeneration = DateTimeOffset.Now.ToUnixTimeSeconds() + Int32.Parse(Token["expires_in"].ToString()) - 10;
}
return Token;
}
public async System.Threading.Tasks.Task<bool> RoomExistAsync(string code)
{
XNamespace atom = "http://www.w3.org/2005/Atom";
Client.DefaultRequestHeaders.Remove("Authorization");
var t = await GetTokenAsync();
Client.DefaultRequestHeaders.Add("Authorization", "Bearer " + t["access_token"].ToString());
var res=await Client.GetAsync("rooms/" + code);
return await Client.GetAsync("rooms/" + code).ContinueWith<bool>(e => e.Result.IsSuccessStatusCode);
}
public async System.Threading.Tasks.Task CourseInfoAsync(string code,string sem="current")
{
XNamespace atom = "http://www.w3.org/2005/Atom";
XNamespace n= "http://kosapi.feld.cvut.cz/schema/3";
Client.DefaultRequestHeaders.Remove("Authorization");
var t = await GetTokenAsync();
Client.DefaultRequestHeaders.Add("Authorization", "Bearer " + t["access_token"].ToString());
var query = HttpUtility.ParseQueryString(string.Empty);
query["limit"] = "1000";
query["detail"] = "1";
query["sem"] = sem;
var res = await Client.GetAsync("courses/" + code+ "/parallels?"+query.ToString());
var body = await res.Content.ReadAsStringAsync();
var doc = XDocument.Parse(body);
var elements = doc.Root.Elements(atom + "entry");
KosCourse course = new KosCourse();
foreach(var element in elements)
{
var content = element.Element(atom + "content");
foreach (var el in content.Elements(n+"timetableSlot"))
{
KosCourseParallel p = new KosCourseParallel();
p.Capacity = content.Element(n + "capacity").Value.ToInt32();
p.Occupied = content.Element(n + "occupied").Value.ToInt32();
p.RoomId = el.Element(n + "room").Value;
p.Day = (DayOfWeek)(el.Element(n + "day").Value.ToInt32());
switch(el.Element(n + "parity").Value)
{
default:
case "BOTH": p.Parity = Parity.BOTH; break;
case "ODD": p.Parity = Parity.ODD; break;
case "EVEN": p.Parity = Parity.EVEN; break;
}
int start = el.Element(n + "firstHour").Value.ToInt32()-1;
var duration = el.Element(n + "duration").Value.ToInt32();
int b = start % 2;
start -= start % 2;
p.From = (7 * 60 + 30) + (start*105/2) + b*45;
p.To = p.From + duration * 45;
switch (content.Element(n + "parallelType").Value)
{
case "LABORATORY": p.Type = ParallelType.Laboratory; break;
default:
case "LECTURE": p.Type = ParallelType.Lecture; break;
case "TUTORIAL": p.Type = ParallelType.Tutorial; break;
}
course.Parallels.Add(p);
}
}
res = await Client.GetAsync("courses/" + code + "?" + query.ToString());
body = await res.Content.ReadAsStringAsync();
doc = XDocument.Parse(body);
}
}
}
......@@ -49,14 +49,15 @@ namespace KazetaNode
RegisterCommands(new CmdTestNetwork(),new CmdNetworkDiscovery());
ConsoleP.WriteLine("Kazeta node (version " + version + ")");
ConsoleP.WriteLine("=====================================");
dynamic yamlObject;
try
{
ConsoleP.Write("Reading configuration file: ");
var deserializer = new DeserializerBuilder().Build();
var input = new StringReader(File.ReadAllText(@"kazeta.yaml"));
dynamic yamlObject = deserializer.Deserialize(input);
yamlObject = deserializer.Deserialize(input);
NodeId = yamlObject["id"];
ConsoleP.WriteLine("OK");
ConsoleP.WriteLine("OK");
ConsoleP.WriteLine("Connecting to network: ");
Network = new Network(yamlObject);
Network.Connect();
......@@ -76,7 +77,7 @@ namespace KazetaNode
ConsoleP.WriteLine(e.ToString());
return;
}
Libraries = AbstractLibrary.Initialize();
Libraries = AbstractLibrary.Initialize(yamlObject["libraries"]);
foreach (AbstractLibrary lib in Libraries)
RegisterCommands(lib.Commands.ToArray());
if (true)
......
......@@ -5,11 +5,16 @@ network:
virtual_host: kazeta
hostname: ndi-rabbit.felk.cvut.cz
port: 5672
libraries:
kosapi:
clientid: 314b28ac-b629-424d-b33b-ee1eec37596e
clientsecret: dLSsmSehALSSwW5x3DnUwxSz7GsaQFPS
experimentional:
net_timeout: 250
commands:
ndi_scan: true
ndi_snapshot: true
ndi_capture: true
test_network: true
network_discovery: true
\ No newline at end of file
network_discovery: true
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment