OSDN Git Service

SQLではなくほとんどをコードで補いました
[newbbs/newbbs.git] / WebModuleUnit1.pas
1 unit WebModuleUnit1;
2
3 interface
4
5 uses System.SysUtils, System.Classes, Web.HTTPApp, Web.DSProd, Web.HTTPProd,
6   Web.DBWeb, System.Variants, System.NetEncoding, System.RegularExpressions,
7   Data.DB, Web.DBXpressWeb, System.Types, FireDAC.Stan.Intf,
8   FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS,
9   FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt,
10   FireDAC.Comp.DataSet, FireDAC.Comp.Client;
11
12 type
13   TWebModule1 = class(TWebModule)
14     articles: TDataSetPageProducer;
15     index: TDataSetPageProducer;
16     admin: TDataSetTableProducer;
17     search: TPageProducer;
18     items: TDataSetPageProducer;
19     help: TPageProducer;
20     top: TPageProducer;
21     master: TPageProducer;
22     alert: TDataSetPageProducer;
23     footer: TDataSetPageProducer;
24     mail: TPageProducer;
25     css1: TPageProducer;
26     css2: TPageProducer;
27     css3: TPageProducer;
28     css4: TPageProducer;
29     header: TDataSetPageProducer;
30     login: TDataSetPageProducer;
31     js1: TPageProducer;
32     js2: TPageProducer;
33     js3: TPageProducer;
34     js4: TPageProducer;
35     adhead: TPageProducer;
36     js5: TPageProducer;
37     title: TPageProducer;
38     ti: TDataSetPageProducer;
39     FDQuery1: TFDQuery;
40     procedure indexHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
41       TagParams: TStrings; var ReplaceText: string);
42     procedure WebModule1indexpageAction(Sender: TObject; Request: TWebRequest;
43       Response: TWebResponse; var Handled: Boolean);
44     procedure WebModule1registAction(Sender: TObject; Request: TWebRequest;
45       Response: TWebResponse; var Handled: Boolean);
46     procedure WebModuleCreate(Sender: TObject);
47     procedure WebModule1adminAction(Sender: TObject; Request: TWebRequest;
48       Response: TWebResponse; var Handled: Boolean);
49     procedure WebModule1topAction(Sender: TObject; Request: TWebRequest;
50       Response: TWebResponse; var Handled: Boolean);
51     procedure itemsHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
52       TagParams: TStrings; var ReplaceText: string);
53     procedure topHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
54       TagParams: TStrings; var ReplaceText: string);
55     procedure WebModule1searchAction(Sender: TObject; Request: TWebRequest;
56       Response: TWebResponse; var Handled: Boolean);
57     procedure WebModule1helpAction(Sender: TObject; Request: TWebRequest;
58       Response: TWebResponse; var Handled: Boolean);
59     procedure searchHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
60       TagParams: TStrings; var ReplaceText: string);
61     procedure masterHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
62       TagParams: TStrings; var ReplaceText: string);
63     procedure articlesHTMLTag(Sender: TObject; Tag: TTag;
64       const TagString: string; TagParams: TStrings; var ReplaceText: string);
65     procedure footerHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
66       TagParams: TStrings; var ReplaceText: string);
67     procedure WebModule1alertAction(Sender: TObject; Request: TWebRequest;
68       Response: TWebResponse; var Handled: Boolean);
69     procedure WebModule1masterAction(Sender: TObject; Request: TWebRequest;
70       Response: TWebResponse; var Handled: Boolean);
71     procedure mailHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
72       TagParams: TStrings; var ReplaceText: string);
73     procedure alertHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
74       TagParams: TStrings; var ReplaceText: string);
75     procedure WebModule1deleteAction(Sender: TObject; Request: TWebRequest;
76       Response: TWebResponse; var Handled: Boolean);
77     procedure WebModule1jumpAction(Sender: TObject; Request: TWebRequest;
78       Response: TWebResponse; var Handled: Boolean);
79     procedure WebModule1linkAction(Sender: TObject; Request: TWebRequest;
80       Response: TWebResponse; var Handled: Boolean);
81     procedure headerHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
82       TagParams: TStrings; var ReplaceText: string);
83     procedure adminFormatCell(Sender: TObject; CellRow, CellColumn: Integer;
84       var BgColor: THTMLBgColor; var Align: THTMLAlign; var VAlign: THTMLVAlign;
85       var CustomAttrs, CellData: string);
86     procedure WebModule1admdelAction(Sender: TObject; Request: TWebRequest;
87       Response: TWebResponse; var Handled: Boolean);
88     procedure WebModule1loginAction(Sender: TObject; Request: TWebRequest;
89       Response: TWebResponse; var Handled: Boolean);
90     procedure WebModule1adminsetAction(Sender: TObject; Request: TWebRequest;
91       Response: TWebResponse; var Handled: Boolean);
92     procedure adheadHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
93       TagParams: TStrings; var ReplaceText: string);
94     procedure WebModule1logoutAction(Sender: TObject; Request: TWebRequest;
95       Response: TWebResponse; var Handled: Boolean);
96     procedure WebModule1imgAction(Sender: TObject; Request: TWebRequest;
97       Response: TWebResponse; var Handled: Boolean);
98     procedure WebModule1fileAction(Sender: TObject; Request: TWebRequest;
99       Response: TWebResponse; var Handled: Boolean);
100     procedure titleHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
101       TagParams: TStrings; var ReplaceText: string);
102     procedure WebModule1titleAction(Sender: TObject; Request: TWebRequest;
103       Response: TWebResponse; var Handled: Boolean);
104     procedure tiHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
105       TagParams: TStrings; var ReplaceText: string);
106     procedure helpHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
107       TagParams: TStrings; var ReplaceText: string);
108     procedure loginHTMLTag(Sender: TObject; Tag: TTag; const TagString: string;
109       TagParams: TStrings; var ReplaceText: string);
110   private
111     { private \90é\8c¾ }
112     ss: TStringList;
113     tagstr: string;
114     procedure pages(count: Integer; var page: Integer);
115     procedure strsCheck(var Error: string; var list: TStringList);
116     procedure setLastArticle;
117     function isInfo: Boolean;
118     function loginCheck: Boolean;
119     function hash(str: string): string;
120     function mente: Boolean;
121     function detail(ts, pid: string): string;
122   public
123     { public \90é\8c¾ }
124   end;
125
126 var
127   WebModuleClass: TComponentClass = TWebModule1;
128
129 implementation
130
131 { %CLASSGROUP 'Vcl.Controls.TControl' }
132
133 uses Unit1, IdHashSHA, IdGlobal, IdHash, IdHashMessageDigest;
134
135 {$R *.dfm}
136
137 const
138   promotion = '\8dL\8d\90:';
139   tcnt = 7;
140
141 procedure TWebModule1.adheadHTMLTag(Sender: TObject; Tag: TTag;
142   const TagString: string; TagParams: TStrings; var ReplaceText: string);
143 begin
144   if TagString = 'pr' then
145     ReplaceText := promotion
146   else if (TagString = 'mente') and
147     (DataModule1.FDTable3.FieldByName('mente').AsBoolean = true) then
148     ReplaceText := 'checked'
149   else if TagString = 'database' then
150     ReplaceText := Request.QueryFields.Values['db'];
151 end;
152
153 procedure TWebModule1.adminFormatCell(Sender: TObject;
154   CellRow, CellColumn: Integer; var BgColor: THTMLBgColor;
155   var Align: THTMLAlign; var VAlign: THTMLVAlign;
156   var CustomAttrs, CellData: string);
157 begin
158   if (CellColumn = 0) and (CellRow > 0) then
159     CellData := Format('<input name=check%d type=checkbox>', [CellRow]);
160 end;
161
162 procedure TWebModule1.alertHTMLTag(Sender: TObject; Tag: TTag;
163   const TagString: string; TagParams: TStrings; var ReplaceText: string);
164 var
165   s: TStringList;
166   i: Integer;
167 begin
168   if (TagString = 'plus') and (alert.Tag = 0) then
169     ReplaceText :=
170       '<a href=/jump?db=<#dbname>&num=<#posnum>>[ <#dbname>-<#posnum> ]</a>'
171   else if TagString = 'article' then
172   begin
173     with DataModule1 do
174       if (FDTable1.Locate('dbnum', FDTable4.FieldByName('dbname').AsInteger)
175         = false) or (FDTable2.Locate('number', FDTable4.FieldByName('posnum')
176         .AsInteger) = false) then
177       begin
178         ReplaceText := '<p>\83\8a\83N\83G\83X\83g';
179         Exit;
180       end;
181     s := TStringList.Create;
182     try
183       s.Text := articles.Content;
184       for i := 1 to 2 do
185         s.Delete(1);
186       for i := s.count - 1 downto 0 do
187         if Copy(s[i], 1, 18) = '<section id=master' then
188         begin
189           s.Delete(i);
190           break;
191         end;
192       ReplaceText := s.Text;
193     finally
194       s.Free;
195     end;
196   end
197   else if TagString = 'request' then
198     ReplaceText := DataModule1.FDTable4.FieldByName('request').AsString;
199 end;
200
201 procedure TWebModule1.articlesHTMLTag(Sender: TObject; Tag: TTag;
202   const TagString: string; TagParams: TStrings; var ReplaceText: string);
203 begin
204   if TagString = 'comment' then
205     ReplaceText := DataModule1.FDTable2.FieldByName('comment').AsString;
206 end;
207
208 function TWebModule1.detail(ts, pid: string): string;
209 var
210   i: Integer;
211 begin
212   for i := 0 to ComponentCount - 1 do
213     if Components[i].Name = ts + pid then
214       result := (Components[i] as TPageProducer).Content;
215 end;
216
217 procedure TWebModule1.footerHTMLTag(Sender: TObject; Tag: TTag;
218   const TagString: string; TagParams: TStrings; var ReplaceText: string);
219 var
220   i: Integer;
221 begin
222   if TagString = 'link' then
223   begin
224     for i := 1 to 10 do
225       if i = index.Tag then
226         ReplaceText := ReplaceText + ' ' + i.ToString + ' '
227       else
228         ReplaceText := ReplaceText +
229           Format(' <a style=text-decoration-line:none href="%s?db=%d&num=%d">%d</a> ',
230           [PString(Self.Tag)^, DataModule1.FDTable1.FieldByName('dbnum')
231           .AsInteger, i, i]);
232   end
233   else if TagString = 'recent' then
234     if index.Tag = -1 then
235       ReplaceText := TagString
236     else
237       ReplaceText := '<a style=text-decoration-line:none href="' +
238         PString(Self.Tag)^ + '?db=' + DataModule1.FDTable1.FieldByName('dbnum')
239         .AsString + '">recent</a>';
240 end;
241
242 function TWebModule1.hash(str: string): string;
243 begin
244   with TIdHashSHA1.Create do
245   begin
246     try
247       result := HashStringAsHex(str);
248     finally
249       Free;
250     end;
251   end;
252 end;
253
254 procedure TWebModule1.headerHTMLTag(Sender: TObject; Tag: TTag;
255   const TagString: string; TagParams: TStrings; var ReplaceText: string);
256 var
257   s: string;
258 begin
259   if TagString = 'cookie' then
260   begin
261     s := TagParams.Values['param'];
262     ReplaceText := TNetEncoding.URL.Decode(Request.CookieFields.Values[s]);
263   end
264   else if (TagString = 'check') and
265     (Request.ContentFields.Values['show'] <> 'false') then
266     ReplaceText := 'checked'
267   else if TagString = 'preview' then
268     ReplaceText := Request.ContentFields.Values['preview']
269   else if TagString = 'raw' then
270     ReplaceText := Request.ContentFields.Values['raw']
271   else if TagString = 'pass' then
272     ReplaceText := Request.ContentFields.Values['password']
273   else if TagString = 'title' then
274     ReplaceText := Request.ContentFields.Values['title'];
275 end;
276
277 procedure TWebModule1.helpHTMLTag(Sender: TObject; Tag: TTag;
278   const TagString: string; TagParams: TStrings; var ReplaceText: string);
279 begin
280   if TagString = 'pr' then
281     ReplaceText := promotion
282   else if TagString = 'area' then
283     if help.Tag = 0 then
284     begin
285       ss := TStringList.Create;
286       try
287         ss.Add('<form action=/help method=post><p>\82¨\96â\82¢\8d\87\82í\82¹<\8dí\8f\9c\88Ë\97\8a\82È\82Ç\89½\82Å\82à></p>');
288         ss.Add('<textarea name=help style=height:100px;width:250px>\93\8a\8de\8eÒ\96¼\82È\82Ç\81F');
289         ss.Add('\91\8a\92k\93à\97e\81F');
290         ss.Add('\82»\82Ì\91¼\81F</textarea><br>');
291         ss.Add('<input type=submit value="\91\97\90M"></form>');
292         ReplaceText := ss.Text;
293       finally
294         ss.Free;
295       end;
296     end
297     else
298       ReplaceText :=
299         '<p style=color:yellow;background-color:aqua>\82²\95ñ\8d\90\82 \82è\82ª\82Æ\82¤\82²\82´\82¢\82Ü\82·.';
300 end;
301
302 procedure TWebModule1.indexHTMLTag(Sender: TObject; Tag: TTag;
303   const TagString: string; TagParams: TStrings; var ReplaceText: string);
304 var
305   i: Integer;
306 begin
307   if TagString = 'pr' then
308     ReplaceText := promotion
309   else if TagString = 'article' then
310   begin
311     for i := 1 to DataModule1.FDTable3.FieldByName('count').AsInteger do
312     begin
313       if DataModule1.FDTable2.Eof = true then
314         break;
315       if isInfo = false then
316         ReplaceText := ReplaceText + articles.Content
317       else
318         ReplaceText := articles.Content + ReplaceText;
319       DataModule1.FDTable2.Next;
320     end;
321   end
322   else if TagString = 'footer' then
323     ReplaceText := footer.Content
324   else if TagString = 'header' then
325     if (DataModule1.FDTable1.FieldByName('dbnum')
326       .AsInteger = DataModule1.FDTable3.FieldByName('info').AsInteger) and
327       (loginCheck = false) then
328       ReplaceText := '<h1 style=text-align:center>\8aÇ\97\9d\90l\82©\82ç\82¨\92m\82ç\82¹\82ª\82 \82è\82Ü\82·.</h1>'
329     else
330     begin
331       i := DataModule1.FDTable3.FieldByName('count').AsInteger;
332       if 10 * i <= DataModule1.FDTable2.RecordCount then
333         ReplaceText := '<h1>\82±\82ê\88È\8fã\93\8a\8de\82Å\82«\82Ü\82¹\82ñ.</h1>'
334       else
335         ReplaceText := header.Content;
336     end
337   else if (TagString = 'css') or (TagString = 'js') then
338     ReplaceText := detail(TagString, TagParams.Values['id'])
339   else if TagString = 'dbnum' then
340     ReplaceText := DataModule1.FDTable1.FieldByName('dbnum').AsString
341   else if TagString = 'database' then
342     ReplaceText := DataModule1.FDTable1.FieldByName('database').AsString;
343 end;
344
345 function TWebModule1.isInfo: Boolean;
346 var
347   s: string;
348 begin
349   result := DataModule1.FDTable1.FieldByName('dbnum')
350     .AsInteger = DataModule1.FDTable3.FieldByName('info').AsInteger;
351 end;
352
353 procedure TWebModule1.itemsHTMLTag(Sender: TObject; Tag: TTag;
354   const TagString: string; TagParams: TStrings; var ReplaceText: string);
355 var
356   s: TStringList;
357   t, str: string;
358   i, j: Integer;
359 begin
360   if TagString = 'item' then
361   begin
362     s := TStringList.Create;
363     try
364       s.Text := DataModule1.FDTable2.FieldByName('raw').AsString;
365       for i := 0 to s.count - 1 do
366         for j := 0 to ss.count - 1 do
367           if Pos(ss[j], s[i]) > 0 then
368             if Self.Tag = 0 then
369               s[i] := '<p style=background-color:aqua>' + s[i]
370             else
371               s[i] := '<p style=background-color:yellow>' + s[i];
372       with DataModule1.FDTable2 do
373       begin
374         i := FieldByName('dbnum').AsInteger;
375         j := FieldByName('number').AsInteger;
376         str := Request.QueryFields.Values['db'];
377         if str = '' then
378           t := Format('<a href="/jump?db=%d&num=%d">[ %d-%d ]</a>',
379             [i, j, i, j])
380         else
381           t := Format('<a href="/jump?db=%s&num=%d">[ %d ]</a>', [str, j, j]);
382       end;
383       ReplaceText := t + s.Text;
384     finally
385       s.Free;
386     end;
387   end;
388 end;
389
390 function TWebModule1.loginCheck: Boolean;
391 begin
392   result := hash(Request.CookieFields.Values['user'])
393     = DataModule1.FDTable3.FieldByName('password').AsString;
394 end;
395
396 procedure TWebModule1.loginHTMLTag(Sender: TObject; Tag: TTag;
397   const TagString: string; TagParams: TStrings; var ReplaceText: string);
398 begin
399   if TagString = 'pr' then
400     ReplaceText := promotion;
401 end;
402
403 procedure TWebModule1.masterHTMLTag(Sender: TObject; Tag: TTag;
404   const TagString: string; TagParams: TStrings; var ReplaceText: string);
405 begin
406   if TagString = 'pr' then
407     ReplaceText := promotion
408   else if TagString = 'request' then
409     with DataModule1.FDTable4 do
410     begin
411       First;
412       ReplaceText := '<table border=1 align=center>';
413       while Eof = false do
414       begin
415         if FieldByName('posnum').AsInteger = -1 then
416           alert.Tag := 1
417         else
418           alert.Tag := 0;
419         ReplaceText := ReplaceText + alert.ContentFromString(alert.Content);
420         Next;
421       end;
422       ReplaceText := ReplaceText + '</table>';
423     end;
424 end;
425
426 function TWebModule1.mente: Boolean;
427 begin
428   if DataModule1.FDTable3.FieldByName('mente').AsBoolean = true then
429   begin
430     result := true;
431     Response.Content :=
432       '<p><br><h1 style=text-align:center>\82½\82¾\82¢\82Ü\83\81\83\93\83e\83i\83\93\83X\92\86\82Å\82·^_^</h1>' +
433       '<p style=text-align:center><a href=/admin>\8aÇ\97\9d\8eÒ\97p\83\8d\83O\83C\83\93</a>'
434   end
435   else
436     result := false;
437 end;
438
439 procedure TWebModule1.pages(count: Integer; var page: Integer);
440 var
441   max: Integer;
442 begin
443   max := DataModule1.FDTable3.FieldByName('count').AsInteger;
444   if (page > -1) and (count < max * (page - 1)) then
445   begin
446     page := (count div max) + 1;
447     if count mod max = 0 then
448       dec(page);
449   end;
450   case page of
451     - 1:
452       begin
453         DataModule1.FDTable2.Last;
454         DataModule1.FDTable2.MoveBy(1 - max);
455       end;
456   else
457     DataModule1.FDTable2.First;
458     DataModule1.FDTable2.MoveBy(max * (page - 1));
459   end;
460 end;
461
462 procedure TWebModule1.mailHTMLTag(Sender: TObject; Tag: TTag;
463   const TagString: string; TagParams: TStrings; var ReplaceText: string);
464 begin
465   if TagString = 'pr' then
466     ReplaceText := promotion
467   else if TagString = 'content' then
468     ReplaceText := articles.Content
469   else if TagString = 'query' then
470     ReplaceText := '?' + Request.Query
471   else if TagString = 'number' then
472     ReplaceText := Request.QueryFields.Values['num'];
473 end;
474
475 procedure TWebModule1.searchHTMLTag(Sender: TObject; Tag: TTag;
476   const TagString: string; TagParams: TStrings; var ReplaceText: string);
477 var
478   s: TStringList;
479   procedure sub;
480   var
481     i: Integer;
482     j: Integer;
483   label jump;
484   begin
485     DataModule1.FDTable2.First;
486     while DataModule1.FDTable2.Eof = false do
487     begin
488       s.Text := DataModule1.FDTable2.FieldByName('raw').AsString;
489       ss.DelimitedText := Request.ContentFields.Values['word1'];
490       for j := 0 to ss.count - 1 do
491         for i := 0 to s.count - 1 do
492           if Pos(ss[j], s[i]) > 0 then
493             if Self.Tag = 0 then
494             begin
495               ReplaceText := ReplaceText + items.Content;
496               goto jump;
497             end
498             else
499             begin
500               if j = ss.count - 1 then
501               begin
502                 ReplaceText := ReplaceText + items.Content;
503                 goto jump;
504               end
505               else
506                 break;
507             end
508           else if i = s.count - 1 then
509             goto jump;
510     jump:
511       DataModule1.FDTable2.Next;
512     end;
513   end;
514
515 begin
516   if TagString = 'pr' then
517     ReplaceText := promotion
518   else if (Request.MethodType = mtPost) and (TagString = 'items') then
519   begin
520     if Request.ContentFields.Values['type'] = 'OR' then
521       Self.Tag := 0
522     else
523       Self.Tag := 1;
524     s := TStringList.Create;
525     ss := TStringList.Create;
526     try
527       ss.Delimiter := ' ';
528       ss.StrictDelimiter := false;
529       if Request.QueryFields.Values['db'] = '' then
530       begin
531         DataModule1.FDTable1.First;
532         while DataModule1.FDTable1.Eof = false do
533         begin
534           sub;
535           DataModule1.FDTable1.Next;
536         end;
537       end
538       else
539         sub;
540     finally
541       s.Free;
542       ss.Free;
543     end;
544   end
545   else if TagString = 'query' then
546   begin
547     ReplaceText := Request.Query;
548     if ReplaceText <> '' then
549       ReplaceText := '?' + ReplaceText;
550   end
551   else if TagString = 'css' then
552     ReplaceText := css2.Content;
553 end;
554
555 procedure TWebModule1.setLastArticle;
556 begin
557   {
558     if isInfo(false) = true then
559     DataModule1.FDTable2.First
560     else
561   }
562   DataModule1.FDTable2.Last;
563 end;
564
565 procedure TWebModule1.strsCheck(var Error: string; var list: TStringList);
566 var
567   s: TStringList;
568   i, j: Integer;
569   x: Boolean;
570 begin
571   x := false;
572   s := TStringList.Create;
573   try
574     s.DelimitedText := DataModule1.FDTable3.FieldByName('ng').AsString;
575     for i := 0 to s.count - 1 do
576       for j := 0 to list.count - 1 do
577       begin
578         if Pos(s[i], list[j]) > 0 then
579           x := true;
580         list[j] := '<p>' + list[j];
581       end;
582   finally
583     s.Free;
584   end;
585   if x = true then
586     Error := Error + '<p>\8bÖ\8e~\8cê\8bå\82ª\8aÜ\82Ü\82ê\82Ä\82¢\82Ü\82·.';
587 end;
588
589 procedure TWebModule1.tiHTMLTag(Sender: TObject; Tag: TTag;
590   const TagString: string; TagParams: TStrings; var ReplaceText: string);
591 begin
592   if TagString = 'count' then
593     ReplaceText := DataModule1.FDTable2.RecordCount.ToString
594   else if TagString = 'database' then
595     ReplaceText := DataModule1.FDTable1.FieldByName('database').AsString
596   else if TagString = 'date' then
597     with DataModule1.FDTable2 do
598     begin
599       Last;
600       ReplaceText := FieldByName('date').AsString;
601     end;
602 end;
603
604 procedure TWebModule1.titleHTMLTag(Sender: TObject; Tag: TTag;
605   const TagString: string; TagParams: TStrings; var ReplaceText: string);
606 begin
607   if TagString = 'pr' then
608     ReplaceText := promotion
609   else if TagString = 'js' then
610     ReplaceText := detail(TagString, TagParams.Values['id'])
611   else if TagString = 'main' then
612     with DataModule1 do
613     begin
614       FDQuery1.Open;
615       FDTable1.First;
616       while FDQuery1.Eof = false do
617       begin
618         if FDTable1.FieldByName('dbnum').AsInteger = FDQuery1.FieldByName
619           ('dbnum').AsInteger then
620         begin
621           ReplaceText := ReplaceText + ti.Content;
622           FDQuery1.Next;
623         end
624         else if FDTable2.Eof = false then
625         begin
626           ti.DataSet := nil;
627           try
628             ReplaceText := ReplaceText + ti.Content;
629           finally
630             ti.DataSet := FDQuery1;
631           end;
632         end;
633         FDTable1.Next;
634       end;
635       FDQuery1.Close;
636     end;
637 end;
638
639 procedure TWebModule1.topHTMLTag(Sender: TObject; Tag: TTag;
640   const TagString: string; TagParams: TStrings; var ReplaceText: string);
641 var
642   s, t: string;
643   i, j, k: Integer;
644 begin
645   if TagString = 'pr' then
646     ReplaceText := promotion
647   else if TagString = 'list' then
648   begin
649     i := DataModule1.FDTable3.FieldByName('info').AsInteger;
650     for k := 0 to tcnt do
651     begin
652       if DataModule1.FDTable1.Eof = true then
653         break;
654       t := '';
655       j := DataModule1.FDTable1.FieldByName('dbnum').AsInteger;
656       s := DataModule1.FDTable1.FieldByName('database').AsString;
657       if (i = j) or (s = 'master') then
658       begin
659         DataModule1.FDTable1.Next;
660         continue;
661       end;
662       DataModule1.FDTable2.Last;
663       if (Now - DataModule1.FDTable2.FieldByName('date').AsDateTime < 1) and
664         (DataModule1.FDTable2.RecordCount > 0) then
665         t := 'background-color:aqua;';
666       if DataModule1.FDTable2.RecordCount >= 10 *
667         DataModule1.FDTable3.FieldByName('count').AsInteger then
668         t := t + 'color:red;';
669       if t <> '' then
670         t := ' style=' + t;
671       ReplaceText := ReplaceText +
672         Format('<p><a%s target=_blank href="/index?db=%d">%s</a><br></p>',
673         [t, j, s]);
674       DataModule1.FDTable1.Next;
675     end;
676   end
677   else if TagString = 'info' then
678     ReplaceText := DataModule1.FDTable1.Lookup('dbnum',
679       DataModule1.FDTable3.FieldByName('info').AsInteger, 'database')
680   else if TagString = 'dbnum' then
681     ReplaceText := DataModule1.FDTable3.FieldByName('info').AsString
682   else if (TagString = 'css') or (TagString = 'js') then
683     ReplaceText := detail(TagString, TagParams.Values['id'])
684   else if TagString = 'slide' then
685   begin
686     for i := 1 to (DataModule1.FDTable1.RecordCount div tcnt) + 1 do
687       ReplaceText := ReplaceText +
688         '<div class="slide"><img src="/src?name=slide' + i.ToString +
689         '.jpg" style=float:right;height:465px><#list></div>';
690   end;
691 end;
692
693 procedure TWebModule1.WebModule1admdelAction(Sender: TObject;
694   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
695 var
696   i, j, k, m: Integer;
697   reg: TRegEx;
698   match: TMatch;
699 begin
700   j := 0;
701   DataModule1.FDTable2.RecNo := admin.Tag;
702   for i := 0 to Request.ContentFields.count - 1 do
703   begin
704     reg := TRegEx.Create('\d+');
705     match := reg.match(Request.ContentFields[i]);
706     if match.Success = true then
707     begin
708       k := match.Value.ToInteger - j - 1;
709       j := match.Value.ToInteger;
710       for m := 1 to k do
711         DataModule1.FDTable2.Next;
712       DataModule1.FDTable2.Delete;
713     end;
714   end;
715   WebModule1adminAction(nil, Request, Response, Handled);
716 end;
717
718 procedure TWebModule1.WebModule1adminAction(Sender: TObject;
719   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
720 var
721   s, t: string;
722   i: Integer;
723 begin
724   s := Request.CookieFields.Values['user'];
725   if (s = '') or (loginCheck = false) then
726   begin
727     WebModule1loginAction(nil, Request, Response, Handled);
728     Exit;
729   end;
730   admin.MaxRows := DataModule1.FDTable3.FieldByName('count').AsInteger;
731   t := Request.QueryFields.Values['db'];
732   if t <> '' then
733     DataModule1.FDTable1.Locate('dbnum', t, []);
734   s := Request.QueryFields.Values['num'];
735   i := StrToIntDef(s, -1);
736   pages(DataModule1.FDTable2.RecordCount, i);
737   index.Tag := i;
738   tagstr := '/admin';
739   Self.Tag := Integer(@tagstr);
740   admin.header.Text := adhead.Content;
741   admin.footer.Clear;
742   admin.footer.Add
743     ('<input type=submit value=\8dí\8f\9c\82·\82é><input type=reset value=\83\8a\83Z\83b\83g></form>');
744   admin.footer.Add(footer.Content);
745   if t <> '' then
746     t := '?db=' + t;
747   admin.footer.Add('<p style=text-align:center><a href="/index' + t +
748     '">\96ß\82é</a>');
749   admin.Tag := DataModule1.FDTable2.RecNo;
750   Response.ContentType := 'text/html;charset=utf-8';
751   Response.Content := admin.Content;
752 end;
753
754 procedure TWebModule1.WebModule1adminsetAction(Sender: TObject;
755   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
756 var
757   s: string;
758 begin
759   s := Request.ContentFields.Values['pass'];
760   with DataModule1.FDTable3 do
761   begin
762     Edit;
763     FieldByName('mente').AsBoolean := Request.ContentFields.Values
764       ['mente'] = 'on';
765     if s <> '' then
766     begin
767       s := hash(s);
768       FieldByName('password').AsString := hash(s);
769       with Response.Cookies.Add do
770       begin
771         Name := 'user';
772         Value := s;
773         Expires := Now + 14;
774         Secure := true;
775       end;
776     end;
777     Post;
778   end;
779   WebModule1adminAction(nil, Request, Response, Handled);
780 end;
781
782 procedure TWebModule1.WebModule1alertAction(Sender: TObject;
783   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
784 var
785   num1, num2, i: Integer;
786   s: string;
787 begin
788   num1 := DataModule1.FDTable1.FieldByName('dbnum').AsInteger;
789   num2 := StrToIntDef(Request.QueryFields.Values['num'], -1);
790   if num2 = -1 then
791     num1 := -1;
792   if Request.MethodType = mtGet then
793   begin
794     DataModule1.FDTable2.Locate('number', num2, []);
795     Response.ContentType := 'text/html;charset=utf-8';
796     Response.Content := mail.Content;
797   end
798   else
799   begin
800     with DataModule1.FDTable4 do
801     begin
802       Last;
803       i := FieldByName('id').AsInteger + 1;
804       s := Request.ContentFields.Values['request'];
805       if s = '' then
806         s := '(No Comment)';
807       AppendRecord([i, num1, num2, Now, s]);
808     end;
809     if num1 > -1 then
810       Response.SendRedirect(Format('/index?db=%d&num=%d#%d',
811         [num1, num2, num2]))
812     else
813       Response.SendRedirect('/top');
814   end;
815 end;
816
817 procedure TWebModule1.WebModule1deleteAction(Sender: TObject;
818   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
819 var
820   num: Integer;
821   s: string;
822 begin
823   s := Request.ContentFields.Values['num'];
824   if s = '' then
825     Exit;
826   num := s.ToInteger;
827   s := hash(Request.ContentFields.Values['password']);
828   with DataModule1.FDTable2 do
829     if Locate('number;pass', VarArrayOf([num, s])) = true then
830     begin
831       Edit;
832       FieldByName('title').AsString := '';
833       FieldByName('name').AsString := ' - - - ';
834       FieldByName('comment').AsString := '<em>\93\8a\8de\8eÒ\82É\82æ\82è\8dí\8f\9c\82³\82ê\82Ü\82µ\82½.</em>';
835       FieldByName('raw').AsString := '';
836       FieldByName('date').AsDateTime := Now;
837       Post;
838       WebModule1jumpAction(nil, Request, Response, Handled);
839     end
840     else
841       WebModule1indexpageAction(nil, Request, Response, Handled);
842 end;
843
844 procedure TWebModule1.WebModule1fileAction(Sender: TObject;
845   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
846 var
847   s: string;
848 begin
849   s := Request.QueryFields.Values['type'];
850   if s = 'js' then
851     Response.ContentType := 'text/javascript'
852   else if s = 'css' then
853     Response.ContentType := 'text/css';
854   Response.Content := detail(s, Request.QueryFields.Values['id']);
855 end;
856
857 procedure TWebModule1.WebModule1helpAction(Sender: TObject;
858   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
859 var
860   k: Integer;
861   s: string;
862 begin
863   Response.ContentType := 'text/html;charset=utf-8';
864   if Request.MethodType = mtPost then
865   begin
866     s := Request.ContentFields.Values['help'];
867     DataModule1.FDTable4.Last;
868     k := DataModule1.FDTable4.FieldByName('id').AsInteger + 1;
869     DataModule1.FDTable4.AppendRecord([k, -1, -1, Now, s]);
870     help.Tag := 1;
871   end
872   else
873     help.Tag := 0;
874   Response.Content := help.Content;
875 end;
876
877 procedure TWebModule1.WebModule1imgAction(Sender: TObject; Request: TWebRequest;
878   Response: TWebResponse; var Handled: Boolean);
879 var
880   s: string;
881   res: TResourceStream;
882 begin
883   with DataModule1.FDTable5 do
884   begin
885     s := Request.ContentFields.Values['name'];
886     Response.ContentType := 'image/jpeg';
887     if Locate('name', s) = true then
888       Response.ContentStream := CreateBlobStream(FieldByName('source'), bmRead)
889     else if s = 'sprites.png' then
890     begin
891       Response.ContentType := 'image/png';
892       res := TResourceStream.Create(HInstance, 'PngImage_1', RT_RCDATA);
893       Response.ContentStream := res;
894     end
895     else
896       Response.ContentStream := nil;
897   end;
898 end;
899
900 procedure TWebModule1.WebModule1indexpageAction(Sender: TObject;
901   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
902 var
903   i: Integer;
904   s: string;
905 begin
906   s := Request.QueryFields.Values['db'];
907   if s <> '' then
908     DataModule1.FDTable1.Locate('dbnum', s, []);
909   i := StrToIntDef(Request.QueryFields.Values['num'], -1);
910   isInfo;
911   pages(DataModule1.FDTable2.RecordCount, i);
912   index.Tag := i;
913   tagstr := '/index';
914   Self.Tag := Integer(@tagstr);
915   Response.ContentType := 'text/html; charset="utf-8"';
916   if mente = false then
917     Response.Content := index.Content;
918 end;
919
920 procedure TWebModule1.WebModule1jumpAction(Sender: TObject;
921   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
922 var
923   DB, s: string;
924   page: Integer;
925 begin
926   DB := Request.QueryFields.Values['db'];
927   s := Request.ContentFields.Values['num'];
928   if DB <> '' then
929     DataModule1.FDTable1.Locate('dbnum', DB.ToInteger, []);
930   DataModule1.FDTable2.Locate('number', s.ToInteger, []);
931   page := 10;
932   pages(DataModule1.FDTable2.RecNo, page);
933   Response.SendRedirect(Format('/index?db=%s&num=%d#%s', [DB, page, s]));
934 end;
935
936 procedure TWebModule1.WebModule1linkAction(Sender: TObject;
937   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
938 var
939   num: Integer;
940   s: string;
941 begin
942   s := Request.QueryFields.Values['num'];
943   if s = '' then
944     Exit;
945   num := s.ToInteger;
946   if DataModule1.FDTable2.Locate('number', num, []) = true then
947   begin
948     Response.ContentType := 'text/html;charset=utf-8';
949     Response.Content := articles.Content;
950   end;
951 end;
952
953 procedure TWebModule1.WebModule1loginAction(Sender: TObject;
954   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
955 var
956   v: Variant;
957   i: Integer;
958   s: string;
959 begin
960   if Request.MethodType = mtGet then
961   begin
962     Response.ContentType := 'text/html;charset=utf-8';
963     Response.Content := login.Content;
964     Exit;
965   end;
966   s := Request.ContentFields.Values['record'];
967   v := DataModule1.FDTable1.Lookup('database', s, 'dbnum');
968   if VarIsNull(v) = false then
969   begin
970     with Response.Cookies.Add do
971     begin
972       Name := 'user';
973       Value := hash(Request.ContentFields.Values['password']);
974       Expires := Now + 14;
975       // Secure := true;
976     end;
977     i := v;
978     if s = 'master' then
979       Response.SendRedirect('/master')
980     else
981       Response.SendRedirect('/admin?db=' + i.ToString);
982   end
983   else
984   begin
985     Response.ContentType := 'text/html;charset=utf-8';
986     Response.Content := login.Content;
987   end;
988 end;
989
990 procedure TWebModule1.WebModule1logoutAction(Sender: TObject;
991   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
992 var
993   i: Integer;
994   s: string;
995   x: Boolean;
996 begin
997   with Response.Cookies.Add do
998   begin
999     Name := 'user';
1000     Expires := Now - 1;
1001   end;
1002   s := Request.QueryFields.Values['db'];
1003   i := StrToIntDef(s, -1);
1004   x := DataModule1.FDTable1.Locate('dbnum', i);
1005   if (x = true) and (DataModule1.FDTable1.FieldByName('database')
1006     .AsString = 'master') then
1007     x := false;
1008   if x = false then
1009     Response.SendRedirect('/')
1010   else
1011     Response.SendRedirect('/index?db=' + s);
1012 end;
1013
1014 procedure TWebModule1.WebModule1masterAction(Sender: TObject;
1015   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
1016 var
1017   s: string;
1018   i: Integer;
1019 begin
1020   if loginCheck = false then
1021   begin
1022     with DataModule1.FDTable1 do
1023       if Locate('database', 'master') = false then
1024       begin
1025         Last;
1026         i := FieldByName('dbnum').AsInteger + 1;
1027         AppendRecord([i, 'master']);
1028       end;
1029     WebModule1loginAction(nil, Request, Response, Handled);
1030     Exit;
1031   end;
1032   if Request.MethodType = mtPost then
1033   begin
1034     s := Request.ContentFields.Values['delete'];
1035     if s = 'all' then
1036       with DataModule1.FDTable4 do
1037         while (Bof = false) or (Eof = false) do
1038           Delete
1039     else
1040     begin
1041       DataModule1.FDTable4.First;
1042       while DataModule1.FDTable4.Eof = false do
1043       begin
1044         i := DataModule1.FDTable4.FieldByName('dbname').AsInteger;
1045         if DataModule1.FDTable1.Locate('dbnum', i) = true then
1046         begin
1047           i := DataModule1.FDTable4.FieldByName('posnum').AsInteger;
1048           if DataModule1.FDTable2.Locate('number', i) = false then
1049             DataModule1.FDTable4.Delete
1050           else
1051             DataModule1.FDTable4.Next;
1052         end
1053         else
1054           DataModule1.FDTable4.Delete;
1055       end;
1056     end;
1057   end;
1058   Response.ContentType := 'text/html;charset=utf-8';
1059   Response.Content := master.Content;
1060 end;
1061
1062 procedure TWebModule1.WebModule1registAction(Sender: TObject;
1063   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
1064 var
1065   number, i: Integer;
1066   title, na, raw, pass, kotoba, Error: string;
1067   comment: TStringList;
1068   function scan(Text: string): string;
1069   var
1070     reg: TRegEx;
1071     coll: TMatchCollection;
1072     j: Integer;
1073     s, t: string;
1074   begin
1075     Text := TNetEncoding.HTML.Encode(Text);
1076     s := TNetEncoding.HTML.Encode('>>');
1077     reg := TRegEx.Create(s + '(\d+)');
1078     coll := reg.Matches(Text);
1079     for j := coll.count - 1 downto 0 do
1080     begin
1081       Delete(Text, coll[j].index, coll[j].Length);
1082       t := Copy(coll[j].Value, Length(s) + 1, coll[j].Length);
1083       result := Format
1084         ('<a class=minpreview data-preview-url=/link?num=%s href=/jump?num=%s>>>%s</a>',
1085         [t, t, t]);
1086       Insert(result, Text, coll[j].index);
1087     end;
1088     result := Text;
1089   end;
1090
1091 begin
1092   kotoba := Request.ContentFields.Values['aikotoba'];
1093   Error := '';
1094   if kotoba <> '\82°\82ñ\82«' then
1095     Error := Error + '<p>\8d\87\8c¾\97t\82ª\82¿\82ª\82¢\82Ü\82·.';
1096   setLastArticle;
1097   number := DataModule1.FDTable2.FieldByName('number').AsInteger + 1;
1098   with Request.ContentFields do
1099   begin
1100     title := Values['title'];
1101     na := Values['name'];
1102     raw := Values['comment'];
1103     pass := hash(Values['password']);
1104   end;
1105   if title = '' then
1106     title := '\83^\83C\83g\83\8b\82È\82µ.';
1107   with Response.Cookies.Add do
1108   begin
1109     Name := 'name';
1110     if na = '' then
1111       Value := '\92N\82©\82³\82ñ.'
1112     else
1113       Value := na;
1114     Expires := Now + 14;
1115   end;
1116   if Error = '' then
1117     with Response.Cookies.Add do
1118     begin
1119       Name := 'aikotoba';
1120       Value := kotoba;
1121       Expires := Now + 14;
1122     end;
1123   comment := TStringList.Create;
1124   try
1125     comment.Text := raw;
1126     strsCheck(Error, comment);
1127     Request.ContentFields.Values['raw'] := raw;
1128     if Error <> '' then
1129       Request.ContentFields.Values['preview'] := '<section style=color:red>' +
1130         Error + '</section>'
1131     else if Request.ContentFields.Values['show'] = 'true' then
1132     begin
1133       Error := '<p style=font-size:2.3em;color:blue>\81«\81«\83v\83\8c\83r\83\85\81[\81«\81«<p>' +
1134         comment.Text;
1135       Request.ContentFields.Values['preview'] := Error;
1136       Request.ContentFields.Values['show'] := 'false';
1137     end
1138     else
1139     begin
1140       i := DataModule1.FDTable1.FieldByName('dbnum').AsInteger;
1141       DataModule1.FDTable2.AppendRecord([i, number, title, na, comment.Text,
1142         raw, Now, pass]);
1143       Response.SendRedirect('index?db=' + i.ToString + '#article');
1144       Exit;
1145     end;
1146   finally
1147     comment.Free;
1148   end;
1149   WebModule1indexpageAction(nil, Request, Response, Handled);
1150 end;
1151
1152 procedure TWebModule1.WebModule1searchAction(Sender: TObject;
1153   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
1154 begin
1155   Response.ContentType := 'text/html;charset=utf-8';
1156   Response.Content := search.Content;
1157 end;
1158
1159 procedure TWebModule1.WebModule1titleAction(Sender: TObject;
1160   Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
1161 begin
1162   Response.ContentType := 'text/html;charset=utf-8';
1163   Response.Content := title.Content;
1164 end;
1165
1166 procedure TWebModule1.WebModule1topAction(Sender: TObject; Request: TWebRequest;
1167   Response: TWebResponse; var Handled: Boolean);
1168 begin
1169   Response.ContentType := 'text/html;charset=utf-8';
1170   DataModule1.FDTable1.First;
1171   if mente = false then
1172     Response.Content := top.ContentFromString(top.Content);
1173 end;
1174
1175 procedure TWebModule1.WebModuleCreate(Sender: TObject);
1176 var
1177   i: Integer;
1178   a: Variant;
1179   s: string;
1180 begin
1181   with DataModule1 do
1182   begin
1183     if FDTable1.Exists = false then
1184       FDTable1.CreateTable;
1185     if FDTable2.Exists = false then
1186       FDTable2.CreateTable;
1187     if FDTable3.Exists = false then
1188       FDTable3.CreateTable;
1189     if FDTable4.Exists = false then
1190       FDTable4.CreateTable;
1191     if FDTable5.Exists = false then
1192       FDTable5.CreateTable;
1193     FDTable1.Open;
1194     FDTable2.Open;
1195     FDTable3.Open;
1196     FDTable4.Open;
1197     FDTable5.Open;
1198     FDTable1.Refresh;
1199     FDTable3.Refresh;
1200     FDTable5.Refresh;
1201   end;
1202   if DataModule1.FDTable1.Bof and DataModule1.FDTable1.Eof then
1203   begin
1204     DataModule1.FDTable1.AppendRecord([0, 'info']);
1205     for i := 1 to 10 do
1206       DataModule1.FDTable1.AppendRecord([i, '\8cf\8e¦\94Â' + i.ToString]);
1207   end;
1208   if DataModule1.FDTable3.Bof and DataModule1.FDTable3.Eof then
1209   begin
1210     a := DataModule1.FDTable1.Lookup('database', 'info', 'dbnum');
1211     s := '\88¢\95Û,\94n\8e­,\8e\80\82Ë';
1212     DataModule1.FDTable3.AppendRecord
1213       (['\82Æ\82é\82Ë\81`\82Ç\8d\86',
1214       '<h1 style=color:maron;text-align:center;font-style:italic>\82Æ\82é\82Ë\81`\82Ç\8d\86</h1>',
1215       false, a, 30, hash(hash('admin')), s]);
1216   end;
1217 end;
1218
1219 end.