PascalScript w Syncovery
Syncovery zawiera silnik PascalScript, który pozwala dostosować działanie profilu na wiele sposobów. PascalScript został dodany w Syncovery 8, a od pierwszej wersji dodano wiele nowych hooków i funkcji.
Aby zmienić określone działanie, trzeba napisać funkcję hook i trochę kodu. W większości przypadków nasz dział wsparcia technicznego napisze kod za Ciebie. W przypadku większych lub bardziej złożonych skryptów prosimy rozważyć subskrypcję wsparcia Premium, która obejmuje tworzenie niestandardowych skryptów.
Skrypt jest określany w profilu za pomocą pola wyboru „Pascal Script…” na karcie kategorii Ustawienia zadania.
Skrypty PascalScript mają dostęp do wszystkich ustawień profilu i mogą je odczytywać oraz modyfikować za pomocą funkcji narzędziowych GetProfileProperty i SetProfileProperty.
Przydatne gotowe skrypty
Poniższe skrypty mogą być użyte w takiej postaci, wystarczy wkleić skrypt do okna PascalScript.
- Skróć długie ścieżki
Ten skrypt skraca nazwy plików, jeśli pełna ścieżka przekracza 250 znaków. Dodaje skrót CRC32 oparty na oryginalnej nazwie pliku, aby skrócone nazwy były unikalne. Nazwy folderów nie są modyfikowane. Skrócone nazwy są używane tylko podczas kopiowania z lewej strony na prawą. Lewa strona pozostaje bez zmian. - Skróć długie nazwy plików
Ten skrypt skraca nazwy plików, które mają ponad 114 znaków, dodając skrót CRC32 oparty na oryginalnej nazwie pliku, aby skrócone nazwy były unikalne. Podobnie jak w poprzednim skrypcie, nazwy folderów nie są modyfikowane, a skrócone nazwy dotyczą tylko prawej strony. - Konwertuj niedozwolone znaki dla systemu Windows
Ten skrypt pozwala używać niedozwolonych znaków /:\?|<>“* w nazwach plików po lewej stronie. Prawa strona może być zgodnym z Windows magazynem, takim jak lokalny dysk NTFS. - Proste powiadomienia e-mail
Ten skrypt upraszcza powiadomienia e-mail i można go łatwo edytować, aby dostosować wiadomości. - Wysyłaj powiadomienia e-mail w zależności od wyniku profilu
Ten skrypt powoduje wysyłanie powiadomień e-mail tylko wtedy, gdy skopiowano z lewej na prawą mniej niż 10 lub więcej niż 100 plików. - Przypisz połączenie FTP do określonego portu LAN
Ten skrypt pozwala określić, którego portu LAN użyć dla połączenia FTP. Uwaga: działa to tylko z biblioteką FTP 3 (w systemie Windows) lub 2 (na innych platformach). - Usuń pliki starsze niż 30 dni ze źródłowej (lewej) strony
Ten skrypt spowoduje, że Syncovery usunie starsze pliki ze źródłowej strony synchronizacji jednokierunkowej. Strona źródłowa musi znajdować się po lewej stronie. Prawa strona będzie służyć jako archiwum, w którym przechowywane są wszystkie historyczne pliki, natomiast lewa strona zawiera tylko pliki z ostatnich 30 dni. Zakłada się, że nowe pliki pojawiają się tylko po lewej stronie. Profil powinien być używany wyłącznie w trybie operacji „Standardowe kopiowanie”. Liczbę dni można dostosować w skrypcie. Można też wybrać, czy usuwać nowo skopiowane pliki (co jest mało prawdopodobne, ponieważ zapewne nie są starsze niż 30 dni), i/lub pliki, które już istnieją po obu stronach w momencie uruchomienia zadania (bardziej prawdopodobny przypadek).
Dostępne haki PascalScript
Obecnie dostępne są następujące haki. W razie potrzeby będą dodawane kolejne, aby spełnić wymagania klientów.
- OnActionComplete
- OnAfterFileCopy
- OnBeforeFileCopy
- OnBeforeFileUpload
- OnBeforeFolderCreate
- OnBeforeMainActionPhase
- OnCanRunProfile
- OnCloudConnect
- OnCloudDisconnect
- OnDownloadComplete
- OnFileCopy
- OnGetCustomHeaders
- OnGetNextRunTime
- OnGetProfilePathBeforeListing
- OnGetProfilePathBeforeCopying
- OnHttpPost
- OnIncludeItem
- OnLogFileClosed
- OnMoveFileToDeletedFolder
- OnNeedToReRun
- OnNoActionItem
- OnNormalizeFilename
- OnProfileStart
- OnProfileResults
- OnProgress
- OnReplaceFilenameLeftToRight
- OnReplaceFilenameRightToLeft
- OnScanFolder
- OnSendEmail
- OnSkipOrIgnoreItem
- OnUploadComplete
- OnVerifySSHServerFingerprint
- OnVerifyTLSCertificate
- OnVolumeShadowComplete
Dostępne funkcje PascalScript
Dostępne są następujące funkcje, z których możesz korzystać.
- standardowe funkcje, takie jak Pos, Copy, Length, Ord
- function GetProfileProperty(const fieldname:UnicodeString):UnicodeString;
- function SetProfileProperty(const fieldname:UnicodeString;const val:UnicodeString):Boolean;(te funkcje używają tych samych nazw pól co format XML i wiersz poleceń. Zobacz słownik ustawień na końcu strony Syncovery Command Line)
- function SaveProfileSettings:Boolean;
- procedure LoadFolderPriorityTextFile(const s:UnicodeString);
- function ConcatPath(const a,b:UnicodeString; const t: Int64):UnicodeString;
- function ConcatPathWithDelim(const a,b,delim:UnicodeString):UnicodeString;
- function ExtractFileName(const s: UnicodeString):UnicodeString;
- function ExtractFileNameFTP(const s: UnicodeString):UnicodeString;
- function ExtractFilePath(const s: UnicodeString):UnicodeString;
- function ExtractFilePathFTP(const s: UnicodeString):UnicodeString;
- function ExtractURLPartAfterServer(const s: UnicodeString):UnicodeString;
- function ExtractFileExt(const s: UnicodeString):UnicodeString;
- function ChangeFileExt(const s,t: UnicodeString):UnicodeString;
- function FileExists(const FileName: UnicodeString):Boolean;
- function FileExistsMatching(const FileName: UnicodeString):Boolean;
- function EntryExists(const FileName: UnicodeString):Boolean;
- function FileAge(const FileName: UnicodeString):Double;
- function FileCopy(const ASource,ADest:UnicodeString):Int64;
- function FileDelete(const AFile:UnicodeString):Int64;
- function FileRename(const ASource,ADest:UnicodeString):Int64;
- function ProfileRunning(const s: UnicodeString):Boolean;
- procedure Log(const s:UnicodeString);
- procedure MessageBox(const s:UnicodeString);
- function Execute(const s:UnicodeString; const TimeOutSeconds: Int64):Int64;
- function GetProfileName:UnicodeString;
- procedure SetProfileResult(const AResultText:UnicodeString);
- function CreateS3Connector(const BucketName,AccessID,SecretKey:UnicodeString;const Options:Integer):Opaque;
- function UploadFile(const LocalPath,DestinationPath:UnicodeString;const Connector:Opaque):Int64;
- function CloseConnector(const Connector:Opaque):Int64;
- function ConnFileExists(const Connector:Opaque; const FileName: UnicodeString):Boolean;
- function ConnDirectoryExists(const Connector:Opaque; const Name: UnicodeString):Boolean;
- function ConnCustomFTPCommand(const Connector:Opaque; const ACommand: UnicodeString;
const AOkResponse1,AOkResponse2,AOkResponse3:Integer;
var ResponseText: UnicodeString):Integer; - function ConnProcessWebForm(const Connector:Opaque;
const URL, AFormName, AField1, AValue1, AField2, AValue2: AnsiString;
const SaveResultPage: Boolean;
const SavePageFileName: UnicodeString): Boolean; - function ConnRenameFile(const Connector:Opaque; const AFromFileName,AToFileName: UnicodeString):Boolean;
- function ConnDeleteFile(const Connector:Opaque; const AFileName: UnicodeString):Boolean;
- function ConnDeleteFiles(const Connector:Opaque; const APath,AMask: UnicodeString):Integer;
- function ConnDeleteFilesOlderThan(const Connector:Opaque; const APath,AMask: UnicodeString;const AWhen:Double):Integer;
- function SendHTTPRequest(const requestype,mimetype,additionalheaders,URL,PostData:AnsiString;var ResultCode:Int64;var Response,ErrorResponse:AnsiString):Boolean;
- function StringReplace(const Source, OldPattern, NewPattern: UnicodeString;const CaseSensitive:Boolean): UnicodeString;
- function EncodeBase64(const s: UnicodeString):UnicodeString;
- function DecodeBase64(const s: UnicodeString):UnicodeString;
- function Utf8Encode(const s: UnicodeString):AnsiString;
- function Utf8Decode(const s: AnsiString):UnicodeString;
- function DecodeAnsiURL(const anurl:AnsiString):AnsiString;
- function DecodeUnicodeURL(const anurl:UnicodeString):UnicodeString;
- function UnicodeStringMD5Hex(const s: UnicodeString):UnicodeString;
- function EightBitStringMD5Hex(const s: AnsiString):AnsiString;
- function UnicodeStringMD5Base64(const s: UnicodeString):UnicodeString;
- function EightBitStringMD5Base64(const s: AnsiString):AnsiString;
- function UnicodeStringCRC32Hex(const s: UnicodeString):UnicodeString;
- function EightBitStringCRC32Hex(const s: AnsiString):AnsiString;
- function UnicodeStringCRC32Base64(const s: UnicodeString):UnicodeString;
- function EightBitStringCRC32Base64(const s: AnsiString):AnsiString;
- function SimpleEncrypt(const s: UnicodeString):UnicodeString;
- function SimpleDecrypt(const s: UnicodeString):UnicodeString;
- function AESEncrypt(const s,passphrase: UnicodeString):UnicodeString;
- function AESDecrypt(const s,passphrase: UnicodeString):UnicodeString;
- function ChooseFile(const Prompt,Extension:UnicodeString):UnicodeString;
- function OpenIniFile(const AFileName:UnicodeString):Int64;
- procedure CloseIniFile(const AnIni:Int64);
- function ReadIniString(const AnIni:Int64;const Section,Ident,Default:UnicodeString):UnicodeString;
- function GetInput(const s: UnicodeString):UnicodeString;
- function GetPassword(const s: UnicodeString):UnicodeString;
- function ReadRegistryString(const Key,OptName:UnicodeString):UnicodeString;
- procedure WriteRegistryString(const Key,OptName,Value:UnicodeString);
- function GetProfileRunID:UnicodeString;
- procedure ClearBody;
- function GetBodyLine(const i:Integer):UnicodeString;
- procedure SetBodyLine(const i:Integer;const s:UnicodeString);
- procedure DeleteBodyLine(const i:Integer);
- procedure AddBodyText(const s:UnicodeString);
- function GetActionList:UnicodeString;
- function GetProfileSettings:UnicodeString;
- function Now:Double;
- function NowUTC:Double;
- function OffsetFromUTC:Double;
- function TimeToStr(const DateTime: Double):UnicodeString;
- function DateTimeToStr(const DateTime: Double):UnicodeString;
- function DateToStr(const DateTime: Double):UnicodeString’;
- function DateTimeToStrWithFormat(const DateTime: Double;const FormatString:UnicodeString):UnicodeString;
- function MakeSurePathExists(const s:UnicodeString;const isRightSide:Boolean):Boolean;
- function GetTempDir:UnicodeString;
- function GetTempFilename(const TryCreateIt:Boolean;const Extension:UnicodeString):UnicodeString;
- function PathDelim:UnicodeString;
- function LeftDelim:UnicodeString;
- function RightDelim:UnicodeString;
- function GetDelim(const Connector: Opaque):UnicodeString;
- function IncludeLeadingPathDelim(const s: UnicodeString):UnicodeString;
- function OpenTextFile(const s:UnicodeString):Opaque;
- function AppendTextFile(const s:UnicodeString):Opaque;
- function CreateTextFile(const s:UnicodeString):Opaque;
- procedure WriteLine(const F:Opaque;const ALine:UnicodeString);
- function ReadLine(const F:Opaque):UnicodeString;
- function EOF(const F:Opaque):Boolean;
- procedure CloseFile(const F:Opaque);
- function AtomicAppendTextFileLine(const APath,ALine:UnicodeString):Boolean;(dopisuje linię w sposób bezpieczny dla wielu wątków i wielu procesów)
- function YearOf(const dt:Double):Integer;
- function MonthOf(const dt:Double):Integer;
- function WeekOf(const dt:Double):Integer;
- function DayOf(const dt:Double):Integer;
- function DayOfTheWeek(const dt:Double):Integer;
- function SecondOf(const dt:Double):Integer;
- function HourOf(const dt:Double):Integer;
- function MinuteOf(const dt:Double):Integer;
- function EncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Integer): Double;
- function FileToCopyExistsLeft:Boolean;
- function FileToCopyExistsRight:Boolean;
- function FileToCopyLeftSize:Int64;
- function FileToCopyRightSize:Int64;
- function FileToCopyLeftModified:Double;
- function FileToCopyRightModified:Double;
- function CurrentFileModified:Double;
- function CurrentFileCreated:Double;
- function CurrentFileLastAccessed:Double;
- procedure CountDeletedFiles(const Left,Right:Integer);
(może być używane z symbolami wieloznacznymi w nazwie pliku, ale nie w folderach nadrzędnych)
Dostępne zmienne globalne
Te zmienne globalne umożliwiają bezpośredni dostęp do wewnętrznych pól Syncovery. Część z nich należy traktować jako tylko do odczytu, a inne można w razie potrzeby modyfikować.
- ProfileTempDir: UnicodeString;
- LeftBasePath: UnicodeString;
- RightBasePath: UnicodeString;
- ProfileName: UnicodeString;
- ResultSummary: UnicodeString;
- LeftBindIP: UnicodeString;
- RightBindIP: UnicodeString;
- MinimumFreeSpaceLeft: Int64;
- MinimumFreeSpaceRight: Int64;
- MaxWaitWhenFreeSpaceLowSeconds: Integer;
- MinDate: Double;
- MaxDate: Double;
- FilterTimestamps: Boolean;
- FilterOnSourceSideOnly: Boolean;
- FiltersMustMatchOnBothSides:Boolean;
- NeedActionsLog: Boolean;
- UseBinaryCompToAvoidCopying: Boolean;
- RemoveEmptyFoldersOnlyOneLevelWhereAFileHasBeenRemoved: Boolean;
- IgnoreFileSizes: Boolean;
- SkipIfFileSizeChanging: Boolean;
- ActionsLogging: Boolean;
- FreeSpaceLogging: Boolean;
- CopyingStatisticsLogging: Boolean;
- FileCopyNoStatNeeded: Boolean;
- DoSmartTrackingDeletionsEvenIfOtherSideModified: Boolean;
Przykładowy skrypt OnActionComplete
Ten hak jest wywoływany po wykonaniu dowolnego typu działania związanego z plikiem lub folderem, takiego jak skopiowanie, przeniesienie lub usunięcie pliku i tak dalej. Przykład po prostu zapisuje akcję do dziennika. Syncovery ignoruje wynik funkcji.
function OnActionComplete(const StartTimeUTC, CompletionTimeUTC: Double;
const Success: Boolean;
const ActionStr, DirectionStr, Filename,
LeftFile, RightFile, Subfolder, MovedTo,
ErrorMsg: UnicodeString;
const ResultCode: Int64;
const ErrorSide: UnicodeString;
const ASize,ACompressedSize:Int64):Boolean;
begin
Log('Action Complete: '+ActionStr+' '+DirectionStr+' '+Filename);
Result:=true;
end;
Przykładowy skrypt OnAfterFileCopy
Ten hook jest wywoływany po skopiowaniu pliku. Wynik funkcji jest ignorowany przez Syncovery. Jest używany przez przykładowy skrypt „Usuwanie plików starszych niż 30 dni ze strony źródłowej (lewej)”.
function OnAfterFileCopy(const DirectionIsL2R:Boolean;
const Source,Dest,DestPath,LeftSubPath,RightSubPath:UnicodeString;
const ResultCode:Int64):Boolean;
begin
Log('File Copy Complete: '+Source+' to '+Dest);
Result:=true;
end;
Przykładowy skrypt OnCanRunProfile
Ten hook jest wywoływany, gdy harmonogram ma uruchomić profil. Możesz zdecydować, czy ma on zostać faktycznie uruchomiony teraz, czy odroczony. W przykładzie hook służy do zapobiegania jednoczesnemu uruchamianiu dwóch konkretnych profili lub ich nakładaniu się. Ten skrypt należy wprowadzić jako Global PascalScript w oknie Ustawienia programu, na karcie Zaawansowane.
const p1='Profile Name 1';
p2='Profile Name 2';
function OnCanRunProfile(const ProfileName:UnicodeString; var PostponeBySeconds:Integer):Boolean;
begin
if ProfileName=p1 then
Result:=not ProfileRunning(p2)
else
if ProfileName=p2 then
Result:=not ProfileRunning(p1)
else
Result:=true;
if not Result then
PostponeBySeconds:=60;
end;
Przykładowy skrypt OnFileCopy
Ten hook umożliwia zastąpienie logiki kopiowania plików. Zwróć 0 w przypadku powodzenia, -1, jeśli Syncovery ma wykonać kopiowanie w zwykły sposób, albo dowolną inną wartość jako kod błędu.
function OnFileCopy(const DirectionIsL2R:Boolean;
const Source,Dest,DestPath,LeftSubPath,RightSubPath:UnicodeString;
const SourceConnector,DestConnector: Opaque):Int64;
begin
Result:=Execute('XCOPY.EXE "'+Source+'" "'+DestPath+'"',60);
end;
Przykładowy skrypt OnGetCustomHeaders
Ten hook umożliwia dodawanie niestandardowych nagłówków HTTP do żądań Amazon S3. W przyszłych wersjach Syncovery ta funkcja może zostać dodana do innych usług chmurowych i protokołów (na życzenie klienta — wystarczy poprosić).
function OnGetCustomHeaders(const RelativePath: UnicodeString;
const URL:AnsiString;var MIMEType, Headers: AnsiString;
const Connector:Opaque):Boolean;
var strDate:string;
begin
Result:=true;
Headers:='Cache-Control: 10';
Log('');
Log('Headers Added to '+RelativePath);
Log(Headers);
Log('');
end;
Przykładowy skrypt OnGetNextRunTime
Ten hook umożliwia modyfikację harmonogramu. Najlepiej użyć go tak, aby profil miał zwykły, prosty harmonogram, a hook był wykorzystywany do pomijania niepożądanych godzin uruchomienia. Ten przykład jest przeznaczony dla profilu zaplanowanego do uruchamiania „codziennie o XX:YY”. Hook zapewnia, że w rzeczywistości uruchamia się on tylko w pierwszy dzień roboczy w miesiącu.
function OnGetNextRunTime(const LastRun, ProposedNextRun: Double):Double;
var DidItRunThisMonth:Boolean;
begin
Result:=ProposedNextRun;
DidItRunThisMonth:=(MonthOf(LastRun)=MonthOf(Now)) and
(MonthOf(LastRun)=MonthOf(ProposedNextRun)) and
(DayOf(LastRun)<DayOf(ProposedNextRun));
if DidItRunThisMonth then begin
// go to the next month
while DayOf(Result)>1 do
Result:=Result+1;
end
else begin
// go to the next month if we are beyond week #1
while DayOf(Result)>7 do
Result:=Result+1;
end;
// second, advance further until it's not a weekend
while DayOfTheWeek(Result)>=6 do
Result:=Result+1;
end;
Przykładowe skrypty OnIncludeItem
Hook OnIncludeItem jest wywoływany osobno dla każdej strony synchronizacji. Parametr isRightSide wskazuje, którą stronę aktualnie analizujemy.
Poniższy skrypt służy do wykluczania plików bez rozszerzenia nazwy. Takie wykluczenie nie jest możliwe za pomocą masek wykluczeń.
function OnIncludeItem(const FileName, RelativePath: UnicodeString;
const isRightSide, isFolder:Boolean;
const FileSize:Int64; const FileAttr:LongWord;
const Connector: Opaque):Boolean;
begin
Result:=isFolder or (Pos('.',FileName)>0);
end;
Drugi przykład dla OnIncludeItem będzie przetwarzać tylko te podfoldery, które zawierają plik READY.toprocess, a także wszelkie podfoldery istniejące po prawej stronie.
function OnIncludeItem(const FileName, RelativePath: UnicodeString;
const isRightSide, isFolder:Boolean;
const FileSize:Int64; const FileAttr:LongWord;
const Connector: Opaque):Boolean;
begin
Result:=isRightSide or not isFolder or
ConnFileExists(Connector,ConcatPath(ConcatPath(LeftBasePath,RelativePath,Connector),FileName,Connector)+
'\READY.toprocess');
end;
Przykładowy skrypt OnScanFolder
To prawdopodobnie lepszy sposób wyszukiwania „READY.toprocess”. Hook OnScanFolder jest wywoływany tuż przed skanowaniem folderu, a w hooku można wykorzystać informacje z obu stron.
function OnScanFolder(const FolderLevel: Integer;
const RelativePath, LeftCompletePath, RightCompletePath: UnicodeString;
const LeftExists,RightExists:Boolean;
const LeftConnector, RightConnector: Opaque):Boolean;
begin
Result:=RightExists or ConnFileExists(LeftConnector,LeftCompletePath+'\READY.toprocess');
end;
Przykładowy skrypt OnProfileStart
Tej funkcji można użyć do sprawdzenia lub zmiany ustawień profilu przy uruchamianiu, w tym niektórych funkcji, które można odblokować tylko za pomocą PascalScript. Przykład sprawdza, czy zaznaczono którekolwiek pola wyboru „Pomiń buforowanie plików” i usuwa je.
var Checked:Boolean;
function OnProfileStart:Boolean;
begin
Result:=true;
if Checked then
Exit;
Checked:=true;
if (GetProfileProperty('BypassOSFileBufferingLeft')='Yes') or
(GetProfileProperty('BypassOSFileBufferingRight')='Yes') then begin
SetProfileProperty('BypassOSFileBufferingLeft','No');
SetProfileProperty('BypassOSFileBufferingRight','No');
SaveProfileSettings;
Log('');
Log('Bypass File Buffering has been removed via PascalScript.');
end
else begin
Log('');
Log('File buffering settings have been verified via PascalScript.');
end;
end;
Przykładowy skrypt OnProfileResults
Ten skrypt nic nie robi, ale funkcja jest wywoływana z pewnymi statystykami po zakończeniu profilu. Przykład z praktycznym zastosowaniem można pobrać u góry tej strony („Wysyłanie powiadomień e-mail zależnie od wyników profilu”). Wartość zwracana przez tę funkcję („Result”) jest ignorowana.
function OnProfileResults(const FilesCopiedL2R,FilesCopiedR2L:Integer;
const FilesToCopyL2R,FilesToCopyR2L:Integer;
const BytesCopiedL2R,BytesCopiedR2L:Int64;
const ResultString:UnicodeString;
const Error:Boolean):Boolean;
begin
Result:=true;
end;
Przykładowy skrypt OnNormalizeFilename
Ten hook umożliwia „normalizowanie” nazw plików, aby Syncovery mógł traktować nazwy plików jako identyczne mimo drobnych różnic. Przykładowy skrypt normalizuje znaki spacji, tak aby między innymi znakami zawsze była tylko jedna spacja. Dwie lub więcej kolejnych spacji jest normalizowane do jednej. W efekcie Syncovery widzi jako identyczne pliki, które po obu stronach profilu mają różną liczbę kolejnych spacji. Nazwy tych plików nie są modyfikowane na dysku. Zmiana odbywa się wyłącznie w pamięci, do celów porównywania. Podgląd synchronizacji pokaże znormalizowane nazwy plików.
function OnNormalizeFilename(const FileName: UnicodeString;
const isFolder, isRightSide: Boolean):UnicodeString;
var Changed:UnicodeString;
begin
Result:=FileName;
repeat
Changed:=StringReplace(Result,' ',' ',true);
if Changed=Result then
break;
Result:=Changed;
until false;
end;
Przykładowy skrypt OnReplaceFilenameLeftToRight
Ten skrypt będzie zmieniał nazwy plików podczas kopiowania z lewej do prawej. W naszym przykładzie przed rozszerzeniem nazwy pliku dodawany jest ciąg „-draft”.
function OnReplaceFilenameLeftToRight(const FileName: UnicodeString;
const isFolder: Boolean):UnicodeString;
begin
if isFolder then
Result:=FileName
else
Result:=ChangeFileExt(FileName,'-draft')+ExtractFileExt(FileName);
end;
Przykładowy skrypt OnReplaceFilenameRightToLeft
Jeśli wykonujesz synchronizację dwukierunkową i po prawej stronie mogą pojawić się nowe pliki, potrzebujemy też sposobu zmiany nazw w drugą stronę. Ten przykładowy skrypt usuwa z nazw wstawiony ciąg „-draft”.
function OnReplaceFilenameRightToLeft(const FileName: UnicodeString;
const isFolder: Boolean):UnicodeString;
var ToFind:UnicodeString;
P:Integer;
begin
if isFolder then
Result:=FileName
else begin
ToFind:=''-draft''+ExtractFileExt(FileName);
p:=Pos(ToFind,FileName);
if p>0 then
Result:=Copy(FileName,1,p-1)+ExtractFileExt(FileName)
else
Result:=FileName
end;
end;
Przykładowy skrypt OnUploadComplete
Ten skrypt ustawi uprawnienia dla plików przesyłanych przez FTP na 777.
function OnUploadComplete(const FileName, LocalFilePath, CompleteURL: UnicodeString;
const isRightSide:Boolean;
const FileSize:Int64;
const Connector: Opaque):Boolean;
var CmdRes:Int64;
ResponseText:UnicodeString;
begin
CmdRes:=ConnCustomFTPCommand(Connector,'SITE CHMOD 777 '+FileName,200,200,200,ResponseText);
Log('Set Permissions for '+FileName+': '+ResponseText);
Result:=true;
end;
Przykładowy skrypt OnDownloadComplete
Ten skrypt zmieni nazwy pobranych plików, dodając dodatkowe rozszerzenie „.downloaded”.
function OnDownloadComplete(const FileName, CompleteURL, LocalFilePath: UnicodeString;
const isRightSide:Boolean;
const FileSize:Int64;
const Connector: Opaque):Boolean;
begin
if ConnRenameFile(Connector,CompleteURL,FileName+'.downloaded') then
Log('Renamed '+FileName+' to '+FileName+'.downloaded')
else
Log('Rename failed: '+FileName+' to '+FileName+'.downloaded');
Result:=true;
end;
Przykładowy skrypt OnVolumeShadowComplete
Ten skrypt wykona zewnętrzne polecenie (plik wsadowy lub CMD) zaraz po utworzeniu migawki woluminu.
function OnVolumeShadowComplete(const Volume,ShadowPath:UnicodeString):Boolean;
begin
Result:=Execute('C:\Tests\test.bat',120)=0;
end;
Przykładowy skrypt OnBeforeFolderCreate
Ten skrypt zapobiegnie tworzeniu jakichkolwiek folderów, z wyjątkiem przypadków koniecznych do skopiowania plików do miejsca docelowego. Możesz również użyć tego hooka do modyfikowania ścieżek folderów po stronie docelowej.
function OnBeforeFolderCreate(const DirectionIsL2R:Boolean;
var Source,Dest,Reason:UnicodeString):Boolean;
begin
Result:=false;
end;
Przykładowy skrypt OnBeforeFileCopy
Ten skrypt będzie modyfikował ścieżki docelowe podczas kopiowania (z lewej do prawej), dodając dodatkowy podfolder „archive”, który nie występuje po stronie źródłowej.
function OnBeforeFileCopy(const DirectionIsL2R:Boolean;
var Source,Dest,DestPath,LeftSubPath,RightSubPath:UnicodeString):Boolean;
var AddFolderName,NewDestPath,NewDest,NewRightSubPath:UnicodeString;
begin
Result:=true;
if not DirectionIsL2R then
Exit;
AddFolderName:='archive';
NewDestPath:=ConcatPathWithDelim(DestPath,AddFolderName,PathDelim);
NewDest:=ConcatPathWithDelim(NewDestPath,ExtractFileName(Dest),PathDelim);
NewRightSubPath:=IncludeLeadingPathDelim(ConcatPathWithDelim(RightSubPath,AddFolderName,PathDelim));
if not MakeSurePathExists(NewDestPath,true) then begin
Log('Could not create '+NewDestPath);
Exit;
end;
Log('OnBeforeFileCopy');
Log('Source:'+Source);
Log('DestPath:'+DestPath+' changed to '+NewDestPath);
Log('Dest:'+Dest+' changed to '+NewDest);
Log('LeftSubPath:'+LeftSubPath);
Log('RightSubPath:'+RightSubPath+' changed to '+NewRightSubPath);
Log('');
Dest:=NewDest;
DestPath:=NewDestPath;
RightSubPath:=NewRightSubPath;
end;
Przykładowy skrypt OnBeforeFileUpload
Ten skrypt jest wywoływany przed przesłaniem pliku przez protokół internetowy i może służyć do modyfikowania sposobu przesyłania. Poniższa przykładowa funkcja uruchomi skaner antywirusowy przed wysłaniem.
function OnBeforeFileUpload(const DirectionIsL2R:Boolean;
var Source,Dest,DestPath,LeftSubPath,RightSubPath,ErrorMsg:UnicodeString;
var ErrorCode:Int64):Boolean;
begin
if not DirectionisL2R then begin
Result:=true;
Exit;
end;
Result:=Execute('"C:\Program Files\ClamAV\clamscan.exe" '+Source,60)=0;
if Result then
Log('Virus scan OK: '+Source)
else begin
Log('Virus scan failed, not uploading: '+Source);
ErrorMsg:='Virus detected';
ErrorCode:=$E1;
end;
end;
Przykładowy skrypt OnHttpPost
Ten hook może służyć do włączenia przesyłania plików przez protokół HTTP. Skrypt musi ustawić odpowiednie nagłówki i właściwości formularza.
function OnHttpPost(const RelativePath : UnicodeString;
var URL, MIMEType, Header : AnsiString; var LAsForm : Boolean;
var LFormData : AnsiString;
const Connector : Opaque) : Boolean;
begin
URL := 'https://pl.syncovery.com';
Header := 'Authorization: Bearer abcdefghijklmnopqrstuvwxyz';
LAsForm := true;
Result := true;
LFormData := 'orderstates';
Log('');
Log('Header Added to '+RelativePath);
Log(Header);
Log('');
end;
Przykładowy skrypt OnGetProfilePathBeforeListing
Ten skrypt używa tego hooka, aby określić indywidualny folder TEMP dla profilu. Pierwotnym przeznaczeniem tej funkcji jest modyfikowanie lewej lub prawej ścieżki i/lub poświadczeń.
function OnGetProfilePathBeforeListing(const isRightSide:Boolean;
var Path,UserName,Password:UnicodeString;
var AuthKey,AuthKeyPassword:AnsiString;
var Port:Integer):Boolean;
begin
ProfileTempDir:='H:\TEMP';
Result:=true;
end;
Przykładowy skrypt OnGetProfilePathBeforeCopying
Ten hook może służyć do modyfikacji ścieżki i/lub poświadczeń. Przykładowy skrypt nic nie robi.
function OnGetProfilePathBeforeCopying(const isRightSide:Boolean;
var Path,UserName,Password:UnicodeString;
var AuthKey,AuthKeyPassword:AnsiString;
var Port:Integer):Boolean;
begin
Result:=true;
end;
Przykładowy skrypt OnBeforeMainActionPhase
Ten skrypt pozwala uruchomić zadanie tylko wtedy, gdy ma zostać skopiowana określona liczba plików z lewej do prawej.
function OnBeforeMainActionPhase(const CopyL2RCount,CopyR2LCount,DeleteLCount,DeleteRCount,MoveLCount,MoveRCount:Int64;
const CopyL2RBytes,CopyR2LBytes,DeleteLBytes,DeleteRBytes,MoveLBytes,MoveRBytes:Int64):Boolean;
begin
if CopyL2RCount=14 then
Result:=true
else begin
Result:=false;
Log('Not continuing because CopyL2RCount is '+IntToStr(CopyL2RCount));
end;
end;
Przykładowy skrypt OnCloudConnect
Ten skrypt może służyć do logowania się do witryny internetowej podczas używania protokołu HTTP do pobierania plików z adresu URL.
function OnCloudConnect(const URL:AnsiString;
const isRightSide,isFirstConnectionInJob:Boolean;
const Connector: Opaque):Boolean;
begin
if isFirstConnectionInJob and not isRightSide then
Result:=ConnProcessWebForm(Connector,
'https://www.superflexible.com/usrlogin.php?',
'login',
'username','tobias',
'password','abcdefghijklmn',
false,'')
else
Result:=true;
end;
Przykładowy skrypt OnCloudDisconnect
Ten hook jest wywoływany przed ostatecznym rozłączeniem z serwerem chmurowym lub FTP na końcu uruchomienia profilu.
Może być użyty do wykonania ostatnich zadań.
Przykładowy skrypt nic nie robi.
function OnCloudDisconnect(const URL:AnsiString;
const isRightSide,isMainConnectionInJob,isFinalDisconnection:Boolean;
const Connector: Opaque):Boolean;
begin
Log('Before final disconnection');
Result:=true;
end;
Przykładowy skrypt OnLogFileClosed
Ten skrypt kopiuje plik dziennika do innego folderu po jego zamknięciu.
function OnLogFileClosed(const FileName:UnicodeString):Boolean;
begin
FileCopy(FileName,'E:\LogCopies\'+ExtractFileName(FileName));
Result:=true;
end;
Przykładowy skrypt OnMoveFileToDeletedFolder
Ten skrypt zapobiega zachowywaniu wielu wersji usuniętych plików, najpierw usuwając potencjalnie istniejący plik z folderu plików usuniętych.
function OnMoveFileToDeletedFolder(const Path:UnicodeString;
var MoveToPath:UnicodeString;
var proceedToDeleteInsteadOfMoving:Boolean;
const Connector:Opaque):Boolean;
begin
if FileExists(MoveToPath) then FileDelete(MoveToPath);
Result:=true;
end;
Przykładowy skrypt OnNeedToRerun
Ten skrypt powoduje ponowne uruchamianie zadania, aż zostanie spełniony oczekiwany warunek (skopiowano co najmniej jeden plik).
function OnNeedToReRun(const FilesCopiedL2R,FilesCopiedR2L:Integer;
const FilesToCopyL2R,FilesToCopyR2L:Integer;
const BytesCopiedL2R,BytesCopiedR2L:Int64;
const ResultString:UnicodeString;
const Error:Boolean):Boolean;
begin
if FilesCopiedL2R+FilesCopiedR2L>0 then
Result:=false
else
Result:=true;
end;
