root/trunk/ImportImpl/unit_ImportInpxThread.pas

349465
1
{******************************************************************************}
1
(* *****************************************************************************
2
{                                                                              }
2
  *
3
{ MyHomeLib                                                                    }
3
  * MyHomeLib
4
{                                                                              }
4
  *
5
{ Version 0.9                                                                  }
5
  * Copyright (C) 2008-2010 Aleksey Penkov
6
{ 20.08.2008                                                                   }
6
  *
7
{ Copyright (c) Aleksey Penkov  alex.penkov@gmail.com                          }
7
  * Created             12.02.2010
8
{                                                                              }
8
  * Description
9
{ @author Nick Rymanov nrymanov@gmail.com                                      }
9
  * Author(s)           Nick Rymanov (nrymanov@gmail.com)
10
{                                                                              }
10
  *                     Aleksey Penkov  alex.penkov@gmail.com
11
{******************************************************************************}
11
  *
12
  * History
13
  * NickR 02.03.2010    Код переформатирован
  *
14
  ****************************************************************************** *)
12
15
16
{ TODO -oNickR : думаю, стоит попробовать не распаковывать архив на диск, а распаковывать нужный файл напрямую в Stream }
17
13
unit unit_ImportInpxThread;
18
unit unit_ImportInpxThread;
14
19
15
interface
20
interface
...
...
22
  unit_MHL_xml,
28
  unit_MHL_xml,
23
  unit_globals;
29
  unit_globals;
24
30
25
26
27
type
31
type
28
32
29
  TFields = (flNone,flAuthor, flTitle, flSeries, flSerNo, flGenre, flLibID,
33
  TFields = (
30
             flInsideNo, flFile, flFolder, flExt, flSize, flLang, flDate,
34
    flNone,
31
             flCode, flDeleted, flRate, flURI, flLibRate, flKeyWords);
35
    flAuthor,
36
    flTitle,
37
    flSeries,
38
    flSerNo,
39
    flGenre,
40
    flLibID,
41
    flInsideNo,
42
    flFile,
43
    flFolder,
44
    flExt,
45
    flSize,
46
    flLang,
47
    flDate,
48
    flCode,
49
    flDeleted,
50
    flRate,
51
    flURI,
52
    flLibRate,
53
    flKeyWords
54
  );
32
55
33
  TFieldDescr = record
56
  TFieldDescr = record
34
                   Code: string;
57
    Code: string;
35
                  FType: TFields;
58
    FType: TFields;
36
  end;
59
  end;
37
60
38
  TImportLibRusEcThread = class(TWorker)
61
  TImportLibRusEcThread = class(TWorker)
39
  private
62
  private
40
41
    FDBFileName: string;
63
    FDBFileName: string;
42
    FCollectionRoot: string;
64
    FCollectionRoot: string;
43
    FCollectionType: Integer;
65
    FCollectionType: Integer;
...
...
50
    FGenresType: TGenresType;
72
    FGenresType: TGenresType;
51
73
52
    procedure SetCollectionRoot(const Value: string);
74
    procedure SetCollectionRoot(const Value: string);
53
    procedure  ParseData(input: WideString; var R: TBookRecord);
75
    procedure ParseData(input: WideString; var R: TBookRecord);
54
76
55
  protected
77
  protected
56
    procedure WorkFunction; override;
78
    procedure WorkFunction; override;
57
    procedure GetFields;
79
    procedure GetFields;
80
58
  public
81
  public
59
    function Import(CheckFiles: boolean):integer;
82
    function Import(CheckFiles: boolean): Integer;
60
83
61
    property DBFileName: string read FDBFileName write FDBFileName;
84
    property DBFileName: string read FDBFileName write FDBFileName;
62
    property CollectionRoot: string read FCollectionRoot write SetCollectionRoot;
85
    property CollectionRoot: string read FCollectionRoot write SetCollectionRoot;
63
    property CollectionType: COLLECTION_TYPE read FCollectionType write FCollectionType;
