minor changes, should work so far, untested!
This commit is contained in:
parent
cc81991822
commit
65ef5db5f1
42
LICENSE
42
LICENSE
|
@ -617,45 +617,3 @@ Program, unless a warranty or assumption of liability accompanies a
|
||||||
copy of the Program in return for a fee.
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published
|
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If your software can interact with users remotely through a computer
|
|
||||||
network, you should also make sure that it provides a way for users to
|
|
||||||
get its source. For example, if your program is a web application, its
|
|
||||||
interface could display a "Source" link that leads users to an archive
|
|
||||||
of the code. There are many ways you could offer source, and different
|
|
||||||
solutions will be better for different programs; see section 13 for the
|
|
||||||
specific requirements.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
60
ownssync.py
60
ownssync.py
|
@ -1,3 +1,20 @@
|
||||||
|
'''
|
||||||
|
A simple pythontool to sync two folders (or harddrives)
|
||||||
|
Copyright (C) 2018 Yannis Gerlach aka MrBesen
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
'''
|
||||||
import os
|
import os
|
||||||
from shutil import copy2
|
from shutil import copy2
|
||||||
|
|
||||||
|
@ -16,12 +33,14 @@ def readfiletoarray(file):
|
||||||
print('Error reading sync data', e)
|
print('Error reading sync data', e)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def shouldsync(fromfile, tofile, data):
|
|
||||||
|
def shouldsync(fromfile, tofile, dataf, datat):
|
||||||
if os.path.exists(tofile):
|
if os.path.exists(tofile):
|
||||||
if getlastchange(tofile) < getlastchange(fromfile): # from file neuer
|
return getlastchange(tofile) < getlastchange(fromfile) # only if source file is newer
|
||||||
return True
|
elif tofile in dataf: # should nver be the case
|
||||||
elif tofile in data:
|
return False # file existed once, but was deleted on source
|
||||||
return False # file existed once, but was deleted
|
elif tofile in datat: # file was synced once, but deleted on target.
|
||||||
|
return False
|
||||||
return True # file dont exists and never existed
|
return True # file dont exists and never existed
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,20 +54,24 @@ def scandir(dir):
|
||||||
if os.path.isfile(dir + file):
|
if os.path.isfile(dir + file):
|
||||||
data.append(dir + file)
|
data.append(dir + file)
|
||||||
else:
|
else:
|
||||||
|
data.append(dir + file)
|
||||||
for f in scandir(dir + file + '/'):
|
for f in scandir(dir + file + '/'):
|
||||||
data.append(f)
|
data.append(f)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def rm(path):
|
def rm(path):
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
else:
|
else:
|
||||||
os.rmdir(path)
|
os.rmdir(path)
|
||||||
|
|
||||||
|
|
||||||
def syncnew(fro, to):
|
def syncnew(fro, to):
|
||||||
#read data
|
#read data
|
||||||
data = readfiletoarray(fro + dataname)
|
dataf = readfiletoarray(fro + dataname)
|
||||||
print(len(data), 'nodes loaded.')
|
datat = readfiletoarray(to + dataname)
|
||||||
|
print(len(dataf), 'nodes loaded.')
|
||||||
listffiles = scandir(fro)
|
listffiles = scandir(fro)
|
||||||
|
|
||||||
#remove prefix
|
#remove prefix
|
||||||
|
@ -62,26 +85,37 @@ def syncnew(fro, to):
|
||||||
del listffiles[pos]
|
del listffiles[pos]
|
||||||
|
|
||||||
for f in listffiles:
|
for f in listffiles:
|
||||||
if shouldsync(fro + f, to + f, data):
|
print('syncing: ', f)
|
||||||
|
if (not os.path.isfile(fro + f)) and os.path.exists(fro + f): # TODO: check if folder was deleted at target.
|
||||||
|
if not os.path.exists(to + f): # seperate if to not enter elif
|
||||||
|
# print('make dir:', to + f)
|
||||||
|
#if is folder and exists in from then create folder in to.
|
||||||
|
os.makedirs(to + f)
|
||||||
|
elif shouldsync(fro + f, to + f, dataf, datat):
|
||||||
folder = to + f
|
folder = to + f
|
||||||
folder = folder[:folder.rfind('/')+1]
|
folder = folder[:folder.rfind('/')+1]
|
||||||
print('make dir:',folder)
|
# print('make required dir:', folder)
|
||||||
if not os.path.exists(folder):
|
if not os.path.exists(folder):
|
||||||
os.makedirs(folder)
|
os.makedirs(folder)
|
||||||
|
|
||||||
|
print( fro + f, '->', to + f)
|
||||||
copy2(fro + f, to + f)
|
copy2(fro + f, to + f)
|
||||||
print('coping', fro + f)
|
|
||||||
else:
|
else:
|
||||||
print('skipping', f)
|
print('skipping', f)
|
||||||
|
|
||||||
for f in data:
|
# delete files, that were deleted on source
|
||||||
|
for f in dataf:
|
||||||
|
f = f[:-1] # remove trailing \n
|
||||||
if not os.path.exists(fro + f):
|
if not os.path.exists(fro + f):
|
||||||
print('delete file', f)
|
print('delete file', to + f)
|
||||||
# rm(fro + f)
|
# rm(fro + f)
|
||||||
|
|
||||||
#store to file
|
#store to file
|
||||||
|
print('writing', len(listffiles), 'files')
|
||||||
f = open(fro + dataname, 'w+')
|
f = open(fro + dataname, 'w+')
|
||||||
f.writelines(listffiles)
|
for line in listffiles:
|
||||||
|
f.write(line + '\n')
|
||||||
|
#f.writelines(listffiles)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue