home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 September
/
Chip_2001-09_cd1.bin
/
zkuste
/
delphi
/
nastroje
/
d5
/
MFTP.ZIP
/
src
/
FtpSearch.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2001-03-05
|
9KB
|
336 lines
unit FtpSearch;
interface
uses
Windows, SysUtils, Classes, Forms, WinINet, FtpData, FtpMisc;
{$I mftp.inc}
const
SearchTypeStr: Array[0..10] of String = (
'Case+insensitive+substring+search',
'Case+sensitive+substring+search',
'Case+insensitive+glob+search',
'Case+sensitive+glob+search',
'Regular+expression+search',
'Exact+search',
'Case+insensitive+substring+match',
'Case+sensitive+substring+match',
'Case+insensitive+glob+match',
'Case+sensitive+glob+match',
'Regular+expression+match');
type
{ C = case, I = insensitive, N = sensitive,
G = glob, E = Exact, X = expression,
S = search, M = match, R = Regular,
U = substring }
TMFtpSearchType = (mstCIUS, mstCNUS, mstCIGS, mstCNGS,
mstRXS, mstES, mstCIUM, mstCNUM,
mstCIGM, mstCNGM, mstEXM);
TMFtpDataEvent = procedure (Data: String) of object;
TMFtpSearchInfo = (searchStart, searchDone, searchFileFound);
TMFtpSearchInfoEvent = procedure (Sender: TObject; info: TMFtpSearchInfo; addinfo: String) of object;
TMFtpSearchThread = class(TThread)
private
FCache: Boolean;
FData: String;
FOnData: TMFtpDataEvent;
FPort: Integer;
FProxy: Boolean;
FRFile: String;
FServer: String;
FTag: Integer;
protected
procedure Execute; override;
property OnData: TMFtpDataEvent read FOnData write FOnData;
public
constructor Create(RemoteFile, Server: String; Port: Integer;
Cache, Proxy: Boolean);
property Tag: Integer read FTag write FTag;
end;
TMFtpSearch = class(TComponent)
private
FBusy: Boolean;
FCache: Boolean;
FFile: String;
FFiles: TMFtpFileInfoList;
FFromDate: String;
FMaxHit: Longword;
FMaxMatch: Longword;
FMaxSize: Longword;
FMinSize: Longword;
FProxy: Boolean;
FSearchInfoEvent: TMFtpSearchInfoEvent;
FServer: TStrings;
FToDate: String;
FType: TMFtpSearchType;
function BuildURL: String;
procedure Parse(L: TStringList);
procedure SetServer(S: TStrings);
procedure ThreadData(Data: String);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Search;
property Busy: Boolean read FBusy;
property Files: TMFtpFileInfoList read FFiles;
published
property Cache: Boolean read FCache write FCache;
property Filename: String read FFile write FFile;
property MaxHit: Longword read FMaxHit write FMaxHit;
property MaxMatch: Longword read FMaxMatch write FMaxMatch;
property MaxSize: Longword read FMaxSize write FMaxSize;
property MinSize: Longword read FMinSize write FMinSize;
property Proxy: Boolean read FProxy write FProxy;
property SearchType: TMFtpSearchType read FType write FType;
property Server: TStrings read FServer write SetServer;
property OnSearchInfo: TMFtpSearchInfoEvent read FSearchInfoEvent write FSearchInfoEvent;
end;
implementation
{ TMFtpSearchThread }
constructor TMFtpSearchThread.Create;
begin
FRFile := RemoteFile;
FServer := Server;
FPort := Port;
FCache := Cache;
FProxy := Proxy;
FData := '';
end;
procedure TMFtpSearchThread.Execute;
var FHandle, FHttpHandle, FRequest: HINTERNET;
DataLen: Longword;
Data: PChar;
begin
if FProxy then
FHandle := InternetOpen('MFtpINet', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0)
else
FHandle := InternetOpen('MFtpINet', INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0);
if FHandle = nil then
begin
OnData('');
Exit;
end;
FHttpHandle := InternetConnect(FHandle, PChar(FServer), FPort, '', '',
INTERNET_SERVICE_HTTP, 0, 0);
if FCache then
FRequest := HttpOpenRequest(FHttpHandle, nil, PChar(FRFile), nil, nil,
nil, 0, 0)
else
FRequest := HttpOpenRequest(FHttpHandle, nil, PChar(FRFile), nil, nil,
nil, INTERNET_FLAG_RELOAD, 0);
HttpSendRequest(FRequest, nil, 0, nil, 0);
GetMem(Data, 4097);
while True do
begin
if not InternetReadFile(FRequest, Data, 4096, DataLen) then
begin
Break;
end
else
begin
if DataLen = 0 then Break; // No more data to read
Data[DataLen] := Char(0);
FData := FData + StrPas(Data);
end;
end;
if Assigned(FOnData) then FOnData(FData);
FreeMem(Data);
InternetCloseHandle(FRequest);
InternetCloseHandle(FHttpHandle);
InternetCloseHandle(FHandle);
end;
{ TMFtpSearch }
constructor TMFtpSearch.Create;
begin
inherited Create(AOwner);
FServer := TStringList.Create;
FServer.Add('ftpsearch.lycos.com:80');
FFiles := TMFtpFileInfoList.Create;
FCache := True;
FMaxHit := 200;
FMaxMatch := 200;
end;
destructor TMFtpSearch.Destroy;
begin
FreeAndNil(FServer);
FFiles.MyFree;
inherited Destroy;
end;
function TMFtpSearch.BuildURL;
begin
Result := '/ftpsearch?query=' + PrepareURL(Trim(FFile)) + '&form=advanced' +
'&hits=' + IntToStr(FMaxHit) + '&matches=' + IntToStr(FMaxMatch) +
'&doit=Search&f1=Count&f2=Mode&f3=Len&f4=Date&f5=Time&f6=Name' +
'&limtime1=' + PrepareURL(Trim(FFromDate)) + '&limtime2=' +
PrepareURL(Trim(FToDate));
if FMinSize > 0 then
begin
Result := Result + '&limsize1=' + IntToStr(FMinSize);
if FMinSize <= FMaxSize then
Result := Result + '&limsize2=' + IntToStr(FMaxSize);
end;
end;
procedure TMFtpSearch.SetServer;
begin
if not FBusy then FServer.Assign(S);
end;
procedure TMFtpSearch.Parse;
var Attrib, Size, DT, URL, S: String;
i, j, j1: Integer;
begin
for i := 0 to L.Count - 1 do
begin
S := Trim(L[i]);
j := Pos('<TT>', S);
if j > 0 then
begin
j1 := Pos('</TT>', S);
Attrib := Trim(Copy(S, j + 4, j1 - j - 4));
Delete(S, 1, j1 + 5);
j := Pos('<B>', S );
j1 := Pos('</B>', S);
Size := Trim(Copy(S, j + 3, j1 - j - 3));
Delete(S, 1, j1 + 4);
j := Pos('<A HREF="', S);
DT := Trim(Copy(S, 1, j - 1));
Delete(S, 1, j + 8);
j := Pos('">', S);
URL := Trim(Copy(S, 1, j - 1));
// work arounds here
if Copy(URL, 1, 6) <> 'ftp://' then
begin
j := Pos('oquery=', URL);
URL := 'ftp://' + Copy(URL, j + 7, 9999);
end;
j := Pos('type=Navigate&query=', URL);
if j > 0 then
begin
URL := 'ftp://' + Copy(URL, j + 20, 9999);
j := Pos('%2', URL);
while j > 0 do
begin
if URL[j + 2] = 'e' then URL := Copy(URL, 1, j - 1) + '.' + Copy(URL, j + 3, 9999) else
if URL[j + 2] = 'f' then URL := Copy(URL, 1, j - 1) + '/' + Copy(URL, j + 3, 9999);
j := Pos('%2', URL);
end;
end;
if FFiles.IndexOf(URL) < 0 then
begin
FFiles.Add(URL, Attrib, DT, Size, '', '', '','');
if Assigned(FSearchInfoEvent) then FSearchInfoEvent(Self, searchFileFound, URL);
end;
end;
if i mod 25 = 0 then Application.ProcessMessages;
end;
end;
procedure TMFtpSearch.Search;
var i, j: Integer;
RFile: String;
Port: Integer;
begin
if FBusy then Exit;
if Trim(FFile) = '' then Exit;
FBusy := True;
RFile := BuildURL;
FFiles.Clear;
for i := 0 to FServer.Count - 1 do
begin
FServer[i] := Trim(FServer[i]);
if Trim(FServer[i]) <> '' then
begin
j := Pos(':', FServer[i]);
if j > 0 then
Port := StrToInt(Copy(FServer[i], j + 1, 999))
else
Port := 80;
if Assigned(FSearchInfoEvent) then
FSearchInfoEvent(Self, searchStart, FServer[i]);
with TMFtpSearchThread.Create(RFile, Copy(FServer[i], 1, j - 1),
Port, FCache, FProxy) do
begin
Tag := i;
OnData := ThreadData;
FreeOnTerminate := True;
Execute;
end;
end;
end;
FBusy := False;
end;
procedure TMFtpSearch.ThreadData;
var TS: TStringList;
begin
TS := TStringList.Create;
try
TS.Text := Data;
Parse(TS);
finally
FreeAndNil(TS);
end;
if Assigned(FSearchInfoEvent) then
FSearchInfoEvent(Self, searchDone, FServer[Tag]);
end;
end.