Odlucio sam da downloadujem ceo sajt :) (FTP)

  • 34 odgovora
  • 8.042 pregleda
Odlucio sam da downloadujem ceo sajt :) (FTP) 21.03.2005. u 18:14 · pre 262 meseci #1
E ljudi, napravio sam neku funkciju koja od onog stringa koji ftp server vrati pri listingu vraca sve redom :) I to sve radi, ali me zanima petlja koja ce proci kroz sve direktorijume (koristeci moj record da vidi da li je item fajl ili dir). Znaci treba mi nesto kao u DOS-u komanda: dir *.* /s, tj. recursive... ali na serveru!

Evo mog .pas fajla:
Code:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Psock, NMFtp;

//define ftp item type
type
TFTPItem = record
   Name,User,Group,Permissions,Date:string;
   Size,Number:integer;
   IsFile:boolean;
end;


type
  TForm1 = class(TForm)
    NMFTP1: TNMFTP;
    procedure NMFTP1ListItem(Listing: String);
    procedure FormCreate(Sender: TObject);
    procedure NMFTP1Connect(Sender: TObject);
  private
    function ParseFTPItem(pFTPItem: string): TFTPItem;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.ParseFTPItem(pFTPItem:string):TFTPItem;
var tmp,zFTPItem,date:string;
    i,o:integer;
begin
zFTPItem:=pFTPItem;
//parse given string
zFTPItem:=Trim(zFTPItem); //remove blanks
i:=POS(' ',zFTPItem); //find space (end of word)
tmp:=copy(zFTPItem,0,i); //copy till space (1st word)
zFTPItem:=StringReplace(zFTPItem,tmp,'',[]); //remove word from FTPItem
zFTPItem:=Trim(zFTPItem); //remove blanks
  Result.Permissions:=trim(tmp); //whole tmp is permissions, but first char tells us whether this is file or not
if tmp[1]='d' then Result.IsFile:=False  //find out whether item is file or not
  else Result.IsFile:=True;
//let's extract stupid number :)
i:=POS(' ',zFTPItem); //find space (end of word)
tmp:=copy(zFTPItem,0,i); //copy till space (1st word)
zFTPItem:=StringReplace(zFTPItem,tmp,'',[]); //remove word from FTPItem
zFTPItem:=Trim(zFTPItem); //remove blanks
  Result.number:=StrToInt(tmp[1]); //we got number!!!
//now user is our target
i:=POS(' ',zFTPItem); //find space (end of word)
tmp:=copy(zFTPItem,0,i); //copy till space (1st word)
zFTPItem:=StringReplace(zFTPItem,tmp,'',[]); //remove word from FTPItem
zFTPItem:=Trim(zFTPItem); //remove blanks
  Result.User:=trim(tmp); //this should be user
//group is next
i:=POS(' ',zFTPItem); //find space (end of word)
tmp:=copy(zFTPItem,0,i); //copy till space (1st word)
zFTPItem:=StringReplace(zFTPItem,tmp,'',[]); //remove word from FTPItem
zFTPItem:=Trim(zFTPItem); //remove blanks
  Result.Group:=trim(tmp); //this should be group
//let's now get file size
i:=POS(' ',zFTPItem); //find space (end of word)
tmp:=copy(zFTPItem,0,i); //copy till space (1st word)
zFTPItem:=StringReplace(zFTPItem,tmp,'',[]); //remove word from FTPItem
zFTPItem:=Trim(zFTPItem); //remove blanks
  Result.Size:=strtoint(trim(tmp)); //this should be size
//date...
i:=POS(' ',zFTPItem); //find space (end of word)
tmp:=copy(zFTPItem,0,i); //copy till space (1st word)
zFTPItem:=StringReplace(zFTPItem,tmp,'',[]); //remove word from FTPItem
zFTPItem:=Trim(zFTPItem); //remove blanks
date:=Trim(tmp);
i:=POS(' ',zFTPItem); //find space (end of word)
tmp:=copy(zFTPItem,0,i); //copy till space (1st word)
zFTPItem:=StringReplace(zFTPItem,tmp,'',[]); //remove word from FTPItem
zFTPItem:=Trim(zFTPItem); //remove blanks
date:=date+'-'+Trim(tmp);
i:=POS(' ',zFTPItem); //find space (end of word)
tmp:=copy(zFTPItem,0,i); //copy till space (1st word)
zFTPItem:=StringReplace(zFTPItem,tmp,'',[]); //remove word from FTPItem
zFTPItem:=Trim(zFTPItem); //remove blanks
date:=date+'-'+Trim(tmp);
  Result.Date:=trim(date); //this should be date
