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, 4 days ago) by figdor32
File size: 14295 byte(s)
Log Message:
Initial check-in

File Contents

# User Rev Content
1 figdor32 2 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     }