PascalScript in Syncovery

Syncovery include un motore PascalScript che consente di personalizzare in molti modi il comportamento del profilo. PascalScript è stato aggiunto in Syncovery 8 e da allora sono stati aggiunti molti nuovi hook e funzioni fin dalla prima versione. Per modificare un comportamento specifico, è necessario scrivere una funzione hook e del codice. Nella maggior parte dei casi, il nostro supporto tecnico scriverà il codice per voi. Per script più lunghi o complessi, vi invitiamo a prendere in considerazione un Abbonamento di Supporto Premium che include lo sviluppo di script personalizzati. Lo script viene specificato nel profilo tramite la casella di controllo “Pascal Script…” nella scheda della categoria Impostazioni attività. Gli script Pascal hanno accesso a tutte le impostazioni del profilo e possono leggerle e modificarle tramite le funzioni di utilità GetProfileProperty e SetProfileProperty.

Script utili già pronti all’uso

Gli script seguenti possono essere usati così come sono, basta incollarli nella finestra di dialogo PascalScript.

  • Accorcia i percorsi lunghi
    Questo script accorcia i nomi dei file se il percorso totale supera i 250 caratteri. Aggiunge un hash CRC32 basato sul nome file originale per garantire che i nomi abbreviati siano univoci. I nomi delle cartelle non vengono modificati. I nomi abbreviati vengono usati solo quando si copia dal lato sinistro al lato destro. Il lato sinistro rimane invariato.
  • Accorcia i nomi file lunghi
    Questo script accorcia i nomi dei file che superano i 114 caratteri, aggiungendo un hash CRC32 basato sul nome file originale per garantire che i nomi abbreviati siano univoci. Come nello script precedente, i nomi delle cartelle non vengono modificati e i nomi abbreviati interessano solo il lato destro.
  • Converti i caratteri non consentiti per Windows
    Questo script consente di avere i caratteri non consentiti /:\?|<>“* nei nomi dei file sul lato sinistro. Il lato destro può essere un’archiviazione compatibile con Windows, ad esempio un’unità NTFS locale.
  • Notifiche e-mail semplici
    Questo script semplifica le notifiche e-mail e può essere modificato facilmente per personalizzare i tuoi messaggi.
  • Invia notifiche e-mail in base ai risultati del profilo
    Questo script fa sì che le notifiche e-mail vengano inviate solo se sono stati copiati da sinistra a destra meno di 10 o più di 100 file.
  • Associare una connessione FTP a una specifica porta LAN
    Questo script consente di specificare quale porta LAN usare per una connessione FTP. Si noti che funziona solo con la libreria FTP 3 (su Windows) oppure 2 (su altre piattaforme).
  • Eliminare i file più vecchi di 30 giorni dal lato sorgente (sinistro)
    Questo script farà sì che Syncovery elimini i file più vecchi dal lato sorgente di una sincronizzazione unidirezionale. Il lato sorgente deve essere quello sinistro. Il lato destro fungerà da archivio in cui vengono conservati tutti i file storici, mentre il lato sinistro conterrà solo i file degli ultimi 30 giorni. Si presume che i nuovi file compaiano solo sul lato sinistro. Il profilo deve essere utilizzato solo con la modalità operativa “Standard Copying”. Il numero di giorni può essere modificato nello script. È inoltre possibile scegliere se eliminare i file appena copiati (improbabile, perché probabilmente non hanno più di 30 giorni), e/o i file che esistono già su entrambi i lati quando il job viene eseguito (il caso più probabile).

Hook PascalScript disponibili

I seguenti hook sono attualmente disponibili. Ulteriori hook saranno aggiunti secondo necessità per soddisfare le richieste dei clienti.

  • 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

Funzioni PascalScript disponibili

Le seguenti funzioni sono disponibili per la chiamata.

  • funzioni standard come Pos, Copy, Length, Ord
     
  • function GetProfileProperty(const fieldname:UnicodeString):UnicodeString;
  • function SetProfileProperty(const fieldname:UnicodeString;const val:UnicodeString):Boolean;(queste funzioni usano gli stessi nomi di campo del formato XML e della riga di comando. Vedere il dizionario delle impostazioni alla fine della pagina 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;
  • (può essere usato con caratteri jolly nel nome del file, ma non nelle cartelle padre)

  • 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;(aggiunge una riga in modo sicuro per ambienti multi-thread e multi-process)
     
  • 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);

Variabili globali disponibili

Queste variabili globali consentono l’accesso diretto ai campi interni di Syncovery. Alcune di esse devono essere considerate di sola lettura, mentre altre sono destinate a essere modificate secondo necessità.

  • 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;
  • FiltriDevonoCorrispondereSuEntrambiILati:Boolean;
  • NeedActionsLog: Boolean;
  • UseBinaryCompToAvoidCopying: Boolean;
  • RemoveEmptyFoldersOnlyOneLevelWhereAFileHasBeenRemoved: Boolean;
  • IgnoreFileSizes: Boolean;
  • SkipIfFileSizeChanging: Boolean;
  • ActionsLogging: Boolean;
  • FreeSpaceLogging: Boolean;
  • CopyingStatisticsLogging: Boolean;
  • FileCopyNoStatNeeded: Boolean;
  • DoSmartTrackingDeletionsEvenIfOtherSideModified: Boolean;

