File synchronization
[1/8] from: g::santilli::tiscalinet::it at: 28-Nov-2002 23:25
[This is a resend... dunno why the first time it didn't arrive. If
it did to you, please accept my apologies for the duplicate.]
Hello all,
I just "finished" (meaning that now it is almost usable :-) a
script to sync two dirs (I use it to sync the REBOL dir between my
desktop PC and my laptop). The GUI is probably awful (and
beta-depended, sorry Carl :-( ), but it is a start.
What it does: it asks you the two dirs you want to sync. It then
scans them to find all the differences. (This process can take
time, and there is no progress bar, so be patient please --- or
add a progress bar to it. :-)
It then displays a list to let you decide the action to take on
files that are missing or that have been modified (only the
modification date is checked). The default is to copy any modified
file over the old one and add any new file to where it is missing;
so if you leave the list alone and just click on "Do it!" it will
just do that.
But you can also click on the list items to toggle the action.
Basically for each item you can select between the default "copy"
action, the "leave it alone" action (i.e. do nothing on that
file), and the "delete" or "restore" action (depending on the
file). If the file is missing on one of the two directories, you
can this way delete it from where it is present; if the file is
modified but you want to restore the old version, you can by
selecting the "restore" option. (I think it is easier to try it
out than to explain it.)
This can be useful to backup your data files to another drive or
so; you can easily keep the backup up to date by synching it every
day or so.
I hope it can be useful. Also, I hope someone with more free time
than me can make a better GUI for it. :-)
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
REBOL [
Title: "File synchronization"
File: %file-sync.r
Author: "Gabriele Santilli"
]
sync-dirs: func [
"Create list of operations needed to synchronize two directories"
a [file!] "First dir"
b [file!] "Second dir"
/local u result
] [
u: union read a read b
result: make block! 256
foreach file u [
switch to-bits exists? a/:file exists? b/:file [
1 [miss-file result a b file]
2 [miss-file result b a file]
3 [check-file result a b file]
]
]
result
]
to-bits: func [a b] [a: to-integer a b: to-integer b a * 2 + b]
miss-file: func [result dest src file] [
either dir? src/:file [
insert/only tail result compose/deep [
(reform ["Copy directory" file "to" dest]) [
either error? try [make-dir (dest/:file)] [
print ["Cannot create" (file) "on" (dest)]
] [
use [result] [
result: make block! 256
modified-file result (dest) (src) (file)
do-it result
]
]
]
(reform ["Leave directory" file "on" src]) [ ]
(reform ["Delete directory" file "from" src]) [
if error? try [delete-r (src/:file)] [
print ["Cannot delete" (file) "from" (src)]
]
]
]
;print ["Directory" file "does not exist in" dest]
] [
insert/only tail result compose/deep [
(reform ["Copy new file" file "to" dest]) [
if error? try [clone-file (dest) (src) (file)] [
print ["Cannot clone" (file) "on" (dest)]
]
]
(reform ["Leave file" file "on" src]) [ ]
(reform ["Delete file" file "from" src]) [
if error? try [delete (src/:file)] [
print ["Cannot delete" (file) "from" (src)]
]
]
]
;print ["File" file "does not exist in" dest]
]
]
delete-r: func [dir [file!]] [
if dir? dir [
foreach file read dir [
delete-r dir/:file
]
]
delete dir
]
check-file: func [result a b file /local ma mb] [
ma: modified? a/:file
mb: modified? b/:file
any [
if ma = mb [
;print ["File" file "seems synched"]
true
]
if ma > mb [
modified-file result b a file
true
]
do [
modified-file result a b file
]
]
]
modified-file: func [result dest src file] [
either dir? src/:file [
;print ["Synching" dest/:file "and" src/:file]
insert tail result sync-dirs dest/:file src/:file
;if error? try [
; set-modes dest/:file get-modes src/:file get-modes src/:file 'file-modes
;] [
; ;print "Cannot clone directory attributes."
;]
] [
insert/only tail result compose/deep [
(reform ["Clone modified file" file "to" dest]) [
if error? try [clone-file (dest) (src) (file)] [
print ["Cannot clone" (file) "to" (dest)]
]
]
(reform ["Leave modified file" file "on" src]) [ ]
(reform ["Restore old file" file "from" dest]) [
if error? try [clone-file (src) (dest) (file)] [
print ["Cannot restore" (file) "to" (src)]
]
]
]
;print ["File" file "has been modified on" src]
]
]
clone-file: func [dest src file /local data] [
dest: open/binary/direct/write dest/:file
src: open/binary/direct/read src/:file
clear dest
while [data: copy/part src 1048576] [
insert dest data
]
close dest
close src
set-modes dest get-modes src get-modes src 'file-modes
]
do-it: func [
"Do the list of operations returned by sync-dirs"
operations [block!]
] [
foreach operation operations [
; print operation/1
do operation/2
]
]
view layout [
Banner "Sync dirs"
Across
f1: Field 300 Btn "Browse..." [
if f1/text: request-file [f1/text: mold first split-path first f1/text]
show f1
]
Return
f2: Field 300 Btn "Browse..." [
if f2/text: request-file [f2/text: mold first split-path first f2/text]
show f2
]
Return
Btn-Enter "Sync" [unview] Btn-Cancel "Quit" [quit]
]
f1: attempt [load f1/text]
f2: attempt [load f2/text]
if all [file? f1 file? f2] [
operations: sync-dirs f1 f2
list: make block! length? operations
i: 1
foreach operation operations [
insert tail list join i [") " operation/1]
i: i + 1
]
view layout [
text-list data (list) 700x500 [
i: index? pos: find face/data face/picked
operation: next next pick operations i
if tail? operation [operation: head operation]
poke operations i operation
pos/1: join i [") " operation/1]
face/picked/1: pos/1
show face
]
Across Btn-Enter "Do it!" [do-it operations quit] Btn-Cancel "Quit" [quit]
]
]
[2/8] from: g:santilli:tiscalinet:it at: 28-Nov-2002 15:40
Hello all,
I just "finished" (meaning that now it is almost usable :-) a
script to sync two dirs (I use it to sync the REBOL dir between my
desktop PC and my laptop). The GUI is probably awful (and
beta-depended, sorry Carl :-( ), but it is a start.
What it does: it asks you the two dirs you want to sync. It then
scans them to find all the differences. (This process can take
time, and there is no progress bar, so be patient please --- or
add a progress bar to it. :-)
It then displays a list to let you decide the action to take on
files that are missing or that have been modified (only the
modification date is checked). The default is to copy any modified
file over the old one and add any new file to where it is missing;
so if you leave the list alone and just click on "Do it!" it will
just do that.
But you can also click on the list items to toggle the action.
Basically for each item you can select between the default "copy"
action, the "leave it alone" action (i.e. do nothing on that
file), and the "delete" or "restore" action (depending on the
file). If the file is missing on one of the two directories, you
can this way delete it from where it is present; if the file is
modified but you want to restore the old version, you can by
selecting the "restore" option. (I think it is easier to try it
out than to explain it.)
This can be useful to backup your data files to another drive or
so; you can easily keep the backup up to date by synching it every
day or so.
I hope it can be useful. Also, I hope someone with more free time
than me can make a better GUI for it. :-)
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
REBOL [
Title: "File synchronization"
File: %file-sync.r
Author: "Gabriele Santilli"
]
sync-dirs: func [
"Create list of operations needed to synchronize two directories"
a [file!] "First dir"
b [file!] "Second dir"
/local u result
] [
u: union read a read b
result: make block! 256
foreach file u [
switch to-bits exists? a/:file exists? b/:file [
1 [miss-file result a b file]
2 [miss-file result b a file]
3 [check-file result a b file]
]
]
result
]
to-bits: func [a b] [a: to-integer a b: to-integer b a * 2 + b]
miss-file: func [result dest src file] [
either dir? src/:file [
insert/only tail result compose/deep [
(reform ["Copy directory" file "to" dest]) [
either error? try [make-dir (dest/:file)] [
print ["Cannot create" (file) "on" (dest)]
] [
use [result] [
result: make block! 256
modified-file result (dest) (src) (file)
do-it result
]
]
]
(reform ["Leave directory" file "on" src]) [ ]
(reform ["Delete directory" file "from" src]) [
if error? try [delete-r (src/:file)] [
print ["Cannot delete" (file) "from" (src)]
]
]
]
;print ["Directory" file "does not exist in" dest]
] [
insert/only tail result compose/deep [
(reform ["Copy new file" file "to" dest]) [
if error? try [clone-file (dest) (src) (file)] [
print ["Cannot clone" (file) "on" (dest)]
]
]
(reform ["Leave file" file "on" src]) [ ]
(reform ["Delete file" file "from" src]) [
if error? try [delete (src/:file)] [
print ["Cannot delete" (file) "from" (src)]
]
]
]
;print ["File" file "does not exist in" dest]
]
]
delete-r: func [dir [file!]] [
if dir? dir [
foreach file read dir [
delete-r dir/:file
]
]
delete dir
]
check-file: func [result a b file /local ma mb] [
ma: modified? a/:file
mb: modified? b/:file
any [
if ma = mb [
;print ["File" file "seems synched"]
true
]
if ma > mb [
modified-file result b a file
true
]
do [
modified-file result a b file
]
]
]
modified-file: func [result dest src file] [
either dir? src/:file [
;print ["Synching" dest/:file "and" src/:file]
insert tail result sync-dirs dest/:file src/:file
;if error? try [
; set-modes dest/:file get-modes src/:file get-modes src/:file 'file-modes
;] [
; ;print "Cannot clone directory attributes."
;]
] [
insert/only tail result compose/deep [
(reform ["Clone modified file" file "to" dest]) [
if error? try [clone-file (dest) (src) (file)] [
print ["Cannot clone" (file) "to" (dest)]
]
]
(reform ["Leave modified file" file "on" src]) [ ]
(reform ["Restore old file" file "from" dest]) [
if error? try [clone-file (src) (dest) (file)] [
print ["Cannot restore" (file) "to" (src)]
]
]
]
;print ["File" file "has been modified on" src]
]
]
clone-file: func [dest src file /local data] [
dest: open/binary/direct/write dest/:file
src: open/binary/direct/read src/:file
clear dest
while [data: copy/part src 1048576] [
insert dest data
]
close dest
close src
set-modes dest get-modes src get-modes src 'file-modes
]
do-it: func [
"Do the list of operations returned by sync-dirs"
operations [block!]
] [
foreach operation operations [
; print operation/1
do operation/2
]
]
view layout [
Banner "Sync dirs"
Across
f1: Field 300 Btn "Browse..." [
if f1/text: request-file [f1/text: mold first split-path first f1/text]
show f1
]
Return
f2: Field 300 Btn "Browse..." [
if f2/text: request-file [f2/text: mold first split-path first f2/text]
show f2
]
Return
Btn-Enter "Sync" [unview] Btn-Cancel "Quit" [quit]
]
f1: attempt [load f1/text]
f2: attempt [load f2/text]
if all [file? f1 file? f2] [
operations: sync-dirs f1 f2
list: make block! length? operations
i: 1
foreach operation operations [
insert tail list join i [") " operation/1]
i: i + 1
]
view layout [
text-list data (list) 700x500 [
i: index? pos: find face/data face/picked
operation: next next pick operations i
if tail? operation [operation: head operation]
poke operations i operation
pos/1: join i [") " operation/1]
face/picked/1: pos/1
show face
]
Across Btn-Enter "Do it!" [do-it operations quit] Btn-Cancel "Quit" [quit]
]
]
[3/8] from: maarten:koopmans:surfnet:nl at: 29-Nov-2002 15:40
Gabriele,
And now you use Rugby to do it over the internet. Isn't that IOS ;-)
--Maarten
Gabriele Santilli wrote:
> [This is a resend... dunno why the first time it didn't arrive. If
> it did to you, please accept my apologies for the duplicate.]
<<quoted lines omitted: 29>>
> Regards,
> Gabriele.
--
Maarten Koopmans
Innovation manager tel: +31 30 2 305 324
SURFnet bv fax: +31 30 2 305 329
P.O.Box 19035 email: [maarten--koopmans--surfnet--nl]
NL-3501 DA Utrecht http://www.surfnet.nl
The netherlands
[4/8] from: g:santilli:tiscalinet:it at: 29-Nov-2002 18:38
Hi Maarten,
On Friday, November 29, 2002, 3:40:51 PM, you wrote:
MK> And now you use Rugby to do it over the internet. Isn't that IOS ;-)
IOS is left to the reader as an exercise.
;-)
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[5/8] from: maarten:koopmans:surfnet:nl at: 1-Dec-2002 8:21
Hi Gabriele,
OK, that's it. Now you have to write a book!
REBOL by Example.
With lots of exercises ;-)
--Maarten
Gabriele Santilli wrote:
> Hi Maarten,
> On Friday, November 29, 2002, 3:40:51 PM, you wrote:
<<quoted lines omitted: 3>>
> Regards,
> Gabriele.
--
Maarten Koopmans
Innovation manager tel: +31 30 2 305 324
SURFnet bv fax: +31 30 2 305 329
P.O.Box 19035 email: [maarten--koopmans--surfnet--nl]
NL-3501 DA Utrecht http://www.surfnet.nl
The netherlands
[6/8] from: petr:krenzelok:trz:cz at: 1-Dec-2002 15:12
Maarten Koopmans wrote:
> Hi Gabriele,
>
> OK, that's it. Now you have to write a book!
To both of you - that's not it, boys :-) Someone here requested
Gabriele's communication protocol proposition as worth starting as a
project, but as usual, our user base has very little resources
(man-power) to proceed with such project.
But - rebol can do better imo. Don't we want grid computing in rebol?
Don't we want at least basic (used by all) protocol framework to build
upon? It is a pity DocKimble has not enough free time to proceed with
Uniserve, but unless we get something like that working, we will see
protocol X here, protocol Y overthere, every such piece of code done
with different requirements/pov in mind, which in a big picture, provide
us with no unified way to what is called messaging framework.
There should be central async multiplexing engine, with the ability to
plug/unplug protocols in real-time, install handlers, etc. But until
then, we are near ... but not exactly there .... :-)
-pekr-
[7/8] from: maarten:koopmans:surfnet:nl at: 2-Dec-2002 11:07
Petr,
That's a long way to say your sorry that Doc has no time. PErhaps it is
even faster to wait for RT ;-)
--Maarten
Petr Krenzelok wrote:
> Maarten Koopmans wrote:
>> Hi Gabriele,
<<quoted lines omitted: 40>>
>>
>>
--
Maarten Koopmans
Innovation manager tel: +31 30 2 305 324
SURFnet bv fax: +31 30 2 305 329
P.O.Box 19035 email: [maarten--koopmans--surfnet--nl]
NL-3501 DA Utrecht http://www.surfnet.nl
The netherlands
[8/8] from: petr:krenzelok:trz:cz at: 2-Dec-2002 11:34
Maarten Koopmans wrote:
> Petr,
>
> That's a long way to say your sorry that Doc has no time. PErhaps it
> is even faster to wait for RT ;-)
Well, yes ... :-) What is RT working upon, imo - is async stack, but
untill announced and released, we have nothing. I am not sure RT will
produce anything like protocol framework Doc has produced. I also
believe some ppl here will insist - "why do you need it, petr, you've
got rebol already" :-)
So, Maarten, could Rugby be used for IOS like secure sync protocol? :-)
Maybe ppl here would also like to know, what is the future of Rugby,
what are you currently working on, etc.? :-)
-pekr-
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted