class ImportWindow(BaseWidget): def __init__(self, timeline=None): super(ImportWindow, self).__init__('Import file') self.setContentsMargins(10, 10, 10, 10) self._timeline = timeline # Definition of the forms fields self._filetype = ControlCombo('Please select the type of file you would like to import:') self._importButton = ControlButton('Import') self._panel = ControlEmptyWidget('Panel') self._file = ControlFile('File to import') self._panel.value = self._file self._filetype.addItem('Events file', 0) self._filetype.addItem('Graph file', 1) self._filetype.addItem('Bonsai events file', 2) self._formset = [ ('_filetype', ' '), '_panel', (' ', '_importButton'), ' '] self._filetype.changed = self.__fileTypeChanged self._importButton.value = self.__importData self._graphCsvParserDlg = CsvParserDialog() self._graphCsvParserDlg.xField.label = "Value column" self._graphCsvParserDlg.yField.hide() self._graphCsvParserDlg.zField.hide() self._graphCsvParserDlg.loadButton.hide() self._bonsaiImportDlg = BonsaiImportFileDlg() def __fileTypeChanged(self): if self._filetype.value == 0: self._panel.value = self._file elif self._filetype.value == 1: self._panel.value = self._graphCsvParserDlg elif self._filetype.value == 2: self._panel.value = self._bonsaiImportDlg def __importData(self): if self._filetype.value == 0: separator = ',' with open(self._file.value, 'rU') as csvfile: line = csvfile.readline() if ";" in line: separator = ';' with open(self._file.value, 'rU') as csvfile: csvfile = csv.reader(csvfile, delimiter=separator) self._timeline._time.import_csv(csvfile) elif self._filetype.value == 1: self._timeline._time.importchart_csv(self._graphCsvParserDlg) elif self._filetype.value == 2: with open(self._bonsaiImportDlg._file.value, 'rU') as csvfile: values = [] csvfile = csv.reader(csvfile, delimiter=' ') for row in csvfile: try: timestr = row[1].rstrip('0') cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S.%f") except: timestr = row[1] cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S") seconds = (cvttime - datetime.datetime(1900, 1, 1)).total_seconds() frame = int(round(self._bonsaiImportDlg._fps.value * seconds)) if row[0].startswith('Start'): eventtype = row[0][5:] else: eventtype = row[0][3:] values.append([eventtype, frame, row[2]]) values = sorted(values, key=lambda x: (x[0].capitalize(), x[1])) ntracks = len(set([x[0] for x in values])) # collapse events = [] eventsTypes = {} currentTrack = 0 for index in range(0, len(values), 2): row0 = values[index] row1 = values[index + 1] if row0[0] not in eventsTypes: eventsTypes[row0[0]] = currentTrack track = currentTrack currentTrack += 1 else: track = eventsTypes[row0[0]] self._timeline.addPeriod([row0[1], row1[1], row0[0]], track=track) self.close()
class ImportWindow(BaseWidget): def __init__(self, timeline=None): super(ImportWindow, self).__init__('Import file') self.setContentsMargins(10, 10, 10, 10) self._timeline = timeline # Definition of the forms fields self._filetype = ControlCombo( 'Please select the type of file you would like to import:') self._importButton = ControlButton('Import') self._panel = ControlEmptyWidget('Panel') self._file = ControlFile('File to import') self._panel.value = self._file self._filetype.addItem('Events file', 0) self._filetype.addItem('Graph file', 1) self._filetype.addItem('Bonsai events file', 2) self._formset = [('_filetype', ' '), '_panel', (' ', '_importButton'), ' '] self._filetype.changed = self.__fileTypeChanged self._importButton.value = self.__importData from pyforms.dialogs import CsvParserDialog self._graphCsvParserDlg = CsvParserDialog() self._graphCsvParserDlg.xField.label = "Value column" self._graphCsvParserDlg.yField.hide() self._graphCsvParserDlg.zField.hide() self._graphCsvParserDlg.loadButton.hide() self._bonsaiImportDlg = BonsaiImportFileDlg() def __fileTypeChanged(self): if self._filetype.value == 0: self._panel.value = self._file elif self._filetype.value == 1: self._panel.value = self._graphCsvParserDlg elif self._filetype.value == 2: self._panel.value = self._bonsaiImportDlg def __importData(self): if self._filetype.value == 0: separator = ',' with open(self._file.value, 'rU') as csvfile: line = csvfile.readline() if ";" in line: separator = ';' with open(self._file.value, 'rU') as csvfile: csvfile = csv.reader(csvfile, delimiter=separator) self._timeline._time.import_csv(csvfile) elif self._filetype.value == 1: self._timeline._time.importchart_csv(self._graphCsvParserDlg) elif self._filetype.value == 2: with open(self._bonsaiImportDlg._file.value, 'rU') as csvfile: values = [] pointEventValues = [] csvfile = csv.reader(csvfile, delimiter=' ') for row in csvfile: # strip Start/End word from all events names which are not PointEven try: timestr = row[1].rstrip('0') cvttime = datetime.datetime.strptime( timestr, "%H:%M:%S.%f") except: timestr = row[1] cvttime = datetime.datetime.strptime( timestr, "%H:%M:%S") seconds = (cvttime - datetime.datetime(1900, 1, 1)).total_seconds() frame = int( round(self._bonsaiImportDlg._fps.value * seconds)) if row[2] == "PointEvent": eventtype = row[0] pointEventValues.append([eventtype, frame, row[2]]) else: if row[0].startswith('Start'): eventtype = row[0][ len('Start' ):] # strip Start word from the beginning else: eventtype = row[0][len( 'End'):] # strip End word from the beginning values.append([eventtype, frame, row[2]]) values = sorted(values, key=lambda x: (x[0].capitalize(), x[1])) pointEventValues = sorted(pointEventValues, key=lambda x: (x[0].capitalize(), x[1])) ntracks = len(set([x[0] for x in values])) + 1 # collapse events = [] eventsTypes = {} # Events names currentTrack = 0 for index in range(0, len(pointEventValues)): pointEventValue = pointEventValues[index] eventsTypes[pointEventValue[0]] = currentTrack self._timeline.addPeriod([ pointEventValue[1], pointEventValue[1] + 50, pointEventValue[0] ], track=currentTrack) currentTrack = 1 for index in range(0, len(values), 2): row0 = values[index] row1 = values[index + 1] if row0[0] not in eventsTypes: eventsTypes[row0[0]] = currentTrack track = currentTrack currentTrack += 1 else: track = eventsTypes[row0[0]] self._timeline.addPeriod([row0[1], row1[1], row0[0]], track=track) self.close() # pylint: disable=no-member
class ImportWindow(BaseWidget): def __init__(self, timeline=None): super(ImportWindow, self).__init__('Import file', parentWindow=timeline) self.setContentsMargins(10, 10, 10, 10) self._timeline = timeline # Definition of the forms fields self._filetype = ControlCombo('Please select the type of file you would like to import:') self._importButton = ControlButton('Import') self._panel = ControlEmptyWidget('Panel') self._file = ControlFile('File to import') self._panel.value = self._file self._filetype.addItem('Events file', 0) self._filetype.addItem('Graph file', 1) self._filetype.addItem('Bonsai events file', 2) self._formset = [ ('_filetype', ' '), '_panel', (' ', '_importButton'), ' '] self._filetype.changed = self.__fileTypeChanged self._importButton.value = self.__importData from pyforms.gui.dialogs.csv_parser import CsvParserDialog self._graphCsvParserDlg = CsvParserDialog() self._graphCsvParserDlg.xField.label = "Value column" self._graphCsvParserDlg.yField.hide() self._graphCsvParserDlg.zField.hide() self._graphCsvParserDlg.loadButton.hide() self._bonsaiImportDlg = BonsaiImportFileDlg() def __fileTypeChanged(self): if self._filetype.value == 0: self._panel.value = self._file elif self._filetype.value == 1: self._panel.value = self._graphCsvParserDlg elif self._filetype.value == 2: self._panel.value = self._bonsaiImportDlg def __importData(self): if self._filetype.value == 0: separator = ',' with open(self._file.value, 'rU') as csvfile: line = csvfile.readline() if ";" in line: separator = ';' with open(self._file.value, 'rU') as csvfile: csvfile = csv.reader(csvfile, delimiter=separator) self._timeline._time.import_csv(csvfile) elif self._filetype.value == 1: self._timeline._time.importchart_csv(self._graphCsvParserDlg) self._timeline.show_graphs_properties() elif self._filetype.value == 2: with open(self._bonsaiImportDlg._file.value, 'rU') as csvfile: values = [] pointEventValues = [] csvfile = csv.reader(csvfile, delimiter=' ') for row in csvfile: # strip Start/End word from all events names which are not PointEven try: timestr = row[1].rstrip('0') cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S.%f") except: timestr = row[1] cvttime = datetime.datetime.strptime(timestr, "%H:%M:%S") seconds = (cvttime - datetime.datetime(1900, 1, 1)).total_seconds() frame = int(round(self._bonsaiImportDlg._fps.value * seconds)) if row[2] == "PointEvent": eventtype = row[0] pointEventValues.append([eventtype, frame, row[2]]) else: if row[0].startswith('Start'): eventtype = row[0][len('Start'):] # strip Start word from the beginning else: eventtype = row[0][len('End'):] # strip End word from the beginning values.append([eventtype, frame, row[2]]) values = sorted(values, key=lambda x: (x[0].capitalize(), x[1])) pointEventValues = sorted(pointEventValues, key=lambda x: (x[0].capitalize(), x[1])) ntracks = len(set([x[0] for x in values])) + 1 # collapse events = [] eventsTypes = {} # Events names currentTrack = 0 for index in range(0, len(pointEventValues)): pointEventValue = pointEventValues[index] eventsTypes[pointEventValue[0]] = currentTrack self._timeline.addPeriod([pointEventValue[1], pointEventValue[1] + 50, pointEventValue[0]], track=currentTrack) currentTrack = 1 for index in range(0, len(values), 2): row0 = values[index] row1 = values[index + 1] if row0[0] not in eventsTypes: eventsTypes[row0[0]] = currentTrack track = currentTrack currentTrack += 1 else: track = eventsTypes[row0[0]] self._timeline.addPeriod([row0[1], row1[1], row0[0]], track=track) self.close() # pylint: disable=no-member def import_chart(self, filename, frame_col=0, val_col=1): self._filetype.value = 1 self._graphCsvParserDlg.filename = filename self._graphCsvParserDlg.frameColumn = frame_col self._graphCsvParserDlg.xColumn = val_col
class Metronome(Programming, BaseWidget): # def global non-settings variables global playing playing = False global bpm global checkSliderThread global metronomeSoundThread global metronomeTime global timeSignatureNumerator global timeSignatureDenominator global subdivision Globals.programRunning = False # def global settings variables global minTempo global maxTempo def metronomeSound(self): global bpm global playing global metronomeTime global timeSignatureNumerator global timeSignatureDenominator global subdivision global measure measure = 0 global tempoChangeCount count = 0 global initialized initialized = False ## The numerator is the number of beats played. ## The denominator is the speed of the beats. ## If the the numerator is the same as the denominator, the the tempo should remain the same. ## If the numerator is not, the tempo should be increased by the denominator divided by four. ## TODO: Add changable beat definitions ## If the numerator is not, the numerator should be divided by the denominator divided by four. metronomeTime = (60.0 / bpm)/int(subdivision) beatOne = pyglet.media.load("sound/beatOne.wav", streaming=False) quarterBeat = pyglet.media.load("sound/quarterBeat.wav", streaming=False) offBeat = pyglet.media.load("sound/offBeat.wav", streaming=False) count = (timeSignatureNumerator*int(subdivision)) timeSigMem = timeSignatureNumerator if not Globals.programRunning: print("Metronome Clicking as metronome") while playing: # May add again later - was moved down to be universal # if metronomeTime != 60.0 / bpm : metronomeTime = 60.0 / bpm if timeSigMem != timeSignatureNumerator: measure = 1 player = beatOne.play() print("UPDATE COUNT!") count = (timeSignatureNumerator*subdivision) timeSigMem = timeSignatureNumerator else: if count%(timeSignatureNumerator*subdivision) == 0: player = beatOne.play() measure += 1 else: if count%subdivision != 0 or subdivision == 1: player = quarterBeat.play() else: player = offBeat.play() Metronome.busy_wait(self, metronomeTime) player.delete() count += 1 Globals.programRunning = False else: print("Metronome Clicking as Program") global currentEvent currentEvent = 0 global programmedBPM programmedBPM = Globals.globalEventList[0][1] global measure global repeatNumber repeatNumber = 1 global changingTempo changingTempo = False global tempoChangeCount tempoChangeCount = 0 while playing: metronomeTime = (60.0 / float(programmedBPM))/float(subdivision) subdivision = int(subdivision) # May add again later - was moved down to be universal # if metronomeTime != 60.0 / bpm : metronomeTime = 60.0 / bpm if int(count) % (int(timeSignatureNumerator)*int(subdivision)) == 0: try: if Globals.globalEventList[currentEvent][0] == "STOP" and measure == int(Globals.globalEventList[currentEvent][5]): print("Program Ended") self._runProgram.label="Run Program" playing = False Globals.programRunning = False break else: if measure == int(Globals.globalEventList[currentEvent][5])-1: print("Event Triggered: "+str(Globals.globalEventList[currentEvent][0])) if int(Globals.globalEventList[currentEvent][6]) > 1: global changingTempo changingTempo = True tempoChange = int(Globals.globalEventList[currentEvent][1]) - int(programmedBPM) global tempoPerBeat tempoPerBeat = tempoChange/int(Globals.globalEventList[currentEvent][6]) else: programmedBPM = Globals.globalEventList[currentEvent][1] global timeSignatureNumerator global timeSignatureDenominator global subdivision timeSignatureNumerator = Globals.globalEventList[currentEvent][2] timeSignatureDenominator = Globals.globalEventList[currentEvent][3] subdivision = Globals.globalEventList[currentEvent][4] programmedBPM = programmedBPM*(int(timeSignatureDenominator)/4) subdivision = int(subdivision) timeSignatureNumerator = int(timeSignatureNumerator) global count count = timeSignatureNumerator self._tempoSlider.value = programmedBPM self._metronomeStatusLabel.value = ("Time Signature: "+str(timeSignatureNumerator)+"/"+str(timeSignatureDenominator)) self._metronomeSubdivLabel.value = ("Subdivision: "+str(subdivision)) player = beatOne.play() measure += 1 try: Globals.globalEventList[currentEvent][6] except IndexError: print("Program Ended") self._runProgram.label="Run Program" playing = False Globals.programRunning = False break except IndexError: print("Program Ended") self._runProgram.label="Run Program" playing = False Globals.programRunning = False break if Globals.globalEventList[currentEvent][0] == "REPEAT" and repeatNumber > 0: global initialized if initialized: global repeatNumber repeatNumber -= 1 else: global repeatNumber repeatNumber = Globals.globalEventList[currentEvent][2] initialized = True currentEvent = int(int(Globals.globalEventList[currentEvent][1])-1) global currentEvent currentEvent = currentEvent+1 int(currentEvent) else: if Globals.globalEventList[currentEvent-1][0] == "STOP" and measure == int(Globals.globalEventList[currentEvent-1][5]): print("Program Ended") self._runProgram.label="Run Program" playing = False Globals.programRunning = False break else: if count%subdivision != 0 or subdivision == 1: player = quarterBeat.play() try: global changingTempo if changingTempo == True and tempoChangeCount <= int(Globals.globalEventList[currentEvent][6]): global programmedBPM programmedBPM = int(programmedBPM)+int(tempoPerBeat) print(programmedBPM) global tempoChangeCount tempoChangeCount += 1 print(tempoChangeCount) except IndexError: print("Program Ended") self._runProgram.label="Run Program" playing = False Globals.programRunning = False break else: player = offBeat.play() Metronome.busy_wait(self, metronomeTime) player.delete() count = int(count)+1 def drawMetronome(self): # Create the Metronome GUI self._tempoSlider = ControlSlider("Tempo", defaultValue=120, min=minTempo, max=maxTempo) self._togglePause = ControlButton("Play/Pause", checkable=True) self._minusOne = ControlButton("-") self._addOne = ControlButton("+") self._togglePause.value = self.togglePauseAction self._minusOne.value = self.minusOneAction self._addOne.value = self.addOneAction global bpm bpm = self._tempoSlider.value def __init__(self): Globals.init() # Initialize the Metronome GUI BaseWidget.__init__(self, "AutoMetronome") # Create the Settings GUI # Metronome Tab self._togglePause = ControlButton("Play/Pause", checkable=True) self._minusOne = ControlButton("-") self._addOne = ControlButton("+") self._togglePause.value = self.togglePauseAction self._minusOne.value = self.minusOneAction self._addOne.value = self.addOneAction # Settings Tab self._minTempoInput = ControlText(label="Minimum Tempo", defaultValue="30") self._maxTempoInput = ControlText(label="Maximum Tempo", defaultValue="255") self._timeSignatureNumeratorInput = ControlNumber(label="Time Signature:", defaultValue=4) self._timeSignatureDenominatorInput = ControlNumber(label="/",defaultValue=4) self._subdivisionInput = ControlNumber("Subdivisions per Beat:", defaultValue=1) self._tempoDividerSet = ControlCombo("Tempo Defined ") self._tempoDividerSet.addItem("In Full Value", value="quarter") self._tempoDividerSet.addItem("In Cut Time", value="half") self._tempoDividerSet.addItem("In One", value="one") self._tempoDividerSet.addItem("In Two", value="eighth") self._tempoDividerSet.addItem("By Dotted Eighth Note (for 6/8 or similar times)", value="eighth_dot") self._tempoDividerSet.addItem("By Dotted Quarter Note (for 6/8 or similar times)", value="quarter_dot") self._updateSettings = ControlButton("Save") self._updateSettings.value = self.updateSettingsAction # Programming Tab self._runProgram = ControlButton("Run Program") self._runProgram.value = self.runProgramAction self._loadProgram = ControlFile(label="Load Program") self._programmingPanel = ControlDockWidget() programmingWindow = Programming() programmingWindow.parent = self self._programmingPanel.value = programmingWindow # self._programmingPanel.hide() # End of UI creation global minTempo global maxTempo minTempo = int(self._minTempoInput.value) maxTempo = int(self._maxTempoInput.value) global timeSignatureNumerator global timeSignatureDenominator timeSignatureNumerator = int(self._timeSignatureNumeratorInput.value) timeSignatureDenominator = int(self._timeSignatureDenominatorInput.value) global subdivision subdivision = float(self._subdivisionInput.value) global tempoDivider global bpmMultiplier tempoDivider = self._tempoDividerSet.value bpmMultiplier = 1 self._metronomeStatusLabel = ControlLabel("Time Signature: "+str(timeSignatureNumerator)+"/"+str(timeSignatureDenominator)) self._metronomeSubdivLabel = ControlLabel("Subdivision: "+str(subdivision)) # Draw the metronome Metronome.drawMetronome(self) # Set layout self._formset = [ { 'Metronome': [('_tempoSlider', '_minusOne','_addOne'), ('_metronomeStatusLabel', '_metronomeSubdivLabel'),'=','_togglePause'], 'Settings': ['_minTempoInput', '_maxTempoInput',('_timeSignatureNumeratorInput', '_timeSignatureDenominatorInput'), '_subdivisionInput', '_tempoDividerSet','_updateSettings'], 'Programming':['_runProgram', '_loadProgram'], 'Vade Mecum':['Programming: \n The window is relatively self explanatory, \n but there are a few hidden details. If you name an Event \"STOP\", \n the program will automatically stop at the beginning of that measure.\n If you name an Event \"REPEAT\", you can put the Event number \n (first Event being \'1\') in the Beats column \n and the number of times to repeat in the BPM column. \n \n Saving/Loading: \n Saving a program happens automatically when you open a file \n in the Save Program window. There is no feedback \n to indicate this yet.'] }] # Multithreaded slider process defined here def checkSlider(self): while(playing): global bpm global bpmMultiplier global metronomeTime global subdivision if bpm != self._tempoSlider.value*float(bpmMultiplier): bpm = self._tempoSlider.value*float(bpmMultiplier) metronomeTime = (60.0/bpm)/subdivision print("BPM updated to "+str(bpm)) time.sleep(0.1) # define the Play/Pause Button action def togglePauseAction(self): global playing if playing == False: print("Playing at "+str(self._tempoSlider.value)+"bpm") playing = True global bpm bpm = self._tempoSlider.value # Start Metronome global metronomeSoundThread metronomeSoundThread = threading.Thread(name='metronomeSoundThread', target=Metronome.metronomeSound, args=(self,)) metronomeSoundThread.setDaemon(True) metronomeSoundThread.start() # Start Slider polling global checkSliderThread checkSliderThread = threading.Thread(name='checkSliderThread', target=Metronome.checkSlider, args=(self,)) checkSliderThread.setDaemon(True) checkSliderThread.start() else: print("Stopped at "+str(self._tempoSlider.value)+"bpm") playing = False # define the add/subtract bpm buttons def minusOneAction(self): self._tempoSlider.value -= 1 def addOneAction(self): self._tempoSlider.value += 1 # define the update settings button action def updateSettingsAction(self): #Save the min/max tempos global minTempo global maxTempo global timeSignatureNumerator global timeSignatureDenominator global subdivision global metronomeTime global bpm global bpmMultiplier global tempoDivider minTempo = int(float(self._minTempoInput.value)) maxTempo = int(float(self._maxTempoInput.value)) timeSignatureNumerator = int(float(self._timeSignatureNumeratorInput.value)) timeSignatureDenominator = int(float(self._timeSignatureDenominatorInput.value)) tempoDivider = self._tempoDividerSet.value # SKETCHY SUBDIVISION VALUES - CHECK HERE FOR GLITCHES # TODO: Bug testing! subdivision = int(float(self._subdivisionInput.value)) metronomeTime = (60.0/bpm)/subdivision bpm = bpm*(timeSignatureDenominator/4) # SKETCHY NEW NOTE LENGTH DEFINITIONS if tempoDivider == "quarter": bpmMultiplier = 1 elif tempoDivider == "half": bpmMultiplier = 2 elif tempoDivider == "one": bpmMultiplier = float(1/float(timeSignatureNumerator)) timeSignatureNumerator = 1 elif tempoDivider == "eighth": bpmMultiplier = 0.5 timeSignatureNumerator = timeSignatureNumerator/2 elif tempoDivider == "eighth_dot": bpmMultiplier = float(0.25*(3.0/2.0)*(timeSignatureDenominator/4)) elif tempoDivider == "quarter_dot": bpmMultiplier = float(0.5*(3.0/2.0)*(timeSignatureDenominator/4)) else: print("bpmMultiplier not recognized") bpmMultiplier = bpmMultiplier*(timeSignatureDenominator/4) # End sketchy self._tempoSlider.min = minTempo self._tempoSlider.max = maxTempo self._metronomeStatusLabel.value ="Time Signature: "+str(timeSignatureNumerator)+"/"+str(timeSignatureDenominator) self._metronomeSubdivLabel.value = "Subdivision: "+str(subdivision) # More accurate sleep, thanks to StackOverflow 17499837. Takes CPU, but that is required to be accurate. def busy_wait(self, waitTime): current_time = time.time() while (time.time() < current_time+waitTime): pass def runProgramAction(self): global playing if Globals.programRunning and playing: print("Stopping Program") Globals.programRunning = False playing = False self._runProgram.label="Run Program" else: print("Running Program") Globals.programRunning = True playing = True # Start Metronome global metronomeSoundThread metronomeSoundThread = threading.Thread(name='metronomeSoundThread', target=Metronome.metronomeSound, args=(self,)) metronomeSoundThread.setDaemon(True) metronomeSoundThread.start() self._runProgram.label="Stop Program"
class AdminStatsApp(BaseWidget): def __init__(self): super(AdminStatsApp, self).__init__('Admin stats') self._totalExec_begin = ControlDate('Starting date', '2014-10-10') self._totalExec_end = ControlDate('Ending date', '2015-10-10') self._totalExec_btn = ControlButton('Refresh') self._totalExec_graph = ControlVisVis('Total execution time') self._apps_list = ControlCombo('Filter by application') self._totalExecApp_graph = ControlVisVis( 'Total execution time per application') self._servers_list = ControlCombo('Filter by server') self._totalExecServer_graph = ControlVisVis( 'Total execution time per server') self._formset = [ ('_totalExec_begin', '_totalExec_end', '_totalExec_btn'), 'h3:Total execution time', '_totalExec_graph', 'h3:Total execution time per application', '_apps_list', '_totalExecApp_graph', 'h3:Total execution time per server', '_servers_list', '_totalExecServer_graph' ] self._totalExec_btn.value = self.__total_exec_stats self._apps_list.addItem('--- All ---', '') for application in Algorithm.objects.all(): self._apps_list.addItem(str(application.algorithm_name), str(application.algorithm_class)) self._servers_list.addItem('--- All ---', '') for server in Server.objects.all().order_by('server_name'): self._servers_list.addItem(str(server.server_name), str(server.pk)) def initForm(self): self.__total_exec_stats() return super(AdminStatsApp, self).initForm() def __calc_total_exec_stats(self, begin, end, app=None, server=None): values = Job.objects.filter(job_created__range=(begin, end)) if app is not None: values = values.filter(job_application=app) if server is not None: values = values.filter(server=server) values = values.extra(select={'created': "DATE(job_created)"}) values = values.values('created').annotate( job_duration=Sum(F('job_ended') - F('job_created'), output_field=fields.DurationField())) values = values.order_by('created') res = [] for row in values: duration = row['job_duration'].total_seconds( ) if row['job_duration'] != None else 0 if duration > 0: res.append([row['created'], duration]) return res def __total_exec_stats(self): begin = datetime.datetime.strptime(self._totalExec_begin.value, "%Y-%m-%d").date() end = datetime.datetime.strptime(self._totalExec_end.value, "%Y-%m-%d").date() total_exec = self.__calc_total_exec_stats(begin, end) self._totalExec_graph.value = [total_exec] series = [] legend = [] apps = Algorithm.objects.all() if self._apps_list.value != '': apps = apps.filter(algorithm_class=self._apps_list.value) for application in apps: res = self.__calc_total_exec_stats(begin, end, app=application.algorithm_class) if len(res) > 0: series.append(res) legend.append(str(application.algorithm_name)) self._totalExecApp_graph.legend = legend self._totalExecApp_graph.value = series series = [] legend = [] servers = Server.objects.all() if self._servers_list.value != '': servers = servers.filter(pk=self._servers_list.value) for server in servers: res = self.__calc_total_exec_stats(begin, end, server=server) if len(res) > 0: series.append(res) legend.append(str(server.server_name)) self._totalExecServer_graph.legend = legend self._totalExecServer_graph.value = series