replay: add nice arg parser
diff --git a/selfdrive/ui/replay/main.cc b/selfdrive/ui/replay/main.cc
index acc8b5d4d36157..be36d5f65d1769 100644
--- a/selfdrive/ui/replay/main.cc
+++ b/selfdrive/ui/replay/main.cc
@@ -3,8 +3,11 @@
 #include <termios.h>
 
 #include <QApplication>
+#include <QCommandLineParser>
 #include <QThread>
 
+const QString DEMO_ROUTE = "3533c53bb29502d1|2019-12-10--01-13-27";
+
 int getch() {
   int ch;
   struct termios oldt;
@@ -58,18 +61,28 @@ void keyboardThread(Replay *replay) {
 int main(int argc, char *argv[]){
   QApplication a(argc, argv);
 
-  QString route(argv[1]);
-  if (route == "") {
-    printf("Usage: ./replay \"route\"\n");
-    printf("  For a public demo route, use '3533c53bb29502d1|2019-12-10--01-13-27'\n");
-    return 1;
+  QCommandLineParser parser;
+  parser.setApplicationDescription("Mock openpilot components by publishing logged messages.");
+  parser.addHelpOption();
+  parser.addPositionalArgument("route", "the drive to replay. find your drives at connect.comma.ai");
+  parser.addOption({{"a", "allow"}, "whitelist of services to send", "allow"});
+  parser.addOption({{"b", "block"}, "blacklist of services to send", "block"});
+  parser.addOption({"demo", "use a demo route instead of providing your own"});
+
+  parser.process(a);
+  const QStringList args = parser.positionalArguments();
+  if (args.empty() && !parser.isSet("demo")) {
+    parser.showHelp();
   }
 
-  Replay *replay = new Replay(route);
+  const QString route = args.empty() ? DEMO_ROUTE : args.first();
+  Replay *replay = new Replay(route, parser.value("allow").split(","), parser.value("block").split(","));
   replay->start();
 
+  // start keyboard control thread
   QThread *t = QThread::create(keyboardThread, replay);
   QObject::connect(t, &QThread::finished, t, &QThread::deleteLater);
   t->start();
+
   return a.exec();
 }
diff --git a/selfdrive/ui/replay/replay.cc b/selfdrive/ui/replay/replay.cc
index 3cef0bcd792a0a..6f76cd73d74b4b 100644
--- a/selfdrive/ui/replay/replay.cc
+++ b/selfdrive/ui/replay/replay.cc
@@ -8,13 +8,7 @@
 #include "selfdrive/common/timing.h"
 #include "selfdrive/hardware/hw.h"
 
-Replay::Replay(QString route, SubMaster *sm_, QObject *parent) : sm(sm_), QObject(parent) {
-  QStringList block = QString(getenv("BLOCK")).split(",");
-  qDebug() << "blocklist" << block;
-
-  QStringList allow = QString(getenv("ALLOW")).split(",");
-  qDebug() << "allowlist" << allow;
-
+Replay::Replay(QString route, QStringList allow, QStringList block, SubMaster *sm_, QObject *parent) : sm(sm_), QObject(parent) {
   std::vector<const char*> s;
   for (const auto &it : services) {
     if ((allow[0].size() == 0 || allow.contains(it.name)) &&
diff --git a/selfdrive/ui/replay/replay.h b/selfdrive/ui/replay/replay.h
index 8b7dc93b4a0382..7a1ea13c0ed6ab 100644
--- a/selfdrive/ui/replay/replay.h
+++ b/selfdrive/ui/replay/replay.h
@@ -20,7 +20,7 @@ class Replay : public QObject {
   Q_OBJECT
 
 public:
-  Replay(QString route, SubMaster *sm = nullptr, QObject *parent = 0);
+  Replay(QString route, QStringList allow, QStringList block, SubMaster *sm = nullptr, QObject *parent = 0);
 
   void start();
   void addSegment(int n);
