OSDN Git Service

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