class GoProGUI: def __init__(self, parent, ssid, snapFunc, transferFunc, clearFunc): self.frame = Frame(parent) self.parent = parent self.cameraLabel = Label(self.frame, text = 'SSID: ' + ssid) self.nameEntry = Textbox(self.frame, 'Name: ') self.recordBox = Checkbox(self.frame, 'Record') self.snap = Button(self.frame, text='Snapshot', command=snapFunc) self.transfer = Button(self.frame, text='Transfer', command=transferFunc) self.clear = Button(self.frame, text='Clear objectives', command=clearFunc) self.mounted = GUIIndicator(self.frame, 'Ready for transfer') self.unsaved = GUIIndicator(self.frame, 'Files synchronized') self.recording = GUIIndicator(self.frame, 'Recording') self.objectivesText = StringVar() self.objectives = Label(self.frame, textvariable=self.objectivesText, justify=LEFT) self.objectivesText.set('Objectives:') self.patternConfirmed = False def setState(self, state): self.state.setText('State: ' + state) def setUnsaved(self, bool): self.unsaved.setStatus(bool) def setMounted(self, bool): self.mounted.setStatus(bool) def setRecording(self, bool): self.recording.setStatus(bool) def displayObjectives(self, objectives): text = 'Objectives:\n' for obj in objectives: text += obj + '\n' self.objectivesText.set(text) def getName(self): return self.nameEntry.getText() def setName(self, text): self.nameEntry.setText(text) def shouldRecord(self): return self.recordBox.getVal() def confirmPattern(self, recordings, patterns): correctPattern = [] top = Toplevel(self.parent) infoText = Label(top, text='I cannot determine what video you recorded. Please select and confirm. Double click videos to watch', font=('Helvetica', 12)) infoText.grid(row=0, column=0, sticky=NW, padx=20, pady=20) for i in range(0, len(patterns)): if len(patterns[i]) == 1: correctPattern.append(patterns[i][0]) continue topFrame = Frame(top) topFrame.grid(row=1, column=0, ipadx=20, ipady=20) okButton = Button(topFrame, text='Confirm', command=self.confirmSelection, bg='green', activebackground='darkgreen') okButton.grid(row=1, column=0, padx=20, pady=20, columnspan=2, sticky=NW) patternList = GUIListbox(topFrame, items=patterns[i], width=100) patternList.grid(row=0, column=0, padx=20) patternList.bindDoubleClick(lambda _,: self.playVideo(patternList.getSelected())) recordingInfoFrame = Frame(topFrame, padx=20, pady=20) recordingInfoFrame.grid(row=0, column=1, sticky=NW) recordingLabel = Label(recordingInfoFrame, text='Recording name: ' + recordings[i].getRecordingName()) recordingLabel.grid(row=0, column=0, sticky=NW) cameraLabel = Label(recordingInfoFrame, text='Camera name: ' + recordings[i].getCameraName()) cameraLabel.grid(row=1, column=0, sticky=NW) while self.patternConfirmed == False: time.sleep(1) correctPattern.append(patternList.getSelected()) for index in range(i+1, len(patterns)): while syscalls.getFileMTime(patterns[index][0]) <= syscalls.getFileMTime(patternList.getSelected()): patterns[index].pop(0) topFrame.destroy() self.patternConfirmed = False top.destroy() return correctPattern def playVideo(self, file): os.system('totem ' + file + ' &') def grid(self, **kwargs): self.frame.grid(kwargs) self.cameraLabel.grid(row=0, column=0, columnspan=2, sticky=NW) self.nameEntry.grid(row=1, column=0, sticky=NW, columnspan=3) self.recordBox.grid(row=3, column=0, sticky=NW, columnspan=3) self.snap.grid(row=4, column=0, sticky=NW) self.transfer.grid(row=4, column=1, sticky=NW) self.clear.grid(row=4, column=2, sticky=NW) self.mounted.grid(row=5, column=0, sticky=NW, columnspan=3) self.unsaved.grid(row=6, column=0, sticky=NW, columnspan=3) self.recording.grid(row=7, column=0, sticky=NW, columnspan=3) self.objectives.grid(row=8, column=0, sticky=NW, columnspan=3) def confirmSelection(self): self.patternConfirmed = True def pack(self): return self.getName() + ',' + str(self.recordBox.getVal()) def load(self, string): if not string: return vals = string.split(',') self.setName(vals[0]) if vals[1] == 'True': self.recordBox.setVal(True) else: self.recordBox.setVal(False)
class Mainloop(threading.Thread): def __init__(self, parent): threading.Thread.__init__(self) self.parent = parent self.network = Network() self.storage = Storage() self.controlFrame = Frame(parent) self.controlFrame.grid(row=0, column=0, columnspan=99, padx=10, pady=10, sticky=NW) self.recordingName = Textbox(self.controlFrame, 'Name of recording: ') self.recordingName.grid(row=0, column=0, sticky=NW, padx=10) self.buttonsFrame = Frame(self.controlFrame) self.buttonsFrame.grid(row=1, column=0, sticky=NW, pady=10) self.recordButton = Toggle(self.buttonsFrame, 'Record', lambda: self.record('on'), lambda: self.record('off')) self.TCPOverride = Toggle(self.buttonsFrame, 'Enable TCP', lambda: self.tcp('on'), lambda: self.tcp('off')) self.recordButton.grid(row=0, column=0, sticky=NW, padx=10) self.TCPOverride.grid(row=0, column=1, sticky=NW, padx=10) self.camerasFrame = Frame(parent) self.camerasFrame.grid(row=1, column=0, padx=10, pady=10, sticky=NW) self.gpMaster = GoProMaster(self.camerasFrame, self.network) self.TCPServer = tcp.TCP() self.localUDP = udp.UDP() self.shouldExit = False self.load() def run(self): self.localUDP.open('127.0.0.1', 6000, 7000, timeout=0) timer = 0 while not self.shouldExit: self.save() self.addMountedCameras() self.sendAliveMessage() if self.TCPServer.isActive(): self.processMessage(self.TCPServer.get()) if timer % 20 == 0: for ssid in self.network.getSSIDList(): if self.network.isGoPro(ssid): self.addCamera(ssid) time.sleep(0.1) timer += 1 def addCamera(self, ssid): if not self.gpMaster.exists(ssid): self.gpMaster.addSlave(ssid) def record(self, state): self.gpMaster.record(state, self.recordingName.getText()) def tcp(self, state): if state == 'on': self.recordButton.disable() self.TCPServer = tcp.TCP() self.TCPServer.listen(config.getTCPInfo()[0], int(config.getTCPInfo()[1]), timeout=0.01) elif state == 'off': self.recordButton.enable() self.TCPServer.close() def processMessage(self, message): if not message: return message = message.lower() if message == 'record on': self.TCPServer.put('Starts recording') self.record('on') self.recordButton.setState(True) elif message == 'record off': self.TCPServer.put('Stops recording') self.record('off') self.recordButton.setState(False) elif message[0:7] == 'recname': self.TCPServer.put('Recording name set to: ' + message[8:]) self.recordingName.setText(message[8:]) def exit(self): self.shouldExit = True self.localUDP.close() self.TCPServer.close() self.gpMaster.exit() def save(self): toSave = self.recordingName.getText() + ',' + str(self.recordButton.getState()) self.storage.save('main', toSave) def load(self): loaded = self.storage.load('main') if not loaded: return loaded = loaded.split(',') self.recordingName.setText(loaded[0]) if loaded[1] == 'True': self.recordButton.setState(True) def addMountedCameras(self): usbids = config.getUSBids() for usbid in usbids: if syscalls.isMounted(usbid): self.addCamera(config.getSSID(usbid)) def sendAliveMessage(self): try: self.localUDP.put('alive') except: pass