86
    property CollectionType: COLLECTION_TYPE read FCollectionType write FCollectionType;
64
    property InpxFileName: string read FInpxFileName write FInpxFileName;
87
    property InpxFileName: string read FInpxFileName write FInpxFileName;
65
    property GenresType: TGenresType write FGenresType;
88
    property GenresType: TGenresType write FGenresType;
66
67
  end;
89
  end;
68
90
69
implementation
91
implementation
...
...
75
  unit_Helpers,
97
  unit_Helpers,
76
  ZipForge;
98
  ZipForge;
77
99
78
type
100
//type
79
  INPXType = (inpUnknown, inpFormat_10, inpFormat_11);
101
//  INPXType = (inpUnknown, inpFormat_10, inpFormat_11);
80
102
81
const
103
const
82
104
  FieldsDescr: array [1 .. 20] of TFieldDescr = (
83
  FieldsDescr: array [1..20] of  TFieldDescr= (
105
    (Code: 'AUTHOR';   FType: flAuthor),
84
    (Code:'AUTHOR'; FType: flAuthor),
106
    (Code: 'TITLE';    FType: flTitle),
85
    (Code:'TITLE';  FType:  flTitle),
107
    (Code: 'SERIES';   FType: flSeries),
86
    (Code:'SERIES'; FType:  flSeries),
108
    (Code: 'SERNO';    FType: flSerNo),
87
    (Code:'SERNO';  FType:  flSerNo),
109
    (Code: 'GENRE';    FType: flGenre),
88
    (Code:'GENRE';  FType:  flGenre),
110
    (Code: 'LIBID';    FType: flLibID),
89
    (Code:'LIBID';  FType:   flLibID),
111
    (Code: 'INSNO';    FType: flInsideNo),
90
    (Code:'INSNO';  FType:  flInsideNo),
112
    (Code: 'FILE';     FType: flFile),
91
    (Code:'FILE';   FType:  flFile),
113
    (Code: 'FOLDER';   FType: flFolder),
92
    (Code:'FOLDER'; FType: flFolder),
114
    (Code: 'EXT';      FType: flExt),
93
    (Code:'EXT';    FType:   flExt),
115
    (Code: 'SIZE';     FType: flSize),
94
    (Code:'SIZE';   FType:   flSize),
116
    (Code: 'LANG';     FType: flLang),
95
    (Code:'LANG';   FType:  flLang),
117
    (Code: 'DATE';     FType: flDate),
96
    (Code:'DATE';   FType:  flDate),
118
    (Code: 'CODE';     FType: flCode),
97
    (Code:'CODE';   FType:  flCode),
119
    (Code: 'DEL';      FType: flDeleted),
98
    (Code:'DEL';    FType:  flDeleted),
120
    (Code: 'RATE';     FType: flRate),
99
    (Code:'RATE';   FType: flRate),
121
    (Code: 'URI';      FType: flURI),
100
    (Code:'URI';    FType:  flURI),
122
    (Code: 'LIBRATE';  FType: flLibRate),
101
    (Code:'LIBRATE';FType:  flLibRate),
123
    (Code: 'KEYWORDS'; FType: flKeyWords),
102
    (Code:'KEYWORDS';FType:  flKeyWords),
124
    (Code: 'URL';      FType: flURI)
103
    (Code:'URL';    FType:  flURI)
104
  );
125
  );
105
126
106
{ TImportLibRusEcThread }
127
  { TImportLibRusEcThread }
107
128
108
function ParseString(const InputStr: String; const DelimiterChar: Char;
129
function ParseString(const InputStr: string; const DelimiterChar: Char; var slParams: TStringList): Boolean;
109
  var slParams: TStringList): Boolean;
130
// const
110
//const
131
// DelimiterChar = Chr(4);
111
//  DelimiterChar = Chr(4);
112
var
132
var
113
  nPos : integer;
133
  nPos: Integer;
114
  cParam: String;