//finally, get item's name
  Result.Name:=trim(zFTPItem); //this should be name
end;

procedure TForm1.NMFTP1ListItem(Listing: String);
var item:tftpitem;
begin
item:=ParseFTPItem(Listing);
ShowMessage('Name: '+item.Name);
ShowMessage('Size: '+IntToStr(item.Size));
ShowMessage('Is File? '+BoolToStr(item.IsFile,true));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
NMFTP1.Host:='localhost';
NMFTP1.UserID:='avram';
NMFTP1.Password:='moj_pass';
NMFTP1.Connect;
end;

procedure TForm1.NMFTP1Connect(Sender: TObject);
begin
NMFTP1.ChangeDir('www');
NMFTP1.List;
end;

end.

Potpis
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 21.03.2005. u 19:21 · pre 262 meseci #2
kad zatrazis FileList od servera on vraca i fajlove i direktorijume, napravi rekurzivnu funkciju koja ce da pokupi listu sa servera, rekurzivno pozove sebe za direktorijume a fajlove izlista(ili kopira ili sta vec). kad obilazis sve pod-foldere u toj funkciji izmedju svaka dva moras da vratis direktorijum za jedan unazad (tipa cd..) da bih mogo da otvoris sledeci folder u ovom koji se skenira trenutno
evo pseudokoda otprilike
Code:

function list(folder: string);
begin
get(files)
for i:=0 to files.count-1 do
 if jesteFolder(files[i]) then
  begin
    list(folder+files[i]);
   chdir('..');
  end
 else
  write(files[i])
end;
Potpis
Ride the rainbow, crack the sky

DIY gitare, pojacala i efekti www.diy-fever.com
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 21.03.2005. u 22:41 · pre 262 meseci #4
Citat:
bancika: kad zatrazis FileList od servera on vraca i fajlove i direktorijume, napravi rekurzivnu funkciju koja ce da pokupi listu sa servera, rekurzivno pozove sebe za direktorijume a fajlove izlista(ili kopira ili sta vec). kad obilazis sve pod-foldere u toj funkciji izmedju svaka dva moras da vratis direktorijum za jedan unazad (tipa cd..) da bih mogo da otvoris sledeci folder u ovom koji se skenira trenutno
evo pseudokoda otprilike


eh, to sam znao, medjutim tu ima problem.. kada uradim deo if FOLDER, i pozovem List ponovo, server mi javi: Error 500(mislim da je 500) - command in progress... zato sto listing vec radi... dakle, to nije greska delphija, vec mi FTP vraca to..........

sto ce reci da moram da pravim neki queue, a to malo... teze... zar ne?

@miniC ... iz Delphi aplikacije koju sam ja pravio zelim da downloadujem sve :)
Potpis
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 21.03.2005. u 23:00 · pre 262 meseci #5
Sta mislis o ovoj ideji. Prvo pokupis podatke o root folderu na FTP-u. Tu ces dobiti sve foldere i fajlove. Te podatke stavi u StringList ili neki prikladniji tip podataka (array, neki collection ili nesto slicno). Nastavicu dalje s pretpostavkom da koristis StringList. Svaki item u string listi ima i rezervisano mesto za neki objekat i u njemu mozes da cuvas dodatne informacije. Kada naidjes na fajl tu mozes upisati velicinu, atribute, vreme kreiranja i ko zna sta jos. Kad naidjes na folder jednostavno za objekat stavi samo nil. I tako dok ne zavrsis root. Time bi imao u StringList-i sve fajlove (oni itemi koji za objekat nemaju nil (ili kako vec odlucis da ih prepoznajes)) i foldere (oni sa nil objektom ili nekom drugom oznakom). Sada krenes redom da trazis kroz StringList koji su kreirao i pronadjes prvi folder i za njegov objekat postavis novu StringList-u u koju ces ponovo da punis na isti nacin. I tako za sledeci folder... itd. Imaces prilicno lepu strukturu. Sve ti je u memoriji, StrinList moze lepo da se sortira za potrebe prikazivanja... mislim da bi to moglo tako da se uradi. Nadam se da ti je ovo malo pomoglo.
Potpis
Play Store
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 22.03.2005. u 10:20 · pre 262 meseci #7
Ovo je samo pseudo kod... nadam se da ce ti pomoci
Code:

