docs: def download(link, outdir='.', chunk_size=4096):
      '''
      This is the Main function, which downloads a given link
      and saves on outdir (default = current directory)
      '''
      url = None
      fh = None
      eta = 'unknown '
      bytes_so_far = 0
      filename = filename_from_url(link) or "."
      cj = cjar.CookieJar()
  
      # get filename for temp file in current directory
      (fd_tmp, tmpfile) = tempfile.mkstemp(
          ".tmp", prefix=filename + ".", dir=outdir)
      os.close(fd_tmp)
      os.unlink(tmpfile)
  
      try:
          opener = ulib.build_opener(ulib.HTTPCookieProcessor(cj))
          url = opener.open(link)
          fh = open(tmpfile, mode='wb')
  
          headers = url.info()
          try:
              total_size = int(headers['Content-Length'])
          except (ValueError, KeyError, TypeError):
              total_size = 'unknown'
  
          try:
              md5_header = headers['Content-MD5']
          except (ValueError, KeyError, TypeError):
              md5_header = None
  
          # Define which callback we're gonna use
          if total_size != 'unknown':
              if CONSOLE_WIDTH > 57:
                  reporthook = report_bar
              else:
                  reporthook = report_onlysize
          else:
              reporthook = report_unknown
  
          # Below are the registers to calculate network transfer rate
          time_register = time()
          speed = 0.0
          speed_list = []
          bytes_register = 0.0
          eta = 'unknown '
  
          # Loop that reads in chunks, calculates speed and does the callback to
          # print the progress
          while True:
              chunk = url.read(chunk_size)
              # Update Download Speed every 1 second
              if time() - time_register > 0.5:
                  speed = (bytes_so_far - bytes_register) / \
                      (time() - time_register)
                  speed_list.append(speed)
  
                  # Set register properly for future use
                  time_register = time()
                  bytes_register = bytes_so_far
  
                  # Estimative of remaining download time
                  if total_size != 'unknown' and len(speed_list) == 3:
                      speed_mean = sum(speed_list) / 3
                      eta_sec = int((total_size - bytes_so_far) / speed_mean)
                      eta = str(datetime.timedelta(seconds=eta_sec))
                      speed_list = []
  
              bytes_so_far += len(chunk)
  
              if not chunk:
                  sys.stdout.write('\n')
                  break
  
              fh.write(chunk)
              reporthook(bytes_so_far, total_size, speed, eta)
      except KeyboardInterrupt:
          print('\n\nCtrl + C: Download aborted by user')
          print('Partial downloaded file:\n{0}'.format(os.path.abspath(tmpfile)))
          sys.exit(1)
      finally:
          if url:
              url.close()
          if fh:
              fh.close()
  
      filenamealt = filename_from_headers(headers)
      if filenamealt:
          filename = filenamealt
  
      # add numeric '(x)' suffix if filename already exists
      if os.path.exists(os.path.join(outdir, filename)):
          filename = filename_fix_existing(filename, outdir)
      filename = os.path.join(outdir, filename)
  
      shutil.move(tmpfile, filename)
  
      # Check if sizes matches
      if total_size != 'unknown' and total_size != bytes_so_far:
          print(
              '\n\nWARNING!! Downloaded file size mismatches... Probably corrupted...')
  
      # Check md5 if it was in html header
      if md5_header:
          print('\nValidating MD5 checksum...')
          if md5_header == md5sum(filename):
              print('MD5 checksum passed!')
          else:
              print('MD5 checksum do NOT passed!!!')
  
      return filename