134
  cParam: string;
115
  nParamsCount : Integer;
135
  nParamsCount: Integer;
116
begin
136
begin
117
  nParamsCount := 0;
137
  nParamsCount := 0;
118
  slParams.Clear;
138
  slParams.Clear;
...
...
122
  // иначе - прибавляем символ ко временной переменной
  //
142
  // иначе - прибавляем символ ко временной переменной
  //
123
  cParam := '';
143
  cParam := '';
124
  for nPos := 1 to Length(InputStr) do begin
144
  for nPos := 1 to Length(InputStr) do
125
    if InputStr[nPos] <> DelimiterChar  then
145
  begin
146
    if InputStr[nPos] <> DelimiterChar then
126
      cParam := cParam + InputStr[nPos]
147
      cParam := cParam + InputStr[nPos]
127
    else begin
148
    else
149
    begin
128
      slParams.Add(cParam);
150
      slParams.Add(cParam);
129
      cParam := '';
151
      cParam := '';
130
      inc(nParamsCount);
152
      Inc(nParamsCount);
131
    end;
153
    end;
132
  end;
154
  end;
133
  //
155
  //
134
  // Если временная переменная не пуста, добавляем её в стринглист.
156
  // Если временная переменная не пуста, добавляем её в стринглист.
135
  //
157
  //
136
  if cParam <> '' then begin
158
  if cParam <> '' then
159
  begin
137
    slParams.Add(cParam);
160
    slParams.Add(cParam);
138
    Inc(nParamsCount);
161
    Inc(nParamsCount);
139
    cParam := '';
162
    cParam := '';
140
  end;
163
  end;
164
141
  //
165
  //
142
  // Проверяем соответствие количества параметров в стринглисте счётчику
166
  // Проверяем соответствие количества параметров в стринглисте счётчику
143
  // и выводим полученное значение как результат функции разбора
167
  // и выводим полученное значение как результат функции разбора
...
...
146
  Result := slParams.Count = nParamsCount;
170
  Result := slParams.Count = nParamsCount;
147
end;
171
end;
148
172
149
150
procedure TImportLibRusEcThread.ParseData(input: WideString; var R: TBookRecord);
173
procedure TImportLibRusEcThread.ParseData(input: WideString; var R: TBookRecord);
151
const
174
const
152
  DelimiterChar = Chr(4);
175
  DelimiterChar = Chr(4);
153
var
176
var
154
  p,i: integer;
177
  p, i: Integer;
155
  slParams: TStringList;
178
  slParams: TStringList;
156
  nParamsCount : Integer;
179
  //nParamsCount: Integer;
157
  AuthorList: string;
180
  AuthorList: string;
158
  strLastName: string;
181
  strLastName: string;
159
  strFirstName: string;
182
  strFirstName: string;
...
...
162
  s: string;
185
  s: string;
163
  mm, dd, yy: word;
186
  mm, dd, yy: word;
164
187
165
  Max : integer;
188
  Max: Integer;
166
189
167
begin
190
begin
168
191
...
...
176
      Max := slParams.Count - 1
199
      Max := slParams.Count - 1
177
    else
200
    else
178
      Max := High(FFields);
201
      Max := High(FFields);
179
    //--
202
    // --
180
203
181
    for i := 0 to Max do
204
    for i := 0 to Max do
205
    begin
182
      case FFields[i] of
206
      case FFields[i] of
183
        flAuthor: begin                                       // Список авторов
207
        flAuthor:
184
                    AuthorList := slParams[i];
208
          begin // Список авторов
185
                    p := PosChr(':', AuthorList);
209
            AuthorList := slParams[i];
186
                    while p <> 0 do
210
            p := PosChr(':', AuthorList);
187
                    begin
211
            while p <> 0 do
188
                      s := Copy(AuthorList, 1, p - 1);
212
            begin
189
                      Delete(AuthorList, 1, p);
213
              s := Copy(AuthorList, 1, p - 1);
