{*********************************************************

 SlavaNap source code.

 Copyright 2001,2002 by SlavaNap development team
 Released under GNU General Public License

 Latest version is available at
 http://www.slavanap.org

**********************************************************

 Unit: Share2

 Some additional functions for unit Share.pas

*********************************************************}
unit Share2;

interface

uses
  Windows, Classes2, SysUtils, STypes, Constants, Slavastrings, Class_Cmdlist,
  Class_Cmd2List, Share, LocalUsers;

{$I Defines.pas}

procedure SplitFileName(FileName: string; var Folder: string; var Name: string);
procedure GetKeywords(FileName: string; List: TNapCmdList); overload;
function GetKeywords(FileName: string; Meta: Integer; User: TLocalUser;
  Item: PShare): Boolean; overload;
function AddKeywordsItem(Meta: Byte; Item: PShare;
  Keywords: TNapCmdList): Boolean;
procedure DeleteKeywordsItem(Item: PShare);

implementation

uses
  Vars, Handler, Keywords, Keywords2, Blocks;

procedure SplitFileName(FileName: string; var Folder: string; var Name: string);
var
  I, P: Integer;
begin
  for I := Length(FileName) - 3 downto 1 do
    if IsDelimiter('\/', FileName, I) then
    begin
      Folder := Copy(FileName, 1, I);
      Name := Copy(FileName, I + 1, Length(FileName) - I);
      Exit;
    end;
  Folder := '';
  Name := FileName;
end;

procedure GetKeywords(FileName: string; List: TNapCmdList);
var
  I, J, K: Integer;
  Dir, Name, Ext: string;
  Start, Len, Crc: Integer;
  C: Char;
begin
  List.Clear;
  Tmp_Pos := 1264;
  Len := Length(FileName);
  if Len < MIN_FILE_NAME then Exit;
  FileName := AnsiLowerCase(FileName);
  // DebugLog('Getting keywords from "' + FileName + '":', True);
   // extracting extension (up to 4 characters extension)
  Start := 0;
  for I := 0 to 4 do
    if Start = 0 then
      if FileName[Len - I] = '.' then
        Start := Len - I;
  if Start = 0 then // no extension
    Ext := ''
  else
  begin // found extension
    Ext := Copy(FileName, Start + 1, 5);
    Len := Start - 1;
    SetLength(FileName, Len);
  end;
  Tmp_Pos := 1265;
  // extracting filename
  Start := 0;
  if Len > 0 then
    for I := Len downto 1 do
      if Start = 0 then
        if IsDelimiter('\/:', FileName, I) then
          Start := I;
  if Start = 0 then // no filename???
    Name := ''
  else
  begin
    Name := Copy(FileName, Start + 1, Len);
    Len := Start - 1;
    if Len < 0 then
      Len := 0;
    SetLength(FileName, Len);
  end;
  Tmp_Pos := 1266;
  // extracting sub-dir
  Start := 0;
  if Len > 0 then
    for I := 1 to Len do
      if IsDelimiter('\/:', FileName, I) then
      begin
        Start := I;
        Break;
      end;
  {  for I := Len downto 1 do
     if Start = 0 then
      if IsDelimiter('\/:', FileName, I) then
       Start := I;
  }
  if Start = 0 then // No directory
    Dir := ''
  else
    Dir := Copy(FileName, Start + 1, Len);
  // DebugLog('  Directory="' + Dir + '", Name="' + Name + '", Ext="' + Ext + '"', True);
   // extracting keywords
  I := MAX_FILE_KEYWORDS;
  Dec(I, SplitToKeywords(Ext + ' ', List, 1));
  J := SplitToKeywords(Name + ' ', List, I);
  if J < 1 then
  begin // no keywords in fileName - cannot share file
    List.Clear;
    Exit;
  end;
  Dec(I, J);
  Tmp_Pos := 1267;
  if (I > 0) and (Length(Dir) > 0) then
  begin
    // checking blocked dirs list
    Crc := StringCRC(Dir, False);
    for I := 0 to DB_Dirs.Count - 1 do
      if Crc > 0 then
        if PNapCmd(DB_Dirs.Items[I])^.Id = Crc then
          if PNapCmd(DB_Dirs.Items[I])^.Cmd = Dir then
            Crc := 0; // blocked directory
    if Crc > 0 then
      SplitToKeywords(Dir + ' ', List, I); // extracting keywords from directory
  end;
end;

function GetKeywords(FileName: string; Meta: Integer; User: TLocalUser;
  Item: PShare): Boolean;
var
  List: TNapCmdList;
  Sharing: Boolean;
begin
  Tmp_Pos := 1268;
  // getting keywords
  List := TNapCmdList.Create;
  GetKeywords(FileName, List);
  Tmp_Pos := 1269;
  // checking blocked files
  if Share_MatchedFile_Only then
    Sharing := IsFileBlocked(User, Item, FileName, List)
  else
    Sharing := not IsFileBlocked(User, Item, FileName, List);
  if not Sharing then
  begin
    if ((User.Data^.Level > napUserModerator) and (not Block_AllowShare_Admins))
      or ((User.Data^.Level < napUserAdmin) and (not Block_AllowShare)) then
    begin
      List.Free;
      Inc(User.Data^.BlockFiles);
      Result := False;
      Exit;
    end;
    opIsShared(Item^.Options, False);
  end;
  Tmp_Pos := 1270;
  // adding keywords
  Result := AddKeywordsItem(Meta, Item, List);
  List.Free;
end;

function AddKeywordsItem(Meta: Byte; Item: PShare;
  Keywords: TNapCmdList): Boolean;
// adds keywords from 'Keywords' pointing to 'Item' to database
var
  I, J: Integer;
  Lst: TMyList;
  Keyword: string;
  Kw: PKeyword;
  Kwi: PKeywordItem;
  Index, KwLength: Integer;
begin
  Tmp_Pos := 1271;
  Result := True;
  if opNumWords(Item^.Options) > 0 then
    FreeKeywordsList(Item);
  Lst := TMyList.Create;
  Tmp_Pos := 1272;
  for I := 0 to Keywords.Count - 1 do
  begin
    Keyword := PNapCmd(Keywords.Items[I])^.Cmd;
    KwLength := Length(Keyword);
    Index := GetKeywordIndex(Keyword);
    if Index <> KEYWORDS_NOINDEX then
    begin
      Tmp_Pos := 1273;
      Kw := KWList_FindItem(DB_Keywords[Meta, Index, KwLength], Keyword);
      if Kw = nil then
        Kw := KWList_AddItem(DB_Keywords[Meta, Index, KwLength], Meta, Keyword);
      Tmp_Pos := 1274;
      Kwi := KWList_AddShare(Kw, Item);
      Lst.Add(Kw);
      Lst.Add(Kwi);
      if Lst.Count >= MAX_FILE_KEYWORDS * 2 then
      begin // too many keywords. stopping
        Tmp_Pos := 1275;
        AllocateKeywordsList(Item, Lst.Count div 2);
        for J := 0 to Lst.Count - 1 do
          Item^.Keywords^[J] := Lst.Items[J];
        Lst.Free;
        Exit;
      end;
    end;
  end;
  Tmp_Pos := 1276;
  if Lst.Count < 2 then
  begin
    Result := False;
    Lst.Free;
    Exit;
  end;
  AllocateKeywordsList(Item, Lst.Count div 2);
  for J := 0 to Lst.Count - 1 do
    Item^.Keywords^[J] := Lst.Items[J];
  Lst.Free;
end;

procedure DeleteKeywordsItem(Item: PShare);
// deletes all keyword items from database
var
  I, Words: Integer;
begin
  Tmp_Pos := 1277;
  Words := opNumWords(Item^.Options);
  for I := 0 to Words - 1 do
    KWList_DeleteShare(Item^.Keywords[I * 2], Item^.Keywords[I * 2 + 1], Item);
  Tmp_Pos := 1278;
  FreeKeywordsList(Item);
end;

end.
