unit Unit_PlugIportForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, MemDS, DBAccess, MyAccess, StdCtrls, RzLabel, clGZip, clMultiDC,
  clDC, clSingleDC, clDownLoader, clProgressBar, RzPrgres, RzEdit, RzPanel, RzRadGrp,
  RzButton, ExtCtrls,MyDump, DADump, DAScript, inifiles, strutils,clDCUtils,clResourceState,
  clProgressBarDC;

type

  TMyThread = class(TThread)
  public
    procedure Execute; override;
  end;

  TIMPORTFORM = class(TForm)
   RzPanel1: TRzPanel;
   BtnStart: TRzButton;
   BtnExit: TRzButton;
   CGOPTIONS: TRzCheckGroup;
   MLOG: TRzMemo;
   PB1: TRzProgressBar;
   PB2: TRzProgressBar;
   DL1: TclDownLoader;
   clGZip1: TclGZip;
   LBBASEDATE: TRzLabel;
   LBFILEDATE: TRzLabel;
   DB: TMyConnection;
   lq: TMyQuery;
   MyDump1: TMyDump;
    PB3: TclProgressBarDC;
    Timer1: TTimer;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure FormPaint(Sender: TObject);
   procedure FormResize(Sender: TObject);
   procedure OnTerminate(Sender: TObject);
   procedure BtnStartClick(Sender: TObject);
   procedure MyDump1RestoreProgress(Sender: TObject; Percent: Integer);
   procedure DL1Error(Sender: TObject; const Error: string; ErrorCode: Integer);
   procedure DL1ProcessCompleted(Sender: TObject);
   procedure DL1StatusChanged(Sender: TObject; Status: TclProcessStatus);
   procedure clGZip1Progress(Sender: TObject; ABytesProceed, ATotalBytes: Int64);
   procedure FormActivate(Sender: TObject);
   procedure CGOPTIONSChange(Sender: TObject; Index: Integer; NewState: TCheckBoxState);
   procedure MyDump1Error(Sender: TObject; E: Exception; SQL: string; var Action: TErrorAction);
    procedure DL1GetResourceInfo(Sender: TObject; ResourceInfo: TclResourceInfo);
    procedure DL1DataItemProceed(Sender: TObject; ResourceInfo: TclResourceInfo; AStateItem: TclResourceStateItem; CurrentData: PAnsiChar; CurrentDataSize: Integer);
    procedure Timer1Timer(Sender: TObject);

  private
   procedure WMGetSysCommand(var message : TMessage); message WM_SYSCOMMAND;
   function ResourceState: TclResourceStateList;
   procedure CreateParams(var params: TCreateParams); override;
  public

   pl_fl2_0000,pl_fl2_0001,pl_fl2_0002,pl_fl2_0003,pl_fl2_0004,
   pl_fl2_0005,pl_fl2_0006,pl_fl2_0007,pl_fl2_0008,pl_fl2_0009,
   pl_fl2_0010,pl_fl2_0011,pl_fl2_0012,pl_fl2_0013,pl_fl2_0014,
   pl_fl2_0015,pl_fl2_0016,pl_fl2_0017,pl_fl2_0018,pl_fl2_0019,
   pl_fl2_0020,pl_fl2_0021,pl_fl2_0022,pl_fl2_0023,pl_fl2_0024,
   pl_fl2_0025,pl_fl2_0026,pl_fl2_0027,pl_fl2_0028,pl_fl2_0029,
   pl_fl2_0030,pl_fl2_0031,pl_fl2_0032,pl_fl2_0033,pl_fl2_0034,
   pl_fl2_0035,pl_fl2_0036,pl_fl2_0037,pl_fl2_0038,pl_fl2_0039,
   pl_fl2_0040,pl_fl2_0041,pl_fl2_0042,pl_fl2_0043,pl_fl2_0044,
   pl_fl2_0045,pl_fl2_0046 :string;

   prevbookcount,lastbookcount,lastnewscount: integer;
   dlpath,sqlpath,tmppath: widestring;
   tablename: WideString;
   savelog,autorun,getinfo,errordb,working,brk,completeOk: Boolean;
   count_d,totalprogress: longint;
   gznamelist,tblnamelist: tstringlist;
   CallForm: thandle;

   http_liburl, http_liblogin, http_libpasswd,
   http_baseurl, http_baselogin, http_basepasswd,
   http_proxyurl, http_proxylogin, http_proxypasswd: widestring;

   http_libport, http_baseport, http_proxyport: integer;
   http_delaydownload, http_thread, http_timeout, http_TryCount, http_ReconnectAfter: integer;
   enable_proxylib,enable_proxybase,enable_proxyprg,GetDataDB: Boolean;
   init,unpackerror,connectOk: boolean;
   prevdate,lastdate,PrevBookId,LastBookId: string;
   delta: byte;

   th: TMyThread;

   mrexit: tmodalresult;

   procedure SetLang(lng:string);
   function MyMoveFile(src,trg:widestring; replace: boolean):boolean;
   function LoadDB: Boolean;
   function DownLoadBase: boolean;
   procedure saveheader(fn: string);
   procedure savefootter(fn: string);
   procedure savedata(fn: string);
   procedure preparedata(tablename: widestring);
   procedure loadconf;
   procedure GetDateFromFile;
   procedure GetDateFromBase;
   procedure ExtractNewBook(lastid: integer{; All: boolean});
   procedure ShowInfo;
   procedure AddLog(s: WideString);
  end;

var
 IMPORTFORM: TIMPORTFORM;

implementation

uses plug_misc;

{$R *.dfm}
{$R plug.RES}

var
 qfn: WideString;
 llq:TMyDump;
 b: array of integer; //bad
 g: array of integer; //good
 thterm: boolean;


function SecToTime(Sec: Integer): string;
var
  H, M, S: INTEGER;
  HS, MS, SS: string;
begin
  S := Sec;
  M := Round(INT(S / 60));
  S := S - M * 60; //Seconds
  H := Round(INT(M / 60)); //Hours
  M := M - H * 60; //Minutes
  if H < 10 then
    HS := '0' + Inttostr(H)
  else
    HS := inttostr(H);
  if M < 10 then
    MS := '0' + Inttostr(M)
  else
    MS := inttostr(M);
  if S < 10 then
    SS := '0' + inttostr(S)
  else
    SS := inttostr(S);
  RESULT := HS + ':' + MS + ':' + SS;
end;