214
              Delete(AuthorList, 1, p);
190
215
191
                      p := PosChr(',', s);
216
              p := PosChr(',', s);
192
                      strLastName := Copy(s, 1, p - 1);
217
              strLastName := Copy(s, 1, p - 1);
193
                      Delete(S, 1, p);
218
              Delete(s, 1, p);
194
219
195
                      p := PosChr(',', s);
220
              p := PosChr(',', s);
196
                      strFirstName := Copy(s, 1, p - 1);
221
              strFirstName := Copy(s, 1, p - 1);
197
                      Delete(S, 1, p);
222
              Delete(s, 1, p);
198
223
199
                      strMidName := S;
224
              strMidName := s;
200
225
201
                      R.AddAuthor(strLastName, strFirstName, strMidName);
226
              R.AddAuthor(strLastName, strFirstName, strMidName);
202
227
203
                      p := PosChr(':', AuthorList);
228
              p := PosChr(':', AuthorList);
204
                    end;
229
            end;
205
                  end;
230
          end;
206
        flGenre: begin                                         // Список жанров
207
                   GenreList := slParams[i];
208
                   p := PosChr(':', GenreList);
209
                   while p <> 0 do
210
                   begin
211
                     if FGenresType = gtFb2 then
212
                       R.AddGenreFB2('', Copy(GenreList, 1, p - 1), '')
213
                     else
214
                       R.AddGenreAny(Copy(GenreList, 1, p - 1), '');
215
231
216
                     Delete(GenreList, 1, p);
232
        flGenre:
217
                     p := PosChr(':', GenreList);
233
          begin // Список жанров
218
                    end;
234
            GenreList := slParams[i];
219
                 end;
235
            p := PosChr(':', GenreList);
220
        flTitle:  R.Title := slParams[i];                        // Название
236
            while p <> 0 do
221
        flSeries: R.Series := slParams[i];                       // Серия
237
            begin
222
        flSerNo:  R.SeqNumber := StrToIntDef(slParams[i], 0);    // Номер внутри серии
        flFile:   R.FileName := CheckSymbols(Trim(slParams[i])); // Имя файла
        flExt:    R.FileExt := '.' + slParams[i];                // Тип
        flSize:   R.Size := StrToIntDef(slParams[i], 0);         // Размер
        flLibID:  R.LibID := StrToIntDef(slParams[i], 0);        // внутр. номер
238
              if FGenresType = gtFb2 then
223
        flDeleted:R.Deleted := (slParams[i] = '1');              // удалена
239
                R.AddGenreFB2('', Copy(GenreList, 1, p - 1), '')
224
        flDate:   begin                                          // дата
                    if slParams[i] <> '' then
240
              else
225
                    begin
241
                R.AddGenreAny(Copy(GenreList, 1, p - 1), '');
226
                      yy := StrToInt(Copy(slParams[i], 1, 4));
227
                      mm := StrToInt(Copy(slParams[i], 6, 2));
228
                      dd := StrToInt(Copy(slParams[i], 9, 2));
229
                      R.Date := EncodeDate(yy, mm, dd);
230
                    end
231
                    else R.Date := EncodeDate(70,01,01);
232
                  end;
233
242
234
        flInsideNo:  R.InsideNo := StrToInt(slParams[i]);        // номер в архиве
        flFolder:    R.Folder := slParams[i];                    // папка
243
              Delete(GenreList, 1, p);
235
        flLibrate:   R.LibRate := StrToIntDef(slParams[i], 0);   // внешний рейтинг
244
              p := PosChr(':', GenreList);
236
        flLang:      R.Lang := slParams[i];                      // язык
245
            end;
237
        flKeyWords:  R.KeyWords := slParams[i];                  // ключевые слова
        flURI:       R.URI := slParams[i];                  // ключевые слова
    end; // case, for
246
          end;
247
248
        flTitle:
249
          R.Title := slParams[i]; // Название
250
251
        flSeries:
