Ejemplo n.º 1
0
def DownloadDatabaseAndClean(scripts, ftp, item):
    DownloadFile(scripts, ftp, item, 'temp')

    # Clean up downloaded file
    WipeUpdateCon = DatabaseHandler.OpenEntryDatabase('temp')
    WipeUpdateCur = WipeUpdateCon.cursor()
    WipeUpdateCur.execute(u"UPDATE Text SET updated=0")
    WipeUpdateCon.commit()

    # Copy it to the right place
    Globals.CopyFile( Globals.configData.LocalDatabasePath + '/temp', Globals.configData.LocalDatabasePath + '/{0}'.format(item) )
                    
    CompletionTable.CalculateCompletionForDatabase(item)
    Globals.Cache.LoadDatabase(item)
    return
Ejemplo n.º 2
0
def RetrieveModifiedFilesWorker(scripts, splash, networkTransferWindow, sendWindowCloseSignal):
    scripts.WriteDatabaseStorageToHdd()

    Globals.Cache.databaseAccessRLock.acquire()
    # Nab the online changelog
    try:
        splash.text = 'Downloading updated files...'
    except:
        pass
            
    # loop to prevent crashes during FTP stuff
    for i in range( 0, 20 ):    # range( start, stop, step )
        try:
                
            try: # try to connect to the FTP
                ftp = ConnectToFtp()
                ftp.cwd('/')
                ftp.cwd(Globals.configData.RemoteDatabasePath)
            except: # if FTP conn fails 3 times assume it doesn't work at all and just cancel
                if i > 2:
                    networkTransferWindow.addListEntry("Couldn't connect to FTP Server. Databases may not be up-to-date.", "< Error >")
                    try:
                        splash.text = 'Grace Note Loaded'.format(scripts.roletext[scripts.role], Globals.ModeFlag)
                        splash.complete = True
                        splash.offline = True
                    except:
                        pass
                    if sendWindowCloseSignal:
                        networkTransferWindow.allowCloseSignal.emit(False)
                    Globals.Cache.databaseAccessRLock.release()
                    return
                networkTransferWindow.addListEntry("Couldn't connect to FTP Server, retrying...", "< Error >")
                continue
                    
                        
            # get new changelog
            transferWindowChangeLogIdx = networkTransferWindow.addListEntry("Downloading...", "ChangeLog")
            changes = DownloadFile(scripts, ftp, 'ChangeLog', 'NewChangeLog')
                
            if not changes:
                networkTransferWindow.modifyListEntryStatus(transferWindowChangeLogIdx, "Failed, please retry.")
                if sendWindowCloseSignal:
                    networkTransferWindow.allowCloseSignal.emit(False)
                Globals.Cache.databaseAccessRLock.release()
                return
            
            networkTransferWindow.modifyListEntryStatus(transferWindowChangeLogIdx, "Complete!")

            # Get any new entries
            LogSet = DatabaseHandler.GetChangelogData()
            newLogSet = DatabaseHandler.GetNewChangelogData()
            DownloaderSet = LogSet.symmetric_difference(newLogSet)
            Downloader = []
                        
            for item in DownloaderSet:
                itemList = item[1].split(',')
                for subitem in itemList:
                    Downloader.append(subitem)
                
            # remove possible duplicates from list, so it doesn't download the same file multiple times
            Downloader = list(set(Downloader))
            FilesToDownload = []

            # Don't download stuff that still has unsaved changes locally
            for item in Downloader:
                if item in scripts.update:
                    networkTransferWindow.addListEntry("Not downloading, still has unsaved local changes.", item)
                else: 
                    transferWindowIdx = networkTransferWindow.addListEntry("Waiting...", item)
                    FilesToDownload.append((item, transferWindowIdx))
                
            # Download the files that have been changed
            for item, transferWindowIdx in FilesToDownload:
                networkTransferWindow.modifyListEntryStatus(transferWindowIdx, "Downloading...")
                DownloadDatabaseAndClean(scripts, ftp, item)
                networkTransferWindow.modifyListEntryStatus(transferWindowIdx, "Complete!")

            ftp.close()

            # Copy new change log over old
            Globals.CopyFile( Globals.configData.LocalDatabasePath + '/NewChangeLog', Globals.configData.LocalDatabasePath + '/ChangeLog' )

            break
                
        except ftplib.all_errors:
            if i == 19:
                networkTransferWindow.addListEntry("Error during FTP transfer. Databases may not be up-to-date.", "< Error >")
                break
            networkTransferWindow.addListEntry("Error during FTP transfer, retrying...", "< Error >")
            continue
                
    try:
        splash.text = 'Grace Note now {0} in {1} Mode'.format(scripts.roletext[scripts.role], Globals.ModeFlag)
        splash.complete = True
    except:
        pass

    Globals.Cache.databaseAccessRLock.release()
    if sendWindowCloseSignal:
        networkTransferWindow.allowCloseSignal.emit(True)
    return
Ejemplo n.º 3
0
def SavetoServerWorker(scripts, networkTransferWindow, sendWindowCloseSignal):
    Globals.Cache.databaseAccessRLock.acquire()

    scripts.WriteDatabaseStorageToHdd()
        
    if len(scripts.update) == 0:
        networkTransferWindow.addListEntry("Nothing to save!", "-")
        if sendWindowCloseSignal:
            networkTransferWindow.allowCloseSignal.emit(False)
        Globals.Cache.databaseAccessRLock.release()
        return False

    # Beginning Save...
    autoRestartAfter = False
    for ftperrorcount in range(1, 20):
        try:        
            try:
                scripts.ftp = ConnectToFtp()
            except:
                if ftperrorcount >= 20:
                    networkTransferWindow.addListEntry("Couldn't connect to FTP Server, stopping upload. Please try again later.", "< Error >")
                    Globals.Settings.setValue('update', set(scripts.update))
                    if sendWindowCloseSignal:
                        networkTransferWindow.allowCloseSignal.emit(False)
                    Globals.Cache.databaseAccessRLock.release()
                    return False
                networkTransferWindow.addListEntry("Couldn't connect to FTP Server, retrying...", "< Error >")
                continue

            scripts.ftp.cwd('/')
            scripts.ftp.cwd(Globals.configData.RemoteDatabasePath)

            # Retrieving any files modified by others...
            RetrieveModifiedFilesWorker(scripts, None, networkTransferWindow, False)
                
            # Uploading Files...
            LogTable = []
            saveUpdate = set()
                
            # stagger upload into multiple 10-file batches
            # the way this is written we cannot keep it, but eh
            singleFileUploadCounter = 0
                
            for filename in scripts.update:
                singleFileUploadCounter = singleFileUploadCounter + 1
                if singleFileUploadCounter > 10:
                    autoRestartAfter = True
                    saveUpdate.add(filename)
                    continue
                
                # 'Uploading ' + Globals.GetDatabaseDescriptionString(filename) + ' [' + filename + ']...'

                transferWindowIdx = networkTransferWindow.addListEntry("Downloading...", filename)

                # Downloading the server version and double checking
                DownloadFile(scripts, scripts.ftp, str(filename), 'temp')

                try:
                    networkTransferWindow.modifyListEntryStatus(transferWindowIdx, "Merging...")
                    RemoteMergeCon = DatabaseHandler.OpenEntryDatabase('temp')
                    DatabaseHandler.MergeDatabaseWithServerVersionBeforeUpload(
                        DatabaseHandler.OpenEntryDatabase(filename).cursor(),
                        RemoteMergeCon.cursor()
                    )
                    RemoteMergeCon.commit()
                        
                    networkTransferWindow.modifyListEntryStatus(transferWindowIdx, "Uploading...")
                    for ftpSingleFileUpErrorCount in range(1, 20):
                        try:
                            if ftpSingleFileUpErrorCount >= 20:
                                networkTransferWindow.modifyListEntryStatus(transferWindowIdx, "!! Error !! Server file may be corrupted, please manually check and fix or inform someone who can.")
                                if sendWindowCloseSignal:
                                    networkTransferWindow.allowCloseSignal.emit(False)
                                Globals.Cache.databaseAccessRLock.release()
                                return False
                            result = UploadFile(scripts, scripts.ftp, 'temp', str(filename))
                            if isinstance(result, str):
                                continue
                            break
                        except ftplib.all_errors:
                            networkTransferWindow.modifyListEntryStatus(transferWindowIdx, "Error, retrying... (" + str(ftpSingleFileUpErrorCount) + ")")
                            continue
            
                    # And copy the new remote over the old local
                    Globals.CopyFile(Globals.configData.LocalDatabasePath + '/temp', Globals.configData.LocalDatabasePath + '/{0}'.format(filename))

                except:
                    networkTransferWindow.modifyListEntryStatus(transferWindowIdx, "Server file corrupted, replacing with local file...")
                    UploadFile(scripts, scripts.ftp, filename, filename)

                LogTable.append(filename)
                
                networkTransferWindow.modifyListEntryStatus(transferWindowIdx, "Complete!")

                CompletionTable.CalculateCompletionForDatabase(filename)
                Globals.Cache.LoadDatabase(filename)

            # Fix up the changelog and upload
            transferWindowChangeLogIdx = networkTransferWindow.addListEntry("Modifying...", "ChangeLog")

            ChangeLogConnection, ChangeLogCursor = Globals.GetNewChangeLogConnectionAndCursor()
            ChangeLogCursor.execute('SELECT Max(ID) as Highest FROM Log')
            MaxID = ChangeLogCursor.fetchall()[0][0]

            fileString = ''.join(["%s," % (k) for k in LogTable])[:-1]
            # 'Uploaded: ', fileString
                
            ChangeLogCursor.execute(u"INSERT INTO Log VALUES({0}, '{1}', '{2}', {3})".format(MaxID + 1, fileString, Globals.Author, "strftime('%s','now')"))
            ChangeLogConnection.commit()
            ChangeLogConnection.close()

            networkTransferWindow.modifyListEntryStatus(transferWindowChangeLogIdx, "Uploading...")
            changeLogUploadSuccess = False
            for changeup in range(1, 20):
                try:
                    result = UploadFile(scripts, scripts.ftp, 'ChangeLog', 'ChangeLog', False)
                    if isinstance(result, str) or not result:
                        if changeup >= 20:
                            break
                        else:
                            networkTransferWindow.modifyListEntryStatus(transferWindowChangeLogIdx, "Error, retrying... (" + str(changeup) + ")")
                            continue
                    networkTransferWindow.modifyListEntryStatus(transferWindowChangeLogIdx, "Complete!")
                    changeLogUploadSuccess = True
                    break
                except ftplib.all_errors:
                    if changeup >= 20:
                        break
                    networkTransferWindow.modifyListEntryStatus(transferWindowChangeLogIdx, "Error, retrying... (" + str(changeup) + ")")
                    continue
            if not changeLogUploadSuccess:
                networkTransferWindow.modifyListEntryStatus(transferWindowChangeLogIdx, "!! Error !! Server ChangeLog may be corrupted, please fix immediately.")
                if sendWindowCloseSignal:
                    networkTransferWindow.allowCloseSignal.emit(False)
                Globals.Cache.databaseAccessRLock.release()
                return False
                
            # Everything is done.
            scripts.ftp.close()
               
            if len(saveUpdate) > 0:
                Globals.MainWindow.displayStatusMessage( 'Retaining the following files for later upload: ' + str(saveUpdate) )
            scripts.update.clear()
            scripts.update = set(saveUpdate)
            Globals.Settings.setValue('update', scripts.update)
            Globals.Settings.sync()

            if autoRestartAfter:
                retval = SavetoServerWorker(scripts, networkTransferWindow, sendWindowCloseSignal)
                Globals.Cache.databaseAccessRLock.release()
                return retval

            if len(scripts.update) > 0:
                Globals.HaveUnsavedChanges = True
            else:
                Globals.HaveUnsavedChanges = False

            scripts.SetWindowTitle()

            if sendWindowCloseSignal:
                networkTransferWindow.allowCloseSignal.emit(True)
            Globals.Cache.databaseAccessRLock.release()
            return True
            
        except ftplib.all_errors:
            if ftperrorcount >= 20:
                networkTransferWindow.addListEntry("Error during FTP transfer. File(s) that were in progress may be corrupted, please confirm and fix.", "< Error >")
                break
            networkTransferWindow.addListEntry("Error during FTP transfer, retrying...", "< Error >")
            continue

    if sendWindowCloseSignal:
        networkTransferWindow.allowCloseSignal.emit(False)
    Globals.Cache.databaseAccessRLock.release()
    return False