type
  FTPItemData = class
    Naziv: String;
    Velicina: Cardinal;
    Datum: TDateTime;
    Fajl: Boolean; // Ako je True to je fajl, u suprotnom je
                   // folder
    SubItems: TStringList; // Ovde drzimo podatke o fajlovima
                           // ako je trenutni Item folder
    // Sve sto ti je jos potrebno
  end;

function GetFTPItemInfo(FTPItem: String): FTPItemData;
begin
  Result := FTPItemData.Create;
  // Ovde pokupis naziva, velicinu i sve sto ti treba
  // kao sto si i do sad radio u svojoj proceduri i
  // dodas na kraju
  Result.SubItems := nil;
end;

function GetFTPData(Folder: String): TStringList;
var
  S: TStringList;
  ItemData: FTPItemData;
  I: Integer;
begin
  S := TStringList.Create;
  // Ne znam tacno kako uzimas podatke sa FTP-a
  // pa cu pisati nesto uopsteno samo da vidis kako bi
  // to trebalo da radi
  GetFirstFTPItem(Folder, ItemData);
  // Recimo da funkcija GetFirstFTPItem uzima putanju do foldera
  // koji zelis da pogledas i vraca ti prvi Item. Nesto kao
  // FindFirst kad trazis fajlove na svom racunaru.
  Repeat
    S.AddObject(ItemData.Naziv, ItemData);
  Until not GetNextFTPItem(Folder, ItemData);
  // Recimo da funkcija GetNextFTPItem uzima putanju do foldera
  // koji zelis da pogledas i vraca ti sledeci Item. Nesto kao
  // FindNext kad trazis fajlove na svom racunaru.

  // Ovo ce napuniti string list podacima iz jednog foldera
  // sad jos samo da pokupimo podatke iz podfoldera

  for I := 0 to S.Count - 1 do
  begin
    ItemData := FTPItemData(S.Objects[I]);
    if not ItemData.Fajl then
    begin
      ItemData.SubItems :=
        GetFTPData(Folder + '/' + ItemData.Naziv);
    end;
  end;
end;