252
          R.Series := slParams[i]; // Серия
253
254
        flSerNo:
255
          R.SeqNumber := StrToIntDef(slParams[i], 0); // Номер внутри серии
256
        flFile:
257
          R.FileName := CheckSymbols(Trim(slParams[i])); // Имя файла
258
        flExt:
259
          R.FileExt := '.' + slParams[i]; // Тип
260
        flSize:
261
          R.Size := StrToIntDef(slParams[i], 0); // Размер
262
        flLibID:
263
          R.LibID := StrToIntDef(slParams[i], 0); // внутр. номер
264
265
        flDeleted:
266
          R.Deleted := (slParams[i] = '1'); // удалена
267
268
        flDate:
269
          begin // дата
            if slParams[i] <> '' then
270
            begin
271
              yy := StrToInt(Copy(slParams[i], 1, 4));
272
              mm := StrToInt(Copy(slParams[i], 6, 2));
273
              dd := StrToInt(Copy(slParams[i], 9, 2));
274
              R.Date := EncodeDate(yy, mm, dd);
275
            end
276
            else
277
              R.Date := EncodeDate(70, 01, 01);
278
          end;
279
280
        flInsideNo:
281
          R.InsideNo := StrToInt(slParams[i]); // номер в архиве
282
        flFolder:
283
          R.Folder := slParams[i]; // папка
284
285
        flLibRate:
286
          R.LibRate := StrToIntDef(slParams[i], 0); // внешний рейтинг
287
288
        flLang:
289
          R.Lang := slParams[i]; // язык
290
291
        flKeyWords:
292
          R.KeyWords := slParams[i]; // ключевые слова
293
        flURI:
294
          R.URI := slParams[i]; // ключевые слова
      end; // case, for
295
    end;
296
238
    R.Normalize;
297
    R.Normalize;
239
  finally
298
  finally
240
    slParams.Free;
299
    slParams.Free;
...
...
256
  FN = 'structure.info';
315
  FN = 'structure.info';
257
316
258
var
317
var
259
  S: string;
318
  s: string;
260
  p, i: integer;
319
  p, i: Integer;
261
  F: text;
320
  F: text;
262
321
263
  function FindType(S:string): TFields;
322
  function FindType(s: string): TFields;
264
  var
323
  var
265
    F: TFieldDescr;
324
    F: TFieldDescr;
266
  begin
325
  begin
267
    for F in FieldsDescr do
326
    for F in FieldsDescr do
268
      if F.Code = S then
327
      if F.Code = s then
269
      begin
328
      begin
270
        Result := F.FType;
329
        Result := F.FType;
271
        Break;
330
        Break;
272
      end;
331
      end;
273
  end;
332
  end;
274
333
275
276
begin
334
begin
277
335
  s := '';
278
  S := '';
279
  if FileExists(Settings.TempPath + FN) then
336
  if FileExists(Settings.TempPath + FN) then
280
  begin
337
  begin
281
    AssignFile(F,Settings.TempPath + FN);
338
    AssignFile(F, Settings.TempPath + FN);
282
    Reset(F);
339
    Reset(F);
283
    Read(F,S);
340
    Read(F, s);
284
    CloseFile(F);
341
    CloseFile(F);
285
342
286
    DeleteFile(Settings.TempPath + FN);
343
    DeleteFile(Settings.TempPath + FN);
287
  end;
344
  end;
288
345
289
  if S = '' then S := Default;
346
  if s = '' then
347
    s := Default;
290
348
291
  // код
349
  // код
292
  SetLength(FFields,0);
350
  SetLength(FFields, 0);
293
  i :=0;
351
  i := 0;
294
  p := pos(del,S);
352
  p := Pos(del, s);
295
  while p <> 0 do
353
  while p <> 0 do
296
  begin
354
  begin
297
    SetLength(FFields,i + 1);
355
    SetLength(FFields, i + 1);
298
    FFields[i] := FindType(copy(S,1,p - 1));
