#
# creates a tar file containing a backup of the entire .bibus user data folder
# in particular, style files and sqlite databases

# The UI part of backupUserData is implemented in BibFrame.py
# procedure doBackup(self,evt)

import os
import os.path
import sys
import tarfile
import unicodedata

FULLPATHARC = False    # archive to be stored under full pathnames (yes: True or no: False)

def backup2tar(src,dest):
    'backup all files (with recursion) in DIRECTORY src to tar FILE dest'
    ## print src,dest
    tarf = tarfile.open(dest,mode='w')
##    # in Bibus, creating a POSIX tar file would probably not generate any problems
##    # so the following lines are commented out
##    if tarf.posix:
##        raw_input("TAR file is POSIX...please quit and check your Python...")
##       sys.exit(1)
    cntfiles=0
    procfiles=0
    errfiles=0
    for root, dirs, files in os.walk(src):
        ## print root
        for name in files:
            cntfiles+=1
            ## print name
####            try:
            filepname = os.path.join(root, name)
            if FULLPATHARC:
                archpname = filepname
            else:
                archpname = os.path.join(root.replace(src,'',1), name)            
            # add file to archive
            ## print filepname,archpname
            # workaround: tarfile unicode support is not clear (python 2.5)
            # situation potentially better with python 2.6
            # hammer unicode down to ascii
            archpname = unicodedata.normalize('NFKD', archpname).encode('ascii','ignore')
            tarf.add(filepname,archpname)
            procfiles+=1
####            except:
####                ## filepname = os.path.join(root, name)
####                ## errfp.write(filepname+'\n')
####                ## errfiles+=1
####                print "Error occurred when accessing"
####                print root
####                print name
####                print
####                continue

    tarf.close()


def restore_tar(src, dest):
    'restore all files from FILE src to destination DIRECTORY dest, renaming duplicate files'
    tarfpname = src
    destdir = dest
    msgstr = '''*** Starting restore operation ***\n
This will only restore the files contained in the 'Databases' and 'Styles' folders.\n
To restore the other files contained in the archive (configuration, shortcuts etc.), do so manually.\n\n'''
    if not tarfile.is_tarfile(tarfpname):
        msgstr = ('Selected file is not a TAR file: \n%s\n' % tarfpname)
        return msgstr
    tarf = tarfile.open(tarfpname,mode='r')
    for tarmember in tarf.getmembers():
        if os.path.isabs(tarmember.name):
            msgstr = msgstr + '\n*** Item:\n'+tarmember.name+'\n'
            msgstr = msgstr + '''    Bibus warning: Archive contains item with absolute pathname!\n
    This is strange! Item ignored...\n\n'''
        elif tarmember.isfile():
            # restore only Databases and Styles
            if (tarmember.name.find('Databases/')==0) or (tarmember.name.find('Styles/')==0):
                fulldestpath=os.path.abspath(destdir) 
                destname=tarmember.name
                msgstr = msgstr + ("Restored '%s' " % destname)
                fulldestpathname=os.path.join(fulldestpath,destname)
                if os.path.exists(fulldestpathname):
                    nnumber = 2 # start filename suggestion at (2), avoid overwriting pre-existing files
                    while os.path.exists(fulldestpathname):
                        tmname,tmext = os.path.splitext(tarmember.name) 
                        destname=tmname + ('(%d)' % nnumber) + tmext
                        fulldestpathname=os.path.join(fulldestpath,destname)
                        nnumber += 1
                    tarmember.name=destname # yes you can change the output file name...
                msgstr = msgstr + ("as '%s'\n" % destname)
                tarf.extract(tarmember,path=fulldestpath)            
    tarf.close()
    msgstr = msgstr + '''\n *** Restore operation finished successfully *** \n
Restart Bibus to see the restored styles in the Style menu.'''
    return msgstr





