@Override
 public void exec(Sys sys, User user, Group group, String used, String[] args, Message message) {
   if (args.length >= 2) {
     String from = args[0], to = args[1];
     try {
       JSONObject res =
           Unirest.get(
                   String.format(
                       "http://www.distance24.org/route.json?stops=%s",
                       URLEncoder.encode(from + "|" + to, "UTF-8")))
               .asJson()
               .getBody()
               .getObject();
       JSONArray arr = res.getJSONArray("stops");
       boolean fromValid = true, toValid = true;
       if (arr.getJSONObject(0).getString("type").equalsIgnoreCase("Invalid")) {
         fromValid = false;
       } else {
         from =
             arr.getJSONObject(0).getString("city")
                 + (arr.getJSONObject(0).has("region")
                     ? ", " + arr.getJSONObject(0).getString("region")
                     : "");
       }
       if (arr.getJSONObject(1).getString("type").equalsIgnoreCase("Invalid")) {
         toValid = false;
       } else {
         to =
             arr.getJSONObject(1).getString("city")
                 + ", "
                 + (arr.getJSONObject(1).has("region")
                     ? ", " + arr.getJSONObject(1).getString("region")
                     : "");
       }
       if (fromValid && toValid) {
         group.sendMessage(
             sys.message()
                 .escaped("Distance (%s => %s): %s km", from, to, res.getDouble("distance")));
       } else {
         String disp = "";
         if (!fromValid) {
           disp += from;
         }
         if (!toValid) {
           disp += (disp.isEmpty() ? "" : ", ") + to;
         }
         group.sendMessage(sys.message().escaped("[Distance] Invalid city name(s): " + disp));
       }
     } catch (IOException | UnirestException e) {
       e.printStackTrace();
     }
   } else {
     this.sendUsage(sys, user, group);
   }
 }
  @Override
  public void exec(Sys sys, User user, Group group, String used, String[] args, Message message) {
    if (args.length < 2) {
      sendUsage(sys, user, group);
    } else {
      Show show = SuperBotShows.getShow(args[0]);
      String ep = args[1].toUpperCase();

      MessageBuilder<?> mb = sys.message();
      if (show == null) {
        group.sendMessage(mb.escaped("Invalid show name: " + args[0]));
      } else if (ep.equalsIgnoreCase("none") || ep.equalsIgnoreCase("remove")) {
        Map<String, String> prg = SuperBotController.getProgress(show);
        prg.remove(user.getUsername());
        SuperBotController.PROGRESS.put(show.getMainName(), prg);
        group.sendMessage(
            mb.escaped(
                    "Removed "
                        + user.getDisplayName().orElse(user.getUsername())
                        + "'s progress on ")
                .bold(true)
                .escaped(show.getDisplay()));
        SuperBotController.saveProgress();
      } else if (!SuperBotShows.EPISODE_PATTERN.matcher(ep).matches()) {
        group.sendMessage(mb.escaped("Invalid episode: " + ep + " (doesn't match SxEyy format)"));
      } else {
        Map<String, String> prg = SuperBotController.getProgress(show);
        prg.put(user.getUsername(), ep);
        SuperBotController.PROGRESS.put(show.getMainName(), prg);
        group.sendMessage(
            mb.escaped(
                    "Set " + user.getDisplayName().orElse(user.getUsername()) + "'s progress on ")
                .bold(true)
                .escaped(show.getDisplay())
                .bold(false)
                .escaped(" to " + ep));
        SuperBotController.saveProgress();
      }
    }
  }
 @Override
 public void exec(Sys sys, User user, Group group, String used, String[] args, Message message) {
   if (args.length == 0) {
     this.sendUsage(sys, user, group);
   } else {
     MessageBuilder mb = sys.message();
     Show show = SuperBotShows.getShow(args[0]);
     if (show != null) {
       if (SuperBotShows.removeLink(args[0])) {
         group.sendMessage(
             mb.bold(true)
                 .escaped("Removed link (" + args[0] + ") from: ")
                 .bold(false)
                 .escaped(show.getDisplay()));
       } else {
         group.sendMessage(mb.escaped("Something went wrong."));
       }
     } else {
       group.sendMessage(mb.escaped("I couldn't find a show with the name \"" + args[0] + "\""));
     }
   }
 }
 @Override
 public void exec(Sys sys, User user, Group group, String used, String[] args, Message message) {
   MessageBuilder mb = sys.message();
   if (args.length == 0) {
     Optional<Profile> prof = user.getProfile();
     if (prof.isPresent()) {
       mb.bold(true).escaped("Your profile (" + prof.get().getName() + "):").bold(false);
       for (Entry<String, String> acc : prof.get().getAccounts().entrySet()) {
         Sys sy = SuperBotController.PROVIDERS.get(acc.getKey());
         mb.newLine()
             .escaped(
                 "   "
                     + acc.getKey()
                     + ": "
                     + (sy != null ? sy.getUserFriendlyName(acc.getValue()) : acc.getValue()));
       }
     } else {
       this.sendNoProfile(sys, user, group);
       return;
     }
   } else {
     String s = sys.isUIDCaseSensitive() ? args[0] : args[0].toLowerCase();
     Optional<Profile> prof = Profile.get(sys, s);
     if (prof.isPresent()) {
       mb.bold(true).escaped(" " + s + "'s profile (" + prof.get().getName() + "):").bold(false);
       for (Entry<String, String> acc : prof.get().getAccounts().entrySet()) {
         Sys sy = SuperBotController.PROVIDERS.get(acc.getKey());
         mb.newLine()
             .escaped(
                 "   "
                     + acc.getKey()
                     + ": "
                     + (sy != null ? sy.getUserFriendlyName(acc.getValue()) : acc.getValue()));
       }
     } else {
       mb.escaped("No profile with (provider: " + sys.getName() + ", name: " + s + ")");
     }
   }
   group.sendMessage(mb);
 }