356
    FFields[i] := FindType(Copy(s, 1, p - 1));
299
    Delete(S,1,p);
357
    Delete(s, 1, p);
300
    p := pos(del,S);
358
    p := Pos(del, s);
301
359
302
    if not FPersonalFolder then
360
    if not FPersonalFolder then
303
        FPersonalFolder := (FFields[i]=flFolder);
361
      FPersonalFolder := (FFields[i] = flFolder);
304
362
305
    inc(i);
363
    Inc(i);
306
  end;
364
  end;
307
end;
365
end;
308
366
309
function TImportLibRusEcThread.Import(CheckFiles: boolean):integer;
367
function TImportLibRusEcThread.Import(CheckFiles: boolean): Integer;
310
var
368
var
311
  FLibrary: TMHLLibrary;
369
  FLibrary: TMHLLibrary;
312
  BookList: TStringList;
370
  BookList: TStringList;
...
...
314
  j: Integer;
372
  j: Integer;
315
  R: TBookRecord;
373
  R: TBookRecord;
316
  filesProcessed: Integer;
374
  filesProcessed: Integer;
317
  unZip:TZipForge;
375
  unZip: TZipForge;
318
  CurrentFile: string;
376
  CurrentFile: string;
319
  ArchItem: TZFArchiveItem;
377
  ArchItem: TZFArchiveItem;
320
  FileStream : TMemoryStream;
378
  //FileStream: TMemoryStream;
321
begin
379
begin
322
  filesProcessed := 0;
380
  filesProcessed := 0;
323
  i := 0;
381
  i := 0;
324
  SetProgress(0);
382
  SetProgress(0);
383
325
  FLibrary := TMHLLibrary.Create(nil);
384
  FLibrary := TMHLLibrary.Create(nil);
326
  try
385
  try
327
    FLibrary.DatabaseFileName := DBFileName;
386
    FLibrary.DatabaseFileName := DBFileName;
328
    FLibrary.Active := True;
387
    FLibrary.Active := True;
329
    FLibrary.BeginBulkOperation;
388
    FLibrary.BeginBulkOperation;
330
    try
389
    try
331
      unZip := TZipForge.Create(Nil);
390
      unZip := TZipForge.Create(nil);
332
      unZip.BaseDir := Settings.TempPath;
333
      unZip.FileName := FInpxFileName;
334
      unZip.OpenArchive;
335
      unZip.ExtractFiles('*.*');
336
      GetFields;
337
      try
391
      try
338
        BookList := TStringListEx.Create;
392
        unZip.BaseDir := Settings.TempPath;
339
        if (unZip.FindFirst('*.inp',ArchItem,faAnyFile-faDirectory)) then
393
        unZip.FileName := FInpxFileName;
340
        repeat
394
        unZip.OpenArchive;
341
          CurrentFile:= ArchItem.FileName;
395
        unZip.ExtractFiles('*.*');
342
          if not(isOnlineCollection(CollectionType)) and
343
            ( CurrentFile = 'extra.inp')
344
            then Continue;
345
396
346
          Teletype(Format('Обрабатываем файл %s', [CurrentFile]), tsInfo);
397
        GetFields;
347
          BookList.LoadFromFile(Settings.TempPath + CurrentFile,TEncoding.UTF8);
398
348
          for j := 0 to BookList.Count - 1 do
399
        BookList := TStringListEx.Create; { TODO -oNickR -cunused code : насколько я понимаю, этот класс больше ненужен }
400
        try
401
          if (unZip.FindFirst('*.inp', ArchItem, faAnyFile - faDirectory)) then
349
          begin
402
          begin
350
            try
403
            repeat
351
              ParseData(BookList[j], R);
404
              CurrentFile := ArchItem.FileName;
352
              if isOnlineCollection(CollectionType) then
405
406
              if not isOnlineCollection(CollectionType) and (CurrentFile = 'extra.inp') then
407
                Continue;
