def __init__(self, fileName: str, parent: QWidget = None): """ :param fileName: name of the file to read. :param parent: parent widget. """ self.viewer = QRemoteDesktop(800, 600) super().__init__(self.viewer, parent) QApplication.instance().aboutToQuit.connect(self.onClose) self.fileName = fileName self.file = open(self.fileName, "rb") self.eventHandler = PlayerMessageHandler(self.widget, self.text) replay = Replay(self.file) self.thread = ReplayThread(replay) self.thread.eventReached.connect(self.readEvent) self.thread.timeUpdated.connect(self.onTimeUpdated) self.thread.clearNeeded.connect(self.clear) self.thread.start() self.controlBar = ReplayBar(replay.duration) self.controlBar.play.connect(self.thread.play) self.controlBar.pause.connect(self.thread.pause) self.controlBar.seek.connect(self.thread.seek) self.controlBar.speedChanged.connect(self.thread.setSpeed) self.layout().insertWidget(0, self.controlBar) self.player = PlayerMessageLayer() self.player.addObserver(self.eventHandler)
def __init__(self, fileName: str, parent: QWidget): """ :param fileName: name of the file to read. :param parent: parent widget. """ self.viewer = QRemoteDesktop(800, 600, parent) super().__init__(self.viewer, parent) QApplication.instance().aboutToQuit.connect(self.onClose) self.fileName = fileName self.file = open(self.fileName, "rb") self.eventHandler = PlayerEventHandler(self.widget, self.text) replay = Replay(self.file) self.reader = ReplayReader(replay) self.thread = ReplayThread(replay) self.thread.eventReached.connect(self.readEvent) self.thread.timeUpdated.connect(self.onTimeUpdated) self.thread.clearNeeded.connect(self.clear) self.thread.start() self.controlBar = ReplayBar(replay.duration) self.controlBar.play.connect(self.thread.play) self.controlBar.pause.connect(self.thread.pause) self.controlBar.seek.connect(self.thread.seek) self.controlBar.speedChanged.connect(self.thread.setSpeed) self.controlBar.scaleCheckbox.stateChanged.connect( self.setScaleToWindow) self.controlBar.button.setDefault(True) self.tabLayout.insertWidget(0, self.controlBar)
def processReplay(self, infile: Path): # FIXME: Sinks need to support progress bar. widgets = [ progressbar.FormatLabel( f'Converting to {self.args.format.upper()}'), progressbar.BouncingBar(), progressbar.FormatLabel(' Elapsed: %(elapsed)s'), ] with progressbar.ProgressBar(widgets=widgets) as progress: print(f"[*] Converting '{infile}' to {self.args.format.upper()}") outfile = self.prefix + infile.stem sink, outfile = getSink(self.args.format, outfile, progress=lambda: progress.update(0)) if not sink: print( "The input file is already a replay file. Nothing to do.") sys.exit(1) fd = open(infile, "rb") replay = Replay(fd, handler=sink) print(f"\n[+] Succesfully wrote '{outfile}'") sink.cleanup() fd.close()
def main(): """ Parse the provided command line arguments and launch the GUI. :return: The app exit code (0 for normal exit, non-zero for errors) """ parser = argparse.ArgumentParser() parser.add_argument("replay", help="Replay files to open on launch (optional)", nargs="*") parser.add_argument("-b", "--bind", help="Bind address (default: 127.0.0.1)", default="127.0.0.1") parser.add_argument("-p", "--port", help="Bind port (default: 3000)", default=3000) parser.add_argument("-o", "--output", help="Output folder", default="pyrdp_output") parser.add_argument("-L", "--log-level", help="Log level", default=None, choices=["INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL"], nargs="?") parser.add_argument("-F", "--log-filter", help="Only show logs from this logger name (accepts '*' wildcards)", default=None) parser.add_argument("--headless", help="Parse a replay without rendering the user interface.", action="store_true") args = parser.parse_args() cfg = settings.load(f'{settings.CONFIG_DIR}/player.ini', DEFAULTS) # Modify configuration with switches. if args.log_level: cfg.set('vars', 'level', args.log_level) if args.log_filter: cfg.set('logs', 'filter', args.log_filter) if args.output: cfg.set('vars', 'output_dir', args.output) outDir = Path(cfg.get('vars', 'output_dir')) outDir.mkdir(exist_ok=True) configureLoggers(cfg) logger = logging.getLogger(LOGGER_NAMES.PYRDP) if cfg.getboolean('logs', 'notifications', fallback=False) and not args.headless: enableNotifications(logger) if not HAS_GUI and not args.headless: logger.error('Headless mode is not specified and PySide2 is not installed.' ' Install PySide2 to use the graphical user interface.') sys.exit(127) if not args.headless: app = QApplication(sys.argv) mainWindow = MainWindow(args.bind, int(args.port), args.replay) mainWindow.showMaximized() mainWindow.show() return app.exec_() else: logger.info('Starting PyRDP Player in headless mode.') from pyrdp.player import HeadlessEventHandler from pyrdp.player.Replay import Replay processEvents = HeadlessEventHandler() for replay in args.replay: processEvents.output.write(f'== REPLAY FILE: {replay}\n') fd = open(replay, "rb") replay = Replay(fd, handler=processEvents) processEvents.output.write('\n-- END --------------------------------\n')
def processReplay(self, infile: Path): widgets = [ progressbar.FormatLabel('Encoding MP4 '), progressbar.BouncingBar(), progressbar.FormatLabel(' Elapsed: %(elapsed)s'), ] with progressbar.ProgressBar(widgets=widgets) as progress: print(f"[*] Converting '{infile}' to MP4.") outfile = self.prefix + infile.stem + '.mp4' sink = Mp4EventHandler(outfile, progress=lambda: progress.update(0)) fd = open(infile, "rb") replay = Replay(fd, handler=sink) print(f"\n[+] Succesfully wrote '{outfile}'") sink.cleanup() fd.close()
def processReplay(self, infile: Path): with open(infile, "rb") as f: replay = Replay(f) print(f"[*] Converting '{infile}' to {self.args.format.upper()}") outfile = self.prefix + infile.stem sink, outfile = getSink(self.args.format, outfile) if not sink: print("The input file is already a replay file. Nothing to do.") sys.exit(1) for event, _ in progressbar(replay): sink.onPDUReceived(event) print(f"\n[+] Succesfully wrote '{outfile}'") sink.cleanup()
def main(): """ Parse the provided command line arguments and launch the GUI. :return: The app exit code (0 for normal exit, non-zero for errors) """ parser = argparse.ArgumentParser() parser.add_argument("replay", help="Replay files to open on launch (optional)", nargs="*") parser.add_argument("-b", "--bind", help="Bind address (default: 127.0.0.1)", default="127.0.0.1") parser.add_argument("-p", "--port", help="Bind port (default: 3000)", default=3000) parser.add_argument("-o", "--output", help="Output folder", default="pyrdp_output") parser.add_argument( "-L", "--log-level", help="Log level", default="INFO", choices=["INFO", "DEBUG", "WARNING", "ERROR", "CRITICAL"], nargs="?") parser.add_argument( "--headless", help="Parse a replay without rendering the user interface.", action="store_true") args = parser.parse_args() outDir = Path(args.output) outDir.mkdir(exist_ok=True) logLevel = getattr(logging, args.log_level) logger = prepareLoggers(logLevel, outDir, args.headless) if not HAS_GUI and not args.headless: logger.error( 'Headless mode is not specified and PySide2 is not installed. Install PySide2 to use the graphical user interface.' ) sys.exit(127) if not args.headless: app = QApplication(sys.argv) mainWindow = MainWindow(args.bind, int(args.port), args.replay) mainWindow.show() return app.exec_() else: logger.info('Starting PyRDP Player in headless mode.') from pyrdp.player import HeadlessEventHandler from pyrdp.player.Replay import Replay processEvents = HeadlessEventHandler() for replay in args.replay: processEvents.output.write(f'== REPLAY FILE: {replay}\n') fd = open(replay, "rb") replay = Replay(fd, handler=processEvents) processEvents.output.write( '\n-- END --------------------------------\n')