ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/Qzhteln/trunk/TELTest/QuizCreator.cs
Revision: 2
Committed: Wed Feb 11 13:07:01 2026 UTC (8 weeks, 3 days ago) by figdor32
File size: 14295 byte(s)
Log Message:
Initial check-in

File Contents

# Content
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics.SymbolStore;
4 using System.Linq;
5 using System.Net.Sockets;
6 using System.Reflection;
7 using System.Text;
8 using System.Threading;
9 using System.Threading.Tasks;
10
11 namespace TELTest {
12 public class QuizCreator {
13 public QuizCreator() {
14 DraftID = null;
15 Password = Utilities.RandomString(15);
16 }
17 bool savedChanges = false;
18 protected QuizContainer GetContainer() {
19 QuizContainer qc = new QuizContainer();
20 qc.Title = Title;
21 qc.Author = Author;
22 qc.Created = DateTime.Now;
23 qc.Guid = Guid.NewGuid();
24 qc.Password = Password;
25 qc.Questions = Questions.ToArray();
26 qc.Visibility = Visibility;
27 return qc;
28 }
29 public void Save() {
30 var qc = GetContainer();
31 bool doNotSave = true;
32 doNotSave &= string.IsNullOrWhiteSpace(Title);
33 doNotSave &= string.IsNullOrWhiteSpace(Author);
34 foreach (var item in Questions) {
35 doNotSave &= string.IsNullOrWhiteSpace(item.Content);
36 foreach (var item2 in item.Answers) {
37 doNotSave &= string.IsNullOrWhiteSpace(item2.Content);
38 }
39 }
40 if (doNotSave) {
41 if (!string.IsNullOrWhiteSpace(DraftID)) QuizDraftManager.DeleteDraft(DraftID);
42 return;
43 }
44 if (DraftID == null) {
45 DraftID = QuizDraftManager.SaveNewDraft(qc);
46 } else {
47 QuizDraftManager.SaveDraft(qc, DraftID);
48 if (isPublished) {
49 QuizListing.UpdateEntry(DraftID, Title, Visibility);
50 }
51 }
52 savedChanges = true;
53 }
54 public async Task Handle(ConnectionHandler handler, NetworkStream stream) {
55 Handler = handler;
56 Stream = stream;
57 string[][] menu = new string[2][];
58 int xsel = 0;
59 int ysel = 0;
60 Questions.Add(new QuizQuestion() { Answers = new[] { new QuizQuestionAnswer() } });
61 while (true) {
62 menu[0] = new[] {
63 /* 0 */ "ID Kopii Roboczej/Quizu: " + DraftID,
64 /* 1 */ "Tytul quizu: " + Title,
65 /* 2 */ "Autor quizu: " + Author,
66 /* 3 */ "Liczba pytan: " + Questions.Count,
67 /* 4 */ "Widocznosc: " + Visibility,
68 /* 5 */ "Haslo: " + Password,
69 /* 6 */ "Wyprobuj....",
70 /* 7 */ "Publikuj/udostepnij...",
71 "Powrot..."
72 };
73 if (menu.Length != Questions.Count + 1)
74 Array.Resize(ref menu, Questions.Count + 1);
75
76 for (int i = 0; i < Questions.Count; i++) {
77 var q = Questions[i];
78 menu[1 + i] = new string[4 + q.Answers.Length];
79 menu[1 + i][0] = "Usun...";
80 menu[1 + i][1] = "Dodaj kolejne...";
81 menu[1 + i][2] = "Pytanie: " + q.Content;
82 for (int j = 0; j < q.Answers.Length; j++) {
83 menu[1 + i][3 + j] = (q.Answers[j].Correct? "[P] " : "") + "Odpowiedz " + (j + 1) + ": " + q.Answers[j].Content;
84 }
85 menu[1 + i][menu[1 + i].Length - 1] = "Dodaj odpowiedz...";
86
87 }
88 List<string> labels = new List<string>();
89 labels.Add("Menu");
90 for (int i = 0; i < Questions.Count; i++) {
91 labels.Add("Pytanie " + (i + 1));
92 }
93 var sel = await GUIUtilities.Create2DMenu(handler, stream, menu, labels.ToArray(), defaultx: xsel, defaulty: ysel);
94 xsel = sel.Item1;
95 ysel = sel.Item2;
96 if (xsel == 0) {
97 switch (ysel) {
98 case 0:
99 await OpenDraft();
100 break;
101 case 1:
102 Title = await Promptfull("Tytul quizu");
103 break;
104 case 2:
105 Author = await Promptfull("Autor quizu");
106 break;
107 case 4:
108 Visibility += 1;
109 if (Visibility > Visibility.Public) Visibility = 0;
110 break;
111 case 6: { // Try
112 QuizContainer qc = GetContainer();
113 BaseQuizContext bc = new BaseQuizContext(Handler, Stream, qc);
114 await bc.Handle();
115 break;
116 }
117 case 7:
118 await Publish();
119 break;
120 default:
121 break;
122 }
123 Save();
124 if (ysel == menu[0].Length - 1) break;
125 } else {
126 int qn = xsel - 1;
127 switch (ysel) {
128 case 0:
129 bool del = await AreYouSure("Na pewno usunac?");
130 if (del) {
131 if (Questions.Count == 1) {
132 Questions[0] = new QuizQuestion() { Answers = new QuizQuestionAnswer[] { new QuizQuestionAnswer() } };
133 } else {
134 Questions.RemoveAt(qn);
135 if (xsel <= qn + 1) xsel--;
136 }
137 Save();
138 }
139
140 break;
141 case 1:
142 Questions.Insert(qn + 1, new QuizQuestion() { Answers = new QuizQuestionAnswer[] { new QuizQuestionAnswer() } });
143 Save();
144 xsel = qn + 2;
145 break;
146 case 2: {
147 var tmp = Questions[qn];
148 tmp.Content = await Promptfull("Pytanie", tmp.Content, 128);
149 Questions[qn] = tmp;
150 Save();
151 break;
152 }
153 default: {
154 if (ysel == menu[xsel].Length - 1) {
155 var arr = Questions[qn].Answers;
156 Array.Resize(ref arr, arr.Length + 1);
157 arr[arr.Length - 1] = new QuizQuestionAnswer();
158 var tmpq = Questions[qn];
159 tmpq.Answers = arr;
160 Questions[qn] = tmpq;
161 ysel++;
162 Save();
163 } else {
164 var tmp = Questions[qn].Answers[ysel - 3];
165 var ans = await ProcAnswer(tmp);
166 if (ans == null) {
167 var l = Questions[qn].Answers.ToList();
168 l.RemoveAt(ysel - 3);
169 var tmpq = Questions[qn];
170 tmpq.Answers = l.ToArray();
171 Questions[qn] = tmpq;
172 break;
173 }
174 tmp = ans.Value;
175 Questions[qn].Answers[ysel - 3] = tmp;
176 Save();
177 }
178 break;
179 }
180 }
181
182 }
183
184 }
185 await Task.Delay(1);
186 }
187 public async Task Publish() {
188 if (string.IsNullOrWhiteSpace(DraftID)) {
189 await Handler.TryClear(Stream);
190 await Handler.WriteASCII(Stream, "Musisz najpierw cokolwiek dodac.\r\n\r\nNacisnij klawisz aby powrocic do edytora quizow...");
191 await Handler.ReadChar(Stream);
192 Handler.Flush(Stream);
193 return;
194 }
195 await Handler.TryClear(Stream);
196 await Handler.WriteASCII(Stream, "Po opublikowaniu quizu bedziesz potrzebowac zarowno jego ID jak hasla aby go edytowac.\r\n\r\n");
197 await Handler.WriteASCII(Stream, "Widocznosc tego quizu to: \"" + Visibility+ "\".\r\n");
198 switch (Visibility) {
199 case Visibility.Private:
200 await Handler.WriteASCII(Stream, "Oznacza to, ze bedzie wymagane jego ID aby w niego zagrac.\r\n");
201 break;
202 case Visibility.Public:
203 await Handler.WriteASCII(Stream, "Oznacza to, ze bedzie on widoczny w eksploratorze quizow dla wszystkich.\r\n");
204 break;
205 default:
206 await Handler.WriteASCII(Stream, "Blad: Nieznana widocznosc.\r\n");
207 break;
208 }
209 bool yes = await AreYouSure("Czy na pewno chcesz kontynuowac?");
210 if (yes) QuizListing.Insert(DraftID, Title, Visibility);
211 }
212 protected ConnectionHandler Handler { get; set; }
213 protected NetworkStream Stream { get; set; }
214 public async Task<QuizQuestionAnswer?> ProcAnswer(QuizQuestionAnswer current) {
215 int ysel = 0;
216 while (true) {
217 string[][] menu = new string[1][];
218 menu[0] = new[] {
219 "Tresc: " + current.Content,
220 "Poprawna? " + (current.Correct? "Tak" : "Nie"),
221 "Powrot...",
222 "Usun..."
223 };
224
225 var res = await GUIUtilities.Create2DMenu(Handler, Stream, menu, new[] { "Pytanie" }, defaulty: ysel);
226 ysel = res.Item2;
227 switch (ysel) {
228 case 0:
229 current.Content = await Promptfull("Tresc");
230 break;
231 case 1:
232 current.Correct = !current.Correct;
233 break;
234 case 2:
235 goto BreakLoop;
236 case 3:
237 if (await AreYouSure("Usunac odpowiedz?")) {
238 return null;
239 }
240 break;
241 default:
242 break;
243 }
244 }
245 BreakLoop:
246 return current;
247 }
248 public async Task<bool> AreYouSure(string prompt, bool nodef = false, bool deffalse = true) {
249 var c = await Handler.Choice(Stream, new[] { 'Y', 'N' }, prompt, def: (nodef ? (char?)null : (deffalse ? 'N' : 'Y')));
250 Handler.Flush(Stream);
251 return c == 'Y';
252 }
253 bool isPublished = false;
254 public async Task<string> OpenDraft() {
255 isPublished = false;
256 await Handler.TryClear(Stream);
257 await Handler.WriteASCII(Stream, "Wpisz ID kopii roboczej lub quizu aby do nigo powrocic. Obecny quiz jest rowniez zapisany jako kopia robocza. Jezeli quiz jest opublikowany lub udostepniony bedziesz potrzebowac hasla aby go edytowac.");
258 string ask = await Promptfull("ID", noClear: true);
259
260 var d = QuizDraftManager.GetDraft(ask);
261 if (d != null) {
262 var lst = QuizListing.Contains(ask);
263 if (lst) {
264 while (true) {
265 await Handler.TryClear(Stream);
266 await Handler.WriteASCII(Stream, "Wpisz haslo: ");
267 ReadConfiguration rc = ReadConfiguration.Default;
268 rc.EchoPasswordChars = true;
269 string pwd = await Handler.Read(Stream, rc);
270 if (d.Password == pwd) break;
271 if (string.IsNullOrWhiteSpace(pwd)) return null;
272 }
273 isPublished = true;
274 }
275 Title = d.Title;
276 Author = d.Author;
277 Password = d.Password;
278 DraftID = ask;
279 Questions = d.Questions.ToList();
280 Visibility = d.Visibility;
281 }
282 if (string.IsNullOrWhiteSpace(ask)) return DraftID;
283
284 return ask;
285 }
286 public async Task<string> Promptfull(string prompt, string @default = null, int nMax = 32, bool noClear = false) {
287 if (!noClear)
288 await Handler.TryClear(Stream);
289
290 await Handler.WriteASCII(Stream, "\r\n" + prompt + ": ");
291 var res = await Handler.Read(Stream, new ReadConfiguration() {
292 Echo = true,
293 MaxLength = nMax,
294 FlushAfterReading = true,
295 Terminator = '\r',
296 Whitelist = Utilities.ALPHANUMERIC + " ?,.{}[]()/\\:;'\"'\b"
297 });
298 return string.IsNullOrWhiteSpace(res) ? @default : res;
299 }
300 public List<QuizQuestion> Questions { get; set; } = new List<QuizQuestion>();
301 public string DraftID { get; set; }
302 public string Title { get; set; }
303 public string Author { get; set; }
304 public string Password { get; set; }
305 public Visibility Visibility { get; set; }
306 }
307 public enum Visibility {
308 Private,
309 Public
310 }
311 }