Bazaar/FMonSync : another fancy FMon class usage example - a trivial path synchronizer

git-svn-id: svn://ultimatepp.org/upp/trunk@4937 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
micio 2012-05-12 12:26:19 +00:00
parent e1b5ce3428
commit c8c5505e56
9 changed files with 292 additions and 132 deletions

40
bazaar/FSMonTest/FSMonSync.h Executable file
View file

@ -0,0 +1,40 @@
#ifndef _FSMonTest_FSMonSync_h
#define _FSMonTest_FSMonSync_h
#include <FSMon/FSMon.h>
using namespace Upp;
#define LAYOUTFILE <FSMonSync/FSMonSync.lay>
#include <CtrlCore/lay.h>
class FSMonSync : public WithFSMonSyncLayout<TopWindow>
{
private:
void Log(String const &s);
void startCb(void);
void stopCb(void);
void quitCb(void);
FSMon fsmMon;
void monitorCb(void);
String srcFolder, dstFolder;
// gets destination path given source one
String GetDestPath(String const &srcPath);
bool started;
protected:
public:
typedef FSMonSync CLASSNAME;
FSMonSync();
};
#endif

View file

@ -1,4 +1,4 @@
LAYOUT(FSMonTestLayout, 504, 288)
LAYOUT(FSMonSyncLayout, 504, 288)
ITEM(LineEdit, logEdit, LeftPosZ(8, 488).TopPosZ(4, 256))
ITEM(Button, stopBtn, SetLabel(t_("Stop")).LeftPosZ(76, 60).TopPosZ(264, 20))
ITEM(Button, quitBtn, SetLabel(t_("Quit")).LeftPosZ(436, 60).TopPosZ(264, 20))

View file

@ -0,0 +1,16 @@
description "Rudimentary file synchronization test for FSMon Filesystem Monitor Package\377";
uses
CtrlLib,
FSMon;
file
SyncUtils.h,
SyncUtils.cpp,
FSMonSync.lay,
FSMonSync.h,
main.cpp;
mainconfig
"" = "GUI MT";

View file

@ -1,33 +0,0 @@
#ifndef _FSMonTest_FSMonTest_h
#define _FSMonTest_FSMonTest_h
#include <FSMon/FSMon.h>
using namespace Upp;
#define LAYOUTFILE <FSMonTest/FSMonTest.lay>
#include <CtrlCore/lay.h>
class FSMonTest : public WithFSMonTestLayout<TopWindow>
{
private:
void Log(String const &s);
void startCb(void);
void stopCb(void);
void quitCb(void);
FSMon fsmMon;
void monitorCb(void);
protected:
public:
typedef FSMonTest CLASSNAME;
FSMonTest();
};
#endif

View file

@ -1,14 +0,0 @@
description "Test FSMon Filesystem Monitor Package\377";
uses
CtrlLib,
FSMon;
file
FSMonTest.lay,
FSMonTest.h,
main.cpp;
mainconfig
"" = "GUI MT";

View file

@ -0,0 +1,80 @@
#include "SyncUtils.h"
// synchronize a source file with a dest one
// checks filestamp, size and attributes
bool SyncFile(String const &src, String const &dst)
{
Time srcTime;
if(src == dst)
return false;
if(!FileExists(src))
{
if(FileExists(dst))
{
FileDelete(dst);
return true;
}
return false;
}
bool shallCopy = false;
if(!FileExists(dst))
shallCopy = true;
else
{
srcTime = FileGetTime(src);
int64 srcLen = GetFileLength(src);
Time dstTime = FileGetTime(dst);
int64 dstLen = GetFileLength(dst);
if(srcTime != dstTime || srcLen != dstLen)
shallCopy = true;
}
if(shallCopy)
{
if(!RealizePath(dst))
return false;
if(FileCopy(src, dst))
return FileSetTime(dst, srcTime);
else
return false;
}
return true;
}
// synchronizes a whole source folder with a dest one
// uses SyncFile for single files synchronization
bool SyncFolder(String const &src, String const &dst)
{
bool res = true;
#ifdef PLATFORM_POSIX
FindFile ff(AppendFileName(src, "*"));
#else
FindFile ff(AppendFileName(src, "*.*"));
#endif
if(!DirectoryExists(dst))
{
if(!RealizeDirectory(dst))
return false;
}
while(ff)
{
// skip . and .. folders...
if(ff.GetName() == "." || ff.GetName() == "..")
{
ff.Next();
continue;
}
String srcPath = AppendFileName(src, ff.GetName());
String dstPath = AppendFileName(dst, ff.GetName());
if(ff.IsFolder())
res &= SyncFolder(srcPath, dstPath);
else
res &= SyncFile(srcPath, dstPath);
ff.Next();
}
return res;
}