function GetSizeName(const Size: Int64): String; // just a helper method to improve readybility
begin
  Result := 'error';
  if Size < 0 then
    Exit;
  if Size < 1024 then
  begin
    Result := inttostr(Size) + ' Byte';
    Exit;
  end;
  if (1024 <= Size) and (Size < 1048576) then
  begin
    Result := floattostr((round((Size / 1024) * 100)) / 100) + ' KB';
    Exit;
  end;
  if (1048576 <= Size) and (Size < 1073741824) then
  begin
    Result := floattostr((round((Size / 1048576) * 100)) / 100) + ' MB';
    Exit;
  end;
  if Size = 1073741824 then
    Result := ('1 GB');
  if Size > 1073741824 then
  begin
    Result := floattostr((round((Size / 1073741824) * 100)) / 100) + ' GB';
  end;
end;


procedure TIMPORTFORM.DL1DataItemProceed(Sender: TObject; ResourceInfo: TclResourceInfo; AStateItem: TclResourceStateItem; CurrentData: PAnsiChar; CurrentDataSize: Integer);
var
 State: TclResourceStateList;
begin
 if brk then exit;
 State := AStateItem.ResourceState;
 // LBFILEDATE.caption := Format('Выполнено: %.2n из %.2n Kb, скорость: %.2n Kb/сек, '+#13+'время: %s , осталось: %s', [State.BytesProceed / 1024, State.ResourceSize / 1024, State.Speed / 1024, SecToTime(round(State.ElapsedTime)), SecToTime(round(State.RemainingTime))]);
 LBFILEDATE.caption := Format(pl_fl2_0006+' %d Kb, %d Kb/'+pl_fl2_0007+', %s '+pl_fl2_0007+'.', [State.BytesProceed div 1024 ,round(State.Speed) div 1024, SecToTime(round(State.RemainingTime))]);
end;

procedure TIMPORTFORM.DL1Error(Sender: TObject; const Error: string; ErrorCode: Integer);
begin
 completeOk:=false;
 MLOG.Lines[MLOG.Lines.Count-1]:=MLOG.Lines[MLOG.Lines.Count-1]+pl_fl2_0008;
 AddLog(error+' ('+inttostr(ErrorCode)+')');
 MLOG.Refresh;
 Application.ProcessMessages;
end;

procedure TIMPORTFORM.DL1GetResourceInfo(Sender: TObject; ResourceInfo: TclResourceInfo);
begin
   if strtoint(FormatDateTime('YYYY',ResourceInfo.Date))<2010 then
    begin
     LBFILEDATE.Font.Color := clRed;
     LBFILEDATE.Caption := pl_fl2_0009;
     lastdate:=pl_fl2_0010;
    end
   else
    begin
     LBFILEDATE.Font.Color := clGreen;
//     RzLabel2.Caption := u3_0041+': ' + formatdatetime('dd.mm.yyyy hh:nn:ss', ResourceInfo.Date);
     try
      LBFILEDATE.Caption := pl_fl2_0011+': ' + formatdatetime('c', ResourceInfo.Date);
      lastdate:=formatdatetime('c', ResourceInfo.Date);
     except
     end;
    end;
end;

procedure TIMPORTFORM.DL1ProcessCompleted(Sender: TObject);
var
 s: string;
begin
 if not completeOk
  then deletefile(DL1.LocalFile)
  else
   begin
    s:=extractfilename(DL1.LocalFile);
    delete(s,length(s)-3,4);
    MyMoveFile(DL1.LocalFile,SQLPath+s,true);
   end;
end;

procedure TIMPORTFORM.AddLog(s: WideString);
begin
  MLOG.Lines.Add(timetostr(now) + ': ' + s);
end;

procedure TIMPORTFORM.DL1StatusChanged(Sender: TObject; Status: TclProcessStatus);
begin
  case Status of
    psSuccess:
      begin
        if getinfo then exit;
        //AddLog('Загрузка файла успешно завершена.');
        Application.ProcessMessages;
        LBFILEDATE.caption :='';
      end;
    psFailed:
      begin
        LBFILEDATE.caption :='';
        if getinfo
         then
          begin
           LBFILEDATE.Font.Color := clRed;
           LBFILEDATE.Caption := pl_fl2_0009;
           lastdate:=pl_fl2_0010;
          end
         else
          if not brk then AddLog(pl_fl2_0012);
        Application.ProcessMessages;
      end;
    psTerminated:
      begin
        if getinfo then exit;
        LBFILEDATE.caption :='';
        AddLog(pl_fl2_0013);
        Application.ProcessMessages;
      end;
    psErrors:
      begin
        LBFILEDATE.caption :='';
        if getinfo
         then
          begin
           LBFILEDATE.Font.Color := clRed;
           LBFILEDATE.Caption := pl_fl2_0009;
           lastdate:=pl_fl2_0010;
          end
         else AddLog(pl_fl2_0012);
        Application.ProcessMessages;
      end;
  end;
end;

procedure TIMPORTFORM.clGZip1Progress(Sender: TObject; ABytesProceed, ATotalBytes: Int64);
begin
 if brk then
  begin
   BtnStart.Enabled:=false;
   BtnStart.Refresh;
  end;
 Application.ProcessMessages;
 LBFILEDATE.Caption := pl_fl2_0014+': ' + GetSizeName(ABytesProceed)+' '+pl_fl2_0015+' '+GetSizeName(ATotalBytes);
 PB2.Percent:=round(ABytesProceed*100/ATotalBytes);
end;

// Цепляем форму к приложению
procedure TIMPORTFORM.Createparams(var params: TCreateParams);
var
 aHWnd: HWND;
begin
 inherited;
 {как-нибудь получаем существующий дескриптор}
 ahWnd := GetForegroundWindow;
 {а теперь:}
 params.WndParent := ahWnd;
end;

function TIMPORTFORM.ResourceState: TclResourceStateList;
begin
 Result := DL1.ResourceState;
end;

procedure TIMPORTFORM.CGOPTIONSChange(Sender: TObject; Index: Integer; NewState: TCheckBoxState);
var
 f: tinifile;
begin
 if not init then exit;
 f:=TIniFile.Create(INIFile);
 f.WriteBool('ImportForm','Download',CGOPTIONS.Checks[0].Checked);
 f.WriteBool('ImportForm','AutoClose',CGOPTIONS.Checks[1].Checked);
 f.Free;
end;

procedure TIMPORTFORM.BtnStartClick(Sender: TObject);
var
 err: boolean;