408
409
              Teletype(Format('Обрабатываем файл %s', [CurrentFile]), tsInfo);
410
411
              BookList.LoadFromFile(Settings.TempPath + CurrentFile, TEncoding.UTF8);
412
413
              for j := 0 to BookList.Count - 1 do
353
              begin
414
              begin
354
                // И\Иванов Иван\1234 Просто книга.fb2.zip
415
                try
355
                R.Folder := R.GenerateLocation + FB2ZIP_EXTENSION;
416
                  ParseData(BookList[j], R);
356
                // Сохраним отметку о существовании файла
                R.Local := FileExists(FCollectionRoot + R.Folder);
417
                  if isOnlineCollection(CollectionType) then
357
              end
418
                  begin
358
              else
419
                    // И\Иванов Иван\1234 Просто книга.fb2.zip
359
              begin
420
                    R.Folder := R.GenerateLocation + FB2ZIP_EXTENSION;
360
                if not FPersonalFolder then
421
                    // Сохраним отметку о существовании файла
                    R.Local := FileExists(FCollectionRoot + R.Folder);
361
                begin
422
                  end
362
                  // 98058-98693.inp -> 98058-98693.zip
423
                  else
363
                  R.Folder := ChangeFileExt(CurrentFile, ZIP_EXTENSION);
424
                  begin
364
                  //
425
                    if not FPersonalFolder then
365
                  R.InsideNo := j;
426
                    begin
366
                end
427
                      // 98058-98693.inp -> 98058-98693.zip
367
              end;
428
                      R.Folder := ChangeFileExt(CurrentFile, ZIP_EXTENSION);
368
              if FLibrary.InsertBook(R, CheckFiles, False)<>0 then
429
                      //
430
                      R.InsideNo := j;
431
                    end
432
                  end;
433
434
                  if FLibrary.InsertBook(R, CheckFiles, False) <> 0 then
369
                    Inc(filesProcessed);
435
                    Inc(filesProcessed);
370
              if (filesProcessed mod ProcessedItemThreshold) = 0 then
436
371
              begin
437
                  if (filesProcessed mod ProcessedItemThreshold) = 0 then
372
                SetProgress(round((i + j/BookList.Count) * 100 / unZip.FileCount));
438
                  begin
373
                SetComment(Format('Добавлено %u книг', [filesProcessed]));
439
                    SetProgress(Round((i + j / BookList.Count) * 100 / unZip.FileCount));
440
                    SetComment(Format('Добавлено %u книг', [filesProcessed]));
441
                  end;
442
                except
443
                  on EConvertError do
444
                    Teletype(Format('Ошибка структуры inp. Файл %s, Строка %u ', [CurrentFile, j]), tsError);
445
                end;
374
              end;
446
              end;
375
            except
447
376
              on EConvertError do
448
              Inc(i);
377
                    Teletype(Format('Ошибка структуры inp. Файл %s  Строка %u ', [CurrentFile,j]), tsError);
449
              if Canceled then
378
            end;
450
                Break;
451
            until (not unZip.FindNext(ArchItem));
379
          end;
452
          end;
380
          inc(i);
453
        finally
381
          if Canceled then
454
          BookList.Free;
382
            Break;
455
        end;
383
        until (not unZip.FindNext(ArchItem));
456
        Teletype(Format('Добавлено %u книг', [filesProcessed]), tsInfo);
384
      finally
457
      finally
385
        BookList.Free;
458
        unZip.Free;
386
      end;
459
      end;
387
      Teletype(Format('Добавлено %u книг', [filesProcessed]), tsInfo);
388
    finally
460
    finally
389
      unZip.Free;
461
      FLibrary.EndBulkOperation;
390
    end;
462
    end;
391
  finally
463
  finally
392
    FLibrary.EndBulkOperation;
393
    FLibrary.Free;
464
    FLibrary.Free;
394
  end;
465
  end;
395
end;
466
end;
...
...
406
end;
477
end;
407
478
408
end.
479
end.
409