Script di esempio OnActionComplete

Questo hook viene chiamato dopo l’esecuzione di qualsiasi tipo di azione relativa a file o cartelle, ad esempio un file copiato, spostato o eliminato e così via. L’esempio si limita a registrare l’azione. Il risultato della funzione viene ignorato da Syncovery.

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;

Script di esempio OnAfterFileCopy

Questo hook viene chiamato dopo che un file è stato copiato. Il risultato della funzione viene ignorato da Syncovery. È usato dallo script di esempio “Elimina i file più vecchi di 30 giorni dal lato sorgente (sinistro)”.

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;

Script di esempio OnCanRunProfile

Questo hook viene chiamato quando l’operatore pianificato sta per eseguire un profilo. È possibile decidere se eseguirlo subito oppure rimandarlo. L’esempio usa l’hook per impedire che due profili specifici vengano eseguiti contemporaneamente o si sovrappongano. Questo script deve essere inserito come PascalScript globale tramite la finestra Impostazioni programma, scheda Avanzate.

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;

Script di esempio OnFileCopy

Questo hook consente di sostituire la logica di copia dei file. Restituisci 0 in caso di successo, -1 se Syncovery deve eseguire la copia normalmente, oppure qualsiasi altro valore come codice di errore.

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;

Script di esempio OnGetCustomHeaders

Questo hook consente di aggiungere intestazioni HTTP personalizzate alle richieste Amazon S3. Nelle future versioni di Syncovery, questa funzionalità potrà essere aggiunta anche ad altri storage cloud e protocolli (su richiesta del cliente: basta chiederlo).

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;

Script di esempio OnGetNextRunTime

Questo hook consente di modificare la pianificazione. Il modo migliore per usarlo è assegnare al profilo una pianificazione regolare e semplice, e usare l’hook per saltare gli orari di esecuzione indesiderati. Questo esempio è pensato per un profilo pianificato per essere eseguito “ogni giorno alle XX:YY”. L’hook assicura che, in realtà, venga eseguito solo il primo giorno feriale del mese.

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;

Script di esempio OnIncludeItem

L’hook OnIncludeItem viene chiamato singolarmente per ciascun lato della sincronizzazione. Il parametro isRightSide indica quale lato stiamo esaminando in quel momento.

Lo script seguente serve a escludere i file senza estensione nel nome file. Questa esclusione non è possibile tramite le Maschere di esclusione.

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;

Il secondo esempio di OnIncludeItem elaborerà solo le sottocartelle che contengono il file READY.toprocess, oltre a tutte le sottocartelle presenti sul lato destro.

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;

Script di esempio OnScanFolder

Questo è probabilmente un modo migliore per cercare “READY.toprocess”. L’hook OnScanFolder viene chiamato appena prima che la cartella venga analizzata, e nel hook è possibile usare le informazioni di entrambi i lati.

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;

Script di esempio OnProfileStart

Questa funzione può essere usata per verificare o modificare le impostazioni del profilo all’avvio, incluse alcune funzioni che possono essere sbloccate solo tramite PascalScript. L’esempio controlla se è selezionata una qualsiasi casella di controllo “Bypass File Buffering” e le rimuove.

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;

Script di esempio OnProfileResults

Questo script non fa nulla, ma la funzione viene chiamata con alcune statistiche quando un profilo viene completato. Un esempio con un uso reale può essere scaricato in alto su questa pagina (“Invia notifiche e-mail in base ai risultati del profilo”). Il valore restituito da questa funzione (“Result”) viene ignorato.

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;

Script di esempio OnNormalizeFilename

Questo hook consente di “normalizzare” i nomi file in modo che Syncovery possa considerarli identici nonostante differenze minori. Lo script di esempio normalizza gli spazi, così tra gli altri caratteri ci sarà sempre un solo carattere di spazio. Due o più spazi consecutivi vengono normalizzati a un solo spazio. Il risultato è che Syncovery considera identici file che hanno un numero diverso di spazi consecutivi su ciascun lato del profilo. Questi nomi file non vengono modificati su disco. La modifica avviene solo in memoria, ai fini del confronto. L’anteprima sincronizzazione mostrerà i nomi file normalizzati.

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;

Script di esempio OnReplaceFilenameLeftToRight

Questo script rinominerà i file quando il file viene copiato da sinistra a destra. Nel nostro esempio, viene aggiunto ‘-draft’ prima dell’estensione del nome file.

function OnReplaceFilenameLeftToRight(const FileName: UnicodeString;
        const isFolder: Boolean):UnicodeString;
