public function hostname(Request $req, $hostname)
 {
     // temporarily disable Stats endpoint.
     return 'disabled';
     // Validate hostname
     if (!$this->is_valid_domain_name($hostname)) {
         return new Response(['error' => 'invalid hostname'], Response::HTTP_BAD_REQUEST);
     }
     // Validate if site exists
     if (!SitesController::siteExists($hostname)) {
         return new Response(['error' => 'site not proxied'], Response::HTTP_BAD_REQUEST);
     }
     return DB::table('stats_hosts')->insertGetId(['hostname' => $hostname, 'created_at' => DB::raw('NOW()'), 'updated_at' => DB::raw('NOW()')]);
 }
 /**
  * @inheritdoc
  */
 public function handle($arguments)
 {
     // This will send a message using `sendMessage` method behind the scenes to
     // the user/chat id who triggered this command.
     // `replyWith<Message|Photo|Audio|Video|Voice|Document|Sticker|Location|ChatAction>()` all the available methods are dynamically
     // handled when you replace `send<Method>` with `replyWith` and use all their parameters except chat_id.
     $this->replyWithMessage('O Ahoy! está a funcionar sem problemas, meu capitão!');
     $load = sys_getloadavg();
     $this->replyWithMessage("Os sistemas estão operacionais, com um load imediato de " . $load[0] . ".");
     if ($load[0] > 1) {
         $this->replyWithMessage("Precisamos de ter algum cuidado com a sobrecarga, capitão!");
     }
     $uptime = shell_exec("cut -d. -f1 /proc/uptime");
     $days = floor($uptime / 60 / 60 / 24);
     $hours = $uptime / 60 / 60 % 24;
     $mins = $uptime / 60 % 60;
     $secs = $uptime % 60;
     $uptime_msg = "Estamos a navegar sem parar à ";
     if ($days > 0) {
         $uptime_msg .= $days . " dias e ";
     }
     $uptime_msg .= $hours . " horas.";
     $this->replyWithMessage($uptime_msg);
     $num_proxies = count(Proxy::all());
     $num_sites = count(SitesController::getAllSites());
     $this->replyWithMessage("Existem " . $num_proxies . " proxies e " . $num_sites . " sites bloqueados.");
     $num_ultima_hora = DB::table('stats_hosts')->where('created_at', '>', \Carbon\Carbon::now()->subHours(1))->count();
     $num_ultimo_minuto = DB::table('stats_hosts')->where('created_at', '>', \Carbon\Carbon::now()->subMinutes(1))->count();
     $this->replyWithMessage($num_ultima_hora . " páginas acedidas na última hora, e {$num_ultimo_minuto} no último minuto.");
     //URL of your extension
     $url = "https://chrome.google.com/webstore/detail/ahoy/ljighgeflmhnpljodhpcifcojkpancpm";
     $file_string = file_get_contents($url);
     //Get the rating
     preg_match('/ratingValue" content="(\\d*\\d+\\.\\d+)/', $file_string, $ratings);
     $rating = $ratings[1];
     //Get the nb of users
     preg_match('/class="e-f-ih" title="(\\d*\\,\\d+)/', $file_string, $users);
     $users = $users[1];
     $this->replyWithMessage("Existem {$users} utilizadores com um rating médio de {$rating}");
     // Trigger another command dynamically from within this command
     // When you want to chain multiple commands within one or process the request further.
     // The method supports second parameter arguments which you can optionally pass, By default
     // it'll pass the same arguments that are received for this command originally.
     //$this->triggerCommand('subscribe');
 }
 /**
  * Generates and outputs a new PAC based on a given IP.
  *
  * This is going to be used on devices that don't allow real time PAC generation.
  *
  * @param Request $req
  *
  * @return string the generated PAC
  */
 public function generatePAC(Request $req)
 {
     $proxy_addr = Input::get('proxy_addr', $this->getProxy($req));
     if (is_array($proxy_addr)) {
         $proxy_addr = $proxy_addr['host'] . ":" . $proxy_addr['port'];
     }
     // check for cache
     if (Cache::tags(['generate_pac'])->has($proxy_addr)) {
         return new Response(Cache::tags(['generate_pac'])->get($proxy_addr), 200, ['Content-Type' => 'application/x-ns-proxy-autoconfig']);
     }
     $pac = "function FindProxyForURL(url, host) {\n";
     foreach (SitesController::getAllSites() as $site) {
         $pac .= "   if (host == \"{$site}\" || host == \"www.{$site}\") { \n";
         $pac .= "       return 'PROXY " . e($proxy_addr) . "';\n";
         $pac .= "   }\n";
     }
     $pac .= "   return 'DIRECT';\n";
     $pac .= "}";
     Cache::tags(['generate_pac'])->put($proxy_addr, $pac, 3600);
     // Store it for a day
     return new Response($pac, 200, ['Content-Type' => 'application/x-ns-proxy-autoconfig']);
 }
 /**
  * When a Ahoy! user gets into a blocked site that isn't on the whitelist,
  *  the application will report back notifying us that a new site should be blocked.
  *
  * @TODO store this information in the database, and add some algorithm to data treatment
  *
  * @param Request $request
  */
 public function autoReportBlockedSite(Request $request)
 {
     $site = $request->input('site');
     $site = str_replace('www.', "", parse_url($site, PHP_URL_HOST));
     $site = rtrim($site, '.');
     // Sometimes there are URL's with a extra dot in the end. Strip all the dots.
     if (empty($site)) {
         return new Response(['error' => 'no site provided'], Response::HTTP_BAD_REQUEST);
     }
     // Validate if site is already on the list
     foreach (SitesController::getAllSites() as $site_in_list) {
         if ($site == $site_in_list) {
             return new Response(['error' => 'site already in the list'], Response::HTTP_ALREADY_REPORTED);
         }
     }
     if (Cache::has('site-ignore-' . $site)) {
         return new Response(['error' => 'site in the ignore list'], Response::HTTP_UNPROCESSABLE_ENTITY);
     }
     // @todo use this for rate limit
     // Test if site was reported in the last 5 minutes
     if (Cache::has('ip-reported-' . $site)) {
         $response = Response(['error' => 'site reported in less than 5 minutes']);
         $response->setStatusCode('420', "Enhance Your Calm");
         return $response;
     }
     // Add a cache key for when a given host is reported. This key has 5 minutes duration
     $site_reported = Cache::remember('ip-reported-' . $site, 5, function () {
         return true;
     });
     // Get the IP details
     $user_ip = $request->ip();
     $ip_details = Cache::remember('ip-details-' . $user_ip, 3600, function () use($user_ip) {
         return $this->getIPDetails($user_ip);
     });
     // Fallback
     if ($ip_details == null) {
         $ip_details = new \stdClass();
         $ip_details->org = "Unknown";
     }
     // Store the site host in cache, without www
     $site_id = $this->generateUniqueID();
     Cache::put('site-' . $site_id, $site, 3600);
     // Store it for a day
     // @todo instead of sending to telegram, store in a database
     Telegram::sendMessage(env("TELEGRAM_CHANNEL"), "Foi detectado um novo site bloqueado.\n\t\t\t\tURL: {$site}\n\t\t\t\tIP: {$user_ip}\n\t\t\t\tProvider: {$ip_details->org}", true);
     Telegram::sendMessage(env("TELEGRAM_CHANNEL"), "Para incluir este site, utiliza o comando /adicionar {$site_id}\nPara ignorar este site, utiliza o comando /ignorar {$site_id}");
     return ['success' => 'true'];
 }