-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathTurKitSocKit.cs
executable file
·407 lines (361 loc) · 16.1 KB
/
TurKitSocKit.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Web.Script.Serialization;
using System.Xml.Serialization;
using System.Text.RegularExpressions;
using Soylent.Model;
using Soylent.Model.Shortn;
using Soylent.Model.Crowdproof;
using Soylent.Model.HumanMacro;
using System.Windows.Forms;
using Soylent.View;
namespace Soylent
{
/**
* Connects to a TurKit instance
*/
public class TurKitSocKit
{
private int port = 11000;
private List<ConnectionInfo> _connections = new List<ConnectionInfo>();
private Socket serverSocket;
private class ConnectionInfo
{
public Socket Socket;
public byte[] Buffer;
}
public TurKitSocKit()
{
}
~TurKitSocKit()
{
// destructor to make sure that socket is closed
serverSocket.Close();
}
/// <summary>
/// Connects to a socket on the local machine and begins listening on the socket.
/// </summary>
public void Listen() {
IPAddress address = IPAddress.Parse("127.0.0.1");
IPEndPoint localEP = new IPEndPoint(address, port);
Debug.WriteLine("Local address and port : " + localEP.ToString());
serverSocket = new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType.IP);
serverSocket.ReceiveBufferSize = 100000;
try
{
serverSocket.Bind(localEP);
serverSocket.Listen(10);
Debug.WriteLine("Waiting for a connection...");
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), serverSocket);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
throw e;
}
Debug.WriteLine("Closing the listener...");
}
/*
* Function called as an asynchronous callback when data is received on the socket.
*/
private void AcceptCallback(IAsyncResult result)
{
Console.WriteLine("Got a connection!");
ConnectionInfo connection = new ConnectionInfo();
try
{
// Finish Accept
Socket s = (Socket)result.AsyncState;
s.ReceiveBufferSize = 100000;
connection.Socket = s.EndAccept(result);
connection.Socket.ReceiveBufferSize = 100000;
connection.Buffer = new byte[100000];
lock (_connections) _connections.Add(connection);
// Start Receive and a new Accept
connection.Socket.BeginReceive(connection.Buffer, 0, connection.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), connection);
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), result.AsyncState);
}
catch (SocketException exc)
{
CloseConnection(connection);
Console.WriteLine("Socket exception: " + exc.SocketErrorCode);
}
catch (Exception exc)
{
CloseConnection(connection);
Console.WriteLine("Exception: " + exc);
}
}
private void ReceiveCallback(IAsyncResult result)
{
Debug.Write("Receiving data: ");
ConnectionInfo connection = (ConnectionInfo)result.AsyncState;
int bytesRead = connection.Socket.EndReceive(result);
Debug.WriteLine(bytesRead + " bytes");
if (0 != bytesRead)
{
/**
* TurKit sends us information that looks like JSON
* {
* "__type__": "status",
* "percent": 43.5,
* ...
* }
*/
string incomingString = System.Text.ASCIIEncoding.ASCII.GetString(connection.Buffer, 0, bytesRead);
Debug.WriteLine(incomingString);
HandleSocketMessage(incomingString);
connection.Socket.BeginReceive(connection.Buffer, 0,
connection.Buffer.Length, SocketFlags.None,
new AsyncCallback(ReceiveCallback), connection);
}
else CloseConnection(connection);
}
private void CloseConnection(ConnectionInfo ci)
{
ci.Socket.Close();
lock (_connections) _connections.Remove(ci);
}
public static void HandleSocketMessage(string incomingString) {
Regex typeRegex = new Regex("\"__type__\"\\s*:\\s*\"(?<messageType>.*)\"");
Match regexResult = typeRegex.Match(incomingString);
string messageType = regexResult.Groups["messageType"].Value;
Regex jobtypeRegex = new Regex("\"__jobType__\"\\s*:\\s*\"(?<jobType>.*)\"");
Match jobregexResult = jobtypeRegex.Match(incomingString);
string jobType = jobregexResult.Groups["jobType"].Value;
JavaScriptSerializer serializer = new JavaScriptSerializer();
if (messageType == "status")
{
TurKitStatus receivedObject = serializer.Deserialize<TurKitStatus>(incomingString);
Microsoft.Office.Interop.Word.Document doc = Globals.Soylent.jobToDoc[receivedObject.job];
HITData concernedHIT = Globals.Soylent.soylentMap[doc].jobMap[receivedObject.job];//Globals.Soylent.soylentMap[Globals.Soylent.Application.ActiveDocument].jobMap[receivedObject.job];
Debug.WriteLine(receivedObject.hitURL);
//if (concernedHIT is ShortnData)
if (jobType == "shortn")
{
Debug.WriteLine("Status update for Shortn");
ShortnData shortenData = concernedHIT as ShortnData;
shortenData.updateStatus(receivedObject);
}
//else if (concernedHIT is CrowdproofData)
else if (jobType == "crowdproof")
{
CrowdproofData crowdproofData = concernedHIT as CrowdproofData;
crowdproofData.updateStatus(receivedObject);
}
if (jobType == "human-macro")
{
Debug.WriteLine("Status update for human-macro");
HumanMacroData humanMacro = concernedHIT as HumanMacroData;
humanMacro.updateStatus(receivedObject);
}
}
else if (messageType == "stageComplete")
{
Debug.WriteLine("Stage complete message");
TurKitStageComplete receivedObject = serializer.Deserialize<TurKitStageComplete>(incomingString);
if (jobType == "shortn")
{
Microsoft.Office.Interop.Word.Document doc = Globals.Soylent.jobToDoc[receivedObject.job];
ShortnData shortenData = Globals.Soylent.soylentMap[doc].jobMap[receivedObject.job] as ShortnData;
//Globals.Soylent.soylentMap[Globals.Soylent.Application.ActiveDocument].jobMap[receivedObject.job] as ShortnData;
shortenData.stageCompleted(receivedObject);
}
else if (jobType == "crowdproof")
{
Microsoft.Office.Interop.Word.Document doc = Globals.Soylent.jobToDoc[receivedObject.job];
CrowdproofData crowdproofData = Globals.Soylent.soylentMap[doc].jobMap[receivedObject.job] as CrowdproofData;
//CrowdproofData crowdproofData = fixthis;//Globals.Soylent.soylentMap[Globals.Soylent.Application.ActiveDocument].jobMap[receivedObject.job] as CrowdproofData;
crowdproofData.stageCompleted(receivedObject);
}
}
else if (messageType == "complete")
{
if (jobType == "human-macro")
{
TurKitHumanMacroResult receivedObject = serializer.Deserialize<TurKitHumanMacroResult>(incomingString);
Debug.WriteLine("\nHUMAN MACRO COMPLEEETE******");
Microsoft.Office.Interop.Word.Document doc = Globals.Soylent.jobToDoc[receivedObject.job];
HumanMacroData humanMacro = Globals.Soylent.soylentMap[doc].jobMap[receivedObject.job] as HumanMacroData;
//HumanMacroData humanMacro = fixthis;//Globals.Soylent.soylentMap[Globals.Soylent.Application.ActiveDocument].jobMap[receivedObject.job] as HumanMacroData;
humanMacro.processSocKitMessage(receivedObject);
}
else if (jobType == "shortn")
{
TurKitFindFixVerify receivedObject = serializer.Deserialize<TurKitFindFixVerify>(incomingString);
Microsoft.Office.Interop.Word.Document doc = Globals.Soylent.jobToDoc[receivedObject.job];
ShortnData shortenData = Globals.Soylent.soylentMap[doc].jobMap[receivedObject.job] as ShortnData;//Globals.Soylent.soylentMap[Globals.Soylent.Application.ActiveDocument].jobMap[receivedObject.job] as ShortnData;
shortenData.processSocKitMessage(receivedObject);
}
else if (jobType == "crowdproof")
{
TurKitFindFixVerify receivedObject = serializer.Deserialize<TurKitFindFixVerify>(incomingString);
Microsoft.Office.Interop.Word.Document doc = Globals.Soylent.jobToDoc[receivedObject.job];
CrowdproofData crowdproofData = Globals.Soylent.soylentMap[doc].jobMap[receivedObject.job] as CrowdproofData;
//CrowdproofData crowdproofData = fixthis;//Globals.Soylent.soylentMap[Globals.Soylent.Application.ActiveDocument].jobMap[receivedObject.job] as CrowdproofData;
crowdproofData.processSocKitMessage(receivedObject);
}
}
else if (messageType == "exception")
{
Debug.WriteLine("TurKit exception thrown:");
TurKitException receivedObject = serializer.Deserialize<TurKitException>(incomingString);
Debug.WriteLine(receivedObject.exceptionString);
Microsoft.Office.Interop.Word.Document doc = Globals.Soylent.jobToDoc[receivedObject.job];
SoylentPanel panel = Globals.Soylent.soylentMap[doc];
HITData concernedHIT = panel.jobMap[receivedObject.job];
panel.Invoke(new HITData.showErrorDelegate(concernedHIT.showError), new object[] { receivedObject.exceptionString });
//concernedHIT.showError(receivedObject.exceptionCode);
}
//Debug.WriteLine("got it!");
}
/// <summary>
/// High-level status report from TurKit
/// </summary>
public class TurKitStatus
{
public int job;
public string stage;
public int numCompleted;
public int totalRequested;
public int paragraph;
public double payment;
public string hitURL;
public int patchNumber;
public int totalPatches;
}
/// <summary>
/// Signals that a stage for a specific job, paragraph, and patch has completed
/// </summary>
public class TurKitStageComplete
{
public int job;
public string stage;
public int totalRequested;
public double payment;
public int paragraph;
public int patchNumber;
public int totalPatches;
}
public class TurKitHumanMacroResult
{
public int job;
public int input;
public List<string> alternatives;
}
/// <summary>
/// Data returned from a Find-Fix-Verify task
/// </summary>
public class TurKitFindFixVerify
{
public int job;
public int paragraph;
public List<TurKitFindFixVerifyPatch> patches;
}
/// <summary>
/// Data returning a patch from a Shortn task.
/// </summary>
public class TurKitFindFixVerifyPatch
{
public int start;
public int end;
public int editStart;
public int editEnd;
public List<TurKitFindFixVerifyOption> options;
public int numEditors;
public bool merged;
public string originalText;
}
/// <summary>
/// Data returning an option for a specific patch
/// </summary>
public class TurKitFindFixVerifyOption
{
public string field;
public List<TurKitFindFixVerifyAlternative> alternatives;
public bool editsText;
}
public class TurKitFindFixVerifyAlternative
{
public string text;
[XmlIgnore] public Dictionary<string, int> votes;
public string editedText;
public int editStart;
public int editEnd;
public int numVoters;
}
/// <summary>
/// Data returned from a Shortn task
/// </summary>
public class TurKitShortn
{
public int job;
public int paragraph;
public List<TurKitShortnPatch> patches;
}
/// <summary>
/// Data returning a patch from a Shortn task.
/// </summary>
public class TurKitShortnPatch
{
public int start;
public int end;
public int editStart;
public int editEnd;
public int numEditors;
public bool merged;
public bool canCut;
public int cutVotes;
public List<TurKitShortnPatchOption> options;
public string originalText;
}
/// <summary>
/// Data returning an option for a specific patch
/// </summary>
public class TurKitShortnPatchOption
{
public string text;
public string editedText;
public int editStart;
public int editEnd;
public int meaningVotes;
public int grammarVotes;
public int numVoters;
}
public class TurKitCrowdproof
{
public int job;
public int paragraph;
public List<TurKitCrowdproofPatch> patches;
}
public class TurKitCrowdproofPatch
{
public int start;
public int end;
public int editStart;
public int editEnd;
public int numEditors;
public List<TurKitCrowdproofPatchOption> options;
public List<string> reasons;
public string originalText;
}
public class TurKitCrowdproofPatchOption
{
public string text;
public int editStart;
public int editEnd;
public string replacement;
//TODO: does this make sense? multiple reasons?
}
public class TurKitException
{
public int job;
public string exceptionString;
}
}
}