begin
 err:=false;
 if working
  then
   begin
    working:=false;
    brk:=true;
    BtnStart.Caption:=pl_fl2_0003;
    BtnStart.Enabled:=true;
    BtnExit.Enabled:=true;
    PB2.Percent:=0;
    PB1.Percent:=0;
    PB2.Visible:=false;
    PB3.Visible:=true;
    ResourceState.Clear();
   end
  else
   begin
    SendMessage(IMPORTFORM.CallForm,wm_user+$101,0,0); // start
    MLOG.Clear;
    PB2.Percent:=0;
    PB1.Percent:=0;
    ResourceState.Clear();
    PB2.Visible:=false;
    PB3.Visible:=true;
    errordb:=false;
    brk:=false;
    BtnStart.Caption:=pl_fl2_0004;
    BtnExit.Enabled:=false;
    working:=true;

    try
     if CGOPTIONS.Checks[0].Checked
      then
       begin
        err:=DownLoadBase;
        if err
         then
          begin
           LBFILEDATE.caption:='';
           err:=LoadDB;
           if err
            then
             begin
              ExtractNewBook(strtoint(PrevBookId));
              ShowInfo;
             end
            else
             begin
              AddLog(pl_fl2_0016);
             end;
          end;
        LBFILEDATE.caption:='';
        BtnStart.Enabled:=true;
       end
      else
       begin
        delta:=round(100/tblnamelist.Count);
        err:=LoadDB;
        if err
         then
          begin
           ExtractNewBook(strtoint(PrevBookId));
           ShowInfo;
          end
         else
          begin
           AddLog(pl_fl2_0016);
          end;
        LBFILEDATE.caption:='';
       end;
    except
     AddLog(pl_fl2_0017);
     BtnStart.Enabled:=true;
     BtnExit.Enabled:=true;
     SendMessage(IMPORTFORM.CallForm,wm_user+$104,0,0);                    // ошибка

     try
     if savelog then MLOG.Lines.SaveToFile(ExtractFilePath(Application.ExeName)+'importdb_'+plug_misc.basename+'_'+formatdatetime('yyyymmddhhnnss', now)+'.txt');
     except
     end;

     if autorun
      then
       begin
        mrexit:=mrCancel;
        Timer1.Enabled:=true;
       end;
     exit;
    end;
    BtnStart.Caption:=pl_fl2_0003;
    BtnExit.Enabled:=true;
    if CGOPTIONS.Checks[1].Checked then modalresult:=mrOk;
    working:=false;
    if brk then SendMessage(IMPORTFORM.CallForm,wm_user+$103,0,0) else     // прервано
    if not err then SendMessage(IMPORTFORM.CallForm,wm_user+$104,0,0) else // ошибка
    SendMessage(IMPORTFORM.CallForm,wm_user+$102,0,0);                     // ок
   end;

     try
     if savelog then MLOG.Lines.SaveToFile(ExtractFilePath(Application.ExeName)+'importdb_'+plug_misc.basename+'_'+formatdatetime('yyyymmddhhnnss', now)+'.txt');
     except
     end;

  if autorun
   then
    begin
     mrexit:=mrOk;
     Timer1.Enabled:=true;
    end;
end;

procedure TIMPORTFORM.WMGetSysCommand(var message : TMessage) ;
begin
 if (message.wParam = SC_MINIMIZE) and (CallForm<>0)
  then SendMessage(callform, wm_User, 0, 0)
  else inherited;
end;

procedure TIMPORTFORM.OnTerminate(Sender: TObject);
begin
 th.Terminate;
 thterm:=false;
end;

procedure TMyThread.Execute;
begin
 try
  llq.RestoreFromFile(qfn);
 except
 end;
 Terminate;
end;


Procedure TIMPORTFORM.GetDateFromFile;
var
  i: Integer;
  s: string;
begin
 try
  brk:=false;
  LBFILEDATE.Font.Color := clBlue;
  LBFILEDATE.Font.Style := [fsbold];
  LBFILEDATE.caption:=pl_fl2_0018;
  LBFILEDATE.Refresh;
  Application.ProcessMessages;
  //LBFILEDATE.Caption := 'Ожидайте. Соединяемся с сервером...';
  for i:=0 to gznamelist.Count - 1 do
   begin
    s:=trim(gznamelist[i]);
    if s<>'' then
     begin
      s:=trim(gznamelist[i]);
      break;
     end;
   end;
  DL1.UserName := http_baselogin;
  DL1.Password := http_basepasswd;
  DL1.ThreadCount := 1;
  DL1.TimeOut := 10000;
  DL1.TryCount := 3;
  DL1.ReconnectAfter := 5000;
  DL1.url := http_baseurl+s;
  if enable_proxybase
   then
    begin
     DL1.HttpProxySettings.Server := http_proxyurl;
     DL1.HttpProxySettings.Port := http_proxyport;
     DL1.HttpProxySettings.Username := http_proxylogin;
     DL1.HttpProxySettings.Password := http_proxypasswd;
    end
   else
    begin
     DL1.HttpProxySettings.Server := '';
     DL1.HttpProxySettings.Port := 0;
     DL1.HttpProxySettings.Username := '';
     DL1.HttpProxySettings.Password := '';
     DL1.ftpProxySettings.Server := '';
     DL1.ftpProxySettings.Port := 0;
     DL1.ftpProxySettings.Username := '';
     DL1.ftpProxySettings.Password := '';
    end;
  getinfo:=true;
  DL1.GetResourceInfo(true);
  repeat
    Application.ProcessMessages;
    sleep(10);
    Application.ProcessMessages;
  until not DL1.IsBusy;
 except
 end;
 getinfo:=false;
 BtnStart.Enabled := true;
 BtnExit.Enabled := true;
end;

procedure TIMPORTFORM.GetDateFromBase;
var
 q: TMyQuery;
 l: tstringlist;
  i: Integer;
  bb: boolean;
  f: tinifile;
begin
 LBBASEDATE.caption:=pl_fl2_0019;
 LBBASEDATE.Refresh;
 Application.ProcessMessages;
 l:=tstringlist.Create;

 db.GetTableNames(l);
 bb:=false;
  for i := 0 to l.Count-1 do
  if ansilowercase(l[i])='mlbook'
   then
    begin
     bb:=true;
     break;
    end;
 l.Free;
 if bb
  then
   begin
    q:=TMyQuery.Create(self);
    q.Connection:=db;
    q.SQL.Text:='select max(date_in) as cnt from `'+plug_misc.basename+'`.`mlbook`';
    try
     q.open;
    except
    end;
    if q.fieldbyname('cnt').AsString<>''
     then
      begin
       LBBASEDATE.Caption:=pl_fl2_0020+': '+ formatdatetime('c', VarToDateTime(q.fieldbyname('cnt').AsString));
       prevdate:=formatdatetime('c', VarToDateTime(q.fieldbyname('cnt').AsString));
      end
     else // Если в базе нет данных
      begin
       LBBASEDATE.Caption:=pl_fl2_0021;
       prevdate:=pl_fl2_0010;
      end;
    q.SQL.Text:='select max(bookid) as cnt from `'+plug_misc.basename+'`.`mlbook`';
    try
     q.open;
    except
    end;
    PrevBookId:=q.fieldbyname('cnt').AsString;
    q.Free;
    if trim(PrevBookId)='' then PrevBookId:='0';      // Если в базе отсутствуют данные
   end
  else // Если нет таблиц (первое обновление)
   begin
    PrevBookId:='0';
    LBBASEDATE.Caption:=pl_fl2_0021;
    prevdate:=pl_fl2_0010;
   end;
 // если в базе нет данных (PrevBookId=0) пытаемся получить PrevBookId из ini-файла
 if PrevBookId='0'
  then
   begin
    f:=TIniFile.Create(INIFile);
    PrevBookId:=f.ReadString('news','PrevBookId','0');
    f.free;
   end;