View file

@ -0,0 +1,16 @@
#ifndef _FSMonSync_SyncUtils_h_
#define _FSMonSync_SyncUtils_h_
#include <Core/Core.h>
using namespace Upp;
// synchronize a source file with a dest one
// checks filestamp, size and attributes
bool SyncFile(String const &src, String const &dst);
// synchronizes a whole source folder with a dest one
// uses SyncFile for single files synchronization
bool SyncFolder(String const &src, String const &dst);
#endif

View file

@ -1,5 +1,5 @@
#ifndef _FSMonTest_icpp_init_stub
#define _FSMonTest_icpp_init_stub
#ifndef _FSMonSync_icpp_init_stub
#define _FSMonSync_icpp_init_stub
#include "CtrlLib/init"
#include "FSMon/init"
#endif

View file

@ -1,82 +1,137 @@
#include "FSMonTest.h"
void FSMonTest::Log(String const &s)
{
logEdit.Set(logEdit.Get() + s + "\n");
logEdit.SetCursor(INT_MAX);
}
void FSMonTest::startCb(void)
{
String path = AppendFileName(GetHomeDirectory(), "FSMonTest_A");
Log("Starting monitor for '" + path + "'");
if(!DirectoryExists(path))
RealizeDirectory(path);
fsmMon.Add(path);
}
void FSMonTest::stopCb(void)
{
Log("Stopping\n");
String path = AppendFileName(GetHomeDirectory(), "FSMonTest_A");
fsmMon.Remove(path);
}
void FSMonTest::quitCb(void)
{
stopCb();
Break();
}
void FSMonTest::monitorCb()
{
Vector<FSMon::Info> infos = fsmMon.GetChanged();
for(int iChange = 0; iChange < infos.GetCount(); iChange++)
{
FSMon::Info const &info = infos[iChange];
switch(info.flags)
{
case FSMon::FSM_NOP :
Log(String("NO-OP EVENT"));
break;
case FSMon::FSM_Created :
Log(String("Creating file '") + info.path + "'");
break;
case FSMon::FSM_Deleted :
Log(String("Deleting file '") + info.path + "'");
break;
case FSMon::FSM_Moved :
Log(String("Moving file '") + info.path + "' to '" + info.newPath + "'");
break;
case FSMon::FSM_FolderCreated :
Log(String("Creating folder '") + info.path + "'");
break;
case FSMon::FSM_FolderDeleted :
Log(String("Deleting folder '") + info.path + "'");
break;
case FSMon::FSM_FolderMoved :
Log(String("Moving folder '") + info.path + "' to '" + info.newPath + "'");
break;
case FSMon::FSM_Modified :
Log(String("Modifying file '") + info.path + "'");
break;
case FSMon::FSM_AttribChange :
Log(String("Modifying file attributes for '") + info.path + "'");
break;
}
}
}
FSMonTest::FSMonTest()
{
CtrlLayout(*this, "Window title");
fsmMon.EventHandler = THISBACK(monitorCb);
startBtn <<= THISBACK(startCb);
stopBtn <<= THISBACK(stopCb);
quitBtn <<= THISBACK(quitCb);
}
GUI_APP_MAIN
{
FSMonTest().Run();
}
#include "FSMonSync.h"
#include "SyncUtils.h"
void FSMonSync::Log(String const &s)
{
logEdit.Set(logEdit.Get() + s);
logEdit.SetCursor(INT_MAX);
}
// gets destination path given source one
String FSMonSync::GetDestPath(String const &srcPath)
{
ASSERT(srcPath.StartsWith(srcFolder));
String res = srcPath.Mid(srcFolder.GetCount());
return AppendFileName(dstFolder, res);
}
void FSMonSync::startCb(void)
{
srcFolder = AppendFileName(GetHomeDirectory(), "FSMonTest_A");
if(!DirectoryExists(srcFolder))
RealizeDirectory(srcFolder);
dstFolder = AppendFileName(GetHomeDirectory(), "FSMonTest_B");
if(!DirectoryExists(dstFolder))
RealizeDirectory(dstFolder);
Log("Starting syncinc '" + srcFolder + "' to '" + dstFolder + "'\n");
Log("Initial sync.....");
ProcessEvents();
SyncFolder(srcFolder, dstFolder);
Log("DONE\n");
ProcessEvents();
fsmMon.Add(srcFolder);
started = true;
stopBtn.Enable();
startBtn.Disable();
}
void FSMonSync::stopCb(void)
{
Log("Stopping\n\n");
fsmMon.Remove(srcFolder);
started = false;
stopBtn.Disable();
startBtn.Enable();
}
void FSMonSync::quitCb(void)
{
if(started)
stopCb();
Break();
}
void FSMonSync::monitorCb()
{
Vector<FSMon::Info> infos = fsmMon.GetChanged();
for(int iChange = 0; iChange < infos.GetCount(); iChange++)
{
FSMon::Info const &info = infos[iChange];
switch(info.flags)
{
case FSMon::FSM_NOP :
Log("NO-OP EVENT\n");
break;
case FSMon::FSM_Created :
Log("Syncing created file '" + info.path + "'.....");
if(SyncFile(info.path, GetDestPath(info.path)))
Log("DONE\n");
else
Log("FAILED\n");
break;
case FSMon::FSM_Deleted :
Log("Syncing deleted file '" + info.path + "'.....");
if(SyncFile(info.path, GetDestPath(info.path)))
Log("DONE\n");
else
Log("FAILED\n");
break;
case FSMon::FSM_Moved :
Log("Syncing file move from '" + info.path + "' to '" + info.newPath + "'.....");
if(FileMove(GetDestPath(info.path), GetDestPath(info.newPath)))
Log("DONE\n");
else
Log("FAILED\n");
break;
case FSMon::FSM_FolderCreated :
Log("Syncing created folder '" + info.path + "'.....");
if(SyncFolder(info.path, GetDestPath(info.path)))
Log("DONE\n");
else
Log("FAILED\n");
break;
case FSMon::FSM_FolderDeleted :
Log("Syncing deleted file '" + info.path + "'.....");
if(DeleteFolderDeep(GetDestPath(info.path)))
Log("DONE\n");
else
Log("FAILED\n");
break;
case FSMon::FSM_FolderMoved :
Log("Syncing folder move from '" + info.path + "' to '" + info.newPath + "'.....");
if(FileMove(GetDestPath(info.path), GetDestPath(info.newPath)))
Log("DONE\n");
else
Log("FAILED\n");
break;
case FSMon::FSM_Modified :
Log("Syncing modified file '" + info.path + "'.....");
if(SyncFile(info.path, GetDestPath(info.path)))
Log("DONE\n");
else
Log("FAILED\n");
break;
case FSMon::FSM_AttribChange :
Log("Attribute syncing not supported\n");
break;
}
}
}
FSMonSync::FSMonSync()
{
CtrlLayout(*this, "Window title");
fsmMon.EventHandler = THISBACK(monitorCb);
startBtn <<= THISBACK(startCb);
stopBtn <<= THISBACK(stopCb);
quitBtn <<= THISBACK(quitCb);
started = false;
stopBtn.Disable();
}
GUI_APP_MAIN
{
FSMonSync().Run();
}