OSDN Git Service

・プラグインメニューを追加。
[gikonavigoeson/gikonavi.git] / ExternalBoardPlugInMain.pas
1 unit ExternalBoardPlugInMain;
2
3 interface
4
5 uses
6         Windows, Classes, SysUtils, Menus,
7         IdHTTP, IdComponent, IdGlobal, IdException,
8         AbonUnit;
9
10 type
11
12         // \83_\83E\83\93\83\8d\81[\83h\82ª\90¬\8c÷\82µ\82½\82©\82Ç\82¤\82©
13         TDownloadState = (dsWait, dsWork, dsComplete, dsDiffComplete, dsNotModify, dsAbort, dsError);
14
15         // \8ew\92è\82µ\82½ URL \82ð\82±\82Ì\83v\83\89\83O\83C\83\93\82Å\8eó\82¯\95t\82¯\82é\82©\82Ç\82¤\82©
16         TAcceptType = (atNoAccept, atBBS, atBoard, atThread);
17
18         // \83\81\83j\83\85\81[\83n\83\93\83h\83\89
19         TMenuHandler    = procedure(
20                 inHandle : HMENU                                        // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
21         ); stdcall;
22
23         // *************************************************************************
24         // \83v\83\89\83O\83C\83\93\82ª(\90³\82µ\82­)\83\8d\81[\83h\82³\82ê\82½
25         // *************************************************************************
26         TOnLoad = procedure (
27                 inInstance : DWORD                              // \83v\83\89\83O\83C\83\93\82Ì\83C\83\93\83X\83^\83\93\83X
28         ); stdcall;
29
30         // *************************************************************************
31         // \83v\83\89\83O\83C\83\93\82Ì\83o\81[\83W\83\87\83\93
32         // *************************************************************************
33         TOnVersionInfo = procedure(
34                 var outAgent            : PChar;        // \83o\81[\83W\83\87\83\93\82ð\88ê\90Ø\8aÜ\82Ü\82È\82¢\8f\83\90\88\82È\96¼\8fÌ
35                 var outMajor            : DWORD;        // \83\81\83W\83\83\81[\83o\81[\83W\83\87\83\93
36                 var outMinor            : DWORD;        // \83}\83C\83i\81[\83o\81[\83W\83\87\83\93
37                 var outRelease  : PChar;        // \83\8a\83\8a\81[\83X\92i\8aK\96¼
38                 var outRevision : DWORD         // \83\8a\83r\83W\83\87\83\93\83i\83\93\83o\81[
39         ); stdcall;
40
41         // *************************************************************************
42         // \8ew\92è\82µ\82½ URL \82ð\82±\82Ì\83v\83\89\83O\83C\83\93\82Å\8eó\82¯\95t\82¯\82é\82©\82Ç\82¤\82©
43         // *************************************************************************
44         TOnAcceptURL = function(
45                 inURL : PChar                                           // \94»\92f\82ð\8bÂ\82¢\82Å\82¢\82é URL
46         ): TAcceptType; stdcall;        // URL \82Ì\8eí\97Þ
47
48         // *************************************************************************
49         // \83\81\83j\83\85\81[\83n\83\93\83h\83\89
50         // *************************************************************************
51         TOnPlugInMenu = procedure(
52                 inInstance : DWORD              // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
53         ); stdcall;
54
55         // *************************************************************************
56         // \83X\83\8c\88ê\97\97\82Ì URL \82©\82ç\83X\83\8c\83b\83h\82Ì URL \82ð\93±\82«\8fo\82·
57         // *************************************************************************
58         TOnListURL2ThreadURL = function(
59                 inListURL               : PChar;        // \83X\83\8c\88ê\97\97\82ð\8e¦\82µ\82½ URL
60                 inFileName      : PChar         // \83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
61         ) : PChar; stdcall;                     // \83X\83\8c\83b\83h\82Ì URL
62
63 function CreateResultString(
64         resultStr : string
65 ) : PChar; stdcall;
66
67 procedure DisposeResultString(
68         resultStr : PChar
69 ); stdcall;
70
71 implementation
72
73 uses ExternalBoardManager, ExternalThreadItem, GikoSystem, BoardGroup, Giko;
74
75 // *************************************************************************
76 // \96ß\82è\92l\82ª PChar \82Å\82 \82é API \82Ì\83\81\83\82\83\8a\82ð\8am\95Û\82·\82é
77 // *************************************************************************
78 function CreateResultString(
79         resultStr : string
80 ) : PChar; stdcall;
81 var
82         tmp : PChar;
83 begin
84
85         tmp := PChar( resultStr );
86         GetMem( Result, Length( tmp ) + 1 );
87         Move( tmp^, Result^, Length( tmp ) + 1 );
88
89 end;
90
91 // *************************************************************************
92 // \96ß\82è\92l\82ª PChar \82Å\82 \82é API \82Ì\83\81\83\82\83\8a\82ð\8aJ\95ú\82·\82é
93 // *************************************************************************
94 procedure DisposeResultString(
95         resultStr : PChar
96 ); stdcall;
97 begin
98
99         FreeMem( resultStr );
100
101 end;
102
103 // *************************************************************************
104 // \83v\83\8d\83O\83\89\83\80\96{\91Ì\82Ì\83o\81[\83W\83\87\83\93\82ð\8eæ\93¾\82·\82é
105 // *************************************************************************
106 procedure VersionInfo(
107         var outAgent            : PChar;        // \83o\81[\83W\83\87\83\93\82ð\88ê\90Ø\8aÜ\82Ü\82È\82¢\8f\83\90\88\82È\96¼\8fÌ
108         var outMajor            : DWORD;        // \83\81\83W\83\83\81[\83o\81[\83W\83\87\83\93
109         var outMinor            : DWORD;        // \83}\83C\83i\81[\83o\81[\83W\83\87\83\93
110         var outRelease  : PChar;        // \83\8a\83\8a\81[\83X\92i\8aK\96¼
111         var outRevision : DWORD         // \83\8a\83r\83W\83\87\83\93\83i\83\93\83o\81[
112 ); stdcall;
113 begin
114
115         {$IFDEF DEBUG}
116         Writeln('ExternalBoardManager.VersionInfo');
117         {$ENDIF}
118         outAgent                := CreateResultString( PChar( APP_NAME ) );
119         outMajor                := 1;
120         outMinor                := 0;
121         outRelease      := CreateResultString( PChar( BETA_VERSION_NAME_E ) );
122         outRevision     := BETA_VERSION;
123
124 end;
125
126 // *************************************************************************
127 // \83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82·\82é
128 // *************************************************************************
129 procedure InternalPrint(
130         inMessage       : PChar // \83\81\83b\83Z\81[\83W
131 ); stdcall;
132 begin
133
134         GikoForm.AddMessageList( inMessage, nil, gmiWhat );
135
136 end;
137
138 // *************************************************************************
139 // \83f\83o\83b\83O\83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82·\82é
140 // *************************************************************************
141 procedure InternalDebugPrint(
142         inMessage       : PChar // \83\81\83b\83Z\81[\83W
143 ); stdcall;
144 begin
145
146         {$IFDEF DEBUG}
147         Writeln( inMessage );
148         {$ENDIF}
149
150 end;
151
152 // *************************************************************************
153 // \83\\83P\83b\83g\82ð\8f\89\8aú\89»\82·\82é(\8eG\97p\8aÖ\90\94)
154 // *************************************************************************
155 procedure       InitializeSocket(
156         inSocket : TIdHTTP
157 );
158 begin
159
160         if inSocket <> nil then begin
161                 // \83C\83x\83\93\83g\82Ì\90Ý\92è
162                 if Assigned( OnWork ) then
163                         inSocket.OnWork                         := OnWork;
164                 if Assigned( OnWorkBegin ) then
165                         inSocket.OnWorkBegin    := OnWorkBegin;
166                 if Assigned( OnWorkEnd ) then
167                         inSocket.OnWorkEnd              := OnWorkEnd;
168
169                 // \92Ê\90M\82É\8aÖ\82·\82é\90Ý\92è
170                 inSocket.Request.CustomHeaders.Clear;
171                 inSocket.Response.Clear;
172                 inSocket.Request.Clear;
173
174                 inSocket.Request.UserAgent      := GikoSys.GetUserAgent;
175                 inSocket.RecvBufferSize                 := Gikosys.Setting.RecvBufferSize;
176                 inSocket.ProxyParams.BasicAuthentication := False;
177                 {$IFDEF DEBUG}
178                 Writeln('------------------------------------------------------------');
179                 {$ENDIF}
180                 //inSocket.AllowCookies := False;
181                 if GikoSys.Setting.ReadProxy then begin
182                         if GikoSys.Setting.ProxyProtocol then
183                                 inSocket.ProtocolVersion := pv1_1
184                         else
185                                 inSocket.ProtocolVersion := pv1_0;
186                         inSocket.ProxyParams.ProxyServer                := GikoSys.Setting.ReadProxyAddress;
187                         inSocket.ProxyParams.ProxyPort                  := GikoSys.Setting.ReadProxyPort;
188                         inSocket.ProxyParams.ProxyUsername      := GikoSys.Setting.ReadProxyUserID;
189                         inSocket.ProxyParams.ProxyPassword      := GikoSys.Setting.ReadProxyPassword;
190                         if GikoSys.Setting.ReadProxyUserID <> '' then
191                                 inSocket.ProxyParams.BasicAuthentication := True;
192                         {$IFDEF DEBUG}
193                         Writeln('\83v\83\8d\83L\83V\90Ý\92è\82 \82è');
194                         Writeln('\83z\83X\83g: ' + GikoSys.Setting.ReadProxyAddress);
195                         Writeln('\83|\81[\83g: ' + IntToStr( GikoSys.Setting.ReadProxyPort ));
196                         {$ENDIF}
197                 end else begin
198                         if GikoSys.Setting.Protocol then
199                                 inSocket.ProtocolVersion := pv1_1
200                         else
201                                 inSocket.ProtocolVersion := pv1_0;
202                         inSocket.ProxyParams.ProxyServer                := '';
203                         inSocket.ProxyParams.ProxyPort                  := 80;
204                         inSocket.ProxyParams.ProxyUsername      := '';
205                         inSocket.ProxyParams.ProxyPassword      := '';
206                         {$IFDEF DEBUG}
207                         Writeln('\83v\83\8d\83L\83V\90Ý\92è\82È\82µ');
208                         {$ENDIF}
209                 end;
210         end;
211
212 end;
213
214 // *************************************************************************
215 // \8ew\92è\82µ\82½ URL \82ð\83_\83E\83\93\83\8d\81[\83h\82µ\82Ä\95Ô\82·
216 // *************************************************************************
217 function InternalDownload(
218         inURL                                                   : PChar;        // \83_\83E\83\93\83\8d\81[\83h\82·\82é URL
219         var ioModified          : Double;       // \8dÅ\8cã\82É\8eæ\93¾\82µ\82½\93ú\8e\9e
220         var outResultData       : PChar;        // \83_\83E\83\93\83\8d\81[\83h\82³\82ê\82½\95\8e\9a\97ñ
221         inRangeStart                    : DWORD;        // \8aJ\8en\88Ê\92u
222         inRangeEnd                              : DWORD         // \8fI\97¹\88Ê\92u
223 ) : Longint; stdcall;                                   // \83\8c\83X\83|\83\93\83X\83R\81[\83h
224 var
225         httpSocket                              : TIdHTTP;
226         resStream                                       : TMemoryStream;
227         content                                         : string;
228 begin
229
230         {$IFDEF DEBUG}
231         Writeln('ExternalBoardManager.InternalDownload');
232         {$ENDIF}
233         Result := -1;
234
235         httpSocket := TIdHTTP.Create( nil );
236         try
237                 InitializeSocket( httpSocket );
238
239                 httpSocket.Request.ContentRangeStart    := inRangeStart;
240                 httpSocket.Request.ContentRangeEnd              := inRangeEnd;
241                 if (ioModified <> 0) and (ioModified <> ZERO_DATE) then
242                         httpSocket.Request.LastModified := ioModified - OffsetFromUTC;
243                 if inRangeStart = 0 then
244                         httpSocket.Request.AcceptEncoding := 'gzip'
245                 else
246                         httpSocket.Request.AcceptEncoding := '';
247                 httpSocket.Request.Accept := 'text/html';
248
249                 resStream := TMemoryStream.Create;
250                 try
251                         try
252                                 resStream.Clear;
253
254                                 {$IFDEF DEBUG}
255                                 Writeln('URL: ' + inURL);
256                                 {$ENDIF}
257                                 httpSocket.Get( inURL, resStream );
258                                 {$IFDEF DEBUG}
259                                 Writeln('\8eæ\93¾\82Å\97á\8aO\82È\82µ');
260                                 {$ENDIF}
261
262                                 content                 := GikoSys.GzipDecompress( resStream, httpSocket.Response.ContentEncoding );
263                                 ioModified      := httpSocket.Response.LastModified;
264
265                                 Result := httpSocket.ResponseCode;
266                                 if (Length( content ) = 0) and (Result = 206) then
267                                         Result := 304;
268
269                                 outResultData := CreateResultString( content );
270                         except
271                                 on E: EIdSocketError do begin
272                                         ioModified              := ZERO_DATE;
273                                         outResultData   := nil;
274                                 end;
275                                 on E: EIdConnectException do begin
276                                         ioModified              := ZERO_DATE;
277                                         outResultData   := nil;
278                                         //Item.ErrText  := E.Message;
279                                 end;
280                                 on E: Exception do begin
281                                         {$IFDEF DEBUG}
282                                         Writeln('\8eæ\93¾\82Å\97á\8aO\82 \82è');
283                                         Writeln('E.Message: ' + E.Message);
284                                         {$ENDIF}
285                                         ioModified              := ZERO_DATE;
286                                         outResultData   := nil;
287                                         Result                          := httpSocket.ResponseCode;
288                                         //Item.ErrText  := E.Message;
289                                 end;
290                         end;
291                 finally
292                         resStream.Free;
293                 end;
294
295         finally
296                 httpSocket.Free;
297         end;
298
299 end;
300
301 // *************************************************************************
302 // \8ew\92è\82µ\82½ URL \82Ö\83f\81[\83^\82ð\91\97\90M\82·\82é
303 // *************************************************************************
304 function        InternalPost(
305         inURL                                                   : PChar;                        // \91\97\90M\82·\82é URL
306         inSource                                        : PChar;                        // \91\97\90M\82·\82é\93à\97e
307         var outResultData       : PChar                         // \95Ô\82Á\82Ä\82«\82½\95\8e\9a\97ñ
308 ) : Longint; stdcall;                                                   // \83\8c\83X\83|\83\93\83X\83R\81[\83h
309 var
310         httpSocket                              : TIdHTTP;
311         content                                         : string;
312         resStream                                       : TStringStream;
313         sourceStream                    : TStringStream;
314 begin
315
316         {$IFDEF DEBUG}
317         Writeln('ExternalBoardManager.InternalPost');
318         {$ENDIF}
319         Result := -1;
320
321         httpSocket := TIdHTTP.Create( nil );
322         try
323                 InitializeSocket( httpSocket );
324
325                 httpSocket.Request.CustomHeaders.Add('Pragma: no-cache');
326                 httpSocket.Request.AcceptLanguage       := 'ja';
327                 httpSocket.Request.Accept                                       := 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*';
328                 httpSocket.Request.ContentType          := 'application/x-www-form-urlencoded';
329
330                 resStream                       := TStringStream.Create( content );
331                 sourceStream    := TStringStream.Create( string( inSource ) );
332                 try
333                         try
334                                 {$IFDEF DEBUG}
335                                 Writeln('URL: ' + inURL);
336                                 Writeln('Source: ' + inSource);
337                                 {$ENDIF}
338                                 httpSocket.Post( string( inURL ), sourceStream, resStream );
339                                 {$IFDEF DEBUG}
340                                 Writeln('\8eæ\93¾\82Å\97á\8aO\82È\82µ');
341                                 {$ENDIF}
342
343                                 Result := httpSocket.ResponseCode;
344
345                                 outResultData := CreateResultString( resStream.DataString );
346                         except
347                                 on E: EIdSocketError do begin
348                                         outResultData   := nil;
349                                 end;
350                                 on E: EIdConnectException do begin
351                                         outResultData   := nil;
352                                 end;
353                                 on E: Exception do begin
354                                         {$IFDEF DEBUG}
355                                         Writeln('\8eæ\93¾\82Å\97á\8aO\82 \82è');
356                                         Writeln('E.Message: ' + E.Message);
357                                         {$ENDIF}
358                                         outResultData := CreateResultString( resStream.DataString );
359                                         Result                          := httpSocket.ResponseCode;
360                                 end;
361                         end;
362                 finally
363                         resStream.Free;
364                         sourceStream.Free;
365                 end;
366         finally
367                 httpSocket.Free;
368         end;
369
370 end;
371
372 // *************************************************************************
373 // \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e®\82ð\83\8d\81[\83J\83\8b\82 \82Ú\81`\82ñ\82É\92Ê\82·
374 // *************************************************************************
375
376 function InternalAbon(
377         inDatText : PChar;                      // \96¼\91O<>\83\81\81[\83\8b<>\93ú\95tID<>\96{\95¶<>[\89ü\8ds] \82Å\8d\\90¬\82³\82ê\82½\83e\83L\83X\83g
378         inDatPath       : PChar                         // dat \83t\83@\83C\83\8b\82Ì\83t\83\8b\83p\83X
379
380 ) : PChar; stdcall;                             // \82 \82Ú\81`\82ñ\8dÏ\82Ý\82Ì dat \8c`\8e®\83e\83L\83X\83g
381 var
382         datList : TStringList;
383                 FileName : String;
384 begin
385
386         datList := TStringList.Create;
387         datList.Text := string( inDatText );
388         FileName := string( inDatPath );
389         GikoSys.FAbon.IndividualAbon( datList, ChangeFileExt(FileName,'.NG'));
390         GikoSys.FAbon.Execute( datList );
391         GikoSys.FSelectResFilter.Execute( datList );
392
393         Result := CreateResultString( datList.Text );
394
395 end;
396 // *************************************************************************
397 // \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e®\82ð\83\8d\81[\83J\83\8b\82 \82Ú\81`\82ñ\82É\92Ê\82·
398 // \82½\82¾\82µ\81A\82P\83\8c\83X\82¸\82Â
399 // *************************************************************************
400
401 function InternalAbonForOne(
402         inDatText : PChar;              // \96¼\91O<>\83\81\81[\83\8b<>\93ú\95tID<>\96{\95¶<>[\89ü\8ds] \82Å\8d\\90¬\82³\82ê\82½\83e\83L\83X\83g
403         inDatPath       : PChar;                // dat \83t\83@\83C\83\8b\82Ì\83t\83\8b\83p\83X
404         inNo : Integer                          // \97v\8b\81\82³\82ê\82½\83\8c\83X\94Ô\8d\86
405 ) : PChar; stdcall;                     // \82 \82Ú\81`\82ñ\8dÏ\82Ý\82Ì dat \8c`\8e®\83e\83L\83X\83g
406 var
407         datString : String;
408                 FileName : String;
409 begin
410
411         datString := string( inDatText );
412         FileName := string( inDatPath );
413         GikoSys.FAbon.IndividualAbon( datString, ChangeFileExt(FileName,'.NG'), inNo);
414         GikoSys.FAbon.Execute( datString , inNo);
415         GikoSys.FSelectResFilter.Execute( datString , inNo );
416
417         Result := CreateResultString( datString );
418
419 end;
420
421 // *************************************************************************
422 // \82Q\82¿\82á\82ñ\82Ë\82é\82Ì dat \8c`\8e® 1 \8ds\82ð HTML \82É\95Ï\8a·\82·\82é
423 // *************************************************************************
424 function InternalDat2HTML(
425         inDatRes                : PChar;                // \96¼\91O<>\83\81\81[\83\8b<>\93ú\95tID<>\96{\95¶<> \82Å\8d\\90¬\82³\82ê\82½\83e\83L\83X\83g
426         inResNo                 : DWORD;                // \83\8c\83X\94Ô\8d\86
427         inIsNew                 : Boolean               // \90V\92\85\83\8c\83X\82È\82ç True
428 ) : PChar; stdcall;                             // \90®\8c`\82³\82ê\82½ HTML
429 var
430         board                           : TBoard;
431         threadItem      : TThreadItem;
432 begin
433
434         // \83_\83~\81[\82Ì\83N\83\89\83X
435         board                           := TBoard.Create( nil, 'about://dummy/' );
436         threadItem      := TThreadItem.Create( nil, 'about://dummy/test/read.cgi/dummy/' );
437         try
438                 try
439                         board.Add( threadItem );
440
441                         Result := ThreadItemDat2HTML( DWORD( threadItem ), inDatRes, inResNo, inIsNew );
442                 except
443                         Result := nil;
444                 end;
445         finally
446                 board.Free;
447         end;
448
449 end;
450
451 // *************************************************************************
452 // \83v\83\89\83O\83C\83\93\83\81\83j\83\85\81[\82É\8d\80\96Ú\82ð\92Ç\89Á
453 // *************************************************************************
454 function AddPlugInMenu(
455         inInstance      : DWORD;                // \83v\83\89\83O\83C\83\93\82Ì\83C\83\93\83X\83^\83\93\83X
456         inCaption       : PChar                         // \83\81\83j\83\85\81[\82É\95\\8e¦\82·\82é\95\8e\9a\97ñ
457 ) : HMENU; stdcall;                             // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b\81A\92Ç\89Á\82É\8e¸\94s\82µ\82½\8fê\8d\87\82Í NULL
458 var
459         newItem         : TMenuItem;
460 begin
461
462         try
463                 newItem                                 := TMenuItem.Create( nil );
464                 newItem.Caption := inCaption;
465                 newItem.Tag                     := inInstance;
466                 newItem.OnClick := GikoForm.OnPlugInMenuItem;
467                 GikoForm.PlugInMenu.Add( newItem );
468
469                 Result := newItem.Handle;
470         except
471                 Result := 0;
472         end;
473
474 end;
475
476 // *************************************************************************
477 // \83v\83\89\83O\83C\83\93\83\81\83j\83\85\81[\82©\82ç\8d\80\96Ú\82ð\8dí\8f\9c
478 // *************************************************************************
479 procedure RemovePlugInMenu(
480         inHandle        : HMENU                         // \83\81\83j\83\85\81[\83n\83\93\83h\83\8b
481 ); stdcall;
482 var
483         i                                       : Integer;
484 begin
485
486         for i := GikoForm.PlugInMenu.Count - 1 downto 0 do begin
487                 if GikoForm.PlugInMenu.Items[ i ].Handle = inHandle then begin
488                         GikoForm.PlugInMenu.Delete( i );
489                         Break;
490                 end;
491         end;
492
493 end;
494
495 exports
496         CreateResultString,
497         DisposeResultString,
498         VersionInfo,
499         InternalPrint,
500         InternalDebugPrint,
501         InternalDownload,
502         InternalPost,
503         InternalAbon,
504         InternalAbonForOne,
505         InternalDat2HTML,
506         AddPlugInMenu,
507         RemovePlugInMenu;
508
509 end.