begin
  if isFolder then
    Result:=FileName
  else
    Result:=ChangeFileExt(FileName,'-draft')+ExtractFileExt(FileName);
  end;

Script di esempio OnReplaceFilenameRightToLeft

Se esegui una sincronizzazione bidirezionale e nuovi file possono comparire sul lato destro, serve anche un modo per rinominare nella direzione opposta. Questo script di esempio rimuove l’inserimento ‘-draft’ dai nomi.

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;

Script di esempio OnUploadComplete

Questo script imposterà i permessi dei file caricati tramite FTP su 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;

Script di esempio OnDownloadComplete

Questo script rinominerà i file scaricati aggiungendo un’ulteriore estensione “.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;

Script di esempio OnVolumeShadowComplete

Questo script eseguirà un comando esterno (file batch o CMD) subito dopo la creazione di una copia shadow del volume.

function OnVolumeShadowComplete(const Volume,ShadowPath:UnicodeString):Boolean;
begin
  Result:=Execute('C:\Tests\test.bat',120)=0;
  end;

Script di esempio OnBeforeFolderCreate

Questo script impedirà la creazione di qualsiasi cartella, tranne dove necessario per copiare i file nella destinazione. Puoi anche usare questo hook per modificare i percorsi delle cartelle nella destinazione.

function OnBeforeFolderCreate(const DirectionIsL2R:Boolean;
        var Source,Dest,Reason:UnicodeString):Boolean;
begin
  Result:=false;
  end;

Script di esempio OnBeforeFileCopy

Questo script modificherà i percorsi di destinazione per la copia (da sinistra a destra), aggiungendo una sottocartella aggiuntiva ‘archive’ che non è presente sul lato sorgente.

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;

Script di esempio OnBeforeFileUpload

Questo script viene chiamato prima del caricamento di un file tramite protocollo Internet e può essere usato per modificare il comportamento di upload. La funzione di esempio qui sotto avvierà una scansione antivirus prima dell’upload.

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;

Script di esempio OnHttpPost

Questo hook può essere usato per abilitare il caricamento di file tramite protocollo HTTP. Lo script deve impostare gli header e le proprietà del modulo pertinenti.

function OnHttpPost(const RelativePath : UnicodeString;
        var URL, MIMEType, Header : AnsiString; var LAsForm : Boolean;
        var LFormData : AnsiString;
        const Connector : Opaque) : Boolean;
begin
  URL := 'https://it.syncovery.com';
  Header := 'Authorization: Bearer abcdefghijklmnopqrstuvwxyz';
  LAsForm := true;
  Result := true;
  LFormData := 'orderstates';
  Log('');
  Log('Header Added to '+RelativePath);
  Log(Header);
  Log('');
  end;

Script di esempio OnGetProfilePathBeforeListing

Questo script usa questo hook per specificare una cartella TEMP individuale per il profilo. Lo scopo originale della funzione è modificare il percorso sinistro o destro e/o le credenziali.

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;

Script di esempio OnGetProfilePathBeforeCopying

Questo hook può essere usato per modificare il percorso e/o le credenziali. Lo script di esempio non fa nulla.

function OnGetProfilePathBeforeCopying(const isRightSide:Boolean;
        var Path,UserName,Password:UnicodeString;
        var AuthKey,AuthKeyPassword:AnsiString;
        var Port:Integer):Boolean;
begin
  Result:=true;
  end;

Script di esempio OnBeforeMainActionPhase

Questo script consente l’esecuzione del job solo se deve essere copiato un numero fisso di file da sinistra a destra.

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;

Script di esempio OnCloudConnect

Questo script può essere usato per effettuare l’accesso a un sito web quando si usa il protocollo HTTP per scaricare file da un 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;

Script di esempio OnCloudDisconnect

Questo hook viene chiamato prima della disconnessione finale da un server cloud o FTP alla fine di un’esecuzione del profilo.
Può essere usato per eseguire alcune attività finali.
Lo script di esempio non fa nulla.

function OnCloudDisconnect(const URL:AnsiString;
                const isRightSide,isMainConnectionInJob,isFinalDisconnection:Boolean;
                const Connector: Opaque):Boolean;
begin
  Log('Before final disconnection');
  Result:=true;
  end;

Script di esempio OnLogFileClosed

Questo script copia il file di log in un’altra cartella dopo la chiusura del file di log.

function OnLogFileClosed(const FileName:UnicodeString):Boolean;
begin
  FileCopy(FileName,'E:\LogCopies\'+ExtractFileName(FileName));
  Result:=true;
  end;

Script di esempio OnMoveFileToDeletedFolder

Questo script impedisce di conservare più versioni dei file eliminati, eliminando prima l’eventuale file esistente dalla cartella dei file eliminati.

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;

Script di esempio OnNeedToRerun

Questo script fa sì che il job venga eseguito nuovamente finché non è stata soddisfatta la condizione prevista (è stato copiato almeno un file).

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;