end;

procedure TIMPORTFORM.FormActivate(Sender: TObject);
begin
 // mlog.Lines.Add('Подключение...');
 Timer1.Enabled:=false;
 Caption:=pl_fl2_0000+' '+plug_misc.BaseName;
 Application.ProcessMessages;
 GetDateFromBase;
 if GetDataDB
  then
   try
    GetDateFromFile;
   except
   end
  else LBFILEDATE.Caption := pl_fl2_0022;
 if db.Connected
  then
   begin
    BtnStart.Enabled:=true;
    if autorun then BtnStartClick(self);
   end;
end;

procedure TIMPORTFORM.FormCreate(Sender: TObject);
var
 f: tinifile;
 s,path,lng: string;
begin
 init:=false;
 working:=false;
 BtnExit.ModalResult:=mrCancel;
 Application.ProcessMessages;

 s:=ChangeFileExt(Application.ExeName,'.ini');
 f:=TIniFile.Create(s);
 path:=ExtractFilePath(Application.ExeName);
 lng:=f.ReadString('main','lang','Russian');
 f.free;
 SetLang(path+lng+'.lng');

 f:=TIniFile.Create(INIFile);
 CGOPTIONS.Checks[0].Checked:=f.ReadBool('ImportForm','Download',true);
 CGOPTIONS.Checks[1].Checked:=f.ReadBool('ImportForm','AutoClose',false);
 f.Free;
 init:=true;
 s:=ChangeFileExt(Application.ExeName,'.ini');
 f:=TIniFile.Create(s);
 db.Port:=f.ReadInteger('MySQL','mysql_port', 3306);
 db.Username:=f.ReadString('MySQL','mysql_username','root');
 db.Password:=f.ReadString('MySQL','mysql_password','');
 db.Server:=f.ReadString('MySQL','mysql_server','localhost');
 f.Free;
 IMPORTFORM:=self;
 LBBASEDATE.Caption:='';
 LBFILEDATE.Caption:='';
 PB2.Visible:=false;
 PB3.Visible:=true;
 Application.ProcessMessages;
 gznamelist:=tstringlist.Create;
 tblnamelist:=tstringlist.Create;
 loadconf;
 MLOG.Clear;
 db.Database:=plug_misc.BaseName;
 caption:=plug_misc.BaseName;
 db.Open;
 if  not db.Connected
  then
   begin
    BtnStart.Enabled:=false;
    AddLog(pl_fl2_0023);
    exit;
   end;
 llq:=MyDump1;
end;

procedure TIMPORTFORM.FormDestroy(Sender: TObject);
begin
 llq:=nil;
 gznamelist.Free;
 tblnamelist.Free;
 db.Close;
end;

procedure TIMPORTFORM.FormPaint(Sender: TObject);
begin
 application.RestoreTopMosts;
end;

procedure TIMPORTFORM.FormResize(Sender: TObject);
begin
 pb3.Width:=pb1.Width;
 BtnStart.Left:=(RzPanel1.ClientWidth div 2)-BtnStart.Width-10;
 BtnExit.Left:=(RzPanel1.ClientWidth div 2)+10;
 BtnStart.Top:=CGOPTIONS.Top+CGOPTIONS.Height+8;
 BtnExit.Top:=BtnStart.Top;
end;

procedure TIMPORTFORM.MyDump1Error(Sender: TObject; E: Exception; SQL: string;
  var Action: TErrorAction);
begin
 AddLog(e.Message);
 errordb:=true;
end;

procedure TIMPORTFORM.MyDump1RestoreProgress(Sender: TObject; Percent: Integer);
begin
 PB2.Percent:=Percent;
 Application.ProcessMessages;
end;

function TIMPORTFORM.MyMoveFile(src,trg:widestring; replace: boolean):boolean;
var
 bb: boolean;
begin
 bb:=CopyFile(pwidechar(src),pwidechar(trg),not(replace));
 if tmppath=ExtractFilePath(src)
  then
   if (fileexists(src))and bb
    then bb:=DeleteFile(src);
 result:=bb;
end;

// Удаляем "USING BTREE"
procedure PrepereFileDump(name: string);
var
 f: file;
 buf: array[0..4095] of ansichar;
 n,m: integer;
 s: ansistring;
begin
 AssignFile(f,name);
 Reset(f,1);
 n:=4095;
 m:=FileSize(f);
 if m<n then n:=m;
 blockread(f,buf,n);
 seek(f,0);
 s:=ansistring(buf);
 s:=replacestr(s,'USING BTREE','           ');
 s:=replacestr(s,'`Modified` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,','`Modified` timestamp NOT NULL DEFAULT ''2009-11-29 05:00:00'',       ');

 Move(s[1], buf[0], length(s));
 blockwrite(f,buf,n);
 closefile(f);


// `Modified` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
// `Modified` timestamp NOT NULL DEFAULT '2009-11-29 05:00:00',

end;

function TIMPORTFORM.LoadDB: Boolean;
var
 l: TStringList;
 i,n: integer;
 s: WideString;
 f: tinifile;
 q: tmyquery;
 ff: file of byte;