Vrlo je bitno da posle uradis ItemData.Free i StringList.Free za sve Iteme i liste koje si kreirao ili ce memorija da ti curi na sve strane.
Potpis
Play Store
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 25.03.2005. u 20:55 · pre 262 meseci #10
Znam da ima, ali zato imas ono GetNextFTPItem. Ta funkcija bi trebala kada nema vise Itema da vrati da zatvori konekciju sa FTP serverom, a GetFirstFTPItem da je otvori. Nisam bas siguran kako to ide sa FTP serverima. Mozda u toj komponenti koju koristis za FTP posle citanja liste fajlova moras da pozoves neku funkcijicu da zavrsi komadnu koja izaziva Error 500 - command in progress.
Ako ti nije frka posalji kod na forum ili meni na mail pa cu probati da ti otkucam taj deo za listanje.
Potpis
Play Store
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 25.03.2005. u 23:31 · pre 262 meseci #11
koda nema :( jer sam sve obrisao (mada i nije bilo mnogo)... a sacuvao sam moj type i funkciju za odredjivanje svojstava ftpitem-a (ono sto stoji gore u mom prvom postu)...

problem je sto ja mogu jedino da pozovem NMFTP1.List da listam trenutni folder (koji pozivam sa NMFTP1.ChangeDir('ftp/putanja/do/foldera'); a onda se za svaki item (fajl/folder) poziva event NMFTP komponente (za svaki red ispisa se pozove NMFTP1.OnListItem)... drugacije ne mogu listati item-e (valjda).
ako bolje pogledas gornji primer (prvi post), videces...
Potpis
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 26.03.2005. u 01:04 · pre 262 meseci #12
Onda ovako:

1. Pozoves FTP.List (root)
2. Pozove se event za Item
3. Uzmes podatke i ubacis ih u StringList kao sto sam ti rekao
4. Goto 2. dok ima itema
5. Kad se zavrsi sa root-om pregledas StringList i kad naidjes na folder krenes iz pocetka (Goto 1.) samo umesto Root stavis folder na koji si naisao.

To bi moglo da radi i sa onim primerom koji sam ti dao.
Kad pozoves GetFirstItem ta funkcija u pozadini odradi FTP.List i sacuva sve sto dobije iz eventa FTP kontrole u StringList i vrati prvu vrednost. GetNextItem bi vracala sledecu, sledecu, sve dok ne bi dosla do kraja. Tako bi onaj kod koji sam ti dao radio.

Kod tebe je greska sto verovatno u tom eventu koji ti daje FTP komponenta za svaki item ti ako naidjes na folder odmah pokusavas da uzmes sta se nalazi u njemu, a FTP komanda za izlistavanje jos nije gotova. Zato ti se i javlja ona greska.
Potpis
Play Store
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 26.03.2005. u 01:25 · pre 262 meseci #13
da, upravo sam to radio i to mi je bila greska

ali ne kapiram te opet (sitni satiiiii)
kako da vidim kad je zavrsio sa rootom?
zar mi ne treba za svaki folder stringlist? ili... aaaaaaaaaaaa, poludecu :D
Potpis
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 26.03.2005. u 12:23 · pre 262 meseci #14
Ako hoces ozbiljnije da koristis FTP, onda bolje da upotrebis INDY ili ICS komponente za FTP jer NMFTP je bagovit. Ali, komponente nisu bitne za tvoj trenutni problem, moras da stavljas svaki poddirektorijum koji zelis da obradis u TStringList, i kada LIST komanda zavrsi (valjda ima event za to), "izvadis" prvi poddirektorijum iz liste i izlistas njega, i tako sve dok se lista ne isprazni. Mislim da ti je dovoljan jedan TStringList.
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 26.03.2005. u 12:34 · pre 262 meseci #15
Da te ne zamaram ponovo mojim objasnjenima... izvoli primer pa probaj sam da shvatis o cemu se radi.

Uradio sam sve sa TreeView-om pa ces lepo moci da vidis sta se nalazi u kom folderu. Fajlovi na kraju imena imaju (file), a folderi (dir). Ne koristim Binary nego obican ASCII prenos jer za imena i ne treba Binary. Takodje koristim anonymus logovanje pa ako neki server bude zahtevao pravo logovanje moraces malo da promenis kod. U edit-u ukucas ime servera i kliknes na Start... onda ce da radi nekoliko minuta u zavisnosti od velicine sajta. Ako te mrzi da cekas uvek mozes da kliknes na Stop i za par trenutaka ce sve stati i imaces delimicnu listu. To je to... pogledaj i reci da li si tako nesto hteo?
Potpis
Play Store
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 26.03.2005. u 17:45 · pre 262 meseci #16
Missing:

properties:
IdFTP1.MaxLineAction
IdFTP1.ReadTimeout
IdFTP1.Username
IdFTP1.ProxyType
IdFTP1.Port

file:
IdFTPList.dcu


verovatno si radio sa novijom verzijom delphija (novijom od D6) :((
Potpis
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
Re: Odlucio sam da downloadujem ceo sajt :) (FTP) 26.03.2005. u 17:57 · pre 262 meseci #17
Delphi 7. Ta svojstva i nisu tako bitna. Pogledaj kod i videces kako sam sve uradio.

P.S.
Mogu da ti iskompajliram kod pa da vidis kako radi.
Potpis
Play Store
Odgovori
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme