def __init__(self, parent): super(GlobalChangelog, self).__init__( None, QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowIcon(QtGui.QIcon('icons/global.png')) self.parent = parent self.setWindowModality(False) self.treewidget = QtGui.QTreeWidget() self.treewidget.setRootIsDecorated(False) self.treewidget.setColumnCount(3) self.treewidget.setHeaderLabels(['Date', 'Name', 'File']) self.treewidget.setSortingEnabled(True) self.treewidget.setColumnWidth(0, 200) self.treewidget.setColumnWidth(1, 100) self.treewidget.setColumnWidth(2, 80) self.treewidget.setMinimumSize(450, 600) ChangeLogConnection, ChangeLogCursor = Globals.GetNewChangeLogConnectionAndCursor( ) ChangeLogCursor.execute("SELECT * FROM Log ORDER BY Timestamp DESC") templist = ChangeLogCursor.fetchall() ChangeLogConnection.close() #templist.pop(0) for entry in templist: for filename in entry[1].split(','): self.treewidget.addTopLevelItem( QtGui.QTreeWidgetItem([ '{0}'.format( time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(entry[3]))), '{0}'.format(entry[2]), '{0}'.format(filename) ])) self.treewidget.itemDoubleClicked.connect(self.JumpToFile) self.setWindowTitle('Global Changelog') layout = QtGui.QVBoxLayout() layout.addWidget(QtGui.QLabel('Recent Changes:')) layout.addWidget(self.treewidget) self.setLayout(layout) geom = Globals.Settings.value('Geometry/GlobalChangelog') if geom is not None: self.restoreGeometry(geom)
def GetChangelogData(cursor=None): if not cursor: connection, cursor = Globals.GetNewChangeLogConnectionAndCursor() closeConnectionWhenDone = True else: closeConnectionWhenDone = False cursor.execute('SELECT ID, File FROM Log ORDER BY ID') results = cursor.fetchall() LogSet = set(results) if closeConnectionWhenDone: connection.close() return LogSet
def __init__(self, file): super(LocalChangelog, self).__init__(None, QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowIcon(QtGui.QIcon('icons/changelog.png')) self.setWindowModality(False) self.listwidget = QtGui.QListWidget() ChangeLogConnection, ChangeLogCursor = Globals.GetNewChangeLogConnectionAndCursor() ChangeLogCursor.execute("SELECT * FROM Log WHERE File='{0}'".format(file)) templist = ChangeLogCursor.fetchall() ChangeLogConnection.close() for entry in templist: self.listwidget.addItem('{0} on {1}'.format(entry[2], time.strftime('%a, %B %d at %H:%M %p', time.localtime(entry[3])))) self.setWindowTitle('Changelog: {0}'.format(file)) layout = QtGui.QVBoxLayout() layout.addWidget(QtGui.QLabel('File Modified By:')) layout.addWidget(self.listwidget) self.setLayout(layout) geom = Globals.Settings.value('Geometry/LocalChangelog') if geom is not None: self.restoreGeometry(geom)
def __init__(self): super(Statistics, self).__init__( None, QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinMaxButtonsHint) self.setWindowIcon(QtGui.QIcon('icons/report.png')) self.setWindowTitle('Reports') self.setWindowModality(False) layout = QtGui.QVBoxLayout() self.setMinimumSize(400, 600) self.setMaximumWidth(400) ChangeLogConnection, ChangeLogCursor = Globals.GetNewChangeLogConnectionAndCursor( ) ChangeLogCursor.execute("SELECT * FROM Log") LogList = ChangeLogCursor.fetchall() ChangeLogConnection.close() # Today Stats TodayGroup = QtGui.QGroupBox() layout.addWidget(TodayGroup) TodayGroup.setTitle('Today:') TodayLay = QtGui.QVBoxLayout() TodayGroup.setLayout(TodayLay) TodayList = set() TodaySet = set() today = time.strftime('%Y/%m/%d', time.localtime(time.time())) for entry in LogList: if time.strftime('%Y/%m/%d', time.localtime(entry[3])) == today: TodaySet.add(entry[2]) for x in entry[1].split(','): TodayList.add((x, entry[2])) if TodaySet == set([]): TodayLay.addWidget(QtGui.QLabel("Nobody's done anything today =(")) else: for name in TodaySet: string = '' i = 0 for entry in TodayList: if entry[1] == name: string = string + entry[0] + ', ' i += 1 label = QtGui.QLabel('{0}: {1} files translated'.format( name, i)) TodayLay.addWidget(label) label = QtGui.QLabel(string[:-2] + '\n') label.setWordWrap(True) font = label.font() font.setPointSize(10) font.setItalic(True) label.setFont(font) TodayLay.addWidget(label) # Yesterday Stats YesterdayGroup = QtGui.QGroupBox() layout.addWidget(YesterdayGroup) YesterdayGroup.setTitle('Yesterday:') YesterdayLay = QtGui.QVBoxLayout() YesterdayGroup.setLayout(YesterdayLay) YesterdayList = set() YesterdaySet = set() yesterday = time.strftime('%Y/%m/%d', time.localtime(time.time() - (24 * 60 * 60))) for entry in LogList: if time.strftime('%Y/%m/%d', time.localtime(entry[3])) == yesterday: YesterdaySet.add(entry[2]) for x in entry[1].split(','): YesterdayList.add((x, entry[2])) if YesterdaySet == (): YesterdayLay.addWidget( QtGui.QLabel("Nobody did anything yesterday =(")) else: for name in YesterdaySet: string = '' i = 0 for entry in YesterdayList: if entry[1] == name: string = string + entry[0] + ', ' i += 1 label = QtGui.QLabel('{0}: {1} files translated'.format( name, i)) YesterdayLay.addWidget(label) label = QtGui.QLabel(string[:-2] + '\n') label.setWordWrap(True) font = label.font() font.setPointSize(10) font.setItalic(True) label.setFont(font) YesterdayLay.addWidget(label) #Lifetime Stats LifetimeGroup = QtGui.QGroupBox() layout.addWidget(LifetimeGroup) LifetimeGroup.setTitle('Lifetime:') LifetimeLay = QtGui.QVBoxLayout() LifetimeGroup.setLayout(LifetimeLay) LifetimeList = [] LifetimeSet = set() for entry in LogList: LifetimeSet.add(entry[2]) for x in entry[1].split(','): LifetimeList.append((x, entry[2])) PrintList = [] for name in LifetimeSet: string = '' countset = set() for entry in LifetimeList: if entry[1] == name: countset.add(entry[0]) PrintList.append([len(countset), name]) PrintList.sort() PrintList.reverse() for entry in PrintList: label = QtGui.QLabel('{0:<20}\t{1} files translated'.format( entry[1] + ':', entry[0])) LifetimeLay.addWidget(label) self.setLayout(layout) geom = Globals.Settings.value('Geometry/Statistics') if geom is not None: self.restoreGeometry(geom)
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