begin
 errordb:=false;
 BtnStart.Enabled:=false;
 q:=TMyQuery.Create(self);
 q.Connection:=db;
 q.SQL.Text:='select count(bookid) as cnt from `'+plug_misc.BaseName+'`.`mlbook` where filesize>0';
 try
  q.open;
 except
 end;
 try
  prevbookcount:=q.FieldByName('cnt').AsInteger;
 except
  prevbookcount:=0;
 end;
 q.Free;
 PB2.Visible:=true;
 PB3.Visible:=false;
 l:=TStringList.Create;
 try
 for i := 0 to tblnamelist.Count - 1 do
  begin
   if gznamelist[i]<>''
    then
     begin
      l.Add(SQLPath+tblnamelist[i]);
     end
    else
     begin
      f:=TIniFile.Create(INIFile);
      s:=abs_path('.\plugins\'+ExtractFilePath(f.ReadString('main','plugfilename','')));
      f.Free;
      l.Add(s+tblnamelist[i]);
     end;
  end;
 for i:=0 to l.Count-1 do
  begin
   assignfile(ff,l[i]);
   reset(ff);
   if filesize(ff)<=0 then
    begin
     closefile(ff);
     result:=false;
     addlog(pl_fl2_0024);
     exit;
    end;
   closefile(ff);
  end;
 for i:=0 to l.Count-1 do
  begin
   PrepereFileDump(l[i]);
   th:=TMyThread.Create(true);
   AddLog(pl_fl2_0025+' '+extractfilename(l[i])+' ...');
   qfn:=l[i];
   thterm:=true;
   th.FreeOnTerminate := true;
   th.Priority:=tpLower;
   th.OnTerminate := OnTerminate;
   th.Resume;
   while {(not th.Terminated)} thterm do begin Application.ProcessMessages; sleep(10); Application.ProcessMessages; end;
   if errordb then begin result:=false; l.Free; exit; end;

   if pos('libavtoraliase',l[i])>0
    then
     begin
      preparedata(l[i]);
      AddLog(pl_fl2_0025+' '+extractfilename(l[i])+' ...');
      th:=TMyThread.Create(true);
      qfn:=l[i];
      thterm:=true;
      th.FreeOnTerminate := true;
      th.Priority:=tpLower;
      th.OnTerminate := OnTerminate;
      th.Resume;
      while {(not th.Terminated)} thterm do begin Application.ProcessMessages; sleep(1); Application.ProcessMessages; end;

      if FileExists(SQLPath+'lib.libavtoraliase.sql.old')
       then
        begin
         if FileExists(SQLPath+'lib.libavtoraliase.sql') then deletefile(SQLPath+'lib.libavtoraliase.sql');
         RenameFile(SQLPath+'lib.libavtoraliase.sql.old',SQLPath+'lib.libavtoraliase.sql');
        end;
     end;
   inc(totalprogress,delta);
   pb1.Percent:=totalprogress;
   pb1.Refresh;
   Application.ProcessMessages;
   MLOG.Lines[MLOG.Lines.Count-1]:=MLOG.Lines[MLOG.Lines.Count-1]+pl_fl2_0037;
   Application.ProcessMessages;
  end;
 pb1.Percent:=100;
 pb2.Percent:=100;
 pb1.Refresh;
 pb2.Refresh;
 Application.ProcessMessages;
 AddLog(pl_fl2_0026);
 // Получаем новый максимальный Bookid
 q:=TMyQuery.Create(self);
 q.Connection:=db;
 q.SQL.Text:='select max(bookid) as cnt from `'+plug_misc.BaseName+'`.`mlbook`';
 try
  q.open;
 except
 end;
 LastBookId:=q.FieldByName('cnt').AsString;
 q.Free;
 if (LastBookId<>PrevBookId)and(LastBookId<>'')
  then
   begin
    // Сохраняем только если база обновилась и произошли изменеиия
    f:=TIniFile.Create(INIFile);
    f.WriteString('news','LastBookId',LastBookId);
    f.WriteString('news','PrevBookId',PrevBookId);
    f.Free;
   end;
 except
 end;
 l.Free;
 q:=TMyQuery.Create(self);
 q.Connection:=db;
 q.SQL.Text:='select count(bookid) as cnt from `'+plug_misc.BaseName+'`.`mlbook` where filesize>0';
 try
  q.open;
 except
 end;
 lastbookcount:=q.FieldByName('cnt').AsInteger;
 q.Free;
 BtnExit.ModalResult:=mrOk;
 result:=True;
end;

procedure TIMPORTFORM.saveheader(fn: string);
var
 f: system.Text;
begin
 AssignFile(f,fn);
 rewrite(f);
 writeln(f,'-- MySQL dump 10.11');
 writeln(f,'--');
 writeln(f,'-- Host: localhost    Database: library');
 writeln(f,'-- ------------------------------------------------------');
 writeln(f,'-- Server version	5.0.87-log');
 writeln(f,'');
 writeln(f,'/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;');
 writeln(f,'/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;');
 writeln(f,'/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;');
 writeln(f,'/*!40101 SET NAMES UTF8 */;');
 writeln(f,'/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;');
 writeln(f,'/*!40103 SET TIME_ZONE=''+00:00'' */;');
 writeln(f,'/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;');
 writeln(f,'/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;');
 writeln(f,'/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=''NO_AUTO_VALUE_ON_ZERO'' */;');
 writeln(f,'/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;');
 writeln(f,'');
 writeln(f,'--');
 writeln(f,'-- Table structure for table `mlauthoraliase`');
 writeln(f,'--');
 writeln(f,'');
 writeln(f,'DROP TABLE IF EXISTS `mlauthoraliase`;');
 writeln(f,'/*!40101 SET @saved_cs_client     = @@character_set_client */;');
 writeln(f,'/*!40101 SET character_set_client = utf8 */;');
 writeln(f,'CREATE TABLE `mlauthoraliase` (');
 writeln(f,'  `AliaseId` int(11) NOT NULL auto_increment,');
 writeln(f,'  `BadId` int(11) NOT NULL default ''0'',');
 writeln(f,'  `GoodId` int(11) NOT NULL default ''0'',');
 writeln(f,'  PRIMARY KEY  (`AliaseId`),');
 writeln(f,'  KEY `u` (`BadId`,`GoodId`),');
 writeln(f,'  KEY `BadId` (`BadId`),');
 writeln(f,'  KEY `GoodId` (`GoodId`)');
 writeln(f,') ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;');
 writeln(f,'/*!40101 SET character_set_client = @saved_cs_client */;');
 writeln(f,'');
 writeln(f,'--');
 writeln(f,'-- Dumping data for table `mlauthoraliase`');
 writeln(f,'--');
 writeln(f,'LOCK TABLES `mlauthoraliase` WRITE;');
 writeln(f,'/*!40000 ALTER TABLE `mlauthoraliase` DISABLE KEYS */;');
 closefile(f);
end;


procedure TIMPORTFORM.savefootter(fn: string);
var
 f: system.Text;
begin
 AssignFile(f,fn);
 append(f);
 writeln(f,'/*!40000 ALTER TABLE `mlauthoraliase` ENABLE KEYS */;');
 writeln(f,'UNLOCK TABLES;');
 writeln(f,'/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;');
 writeln(f,'');
 writeln(f,'/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;');
 writeln(f,'/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;');
 writeln(f,'/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;');
 writeln(f,'/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;');
 writeln(f,'/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;');
 writeln(f,'/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;');
 writeln(f,'/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;');
 writeln(f,'');
 writeln(f,'-- Dump completed on 2010-08-31 19:50:02');
 closefile(f);
end;

procedure TIMPORTFORM.savedata(fn: string);
var
 f: system.Text;
 I: Integer;
begin
 AssignFile(f,fn);
 append(f);
 write(f,'INSERT ignore INTO `mlauthoraliase` VALUES ');
 for I := 0 to high(g) do
  begin
   if g[i]<0 then continue;
   write(f,'('+inttostr(i+1)+','+inttostr(b[i])+','+inttostr(g[i])+')');
   if i<>high(g) then write(f,',') else write(f,';');
  end;
 writeln(f,'');
 closefile(f);
end;

procedure TIMPORTFORM.preparedata(tablename: widestring);
var
 i,j,m,n,k: integer;
 bb: boolean;
 q: TMyQuery;
begin
 m:=0;
 n:=0;
 k:=0;
 setlength(b,0);
 setlength(g,0);
 q:=TMyQuery.Create(nil);
 q.Connection:=db;
 q.SQL.Text:='select * from `'+plug_misc.basename+'`.`libavtoraliase`';
 q.Open;
 q.First;
 while not q.Eof do
  begin
   setlength(b,length(b)+1);
   setlength(g,length(g)+1);
   b[high(b)]:=q.FieldByName('badid').AsInteger;
   g[high(g)]:=q.FieldByName('goodid').AsInteger;
   q.Next;
  end;
 repeat
  inc(n);
  bb:=true;
  for j := 0 to high(b) do
   for i := 0 to high(b) do
    if g[j]=b[i]
     then
      begin
       k:=k-2;
       if i=j
        then
         begin
          g[j]:=k;
          b[j]:=k+1;
         end;
       bb:=false;
       inc(m);
       g[j]:=g[i];
      end;
 until bb;
 q.Close;
 q.SQL.Text:='drop table if exists `'+plug_misc.basename+'`.`libavtoraliase`';
 q.Execute;
 q.Free;
 qfn:=SQLPath+tablename;
 if FileExists(SQLPath+'lib.libavtoraliase.sql') then RenameFile(SQLPath+'lib.libavtoraliase.sql',SQLPath+'lib.libavtoraliase.sql.old');
 saveheader(SQLPath+'lib.libavtoraliase.sql');
 savedata(SQLPath+'lib.libavtoraliase.sql');
 savefootter(SQLPath+'lib.libavtoraliase.sql');
 setlength(b,0);
 setlength(g,0);
 MLOG.Lines.Add(pl_fl2_0027+': '+inttostr(n)+' - '+pl_fl2_0028+':'+inttostr(m))
end;

procedure TIMPORTFORM.loadconf;
var
 f: TIniFile;
 l: tstringlist;
 i,n: integer;
 s: WideString;
begin
 f:=TIniFile.Create(INIFile);
 http_liburl:=addbackslash(f.ReadString('Net','http_liburl','http://lib.rus.ec'));
 http_libport:=f.ReadInteger('Net','http_libport', 0);
 http_liblogin:=f.ReadString('Net','http_liblogin','');
 http_libpasswd:=decodepass(f.ReadString('Net','http_libpasswd',''));
 http_baseurl:=addbackslash(f.ReadString('Net','http_baseurl','http://lib.rus.ec/sql'));
 http_baseport:=f.ReadInteger('Net','http_baseport', 0);
 http_baselogin:=f.ReadString('Net','http_baselogin','');
 http_basepasswd:=decodepass(f.ReadString('Net','http_basepasswd',''));
 enable_proxybase:=(f.ReadBool('Net','enable_proxybase',false));
 GetDataDB:=(f.ReadBool('Net','getdatadb',true));
 enable_proxylib:=(f.ReadBool('Net','enable_proxylib',false));
 http_proxyurl:=(f.ReadString('Net','http_proxyurl',''));
 http_proxyport:=f.ReadInteger('Net','http_proxyport', 0);
 http_proxylogin:=f.ReadString('Net','http_proxylogin','');
 http_proxypasswd:=decodepass(f.ReadString('Net','http_proxypasswd',''));
 http_thread:=f.ReadInteger('Net','http_thread', 1);
 http_timeout:=f.ReadInteger('Net','http_timeout', 10000);
 http_TryCount:=f.ReadInteger('Net','http_TryCount', 5);
 http_ReconnectAfter:=f.ReadInteger('Net','http_ReconnectAfter', 5000);
 http_delaydownload:=f.ReadInteger('Net','http_delaydownload', 5000);
 dlpath:=abs_path(IncludeTrailingBackslash(f.ReadString('main','dlpath','')));
 sqlpath:=abs_path(IncludeTrailingBackslash(f.ReadString('main','sqlpath','')));
 tmppath:=abs_path(IncludeTrailingBackslash(f.ReadString('main','tmppath','')));
 if not DirectoryExists(tmppath) then ForceDirectories(tmppath);
 if not DirectoryExists(SQLPath) then ForceDirectories(SQLPath);
 if not DirectoryExists(dlpath) then ForceDirectories(dlpath);
 count_d:=0;
 l:=TStringList.Create;
 f.ReadSectionValues('Tables',l);
 gznamelist.Clear;
 tblnamelist.Clear;
 for i := 0 to l.Count - 1 do
  begin
   n:=pos('=',l[i]);
   if n>0
    then
     begin
       s:=l[i];
       tblnamelist.Add(trim(copy(s,1,n-1)));
       delete(s,1,n);
       gznamelist.Add(trim(s));
       if trim(s)<>'' then inc(count_d);
     end;
   end;
 l.Free;
 f.Free;
end;

function TIMPORTFORM.DownLoadBase: boolean;
var
 i,n,d: integer;
 s: WideString;
begin
 result:=True;
 completeOk:=true;
 PB2.Visible:=false;
 PB3.Visible:=true;
 pb1.Percent:=0;
 totalprogress:=0;
 d:=count_d*2+tblnamelist.Count;
 delta:=round(100/d);
 for i:=0 to gznamelist.Count-1 do
  begin
   if gznamelist[i]='' then continue;
    try
     if (not completeOk) then
      begin
       AddLog(pl_fl2_0029);
       result:=False;
       exit;
      end;
     if (brk)
      then
       begin
        AddLog(pl_fl2_0030);
        result:=False;
        exit;
       end;
     LBFILEDATE.Caption:=gznamelist[i];
     AddLog(pl_fl2_0031+' '+gznamelist[i]+'... ');
     MLOG.Refresh;
     Application.ProcessMessages;
     DL1.Port:=http_baseport;
     if enable_proxybase
      then
       begin
        DL1.HttpProxySettings.Server:=http_proxyurl;
        DL1.HttpProxySettings.Port:=http_proxyport;
        DL1.HttpProxySettings.UserName:=http_proxylogin;
        DL1.HttpProxySettings.Password:=http_proxypasswd;
       end
      else
       begin
        DL1.HttpProxySettings.Server:='';
        DL1.HttpProxySettings.Port:=0;
        DL1.HttpProxySettings.UserName:='';
        DL1.HttpProxySettings.Password:='';
       end;
     DL1.UserName:=http_baselogin;
     DL1.Password:=http_basepasswd;
     DL1.ThreadCount:=http_thread;
     DL1.TimeOut:=http_timeout;
     DL1.TryCount:=http_TryCount;
     DL1.ReconnectAfter:=http_ReconnectAfter;
     DL1.URL:=http_baseurl+gznamelist[i];
     DL1.LocalFile:=tmppath+gznamelist[i]+'.dnl';
     DL1.Start(True);
     repeat
      Application.ProcessMessages;
      sleep(1);
      Application.ProcessMessages;
      if brk
       then
        begin
         DL1.TimeOut:=1;
         DL1.ReconnectAfter:=1;
         DL1.TryCount:=1;
         DL1.Stop;
        end;
     until not DL1.IsBusy;
     if brk
      then
       begin
        MLOG.Lines[MLOG.Lines.Count-1]:=MLOG.Lines[MLOG.Lines.Count-1]+pl_fl2_0008;
        AddLog(pl_fl2_0030);
        result:=false;
        exit;
       end;
     inc(totalprogress,delta);
     pb1.Percent:=totalprogress;
     pb1.Refresh;
     Application.ProcessMessages;
    finally
     if not brk and completeOk
      then MLOG.Lines[MLOG.Lines.Count-1]:=MLOG.Lines[MLOG.Lines.Count-1]+pl_fl2_0037;
    end;
  end;
 ResourceState.Clear();
 if not completeOk
  then
   begin
    AddLog(pl_fl2_0032);
    result:=False;
   end
  else
   begin
    PB2.Visible:=true;
    PB3.Visible:=false;
    unpackerror:=false;
    for i:=0 to gznamelist.Count-1 do
     begin
      if gznamelist[i]='' then continue;
      try
       if brk then
        begin
         AddLog(pl_fl2_0033);
         result:=False;
         exit;
        end;
       AddLog(pl_fl2_0034+' '+gznamelist[i]+'... ');
       MLOG.Refresh;
       Application.ProcessMessages;
       s:=SQLPath+tblnamelist[i];
//       delete(s,length(s)-2,3);
       try
        clGZip1.Uncompress(SQLPath+gznamelist[i],s);
       except
        unpackerror:=true;
       end;
       if unpackerror
        then
         begin
           MLOG.Lines[MLOG.Lines.Count-1]:=MLOG.Lines[MLOG.Lines.Count-1]+pl_fl2_0008;
           AddLog(pl_fl2_0035);
           result:=False;
           Exit;
         end
        else MLOG.Lines[MLOG.Lines.Count-1]:=MLOG.Lines[MLOG.Lines.Count-1]+pl_fl2_0037;
       if not deletefile(SQLPath+gznamelist[i]) then AddLog(pl_fl2_0036+' '+SQLPath+gznamelist[i]);
       if brk then
        begin
         AddLog(pl_fl2_0033);
         result:=False;
         exit;
        end;
       inc(totalprogress,delta);
       pb1.Percent:=totalprogress;
       pb1.Refresh;
       Application.ProcessMessages;
      finally
      end;
     end;
   end;
end;

procedure TIMPORTFORM.ExtractNewBook(lastid: integer{; All: boolean});
var
 q,q1: tmyquery;
 s,n,ss: string;
 i: Integer;
 b: Boolean;
begin
 lastnewscount:=0;
 db.Connected:=false;
 db.Options.UseUnicode:=true;
 db.Options.Charset:='utf8';
 db.Connected:=true;
 if not db.Connected then exit;
 q:=TMyQuery.Create(self);
 q.Connection:=DB;
 q1:=TMyQuery.Create(self);
 q1.Connection:=DB;
 q1.SQL.Text:='select * from `'+plug_misc.BaseName+'`.`mlnewsname`';
 q1.Open;
 q1.First;
 if q1.RecordCount>0 then AddLog(pl_fl2_0038);
 while not q1.Eof do
  begin
   n:=q1.FieldByName('critid').AsString;
   ss:= {UTF8Decode}(q1.FieldByName('critname').AsString);
   MLOG.Lines.Add(pl_fl2_0039+'  '+ss+' ...');
   s:=q1.FieldByName('critsql').AsString;
   q.SQL.Text:='INSERT ignore INTO `'+plug_misc.basename+'`.`mlnews`(bookid,critid)';
   q.SQL.Add('SELECT bookid,' +n+ ' FROM `'+plug_misc.basename+'`.`mlbook`');
   q.SQL.Add('left join `'+plug_misc.basename+'`.`mlauthor` using(bookid)');
   q.SQL.Add('left join `'+plug_misc.basename+'`.`mlauthorname` using(authorid)');
   q.SQL.Add('left join `'+plug_misc.basename+'`.`mlgenre` using(bookid)');
   q.SQL.Add('left join `'+plug_misc.basename+'`.`mlgenrename` using(genreid)');
   q.SQL.Add('left join `'+plug_misc.basename+'`.`mlseq` using(bookid)');
   q.SQL.Add('left join `'+plug_misc.basename+'`.`mlseqname` using(seqid)');
   // Находим все записи у которых bookid больше чем bookid перед обновлением и подходят под критерий отбора
   q.SQL.Add('WHERE mlbook.bookid>'+inttostr(LastId)+' and ('+s+')');
   try
    q.Execute;
   except
   end;
   //lastnewscount:=lastnewscount+q.RowsAffected;
   MLOG.Lines[MLOG.Lines.Count-1]:=MLOG.Lines[MLOG.Lines.Count-1]+inttostr(q.RowsAffected)+' '+pl_fl2_0040;
   q1.Next;
  end;
 q.SQL.Text:='SELECT COUNT(DISTINCT bookid) cnt FROM `'+plug_misc.basename+'`.`mlnews` WHERE bookid>'+inttostr(LastId);
 try
  q.open;
  lastnewscount:=q.FieldByName('cnt').AsInteger;
 except
 end;
 q.Free;
 q1.Free;
end;

procedure TIMPORTFORM.ShowInfo;
var
 i: integer;
begin
 mlog.Lines.Add('');
 mlog.Lines.Add(pl_fl2_0041+': '+prevdate);
 mlog.Lines.Add(pl_fl2_0042+': '+lastdate);
 mlog.Lines.Add('');
 mlog.Lines.Add(pl_fl2_0043+': '+inttostr(prevbookcount));
 mlog.Lines.Add(pl_fl2_0044+': '+inttostr(lastbookcount-prevbookcount));
 mlog.Lines.Add(pl_fl2_0045+': '+inttostr(lastnewscount));
 if PrevBookId<>''
  then
   begin
    i:=strtoint(PrevBookId);
    inc(i);
    if PrevBookId<>LastBookId then mlog.Lines.Add(pl_fl2_0046+': '+inttostr(i)+'-'+LastBookId);
   end;
end;

procedure TIMPORTFORM.Timer1Timer(Sender: TObject);
begin
 IMPORTFORM.ModalResult:=mrexit;
end;

procedure TIMPORTFORM.SetLang(lng:string);
var
 f: TMemIniFile;
 cp: word;
begin
 f:=TMemIniFile.Create(lng,TEncoding.GetEncoding(1251));
 cp:=f.ReadInteger('Custom Resource Strings','codepage',1251);
 f.free;
 f:=TMemIniFile.Create(lng,TEncoding.GetEncoding(cp));
 pl_fl2_0000:=f.ReadString('Custom Resource Strings','pl_fl2_0000','Импорт библиотеки');
 pl_fl2_0001:=f.ReadString('Custom Resource Strings','pl_fl2_0001','Загружать из интернета');
 pl_fl2_0002:=f.ReadString('Custom Resource Strings','pl_fl2_0002','Закрыть окно после удачной загрузки');
 pl_fl2_0003:=f.ReadString('Custom Resource Strings','pl_fl2_0003','Начать');
 pl_fl2_0004:=f.ReadString('Custom Resource Strings','pl_fl2_0004','Отмена');
 pl_fl2_0005:=f.ReadString('Custom Resource Strings','pl_fl2_0005','Выход');
 pl_fl2_0006:=f.ReadString('Custom Resource Strings','pl_fl2_0006','Загрузка:');
 pl_fl2_0007:=f.ReadString('Custom Resource Strings','pl_fl2_0007','сек');
 pl_fl2_0008:=f.ReadString('Custom Resource Strings','pl_fl2_0008','Ошибка');
 pl_fl2_0009:=f.ReadString('Custom Resource Strings','pl_fl2_0009','Дата файлов базы данных не определена');
 pl_fl2_0010:=f.ReadString('Custom Resource Strings','pl_fl2_0010','не определена.');
 pl_fl2_0011:=f.ReadString('Custom Resource Strings','pl_fl2_0011','Дата файлов базы данных');
 pl_fl2_0012:=f.ReadString('Custom Resource Strings','pl_fl2_0012','Ошибка загрузки.');
 pl_fl2_0013:=f.ReadString('Custom Resource Strings','pl_fl2_0013','Загрузка прервана.');
 pl_fl2_0014:=f.ReadString('Custom Resource Strings','pl_fl2_0014','Распаковано');
 pl_fl2_0015:=f.ReadString('Custom Resource Strings','pl_fl2_0015','из');
 pl_fl2_0016:=f.ReadString('Custom Resource Strings','pl_fl2_0016','Ошибка импорта базы. База обновлена не будет.');
 pl_fl2_0017:=f.ReadString('Custom Resource Strings','pl_fl2_0017','Ошибка обновления базы.');
 pl_fl2_0018:=f.ReadString('Custom Resource Strings','pl_fl2_0018','Определяем дату файлов на сервере...');
 pl_fl2_0019:=f.ReadString('Custom Resource Strings','pl_fl2_0019','Определяем дату последнего поступления...');
 pl_fl2_0020:=f.ReadString('Custom Resource Strings','pl_fl2_0020','Дата последнего поступления');
 pl_fl2_0021:=f.ReadString('Custom Resource Strings','pl_fl2_0021','Данные о дате последнего поступления отсутствуют.');
 pl_fl2_0022:=f.ReadString('Custom Resource Strings','pl_fl2_0022','Определение даты файлов базы данных на сервере отключено.');
 pl_fl2_0023:=f.ReadString('Custom Resource Strings','pl_fl2_0023','Ошибка подключения к базе.');
 pl_fl2_0024:=f.ReadString('Custom Resource Strings','pl_fl2_0024','Файл базы данных не содержит информации.');
 pl_fl2_0025:=f.ReadString('Custom Resource Strings','pl_fl2_0025','Импортируется');
 pl_fl2_0026:=f.ReadString('Custom Resource Strings','pl_fl2_0026','Загрузка завершена');
 pl_fl2_0027:=f.ReadString('Custom Resource Strings','pl_fl2_0027','Проходов');
 pl_fl2_0028:=f.ReadString('Custom Resource Strings','pl_fl2_0028','Замен');
 pl_fl2_0029:=f.ReadString('Custom Resource Strings','pl_fl2_0029','При загрузке базы произошла ошибка. База не обновлена.');
 pl_fl2_0030:=f.ReadString('Custom Resource Strings','pl_fl2_0030','Загрузка базы прервана. База не обновлена.');
 pl_fl2_0031:=f.ReadString('Custom Resource Strings','pl_fl2_0031','Закачивается');
 pl_fl2_0032:=f.ReadString('Custom Resource Strings','pl_fl2_0032','Ошибка загрузки. База обновлена не будет.');
 pl_fl2_0033:=f.ReadString('Custom Resource Strings','pl_fl2_0033','Распаковка прервана. База не обновлена.');
 pl_fl2_0034:=f.ReadString('Custom Resource Strings','pl_fl2_0034','Распаковка');
 pl_fl2_0035:=f.ReadString('Custom Resource Strings','pl_fl2_0035','Ошибка распаковки. База обновлена не будет.');
 pl_fl2_0036:=f.ReadString('Custom Resource Strings','pl_fl2_0036','Ошибка удаления');
 pl_fl2_0037:=f.ReadString('Custom Resource Strings','pl_fl2_0037','Ok');
 pl_fl2_0038:=f.ReadString('Custom Resource Strings','pl_fl2_0038','Производится отбор новинок...');
 pl_fl2_0039:=f.ReadString('Custom Resource Strings','pl_fl2_0039','Критерий');
 pl_fl2_0040:=f.ReadString('Custom Resource Strings','pl_fl2_0040','записей');
 pl_fl2_0041:=f.ReadString('Custom Resource Strings','pl_fl2_0041','Дата предыдущего обновления');
 pl_fl2_0042:=f.ReadString('Custom Resource Strings','pl_fl2_0042','Дата последнего обновления');
 pl_fl2_0043:=f.ReadString('Custom Resource Strings','pl_fl2_0043','Книг в библиотеке');
 pl_fl2_0044:=f.ReadString('Custom Resource Strings','pl_fl2_0044','Добавлено новых книг');
 pl_fl2_0045:=f.ReadString('Custom Resource Strings','pl_fl2_0045','Добавлено в "Новинки"');
 pl_fl2_0046:=f.ReadString('Custom Resource Strings','pl_fl2_0046','Диапазон ID новых книг');
 f.Free;
 BtnStart.Caption:=pl_fl2_0003;
 BtnExit.Caption:=pl_fl2_0005;
 CGOPTIONS.Items[0]:=pl_fl2_0001;
 CGOPTIONS.Items[1]:=pl_fl2_0002;
end;

end.
